1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  package org.htmlunit.javascript.host.css;
16  
17  import java.util.ArrayList;
18  import java.util.List;
19  
20  import org.htmlunit.cssparser.dom.AbstractCSSRuleImpl;
21  import org.htmlunit.cssparser.dom.CSSCharsetRuleImpl;
22  import org.htmlunit.cssparser.dom.CSSMediaRuleImpl;
23  import org.htmlunit.cssparser.dom.CSSRuleListImpl;
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  import org.w3c.dom.DOMException;
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  @JsxClass
40  public class CSSGroupingRule extends CSSRule {
41  
42      
43      private CSSRuleList cssRules_;
44      private List<Integer> cssRulesIndexFix_;
45  
46      
47  
48  
49      public CSSGroupingRule() {
50          super();
51      }
52  
53      
54  
55  
56      @JsxConstructor
57      @Override
58      public void jsConstructor() {
59          super.jsConstructor();
60      }
61  
62      
63  
64  
65  
66  
67      protected CSSGroupingRule(final CSSStyleSheet stylesheet, final CSSMediaRuleImpl rule) {
68          super(stylesheet, rule);
69      }
70  
71      
72  
73  
74  
75      @JsxGetter
76      public CSSRuleList getCssRules() {
77          initCssRules();
78          return cssRules_;
79      }
80  
81      
82  
83  
84  
85  
86  
87      @JsxFunction
88      public int insertRule(final String rule, final Object position) {
89          final int positionInt;
90          if (position == null) {
91              positionInt = 0;
92          }
93          else if (JavaScriptEngine.isUndefined(position)) {
94              positionInt = 0;
95          }
96          else {
97              positionInt = JavaScriptEngine.toInt32(position);
98          }
99  
100         try {
101             initCssRules();
102             getGroupingRule().insertRule(rule, fixIndex(positionInt));
103             refreshCssRules();
104             return positionInt;
105         }
106         catch (final DOMException e) {
107             
108             final int pos = rule.indexOf('{');
109             if (pos > -1) {
110                 final String newRule = rule.substring(0, pos) + "{}";
111                 try {
112                     getGroupingRule().insertRule(newRule, fixIndex(positionInt));
113                     refreshCssRules();
114                     return positionInt;
115                 }
116                 catch (final DOMException ex) {
117                     throw JavaScriptEngine.asJavaScriptException(
118                             getWindow(), ex.getMessage(), ex.code);
119                 }
120             }
121             throw JavaScriptEngine.asJavaScriptException(
122                     getWindow(),
123                     e.getMessage(),
124                     org.htmlunit.javascript.host.dom.DOMException.SYNTAX_ERR);
125         }
126     }
127 
128     
129 
130 
131 
132     @JsxFunction
133     public void deleteRule(final int position) {
134         try {
135             initCssRules();
136             getGroupingRule().deleteRule(fixIndex(position));
137             refreshCssRules();
138         }
139         catch (final DOMException e) {
140             throw JavaScriptEngine.asJavaScriptException(getWindow(), e.getMessage(), e.code);
141         }
142     }
143 
144     private void initCssRules() {
145         if (cssRules_ == null) {
146             cssRules_ = new CSSRuleList(this);
147             cssRulesIndexFix_ = new ArrayList<>();
148             refreshCssRules();
149         }
150     }
151 
152     private int fixIndex(int index) {
153         for (final int fix : cssRulesIndexFix_) {
154             if (fix > index) {
155                 return index;
156             }
157             index++;
158         }
159         return index;
160     }
161 
162     private void refreshCssRules() {
163         if (cssRules_ == null) {
164             return;
165         }
166 
167         cssRules_.clearRules();
168         cssRulesIndexFix_.clear();
169 
170         final CSSRuleListImpl ruleList = getGroupingRule().getCssRules();
171         final List<AbstractCSSRuleImpl> rules = ruleList.getRules();
172         int pos = 0;
173         for (final AbstractCSSRuleImpl rule : rules) {
174             if (rule instanceof CSSCharsetRuleImpl) {
175                 cssRulesIndexFix_.add(pos);
176                 continue;
177             }
178 
179             final CSSRule cssRule = CSSRule.create(getParentStyleSheet(), rule);
180             if (null == cssRule) {
181                 cssRulesIndexFix_.add(pos);
182             }
183             else {
184                 cssRules_.addRule(cssRule);
185             }
186             pos++;
187         }
188     }
189 
190     
191 
192 
193 
194     private CSSMediaRuleImpl getGroupingRule() {
195         return (CSSMediaRuleImpl) getRule();
196     }
197 }