mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2025-01-27 13:01:13 +01:00
661 lines
23 KiB
JavaScript
661 lines
23 KiB
JavaScript
|
|
/*
|
|
* aciTree jQuery Plugin v4.5.0-rc.7
|
|
* http://acoderinsights.ro
|
|
*
|
|
* Copyright (c) 2014 Dragos Ursu
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
*
|
|
* Require jQuery Library >= v1.9.0 http://jquery.com
|
|
* + aciPlugin >= v1.5.1 https://github.com/dragosu/jquery-aciPlugin
|
|
*/
|
|
|
|
/*
|
|
* The aciTree low-level DOM functions.
|
|
*
|
|
* A collection of functions optimised for aciTree DOM structure.
|
|
*
|
|
* Need to be included before the aciTree core and after aciPlugin.
|
|
*/
|
|
|
|
aciPluginClass.plugins.aciTree_dom = {
|
|
// get the UL container from a LI
|
|
// `node` must be valid LI DOM node
|
|
// can return NULL
|
|
container: function(node) {
|
|
var container = node.lastChild;
|
|
if (container && (container.nodeName == 'UL')) {
|
|
return container;
|
|
}
|
|
return null;
|
|
},
|
|
// get the first children from a LI (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node
|
|
// can return NULL
|
|
firstChild: function(node, callback) {
|
|
var container = this.container(node);
|
|
if (container) {
|
|
var firstChild = container.firstChild;
|
|
if (callback) {
|
|
while (firstChild && !callback.call(this, firstChild)) {
|
|
firstChild = firstChild.nextSibling;
|
|
}
|
|
}
|
|
return firstChild;
|
|
}
|
|
return null;
|
|
},
|
|
// get the last children from a LI (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node
|
|
// can return NULL
|
|
lastChild: function(node, callback) {
|
|
var container = this.container(node);
|
|
if (container) {
|
|
var lastChild = container.lastChild;
|
|
if (callback) {
|
|
while (lastChild && !callback.call(this, lastChild)) {
|
|
lastChild = lastChild.previousSibling;
|
|
}
|
|
}
|
|
return lastChild;
|
|
}
|
|
return null;
|
|
},
|
|
// get the previous LI sibling (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node
|
|
// can return NULL
|
|
prev: function(node, callback) {
|
|
var previous = node.previousSibling;
|
|
if (callback) {
|
|
while (previous && !callback.call(this, previous)) {
|
|
previous = previous.previousSibling;
|
|
}
|
|
}
|
|
return previous;
|
|
},
|
|
// get the next LI sibling (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node
|
|
// can return NULL
|
|
next: function(node, callback) {
|
|
var next = node.nextSibling;
|
|
if (callback) {
|
|
while (next && !callback.call(this, next)) {
|
|
next = next.nextSibling;
|
|
}
|
|
}
|
|
return next;
|
|
},
|
|
// get the previous LI in tree order (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node
|
|
// can return NULL
|
|
prevAll: function(node, callback) {
|
|
var previous, lastChild, drillDown, match, prev, parent;
|
|
while (true) {
|
|
previous = this.prev(node);
|
|
if (previous) {
|
|
if (callback) {
|
|
match = callback.call(this, previous);
|
|
if (match === null) {
|
|
node = previous;
|
|
continue;
|
|
}
|
|
}
|
|
lastChild = this.lastChild(previous);
|
|
if (lastChild) {
|
|
if (callback && (callback.call(this, lastChild) === null)) {
|
|
node = lastChild;
|
|
continue;
|
|
}
|
|
prev = false;
|
|
while (drillDown = this.lastChild(lastChild)) {
|
|
lastChild = drillDown;
|
|
if (callback) {
|
|
match = callback.call(this, lastChild);
|
|
if (match === null) {
|
|
node = lastChild;
|
|
prev = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (prev) {
|
|
continue;
|
|
}
|
|
if (callback) {
|
|
match = callback.call(this, lastChild);
|
|
if (match) {
|
|
return lastChild;
|
|
} else if (match !== null) {
|
|
node = lastChild;
|
|
continue;
|
|
}
|
|
} else {
|
|
return lastChild;
|
|
}
|
|
} else {
|
|
if (!callback || match) {
|
|
return previous;
|
|
} else {
|
|
node = previous;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
parent = this.parent(node);
|
|
if (parent) {
|
|
if (callback) {
|
|
match = callback.call(this, parent);
|
|
if (match) {
|
|
return parent;
|
|
} else {
|
|
node = parent;
|
|
}
|
|
} else {
|
|
return parent;
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
// get the next LI in tree order (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node
|
|
// can return NULL
|
|
nextAll: function(node, callback) {
|
|
var firstChild, match, next, parent, child;
|
|
while (true) {
|
|
firstChild = this.firstChild(node);
|
|
if (firstChild) {
|
|
if (callback) {
|
|
match = callback.call(this, firstChild);
|
|
if (match) {
|
|
return firstChild;
|
|
} else {
|
|
node = firstChild;
|
|
if (match !== null) {
|
|
continue;
|
|
}
|
|
}
|
|
} else {
|
|
return firstChild;
|
|
}
|
|
}
|
|
while (true) {
|
|
next = this.next(node);
|
|
if (next) {
|
|
if (callback) {
|
|
match = callback.call(this, next);
|
|
if (match) {
|
|
return next;
|
|
} else {
|
|
node = next;
|
|
if (match !== null) {
|
|
break;
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
} else {
|
|
return next;
|
|
}
|
|
} else {
|
|
parent = node;
|
|
child = null;
|
|
while (parent = this.parent(parent)) {
|
|
next = this.next(parent);
|
|
if (next) {
|
|
if (callback) {
|
|
match = callback.call(this, next);
|
|
if (match) {
|
|
return next;
|
|
} else {
|
|
node = next;
|
|
if (match !== null) {
|
|
child = true;
|
|
} else {
|
|
child = false;
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
return next;
|
|
}
|
|
}
|
|
}
|
|
if (child !== null) {
|
|
if (child) {
|
|
break;
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
// get the first LI in tree order (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node
|
|
// can return NULL
|
|
first: function(node, callback) {
|
|
var container = this.container(node);
|
|
if (container) {
|
|
var firstChild = container.firstChild;
|
|
if (firstChild) {
|
|
if (callback && !callback.call(this, firstChild)) {
|
|
return this.nextAll(firstChild, callback);
|
|
}
|
|
return firstChild;
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
// get the last LI in tree order (with filtering)
|
|
// `node` must be valid LI DOM node
|
|
// `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node
|
|
// can return NULL
|
|
last: function(node, callback) {
|
|
var container = this.container(node);
|
|
if (container) {
|
|
var lastChild = container.lastChild;
|
|
if (lastChild) {
|
|
if (callback && (callback.call(this, lastChild) === null)) {
|
|
return this.prevAll(lastChild, callback);
|
|
} else {
|
|
var drillDown;
|
|
while (drillDown = this.lastChild(lastChild)) {
|
|
lastChild = drillDown;
|
|
}
|
|
if (callback && !callback.call(this, lastChild)) {
|
|
return this.prevAll(lastChild, callback);
|
|
}
|
|
return lastChild;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
// get the children LI from the node
|
|
// `node` must be valid LI DOM node
|
|
// `drillDown` if TRUE all children are returned
|
|
// `callback` can return FALSE to skip a node or NULL to prevent drill down/skip the node
|
|
children: function(node, drillDown, callback) {
|
|
var children = [], levels = [], match, next, skip;
|
|
var firstChild = this.firstChild(node);
|
|
if (firstChild) {
|
|
while (true) {
|
|
skip = false;
|
|
do {
|
|
if (callback) {
|
|
match = callback.call(this, firstChild);
|
|
if (match) {
|
|
children.push(firstChild);
|
|
}
|
|
if (drillDown && (match !== null)) {
|
|
next = this.firstChild(firstChild);
|
|
if (next) {
|
|
levels.push(firstChild);
|
|
firstChild = next;
|
|
skip = true;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
children.push(firstChild);
|
|
if (drillDown) {
|
|
next = this.firstChild(firstChild);
|
|
if (next) {
|
|
levels.push(firstChild);
|
|
firstChild = next;
|
|
skip = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} while (firstChild = firstChild.nextSibling);
|
|
if (!skip) {
|
|
while (firstChild = levels.pop()) {
|
|
firstChild = firstChild.nextSibling;
|
|
if (firstChild) {
|
|
break;
|
|
}
|
|
}
|
|
if (!firstChild) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return children;
|
|
},
|
|
// get a children from the node
|
|
// `node` must be valid DOM node
|
|
// `callback` can return FALSE to skip a node or NULL to stop the search
|
|
// can return NULL
|
|
childrenTill: function(node, callback) {
|
|
var levels = [], match, next, skip;
|
|
var firstChild = node.firstChild;
|
|
if (firstChild) {
|
|
while (true) {
|
|
skip = false;
|
|
do {
|
|
match = callback.call(this, firstChild);
|
|
if (match) {
|
|
return firstChild;
|
|
} else if (match === null) {
|
|
return null;
|
|
}
|
|
next = firstChild.firstChild;
|
|
if (next) {
|
|
levels.push(firstChild);
|
|
firstChild = next;
|
|
skip = true;
|
|
break;
|
|
}
|
|
} while (firstChild = firstChild.nextSibling);
|
|
if (!skip) {
|
|
while (firstChild = levels.pop()) {
|
|
firstChild = firstChild.nextSibling;
|
|
if (firstChild) {
|
|
break;
|
|
}
|
|
}
|
|
if (!firstChild) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
// get a children from the node having a class
|
|
// `node` must be valid DOM node
|
|
// `className` String or Array to check for
|
|
// can return NULL
|
|
childrenByClass: function(node, className) {
|
|
if (node.getElementsByClassName) {
|
|
var list = node.getElementsByClassName(className instanceof Array ? className.join(' ') : className);
|
|
return list ? list[0] : null;
|
|
} else {
|
|
return this.childrenTill(node, function(node) {
|
|
return this.hasClass(node, className);
|
|
});
|
|
}
|
|
},
|
|
// get the parent LI from the children LI
|
|
// `node` must be valid LI DOM node
|
|
// can return NULL
|
|
parent: function(node) {
|
|
var parent = node.parentNode.parentNode;
|
|
if (parent && (parent.nodeName == 'LI')) {
|
|
return parent;
|
|
}
|
|
return null;
|
|
},
|
|
// get the parent LI from any children
|
|
// `node` must be valid children of a LI DOM node
|
|
// can return NULL
|
|
parentFrom: function(node) {
|
|
while (node.nodeName != 'LI') {
|
|
node = node.parentNode;
|
|
if (!node) {
|
|
return null;
|
|
}
|
|
}
|
|
return node;
|
|
},
|
|
// get a parent from the node
|
|
// `node` must be valid DOM node
|
|
// `callback` can return FALSE to skip a node or NULL to stop the search
|
|
// can return NULL
|
|
parentTill: function(node, callback) {
|
|
var match;
|
|
while (node = node.parentNode) {
|
|
match = callback.call(this, node);
|
|
if (match) {
|
|
return node;
|
|
} else if (match === null) {
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
// get a parent from the node having a class
|
|
// `node` must be valid DOM node
|
|
// `className` String or Array to check for
|
|
// can return NULL
|
|
parentByClass: function(node, className) {
|
|
return this.parentTill(node, function(node) {
|
|
return this.hasClass(node, className);
|
|
});
|
|
},
|
|
// test if node has class(es)
|
|
// `className` String or Array to check for
|
|
// `withOut` String or Array to exclude with
|
|
hasClass: function(node, className, withOut) {
|
|
var oldClass = ' ' + node.className + ' ';
|
|
if (withOut instanceof Array) {
|
|
for (var i = 0; i < withOut.length; i++) {
|
|
if (oldClass.indexOf(' ' + withOut[i] + ' ') != -1) {
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
if (withOut && oldClass.indexOf(' ' + withOut + ' ') != -1) {
|
|
return false;
|
|
}
|
|
}
|
|
if (className instanceof Array) {
|
|
for (var i = 0; i < className.length; i++) {
|
|
if (oldClass.indexOf(' ' + className[i] + ' ') == -1) {
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
if (className && oldClass.indexOf(' ' + className + ' ') == -1) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
// filter nodes with class(es)
|
|
// `nodes` Array of DOM nodes
|
|
// @see `hasClass`
|
|
withClass: function(nodes, className, withOut) {
|
|
var filter = [];
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
if (this.hasClass(nodes[i], className, withOut)) {
|
|
filter.push(nodes[i]);
|
|
}
|
|
}
|
|
return filter;
|
|
},
|
|
// test if node has any class(es)
|
|
// `className` String or Array to check for (any class)
|
|
// `withOut` String or Array to exclude with
|
|
hasAnyClass: function(node, className, withOut) {
|
|
var oldClass = ' ' + node.className + ' ';
|
|
if (withOut instanceof Array) {
|
|
for (var i = 0; i < withOut.length; i++) {
|
|
if (oldClass.indexOf(' ' + withOut[i] + ' ') != -1) {
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
if (withOut && oldClass.indexOf(' ' + withOut + ' ') != -1) {
|
|
return false;
|
|
}
|
|
}
|
|
if (className instanceof Array) {
|
|
for (var i = 0; i < className.length; i++) {
|
|
if (oldClass.indexOf(' ' + className[i] + ' ') != -1) {
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
if (className && oldClass.indexOf(' ' + className + ' ') != -1) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
// filter nodes with any class(es)
|
|
// `nodes` Array of DOM nodes
|
|
// @see `hasAnyClass`
|
|
withAnyClass: function(nodes, className, withOut) {
|
|
var filter = [];
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
if (this.hasAnyClass(nodes[i], className, withOut)) {
|
|
filter.push(nodes[i]);
|
|
}
|
|
}
|
|
return filter;
|
|
},
|
|
// add class(es) to node
|
|
// `node` must be valid DOM node
|
|
// `className` String or Array to add
|
|
// return TRUE if className changed
|
|
addClass: function(node, className) {
|
|
var oldClass = ' ' + node.className + ' ', append = '';
|
|
if (className instanceof Array) {
|
|
for (var i = 0; i < className.length; i++) {
|
|
if (oldClass.indexOf(' ' + className[i] + ' ') == -1) {
|
|
append += ' ' + className[i];
|
|
}
|
|
}
|
|
} else {
|
|
if (oldClass.indexOf(' ' + className + ' ') == -1) {
|
|
append += ' ' + className;
|
|
}
|
|
}
|
|
if (append) {
|
|
node.className = node.className + append;
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
// add class(es) to nodes
|
|
// `nodes` Array of DOM nodes
|
|
// @see `addClass`
|
|
addListClass: function(nodes, className, callback) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
this.addClass(nodes[i], className);
|
|
if (callback) {
|
|
callback.call(this, nodes[i]);
|
|
}
|
|
}
|
|
},
|
|
// remove class(es) from node
|
|
// `node` must be valid DOM node
|
|
// `className` String or Array to remove
|
|
// return TRUE if className changed
|
|
removeClass: function(node, className) {
|
|
var oldClass = ' ' + node.className + ' ';
|
|
if (className instanceof Array) {
|
|
for (var i = 0; i < className.length; i++) {
|
|
oldClass = oldClass.replace(' ' + className[i] + ' ', ' ');
|
|
}
|
|
} else {
|
|
oldClass = oldClass.replace(' ' + className + ' ', ' ');
|
|
}
|
|
oldClass = oldClass.substr(1, oldClass.length - 2);
|
|
if (node.className != oldClass) {
|
|
node.className = oldClass;
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
// remove class(es) from nodes
|
|
// `nodes` Array of DOM nodes
|
|
// @see `removeClass`
|
|
removeListClass: function(nodes, className, callback) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
this.removeClass(nodes[i], className);
|
|
if (callback) {
|
|
callback.call(this, nodes[i]);
|
|
}
|
|
}
|
|
},
|
|
// toggle node class(es)
|
|
// `node` must be valid DOM node
|
|
// `className` String or Array to toggle
|
|
// `add` TRUE to add them
|
|
// return TRUE if className changed
|
|
toggleClass: function(node, className, add) {
|
|
if (add) {
|
|
return this.addClass(node, className);
|
|
} else {
|
|
return this.removeClass(node, className);
|
|
}
|
|
},
|
|
// toggle nodes class(es)
|
|
// `nodes` Array of DOM nodes
|
|
// @see `toggleClass`
|
|
toggleListClass: function(nodes, className, add, callback) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
this.toggleClass(nodes[i], className, add);
|
|
if (callback) {
|
|
callback.call(this, nodes[i]);
|
|
}
|
|
}
|
|
},
|
|
// add/remove and keep old class(es)
|
|
// `node` must be valid DOM node
|
|
// `addClass` String or Array to add
|
|
// `removeClass` String or Array to remove
|
|
// return TRUE if className changed
|
|
addRemoveClass: function(node, addClass, removeClass) {
|
|
var oldClass = ' ' + node.className + ' ';
|
|
if (removeClass) {
|
|
if (removeClass instanceof Array) {
|
|
for (var i = 0; i < removeClass.length; i++) {
|
|
oldClass = oldClass.replace(' ' + removeClass[i] + ' ', ' ');
|
|
}
|
|
} else {
|
|
oldClass = oldClass.replace(' ' + removeClass + ' ', ' ');
|
|
}
|
|
}
|
|
if (addClass) {
|
|
var append = '';
|
|
if (addClass instanceof Array) {
|
|
for (var i = 0; i < addClass.length; i++) {
|
|
if (oldClass.indexOf(' ' + addClass[i] + ' ') == -1) {
|
|
append += addClass[i] + ' ';
|
|
}
|
|
}
|
|
} else {
|
|
if (oldClass.indexOf(' ' + addClass + ' ') == -1) {
|
|
append += addClass + ' ';
|
|
}
|
|
}
|
|
oldClass += append;
|
|
}
|
|
oldClass = oldClass.substr(1, oldClass.length - 2);
|
|
if (node.className != oldClass) {
|
|
node.className = oldClass;
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
// add/remove and keep old class(es)
|
|
// `nodes` Array of DOM nodes
|
|
// @see `addRemoveClass`
|
|
addRemoveListClass: function(nodes, addClass, removeClass, callback) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
this.addRemoveClass(nodes[i], addClass, removeClass);
|
|
if (callback) {
|
|
callback.call(this, nodes[i]);
|
|
}
|
|
}
|
|
}
|
|
};
|