nestablejs
Advanced tools
Comparing version 0.0.8 to 0.0.9
1130
dist/nestable.js
@@ -8,1089 +8,47 @@ /*! | ||
* | ||
* Version: 0.0.8 | ||
* Version: 0.0.9 | ||
* | ||
*/ | ||
const DOM = { | ||
select: (selector, parent = document) => { | ||
return parent.querySelector(selector); | ||
}, | ||
selectAll: (selector, parent = document) => { | ||
return parent.querySelectorAll(selector); | ||
}, | ||
/** | ||
* Get an elements children that match the selector | ||
* @param {Node} elem The base element | ||
* @param {String} selector CSS3 selector string | ||
* @return {Array} | ||
*/ | ||
children: (elem, selector) => { | ||
const arr = []; | ||
const children = elem.children; | ||
const l = children.length; | ||
for (let i = 0; i < l; ++i) { | ||
const child = children[i]; | ||
if (child.matches(selector)) { | ||
arr.push(child); | ||
} | ||
} | ||
return arr; | ||
}, | ||
/** | ||
* Get all DOM element up the tree that match the selector | ||
* @param {Node} elem The base element | ||
* @param {String} selector CSS3 selector string | ||
* @return {Array} | ||
*/ | ||
parents: (elem, selector) => { | ||
// Set up a parent array | ||
var parents = []; | ||
// Push each parent element to the array | ||
for (; elem && elem !== document; elem = elem.parentNode) { | ||
if (selector) { | ||
if (elem.matches(selector)) { | ||
parents.push(elem); | ||
} | ||
continue; | ||
} | ||
parents.push(elem); | ||
} | ||
// Return our parent array | ||
return parents; | ||
}, | ||
/** | ||
* Get an element's DOMRect relative to the document instead of the viewport. | ||
* @param {Object} el HTMLElement | ||
* @return {Object} Formatted DOMRect copy | ||
*/ | ||
rect(el) { | ||
var w = window, | ||
st = (w.pageYOffset !== undefined) ? w.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop, | ||
o = el.getBoundingClientRect(), | ||
x = w.pageXOffset, | ||
y = st; | ||
return { | ||
left: o.left + x, | ||
top: o.top + y, | ||
height: o.height, | ||
width: o.width | ||
}; | ||
} | ||
} | ||
class Nestable { | ||
constructor(list, options) { | ||
this.defaultConfig = { | ||
threshold: 40, | ||
animation: 0, | ||
collapseButtonContent: "–", | ||
expandButtonContent: "+", | ||
includeContent: false, | ||
maxDepth: 3, | ||
showPlaceholderOnMove: false, | ||
nodes: { | ||
list: "ol", | ||
item: "li" | ||
}, | ||
classes: { | ||
list: "nst-list", | ||
item: "nst-item", | ||
content: "nst-content", | ||
parent: "nst-parent", | ||
dragging: "nst-dragging", | ||
handle: "nst-handle", | ||
placeholder: "nst-placeholder", | ||
container: "nst-container", | ||
button: "nst-button", | ||
collapsed: "nst-collapsed", | ||
disabled: "nst-disabled", | ||
error: "nst-error", | ||
moving: "nst-moving", | ||
}, | ||
}; | ||
this.config = Object.assign({}, this.defaultConfig, options); | ||
if (options) { | ||
if (options.nodes) { | ||
this.config.nodes = Object.assign({}, this.defaultConfig.nodes, options.nodes); | ||
} | ||
if (options.classes) { | ||
this.config.classes = Object.assign({}, this.defaultConfig.classes, options.classes); | ||
} | ||
} | ||
this.parent = typeof list === "string" ? DOM.select(list) : list; | ||
if (!this.parent) { | ||
return console.error(`Node (${list}) not found.`); | ||
} | ||
if (this.parent._nestable) { | ||
return console.error("There is already a Nestable instance active on this node."); | ||
} | ||
this.initialised = false; | ||
this.disabled = true; | ||
this.last = { | ||
x: 0, | ||
y: 0 | ||
}; | ||
this.init(); | ||
} | ||
/** | ||
* Add custom event listener | ||
* @param {String} event | ||
* @param {Function} callback | ||
* @return {Void} | ||
*/ | ||
on(listener, fn, capture) { | ||
if (typeof listener === "string") { | ||
this.listeners = this.listeners || {}; | ||
this.listeners[listener] = this.listeners[listener] || []; | ||
this.listeners[listener].push(fn); | ||
} else { | ||
arguments[0].addEventListener(arguments[1], arguments[2], false); | ||
} | ||
} | ||
/** | ||
* Remove custom listener listener | ||
* @param {String} listener | ||
* @param {Function} callback | ||
* @return {Void} | ||
*/ | ||
off(listener, fn) { | ||
if (typeof listener === "string") { | ||
this.listeners = this.listeners || {}; | ||
if (listener in this.listeners === false) return; | ||
this.listeners[listener].splice(this.listeners[listener].indexOf(fn), 1); | ||
} else { | ||
arguments[0].removeEventListener(arguments[1], arguments[2]); | ||
} | ||
} | ||
/** | ||
* Fire custom listener | ||
* @param {String} listener | ||
* @return {Void} | ||
*/ | ||
emit(listener) { | ||
this.listeners = this.listeners || {}; | ||
if (listener in this.listeners === false) return; | ||
for (var i = 0; i < this.listeners[listener].length; i++) { | ||
this.listeners[listener][i].apply(this, Array.prototype.slice.call(arguments, 1)); | ||
} | ||
} | ||
init(options) { | ||
if (!this.initialised) { | ||
this.touch = | ||
"ontouchstart" in window || | ||
(window.DocumentTouch && document instanceof DocumentTouch); | ||
if (options) { | ||
this.config = Object.assign({}, this.defaultConfig, options); | ||
} | ||
this.dragDepth = 0; | ||
this.parent.classList.add(this.config.classes.list); | ||
this.parent.classList.add(this.config.classes.parent); | ||
const items = DOM.children(this.parent, this.config.nodes.item); | ||
for (const item of items) { | ||
this._nest(item); | ||
} | ||
this.placeholder = document.createElement(this.config.nodes.item); | ||
this.placeholder.classList.add(this.config.classes.placeholder); | ||
this._getData(); | ||
this.parent._nestable = this; | ||
if (!window._nestableInstances) { | ||
window._nestableInstances = 1; | ||
this.id = 1; | ||
} else { | ||
window._nestableInstances += 1; | ||
this.id = window._nestableInstances | ||
} | ||
this.enable(); | ||
this._getData(); | ||
setTimeout(() => { | ||
this.emit("init"); | ||
}, 10); | ||
this.initialised = true; | ||
} | ||
} | ||
destroy() { | ||
if (this.initialised) { | ||
this.initialised = false; | ||
this.disable(); | ||
this.parent.classList.remove(this.config.classes.list); | ||
this.parent.classList.remove(this.config.classes.parent); | ||
delete(this.parent._nestable); | ||
if (window._nestableInstances) { | ||
window._nestableInstances -= 1; | ||
} | ||
const destroyItem = (item) => { | ||
item.classList.remove(this.config.classes.item); | ||
item.classList.remove(this.config.classes.collapsed); | ||
const listEl = item.querySelector(this.config.nodes.list); | ||
const contentEl = item.querySelector(`.${this.config.classes.content}`); | ||
const handleEl = item.querySelector(`.${this.config.classes.handle}`); | ||
const buttonEl = item.querySelector(`.${this.config.classes.button}`); | ||
// default handle is also the content container | ||
const defaultHandle = contentEl.classList.contains(this.config.classes.handle); | ||
const div = document.createDocumentFragment(); | ||
for (var i = contentEl.childNodes.length - 1; i >= 0; i--) { | ||
div.insertBefore(contentEl.childNodes[i], div.firstChild); | ||
} | ||
item.insertBefore(div, contentEl) | ||
item.removeChild(contentEl); | ||
if (listEl) { | ||
listEl.classList.remove(this.config.classes.list); | ||
item.removeChild(buttonEl); | ||
const items = DOM.children(listEl, this.config.nodes.item); | ||
for (const item of items) { | ||
destroyItem(item); | ||
} | ||
} | ||
}; | ||
const items = DOM.children(this.parent, this.config.nodes.item); | ||
for (const item of items) { | ||
destroyItem(item); | ||
} | ||
this.emit("destroy", this.parent); | ||
} | ||
} | ||
bind() { | ||
this.events = { | ||
start: this._onMouseDown.bind(this), | ||
move: this._onMouseMove.bind(this), | ||
end: this._onMouseUp.bind(this), | ||
}; | ||
if (this.touch) { | ||
this.parent.addEventListener("touchstart", this.events.start, false); | ||
document.addEventListener("touchmove", this.events.move, false); | ||
document.addEventListener("touchend", this.events.end, false); | ||
document.addEventListener("touchcancel", this.events.end, false); | ||
} else { | ||
this.parent.addEventListener("mousedown", this.events.start, false); | ||
document.addEventListener("mousemove", this.events.move, false); | ||
document.addEventListener("mouseup", this.events.end, false); | ||
} | ||
} | ||
unbind() { | ||
this.parent.removeEventListener("mousedown", this.events.start); | ||
document.removeEventListener("mousemove", this.events.move); | ||
document.removeEventListener("mouseup", this.events.end); | ||
} | ||
enable() { | ||
if (this.disabled) { | ||
this.bind(); | ||
this.parent.classList.remove(this.config.classes.disabled); | ||
this.disabled = false; | ||
} | ||
} | ||
disable() { | ||
if (!this.disabled) { | ||
this.unbind(); | ||
this.parent.classList.add(this.config.classes.disabled); | ||
this.disabled = true; | ||
} | ||
} | ||
serialise() { | ||
this.serialize(); | ||
} | ||
serialize() { | ||
return this._getData("data"); | ||
} | ||
collapseAll() { | ||
const items = DOM.selectAll(`.${this.config.classes.item}`, this.parent); | ||
for (const item of items) { | ||
if (!item.classList.contains(this.config.classes.collapsed)) { | ||
const btn = item.querySelector(`.${this.config.classes.button}`); | ||
if (btn) { | ||
this._collapseList(item, btn); | ||
} | ||
} | ||
} | ||
} | ||
expandAll() { | ||
const items = DOM.selectAll(`.${this.config.classes.item}`, this.parent); | ||
for (const item of items) { | ||
if (item.classList.contains(this.config.classes.collapsed)) { | ||
const btn = item.querySelector(`.${this.config.classes.button}`); | ||
if (btn) { | ||
this._expandList(item, btn); | ||
} | ||
} | ||
} | ||
} | ||
add(element, parent) { | ||
if (!parent) { | ||
parent = this.parent; | ||
} | ||
this._nest(element); | ||
if (parent !== this.parent) { | ||
const listEl = DOM.select(this.config.nodes.list, parent); | ||
if (!listEl) { | ||
parent = this._makeParent(parent); | ||
} else { | ||
parent = listEl; | ||
} | ||
} | ||
parent.appendChild(element); | ||
this.update(); | ||
} | ||
remove(element, removeChildElements = true) { | ||
const parentEl = element.closest(this.config.nodes.list); | ||
if (!removeChildElements) { | ||
const childList = element.querySelector(`.${this.config.classes.list}`); | ||
if (childList) { | ||
const childElements = DOM.children(childList, this.config.nodes.item); | ||
if (childElements.length) { | ||
const frag = document.createDocumentFragment(); | ||
for (var i = childElements.length - 1; i >= 0; i--) { | ||
const childElement = childElements[i]; | ||
frag.insertBefore(childElement, frag.firstElementChild); | ||
} | ||
parentEl.replaceChild(frag, element); | ||
} | ||
} | ||
} else { | ||
parentEl.removeChild(element); | ||
} | ||
this.update(); | ||
} | ||
update() { | ||
this._getData("nodes"); | ||
this.emit("update"); | ||
} | ||
_nest(el) { | ||
const handle = el.querySelector(`.${this.config.classes.handle}`); | ||
const content = document.createElement("div"); | ||
content.classList.add(this.config.classes.content); | ||
const nodes = el.childNodes; | ||
if (!handle) { | ||
content.classList.add(this.config.classes.handle); | ||
for (var i = nodes.length - 1; i >= 0; i--) { | ||
const node = nodes[i]; | ||
if (node.nodeName.toLowerCase() !== this.config.nodes.list) { | ||
content.insertBefore(node, content.firstChild); | ||
} | ||
} | ||
} else { | ||
for (var i = nodes.length - 1; i >= 0; i--) { | ||
const node = nodes[i]; | ||
if (node !== handle && node.nodeName.toLowerCase() !== this.config.nodes.list) { | ||
content.insertBefore(node, content.firstChild); | ||
} | ||
} | ||
} | ||
el.classList.add(this.config.classes.item); | ||
const list = el.querySelector(this.config.nodes.list); | ||
if (list) { | ||
el.insertBefore(content, list); | ||
const parent = this._makeParent(el); | ||
const items = DOM.children(parent, this.config.nodes.item); | ||
if (el.classList.contains(this.config.classes.collapsed)) { | ||
this._collapseList(el); | ||
} | ||
for (const i of items) { | ||
this._nest(i); | ||
} | ||
} else { | ||
el.appendChild(content); | ||
} | ||
} | ||
_isDisabled(item) { | ||
// item has the [data-nestable-disabled] attribute | ||
if ("nestableDisabled" in item.dataset) { | ||
if (!item.dataset.nestableDisabled.length || item.dataset.nestableDisabled !== "false") { | ||
return true; | ||
} | ||
} | ||
if (item.classList.contains(this.config.classes.disabled)) { | ||
return true; | ||
} | ||
const listEls = DOM.parents(item, `.${this.config.classes.disabled}`); | ||
if (listEls.length) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
* Get event | ||
* @return {Object} | ||
*/ | ||
_getEvent(e) { | ||
if (this.touch) { | ||
if (e.type === "touchend") { | ||
return e.changedTouches[0]; | ||
} | ||
return e.touches[0]; | ||
} | ||
return e; | ||
} | ||
_onMouseDown(e) { | ||
const evt = this._getEvent(e); | ||
const button = e.target.closest(`.${this.config.classes.button}`); | ||
const item = e.target.closest(`.${this.config.classes.item}`); | ||
if (button) { | ||
return this._toggleList(item, button); | ||
} | ||
const handle = e.target.closest(`.${this.config.classes.handle}`); | ||
if (!handle) { | ||
return false; | ||
} | ||
if (item) { | ||
if (this._isDisabled(item)) { | ||
return false; | ||
} | ||
e.preventDefault(); | ||
this.parent.classList.add(this.config.classes.moving); | ||
item.classList.add(this.config.classes.dragging); | ||
const rect = DOM.rect(item); | ||
this.origin = { | ||
x: evt.pageX, | ||
y: evt.pageY, | ||
original: { | ||
x: evt.pageX, | ||
y: evt.pageY, | ||
} | ||
}; | ||
this.active = { | ||
maxDepth: false, | ||
collapsedParent: false, | ||
disabledParent: false, | ||
confinedParent: false, | ||
node: item, | ||
rect: rect, | ||
parent: false, | ||
axis: false, | ||
}; | ||
// item has the [data-nestable-parent] attribute | ||
if ("nestableParent" in item.dataset) { | ||
const parent = document.getElementById(item.dataset.nestableParent); | ||
if (parent) { | ||
this.active.parent = parent; | ||
} | ||
} | ||
// item has the [data-nestable-axis] attribute | ||
if ("nestableAxis" in item.dataset) { | ||
const axis = item.dataset.nestableAxis; | ||
if (axis === "x") { | ||
this.active.axis = "x"; | ||
} else if (axis === "y") { | ||
this.active.axis = "y"; | ||
} | ||
} | ||
this.placeholder.style.height = `${rect.height}px`; | ||
// this.placeholder.style.width = `${rect.width}px`; | ||
if (this.config.showPlaceholderOnMove) { | ||
this.placeholder.style.opacity = 0; | ||
} | ||
if (!this.container) { | ||
this.container = document.createElement(this.config.nodes.list); | ||
this.container.classList.add(this.config.classes.list); | ||
this.container.classList.add(this.config.classes.container); | ||
this.container.id = `nestable_${this.id}`; | ||
} | ||
this.container.style.left = `${rect.left}px`; | ||
this.container.style.top = `${rect.top}px`; | ||
this.container.style.height = `${rect.height}px`; | ||
this.container.style.width = `${rect.width}px`; | ||
item.parentNode.insertBefore(this.placeholder, item); | ||
document.body.appendChild(this.container); | ||
this.container.appendChild(item); | ||
this.newParent = false; | ||
this.dragDepth = 0; | ||
// total depth of dragging item | ||
const items = DOM.selectAll(this.config.nodes.item, item); | ||
for (let i = 0; i < items.length; i++) { | ||
const depth = DOM.parents(items[i], this.config.nodes.list).length - 1; | ||
if (depth > this.dragDepth) { | ||
this.dragDepth = depth; | ||
} | ||
} | ||
this.emit("start", this.active); | ||
} | ||
} | ||
_onMouseMove(e) { | ||
if (this.active) { | ||
if (this.config.showPlaceholderOnMove) { | ||
this.placeholder.style.opacity = 1; | ||
} | ||
e = this._getEvent(e); | ||
let x = e.pageX - this.origin.x; | ||
let y = e.pageY - this.origin.y; | ||
if (e.pageY > this.last.y) { | ||
this.last.dirY = 1; | ||
} else if (e.pageY < this.last.y) { | ||
this.last.dirY = -1; | ||
} | ||
if (e.pageX > this.last.x) { | ||
this.last.dirX = 1; | ||
} else if (e.pageX < this.last.x) { | ||
this.last.dirX = -1; | ||
} | ||
let movement = false; | ||
if (Math.abs(x) > Math.abs(y)) { | ||
movement = "x"; | ||
} else if (Math.abs(x) < Math.abs(y)) { | ||
movement = "y"; | ||
} | ||
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; | ||
const elements = document.elementsFromPoint(e.pageX, e.pageY - scrollTop); | ||
if (movement === "x" && this.active.axis !== "y") { | ||
if (this.last.dirX > 0 && x > this.config.threshold) { // moving right | ||
const prevEl = this.placeholder.previousElementSibling; | ||
if (prevEl) { | ||
if (prevEl.classList.contains(this.config.classes.collapsed)) { | ||
if (!this.active.collapsedParent) { | ||
this.emit("error.collapsed", this.active.node, prevEl); | ||
this.active.collapsedParent = true; | ||
} | ||
} else { | ||
const disabled = this._isDisabled(prevEl); | ||
if (!disabled) { | ||
const depth = DOM.parents(this.placeholder, this.config.nodes.list).length; | ||
let allowNesting = depth + this.dragDepth <= this.config.maxDepth; | ||
let parentEl = prevEl.querySelector(this.config.nodes.list); | ||
if (allowNesting) { | ||
this.active.maxDepth = false; | ||
const oldParent = this.placeholder.closest(`.${this.config.classes.list}`); | ||
if (!parentEl) { | ||
parentEl = this._makeParent(prevEl); | ||
} | ||
this._moveElement(this.placeholder, { | ||
parent: parentEl, | ||
type: "appendChild", | ||
}); | ||
this.emit("nest", parentEl, oldParent); | ||
this.origin.x = e.pageX; | ||
} else { | ||
if (!this.active.maxDepth) { | ||
this.emit("error.maxdepth", this.active.node, this.config.maxDepth); | ||
this.active.maxDepth = true; | ||
} | ||
} | ||
} else { | ||
if (!this.active.disabledParent) { | ||
this.emit("error.disabled"); | ||
this.active.disabledParent = true; | ||
} | ||
} | ||
} | ||
} | ||
} else if (this.last.dirX < 0 && x < -this.config.threshold) { // moving left | ||
this.active.maxDepth = false; | ||
this.active.disabledParent = false; | ||
this.active.collapsedParent = false; | ||
// this.active.confinedParent = false; | ||
const listEl = this.placeholder.closest(this.config.nodes.list); | ||
const parentEl = listEl.closest(this.config.nodes.item); | ||
if (parentEl && | ||
((listEl.childElementCount > 1 && this.placeholder !== listEl.firstElementChild) || listEl.childElementCount < 2 && this.placeholder === listEl.firstElementChild)) { | ||
const nextEl = parentEl.nextElementSibling; | ||
const oldParent = this.placeholder.closest(`.${this.config.classes.list}`); | ||
if (nextEl) { | ||
const list = nextEl.closest(this.config.nodes.list); | ||
this._moveElement(this.placeholder, { | ||
parent: list, | ||
type: "insertBefore", | ||
sibling: nextEl | ||
}); | ||
this.origin.x = e.pageX; | ||
} else { | ||
this._moveElement(this.placeholder, { | ||
parent: parentEl.closest(this.config.nodes.list), | ||
type: "appendChild", | ||
}); | ||
this.origin.x = e.pageX; | ||
} | ||
this.emit("unnest", parentEl, oldParent); | ||
} | ||
} | ||
} else { | ||
// check if we're over a valid item | ||
for (const element of elements) { | ||
const moveY = element !== this.active.node && | ||
!this.active.node.contains(element) && | ||
element.classList.contains(this.config.classes.content) && | ||
this.active.axis !== "x"; | ||
if (moveY) { | ||
const item = element.closest(`.${this.config.classes.item}`); | ||
if (item) { | ||
if (movement === "y") { | ||
const childListEl = item.querySelector(this.config.nodes.list); | ||
if (childListEl && !item.classList.contains(this.config.classes.collapsed)) { // item is parent | ||
if (this.last.dirY > 0) { // moving item down | ||
this._moveElement(this.placeholder, { | ||
parent: item.lastElementChild, | ||
type: "insertBefore", | ||
sibling: item.lastElementChild.firstElementChild, | ||
animatable: item.querySelector(`.${this.config.classes.content}`) | ||
}); | ||
} else if (this.last.dirY < 0) { // moving item up | ||
this._moveElement(this.placeholder, { | ||
parent: item.parentNode, | ||
type: "insertBefore", | ||
sibling: item, | ||
animatable: item.querySelector(`.${this.config.classes.content}`) | ||
}); | ||
} | ||
this.emit("reorder"); | ||
} else { // item is not a parent | ||
if (this.last.dirY > 0) { // moving item down | ||
const nextEl = item.nextElementSibling; | ||
if (nextEl) { // item has an item below it | ||
this._moveElement(this.placeholder, { | ||
parent: item.parentNode, | ||
type: "insertBefore", | ||
sibling: nextEl, | ||
animatable: item.querySelector(`.${this.config.classes.content}`) | ||
}); | ||
} else { // item is last in list | ||
this._moveElement(this.placeholder, { | ||
parent: item.closest(this.config.nodes.list), | ||
type: "appendChild", | ||
animatable: item.querySelector(`.${this.config.classes.content}`) | ||
}); | ||
} | ||
} else if (this.last.dirY < 0) { // moving item up | ||
this._moveElement(this.placeholder, { | ||
parent: item.parentNode, | ||
type: "insertBefore", | ||
sibling: item, | ||
animatable: item.querySelector(`.${this.config.classes.content}`) | ||
}); | ||
} | ||
this.emit("reorder"); | ||
} | ||
} | ||
} | ||
const parentEl = item.closest(`.${this.config.classes.parent}`); | ||
if (parentEl) { | ||
if (parentEl !== this.parent) { | ||
if (parentEl._nestable) { | ||
this.newParent = parentEl; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
this.placeholder.classList.toggle(this.config.classes.error, | ||
this.active.disabledParent || | ||
this.active.maxDepth || | ||
this.active.collapsedParent || | ||
this.active.confinedParent); | ||
let mx = e.pageX - this.origin.original.x; | ||
let my = e.pageY - this.origin.original.y; | ||
// item movement is confined | ||
if (this.active.axis) { | ||
if (this.active.axis === "x") { | ||
my = 0; | ||
} else if (this.active.axis === "y") { | ||
mx = 0; | ||
} | ||
} | ||
this.container.style.transform = `translate3d(${mx}px, ${my}px, 0)`; | ||
this.lastParent = this.placeholder.parentNode; | ||
this.emit("move", this.active); | ||
} | ||
this.last = { | ||
x: e.pageX, | ||
y: e.pageY | ||
}; | ||
} | ||
_moveElement(el, type) { | ||
let ppos = false; | ||
let ipos = false; | ||
// prevent moving if item has disabled parents | ||
if (this._isDisabled(type.parent)) { | ||
return false; | ||
} | ||
// prevent moving if item is confined to parent with data-nestable-parent | ||
if (this.active.parent) { | ||
if (!DOM.parents(type.parent, `#${this.active.parent.id}`).includes(this.active.parent)) { | ||
if (!this.active.confinedParent) { | ||
this.emit("error.confined", el, this.active.parent, type.parent); | ||
this.active.confinedParent = true; | ||
} | ||
return false; | ||
} | ||
} | ||
let listEl = el.closest(this.config.nodes.list); | ||
// if animation is enabled, we need to get the original position of the element first | ||
if (this.config.animation > 0) { | ||
ppos = DOM.rect(this.placeholder); | ||
if (type.animatable) { | ||
ipos = DOM.rect(type.animatable) | ||
} | ||
} | ||
if (type.type === "insertBefore") { | ||
type.parent.insertBefore(el, type.sibling); | ||
} else if (type.type === "appendChild") { | ||
type.parent.appendChild(el); | ||
} | ||
if (!listEl.childElementCount) { | ||
this._unmakeParent(listEl.parentNode); | ||
} | ||
this.emit("order.change", this.active.node, type.parent, listEl); | ||
// animate the elements | ||
if (this.config.animation > 0) { | ||
this._animateElement(this.placeholder, ppos); | ||
if (type.animatable && ipos) { | ||
this._animateElement(type.animatable, ipos); | ||
} | ||
} | ||
} | ||
_animateElement(el, obj) { | ||
// Animate an element's change in position | ||
// caused by a change in the DOM order | ||
let css = el.style; | ||
// Get the node's positon AFTER the change | ||
let r = DOM.rect(el); | ||
// Calculate the difference in position | ||
let x = obj.left - r.left; | ||
let y = obj.top - r.top; | ||
// Move the node to it's original position before the DOM change | ||
css.transform = `translate3d(${x}px, ${y}px, 0px)`; | ||
// css.zIndex = 10000; | ||
// Trigger a repaint so the next bit works | ||
this._repaint(el); | ||
// Reset the transform, but add a transition so it's smooth | ||
css.transform = `translate3d(0px, 0px, 0px)`; | ||
css.transition = `transform ${this.config.animation}ms`; | ||
// Reset the style | ||
setTimeout(function() { | ||
// console.log("foo") | ||
// css.zIndex = ""; | ||
css.transform = ""; | ||
css.transition = ""; | ||
}, this.config.animation); | ||
} | ||
_repaint(el) { | ||
return el.offsetHeight; | ||
} | ||
_onMouseUp(e) { | ||
if (this.active) { | ||
if (this.config.showPlaceholderOnMove) { | ||
this.placeholder.style.opacity = 0; | ||
} | ||
e = this._getEvent(e); | ||
const prect = DOM.rect(this.active.node); | ||
// this.active.node.removeAttribute("style"); | ||
this.container.removeAttribute("style"); | ||
this.parent.classList.remove(this.config.classes.moving); | ||
this.placeholder.parentNode.replaceChild(this.active.node, this.placeholder); | ||
this._animateElement(this.active.node, prect); | ||
this.placeholder.classList.remove(this.config.classes.error); | ||
this.active.node.classList.remove(this.config.classes.dragging); | ||
this.active = false; | ||
document.body.removeChild(this.container); | ||
this._getData(); | ||
if (this.newParent) { | ||
this.newParent._nestable._getData(); | ||
} | ||
this.emit("stop", this.data); | ||
this.update(); | ||
} | ||
} | ||
_toggleList(item, btn) { | ||
if (!item.classList.contains(this.config.classes.collapsed)) { | ||
this._collapseList(item, btn); | ||
} else { | ||
this._expandList(item, btn); | ||
} | ||
} | ||
_collapseList(item, btn) { | ||
if (!btn) { | ||
btn = item.querySelector(`.${this.config.classes.button}`) | ||
} | ||
btn.textContent = this.config.expandButtonContent; | ||
item.classList.add(this.config.classes.collapsed); | ||
} | ||
_expandList(item, btn) { | ||
if (!btn) { | ||
btn = item.querySelector(`.${this.config.classes.button}`) | ||
} | ||
btn.textContent = this.config.collapseButtonContent; | ||
item.classList.remove(this.config.classes.collapsed); | ||
} | ||
_makeParent(el) { | ||
let parentEl = el.querySelector(this.config.nodes.list); | ||
if (!parentEl) { | ||
parentEl = document.createElement(this.config.nodes.list); | ||
parentEl.classList.add(this.config.classes.list); | ||
el.appendChild(parentEl); | ||
} else { | ||
parentEl.classList.add(this.config.classes.list); | ||
} | ||
const button = document.createElement("button"); | ||
button.classList.add(this.config.classes.button); | ||
button.type = "button"; | ||
button.textContent = this.config.collapseButtonContent; | ||
el.insertBefore(button, el.firstElementChild); | ||
return parentEl; | ||
} | ||
_unmakeParent(el) { | ||
const list = el.querySelector(this.config.nodes.list); | ||
const btn = el.querySelector("button"); | ||
if (list) { | ||
el.removeChild(list); | ||
} | ||
if (btn) { | ||
el.removeChild(btn); | ||
} | ||
return | ||
} | ||
_getData(type = "nodes") { | ||
let data = []; | ||
const step = (level) => { | ||
const array = []; | ||
const items = DOM.children(level, this.config.nodes.item); | ||
items.forEach((li) => { | ||
const item = {}; | ||
if (type === "nodes") { | ||
item.node = li; | ||
} else { | ||
item.data = Object.assign({}, li.dataset); | ||
if (this.config.includeContent) { | ||
const content = li.querySelector(`.${this.config.classes.content}`); | ||
if (content) { | ||
item.content = content.innerHTML; | ||
} | ||
} | ||
} | ||
const sub = li.querySelector(this.config.nodes.list); | ||
if (sub) { | ||
item.children = step(sub); | ||
} | ||
array.push(item); | ||
}); | ||
return array; | ||
}; | ||
data = step(this.parent); | ||
if (type === "nodes") { | ||
this.data = data; | ||
} | ||
return data; | ||
} | ||
} | ||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.makeIterator=function(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):$jscomp.arrayIterator(a)}; | ||
var DOM={select:function(a,b){b=void 0===b?document:b;return b.querySelector(a)},selectAll:function(a,b){b=void 0===b?document:b;return b.querySelectorAll(a)},children:function(a,b){for(var c=[],d=a.children,e=d.length,f=0;f<e;++f){var l=d[f];l.matches(b)&&c.push(l)}return c},parents:function(a,b){for(var c=[];a&&a!==document;a=a.parentNode)b?a.matches(b)&&c.push(a):c.push(a);return c},rect:function(a){var b=window,c=void 0!==b.pageYOffset?b.pageYOffset:(document.documentElement||document.body.parentNode|| | ||
document.body).scrollTop;a=a.getBoundingClientRect();return{left:a.left+b.pageXOffset,top:a.top+c,height:a.height,width:a.width}}},Nestable=function(a,b){this.defaultConfig={threshold:40,animation:0,collapseButtonContent:"\u2013",expandButtonContent:"+",includeContent:!1,maxDepth:3,showPlaceholderOnMove:!1,nodes:{list:"ol",item:"li"},classes:{list:"nst-list",item:"nst-item",content:"nst-content",parent:"nst-parent",dragging:"nst-dragging",handle:"nst-handle",placeholder:"nst-placeholder",container:"nst-container", | ||
button:"nst-button",collapsed:"nst-collapsed",disabled:"nst-disabled",error:"nst-error",moving:"nst-moving"}};this.config=Object.assign({},this.defaultConfig,b);b&&(b.nodes&&(this.config.nodes=Object.assign({},this.defaultConfig.nodes,b.nodes)),b.classes&&(this.config.classes=Object.assign({},this.defaultConfig.classes,b.classes)));this.parent="string"===typeof a?DOM.select(a):a;if(!this.parent)return console.error("Node ("+a+") not found.");if(this.parent._nestable)return console.error("There is already a Nestable instance active on this node."); | ||
this.initialised=!1;this.disabled=!0;this.last={x:0,y:0};this.init()}; | ||
Nestable.prototype.init=function(a){var b=this;if(!this.initialised){this.touch="ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch;a&&(this.config=Object.assign({},this.defaultConfig,a));this.dragDepth=0;this.parent.classList.add(this.config.classes.list);this.parent.classList.add(this.config.classes.parent);a=DOM.children(this.parent,this.config.nodes.item);a=$jscomp.makeIterator(a);for(var c=a.next();!c.done;c=a.next())this._nest(c.value);this.placeholder=document.createElement(this.config.nodes.item); | ||
this.placeholder.classList.add(this.config.classes.placeholder);this._getData();this.parent._nestable=this;window._nestableInstances?(window._nestableInstances+=1,this.id=window._nestableInstances):this.id=window._nestableInstances=1;this.enable();this._getData();setTimeout(function(){b.emit("init")},10);this.initialised=!0;if(this.config.data){var d=new XMLHttpRequest;d.responseType="json";d.open("GET",this.config.data,!0);d.onload=function(){b.load(d)};d.send(null)}}}; | ||
Nestable.prototype.destroy=function(){var a=this;if(this.initialised){this.initialised=!1;this.disable();this.parent.classList.remove(this.config.classes.list);this.parent.classList.remove(this.config.classes.parent);delete this.parent._nestable;window._nestableInstances&&--window._nestableInstances;var b=function(c){c.classList.remove(a.config.classes.item);c.classList.remove(a.config.classes.collapsed);var d=c.querySelector(a.config.nodes.list),e=c.querySelector("."+a.config.classes.content);c.querySelector("."+ | ||
a.config.classes.handle);var h=c.querySelector("."+a.config.classes.button);e.classList.contains(a.config.classes.handle);for(var g=document.createDocumentFragment(),k=e.childNodes.length-1;0<=k;k--)g.insertBefore(e.childNodes[k],g.firstChild);c.insertBefore(g,e);c.removeChild(e);if(d)for(d.classList.remove(a.config.classes.list),c.removeChild(h),c=DOM.children(d,a.config.nodes.item),c=$jscomp.makeIterator(c),d=c.next();!d.done;d=c.next())b(d.value)},c=DOM.children(this.parent,this.config.nodes.item); | ||
c=$jscomp.makeIterator(c);for(var d=c.next();!d.done;d=c.next())b(d.value);this.emit("destroy",this.parent)}}; | ||
Nestable.prototype.bind=function(){this.events={start:this._onMouseDown.bind(this),move:this._onMouseMove.bind(this),end:this._onMouseUp.bind(this)};this.touch?(this.parent.addEventListener("touchstart",this.events.start,!1),document.addEventListener("touchmove",this.events.move,!1),document.addEventListener("touchend",this.events.end,!1),document.addEventListener("touchcancel",this.events.end,!1)):(this.parent.addEventListener("mousedown",this.events.start,!1),document.addEventListener("mousemove", | ||
this.events.move,!1),document.addEventListener("mouseup",this.events.end,!1))};Nestable.prototype.unbind=function(){this.parent.removeEventListener("mousedown",this.events.start);document.removeEventListener("mousemove",this.events.move);document.removeEventListener("mouseup",this.events.end)};Nestable.prototype.on=function(a,b,c){"string"===typeof a?(this.listeners=this.listeners||{},this.listeners[a]=this.listeners[a]||[],this.listeners[a].push(b)):a.addEventListener(b,c,!1)}; | ||
Nestable.prototype.off=function(a,b,c){"string"===typeof a?(this.listeners=this.listeners||{},!1!==a in this.listeners&&this.listeners[a].splice(this.listeners[a].indexOf(b),1)):a.removeEventListener(b,c)};Nestable.prototype.emit=function(a){this.listeners=this.listeners||{};if(!1!==a in this.listeners)for(var b=0;b<this.listeners[a].length;b++)this.listeners[a][b].apply(this,Array.prototype.slice.call(arguments,1))}; | ||
Nestable.prototype.enable=function(){this.disabled&&(this.bind(),this.parent.classList.remove(this.config.classes.disabled),this.disabled=!1)};Nestable.prototype.disable=function(){this.disabled||(this.unbind(),this.parent.classList.add(this.config.classes.disabled),this.disabled=!0)};Nestable.prototype.serialise=function(){this.serialize()};Nestable.prototype.serialize=function(){return this._getData("data")}; | ||
Nestable.prototype.collapseAll=function(){var a=DOM.selectAll("."+this.config.classes.item,this.parent);a=$jscomp.makeIterator(a);for(var b=a.next();!b.done;b=a.next())if(b=b.value,!b.classList.contains(this.config.classes.collapsed)){var c=b.querySelector("."+this.config.classes.button);c&&this._collapseList(b,c)}}; | ||
Nestable.prototype.expandAll=function(){var a=DOM.selectAll("."+this.config.classes.item,this.parent);a=$jscomp.makeIterator(a);for(var b=a.next();!b.done;b=a.next())if(b=b.value,b.classList.contains(this.config.classes.collapsed)){var c=b.querySelector("."+this.config.classes.button);c&&this._expandList(b,c)}};Nestable.prototype.add=function(a,b){b||(b=this.parent);this._nest(a);if(b!==this.parent){var c=DOM.select(this.config.nodes.list,b);b=c?c:this._makeParent(b)}b.appendChild(a);this.update()}; | ||
Nestable.prototype.remove=function(a,b){b=void 0===b?!0:b;var c=a.closest(this.config.nodes.list);if(b)c.removeChild(a);else{var d=a.querySelector("."+this.config.classes.list);if(d&&(d=DOM.children(d,this.config.nodes.item),d.length)){for(var e=document.createDocumentFragment(),f=d.length-1;0<=f;f--)e.insertBefore(d[f],e.firstElementChild);c.replaceChild(e,a)}}this.update()};Nestable.prototype.removeAll=function(){for(var a=this.parent.children,b=a.length-1;0<=b;b--)this.parent.removeChild(a[b])}; | ||
Nestable.prototype.update=function(){this._getData("nodes");this.emit("update")}; | ||
Nestable.prototype._nest=function(a){var b=a.querySelector("."+this.config.classes.handle),c=document.createElement("div");c.classList.add(this.config.classes.content);var d=a.childNodes;if(b)for(f=d.length-1;0<=f;f--){var e=d[f];e!==b&&e.nodeName.toLowerCase()!==this.config.nodes.list&&c.insertBefore(e,c.firstChild)}else{c.classList.add(this.config.classes.handle);for(var f=d.length-1;0<=f;f--)b=d[f],b.nodeName.toLowerCase()!==this.config.nodes.list&&c.insertBefore(b,c.firstChild)}a.classList.add(this.config.classes.item); | ||
if(d=a.querySelector(this.config.nodes.list))for(a.insertBefore(c,d),c=this._makeParent(a),c=DOM.children(c,this.config.nodes.item),a.classList.contains(this.config.classes.collapsed)&&this._collapseList(a),a=$jscomp.makeIterator(c),c=a.next();!c.done;c=a.next())this._nest(c.value);else a.appendChild(c)}; | ||
Nestable.prototype._isDisabled=function(a){return"nestableDisabled"in a.dataset&&(!a.dataset.nestableDisabled.length||"false"!==a.dataset.nestableDisabled)||a.classList.contains(this.config.classes.disabled)||DOM.parents(a,"."+this.config.classes.disabled).length?!0:!1};Nestable.prototype._getEvent=function(a){return this.touch?"touchend"===a.type?a.changedTouches[0]:a.touches[0]:a}; | ||
Nestable.prototype._onMouseDown=function(a){var b=this._getEvent(a),c=a.target.closest("."+this.config.classes.button),d=a.target.closest("."+this.config.classes.item);if(c)return this._toggleList(d,c);if(!a.target.closest("."+this.config.classes.handle))return!1;if(d){if(this._isDisabled(d))return!1;a.preventDefault();this.parent.classList.add(this.config.classes.moving);d.classList.add(this.config.classes.dragging);a=DOM.rect(d);this.origin={x:b.pageX,y:b.pageY,original:{x:b.pageX,y:b.pageY}};this.active= | ||
{maxDepth:!1,collapsedParent:!1,disabledParent:!1,confinedParent:!1,node:d,rect:a,parent:!1,axis:!1};"nestableParent"in d.dataset&&(b=document.getElementById(d.dataset.nestableParent))&&(this.active.parent=b);"nestableAxis"in d.dataset&&(b=d.dataset.nestableAxis,"x"===b?this.active.axis="x":"y"===b&&(this.active.axis="y"));this.placeholder.style.height=a.height+"px";this.config.showPlaceholderOnMove&&(this.placeholder.style.opacity=0);this.container||(this.container=document.createElement(this.config.nodes.list), | ||
this.container.classList.add(this.config.classes.list),this.container.classList.add(this.config.classes.container),this.container.id="nestable_"+this.id);this.container.style.left=a.left+"px";this.container.style.top=a.top+"px";this.container.style.height=a.height+"px";this.container.style.width=a.width+"px";d.parentNode.insertBefore(this.placeholder,d);document.body.appendChild(this.container);this.container.appendChild(d);this.newParent=!1;this.dragDepth=0;d=DOM.selectAll(this.config.nodes.item, | ||
d);for(b=0;b<d.length;b++)a=DOM.parents(d[b],this.config.nodes.list).length-1,a>this.dragDepth&&(this.dragDepth=a);this.emit("start",this.active)}}; | ||
Nestable.prototype._onMouseMove=function(a){if(this.active){this.config.showPlaceholderOnMove&&(this.placeholder.style.opacity=1);a=this._getEvent(a);var b=a.pageX-this.origin.x,c=a.pageY-this.origin.y;a.pageY>this.last.y?this.last.dirY=1:a.pageY<this.last.y&&(this.last.dirY=-1);a.pageX>this.last.x?this.last.dirX=1:a.pageX<this.last.x&&(this.last.dirX=-1);var d=!1;Math.abs(b)>Math.abs(c)?d="x":Math.abs(b)<Math.abs(c)&&(d="y");c=document.elementsFromPoint(a.pageX,a.pageY-(void 0!==window.pageYOffset? | ||
window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop));if("x"===d&&"y"!==this.active.axis)if(0<this.last.dirX&&b>this.config.threshold){if(d=this.placeholder.previousElementSibling)d.classList.contains(this.config.classes.collapsed)?this.active.collapsedParent||(this.emit("error.collapsed",this.active.node,d),this.active.collapsedParent=!0):this._isDisabled(d)?this.active.disabledParent||(this.emit("error.disabled"),this.active.disabledParent=!0):(c=DOM.parents(this.placeholder, | ||
this.config.nodes.list).length+this.dragDepth<=this.config.maxDepth,b=d.querySelector(this.config.nodes.list),c?(this.active.maxDepth=!1,c=this.placeholder.closest("."+this.config.classes.list),b||(b=this._makeParent(d)),this._moveElement(this.placeholder,{parent:b,type:"appendChild"}),this.emit("nest",b,c),this.origin.x=a.pageX):this.active.maxDepth||(this.emit("error.maxdepth",this.active.node,this.config.maxDepth),this.active.maxDepth=!0))}else{if(0>this.last.dirX&&b<-this.config.threshold&&(this.active.maxDepth= | ||
!1,this.active.disabledParent=!1,this.active.collapsedParent=!1,b=this.placeholder.closest(this.config.nodes.list),(d=b.closest(this.config.nodes.item))&&(1<b.childElementCount&&this.placeholder!==b.firstElementChild||2>b.childElementCount&&this.placeholder===b.firstElementChild))){b=d.nextElementSibling;c=this.placeholder.closest("."+this.config.classes.list);if(b){var e=b.closest(this.config.nodes.list);this._moveElement(this.placeholder,{parent:e,type:"insertBefore",sibling:b})}else this._moveElement(this.placeholder, | ||
{parent:d.closest(this.config.nodes.list),type:"appendChild"});this.origin.x=a.pageX;this.emit("unnest",d,c)}}else for(b=$jscomp.makeIterator(c),c=b.next();!c.done;c=b.next())c=c.value,c!==this.active.node&&!this.active.node.contains(c)&&c.classList.contains(this.config.classes.content)&&"x"!==this.active.axis&&((c=c.closest("."+this.config.classes.item))&&"y"===d&&(c.querySelector(this.config.nodes.list)&&!c.classList.contains(this.config.classes.collapsed)?0<this.last.dirY?this._moveElement(this.placeholder, | ||
{parent:c.lastElementChild,type:"insertBefore",sibling:c.lastElementChild.firstElementChild,animatable:c.querySelector("."+this.config.classes.content)}):0>this.last.dirY&&this._moveElement(this.placeholder,{parent:c.parentNode,type:"insertBefore",sibling:c,animatable:c.querySelector("."+this.config.classes.content)}):0<this.last.dirY?(e=c.nextElementSibling)?this._moveElement(this.placeholder,{parent:c.parentNode,type:"insertBefore",sibling:e,animatable:c.querySelector("."+this.config.classes.content)}): | ||
this._moveElement(this.placeholder,{parent:c.closest(this.config.nodes.list),type:"appendChild",animatable:c.querySelector("."+this.config.classes.content)}):0>this.last.dirY&&this._moveElement(this.placeholder,{parent:c.parentNode,type:"insertBefore",sibling:c,animatable:c.querySelector("."+this.config.classes.content)}),this.emit("reorder")),(c=c.closest("."+this.config.classes.parent))&&c!==this.parent&&c._nestable&&(this.newParent=c));this.placeholder.classList.toggle(this.config.classes.error, | ||
this.active.disabledParent||this.active.maxDepth||this.active.collapsedParent||this.active.confinedParent);d=a.pageX-this.origin.original.x;b=a.pageY-this.origin.original.y;this.active.axis&&("x"===this.active.axis?b=0:"y"===this.active.axis&&(d=0));this.container.style.transform="translate3d("+d+"px, "+b+"px, 0)";this.lastParent=this.placeholder.parentNode;this.emit("move",this.active)}this.last={x:a.pageX,y:a.pageY}}; | ||
Nestable.prototype._moveElement=function(a,b){var c=!1,d=!1;if(this._isDisabled(b.parent))return!1;if(this.active.parent&&!DOM.parents(b.parent,"#"+this.active.parent.id).includes(this.active.parent))return this.active.confinedParent||(this.emit("error.confined",a,this.active.parent,b.parent),this.active.confinedParent=!0),!1;var e=a.closest(this.config.nodes.list);0<this.config.animation&&(c=DOM.rect(this.placeholder),b.animatable&&(d=DOM.rect(b.animatable)));"insertBefore"===b.type?b.parent.insertBefore(a, | ||
b.sibling):"appendChild"===b.type&&b.parent.appendChild(a);e.childElementCount||this._unmakeParent(e.parentNode);this.emit("order.change",this.active.node,b.parent,e);0<this.config.animation&&(this._animateElement(this.placeholder,c),b.animatable&&d&&this._animateElement(b.animatable,d))}; | ||
Nestable.prototype._animateElement=function(a,b){var c=a.style,d=DOM.rect(a);c.transform="translate3d("+(b.left-d.left)+"px, "+(b.top-d.top)+"px, 0px)";this._repaint(a);c.transform="translate3d(0px, 0px, 0px)";c.transition="transform "+this.config.animation+"ms";setTimeout(function(){c.transform="";c.transition=""},this.config.animation)};Nestable.prototype._repaint=function(a){return a.offsetHeight}; | ||
Nestable.prototype._onMouseUp=function(a){this.active&&(this.config.showPlaceholderOnMove&&(this.placeholder.style.opacity=0),this._getEvent(a),a=DOM.rect(this.active.node),this.container.removeAttribute("style"),this.parent.classList.remove(this.config.classes.moving),this.placeholder.parentNode.replaceChild(this.active.node,this.placeholder),this._animateElement(this.active.node,a),this.placeholder.classList.remove(this.config.classes.error),this.active.node.classList.remove(this.config.classes.dragging), | ||
this.active=!1,document.body.removeChild(this.container),this._getData(),this.newParent&&this.newParent._nestable._getData(),this.emit("stop",this.data),this.update())};Nestable.prototype._toggleList=function(a,b){a.classList.contains(this.config.classes.collapsed)?this._expandList(a,b):this._collapseList(a,b)};Nestable.prototype._collapseList=function(a,b){b||(b=a.querySelector("."+this.config.classes.button));b.textContent=this.config.expandButtonContent;a.classList.add(this.config.classes.collapsed)}; | ||
Nestable.prototype._expandList=function(a,b){b||(b=a.querySelector("."+this.config.classes.button));b.textContent=this.config.collapseButtonContent;a.classList.remove(this.config.classes.collapsed)}; | ||
Nestable.prototype._makeParent=function(a){var b=a.querySelector(this.config.nodes.list);b?b.classList.add(this.config.classes.list):(b=document.createElement(this.config.nodes.list),b.classList.add(this.config.classes.list),a.appendChild(b));var c=document.createElement("button");c.classList.add(this.config.classes.button);c.type="button";c.textContent=this.config.collapseButtonContent;a.insertBefore(c,a.firstElementChild);return b}; | ||
Nestable.prototype._unmakeParent=function(a){var b=a.querySelector(this.config.nodes.list),c=a.querySelector("button");b&&a.removeChild(b);c&&a.removeChild(c)}; | ||
Nestable.prototype._getData=function(a){var b=this;a=void 0===a?"nodes":a;var c=[],d=function(c){var e=[];DOM.children(c,b.config.nodes.item).forEach(function(c){var f={};if("nodes"===a)f.node=c;else if(f.data=Object.assign({},c.dataset),b.config.includeContent){var g=c.querySelector("."+b.config.classes.content);g&&(f.content=g.innerHTML)}if(c=c.querySelector(b.config.nodes.list))f.children=d(c);e.push(f)});return e};c=d(this.parent);"nodes"===a&&(this.data=c);return c}; | ||
Nestable.prototype.load=function(a){var b=this;this.removeAll();"response"in a&&(a=a.response);var c=function(a){var d=document.createElement(b.config.nodes.item);d.textContent=a.content;if(a.children){var e=document.createElement(b.config.nodes.list);d.appendChild(e);a=$jscomp.makeIterator(a.children);for(var h=a.next();!h.done;h=a.next())e.appendChild(c(h.value))}return d};a=$jscomp.makeIterator(a);for(var d=a.next();!d.done;d=a.next())this._nest(this.parent.appendChild(c(d.value)));this.emit("loaded")}; |
{ | ||
"name": "nestablejs", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "NestableJS is a javascript library for creating drag & drop heirarchical lists.", | ||
@@ -5,0 +5,0 @@ "main": "dist/nestable.js", |
@@ -118,5 +118,45 @@ import DOM from "./utils/DOM.js"; | ||
this.initialised = true; | ||
if ( this.config.data ) { | ||
const req = new XMLHttpRequest(); | ||
req.responseType = 'json'; | ||
req.open('GET', this.config.data, true); | ||
req.onload = () => { | ||
this.load(req); | ||
}; | ||
req.send(null); | ||
} | ||
} | ||
} | ||
load(data) { | ||
this.removeAll(); | ||
if ( "response" in data ) { | ||
data = data.response; | ||
} | ||
const nest = (item) => { | ||
const el = document.createElement(this.config.nodes.item); | ||
el.textContent = item.content; | ||
if ( item.children ) { | ||
const list = document.createElement(this.config.nodes.list); | ||
el.appendChild(list); | ||
for ( const child of item.children ) { | ||
list.appendChild(nest(child)); | ||
} | ||
} | ||
return el; | ||
}; | ||
for ( const item of data ) { | ||
this._nest(this.parent.appendChild(nest(item))) | ||
} | ||
this.emit("loaded"); | ||
} | ||
destroy() { | ||
@@ -123,0 +163,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6294257
7994