1 /*
2 * Copyright (c) 2002-2026 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit.javascript.host.dom;
16
17 import org.htmlunit.html.DomNode;
18 import org.htmlunit.html.DomNodeIterator;
19 import org.htmlunit.javascript.HtmlUnitScriptable;
20 import org.htmlunit.javascript.configuration.JsxClass;
21 import org.htmlunit.javascript.configuration.JsxConstructor;
22 import org.htmlunit.javascript.configuration.JsxFunction;
23 import org.htmlunit.javascript.configuration.JsxGetter;
24
25 /**
26 * A JavaScript object for {@code NodeIterator}.
27 *
28 * @author Ahmed Ashour
29 * @author Ronald Brill
30 *
31 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator">MDN Documentation</a>
32 */
33 @JsxClass
34 public class NodeIterator extends HtmlUnitScriptable {
35
36 private DomNodeIterator iterator_;
37
38 /**
39 * Creates an instance.
40 */
41 public NodeIterator() {
42 super();
43 }
44
45 /**
46 * JavaScript constructor.
47 */
48 @JsxConstructor
49 public void jsConstructor() {
50 // nothing to do
51 }
52
53 /**
54 * Creates a new instance.
55 *
56 * @param root The root node at which to begin the {@link NodeIterator}'s traversal
57 * @param whatToShow an optional long representing a bitmask created by combining
58 * the constant properties of {@link NodeFilter}
59 * @param filter an object implementing the {@link NodeFilter} interface
60 */
61 public NodeIterator(final Node root, final int whatToShow,
62 final org.w3c.dom.traversal.NodeFilter filter) {
63 super();
64 iterator_ = new DomNodeIterator(root.getDomNodeOrDie(), whatToShow, filter, true);
65 }
66
67 /**
68 * Returns the root node.
69 * @return the root node
70 */
71 @JsxGetter
72 public Node getRoot() {
73 return getNodeOrNull(iterator_.getRoot());
74 }
75
76 private static Node getNodeOrNull(final DomNode domNode) {
77 if (domNode == null) {
78 return null;
79 }
80 return domNode.getScriptableObject();
81 }
82
83 /**
84 * Returns the types of nodes being presented.
85 * @return combined bitmask of {@link NodeFilter}
86 */
87 public long getWhatToShow() {
88 if (iterator_.getWhatToShow() == NodeFilter.SHOW_ALL) {
89 return 0xFFFFFFFFL;
90 }
91 return iterator_.getWhatToShow();
92 }
93
94 /**
95 * Returns the filter.
96 * @return the filter
97 */
98 @JsxGetter
99 public Object getFilter() {
100 //TODO: we should return the original filter
101 return iterator_.getFilter();
102 }
103
104 /**
105 * This operation is a no-op.
106 */
107 @JsxFunction
108 public void detach() {
109 iterator_.detach();
110 }
111
112 /**
113 * Returns the next Node in the document, or null if there are none.
114 * @return the next node
115 */
116 @JsxFunction
117 public Node nextNode() {
118 return getNodeOrNull(iterator_.nextNode());
119 }
120
121 /**
122 * Returns the previous Node in the document, or null if there are none.
123 * @return the previous node
124 */
125 @JsxFunction
126 public Node previousNode() {
127 return getNodeOrNull(iterator_.previousNode());
128 }
129 }