Skip to content

Commit c3d1ea7

Browse files
authored
plugin API revamp (#1595)
1 parent 211b030 commit c3d1ea7

File tree

7 files changed

+72
-64
lines changed

7 files changed

+72
-64
lines changed

plugins/AutoScroll/AutoScroll.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ let autoScrolls = [],
2727
function AutoScrollPlugin() {
2828

2929
function AutoScroll() {
30-
this.options = {
30+
this.defaults = {
3131
scroll: true,
3232
scrollSensitivity: 30,
3333
scrollSpeed: 10,
@@ -47,7 +47,7 @@ function AutoScrollPlugin() {
4747
if (this.sortable.nativeDraggable) {
4848
on(document, 'dragover', this._handleAutoScroll);
4949
} else {
50-
if (this.sortable.options.supportPointer) {
50+
if (this.options.supportPointer) {
5151
on(document, 'pointermove', this._handleFallbackAutoScroll);
5252
} else if (originalEvent.touches) {
5353
on(document, 'touchmove', this._handleFallbackAutoScroll);
@@ -59,7 +59,7 @@ function AutoScrollPlugin() {
5959

6060
dragOverCompleted({ originalEvent }) {
6161
// For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
62-
if (!this.sortable.options.dragOverBubble && !originalEvent.rootEl) {
62+
if (!this.options.dragOverBubble && !originalEvent.rootEl) {
6363
this._handleAutoScroll(originalEvent);
6464
}
6565
},
@@ -107,7 +107,7 @@ function AutoScrollPlugin() {
107107
// MACOS Safari does not have autoscroll,
108108
// Firefox and Chrome are good
109109
if (fallback || Edge || IE11OrLess || Safari) {
110-
autoScroll(evt, this.sortable.options, elem, fallback);
110+
autoScroll(evt, this.options, elem, fallback);
111111

112112
// Listener for pointer element change
113113
let ogElemScroller = getParentAutoScrollElement(elem, true);
@@ -127,18 +127,18 @@ function AutoScrollPlugin() {
127127
ogElemScroller = newElem;
128128
clearAutoScrolls();
129129
}
130-
autoScroll(evt, this.sortable.options, newElem, fallback);
130+
autoScroll(evt, this.options, newElem, fallback);
131131
}, 10);
132132
lastAutoScrollX = x;
133133
lastAutoScrollY = y;
134134
}
135135
} else {
136136
// if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
137-
if (!this.sortable.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
137+
if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
138138
clearAutoScrolls();
139139
return;
140140
}
141-
autoScroll(evt, this.sortable.options, getParentAutoScrollElement(elem, false), false);
141+
autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
142142
}
143143
}
144144
};

plugins/MultiDrag/MultiDrag.js

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function MultiDragPlugin() {
4545
on(document, 'keydown', this._checkKeyDown);
4646
on(document, 'keyup', this._checkKeyUp);
4747

48-
this.options = {
48+
this.defaults = {
4949
selectedClass: 'sortable-selected',
5050
multiDragKey: null,
5151
setData(dataTransfer, dragEl) {
@@ -75,7 +75,7 @@ function MultiDragPlugin() {
7575
this.isMultiDrag = ~multiDragElements.indexOf(dragEl);
7676
},
7777

78-
setupClone({ sortable }) {
78+
setupClone({ sortable, cancel }) {
7979
if (!this.isMultiDrag) return;
8080
for (let i = 0; i < multiDragElements.length; i++) {
8181
multiDragClones.push(clone(multiDragElements[i]));
@@ -85,27 +85,27 @@ function MultiDragPlugin() {
8585
multiDragClones[i].draggable = false;
8686
multiDragClones[i].style['will-change'] = '';
8787

88-
toggleClass(multiDragClones[i], sortable.options.selectedClass, false);
89-
multiDragElements[i] === dragEl && toggleClass(multiDragClones[i], sortable.options.chosenClass, false);
88+
toggleClass(multiDragClones[i], this.options.selectedClass, false);
89+
multiDragElements[i] === dragEl && toggleClass(multiDragClones[i], this.options.chosenClass, false);
9090
}
9191

9292
sortable._hideClone();
93-
return true;
93+
cancel();
9494
},
9595

96-
clone({ sortable, rootEl, dispatchSortableEvent }) {
96+
clone({ sortable, rootEl, dispatchSortableEvent, cancel }) {
9797
if (!this.isMultiDrag) return;
98-
if (!sortable.options.removeCloneOnHide) {
98+
if (!this.options.removeCloneOnHide) {
9999
if (multiDragElements.length && multiDragSortable === sortable) {
100100
insertMultiDragClones(true, rootEl);
101101
dispatchSortableEvent('clone');
102102

103-
return true;
103+
cancel();
104104
}
105105
}
106106
},
107107

108-
showClone({ cloneNowShown, rootEl }) {
108+
showClone({ cloneNowShown, rootEl, cancel }) {
109109
if (!this.isMultiDrag) return;
110110
insertMultiDragClones(false, rootEl);
111111
multiDragClones.forEach(clone => {
@@ -114,21 +114,21 @@ function MultiDragPlugin() {
114114

115115
cloneNowShown();
116116
clonesHidden = false;
117-
return true;
117+
cancel();
118118
},
119119

120-
hideClone({ sortable, cloneNowHidden }) {
120+
hideClone({ sortable, cloneNowHidden, cancel }) {
121121
if (!this.isMultiDrag) return;
122122
multiDragClones.forEach(clone => {
123123
css(clone, 'display', 'none');
124-
if (sortable.options.removeCloneOnHide && clone.parentNode) {
124+
if (this.options.removeCloneOnHide && clone.parentNode) {
125125
clone.parentNode.removeChild(clone);
126126
}
127127
});
128128

129129
cloneNowHidden();
130130
clonesHidden = true;
131-
return true;
131+
cancel();
132132
},
133133

134134
dragStartGlobal({ sortable }) {
@@ -149,7 +149,7 @@ function MultiDragPlugin() {
149149

150150
dragStarted({ sortable }) {
151151
if (!this.isMultiDrag) return;
152-
if (sortable.options.sort) {
152+
if (this.options.sort) {
153153
// Capture rects,
154154
// hide multi drag elements (by positioning them absolute),
155155
// set multi drag elements rects to dragRect,
@@ -159,7 +159,7 @@ function MultiDragPlugin() {
159159

160160
sortable.captureAnimationState();
161161

162-
if (sortable.options.animation) {
162+
if (this.options.animation) {
163163
multiDragElements.forEach(multiDragElement => {
164164
if (multiDragElement === dragEl) return;
165165
css(multiDragElement, 'position', 'absolute');
@@ -177,26 +177,27 @@ function MultiDragPlugin() {
177177
}
178178
}
179179

180-
sortable.animateAll(function() {
180+
sortable.animateAll(() => {
181181
folding = false;
182182
initialFolding = false;
183183

184-
if (sortable.options.animation) {
184+
if (this.options.animation) {
185185
multiDragElements.forEach(multiDragElement => {
186186
unsetRect(multiDragElement);
187187
});
188188
}
189189

190190
// Remove all auxiliary multidrag items from el, if sorting enabled
191-
if (sortable.options.sort) {
191+
if (this.options.sort) {
192192
removeMultiDragElements();
193193
}
194194
});
195195
},
196196

197-
dragOver({ target, completed }) {
197+
dragOver({ target, completed, cancel }) {
198198
if (folding && ~multiDragElements.indexOf(target)) {
199-
return completed(false);
199+
completed(false);
200+
cancel();
200201
}
201202
},
202203

@@ -216,12 +217,12 @@ function MultiDragPlugin() {
216217
fromSortable.removeAnimationState(multiDragElement);
217218
});
218219
folding = false;
219-
insertMultiDragElements(!sortable.options.removeCloneOnHide, rootEl);
220+
insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
220221
}
221222
},
222223

223224
dragOverCompleted({ sortable, isOwner, insertion, activeSortable, parentEl, putSortable }) {
224-
let options = sortable.options;
225+
let options = this.options;
225226
if (insertion) {
226227
// Clones must be hidden before folding animation to capture dragRectAbsolute properly
227228
if (isOwner) {
@@ -301,7 +302,7 @@ function MultiDragPlugin() {
301302

302303
if (!evt) return;
303304

304-
let options = sortable.options,
305+
let options = this.options,
305306
children = parentEl.children;
306307

307308
// Multi-drag selection
@@ -344,7 +345,7 @@ function MultiDragPlugin() {
344345
multiDragElements.push(children[i]);
345346

346347
dispatchEvent({
347-
sortable: sortable,
348+
sortable,
348349
rootEl,
349350
name: 'select',
350351
targetEl: children[i],
@@ -375,7 +376,7 @@ function MultiDragPlugin() {
375376
// Do not "unfold" after around dragEl if reverted
376377
if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
377378
let dragRect = getRect(dragEl),
378-
multiDragIndex = index(dragEl, ':not(.' + sortable.options.selectedClass + ')');
379+
multiDragIndex = index(dragEl, ':not(.' + this.options.selectedClass + ')');
379380

380381
if (!initialFolding && options.animation) dragEl.thisAnimationDuration = null;
381382

@@ -472,14 +473,14 @@ function MultiDragPlugin() {
472473
if (multiDragSortable !== this.sortable) return;
473474

474475
// Only deselect if target is not item in this sortable
475-
if (evt && closest(evt.target, this.sortable.options.draggable, this.sortable.el, false)) return;
476+
if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
476477

477478
// Only deselect if left click
478479
if (evt && evt.button !== 0) return;
479480

480481
while (multiDragElements.length) {
481482
let el = multiDragElements[0];
482-
toggleClass(el, this.sortable.options.selectedClass, false);
483+
toggleClass(el, this.options.selectedClass, false);
483484
multiDragElements.shift();
484485
dispatchEvent({
485486
sortable: this.sortable,
@@ -492,13 +493,13 @@ function MultiDragPlugin() {
492493
},
493494

494495
_checkKeyDown(evt) {
495-
if (evt.key === this.sortable.options.multiDragKey) {
496+
if (evt.key === this.options.multiDragKey) {
496497
this.multiDragKeyDown = true;
497498
}
498499
},
499500

500501
_checkKeyUp(evt) {
501-
if (evt.key === this.sortable.options.multiDragKey) {
502+
if (evt.key === this.options.multiDragKey) {
502503
this.multiDragKeyDown = false;
503504
}
504505
}
@@ -534,7 +535,7 @@ function MultiDragPlugin() {
534535
multiDragElements.splice(index, 1);
535536
}
536537
},
537-
eventOptions() {
538+
eventProperties() {
538539
const oldIndicies = [],
539540
newIndicies = [];
540541

plugins/OnSpill/OnSpill.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Revert.prototype = {
3333
if (putSortable) {
3434
putSortable.captureAnimationState();
3535
}
36-
let nextSibling = getChild(this.sortable.el, this.startIndex, this.sortable.options);
36+
let nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
3737

3838
if (nextSibling) {
3939
this.sortable.el.insertBefore(dragEl, nextSibling);

plugins/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Sortable plugins are plugins that can be directly mounted to the Sortable class.
88

99
`el: HTMLElement` — The element that the sortable is being initialized on
1010

11+
`options: Object` — The options object that the user has passed into Sortable (not merged with defaults yet)
12+
1113

1214
## Static Properties
1315
The constructor function passed to `Sortable.mount` may contain several static properties and methods. The following static properties may be defined:
@@ -16,10 +18,10 @@ The constructor function passed to `Sortable.mount` may contain several static p
1618
The name of the option that the user will use in their sortable's options to enable the plugin. Should start with a lower case and be camel-cased. For example: `'multiDrag'`. This is also the property name that the plugin's instance will be under in a sortable instance (ex. `sortableInstance.multiDrag`).
1719

1820
`utils: Object`
19-
Object containing functions that will be added to the `Sortable.utils` default object on the Sortable class.
21+
Object containing functions that will be added to the `Sortable.utils` static object on the Sortable class.
2022

2123
`eventOptions(eventName: String): Function`
22-
A function that is called whenever Sortable fires an event. This function should return an object to be combined with the event object that Sortable will emit. The function will be called in the context of the Sortable that is firing the event (ie. the `this` keyword will be the Sortable calling the event).
24+
A function that is called whenever Sortable fires an event. This function should return an object to be combined with the event object that Sortable will emit. The function will be called in the context of the instance of the plugin on the Sortable that is firing the event (ie. the `this` keyword will be the plugin instance).
2325

2426
`initializeByDefault: Boolean`
2527
Determines whether or not the plugin will always be initialized on every new Sortable instance. If this option is enabled, it does not mean that by default the plugin will be enabled on the Sortable - this must still be done in the options via the plugin's `pluginName`, or it can be enabled by default if your plugin specifies it's pluginName as a default option that is truthy. Since the plugin will already be initialized on every Sortable instance, it can also be enabled dynamically via `sortableInstance.option('pluginName', true)`.
@@ -51,11 +53,11 @@ Plugin.optionModifiers = {
5153
```
5254

5355
## Plugin Options
54-
Plugins may have custom options or override the defaults of certain options. In order to do this, there must be an `options` object on the initialized plugin. This can be set in the plugin's prototype, or during the initialization of the plugin (when the `el` is available). For example:
56+
Plugins may have custom default options or may override the defaults of other options. In order to do this, there must be a `defaults` object on the initialized plugin. This can be set in the plugin's prototype, or during the initialization of the plugin (when the `el` is available). For example:
5557

5658
```js
57-
function myPlugin(el) {
58-
this.options = {
59+
function myPlugin(sortable, el, options) {
60+
this.defaults = {
5961
color: el.style.backgroundColor
6062
};
6163
}
@@ -67,7 +69,7 @@ Sortable.mount(myPlugin);
6769
## Plugin Events
6870

6971
### Context
70-
The events will be fired in the context of their own parent object (ie. context is not changed), however the plugin instance's Sortable instance is available under `this.sortable`.
72+
The events will be fired in the context of their own parent object (ie. context is not changed), however the plugin instance's Sortable instance is available under `this.sortable`. Likewise, the options are available under `this.options`.
7173

7274
### Event List
7375
The following table contains details on the events that a plugin may handle in the prototype of the plugin's constructor function.

plugins/Swap/Swap.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ let lastSwapEl;
88

99
function SwapPlugin() {
1010
function Swap() {
11-
this.options = {
11+
this.defaults = {
1212
swapClass: 'sortable-swap-highlight'
1313
};
1414
}
@@ -17,10 +17,10 @@ function SwapPlugin() {
1717
dragStart({ dragEl }) {
1818
lastSwapEl = dragEl;
1919
},
20-
dragOverValid({ completed, target, onMove, activeSortable, changed }) {
20+
dragOverValid({ completed, target, onMove, activeSortable, changed, cancel }) {
2121
if (!activeSortable.options.swap) return;
2222
let el = this.sortable.el,
23-
options = this.sortable.options;
23+
options = this.options;
2424
if (target && target !== el) {
2525
let prevSwapEl = lastSwapEl;
2626
if (onMove(target) !== false) {
@@ -36,11 +36,12 @@ function SwapPlugin() {
3636
}
3737
changed();
3838

39-
return completed(true);
39+
completed(true);
40+
cancel();
4041
},
4142
drop({ activeSortable, putSortable, dragEl }) {
4243
let toSortable = (putSortable || this.sortable);
43-
let options = this.sortable.options;
44+
let options = this.options;
4445
lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
4546
if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
4647
if (dragEl !== lastSwapEl) {
@@ -60,7 +61,7 @@ function SwapPlugin() {
6061

6162
return Object.assign(Swap, {
6263
pluginName: 'swap',
63-
eventOptions() {
64+
eventProperties() {
6465
return {
6566
swapItem: lastSwapEl
6667
};

src/EventDispatcher.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default function dispatchEvent(
88
targetEl, cloneEl, toEl, fromEl,
99
oldIndex, newIndex,
1010
oldDraggableIndex, newDraggableIndex,
11-
originalEvent, putSortable, eventOptions
11+
originalEvent, putSortable, extraEventProperties
1212
}
1313
) {
1414
sortable = (sortable || (rootEl && rootEl[expando]));
@@ -42,9 +42,9 @@ export default function dispatchEvent(
4242
evt.originalEvent = originalEvent;
4343
evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
4444

45-
let allEventOptions = { ...eventOptions, ...PluginManager.getEventOptions(name, sortable) };
46-
for (let option in allEventOptions) {
47-
evt[option] = allEventOptions[option];
45+
let allEventProperties = { ...extraEventProperties, ...PluginManager.getEventProperties(name, sortable) };
46+
for (let option in allEventProperties) {
47+
evt[option] = allEventProperties[option];
4848
}
4949

5050
if (rootEl) {

0 commit comments

Comments
 (0)