Socket
Socket
Sign inDemoInstall

nested-sort

Package Overview
Dependencies
0
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.0.0 to 5.0.1

8

dist/data-engine.d.ts

@@ -1,2 +0,2 @@

import { DataEngineOptions, DataItem, ListElement, PropertyMap } from './types';
import { DataEngineOptions, DataItem, ListElement, MappedDataItem, PropertyMap } from './types';
declare class DataEngine {

@@ -19,8 +19,8 @@ data: Array<DataItem>;

elementIsAncestorOfItem(node: HTMLElement, item: DataItem): boolean;
getDirectListParentOfItem(node: HTMLElement, item: DataItem): HTMLElement;
getDirectListParentOfItem(node: HTMLElement, item: DataItem): HTMLElement | null;
maybeAppendItemToParentDom(item: DataItem): boolean;
getListItemsDom(): Array<HTMLElement>;
convertDomToData(list: ListElement): Array<Record<string, unknown>>;
render(): ListElement;
convertDomToData(list: ListElement): Array<MappedDataItem>;
render(): Node;
}
export default DataEngine;
import DataEngine from './data-engine';
import { Actions, ClassNames, ClassNamesList, Cursor, DataItem, Dimensions, Distances, DropLocation, EventListeners, ListElement, ListInterface, ListTagName, Options, PlaceholderMaintenanceActions, PropertyMap, TargetNode } from './types';
import { Actions, ClassNames, ClassNamesList, Cursor, DataItem, Distances, DropLocation, EventListeners, ListElement, ListInterface, ListTagName, Options, PlaceholderMaintenanceActions, PropertyMap, TargetNode } from './types';
declare class NestedSort {
actions: Actions;
classNames: ClassNames;
cursor: Cursor;
data: Array<DataItem>;
dataEngine: DataEngine;
draggedNode: HTMLElement;
distances: Partial<Distances>;
draggedNode?: HTMLElement;
initialised: boolean;
listClassNames: Array<string>;
listEventListeners: EventListeners;
listInterface: ListInterface;
listItemClassNames: Array<string>;
mainListClassName: string;
nestingLevels: number;
placeholderList: HTMLElement;
placeholderInUse: HTMLElement;
propertyMap: Partial<PropertyMap>;
el: HTMLElement;
selector: string;
sortableList: ListElement;
targetedNode: HTMLElement;
targetedNode?: HTMLElement;
targetNode: TargetNode;
distances: Distances;
dimensions: Dimensions;
cursor: Cursor;
classNames: ClassNames;
listEventListeners: EventListeners;
nestingLevels: number;
listInterface: ListInterface;
wrapper?: Element;
constructor({ actions, data, droppingEdge, el, init, listClassNames, listItemClassNames, nestingLevels, propertyMap, }: Options);

@@ -41,3 +39,3 @@ getListInterface(): ListInterface;

destroy(): void;
removeClassFromEl(el: HTMLElement, className: string): void;
removeClassFromEl(className: string, el?: HTMLElement): void;
canBeTargeted(el: HTMLElement): boolean;

@@ -50,3 +48,3 @@ onDragStart(e: DragEvent): void;

updateCoordination(e: DragEvent): void;
getDropLocation(): DropLocation;
getDropLocation(): DropLocation | undefined;
maybeDrop(): void;

@@ -56,3 +54,3 @@ dropTheItem(place: DropLocation): void;

calcMouseToTargetedElDist(): void;
areNested(child: HTMLElement, parent: HTMLElement): boolean;
areNested(child: HTMLElement | undefined, parent: HTMLElement | undefined): boolean;
cursorIsIndentedEnough(): boolean;

@@ -59,0 +57,0 @@ mouseIsTooCloseToTop(): boolean;

'use strict';
class DataEngine {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var DataEngine = /*#__PURE__*/function () {
/**
* @constructor
* @param {object[]} [data]
* @param {object} [propertyMap={}]
*/
constructor({ data, propertyMap = {} }) {
function DataEngine(_ref) {
var data = _ref.data,
_ref$propertyMap = _ref.propertyMap,
propertyMap = _ref$propertyMap === void 0 ? {} : _ref$propertyMap;
_classCallCheck(this, DataEngine);
_defineProperty(this, "data", void 0);
_defineProperty(this, "sortedData", void 0);
_defineProperty(this, "sortedDataDomArray", void 0);
_defineProperty(this, "propertyMap", void 0);
this.data = data;

@@ -14,48 +96,47 @@ this.sortedData = [];

this.propertyMap = propertyMap;
this.maybeTransformData();
}
maybeTransformData() {
if (!Object.keys(this.propertyMap).length || !Array.isArray(this.data)) return
_createClass(DataEngine, [{
key: "maybeTransformData",
value: function maybeTransformData() {
if (!Object.keys(this.propertyMap).length || !Array.isArray(this.data)) return;
var getItemPropProxyName = this.getItemPropProxyName.bind(this);
this.data = this.data.map(function (item) {
return new Proxy(item, {
get: function get(target, prop, receiver) {
return Reflect.get(target, getItemPropProxyName(prop), receiver);
}
});
});
}
}, {
key: "getItemPropProxyName",
value: function getItemPropProxyName(prop) {
if (Object.prototype.hasOwnProperty.call(this.propertyMap, prop)) {
return this.propertyMap[prop];
}
const getItemPropProxyName = this.getItemPropProxyName.bind(this);
this.data = this.data.map(item => {
return new Proxy(item, {
get(target, prop, receiver) {
return Reflect.get(target, getItemPropProxyName(prop), receiver)
},
})
});
}
/**
* @param {PropertyKey} prop
* @returns {PropertyKey}
*/
getItemPropProxyName(prop) {
if (Object.prototype.hasOwnProperty.call(this.propertyMap, prop)) {
return this.propertyMap[prop]
return prop;
}
return prop
}
}, {
key: "isTopLevelItem",
value: function isTopLevelItem(item) {
return !item.parent;
}
}, {
key: "sortListItems",
value: function sortListItems() {
var _this = this;
isTopLevelItem(item) {
return !item.parent
}
var items = _toConsumableArray(this.data);
/**
* @returns {object[]}
*/
sortListItems() {
const items = [...this.data];
const topLevelItems = items
.filter(a => this.isTopLevelItem(a))
.sort((a, b) => a.order && b.order ? a.order - b.order : 0);
const childItems = items
.filter(a => !this.isTopLevelItem(a))
.reduce((groups, item) => {
var topLevelItems = items.filter(function (a) {
return _this.isTopLevelItem(a);
}).sort(function (a, b) {
return a.order && b.order ? a.order - b.order : 0;
});
var childItems = items.filter(function (a) {
return !_this.isTopLevelItem(a);
}).reduce(function (groups, item) {
if (Object.prototype.hasOwnProperty.call(groups, item.parent)) {

@@ -66,184 +147,195 @@ groups[item.parent].push(item);

}
return groups
return groups;
}, {});
Object.keys(childItems).forEach(function (parentId) {
childItems[parentId].sort(function (a, b) {
return a.order && b.order ? a.order - b.order : 0;
});
});
this.sortedData = [].concat(_toConsumableArray(topLevelItems), _toConsumableArray(Object.values(childItems).flat()));
return this.sortedData;
}
}, {
key: "createItemElement",
value: function createItemElement(item) {
var nodeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'li';
var id = item.id,
text = item.text;
var el = document.createElement(nodeName);
el.dataset.id = id;
if (nodeName === 'li' && text) el.innerHTML = text;
return el;
}
}, {
key: "elementIsParentOfItem",
value: function elementIsParentOfItem(node, item) {
return node.dataset.id === "".concat(item.parent);
}
}, {
key: "getParentNodeOfItem",
value: function getParentNodeOfItem(node, item, nodeName) {
return node.querySelector("".concat(nodeName, "[data-id=\"").concat(item.parent, "\"]"));
}
}, {
key: "elementIsAncestorOfItem",
value: function elementIsAncestorOfItem(node, item) {
return !!this.getParentNodeOfItem(node, item, 'li');
}
}, {
key: "getDirectListParentOfItem",
value: function getDirectListParentOfItem(node, item) {
return this.getParentNodeOfItem(node, item, 'ol');
}
}, {
key: "maybeAppendItemToParentDom",
value: function maybeAppendItemToParentDom(item) {
var _this2 = this;
Object.keys(childItems).forEach(parentId => {
childItems[parentId].sort((a, b) => a.order && b.order ? a.order - b.order : 0);
});
var parent = item.parent;
var topParent = this.sortedDataDomArray.find(function (topLevelListItem) {
return _this2.elementIsParentOfItem(topLevelListItem, item) || _this2.elementIsAncestorOfItem(topLevelListItem, item);
});
if (!topParent) return false;
var listItem = this.createItemElement(item);
var directParentList = this.getDirectListParentOfItem(topParent, item);
this.sortedData = [
...topLevelItems,
...Object.values(childItems).flat(),
];
if (!directParentList) {
// we need to create the direct parent OL and append it to the direct parent LI
directParentList = this.createItemElement({
id: parent
}, 'ol');
var directParentListItem = this.getParentNodeOfItem(topParent, item, 'li') || topParent;
directParentListItem.appendChild(directParentList);
}
return this.sortedData
}
directParentList.appendChild(listItem);
return true;
}
}, {
key: "getListItemsDom",
value: function getListItemsDom() {
var _this3 = this;
/**
* @param {object[]} item
* @param {string} nodeName
* @returns {HTMLElement}
*/
createItemElement(item, nodeName = 'li') {
const { id, text } = item;
const el = document.createElement(nodeName);
el.dataset.id = id;
if (nodeName === 'li') el.innerHTML = text;
this.sortedDataDomArray = [];
var processedItems = [];
return el
}
while (processedItems.length !== this.sortListItems().length) {
processedItems = this.sortedData.reduce(function (processedItems, item) {
var id = item.id.toString();
if (processedItems.includes(id)) return processedItems;
var itemAdded;
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {boolean}
*/
elementIsParentOfItem(node, item) {
return node.dataset.id === `${item.parent}`
}
if (!item.parent) {
var listItem = _this3.createItemElement(item);
/**
* @param {HTMLElement} node
* @param {object} item
* @param {string} nodeName
* @returns {Element|null}
*/
getParentNodeOfItem(node, item, nodeName) {
return node.querySelector(`${nodeName}[data-id="${item.parent}"]`)
}
_this3.sortedDataDomArray.push(listItem);
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {boolean}
*/
elementIsAncestorOfItem(node, item) {
return !!this.getParentNodeOfItem(node, item, 'li')
}
itemAdded = true;
} else {
itemAdded = _this3.maybeAppendItemToParentDom(item);
}
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {HTMLElement}
*/
getDirectListParentOfItem(node, item) {
return this.getParentNodeOfItem(node, item, 'ol')
}
if (itemAdded) processedItems.push(id);
return processedItems;
}, processedItems);
}
/**
* @param {object} item
* @returns {boolean}
*/
maybeAppendItemToParentDom(item) {
const { parent } = item;
const topParent = this.sortedDataDomArray.find(topLevelListItem => {
return this.elementIsParentOfItem(topLevelListItem, item) || this.elementIsAncestorOfItem(topLevelListItem, item)
});
return this.sortedDataDomArray;
}
}, {
key: "convertDomToData",
value: function convertDomToData(list) {
var _this4 = this;
if (!topParent) return false
return Array.from((list === null || list === void 0 ? void 0 : list.querySelectorAll('li')) || []).map(function (li) {
var _ref2;
const listItem = this.createItemElement(item);
let directParentList = this.getDirectListParentOfItem(topParent, item);
if (!directParentList) {
// we need to create the direct parent OL and append it to the direct parent LI
directParentList = this.createItemElement({ id: parent }, 'ol');
const directParentListItem = this.getParentNodeOfItem(topParent, item, 'li') || topParent;
directParentListItem.appendChild(directParentList);
var parentListItem = li.parentNode;
var parent = parentListItem.dataset.id;
var order = Array.from(parentListItem.children).findIndex(function (item) {
return item === li;
}) + 1;
return _ref2 = {}, _defineProperty(_ref2, _this4.getItemPropProxyName('id'), li.dataset.id), _defineProperty(_ref2, _this4.getItemPropProxyName('parent'), parent), _defineProperty(_ref2, _this4.getItemPropProxyName('order'), order), _ref2;
});
}
}, {
key: "render",
value: function render() {
var list = document.createElement('ol');
this.getListItemsDom().forEach(function (listItem) {
return list.appendChild(listItem);
});
return list;
}
}]);
directParentList.appendChild(listItem);
return DataEngine;
}();
return true
}
var NestedSort = /*#__PURE__*/function () {
function NestedSort(_ref) {
var _ref$actions = _ref.actions,
actions = _ref$actions === void 0 ? {} : _ref$actions,
data = _ref.data,
_ref$droppingEdge = _ref.droppingEdge,
droppingEdge = _ref$droppingEdge === void 0 ? 15 : _ref$droppingEdge,
el = _ref.el,
_ref$init = _ref.init,
init = _ref$init === void 0 ? true : _ref$init,
listClassNames = _ref.listClassNames,
listItemClassNames = _ref.listItemClassNames,
nestingLevels = _ref.nestingLevels,
_ref$propertyMap = _ref.propertyMap,
propertyMap = _ref$propertyMap === void 0 ? {} : _ref$propertyMap;
/**
* @returns {array}
*/
getListItemsDom() {
this.sortedDataDomArray = [];
let processedItems = [];
_classCallCheck(this, NestedSort);
while (processedItems.length !== this.sortListItems().length) {
processedItems = this.sortedData.reduce((processedItems, item) => {
const { id } = item;
if (processedItems.includes(id)) return processedItems
_defineProperty(this, "actions", void 0);
let itemAdded;
if (!item.parent) {
const listItem = this.createItemElement(item);
this.sortedDataDomArray.push(listItem);
itemAdded = true;
} else {
itemAdded = this.maybeAppendItemToParentDom(item);
}
_defineProperty(this, "classNames", void 0);
if (itemAdded) processedItems.push(id);
_defineProperty(this, "cursor", void 0);
return processedItems
}, processedItems);
}
_defineProperty(this, "data", void 0);
return this.sortedDataDomArray
}
_defineProperty(this, "dataEngine", void 0);
/**
* @param {HTMLOListElement|HTMLUListElement} list
* @returns {object[]}
*/
convertDomToData(list) {
return Array.from(list.querySelectorAll('li')).map(li => {
const parentListItem = li.parentNode;
const parent = parentListItem.dataset.id;
const order = Array.from(parentListItem.children).findIndex(item => item === li) + 1;
_defineProperty(this, "distances", void 0);
return {
[this.getItemPropProxyName('id')]: li.dataset.id,
[this.getItemPropProxyName('parent')]: parent,
[this.getItemPropProxyName('order')]: order,
}
})
}
_defineProperty(this, "draggedNode", void 0);
/**
* @returns {HTMLOListElement}
*/
render() {
const list = document.createElement('ol');
this.getListItemsDom().forEach(listItem => list.appendChild(listItem));
return list
}
}
_defineProperty(this, "initialised", void 0);
class NestedSort {
/**
* @constructor
* @param {object} [actions={}]
* @param {array} [data]
* @param {number} [droppingEdge=15]
* @param {string|HTMLElement} el
* @param {boolean} [init=true]
* @param {array|string} [listClassNames]
* @param {array|string} [listItemClassNames]
* @param {number|string} [nestingLevels]
* @param {object} [propertyMap={}]
*/
constructor({
actions: { onDrop } = {},
data,
droppingEdge = 15,
el,
init = true,
listClassNames,
listItemClassNames,
nestingLevels,
propertyMap = {},
}) {
_defineProperty(this, "listClassNames", void 0);
_defineProperty(this, "listEventListeners", void 0);
_defineProperty(this, "listInterface", void 0);
_defineProperty(this, "listItemClassNames", void 0);
_defineProperty(this, "mainListClassName", void 0);
_defineProperty(this, "nestingLevels", void 0);
_defineProperty(this, "placeholderList", void 0);
_defineProperty(this, "placeholderInUse", void 0);
_defineProperty(this, "propertyMap", void 0);
_defineProperty(this, "sortableList", void 0);
_defineProperty(this, "targetedNode", void 0);
_defineProperty(this, "targetNode", void 0);
_defineProperty(this, "wrapper", void 0);
var element = typeof el === 'string' ? document.querySelector(el) : el;
var elementIsAList = element instanceof HTMLOListElement || element instanceof HTMLUListElement;
this.wrapper = elementIsAList ? undefined : element;
this.sortableList = elementIsAList ? element : null;
this.data = data;
this.selector = el;
this.sortableList = null;
this.placeholderList = null;
this.placeholderInUse = null;
this.draggedNode = null;
this.targetedNode = null;
this.listClassNames = this.createListClassNamesArray(listClassNames);

@@ -254,29 +346,12 @@ this.mainListClassName = this.listClassNames[0] || 'nested-sort';

this.actions = {
onDrop,
onDrop: actions.onDrop
};
this.initialised = false;
this.targetNode = {
X: null,
Y: null,
};
this.distances = {
droppingEdge,
droppingEdgeNegative: droppingEdge * -1,
mouseTo: {
targetedElTop: undefined,
},
droppingEdge: droppingEdge
};
this.dimensions = {
targetedEl: {
H: undefined,
},
};
this.cursor = {
X: null,
Y: null,
};
this.classNames = {
dragged: 'ns-dragged',
placeholder: 'ns-placeholder',
targeted: 'ns-targeted',
targeted: 'ns-targeted'
};

@@ -288,8 +363,8 @@ this.listEventListeners = {

dragend: this.onDragEnd.bind(this),
drop: this.onDrop.bind(this),
drop: this.onDrop.bind(this)
};
const intNestingLevels = parseInt(nestingLevels);
var intNestingLevels = parseInt(nestingLevels);
this.nestingLevels = isNaN(intNestingLevels) ? -1 : intNestingLevels; // values less than 0 mean infinite levels of nesting
this.listInterface = this.getListInterface();
this.maybeInitDataDom();

@@ -300,344 +375,411 @@ this.addListAttributes();

getListInterface() {
if (Array.isArray(this.data) && this.data.length) return HTMLOListElement
_createClass(NestedSort, [{
key: "getListInterface",
value: function getListInterface() {
if (Array.isArray(this.data) && this.data.length) return HTMLOListElement;
return this.sortableList instanceof HTMLOListElement ? HTMLOListElement : HTMLUListElement;
}
}, {
key: "getDataEngine",
value: function getDataEngine() {
if (this.dataEngine) return this.dataEngine;
this.dataEngine = new DataEngine({
data: this.data,
propertyMap: this.propertyMap
});
return this.dataEngine;
}
}, {
key: "createListClassNamesArray",
value: function createListClassNamesArray(listClassNames) {
if (!listClassNames) return [];
return Array.isArray(listClassNames) ? listClassNames : listClassNames.split(' ');
}
}, {
key: "maybeInitDataDom",
value: function maybeInitDataDom() {
if (!(Array.isArray(this.data) && this.data.length && this.wrapper)) return;
var list = this.getDataEngine().render();
this.wrapper.innerHTML = '';
this.wrapper.appendChild(list);
}
}, {
key: "getListTagName",
value: function getListTagName() {
return this.listInterface === HTMLOListElement ? 'ol' : 'ul';
}
}, {
key: "getSortableList",
value: function getSortableList() {
var _this$wrapper;
const el = this.selector instanceof HTMLElement
? this.selector
: document.querySelector(this.selector);
return el instanceof HTMLOListElement ? HTMLOListElement : HTMLUListElement
}
getDataEngine() {
if (this.dataEngine instanceof DataEngine) {
return this.dataEngine
if (this.sortableList instanceof this.listInterface) return this.sortableList;
this.sortableList = (_this$wrapper = this.wrapper) === null || _this$wrapper === void 0 ? void 0 : _this$wrapper.querySelector(this.getListTagName());
return this.sortableList;
}
this.dataEngine = new DataEngine({data: this.data, propertyMap: this.propertyMap});
return this.dataEngine
}
}, {
key: "addListAttributes",
value: function addListAttributes() {
var _list$classList,
_this = this;
createListClassNamesArray(listClassNames) {
if (!listClassNames) return []
return Array.isArray(listClassNames) ? listClassNames : listClassNames.split(' ')
}
var list = this.getSortableList();
if (!list) return;
maybeInitDataDom() {
if (!(Array.isArray(this.data) && this.data.length)) return
(_list$classList = list.classList).add.apply(_list$classList, _toConsumableArray(this.listClassNames.concat(this.mainListClassName)));
const wrapper = document.querySelector(this.selector);
const list = this.getDataEngine().render();
wrapper.innerHTML = '';
wrapper.appendChild(list);
}
list.querySelectorAll(this.getListTagName()).forEach(function (l) {
var _l$classList;
getListTagName() {
return this.listInterface === HTMLOListElement ? 'ol' : 'ul'
}
(_l$classList = l.classList).add.apply(_l$classList, _toConsumableArray(_this.listClassNames));
});
list.querySelectorAll('li').forEach(function (li) {
var _li$classList;
getSortableList() {
if (this.sortableList instanceof this.listInterface) return this.sortableList
(_li$classList = li.classList).add.apply(_li$classList, _toConsumableArray(_this.listItemClassNames));
});
}
}, {
key: "toggleMainListLifeCycleClassName",
value: function toggleMainListLifeCycleClassName() {
var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var list = this.getSortableList();
if (!list) return;
var className = "".concat(this.mainListClassName, "--enabled");
enabled ? list.classList.add(className) : list.classList.remove(className);
}
}, {
key: "toggleListItemAttributes",
value: function toggleListItemAttributes() {
var _this$getSortableList;
if (this.selector instanceof this.listInterface) {
this.sortableList = this.selector;
} else {
const list = document.querySelector(this.selector);
this.sortableList = list instanceof this.listInterface
? list
: list.querySelector(this.getListTagName());
var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
(_this$getSortableList = this.getSortableList()) === null || _this$getSortableList === void 0 ? void 0 : _this$getSortableList.querySelectorAll('li').forEach(function (el) {
el.setAttribute('draggable', enable.toString());
});
}
}, {
key: "toggleListEventListeners",
value: function toggleListEventListeners() {
var _this2 = this;
return this.sortableList
}
var remove = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var list = this.getSortableList();
if (!list) return;
Object.keys(this.listEventListeners).forEach(function (event) {
remove ? list.removeEventListener(event, _this2.listEventListeners[event]) : list.addEventListener(event, _this2.listEventListeners[event], false);
});
}
}, {
key: "initDragAndDrop",
value: function initDragAndDrop() {
if (this.initialised) return;
this.toggleListEventListeners();
this.initPlaceholderList();
this.toggleListItemAttributes();
this.toggleMainListLifeCycleClassName();
this.initialised = true;
}
}, {
key: "init",
value: function init() {
this.initDragAndDrop();
}
}, {
key: "destroy",
value: function destroy() {
this.toggleListEventListeners(true);
this.toggleListItemAttributes(false);
this.toggleMainListLifeCycleClassName(false);
this.initialised = false;
}
}, {
key: "removeClassFromEl",
value: function removeClassFromEl(className, el) {
if (el && el.classList.contains(className)) {
el.classList.remove(className);
}
}
}, {
key: "canBeTargeted",
value: function canBeTargeted(el) {
if (!this.draggedNode || this.draggedNode === el) return false;
return el.nodeName === 'LI' || el instanceof this.listInterface && el.classList.contains(this.classNames.placeholder);
}
}, {
key: "onDragStart",
value: function onDragStart(e) {
var _e$dataTransfer;
addListAttributes() {
const list = this.getSortableList();
this.draggedNode = e.target;
this.draggedNode.classList.add(this.classNames.dragged);
(_e$dataTransfer = e.dataTransfer) === null || _e$dataTransfer === void 0 ? void 0 : _e$dataTransfer.setData('text', 'Drag started!'); // Hack for Firefox!
}
}, {
key: "onDragOver",
value: function onDragOver(e) {
e.preventDefault(); // prevent default to allow drop
list.classList.add(...this.listClassNames.concat(this.mainListClassName));
list.querySelectorAll(this.getListTagName()).forEach(l => {
l.classList.add(...this.listClassNames);
});
this.updateCoordination(e);
this.managePlaceholderLists();
}
}, {
key: "onDragEnter",
value: function onDragEnter(e) {
if (!this.canBeTargeted(e.target)) return;
this.removeClassFromEl(this.classNames.targeted, this.targetedNode);
this.targetedNode = e.target;
this.targetedNode.classList.add(this.classNames.targeted);
}
}, {
key: "onDragEnd",
value: function onDragEnd(e) {
e.stopPropagation();
this.removeClassFromEl(this.classNames.dragged, this.draggedNode);
this.removeClassFromEl(this.classNames.targeted, this.targetedNode);
this.cleanupPlaceholderLists();
delete this.draggedNode;
delete this.targetedNode;
}
}, {
key: "onDrop",
value: function onDrop(e) {
e.stopPropagation();
this.maybeDrop();
this.cleanupPlaceholderLists();
list.querySelectorAll('li').forEach(li => {
li.classList.add(...this.listItemClassNames);
});
}
toggleMainListLifeCycleClassName(enabled = true) {
const className = `${this.mainListClassName}--enabled`;
const classList = this.getSortableList().classList;
return enabled
? classList.add(className)
: classList.remove(className)
}
toggleListItemAttributes(enable = true) {
this.getSortableList().querySelectorAll('li').forEach(el => {
el.setAttribute('draggable', enable);
});
}
toggleListEventListeners(remove = false) {
const list = this.getSortableList();
Object.keys(this.listEventListeners).forEach(event => {
if (remove) {
list.removeEventListener(event, this.listEventListeners[event]);
} else {
list.addEventListener(event, this.listEventListeners[event], false);
if (typeof this.actions.onDrop === 'function') {
this.actions.onDrop(this.getDataEngine().convertDomToData(this.getSortableList()));
}
});
}
initDragAndDrop() {
if (this.initialised) return
this.toggleListEventListeners();
this.initPlaceholderList();
this.toggleListItemAttributes();
this.toggleMainListLifeCycleClassName();
this.initialised = true;
}
init() {
this.initDragAndDrop();
}
destroy() {
this.toggleListEventListeners(true);
this.toggleListItemAttributes(false);
this.toggleMainListLifeCycleClassName(false);
this.initialised = false;
}
removeClassFromEl(el, className) {
if (el && el.classList.contains(className)) {
el.classList.remove(className);
}
}
}, {
key: "updateCoordination",
value: function updateCoordination(e) {
this.calcMouseCoords(e);
this.calcMouseToTargetedElDist();
}
}, {
key: "getDropLocation",
value: function getDropLocation() {
if (this.canBeDropped()) {
var _this$targetedNode;
canBeTargeted(el) {
if (!this.draggedNode || this.draggedNode === el) return false
return el.nodeName === 'LI' || (el instanceof this.listInterface && el.classList.contains(this.classNames.placeholder))
}
onDragStart(e) {
this.draggedNode = e.target;
this.draggedNode.classList.add(this.classNames.dragged);
e.dataTransfer.setData('text', 'Drag started!'); // Hack for Firefox!
}
onDragOver(e) {
e.preventDefault(); // prevent default to allow drop
this.updateCoordination(e);
this.managePlaceholderLists(e);
}
onDragEnter(e) {
if (!this.canBeTargeted(e.target)) return
this.removeClassFromEl(this.targetedNode, this.classNames.targeted);
this.targetedNode = e.target;
this.targetedNode.classList.add(this.classNames.targeted);
}
onDragEnd(e) {
e.stopPropagation();
this.removeClassFromEl(this.draggedNode, this.classNames.dragged);
this.removeClassFromEl(this.targetedNode, this.classNames.targeted);
this.cleanupPlaceholderLists();
this.draggedNode = null;
this.targetedNode = null;
}
onDrop(e) {
e.stopPropagation();
this.maybeDrop();
this.cleanupPlaceholderLists();
if (typeof this.actions.onDrop === 'function') {
this.actions.onDrop(this.getDataEngine().convertDomToData(this.getSortableList()));
if (((_this$targetedNode = this.targetedNode) === null || _this$targetedNode === void 0 ? void 0 : _this$targetedNode.nodeName) === 'LI') return 'before';else if (this.targetedNode instanceof this.listInterface) return 'inside';
}
}
}
}, {
key: "maybeDrop",
value: function maybeDrop() {
var location = this.getDropLocation();
if (location) this.dropTheItem(location);
}
}, {
key: "dropTheItem",
value: function dropTheItem(place) {
var _this$targetedNode2, _this$targetedNode2$p, _this$targetedNode3;
updateCoordination(e) {
this.calcMouseCoords(e);
this.calcMouseToTargetedElDist();
}
switch (place) {
case 'before':
(_this$targetedNode2 = this.targetedNode) === null || _this$targetedNode2 === void 0 ? void 0 : (_this$targetedNode2$p = _this$targetedNode2.parentNode) === null || _this$targetedNode2$p === void 0 ? void 0 : _this$targetedNode2$p.insertBefore(this.draggedNode, this.targetedNode);
break;
getDropLocation() {
if (this.canBeDropped()) {
if (this.targetedNode.nodeName === 'LI' && !this.cursorIsIndentedEnough()) return 'before'
else if (this.targetedNode instanceof this.listInterface) return 'inside'
case 'inside':
(_this$targetedNode3 = this.targetedNode) === null || _this$targetedNode3 === void 0 ? void 0 : _this$targetedNode3.appendChild(this.draggedNode);
break;
}
}
}
}, {
key: "calcMouseCoords",
value: function calcMouseCoords(e) {
// we're having the client coords because on the next lines, we use getBoundingClientRect which behaves in the same way
this.cursor = {
X: e.clientX,
Y: e.clientY
};
}
}, {
key: "calcMouseToTargetedElDist",
value: function calcMouseToTargetedElDist() {
if (!this.targetedNode) {
return;
}
maybeDrop(e) {
const location = this.getDropLocation();
if (location) this.dropTheItem(location, e);
}
dropTheItem(place) {
switch (place) {
case 'before':
this.targetedNode.parentNode.insertBefore(this.draggedNode, this.targetedNode);
break
case 'inside':
this.targetedNode.appendChild(this.draggedNode);
break
var offset = this.targetedNode.getBoundingClientRect();
this.targetNode = {
X: offset.left,
Y: offset.top
};
var result = this.targetNode.Y - this.cursor.Y;
var targetedElTopAbs = Math.abs(result);
this.distances.mouseTo = {
targetedElTop: result,
targetedElTopAbs: targetedElTopAbs,
targetedElBot: targetedElTopAbs - this.targetedNode.clientHeight
};
}
}
}, {
key: "areNested",
value: function areNested(child, parent) {
return !!child && !!parent && Array.from(parent === null || parent === void 0 ? void 0 : parent.querySelectorAll('li')).some(function (li) {
return li === child;
});
}
}, {
key: "cursorIsIndentedEnough",
value: function cursorIsIndentedEnough() {
return this.cursor.X - this.targetNode.X > 50;
}
}, {
key: "mouseIsTooCloseToTop",
value: function mouseIsTooCloseToTop() {
var _this$distances;
calcMouseCoords(e) {
// we're having the client coords because on the next lines, we use getBoundingClientRect which behaves in the same way
this.cursor.X = e.clientX;
this.cursor.Y = e.clientY;
}
calcMouseToTargetedElDist() {
if (!this.targetedNode) {
return
if (!((_this$distances = this.distances) !== null && _this$distances !== void 0 && _this$distances.droppingEdge)) return false;
return this.cursor.Y - this.targetNode.Y < this.distances.droppingEdge;
}
}, {
key: "managePlaceholderLists",
value: function managePlaceholderLists() {
var _this3 = this;
let offset = this.targetedNode.getBoundingClientRect();
this.targetNode.X = offset.left;
this.targetNode.Y = offset.top;
var actions = this.analysePlaceHolderSituation();
actions.forEach(function (action) {
switch (action) {
case 'add':
_this3.cleanupPlaceholderLists();
let result = this.targetNode.Y - this.cursor.Y;
this.distances.mouseTo.targetedElTop = result;
this.distances.mouseTo.targetedElTopAbs = Math.abs(result);
this.dimensions.targetedEl.H = this.targetedNode.clientHeight;
this.distances.mouseTo.targetedElBot = this.distances.mouseTo.targetedElTopAbs - this.dimensions.targetedEl.H;
}
_this3.addPlaceholderList();
areNested(child, parent) {
return parent && Array.from(parent.querySelectorAll('li')).some(li => li === child)
}
break;
cursorIsIndentedEnough() {
return this.cursor.X - this.targetNode.X > 50
}
case 'cleanup':
_this3.cleanupPlaceholderLists();
mouseIsTooCloseToTop() {
return this.cursor.Y - this.targetNode.Y < this.distances.droppingEdge
}
break;
}
});
}
}, {
key: "targetedNodeIsPlaceholder",
value: function targetedNodeIsPlaceholder() {
return this.targetedNode instanceof this.listInterface && this.targetedNode.classList.contains(this.classNames.placeholder);
}
}, {
key: "getTargetedNodeDepth",
value: function getTargetedNodeDepth() {
var depth = 0;
var el = this.targetedNode;
var list = this.getSortableList();
managePlaceholderLists(e) {
while (list !== ((_el = el) === null || _el === void 0 ? void 0 : _el.parentElement)) {
var _el, _el2, _el3;
let actions = this.analysePlaceHolderSituation(e);
if (((_el2 = el) === null || _el2 === void 0 ? void 0 : _el2.parentElement) instanceof this.listInterface) depth++;
el = (_el3 = el) === null || _el3 === void 0 ? void 0 : _el3.parentElement;
}
actions.forEach(action => {
switch (action) {
case 'add':
this.cleanupPlaceholderLists();
this.addPlaceholderList();
break
case 'cleanup':
this.cleanupPlaceholderLists();
break
return depth;
}
}, {
key: "nestingThresholdReached",
value: function nestingThresholdReached() {
if (this.nestingLevels < 0) return false;
if (this.nestingLevels === 0) return true;
return this.getTargetedNodeDepth() >= this.nestingLevels;
}
}, {
key: "analysePlaceHolderSituation",
value: function analysePlaceHolderSituation() {
if (!this.targetedNode || this.areNested(this.targetedNode, this.draggedNode)) {
return [];
}
});
}
targetedNodeIsPlaceholder() {
return this.targetedNode instanceof this.listInterface
&& this.targetedNode.classList.contains(this.classNames.placeholder)
}
var actions = [];
getTargetedNodeDepth() {
let depth = 0;
let el = this.targetedNode;
const list = this.getSortableList();
if (!this.cursorIsIndentedEnough() || this.mouseIsTooCloseToTop()) {
if (!this.targetedNodeIsPlaceholder()) {
actions.push('cleanup');
}
} else if (this.targetedNode !== this.draggedNode && this.targetedNode.nodeName === 'LI' && !this.targetedNode.querySelectorAll(this.getListTagName()).length && !this.nestingThresholdReached()) {
actions.push('add');
}
while (list !== el.parentElement) {
if (el.parentElement instanceof this.listInterface) depth++;
el = el.parentElement;
return actions;
}
}, {
key: "animatePlaceholderList",
value: function animatePlaceholderList() {
var _this$draggedNode;
return depth
}
this.placeholderInUse.style.minHeight = '0';
this.placeholderInUse.style.transition = 'min-height ease .2s';
this.placeholderInUse.style.minHeight = "".concat((_this$draggedNode = this.draggedNode) === null || _this$draggedNode === void 0 ? void 0 : _this$draggedNode.offsetHeight, "px");
}
}, {
key: "addPlaceholderList",
value: function addPlaceholderList() {
var _this$targetedNode4;
nestingThresholdReached() {
if (this.nestingLevels < 0) return false
if (this.nestingLevels === 0) return true
this.getPlaceholderList();
(_this$targetedNode4 = this.targetedNode) === null || _this$targetedNode4 === void 0 ? void 0 : _this$targetedNode4.appendChild(this.placeholderInUse);
this.animatePlaceholderList();
}
}, {
key: "targetNodeIsIdentified",
value: function targetNodeIsIdentified() {
return !!this.targetedNode;
}
}, {
key: "targetNodeIsBeingDragged",
value: function targetNodeIsBeingDragged() {
return this.targetNodeIsIdentified() && this.targetedNode === this.draggedNode;
}
}, {
key: "targetNodeIsListWithItems",
value: function targetNodeIsListWithItems() {
return this.targetNodeIsIdentified() && this.targetedNode instanceof this.listInterface && !!this.targetedNode.querySelectorAll('li').length;
}
}, {
key: "canBeDropped",
value: function canBeDropped() {
return this.targetNodeIsIdentified() && !this.targetNodeIsBeingDragged() && !this.targetNodeIsListWithItems() && !this.areNested(this.targetedNode, this.draggedNode);
}
}, {
key: "cleanupPlaceholderLists",
value: function cleanupPlaceholderLists() {
var _this$getSortableList2,
_this4 = this;
return this.getTargetedNodeDepth() >= this.nestingLevels
}
analysePlaceHolderSituation() {
if (!this.targetedNode || this.areNested(this.targetedNode, this.draggedNode)) {
return []
var tag = this.getListTagName();
var listsArray = ((_this$getSortableList2 = this.getSortableList()) === null || _this$getSortableList2 === void 0 ? void 0 : _this$getSortableList2.querySelectorAll(tag)) || [];
Array.from(listsArray).forEach(function (ul) {
if (!ul.querySelectorAll('li').length) {
ul.remove();
} else if (ul.classList.contains(_this4.classNames.placeholder)) {
ul.classList.remove(_this4.classNames.placeholder);
ul.style.minHeight = 'auto';
ul.dataset.id = ul.parentNode.dataset.id;
}
});
}
}, {
key: "initPlaceholderList",
value: function initPlaceholderList() {
var _this$placeholderList;
let actions = [];
this.placeholderList = document.createElement(this.getListTagName());
if (!this.cursorIsIndentedEnough() || this.mouseIsTooCloseToTop()) {
if (!this.targetedNodeIsPlaceholder()) {
actions.push('cleanup');
}
} else if (this.targetedNode !== this.draggedNode
&& this.targetedNode.nodeName === 'LI'
&& !this.targetedNode.querySelectorAll(this.getListTagName()).length
&& !this.nestingThresholdReached()) {
actions.push('add');
(_this$placeholderList = this.placeholderList.classList).add.apply(_this$placeholderList, [this.classNames.placeholder].concat(_toConsumableArray(this.listClassNames)));
}
}, {
key: "getPlaceholderList",
value: function getPlaceholderList() {
this.placeholderInUse = this.placeholderList.cloneNode(true);
return this.placeholderInUse;
}
}]);
return actions
}
return NestedSort;
}();
animatePlaceholderList() {
this.placeholderInUse.style.minHeight = '0';
this.placeholderInUse.style.transition = 'min-height ease .2s';
this.placeholderInUse.style.minHeight = `${this.draggedNode.offsetHeight}px`;
}
addPlaceholderList() {
this.getPlaceholderList();
this.targetedNode.appendChild(this.placeholderInUse);
this.animatePlaceholderList();
}
targetNodeIsIdentified() {
return !!this.targetedNode
}
targetNodeIsBeingDragged() {
return this.targetNodeIsIdentified()
&& this.targetedNode === this.draggedNode
}
targetNodeIsListWithItems() {
return this.targetNodeIsIdentified()
&& this.targetedNode instanceof this.listInterface
&& this.targetedNode.querySelectorAll('li').length
}
canBeDropped() {
return this.targetNodeIsIdentified()
&& !this.targetNodeIsBeingDragged()
&& !this.targetNodeIsListWithItems()
&& !this.areNested(this.targetedNode, this.draggedNode)
}
cleanupPlaceholderLists() {
this.getSortableList().querySelectorAll(this.getListTagName()).forEach(ul => {
if (!ul.querySelectorAll('li').length) {
ul.remove();
} else if (ul.classList.contains(this.classNames.placeholder)) {
ul.classList.remove(this.classNames.placeholder);
ul.style.minHeight = 'auto';
ul.dataset.id = ul.parentNode.dataset.id;
}
});
}
initPlaceholderList() {
this.placeholderList = document.createElement(this.getListTagName());
this.placeholderList.classList.add(this.classNames.placeholder, ...this.listClassNames);
}
getPlaceholderList() {
this.placeholderInUse = this.placeholderList.cloneNode(true);
return this.placeholderInUse
}
}
module.exports = NestedSort;

@@ -1,8 +0,90 @@

class DataEngine {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var DataEngine = /*#__PURE__*/function () {
/**
* @constructor
* @param {object[]} [data]
* @param {object} [propertyMap={}]
*/
constructor({ data, propertyMap = {} }) {
function DataEngine(_ref) {
var data = _ref.data,
_ref$propertyMap = _ref.propertyMap,
propertyMap = _ref$propertyMap === void 0 ? {} : _ref$propertyMap;
_classCallCheck(this, DataEngine);
_defineProperty(this, "data", void 0);
_defineProperty(this, "sortedData", void 0);
_defineProperty(this, "sortedDataDomArray", void 0);
_defineProperty(this, "propertyMap", void 0);
this.data = data;

@@ -12,48 +94,47 @@ this.sortedData = [];

this.propertyMap = propertyMap;
this.maybeTransformData();
}
maybeTransformData() {
if (!Object.keys(this.propertyMap).length || !Array.isArray(this.data)) return
_createClass(DataEngine, [{
key: "maybeTransformData",
value: function maybeTransformData() {
if (!Object.keys(this.propertyMap).length || !Array.isArray(this.data)) return;
var getItemPropProxyName = this.getItemPropProxyName.bind(this);
this.data = this.data.map(function (item) {
return new Proxy(item, {
get: function get(target, prop, receiver) {
return Reflect.get(target, getItemPropProxyName(prop), receiver);
}
});
});
}
}, {
key: "getItemPropProxyName",
value: function getItemPropProxyName(prop) {
if (Object.prototype.hasOwnProperty.call(this.propertyMap, prop)) {
return this.propertyMap[prop];
}
const getItemPropProxyName = this.getItemPropProxyName.bind(this);
this.data = this.data.map(item => {
return new Proxy(item, {
get(target, prop, receiver) {
return Reflect.get(target, getItemPropProxyName(prop), receiver)
},
})
});
}
/**
* @param {PropertyKey} prop
* @returns {PropertyKey}
*/
getItemPropProxyName(prop) {
if (Object.prototype.hasOwnProperty.call(this.propertyMap, prop)) {
return this.propertyMap[prop]
return prop;
}
return prop
}
}, {
key: "isTopLevelItem",
value: function isTopLevelItem(item) {
return !item.parent;
}
}, {
key: "sortListItems",
value: function sortListItems() {
var _this = this;
isTopLevelItem(item) {
return !item.parent
}
var items = _toConsumableArray(this.data);
/**
* @returns {object[]}
*/
sortListItems() {
const items = [...this.data];
const topLevelItems = items
.filter(a => this.isTopLevelItem(a))
.sort((a, b) => a.order && b.order ? a.order - b.order : 0);
const childItems = items
.filter(a => !this.isTopLevelItem(a))
.reduce((groups, item) => {
var topLevelItems = items.filter(function (a) {
return _this.isTopLevelItem(a);
}).sort(function (a, b) {
return a.order && b.order ? a.order - b.order : 0;
});
var childItems = items.filter(function (a) {
return !_this.isTopLevelItem(a);
}).reduce(function (groups, item) {
if (Object.prototype.hasOwnProperty.call(groups, item.parent)) {

@@ -64,184 +145,195 @@ groups[item.parent].push(item);

}
return groups
return groups;
}, {});
Object.keys(childItems).forEach(function (parentId) {
childItems[parentId].sort(function (a, b) {
return a.order && b.order ? a.order - b.order : 0;
});
});
this.sortedData = [].concat(_toConsumableArray(topLevelItems), _toConsumableArray(Object.values(childItems).flat()));
return this.sortedData;
}
}, {
key: "createItemElement",
value: function createItemElement(item) {
var nodeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'li';
var id = item.id,
text = item.text;
var el = document.createElement(nodeName);
el.dataset.id = id;
if (nodeName === 'li' && text) el.innerHTML = text;
return el;
}
}, {
key: "elementIsParentOfItem",
value: function elementIsParentOfItem(node, item) {
return node.dataset.id === "".concat(item.parent);
}
}, {
key: "getParentNodeOfItem",
value: function getParentNodeOfItem(node, item, nodeName) {
return node.querySelector("".concat(nodeName, "[data-id=\"").concat(item.parent, "\"]"));
}
}, {
key: "elementIsAncestorOfItem",
value: function elementIsAncestorOfItem(node, item) {
return !!this.getParentNodeOfItem(node, item, 'li');
}
}, {
key: "getDirectListParentOfItem",
value: function getDirectListParentOfItem(node, item) {
return this.getParentNodeOfItem(node, item, 'ol');
}
}, {
key: "maybeAppendItemToParentDom",
value: function maybeAppendItemToParentDom(item) {
var _this2 = this;
Object.keys(childItems).forEach(parentId => {
childItems[parentId].sort((a, b) => a.order && b.order ? a.order - b.order : 0);
});
var parent = item.parent;
var topParent = this.sortedDataDomArray.find(function (topLevelListItem) {
return _this2.elementIsParentOfItem(topLevelListItem, item) || _this2.elementIsAncestorOfItem(topLevelListItem, item);
});
if (!topParent) return false;
var listItem = this.createItemElement(item);
var directParentList = this.getDirectListParentOfItem(topParent, item);
this.sortedData = [
...topLevelItems,
...Object.values(childItems).flat(),
];
if (!directParentList) {
// we need to create the direct parent OL and append it to the direct parent LI
directParentList = this.createItemElement({
id: parent
}, 'ol');
var directParentListItem = this.getParentNodeOfItem(topParent, item, 'li') || topParent;
directParentListItem.appendChild(directParentList);
}
return this.sortedData
}
directParentList.appendChild(listItem);
return true;
}
}, {
key: "getListItemsDom",
value: function getListItemsDom() {
var _this3 = this;
/**
* @param {object[]} item
* @param {string} nodeName
* @returns {HTMLElement}
*/
createItemElement(item, nodeName = 'li') {
const { id, text } = item;
const el = document.createElement(nodeName);
el.dataset.id = id;
if (nodeName === 'li') el.innerHTML = text;
this.sortedDataDomArray = [];
var processedItems = [];
return el
}
while (processedItems.length !== this.sortListItems().length) {
processedItems = this.sortedData.reduce(function (processedItems, item) {
var id = item.id.toString();
if (processedItems.includes(id)) return processedItems;
var itemAdded;
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {boolean}
*/
elementIsParentOfItem(node, item) {
return node.dataset.id === `${item.parent}`
}
if (!item.parent) {
var listItem = _this3.createItemElement(item);
/**
* @param {HTMLElement} node
* @param {object} item
* @param {string} nodeName
* @returns {Element|null}
*/
getParentNodeOfItem(node, item, nodeName) {
return node.querySelector(`${nodeName}[data-id="${item.parent}"]`)
}
_this3.sortedDataDomArray.push(listItem);
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {boolean}
*/
elementIsAncestorOfItem(node, item) {
return !!this.getParentNodeOfItem(node, item, 'li')
}
itemAdded = true;
} else {
itemAdded = _this3.maybeAppendItemToParentDom(item);
}
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {HTMLElement}
*/
getDirectListParentOfItem(node, item) {
return this.getParentNodeOfItem(node, item, 'ol')
}
if (itemAdded) processedItems.push(id);
return processedItems;
}, processedItems);
}
/**
* @param {object} item
* @returns {boolean}
*/
maybeAppendItemToParentDom(item) {
const { parent } = item;
const topParent = this.sortedDataDomArray.find(topLevelListItem => {
return this.elementIsParentOfItem(topLevelListItem, item) || this.elementIsAncestorOfItem(topLevelListItem, item)
});
return this.sortedDataDomArray;
}
}, {
key: "convertDomToData",
value: function convertDomToData(list) {
var _this4 = this;
if (!topParent) return false
return Array.from((list === null || list === void 0 ? void 0 : list.querySelectorAll('li')) || []).map(function (li) {
var _ref2;
const listItem = this.createItemElement(item);
let directParentList = this.getDirectListParentOfItem(topParent, item);
if (!directParentList) {
// we need to create the direct parent OL and append it to the direct parent LI
directParentList = this.createItemElement({ id: parent }, 'ol');
const directParentListItem = this.getParentNodeOfItem(topParent, item, 'li') || topParent;
directParentListItem.appendChild(directParentList);
var parentListItem = li.parentNode;
var parent = parentListItem.dataset.id;
var order = Array.from(parentListItem.children).findIndex(function (item) {
return item === li;
}) + 1;
return _ref2 = {}, _defineProperty(_ref2, _this4.getItemPropProxyName('id'), li.dataset.id), _defineProperty(_ref2, _this4.getItemPropProxyName('parent'), parent), _defineProperty(_ref2, _this4.getItemPropProxyName('order'), order), _ref2;
});
}
}, {
key: "render",
value: function render() {
var list = document.createElement('ol');
this.getListItemsDom().forEach(function (listItem) {
return list.appendChild(listItem);
});
return list;
}
}]);
directParentList.appendChild(listItem);
return DataEngine;
}();
return true
}
var NestedSort = /*#__PURE__*/function () {
function NestedSort(_ref) {
var _ref$actions = _ref.actions,
actions = _ref$actions === void 0 ? {} : _ref$actions,
data = _ref.data,
_ref$droppingEdge = _ref.droppingEdge,
droppingEdge = _ref$droppingEdge === void 0 ? 15 : _ref$droppingEdge,
el = _ref.el,
_ref$init = _ref.init,
init = _ref$init === void 0 ? true : _ref$init,
listClassNames = _ref.listClassNames,
listItemClassNames = _ref.listItemClassNames,
nestingLevels = _ref.nestingLevels,
_ref$propertyMap = _ref.propertyMap,
propertyMap = _ref$propertyMap === void 0 ? {} : _ref$propertyMap;
/**
* @returns {array}
*/
getListItemsDom() {
this.sortedDataDomArray = [];
let processedItems = [];
_classCallCheck(this, NestedSort);
while (processedItems.length !== this.sortListItems().length) {
processedItems = this.sortedData.reduce((processedItems, item) => {
const { id } = item;
if (processedItems.includes(id)) return processedItems
_defineProperty(this, "actions", void 0);
let itemAdded;
if (!item.parent) {
const listItem = this.createItemElement(item);
this.sortedDataDomArray.push(listItem);
itemAdded = true;
} else {
itemAdded = this.maybeAppendItemToParentDom(item);
}
_defineProperty(this, "classNames", void 0);
if (itemAdded) processedItems.push(id);
_defineProperty(this, "cursor", void 0);
return processedItems
}, processedItems);
}
_defineProperty(this, "data", void 0);
return this.sortedDataDomArray
}
_defineProperty(this, "dataEngine", void 0);
/**
* @param {HTMLOListElement|HTMLUListElement} list
* @returns {object[]}
*/
convertDomToData(list) {
return Array.from(list.querySelectorAll('li')).map(li => {
const parentListItem = li.parentNode;
const parent = parentListItem.dataset.id;
const order = Array.from(parentListItem.children).findIndex(item => item === li) + 1;
_defineProperty(this, "distances", void 0);
return {
[this.getItemPropProxyName('id')]: li.dataset.id,
[this.getItemPropProxyName('parent')]: parent,
[this.getItemPropProxyName('order')]: order,
}
})
}
_defineProperty(this, "draggedNode", void 0);
/**
* @returns {HTMLOListElement}
*/
render() {
const list = document.createElement('ol');
this.getListItemsDom().forEach(listItem => list.appendChild(listItem));
return list
}
}
_defineProperty(this, "initialised", void 0);
class NestedSort {
/**
* @constructor
* @param {object} [actions={}]
* @param {array} [data]
* @param {number} [droppingEdge=15]
* @param {string|HTMLElement} el
* @param {boolean} [init=true]
* @param {array|string} [listClassNames]
* @param {array|string} [listItemClassNames]
* @param {number|string} [nestingLevels]
* @param {object} [propertyMap={}]
*/
constructor({
actions: { onDrop } = {},
data,
droppingEdge = 15,
el,
init = true,
listClassNames,
listItemClassNames,
nestingLevels,
propertyMap = {},
}) {
_defineProperty(this, "listClassNames", void 0);
_defineProperty(this, "listEventListeners", void 0);
_defineProperty(this, "listInterface", void 0);
_defineProperty(this, "listItemClassNames", void 0);
_defineProperty(this, "mainListClassName", void 0);
_defineProperty(this, "nestingLevels", void 0);
_defineProperty(this, "placeholderList", void 0);
_defineProperty(this, "placeholderInUse", void 0);
_defineProperty(this, "propertyMap", void 0);
_defineProperty(this, "sortableList", void 0);
_defineProperty(this, "targetedNode", void 0);
_defineProperty(this, "targetNode", void 0);
_defineProperty(this, "wrapper", void 0);
var element = typeof el === 'string' ? document.querySelector(el) : el;
var elementIsAList = element instanceof HTMLOListElement || element instanceof HTMLUListElement;
this.wrapper = elementIsAList ? undefined : element;
this.sortableList = elementIsAList ? element : null;
this.data = data;
this.selector = el;
this.sortableList = null;
this.placeholderList = null;
this.placeholderInUse = null;
this.draggedNode = null;
this.targetedNode = null;
this.listClassNames = this.createListClassNamesArray(listClassNames);

@@ -252,29 +344,12 @@ this.mainListClassName = this.listClassNames[0] || 'nested-sort';

this.actions = {
onDrop,
onDrop: actions.onDrop
};
this.initialised = false;
this.targetNode = {
X: null,
Y: null,
};
this.distances = {
droppingEdge,
droppingEdgeNegative: droppingEdge * -1,
mouseTo: {
targetedElTop: undefined,
},
droppingEdge: droppingEdge
};
this.dimensions = {
targetedEl: {
H: undefined,
},
};
this.cursor = {
X: null,
Y: null,
};
this.classNames = {
dragged: 'ns-dragged',
placeholder: 'ns-placeholder',
targeted: 'ns-targeted',
targeted: 'ns-targeted'
};

@@ -286,8 +361,8 @@ this.listEventListeners = {

dragend: this.onDragEnd.bind(this),
drop: this.onDrop.bind(this),
drop: this.onDrop.bind(this)
};
const intNestingLevels = parseInt(nestingLevels);
var intNestingLevels = parseInt(nestingLevels);
this.nestingLevels = isNaN(intNestingLevels) ? -1 : intNestingLevels; // values less than 0 mean infinite levels of nesting
this.listInterface = this.getListInterface();
this.maybeInitDataDom();

@@ -298,344 +373,411 @@ this.addListAttributes();

getListInterface() {
if (Array.isArray(this.data) && this.data.length) return HTMLOListElement
_createClass(NestedSort, [{
key: "getListInterface",
value: function getListInterface() {
if (Array.isArray(this.data) && this.data.length) return HTMLOListElement;
return this.sortableList instanceof HTMLOListElement ? HTMLOListElement : HTMLUListElement;
}
}, {
key: "getDataEngine",
value: function getDataEngine() {
if (this.dataEngine) return this.dataEngine;
this.dataEngine = new DataEngine({
data: this.data,
propertyMap: this.propertyMap
});
return this.dataEngine;
}
}, {
key: "createListClassNamesArray",
value: function createListClassNamesArray(listClassNames) {
if (!listClassNames) return [];
return Array.isArray(listClassNames) ? listClassNames : listClassNames.split(' ');
}
}, {
key: "maybeInitDataDom",
value: function maybeInitDataDom() {
if (!(Array.isArray(this.data) && this.data.length && this.wrapper)) return;
var list = this.getDataEngine().render();
this.wrapper.innerHTML = '';
this.wrapper.appendChild(list);
}
}, {
key: "getListTagName",
value: function getListTagName() {
return this.listInterface === HTMLOListElement ? 'ol' : 'ul';
}
}, {
key: "getSortableList",
value: function getSortableList() {
var _this$wrapper;
const el = this.selector instanceof HTMLElement
? this.selector
: document.querySelector(this.selector);
return el instanceof HTMLOListElement ? HTMLOListElement : HTMLUListElement
}
getDataEngine() {
if (this.dataEngine instanceof DataEngine) {
return this.dataEngine
if (this.sortableList instanceof this.listInterface) return this.sortableList;
this.sortableList = (_this$wrapper = this.wrapper) === null || _this$wrapper === void 0 ? void 0 : _this$wrapper.querySelector(this.getListTagName());
return this.sortableList;
}
this.dataEngine = new DataEngine({data: this.data, propertyMap: this.propertyMap});
return this.dataEngine
}
}, {
key: "addListAttributes",
value: function addListAttributes() {
var _list$classList,
_this = this;
createListClassNamesArray(listClassNames) {
if (!listClassNames) return []
return Array.isArray(listClassNames) ? listClassNames : listClassNames.split(' ')
}
var list = this.getSortableList();
if (!list) return;
maybeInitDataDom() {
if (!(Array.isArray(this.data) && this.data.length)) return
(_list$classList = list.classList).add.apply(_list$classList, _toConsumableArray(this.listClassNames.concat(this.mainListClassName)));
const wrapper = document.querySelector(this.selector);
const list = this.getDataEngine().render();
wrapper.innerHTML = '';
wrapper.appendChild(list);
}
list.querySelectorAll(this.getListTagName()).forEach(function (l) {
var _l$classList;
getListTagName() {
return this.listInterface === HTMLOListElement ? 'ol' : 'ul'
}
(_l$classList = l.classList).add.apply(_l$classList, _toConsumableArray(_this.listClassNames));
});
list.querySelectorAll('li').forEach(function (li) {
var _li$classList;
getSortableList() {
if (this.sortableList instanceof this.listInterface) return this.sortableList
(_li$classList = li.classList).add.apply(_li$classList, _toConsumableArray(_this.listItemClassNames));
});
}
}, {
key: "toggleMainListLifeCycleClassName",
value: function toggleMainListLifeCycleClassName() {
var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var list = this.getSortableList();
if (!list) return;
var className = "".concat(this.mainListClassName, "--enabled");
enabled ? list.classList.add(className) : list.classList.remove(className);
}
}, {
key: "toggleListItemAttributes",
value: function toggleListItemAttributes() {
var _this$getSortableList;
if (this.selector instanceof this.listInterface) {
this.sortableList = this.selector;
} else {
const list = document.querySelector(this.selector);
this.sortableList = list instanceof this.listInterface
? list
: list.querySelector(this.getListTagName());
var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
(_this$getSortableList = this.getSortableList()) === null || _this$getSortableList === void 0 ? void 0 : _this$getSortableList.querySelectorAll('li').forEach(function (el) {
el.setAttribute('draggable', enable.toString());
});
}
}, {
key: "toggleListEventListeners",
value: function toggleListEventListeners() {
var _this2 = this;
return this.sortableList
}
var remove = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var list = this.getSortableList();
if (!list) return;
Object.keys(this.listEventListeners).forEach(function (event) {
remove ? list.removeEventListener(event, _this2.listEventListeners[event]) : list.addEventListener(event, _this2.listEventListeners[event], false);
});
}
}, {
key: "initDragAndDrop",
value: function initDragAndDrop() {
if (this.initialised) return;
this.toggleListEventListeners();
this.initPlaceholderList();
this.toggleListItemAttributes();
this.toggleMainListLifeCycleClassName();
this.initialised = true;
}
}, {
key: "init",
value: function init() {
this.initDragAndDrop();
}
}, {
key: "destroy",
value: function destroy() {
this.toggleListEventListeners(true);
this.toggleListItemAttributes(false);
this.toggleMainListLifeCycleClassName(false);
this.initialised = false;
}
}, {
key: "removeClassFromEl",
value: function removeClassFromEl(className, el) {
if (el && el.classList.contains(className)) {
el.classList.remove(className);
}
}
}, {
key: "canBeTargeted",
value: function canBeTargeted(el) {
if (!this.draggedNode || this.draggedNode === el) return false;
return el.nodeName === 'LI' || el instanceof this.listInterface && el.classList.contains(this.classNames.placeholder);
}
}, {
key: "onDragStart",
value: function onDragStart(e) {
var _e$dataTransfer;
addListAttributes() {
const list = this.getSortableList();
this.draggedNode = e.target;
this.draggedNode.classList.add(this.classNames.dragged);
(_e$dataTransfer = e.dataTransfer) === null || _e$dataTransfer === void 0 ? void 0 : _e$dataTransfer.setData('text', 'Drag started!'); // Hack for Firefox!
}
}, {
key: "onDragOver",
value: function onDragOver(e) {
e.preventDefault(); // prevent default to allow drop
list.classList.add(...this.listClassNames.concat(this.mainListClassName));
list.querySelectorAll(this.getListTagName()).forEach(l => {
l.classList.add(...this.listClassNames);
});
this.updateCoordination(e);
this.managePlaceholderLists();
}
}, {
key: "onDragEnter",
value: function onDragEnter(e) {
if (!this.canBeTargeted(e.target)) return;
this.removeClassFromEl(this.classNames.targeted, this.targetedNode);
this.targetedNode = e.target;
this.targetedNode.classList.add(this.classNames.targeted);
}
}, {
key: "onDragEnd",
value: function onDragEnd(e) {
e.stopPropagation();
this.removeClassFromEl(this.classNames.dragged, this.draggedNode);
this.removeClassFromEl(this.classNames.targeted, this.targetedNode);
this.cleanupPlaceholderLists();
delete this.draggedNode;
delete this.targetedNode;
}
}, {
key: "onDrop",
value: function onDrop(e) {
e.stopPropagation();
this.maybeDrop();
this.cleanupPlaceholderLists();
list.querySelectorAll('li').forEach(li => {
li.classList.add(...this.listItemClassNames);
});
}
toggleMainListLifeCycleClassName(enabled = true) {
const className = `${this.mainListClassName}--enabled`;
const classList = this.getSortableList().classList;
return enabled
? classList.add(className)
: classList.remove(className)
}
toggleListItemAttributes(enable = true) {
this.getSortableList().querySelectorAll('li').forEach(el => {
el.setAttribute('draggable', enable);
});
}
toggleListEventListeners(remove = false) {
const list = this.getSortableList();
Object.keys(this.listEventListeners).forEach(event => {
if (remove) {
list.removeEventListener(event, this.listEventListeners[event]);
} else {
list.addEventListener(event, this.listEventListeners[event], false);
if (typeof this.actions.onDrop === 'function') {
this.actions.onDrop(this.getDataEngine().convertDomToData(this.getSortableList()));
}
});
}
initDragAndDrop() {
if (this.initialised) return
this.toggleListEventListeners();
this.initPlaceholderList();
this.toggleListItemAttributes();
this.toggleMainListLifeCycleClassName();
this.initialised = true;
}
init() {
this.initDragAndDrop();
}
destroy() {
this.toggleListEventListeners(true);
this.toggleListItemAttributes(false);
this.toggleMainListLifeCycleClassName(false);
this.initialised = false;
}
removeClassFromEl(el, className) {
if (el && el.classList.contains(className)) {
el.classList.remove(className);
}
}
}, {
key: "updateCoordination",
value: function updateCoordination(e) {
this.calcMouseCoords(e);
this.calcMouseToTargetedElDist();
}
}, {
key: "getDropLocation",
value: function getDropLocation() {
if (this.canBeDropped()) {
var _this$targetedNode;
canBeTargeted(el) {
if (!this.draggedNode || this.draggedNode === el) return false
return el.nodeName === 'LI' || (el instanceof this.listInterface && el.classList.contains(this.classNames.placeholder))
}
onDragStart(e) {
this.draggedNode = e.target;
this.draggedNode.classList.add(this.classNames.dragged);
e.dataTransfer.setData('text', 'Drag started!'); // Hack for Firefox!
}
onDragOver(e) {
e.preventDefault(); // prevent default to allow drop
this.updateCoordination(e);
this.managePlaceholderLists(e);
}
onDragEnter(e) {
if (!this.canBeTargeted(e.target)) return
this.removeClassFromEl(this.targetedNode, this.classNames.targeted);
this.targetedNode = e.target;
this.targetedNode.classList.add(this.classNames.targeted);
}
onDragEnd(e) {
e.stopPropagation();
this.removeClassFromEl(this.draggedNode, this.classNames.dragged);
this.removeClassFromEl(this.targetedNode, this.classNames.targeted);
this.cleanupPlaceholderLists();
this.draggedNode = null;
this.targetedNode = null;
}
onDrop(e) {
e.stopPropagation();
this.maybeDrop();
this.cleanupPlaceholderLists();
if (typeof this.actions.onDrop === 'function') {
this.actions.onDrop(this.getDataEngine().convertDomToData(this.getSortableList()));
if (((_this$targetedNode = this.targetedNode) === null || _this$targetedNode === void 0 ? void 0 : _this$targetedNode.nodeName) === 'LI') return 'before';else if (this.targetedNode instanceof this.listInterface) return 'inside';
}
}
}
}, {
key: "maybeDrop",
value: function maybeDrop() {
var location = this.getDropLocation();
if (location) this.dropTheItem(location);
}
}, {
key: "dropTheItem",
value: function dropTheItem(place) {
var _this$targetedNode2, _this$targetedNode2$p, _this$targetedNode3;
updateCoordination(e) {
this.calcMouseCoords(e);
this.calcMouseToTargetedElDist();
}
switch (place) {
case 'before':
(_this$targetedNode2 = this.targetedNode) === null || _this$targetedNode2 === void 0 ? void 0 : (_this$targetedNode2$p = _this$targetedNode2.parentNode) === null || _this$targetedNode2$p === void 0 ? void 0 : _this$targetedNode2$p.insertBefore(this.draggedNode, this.targetedNode);
break;
getDropLocation() {
if (this.canBeDropped()) {
if (this.targetedNode.nodeName === 'LI' && !this.cursorIsIndentedEnough()) return 'before'
else if (this.targetedNode instanceof this.listInterface) return 'inside'
case 'inside':
(_this$targetedNode3 = this.targetedNode) === null || _this$targetedNode3 === void 0 ? void 0 : _this$targetedNode3.appendChild(this.draggedNode);
break;
}
}
}
}, {
key: "calcMouseCoords",
value: function calcMouseCoords(e) {
// we're having the client coords because on the next lines, we use getBoundingClientRect which behaves in the same way
this.cursor = {
X: e.clientX,
Y: e.clientY
};
}
}, {
key: "calcMouseToTargetedElDist",
value: function calcMouseToTargetedElDist() {
if (!this.targetedNode) {
return;
}
maybeDrop(e) {
const location = this.getDropLocation();
if (location) this.dropTheItem(location, e);
}
dropTheItem(place) {
switch (place) {
case 'before':
this.targetedNode.parentNode.insertBefore(this.draggedNode, this.targetedNode);
break
case 'inside':
this.targetedNode.appendChild(this.draggedNode);
break
var offset = this.targetedNode.getBoundingClientRect();
this.targetNode = {
X: offset.left,
Y: offset.top
};
var result = this.targetNode.Y - this.cursor.Y;
var targetedElTopAbs = Math.abs(result);
this.distances.mouseTo = {
targetedElTop: result,
targetedElTopAbs: targetedElTopAbs,
targetedElBot: targetedElTopAbs - this.targetedNode.clientHeight
};
}
}
}, {
key: "areNested",
value: function areNested(child, parent) {
return !!child && !!parent && Array.from(parent === null || parent === void 0 ? void 0 : parent.querySelectorAll('li')).some(function (li) {
return li === child;
});
}
}, {
key: "cursorIsIndentedEnough",
value: function cursorIsIndentedEnough() {
return this.cursor.X - this.targetNode.X > 50;
}
}, {
key: "mouseIsTooCloseToTop",
value: function mouseIsTooCloseToTop() {
var _this$distances;
calcMouseCoords(e) {
// we're having the client coords because on the next lines, we use getBoundingClientRect which behaves in the same way
this.cursor.X = e.clientX;
this.cursor.Y = e.clientY;
}
calcMouseToTargetedElDist() {
if (!this.targetedNode) {
return
if (!((_this$distances = this.distances) !== null && _this$distances !== void 0 && _this$distances.droppingEdge)) return false;
return this.cursor.Y - this.targetNode.Y < this.distances.droppingEdge;
}
}, {
key: "managePlaceholderLists",
value: function managePlaceholderLists() {
var _this3 = this;
let offset = this.targetedNode.getBoundingClientRect();
this.targetNode.X = offset.left;
this.targetNode.Y = offset.top;
var actions = this.analysePlaceHolderSituation();
actions.forEach(function (action) {
switch (action) {
case 'add':
_this3.cleanupPlaceholderLists();
let result = this.targetNode.Y - this.cursor.Y;
this.distances.mouseTo.targetedElTop = result;
this.distances.mouseTo.targetedElTopAbs = Math.abs(result);
this.dimensions.targetedEl.H = this.targetedNode.clientHeight;
this.distances.mouseTo.targetedElBot = this.distances.mouseTo.targetedElTopAbs - this.dimensions.targetedEl.H;
}
_this3.addPlaceholderList();
areNested(child, parent) {
return parent && Array.from(parent.querySelectorAll('li')).some(li => li === child)
}
break;
cursorIsIndentedEnough() {
return this.cursor.X - this.targetNode.X > 50
}
case 'cleanup':
_this3.cleanupPlaceholderLists();
mouseIsTooCloseToTop() {
return this.cursor.Y - this.targetNode.Y < this.distances.droppingEdge
}
break;
}
});
}
}, {
key: "targetedNodeIsPlaceholder",
value: function targetedNodeIsPlaceholder() {
return this.targetedNode instanceof this.listInterface && this.targetedNode.classList.contains(this.classNames.placeholder);
}
}, {
key: "getTargetedNodeDepth",
value: function getTargetedNodeDepth() {
var depth = 0;
var el = this.targetedNode;
var list = this.getSortableList();
managePlaceholderLists(e) {
while (list !== ((_el = el) === null || _el === void 0 ? void 0 : _el.parentElement)) {
var _el, _el2, _el3;
let actions = this.analysePlaceHolderSituation(e);
if (((_el2 = el) === null || _el2 === void 0 ? void 0 : _el2.parentElement) instanceof this.listInterface) depth++;
el = (_el3 = el) === null || _el3 === void 0 ? void 0 : _el3.parentElement;
}
actions.forEach(action => {
switch (action) {
case 'add':
this.cleanupPlaceholderLists();
this.addPlaceholderList();
break
case 'cleanup':
this.cleanupPlaceholderLists();
break
return depth;
}
}, {
key: "nestingThresholdReached",
value: function nestingThresholdReached() {
if (this.nestingLevels < 0) return false;
if (this.nestingLevels === 0) return true;
return this.getTargetedNodeDepth() >= this.nestingLevels;
}
}, {
key: "analysePlaceHolderSituation",
value: function analysePlaceHolderSituation() {
if (!this.targetedNode || this.areNested(this.targetedNode, this.draggedNode)) {
return [];
}
});
}
targetedNodeIsPlaceholder() {
return this.targetedNode instanceof this.listInterface
&& this.targetedNode.classList.contains(this.classNames.placeholder)
}
var actions = [];
getTargetedNodeDepth() {
let depth = 0;
let el = this.targetedNode;
const list = this.getSortableList();
if (!this.cursorIsIndentedEnough() || this.mouseIsTooCloseToTop()) {
if (!this.targetedNodeIsPlaceholder()) {
actions.push('cleanup');
}
} else if (this.targetedNode !== this.draggedNode && this.targetedNode.nodeName === 'LI' && !this.targetedNode.querySelectorAll(this.getListTagName()).length && !this.nestingThresholdReached()) {
actions.push('add');
}
while (list !== el.parentElement) {
if (el.parentElement instanceof this.listInterface) depth++;
el = el.parentElement;
return actions;
}
}, {
key: "animatePlaceholderList",
value: function animatePlaceholderList() {
var _this$draggedNode;
return depth
}
this.placeholderInUse.style.minHeight = '0';
this.placeholderInUse.style.transition = 'min-height ease .2s';
this.placeholderInUse.style.minHeight = "".concat((_this$draggedNode = this.draggedNode) === null || _this$draggedNode === void 0 ? void 0 : _this$draggedNode.offsetHeight, "px");
}
}, {
key: "addPlaceholderList",
value: function addPlaceholderList() {
var _this$targetedNode4;
nestingThresholdReached() {
if (this.nestingLevels < 0) return false
if (this.nestingLevels === 0) return true
this.getPlaceholderList();
(_this$targetedNode4 = this.targetedNode) === null || _this$targetedNode4 === void 0 ? void 0 : _this$targetedNode4.appendChild(this.placeholderInUse);
this.animatePlaceholderList();
}
}, {
key: "targetNodeIsIdentified",
value: function targetNodeIsIdentified() {
return !!this.targetedNode;
}
}, {
key: "targetNodeIsBeingDragged",
value: function targetNodeIsBeingDragged() {
return this.targetNodeIsIdentified() && this.targetedNode === this.draggedNode;
}
}, {
key: "targetNodeIsListWithItems",
value: function targetNodeIsListWithItems() {
return this.targetNodeIsIdentified() && this.targetedNode instanceof this.listInterface && !!this.targetedNode.querySelectorAll('li').length;
}
}, {
key: "canBeDropped",
value: function canBeDropped() {
return this.targetNodeIsIdentified() && !this.targetNodeIsBeingDragged() && !this.targetNodeIsListWithItems() && !this.areNested(this.targetedNode, this.draggedNode);
}
}, {
key: "cleanupPlaceholderLists",
value: function cleanupPlaceholderLists() {
var _this$getSortableList2,
_this4 = this;
return this.getTargetedNodeDepth() >= this.nestingLevels
}
analysePlaceHolderSituation() {
if (!this.targetedNode || this.areNested(this.targetedNode, this.draggedNode)) {
return []
var tag = this.getListTagName();
var listsArray = ((_this$getSortableList2 = this.getSortableList()) === null || _this$getSortableList2 === void 0 ? void 0 : _this$getSortableList2.querySelectorAll(tag)) || [];
Array.from(listsArray).forEach(function (ul) {
if (!ul.querySelectorAll('li').length) {
ul.remove();
} else if (ul.classList.contains(_this4.classNames.placeholder)) {
ul.classList.remove(_this4.classNames.placeholder);
ul.style.minHeight = 'auto';
ul.dataset.id = ul.parentNode.dataset.id;
}
});
}
}, {
key: "initPlaceholderList",
value: function initPlaceholderList() {
var _this$placeholderList;
let actions = [];
this.placeholderList = document.createElement(this.getListTagName());
if (!this.cursorIsIndentedEnough() || this.mouseIsTooCloseToTop()) {
if (!this.targetedNodeIsPlaceholder()) {
actions.push('cleanup');
}
} else if (this.targetedNode !== this.draggedNode
&& this.targetedNode.nodeName === 'LI'
&& !this.targetedNode.querySelectorAll(this.getListTagName()).length
&& !this.nestingThresholdReached()) {
actions.push('add');
(_this$placeholderList = this.placeholderList.classList).add.apply(_this$placeholderList, [this.classNames.placeholder].concat(_toConsumableArray(this.listClassNames)));
}
}, {
key: "getPlaceholderList",
value: function getPlaceholderList() {
this.placeholderInUse = this.placeholderList.cloneNode(true);
return this.placeholderInUse;
}
}]);
return actions
}
return NestedSort;
}();
animatePlaceholderList() {
this.placeholderInUse.style.minHeight = '0';
this.placeholderInUse.style.transition = 'min-height ease .2s';
this.placeholderInUse.style.minHeight = `${this.draggedNode.offsetHeight}px`;
}
addPlaceholderList() {
this.getPlaceholderList();
this.targetedNode.appendChild(this.placeholderInUse);
this.animatePlaceholderList();
}
targetNodeIsIdentified() {
return !!this.targetedNode
}
targetNodeIsBeingDragged() {
return this.targetNodeIsIdentified()
&& this.targetedNode === this.draggedNode
}
targetNodeIsListWithItems() {
return this.targetNodeIsIdentified()
&& this.targetedNode instanceof this.listInterface
&& this.targetedNode.querySelectorAll('li').length
}
canBeDropped() {
return this.targetNodeIsIdentified()
&& !this.targetNodeIsBeingDragged()
&& !this.targetNodeIsListWithItems()
&& !this.areNested(this.targetedNode, this.draggedNode)
}
cleanupPlaceholderLists() {
this.getSortableList().querySelectorAll(this.getListTagName()).forEach(ul => {
if (!ul.querySelectorAll('li').length) {
ul.remove();
} else if (ul.classList.contains(this.classNames.placeholder)) {
ul.classList.remove(this.classNames.placeholder);
ul.style.minHeight = 'auto';
ul.dataset.id = ul.parentNode.dataset.id;
}
});
}
initPlaceholderList() {
this.placeholderList = document.createElement(this.getListTagName());
this.placeholderList.classList.add(this.classNames.placeholder, ...this.listClassNames);
}
getPlaceholderList() {
this.placeholderInUse = this.placeholderList.cloneNode(true);
return this.placeholderInUse
}
}
export default NestedSort;
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.NestedSort = factory());
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.NestedSort = factory());
}(this, (function () { 'use strict';
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) {
arr2[i] = arr[i];
}
return arr2;
}
var arrayLikeToArray = _arrayLikeToArray;
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return arrayLikeToArray(arr);
}
var arrayWithoutHoles = _arrayWithoutHoles;
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
var iterableToArray = _iterableToArray;
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
}
var unsupportedIterableToArray = _unsupportedIterableToArray;
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var nonIterableSpread = _nonIterableSpread;
function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
}
var toConsumableArray = _toConsumableArray;
function _classCallCheck(instance, Constructor) {

@@ -60,4 +13,2 @@ if (!(instance instanceof Constructor)) {

var classCallCheck = _classCallCheck;
function _defineProperties(target, props) {

@@ -79,4 +30,2 @@ for (var i = 0; i < props.length; i++) {

var createClass = _createClass;
function _defineProperty(obj, key, value) {

@@ -97,9 +46,38 @@ if (key in obj) {

var defineProperty = _defineProperty;
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var DataEngine = /*#__PURE__*/function () {
/**
* @constructor
* @param {object[]} [data]
* @param {object} [propertyMap={}]
*/

@@ -111,4 +89,12 @@ function DataEngine(_ref) {

classCallCheck(this, DataEngine);
_classCallCheck(this, DataEngine);
_defineProperty(this, "data", void 0);
_defineProperty(this, "sortedData", void 0);
_defineProperty(this, "sortedDataDomArray", void 0);
_defineProperty(this, "propertyMap", void 0);
this.data = data;

@@ -121,3 +107,3 @@ this.sortedData = [];

createClass(DataEngine, [{
_createClass(DataEngine, [{
key: "maybeTransformData",

@@ -135,7 +121,2 @@ value: function maybeTransformData() {

}
/**
* @param {PropertyKey} prop
* @returns {PropertyKey}
*/
}, {

@@ -155,6 +136,2 @@ key: "getItemPropProxyName",

}
/**
* @returns {object[]}
*/
}, {

@@ -165,3 +142,3 @@ key: "sortListItems",

var items = toConsumableArray(this.data);
var items = _toConsumableArray(this.data);

@@ -189,11 +166,5 @@ var topLevelItems = items.filter(function (a) {

});
this.sortedData = [].concat(toConsumableArray(topLevelItems), toConsumableArray(Object.values(childItems).flat()));
this.sortedData = [].concat(_toConsumableArray(topLevelItems), _toConsumableArray(Object.values(childItems).flat()));
return this.sortedData;
}
/**
* @param {object[]} item
* @param {string} nodeName
* @returns {HTMLElement}
*/
}, {

@@ -207,11 +178,5 @@ key: "createItemElement",

el.dataset.id = id;
if (nodeName === 'li') el.innerHTML = text;
if (nodeName === 'li' && text) el.innerHTML = text;
return el;
}
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {boolean}
*/
}, {

@@ -222,9 +187,2 @@ key: "elementIsParentOfItem",

}
/**
* @param {HTMLElement} node
* @param {object} item
* @param {string} nodeName
* @returns {Element|null}
*/
}, {

@@ -235,8 +193,2 @@ key: "getParentNodeOfItem",

}
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {boolean}
*/
}, {

@@ -247,8 +199,2 @@ key: "elementIsAncestorOfItem",

}
/**
* @param {HTMLElement} node
* @param {object} item
* @returns {HTMLElement}
*/
}, {

@@ -259,7 +205,2 @@ key: "getDirectListParentOfItem",

}
/**
* @param {object} item
* @returns {boolean}
*/
}, {

@@ -290,6 +231,2 @@ key: "maybeAppendItemToParentDom",

}
/**
* @returns {array}
*/
}, {

@@ -305,3 +242,3 @@ key: "getListItemsDom",

processedItems = this.sortedData.reduce(function (processedItems, item) {
var id = item.id;
var id = item.id.toString();
if (processedItems.includes(id)) return processedItems;

@@ -327,7 +264,2 @@ var itemAdded;

}
/**
* @param {HTMLOListElement|HTMLUListElement} list
* @returns {object[]}
*/
}, {

@@ -338,3 +270,3 @@ key: "convertDomToData",

return Array.from(list.querySelectorAll('li')).map(function (li) {
return Array.from((list === null || list === void 0 ? void 0 : list.querySelectorAll('li')) || []).map(function (li) {
var _ref2;

@@ -347,9 +279,5 @@

}) + 1;
return _ref2 = {}, defineProperty(_ref2, _this4.getItemPropProxyName('id'), li.dataset.id), defineProperty(_ref2, _this4.getItemPropProxyName('parent'), parent), defineProperty(_ref2, _this4.getItemPropProxyName('order'), order), _ref2;
return _ref2 = {}, _defineProperty(_ref2, _this4.getItemPropProxyName('id'), li.dataset.id), _defineProperty(_ref2, _this4.getItemPropProxyName('parent'), parent), _defineProperty(_ref2, _this4.getItemPropProxyName('order'), order), _ref2;
});
}
/**
* @returns {HTMLOListElement}
*/
}, {

@@ -370,18 +298,5 @@ key: "render",

var NestedSort = /*#__PURE__*/function () {
/**
* @constructor
* @param {object} [actions={}]
* @param {array} [data]
* @param {number} [droppingEdge=15]
* @param {string|HTMLElement} el
* @param {boolean} [init=true]
* @param {array|string} [listClassNames]
* @param {array|string} [listItemClassNames]
* @param {number|string} [nestingLevels]
* @param {object} [propertyMap={}]
*/
function NestedSort(_ref) {
var _ref$actions = _ref.actions;
_ref$actions = _ref$actions === void 0 ? {} : _ref$actions;
var onDrop = _ref$actions.onDrop,
var _ref$actions = _ref.actions,
actions = _ref$actions === void 0 ? {} : _ref$actions,
data = _ref.data,

@@ -399,11 +314,51 @@ _ref$droppingEdge = _ref.droppingEdge,

classCallCheck(this, NestedSort);
_classCallCheck(this, NestedSort);
_defineProperty(this, "actions", void 0);
_defineProperty(this, "classNames", void 0);
_defineProperty(this, "cursor", void 0);
_defineProperty(this, "data", void 0);
_defineProperty(this, "dataEngine", void 0);
_defineProperty(this, "distances", void 0);
_defineProperty(this, "draggedNode", void 0);
_defineProperty(this, "initialised", void 0);
_defineProperty(this, "listClassNames", void 0);
_defineProperty(this, "listEventListeners", void 0);
_defineProperty(this, "listInterface", void 0);
_defineProperty(this, "listItemClassNames", void 0);
_defineProperty(this, "mainListClassName", void 0);
_defineProperty(this, "nestingLevels", void 0);
_defineProperty(this, "placeholderList", void 0);
_defineProperty(this, "placeholderInUse", void 0);
_defineProperty(this, "propertyMap", void 0);
_defineProperty(this, "sortableList", void 0);
_defineProperty(this, "targetedNode", void 0);
_defineProperty(this, "targetNode", void 0);
_defineProperty(this, "wrapper", void 0);
var element = typeof el === 'string' ? document.querySelector(el) : el;
var elementIsAList = element instanceof HTMLOListElement || element instanceof HTMLUListElement;
this.wrapper = elementIsAList ? undefined : element;
this.sortableList = elementIsAList ? element : null;
this.data = data;
this.selector = el;
this.sortableList = null;
this.placeholderList = null;
this.placeholderInUse = null;
this.draggedNode = null;
this.targetedNode = null;
this.listClassNames = this.createListClassNamesArray(listClassNames);

@@ -414,25 +369,8 @@ this.mainListClassName = this.listClassNames[0] || 'nested-sort';

this.actions = {
onDrop: onDrop
onDrop: actions.onDrop
};
this.initialised = false;
this.targetNode = {
X: null,
Y: null
};
this.distances = {
droppingEdge: droppingEdge,
droppingEdgeNegative: droppingEdge * -1,
mouseTo: {
targetedElTop: undefined
}
droppingEdge: droppingEdge
};
this.dimensions = {
targetedEl: {
H: undefined
}
};
this.cursor = {
X: null,
Y: null
};
this.classNames = {

@@ -459,8 +397,7 @@ dragged: 'ns-dragged',

createClass(NestedSort, [{
_createClass(NestedSort, [{
key: "getListInterface",
value: function getListInterface() {
if (Array.isArray(this.data) && this.data.length) return HTMLOListElement;
var el = this.selector instanceof HTMLElement ? this.selector : document.querySelector(this.selector);
return el instanceof HTMLOListElement ? HTMLOListElement : HTMLUListElement;
return this.sortableList instanceof HTMLOListElement ? HTMLOListElement : HTMLUListElement;
}

@@ -470,6 +407,3 @@ }, {

value: function getDataEngine() {
if (this.dataEngine instanceof DataEngine) {
return this.dataEngine;
}
if (this.dataEngine) return this.dataEngine;
this.dataEngine = new DataEngine({

@@ -490,7 +424,6 @@ data: this.data,

value: function maybeInitDataDom() {
if (!(Array.isArray(this.data) && this.data.length)) return;
var wrapper = document.querySelector(this.selector);
if (!(Array.isArray(this.data) && this.data.length && this.wrapper)) return;
var list = this.getDataEngine().render();
wrapper.innerHTML = '';
wrapper.appendChild(list);
this.wrapper.innerHTML = '';
this.wrapper.appendChild(list);
}

@@ -505,11 +438,6 @@ }, {

value: function getSortableList() {
var _this$wrapper;
if (this.sortableList instanceof this.listInterface) return this.sortableList;
if (this.selector instanceof this.listInterface) {
this.sortableList = this.selector;
} else {
var list = document.querySelector(this.selector);
this.sortableList = list instanceof this.listInterface ? list : list.querySelector(this.getListTagName());
}
this.sortableList = (_this$wrapper = this.wrapper) === null || _this$wrapper === void 0 ? void 0 : _this$wrapper.querySelector(this.getListTagName());
return this.sortableList;

@@ -524,4 +452,5 @@ }

var list = this.getSortableList();
if (!list) return;
(_list$classList = list.classList).add.apply(_list$classList, toConsumableArray(this.listClassNames.concat(this.mainListClassName)));
(_list$classList = list.classList).add.apply(_list$classList, _toConsumableArray(this.listClassNames.concat(this.mainListClassName)));

@@ -531,3 +460,3 @@ list.querySelectorAll(this.getListTagName()).forEach(function (l) {

(_l$classList = l.classList).add.apply(_l$classList, toConsumableArray(_this.listClassNames));
(_l$classList = l.classList).add.apply(_l$classList, _toConsumableArray(_this.listClassNames));
});

@@ -537,3 +466,3 @@ list.querySelectorAll('li').forEach(function (li) {

(_li$classList = li.classList).add.apply(_li$classList, toConsumableArray(_this.listItemClassNames));
(_li$classList = li.classList).add.apply(_li$classList, _toConsumableArray(_this.listItemClassNames));
});

@@ -545,5 +474,6 @@ }

var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var list = this.getSortableList();
if (!list) return;
var className = "".concat(this.mainListClassName, "--enabled");
var classList = this.getSortableList().classList;
return enabled ? classList.add(className) : classList.remove(className);
enabled ? list.classList.add(className) : list.classList.remove(className);
}

@@ -553,5 +483,7 @@ }, {

value: function toggleListItemAttributes() {
var _this$getSortableList;
var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
this.getSortableList().querySelectorAll('li').forEach(function (el) {
el.setAttribute('draggable', enable);
(_this$getSortableList = this.getSortableList()) === null || _this$getSortableList === void 0 ? void 0 : _this$getSortableList.querySelectorAll('li').forEach(function (el) {
el.setAttribute('draggable', enable.toString());
});

@@ -566,8 +498,5 @@ }

var list = this.getSortableList();
if (!list) return;
Object.keys(this.listEventListeners).forEach(function (event) {
if (remove) {
list.removeEventListener(event, _this2.listEventListeners[event]);
} else {
list.addEventListener(event, _this2.listEventListeners[event], false);
}
remove ? list.removeEventListener(event, _this2.listEventListeners[event]) : list.addEventListener(event, _this2.listEventListeners[event], false);
});

@@ -600,3 +529,3 @@ }

key: "removeClassFromEl",
value: function removeClassFromEl(el, className) {
value: function removeClassFromEl(className, el) {
if (el && el.classList.contains(className)) {

@@ -615,5 +544,7 @@ el.classList.remove(className);

value: function onDragStart(e) {
var _e$dataTransfer;
this.draggedNode = e.target;
this.draggedNode.classList.add(this.classNames.dragged);
e.dataTransfer.setData('text', 'Drag started!'); // Hack for Firefox!
(_e$dataTransfer = e.dataTransfer) === null || _e$dataTransfer === void 0 ? void 0 : _e$dataTransfer.setData('text', 'Drag started!'); // Hack for Firefox!
}

@@ -626,3 +557,3 @@ }, {

this.updateCoordination(e);
this.managePlaceholderLists(e);
this.managePlaceholderLists();
}

@@ -633,3 +564,3 @@ }, {

if (!this.canBeTargeted(e.target)) return;
this.removeClassFromEl(this.targetedNode, this.classNames.targeted);
this.removeClassFromEl(this.classNames.targeted, this.targetedNode);
this.targetedNode = e.target;

@@ -642,7 +573,7 @@ this.targetedNode.classList.add(this.classNames.targeted);

e.stopPropagation();
this.removeClassFromEl(this.draggedNode, this.classNames.dragged);
this.removeClassFromEl(this.targetedNode, this.classNames.targeted);
this.removeClassFromEl(this.classNames.dragged, this.draggedNode);
this.removeClassFromEl(this.classNames.targeted, this.targetedNode);
this.cleanupPlaceholderLists();
this.draggedNode = null;
this.targetedNode = null;
delete this.draggedNode;
delete this.targetedNode;
}

@@ -670,3 +601,5 @@ }, {

if (this.canBeDropped()) {
if (this.targetedNode.nodeName === 'LI' && !this.cursorIsIndentedEnough()) return 'before';else if (this.targetedNode instanceof this.listInterface) return 'inside';
var _this$targetedNode;
if (((_this$targetedNode = this.targetedNode) === null || _this$targetedNode === void 0 ? void 0 : _this$targetedNode.nodeName) === 'LI') return 'before';else if (this.targetedNode instanceof this.listInterface) return 'inside';
}

@@ -676,5 +609,5 @@ }

key: "maybeDrop",
value: function maybeDrop(e) {
value: function maybeDrop() {
var location = this.getDropLocation();
if (location) this.dropTheItem(location, e);
if (location) this.dropTheItem(location);
}

@@ -684,9 +617,11 @@ }, {

value: function dropTheItem(place) {
var _this$targetedNode2, _this$targetedNode2$p, _this$targetedNode3;
switch (place) {
case 'before':
this.targetedNode.parentNode.insertBefore(this.draggedNode, this.targetedNode);
(_this$targetedNode2 = this.targetedNode) === null || _this$targetedNode2 === void 0 ? void 0 : (_this$targetedNode2$p = _this$targetedNode2.parentNode) === null || _this$targetedNode2$p === void 0 ? void 0 : _this$targetedNode2$p.insertBefore(this.draggedNode, this.targetedNode);
break;
case 'inside':
this.targetedNode.appendChild(this.draggedNode);
(_this$targetedNode3 = this.targetedNode) === null || _this$targetedNode3 === void 0 ? void 0 : _this$targetedNode3.appendChild(this.draggedNode);
break;

@@ -699,4 +634,6 @@ }

// we're having the client coords because on the next lines, we use getBoundingClientRect which behaves in the same way
this.cursor.X = e.clientX;
this.cursor.Y = e.clientY;
this.cursor = {
X: e.clientX,
Y: e.clientY
};
}

@@ -711,9 +648,13 @@ }, {

var offset = this.targetedNode.getBoundingClientRect();
this.targetNode.X = offset.left;
this.targetNode.Y = offset.top;
this.targetNode = {
X: offset.left,
Y: offset.top
};
var result = this.targetNode.Y - this.cursor.Y;
this.distances.mouseTo.targetedElTop = result;
this.distances.mouseTo.targetedElTopAbs = Math.abs(result);
this.dimensions.targetedEl.H = this.targetedNode.clientHeight;
this.distances.mouseTo.targetedElBot = this.distances.mouseTo.targetedElTopAbs - this.dimensions.targetedEl.H;
var targetedElTopAbs = Math.abs(result);
this.distances.mouseTo = {
targetedElTop: result,
targetedElTopAbs: targetedElTopAbs,
targetedElBot: targetedElTopAbs - this.targetedNode.clientHeight
};
}

@@ -723,3 +664,3 @@ }, {

value: function areNested(child, parent) {
return parent && Array.from(parent.querySelectorAll('li')).some(function (li) {
return !!child && !!parent && Array.from(parent === null || parent === void 0 ? void 0 : parent.querySelectorAll('li')).some(function (li) {
return li === child;

@@ -736,2 +677,5 @@ });

value: function mouseIsTooCloseToTop() {
var _this$distances;
if (!((_this$distances = this.distances) !== null && _this$distances !== void 0 && _this$distances.droppingEdge)) return false;
return this.cursor.Y - this.targetNode.Y < this.distances.droppingEdge;

@@ -741,6 +685,6 @@ }

key: "managePlaceholderLists",
value: function managePlaceholderLists(e) {
value: function managePlaceholderLists() {
var _this3 = this;
var actions = this.analysePlaceHolderSituation(e);
var actions = this.analysePlaceHolderSituation();
actions.forEach(function (action) {

@@ -774,5 +718,7 @@ switch (action) {

while (list !== el.parentElement) {
if (el.parentElement instanceof this.listInterface) depth++;
el = el.parentElement;
while (list !== ((_el = el) === null || _el === void 0 ? void 0 : _el.parentElement)) {
var _el, _el2, _el3;
if (((_el2 = el) === null || _el2 === void 0 ? void 0 : _el2.parentElement) instanceof this.listInterface) depth++;
el = (_el3 = el) === null || _el3 === void 0 ? void 0 : _el3.parentElement;
}

@@ -811,5 +757,7 @@

value: function animatePlaceholderList() {
var _this$draggedNode;
this.placeholderInUse.style.minHeight = '0';
this.placeholderInUse.style.transition = 'min-height ease .2s';
this.placeholderInUse.style.minHeight = "".concat(this.draggedNode.offsetHeight, "px");
this.placeholderInUse.style.minHeight = "".concat((_this$draggedNode = this.draggedNode) === null || _this$draggedNode === void 0 ? void 0 : _this$draggedNode.offsetHeight, "px");
}

@@ -819,4 +767,6 @@ }, {

value: function addPlaceholderList() {
var _this$targetedNode4;
this.getPlaceholderList();
this.targetedNode.appendChild(this.placeholderInUse);
(_this$targetedNode4 = this.targetedNode) === null || _this$targetedNode4 === void 0 ? void 0 : _this$targetedNode4.appendChild(this.placeholderInUse);
this.animatePlaceholderList();

@@ -837,3 +787,3 @@ }

value: function targetNodeIsListWithItems() {
return this.targetNodeIsIdentified() && this.targetedNode instanceof this.listInterface && this.targetedNode.querySelectorAll('li').length;
return this.targetNodeIsIdentified() && this.targetedNode instanceof this.listInterface && !!this.targetedNode.querySelectorAll('li').length;
}

@@ -848,5 +798,8 @@ }, {

value: function cleanupPlaceholderLists() {
var _this4 = this;
var _this$getSortableList2,
_this4 = this;
this.getSortableList().querySelectorAll(this.getListTagName()).forEach(function (ul) {
var tag = this.getListTagName();
var listsArray = ((_this$getSortableList2 = this.getSortableList()) === null || _this$getSortableList2 === void 0 ? void 0 : _this$getSortableList2.querySelectorAll(tag)) || [];
Array.from(listsArray).forEach(function (ul) {
if (!ul.querySelectorAll('li').length) {

@@ -868,3 +821,3 @@ ul.remove();

(_this$placeholderList = this.placeholderList.classList).add.apply(_this$placeholderList, [this.classNames.placeholder].concat(toConsumableArray(this.listClassNames)));
(_this$placeholderList = this.placeholderList.classList).add.apply(_this$placeholderList, [this.classNames.placeholder].concat(_toConsumableArray(this.listClassNames)));
}

@@ -871,0 +824,0 @@ }, {

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).NestedSort=t()}(this,(function(){"use strict";var e=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var s=0,i=new Array(t);s<t;s++)i[s]=e[s];return i};var t=function(t){if(Array.isArray(t))return e(t)};var s=function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)};var i=function(t,s){if(t){if("string"==typeof t)return e(t,s);var i=Object.prototype.toString.call(t).slice(8,-1);return"Object"===i&&t.constructor&&(i=t.constructor.name),"Map"===i||"Set"===i?Array.from(i):"Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?e(t,s):void 0}};var a=function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")};var r=function(e){return t(e)||s(e)||i(e)||a()};var n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")};function o(e,t){for(var s=0;s<t.length;s++){var i=t[s];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var l=function(e,t,s){return t&&o(e.prototype,t),s&&o(e,s),e};var d=function(e,t,s){return t in e?Object.defineProperty(e,t,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[t]=s,e},h=function(){function e(t){var s=t.data,i=t.propertyMap,a=void 0===i?{}:i;n(this,e),this.data=s,this.sortedData=[],this.sortedDataDomArray=[],this.propertyMap=a,this.maybeTransformData()}return l(e,[{key:"maybeTransformData",value:function(){if(Object.keys(this.propertyMap).length&&Array.isArray(this.data)){var e=this.getItemPropProxyName.bind(this);this.data=this.data.map((function(t){return new Proxy(t,{get:function(t,s,i){return Reflect.get(t,e(s),i)}})}))}}},{key:"getItemPropProxyName",value:function(e){return Object.prototype.hasOwnProperty.call(this.propertyMap,e)?this.propertyMap[e]:e}},{key:"isTopLevelItem",value:function(e){return!e.parent}},{key:"sortListItems",value:function(){var e=this,t=r(this.data),s=t.filter((function(t){return e.isTopLevelItem(t)})).sort((function(e,t){return e.order&&t.order?e.order-t.order:0})),i=t.filter((function(t){return!e.isTopLevelItem(t)})).reduce((function(e,t){return Object.prototype.hasOwnProperty.call(e,t.parent)?e[t.parent].push(t):e[t.parent]=[t],e}),{});return Object.keys(i).forEach((function(e){i[e].sort((function(e,t){return e.order&&t.order?e.order-t.order:0}))})),this.sortedData=[].concat(r(s),r(Object.values(i).flat())),this.sortedData}},{key:"createItemElement",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"li",s=e.id,i=e.text,a=document.createElement(t);return a.dataset.id=s,"li"===t&&(a.innerHTML=i),a}},{key:"elementIsParentOfItem",value:function(e,t){return e.dataset.id==="".concat(t.parent)}},{key:"getParentNodeOfItem",value:function(e,t,s){return e.querySelector("".concat(s,'[data-id="').concat(t.parent,'"]'))}},{key:"elementIsAncestorOfItem",value:function(e,t){return!!this.getParentNodeOfItem(e,t,"li")}},{key:"getDirectListParentOfItem",value:function(e,t){return this.getParentNodeOfItem(e,t,"ol")}},{key:"maybeAppendItemToParentDom",value:function(e){var t=this,s=e.parent,i=this.sortedDataDomArray.find((function(s){return t.elementIsParentOfItem(s,e)||t.elementIsAncestorOfItem(s,e)}));if(!i)return!1;var a=this.createItemElement(e),r=this.getDirectListParentOfItem(i,e);r||(r=this.createItemElement({id:s},"ol"),(this.getParentNodeOfItem(i,e,"li")||i).appendChild(r));return r.appendChild(a),!0}},{key:"getListItemsDom",value:function(){var e=this;this.sortedDataDomArray=[];for(var t=[];t.length!==this.sortListItems().length;)t=this.sortedData.reduce((function(t,s){var i,a=s.id;if(t.includes(a))return t;if(s.parent)i=e.maybeAppendItemToParentDom(s);else{var r=e.createItemElement(s);e.sortedDataDomArray.push(r),i=!0}return i&&t.push(a),t}),t);return this.sortedDataDomArray}},{key:"convertDomToData",value:function(e){var t=this;return Array.from(e.querySelectorAll("li")).map((function(e){var s,i=e.parentNode,a=i.dataset.id,r=Array.from(i.children).findIndex((function(t){return t===e}))+1;return d(s={},t.getItemPropProxyName("id"),e.dataset.id),d(s,t.getItemPropProxyName("parent"),a),d(s,t.getItemPropProxyName("order"),r),s}))}},{key:"render",value:function(){var e=document.createElement("ol");return this.getListItemsDom().forEach((function(t){return e.appendChild(t)})),e}}]),e}();return function(){function e(t){var s=t.actions,i=(s=void 0===s?{}:s).onDrop,a=t.data,r=t.droppingEdge,o=void 0===r?15:r,l=t.el,d=t.init,h=void 0===d||d,c=t.listClassNames,u=t.listItemClassNames,g=t.nestingLevels,f=t.propertyMap,m=void 0===f?{}:f;n(this,e),this.data=a,this.selector=l,this.sortableList=null,this.placeholderList=null,this.placeholderInUse=null,this.draggedNode=null,this.targetedNode=null,this.listClassNames=this.createListClassNamesArray(c),this.mainListClassName=this.listClassNames[0]||"nested-sort",this.listItemClassNames=this.createListClassNamesArray(u),this.propertyMap=m,this.actions={onDrop:i},this.initialised=!1,this.targetNode={X:null,Y:null},this.distances={droppingEdge:o,droppingEdgeNegative:-1*o,mouseTo:{targetedElTop:void 0}},this.dimensions={targetedEl:{H:void 0}},this.cursor={X:null,Y:null},this.classNames={dragged:"ns-dragged",placeholder:"ns-placeholder",targeted:"ns-targeted"},this.listEventListeners={dragover:this.onDragOver.bind(this),dragstart:this.onDragStart.bind(this),dragenter:this.onDragEnter.bind(this),dragend:this.onDragEnd.bind(this),drop:this.onDrop.bind(this)};var p=parseInt(g);this.nestingLevels=isNaN(p)?-1:p,this.listInterface=this.getListInterface(),this.maybeInitDataDom(),this.addListAttributes(),h&&this.initDragAndDrop()}return l(e,[{key:"getListInterface",value:function(){return Array.isArray(this.data)&&this.data.length||(this.selector instanceof HTMLElement?this.selector:document.querySelector(this.selector))instanceof HTMLOListElement?HTMLOListElement:HTMLUListElement}},{key:"getDataEngine",value:function(){return this.dataEngine instanceof h||(this.dataEngine=new h({data:this.data,propertyMap:this.propertyMap})),this.dataEngine}},{key:"createListClassNamesArray",value:function(e){return e?Array.isArray(e)?e:e.split(" "):[]}},{key:"maybeInitDataDom",value:function(){if(Array.isArray(this.data)&&this.data.length){var e=document.querySelector(this.selector),t=this.getDataEngine().render();e.innerHTML="",e.appendChild(t)}}},{key:"getListTagName",value:function(){return this.listInterface===HTMLOListElement?"ol":"ul"}},{key:"getSortableList",value:function(){if(this.sortableList instanceof this.listInterface)return this.sortableList;if(this.selector instanceof this.listInterface)this.sortableList=this.selector;else{var e=document.querySelector(this.selector);this.sortableList=e instanceof this.listInterface?e:e.querySelector(this.getListTagName())}return this.sortableList}},{key:"addListAttributes",value:function(){var e,t=this,s=this.getSortableList();(e=s.classList).add.apply(e,r(this.listClassNames.concat(this.mainListClassName))),s.querySelectorAll(this.getListTagName()).forEach((function(e){var s;(s=e.classList).add.apply(s,r(t.listClassNames))})),s.querySelectorAll("li").forEach((function(e){var s;(s=e.classList).add.apply(s,r(t.listItemClassNames))}))}},{key:"toggleMainListLifeCycleClassName",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t="".concat(this.mainListClassName,"--enabled"),s=this.getSortableList().classList;return e?s.add(t):s.remove(t)}},{key:"toggleListItemAttributes",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.getSortableList().querySelectorAll("li").forEach((function(t){t.setAttribute("draggable",e)}))}},{key:"toggleListEventListeners",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],s=this.getSortableList();Object.keys(this.listEventListeners).forEach((function(i){t?s.removeEventListener(i,e.listEventListeners[i]):s.addEventListener(i,e.listEventListeners[i],!1)}))}},{key:"initDragAndDrop",value:function(){this.initialised||(this.toggleListEventListeners(),this.initPlaceholderList(),this.toggleListItemAttributes(),this.toggleMainListLifeCycleClassName(),this.initialised=!0)}},{key:"init",value:function(){this.initDragAndDrop()}},{key:"destroy",value:function(){this.toggleListEventListeners(!0),this.toggleListItemAttributes(!1),this.toggleMainListLifeCycleClassName(!1),this.initialised=!1}},{key:"removeClassFromEl",value:function(e,t){e&&e.classList.contains(t)&&e.classList.remove(t)}},{key:"canBeTargeted",value:function(e){return!(!this.draggedNode||this.draggedNode===e)&&("LI"===e.nodeName||e instanceof this.listInterface&&e.classList.contains(this.classNames.placeholder))}},{key:"onDragStart",value:function(e){this.draggedNode=e.target,this.draggedNode.classList.add(this.classNames.dragged),e.dataTransfer.setData("text","Drag started!")}},{key:"onDragOver",value:function(e){e.preventDefault(),this.updateCoordination(e),this.managePlaceholderLists(e)}},{key:"onDragEnter",value:function(e){this.canBeTargeted(e.target)&&(this.removeClassFromEl(this.targetedNode,this.classNames.targeted),this.targetedNode=e.target,this.targetedNode.classList.add(this.classNames.targeted))}},{key:"onDragEnd",value:function(e){e.stopPropagation(),this.removeClassFromEl(this.draggedNode,this.classNames.dragged),this.removeClassFromEl(this.targetedNode,this.classNames.targeted),this.cleanupPlaceholderLists(),this.draggedNode=null,this.targetedNode=null}},{key:"onDrop",value:function(e){e.stopPropagation(),this.maybeDrop(),this.cleanupPlaceholderLists(),"function"==typeof this.actions.onDrop&&this.actions.onDrop(this.getDataEngine().convertDomToData(this.getSortableList()))}},{key:"updateCoordination",value:function(e){this.calcMouseCoords(e),this.calcMouseToTargetedElDist()}},{key:"getDropLocation",value:function(){if(this.canBeDropped()){if("LI"===this.targetedNode.nodeName&&!this.cursorIsIndentedEnough())return"before";if(this.targetedNode instanceof this.listInterface)return"inside"}}},{key:"maybeDrop",value:function(e){var t=this.getDropLocation();t&&this.dropTheItem(t,e)}},{key:"dropTheItem",value:function(e){switch(e){case"before":this.targetedNode.parentNode.insertBefore(this.draggedNode,this.targetedNode);break;case"inside":this.targetedNode.appendChild(this.draggedNode)}}},{key:"calcMouseCoords",value:function(e){this.cursor.X=e.clientX,this.cursor.Y=e.clientY}},{key:"calcMouseToTargetedElDist",value:function(){if(this.targetedNode){var e=this.targetedNode.getBoundingClientRect();this.targetNode.X=e.left,this.targetNode.Y=e.top;var t=this.targetNode.Y-this.cursor.Y;this.distances.mouseTo.targetedElTop=t,this.distances.mouseTo.targetedElTopAbs=Math.abs(t),this.dimensions.targetedEl.H=this.targetedNode.clientHeight,this.distances.mouseTo.targetedElBot=this.distances.mouseTo.targetedElTopAbs-this.dimensions.targetedEl.H}}},{key:"areNested",value:function(e,t){return t&&Array.from(t.querySelectorAll("li")).some((function(t){return t===e}))}},{key:"cursorIsIndentedEnough",value:function(){return this.cursor.X-this.targetNode.X>50}},{key:"mouseIsTooCloseToTop",value:function(){return this.cursor.Y-this.targetNode.Y<this.distances.droppingEdge}},{key:"managePlaceholderLists",value:function(e){var t=this;this.analysePlaceHolderSituation(e).forEach((function(e){switch(e){case"add":t.cleanupPlaceholderLists(),t.addPlaceholderList();break;case"cleanup":t.cleanupPlaceholderLists()}}))}},{key:"targetedNodeIsPlaceholder",value:function(){return this.targetedNode instanceof this.listInterface&&this.targetedNode.classList.contains(this.classNames.placeholder)}},{key:"getTargetedNodeDepth",value:function(){for(var e=0,t=this.targetedNode,s=this.getSortableList();s!==t.parentElement;)t.parentElement instanceof this.listInterface&&e++,t=t.parentElement;return e}},{key:"nestingThresholdReached",value:function(){return!(this.nestingLevels<0)&&(0===this.nestingLevels||this.getTargetedNodeDepth()>=this.nestingLevels)}},{key:"analysePlaceHolderSituation",value:function(){if(!this.targetedNode||this.areNested(this.targetedNode,this.draggedNode))return[];var e=[];return!this.cursorIsIndentedEnough()||this.mouseIsTooCloseToTop()?this.targetedNodeIsPlaceholder()||e.push("cleanup"):this.targetedNode===this.draggedNode||"LI"!==this.targetedNode.nodeName||this.targetedNode.querySelectorAll(this.getListTagName()).length||this.nestingThresholdReached()||e.push("add"),e}},{key:"animatePlaceholderList",value:function(){this.placeholderInUse.style.minHeight="0",this.placeholderInUse.style.transition="min-height ease .2s",this.placeholderInUse.style.minHeight="".concat(this.draggedNode.offsetHeight,"px")}},{key:"addPlaceholderList",value:function(){this.getPlaceholderList(),this.targetedNode.appendChild(this.placeholderInUse),this.animatePlaceholderList()}},{key:"targetNodeIsIdentified",value:function(){return!!this.targetedNode}},{key:"targetNodeIsBeingDragged",value:function(){return this.targetNodeIsIdentified()&&this.targetedNode===this.draggedNode}},{key:"targetNodeIsListWithItems",value:function(){return this.targetNodeIsIdentified()&&this.targetedNode instanceof this.listInterface&&this.targetedNode.querySelectorAll("li").length}},{key:"canBeDropped",value:function(){return this.targetNodeIsIdentified()&&!this.targetNodeIsBeingDragged()&&!this.targetNodeIsListWithItems()&&!this.areNested(this.targetedNode,this.draggedNode)}},{key:"cleanupPlaceholderLists",value:function(){var e=this;this.getSortableList().querySelectorAll(this.getListTagName()).forEach((function(t){t.querySelectorAll("li").length?t.classList.contains(e.classNames.placeholder)&&(t.classList.remove(e.classNames.placeholder),t.style.minHeight="auto",t.dataset.id=t.parentNode.dataset.id):t.remove()}))}},{key:"initPlaceholderList",value:function(){var e;this.placeholderList=document.createElement(this.getListTagName()),(e=this.placeholderList.classList).add.apply(e,[this.classNames.placeholder].concat(r(this.listClassNames)))}},{key:"getPlaceholderList",value:function(){return this.placeholderInUse=this.placeholderList.cloneNode(!0),this.placeholderInUse}}]),e}()}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).NestedSort=t()}(this,(function(){"use strict";function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var i=0;i<t.length;i++){var s=t[i];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}function i(e,i,s){return i&&t(e.prototype,i),s&&t(e,s),e}function s(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e){return function(e){if(Array.isArray(e))return r(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var i=Object.prototype.toString.call(e).slice(8,-1);"Object"===i&&e.constructor&&(i=e.constructor.name);if("Map"===i||"Set"===i)return Array.from(e);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return r(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,s=new Array(t);i<t;i++)s[i]=e[i];return s}var n=function(){function t(i){var a=i.data,r=i.propertyMap,n=void 0===r?{}:r;e(this,t),s(this,"data",void 0),s(this,"sortedData",void 0),s(this,"sortedDataDomArray",void 0),s(this,"propertyMap",void 0),this.data=a,this.sortedData=[],this.sortedDataDomArray=[],this.propertyMap=n,this.maybeTransformData()}return i(t,[{key:"maybeTransformData",value:function(){if(Object.keys(this.propertyMap).length&&Array.isArray(this.data)){var e=this.getItemPropProxyName.bind(this);this.data=this.data.map((function(t){return new Proxy(t,{get:function(t,i,s){return Reflect.get(t,e(i),s)}})}))}}},{key:"getItemPropProxyName",value:function(e){return Object.prototype.hasOwnProperty.call(this.propertyMap,e)?this.propertyMap[e]:e}},{key:"isTopLevelItem",value:function(e){return!e.parent}},{key:"sortListItems",value:function(){var e=this,t=a(this.data),i=t.filter((function(t){return e.isTopLevelItem(t)})).sort((function(e,t){return e.order&&t.order?e.order-t.order:0})),s=t.filter((function(t){return!e.isTopLevelItem(t)})).reduce((function(e,t){return Object.prototype.hasOwnProperty.call(e,t.parent)?e[t.parent].push(t):e[t.parent]=[t],e}),{});return Object.keys(s).forEach((function(e){s[e].sort((function(e,t){return e.order&&t.order?e.order-t.order:0}))})),this.sortedData=[].concat(a(i),a(Object.values(s).flat())),this.sortedData}},{key:"createItemElement",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"li",i=e.id,s=e.text,a=document.createElement(t);return a.dataset.id=i,"li"===t&&s&&(a.innerHTML=s),a}},{key:"elementIsParentOfItem",value:function(e,t){return e.dataset.id==="".concat(t.parent)}},{key:"getParentNodeOfItem",value:function(e,t,i){return e.querySelector("".concat(i,'[data-id="').concat(t.parent,'"]'))}},{key:"elementIsAncestorOfItem",value:function(e,t){return!!this.getParentNodeOfItem(e,t,"li")}},{key:"getDirectListParentOfItem",value:function(e,t){return this.getParentNodeOfItem(e,t,"ol")}},{key:"maybeAppendItemToParentDom",value:function(e){var t=this,i=e.parent,s=this.sortedDataDomArray.find((function(i){return t.elementIsParentOfItem(i,e)||t.elementIsAncestorOfItem(i,e)}));if(!s)return!1;var a=this.createItemElement(e),r=this.getDirectListParentOfItem(s,e);r||(r=this.createItemElement({id:i},"ol"),(this.getParentNodeOfItem(s,e,"li")||s).appendChild(r));return r.appendChild(a),!0}},{key:"getListItemsDom",value:function(){var e=this;this.sortedDataDomArray=[];for(var t=[];t.length!==this.sortListItems().length;)t=this.sortedData.reduce((function(t,i){var s,a=i.id.toString();if(t.includes(a))return t;if(i.parent)s=e.maybeAppendItemToParentDom(i);else{var r=e.createItemElement(i);e.sortedDataDomArray.push(r),s=!0}return s&&t.push(a),t}),t);return this.sortedDataDomArray}},{key:"convertDomToData",value:function(e){var t=this;return Array.from((null==e?void 0:e.querySelectorAll("li"))||[]).map((function(e){var i,a=e.parentNode,r=a.dataset.id,n=Array.from(a.children).findIndex((function(t){return t===e}))+1;return s(i={},t.getItemPropProxyName("id"),e.dataset.id),s(i,t.getItemPropProxyName("parent"),r),s(i,t.getItemPropProxyName("order"),n),i}))}},{key:"render",value:function(){var e=document.createElement("ol");return this.getListItemsDom().forEach((function(t){return e.appendChild(t)})),e}}]),t}();return function(){function t(i){var a=i.actions,r=void 0===a?{}:a,n=i.data,o=i.droppingEdge,l=void 0===o?15:o,d=i.el,h=i.init,c=void 0===h||h,u=i.listClassNames,g=i.listItemClassNames,f=i.nestingLevels,v=i.propertyMap,p=void 0===v?{}:v;e(this,t),s(this,"actions",void 0),s(this,"classNames",void 0),s(this,"cursor",void 0),s(this,"data",void 0),s(this,"dataEngine",void 0),s(this,"distances",void 0),s(this,"draggedNode",void 0),s(this,"initialised",void 0),s(this,"listClassNames",void 0),s(this,"listEventListeners",void 0),s(this,"listInterface",void 0),s(this,"listItemClassNames",void 0),s(this,"mainListClassName",void 0),s(this,"nestingLevels",void 0),s(this,"placeholderList",void 0),s(this,"placeholderInUse",void 0),s(this,"propertyMap",void 0),s(this,"sortableList",void 0),s(this,"targetedNode",void 0),s(this,"targetNode",void 0),s(this,"wrapper",void 0);var m="string"==typeof d?document.querySelector(d):d,y=m instanceof HTMLOListElement||m instanceof HTMLUListElement;this.wrapper=y?void 0:m,this.sortableList=y?m:null,this.data=n,this.listClassNames=this.createListClassNamesArray(u),this.mainListClassName=this.listClassNames[0]||"nested-sort",this.listItemClassNames=this.createListClassNamesArray(g),this.propertyMap=p,this.actions={onDrop:r.onDrop},this.initialised=!1,this.distances={droppingEdge:l},this.classNames={dragged:"ns-dragged",placeholder:"ns-placeholder",targeted:"ns-targeted"},this.listEventListeners={dragover:this.onDragOver.bind(this),dragstart:this.onDragStart.bind(this),dragenter:this.onDragEnter.bind(this),dragend:this.onDragEnd.bind(this),drop:this.onDrop.bind(this)};var L=parseInt(f);this.nestingLevels=isNaN(L)?-1:L,this.listInterface=this.getListInterface(),this.maybeInitDataDom(),this.addListAttributes(),c&&this.initDragAndDrop()}return i(t,[{key:"getListInterface",value:function(){return Array.isArray(this.data)&&this.data.length||this.sortableList instanceof HTMLOListElement?HTMLOListElement:HTMLUListElement}},{key:"getDataEngine",value:function(){return this.dataEngine||(this.dataEngine=new n({data:this.data,propertyMap:this.propertyMap})),this.dataEngine}},{key:"createListClassNamesArray",value:function(e){return e?Array.isArray(e)?e:e.split(" "):[]}},{key:"maybeInitDataDom",value:function(){if(Array.isArray(this.data)&&this.data.length&&this.wrapper){var e=this.getDataEngine().render();this.wrapper.innerHTML="",this.wrapper.appendChild(e)}}},{key:"getListTagName",value:function(){return this.listInterface===HTMLOListElement?"ol":"ul"}},{key:"getSortableList",value:function(){var e;return this.sortableList instanceof this.listInterface||(this.sortableList=null===(e=this.wrapper)||void 0===e?void 0:e.querySelector(this.getListTagName())),this.sortableList}},{key:"addListAttributes",value:function(){var e,t=this,i=this.getSortableList();i&&((e=i.classList).add.apply(e,a(this.listClassNames.concat(this.mainListClassName))),i.querySelectorAll(this.getListTagName()).forEach((function(e){var i;(i=e.classList).add.apply(i,a(t.listClassNames))})),i.querySelectorAll("li").forEach((function(e){var i;(i=e.classList).add.apply(i,a(t.listItemClassNames))})))}},{key:"toggleMainListLifeCycleClassName",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=this.getSortableList();if(t){var i="".concat(this.mainListClassName,"--enabled");e?t.classList.add(i):t.classList.remove(i)}}},{key:"toggleListItemAttributes",value:function(){var e,t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];null===(e=this.getSortableList())||void 0===e||e.querySelectorAll("li").forEach((function(e){e.setAttribute("draggable",t.toString())}))}},{key:"toggleListEventListeners",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.getSortableList();i&&Object.keys(this.listEventListeners).forEach((function(s){t?i.removeEventListener(s,e.listEventListeners[s]):i.addEventListener(s,e.listEventListeners[s],!1)}))}},{key:"initDragAndDrop",value:function(){this.initialised||(this.toggleListEventListeners(),this.initPlaceholderList(),this.toggleListItemAttributes(),this.toggleMainListLifeCycleClassName(),this.initialised=!0)}},{key:"init",value:function(){this.initDragAndDrop()}},{key:"destroy",value:function(){this.toggleListEventListeners(!0),this.toggleListItemAttributes(!1),this.toggleMainListLifeCycleClassName(!1),this.initialised=!1}},{key:"removeClassFromEl",value:function(e,t){t&&t.classList.contains(e)&&t.classList.remove(e)}},{key:"canBeTargeted",value:function(e){return!(!this.draggedNode||this.draggedNode===e)&&("LI"===e.nodeName||e instanceof this.listInterface&&e.classList.contains(this.classNames.placeholder))}},{key:"onDragStart",value:function(e){var t;this.draggedNode=e.target,this.draggedNode.classList.add(this.classNames.dragged),null===(t=e.dataTransfer)||void 0===t||t.setData("text","Drag started!")}},{key:"onDragOver",value:function(e){e.preventDefault(),this.updateCoordination(e),this.managePlaceholderLists()}},{key:"onDragEnter",value:function(e){this.canBeTargeted(e.target)&&(this.removeClassFromEl(this.classNames.targeted,this.targetedNode),this.targetedNode=e.target,this.targetedNode.classList.add(this.classNames.targeted))}},{key:"onDragEnd",value:function(e){e.stopPropagation(),this.removeClassFromEl(this.classNames.dragged,this.draggedNode),this.removeClassFromEl(this.classNames.targeted,this.targetedNode),this.cleanupPlaceholderLists(),delete this.draggedNode,delete this.targetedNode}},{key:"onDrop",value:function(e){e.stopPropagation(),this.maybeDrop(),this.cleanupPlaceholderLists(),"function"==typeof this.actions.onDrop&&this.actions.onDrop(this.getDataEngine().convertDomToData(this.getSortableList()))}},{key:"updateCoordination",value:function(e){this.calcMouseCoords(e),this.calcMouseToTargetedElDist()}},{key:"getDropLocation",value:function(){if(this.canBeDropped()){var e;if("LI"===(null===(e=this.targetedNode)||void 0===e?void 0:e.nodeName))return"before";if(this.targetedNode instanceof this.listInterface)return"inside"}}},{key:"maybeDrop",value:function(){var e=this.getDropLocation();e&&this.dropTheItem(e)}},{key:"dropTheItem",value:function(e){var t,i,s;switch(e){case"before":null===(t=this.targetedNode)||void 0===t||null===(i=t.parentNode)||void 0===i||i.insertBefore(this.draggedNode,this.targetedNode);break;case"inside":null===(s=this.targetedNode)||void 0===s||s.appendChild(this.draggedNode)}}},{key:"calcMouseCoords",value:function(e){this.cursor={X:e.clientX,Y:e.clientY}}},{key:"calcMouseToTargetedElDist",value:function(){if(this.targetedNode){var e=this.targetedNode.getBoundingClientRect();this.targetNode={X:e.left,Y:e.top};var t=this.targetNode.Y-this.cursor.Y,i=Math.abs(t);this.distances.mouseTo={targetedElTop:t,targetedElTopAbs:i,targetedElBot:i-this.targetedNode.clientHeight}}}},{key:"areNested",value:function(e,t){return!!e&&!!t&&Array.from(null==t?void 0:t.querySelectorAll("li")).some((function(t){return t===e}))}},{key:"cursorIsIndentedEnough",value:function(){return this.cursor.X-this.targetNode.X>50}},{key:"mouseIsTooCloseToTop",value:function(){var e;return!(null===(e=this.distances)||void 0===e||!e.droppingEdge)&&this.cursor.Y-this.targetNode.Y<this.distances.droppingEdge}},{key:"managePlaceholderLists",value:function(){var e=this;this.analysePlaceHolderSituation().forEach((function(t){switch(t){case"add":e.cleanupPlaceholderLists(),e.addPlaceholderList();break;case"cleanup":e.cleanupPlaceholderLists()}}))}},{key:"targetedNodeIsPlaceholder",value:function(){return this.targetedNode instanceof this.listInterface&&this.targetedNode.classList.contains(this.classNames.placeholder)}},{key:"getTargetedNodeDepth",value:function(){for(var e=0,t=this.targetedNode,i=this.getSortableList();i!==(null===(s=t)||void 0===s?void 0:s.parentElement);){var s,a,r;(null===(a=t)||void 0===a?void 0:a.parentElement)instanceof this.listInterface&&e++,t=null===(r=t)||void 0===r?void 0:r.parentElement}return e}},{key:"nestingThresholdReached",value:function(){return!(this.nestingLevels<0)&&(0===this.nestingLevels||this.getTargetedNodeDepth()>=this.nestingLevels)}},{key:"analysePlaceHolderSituation",value:function(){if(!this.targetedNode||this.areNested(this.targetedNode,this.draggedNode))return[];var e=[];return!this.cursorIsIndentedEnough()||this.mouseIsTooCloseToTop()?this.targetedNodeIsPlaceholder()||e.push("cleanup"):this.targetedNode===this.draggedNode||"LI"!==this.targetedNode.nodeName||this.targetedNode.querySelectorAll(this.getListTagName()).length||this.nestingThresholdReached()||e.push("add"),e}},{key:"animatePlaceholderList",value:function(){var e;this.placeholderInUse.style.minHeight="0",this.placeholderInUse.style.transition="min-height ease .2s",this.placeholderInUse.style.minHeight="".concat(null===(e=this.draggedNode)||void 0===e?void 0:e.offsetHeight,"px")}},{key:"addPlaceholderList",value:function(){var e;this.getPlaceholderList(),null===(e=this.targetedNode)||void 0===e||e.appendChild(this.placeholderInUse),this.animatePlaceholderList()}},{key:"targetNodeIsIdentified",value:function(){return!!this.targetedNode}},{key:"targetNodeIsBeingDragged",value:function(){return this.targetNodeIsIdentified()&&this.targetedNode===this.draggedNode}},{key:"targetNodeIsListWithItems",value:function(){return this.targetNodeIsIdentified()&&this.targetedNode instanceof this.listInterface&&!!this.targetedNode.querySelectorAll("li").length}},{key:"canBeDropped",value:function(){return this.targetNodeIsIdentified()&&!this.targetNodeIsBeingDragged()&&!this.targetNodeIsListWithItems()&&!this.areNested(this.targetedNode,this.draggedNode)}},{key:"cleanupPlaceholderLists",value:function(){var e,t=this,i=this.getListTagName(),s=(null===(e=this.getSortableList())||void 0===e?void 0:e.querySelectorAll(i))||[];Array.from(s).forEach((function(e){e.querySelectorAll("li").length?e.classList.contains(t.classNames.placeholder)&&(e.classList.remove(t.classNames.placeholder),e.style.minHeight="auto",e.dataset.id=e.parentNode.dataset.id):e.remove()}))}},{key:"initPlaceholderList",value:function(){var e;this.placeholderList=document.createElement(this.getListTagName()),(e=this.placeholderList.classList).add.apply(e,[this.classNames.placeholder].concat(a(this.listClassNames)))}},{key:"getPlaceholderList",value:function(){return this.placeholderInUse=this.placeholderList.cloneNode(!0),this.placeholderInUse}}]),t}()}));
{
"name": "nested-sort",
"version": "5.0.0",
"author": "Hesam Bahrami (Genzo)",
"description": "A JavaScript library to create a nested list of elements",
"version": "5.0.1",
"author": "Hesam Bahrami (hesamurai)",
"description": "A JavaScript library for sorting a nested list of items via drag and drop.",
"umdClassName": "NestedSort",
"main": "dist/nested-sort.cjs.js",

@@ -16,22 +17,30 @@ "module": "dist/nested-sort.esm.js",

"devDependencies": {
"@babel/core": "7.9.0",
"@babel/core": "7.12.7",
"@babel/plugin-proposal-class-properties": "7.12.1",
"@babel/plugin-proposal-object-rest-spread": "7.12.1",
"@babel/plugin-transform-runtime": "^7.11.5",
"@babel/preset-env": "7.9.5",
"babel-core": "7.0.0-bridge.0",
"@babel/preset-env": "7.12.7",
"@babel/preset-typescript": "7.12.7",
"@rollup/plugin-babel": "5.2.1",
"@rollup/plugin-commonjs": "16.0.0",
"@rollup/plugin-eslint": "^8.0.1",
"@rollup/plugin-node-resolve": "10.0.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
"babel-jest": "24.9.0",
"concurrently": "5.3.0",
"eslint": "^7.21.0",
"husky": "^4.2.5",
"jest": "26.6.3",
"jsdom": "^16.4.0",
"rollup": "1.32.1",
"rollup-plugin-babel": "4.4.0",
"rollup-plugin-commonjs": "10.1.0",
"rollup-plugin-eslint": "^7.0.0",
"rollup-plugin-node-resolve": "5.2.0",
"rollup-plugin-terser": "^6.1.0",
"serve": "11.3.2"
"rollup": "2.33.3",
"rollup-plugin-terser": "^7.0.2",
"serve": "11.3.2",
"typescript": "4.1.2"
},
"scripts": {
"prepare": "yarn build",
"build": "rollup -c",
"build": "yarn build:types && yarn build:js",
"build:js": "rollup -c",
"build:types": "tsc --emitDeclarationOnly",
"build:watch": "rollup -c -w",

@@ -38,0 +47,0 @@ "watch": "concurrently 'yarn build:watch' 'yarn serve -l tcp://127.0.0.1'",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc