View Javadoc
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 }