From 509a7a611a6e9c8998bd2ad6989df42050b85531 Mon Sep 17 00:00:00 2001 From: Taye Adeyemi Date: Thu, 17 May 2018 14:21:43 +0200 Subject: [PATCH] modifiers: simplify things --- packages/inertia/index.js | 11 +- packages/modifiers/base.js | 193 ++++++++++++++-------- packages/modifiers/restrict.js | 27 +-- packages/modifiers/restrictEdges.js | 17 +- packages/modifiers/snap.js | 8 +- packages/modifiers/tests/restrictEdges.js | 25 +-- packages/modifiers/tests/restrictSize.js | 3 - packages/modifiers/tests/snap.js | 14 +- packages/modifiers/tests/snapEdges.js | 16 +- packages/modifiers/tests/snapSize.js | 14 +- 10 files changed, 168 insertions(+), 160 deletions(-) diff --git a/packages/inertia/index.js b/packages/inertia/index.js index cad2a63cf..c85f67ae3 100644 --- a/packages/inertia/index.js +++ b/packages/inertia/index.js @@ -77,7 +77,6 @@ function resume ({ interaction, event, pointer, eventTarget }, scope) { interaction, event, interaction.prepared.name, 'resume', interaction.element); interaction._fireEvent(resumeEvent); - interaction.modifiers.statuses.forEach(modifiers.resetStatus); utils.pointer.copyCoords(interaction.coords.prev, interaction.coords.cur); break; @@ -117,13 +116,9 @@ function release ({ interaction, event }, scope) { const modifierArg = { interaction, pageCoords: utils.extend({}, interaction.coords.cur.page), - statuses: inertiaPossible && interaction.modifiers.statuses.map(modifierStatus => { - const newStatus = utils.extend({}, modifierStatus); - - modifiers.resetStatus(newStatus); - - return newStatus; - }), + statuses: inertiaPossible && interaction.modifiers.statuses.map( + modifierStatus => utils.extend({}, modifierStatus) + ), preEnd: true, requireEndOnly: true, }; diff --git a/packages/modifiers/base.js b/packages/modifiers/base.js index 580f9a1a7..839edc09f 100644 --- a/packages/modifiers/base.js +++ b/packages/modifiers/base.js @@ -34,58 +34,99 @@ function init (scope) { interactions.signals.on('after-action-start', restoreCurCoords); interactions.signals.on('after-action-move', restoreCurCoords); - interactions.signals.on('action-stop', restoreCurCoords); + interactions.signals.on('stop', stop); } function startAll (arg) { - const { statuses, startOffset, rect, pageCoords: page } = arg; + for (const status of arg.statuses) { + if (status.methods.start) { + arg.status = status; + status.methods.start(arg); + } + } +} - if (rect) { - startOffset.left = page.x - rect.left; - startOffset.top = page.y - rect.top; +function getRectOffset (rect, coords) { + return rect + ? { + left : coords.x - rect.left, + top : coords.y - rect.top, + right : rect.right - coords.x, + bottom: rect.bottom - coords.y, + } + : { + left : 0, + top : 0, + right : 0, + bottom: 0, + }; +} - startOffset.right = rect.right - page.x; - startOffset.bottom = rect.bottom - page.y; +function start ({ interaction, phase }, pageCoords) { + const { target: interactable, element } = interaction; + const modifierList = getModifierList(interaction); + const statuses = prepareStatuses(modifierList); - if (!('width' in rect)) { rect.width = rect.right - rect.left; } - if (!('height' in rect)) { rect.height = rect.bottom - rect.top ; } - } - else { - startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0; - } + const rect = extend({}, interactable.getRect(element)); - for (const status of statuses) { - arg.status = status; - status.methods.start(arg); - } + if (!('width' in rect)) { rect.width = rect.right - rect.left; } + if (!('height' in rect)) { rect.height = rect.bottom - rect.top ; } + + const startOffset = getRectOffset(rect, pageCoords); + interaction.modifiers.startOffset = startOffset; + + const arg = { + interaction, + interactable, + element, + pageCoords, + phase, + rect, + startOffset, + statuses, + preEnd: false, + requireEndOnly: false, + }; + + interaction.modifiers.statuses = statuses; + startAll(arg); + + arg.pageCoords = extend({}, interaction.coords.start.page); + + const result = interaction.modifiers.result = setAll(arg); + + return result; } function setAll (arg) { - const { interaction, statuses, preEnd, requireEndOnly } = arg; + const { interaction, preEnd, requireEndOnly, rect, skipModifiers } = arg; + + const statuses = skipModifiers + ? arg.statuses.slice(interaction.modifiers.skil) + : arg.statuses; arg.coords = extend({}, arg.pageCoords); + arg.rect = extend({}, rect); const result = { + delta: { x: 0, y: 0 }, coords: arg.coords, shouldMove: true, }; - resetStatus(result); - for (const status of statuses) { const { options } = status; - if (!shouldDo(options, preEnd, requireEndOnly)) { continue; } + if (!status.methods.set || + !shouldDo(options, preEnd, requireEndOnly)) { continue; } arg.status = status; status.methods.set(arg); + } - arg.coords.x += status.delta.x; - arg.coords.y += status.delta.y; + result.delta.x = arg.coords.x - arg.pageCoords.x; + result.delta.y = arg.coords.y - arg.pageCoords.y; - result.delta.x += status.delta.x; - result.delta.y += status.delta.y; - } const differsFromPrevCoords = interaction.coords.prev.page.x !== result.coords.x || @@ -103,60 +144,34 @@ function setAll (arg) { function prepareStatuses (modifierList) { const statuses = []; - for (const { options, methods } of modifierList) { + for (let index = 0; index < modifierList.length; index++) { + const { options, methods } = modifierList[index]; + if (options && options.enabled === false) { continue; } const status = { options, methods, + index, }; - resetStatus(status); statuses.push(status); } return statuses; } -function resetStatus (status) { - status.delta = { x: 0, y: 0 }; -} - -function start ({ interaction, phase }, pageCoords) { - const { target: interactable, element } = interaction; - const rect = interactable.getRect(element); - const modifierList = getModifierList(interaction); - const statuses = prepareStatuses(modifierList); - - const arg = { - interaction, - interactable, - element, - pageCoords, - phase, - rect, - startOffset: interaction.modifiers.startOffset, - statuses, - preEnd: false, - requireEndOnly: false, - }; - - interaction.modifiers.statuses = statuses; - startAll(arg); - - arg.pageCoords = extend({}, interaction.coords.start.page); - interaction.modifiers.result = setAll(arg); -} - function beforeMove ({ interaction, phase, preEnd, skipModifiers }) { + const { target: interactable, element } = interaction; const modifierResult = setAll( { interaction, - interactable: interaction.target, - element: interaction.elemnet, + interactable, + element, preEnd, phase, pageCoords: interaction.coords.cur.page, + rect: interactable.getRect(element), statuses: interaction.modifiers.statuses, requireEndOnly: false, skipModifiers, @@ -171,19 +186,61 @@ function beforeMove ({ interaction, phase, preEnd, skipModifiers }) { } } -function beforeEnd ({ interaction, event }) { - const modifierList = getModifierList(interaction); +function beforeEnd (arg) { + const { interaction, event } = arg; + const statuses = interaction.modifiers.statuses; + + if (!statuses || !statuses.length) { + return; + } + + let didPreEnd = false; + + for (const status of statuses) { + arg.status = status; + const { options, methods } = status; + + const endResult = methods.beforeEnd && methods.beforeEnd(arg); + + if (endResult === false) { + return false; + } - for (const { options } of modifierList) { // if the endOnly option is true for any modifier - if (shouldDo(options, true, true)) { + if (!didPreEnd && shouldDo(options, true, true)) { // fire a move event at the modified coordinates interaction.move({ event, preEnd: true }); - break; + didPreEnd = true; } } } +function stop (arg) { + const { interaction } = arg; + const statuses = interaction.modifiers.statuses; + + if (!statuses || !statuses.length) { + return; + } + + const modifierArg = extend({ + statuses, + interactable: interaction.target, + element: interaction.element, + }, arg); + + + restoreCurCoords(arg); + + for (const status of statuses) { + modifierArg.status = status; + + if (status.methods.stop) { status.methods.stop(modifierArg); } + } + + arg.interaction.modifiers.statuses = null; +} + function setCurCoords (arg) { const { interaction } = arg; const modifierArg = extend({ @@ -193,8 +250,8 @@ function setCurCoords (arg) { const { delta } = interaction.modifiers.result; - modifierArg.page.x += delta.x; - modifierArg.page.y += delta.y; + modifierArg.page.x += delta.x; + modifierArg.page.y += delta.y; modifierArg.client.x += delta.x; modifierArg.client.y += delta.y; } @@ -241,10 +298,10 @@ export default { startAll, setAll, prepareStatuses, - resetStatus, start, beforeMove, beforeEnd, + stop, shouldDo, getModifierList, }; diff --git a/packages/modifiers/restrict.js b/packages/modifiers/restrict.js index 771bfe343..e6465cb20 100644 --- a/packages/modifiers/restrict.js +++ b/packages/modifiers/restrict.js @@ -1,5 +1,4 @@ import * as is from '@interactjs/utils/is'; -import extend from '@interactjs/utils/extend'; import rectUtils from '@interactjs/utils/rect'; function start ({ rect, startOffset, status }) { @@ -26,40 +25,28 @@ function set ({ coords, interaction, status, phase }) { if (phase === 'start' && options.elementRect) { return; } - const page = extend({}, coords); - const restriction = getRestrictionRect(options.restriction, interaction, page); + const restriction = getRestrictionRect(options.restriction, interaction, coords); if (!restriction) { return status; } - status.delta.x = 0; - status.delta.y = 0; - const rect = restriction; - let modifiedX = page.x; - let modifiedY = page.y; // object is assumed to have // x, y, width, height or // left, top, right, bottom if ('x' in restriction && 'y' in restriction) { - modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right , page.x), rect.x + offset.left); - modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top ); + coords.x = Math.max(Math.min(rect.x + rect.width - offset.right , coords.x), rect.x + offset.left); + coords.y = Math.max(Math.min(rect.y + rect.height - offset.bottom, coords.y), rect.y + offset.top ); } else { - modifiedX = Math.max(Math.min(rect.right - offset.right , page.x), rect.left + offset.left); - modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top ); + coords.x = Math.max(Math.min(rect.right - offset.right , coords.x), rect.left + offset.left); + coords.y = Math.max(Math.min(rect.bottom - offset.bottom, coords.y), rect.top + offset.top ); } - - status.delta.x = modifiedX - page.x; - status.delta.y = modifiedY - page.y; - - status.modifiedX = modifiedX; - status.modifiedY = modifiedY; } -function getRestrictionRect (value, interaction, page) { +function getRestrictionRect (value, interaction, coords) { if (is.func(value)) { - return rectUtils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]); + return rectUtils.resolveRectLike(value, interaction.target, interaction.element, [coords.x, coords.y, interaction]); } else { return rectUtils.resolveRectLike(value, interaction.target, interaction.element); } diff --git a/packages/modifiers/restrictEdges.js b/packages/modifiers/restrictEdges.js index a427e0e82..747f9b6fd 100644 --- a/packages/modifiers/restrictEdges.js +++ b/packages/modifiers/restrictEdges.js @@ -53,27 +53,18 @@ function set ({ coords, interaction, status, phase }) { fixRect(inner, noInner); fixRect(outer, noOuter); - let modifiedX = page.x; - let modifiedY = page.y; - - status.delta.x = 0; - status.delta.y = 0; - if (edges.top) { - modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top); + coords.y = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top); } else if (edges.bottom) { - modifiedY = Math.max(Math.min(outer.bottom + offset.bottom, page.y), inner.bottom + offset.bottom); + coords.y = Math.max(Math.min(outer.bottom + offset.bottom, page.y), inner.bottom + offset.bottom); } if (edges.left) { - modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left); + coords.x = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left); } else if (edges.right) { - modifiedX = Math.max(Math.min(outer.right + offset.right, page.x), inner.right + offset.right); + coords.x = Math.max(Math.min(outer.right + offset.right, page.x), inner.right + offset.right); } - - status.delta.x = modifiedX - page.x; - status.delta.y = modifiedY - page.y; } function fixRect (rect, defaults) { diff --git a/packages/modifiers/snap.js b/packages/modifiers/snap.js index b936f1e2f..e5555ed73 100644 --- a/packages/modifiers/snap.js +++ b/packages/modifiers/snap.js @@ -128,12 +128,8 @@ function set ({ interaction, coords, status, phase }) { } if (closest.inRange) { - status.delta.x = closest.dx; - status.delta.y = closest.dy; - } - else { - status.delta.x = 0; - status.delta.y = 0; + coords.x = closest.target.x; + coords.y = closest.target.y; } } diff --git a/packages/modifiers/tests/restrictEdges.js b/packages/modifiers/tests/restrictEdges.js index 87844896a..32eb84c7c 100644 --- a/packages/modifiers/tests/restrictEdges.js +++ b/packages/modifiers/tests/restrictEdges.js @@ -15,31 +15,31 @@ test('restrictEdges', t => { const options = { enabled: true }; const coords = { x: 40, y: 40 }; const offset = { top: 0, left: 0, bottom: 0, right: 0 }; - const status = { - delta: { x: 0, y: 0 }, - options, - offset, - }; - const arg = { interaction, status, coords }; + const status = { options, offset }; + const arg = { interaction, status }; + + arg.coords = { ...coords }; // outer restriction options.outer = { top: 100, left: 100, bottom: 200, right: 200 }; restrictEdges.set(arg); t.deepEqual( - status.delta, - { x: 60, y: 60 }, + arg.coords, + { x: coords.y + 60, y: coords.y + 60 }, 'outer restriction is applied correctly' ); + arg.coords = { ...coords }; + // inner restriction options.outer = null; options.inner = { top: 0, left: 0, bottom: 10, right: 10 }; restrictEdges.set(arg); t.deepEqual( - status.delta, - { x: -40, y: -40 }, + arg.coords, + { x: coords.x - 40, y: coords.y - 40 }, 'inner restriction is applied correctly' ); @@ -50,14 +50,15 @@ test('restrictEdges', t => { bottom: 200, right: 200, }); + arg.coords = { ...coords }; options.outer = { top: 100, left: 100, bottom: 200, right: 200 }; options.inner = null; restrictEdges.set(arg); t.deepEqual( - status.delta, - { x: 160, y: 160 }, + arg.coords, + { x: coords.x + 160, y: coords.x + 160 }, 'outer restriction is applied correctly with offset' ); diff --git a/packages/modifiers/tests/restrictSize.js b/packages/modifiers/tests/restrictSize.js index e56c69bfb..6a584b731 100644 --- a/packages/modifiers/tests/restrictSize.js +++ b/packages/modifiers/tests/restrictSize.js @@ -20,7 +20,6 @@ test('restrictSize', t => { const pageCoords = { x: 5, y: 15 }; const offset = { top: 0, bottom: 0, left: 0, right: 0 }; const status = { - delta: { x: 0, y: 0 }, options, offset, }; @@ -39,7 +38,6 @@ test('restrictSize', t => { const pageCoords = { x: 5, y: 15 }; const offset = { top: 0, bottom: 0, left: 0, right: 0 }; const status = { - delta: { x: 0, y: 0 }, options, offset, }; @@ -58,7 +56,6 @@ test('restrictSize', t => { const pageCoords = { x: 5, y: 15 }; const offset = { top: 0, bottom: 0, left: 0, right: 0 }; const status = { - delta: { x: 0, y: 0 }, options, offset, }; diff --git a/packages/modifiers/tests/snap.js b/packages/modifiers/tests/snap.js index 683191806..c2016972b 100644 --- a/packages/modifiers/tests/snap.js +++ b/packages/modifiers/tests/snap.js @@ -1,5 +1,5 @@ import test from '@interactjs/_dev/test/test'; -import { mockSignals, mockInteractable, getProps } from '@interactjs/_dev/test/helpers'; +import { mockSignals, mockInteractable } from '@interactjs/_dev/test/helpers'; import snap from '@interactjs/modifiers/snap'; import Interaction from '@interactjs/core/Interaction'; @@ -34,16 +34,8 @@ test('modifiers/snap', t => { snap.set(arg); t.deepEqual( - getProps(status, 'range realX realY delta'.split(' ')), - { - range: Infinity, - realX: pageCoords.x, - realY: pageCoords.y, - delta: { - x: target0.x - pageCoords.x, - y: target0.y - pageCoords.y, - }, - }, + arg.coords, + target0, 'snap.set single target, zereo offset' ); diff --git a/packages/modifiers/tests/snapEdges.js b/packages/modifiers/tests/snapEdges.js index ac8d5d77c..48cce426e 100644 --- a/packages/modifiers/tests/snapEdges.js +++ b/packages/modifiers/tests/snapEdges.js @@ -35,26 +35,26 @@ test('modifiers/snapEdges', t => { // resize from top left interaction.prepared.edges = { top: true, left: true }; - arg.status = { options, delta: { x: 0, y: 0 } }; + arg.status = { options }; snapEdges.start(arg); snapEdges.set(arg); t.deepEqual( - arg.status.delta, - { x: target0.left - pageCoords.x, y: target0.top - pageCoords.y }, - 'modified delta is correct'); + arg.coords, + { x: target0.left, y: target0.top }, + 'modified coords are correct'); // resize from bottom right interaction.prepared.edges = { bottom: true, right: true }; - arg.status = { options, delta: { x: 0, y: 0 } }; + arg.status = { options }; snapEdges.start(arg); snapEdges.set(arg); t.deepEqual( - arg.status.delta, - { x: target0.right - pageCoords.x, y: target0.bottom - pageCoords.y }, - 'modified coord is correct'); + arg.coords, + { x: target0.right, y: target0.bottom }, + 'modified coord are correct'); t.end(); }); diff --git a/packages/modifiers/tests/snapSize.js b/packages/modifiers/tests/snapSize.js index fc6de2a37..4c2a5a261 100644 --- a/packages/modifiers/tests/snapSize.js +++ b/packages/modifiers/tests/snapSize.js @@ -1,5 +1,5 @@ import test from '@interactjs/_dev/test/test'; -import { mockSignals, mockInteractable, getProps } from '@interactjs/_dev/test/helpers'; +import { mockSignals, mockInteractable } from '@interactjs/_dev/test/helpers'; import snapSize from '@interactjs/modifiers/snapSize'; import Interaction from '@interactjs/core/Interaction'; @@ -38,16 +38,8 @@ test('modifiers/snapSize', t => { snapSize.set(arg); t.deepEqual( - getProps(status, 'range realX realY delta'.split(' ')), - { - range: Infinity, - realX: pageCoords.x, - realY: pageCoords.y, - delta: { - x: target0.x - pageCoords.x, - y: target0.y - pageCoords.y, - }, - }, + arg.coords, + target0, 'snapSize.set single target, zereo offset' );