|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <head> |
|
4 <title>Test for CSS EOF handling</title> |
|
5 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
7 </head> |
|
8 <body> |
|
9 <p><a target="_blank" |
|
10 href="https://bugzilla.mozilla.org/show_bug.cgi?id=311616">bug 311616</a>, |
|
11 <a target="_blank" |
|
12 href="https://bugzilla.mozilla.org/show_bug.cgi?id=325064">bug 325064</a></p> |
|
13 <iframe id="display"></iframe> |
|
14 <p id="log"></p> |
|
15 <pre id="test"> |
|
16 <script class="testbody" type="text/javascript"> |
|
17 const tests = [ |
|
18 { |
|
19 name: "basic rule", |
|
20 ref: "#r {background-color : orange}", |
|
21 tst: "#t {background-color : orange", |
|
22 prop: "background-color", pseudo: "" |
|
23 }, |
|
24 { |
|
25 name: "function", |
|
26 ref: "#r {background-color: rgb(0,255,0)}", |
|
27 tst: "#t {background-color: rgb(0,255,0", |
|
28 prop: "background-color", pseudo: "" |
|
29 }, |
|
30 { |
|
31 name: "comment", |
|
32 ref: "#r {background-color: aqua/*marine*/}", |
|
33 tst: "#t {background-color: aqua/*marine", |
|
34 prop: "background-color", pseudo: "" |
|
35 }, |
|
36 { |
|
37 name: "@media 1", |
|
38 ref: "@media all { #r { background-color: yellow } }", |
|
39 tst: "@media all { #t { background-color: yellow }", |
|
40 prop: "background-color", pseudo: "" |
|
41 }, |
|
42 { |
|
43 name: "@media 2", |
|
44 ref: "@media all { #r { background-color: magenta } }", |
|
45 tst: "@media all { #t { background-color: magenta", |
|
46 prop: "background-color", pseudo: "" |
|
47 }, |
|
48 { |
|
49 name: "@import 1", |
|
50 ref: "@import 'data:text/css,%23r%7Bbackground-color%3Agray%7D';", |
|
51 tst: "@import 'data:text/css,%23t%7Bbackground-color%3Agray%7D", |
|
52 prop: "background-color", pseudo: "" |
|
53 }, |
|
54 { |
|
55 name: "@import 2", |
|
56 ref: "@import 'data:text/css,%23r%7Bbackground-color%3Ablack%7D' all;", |
|
57 tst: "@import 'data:text/css,%23t%7Bbackground-color%3Ablack%7D' all", |
|
58 prop: "background-color", pseudo: "" |
|
59 }, |
|
60 { |
|
61 name: "url-token 1", |
|
62 ref: "#r { background-image: url(data:image/png;base64," + |
|
63 "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAADklEQVQI12NI" + |
|
64 "YJgAhAkAB4gB4Ry+pcoAAAAASUVORK5CYII=) }", |
|
65 tst: "#t { background-image: url(data:image/png;base64," + |
|
66 "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAADklEQVQI12NI" + |
|
67 "YJgAhAkAB4gB4Ry+pcoAAAAASUVORK5CYII=", |
|
68 prop: "background-image", pseudo: "" |
|
69 }, |
|
70 { |
|
71 name: "url-token 2", |
|
72 ref: "#r { background-image: url('data:image/png;base64," + |
|
73 "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAAEElEQVQI12Mo" + |
|
74 "YNjAcIHhAQAJ2ALR4kRk1gAAAABJRU5ErkJggg==') }", |
|
75 tst: "#t { background-image: url('data:image/png;base64," + |
|
76 "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAAEElEQVQI12Mo" + |
|
77 "YNjAcIHhAQAJ2ALR4kRk1gAAAABJRU5ErkJggg==", |
|
78 prop: "background-image", pseudo: "" |
|
79 }, |
|
80 { |
|
81 name: "url-token 3", |
|
82 ref: "#r { background-image: url('data:image/png;base64," + |
|
83 "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAAEElEQVQI12N4" + |
|
84 "wHCBYQNDAQAMuALRrGb97AAAAABJRU5ErkJggg==') }", |
|
85 tst: "#t { background-image: url('data:image/png;base64," + |
|
86 "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAAEElEQVQI12N4" + |
|
87 "wHCBYQNDAQAMuALRrGb97AAAAABJRU5ErkJggg=='", |
|
88 prop: "background-image", pseudo: "" |
|
89 }, |
|
90 { |
|
91 name: "counter", |
|
92 ref: "#r::before { content: counter(tr, upper-alpha) }", |
|
93 tst: "#t::before { content: counter(tr, upper-alpha", |
|
94 prop: "content", pseudo: "::before" |
|
95 }, |
|
96 { |
|
97 name: "string", |
|
98 ref: "#r::before { content: 'B' }", |
|
99 tst: "#t::before { content: 'B", |
|
100 prop: "content", pseudo: "::before" |
|
101 }, |
|
102 |
|
103 /* For these tests, there is no visible effect on computed style; |
|
104 instead we have to audit the DOM stylesheet object. */ |
|
105 |
|
106 { |
|
107 todo: 1, /* bug 446226 */ |
|
108 name: "selector 1", |
|
109 ref: "td[colspan='3'] {}", |
|
110 tst: "td[colspan='3" |
|
111 }, |
|
112 { |
|
113 todo: 1, /* bug 446226 */ |
|
114 name: "selector 2", |
|
115 ref: "td[colspan='3'] {}", |
|
116 tst: "td[colspan='3'" |
|
117 }, |
|
118 { |
|
119 todo: 1, /* bug 446226 */ |
|
120 name: "selector 3", |
|
121 ref: "td:lang(en) {}", |
|
122 tst: "td:lang(en" |
|
123 }, |
|
124 |
|
125 { |
|
126 name: "@charset 1", |
|
127 ref: "@charset 'utf-8';", |
|
128 tst: "@charset 'utf-8" |
|
129 }, |
|
130 { |
|
131 name: "@charset 2", |
|
132 ref: "@charset 'utf-8';", |
|
133 tst: "@charset 'utf-8'" |
|
134 }, |
|
135 { |
|
136 name: "@media 3", |
|
137 ref: "@media all {}", |
|
138 tst: "@media all {", |
|
139 }, |
|
140 { |
|
141 name: "@namespace 1a", |
|
142 ref: "@namespace foo url('http://foo.example.com/');", |
|
143 tst: "@namespace foo url('http://foo.example.com/')" |
|
144 }, |
|
145 { |
|
146 name: "@namespace 1b", |
|
147 ref: "@namespace foo url(http://foo.example.com/);", |
|
148 tst: "@namespace foo url(http://foo.example.com/" |
|
149 }, |
|
150 { |
|
151 name: "@namespace 1c", |
|
152 ref: "@namespace foo url('http://foo.example.com/');", |
|
153 tst: "@namespace foo url('http://foo.example.com/" |
|
154 }, |
|
155 { |
|
156 name: "@namespace 1d", |
|
157 ref: "@namespace foo 'http://foo.example.com/';", |
|
158 tst: "@namespace foo 'http://foo.example.com/'" |
|
159 }, |
|
160 { |
|
161 name: "@namespace 1e", |
|
162 ref: "@namespace foo 'http://foo.example.com/';", |
|
163 tst: "@namespace foo 'http://foo.example.com/" |
|
164 }, |
|
165 { |
|
166 name: "@namespace 2a", |
|
167 ref: "@namespace url('http://foo.example.com/');", |
|
168 tst: "@namespace url('http://foo.example.com/')" |
|
169 }, |
|
170 { |
|
171 name: "@namespace 2b", |
|
172 ref: "@namespace url('http://foo.example.com/');", |
|
173 tst: "@namespace url('http://foo.example.com/'" |
|
174 }, |
|
175 { |
|
176 name: "@namespace 2c", |
|
177 ref: "@namespace url('http://foo.example.com/');", |
|
178 tst: "@namespace url('http://foo.example.com/" |
|
179 }, |
|
180 { |
|
181 name: "@namespace 2d", |
|
182 ref: "@namespace 'http://foo.example.com/';", |
|
183 tst: "@namespace 'http://foo.example.com/'" |
|
184 }, |
|
185 { |
|
186 name: "@namespace 2e", |
|
187 ref: "@namespace 'http://foo.example.com/';", |
|
188 tst: "@namespace 'http://foo.example.com/" |
|
189 }, |
|
190 { |
|
191 name: "@-moz-document 1", |
|
192 ref: "@-moz-document domain('example.com') {}", |
|
193 tst: "@-moz-document domain('example.com') {" |
|
194 }, |
|
195 { |
|
196 name: "@-moz-document 2", |
|
197 ref: "@-moz-document domain('example.com') { p {} }", |
|
198 tst: "@-moz-document domain('example.com') { p {" |
|
199 } |
|
200 ]; |
|
201 |
|
202 const basestyle = ("table {\n"+ |
|
203 " border-collapse: collapse;\n"+ |
|
204 "}\n"+ |
|
205 "td {\n"+ |
|
206 " width: 1.5em;\n"+ |
|
207 " height: 1.5em;\n"+ |
|
208 " border: 1px solid black;\n"+ |
|
209 " text-align: center;\n"+ |
|
210 " margin: 0;\n"+ |
|
211 "}\n"+ |
|
212 "tr { counter-increment: tr }\n"); |
|
213 |
|
214 /* This is more complicated than it might look like it needs to be, |
|
215 because for each subtest we have to splat stuff into the iframe, |
|
216 allow the renderer to run, and only then interrogate the computed |
|
217 styles. */ |
|
218 |
|
219 SimpleTest.waitForExplicitFinish(); |
|
220 |
|
221 window.onload = function() { |
|
222 const frame = document.getElementById("display"); |
|
223 var curTest = 0; |
|
224 |
|
225 const prepareTest = function() { |
|
226 var cd = frame.contentDocument; |
|
227 cd.open(); |
|
228 cd.write('<!DOCTYPE HTML><html><head>' + |
|
229 '<style>\n' + basestyle + '</style>\n' + |
|
230 '<style>\n' + tests[curTest].ref + '</style>\n' + |
|
231 '<style>\n' + tests[curTest].tst + '</style>\n' + |
|
232 '</head><body>\n' + |
|
233 '<table><tr><td id="r"><td id="t"></table>' + |
|
234 '</body></html>'); |
|
235 cd.close(); |
|
236 }; |
|
237 |
|
238 const checkTest = function() { |
|
239 var cd = frame.contentDocument; |
|
240 var _is = tests[curTest].todo ? todo_is : is; |
|
241 var _ok = tests[curTest].todo ? todo : ok; |
|
242 |
|
243 if (cd.styleSheets[1].cssRules.length == 1 && |
|
244 cd.styleSheets[2].cssRules.length == 1) { |
|
245 // If we have a .prop for this test, the .cssText of the reference |
|
246 // and test rules will differ in the selector. Change #t to #r |
|
247 // in the test rule. |
|
248 var ref_canon = cd.styleSheets[1].cssRules[0].cssText; |
|
249 var tst_canon = cd.styleSheets[2].cssRules[0].cssText; |
|
250 tst_canon = tst_canon.replace(/(#|%23)t\b/, "$1r"); |
|
251 _is(tst_canon, ref_canon, |
|
252 tests[curTest].name + " (canonicalized rule)"); |
|
253 } else { |
|
254 _ok(false, tests[curTest].name + " (rule missing)"); |
|
255 } |
|
256 if (tests[curTest].prop) { |
|
257 var prop = tests[curTest].prop; |
|
258 var pseudo = tests[curTest].pseudo; |
|
259 |
|
260 var refElt = cd.getElementById("r"); |
|
261 var tstElt = cd.getElementById("t"); |
|
262 var refStyle = cd.defaultView.getComputedStyle(refElt, pseudo); |
|
263 var tstStyle = cd.defaultView.getComputedStyle(tstElt, pseudo); |
|
264 _is(tstStyle.getPropertyValue(prop), |
|
265 refStyle.getPropertyValue(prop), |
|
266 tests[curTest].name + " (computed style)"); |
|
267 } |
|
268 curTest++; |
|
269 if (curTest < tests.length) { |
|
270 prepareTest(); |
|
271 } else { |
|
272 SimpleTest.finish(); |
|
273 } |
|
274 }; |
|
275 |
|
276 frame.onload = function(){setTimeout(checkTest, 0);}; |
|
277 prepareTest(); |
|
278 }; |
|
279 </script> |
|
280 </pre> |
|
281 </body> |
|
282 </html> |