<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[177333] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/177333">177333</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-12-15 21:56:33 -0800 (Mon, 15 Dec 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Extend :lang()'s selector checker to handle ranges with '*' properly and perform matching within the ASCII range
https://bugs.webkit.org/show_bug.cgi?id=139340
Patch by Dhi Aurrahman <diorahman@rockybars.com> on 2014-12-15
Reviewed by Benjamin Poulain.
Source/WebCore:
Asterisk is considered as a valid subtag of a language range to express wildcard matching
in :lang()'s extended filtering procedure. The matching rules introduced by language
range with '*' is outlined in [1].
The matching of subtags is performed case-insensitively within the ASCII range[2].
[1] www.ietf.org/rfc/rfc4647.txt
[2] http://dev.w3.org/csswg/selectors4/#the-lang-pseudo
Test: fast/selectors/lang-equal-ignoring-case.html
fast/selectors/lang-valid-extended-filtering.html
* css/SelectorCheckerTestFunctions.h:
(WebCore::equalIgnoringCaseWithinASCIIRange): Handle matching case-insensitively within the ASCII range.
(WebCore::containslanguageSubtagMatchingRange):
(WebCore::matchesLangPseudoClass):
LayoutTests:
* fast/selectors/lang-equal-ignoring-ascii-case-expected.txt: Added.
* fast/selectors/lang-equal-ignoring-ascii-case.html: Added.
* fast/selectors/lang-extended-filtering-expected.txt: Updated.
* fast/selectors/lang-extended-filtering.html: Updated.
* fast/selectors/lang-valid-extended-filtering-expected.txt: Added.
* fast/selectors/lang-valid-extended-filtering.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastselectorslangextendedfilteringexpectedtxt">trunk/LayoutTests/fast/selectors/lang-extended-filtering-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorslangextendedfilteringhtml">trunk/LayoutTests/fast/selectors/lang-extended-filtering.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckerTestFunctionsh">trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorslangequalignoringasciicaseexpectedtxt">trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorslangequalignoringasciicasehtml">trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorslangvalidextendedfilteringexpectedtxt">trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorslangvalidextendedfilteringhtml">trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (177332 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-12-16 04:51:22 UTC (rev 177332)
+++ trunk/LayoutTests/ChangeLog        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-12-15 Dhi Aurrahman <diorahman@rockybars.com>
+
+ Extend :lang()'s selector checker to handle ranges with '*' properly and perform matching within the ASCII range
+ https://bugs.webkit.org/show_bug.cgi?id=139340
+
+ Reviewed by Benjamin Poulain.
+
+ * fast/selectors/lang-equal-ignoring-ascii-case-expected.txt: Added.
+ * fast/selectors/lang-equal-ignoring-ascii-case.html: Added.
+ * fast/selectors/lang-extended-filtering-expected.txt: Updated.
+ * fast/selectors/lang-extended-filtering.html: Updated.
+ * fast/selectors/lang-valid-extended-filtering-expected.txt: Added.
+ * fast/selectors/lang-valid-extended-filtering.html: Added.
+
</ins><span class="cx"> 2014-12-15 Said Abou-Hallawa <sabouhallawa@apple.com>
</span><span class="cx">
</span><span class="cx"> Import Mozilla test suite for SVG.
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorslangequalignoringasciicaseexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case-expected.txt (0 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case-expected.txt        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+Verify :lang()'s equal ignoring ascii case
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelector(':lang(AÃ )') is document.getElementById('a')
+PASS document.querySelector(':lang(aÀ)') is null
+PASS document.querySelector(':lang(AÀ)') is null
+PASS document.querySelector(':lang(CÄ)') is document.getElementById('c')
+PASS document.querySelector(':lang(cČ)') is null
+PASS document.querySelector(':lang(CČ)') is null
+PASS document.querySelector(':lang(eê)') is document.getElementById('e')
+PASS document.querySelector(':lang(eÊ)') is null
+PASS document.querySelector(':lang(EÊ)') is null
+PASS document.querySelector(':lang(Iį)') is document.getElementById('i')
+PASS document.querySelector(':lang(iÄ®)') is null
+PASS document.querySelector(':lang(IÄ®)') is null
+PASS document.querySelector(':lang(uû)') is document.getElementById('u')
+PASS document.querySelector(':lang(uÛ)') is null
+PASS document.querySelector(':lang(UÛ)') is null
+PASS document.querySelector(':lang(oø)') is document.getElementById('o')
+PASS document.querySelector(':lang(oØ)') is null
+PASS document.querySelector(':lang(OØ)') is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorslangequalignoringasciicasehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case.html (0 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/lang-equal-ignoring-ascii-case.html        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+ <div id="a" lang="aà"></div>
+ <div id="c" lang="cč"></div>
+ <div id="e" lang="eê"></div>
+ <div id="i" lang="iį"></div>
+ <div id="u" lang="uû"></div>
+ <div id="o" lang="oø"></div>
+<script>
+description('Verify :lang()\'s equal ignoring ascii case');
+
+shouldBe("document.querySelector(':lang(Aà)')", "document.getElementById('a')");
+shouldBeNull("document.querySelector(':lang(aÀ)')");
+shouldBeNull("document.querySelector(':lang(AÀ)')");
+
+shouldBe("document.querySelector(':lang(Cč)')", "document.getElementById('c')");
+shouldBeNull("document.querySelector(':lang(cČ)')");
+shouldBeNull("document.querySelector(':lang(CČ)')");
+
+shouldBe("document.querySelector(':lang(eê)')", "document.getElementById('e')");
+shouldBeNull("document.querySelector(':lang(eÊ)')");
+shouldBeNull("document.querySelector(':lang(EÊ)')");
+
+shouldBe("document.querySelector(':lang(Iį)')", "document.getElementById('i')");
+shouldBeNull("document.querySelector(':lang(iĮ)')");
+shouldBeNull("document.querySelector(':lang(IĮ)')");
+
+shouldBe("document.querySelector(':lang(uû)')", "document.getElementById('u')");
+shouldBeNull("document.querySelector(':lang(uÛ)')");
+shouldBeNull("document.querySelector(':lang(UÛ)')");
+
+shouldBe("document.querySelector(':lang(oø)')", "document.getElementById('o')");
+shouldBeNull("document.querySelector(':lang(oØ)')");
+shouldBeNull("document.querySelector(':lang(OØ)')");
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorslangextendedfilteringexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/selectors/lang-extended-filtering-expected.txt (177332 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/lang-extended-filtering-expected.txt        2014-12-16 04:51:22 UTC (rev 177332)
+++ trunk/LayoutTests/fast/selectors/lang-extended-filtering-expected.txt        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-Verify selector specifying extended filetring of :lang() pseudo class
</del><ins>+Verify selector specifying extended filtering of :lang() pseudo class
</ins><span class="cx">
</span><span class="cx"> On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
</span><span class="cx">
</span><span class="lines">@@ -79,9 +79,73 @@
</span><span class="cx"> PASS document.querySelectorAll(":lang(tic-tac-toe)").length is 1
</span><span class="cx"> PASS document.querySelectorAll(":lang(tic-toe-tac)").length is 0
</span><span class="cx">
</span><ins>+PASS document.querySelectorAll(":lang(\\*)").length is 35
+PASS document.querySelectorAll(":lang(*-CH)").length is 5
+
+PASS document.querySelectorAll(":lang(a)").length is 2
+PASS document.querySelectorAll(":lang(a-\\*)").length is 1
+PASS document.querySelectorAll(":lang(*-fr-\\*)").length is 2
+PASS document.querySelectorAll(":lang(*-\\*-lang)").length is 2
+PASS document.querySelectorAll(":lang(*-\\*-aa-bb-cc-dd)").length is 3
+PASS document.querySelectorAll(":lang(*-\\*-\\*-bb-cc-dd)").length is 3
+PASS document.querySelectorAll(":lang(*-\\*-\\*-\\*-cc-dd)").length is 3
+PASS document.querySelectorAll(":lang(*-\\*-\\*-\\*-\\*-dd)").length is 3
+PASS document.querySelectorAll(":lang(*-\\*-\\*-\\*-\\*-\\*)").length is 3
+PASS document.querySelectorAll(":lang(*-\\*-aa-\\*-cc-\\*)").length is 3
+PASS document.querySelectorAll(":lang(*-\\*-\\*-bb-\\*)").length is 3
+PASS document.querySelectorAll(":lang(fooÉ)").length is 1
+PASS document.querySelectorAll(":lang(fOOÉ)").length is 1
+PASS document.querySelectorAll(":lang(FoOÉ)").length is 1
+PASS document.querySelectorAll(":lang(FOOÉ)").length is 1
+PASS document.querySelectorAll(":lang(fooé)").length is 0
+PASS document.querySelectorAll(":lang(FOOé)").length is 0
+PASS document.querySelectorAll(":lang(foöÉ-bÃr)").length is 1
+PASS document.querySelectorAll(":lang(FoöÉ-bÃr)").length is 1
+PASS document.querySelectorAll(":lang(FOöÉ-bÃr)").length is 1
+PASS document.querySelectorAll(":lang(FOòÉ-bÃr)").length is 0
+PASS document.querySelectorAll(":lang(FOòę-bÃr)").length is 0
+PASS document.querySelectorAll(":lang(foöÉ-\\*)").length is 1
+PASS document.querySelectorAll(":lang(\\*-bÃr)").length is 1
+PASS document.querySelectorAll(":lang(\\*-BÃr)").length is 1
+PASS document.querySelectorAll(":lang(\\*-BÃR)").length is 1
+PASS document.querySelectorAll(":lang(\\*-Bár)").length is 0
+PASS document.querySelectorAll(":lang(\\*-báR)").length is 0
+PASS document.querySelectorAll(":lang(\\*-BáR)").length is 0
+
+PASS document.querySelectorAll(":lang(FOöÉ-BÃr)").length is 1
+PASS document.querySelectorAll(":lang(FOöÉ-BÃ)").length is 0
+PASS document.querySelectorAll(":lang(FOöÉ-B)").length is 0
+PASS document.querySelectorAll(":lang(f-BÃr)").length is 0
+PASS document.querySelectorAll(":lang(fO-BÃr)").length is 0
+PASS document.querySelectorAll(":lang(fOö-BÃr)").length is 0
+PASS document.querySelectorAll(":lang(FOöÉ-BÃr1)").length is 0
+PASS document.querySelectorAll(":lang(FOöÉ-BÃr12)").length is 0
+PASS document.querySelectorAll(":lang(FOöÉ-BÃr123)").length is 0
+PASS document.querySelectorAll(":lang(F-Xe)").length is 0
+PASS document.querySelectorAll(":lang(Fr-Xe)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xe)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xen)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xeno)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xenom)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xenomo)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xenomor)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xenomorp)").length is 0
+PASS document.querySelectorAll(":lang(fr-Xènömòrph)").length is 0
+PASS document.querySelectorAll(":lang(FR-XENOMORPH)").length is 1
+PASS document.querySelectorAll(":lang(foöÉbÃr)").length is 1
+PASS document.querySelectorAll(":lang(foöÉbÃ)").length is 0
+PASS document.querySelectorAll(":lang(foöÉb)").length is 0
+PASS document.querySelectorAll(":lang(foöÉ)").length is 1
+PASS document.querySelectorAll(":lang(foö)").length is 0
+PASS document.querySelectorAll(":lang(fo)").length is 0
+PASS document.querySelectorAll(":lang(f)").length is 0
+
+PASS document.querySelectorAll(":lang(*)").length threw exception Error: SyntaxError: DOM Exception 12.
+PASS document.querySelectorAll(":lang(*foöÉ)").length threw exception Error: SyntaxError: DOM Exception 12.
</ins><span class="cx"> PASS document.querySelectorAll(":lang(--en--)").length threw exception Error: SyntaxError: DOM Exception 12.
</span><span class="cx"> PASS document.querySelectorAll(":lang(---en---)").length threw exception Error: SyntaxError: DOM Exception 12.
</span><span class="cx"> PASS document.querySelectorAll(":lang(en us- de- fr-).length") threw exception Error: SyntaxError: DOM Exception 12.
</span><ins>+PASS document.querySelectorAll(":lang(-\\* \\*-)").length threw exception Error: SyntaxError: DOM Exception 12.
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx">
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorslangextendedfilteringhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/selectors/lang-extended-filtering.html (177332 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/lang-extended-filtering.html        2014-12-16 04:51:22 UTC (rev 177332)
+++ trunk/LayoutTests/fast/selectors/lang-extended-filtering.html        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -37,8 +37,26 @@
</span><span class="cx"> <div lang="cocoa-1-bar"></div>
</span><span class="cx"> <div lang="cocoa-a-bar"></div>
</span><span class="cx">
</span><ins>+ <div lang="a"></div>
+ <div lang="a-fr-lang"></div>
+ <div lang="b-fr-lang"></div>
+
+ <div lang="de-CH"></div>
+ <div lang="it-CH"></div>
+ <div lang="fr-CH"></div>
+ <div lang="rm-CH"></div>
+ <div lang="es-CH"></div>
+
+ <div lang="es1-KK-aa-bb-cc-dd"></div>
+ <div lang="es2-KL-aa-bb-cc-dd"></div>
+ <div lang="es3-KM-aa-bb-cc-dd"></div>
+
+ <div lang="fooÉ"></div>
+ <div lang="foöÉ-bÁr"></div>
+ <div lang="foöÉbÁr"></div>
+
</ins><span class="cx"> <script>
</span><del>- description('Verify selector specifying extended filetring of :lang() pseudo class');
</del><ins>+ description('Verify selector specifying extended filtering of :lang() pseudo class');
</ins><span class="cx">
</span><span class="cx"> shouldBe('document.querySelectorAll(":lang(en)").length', '3');
</span><span class="cx"> shouldBe('document.querySelectorAll(":lang(en-)").length', '2');
</span><span class="lines">@@ -138,9 +156,87 @@
</span><span class="cx">
</span><span class="cx"> debug('');
</span><span class="cx">
</span><ins>+ shouldBe('document.querySelectorAll(":lang(\\\\*)").length', '35');
+ shouldBe('document.querySelectorAll(":lang(*-CH)").length', '5');
+
+ debug('');
+
+ shouldBe('document.querySelectorAll(":lang(a)").length', '2');
+ shouldBe('document.querySelectorAll(":lang(a-\\\\*)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(*-fr-\\\\*)").length', '2');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-lang)").length', '2');
+
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-aa-bb-cc-dd)").length', '3');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-\\\\*-bb-cc-dd)").length', '3');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-\\\\*-\\\\*-cc-dd)").length', '3');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-\\\\*-\\\\*-\\\\*-dd)").length', '3');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-\\\\*-\\\\*-\\\\*-\\\\*)").length', '3');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-aa-\\\\*-cc-\\\\*)").length', '3');
+ shouldBe('document.querySelectorAll(":lang(*-\\\\*-\\\\*-bb-\\\\*)").length', '3');
+
+ shouldBe('document.querySelectorAll(":lang(fooÉ)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(fOOÉ)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(FoOÉ)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(FOOÉ)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(fooé)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FOOé)").length', '0');
+
+ shouldBe('document.querySelectorAll(":lang(foöÉ-bÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(FoöÉ-bÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-bÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(FOòÉ-bÁr)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FOòę-bÁr)").length', '0');
+
+ shouldBe('document.querySelectorAll(":lang(foöÉ-\\\\*)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(\\\\*-bÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(\\\\*-BÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(\\\\*-BÁR)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(\\\\*-Bár)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(\\\\*-báR)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(\\\\*-BáR)").length', '0');
+
+ debug('');
+
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-BÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-BÁ)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-B)").length', '0');
+
+ shouldBe('document.querySelectorAll(":lang(f-BÁr)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fO-BÁr)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fOö-BÁr)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-BÁr1)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-BÁr12)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FOöÉ-BÁr123)").length', '0');
+
+ shouldBe('document.querySelectorAll(":lang(F-Xe)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(Fr-Xe)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xe)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xen)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xeno)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xenom)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xenomo)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xenomor)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xenomorp)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fr-Xènömòrph)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(FR-XENOMORPH)").length', '1');
+
+ shouldBe('document.querySelectorAll(":lang(foöÉbÁr)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(foöÉbÁ)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(foöÉb)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(foöÉ)").length', '1');
+ shouldBe('document.querySelectorAll(":lang(foö)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(fo)").length', '0');
+ shouldBe('document.querySelectorAll(":lang(f)").length', '0');
+
+ debug('');
+
+ shouldThrow('document.querySelectorAll(":lang(*)").length');
+ shouldThrow('document.querySelectorAll(":lang(*foöÉ)").length');
</ins><span class="cx"> shouldThrow('document.querySelectorAll(":lang(--en--)").length');
</span><span class="cx"> shouldThrow('document.querySelectorAll(":lang(---en---)").length');
</span><span class="cx"> shouldThrow('document.querySelectorAll(":lang(en us- de- fr-).length")');
</span><ins>+ shouldThrow('document.querySelectorAll(":lang(-\\\\* \\\\*-)").length');
+
</ins><span class="cx"> </script>
</span><span class="cx"> <script src="../../resources/js-test-post.js"></script>
</span><span class="cx"> </body>
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorslangvalidextendedfilteringexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering-expected.txt (0 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering-expected.txt        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -0,0 +1,594 @@
</span><ins>+Verify selector specifying extended filtering of :lang() pseudo class
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+- af-ZA
+PASS document.querySelectorAll(':lang(af)').length == 1 is true
+PASS document.querySelectorAll(':lang(af-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(af-ZA)').length == 1 is true
+PASS document.querySelectorAll(':lang(af-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ZA)').length == 1 is true
+
+- ar-AE
+PASS document.querySelectorAll(':lang(ar)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-AE)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-AE)').length == 1 is true
+
+- ar-BH
+PASS document.querySelectorAll(':lang(ar)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-BH)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BH)').length == 1 is true
+
+- ar-YE
+PASS document.querySelectorAll(':lang(ar)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-YE)').length == 1 is true
+PASS document.querySelectorAll(':lang(ar-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-YE)').length == 1 is true
+
+- art-lojban
+PASS document.querySelectorAll(':lang(art)').length == 1 is true
+PASS document.querySelectorAll(':lang(art-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(art-lojban)').length == 1 is true
+PASS document.querySelectorAll(':lang(art-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-lojban)').length == 1 is true
+
+- az-Arab-IR
+PASS document.querySelectorAll(':lang(az)').length == 1 is true
+PASS document.querySelectorAll(':lang(az-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(az-Arab)').length == 1 is true
+PASS document.querySelectorAll(':lang(az-\\*-IR)').length == 1 is true
+PASS document.querySelectorAll(':lang(az-Arab-IR)').length == 1 is true
+PASS document.querySelectorAll(':lang(az-Arab-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Arab-IR)').length == 1 is true
+
+- be-BY
+PASS document.querySelectorAll(':lang(be)').length == 1 is true
+PASS document.querySelectorAll(':lang(be-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(be-BY)').length == 1 is true
+PASS document.querySelectorAll(':lang(be-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BY)').length == 1 is true
+
+- bg-BG
+PASS document.querySelectorAll(':lang(bg)').length == 1 is true
+PASS document.querySelectorAll(':lang(bg-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(bg-BG)').length == 1 is true
+PASS document.querySelectorAll(':lang(bg-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BG)').length == 1 is true
+
+- ca-ES
+PASS document.querySelectorAll(':lang(ca)').length == 1 is true
+PASS document.querySelectorAll(':lang(ca-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ca-ES)').length == 1 is true
+PASS document.querySelectorAll(':lang(ca-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ES)').length == 1 is true
+
+- cs-CZ
+PASS document.querySelectorAll(':lang(cs)').length == 1 is true
+PASS document.querySelectorAll(':lang(cs-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(cs-CZ)').length == 1 is true
+PASS document.querySelectorAll(':lang(cs-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CZ)').length == 1 is true
+
+- cy-GB
+PASS document.querySelectorAll(':lang(cy)').length == 1 is true
+PASS document.querySelectorAll(':lang(cy-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(cy-GB)').length == 1 is true
+PASS document.querySelectorAll(':lang(cy-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-GB)').length == 1 is true
+
+- de-AT
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-AT)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-AT)').length == 1 is true
+
+- de-CH
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH)').length == 1 is true
+
+- de-CH-1996
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH-1996)').length == 1 is true
+
+- de-CH-1997
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-1997)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH-1997)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH-1997)').length == 1 is true
+
+- de-DE
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-DE)').length == 1 is true
+
+- de-DE-1996
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-DE-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-DE-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-DE-1996)').length == 1 is true
+
+- de-Latn-DE
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Latn-DE)').length == 1 is true
+
+- de-Latf-DE
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latf)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latf-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latf-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Latf-DE)').length == 1 is true
+
+- de-Latn-DE-1996
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*-DE-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn-\\*-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn-DE-1996)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-Latn-DE-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Latn-DE-1996)').length == 1 is true
+
+- en-US
+PASS document.querySelectorAll(':lang(en)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-US)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-US)').length == 1 is true
+
+- en-GB
+PASS document.querySelectorAll(':lang(en)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-GB)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-GB)').length == 1 is true
+
+- en-Latn-Brai
+PASS document.querySelectorAll(':lang(en)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-Latn)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-\\*-Brai)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-Latn-Brai)').length == 1 is true
+PASS document.querySelectorAll(':lang(en-Latn-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Latn-Brai)').length == 1 is true
+
+- es-ES
+PASS document.querySelectorAll(':lang(es)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-ES)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ES)').length == 1 is true
+
+- es-ES-valencia
+PASS document.querySelectorAll(':lang(es)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-ES)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-\\*-valencia)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-ES-valencia)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-ES-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ES-valencia)').length == 1 is true
+
+- es-AR
+PASS document.querySelectorAll(':lang(es)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-AR)').length == 1 is true
+PASS document.querySelectorAll(':lang(es-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-AR)').length == 1 is true
+
+- fr-BE
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-BE)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BE)').length == 1 is true
+
+- fr-CA
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-CA)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CA)').length == 1 is true
+
+- fr-CH
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH)').length == 1 is true
+
+- fr-FR
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-FR)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-FR)').length == 1 is true
+
+- fr-LU
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-LU)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-LU)').length == 1 is true
+
+- fr-MC
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-MC)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-MC)').length == 1 is true
+
+- gl-ES
+PASS document.querySelectorAll(':lang(gl)').length == 1 is true
+PASS document.querySelectorAll(':lang(gl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(gl-ES)').length == 1 is true
+PASS document.querySelectorAll(':lang(gl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ES)').length == 1 is true
+
+- gu-IN
+PASS document.querySelectorAll(':lang(gu)').length == 1 is true
+PASS document.querySelectorAll(':lang(gu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(gu-IN)').length == 1 is true
+PASS document.querySelectorAll(':lang(gu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-IN)').length == 1 is true
+
+- hr-BA
+PASS document.querySelectorAll(':lang(hr)').length == 1 is true
+PASS document.querySelectorAll(':lang(hr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(hr-BA)').length == 1 is true
+PASS document.querySelectorAll(':lang(hr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BA)').length == 1 is true
+
+- id-ID
+PASS document.querySelectorAll(':lang(id)').length == 1 is true
+PASS document.querySelectorAll(':lang(id-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(id-ID)').length == 1 is true
+PASS document.querySelectorAll(':lang(id-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ID)').length == 1 is true
+
+- i-klingon
+PASS document.querySelectorAll(':lang(i)').length == 1 is true
+PASS document.querySelectorAll(':lang(i-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(i-klingon)').length == 1 is true
+PASS document.querySelectorAll(':lang(i-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-klingon)').length == 1 is true
+
+- ja-JP
+PASS document.querySelectorAll(':lang(ja)').length == 1 is true
+PASS document.querySelectorAll(':lang(ja-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ja-JP)').length == 1 is true
+PASS document.querySelectorAll(':lang(ja-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-JP)').length == 1 is true
+
+- ko-KR
+PASS document.querySelectorAll(':lang(ko)').length == 1 is true
+PASS document.querySelectorAll(':lang(ko-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ko-KR)').length == 1 is true
+PASS document.querySelectorAll(':lang(ko-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-KR)').length == 1 is true
+
+- lt-LT
+PASS document.querySelectorAll(':lang(lt)').length == 1 is true
+PASS document.querySelectorAll(':lang(lt-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(lt-LT)').length == 1 is true
+PASS document.querySelectorAll(':lang(lt-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-LT)').length == 1 is true
+
+- mi-NZ
+PASS document.querySelectorAll(':lang(mi)').length == 1 is true
+PASS document.querySelectorAll(':lang(mi-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(mi-NZ)').length == 1 is true
+PASS document.querySelectorAll(':lang(mi-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-NZ)').length == 1 is true
+
+- mn-MN
+PASS document.querySelectorAll(':lang(mn)').length == 1 is true
+PASS document.querySelectorAll(':lang(mn-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(mn-MN)').length == 1 is true
+PASS document.querySelectorAll(':lang(mn-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-MN)').length == 1 is true
+
+- nl-BE
+PASS document.querySelectorAll(':lang(nl)').length == 1 is true
+PASS document.querySelectorAll(':lang(nl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(nl-BE)').length == 1 is true
+PASS document.querySelectorAll(':lang(nl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BE)').length == 1 is true
+
+- nl-NL
+PASS document.querySelectorAll(':lang(nl)').length == 1 is true
+PASS document.querySelectorAll(':lang(nl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(nl-NL)').length == 1 is true
+PASS document.querySelectorAll(':lang(nl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-NL)').length == 1 is true
+
+- pl-PL
+PASS document.querySelectorAll(':lang(pl)').length == 1 is true
+PASS document.querySelectorAll(':lang(pl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(pl-PL)').length == 1 is true
+PASS document.querySelectorAll(':lang(pl-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-PL)').length == 1 is true
+
+- qu-BO
+PASS document.querySelectorAll(':lang(qu)').length == 1 is true
+PASS document.querySelectorAll(':lang(qu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(qu-BO)').length == 1 is true
+PASS document.querySelectorAll(':lang(qu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BO)').length == 1 is true
+
+- se-FI
+PASS document.querySelectorAll(':lang(se)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-FI)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-FI)').length == 1 is true
+
+- se-NO
+PASS document.querySelectorAll(':lang(se)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-NO)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-NO)').length == 1 is true
+
+- sgn-BE-FR
+PASS document.querySelectorAll(':lang(sgn)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-BE)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-\\*-FR)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-BE-FR)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-BE-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BE-FR)').length == 1 is true
+
+- sgn-BE-NL
+PASS document.querySelectorAll(':lang(sgn)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-BE)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-\\*-NL)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-BE-NL)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-BE-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-BE-NL)').length == 1 is true
+
+- sgn-CH-DE
+PASS document.querySelectorAll(':lang(sgn)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-\\*-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-CH-DE)').length == 1 is true
+PASS document.querySelectorAll(':lang(sgn-CH-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH-DE)').length == 1 is true
+
+- sr-Latn-RS
+PASS document.querySelectorAll(':lang(sr)').length == 1 is true
+PASS document.querySelectorAll(':lang(sr-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(sr-Latn)').length == 1 is true
+PASS document.querySelectorAll(':lang(sr-\\*-RS)').length == 1 is true
+PASS document.querySelectorAll(':lang(sr-Latn-RS)').length == 1 is true
+PASS document.querySelectorAll(':lang(sr-Latn-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Latn-RS)').length == 1 is true
+
+- sv-SE
+PASS document.querySelectorAll(':lang(sv)').length == 1 is true
+PASS document.querySelectorAll(':lang(sv-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(sv-SE)').length == 1 is true
+PASS document.querySelectorAll(':lang(sv-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-SE)').length == 1 is true
+
+- syr-SY
+PASS document.querySelectorAll(':lang(syr)').length == 1 is true
+PASS document.querySelectorAll(':lang(syr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(syr-SY)').length == 1 is true
+PASS document.querySelectorAll(':lang(syr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-SY)').length == 1 is true
+
+- tt-RU
+PASS document.querySelectorAll(':lang(tt)').length == 1 is true
+PASS document.querySelectorAll(':lang(tt-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(tt-RU)').length == 1 is true
+PASS document.querySelectorAll(':lang(tt-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-RU)').length == 1 is true
+
+- uz-UZ
+PASS document.querySelectorAll(':lang(uz)').length == 1 is true
+PASS document.querySelectorAll(':lang(uz-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(uz-UZ)').length == 1 is true
+PASS document.querySelectorAll(':lang(uz-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-UZ)').length == 1 is true
+
+- vi-VN
+PASS document.querySelectorAll(':lang(vi)').length == 1 is true
+PASS document.querySelectorAll(':lang(vi-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(vi-VN)').length == 1 is true
+PASS document.querySelectorAll(':lang(vi-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-VN)').length == 1 is true
+
+- xh-ZA
+PASS document.querySelectorAll(':lang(xh)').length == 1 is true
+PASS document.querySelectorAll(':lang(xh-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(xh-ZA)').length == 1 is true
+PASS document.querySelectorAll(':lang(xh-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ZA)').length == 1 is true
+
+- yue-Hant-HK
+PASS document.querySelectorAll(':lang(yue)').length == 1 is true
+PASS document.querySelectorAll(':lang(yue-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(yue-Hant)').length == 1 is true
+PASS document.querySelectorAll(':lang(yue-\\*-HK)').length == 1 is true
+PASS document.querySelectorAll(':lang(yue-Hant-HK)').length == 1 is true
+PASS document.querySelectorAll(':lang(yue-Hant-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Hant-HK)').length == 1 is true
+
+- zh-yue-Hant-HK
+PASS document.querySelectorAll(':lang(zh)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-yue)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*-Hant-HK)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-yue-Hant)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-yue-\\*-HK)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-yue-Hant-HK)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-yue-Hant-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-yue-Hant-HK)').length == 1 is true
+
+- zh-CN
+PASS document.querySelectorAll(':lang(zh)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-CN)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CN)').length == 1 is true
+
+- zh-Hant-CN
+PASS document.querySelectorAll(':lang(zh)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hant)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*-CN)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hant-CN)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hant-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Hant-CN)').length == 1 is true
+
+- zh-Hans-CN
+PASS document.querySelectorAll(':lang(zh)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hans)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*-CN)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hans-CN)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hans-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Hans-CN)').length == 1 is true
+
+- zh-Hant
+PASS document.querySelectorAll(':lang(zh)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-Hant)').length == 1 is true
+PASS document.querySelectorAll(':lang(zh-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-Hant)').length == 1 is true
+
+- de-CH
+PASS document.querySelectorAll(':lang(de)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(de-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH)').length == 1 is true
+
+- it-CH
+PASS document.querySelectorAll(':lang(it)').length == 1 is true
+PASS document.querySelectorAll(':lang(it-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(it-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(it-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH)').length == 2 is true
+
+- fr-CH
+PASS document.querySelectorAll(':lang(fr)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(fr-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH)').length == 3 is true
+
+- rm-CH
+PASS document.querySelectorAll(':lang(rm)').length == 1 is true
+PASS document.querySelectorAll(':lang(rm-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(rm-CH)').length == 1 is true
+PASS document.querySelectorAll(':lang(rm-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-CH)').length == 4 is true
+
+- de-CH,it-CH,fr-CH,rm-CH
+PASS document.querySelectorAll(':lang(*-CH)').length == 4 is true
+
+- hi-IN
+PASS document.querySelectorAll(':lang(hi)').length == 1 is true
+PASS document.querySelectorAll(':lang(hi-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(hi-IN)').length == 1 is true
+PASS document.querySelectorAll(':lang(hi-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-IN)').length == 1 is true
+
+- gu-IN
+PASS document.querySelectorAll(':lang(gu)').length == 1 is true
+PASS document.querySelectorAll(':lang(gu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(gu-IN)').length == 1 is true
+PASS document.querySelectorAll(':lang(gu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-IN)').length == 2 is true
+
+- kok-IN
+PASS document.querySelectorAll(':lang(kok)').length == 1 is true
+PASS document.querySelectorAll(':lang(kok-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(kok-IN)').length == 1 is true
+PASS document.querySelectorAll(':lang(kok-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-IN)').length == 3 is true
+
+- hi-IN,gu-IN,kok-IN
+PASS document.querySelectorAll(':lang(*-IN)').length == 3 is true
+
+- xa-ZA
+PASS document.querySelectorAll(':lang(xa)').length == 1 is true
+PASS document.querySelectorAll(':lang(xa-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(xa-ZA)').length == 1 is true
+PASS document.querySelectorAll(':lang(xa-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ZA)').length == 1 is true
+
+- zu-ZA
+PASS document.querySelectorAll(':lang(zu)').length == 1 is true
+PASS document.querySelectorAll(':lang(zu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(zu-ZA)').length == 1 is true
+PASS document.querySelectorAll(':lang(zu-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-ZA)').length == 2 is true
+
+- xa-ZA,zu-ZA
+PASS document.querySelectorAll(':lang(*-ZA)').length == 2 is true
+
+- se-FI
+PASS document.querySelectorAll(':lang(se)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-FI)').length == 1 is true
+PASS document.querySelectorAll(':lang(se-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-FI)').length == 1 is true
+
+- sv-FI
+PASS document.querySelectorAll(':lang(sv)').length == 1 is true
+PASS document.querySelectorAll(':lang(sv-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(sv-FI)').length == 1 is true
+PASS document.querySelectorAll(':lang(sv-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-FI)').length == 2 is true
+
+- se-FI,sv-FI
+PASS document.querySelectorAll(':lang(*-FI)').length == 2 is true
+
+- ur-PK
+PASS document.querySelectorAll(':lang(ur)').length == 1 is true
+PASS document.querySelectorAll(':lang(ur-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(ur-PK)').length == 1 is true
+PASS document.querySelectorAll(':lang(ur-\\*)').length == 1 is true
+PASS document.querySelectorAll(':lang(*-PK)').length == 1 is true
+
+- ur-PK
+PASS document.querySelectorAll(':lang(*-PK)').length == 1 is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorslangvalidextendedfilteringhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering.html (0 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/lang-valid-extended-filtering.html        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -0,0 +1,156 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style id="style-container">
+</style>
+</head>
+<body>
+<div id="target"></div>
+<div id="target1"></div>
+<div id="target2"></div>
+<div id="target3"></div>
+<div id="target4"></div>
+</body>
+<script>
+description('Verify selector specifying extended filtering of :lang() pseudo class');
+
+function testValidLanguageSelectorOnSingleElement(language, length) {
+ var range = language;
+ var rangeSubtags = language.split('-');
+ var target = document.querySelector('#target').setAttribute('lang', language);
+ var currentRange = rangeSubtags[0];
+ var suffixRange = '';
+
+ length = length || 1;
+ debug('- ' + language);
+
+ for (var i = 0; i < rangeSubtags.length; i++){
+ shouldBeTrue("document.querySelectorAll(':lang(" + currentRange + ")').length == 1");
+ currentRange += '-' + rangeSubtags[i + 1];
+
+ var asteriskRange = rangeSubtags[0];
+ for (var j = 1; j < rangeSubtags.length; j++) {
+ if (i == j || i == 0) {
+ asteriskRange += '-\\\\*';
+ } else {
+ asteriskRange += '-' + rangeSubtags[j];
+ }
+ }
+ shouldBeTrue("document.querySelectorAll(':lang(" + asteriskRange + ")').length == 1");
+ if (i > 0)
+ suffixRange += '-' + rangeSubtags[i];
+ }
+ shouldBeTrue("document.querySelectorAll(':lang(*" + suffixRange + ")').length == " + length);
+ document.querySelector('#target').removeAttribute('lang');
+
+ debug('');
+}
+
+function testValidLanguageSelectorOnMultipleElementsWithFirstAsterisk(languages) {
+ for (var i = 0; i < languages.length; i++) {
+ var language = languages[i];
+ testValidLanguageSelectorOnSingleElement(language, i + 1);
+ document.querySelector('#target' + (i + 1)).setAttribute('lang', language);
+ }
+
+ debug('- ' + languages);
+ for (var i = 0; i < languages.length; i++) {
+ var language = languages[i];
+ var ranges = language.split('-');
+ var range = '*';
+ for (var j = 1; j < ranges.length; j++) {
+ range += '-' + ranges[j];
+ }
+ }
+ shouldBeTrue("document.querySelectorAll(':lang(" + range + ")').length == " + languages.length);
+ debug('');
+}
+
+var validLanguagesOnSingleElement = [
+ "af-ZA",
+ "ar-AE",
+ "ar-BH",
+ "ar-YE",
+ "art-lojban",
+ "az-Arab-IR",
+ "be-BY",
+ "bg-BG",
+ "ca-ES",
+ "cs-CZ",
+ "cy-GB",
+ "de-AT",
+ "de-CH",
+ "de-CH-1996",
+ "de-CH-1997",
+ "de-DE",
+ "de-DE-1996",
+ "de-Latn-DE",
+ "de-Latf-DE",
+ "de-Latn-DE-1996",
+ "en-US",
+ "en-GB",
+ "en-Latn-Brai",
+ "es-ES",
+ "es-ES-valencia",
+ "es-AR",
+ "fr-BE",
+ "fr-CA",
+ "fr-CH",
+ "fr-FR",
+ "fr-LU",
+ "fr-MC",
+ "gl-ES",
+ "gu-IN",
+ "hr-BA",
+ "id-ID",
+ "i-klingon",
+ "ja-JP",
+ "ko-KR",
+ "lt-LT",
+ "mi-NZ",
+ "mn-MN",
+ "nl-BE",
+ "nl-NL",
+ "pl-PL",
+ "qu-BO",
+ "se-FI",
+ "se-NO",
+ "sgn-BE-FR",
+ "sgn-BE-NL",
+ "sgn-CH-DE",
+ "sr-Latn-RS",
+ "sv-SE",
+ "syr-SY",
+ "tt-RU",
+ "uz-UZ",
+ "vi-VN",
+ "xh-ZA",
+ "yue-Hant-HK",
+ "zh-yue-Hant-HK",
+ "zh-CN",
+ "zh-Hant-CN",
+ "zh-Hans-CN",
+ "zh-Hant"
+];
+
+var validLanguagesOnMultipleElements = [
+ ["de-CH", "it-CH", "fr-CH", "rm-CH"],
+ ["hi-IN", "gu-IN", "kok-IN"],
+ ["xa-ZA", "zu-ZA"],
+ ["se-FI", "sv-FI"],
+ ["ur-PK"],
+];
+
+for (var i = 0; i < validLanguagesOnSingleElement.length; ++i) {
+ var lang = validLanguagesOnSingleElement[i];
+ testValidLanguageSelectorOnSingleElement(lang);
+}
+
+for (var i = 0; i < validLanguagesOnMultipleElements.length; ++i) {
+ var lang = validLanguagesOnMultipleElements[i];
+ testValidLanguageSelectorOnMultipleElementsWithFirstAsterisk(lang);
+}
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (177332 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-12-16 04:51:22 UTC (rev 177332)
+++ trunk/Source/WebCore/ChangeLog        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-12-15 Dhi Aurrahman <diorahman@rockybars.com>
+
+ Extend :lang()'s selector checker to handle ranges with '*' properly and perform matching within the ASCII range
+ https://bugs.webkit.org/show_bug.cgi?id=139340
+
+ Reviewed by Benjamin Poulain.
+
+ Asterisk is considered as a valid subtag of a language range to express wildcard matching
+ in :lang()'s extended filtering procedure. The matching rules introduced by language
+ range with '*' is outlined in [1].
+
+ The matching of subtags is performed case-insensitively within the ASCII range[2].
+
+ [1] www.ietf.org/rfc/rfc4647.txt
+ [2] http://dev.w3.org/csswg/selectors4/#the-lang-pseudo
+
+ Test: fast/selectors/lang-equal-ignoring-case.html
+ fast/selectors/lang-valid-extended-filtering.html
+
+ * css/SelectorCheckerTestFunctions.h:
+ (WebCore::equalIgnoringCaseWithinASCIIRange): Handle matching case-insensitively within the ASCII range.
+ (WebCore::containslanguageSubtagMatchingRange):
+ (WebCore::matchesLangPseudoClass):
+
</ins><span class="cx"> 2014-12-15 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><span class="cx"> [iOS] Add feature counting support
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckerTestFunctionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (177332 => 177333)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h        2014-12-16 04:51:22 UTC (rev 177332)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h        2014-12-16 05:56:33 UTC (rev 177333)
</span><span class="lines">@@ -121,13 +121,24 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(CSS_SELECTORS_LEVEL4)
</span><ins>+inline bool equalIgnoringASCIICase(const String& a, const String& b)
+{
+ if (a.length() != b.length())
+ return false;
+ for (size_t i = 0; i < a.length(); ++i) {
+ if (toASCIILower(a[i]) != toASCIILower(b[i]))
+ return false;
+ }
+ return true;
+}
+
</ins><span class="cx"> inline bool containslanguageSubtagMatchingRange(const Vector<String>& languageSubtags, const String& range, size_t& position)
</span><span class="cx"> {
</span><span class="cx"> for (size_t languageSubtagIndex = position; languageSubtagIndex < languageSubtags.size(); ++languageSubtagIndex) {
</span><span class="cx"> const String& currentLanguageSubtag = languageSubtags[languageSubtagIndex];
</span><del>- if (currentLanguageSubtag.length() == 1)
</del><ins>+ if (currentLanguageSubtag.length() == 1 && range != "*")
</ins><span class="cx"> return false;
</span><del>- if (equalIgnoringCase(range, currentLanguageSubtag)) {
</del><ins>+ if (equalIgnoringASCIICase(range, currentLanguageSubtag) || range == "*") {
</ins><span class="cx"> position = languageSubtagIndex + 1;
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="lines">@@ -158,15 +169,19 @@
</span><span class="cx"> language.string().split('-', true, languageSubtags);
</span><span class="cx">
</span><span class="cx"> for (const AtomicString& range : ranges) {
</span><del>- if (equalIgnoringCase(language, range) && !language.contains('-'))
</del><ins>+ if (range == "*")
</ins><span class="cx"> return true;
</span><span class="cx">
</span><ins>+ if (equalIgnoringASCIICase(language, range) && !language.contains('-'))
+ return true;
+
</ins><span class="cx"> range.string().split('-', true, rangeSubtags);
</span><span class="cx">
</span><span class="cx"> if (rangeSubtags.size() > languageSubtags.size())
</span><span class="cx"> continue;
</span><span class="cx">
</span><del>- if (!equalIgnoringCase(rangeSubtags.first(), languageSubtags.first()))
</del><ins>+ const String& firstRangeSubtag = rangeSubtags.first();
+ if (!equalIgnoringASCIICase(firstRangeSubtag, languageSubtags.first()) && firstRangeSubtag != "*")
</ins><span class="cx"> continue;
</span><span class="cx">
</span><span class="cx"> size_t lastMatchedLanguageSubtagIndex = 1;
</span></span></pre>
</div>
</div>
</body>
</html>