diff --git a/dist/html5sortable.amd.js b/dist/html5sortable.amd.js index 56798fc0..36febdfb 100644 --- a/dist/html5sortable.amd.js +++ b/dist/html5sortable.amd.js @@ -143,7 +143,7 @@ function index (element, elementList) { } function isInDom (element) { - if (!element || element.nodeType !== 1) { + if (!(element instanceof Element)) { throw new Error('Element is not a node element.'); } return element.parentNode !== null; @@ -209,6 +209,52 @@ function _serialize (sortableContainer, customItemSerializer, customContainerSer }; } +function _makePlaceholder (sortableElement, placeholder, placeholderClass) { + if (placeholderClass === void 0) { placeholderClass = 'sortable-placeholder'; } + if (!(sortableElement instanceof Element)) { + throw new Error('You must provide a valid element as a sortable.'); + } + // if placeholder is not an element + if (!(placeholder instanceof Element) && placeholder !== undefined) { + throw new Error('You must provide a valid element as a placeholder or set ot to undefined.'); + } + // if no placeholder element is given + if (placeholder === undefined) { + if (['UL', 'OL'].includes(sortableElement.tagName)) { + placeholder = document.createElement('li'); + } + else if (['TABLE', 'TBODY'].includes(sortableElement.tagName)) { + placeholder = document.createElement('tr'); + // set colspan to always all rows, otherwise the item can only be dropped in first column + placeholder.innerHTML = ''; + } + else { + placeholder = document.createElement('div'); + } + } + // add classes to placeholder + if (typeof placeholderClass === 'string') { + (_a = placeholder.classList).add.apply(_a, placeholderClass.split(' ')); + } + return placeholder; + var _a; +} + +function _getElementHeight (element) { + if (!(element instanceof Element)) { + throw new Error('You must provide a valid dom element'); + } + // get calculated style of element + var style = window.getComputedStyle(element); + // pick applicable properties, convert to int and reduce by adding + return ['height', 'padding-top', 'padding-bottom'] + .map(function (key) { + var int = parseInt(style.getPropertyValue(key), 10); + return isNaN(int) ? 0 : int; + }) + .reduce(function (sum, value) { return sum + value; }); +} + /* eslint-env browser */ /* * variables global to the plugin @@ -240,45 +286,6 @@ var _removeSortableEvents = function (sortable) { removeEventListener(sortable, 'dragenter'); removeEventListener(sortable, 'drop'); }; -/** - * create a placeholder element - * @param {Elememnt} sortableElement a single sortable - * @param {string|undefine} placeholder a string representing an html element - * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder - */ -var _makePlaceholder = function (sortableElement, placeholder, placeholderClasses) { - if (placeholder === void 0) { placeholder = undefined; } - if (placeholderClasses === void 0) { placeholderClasses = 'sortable-placeholder'; } - if (typeof placeholder === 'string') { - var tempContainer = document.createElement(sortableElement.tagName); - tempContainer.innerHTML = placeholder; - placeholder = tempContainer.children[0]; - } - else { - switch (sortableElement.tagName) { - case 'UL': - placeholder = document.createElement('li'); - break; - case 'OL': - placeholder = document.createElement('li'); - break; - case 'TABLE': - placeholder = 'tr'; - placeholder.innerHTML = ''; - break; - case 'TBODY': - placeholder = document.createElement('tr'); - placeholder.innerHTML = ''; - break; - default: - placeholder = document.createElement('div'); - } - } - // add classes to placeholder - (_a = placeholder.classList).add.apply(_a, placeholderClasses.split(' ')); - return placeholder; - var _a; -}; /** * Attach ghost to dataTransfer object * @param {Event} original event @@ -397,21 +404,6 @@ var _listsConnected = function (curList, destList) { var _isCopyActive = function (sortable) { return addData(sortable, 'opts').copy === true; }; -/** - * Get height of an element including padding - * @param {Element} sortable a single sortable - */ -var _getElementHeight = function (element) { - // get calculated style of element - var style = window.getComputedStyle(element); - // pick applicable properties, convert to int and reduce by adding - return ['height', 'padding-top', 'padding-bottom'] - .map(function (key) { - var int = parseInt(style.getPropertyValue(key), 10); - return isNaN(int) ? 0 : int; - }) - .reduce(function (prev, cur) { return prev + cur; }); -}; /** * get handle or return item * @param {Array} items @@ -540,32 +532,28 @@ var _reloadSortable = function (sortableElement) { * @param {object|string} options|method */ function sortable(sortableElements, options) { + // get method string to see if a method is called var method = String(options); - options = (function (options) { - var result = { - connectWith: false, - acceptFrom: null, - copy: false, - placeholder: null, - disableIEFix: false, - placeholderClass: 'sortable-placeholder', - draggingClass: 'sortable-dragging', - hoverClass: false, - debounce: 0, - maxItems: 0, - itemSerializer: undefined, - containerSerializer: undefined - }; - if (typeof options === 'object') { - for (var option in options) { - result[option] = options[option]; - } - } - return result; - })(options); + // merge user options with defaults + options = Object.assign({ + connectWith: false, + acceptFrom: null, + copy: false, + placeholder: null, + disableIEFix: false, + placeholderClass: 'sortable-placeholder', + draggingClass: 'sortable-dragging', + hoverClass: false, + debounce: 0, + maxItems: 0, + itemSerializer: undefined, + containerSerializer: undefined + }, (typeof options === 'object') ? options : {}); + // check if the user provided a selector instead of an element if (typeof sortableElements === 'string') { sortableElements = document.querySelectorAll(sortableElements); } + // if the user provided an element, return it in an array to keep the return value consistant if (sortableElements instanceof Element) { sortableElements = [sortableElements]; } @@ -591,7 +579,14 @@ function sortable(sortableElements, options) { var items = filter(sortableElement.children, options.items); var index$$1; var startList; - var placeholder = _makePlaceholder(sortableElement, options.placeholder, options.placeholderClass); + // create element if user defined a placeholder element as a string + var customPlaceholder; + if (options.placeholder !== null && options.placeholder !== undefined) { + var tempContainer = document.createElement(sortableElement.tagName); + tempContainer.innerHTML = options.placeholder; + customPlaceholder = tempContainer.children[0]; + } + var placeholder = _makePlaceholder(sortableElement, customPlaceholder, options.placeholderClass); addData(sortableElement, 'items', options.items); placeholderMap.set(sortableElement, placeholder); if (options.acceptFrom) { @@ -752,8 +747,7 @@ function sortable(sortableElements, options) { // Dead zone? var deadZone = thisHeight - draggingHeight; var offsetTop = _offset(element).top; - if (placeholderIndex < thisIndex && - pageY < offsetTop + deadZone) { + if (placeholderIndex < thisIndex && pageY < offsetTop) { return; } if (placeholderIndex > thisIndex && diff --git a/dist/html5sortable.cjs.js b/dist/html5sortable.cjs.js index 574bc22c..b433d9d5 100644 --- a/dist/html5sortable.cjs.js +++ b/dist/html5sortable.cjs.js @@ -143,7 +143,7 @@ function index (element, elementList) { } function isInDom (element) { - if (!element || element.nodeType !== 1) { + if (!(element instanceof Element)) { throw new Error('Element is not a node element.'); } return element.parentNode !== null; @@ -209,6 +209,52 @@ function _serialize (sortableContainer, customItemSerializer, customContainerSer }; } +function _makePlaceholder (sortableElement, placeholder, placeholderClass) { + if (placeholderClass === void 0) { placeholderClass = 'sortable-placeholder'; } + if (!(sortableElement instanceof Element)) { + throw new Error('You must provide a valid element as a sortable.'); + } + // if placeholder is not an element + if (!(placeholder instanceof Element) && placeholder !== undefined) { + throw new Error('You must provide a valid element as a placeholder or set ot to undefined.'); + } + // if no placeholder element is given + if (placeholder === undefined) { + if (['UL', 'OL'].includes(sortableElement.tagName)) { + placeholder = document.createElement('li'); + } + else if (['TABLE', 'TBODY'].includes(sortableElement.tagName)) { + placeholder = document.createElement('tr'); + // set colspan to always all rows, otherwise the item can only be dropped in first column + placeholder.innerHTML = ''; + } + else { + placeholder = document.createElement('div'); + } + } + // add classes to placeholder + if (typeof placeholderClass === 'string') { + (_a = placeholder.classList).add.apply(_a, placeholderClass.split(' ')); + } + return placeholder; + var _a; +} + +function _getElementHeight (element) { + if (!(element instanceof Element)) { + throw new Error('You must provide a valid dom element'); + } + // get calculated style of element + var style = window.getComputedStyle(element); + // pick applicable properties, convert to int and reduce by adding + return ['height', 'padding-top', 'padding-bottom'] + .map(function (key) { + var int = parseInt(style.getPropertyValue(key), 10); + return isNaN(int) ? 0 : int; + }) + .reduce(function (sum, value) { return sum + value; }); +} + /* eslint-env browser */ /* * variables global to the plugin @@ -240,45 +286,6 @@ var _removeSortableEvents = function (sortable) { removeEventListener(sortable, 'dragenter'); removeEventListener(sortable, 'drop'); }; -/** - * create a placeholder element - * @param {Elememnt} sortableElement a single sortable - * @param {string|undefine} placeholder a string representing an html element - * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder - */ -var _makePlaceholder = function (sortableElement, placeholder, placeholderClasses) { - if (placeholder === void 0) { placeholder = undefined; } - if (placeholderClasses === void 0) { placeholderClasses = 'sortable-placeholder'; } - if (typeof placeholder === 'string') { - var tempContainer = document.createElement(sortableElement.tagName); - tempContainer.innerHTML = placeholder; - placeholder = tempContainer.children[0]; - } - else { - switch (sortableElement.tagName) { - case 'UL': - placeholder = document.createElement('li'); - break; - case 'OL': - placeholder = document.createElement('li'); - break; - case 'TABLE': - placeholder = 'tr'; - placeholder.innerHTML = ''; - break; - case 'TBODY': - placeholder = document.createElement('tr'); - placeholder.innerHTML = ''; - break; - default: - placeholder = document.createElement('div'); - } - } - // add classes to placeholder - (_a = placeholder.classList).add.apply(_a, placeholderClasses.split(' ')); - return placeholder; - var _a; -}; /** * Attach ghost to dataTransfer object * @param {Event} original event @@ -397,21 +404,6 @@ var _listsConnected = function (curList, destList) { var _isCopyActive = function (sortable) { return addData(sortable, 'opts').copy === true; }; -/** - * Get height of an element including padding - * @param {Element} sortable a single sortable - */ -var _getElementHeight = function (element) { - // get calculated style of element - var style = window.getComputedStyle(element); - // pick applicable properties, convert to int and reduce by adding - return ['height', 'padding-top', 'padding-bottom'] - .map(function (key) { - var int = parseInt(style.getPropertyValue(key), 10); - return isNaN(int) ? 0 : int; - }) - .reduce(function (prev, cur) { return prev + cur; }); -}; /** * get handle or return item * @param {Array} items @@ -540,32 +532,28 @@ var _reloadSortable = function (sortableElement) { * @param {object|string} options|method */ function sortable(sortableElements, options) { + // get method string to see if a method is called var method = String(options); - options = (function (options) { - var result = { - connectWith: false, - acceptFrom: null, - copy: false, - placeholder: null, - disableIEFix: false, - placeholderClass: 'sortable-placeholder', - draggingClass: 'sortable-dragging', - hoverClass: false, - debounce: 0, - maxItems: 0, - itemSerializer: undefined, - containerSerializer: undefined - }; - if (typeof options === 'object') { - for (var option in options) { - result[option] = options[option]; - } - } - return result; - })(options); + // merge user options with defaults + options = Object.assign({ + connectWith: false, + acceptFrom: null, + copy: false, + placeholder: null, + disableIEFix: false, + placeholderClass: 'sortable-placeholder', + draggingClass: 'sortable-dragging', + hoverClass: false, + debounce: 0, + maxItems: 0, + itemSerializer: undefined, + containerSerializer: undefined + }, (typeof options === 'object') ? options : {}); + // check if the user provided a selector instead of an element if (typeof sortableElements === 'string') { sortableElements = document.querySelectorAll(sortableElements); } + // if the user provided an element, return it in an array to keep the return value consistant if (sortableElements instanceof Element) { sortableElements = [sortableElements]; } @@ -591,7 +579,14 @@ function sortable(sortableElements, options) { var items = filter(sortableElement.children, options.items); var index$$1; var startList; - var placeholder = _makePlaceholder(sortableElement, options.placeholder, options.placeholderClass); + // create element if user defined a placeholder element as a string + var customPlaceholder; + if (options.placeholder !== null && options.placeholder !== undefined) { + var tempContainer = document.createElement(sortableElement.tagName); + tempContainer.innerHTML = options.placeholder; + customPlaceholder = tempContainer.children[0]; + } + var placeholder = _makePlaceholder(sortableElement, customPlaceholder, options.placeholderClass); addData(sortableElement, 'items', options.items); placeholderMap.set(sortableElement, placeholder); if (options.acceptFrom) { @@ -752,8 +747,7 @@ function sortable(sortableElements, options) { // Dead zone? var deadZone = thisHeight - draggingHeight; var offsetTop = _offset(element).top; - if (placeholderIndex < thisIndex && - pageY < offsetTop + deadZone) { + if (placeholderIndex < thisIndex && pageY < offsetTop) { return; } if (placeholderIndex > thisIndex && diff --git a/dist/html5sortable.es.js b/dist/html5sortable.es.js index 169f6f24..2fe060a3 100644 --- a/dist/html5sortable.es.js +++ b/dist/html5sortable.es.js @@ -141,7 +141,7 @@ function index (element, elementList) { } function isInDom (element) { - if (!element || element.nodeType !== 1) { + if (!(element instanceof Element)) { throw new Error('Element is not a node element.'); } return element.parentNode !== null; @@ -207,6 +207,52 @@ function _serialize (sortableContainer, customItemSerializer, customContainerSer }; } +function _makePlaceholder (sortableElement, placeholder, placeholderClass) { + if (placeholderClass === void 0) { placeholderClass = 'sortable-placeholder'; } + if (!(sortableElement instanceof Element)) { + throw new Error('You must provide a valid element as a sortable.'); + } + // if placeholder is not an element + if (!(placeholder instanceof Element) && placeholder !== undefined) { + throw new Error('You must provide a valid element as a placeholder or set ot to undefined.'); + } + // if no placeholder element is given + if (placeholder === undefined) { + if (['UL', 'OL'].includes(sortableElement.tagName)) { + placeholder = document.createElement('li'); + } + else if (['TABLE', 'TBODY'].includes(sortableElement.tagName)) { + placeholder = document.createElement('tr'); + // set colspan to always all rows, otherwise the item can only be dropped in first column + placeholder.innerHTML = ''; + } + else { + placeholder = document.createElement('div'); + } + } + // add classes to placeholder + if (typeof placeholderClass === 'string') { + (_a = placeholder.classList).add.apply(_a, placeholderClass.split(' ')); + } + return placeholder; + var _a; +} + +function _getElementHeight (element) { + if (!(element instanceof Element)) { + throw new Error('You must provide a valid dom element'); + } + // get calculated style of element + var style = window.getComputedStyle(element); + // pick applicable properties, convert to int and reduce by adding + return ['height', 'padding-top', 'padding-bottom'] + .map(function (key) { + var int = parseInt(style.getPropertyValue(key), 10); + return isNaN(int) ? 0 : int; + }) + .reduce(function (sum, value) { return sum + value; }); +} + /* eslint-env browser */ /* * variables global to the plugin @@ -238,45 +284,6 @@ var _removeSortableEvents = function (sortable) { removeEventListener(sortable, 'dragenter'); removeEventListener(sortable, 'drop'); }; -/** - * create a placeholder element - * @param {Elememnt} sortableElement a single sortable - * @param {string|undefine} placeholder a string representing an html element - * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder - */ -var _makePlaceholder = function (sortableElement, placeholder, placeholderClasses) { - if (placeholder === void 0) { placeholder = undefined; } - if (placeholderClasses === void 0) { placeholderClasses = 'sortable-placeholder'; } - if (typeof placeholder === 'string') { - var tempContainer = document.createElement(sortableElement.tagName); - tempContainer.innerHTML = placeholder; - placeholder = tempContainer.children[0]; - } - else { - switch (sortableElement.tagName) { - case 'UL': - placeholder = document.createElement('li'); - break; - case 'OL': - placeholder = document.createElement('li'); - break; - case 'TABLE': - placeholder = 'tr'; - placeholder.innerHTML = ''; - break; - case 'TBODY': - placeholder = document.createElement('tr'); - placeholder.innerHTML = ''; - break; - default: - placeholder = document.createElement('div'); - } - } - // add classes to placeholder - (_a = placeholder.classList).add.apply(_a, placeholderClasses.split(' ')); - return placeholder; - var _a; -}; /** * Attach ghost to dataTransfer object * @param {Event} original event @@ -395,21 +402,6 @@ var _listsConnected = function (curList, destList) { var _isCopyActive = function (sortable) { return addData(sortable, 'opts').copy === true; }; -/** - * Get height of an element including padding - * @param {Element} sortable a single sortable - */ -var _getElementHeight = function (element) { - // get calculated style of element - var style = window.getComputedStyle(element); - // pick applicable properties, convert to int and reduce by adding - return ['height', 'padding-top', 'padding-bottom'] - .map(function (key) { - var int = parseInt(style.getPropertyValue(key), 10); - return isNaN(int) ? 0 : int; - }) - .reduce(function (prev, cur) { return prev + cur; }); -}; /** * get handle or return item * @param {Array} items @@ -538,32 +530,28 @@ var _reloadSortable = function (sortableElement) { * @param {object|string} options|method */ function sortable(sortableElements, options) { + // get method string to see if a method is called var method = String(options); - options = (function (options) { - var result = { - connectWith: false, - acceptFrom: null, - copy: false, - placeholder: null, - disableIEFix: false, - placeholderClass: 'sortable-placeholder', - draggingClass: 'sortable-dragging', - hoverClass: false, - debounce: 0, - maxItems: 0, - itemSerializer: undefined, - containerSerializer: undefined - }; - if (typeof options === 'object') { - for (var option in options) { - result[option] = options[option]; - } - } - return result; - })(options); + // merge user options with defaults + options = Object.assign({ + connectWith: false, + acceptFrom: null, + copy: false, + placeholder: null, + disableIEFix: false, + placeholderClass: 'sortable-placeholder', + draggingClass: 'sortable-dragging', + hoverClass: false, + debounce: 0, + maxItems: 0, + itemSerializer: undefined, + containerSerializer: undefined + }, (typeof options === 'object') ? options : {}); + // check if the user provided a selector instead of an element if (typeof sortableElements === 'string') { sortableElements = document.querySelectorAll(sortableElements); } + // if the user provided an element, return it in an array to keep the return value consistant if (sortableElements instanceof Element) { sortableElements = [sortableElements]; } @@ -589,7 +577,14 @@ function sortable(sortableElements, options) { var items = filter(sortableElement.children, options.items); var index$$1; var startList; - var placeholder = _makePlaceholder(sortableElement, options.placeholder, options.placeholderClass); + // create element if user defined a placeholder element as a string + var customPlaceholder; + if (options.placeholder !== null && options.placeholder !== undefined) { + var tempContainer = document.createElement(sortableElement.tagName); + tempContainer.innerHTML = options.placeholder; + customPlaceholder = tempContainer.children[0]; + } + var placeholder = _makePlaceholder(sortableElement, customPlaceholder, options.placeholderClass); addData(sortableElement, 'items', options.items); placeholderMap.set(sortableElement, placeholder); if (options.acceptFrom) { @@ -750,8 +745,7 @@ function sortable(sortableElements, options) { // Dead zone? var deadZone = thisHeight - draggingHeight; var offsetTop = _offset(element).top; - if (placeholderIndex < thisIndex && - pageY < offsetTop + deadZone) { + if (placeholderIndex < thisIndex && pageY < offsetTop) { return; } if (placeholderIndex > thisIndex && diff --git a/dist/html5sortable.js b/dist/html5sortable.js index e5920cc3..e9e1c665 100644 --- a/dist/html5sortable.js +++ b/dist/html5sortable.js @@ -144,7 +144,7 @@ function index (element, elementList) { } function isInDom (element) { - if (!element || element.nodeType !== 1) { + if (!(element instanceof Element)) { throw new Error('Element is not a node element.'); } return element.parentNode !== null; @@ -210,6 +210,52 @@ function _serialize (sortableContainer, customItemSerializer, customContainerSer }; } +function _makePlaceholder (sortableElement, placeholder, placeholderClass) { + if (placeholderClass === void 0) { placeholderClass = 'sortable-placeholder'; } + if (!(sortableElement instanceof Element)) { + throw new Error('You must provide a valid element as a sortable.'); + } + // if placeholder is not an element + if (!(placeholder instanceof Element) && placeholder !== undefined) { + throw new Error('You must provide a valid element as a placeholder or set ot to undefined.'); + } + // if no placeholder element is given + if (placeholder === undefined) { + if (['UL', 'OL'].includes(sortableElement.tagName)) { + placeholder = document.createElement('li'); + } + else if (['TABLE', 'TBODY'].includes(sortableElement.tagName)) { + placeholder = document.createElement('tr'); + // set colspan to always all rows, otherwise the item can only be dropped in first column + placeholder.innerHTML = ''; + } + else { + placeholder = document.createElement('div'); + } + } + // add classes to placeholder + if (typeof placeholderClass === 'string') { + (_a = placeholder.classList).add.apply(_a, placeholderClass.split(' ')); + } + return placeholder; + var _a; +} + +function _getElementHeight (element) { + if (!(element instanceof Element)) { + throw new Error('You must provide a valid dom element'); + } + // get calculated style of element + var style = window.getComputedStyle(element); + // pick applicable properties, convert to int and reduce by adding + return ['height', 'padding-top', 'padding-bottom'] + .map(function (key) { + var int = parseInt(style.getPropertyValue(key), 10); + return isNaN(int) ? 0 : int; + }) + .reduce(function (sum, value) { return sum + value; }); +} + /* eslint-env browser */ /* * variables global to the plugin @@ -241,45 +287,6 @@ var _removeSortableEvents = function (sortable) { removeEventListener(sortable, 'dragenter'); removeEventListener(sortable, 'drop'); }; -/** - * create a placeholder element - * @param {Elememnt} sortableElement a single sortable - * @param {string|undefine} placeholder a string representing an html element - * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder - */ -var _makePlaceholder = function (sortableElement, placeholder, placeholderClasses) { - if (placeholder === void 0) { placeholder = undefined; } - if (placeholderClasses === void 0) { placeholderClasses = 'sortable-placeholder'; } - if (typeof placeholder === 'string') { - var tempContainer = document.createElement(sortableElement.tagName); - tempContainer.innerHTML = placeholder; - placeholder = tempContainer.children[0]; - } - else { - switch (sortableElement.tagName) { - case 'UL': - placeholder = document.createElement('li'); - break; - case 'OL': - placeholder = document.createElement('li'); - break; - case 'TABLE': - placeholder = 'tr'; - placeholder.innerHTML = ''; - break; - case 'TBODY': - placeholder = document.createElement('tr'); - placeholder.innerHTML = ''; - break; - default: - placeholder = document.createElement('div'); - } - } - // add classes to placeholder - (_a = placeholder.classList).add.apply(_a, placeholderClasses.split(' ')); - return placeholder; - var _a; -}; /** * Attach ghost to dataTransfer object * @param {Event} original event @@ -398,21 +405,6 @@ var _listsConnected = function (curList, destList) { var _isCopyActive = function (sortable) { return addData(sortable, 'opts').copy === true; }; -/** - * Get height of an element including padding - * @param {Element} sortable a single sortable - */ -var _getElementHeight = function (element) { - // get calculated style of element - var style = window.getComputedStyle(element); - // pick applicable properties, convert to int and reduce by adding - return ['height', 'padding-top', 'padding-bottom'] - .map(function (key) { - var int = parseInt(style.getPropertyValue(key), 10); - return isNaN(int) ? 0 : int; - }) - .reduce(function (prev, cur) { return prev + cur; }); -}; /** * get handle or return item * @param {Array} items @@ -541,32 +533,28 @@ var _reloadSortable = function (sortableElement) { * @param {object|string} options|method */ function sortable(sortableElements, options) { + // get method string to see if a method is called var method = String(options); - options = (function (options) { - var result = { - connectWith: false, - acceptFrom: null, - copy: false, - placeholder: null, - disableIEFix: false, - placeholderClass: 'sortable-placeholder', - draggingClass: 'sortable-dragging', - hoverClass: false, - debounce: 0, - maxItems: 0, - itemSerializer: undefined, - containerSerializer: undefined - }; - if (typeof options === 'object') { - for (var option in options) { - result[option] = options[option]; - } - } - return result; - })(options); + // merge user options with defaults + options = Object.assign({ + connectWith: false, + acceptFrom: null, + copy: false, + placeholder: null, + disableIEFix: false, + placeholderClass: 'sortable-placeholder', + draggingClass: 'sortable-dragging', + hoverClass: false, + debounce: 0, + maxItems: 0, + itemSerializer: undefined, + containerSerializer: undefined + }, (typeof options === 'object') ? options : {}); + // check if the user provided a selector instead of an element if (typeof sortableElements === 'string') { sortableElements = document.querySelectorAll(sortableElements); } + // if the user provided an element, return it in an array to keep the return value consistant if (sortableElements instanceof Element) { sortableElements = [sortableElements]; } @@ -592,7 +580,14 @@ function sortable(sortableElements, options) { var items = filter(sortableElement.children, options.items); var index$$1; var startList; - var placeholder = _makePlaceholder(sortableElement, options.placeholder, options.placeholderClass); + // create element if user defined a placeholder element as a string + var customPlaceholder; + if (options.placeholder !== null && options.placeholder !== undefined) { + var tempContainer = document.createElement(sortableElement.tagName); + tempContainer.innerHTML = options.placeholder; + customPlaceholder = tempContainer.children[0]; + } + var placeholder = _makePlaceholder(sortableElement, customPlaceholder, options.placeholderClass); addData(sortableElement, 'items', options.items); placeholderMap.set(sortableElement, placeholder); if (options.acceptFrom) { @@ -753,8 +748,7 @@ function sortable(sortableElements, options) { // Dead zone? var deadZone = thisHeight - draggingHeight; var offsetTop = _offset(element).top; - if (placeholderIndex < thisIndex && - pageY < offsetTop + deadZone) { + if (placeholderIndex < thisIndex && pageY < offsetTop) { return; } if (placeholderIndex > thisIndex && diff --git a/dist/html5sortable.min.js b/dist/html5sortable.min.js index 2d8ac9a0..b875a469 100644 --- a/dist/html5sortable.min.js +++ b/dist/html5sortable.min.js @@ -1,2 +1,2 @@ -var sortable=function(){"use strict";function e(e,t,n){if(void 0===n)return e&&e.h5s&&e.h5s.data&&e.h5s.data[t];e.h5s=e.h5s||{},e.h5s.data=e.h5s.data||{},e.h5s.data[t]=n}function t(e,t){if(!(e instanceof NodeList||e instanceof HTMLCollection))throw new Error("You must provide a nodeList/HTMLCollection of elements to be filtered.");return"string"!=typeof t?Array.from(e):Array.from(e).filter(function(e){return 1===e.nodeType&&e.matches(t)})}function n(e,t,r){if(e instanceof Array)for(var a=0;a';break;case"TBODY":(t=document.createElement("tr")).innerHTML='';break;default:t=document.createElement("div")}return(a=t.classList).add.apply(a,n.split(" ")),t;var a},b=function(e,t){var n=function(e){return{draggedItem:e}}(t);!function(e,t){e.dataTransfer.effectAllowed="copyMove",e.dataTransfer.setData("text","arbitrary-content"),e.dataTransfer.setDragImage&&e.dataTransfer.setDragImage(t.draggedItem,t.x,t.y)}(e,n=function(e,t){return t.x||(t.x=parseInt(e.pageX-i(t.draggedItem).left)),t.y||(t.y=parseInt(e.pageY-i(t.draggedItem).top)),t}(e,n))},w=function(e,t){var n=e;return L(t)&&(a(n=e.cloneNode(!0),"aria-copied","true"),e.parentElement.appendChild(n),n.style.display="none",n.oldDisplay=e.style.display),n},x=function(t,n){if(I(t)){var r=e(t,"opts").acceptFrom;if(null!==r)return!1!==r&&r.split(",").filter(function(e){return e.length>0&&n.matches(e)}).length>0;if(t===n)return!0;if(void 0!==e(t,"connectWith"))return e(t,"connectWith")===e(n,"connectWith")}return!1},L=function(t){return!0===e(t,"opts").copy},A=function(e){var t=window.getComputedStyle(e);return["height","padding-top","padding-bottom"].map(function(e){var n=parseInt(t.getPropertyValue(e),10);return isNaN(n)?0:n}).reduce(function(e,t){return e+t})},C=function(e,t){var n,r=[];if(!t)return e;for(var a=0;a0?o[0]:r}var D=function(n){var a,i,s=e(n,"opts")||{},l=t(n.children,s.items),d=C(l,s.handle);y(n),(i=a=n).h5s&&delete i.h5s.data,o(a,"aria-dropeffect"),r(d,"mousedown"),g(l),function(e){o(e,"aria-grabbed"),o(e,"aria-copied"),o(e,"draggable"),o(e,"role")}(l)},O=function(r){var o=e(r,"opts"),i=t(r.children,o.items),s=C(i,o.handle);a(r,"aria-dropeffect","move"),e(r,"_disabled","false"),a(s,"draggable","true"),"function"!=typeof(document||window.document).createElement("span").dragDrop||o.disableIEFix||n(s,"mousedown",function(){if(-1!==i.indexOf(this))this.dragDrop();else{for(var e=this.parentElement;-1===i.indexOf(e);)e=e.parentElement;e.dragDrop()}})},M=function(n){var a=e(n,"opts"),o=t(n.children,a.items),i=C(o,a.handle);e(n,"_disabled","false"),g(o),r(i,"mousedown"),y(n)};function Y(r,o){var f=String(o);return o=function(e){var t={connectWith:!1,acceptFrom:null,copy:!1,placeholder:null,disableIEFix:!1,placeholderClass:"sortable-placeholder",draggingClass:"sortable-dragging",hoverClass:!1,debounce:0,maxItems:0,itemSerializer:void 0,containerSerializer:void 0};if("object"==typeof e)for(var n in e)t[n]=e[n];return t}(o),"string"==typeof r&&(r=document.querySelectorAll(r)),r instanceof Element&&(r=[r]),r=Array.prototype.slice.call(r),/serialize/.test(f)?r.map(function(t){var n=e(t,"opts");return m(t,n.itemSerializer,n.containerSerializer)}):(r.forEach(function(r){if(/enable|disable|destroy/.test(f))return Y[f](r);o=e(r,"opts")||o,e(r,"opts",o),r.isSortable=!0,M(r);var g,y,C=t(r.children,o.items),D=E(r,o.placeholder,o.placeholderClass);if(e(r,"items",o.items),v.set(r,D),o.acceptFrom?e(r,"acceptFrom",o.acceptFrom):o.connectWith&&e(r,"connectWith",o.connectWith),O(r),a(C,"role","option"),a(C,"aria-grabbed","false"),"string"==typeof o.hoverClass){var z=o.hoverClass.split(" ");n(C,"mouseenter",function(e){var t;(t=e.target.classList).add.apply(t,z)}),n(C,"mouseleave",function(e){var t;(t=e.target.classList).remove.apply(t,z)})}n(r,"dragstart",function(e){if(!I(e.target)&&(e.stopImmediatePropagation(),(!o.handle||e.target.matches(o.handle))&&"false"!==e.target.getAttribute("draggable"))){var t=T(e.target),n=S(t,e.target);b(e,n),c=A(n),n.classList.add(o.draggingClass),a(d=w(n,t),"aria-grabbed","true"),g=s(d,d.parentElement.children),h=T(e.target),y=m(h),t.dispatchEvent(new CustomEvent("sortstart",{detail:{item:d,placeholder:v.get(t),startparent:h}}))}}),n(r,"dragend",function(n){var r;if(d){var i=T(n.target);d.classList.remove(o.draggingClass),a(d,"aria-grabbed","false"),"true"===d.getAttribute("aria-copied")&&"true"!==e(d,"dropped")&&d.remove(),d.style.display=d.oldDisplay,delete d.oldDisplay,v.forEach(function(e){return e.remove()}),r=this.parentElement,x(r,h)&&(i.dispatchEvent(new CustomEvent("sortstop",{detail:{item:d,startparent:h}})),g===s(d,d.parentElement.children)&&h===r||i.dispatchEvent(new CustomEvent("sortupdate",{detail:{item:d,index:t(r.children,e(r,"items")).indexOf(d),oldindex:C.indexOf(d),elementIndex:s(d,d.parentElement.children),oldElementIndex:g,startparent:h,endparent:r,newEndList:m(r),newStartList:m(h),oldStartList:y}}))),d=null,c=null}}),n(r,"drop",function(n){if(x(r,d.parentElement)){n.preventDefault(),n.stopPropagation(),e(d,"dropped","true");var a=Array.from(v.values()).filter(l)[0];p(a,d),r.dispatchEvent(new CustomEvent("sortstop",{detail:{item:d,startparent:h}}));var o=I(this)?this:this.parentElement;g===s(d,d.parentElement.children)&&h===o||r.dispatchEvent(new CustomEvent("sortupdate",{detail:{item:d,index:s(d,t(o.children,e(o,"items"))),oldindex:C.indexOf(d),elementIndex:s(d,d.parentElement.children),oldElementIndex:g,startparent:h,endparent:o,newEndList:m(o),newStartList:m(h),oldStartList:y}}))}});var N,F,H,W=(N=function(e,n,r){if(d){var a=v.get(e);if(o.forcePlaceholderSize&&(a.style.height=c+"px"),Array.from(e.children).indexOf(n)>-1){var l=A(n),f=s(a,n.parentElement.children),m=s(n,n.parentElement.children);if(l>c){var h=l-c,g=i(n).top;if(fm&&r>g+l-h)return}void 0===d.oldDisplay&&(d.oldDisplay=d.style.display),"none"!==d.style.display&&(d.style.display="none"),f=parseInt(o.maxItems)||(n.preventDefault(),n.stopPropagation(),n.dataTransfer.dropEffect=L(a)?"copy":"move",W(a,r,n.pageY))}};n(C.concat(r),"dragover",P),n(C.concat(r),"dragenter",P)}),r)}return Y.destroy=function(e){D(e)},Y.enable=function(e){O(e)},Y.disable=function(n){!function(n){var o=e(n,"opts"),i=t(n.children,o.items),s=C(i,o.handle);a(n,"aria-dropeffect","none"),e(n,"_disabled","true"),a(s,"draggable","false"),r(s,"mousedown")}(n)},Y}(); +var sortable=function(){"use strict";function e(e,t,n){if(void 0===n)return e&&e.h5s&&e.h5s.data&&e.h5s.data[t];e.h5s=e.h5s||{},e.h5s.data=e.h5s.data||{},e.h5s.data[t]=n}function t(e,t){if(!(e instanceof NodeList||e instanceof HTMLCollection))throw new Error("You must provide a nodeList/HTMLCollection of elements to be filtered.");return"string"!=typeof t?Array.from(e):Array.from(e).filter(function(e){return 1===e.nodeType&&e.matches(t)})}function n(e,t,r){if(e instanceof Array)for(var a=0;a0&&n.matches(e)}).length>0;if(t===n)return!0;if(void 0!==e(t,"connectWith"))return e(t,"connectWith")===e(n,"connectWith")}return!1},L=function(t){return!0===e(t,"opts").copy},A=function(e,t){var n,r=[];if(!t)return e;for(var a=0;a0?o[0]:r}var T=function(n){var a,i,l=e(n,"opts")||{},s=t(n.children,l.items),d=A(s,l.handle);y(n),(i=a=n).h5s&&delete i.h5s.data,o(a,"aria-dropeffect"),r(d,"mousedown"),E(s),function(e){o(e,"aria-grabbed"),o(e,"aria-copied"),o(e,"draggable"),o(e,"role")}(s)},D=function(r){var o=e(r,"opts"),i=t(r.children,o.items),l=A(i,o.handle);a(r,"aria-dropeffect","move"),e(r,"_disabled","false"),a(l,"draggable","true"),"function"!=typeof(document||window.document).createElement("span").dragDrop||o.disableIEFix||n(l,"mousedown",function(){if(-1!==i.indexOf(this))this.dragDrop();else{for(var e=this.parentElement;-1===i.indexOf(e);)e=e.parentElement;e.dragDrop()}})},Y=function(n){var a=e(n,"opts"),o=t(n.children,a.items),i=A(o,a.handle);e(n,"_disabled","false"),E(o),r(i,"mousedown"),y(n)};function O(r,o){var f=String(o);return o=Object.assign({connectWith:!1,acceptFrom:null,copy:!1,placeholder:null,disableIEFix:!1,placeholderClass:"sortable-placeholder",draggingClass:"sortable-dragging",hoverClass:!1,debounce:0,maxItems:0,itemSerializer:void 0,containerSerializer:void 0},"object"==typeof o?o:{}),"string"==typeof r&&(r=document.querySelectorAll(r)),r instanceof Element&&(r=[r]),r=Array.prototype.slice.call(r),/serialize/.test(f)?r.map(function(t){var n=e(t,"opts");return m(t,n.itemSerializer,n.containerSerializer)}):(r.forEach(function(r){if(/enable|disable|destroy/.test(f))return O[f](r);o=e(r,"opts")||o,e(r,"opts",o),r.isSortable=!0,Y(r);var E,y,A,T=t(r.children,o.items);if(null!==o.placeholder&&void 0!==o.placeholder){var N=document.createElement(r.tagName);N.innerHTML=o.placeholder,A=N.children[0]}var z=function(e,t,n){if(void 0===n&&(n="sortable-placeholder"),!(e instanceof Element))throw new Error("You must provide a valid element as a sortable.");if(!(t instanceof Element)&&void 0!==t)throw new Error("You must provide a valid element as a placeholder or set ot to undefined.");return void 0===t&&(["UL","OL"].includes(e.tagName)?t=document.createElement("li"):["TABLE","TBODY"].includes(e.tagName)?(t=document.createElement("tr")).innerHTML='':t=document.createElement("div")),"string"==typeof n&&(r=t.classList).add.apply(r,n.split(" ")),t;var r}(r,A,o.placeholderClass);if(e(r,"items",o.items),g.set(r,z),o.acceptFrom?e(r,"acceptFrom",o.acceptFrom):o.connectWith&&e(r,"connectWith",o.connectWith),D(r),a(T,"role","option"),a(T,"aria-grabbed","false"),"string"==typeof o.hoverClass){var M=o.hoverClass.split(" ");n(T,"mouseenter",function(e){var t;(t=e.target.classList).add.apply(t,M)}),n(T,"mouseleave",function(e){var t;(t=e.target.classList).remove.apply(t,M)})}n(r,"dragstart",function(e){if(!C(e.target)&&(e.stopImmediatePropagation(),(!o.handle||e.target.matches(o.handle))&&"false"!==e.target.getAttribute("draggable"))){var t=I(e.target),n=S(t,e.target);b(e,n),c=h(n),n.classList.add(o.draggingClass),a(d=w(n,t),"aria-grabbed","true"),E=l(d,d.parentElement.children),v=I(e.target),y=m(v),t.dispatchEvent(new CustomEvent("sortstart",{detail:{item:d,placeholder:g.get(t),startparent:v}}))}}),n(r,"dragend",function(n){var r;if(d){var i=I(n.target);d.classList.remove(o.draggingClass),a(d,"aria-grabbed","false"),"true"===d.getAttribute("aria-copied")&&"true"!==e(d,"dropped")&&d.remove(),d.style.display=d.oldDisplay,delete d.oldDisplay,g.forEach(function(e){return e.remove()}),r=this.parentElement,x(r,v)&&(i.dispatchEvent(new CustomEvent("sortstop",{detail:{item:d,startparent:v}})),E===l(d,d.parentElement.children)&&v===r||i.dispatchEvent(new CustomEvent("sortupdate",{detail:{item:d,index:t(r.children,e(r,"items")).indexOf(d),oldindex:T.indexOf(d),elementIndex:l(d,d.parentElement.children),oldElementIndex:E,startparent:v,endparent:r,newEndList:m(r),newStartList:m(v),oldStartList:y}}))),d=null,c=null}}),n(r,"drop",function(n){if(x(r,d.parentElement)){n.preventDefault(),n.stopPropagation(),e(d,"dropped","true");var a=Array.from(g.values()).filter(s)[0];p(a,d),r.dispatchEvent(new CustomEvent("sortstop",{detail:{item:d,startparent:v}}));var o=C(this)?this:this.parentElement;E===l(d,d.parentElement.children)&&v===o||r.dispatchEvent(new CustomEvent("sortupdate",{detail:{item:d,index:l(d,t(o.children,e(o,"items"))),oldindex:T.indexOf(d),elementIndex:l(d,d.parentElement.children),oldElementIndex:E,startparent:v,endparent:o,newEndList:m(o),newStartList:m(v),oldStartList:y}}))}});var F,W,H,P=(F=function(e,n,r){if(d){var a=g.get(e);if(o.forcePlaceholderSize&&(a.style.height=c+"px"),Array.from(e.children).indexOf(n)>-1){var s=h(n),f=l(a,n.parentElement.children),m=l(n,n.parentElement.children);if(s>c){var v=s-c,E=i(n).top;if(fm&&r>E+s-v)return}void 0===d.oldDisplay&&(d.oldDisplay=d.style.display),"none"!==d.style.display&&(d.style.display="none"),f=parseInt(o.maxItems)||(n.preventDefault(),n.stopPropagation(),n.dataTransfer.dropEffect=L(a)?"copy":"move",P(a,r,n.pageY))}};n(T.concat(r),"dragover",_),n(T.concat(r),"dragenter",_)}),r)}return O.destroy=function(e){T(e)},O.enable=function(e){D(e)},O.disable=function(n){!function(n){var o=e(n,"opts"),i=t(n.children,o.items),l=A(i,o.handle);a(n,"aria-dropeffect","none"),e(n,"_disabled","true"),a(l,"draggable","false"),r(l,"mousedown")}(n)},O}(); //# sourceMappingURL=html5sortable.min.js.map diff --git a/dist/html5sortable.min.js.map b/dist/html5sortable.min.js.map index 7c7a30f6..b171a398 100644 --- a/dist/html5sortable.min.js.map +++ b/dist/html5sortable.min.js.map @@ -1 +1 @@ -{"version":3,"file":"html5sortable.min.js","sources":["../src/data.ts","../src/filter.ts","../src/eventListener.ts","../src/attribute.ts","../src/offset.ts","../src/index.ts","../src/isInDom.ts","../src/insertHtmlElements.ts","../src/html5sortable.ts","../src/serialize.ts","../src/debounce.ts"],"sourcesContent":["/**\n * Get or set data on element\n * @param {Element} element\n * @param {string} key\n * @param {*} value\n * @return {*}\n */\nfunction addData (element: Element, key: string, value?: any) {\n if (value === undefined) {\n return element && element.h5s && element.h5s.data && element.h5s.data[key]\n } else {\n element.h5s = element.h5s || {}\n element.h5s.data = element.h5s.data || {}\n element.h5s.data[key] = value\n }\n}\n/**\n * Remove data from element\n * @param {Element} element\n */\nfunction removeData (element: Element) {\n if (element.h5s) {\n delete element.h5s.data\n }\n}\n\nexport { addData, removeData }\n","/* global HTMLCollection, NodeList */\n/**\n * Filter only wanted nodes\n * @param {NodeList|HTMLCollection} nodes\n * @param {String} selector\n * @returns {Array}\n */\nexport default (nodes: NodeList|HTMLCollection, selector: string): Array => {\n if (!(nodes instanceof NodeList || nodes instanceof HTMLCollection)) {\n throw new Error('You must provide a nodeList/HTMLCollection of elements to be filtered.')\n }\n if (typeof selector !== 'string') {\n return Array.from(nodes)\n }\n\n return Array.from(nodes).filter((item) => item.nodeType === 1 && item.matches(selector))\n}\n","/**\n * @param {Array|Element} element\n * @param {Array|string} event\n * @param {Function} callback\n */\nfunction addEventListener (element, event, callback) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n addEventListener(element[i], event, callback)\n }\n return\n }\n element.addEventListener(event, callback)\n element.h5s = element.h5s || {}\n element.h5s.events = element.h5s.events || {}\n element.h5s.events[event] = callback\n}\n/**\n * @param {Array|Element} element\n * @param {Array|string} event\n */\nfunction removeEventListener (element, event) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n removeEventListener(element[i], event)\n }\n return\n }\n if (element.h5s && element.h5s.events && element.h5s.events[event]) {\n element.removeEventListener(event, element.h5s.events[event])\n delete element.h5s.events[event]\n }\n}\n\nexport { addEventListener, removeEventListener }\n","/**\n * @param {Array|Element} element\n * @param {string} attribute\n * @param {*} value\n */\nfunction addAttribute (element, attribute, value) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n addAttribute(element[i], attribute, value)\n }\n return\n }\n element.setAttribute(attribute, value)\n}\n/**\n * @param {Array|Element} element\n * @param {string} attribute\n */\nfunction removeAttribute (element, attribute) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n removeAttribute(element[i], attribute)\n }\n return\n }\n element.removeAttribute(attribute)\n}\n\nexport { addAttribute, removeAttribute }\n","/**\n * @param {Element} element\n * @returns {Object}\n */\nexport default (element: Element): object => {\n if (!element.parentElement) {\n throw new Error('target element must be part of the dom')\n }\n\n let rect = element.getClientRects()[0]\n return {\n left: rect.left + window.scrollX,\n right: rect.right + window.scrollX,\n top: rect.top + window.scrollY,\n bottom: rect.bottom + window.scrollY\n }\n}\n","/* eslint-env browser */\n/**\n * Get position of the element relatively to its sibling elements\n * @param {Element} element\n * @returns {number}\n */\nexport default (element: Element, elementList: HTMLCollection | NodeList | Array): number => {\n if (!(element instanceof Element) || !(elementList instanceof NodeList || elementList instanceof HTMLCollection || elementList instanceof Array)) {\n throw new Error('You must provide an element and a list of elements.')\n }\n\n return Array.from(elementList).indexOf(element)\n}\n","/**\n * Test whether element is in DOM\n * @param {Element} element\n * @returns {boolean}\n */\nexport default (element: Element): boolean => {\n if (!element || element.nodeType !== 1) {\n throw new Error('Element is not a node element.')\n }\n\n return element.parentNode !== null\n}\n","/* eslint-env browser */\n/**\n * Insert node before or after target\n * @param {Element} referenceNode - reference element\n * @param {Element} newElement - element to be inserted\n * @param {String} position - insert before or after reference element\n */\nlet insertNode = (referenceNode: any, newElement: any, position: String) => {\n if (!(referenceNode instanceof Element) || !(referenceNode.parentElement instanceof Element)) {\n throw new Error('target and element must be a node')\n }\n referenceNode.parentElement.insertBefore(\n newElement,\n (position === 'before' ? referenceNode : referenceNode.nextElementSibling)\n )\n}\n/**\n * Insert before target\n * @param {Element} target\n * @param {Element} element\n */\nlet insertBefore = (target, element) => insertNode(target, element, 'before')\n/**\n * Insert after target\n * @param {Element} target\n * @param {Element} element\n */\nlet insertAfter = (target, element) => insertNode(target, element, 'after')\n\nexport { insertBefore, insertAfter }\n","/* eslint-env browser */\n'use strict'\n\nimport { addData as _data, removeData as _removeData } from './data'\nimport _filter from './filter'\nimport { addEventListener as _on, removeEventListener as _off } from './eventListener'\nimport { addAttribute as _attr, removeAttribute as _removeAttr } from './attribute'\nimport _offset from './offset'\nimport _debounce from './debounce'\nimport _index from './index'\nimport isInDom from './isInDom'\nimport {insertBefore as _before, insertAfter as _after} from './insertHtmlElements'\nimport _serialize from './serialize'\n/*\n * variables global to the plugin\n */\nvar dragging\nvar draggingHeight\nvar placeholderMap = new Map()\nlet startParent\n/**\n * remove event handlers from items\n * @param {Array|NodeList} items\n */\nvar _removeItemEvents = function (items) {\n _off(items, 'dragstart')\n _off(items, 'dragend')\n _off(items, 'selectstart')\n _off(items, 'dragover')\n _off(items, 'dragenter')\n _off(items, 'drop')\n _off(items, 'mouseenter')\n _off(items, 'mouseleave')\n}\n/**\n * Remove event handlers from sortable\n * @param {Element} sortable a single sortable\n */\nvar _removeSortableEvents = function (sortable) {\n _off(sortable, 'dragover')\n _off(sortable, 'dragenter')\n _off(sortable, 'drop')\n}\n/**\n * create a placeholder element\n * @param {Elememnt} sortableElement a single sortable\n * @param {string|undefine} placeholder a string representing an html element\n * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder\n */\nlet _makePlaceholder = (sortableElement, placeholder = undefined, placeholderClasses = 'sortable-placeholder') => {\n if (typeof placeholder === 'string') {\n let tempContainer = document.createElement(sortableElement.tagName)\n tempContainer.innerHTML = placeholder\n placeholder = tempContainer.children[0]\n } else {\n switch (sortableElement.tagName) {\n case 'UL':\n placeholder = document.createElement('li')\n break\n case 'OL':\n placeholder = document.createElement('li')\n break\n case 'TABLE':\n placeholder = 'tr'\n placeholder.innerHTML = ''\n break\n case 'TBODY':\n placeholder = document.createElement('tr')\n placeholder.innerHTML = ''\n break\n default:\n placeholder = document.createElement('div')\n }\n }\n // add classes to placeholder\n placeholder.classList.add(...placeholderClasses.split(' '))\n\n return placeholder\n}\n/**\n * Attach ghost to dataTransfer object\n * @param {Event} original event\n * @param {object} ghost-object with item, x and y coordinates\n */\nvar _attachGhost = function (event, ghost) {\n // this needs to be set for HTML5 drag & drop to work\n event.dataTransfer.effectAllowed = 'copyMove'\n // Firefox requires some arbitrary content in the data in order for\n // the drag & drop functionality to work\n event.dataTransfer.setData('text', 'arbitrary-content')\n\n // check if setDragImage method is available\n if (event.dataTransfer.setDragImage) {\n event.dataTransfer.setDragImage(ghost.draggedItem, ghost.x, ghost.y)\n }\n}\n/**\n * _addGhostPos clones the dragged item and adds it as a Ghost item\n * @param {Event} event - the event fired when dragstart is triggered\n * @param {object} ghost - .draggedItem = Element\n */\nvar _addGhostPos = function (event, ghost) {\n if (!ghost.x) {\n ghost.x = parseInt(event.pageX - _offset(ghost.draggedItem).left)\n }\n if (!ghost.y) {\n ghost.y = parseInt(event.pageY - _offset(ghost.draggedItem).top)\n }\n return ghost\n}\n/**\n * _makeGhost decides which way to make a ghost and passes it to attachGhost\n * @param {Element} draggedItem - the item that the user drags\n */\nvar _makeGhost = function (draggedItem) {\n return {\n draggedItem: draggedItem\n }\n}\n/**\n * _getGhost constructs ghost and attaches it to dataTransfer\n * @param {Event} event - the original drag event object\n * @param {Element} draggedItem - the item that the user drags\n */\n// TODO: could draggedItem be replaced by event.target in all instances\nvar _getGhost = function (event, draggedItem) {\n // add ghost item & draggedItem to ghost object\n var ghost = _makeGhost(draggedItem)\n // attach ghost position\n ghost = _addGhostPos(event, ghost)\n // attach ghost to dataTransfer\n _attachGhost(event, ghost)\n}\n/**\n * _getDragging returns the current element to drag or\n * a copy of the element.\n * Is Copy Active for sortable\n * @param {Element} draggedItem - the item that the user drags\n * @param {Element} sortable a single sortable\n */\nvar _getDragging = function (draggedItem, sortable) {\n var ditem = draggedItem\n if (_isCopyActive(sortable)) {\n ditem = draggedItem.cloneNode(true)\n _attr(ditem, 'aria-copied', 'true')\n draggedItem.parentElement.appendChild(ditem)\n ditem.style.display = 'none'\n ditem.oldDisplay = draggedItem.style.display\n }\n return ditem\n}\n/**\n * Remove data from sortable\n * @param {Element} sortable a single sortable\n */\nvar _removeSortableData = function (sortable) {\n _removeData(sortable)\n _removeAttr(sortable, 'aria-dropeffect')\n}\n/**\n * Remove data from items\n * @param {Array|Element} items\n */\nvar _removeItemData = function (items) {\n _removeAttr(items, 'aria-grabbed')\n _removeAttr(items, 'aria-copied')\n _removeAttr(items, 'draggable')\n _removeAttr(items, 'role')\n}\n/**\n * Check if two lists are connected\n * @param {Element} curList\n * @param {Element} destList\n */\nvar _listsConnected = function (curList, destList) {\n if (_isSortable(curList)) {\n var acceptFrom = _data(curList, 'opts').acceptFrom\n if (acceptFrom !== null) {\n return acceptFrom !== false && acceptFrom.split(',').filter(function (sel) {\n return sel.length > 0 && destList.matches(sel)\n }).length > 0\n }\n if (curList === destList) {\n return true\n }\n if (_data(curList, 'connectWith') !== undefined) {\n return _data(curList, 'connectWith') === _data(destList, 'connectWith')\n }\n }\n return false\n}\n/**\n * Is Copy Active for sortable\n * @param {Element} sortable a single sortable\n */\nvar _isCopyActive = function (sortable) {\n return _data(sortable, 'opts').copy === true\n}\n/**\n * Get height of an element including padding\n * @param {Element} sortable a single sortable\n */\nlet _getElementHeight = (element) => {\n // get calculated style of element\n let style = window.getComputedStyle(element)\n // pick applicable properties, convert to int and reduce by adding\n return ['height', 'padding-top', 'padding-bottom']\n .map((key) => {\n let int = parseInt(style.getPropertyValue(key), 10)\n return isNaN(int) ? 0 : int\n })\n .reduce((prev, cur) => prev + cur)\n}\n/**\n * get handle or return item\n * @param {Array} items\n * @param {selector} handle\n */\nvar _getHandles = function (items, handle) {\n var result = []\n var handles\n if (!handle) {\n return items\n }\n for (var i = 0; i < items.length; ++i) {\n handles = items[i].querySelectorAll(handle)\n result = result.concat(Array.prototype.slice.call(handles))\n }\n return result\n}\n/**\n * Is {Element} a sortable.\n * @param {Element} sortable a single sortable\n */\nfunction _isSortable (element) {\n return element !== undefined && element != null && _data(element, 'opts') !== undefined\n}\n/**\n * find sortable from element. travels up parent element until found or null.\n * @param {Element} sortable a single sortable\n */\nfunction findSortable (element) {\n while ((element = element.parentElement) && !_isSortable(element));\n return element\n}\n/**\n * Dragging event is on the sortable element. finds the top child that\n * contains the element.\n * @param {Element} sortable a single sortable\n * @param {Element} element is that being dragged\n */\nfunction findDragElement (sortableElement, element) {\n var options = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, options.items)\n var itemlist = items.filter(function (ele) {\n return ele.contains(element)\n })\n\n return itemlist.length > 0 ? itemlist[0] : element\n}\n/**\n * Destroy the sortable\n * @param {Element} sortableElement a single sortable\n */\nvar _destroySortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts') || {}\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n // remove event handlers & data from sortable\n _removeSortableEvents(sortableElement)\n _removeSortableData(sortableElement)\n // remove event handlers & data from items\n _off(handles, 'mousedown')\n _removeItemEvents(items)\n _removeItemData(items)\n}\n/**\n * Enable the sortable\n * @param {Element} sortableElement a single sortable\n */\nvar _enableSortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n _attr(sortableElement, 'aria-dropeffect', 'move')\n _data(sortableElement, '_disabled', 'false')\n _attr(handles, 'draggable', 'true')\n // IE FIX for ghost\n // can be disabled as it has the side effect that other events\n // (e.g. click) will be ignored\n var spanEl = (document || window.document).createElement('span')\n if (typeof spanEl.dragDrop === 'function' && !opts.disableIEFix) {\n _on(handles, 'mousedown', function () {\n if (items.indexOf(this) !== -1) {\n this.dragDrop()\n } else {\n var parent = this.parentElement\n while (items.indexOf(parent) === -1) {\n parent = parent.parentElement\n }\n parent.dragDrop()\n }\n })\n }\n}\n/**\n * Disable the sortable\n * @param {Element} sortableElement a single sortable\n */\nvar _disableSortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n _attr(sortableElement, 'aria-dropeffect', 'none')\n _data(sortableElement, '_disabled', 'true')\n _attr(handles, 'draggable', 'false')\n _off(handles, 'mousedown')\n}\n/**\n * Reload the sortable\n * @param {Element} sortableElement a single sortable\n * @description events need to be removed to not be double bound\n */\nvar _reloadSortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n _data(sortableElement, '_disabled', 'false')\n // remove event handlers from items\n _removeItemEvents(items)\n _off(handles, 'mousedown')\n // remove event handlers from sortable\n _removeSortableEvents(sortableElement)\n}\n\n/**\n * Public sortable object\n * @param {Array|NodeList} sortableElements\n * @param {object|string} options|method\n */\nexport default function sortable (sortableElements, options) {\n var method = String(options)\n options = (function (options) {\n var result = {\n connectWith: false,\n acceptFrom: null,\n copy: false,\n placeholder: null,\n disableIEFix: false,\n placeholderClass: 'sortable-placeholder',\n draggingClass: 'sortable-dragging',\n hoverClass: false,\n debounce: 0,\n maxItems: 0,\n itemSerializer: undefined,\n containerSerializer: undefined\n }\n if (typeof options === 'object') {\n for (var option in options) {\n result[option] = options[option]\n }\n }\n return result\n })(options)\n\n if (typeof sortableElements === 'string') {\n sortableElements = document.querySelectorAll(sortableElements)\n }\n\n if (sortableElements instanceof Element) {\n sortableElements = [sortableElements]\n }\n\n sortableElements = Array.prototype.slice.call(sortableElements)\n\n if (/serialize/.test(method)) {\n return sortableElements.map((sortableContainer) => {\n let opts = _data(sortableContainer, 'opts')\n return _serialize(sortableContainer, opts.itemSerializer, opts.containerSerializer)\n })\n }\n\n sortableElements.forEach(function (sortableElement) {\n if (/enable|disable|destroy/.test(method)) {\n return sortable[method](sortableElement)\n }\n\n // get options & set options on sortable\n options = _data(sortableElement, 'opts') || options\n _data(sortableElement, 'opts', options)\n // property to define as sortable\n sortableElement.isSortable = true\n // reset sortable\n _reloadSortable(sortableElement)\n // initialize\n var items = _filter(sortableElement.children, options.items)\n var index\n var startList\n let placeholder = _makePlaceholder(sortableElement, options.placeholder, options.placeholderClass)\n\n _data(sortableElement, 'items', options.items)\n placeholderMap.set(sortableElement, placeholder)\n if (options.acceptFrom) {\n _data(sortableElement, 'acceptFrom', options.acceptFrom)\n } else if (options.connectWith) {\n _data(sortableElement, 'connectWith', options.connectWith)\n }\n\n _enableSortable(sortableElement)\n _attr(items, 'role', 'option')\n _attr(items, 'aria-grabbed', 'false')\n\n // Mouse over class\n if (typeof options.hoverClass === 'string') {\n let hoverClasses = options.hoverClass.split(' ')\n // add class on hover\n _on(items, 'mouseenter', function (e) {\n e.target.classList.add(...hoverClasses)\n })\n // remove class on leave\n _on(items, 'mouseleave', function (e) {\n e.target.classList.remove(...hoverClasses)\n })\n }\n\n // Handle drag events on draggable items\n // Handle set at sortableelement level as it will bubble up\n // from the item\n _on(sortableElement, 'dragstart', function (e) {\n // ignore dragstart events\n if (_isSortable(e.target)) {\n return\n }\n e.stopImmediatePropagation()\n\n if ((options.handle && !e.target.matches(options.handle)) || e.target.getAttribute('draggable') === 'false') {\n return\n }\n\n var sortableElement = findSortable(e.target)\n var dragitem = findDragElement(sortableElement, e.target)\n // add transparent clone or other ghost to cursor\n _getGhost(e, dragitem)\n // cache selsection & add attr for dragging\n draggingHeight = _getElementHeight(dragitem)\n dragitem.classList.add(options.draggingClass)\n dragging = _getDragging(dragitem, sortableElement)\n _attr(dragging, 'aria-grabbed', 'true')\n // grab values\n index = _index(dragging, dragging.parentElement.children)\n startParent = findSortable(e.target)\n startList = _serialize(startParent)\n // dispatch sortstart event on each element in group\n\n sortableElement.dispatchEvent(new CustomEvent('sortstart', {\n detail: {\n item: dragging,\n placeholder: placeholderMap.get(sortableElement),\n startparent: startParent\n }\n }))\n })\n // Handle drag events on draggable items\n _on(sortableElement, 'dragend', function (e) {\n var newParent\n if (!dragging) {\n return\n }\n var sortableElement = findSortable(e.target)\n // remove dragging attributes and show item\n dragging.classList.remove(options.draggingClass)\n _attr(dragging, 'aria-grabbed', 'false')\n\n if (dragging.getAttribute('aria-copied') === 'true' && _data(dragging, 'dropped') !== 'true') {\n dragging.remove()\n }\n\n dragging.style.display = dragging.oldDisplay\n delete dragging.oldDisplay\n\n placeholderMap.forEach((element) => element.remove())\n newParent = this.parentElement\n\n if (_listsConnected(newParent, startParent)) {\n sortableElement.dispatchEvent(new CustomEvent('sortstop', {\n detail: {\n item: dragging,\n startparent: startParent\n }\n }))\n if (index !== _index(dragging, dragging.parentElement.children) || startParent !== newParent) {\n sortableElement.dispatchEvent(new CustomEvent('sortupdate', {\n detail: {\n item: dragging,\n index: _filter(newParent.children, _data(newParent, 'items'))\n .indexOf(dragging),\n oldindex: items.indexOf(dragging),\n elementIndex: _index(dragging, dragging.parentElement.children),\n oldElementIndex: index,\n startparent: startParent,\n endparent: newParent,\n newEndList: _serialize(newParent),\n newStartList: _serialize(startParent),\n oldStartList: startList\n }\n }))\n }\n }\n dragging = null\n draggingHeight = null\n })\n // Handle drop event on sortable & placeholder\n _on(sortableElement, 'drop', function (e) {\n if (!_listsConnected(sortableElement, dragging.parentElement)) {\n return\n }\n e.preventDefault()\n e.stopPropagation()\n\n _data(dragging, 'dropped', 'true')\n var visiblePlaceholder = Array.from(placeholderMap.values()).filter(isInDom)[0]\n _after(visiblePlaceholder, dragging)\n // fire sortstop\n sortableElement.dispatchEvent(new CustomEvent('sortstop', {\n detail: {\n item: dragging,\n startparent: startParent\n }\n }))\n\n let newParent = _isSortable(this) ? this : this.parentElement\n // fire sortupdate if index or parent changed\n if (index !== _index(dragging, dragging.parentElement.children) || startParent !== newParent) {\n sortableElement.dispatchEvent(new CustomEvent('sortupdate', {\n detail: {\n item: dragging,\n index: _index(dragging, _filter(newParent.children, _data(newParent, 'items'))),\n oldindex: items.indexOf(dragging),\n elementIndex: _index(dragging, dragging.parentElement.children),\n oldElementIndex: index,\n startparent: startParent,\n endparent: newParent,\n newEndList: _serialize(newParent),\n newStartList: _serialize(startParent),\n oldStartList: startList\n }\n }))\n }\n })\n\n var debouncedDragOverEnter = _debounce((sortableElement, element, pageY) => {\n if (!dragging) {\n return\n }\n\n var placeholder = placeholderMap.get(sortableElement)\n // set placeholder height if forcePlaceholderSize option is set\n if (options.forcePlaceholderSize) {\n placeholder.style.height = draggingHeight + 'px'\n }\n // if element the draggedItem is dragged onto is within the array of all elements in list\n // (not only items, but also disabled, etc.)\n if (Array.from(sortableElement.children).indexOf(element) > -1) {\n let thisHeight = _getElementHeight(element)\n var placeholderIndex = _index(placeholder, element.parentElement.children)\n var thisIndex = _index(element, element.parentElement.children)\n // Check if `element` is bigger than the draggable. If it is, we have to define a dead zone to prevent flickering\n if (thisHeight > draggingHeight) {\n // Dead zone?\n var deadZone = thisHeight - draggingHeight\n var offsetTop = _offset(element).top\n if (placeholderIndex < thisIndex &&\n pageY < offsetTop + deadZone) {\n return\n }\n if (placeholderIndex > thisIndex &&\n pageY > offsetTop + thisHeight - deadZone) {\n return\n }\n }\n\n if (dragging.oldDisplay === undefined) {\n dragging.oldDisplay = dragging.style.display\n }\n\n if (dragging.style.display !== 'none') {\n dragging.style.display = 'none'\n }\n if (placeholderIndex < thisIndex) {\n _after(element, placeholder)\n } else {\n _before(element, placeholder)\n }\n // Intentionally violated chaining, it is more complex otherwise\n Array.from(placeholderMap.values())\n .filter(function (element) { return element !== placeholder })\n .forEach((element) => element.remove())\n } else {\n if (Array.from(placeholderMap.values()).indexOf(element) === -1 &&\n sortableElement === element &&\n !_filter(element.children, options.items).length) {\n placeholderMap.forEach((element) => element.remove())\n element.appendChild(placeholder)\n }\n }\n }, options.debounce)\n // Handle dragover and dragenter events on draggable items\n var onDragOverEnter = function (e) {\n var element = e.target\n var sortableElement = _isSortable(element) ? element : findSortable(element)\n element = findDragElement(sortableElement, element)\n if (!dragging || !_listsConnected(sortableElement, dragging.parentElement) || _data(sortableElement, '_disabled') === 'true') {\n return\n }\n var options = _data(sortableElement, 'opts')\n if (parseInt(options.maxItems) && _filter(sortableElement.children, _data(sortableElement, 'items')).length >= parseInt(options.maxItems)) {\n return\n }\n e.preventDefault()\n e.stopPropagation()\n e.dataTransfer.dropEffect = _isCopyActive(sortableElement) ? 'copy' : 'move'\n debouncedDragOverEnter(sortableElement, element, e.pageY)\n }\n\n _on(items.concat(sortableElement), 'dragover', onDragOverEnter)\n _on(items.concat(sortableElement), 'dragenter', onDragOverEnter)\n })\n\n return sortableElements\n}\n\nsortable.destroy = function (sortableElement) {\n _destroySortable(sortableElement)\n}\n\nsortable.enable = function (sortableElement) {\n _enableSortable(sortableElement)\n}\n\nsortable.disable = function (sortableElement) {\n _disableSortable(sortableElement)\n}\n\n/* START.TESTS_ONLY */\nsortable.__testing = {\n // add internal methods here for testing purposes\n _data: _data,\n _removeSortableEvents: _removeSortableEvents,\n _removeItemEvents: _removeItemEvents,\n _removeItemData: _removeItemData,\n _removeSortableData: _removeSortableData,\n _listsConnected: _listsConnected,\n _attachGhost: _attachGhost,\n _addGhostPos: _addGhostPos,\n _getGhost: _getGhost,\n _getHandles: _getHandles,\n _makeGhost: _makeGhost,\n _index: _index,\n _getPlaceholders: () => placeholderMap,\n _resetPlaceholders: () => {\n placeholderMap.clear()\n }\n}\n/* END.TESTS_ONLY */\n","/* eslint-env browser */\nimport {addData as _data} from './data' // yuk, data really needs to be refactored\nimport filter from './filter'\nimport index from './index'\n/**\n * Filter only wanted nodes\n * @param {Element} sortableContainer\n * @param {Function} customSerializer\n * @returns {Array}\n */\nexport default (sortableContainer: Element, customItemSerializer: Function = (serializedItem: object, sortableContainer: Element) => serializedItem, customContainerSerializer: Function = (serializedContainer: object) => serializedContainer): object => {\n // check for valid sortableContainer\n if (!(sortableContainer instanceof Element) || !sortableContainer.isSortable === true) {\n throw new Error('You need to provide a sortableContainer to be serialized.')\n }\n // check for valid serializers\n if (typeof customItemSerializer !== 'function' || typeof customContainerSerializer !== 'function') {\n throw new Error('You need to provide a valid serializer for items and the container.')\n }\n // get options\n let options = _data(sortableContainer, 'opts')\n // serialize container\n let items = filter(sortableContainer.children, options.items)\n items = items.map((item) => {\n return {\n parent: sortableContainer,\n node: item,\n html: item.outerHTML,\n index: index(item, items)\n }\n })\n // serialize container\n let container = {\n node: sortableContainer,\n itemCount: items.length\n }\n\n return {\n container: customContainerSerializer(container),\n items: items.map((item: object) => customItemSerializer(item, sortableContainer))\n }\n}\n","/**\n * Creates and returns a new debounced version of the passed function which will postpone its execution until after wait milliseconds have elapsed\n * @param {func} Function to debounce\n * @param {wait} time to wait before calling function with latest arguments, 0 - no debounce\n * @returns {function} - debounced function\n */\nexport default (func: Function, wait: number = 0): Function => {\n let timeout\n\n return (...args) => {\n clearTimeout(timeout)\n timeout = setTimeout(() => {\n func(...args)\n }, wait)\n }\n}\n"],"names":["element","key","value","undefined","h5s","data","nodes","selector","NodeList","HTMLCollection","Error","Array","from","filter","item","nodeType","matches","event","callback","i","length","addEventListener","events","removeEventListener","attribute","addAttribute","setAttribute","removeAttribute","parentElement","rect","getClientRects","left","window","scrollX","right","top","scrollY","bottom","elementList","Element","indexOf","parentNode","dragging","draggingHeight","insertNode","referenceNode","newElement","position","insertBefore","nextElementSibling","target","insertAfter","sortableContainer","customItemSerializer","customContainerSerializer","serializedItem","serializedContainer","isSortable","options","_data","items","children","map","parent","node","html","outerHTML","index","container","itemCount","startParent","placeholderMap","Map","_removeItemEvents","_off","_removeSortableEvents","sortable","_makePlaceholder","sortableElement","placeholder","placeholderClasses","tempContainer","document","createElement","tagName","innerHTML","classList","add","split","_getGhost","draggedItem","ghost","_makeGhost","dataTransfer","effectAllowed","setData","setDragImage","x","y","_attachGhost","parseInt","pageX","_offset","pageY","_addGhostPos","_getDragging","ditem","_isCopyActive","_attr","cloneNode","appendChild","style","display","oldDisplay","_listsConnected","curList","destList","_isSortable","acceptFrom","sel","copy","_getElementHeight","getComputedStyle","int","getPropertyValue","isNaN","reduce","prev","cur","_getHandles","handle","handles","result","querySelectorAll","concat","prototype","slice","call","itemlist","_filter","ele","contains","_destroySortable","opts","_removeAttr","_removeItemData","_enableSortable","dragDrop","disableIEFix","_on","this","_reloadSortable","sortableElements","method","String","connectWith","placeholderClass","draggingClass","hoverClass","debounce","maxItems","itemSerializer","containerSerializer","option","test","_serialize","forEach","startList","set","hoverClasses_1","e","remove","stopImmediatePropagation","getAttribute","findSortable","dragitem","findDragElement","_index","dispatchEvent","CustomEvent","detail","get","startparent","newParent","oldindex","elementIndex","oldElementIndex","endparent","newEndList","newStartList","oldStartList","preventDefault","stopPropagation","visiblePlaceholder","values","isInDom","_after","func","wait","timeout","debouncedDragOverEnter","forcePlaceholderSize","height","thisHeight","placeholderIndex","thisIndex","deadZone","offsetTop","_before","_i","args","clearTimeout","setTimeout","onDragOverEnter","dropEffect","destroy","enable","disable","_disableSortable"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"html5sortable.min.js","sources":["../src/data.ts","../src/filter.ts","../src/eventListener.ts","../src/attribute.ts","../src/offset.ts","../src/index.ts","../src/isInDom.ts","../src/insertHtmlElements.ts","../src/html5sortable.ts","../src/serialize.ts","../src/elementHeight.ts","../src/makePlaceholder.ts","../src/debounce.ts"],"sourcesContent":["/**\n * Get or set data on element\n * @param {Element} element\n * @param {string} key\n * @param {*} value\n * @return {*}\n */\nfunction addData (element: Element, key: string, value?: any) {\n if (value === undefined) {\n return element && element.h5s && element.h5s.data && element.h5s.data[key]\n } else {\n element.h5s = element.h5s || {}\n element.h5s.data = element.h5s.data || {}\n element.h5s.data[key] = value\n }\n}\n/**\n * Remove data from element\n * @param {Element} element\n */\nfunction removeData (element: Element) {\n if (element.h5s) {\n delete element.h5s.data\n }\n}\n\nexport { addData, removeData }\n","/* global HTMLCollection, NodeList */\n/**\n * Filter only wanted nodes\n * @param {NodeList|HTMLCollection} nodes\n * @param {String} selector\n * @returns {Array}\n */\nexport default (nodes: NodeList|HTMLCollection, selector: string): Array => {\n if (!(nodes instanceof NodeList || nodes instanceof HTMLCollection)) {\n throw new Error('You must provide a nodeList/HTMLCollection of elements to be filtered.')\n }\n if (typeof selector !== 'string') {\n return Array.from(nodes)\n }\n\n return Array.from(nodes).filter((item) => item.nodeType === 1 && item.matches(selector))\n}\n","/**\n * @param {Array|Element} element\n * @param {Array|string} event\n * @param {Function} callback\n */\nfunction addEventListener (element, event, callback) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n addEventListener(element[i], event, callback)\n }\n return\n }\n element.addEventListener(event, callback)\n element.h5s = element.h5s || {}\n element.h5s.events = element.h5s.events || {}\n element.h5s.events[event] = callback\n}\n/**\n * @param {Array|Element} element\n * @param {Array|string} event\n */\nfunction removeEventListener (element, event) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n removeEventListener(element[i], event)\n }\n return\n }\n if (element.h5s && element.h5s.events && element.h5s.events[event]) {\n element.removeEventListener(event, element.h5s.events[event])\n delete element.h5s.events[event]\n }\n}\n\nexport { addEventListener, removeEventListener }\n","/**\n * @param {Array|Element} element\n * @param {string} attribute\n * @param {*} value\n */\nfunction addAttribute (element, attribute, value) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n addAttribute(element[i], attribute, value)\n }\n return\n }\n element.setAttribute(attribute, value)\n}\n/**\n * @param {Array|Element} element\n * @param {string} attribute\n */\nfunction removeAttribute (element, attribute) {\n if (element instanceof Array) {\n for (var i = 0; i < element.length; ++i) {\n removeAttribute(element[i], attribute)\n }\n return\n }\n element.removeAttribute(attribute)\n}\n\nexport { addAttribute, removeAttribute }\n","/**\n * @param {Element} element\n * @returns {Object}\n */\nexport default (element: Element): object => {\n if (!element.parentElement) {\n throw new Error('target element must be part of the dom')\n }\n\n let rect = element.getClientRects()[0]\n return {\n left: rect.left + window.scrollX,\n right: rect.right + window.scrollX,\n top: rect.top + window.scrollY,\n bottom: rect.bottom + window.scrollY\n }\n}\n","/* eslint-env browser */\n/**\n * Get position of the element relatively to its sibling elements\n * @param {Element} element\n * @returns {number}\n */\nexport default (element: Element, elementList: HTMLCollection | NodeList | Array): number => {\n if (!(element instanceof Element) || !(elementList instanceof NodeList || elementList instanceof HTMLCollection || elementList instanceof Array)) {\n throw new Error('You must provide an element and a list of elements.')\n }\n\n return Array.from(elementList).indexOf(element)\n}\n","/* eslint-env browser */\n/**\n * Test whether element is in DOM\n * @param {Element} element\n * @returns {boolean}\n */\nexport default (element: Element): boolean => {\n if (!(element instanceof Element)) {\n throw new Error('Element is not a node element.')\n }\n\n return element.parentNode !== null\n}\n","/* eslint-env browser */\n/**\n * Insert node before or after target\n * @param {Element} referenceNode - reference element\n * @param {Element} newElement - element to be inserted\n * @param {String} position - insert before or after reference element\n */\nlet insertNode = (referenceNode: any, newElement: any, position: String) => {\n if (!(referenceNode instanceof Element) || !(referenceNode.parentElement instanceof Element)) {\n throw new Error('target and element must be a node')\n }\n referenceNode.parentElement.insertBefore(\n newElement,\n (position === 'before' ? referenceNode : referenceNode.nextElementSibling)\n )\n}\n/**\n * Insert before target\n * @param {Element} target\n * @param {Element} element\n */\nlet insertBefore = (target, element) => insertNode(target, element, 'before')\n/**\n * Insert after target\n * @param {Element} target\n * @param {Element} element\n */\nlet insertAfter = (target, element) => insertNode(target, element, 'after')\n\nexport { insertBefore, insertAfter }\n","/* eslint-env browser */\n'use strict'\n\nimport { addData as _data, removeData as _removeData } from './data'\nimport _filter from './filter'\nimport { addEventListener as _on, removeEventListener as _off } from './eventListener'\nimport { addAttribute as _attr, removeAttribute as _removeAttr } from './attribute'\nimport _offset from './offset'\nimport _debounce from './debounce'\nimport _index from './index'\nimport isInDom from './isInDom'\nimport {insertBefore as _before, insertAfter as _after} from './insertHtmlElements'\nimport _serialize from './serialize'\nimport _makePlaceholder from './makePlaceholder'\nimport _getElementHeight from './elementHeight'\n\n/*\n * variables global to the plugin\n */\nvar dragging\nvar draggingHeight\nvar placeholderMap = new Map()\nlet startParent\n/**\n * remove event handlers from items\n * @param {Array|NodeList} items\n */\nvar _removeItemEvents = function (items) {\n _off(items, 'dragstart')\n _off(items, 'dragend')\n _off(items, 'selectstart')\n _off(items, 'dragover')\n _off(items, 'dragenter')\n _off(items, 'drop')\n _off(items, 'mouseenter')\n _off(items, 'mouseleave')\n}\n/**\n * Remove event handlers from sortable\n * @param {Element} sortable a single sortable\n */\nvar _removeSortableEvents = function (sortable) {\n _off(sortable, 'dragover')\n _off(sortable, 'dragenter')\n _off(sortable, 'drop')\n}\n/**\n * Attach ghost to dataTransfer object\n * @param {Event} original event\n * @param {object} ghost-object with item, x and y coordinates\n */\nvar _attachGhost = function (event, ghost) {\n // this needs to be set for HTML5 drag & drop to work\n event.dataTransfer.effectAllowed = 'copyMove'\n // Firefox requires some arbitrary content in the data in order for\n // the drag & drop functionality to work\n event.dataTransfer.setData('text', 'arbitrary-content')\n\n // check if setDragImage method is available\n if (event.dataTransfer.setDragImage) {\n event.dataTransfer.setDragImage(ghost.draggedItem, ghost.x, ghost.y)\n }\n}\n/**\n * _addGhostPos clones the dragged item and adds it as a Ghost item\n * @param {Event} event - the event fired when dragstart is triggered\n * @param {object} ghost - .draggedItem = Element\n */\nvar _addGhostPos = function (event, ghost) {\n if (!ghost.x) {\n ghost.x = parseInt(event.pageX - _offset(ghost.draggedItem).left)\n }\n if (!ghost.y) {\n ghost.y = parseInt(event.pageY - _offset(ghost.draggedItem).top)\n }\n return ghost\n}\n/**\n * _makeGhost decides which way to make a ghost and passes it to attachGhost\n * @param {Element} draggedItem - the item that the user drags\n */\nvar _makeGhost = function (draggedItem) {\n return {\n draggedItem: draggedItem\n }\n}\n/**\n * _getGhost constructs ghost and attaches it to dataTransfer\n * @param {Event} event - the original drag event object\n * @param {Element} draggedItem - the item that the user drags\n */\n// TODO: could draggedItem be replaced by event.target in all instances\nvar _getGhost = function (event, draggedItem) {\n // add ghost item & draggedItem to ghost object\n var ghost = _makeGhost(draggedItem)\n // attach ghost position\n ghost = _addGhostPos(event, ghost)\n // attach ghost to dataTransfer\n _attachGhost(event, ghost)\n}\n/**\n * _getDragging returns the current element to drag or\n * a copy of the element.\n * Is Copy Active for sortable\n * @param {Element} draggedItem - the item that the user drags\n * @param {Element} sortable a single sortable\n */\nvar _getDragging = function (draggedItem, sortable) {\n var ditem = draggedItem\n if (_isCopyActive(sortable)) {\n ditem = draggedItem.cloneNode(true)\n _attr(ditem, 'aria-copied', 'true')\n draggedItem.parentElement.appendChild(ditem)\n ditem.style.display = 'none'\n ditem.oldDisplay = draggedItem.style.display\n }\n return ditem\n}\n/**\n * Remove data from sortable\n * @param {Element} sortable a single sortable\n */\nvar _removeSortableData = function (sortable) {\n _removeData(sortable)\n _removeAttr(sortable, 'aria-dropeffect')\n}\n/**\n * Remove data from items\n * @param {Array|Element} items\n */\nvar _removeItemData = function (items) {\n _removeAttr(items, 'aria-grabbed')\n _removeAttr(items, 'aria-copied')\n _removeAttr(items, 'draggable')\n _removeAttr(items, 'role')\n}\n/**\n * Check if two lists are connected\n * @param {Element} curList\n * @param {Element} destList\n */\nvar _listsConnected = function (curList, destList) {\n if (_isSortable(curList)) {\n var acceptFrom = _data(curList, 'opts').acceptFrom\n if (acceptFrom !== null) {\n return acceptFrom !== false && acceptFrom.split(',').filter(function (sel) {\n return sel.length > 0 && destList.matches(sel)\n }).length > 0\n }\n if (curList === destList) {\n return true\n }\n if (_data(curList, 'connectWith') !== undefined) {\n return _data(curList, 'connectWith') === _data(destList, 'connectWith')\n }\n }\n return false\n}\n/**\n * Is Copy Active for sortable\n * @param {Element} sortable a single sortable\n */\nvar _isCopyActive = function (sortable) {\n return _data(sortable, 'opts').copy === true\n}\n/**\n * get handle or return item\n * @param {Array} items\n * @param {selector} handle\n */\nvar _getHandles = function (items, handle) {\n var result = []\n var handles\n if (!handle) {\n return items\n }\n for (var i = 0; i < items.length; ++i) {\n handles = items[i].querySelectorAll(handle)\n result = result.concat(Array.prototype.slice.call(handles))\n }\n return result\n}\n/**\n * Is {Element} a sortable.\n * @param {Element} sortable a single sortable\n */\nfunction _isSortable (element) {\n return element !== undefined && element != null && _data(element, 'opts') !== undefined\n}\n/**\n * find sortable from element. travels up parent element until found or null.\n * @param {Element} sortable a single sortable\n */\nfunction findSortable (element) {\n while ((element = element.parentElement) && !_isSortable(element));\n return element\n}\n/**\n * Dragging event is on the sortable element. finds the top child that\n * contains the element.\n * @param {Element} sortable a single sortable\n * @param {Element} element is that being dragged\n */\nfunction findDragElement (sortableElement, element) {\n var options = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, options.items)\n var itemlist = items.filter(function (ele) {\n return ele.contains(element)\n })\n\n return itemlist.length > 0 ? itemlist[0] : element\n}\n/**\n * Destroy the sortable\n * @param {Element} sortableElement a single sortable\n */\nvar _destroySortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts') || {}\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n // remove event handlers & data from sortable\n _removeSortableEvents(sortableElement)\n _removeSortableData(sortableElement)\n // remove event handlers & data from items\n _off(handles, 'mousedown')\n _removeItemEvents(items)\n _removeItemData(items)\n}\n/**\n * Enable the sortable\n * @param {Element} sortableElement a single sortable\n */\nvar _enableSortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n _attr(sortableElement, 'aria-dropeffect', 'move')\n _data(sortableElement, '_disabled', 'false')\n _attr(handles, 'draggable', 'true')\n // IE FIX for ghost\n // can be disabled as it has the side effect that other events\n // (e.g. click) will be ignored\n var spanEl = (document || window.document).createElement('span')\n if (typeof spanEl.dragDrop === 'function' && !opts.disableIEFix) {\n _on(handles, 'mousedown', function () {\n if (items.indexOf(this) !== -1) {\n this.dragDrop()\n } else {\n var parent = this.parentElement\n while (items.indexOf(parent) === -1) {\n parent = parent.parentElement\n }\n parent.dragDrop()\n }\n })\n }\n}\n/**\n * Disable the sortable\n * @param {Element} sortableElement a single sortable\n */\nvar _disableSortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n _attr(sortableElement, 'aria-dropeffect', 'none')\n _data(sortableElement, '_disabled', 'true')\n _attr(handles, 'draggable', 'false')\n _off(handles, 'mousedown')\n}\n/**\n * Reload the sortable\n * @param {Element} sortableElement a single sortable\n * @description events need to be removed to not be double bound\n */\nvar _reloadSortable = function (sortableElement) {\n var opts = _data(sortableElement, 'opts')\n var items = _filter(sortableElement.children, opts.items)\n var handles = _getHandles(items, opts.handle)\n _data(sortableElement, '_disabled', 'false')\n // remove event handlers from items\n _removeItemEvents(items)\n _off(handles, 'mousedown')\n // remove event handlers from sortable\n _removeSortableEvents(sortableElement)\n}\n\n/**\n * Public sortable object\n * @param {Array|NodeList} sortableElements\n * @param {object|string} options|method\n */\nexport default function sortable (sortableElements, options: object|string|undefined) {\n // get method string to see if a method is called\n var method = String(options)\n // merge user options with defaults\n options = Object.assign({\n connectWith: false,\n acceptFrom: null,\n copy: false,\n placeholder: null,\n disableIEFix: false,\n placeholderClass: 'sortable-placeholder',\n draggingClass: 'sortable-dragging',\n hoverClass: false,\n debounce: 0,\n maxItems: 0,\n itemSerializer: undefined,\n containerSerializer: undefined\n // if options is an object, merge it, otherwise use empty object\n }, (typeof options === 'object') ? options : {})\n // check if the user provided a selector instead of an element\n if (typeof sortableElements === 'string') {\n sortableElements = document.querySelectorAll(sortableElements)\n }\n // if the user provided an element, return it in an array to keep the return value consistant\n if (sortableElements instanceof Element) {\n sortableElements = [sortableElements]\n }\n\n sortableElements = Array.prototype.slice.call(sortableElements)\n\n if (/serialize/.test(method)) {\n return sortableElements.map((sortableContainer) => {\n let opts = _data(sortableContainer, 'opts')\n return _serialize(sortableContainer, opts.itemSerializer, opts.containerSerializer)\n })\n }\n\n sortableElements.forEach(function (sortableElement) {\n if (/enable|disable|destroy/.test(method)) {\n return sortable[method](sortableElement)\n }\n\n // get options & set options on sortable\n options = _data(sortableElement, 'opts') || options\n _data(sortableElement, 'opts', options)\n // property to define as sortable\n sortableElement.isSortable = true\n // reset sortable\n _reloadSortable(sortableElement)\n // initialize\n var items = _filter(sortableElement.children, options.items)\n var index\n var startList\n // create element if user defined a placeholder element as a string\n let customPlaceholder\n if (options.placeholder !== null && options.placeholder !== undefined) {\n let tempContainer = document.createElement(sortableElement.tagName)\n tempContainer.innerHTML = options.placeholder\n customPlaceholder = tempContainer.children[0]\n }\n let placeholder = _makePlaceholder(sortableElement, customPlaceholder, options.placeholderClass)\n\n _data(sortableElement, 'items', options.items)\n placeholderMap.set(sortableElement, placeholder)\n if (options.acceptFrom) {\n _data(sortableElement, 'acceptFrom', options.acceptFrom)\n } else if (options.connectWith) {\n _data(sortableElement, 'connectWith', options.connectWith)\n }\n\n _enableSortable(sortableElement)\n _attr(items, 'role', 'option')\n _attr(items, 'aria-grabbed', 'false')\n\n // Mouse over class\n if (typeof options.hoverClass === 'string') {\n let hoverClasses = options.hoverClass.split(' ')\n // add class on hover\n _on(items, 'mouseenter', function (e) {\n e.target.classList.add(...hoverClasses)\n })\n // remove class on leave\n _on(items, 'mouseleave', function (e) {\n e.target.classList.remove(...hoverClasses)\n })\n }\n\n // Handle drag events on draggable items\n // Handle set at sortableelement level as it will bubble up\n // from the item\n _on(sortableElement, 'dragstart', function (e) {\n // ignore dragstart events\n if (_isSortable(e.target)) {\n return\n }\n e.stopImmediatePropagation()\n\n if ((options.handle && !e.target.matches(options.handle)) || e.target.getAttribute('draggable') === 'false') {\n return\n }\n\n var sortableElement = findSortable(e.target)\n var dragitem = findDragElement(sortableElement, e.target)\n // add transparent clone or other ghost to cursor\n _getGhost(e, dragitem)\n // cache selsection & add attr for dragging\n draggingHeight = _getElementHeight(dragitem)\n dragitem.classList.add(options.draggingClass)\n dragging = _getDragging(dragitem, sortableElement)\n _attr(dragging, 'aria-grabbed', 'true')\n // grab values\n index = _index(dragging, dragging.parentElement.children)\n startParent = findSortable(e.target)\n startList = _serialize(startParent)\n // dispatch sortstart event on each element in group\n\n sortableElement.dispatchEvent(new CustomEvent('sortstart', {\n detail: {\n item: dragging,\n placeholder: placeholderMap.get(sortableElement),\n startparent: startParent\n }\n }))\n })\n // Handle drag events on draggable items\n _on(sortableElement, 'dragend', function (e) {\n var newParent\n if (!dragging) {\n return\n }\n var sortableElement = findSortable(e.target)\n // remove dragging attributes and show item\n dragging.classList.remove(options.draggingClass)\n _attr(dragging, 'aria-grabbed', 'false')\n\n if (dragging.getAttribute('aria-copied') === 'true' && _data(dragging, 'dropped') !== 'true') {\n dragging.remove()\n }\n\n dragging.style.display = dragging.oldDisplay\n delete dragging.oldDisplay\n\n placeholderMap.forEach((element) => element.remove())\n newParent = this.parentElement\n\n if (_listsConnected(newParent, startParent)) {\n sortableElement.dispatchEvent(new CustomEvent('sortstop', {\n detail: {\n item: dragging,\n startparent: startParent\n }\n }))\n if (index !== _index(dragging, dragging.parentElement.children) || startParent !== newParent) {\n sortableElement.dispatchEvent(new CustomEvent('sortupdate', {\n detail: {\n item: dragging,\n index: _filter(newParent.children, _data(newParent, 'items'))\n .indexOf(dragging),\n oldindex: items.indexOf(dragging),\n elementIndex: _index(dragging, dragging.parentElement.children),\n oldElementIndex: index,\n startparent: startParent,\n endparent: newParent,\n newEndList: _serialize(newParent),\n newStartList: _serialize(startParent),\n oldStartList: startList\n }\n }))\n }\n }\n dragging = null\n draggingHeight = null\n })\n // Handle drop event on sortable & placeholder\n _on(sortableElement, 'drop', function (e) {\n if (!_listsConnected(sortableElement, dragging.parentElement)) {\n return\n }\n e.preventDefault()\n e.stopPropagation()\n\n _data(dragging, 'dropped', 'true')\n var visiblePlaceholder = Array.from(placeholderMap.values()).filter(isInDom)[0]\n _after(visiblePlaceholder, dragging)\n // fire sortstop\n sortableElement.dispatchEvent(new CustomEvent('sortstop', {\n detail: {\n item: dragging,\n startparent: startParent\n }\n }))\n\n let newParent = _isSortable(this) ? this : this.parentElement\n // fire sortupdate if index or parent changed\n if (index !== _index(dragging, dragging.parentElement.children) || startParent !== newParent) {\n sortableElement.dispatchEvent(new CustomEvent('sortupdate', {\n detail: {\n item: dragging,\n index: _index(dragging, _filter(newParent.children, _data(newParent, 'items'))),\n oldindex: items.indexOf(dragging),\n elementIndex: _index(dragging, dragging.parentElement.children),\n oldElementIndex: index,\n startparent: startParent,\n endparent: newParent,\n newEndList: _serialize(newParent),\n newStartList: _serialize(startParent),\n oldStartList: startList\n }\n }))\n }\n })\n\n var debouncedDragOverEnter = _debounce((sortableElement, element, pageY) => {\n if (!dragging) {\n return\n }\n\n var placeholder = placeholderMap.get(sortableElement)\n // set placeholder height if forcePlaceholderSize option is set\n if (options.forcePlaceholderSize) {\n placeholder.style.height = draggingHeight + 'px'\n }\n // if element the draggedItem is dragged onto is within the array of all elements in list\n // (not only items, but also disabled, etc.)\n if (Array.from(sortableElement.children).indexOf(element) > -1) {\n let thisHeight = _getElementHeight(element)\n var placeholderIndex = _index(placeholder, element.parentElement.children)\n var thisIndex = _index(element, element.parentElement.children)\n // Check if `element` is bigger than the draggable. If it is, we have to define a dead zone to prevent flickering\n if (thisHeight > draggingHeight) {\n // Dead zone?\n var deadZone = thisHeight - draggingHeight\n var offsetTop = _offset(element).top\n if (placeholderIndex < thisIndex && pageY < offsetTop) {\n return\n }\n if (placeholderIndex > thisIndex &&\n pageY > offsetTop + thisHeight - deadZone) {\n return\n }\n }\n\n if (dragging.oldDisplay === undefined) {\n dragging.oldDisplay = dragging.style.display\n }\n\n if (dragging.style.display !== 'none') {\n dragging.style.display = 'none'\n }\n if (placeholderIndex < thisIndex) {\n _after(element, placeholder)\n } else {\n _before(element, placeholder)\n }\n // Intentionally violated chaining, it is more complex otherwise\n Array.from(placeholderMap.values())\n .filter(function (element) { return element !== placeholder })\n .forEach((element) => element.remove())\n } else {\n if (Array.from(placeholderMap.values()).indexOf(element) === -1 &&\n sortableElement === element &&\n !_filter(element.children, options.items).length) {\n placeholderMap.forEach((element) => element.remove())\n element.appendChild(placeholder)\n }\n }\n }, options.debounce)\n // Handle dragover and dragenter events on draggable items\n var onDragOverEnter = function (e) {\n var element = e.target\n var sortableElement = _isSortable(element) ? element : findSortable(element)\n element = findDragElement(sortableElement, element)\n if (!dragging || !_listsConnected(sortableElement, dragging.parentElement) || _data(sortableElement, '_disabled') === 'true') {\n return\n }\n var options = _data(sortableElement, 'opts')\n if (parseInt(options.maxItems) && _filter(sortableElement.children, _data(sortableElement, 'items')).length >= parseInt(options.maxItems)) {\n return\n }\n e.preventDefault()\n e.stopPropagation()\n e.dataTransfer.dropEffect = _isCopyActive(sortableElement) ? 'copy' : 'move'\n debouncedDragOverEnter(sortableElement, element, e.pageY)\n }\n\n _on(items.concat(sortableElement), 'dragover', onDragOverEnter)\n _on(items.concat(sortableElement), 'dragenter', onDragOverEnter)\n })\n\n return sortableElements\n}\n\nsortable.destroy = function (sortableElement) {\n _destroySortable(sortableElement)\n}\n\nsortable.enable = function (sortableElement) {\n _enableSortable(sortableElement)\n}\n\nsortable.disable = function (sortableElement) {\n _disableSortable(sortableElement)\n}\n\n/* START.TESTS_ONLY */\nsortable.__testing = {\n // add internal methods here for testing purposes\n _data: _data,\n _removeSortableEvents: _removeSortableEvents,\n _removeItemEvents: _removeItemEvents,\n _removeItemData: _removeItemData,\n _removeSortableData: _removeSortableData,\n _listsConnected: _listsConnected,\n _attachGhost: _attachGhost,\n _addGhostPos: _addGhostPos,\n _getGhost: _getGhost,\n _getHandles: _getHandles,\n _makeGhost: _makeGhost,\n _index: _index,\n _getPlaceholders: () => placeholderMap,\n _resetPlaceholders: () => {\n placeholderMap.clear()\n }\n}\n/* END.TESTS_ONLY */\n","/* eslint-env browser */\nimport {addData as _data} from './data' // yuk, data really needs to be refactored\nimport filter from './filter'\nimport index from './index'\n/**\n * Filter only wanted nodes\n * @param {Element} sortableContainer\n * @param {Function} customSerializer\n * @returns {Array}\n */\nexport default (sortableContainer: Element, customItemSerializer: Function = (serializedItem: object, sortableContainer: Element) => serializedItem, customContainerSerializer: Function = (serializedContainer: object) => serializedContainer): object => {\n // check for valid sortableContainer\n if (!(sortableContainer instanceof Element) || !sortableContainer.isSortable === true) {\n throw new Error('You need to provide a sortableContainer to be serialized.')\n }\n // check for valid serializers\n if (typeof customItemSerializer !== 'function' || typeof customContainerSerializer !== 'function') {\n throw new Error('You need to provide a valid serializer for items and the container.')\n }\n // get options\n let options = _data(sortableContainer, 'opts')\n // serialize container\n let items = filter(sortableContainer.children, options.items)\n items = items.map((item) => {\n return {\n parent: sortableContainer,\n node: item,\n html: item.outerHTML,\n index: index(item, items)\n }\n })\n // serialize container\n let container = {\n node: sortableContainer,\n itemCount: items.length\n }\n\n return {\n container: customContainerSerializer(container),\n items: items.map((item: object) => customItemSerializer(item, sortableContainer))\n }\n}\n","/* eslint-env browser */\n/**\n * Get height of an element including padding\n * @param {Element} element an dom element\n */\nexport default element => {\n if (!(element instanceof Element)) {\n throw new Error('You must provide a valid dom element')\n }\n // get calculated style of element\n let style = window.getComputedStyle(element)\n // pick applicable properties, convert to int and reduce by adding\n return ['height', 'padding-top', 'padding-bottom']\n .map((key) => {\n let int = parseInt(style.getPropertyValue(key), 10)\n return isNaN(int) ? 0 : int\n })\n .reduce((sum, value) => sum + value)\n}\n","/* eslint-env browser */\n/**\n * create a placeholder element\n * @param {Elememnt} sortableElement a single sortable\n * @param {string|undefine} placeholder a string representing an html element\n * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder\n */\nexport default (sortableElement: Element, placeholder: Element | undefined, placeholderClass: string = 'sortable-placeholder') => {\n if (!(sortableElement instanceof Element)) {\n throw new Error('You must provide a valid element as a sortable.')\n }\n // if placeholder is not an element\n if (!(placeholder instanceof Element) && placeholder !== undefined) {\n throw new Error('You must provide a valid element as a placeholder or set ot to undefined.')\n }\n // if no placeholder element is given\n if (placeholder === undefined) {\n if (['UL', 'OL'].includes(sortableElement.tagName)) {\n placeholder = document.createElement('li')\n } else if (['TABLE', 'TBODY'].includes(sortableElement.tagName)) {\n placeholder = document.createElement('tr')\n // set colspan to always all rows, otherwise the item can only be dropped in first column\n placeholder.innerHTML = ''\n } else {\n placeholder = document.createElement('div')\n }\n }\n // add classes to placeholder\n if (typeof placeholderClass === 'string') {\n placeholder.classList.add(...placeholderClass.split(' '))\n }\n\n return placeholder\n}\n","/**\n * Creates and returns a new debounced version of the passed function which will postpone its execution until after wait milliseconds have elapsed\n * @param {func} Function to debounce\n * @param {wait} time to wait before calling function with latest arguments, 0 - no debounce\n * @returns {function} - debounced function\n */\nexport default (func: Function, wait: number = 0): Function => {\n let timeout\n\n return (...args) => {\n clearTimeout(timeout)\n timeout = setTimeout(() => {\n func(...args)\n }, wait)\n }\n}\n"],"names":["element","key","value","undefined","h5s","data","nodes","selector","NodeList","HTMLCollection","Error","Array","from","filter","item","nodeType","matches","event","callback","i","length","addEventListener","events","removeEventListener","attribute","addAttribute","setAttribute","removeAttribute","parentElement","rect","getClientRects","left","window","scrollX","right","top","scrollY","bottom","elementList","Element","indexOf","parentNode","dragging","draggingHeight","insertNode","referenceNode","newElement","position","insertBefore","nextElementSibling","target","insertAfter","sortableContainer","customItemSerializer","customContainerSerializer","serializedItem","serializedContainer","isSortable","options","_data","items","children","map","parent","node","html","outerHTML","index","container","itemCount","style","getComputedStyle","int","parseInt","getPropertyValue","isNaN","reduce","sum","startParent","placeholderMap","Map","_removeItemEvents","_off","_removeSortableEvents","sortable","_getGhost","draggedItem","ghost","_makeGhost","dataTransfer","effectAllowed","setData","setDragImage","x","y","_attachGhost","pageX","_offset","pageY","_addGhostPos","_getDragging","ditem","_isCopyActive","_attr","cloneNode","appendChild","display","oldDisplay","_listsConnected","curList","destList","_isSortable","acceptFrom","split","sel","copy","_getHandles","handle","handles","result","querySelectorAll","concat","prototype","slice","call","sortableElement","itemlist","_filter","ele","contains","_destroySortable","opts","_removeAttr","_removeItemData","_enableSortable","document","createElement","dragDrop","disableIEFix","_on","this","_reloadSortable","sortableElements","method","String","Object","assign","connectWith","placeholder","placeholderClass","draggingClass","hoverClass","debounce","maxItems","itemSerializer","containerSerializer","test","_serialize","forEach","startList","customPlaceholder","tempContainer","tagName","innerHTML","includes","classList","add","_makePlaceholder","set","hoverClasses_1","e","remove","stopImmediatePropagation","getAttribute","findSortable","dragitem","findDragElement","_getElementHeight","_index","dispatchEvent","CustomEvent","detail","get","startparent","newParent","oldindex","elementIndex","oldElementIndex","endparent","newEndList","newStartList","oldStartList","preventDefault","stopPropagation","visiblePlaceholder","values","isInDom","_after","func","wait","timeout","debouncedDragOverEnter","forcePlaceholderSize","height","thisHeight","placeholderIndex","thisIndex","deadZone","offsetTop","_before","_i","args","clearTimeout","setTimeout","onDragOverEnter","dropEffect","destroy","enable","disable","_disableSortable"],"mappings":"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"} \ No newline at end of file diff --git a/docs/html5sortable.js b/docs/html5sortable.js index e5920cc3..e9e1c665 100644 --- a/docs/html5sortable.js +++ b/docs/html5sortable.js @@ -144,7 +144,7 @@ function index (element, elementList) { } function isInDom (element) { - if (!element || element.nodeType !== 1) { + if (!(element instanceof Element)) { throw new Error('Element is not a node element.'); } return element.parentNode !== null; @@ -210,6 +210,52 @@ function _serialize (sortableContainer, customItemSerializer, customContainerSer }; } +function _makePlaceholder (sortableElement, placeholder, placeholderClass) { + if (placeholderClass === void 0) { placeholderClass = 'sortable-placeholder'; } + if (!(sortableElement instanceof Element)) { + throw new Error('You must provide a valid element as a sortable.'); + } + // if placeholder is not an element + if (!(placeholder instanceof Element) && placeholder !== undefined) { + throw new Error('You must provide a valid element as a placeholder or set ot to undefined.'); + } + // if no placeholder element is given + if (placeholder === undefined) { + if (['UL', 'OL'].includes(sortableElement.tagName)) { + placeholder = document.createElement('li'); + } + else if (['TABLE', 'TBODY'].includes(sortableElement.tagName)) { + placeholder = document.createElement('tr'); + // set colspan to always all rows, otherwise the item can only be dropped in first column + placeholder.innerHTML = ''; + } + else { + placeholder = document.createElement('div'); + } + } + // add classes to placeholder + if (typeof placeholderClass === 'string') { + (_a = placeholder.classList).add.apply(_a, placeholderClass.split(' ')); + } + return placeholder; + var _a; +} + +function _getElementHeight (element) { + if (!(element instanceof Element)) { + throw new Error('You must provide a valid dom element'); + } + // get calculated style of element + var style = window.getComputedStyle(element); + // pick applicable properties, convert to int and reduce by adding + return ['height', 'padding-top', 'padding-bottom'] + .map(function (key) { + var int = parseInt(style.getPropertyValue(key), 10); + return isNaN(int) ? 0 : int; + }) + .reduce(function (sum, value) { return sum + value; }); +} + /* eslint-env browser */ /* * variables global to the plugin @@ -241,45 +287,6 @@ var _removeSortableEvents = function (sortable) { removeEventListener(sortable, 'dragenter'); removeEventListener(sortable, 'drop'); }; -/** - * create a placeholder element - * @param {Elememnt} sortableElement a single sortable - * @param {string|undefine} placeholder a string representing an html element - * @param {string} placeholderClasses a string representing the classes that should be added to the placeholder - */ -var _makePlaceholder = function (sortableElement, placeholder, placeholderClasses) { - if (placeholder === void 0) { placeholder = undefined; } - if (placeholderClasses === void 0) { placeholderClasses = 'sortable-placeholder'; } - if (typeof placeholder === 'string') { - var tempContainer = document.createElement(sortableElement.tagName); - tempContainer.innerHTML = placeholder; - placeholder = tempContainer.children[0]; - } - else { - switch (sortableElement.tagName) { - case 'UL': - placeholder = document.createElement('li'); - break; - case 'OL': - placeholder = document.createElement('li'); - break; - case 'TABLE': - placeholder = 'tr'; - placeholder.innerHTML = ''; - break; - case 'TBODY': - placeholder = document.createElement('tr'); - placeholder.innerHTML = ''; - break; - default: - placeholder = document.createElement('div'); - } - } - // add classes to placeholder - (_a = placeholder.classList).add.apply(_a, placeholderClasses.split(' ')); - return placeholder; - var _a; -}; /** * Attach ghost to dataTransfer object * @param {Event} original event @@ -398,21 +405,6 @@ var _listsConnected = function (curList, destList) { var _isCopyActive = function (sortable) { return addData(sortable, 'opts').copy === true; }; -/** - * Get height of an element including padding - * @param {Element} sortable a single sortable - */ -var _getElementHeight = function (element) { - // get calculated style of element - var style = window.getComputedStyle(element); - // pick applicable properties, convert to int and reduce by adding - return ['height', 'padding-top', 'padding-bottom'] - .map(function (key) { - var int = parseInt(style.getPropertyValue(key), 10); - return isNaN(int) ? 0 : int; - }) - .reduce(function (prev, cur) { return prev + cur; }); -}; /** * get handle or return item * @param {Array} items @@ -541,32 +533,28 @@ var _reloadSortable = function (sortableElement) { * @param {object|string} options|method */ function sortable(sortableElements, options) { + // get method string to see if a method is called var method = String(options); - options = (function (options) { - var result = { - connectWith: false, - acceptFrom: null, - copy: false, - placeholder: null, - disableIEFix: false, - placeholderClass: 'sortable-placeholder', - draggingClass: 'sortable-dragging', - hoverClass: false, - debounce: 0, - maxItems: 0, - itemSerializer: undefined, - containerSerializer: undefined - }; - if (typeof options === 'object') { - for (var option in options) { - result[option] = options[option]; - } - } - return result; - })(options); + // merge user options with defaults + options = Object.assign({ + connectWith: false, + acceptFrom: null, + copy: false, + placeholder: null, + disableIEFix: false, + placeholderClass: 'sortable-placeholder', + draggingClass: 'sortable-dragging', + hoverClass: false, + debounce: 0, + maxItems: 0, + itemSerializer: undefined, + containerSerializer: undefined + }, (typeof options === 'object') ? options : {}); + // check if the user provided a selector instead of an element if (typeof sortableElements === 'string') { sortableElements = document.querySelectorAll(sortableElements); } + // if the user provided an element, return it in an array to keep the return value consistant if (sortableElements instanceof Element) { sortableElements = [sortableElements]; } @@ -592,7 +580,14 @@ function sortable(sortableElements, options) { var items = filter(sortableElement.children, options.items); var index$$1; var startList; - var placeholder = _makePlaceholder(sortableElement, options.placeholder, options.placeholderClass); + // create element if user defined a placeholder element as a string + var customPlaceholder; + if (options.placeholder !== null && options.placeholder !== undefined) { + var tempContainer = document.createElement(sortableElement.tagName); + tempContainer.innerHTML = options.placeholder; + customPlaceholder = tempContainer.children[0]; + } + var placeholder = _makePlaceholder(sortableElement, customPlaceholder, options.placeholderClass); addData(sortableElement, 'items', options.items); placeholderMap.set(sortableElement, placeholder); if (options.acceptFrom) { @@ -753,8 +748,7 @@ function sortable(sortableElements, options) { // Dead zone? var deadZone = thisHeight - draggingHeight; var offsetTop = _offset(element).top; - if (placeholderIndex < thisIndex && - pageY < offsetTop + deadZone) { + if (placeholderIndex < thisIndex && pageY < offsetTop) { return; } if (placeholderIndex > thisIndex && diff --git a/package.json b/package.json index e596cb65..82ff6b9b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "main": "dist/html5sortable.js", "file": "src/html5sortable.ts", "dist": "dist", - "version": "0.8.0", + "version": "0.8.1", "license": "MIT", "description": "VanillaJS sortable lists and grids using native HTML5 drag and drop API.", "author": {