Skip to content

Commit

Permalink
Merge branch 'v1.3-bugfix' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
taye committed Jan 2, 2018
2 parents 25c2300 + f0462da commit 0ac7ef7
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 6 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## v1.3.2
- fixed issues with action options ([PR
#567](https://github.com/taye/interact.js/pull/567), [issue
#570](https://github.com/taye/interact.js/issues/570))

## v1.3.1
- fixed iOS preventDefault passive event issue ([issue
#561](https://github.com/taye/interact.js/issues/561))

## v1.3.1
- allowed calling `draggable.unset()` during `dragend` and `drop` event
listeners ([issue #560](https://github.com/taye/interact.js/issues/560))
- allowed snap to be enabled with falsey targets value [issue
#562](https://github.com/taye/interact.js/issues/562)

## v1.3.0

Most notably:
Expand Down
12 changes: 7 additions & 5 deletions src/Interactable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const clone = require('./utils/clone');
const is = require('./utils/is');
const events = require('./utils/events');
const extend = require('./utils/extend');
Expand Down Expand Up @@ -63,8 +64,9 @@ class Interactable {
if (option in defaults[action]) {
// if the option in the options arg is an object value
if (is.object(options[option])) {
// duplicate the object
this.options[action][option] = extend(this.options[action][option] || {}, options[option]);
// duplicate the object and merge
this.options[action][option] = clone(this.options[action][option] || {});
extend(this.options[action][option], options[option]);

if (is.object(defaults.perAction[option]) && 'enabled' in defaults.perAction[option]) {
this.options[action][option].enabled = options[option].enabled === false? false : true;
Expand Down Expand Up @@ -294,14 +296,14 @@ class Interactable {
options = {};
}

this.options = extend({}, defaults.base);
this.options = clone(defaults.base);

const perActions = extend({}, defaults.perAction);
const perActions = clone(defaults.perAction);

for (const actionName in actions.methodDict) {
const methodName = actions.methodDict[actionName];

this.options[actionName] = extend({}, defaults[actionName]);
this.options[actionName] = clone(defaults[actionName]);

this.setPerAction(actionName, perActions);

Expand Down
13 changes: 13 additions & 0 deletions src/utils/clone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const is = require('./is');

module.exports = function clone (source) {
const dest = {};
for (const prop in source) {
if (is.plainObject(source[prop])) {
dest[prop] = clone(source[prop]);
} else {
dest[prop] = source[prop];
}
}
return dest;
};
2 changes: 2 additions & 0 deletions src/utils/is.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const is = {
? thing instanceof _window.Element //DOM2
: thing.nodeType === 1 && typeof thing.nodeName === 'string');
},

plainObject: thing => is.object(thing) && thing.constructor.name === 'Object',
};

is.array = thing => (is.object(thing)
Expand Down
84 changes: 84 additions & 0 deletions tests/Interactable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const test = require('./test');
const d = require('./domator');

const Interactable = require('../src/Interactable');
const actions = require('../src/actions/base');

test('Interactable copies and extends defaults', t => {
actions.methodDict.test = 'testize';
Interactable.prototype.testize = function (options) {
this.setPerAction('test', options);
};

const defaults = require('../src/defaultOptions');
defaults.test = {
fromDefault: { a: 1, b: 2 },
specified: { c: 1, d: 2 },
};

const specified = { specified: 'parent' };

const div = d('div');
const interactable = new Interactable(div, { test: specified });

t.deepEqual(interactable.options.test.specified, specified.specified,
'specified options are properly set');
t.deepEqual(interactable.options.test.fromDefault, defaults.test.fromDefault,
'default options are properly set');
t.notEqual(interactable.options.test.fromDefault, defaults.test.fromDefault,
'defaults are not aliased');

defaults.test.fromDefault.c = 3;
t.notOk('c' in interactable.options.test.fromDefault,
'modifying defaults does not affect constructed interactables');

// Undo global changes
delete actions.methodDict.test;
delete Interactable.prototype.testize;
delete defaults.test;

t.end();
});

test('Interactable copies and extends per action defaults', t => {
actions.methodDict.test = 'testize';
Interactable.prototype.testize = function (options) {
this.setPerAction('test', options);
};

const defaults = require('../src/defaultOptions');
defaults.perAction.testModifier = {
fromDefault: { a: 1, b: 2 },
specified: null,
};
defaults.test = { testModifier: defaults.perAction.testModifier };

const div = d('div');
const interactable = new Interactable(div, {});
interactable.testize({ testModifier: { specified: 'parent' } });

t.deepEqual(interactable.options.test, { testModifier: {
fromDefault: { a: 1, b: 2},
specified: 'parent',
}}, 'specified options are properly set');
t.deepEqual(
interactable.options.test.testModifier.fromDefault,
defaults.perAction.testModifier.fromDefault,
'default options are properly set');
t.notEqual(
interactable.options.test.testModifier.fromDefault,
defaults.perAction.testModifier.fromDefault,
'defaults are not aliased');

defaults.perAction.testModifier.fromDefault.c = 3;
t.notOk('c' in interactable.options.test.testModifier.fromDefault,
'modifying defaults does not affect constructed interactables');

// Undo global changes
delete actions.methodDict.test;
delete Interactable.prototype.test;
delete defaults.test;
delete defaults.perAction.testModifier;

t.end();
});
2 changes: 1 addition & 1 deletion tests/Interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ test('Interaction.start', t => {
const Interaction = require('../src/Interaction');
const interaction = new Interaction({});
const action = { name: 'TEST' };
const target = {};
const target = helpers.mockInteractable();
const element = {};
const pointer = helpers.newPointer();
const event = {};
Expand Down
52 changes: 52 additions & 0 deletions tests/helpers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const _ = require('lodash');
const { window: { document } } = require('../src/utils/window');
const utils = require('../src/utils');

let counter = 0;

Expand Down Expand Up @@ -64,6 +65,57 @@ const helpers = {
createEl (name) {
return document.createElement(name);
},

mockScope (options) {
return Object.assign({
documents: [],
defaults: require('../src/defaultOptions'),
interactions: [],
signals: require('../src/utils/Signals').new(),
Interaction: {
signals: require('../src/utils/Signals').new(),
new () {
return {};
},
},
InteractEvent: {
signals: require('../src/utils/Signals').new(),
},
Interactable: {
signals: require('../src/utils/Signals').new(),
},
}, options);
},

mockSignals () {
return {
on () {},
off () {},
fire () {},
};
},

mockInteractable (props) {
const Eventable = require('../src/Eventable');

return Object.assign(
{
options: {
deltaSource: 'page',
},
target: {},
events: new Eventable(),
getRect () {
return this.element
? utils.dom.getClientRect(this.element)
: { left: 0, top: 0, right: 0, bottom: 0 };
},
fire (event) {
this.events.fire(event);
},
},
props);
},
};

module.exports = helpers;
1 change: 1 addition & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('./Interactable');
require('./Interaction');

// Legacy browser support
Expand Down

0 comments on commit 0ac7ef7

Please sign in to comment.