UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

99 lines (85 loc) 2.67 kB
/** * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved. * Node module: @schukai/monster * * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3). * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html * * For those who do not wish to adhere to the AGPLv3, a commercial license is available. * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms. * For more information about purchasing a commercial license, please contact schukai GmbH. * * SPDX-License-Identifier: AGPL-3.0 */ import { internalSymbol } from "../constants.mjs"; import { Base } from "./base.mjs"; import { isInstance } from "./is.mjs"; import { Node } from "./node.mjs"; import { NodeList } from "./nodelist.mjs"; import { validateInstance } from "./validate.mjs"; export { NodeRecursiveIterator }; /** * @private * @type {symbol} */ const isNodeListSymbol = Symbol("isNodeList"); /** * Represents a recursive iterator for traversing nodes in a DOM tree. * * @since 1.26.0 * @summary An iterator to run recursively through a tree of nodes * @extends Base */ class NodeRecursiveIterator extends Base { /** * @param node */ constructor(node) { super(); this[isNodeListSymbol] = false; // iterator is a NodeList if (isInstance(node, NodeList)) { const children = node; const n = new Node(); n.childNodes = children; this[isNodeListSymbol] = true; this[internalSymbol] = n; return; } this[internalSymbol] = validateInstance(node, Node); } /** * @private * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield */ [Symbol.iterator] = function* () { /** * The end of the generator function is reached. In this case, execution of the generator * ends and an IteratorResult is returned to the caller in which the value is undefined and done is true. * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield */ if (this[internalSymbol] === undefined) { return; } // iterator is a nodelist and the main node is only a placeholder if (this[isNodeListSymbol] !== true) { yield this[internalSymbol]; } if (this[internalSymbol].hasChildNodes()) { const childNodes = this[internalSymbol].childNodes; for (const node of childNodes) { yield* new NodeRecursiveIterator(node); } } }; /** * @param {function} callback * @return {NodeRecursiveIterator} */ forEach(callback) { for (const node of this) { callback(node); } return this; } }