UNPKG

infusion

Version:

Infusion is an application framework for developing flexible stuff with JavaScript

121 lines (108 loc) 5.02 kB
/* Copyright The Infusion copyright holders See the AUTHORS.md file at the top-level directory of this distribution and at https://github.com/fluid-project/infusion/raw/master/AUTHORS.md. 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) { if (condition === "delete") { currentNode.node.parentNode.removeChild(currentNode.node); currentNode.node = prevNode; } else if (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);