Diff
Modified: trunk/LayoutTests/ChangeLog (176901 => 176902)
--- trunk/LayoutTests/ChangeLog 2014-12-06 02:04:13 UTC (rev 176901)
+++ trunk/LayoutTests/ChangeLog 2014-12-06 05:09:11 UTC (rev 176902)
@@ -1,3 +1,15 @@
+2014-12-05 Dhi Aurrahman <[email protected]>
+
+ Implement parser for :lang pseudo class selector arguments that contain wildcard '*' subtags
+ https://bugs.webkit.org/show_bug.cgi?id=139014
+
+ Reviewed by Benjamin Poulain.
+
+ * fast/css/css-selector-text-expected.txt: Updated for asterisk containing input.
+ * fast/css/css-selector-text.html: Updated for asterisk containing input.
+ * fast/css/parsing-css-lang-expected.txt: Added.
+ * fast/css/parsing-css-lang.html: Added.
+
2014-12-05 Benjamin Poulain <[email protected]>
Fix style sharing with the "type" and "readonly" attributes
Modified: trunk/LayoutTests/fast/css/css-selector-text-expected.txt (176901 => 176902)
--- trunk/LayoutTests/fast/css/css-selector-text-expected.txt 2014-12-06 02:04:13 UTC (rev 176901)
+++ trunk/LayoutTests/fast/css/css-selector-text-expected.txt 2014-12-06 05:09:11 UTC (rev 176902)
@@ -47,6 +47,16 @@
PASS parseThenSerializeRule(':target { }') is ':target { }'
PASS parseThenSerializeRule(':visited { }') is ':visited { }'
+PASS parseThenSerializeRule(':lang(*-) { }') is ':lang(*-) { }'
+PASS parseThenSerializeRule(':lang(*--) { }') is ':lang(*--) { }'
+PASS parseThenSerializeRule(':lang(*---) { }') is ':lang(*---) { }'
+PASS parseThenSerializeRule(':lang(*----) { }') is ':lang(*----) { }'
+
+PASS parseThenSerializeRule(':lang(*-ab) { }') is ':lang(*-ab) { }'
+PASS parseThenSerializeRule(':lang(*-ab-) { }') is ':lang(*-ab-) { }'
+PASS parseThenSerializeRule(':lang(*-1996) { }') is ':lang(*-1996) { }'
+PASS parseThenSerializeRule(':lang(*-DE-1996) { }') is ':lang(*-DE-1996) { }'
+
PASS parseThenSerializeRule(':lang(a) { }') is ':lang(a) { }'
PASS parseThenSerializeRule(':lang(a, b, c) { }') is ':lang(a, b, c) { }'
PASS parseThenSerializeRule(':lang(fr, de, en, id) { }') is ':lang(fr, de, en, id) { }'
@@ -294,6 +304,76 @@
PASS parseThenSerializeRule(':lang( en , en , en ) { }') is ':lang(en, en, en) { }'
PASS parseThenSerializeRule(':lang( en,en,en ) { }') is ':lang(en, en, en) { }'
+PASS parseThenSerializeRule(':lang(*-DE, *-CH, *-EN) { }') is ':lang(*-DE, *-CH, *-EN) { }'
+PASS parseThenSerializeRule(':lang(*-DE,*-CH,*-EN) { }') is ':lang(*-DE, *-CH, *-EN) { }'
+PASS parseThenSerializeRule(':lang( *-DE , *-CH , *-EN ) { }') is ':lang(*-DE, *-CH, *-EN) { }'
+
+PASS parseThenSerializeRule(':lang(\\*) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang(*-\\*) { }') is ':lang(*-*) { }'
+PASS parseThenSerializeRule(':lang(*-\\*-\\*) { }') is ':lang(*-*-*) { }'
+PASS parseThenSerializeRule(':lang(*-\\*-\\*-\\*) { }') is ':lang(*-*-*-*) { }'
+
+PASS parseThenSerializeRule(':lang(ab-\\*) { }') is ':lang(ab-*) { }'
+PASS parseThenSerializeRule(':lang(*-ab-\\*) { }') is ':lang(*-ab-*) { }'
+PASS parseThenSerializeRule(':lang(*-ab-\\*-) { }') is ':lang(*-ab-*-) { }'
+PASS parseThenSerializeRule(':lang(*-foo-\\3A) { }') is ':lang(*-foo-:) { }'
+PASS parseThenSerializeRule(':lang(*-foo-\\3A\\`\\)) { }') is ':lang(*-foo-:`)) { }'
+PASS parseThenSerializeRule(':lang(*-foo-\\*) { }') is ':lang(*-foo-*) { }'
+PASS parseThenSerializeRule(':lang(*-foo-\\0072 aisin) { }') is ':lang(*-foo-raisin) { }'
+PASS parseThenSerializeRule(':lang(*-foo-\\0062 \\0061 r) { }') is ':lang(*-foo-bar) { }'
+PASS parseThenSerializeRule(':lang(*-foo-col\\6Fr) { }') is ':lang(*-foo-color) { }'
+
+PASS parseThenSerializeRule(':lang(\\* ) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang(*- ) { }') is ':lang(*-) { }'
+PASS parseThenSerializeRule(':lang(*-en ) { }') is ':lang(*-en) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\* ) { }') is ':lang(*-en-*) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr ) { }') is ':lang(*-en-*-fr) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr,br ) { }') is ':lang(*-en-*-fr, br) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, br ) { }') is ':lang(*-en-*-fr, br) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, br ) { }') is ':lang(*-en-*-fr, br) { }'
+PASS parseThenSerializeRule(':lang( *-en-\\*-fr, br ) { }') is ':lang(*-en-*-fr, br) { }'
+PASS parseThenSerializeRule(':lang( *-en-\\*-fr, br ) { }') is ':lang(*-en-*-fr, br) { }'
+PASS parseThenSerializeRule(':lang( *-en-\\*-fr , br ) { }') is ':lang(*-en-*-fr, br) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr,*-br-zh ) { }') is ':lang(*-en-*-fr, *-br-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, *-br-zh ) { }') is ':lang(*-en-*-fr, *-br-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, *-br-zh ) { }') is ':lang(*-en-*-fr, *-br-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, *-br-zh ) { }') is ':lang(*-en-*-fr, *-br-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, *-br-zh ) { }') is ':lang(*-en-*-fr, *-br-zh) { }'
+
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr,br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+PASS parseThenSerializeRule(':lang(*-en-\\*-fr, br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+PASS parseThenSerializeRule(':lang( *-en-\\*-fr, br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+PASS parseThenSerializeRule(':lang( *-en-\\*-fr , br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+PASS parseThenSerializeRule(':lang( *-en-\\*-fr , br-\\*-zh ) { }') is ':lang(*-en-*-fr, br-*-zh) { }'
+
+PASS parseThenSerializeRule(':lang(\\*) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang(\\* ) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang(\\* ) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang( \\* ) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang( \\*) { }') is ':lang(*) { }'
+PASS parseThenSerializeRule(':lang( \\* ) { }') is ':lang(*) { }'
+
+PASS parseThenSerializeRule(':lang( \\*,id-\\*-sumatra ) { }') is ':lang(*, id-*-sumatra) { }'
+PASS parseThenSerializeRule(':lang( \\* ,id-\\*-sumatra) { }') is ':lang(*, id-*-sumatra) { }'
+PASS parseThenSerializeRule(':lang( \\* , id-\\*-sumatra ) { }') is ':lang(*, id-*-sumatra) { }'
+PASS parseThenSerializeRule(':lang( \\* , id-\\*-sumatra ) { }') is ':lang(*, id-*-sumatra) { }'
+
+PASS parseThenSerializeRule(':lang(*-1996) { }') is ':lang(*-1996) { }'
+PASS parseThenSerializeRule(':lang(*-1996, *-1997) { }') is ':lang(*-1996, *-1997) { }'
+PASS parseThenSerializeRule(':lang(*-1996, *-1997 ) { }') is ':lang(*-1996, *-1997) { }'
+PASS parseThenSerializeRule(':lang( *-1996 , *-1997 ) { }') is ':lang(*-1996, *-1997) { }'
+PASS parseThenSerializeRule(':lang( *-1996 ,*-1997 ) { }') is ':lang(*-1996, *-1997) { }'
+PASS parseThenSerializeRule(':lang( *-1996,*-1997 ) { }') is ':lang(*-1996, *-1997) { }'
+
+PASS parseThenSerializeRule(':lang(en-\\*) { }') is ':lang(en-*) { }'
+PASS parseThenSerializeRule(':lang(en-\\*, fr-\\*) { }') is ':lang(en-*, fr-*) { }'
+PASS parseThenSerializeRule(':lang(en-\\*, fr-\\* ) { }') is ':lang(en-*, fr-*) { }'
+PASS parseThenSerializeRule(':lang( en-\\* , fr-\\* ) { }') is ':lang(en-*, fr-*) { }'
+PASS parseThenSerializeRule(':lang( en-\\* ,fr-\\* ) { }') is ':lang(en-*, fr-*) { }'
+PASS parseThenSerializeRule(':lang( en-\\*,fr-\\* ) { }') is ':lang(en-*, fr-*) { }'
+
PASS parseThenSerializeRule(':lang() { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
PASS parseThenSerializeRule(':lang(12, b, c) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
PASS parseThenSerializeRule(':lang(a, 12, c) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
@@ -316,6 +396,27 @@
PASS parseThenSerializeRule(':lang([) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
PASS parseThenSerializeRule(':lang([]) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
PASS parseThenSerializeRule(':lang(@media screen {}) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*)') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(**)') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(-*-)') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(de-*)') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-en-*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-en-fr-*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-en-*fr) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-*en-fr) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-1997)') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-1997-*)') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*a*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*a) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(a*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-a, a*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-a, a**) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-a, *a) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-a, **a) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*- a*) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-a, br fr) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
+PASS parseThenSerializeRule(':lang(*-a, br fr en *) { }') threw exception TypeError: undefined is not an object (evaluating 'styleElement.sheet.cssRules[0].cssText').
PASS parseThenSerializeRule(':role(a) { }') is ':role(a) { }'
PASS parseThenSerializeRule(':role(button) { }') is ':role(button) { }'
Modified: trunk/LayoutTests/fast/css/css-selector-text.html (176901 => 176902)
--- trunk/LayoutTests/fast/css/css-selector-text.html 2014-12-06 02:04:13 UTC (rev 176901)
+++ trunk/LayoutTests/fast/css/css-selector-text.html 2014-12-06 05:09:11 UTC (rev 176902)
@@ -80,6 +80,20 @@
debug('');
+testSelectorRoundTrip(":lang(*-)");
+testSelectorRoundTrip(":lang(*--)");
+testSelectorRoundTrip(":lang(*---)");
+testSelectorRoundTrip(":lang(*----)");
+
+debug('');
+
+testSelectorRoundTrip(":lang(*-ab)");
+testSelectorRoundTrip(":lang(*-ab-)");
+testSelectorRoundTrip(":lang(*-1996)");
+testSelectorRoundTrip(":lang(*-DE-1996)");
+
+debug('');
+
testSelectorRoundTrip(":lang(a)");
testSelectorRoundTrip(":lang(a, b, c)");
testSelectorRoundTrip(":lang(fr, de, en, id)");
@@ -88,7 +102,7 @@
testSelectorRoundTrip(":lang(de-CH, it-CH, fr-CH, rm-CH)");
testSelectorRoundTrip(":lang(de-DE, de-DE-1996, de-Latn-DE, de-Latf-DE, de-Latn-DE-1996, de-CH, it-CH, fr-CH, rm-CH)");
-debug('')
+debug('');
testSelectorRoundTrip(":lang(a, a, a)");
testSelectorRoundTrip(":lang(en, en, en)");
@@ -375,6 +389,96 @@
debug('');
+shouldBe("parseThenSerializeRule(':lang(*-DE, *-CH, *-EN) { }')", "':lang(*-DE, *-CH, *-EN) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-DE,*-CH,*-EN) { }')", "':lang(*-DE, *-CH, *-EN) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-DE , *-CH , *-EN ) { }')", "':lang(*-DE, *-CH, *-EN) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(\\\\*) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-\\\\*) { }')", "':lang(*-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-\\\\*-\\\\*) { }')", "':lang(*-*-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-\\\\*-\\\\*-\\\\*) { }')", "':lang(*-*-*-*) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(ab-\\\\*) { }')", "':lang(ab-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-ab-\\\\*) { }')", "':lang(*-ab-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-ab-\\\\*-) { }')", "':lang(*-ab-*-) { }'");
+
+shouldBe("parseThenSerializeRule(':lang(*-foo-\\\\3A) { }')", "':lang(*-foo-:) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-foo-\\\\3A\\\\`\\\\)) { }')", "':lang(*-foo-:`)) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-foo-\\\\*) { }')", "':lang(*-foo-*) { }'");
+
+shouldBe("parseThenSerializeRule(':lang(*-foo-\\\\0072 aisin) { }')", "':lang(*-foo-raisin) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-foo-\\\\0062 \\\\0061 r) { }')", "':lang(*-foo-bar) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-foo-col\\\\6Fr) { }')", "':lang(*-foo-color) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(\\\\* ) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*- ) { }')", "':lang(*-) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en ) { }')", "':lang(*-en) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\* ) { }')", "':lang(*-en-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr ) { }')", "':lang(*-en-*-fr) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr,br ) { }')", "':lang(*-en-*-fr, br) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, br ) { }')", "':lang(*-en-*-fr, br) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, br ) { }')", "':lang(*-en-*-fr, br) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-en-\\\\*-fr, br ) { }')", "':lang(*-en-*-fr, br) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-en-\\\\*-fr, br ) { }')", "':lang(*-en-*-fr, br) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-en-\\\\*-fr , br ) { }')", "':lang(*-en-*-fr, br) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr,*-br-zh ) { }')", "':lang(*-en-*-fr, *-br-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, *-br-zh ) { }')", "':lang(*-en-*-fr, *-br-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, *-br-zh ) { }')", "':lang(*-en-*-fr, *-br-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, *-br-zh ) { }')", "':lang(*-en-*-fr, *-br-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, *-br-zh ) { }')", "':lang(*-en-*-fr, *-br-zh) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr,br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-en-\\\\*-fr, br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-en-\\\\*-fr, br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-en-\\\\*-fr , br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-en-\\\\*-fr , br-\\\\*-zh ) { }')", "':lang(*-en-*-fr, br-*-zh) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(\\\\*) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang(\\\\* ) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang(\\\\* ) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang( \\\\* ) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang( \\\\*) { }')", "':lang(*) { }'");
+shouldBe("parseThenSerializeRule(':lang( \\\\* ) { }')", "':lang(*) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang( \\\\*,id-\\\\*-sumatra ) { }')", "':lang(*, id-*-sumatra) { }'");
+shouldBe("parseThenSerializeRule(':lang( \\\\* ,id-\\\\*-sumatra) { }')", "':lang(*, id-*-sumatra) { }'");
+shouldBe("parseThenSerializeRule(':lang( \\\\* , id-\\\\*-sumatra ) { }')", "':lang(*, id-*-sumatra) { }'");
+shouldBe("parseThenSerializeRule(':lang( \\\\* , id-\\\\*-sumatra ) { }')", "':lang(*, id-*-sumatra) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(*-1996) { }')", "':lang(*-1996) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-1996, *-1997) { }')", "':lang(*-1996, *-1997) { }'");
+shouldBe("parseThenSerializeRule(':lang(*-1996, *-1997 ) { }')", "':lang(*-1996, *-1997) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-1996 , *-1997 ) { }')", "':lang(*-1996, *-1997) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-1996 ,*-1997 ) { }')", "':lang(*-1996, *-1997) { }'");
+shouldBe("parseThenSerializeRule(':lang( *-1996,*-1997 ) { }')", "':lang(*-1996, *-1997) { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':lang(en-\\\\*) { }')", "':lang(en-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(en-\\\\*, fr-\\\\*) { }')", "':lang(en-*, fr-*) { }'");
+shouldBe("parseThenSerializeRule(':lang(en-\\\\*, fr-\\\\* ) { }')", "':lang(en-*, fr-*) { }'");
+shouldBe("parseThenSerializeRule(':lang( en-\\\\* , fr-\\\\* ) { }')", "':lang(en-*, fr-*) { }'");
+shouldBe("parseThenSerializeRule(':lang( en-\\\\* ,fr-\\\\* ) { }')", "':lang(en-*, fr-*) { }'");
+shouldBe("parseThenSerializeRule(':lang( en-\\\\*,fr-\\\\* ) { }')", "':lang(en-*, fr-*) { }'");
+
+debug('');
+
shouldThrow("parseThenSerializeRule(':lang() { }')");
shouldThrow("parseThenSerializeRule(':lang(12, b, c) { }')");
shouldThrow("parseThenSerializeRule(':lang(a, 12, c) { }')");
@@ -398,6 +502,28 @@
shouldThrow("parseThenSerializeRule(':lang([]) { }')");
shouldThrow("parseThenSerializeRule(':lang(@media screen {}) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*)')");
+shouldThrow("parseThenSerializeRule(':lang(**)')");
+shouldThrow("parseThenSerializeRule(':lang(-*-)')");
+shouldThrow("parseThenSerializeRule(':lang(*-*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(de-*)')");
+shouldThrow("parseThenSerializeRule(':lang(*-en-*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-en-fr-*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-en-*fr) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-*en-fr) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-1997)')");
+shouldThrow("parseThenSerializeRule(':lang(*-1997-*)')");
+shouldThrow("parseThenSerializeRule(':lang(*a*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*a) { }')");
+shouldThrow("parseThenSerializeRule(':lang(a*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-a, a*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-a, a**) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-a, *a) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-a, **a) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*- a*) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-a, br fr) { }')");
+shouldThrow("parseThenSerializeRule(':lang(*-a, br fr en *) { }')");
+
debug('');
testSelectorRoundTrip(":role(a)");
Added: trunk/LayoutTests/fast/css/parsing-css-lang-expected.txt (0 => 176902)
--- trunk/LayoutTests/fast/css/parsing-css-lang-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/css/parsing-css-lang-expected.txt 2014-12-06 05:09:11 UTC (rev 176902)
@@ -0,0 +1,286 @@
+Test the parsing of :lang(stringList) for querySelector and style.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+valid language ranges
+PASS document.querySelector(":lang(e)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(e)"
+PASS document.querySelector(":lang(e )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(e)"
+PASS document.querySelector(":lang(en)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en)"
+PASS document.querySelector(":lang(en )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en)"
+PASS document.querySelector(":lang(en-)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-)"
+PASS document.querySelector(":lang(en- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-)"
+PASS document.querySelector(":lang(en--)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en--)"
+PASS document.querySelector(":lang(en-- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en--)"
+PASS document.querySelector(":lang(en---)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en---)"
+PASS document.querySelector(":lang(en--- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en---)"
+PASS document.querySelector(":lang(en-fr)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-fr)"
+PASS document.querySelector(":lang(en-fr )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-fr)"
+PASS document.querySelector(":lang(en-fr-)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-fr-)"
+PASS document.querySelector(":lang(en-fr- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-fr-)"
+PASS document.querySelector(":lang(en-fr--)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-fr--)"
+PASS document.querySelector(":lang(en-fr-- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-fr--)"
+PASS document.querySelector(":lang(en--fr)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en--fr)"
+PASS document.querySelector(":lang(en--fr )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en--fr)"
+PASS document.querySelector(":lang(en---fr)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en---fr)"
+PASS document.querySelector(":lang(en---fr )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en---fr)"
+PASS document.querySelector(":lang(en---fr---)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en---fr---)"
+PASS document.querySelector(":lang(en---fr--- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en---fr---)"
+PASS document.querySelector(":lang(de-DE)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-DE)"
+PASS document.querySelector(":lang(de-DE )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-DE)"
+PASS document.querySelector(":lang(de-DE-1996)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-DE-1996)"
+PASS document.querySelector(":lang(de-DE-1996 )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-DE-1996)"
+PASS document.querySelector(":lang(de-Latn-DE)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-Latn-DE)"
+PASS document.querySelector(":lang(de-Latn-DE )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-Latn-DE)"
+PASS document.querySelector(":lang(de-Latf-DE)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-Latf-DE)"
+PASS document.querySelector(":lang(de-Latf-DE )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-Latf-DE)"
+PASS document.querySelector(":lang(de-Latn-DE-1996)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-Latn-DE-1996)"
+PASS document.querySelector(":lang(de-Latn-DE-1996 )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-Latn-DE-1996)"
+PASS document.querySelector(":lang(de-CH)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-CH)"
+PASS document.querySelector(":lang(de-CH )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(de-CH)"
+PASS document.querySelector(":lang(it-CH)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(it-CH)"
+PASS document.querySelector(":lang(it-CH )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(it-CH)"
+PASS document.querySelector(":lang(fr-CH)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(fr-CH)"
+PASS document.querySelector(":lang(fr-CH )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(fr-CH)"
+PASS document.querySelector(":lang(rm-CH)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(rm-CH)"
+PASS document.querySelector(":lang(rm-CH )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(rm-CH)"
+PASS document.querySelector(":lang(*-)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-)"
+PASS document.querySelector(":lang(*- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-)"
+PASS document.querySelector(":lang(*--)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*--)"
+PASS document.querySelector(":lang(*-- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*--)"
+PASS document.querySelector(":lang(*---)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*---)"
+PASS document.querySelector(":lang(*--- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*---)"
+PASS document.querySelector(":lang(*----)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*----)"
+PASS document.querySelector(":lang(*---- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*----)"
+PASS document.querySelector(":lang(*-CH)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-CH)"
+PASS document.querySelector(":lang(*-CH )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-CH)"
+PASS document.querySelector(":lang(*-DE-1996)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-DE-1996)"
+PASS document.querySelector(":lang(*-DE-1996 )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-DE-1996)"
+PASS document.querySelector(":lang(*-1996)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-1996)"
+PASS document.querySelector(":lang(*-1996 )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-1996)"
+PASS document.querySelector(":lang(*-br-zh)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-br-zh)"
+PASS document.querySelector(":lang(*-br-zh )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-br-zh)"
+PASS document.querySelector(":lang(id-\\*-sumatra)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(id-*-sumatra)"
+PASS document.querySelector(":lang(id-\\*-sumatra )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(id-*-sumatra)"
+PASS document.querySelector(":lang(*-en-\\*-fr)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-en-*-fr)"
+PASS document.querySelector(":lang(*-en-\\*-fr )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-en-*-fr)"
+PASS document.querySelector(":lang(*-en-\\*-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-en-*-*)"
+PASS document.querySelector(":lang(*-en-\\*-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-en-*-*)"
+PASS document.querySelector(":lang(\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*)"
+PASS document.querySelector(":lang(\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*)"
+PASS document.querySelector(":lang(*-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-*)"
+PASS document.querySelector(":lang(*-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-*)"
+PASS document.querySelector(":lang(*-\\*-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-*-*)"
+PASS document.querySelector(":lang(*-\\*-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-*-*)"
+PASS document.querySelector(":lang(*-\\*-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-*-*)"
+PASS document.querySelector(":lang(*-\\*-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-*-*)"
+PASS document.querySelector(":lang(ab-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(ab-*)"
+PASS document.querySelector(":lang(ab-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(ab-*)"
+PASS document.querySelector(":lang(*-ab-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*)"
+PASS document.querySelector(":lang(*-ab-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*)"
+PASS document.querySelector(":lang(*-ab-\\*-)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*-)"
+PASS document.querySelector(":lang(*-ab-\\*- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*-)"
+PASS document.querySelector(":lang(*-ab-\\*--)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*--)"
+PASS document.querySelector(":lang(*-ab-\\*-- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*--)"
+PASS document.querySelector(":lang(*-ab-\\*---)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*---)"
+PASS document.querySelector(":lang(*-ab-\\*--- )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-ab-*---)"
+PASS document.querySelector(":lang(*-foo-\\:)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:)"
+PASS document.querySelector(":lang(*-foo-\\: )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:)"
+PASS document.querySelector(":lang(*-foo-\\:)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:)"
+PASS document.querySelector(":lang(*-foo-\\: )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:)"
+PASS document.querySelector(":lang(*-foo-\\:\\`\\))") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:`))"
+PASS document.querySelector(":lang(*-foo-\\:\\`\\) )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:`))"
+PASS document.querySelector(":lang(*-foo-\\:\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:*)"
+PASS document.querySelector(":lang(*-foo-\\:\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(*-foo-:*)"
+PASS document.querySelector(":lang(en-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-*)"
+PASS document.querySelector(":lang(en-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(en-*)"
+PASS document.querySelector(":lang(fr-\\*)") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(fr-*)"
+PASS document.querySelector(":lang(fr-\\* )") did not throw exception.
+PASS document.getElementById('style-container').sheet.cssRules.length is 1
+PASS document.getElementById('style-container').sheet.cssRules[0].selectorText is ":lang(fr-*)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/css/parsing-css-lang.html (0 => 176902)
--- trunk/LayoutTests/fast/css/parsing-css-lang.html (rev 0)
+++ trunk/LayoutTests/fast/css/parsing-css-lang.html 2014-12-06 05:09:11 UTC (rev 176902)
@@ -0,0 +1,91 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<style id="style-container">
+</style>
+</head>
+<body>
+</body>
+<script>
+description('Test the parsing of :lang(stringList) for querySelector and style.');
+
+function testValidLanguageRange(languageRangeString, expectedSerializedLanguageRange) {
+ shouldNotThrow('document.querySelector(":lang(' + languageRangeString.replace(/\\/g, '\\\\') + ')")', '"Error: SyntaxError: DOM Exception 12"');
+
+ var styleContainer = document.getElementById('style-container');
+ styleContainer.innerHTML = ':lang(' + languageRangeString + ') { }';
+ shouldBe("document.getElementById('style-container').sheet.cssRules.length", "1");
+ if (!expectedSerializedLanguageRange)
+ expectedSerializedLanguageRange = languageRangeString;
+ shouldBeEqualToString("document.getElementById('style-container').sheet.cssRules[0].selectorText", ':lang(' + expectedSerializedLanguageRange.replace(/\\/g, '') + ')');
+ styleContainer.innerHTML = '';
+}
+
+var validLanguageRanges = [
+
+ "e",
+ "en",
+ "en-",
+ "en--",
+ "en---",
+ "en-fr",
+ "en-fr-",
+ "en-fr--",
+ "en--fr",
+ "en---fr",
+ "en---fr---",
+
+ "de-DE",
+ "de-DE-1996",
+ "de-Latn-DE",
+ "de-Latf-DE",
+ "de-Latn-DE-1996",
+ "de-CH",
+ "it-CH",
+ "fr-CH",
+ "rm-CH",
+
+ "*-",
+ "*--",
+ "*---",
+ "*----",
+
+ "*-CH",
+ "*-DE-1996",
+ "*-1996",
+ "*-br-zh",
+ "id-\\*-sumatra",
+ "*-en-\\*-fr",
+ "*-en-\\*-\\*",
+
+ "\\*",
+ "*-\\*",
+ "*-\\*-\\*",
+ "*-\\*-\\*",
+
+ "ab-\\*",
+ "*-ab-\\*",
+ "*-ab-\\*-",
+ "*-ab-\\*--",
+ "*-ab-\\*---",
+
+ "*-foo-\\:",
+ "*-foo-\\:",
+ "*-foo-\\:\\`\\)",
+ "*-foo-\\:\\*",
+
+ "en-\\*",
+ "fr-\\*"
+];
+
+debug("valid language ranges");
+for (var i = 0; i < validLanguageRanges.length; ++i) {
+ var languageRangeString = validLanguageRanges[i];
+ testValidLanguageRange(languageRangeString);
+ testValidLanguageRange(languageRangeString + " ", languageRangeString);
+}
+
+</script>
+<script src=""
+</html>
Modified: trunk/Source/WebCore/ChangeLog (176901 => 176902)
--- trunk/Source/WebCore/ChangeLog 2014-12-06 02:04:13 UTC (rev 176901)
+++ trunk/Source/WebCore/ChangeLog 2014-12-06 05:09:11 UTC (rev 176902)
@@ -1,3 +1,22 @@
+2014-12-05 Dhi Aurrahman <[email protected]>
+
+ Implement parser for :lang pseudo class selector arguments that contain wildcard '*' subtags
+ https://bugs.webkit.org/show_bug.cgi?id=139014
+
+ Reviewed by Benjamin Poulain.
+
+ Consider each language range in :lang() that consists of an asterisk
+ immediately followed by an identifier beginning with an ASCII hyphen
+ as a valid input for the selector as specified in [1].
+
+ [1] http://dev.w3.org/csswg/selectors4/#the-lang-pseudo
+
+ Test: fast/css/parsing-css-lang.html
+
+ * css/CSSGrammar.y.in:
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::realLex):
+
2014-12-05 Simon Fraser <[email protected]>
Programmatic scrolling and content changes are not always synchronized
Modified: trunk/Source/WebCore/css/CSSGrammar.y.in (176901 => 176902)
--- trunk/Source/WebCore/css/CSSGrammar.y.in 2014-12-06 02:04:13 UTC (rev 176901)
+++ trunk/Source/WebCore/css/CSSGrammar.y.in 2014-12-06 05:09:11 UTC (rev 176902)
@@ -234,6 +234,7 @@
#if ENABLE_CSS_SELECTORS_LEVEL4
%token <string> DIRFUNCTION
+%token <string> LANGRANGE
%token <string> LANGFUNCTION
%token <string> ROLEFUNCTION
#endif
@@ -335,9 +336,10 @@
%destructor { delete $$; } calc_func_expr calc_func_expr_list calc_func_paren_expr expr key_list maybe_media_value valid_calc_func_expr valid_expr
#if ENABLE_CSS_SELECTORS_LEVEL4
+%type <string> lang_range
%union { Vector<CSSParserString>* stringList; }
-%type <stringList> comma_separated_identifiers
-%destructor { delete $$; } comma_separated_identifiers
+%type <stringList> comma_separated_lang_ranges
+%destructor { delete $$; } comma_separated_lang_ranges
#endif
%type <string> min_or_max
@@ -1102,17 +1104,19 @@
;
#if ENABLE_CSS_SELECTORS_LEVEL4
-comma_separated_identifiers:
- IDENT %prec UNIMPORTANT_TOK {
+lang_range: LANGRANGE | IDENT
+
+comma_separated_lang_ranges:
+ lang_range %prec UNIMPORTANT_TOK {
$$ = new Vector<CSSParserString>;
$$->append($1);
}
- | comma_separated_identifiers maybe_space ',' maybe_space IDENT %prec UNIMPORTANT_TOK {
+ | comma_separated_lang_ranges maybe_space ',' maybe_space lang_range %prec UNIMPORTANT_TOK {
$$ = $1;
if ($$)
$1->append($5);
}
- | comma_separated_identifiers error {
+ | comma_separated_lang_ranges error {
$$ = nullptr;
delete $1;
}
@@ -1388,7 +1392,7 @@
$$ = selector.release();
}
- | ':' LANGFUNCTION maybe_space comma_separated_identifiers maybe_space ')' {
+ | ':' LANGFUNCTION maybe_space comma_separated_lang_ranges maybe_space ')' {
$$ = nullptr;
if ($4) {
auto selector = std::make_unique<CSSParserSelector>();
Modified: trunk/Source/WebCore/css/CSSParser.cpp (176901 => 176902)
--- trunk/Source/WebCore/css/CSSParser.cpp 2014-12-06 02:04:13 UTC (rev 176901)
+++ trunk/Source/WebCore/css/CSSParser.cpp 2014-12-06 05:09:11 UTC (rev 176902)
@@ -11486,6 +11486,18 @@
if (*currentCharacter<SrcCharacterType>() == '=') {
++currentCharacter<SrcCharacterType>();
m_token = CONTAINS;
+ } else if (*currentCharacter<SrcCharacterType>() == '-') {
+ result = currentCharacter<SrcCharacterType>();
+
+ CSSParserString parsedIdentifier;
+ parseIdentifier(result, parsedIdentifier, hasEscape);
+
+ StringBuilder parsedLangRange;
+ parsedLangRange.append('*');
+ parsedLangRange.append(parsedIdentifier);
+
+ m_token = LANGRANGE;
+ yylval->string.init(parsedLangRange.toString());
}
break;