UNPKG

4.93 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
5 * This code may only be used under the BSD style license found at
6 * http://polymer.github.io/LICENSE.txt
7 * The complete set of authors may be found at
8 * http://polymer.github.io/AUTHORS.txt
9 * The complete set of contributors may be found at
10 * http://polymer.github.io/CONTRIBUTORS.txt
11 * Code distributed by Google as part of the polymer project is also
12 * subject to an additional IP rights grant found at
13 * http://polymer.github.io/PATENTS.txt
14 */
15Object.defineProperty(exports, "__esModule", { value: true });
16const predicates_1 = require("./predicates");
17const util_1 = require("./util");
18/**
19 * Applies `mapfn` to `node` and the tree below `node`, yielding a flattened
20 * list of results.
21 */
22function* treeMap(node, mapfn, getChildNodes) {
23 for (const child of depthFirst(node, getChildNodes)) {
24 yield* mapfn(child);
25 }
26}
27exports.treeMap = treeMap;
28/**
29 * Yields `node` and all of its children, recursively.
30 *
31 * Yields `node` first, then yields each descendent in depth first order.
32 */
33function* depthFirst(node, getChildNodes = util_1.defaultChildNodes) {
34 yield node;
35 const childNodes = getChildNodes(node);
36 if (childNodes === undefined) {
37 return;
38 }
39 for (const child of childNodes) {
40 yield* depthFirst(child, getChildNodes);
41 }
42}
43exports.depthFirst = depthFirst;
44/**
45 * Yields node and all its descendents in reverse document order.
46 *
47 * Equivalent to:
48 * yield* [...depthFirst(node)].reverse()
49 */
50function* depthFirstReversed(node, getChildNodes = util_1.defaultChildNodes) {
51 const childNodes = getChildNodes(node);
52 if (childNodes !== undefined) {
53 for (const child of reversedView(childNodes)) {
54 yield* depthFirstReversed(child, getChildNodes);
55 }
56 }
57 yield node;
58}
59exports.depthFirstReversed = depthFirstReversed;
60/**
61 * Like `depthFirst`, but descends into the bodies of `<template>`s.
62 */
63function depthFirstIncludingTemplates(node) {
64 return depthFirst(node, util_1.childNodesIncludeTemplate);
65}
66exports.depthFirstIncludingTemplates = depthFirstIncludingTemplates;
67/**
68 * Yields `node` and each of its ancestors leading up the tree.
69 */
70function* ancestors(node) {
71 let currNode = node;
72 while (currNode !== undefined) {
73 yield currNode;
74 currNode = currNode.parentNode;
75 }
76}
77exports.ancestors = ancestors;
78/**
79 * Yields each element that has the same parent as `node` but that
80 * comes before it in the document.
81 *
82 * Nodes are yielded in reverse document order (i.e. starting with the one
83 * closest to `node`)
84 */
85function* previousSiblings(node) {
86 const parent = node.parentNode;
87 if (parent === undefined) {
88 return;
89 }
90 const siblings = parent.childNodes;
91 if (siblings === undefined) {
92 throw new Error(`Inconsistent parse5 tree: parent does not have children`);
93 }
94 const index = siblings.indexOf(node);
95 if (index === -1) {
96 throw new Error(`Inconsistent parse5 tree: parent does not know about child`);
97 }
98 yield* reversedView(siblings, index - 1);
99}
100exports.previousSiblings = previousSiblings;
101/** Iterate arr in reverse, optionally starting at a given index. */
102function* reversedView(arr, initialIndex = arr.length - 1) {
103 for (let index = initialIndex; index >= 0; index--) {
104 yield arr[index];
105 }
106}
107/**
108 * Yields every node in the document that comes before `node`, in reverse
109 * document order.
110 *
111 * So if you have a tree like:
112 * ```html
113 * <body>
114 * <nav>
115 * <li></li>
116 * </nav>
117 * <div>
118 * <span></span>
119 * <b></b>
120 * <em></em>
121 * ...
122 * ```
123 *
124 * Then `prior(<b>)` will yield:
125 *
126 * <span>, <div>, <li>, <nav>, <body>, <head>, #document
127 *
128 * (`<head>` and `#document` are hallucinated by the html parser)
129 */
130function* prior(node) {
131 for (const previousSibling of previousSiblings(node)) {
132 yield* depthFirstReversed(previousSibling);
133 }
134 const parent = node.parentNode;
135 if (parent) {
136 yield parent;
137 yield* prior(parent);
138 }
139}
140exports.prior = prior;
141/**
142 * Like queryAll, but just returns the first result.
143 */
144function query(node, predicate, getChildNodes = util_1.defaultChildNodes) {
145 for (const result of queryAll(node, predicate, getChildNodes)) {
146 return result;
147 }
148 return null;
149}
150exports.query = query;
151/**
152 * Applies `depthFirst` to node and yields each Element that matches the given
153 * predicate.
154 */
155function* queryAll(node, predicate, getChildNodes = util_1.defaultChildNodes) {
156 const elementPredicate = predicates_1.predicates.AND(predicates_1.isElement, predicate);
157 for (const desc of depthFirst(node, getChildNodes)) {
158 if (elementPredicate(desc)) {
159 yield desc;
160 }
161 }
162}
163exports.queryAll = queryAll;
164//# sourceMappingURL=iteration.js.map
\No newline at end of file