|
1 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ |
|
2 /* Any copyright is dedicated to the Public Domain. |
|
3 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 // Test that pseudoelements are displayed correctly in the rule view |
|
8 |
|
9 const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html"; |
|
10 |
|
11 let test = asyncTest(function*() { |
|
12 yield addTab(TEST_URI); |
|
13 let {toolbox, inspector, view} = yield openRuleView(); |
|
14 |
|
15 yield testTopLeft(inspector, view); |
|
16 yield testTopRight(inspector, view); |
|
17 yield testBottomRight(inspector, view); |
|
18 yield testBottomLeft(inspector, view); |
|
19 yield testParagraph(inspector, view); |
|
20 yield testBody(inspector, view); |
|
21 }); |
|
22 |
|
23 function* testTopLeft(inspector, view) { |
|
24 let { |
|
25 rules, |
|
26 element, |
|
27 elementStyle |
|
28 } = yield assertPseudoElementRulesNumbers("#topleft", inspector, view, { |
|
29 elementRulesNb: 4, |
|
30 afterRulesNb: 1, |
|
31 beforeRulesNb: 2, |
|
32 firstLineRulesNb: 0, |
|
33 firstLetterRulesNb: 0, |
|
34 selectionRulesNb: 0 |
|
35 }); |
|
36 |
|
37 let gutters = assertGutters(view); |
|
38 |
|
39 // Make sure that clicking on the twisty hides pseudo elements |
|
40 let expander = gutters[0].querySelector(".ruleview-expander"); |
|
41 ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded"); |
|
42 expander.click(); |
|
43 ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty"); |
|
44 expander.click(); |
|
45 ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again"); |
|
46 |
|
47 // Make sure that dblclicking on the header container also toggles the pseudo elements |
|
48 EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2}, inspector.sidebar.getWindowForTab("ruleview")); |
|
49 ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by dblclicking"); |
|
50 |
|
51 let defaultView = element.ownerDocument.defaultView; |
|
52 let elementRule = rules.elementRules[0]; |
|
53 let elementRuleView = [].filter.call(view.element.children, e => { |
|
54 return e._ruleEditor && e._ruleEditor.rule === elementRule; |
|
55 })[0]._ruleEditor; |
|
56 |
|
57 let elementAfterRule = rules.afterRules[0]; |
|
58 let elementAfterRuleView = [].filter.call(view.element.children, (e) => { |
|
59 return e._ruleEditor && e._ruleEditor.rule === elementAfterRule; |
|
60 })[0]._ruleEditor; |
|
61 |
|
62 is |
|
63 ( |
|
64 convertTextPropsToString(elementAfterRule.textProps), |
|
65 "background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " + |
|
66 "border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px", |
|
67 "TopLeft after properties are correct" |
|
68 ); |
|
69 |
|
70 let elementBeforeRule = rules.beforeRules[0]; |
|
71 let elementBeforeRuleView = [].filter.call(view.element.children, (e) => { |
|
72 return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule; |
|
73 })[0]._ruleEditor; |
|
74 |
|
75 is |
|
76 ( |
|
77 convertTextPropsToString(elementBeforeRule.textProps), |
|
78 "top: 0px; left: 0px", |
|
79 "TopLeft before properties are correct" |
|
80 ); |
|
81 |
|
82 let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", ""); |
|
83 let secondProp = elementAfterRuleView.addProperty("padding", "100px", ""); |
|
84 |
|
85 is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2], |
|
86 "First added property is on back of array"); |
|
87 is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1], |
|
88 "Second added property is on back of array"); |
|
89 |
|
90 yield elementAfterRule._applyingModifications; |
|
91 |
|
92 is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), |
|
93 "rgb(0, 255, 0)", "Added property should have been used."); |
|
94 is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), |
|
95 "100px", "Added property should have been used."); |
|
96 is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), |
|
97 "32px", "Added property should not apply to element"); |
|
98 |
|
99 secondProp.setEnabled(false); |
|
100 yield elementAfterRule._applyingModifications; |
|
101 |
|
102 is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px", |
|
103 "Disabled property should have been used."); |
|
104 is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", |
|
105 "Added property should not apply to element"); |
|
106 |
|
107 secondProp.setEnabled(true); |
|
108 yield elementAfterRule._applyingModifications; |
|
109 |
|
110 is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px", |
|
111 "Enabled property should have been used."); |
|
112 is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", |
|
113 "Added property should not apply to element"); |
|
114 |
|
115 let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", ""); |
|
116 yield elementRule._applyingModifications; |
|
117 |
|
118 is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)", |
|
119 "Added property should have been used."); |
|
120 is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)", |
|
121 "Added prop does not apply to pseudo"); |
|
122 } |
|
123 |
|
124 function* testTopRight(inspector, view) { |
|
125 let { |
|
126 rules, |
|
127 element, |
|
128 elementStyle |
|
129 } = yield assertPseudoElementRulesNumbers("#topright", inspector, view, { |
|
130 elementRulesNb: 4, |
|
131 afterRulesNb: 1, |
|
132 beforeRulesNb: 2, |
|
133 firstLineRulesNb: 0, |
|
134 firstLetterRulesNb: 0, |
|
135 selectionRulesNb: 0 |
|
136 }); |
|
137 |
|
138 let gutters = assertGutters(view); |
|
139 |
|
140 let expander = gutters[0].querySelector(".ruleview-expander"); |
|
141 ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element"); |
|
142 expander.scrollIntoView(); |
|
143 expander.click(); |
|
144 ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty"); |
|
145 } |
|
146 |
|
147 function* testBottomRight(inspector, view) { |
|
148 yield assertPseudoElementRulesNumbers("#bottomright", inspector, view, { |
|
149 elementRulesNb: 4, |
|
150 afterRulesNb: 1, |
|
151 beforeRulesNb: 3, |
|
152 firstLineRulesNb: 0, |
|
153 firstLetterRulesNb: 0, |
|
154 selectionRulesNb: 0 |
|
155 }); |
|
156 } |
|
157 |
|
158 function* testBottomLeft(inspector, view) { |
|
159 yield assertPseudoElementRulesNumbers("#bottomleft", inspector, view, { |
|
160 elementRulesNb: 4, |
|
161 afterRulesNb: 1, |
|
162 beforeRulesNb: 2, |
|
163 firstLineRulesNb: 0, |
|
164 firstLetterRulesNb: 0, |
|
165 selectionRulesNb: 0 |
|
166 }); |
|
167 } |
|
168 |
|
169 function* testParagraph(inspector, view) { |
|
170 let { |
|
171 rules, |
|
172 element, |
|
173 elementStyle |
|
174 } = yield assertPseudoElementRulesNumbers("#bottomleft p", inspector, view, { |
|
175 elementRulesNb: 3, |
|
176 afterRulesNb: 0, |
|
177 beforeRulesNb: 0, |
|
178 firstLineRulesNb: 1, |
|
179 firstLetterRulesNb: 1, |
|
180 selectionRulesNb: 1 |
|
181 }); |
|
182 |
|
183 let gutters = assertGutters(view); |
|
184 |
|
185 let elementFirstLineRule = rules.firstLineRules[0]; |
|
186 let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => { |
|
187 return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule; |
|
188 })[0]._ruleEditor; |
|
189 |
|
190 is |
|
191 ( |
|
192 convertTextPropsToString(elementFirstLineRule.textProps), |
|
193 "background: none repeat scroll 0% 0% blue", |
|
194 "Paragraph first-line properties are correct" |
|
195 ); |
|
196 |
|
197 let elementFirstLetterRule = rules.firstLetterRules[0]; |
|
198 let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => { |
|
199 return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule; |
|
200 })[0]._ruleEditor; |
|
201 |
|
202 is |
|
203 ( |
|
204 convertTextPropsToString(elementFirstLetterRule.textProps), |
|
205 "color: red; font-size: 130%", |
|
206 "Paragraph first-letter properties are correct" |
|
207 ); |
|
208 |
|
209 let elementSelectionRule = rules.selectionRules[0]; |
|
210 let elementSelectionRuleView = [].filter.call(view.element.children, (e) => { |
|
211 return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule; |
|
212 })[0]._ruleEditor; |
|
213 |
|
214 is |
|
215 ( |
|
216 convertTextPropsToString(elementSelectionRule.textProps), |
|
217 "color: white; background: none repeat scroll 0% 0% black", |
|
218 "Paragraph first-letter properties are correct" |
|
219 ); |
|
220 } |
|
221 |
|
222 function* testBody(inspector, view) { |
|
223 let {element, elementStyle} = yield testNode("body", inspector, view); |
|
224 |
|
225 let gutters = view.element.querySelectorAll(".theme-gutter"); |
|
226 is (gutters.length, 0, "There are no gutter headings"); |
|
227 } |
|
228 |
|
229 function convertTextPropsToString(textProps) { |
|
230 return textProps.map(t => t.name + ": " + t.value).join("; "); |
|
231 } |
|
232 |
|
233 function* testNode(selector, inspector, view) { |
|
234 let element = getNode(selector); |
|
235 yield selectNode(element, inspector); |
|
236 let elementStyle = view._elementStyle; |
|
237 return {element: element, elementStyle: elementStyle}; |
|
238 } |
|
239 |
|
240 function* assertPseudoElementRulesNumbers(selector, inspector, view, ruleNbs) { |
|
241 let {element, elementStyle} = yield testNode(selector, inspector, view); |
|
242 |
|
243 let rules = { |
|
244 elementRules: elementStyle.rules.filter(rule => !rule.pseudoElement), |
|
245 afterRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":after"), |
|
246 beforeRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":before"), |
|
247 firstLineRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":first-line"), |
|
248 firstLetterRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":first-letter"), |
|
249 selectionRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":-moz-selection") |
|
250 }; |
|
251 |
|
252 is(rules.elementRules.length, ruleNbs.elementRulesNb, selector + |
|
253 " has the correct number of non pseudo element rules"); |
|
254 is(rules.afterRules.length, ruleNbs.afterRulesNb, selector + |
|
255 " has the correct number of :after rules"); |
|
256 is(rules.beforeRules.length, ruleNbs.beforeRulesNb, selector + |
|
257 " has the correct number of :before rules"); |
|
258 is(rules.firstLineRules.length, ruleNbs.firstLineRulesNb, selector + |
|
259 " has the correct number of :first-line rules"); |
|
260 is(rules.firstLetterRules.length, ruleNbs.firstLetterRulesNb, selector + |
|
261 " has the correct number of :first-letter rules"); |
|
262 is(rules.selectionRules.length, ruleNbs.selectionRulesNb, selector + |
|
263 " has the correct number of :selection rules"); |
|
264 |
|
265 return {rules: rules, element: element, elementStyle: elementStyle}; |
|
266 } |
|
267 |
|
268 function assertGutters(view) { |
|
269 let gutters = view.element.querySelectorAll(".theme-gutter"); |
|
270 is (gutters.length, 3, "There are 3 gutter headings"); |
|
271 is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct"); |
|
272 is (gutters[1].textContent, "This Element", "Gutter heading is correct"); |
|
273 is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct"); |
|
274 return gutters; |
|
275 } |