/*
Copyright 2008-2010 University of Cambridge
Copyright 2008-2009 University of Toronto
Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Licenses.
You may obtain a copy of the ECL 2.0 License and BSD License at
https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
*/
var fluid_3_0_0 = fluid_3_0_0 || {};
(function ($, fluid) {
"use strict";
fluid.dom = fluid.dom || {};
// Node walker function for iterateDom.
var getNextNode = function (iterator) {
if (iterator.node.firstChild) {
iterator.node = iterator.node.firstChild;
iterator.depth += 1;
return iterator;
}
while (iterator.node) {
if (iterator.node.nextSibling) {
iterator.node = iterator.node.nextSibling;
return iterator;
}
iterator.node = iterator.node.parentNode;
iterator.depth -= 1;
}
return iterator;
};
/**
* Walks the DOM, applying the specified acceptor function to each element.
* There is a special case for the acceptor, allowing for quick deletion of elements and their children.
* Return "delete" from your acceptor function if you want to delete the element in question.
* Return "stop" to terminate iteration.
* Implementation note - this utility exists mainly for performance reasons. It was last tested
* carefully some time ago (around jQuery 1.2) but at that time was around 3-4x faster at raw DOM
* filtration tasks than the jQuery equivalents, which was an important source of performance loss in the
* Reorderer component. General clients of the framework should use this method with caution if at all, and
* the performance issues should be reassessed when we have time.
*
* @param {Element} node - The node to start walking from.
* @param {Function} acceptor - The function to invoke with each DOM element.
* @param {Boolean} allNodes - Use <code>true</code> to call acceptor on all nodes, rather than just element nodes
* (type 1).
* @return {Object|undefined} - Returns `undefined` if the run completed successfully. If a node stopped the run,
* that node is returned.
*/
fluid.dom.iterateDom = function (node, acceptor, allNodes) {
var currentNode = {node: node, depth: 0};
var prevNode = node;
var condition;
while (currentNode.node !== null && currentNode.depth >= 0 && currentNode.depth < fluid.dom.iterateDom.DOM_BAIL_DEPTH) {
condition = null;
if (currentNode.node.nodeType === 1 || allNodes) {
condition = acceptor(currentNode.node, currentNode.depth);
}
if (condition) {
Iif (condition === "delete") {
currentNode.node.parentNode.removeChild(currentNode.node);
currentNode.node = prevNode;
}
else Eif (condition === "stop") {
return currentNode.node;
}
}
prevNode = currentNode.node;
currentNode = getNextNode(currentNode);
}
};
// Work around IE circular DOM issue. This is the default max DOM depth on IE.
// http://msdn2.microsoft.com/en-us/library/ms761392(VS.85).aspx
fluid.dom.iterateDom.DOM_BAIL_DEPTH = 256;
/**
* Checks if the specified container is actually the parent of containee.
*
* @param {Element} container - the potential parent
* @param {Element} containee - the child in question
* @return {Boolean} - `true` if `container` contains `containee`, `false` otherwise.
*/
fluid.dom.isContainer = function (container, containee) {
for (; containee; containee = containee.parentNode) {
if (container === containee) {
return true;
}
}
return false;
};
/* Return the element text from the supplied DOM node as a single String.
* Implementation note - this is a special-purpose utility used in the framework in just one
* position in the Reorderer. It only performs a "shallow" traversal of the text and was intended
* as a quick and dirty means of extracting element labels where the user had not explicitly provided one.
* It should not be used by general users of the framework and its presence here needs to be
* reassessed.
*/
fluid.dom.getElementText = function (element) {
var nodes = element.childNodes;
var text = "";
for (var i = 0; i < nodes.length; ++i) {
var child = nodes[i];
if (child.nodeType === 3) {
text = text + child.nodeValue;
}
}
return text;
};
})(jQuery, fluid_3_0_0);
|