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 }