View Javadoc
1   /*
2    * Copyright (c) 2002-2025 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.css;
16  
17  import static org.htmlunit.BrowserVersionFeatures.JS_CSSRULELIST_ENUM_ITEM_LENGTH;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.htmlunit.corejs.javascript.Scriptable;
23  import org.htmlunit.javascript.HtmlUnitScriptable;
24  import org.htmlunit.javascript.JavaScriptEngine;
25  import org.htmlunit.javascript.configuration.JsxClass;
26  import org.htmlunit.javascript.configuration.JsxConstructor;
27  import org.htmlunit.javascript.configuration.JsxFunction;
28  import org.htmlunit.javascript.configuration.JsxGetter;
29  
30  /**
31   * A JavaScript object for {@code CSSRuleList}.
32   *
33   * @author Ahmed Ashour
34   * @author Ronald Brill
35   * @author Frank Danek
36   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList">MDN doc</a>
37   */
38  @JsxClass
39  public class CSSRuleList extends HtmlUnitScriptable {
40  
41      private final List<CSSRule> rules_ = new ArrayList<>();
42  
43      /**
44       * Creates a new instance.
45       */
46      public CSSRuleList() {
47          super();
48      }
49  
50      /**
51       * Creates an instance.
52       */
53      @JsxConstructor
54      public void jsConstructor() {
55          throw JavaScriptEngine.typeErrorIllegalConstructor();
56      }
57  
58      /**
59       * Creates a new instance.
60       * @param stylesheet the stylesheet
61       */
62      public CSSRuleList(final CSSStyleSheet stylesheet) {
63          super();
64          setParentScope(stylesheet.getParentScope());
65          setPrototype(getPrototype(getClass()));
66      }
67  
68      /**
69       * Creates a new instance.
70       * @param groupingRule the grouping rule
71       */
72      public CSSRuleList(final CSSGroupingRule groupingRule) {
73          super();
74          setParentScope(groupingRule.getParentScope());
75          setPrototype(getPrototype(getClass()));
76      }
77  
78      /**
79       * Add a rule.
80       * @param rule the rule to add
81       */
82      protected void addRule(final CSSRule rule) {
83          rules_.add(rule);
84      }
85  
86      /**
87       * Clear the listOfRules.
88       */
89      protected void clearRules() {
90          rules_.clear();
91      }
92  
93      /**
94       * Returns the length of this list.
95       * @return the length of this list.
96       */
97      @JsxGetter
98      public int getLength() {
99          return rules_.size();
100     }
101 
102     /**
103      * Returns the item in the given index.
104      * @param index the index
105      * @return the item in the given index
106      */
107     @JsxFunction
108     public Object item(final int index) {
109         final Object item = get(index, this);
110         if (NOT_FOUND == item) {
111             return null;
112         }
113         return item;
114     }
115 
116     /**
117      * {@inheritDoc}.
118      */
119     @Override
120     public Object[] getIds() {
121         final List<String> idList = new ArrayList<>();
122 
123         final int length = getLength();
124         for (int i = 0; i < length; i++) {
125             idList.add(Integer.toString(i));
126         }
127 
128         if (getBrowserVersion().hasFeature(JS_CSSRULELIST_ENUM_ITEM_LENGTH)) {
129             idList.add("item");
130             idList.add("length");
131         }
132         else {
133             idList.add("length");
134             idList.add("item");
135         }
136         return idList.toArray();
137     }
138 
139     /**
140      * {@inheritDoc}
141      */
142     @Override
143     public boolean has(final int index, final Scriptable start) {
144         return index >= 0 && index < getLength();
145     }
146 
147     /**
148      * {@inheritDoc}.
149      */
150     @Override
151     public boolean has(final String name, final Scriptable start) {
152         if ("length".equals(name) || "item".equals(name)) {
153             return true;
154         }
155         try {
156             return has(Integer.parseInt(name), start);
157         }
158         catch (final Exception ignored) {
159             // ignore
160         }
161         return false;
162     }
163 
164     /**
165      * {@inheritDoc}
166      */
167     @Override
168     public Object get(final int index, final Scriptable start) {
169         if (index < 0 || getLength() <= index) {
170             return NOT_FOUND;
171         }
172         return rules_.get(index);
173     }
174 
175 }