|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <head> |
|
4 <title>Test for CSS Namespace rules</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 onload="run()"> |
|
9 <p id="display"><iframe id="iframe" src="data:application/xhtml+xml,<html%20xmlns='http://www.w3.org/1999/xhtml'><head/><body/></html>"></iframe></p> |
|
10 <pre id="test"> |
|
11 <script class="testbody" type="text/javascript"> |
|
12 |
|
13 SimpleTest.waitForExplicitFinish(); |
|
14 |
|
15 var HTML_NS = "http://www.w3.org/1999/xhtml"; |
|
16 var style_text; |
|
17 |
|
18 function run() { |
|
19 var iframe = $("iframe"); |
|
20 var ifwin = iframe.contentWindow; |
|
21 var ifdoc = iframe.contentDocument; |
|
22 var ifbody = ifdoc.getElementsByTagName("body")[0]; |
|
23 |
|
24 function setup_style_text() { |
|
25 var style_elem = ifdoc.createElement("style"); |
|
26 style_elem.setAttribute("type", "text/css"); |
|
27 ifdoc.getElementsByTagName("head")[0].appendChild(style_elem); |
|
28 var style_text = ifdoc.createCDATASection(""); |
|
29 style_elem.appendChild(style_text); |
|
30 return style_text; |
|
31 } |
|
32 |
|
33 style_text = setup_style_text(); |
|
34 var gCounter = 0; |
|
35 |
|
36 /* |
|
37 * namespaceRules: the @namespace rules to use |
|
38 * selector: the selector to test |
|
39 * body_contents: what to set the body's innerHTML to |
|
40 * match_fn: a function that, given the document object into which |
|
41 * body_contents has been inserted, produces an array of nodes that |
|
42 * should match selector |
|
43 * notmatch_fn: likewise, but for nodes that should not match |
|
44 */ |
|
45 function test_selector_in_html(namespaceRules, selector, body_contents, |
|
46 match_fn, notmatch_fn) |
|
47 { |
|
48 var zi = ++gCounter; |
|
49 if (typeof(body_contents) == "string") { |
|
50 ifbody.innerHTML = body_contents; |
|
51 } else { |
|
52 // It's a function. |
|
53 ifbody.innerHTML = ""; |
|
54 body_contents(ifbody); |
|
55 } |
|
56 style_text.data = |
|
57 namespaceRules + " " + selector + "{ z-index: " + zi + " }"; |
|
58 var should_match = match_fn(ifdoc); |
|
59 var should_not_match = notmatch_fn(ifdoc); |
|
60 if (should_match.length + should_not_match.length == 0) { |
|
61 ok(false, "nothing to check"); |
|
62 } |
|
63 |
|
64 for (var i = 0; i < should_match.length; ++i) { |
|
65 var e = should_match[i]; |
|
66 is(ifwin.getComputedStyle(e, "").zIndex, zi, |
|
67 "element in " + body_contents + " matched " + selector); |
|
68 } |
|
69 for (var i = 0; i < should_not_match.length; ++i) { |
|
70 var e = should_not_match[i]; |
|
71 is(ifwin.getComputedStyle(e, "").zIndex, "auto", |
|
72 "element in " + body_contents + " did not match " + selector); |
|
73 } |
|
74 |
|
75 // Now, since we're here, may as well make sure serialization |
|
76 // works correctly. It need not produce the exact same text, |
|
77 // but it should produce a selector that matches the same |
|
78 // elements. |
|
79 zi = ++gCounter; |
|
80 var ruleList = style_text.parentNode.sheet.cssRules; |
|
81 var ser1 = ruleList[ruleList.length-1].selectorText; |
|
82 style_text.data = |
|
83 namespaceRules + " " + ser1 + "{ z-index: " + zi + " }"; |
|
84 for (var i = 0; i < should_match.length; ++i) { |
|
85 var e = should_match[i]; |
|
86 is(ifwin.getComputedStyle(e, "").zIndex, zi, |
|
87 "element in " + body_contents + " matched " + ser1 + |
|
88 " which is the reserialization of " + selector); |
|
89 } |
|
90 for (var i = 0; i < should_not_match.length; ++i) { |
|
91 var e = should_not_match[i]; |
|
92 is(ifwin.getComputedStyle(e, "").zIndex, "auto", |
|
93 "element in " + body_contents + " did not match " + ser1 + |
|
94 " which is the reserialization of " + selector); |
|
95 } |
|
96 |
|
97 // But when we serialize the serialized result, we should get |
|
98 // the same text. |
|
99 var ser2 = ruleList[ruleList.length-1].selectorText; |
|
100 is(ser2, ser1, "parse+serialize of selector \"" + selector + |
|
101 "\" is idempotent"); |
|
102 |
|
103 ifbody.innerHTML = ""; |
|
104 style_text.data = ""; |
|
105 } |
|
106 |
|
107 // 2 tests from http://tc.labs.opera.com/css/namespaces/prefix-001.xml |
|
108 test_selector_in_html( |
|
109 '@namespace foo "x"; @namespace Foo "y";', |
|
110 'Foo|test', |
|
111 '<test xmlns="y"/>', |
|
112 function (doc) { return doc.getElementsByTagName("test"); }, |
|
113 function (doc) { return []; } |
|
114 ); |
|
115 |
|
116 test_selector_in_html( |
|
117 '@namespace foo "x"; @namespace Foo "y";', |
|
118 'foo|test', |
|
119 '<test xmlns="y"/>', |
|
120 function (doc) { return []; }, |
|
121 function (doc) { return doc.getElementsByTagName("test");} |
|
122 ); |
|
123 |
|
124 // 2 tests from http://tc.labs.opera.com/css/namespaces/prefix-002.xml |
|
125 test_selector_in_html( |
|
126 '@namespace foo "";', |
|
127 'test', |
|
128 '<test xmlns=""/>', |
|
129 function (doc) { return doc.getElementsByTagName("test");}, |
|
130 function (doc) { return []; } |
|
131 ); |
|
132 |
|
133 test_selector_in_html( |
|
134 '@namespace foo "";', |
|
135 'foo|test', |
|
136 '<test xmlns=""/>', |
|
137 function (doc) { return doc.getElementsByTagName("test");}, |
|
138 function (doc) { return []; } |
|
139 ); |
|
140 |
|
141 // 2 tests from http://tc.labs.opera.com/css/namespaces/prefix-003.xml |
|
142 test_selector_in_html( |
|
143 '@namespace foo "";', |
|
144 'test', |
|
145 '<foo xmlns=""><test/></foo>', |
|
146 function (doc) { return doc.getElementsByTagName("test");}, |
|
147 function (doc) { return []; } |
|
148 ); |
|
149 |
|
150 test_selector_in_html( |
|
151 '@namespace foo "";', |
|
152 'foo|test', |
|
153 '<foo xmlns=""><test/></foo>', |
|
154 function (doc) { return doc.getElementsByTagName("test");}, |
|
155 function (doc) { return []; } |
|
156 ); |
|
157 |
|
158 // 4 tests from http://tc.labs.opera.com/css/namespaces/prefix-004.xml |
|
159 test_selector_in_html( |
|
160 '@namespace ""; @namespace x "test";', |
|
161 'test[x]', |
|
162 '<foo xmlns=""><test x=""/></foo>', |
|
163 function (doc) { return doc.getElementsByTagName("test");}, |
|
164 function (doc) { return []; } |
|
165 ); |
|
166 |
|
167 test_selector_in_html( |
|
168 '@namespace ""; @namespace x "test";', |
|
169 '*|test', |
|
170 '<foo xmlns=""><test x=""/></foo>', |
|
171 function (doc) { return doc.getElementsByTagName("test");}, |
|
172 function (doc) { return []; } |
|
173 ); |
|
174 |
|
175 test_selector_in_html( |
|
176 '@namespace ""; @namespace x "test";', |
|
177 '*|test', |
|
178 '<test xmlns="test"/>', |
|
179 function (doc) { return doc.getElementsByTagName("test");}, |
|
180 function (doc) { return []; } |
|
181 ); |
|
182 |
|
183 test_selector_in_html( |
|
184 '@namespace ""; @namespace x "test";', |
|
185 'test', |
|
186 '<test xmlns="test"/>', |
|
187 function (doc) { return []; }, |
|
188 function (doc) { return doc.getElementsByTagName("test");} |
|
189 ); |
|
190 |
|
191 // 2 tests from http://tc.labs.opera.com/css/namespaces/prefix-005.xml |
|
192 test_selector_in_html( |
|
193 '@namespace x "test";', |
|
194 'test', |
|
195 '<test/>', |
|
196 function (doc) { return doc.getElementsByTagName("test");}, |
|
197 function (doc) { return []; } |
|
198 ); |
|
199 |
|
200 test_selector_in_html( |
|
201 '@namespace x "test";', |
|
202 'test', |
|
203 '<test xmlns="test"/>', |
|
204 function (doc) { return doc.getElementsByTagName("test");}, |
|
205 function (doc) { return []; } |
|
206 ); |
|
207 |
|
208 // Skipping the scope tests because they involve import, and we have no way |
|
209 // to know when the import load completes. |
|
210 |
|
211 // 1 test from http://tc.labs.opera.com/css/namespaces/syntax-001.xml |
|
212 test_selector_in_html( |
|
213 '@NAmespace x "http://www.w3.org/1999/xhtml";', |
|
214 'x|test', |
|
215 '<test/>', |
|
216 function (doc) { return doc.getElementsByTagName("test");}, |
|
217 function (doc) { return []; } |
|
218 ); |
|
219 |
|
220 // 1 test from http://tc.labs.opera.com/css/namespaces/syntax-002.xml |
|
221 test_selector_in_html( |
|
222 '@NAmespac\\65 x "http://www.w3.org/1999/xhtml";', |
|
223 'x|test', |
|
224 '<test/>', |
|
225 function (doc) { return doc.getElementsByTagName("test");}, |
|
226 function (doc) { return []; } |
|
227 ); |
|
228 |
|
229 // 3 tests from http://tc.labs.opera.com/css/namespaces/syntax-003.xml |
|
230 test_selector_in_html( |
|
231 '@namespace url("test");', |
|
232 '*|test', |
|
233 '<test xmlns="test"/>', |
|
234 function (doc) { return doc.getElementsByTagName("test");}, |
|
235 function (doc) { return []; } |
|
236 ); |
|
237 |
|
238 test_selector_in_html( |
|
239 '@namespace url("test");', |
|
240 'test', |
|
241 '<test xmlns="test"/>', |
|
242 function (doc) { return doc.getElementsByTagName("test");}, |
|
243 function (doc) { return []; } |
|
244 ); |
|
245 |
|
246 test_selector_in_html( |
|
247 '@namespace url("test");', |
|
248 'test', |
|
249 '<test/>', |
|
250 function (doc) { return []; }, |
|
251 function (doc) { return doc.getElementsByTagName("test");} |
|
252 ); |
|
253 |
|
254 // 3 tests from http://tc.labs.opera.com/css/namespaces/syntax-004.xml |
|
255 test_selector_in_html( |
|
256 '@namespace u\\00072l("test");', |
|
257 '*|test', |
|
258 '<test xmlns="test"/>', |
|
259 function (doc) { return doc.getElementsByTagName("test");}, |
|
260 function (doc) { return []; } |
|
261 ); |
|
262 |
|
263 test_selector_in_html( |
|
264 '@namespace u\\00072l("test");', |
|
265 'test', |
|
266 '<test xmlns="test"/>', |
|
267 function (doc) { return doc.getElementsByTagName("test");}, |
|
268 function (doc) { return []; } |
|
269 ); |
|
270 |
|
271 test_selector_in_html( |
|
272 '@namespace u\\00072l("test");', |
|
273 'test', |
|
274 '<test/>', |
|
275 function (doc) { return []; }, |
|
276 function (doc) { return doc.getElementsByTagName("test");} |
|
277 ); |
|
278 |
|
279 // Skipping http://tc.labs.opera.com/css/namespaces/syntax-005.xml because it |
|
280 // involves import, and we have no way // to know when the import load completes. |
|
281 |
|
282 // Skipping http://tc.labs.opera.com/css/namespaces/syntax-006.xml because it |
|
283 // involves import, and we have no way // to know when the import load completes. |
|
284 |
|
285 // 2 tests from http://tc.labs.opera.com/css/namespaces/syntax-007.xml |
|
286 test_selector_in_html( |
|
287 '@charset "x"; @namespace url("test"); @namespace url("test2");', |
|
288 '*|test', |
|
289 '<test xmlns="test"/>', |
|
290 function (doc) { return doc.getElementsByTagName("test");}, |
|
291 function (doc) { return []; } |
|
292 ); |
|
293 |
|
294 test_selector_in_html( |
|
295 '@charset "x"; @namespace url("test"); @namespace url("test2");', |
|
296 'test', |
|
297 '<test xmlns="test"/>', |
|
298 function (doc) { return []; }, |
|
299 function (doc) { return doc.getElementsByTagName("test");} |
|
300 ); |
|
301 |
|
302 // 2 tests from http://tc.labs.opera.com/css/namespaces/syntax-008.xml |
|
303 test_selector_in_html( |
|
304 '@namespace \\72x url("test");', |
|
305 'rx|test', |
|
306 '<test xmlns="test"/>', |
|
307 function (doc) { return doc.getElementsByTagName("test");}, |
|
308 function (doc) { return []; } |
|
309 ); |
|
310 |
|
311 test_selector_in_html( |
|
312 '@namespace \\72x url("test");', |
|
313 'test', |
|
314 '<test xmlns="test"/>', |
|
315 function (doc) { return doc.getElementsByTagName("test");}, |
|
316 function (doc) { return []; } |
|
317 ); |
|
318 |
|
319 // And now some :not() tests |
|
320 test_selector_in_html( |
|
321 '@namespace url("test");', |
|
322 '*|*:not(test)', |
|
323 '<test xmlns="test"/>', |
|
324 function (doc) { return []; }, |
|
325 function (doc) { return doc.getElementsByTagName("test");} |
|
326 ); |
|
327 |
|
328 test_selector_in_html( |
|
329 '@namespace url("test");', |
|
330 '*|*:not(test)', |
|
331 '<test xmlns="testing"/>', |
|
332 function (doc) { return doc.getElementsByTagName("test");}, |
|
333 function (doc) { return []; } |
|
334 ); |
|
335 |
|
336 test_selector_in_html( |
|
337 '@namespace x url("test");', |
|
338 '*|*:not(x|test)', |
|
339 '<test xmlns="test"/>', |
|
340 function (doc) { return []; }, |
|
341 function (doc) { return doc.getElementsByTagName("test");} |
|
342 ); |
|
343 |
|
344 test_selector_in_html( |
|
345 '@namespace x url("test");', |
|
346 '*|*:not(x|test)', |
|
347 '<test xmlns="testing"/>', |
|
348 function (doc) { return doc.getElementsByTagName("test");}, |
|
349 function (doc) { return []; } |
|
350 ); |
|
351 |
|
352 test_selector_in_html( |
|
353 '@namespace url("test");', |
|
354 '*|*:not(*)', |
|
355 '<test xmlns="testing"/>', |
|
356 function (doc) { return doc.getElementsByTagName("test");}, |
|
357 function (doc) { return []; } |
|
358 ); |
|
359 |
|
360 test_selector_in_html( |
|
361 '@namespace url("test");', |
|
362 '*|*:not(*)', |
|
363 '<test xmlns="test"/>', |
|
364 function (doc) { return []; }, |
|
365 function (doc) { return doc.getElementsByTagName("test");} |
|
366 ); |
|
367 |
|
368 test_selector_in_html( |
|
369 '@namespace x url("test");', |
|
370 '*|*:not(x|*)', |
|
371 '<test xmlns="testing"/>', |
|
372 function (doc) { return doc.getElementsByTagName("test");}, |
|
373 function (doc) { return []; } |
|
374 ); |
|
375 |
|
376 test_selector_in_html( |
|
377 '@namespace x url("test");', |
|
378 '*|*:not(x|*)', |
|
379 '<test xmlns="test"/>', |
|
380 function (doc) { return []; }, |
|
381 function (doc) { return doc.getElementsByTagName("test");} |
|
382 ); |
|
383 |
|
384 test_selector_in_html( |
|
385 '@namespace url("test");', |
|
386 '*|*:not([foo])', |
|
387 '<test xmlns="testing" foo="bar"/>', |
|
388 function (doc) { return []; }, |
|
389 function (doc) { return doc.getElementsByTagName("test");} |
|
390 ); |
|
391 |
|
392 test_selector_in_html( |
|
393 '@namespace url("test");', |
|
394 '*|*:not([foo])', |
|
395 '<test xmlns="test" foo="bar"/>', |
|
396 function (doc) { return []; }, |
|
397 function (doc) { return doc.getElementsByTagName("test");} |
|
398 ); |
|
399 |
|
400 test_selector_in_html( |
|
401 '@namespace url("test");', |
|
402 '*|*[foo]', |
|
403 '<test foo="bar"/>', |
|
404 function (doc) { return doc.getElementsByTagName("test");}, |
|
405 function (doc) { return []; } |
|
406 ); |
|
407 |
|
408 test_selector_in_html( |
|
409 '@namespace url("test");', |
|
410 '*|*[|foo]', |
|
411 '<test foo="bar"/>', |
|
412 function (doc) { return doc.getElementsByTagName("test");}, |
|
413 function (doc) { return []; } |
|
414 ); |
|
415 |
|
416 test_selector_in_html( |
|
417 '@namespace test url("test");', |
|
418 '*|*[test|foo]', |
|
419 '<test foo="bar"/>', |
|
420 function (doc) { return []; }, |
|
421 function (doc) { return doc.getElementsByTagName("test");} |
|
422 ); |
|
423 |
|
424 test_selector_in_html( |
|
425 '@namespace test url("test");', |
|
426 '*|*[test|foo]', |
|
427 '<test xmlns:t="test" t:foo="bar"/>', |
|
428 function (doc) { return doc.getElementsByTagName("test");}, |
|
429 function (doc) { return []; } |
|
430 ); |
|
431 |
|
432 test_selector_in_html( |
|
433 '@namespace url("test");', |
|
434 '*|*[foo]', |
|
435 '<test xmlns:t="test" t:foo="bar"/>', |
|
436 function (doc) { return []; }, |
|
437 function (doc) { return doc.getElementsByTagName("test");} |
|
438 ); |
|
439 |
|
440 test_selector_in_html( |
|
441 '@namespace url("test");', |
|
442 '*|*[*|foo]', |
|
443 '<test xmlns:t="test" t:foo="bar"/>', |
|
444 function (doc) { return doc.getElementsByTagName("test");}, |
|
445 function (doc) { return []; } |
|
446 ); |
|
447 |
|
448 test_selector_in_html( |
|
449 '', |
|
450 '*|*[*|foo]', |
|
451 '<test xmlns:t="test" t:foo="bar"/>', |
|
452 function (doc) { return doc.getElementsByTagName("test");}, |
|
453 function (doc) { return []; } |
|
454 ); |
|
455 |
|
456 SimpleTest.finish(); |
|
457 } |
|
458 |
|
459 </script> |
|
460 </pre> |
|
461 </body> |
|
462 </html> |