<!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>[181525] 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/181525">181525</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2015-03-15 23:51:44 -0700 (Sun, 15 Mar 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>CSS: fix the case-insensitive matching of the attribute selectors Begin, End and Hyphen
https://bugs.webkit.org/show_bug.cgi?id=142715
Reviewed by Brent Fulgham.
Source/WebCore:
Fix attribute matching with:
-Begin: [a^=b].
-End: [a$=b].
-Hyphen: [a|=b].
Tests: fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html
fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html
fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html
* css/SelectorChecker.cpp:
(WebCore::attributeValueMatches):
I forgot to change CSSSelector::Exact in my last patch.
The tests could not catch that since we use the CSS JIT almost everywhere.
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::attributeValueBeginsWith):
(WebCore::SelectorCompiler::attributeValueEndsWith):
(WebCore::SelectorCompiler::attributeValueMatchHyphenRule):
Source/WTF:
Add the necessary infrastructure to test startsWith() and endsWith() with
ASCII case-insentive comparisons.
* wtf/text/AtomicString.h:
(WTF::AtomicString::startsWith):
(WTF::AtomicString::startsWithIgnoringASCIICase):
(WTF::AtomicString::endsWith):
(WTF::AtomicString::endsWithIgnoringASCIICase):
* wtf/text/StringCommon.h:
(WTF::loadUnaligned):
(WTF::equal):
I moved the low level equal() code from StringImpl to StringCommon
since it is used by both StringImpl and StringView.
(WTF::equalCommon):
(WTF::equalIgnoringASCIICaseCommon):
Ideally we should drop the "Common" part of the name but StringView
wants this inline for some reason. I prefered keeping the current behavior
since I don't know how StringView's matching performance was evaluated.
(WTF::startsWith):
(WTF::startsWithIgnoringASCIICase):
(WTF::endsWith):
(WTF::endsWithIgnoringASCIICase):
Make all that code shared between StringView and Stringimpl.
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::startsWith):
(WTF::StringImpl::startsWithIgnoringASCIICase):
(WTF::StringImpl::endsWith):
(WTF::StringImpl::endsWithIgnoringASCIICase):
(WTF::equal):
(WTF::stringImplContentEqual): Deleted.
* wtf/text/StringImpl.h:
(WTF::loadUnaligned): Deleted.
(WTF::equal): Deleted.
* wtf/text/StringView.cpp:
(WTF::StringView::startsWith):
(WTF::StringView::startsWithIgnoringASCIICase):
(WTF::StringView::endsWith):
(WTF::StringView::endsWithIgnoringASCIICase):
* wtf/text/StringView.h:
Since those are new, we can safely make them out-of-line and
evaluate the inlining impact as needed.
* wtf/text/WTFString.h:
(WTF::String::startsWithIgnoringASCIICase):
(WTF::String::endsWith):
(WTF::String::endsWithIgnoringASCIICase):
Tools:
* TestWebKitAPI/Tests/WTF/StringImpl.cpp:
(TestWebKitAPI::TEST):
LayoutTests:
* fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive-expected.txt: Added.
* fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html: Added.
* fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive-expected.txt: Added.
* fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html: Added.
* fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive-expected.txt: Added.
* fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextAtomicStringh">trunk/Source/WTF/wtf/text/AtomicString.h</a></li>
<li><a href="#trunkSourceWTFwtftextStringCommonh">trunk/Source/WTF/wtf/text/StringCommon.h</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplcpp">trunk/Source/WTF/wtf/text/StringImpl.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplh">trunk/Source/WTF/wtf/text/StringImpl.h</a></li>
<li><a href="#trunkSourceWTFwtftextStringViewcpp">trunk/Source/WTF/wtf/text/StringView.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextStringViewh">trunk/Source/WTF/wtf/text/StringView.h</a></li>
<li><a href="#trunkSourceWTFwtftextWTFStringh">trunk/Source/WTF/wtf/text/WTFString.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssSelectorCheckercpp">trunk/Source/WebCore/css/SelectorChecker.cpp</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFStringImplcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorsattributeendswithvaluematchingisasciicaseinsensitiveexpectedtxt">trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributeendswithvaluematchingisasciicaseinsensitivehtml">trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributehyphenvaluematchingisasciicaseinsensitiveexpectedtxt">trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributehyphenvaluematchingisasciicaseinsensitivehtml">trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributestartswithvaluematchingisasciicaseinsensitiveexpectedtxt">trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsattributestartswithvaluematchingisasciicaseinsensitivehtml">trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/LayoutTests/ChangeLog        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-03-15 Benjamin Poulain <benjamin@webkit.org>
+
+ CSS: fix the case-insensitive matching of the attribute selectors Begin, End and Hyphen
+ https://bugs.webkit.org/show_bug.cgi?id=142715
+
+ Reviewed by Brent Fulgham.
+
+ * fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive-expected.txt: Added.
+ * fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html: Added.
+ * fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive-expected.txt: Added.
+ * fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html: Added.
+ * fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive-expected.txt: Added.
+ * fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html: Added.
+
</ins><span class="cx"> 2015-03-15 Brent Fulgham <bfulgham@apple.com>
</span><span class="cx">
</span><span class="cx"> Scroll snap points are not supported on iframe content
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributeendswithvaluematchingisasciicaseinsensitiveexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive-expected.txt (0 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive-expected.txt        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -0,0 +1,417 @@
</span><ins>+When matching attributes case insensitively, it should be ASCII case insensitive. This test verifies the behavior when matching the end of the values (e.g. [a$="b"])
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing "[data-attribute$=Web-É-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-É-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-É-Kit]')[0].id is "target1"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=É-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=É-Kit]')[0].id is "target1"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=web-É-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-É-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=web-É-kit]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=É-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=É-kit]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=WEB-É-KIT]"
+PASS document.querySelectorAll('#test-root [data-attribute$=WEB-É-KIT]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=WEB-É-KIT]')[0].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=É-KIT]"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-KIT]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=É-KIT]')[0].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=Web-é-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-é-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-é-Kit]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=é-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=é-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=é-Kit]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=web-é-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-é-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=web-é-kit]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute$=é-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute$=é-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute$=é-kit]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute$=Web-É-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-É-Kit i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-É-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-É-Kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-É-Kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=É-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-Kit i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute$=É-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-Kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-Kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=web-É-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-É-kit i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute$=web-É-kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-É-kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-É-kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=É-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-kit i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute$=É-kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=WEB-É-KIT i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=WEB-É-KIT i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute$=WEB-É-KIT i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute$=WEB-É-KIT i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute$=WEB-É-KIT i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=É-KIT i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-KIT i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute$=É-KIT i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-KIT i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute$=É-KIT i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute$=Web-é-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-é-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-é-Kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute$=Web-é-Kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute$=é-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=é-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute$=é-Kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute$=é-Kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute$=web-é-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-é-kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute$=web-é-kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute$=web-é-kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute$=é-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute$=é-kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute$=é-kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute$=é-kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=WEB-é-KIT]"
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=é-KIT]"
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=Web-é-Kit]"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=é-Kit]"
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=Web-é-kit]"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=é-kit]"
+PASS document.querySelectorAll('#test-root [multiple$=é-kit]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=é-kit]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=é-kit]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=é-kit]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=web-É-kit]"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-kit]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=web-É-kit]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-kit]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=É-kit]"
+PASS document.querySelectorAll('#test-root [multiple$=É-kit]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=É-kit]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=É-kit]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=web-É-Kit]"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-Kit]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=web-É-Kit]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-Kit]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=É-Kit]"
+PASS document.querySelectorAll('#test-root [multiple$=É-Kit]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=É-Kit]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=É-Kit]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=WEB-é-KIT i]"
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=WEB-é-KIT i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=é-KIT i]"
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=é-KIT i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=Web-é-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-Kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=é-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=é-Kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=Web-é-kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=Web-é-kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=é-kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=é-kit i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple$=é-kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple$=é-kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple$=é-kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple$=web-É-kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-kit i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=web-É-kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=É-kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=É-kit i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=É-kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=É-kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=web-É-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=web-É-Kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=web-É-Kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple$=É-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple$=É-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple$=É-Kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple$=É-Kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributeendswithvaluematchingisasciicaseinsensitivehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html (0 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -0,0 +1,122 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+#test-root * {
+ background-color: red;
+}
+</style>
+<style id="style">
+</style>
+</head>
+<body>
+ <div style="display:none" id="test-root">
+ <div data-attribute="Web-É-Kit" multiple="WEB-é-KIT" id="target1"></div>
+ <div data-attribute="web-É-kit" multiple="Web-é-Kit" id="target2"></div>
+ <div data-attribute="WEB-É-KIT" multiple="Web-é-kit" id="target3"></div>
+ <div data-attribute="Web-é-Kit" multiple="web-É-kit" id="target4"></div>
+ <div data-attribute="web-é-kit" multiple="web-É-Kit" id="target5"></div>
+ </div>
+</body>
+<script>
+description('When matching attributes case insensitively, it should be ASCII case insensitive. This test verifies the behavior when matching the end of the values (e.g. [a$="b"])');
+
+function testQuerySelector(selector, expectedIds) {
+ shouldBe("document.querySelectorAll('" + selector + "').length", '' + expectedIds.length);
+ for (var i = 0; i < expectedIds.length; ++i)
+ shouldBeEqualToString("document.querySelectorAll('" + selector + "')[" + i + "].id", 'target' + expectedIds[i]);
+}
+
+function testStyling(selector, expectedIds) {
+ var stylingElement = document.getElementById("style");
+ stylingElement.innerHTML = '' + selector + ' { background-color: rgb(10, 100, 200); }';
+
+ var allTestCases = document.querySelectorAll("#test-root *");
+ for (var i = 0; i < allTestCases.length; ++i) {
+ var expectMatch = expectedIds.indexOf(parseInt(allTestCases[i].id.replace('target', ''))) >= 0;
+ shouldBeEqualToString('getComputedStyle(document.querySelectorAll("#test-root *")[' + i + ']).backgroundColor', expectMatch ? 'rgb(10, 100, 200)' : 'rgb(255, 0, 0)');
+ }
+
+ stylingElement.innerHTML = '';
+}
+
+function testSelector(selector, expectedIds) {
+ debug("Testing \"" + selector + "\"");
+ testQuerySelector("#test-root " + selector, expectedIds);
+ testStyling("#test-root " + selector, expectedIds);
+ debug("");
+}
+
+var testCases = [
+ // Regular attribute matching is case sensitive.
+ ['[data-attribute$=Web-É-Kit]', [1]],
+ ['[data-attribute$=É-Kit]', [1]],
+
+ ['[data-attribute$=web-É-kit]', [2]],
+ ['[data-attribute$=É-kit]', [2]],
+
+ ['[data-attribute$=WEB-É-KIT]', [3]],
+ ['[data-attribute$=É-KIT]', [3]],
+
+ ['[data-attribute$=Web-é-Kit]', [4]],
+ ['[data-attribute$=é-Kit]', [4]],
+
+ ['[data-attribute$=web-é-kit]', [5]],
+ ['[data-attribute$=é-kit]', [5]],
+
+ // Same selectors with the case-insensitive flag.
+ ['[data-attribute$=Web-É-Kit i]', [1, 2, 3]],
+ ['[data-attribute$=É-Kit i]', [1, 2, 3]],
+
+ ['[data-attribute$=web-É-kit i]', [1, 2, 3]],
+ ['[data-attribute$=É-kit i]', [1, 2, 3]],
+
+ ['[data-attribute$=WEB-É-KIT i]', [1, 2, 3]],
+ ['[data-attribute$=É-KIT i]', [1, 2, 3]],
+
+ ['[data-attribute$=Web-é-Kit i]', [4, 5]],
+ ['[data-attribute$=é-Kit i]', [4, 5]],
+
+ ['[data-attribute$=web-é-kit i]', [4, 5]],
+ ['[data-attribute$=é-kit i]', [4, 5]],
+
+ // "multiple" is one of those weird legacy exception: it is always case insensitive in HTML.
+ ['[multiple$=WEB-é-KIT]', [1, 2, 3]],
+ ['[multiple$=é-KIT]', [1, 2, 3]],
+
+ ['[multiple$=Web-é-Kit]', [1, 2, 3]],
+ ['[multiple$=é-Kit]', [1, 2, 3]],
+
+ ['[multiple$=Web-é-kit]', [1, 2, 3]],
+ ['[multiple$=é-kit]', [1, 2, 3]],
+
+ ['[multiple$=web-É-kit]', [4, 5]],
+ ['[multiple$=É-kit]', [4, 5]],
+
+ ['[multiple$=web-É-Kit]', [4, 5]],
+ ['[multiple$=É-Kit]', [4, 5]],
+
+ ['[multiple$=WEB-é-KIT i]', [1, 2, 3]],
+ ['[multiple$=é-KIT i]', [1, 2, 3]],
+
+ ['[multiple$=Web-é-Kit i]', [1, 2, 3]],
+ ['[multiple$=é-Kit i]', [1, 2, 3]],
+
+ ['[multiple$=Web-é-kit i]', [1, 2, 3]],
+ ['[multiple$=é-kit i]', [1, 2, 3]],
+
+ ['[multiple$=web-É-kit i]', [4, 5]],
+ ['[multiple$=É-kit i]', [4, 5]],
+
+ ['[multiple$=web-É-Kit i]', [4, 5]],
+ ['[multiple$=É-Kit i]', [4, 5]],
+];
+
+for (var testCase of testCases) {
+ testSelector(testCase[0], testCase[1]);
+}
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributehyphenvaluematchingisasciicaseinsensitiveexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive-expected.txt (0 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive-expected.txt        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -0,0 +1,349 @@
</span><ins>+When matching attributes case insensitively, it should be ASCII case insensitive. This test verifies the behavior when doing hyphen matching on the value (e.g. [a|="b"])
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing "[data-attribute|=Web-É-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É-Kit]')[0].id is "target1"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=Web-É]"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É]')[0].id is "target1"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=web-É]"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-É]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=web-É]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=WEB-É-KIT]"
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É-KIT]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É-KIT]')[0].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=WEB-É]"
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É]')[0].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=Web-é]"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-é]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-é]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=web-é-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é-kit]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute|=web-é]"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute|=Web-É-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É-Kit i]')[1].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=Web-É i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-É i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=web-É i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-É i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute|=web-É i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-É i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-É i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=WEB-É i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute|=WEB-É i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute|=Web-é i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-é i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-é i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute|=Web-é i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute|=web-é-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é-kit i]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é-kit i]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute|=web-é i]"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute|=web-é i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple|=WEB-é-KIT]"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é-KIT]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é-KIT]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=WEB-é]"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é]').length is 3
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é-Kit]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-Kit]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]').length is 3
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é-kit]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-kit]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-kit]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]').length is 3
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=web-É-kit]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É-kit]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=web-É-kit]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=web-É]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É]').length is 2
+PASS document.querySelectorAll('#test-root [multiple|=web-É]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple|=web-É]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple|=web-É-Kit]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=web-É-Kit]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=web-É]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É]').length is 2
+PASS document.querySelectorAll('#test-root [multiple|=web-É]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple|=web-É]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple|=WEB-é-KIT i]"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é-KIT i]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é-KIT i]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=WEB-é i]"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple|=WEB-é i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-Kit i]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-Kit i]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é i]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é-kit i]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-kit i]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=Web-é-kit i]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=Web-é i]"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple|=Web-é i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=web-É-kit i]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É-kit i]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=web-É-kit i]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=web-É i]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple|=web-É i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple|=web-É i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple|=web-É-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É-Kit i]').length is 1
+PASS document.querySelectorAll('#test-root [multiple|=web-É-Kit i]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple|=web-É i]"
+PASS document.querySelectorAll('#test-root [multiple|=web-É i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple|=web-É i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple|=web-É i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributehyphenvaluematchingisasciicaseinsensitivehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html (0 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+#test-root * {
+ background-color: red;
+}
+</style>
+<style id="style">
+</style>
+</head>
+<body>
+ <div style="display:none" id="test-root">
+ <div data-attribute="Web-É-Kit" multiple="WEB-é" id="target1"></div>
+ <div data-attribute="web-É" multiple="Web-é-Kit" id="target2"></div>
+ <div data-attribute="WEB-É-KIT" multiple="Web-é" id="target3"></div>
+ <div data-attribute="Web-é" multiple="web-É-kit" id="target4"></div>
+ <div data-attribute="web-é-kit" multiple="web-É" id="target5"></div>
+ </div>
+</body>
+<script>
+description('When matching attributes case insensitively, it should be ASCII case insensitive. This test verifies the behavior when doing hyphen matching on the value (e.g. [a|="b"])');
+
+function testQuerySelector(selector, expectedIds) {
+ shouldBe("document.querySelectorAll('" + selector + "').length", '' + expectedIds.length);
+ for (var i = 0; i < expectedIds.length; ++i)
+ shouldBeEqualToString("document.querySelectorAll('" + selector + "')[" + i + "].id", 'target' + expectedIds[i]);
+}
+
+function testStyling(selector, expectedIds) {
+ var stylingElement = document.getElementById("style");
+ stylingElement.innerHTML = '' + selector + ' { background-color: rgb(10, 100, 200); }';
+
+ var allTestCases = document.querySelectorAll("#test-root *");
+ for (var i = 0; i < allTestCases.length; ++i) {
+ var expectMatch = expectedIds.indexOf(parseInt(allTestCases[i].id.replace('target', ''))) >= 0;
+ shouldBeEqualToString('getComputedStyle(document.querySelectorAll("#test-root *")[' + i + ']).backgroundColor', expectMatch ? 'rgb(10, 100, 200)' : 'rgb(255, 0, 0)');
+ }
+
+ stylingElement.innerHTML = '';
+}
+
+function testSelector(selector, expectedIds) {
+ debug("Testing \"" + selector + "\"");
+ testQuerySelector("#test-root " + selector, expectedIds);
+ testStyling("#test-root " + selector, expectedIds);
+ debug("");
+}
+
+var testCases = [
+ // Regular attribute matching is case sensitive.
+ ['[data-attribute|=Web-É-Kit]', [1]],
+ ['[data-attribute|=Web-É]', [1]],
+
+ ['[data-attribute|=web-É]', [2]],
+
+ ['[data-attribute|=WEB-É-KIT]', [3]],
+ ['[data-attribute|=WEB-É]', [3]],
+
+ ['[data-attribute|=Web-é]', [4]],
+
+ ['[data-attribute|=web-é-kit]', [5]],
+ ['[data-attribute|=web-é]', [5]],
+
+ // Same selectors with the case-insensitive flag.
+ ['[data-attribute|=Web-É-Kit i]', [1, 3]],
+ ['[data-attribute|=Web-É i]', [1, 2, 3]],
+
+ ['[data-attribute|=web-É i]', [1, 2, 3]],
+
+ ['[data-attribute|=WEB-É i]', [1, 2, 3]],
+
+ ['[data-attribute|=Web-é i]', [4, 5]],
+
+ ['[data-attribute|=web-é-kit i]', [5]],
+ ['[data-attribute|=web-é i]', [4, 5]],
+
+ // "multiple" is one of those weird legacy exception: it is always case insensitive in HTML.
+ ['[multiple|=WEB-é-KIT]', [2]],
+ ['[multiple|=WEB-é]', [1, 2, 3]],
+
+ ['[multiple|=Web-é-Kit]', [2]],
+ ['[multiple|=Web-é]', [1, 2, 3]],
+
+ ['[multiple|=Web-é-kit]', [2]],
+ ['[multiple|=Web-é]', [1, 2, 3]],
+
+ ['[multiple|=web-É-kit]', [4]],
+ ['[multiple|=web-É]', [4, 5]],
+
+ ['[multiple|=web-É-Kit]', [4]],
+ ['[multiple|=web-É]', [4, 5]],
+
+ ['[multiple|=WEB-é-KIT i]', [2]],
+ ['[multiple|=WEB-é i]', [1, 2, 3]],
+
+ ['[multiple|=Web-é-Kit i]', [2]],
+ ['[multiple|=Web-é i]', [1, 2, 3]],
+
+ ['[multiple|=Web-é-kit i]', [2]],
+ ['[multiple|=Web-é i]', [1, 2, 3]],
+
+ ['[multiple|=web-É-kit i]', [4]],
+ ['[multiple|=web-É i]', [4, 5]],
+
+ ['[multiple|=web-É-Kit i]', [4]],
+ ['[multiple|=web-É i]', [4, 5]],
+];
+
+for (var testCase of testCases) {
+ testSelector(testCase[0], testCase[1]);
+}
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributestartswithvaluematchingisasciicaseinsensitiveexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive-expected.txt (0 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive-expected.txt        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -0,0 +1,417 @@
</span><ins>+When matching attributes case insensitively, it should be ASCII case insensitive. This test verifies the behavior when matching the start of the values (e.g. [a^="b"])
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing "[data-attribute^=Web-É-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É-Kit]')[0].id is "target1"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=Web-É]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É]')[0].id is "target1"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=web-É-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É-kit]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=web-É]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É]')[0].id is "target2"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=WEB-É-KIT]"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É-KIT]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É-KIT]')[0].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=WEB-É]"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É]')[0].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=Web-é-Kit]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é-Kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é-Kit]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=Web-é]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é]')[0].id is "target4"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=web-é-kit]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é-kit]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é-kit]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute^=web-é]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é]').length is 1
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é]')[0].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute^=Web-É-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É-Kit i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É-Kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É-Kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=Web-É i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-É i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=web-É-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É-kit i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É-kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É-kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É-kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=web-É i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-É i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=WEB-É-KIT i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É-KIT i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É-KIT i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É-KIT i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É-KIT i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=WEB-É i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É i]').length is 3
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [data-attribute^=WEB-É i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[data-attribute^=Web-é-Kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é-Kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é-Kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute^=Web-é i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute^=Web-é i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute^=web-é-kit i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é-kit i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é-kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é-kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[data-attribute^=web-é i]"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é i]').length is 2
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [data-attribute^=web-é i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=WEB-é-KIT]"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=WEB-é]"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é-Kit]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é-kit]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=web-É-kit]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-kit]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É-kit]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-kit]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=web-É]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=web-É-Kit]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-Kit]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É-Kit]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-Kit]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=web-É]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=WEB-é-KIT i]"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é-KIT i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=WEB-é i]"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=WEB-é i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-Kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é i]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é-kit i]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é-kit i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=Web-é i]"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]').length is 3
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]')[0].id is "target1"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]')[1].id is "target2"
+PASS document.querySelectorAll('#test-root [multiple^=Web-é i]')[2].id is "target3"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(255, 0, 0)"
+
+Testing "[multiple^=web-É-kit i]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-kit i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É-kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=web-É i]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=web-É-Kit i]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-Kit i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É-Kit i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É-Kit i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+Testing "[multiple^=web-É i]"
+PASS document.querySelectorAll('#test-root [multiple^=web-É i]').length is 2
+PASS document.querySelectorAll('#test-root [multiple^=web-É i]')[0].id is "target4"
+PASS document.querySelectorAll('#test-root [multiple^=web-É i]')[1].id is "target5"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[0]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[1]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[2]).backgroundColor is "rgb(255, 0, 0)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[3]).backgroundColor is "rgb(10, 100, 200)"
+PASS getComputedStyle(document.querySelectorAll("#test-root *")[4]).backgroundColor is "rgb(10, 100, 200)"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsattributestartswithvaluematchingisasciicaseinsensitivehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html (0 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -0,0 +1,122 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+#test-root * {
+ background-color: red;
+}
+</style>
+<style id="style">
+</style>
+</head>
+<body>
+ <div style="display:none" id="test-root">
+ <div data-attribute="Web-É-Kit" multiple="WEB-é-KIT" id="target1"></div>
+ <div data-attribute="web-É-kit" multiple="Web-é-Kit" id="target2"></div>
+ <div data-attribute="WEB-É-KIT" multiple="Web-é-kit" id="target3"></div>
+ <div data-attribute="Web-é-Kit" multiple="web-É-kit" id="target4"></div>
+ <div data-attribute="web-é-kit" multiple="web-É-Kit" id="target5"></div>
+ </div>
+</body>
+<script>
+description('When matching attributes case insensitively, it should be ASCII case insensitive. This test verifies the behavior when matching the start of the values (e.g. [a^="b"])');
+
+function testQuerySelector(selector, expectedIds) {
+ shouldBe("document.querySelectorAll('" + selector + "').length", '' + expectedIds.length);
+ for (var i = 0; i < expectedIds.length; ++i)
+ shouldBeEqualToString("document.querySelectorAll('" + selector + "')[" + i + "].id", 'target' + expectedIds[i]);
+}
+
+function testStyling(selector, expectedIds) {
+ var stylingElement = document.getElementById("style");
+ stylingElement.innerHTML = '' + selector + ' { background-color: rgb(10, 100, 200); }';
+
+ var allTestCases = document.querySelectorAll("#test-root *");
+ for (var i = 0; i < allTestCases.length; ++i) {
+ var expectMatch = expectedIds.indexOf(parseInt(allTestCases[i].id.replace('target', ''))) >= 0;
+ shouldBeEqualToString('getComputedStyle(document.querySelectorAll("#test-root *")[' + i + ']).backgroundColor', expectMatch ? 'rgb(10, 100, 200)' : 'rgb(255, 0, 0)');
+ }
+
+ stylingElement.innerHTML = '';
+}
+
+function testSelector(selector, expectedIds) {
+ debug("Testing \"" + selector + "\"");
+ testQuerySelector("#test-root " + selector, expectedIds);
+ testStyling("#test-root " + selector, expectedIds);
+ debug("");
+}
+
+var testCases = [
+ // Regular attribute matching is case sensitive.
+ ['[data-attribute^=Web-É-Kit]', [1]],
+ ['[data-attribute^=Web-É]', [1]],
+
+ ['[data-attribute^=web-É-kit]', [2]],
+ ['[data-attribute^=web-É]', [2]],
+
+ ['[data-attribute^=WEB-É-KIT]', [3]],
+ ['[data-attribute^=WEB-É]', [3]],
+
+ ['[data-attribute^=Web-é-Kit]', [4]],
+ ['[data-attribute^=Web-é]', [4]],
+
+ ['[data-attribute^=web-é-kit]', [5]],
+ ['[data-attribute^=web-é]', [5]],
+
+ // Same selectors with the case-insensitive flag.
+ ['[data-attribute^=Web-É-Kit i]', [1, 2, 3]],
+ ['[data-attribute^=Web-É i]', [1, 2, 3]],
+
+ ['[data-attribute^=web-É-kit i]', [1, 2, 3]],
+ ['[data-attribute^=web-É i]', [1, 2, 3]],
+
+ ['[data-attribute^=WEB-É-KIT i]', [1, 2, 3]],
+ ['[data-attribute^=WEB-É i]', [1, 2, 3]],
+
+ ['[data-attribute^=Web-é-Kit i]', [4, 5]],
+ ['[data-attribute^=Web-é i]', [4, 5]],
+
+ ['[data-attribute^=web-é-kit i]', [4, 5]],
+ ['[data-attribute^=web-é i]', [4, 5]],
+
+ // "multiple" is one of those weird legacy exception: it is always case insensitive in HTML.
+ ['[multiple^=WEB-é-KIT]', [1, 2, 3]],
+ ['[multiple^=WEB-é]', [1, 2, 3]],
+
+ ['[multiple^=Web-é-Kit]', [1, 2, 3]],
+ ['[multiple^=Web-é]', [1, 2, 3]],
+
+ ['[multiple^=Web-é-kit]', [1, 2, 3]],
+ ['[multiple^=Web-é]', [1, 2, 3]],
+
+ ['[multiple^=web-É-kit]', [4, 5]],
+ ['[multiple^=web-É]', [4, 5]],
+
+ ['[multiple^=web-É-Kit]', [4, 5]],
+ ['[multiple^=web-É]', [4, 5]],
+
+ ['[multiple^=WEB-é-KIT i]', [1, 2, 3]],
+ ['[multiple^=WEB-é i]', [1, 2, 3]],
+
+ ['[multiple^=Web-é-Kit i]', [1, 2, 3]],
+ ['[multiple^=Web-é i]', [1, 2, 3]],
+
+ ['[multiple^=Web-é-kit i]', [1, 2, 3]],
+ ['[multiple^=Web-é i]', [1, 2, 3]],
+
+ ['[multiple^=web-É-kit i]', [4, 5]],
+ ['[multiple^=web-É i]', [4, 5]],
+
+ ['[multiple^=web-É-Kit i]', [4, 5]],
+ ['[multiple^=web-É i]', [4, 5]],
+];
+
+for (var testCase of testCases) {
+ testSelector(testCase[0], testCase[1]);
+}
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/ChangeLog        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2015-03-15 Benjamin Poulain <benjamin@webkit.org>
+
+ CSS: fix the case-insensitive matching of the attribute selectors Begin, End and Hyphen
+ https://bugs.webkit.org/show_bug.cgi?id=142715
+
+ Reviewed by Brent Fulgham.
+
+ Add the necessary infrastructure to test startsWith() and endsWith() with
+ ASCII case-insentive comparisons.
+
+ * wtf/text/AtomicString.h:
+ (WTF::AtomicString::startsWith):
+ (WTF::AtomicString::startsWithIgnoringASCIICase):
+ (WTF::AtomicString::endsWith):
+ (WTF::AtomicString::endsWithIgnoringASCIICase):
+
+ * wtf/text/StringCommon.h:
+ (WTF::loadUnaligned):
+ (WTF::equal):
+ I moved the low level equal() code from StringImpl to StringCommon
+ since it is used by both StringImpl and StringView.
+
+ (WTF::equalCommon):
+ (WTF::equalIgnoringASCIICaseCommon):
+ Ideally we should drop the "Common" part of the name but StringView
+ wants this inline for some reason. I prefered keeping the current behavior
+ since I don't know how StringView's matching performance was evaluated.
+
+ (WTF::startsWith):
+ (WTF::startsWithIgnoringASCIICase):
+ (WTF::endsWith):
+ (WTF::endsWithIgnoringASCIICase):
+ Make all that code shared between StringView and Stringimpl.
+
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::startsWith):
+ (WTF::StringImpl::startsWithIgnoringASCIICase):
+ (WTF::StringImpl::endsWith):
+ (WTF::StringImpl::endsWithIgnoringASCIICase):
+ (WTF::equal):
+ (WTF::stringImplContentEqual): Deleted.
+ * wtf/text/StringImpl.h:
+ (WTF::loadUnaligned): Deleted.
+ (WTF::equal): Deleted.
+
+ * wtf/text/StringView.cpp:
+ (WTF::StringView::startsWith):
+ (WTF::StringView::startsWithIgnoringASCIICase):
+ (WTF::StringView::endsWith):
+ (WTF::StringView::endsWithIgnoringASCIICase):
+ * wtf/text/StringView.h:
+ Since those are new, we can safely make them out-of-line and
+ evaluate the inlining impact as needed.
+
+ * wtf/text/WTFString.h:
+ (WTF::String::startsWithIgnoringASCIICase):
+ (WTF::String::endsWith):
+ (WTF::String::endsWithIgnoringASCIICase):
+
</ins><span class="cx"> 2015-03-15 Benjamin Poulain <bpoulain@apple.com>
</span><span class="cx">
</span><span class="cx"> Change the exact attribute matching to be ASCII case-insensitive
</span></span></pre></div>
<a id="trunkSourceWTFwtftextAtomicStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/AtomicString.h (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/AtomicString.h        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/AtomicString.h        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -126,7 +126,11 @@
</span><span class="cx"> size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const
</span><span class="cx"> { return m_string.find(matchFunction, start); }
</span><span class="cx">
</span><del>- bool startsWith(const String& s, bool caseSensitive = true) const
</del><ins>+ bool startsWith(const String& s) const
+ { return m_string.startsWith(s); }
+ bool startsWithIgnoringASCIICase(const String& s) const
+ { return m_string.startsWithIgnoringASCIICase(s); }
+ bool startsWith(const String& s, bool caseSensitive) const
</ins><span class="cx"> { return m_string.startsWith(s, caseSensitive); }
</span><span class="cx"> bool startsWith(UChar character) const
</span><span class="cx"> { return m_string.startsWith(character); }
</span><span class="lines">@@ -134,7 +138,11 @@
</span><span class="cx"> bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const
</span><span class="cx"> { return m_string.startsWith<matchLength>(prefix, caseSensitive); }
</span><span class="cx">
</span><del>- bool endsWith(const String& s, bool caseSensitive = true) const
</del><ins>+ bool endsWith(const String& s) const
+ { return m_string.endsWith(s); }
+ bool endsWithIgnoringASCIICase(const String& s) const
+ { return m_string.endsWithIgnoringASCIICase(s); }
+ bool endsWith(const String& s, bool caseSensitive) const
</ins><span class="cx"> { return m_string.endsWith(s, caseSensitive); }
</span><span class="cx"> bool endsWith(UChar character) const
</span><span class="cx"> { return m_string.endsWith(character); }
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringCommonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringCommon.h (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringCommon.h        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/StringCommon.h        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -31,6 +31,288 @@
</span><span class="cx">
</span><span class="cx"> namespace WTF {
</span><span class="cx">
</span><ins>+template<typename T>
+inline T loadUnaligned(const char* s)
+{
+#if COMPILER(CLANG)
+ T tmp;
+ memcpy(&tmp, s, sizeof(T));
+ return tmp;
+#else
+ // This may result in undefined behavior due to unaligned access.
+ return *reinterpret_cast<const T*>(s);
+#endif
+}
+
+// Do comparisons 8 or 4 bytes-at-a-time on architectures where it's safe.
+#if (CPU(X86_64) || CPU(ARM64)) && !ASAN_ENABLED
+ALWAYS_INLINE bool equal(const LChar* aLChar, const LChar* bLChar, unsigned length)
+{
+ unsigned dwordLength = length >> 3;
+
+ const char* a = reinterpret_cast<const char*>(aLChar);
+ const char* b = reinterpret_cast<const char*>(bLChar);
+
+ if (dwordLength) {
+ for (unsigned i = 0; i != dwordLength; ++i) {
+ if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b))
+ return false;
+
+ a += sizeof(uint64_t);
+ b += sizeof(uint64_t);
+ }
+ }
+
+ if (length & 4) {
+ if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
+ return false;
+
+ a += sizeof(uint32_t);
+ b += sizeof(uint32_t);
+ }
+
+ if (length & 2) {
+ if (loadUnaligned<uint16_t>(a) != loadUnaligned<uint16_t>(b))
+ return false;
+
+ a += sizeof(uint16_t);
+ b += sizeof(uint16_t);
+ }
+
+ if (length & 1 && (*reinterpret_cast<const LChar*>(a) != *reinterpret_cast<const LChar*>(b)))
+ return false;
+
+ return true;
+}
+
+ALWAYS_INLINE bool equal(const UChar* aUChar, const UChar* bUChar, unsigned length)
+{
+ unsigned dwordLength = length >> 2;
+
+ const char* a = reinterpret_cast<const char*>(aUChar);
+ const char* b = reinterpret_cast<const char*>(bUChar);
+
+ if (dwordLength) {
+ for (unsigned i = 0; i != dwordLength; ++i) {
+ if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b))
+ return false;
+
+ a += sizeof(uint64_t);
+ b += sizeof(uint64_t);
+ }
+ }
+
+ if (length & 2) {
+ if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
+ return false;
+
+ a += sizeof(uint32_t);
+ b += sizeof(uint32_t);
+ }
+
+ if (length & 1 && (*reinterpret_cast<const UChar*>(a) != *reinterpret_cast<const UChar*>(b)))
+ return false;
+
+ return true;
+}
+#elif CPU(X86) && !ASAN_ENABLED
+ALWAYS_INLINE bool equal(const LChar* aLChar, const LChar* bLChar, unsigned length)
+{
+ const char* a = reinterpret_cast<const char*>(aLChar);
+ const char* b = reinterpret_cast<const char*>(bLChar);
+
+ unsigned wordLength = length >> 2;
+ for (unsigned i = 0; i != wordLength; ++i) {
+ if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
+ return false;
+ a += sizeof(uint32_t);
+ b += sizeof(uint32_t);
+ }
+
+ length &= 3;
+
+ if (length) {
+ const LChar* aRemainder = reinterpret_cast<const LChar*>(a);
+ const LChar* bRemainder = reinterpret_cast<const LChar*>(b);
+
+ for (unsigned i = 0; i < length; ++i) {
+ if (aRemainder[i] != bRemainder[i])
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ALWAYS_INLINE bool equal(const UChar* aUChar, const UChar* bUChar, unsigned length)
+{
+ const char* a = reinterpret_cast<const char*>(aUChar);
+ const char* b = reinterpret_cast<const char*>(bUChar);
+
+ unsigned wordLength = length >> 1;
+ for (unsigned i = 0; i != wordLength; ++i) {
+ if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
+ return false;
+ a += sizeof(uint32_t);
+ b += sizeof(uint32_t);
+ }
+
+ if (length & 1 && *reinterpret_cast<const UChar*>(a) != *reinterpret_cast<const UChar*>(b))
+ return false;
+
+ return true;
+}
+#elif PLATFORM(IOS) && WTF_ARM_ARCH_AT_LEAST(7) && !ASAN_ENABLED
+ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
+{
+ bool isEqual = false;
+ uint32_t aValue;
+ uint32_t bValue;
+ asm("subs %[length], #4\n"
+ "blo 2f\n"
+
+ "0:\n" // Label 0 = Start of loop over 32 bits.
+ "ldr %[aValue], [%[a]], #4\n"
+ "ldr %[bValue], [%[b]], #4\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+ "subs %[length], #4\n"
+ "bhs 0b\n"
+
+ // At this point, length can be:
+ // -0: 00000000000000000000000000000000 (0 bytes left)
+ // -1: 11111111111111111111111111111111 (3 bytes left)
+ // -2: 11111111111111111111111111111110 (2 bytes left)
+ // -3: 11111111111111111111111111111101 (1 byte left)
+ // -4: 11111111111111111111111111111100 (length was 0)
+ // The pointers are at the correct position.
+ "2:\n" // Label 2 = End of loop over 32 bits, check for pair of characters.
+ "tst %[length], #2\n"
+ "beq 1f\n"
+ "ldrh %[aValue], [%[a]], #2\n"
+ "ldrh %[bValue], [%[b]], #2\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+
+ "1:\n" // Label 1 = Check for a single character left.
+ "tst %[length], #1\n"
+ "beq 42f\n"
+ "ldrb %[aValue], [%[a]]\n"
+ "ldrb %[bValue], [%[b]]\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+
+ "42:\n" // Label 42 = Success.
+ "mov %[isEqual], #1\n"
+ "66:\n" // Label 66 = End without changing isEqual to 1.
+ : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
+ :
+ :
+ );
+ return isEqual;
+}
+
+ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
+{
+ bool isEqual = false;
+ uint32_t aValue;
+ uint32_t bValue;
+ asm("subs %[length], #2\n"
+ "blo 1f\n"
+
+ "0:\n" // Label 0 = Start of loop over 32 bits.
+ "ldr %[aValue], [%[a]], #4\n"
+ "ldr %[bValue], [%[b]], #4\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+ "subs %[length], #2\n"
+ "bhs 0b\n"
+
+ // At this point, length can be:
+ // -0: 00000000000000000000000000000000 (0 bytes left)
+ // -1: 11111111111111111111111111111111 (1 character left, 2 bytes)
+ // -2: 11111111111111111111111111111110 (length was zero)
+ // The pointers are at the correct position.
+ "1:\n" // Label 1 = Check for a single character left.
+ "tst %[length], #1\n"
+ "beq 42f\n"
+ "ldrh %[aValue], [%[a]]\n"
+ "ldrh %[bValue], [%[b]]\n"
+ "cmp %[aValue], %[bValue]\n"
+ "bne 66f\n"
+
+ "42:\n" // Label 42 = Success.
+ "mov %[isEqual], #1\n"
+ "66:\n" // Label 66 = End without changing isEqual to 1.
+ : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
+ :
+ :
+ );
+ return isEqual;
+}
+#elif !ASAN_ENABLED
+ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length) { return !memcmp(a, b, length); }
+ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length) { return !memcmp(a, b, length * sizeof(UChar)); }
+#else
+ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
+{
+ for (unsigned i = 0; i < length; ++i) {
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+}
+ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
+{
+ for (unsigned i = 0; i < length; ++i) {
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+}
+#endif
+
+ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length)
+{
+ for (unsigned i = 0; i < length; ++i) {
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+}
+
+ALWAYS_INLINE bool equal(const UChar* a, const LChar* b, unsigned length) { return equal(b, a, length); }
+
+template<typename StringClassA, typename StringClassB>
+ALWAYS_INLINE bool equalCommon(const StringClassA& a, const StringClassB& b)
+{
+ unsigned length = a.length();
+ if (length != b.length())
+ return false;
+
+ if (a.is8Bit()) {
+ if (b.is8Bit())
+ return equal(a.characters8(), b.characters8(), length);
+
+ return equal(a.characters8(), b.characters16(), length);
+ }
+
+ if (b.is8Bit())
+ return equal(a.characters16(), b.characters8(), length);
+
+ return equal(a.characters16(), b.characters16(), length);
+}
+
+template<typename StringClassA, typename StringClassB>
+ALWAYS_INLINE bool equalCommon(const StringClassA* a, const StringClassB* b)
+{
+ if (a == b)
+ return true;
+ if (!a || !b)
+ return false;
+ return equal(*a, *b);
+}
+
</ins><span class="cx"> template<typename CharacterTypeA, typename CharacterTypeB>
</span><span class="cx"> inline bool equalIgnoringASCIICase(const CharacterTypeA* a, const CharacterTypeB* b, unsigned length)
</span><span class="cx"> {
</span><span class="lines">@@ -41,8 +323,8 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-template<typename StringClass>
-bool equalIgnoringASCIICaseCommon(const StringClass& a, const StringClass& b)
</del><ins>+template<typename StringClassA, typename StringClassB>
+bool equalIgnoringASCIICaseCommon(const StringClassA& a, const StringClassB& b)
</ins><span class="cx"> {
</span><span class="cx"> unsigned length = a.length();
</span><span class="cx"> if (length != b.length())
</span><span class="lines">@@ -61,6 +343,80 @@
</span><span class="cx"> return equalIgnoringASCIICase(a.characters16(), b.characters16(), length);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+template<typename StringClassA, typename StringClassB>
+bool startsWith(const StringClassA& reference, const StringClassB& prefix)
+{
+ unsigned prefixLength = prefix.length();
+ if (prefixLength > reference.length())
+ return false;
+
+ if (reference.is8Bit()) {
+ if (prefix.is8Bit())
+ return equal(reference.characters8(), prefix.characters8(), prefixLength);
+ return equal(reference.characters8(), prefix.characters16(), prefixLength);
+ }
+ if (prefix.is8Bit())
+ return equal(reference.characters16(), prefix.characters8(), prefixLength);
+ return equal(reference.characters16(), prefix.characters16(), prefixLength);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+template<typename StringClassA, typename StringClassB>
+bool startsWithIgnoringASCIICase(const StringClassA& reference, const StringClassB& prefix)
+{
+ unsigned prefixLength = prefix.length();
+ if (prefixLength > reference.length())
+ return false;
+
+ if (reference.is8Bit()) {
+ if (prefix.is8Bit())
+ return equalIgnoringASCIICase(reference.characters8(), prefix.characters8(), prefixLength);
+ return equalIgnoringASCIICase(reference.characters8(), prefix.characters16(), prefixLength);
+ }
+ if (prefix.is8Bit())
+ return equalIgnoringASCIICase(reference.characters16(), prefix.characters8(), prefixLength);
+ return equalIgnoringASCIICase(reference.characters16(), prefix.characters16(), prefixLength);
+}
+
+template<typename StringClassA, typename StringClassB>
+bool endsWith(const StringClassA& reference, const StringClassB& suffix)
+{
+ unsigned suffixLength = suffix.length();
+ unsigned referenceLength = reference.length();
+ if (suffixLength > referenceLength)
+ return false;
+
+ unsigned startOffset = referenceLength - suffixLength;
+
+ if (reference.is8Bit()) {
+ if (suffix.is8Bit())
+ return equal(reference.characters8() + startOffset, suffix.characters8(), suffixLength);
+ return equal(reference.characters8() + startOffset, suffix.characters16(), suffixLength);
+ }
+ if (suffix.is8Bit())
+ return equal(reference.characters16() + startOffset, suffix.characters8(), suffixLength);
+ return equal(reference.characters16() + startOffset, suffix.characters16(), suffixLength);
+}
+
+template<typename StringClassA, typename StringClassB>
+bool endsWithIgnoringASCIICase(const StringClassA& reference, const StringClassB& suffix)
+{
+ unsigned suffixLength = suffix.length();
+ unsigned referenceLength = reference.length();
+ if (suffixLength > referenceLength)
+ return false;
+
+ unsigned startOffset = referenceLength - suffixLength;
+
+ if (reference.is8Bit()) {
+ if (suffix.is8Bit())
+ return equalIgnoringASCIICase(reference.characters8() + startOffset, suffix.characters8(), suffixLength);
+ return equalIgnoringASCIICase(reference.characters8() + startOffset, suffix.characters16(), suffixLength);
+ }
+ if (suffix.is8Bit())
+ return equalIgnoringASCIICase(reference.characters16() + startOffset, suffix.characters8(), suffixLength);
+ return equalIgnoringASCIICase(reference.characters16() + startOffset, suffix.characters16(), suffixLength);
+}
+
+}
+
</ins><span class="cx"> #endif // StringCommon_h
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.cpp        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -1380,20 +1380,27 @@
</span><span class="cx"> {
</span><span class="cx"> if (!str)
</span><span class="cx"> return false;
</span><ins>+ return ::WTF::startsWith(*this, *str);
+}
</ins><span class="cx">
</span><del>- if (str->length() > length())
</del><ins>+bool StringImpl::startsWith(const StringImpl& str) const
+{
+ return ::WTF::startsWith(*this, str);
+}
+
+bool StringImpl::startsWithIgnoringASCIICase(const StringImpl* prefix) const
+{
+ if (!prefix)
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (is8Bit()) {
- if (str->is8Bit())
- return equal(characters8(), str->characters8(), str->length());
- return equal(characters8(), str->characters16(), str->length());
- }
- if (str->is8Bit())
- return equal(characters16(), str->characters8(), str->length());
- return equal(characters16(), str->characters16(), str->length());
</del><ins>+ return ::WTF::startsWithIgnoringASCIICase(*this, *prefix);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+bool StringImpl::startsWithIgnoringASCIICase(const StringImpl& prefix) const
+{
+ return ::WTF::startsWithIgnoringASCIICase(*this, prefix);
+}
+
</ins><span class="cx"> bool StringImpl::startsWith(UChar character) const
</span><span class="cx"> {
</span><span class="cx"> return m_length && (*this)[0] == character;
</span><span class="lines">@@ -1412,6 +1419,19 @@
</span><span class="cx"> return equalInner(*this, startOffset, matchString);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool StringImpl::endsWith(StringImpl* suffix)
+{
+ if (!suffix)
+ return false;
+
+ return ::WTF::endsWith(*this, *suffix);
+}
+
+bool StringImpl::endsWith(StringImpl& suffix)
+{
+ return ::WTF::endsWith(*this, suffix);
+}
+
</ins><span class="cx"> bool StringImpl::endsWith(StringImpl* matchString, bool caseSensitive)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(matchString);
</span><span class="lines">@@ -1422,6 +1442,19 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool StringImpl::endsWithIgnoringASCIICase(const StringImpl* suffix) const
+{
+ if (!suffix)
+ return false;
+
+ return ::WTF::endsWithIgnoringASCIICase(*this, *suffix);
+}
+
+bool StringImpl::endsWithIgnoringASCIICase(const StringImpl& suffix) const
+{
+ return ::WTF::endsWithIgnoringASCIICase(*this, suffix);
+}
+
</ins><span class="cx"> bool StringImpl::endsWith(UChar character) const
</span><span class="cx"> {
</span><span class="cx"> return m_length && (*this)[m_length - 1] == character;
</span><span class="lines">@@ -1824,34 +1857,9 @@
</span><span class="cx"> return newImpl;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static ALWAYS_INLINE bool stringImplContentEqual(const StringImpl& a, const StringImpl& b)
-{
- unsigned aLength = a.length();
- unsigned bLength = b.length();
- if (aLength != bLength)
- return false;
-
- if (a.is8Bit()) {
- if (b.is8Bit())
- return equal(a.characters8(), b.characters8(), aLength);
-
- return equal(a.characters8(), b.characters16(), aLength);
- }
-
- if (b.is8Bit())
- return equal(a.characters16(), b.characters8(), aLength);
-
- return equal(a.characters16(), b.characters16(), aLength);
-}
-
</del><span class="cx"> bool equal(const StringImpl* a, const StringImpl* b)
</span><span class="cx"> {
</span><del>- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- return stringImplContentEqual(*a, *b);
</del><ins>+ return equalCommon(a, b);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template <typename CharType>
</span><span class="lines">@@ -1916,10 +1924,7 @@
</span><span class="cx">
</span><span class="cx"> bool equal(const StringImpl& a, const StringImpl& b)
</span><span class="cx"> {
</span><del>- if (&a == &b)
- return true;
-
- return stringImplContentEqual(a, b);
</del><ins>+ return equalCommon(a, b);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool equalIgnoringCase(const StringImpl* a, const StringImpl* b)
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.h (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.h        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/StringImpl.h        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -669,6 +669,9 @@
</span><span class="cx"> WTF_EXPORT_STRING_API size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX);
</span><span class="cx">
</span><span class="cx"> WTF_EXPORT_STRING_API bool startsWith(const StringImpl*) const;
</span><ins>+ WTF_EXPORT_STRING_API bool startsWith(const StringImpl&) const;
+ WTF_EXPORT_STRING_API bool startsWithIgnoringASCIICase(const StringImpl*) const;
+ WTF_EXPORT_STRING_API bool startsWithIgnoringASCIICase(const StringImpl&) const;
</ins><span class="cx"> bool startsWith(StringImpl* str, bool caseSensitive) { return caseSensitive ? startsWith(str) : (reverseFindIgnoringCase(str, 0) == 0); }
</span><span class="cx"> WTF_EXPORT_STRING_API bool startsWith(UChar) const;
</span><span class="cx"> WTF_EXPORT_STRING_API bool startsWith(const char*, unsigned matchLength, bool caseSensitive) const;
</span><span class="lines">@@ -676,7 +679,11 @@
</span><span class="cx"> bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const { return startsWith(prefix, matchLength - 1, caseSensitive); }
</span><span class="cx"> WTF_EXPORT_STRING_API bool hasInfixStartingAt(const StringImpl&, unsigned startOffset) const;
</span><span class="cx">
</span><del>- WTF_EXPORT_STRING_API bool endsWith(StringImpl*, bool caseSensitive = true);
</del><ins>+ WTF_EXPORT_STRING_API bool endsWith(StringImpl*);
+ WTF_EXPORT_STRING_API bool endsWith(StringImpl&);
+ WTF_EXPORT_STRING_API bool endsWithIgnoringASCIICase(const StringImpl*) const;
+ WTF_EXPORT_STRING_API bool endsWithIgnoringASCIICase(const StringImpl&) const;
+ WTF_EXPORT_STRING_API bool endsWith(StringImpl*, bool caseSensitive);
</ins><span class="cx"> WTF_EXPORT_STRING_API bool endsWith(UChar) const;
</span><span class="cx"> WTF_EXPORT_STRING_API bool endsWith(const char*, unsigned matchLength, bool caseSensitive) const;
</span><span class="cx"> template<unsigned matchLength>
</span><span class="lines">@@ -861,258 +868,6 @@
</span><span class="cx"> inline bool equal(const char* a, StringImpl* b) { return equal(b, reinterpret_cast<const LChar*>(a)); }
</span><span class="cx"> WTF_EXPORT_STRING_API bool equal(const StringImpl& a, const StringImpl& b);
</span><span class="cx">
</span><del>-template<typename T>
-inline T loadUnaligned(const char* s)
-{
-#if COMPILER(CLANG)
- T tmp;
- memcpy(&tmp, s, sizeof(T));
- return tmp;
-#else
- // This may result in undefined behavior due to unaligned access.
- return *reinterpret_cast<const T*>(s);
-#endif
-}
-
-// Do comparisons 8 or 4 bytes-at-a-time on architectures where it's safe.
-#if (CPU(X86_64) || CPU(ARM64)) && !ASAN_ENABLED
-ALWAYS_INLINE bool equal(const LChar* aLChar, const LChar* bLChar, unsigned length)
-{
- unsigned dwordLength = length >> 3;
-
- const char* a = reinterpret_cast<const char*>(aLChar);
- const char* b = reinterpret_cast<const char*>(bLChar);
-
- if (dwordLength) {
- for (unsigned i = 0; i != dwordLength; ++i) {
- if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b))
- return false;
-
- a += sizeof(uint64_t);
- b += sizeof(uint64_t);
- }
- }
-
- if (length & 4) {
- if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
- return false;
-
- a += sizeof(uint32_t);
- b += sizeof(uint32_t);
- }
-
- if (length & 2) {
- if (loadUnaligned<uint16_t>(a) != loadUnaligned<uint16_t>(b))
- return false;
-
- a += sizeof(uint16_t);
- b += sizeof(uint16_t);
- }
-
- if (length & 1 && (*reinterpret_cast<const LChar*>(a) != *reinterpret_cast<const LChar*>(b)))
- return false;
-
- return true;
-}
-
-ALWAYS_INLINE bool equal(const UChar* aUChar, const UChar* bUChar, unsigned length)
-{
- unsigned dwordLength = length >> 2;
-
- const char* a = reinterpret_cast<const char*>(aUChar);
- const char* b = reinterpret_cast<const char*>(bUChar);
-
- if (dwordLength) {
- for (unsigned i = 0; i != dwordLength; ++i) {
- if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b))
- return false;
-
- a += sizeof(uint64_t);
- b += sizeof(uint64_t);
- }
- }
-
- if (length & 2) {
- if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
- return false;
-
- a += sizeof(uint32_t);
- b += sizeof(uint32_t);
- }
-
- if (length & 1 && (*reinterpret_cast<const UChar*>(a) != *reinterpret_cast<const UChar*>(b)))
- return false;
-
- return true;
-}
-#elif CPU(X86) && !ASAN_ENABLED
-ALWAYS_INLINE bool equal(const LChar* aLChar, const LChar* bLChar, unsigned length)
-{
- const char* a = reinterpret_cast<const char*>(aLChar);
- const char* b = reinterpret_cast<const char*>(bLChar);
-
- unsigned wordLength = length >> 2;
- for (unsigned i = 0; i != wordLength; ++i) {
- if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
- return false;
- a += sizeof(uint32_t);
- b += sizeof(uint32_t);
- }
-
- length &= 3;
-
- if (length) {
- const LChar* aRemainder = reinterpret_cast<const LChar*>(a);
- const LChar* bRemainder = reinterpret_cast<const LChar*>(b);
-
- for (unsigned i = 0; i < length; ++i) {
- if (aRemainder[i] != bRemainder[i])
- return false;
- }
- }
-
- return true;
-}
-
-ALWAYS_INLINE bool equal(const UChar* aUChar, const UChar* bUChar, unsigned length)
-{
- const char* a = reinterpret_cast<const char*>(aUChar);
- const char* b = reinterpret_cast<const char*>(bUChar);
-
- unsigned wordLength = length >> 1;
- for (unsigned i = 0; i != wordLength; ++i) {
- if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
- return false;
- a += sizeof(uint32_t);
- b += sizeof(uint32_t);
- }
-
- if (length & 1 && *reinterpret_cast<const UChar*>(a) != *reinterpret_cast<const UChar*>(b))
- return false;
-
- return true;
-}
-#elif PLATFORM(IOS) && WTF_ARM_ARCH_AT_LEAST(7) && !ASAN_ENABLED
-ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
-{
- bool isEqual = false;
- uint32_t aValue;
- uint32_t bValue;
- asm("subs %[length], #4\n"
- "blo 2f\n"
-
- "0:\n" // Label 0 = Start of loop over 32 bits.
- "ldr %[aValue], [%[a]], #4\n"
- "ldr %[bValue], [%[b]], #4\n"
- "cmp %[aValue], %[bValue]\n"
- "bne 66f\n"
- "subs %[length], #4\n"
- "bhs 0b\n"
-
- // At this point, length can be:
- // -0: 00000000000000000000000000000000 (0 bytes left)
- // -1: 11111111111111111111111111111111 (3 bytes left)
- // -2: 11111111111111111111111111111110 (2 bytes left)
- // -3: 11111111111111111111111111111101 (1 byte left)
- // -4: 11111111111111111111111111111100 (length was 0)
- // The pointers are at the correct position.
- "2:\n" // Label 2 = End of loop over 32 bits, check for pair of characters.
- "tst %[length], #2\n"
- "beq 1f\n"
- "ldrh %[aValue], [%[a]], #2\n"
- "ldrh %[bValue], [%[b]], #2\n"
- "cmp %[aValue], %[bValue]\n"
- "bne 66f\n"
-
- "1:\n" // Label 1 = Check for a single character left.
- "tst %[length], #1\n"
- "beq 42f\n"
- "ldrb %[aValue], [%[a]]\n"
- "ldrb %[bValue], [%[b]]\n"
- "cmp %[aValue], %[bValue]\n"
- "bne 66f\n"
-
- "42:\n" // Label 42 = Success.
- "mov %[isEqual], #1\n"
- "66:\n" // Label 66 = End without changing isEqual to 1.
- : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
- :
- :
- );
- return isEqual;
-}
-
-ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
-{
- bool isEqual = false;
- uint32_t aValue;
- uint32_t bValue;
- asm("subs %[length], #2\n"
- "blo 1f\n"
-
- "0:\n" // Label 0 = Start of loop over 32 bits.
- "ldr %[aValue], [%[a]], #4\n"
- "ldr %[bValue], [%[b]], #4\n"
- "cmp %[aValue], %[bValue]\n"
- "bne 66f\n"
- "subs %[length], #2\n"
- "bhs 0b\n"
-
- // At this point, length can be:
- // -0: 00000000000000000000000000000000 (0 bytes left)
- // -1: 11111111111111111111111111111111 (1 character left, 2 bytes)
- // -2: 11111111111111111111111111111110 (length was zero)
- // The pointers are at the correct position.
- "1:\n" // Label 1 = Check for a single character left.
- "tst %[length], #1\n"
- "beq 42f\n"
- "ldrh %[aValue], [%[a]]\n"
- "ldrh %[bValue], [%[b]]\n"
- "cmp %[aValue], %[bValue]\n"
- "bne 66f\n"
-
- "42:\n" // Label 42 = Success.
- "mov %[isEqual], #1\n"
- "66:\n" // Label 66 = End without changing isEqual to 1.
- : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
- :
- :
- );
- return isEqual;
-}
-#elif !ASAN_ENABLED
-ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length) { return !memcmp(a, b, length); }
-ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length) { return !memcmp(a, b, length * sizeof(UChar)); }
-#else
-ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
-{
- for (unsigned i = 0; i < length; ++i) {
- if (a[i] != b[i])
- return false;
- }
- return true;
-}
-ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
-{
- for (unsigned i = 0; i < length; ++i) {
- if (a[i] != b[i])
- return false;
- }
- return true;
-}
-#endif
-
-ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length)
-{
- for (unsigned i = 0; i < length; ++i) {
- if (a[i] != b[i])
- return false;
- }
- return true;
-}
-
-ALWAYS_INLINE bool equal(const UChar* a, const LChar* b, unsigned length) { return equal(b, a, length); }
-
</del><span class="cx"> WTF_EXPORT_STRING_API bool equalIgnoringCase(const StringImpl*, const StringImpl*);
</span><span class="cx"> WTF_EXPORT_STRING_API bool equalIgnoringCase(const StringImpl*, const LChar*);
</span><span class="cx"> inline bool equalIgnoringCase(const LChar* a, const StringImpl* b) { return equalIgnoringCase(b, a); }
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringView.cpp (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringView.cpp        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/StringView.cpp        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -118,6 +118,26 @@
</span><span class="cx"> adoptUnderlyingString(underlyingString);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool StringView::startsWith(const StringView& prefix) const
+{
+ return ::WTF::startsWith(*this, prefix);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+bool StringView::startsWithIgnoringASCIICase(const StringView& prefix) const
+{
+ return ::WTF::endsWithIgnoringASCIICase(*this, prefix);
+}
+
+bool StringView::endsWith(const StringView& prefix) const
+{
+ return ::WTF::startsWith(*this, prefix);
+}
+
+bool StringView::endsWithIgnoringASCIICase(const StringView& prefix) const
+{
+ return ::WTF::endsWithIgnoringASCIICase(*this, prefix);
+}
+
+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringView.h (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringView.h        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/StringView.h        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -106,6 +106,12 @@
</span><span class="cx"> size_t find(UChar, unsigned start = 0) const;
</span><span class="cx"> bool contains(UChar) const;
</span><span class="cx">
</span><ins>+ bool startsWith(const StringView&) const;
+ bool startsWithIgnoringASCIICase(const StringView&) const;
+
+ bool endsWith(const StringView&) const;
+ bool endsWithIgnoringASCIICase(const StringView&) const;
+
</ins><span class="cx"> int toInt(bool& isValid) const;
</span><span class="cx"> float toFloat(bool& isValid) const;
</span><span class="cx">
</span><span class="lines">@@ -469,22 +475,7 @@
</span><span class="cx">
</span><span class="cx"> inline bool equal(StringView a, StringView b)
</span><span class="cx"> {
</span><del>- unsigned aLength = a.length();
- unsigned bLength = b.length();
- if (aLength != bLength)
- return false;
-
- if (a.is8Bit()) {
- if (b.is8Bit())
- return equal(a.characters8(), b.characters8(), aLength);
-
- return equal(a.characters8(), b.characters16(), aLength);
- }
-
- if (b.is8Bit())
- return equal(a.characters16(), b.characters8(), aLength);
-
- return equal(a.characters16(), b.characters16(), aLength);
</del><ins>+ return equalCommon(a, b);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline bool equal(StringView a, const LChar* b)
</span></span></pre></div>
<a id="trunkSourceWTFwtftextWTFStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/WTFString.h (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/WTFString.h        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WTF/wtf/text/WTFString.h        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -263,6 +263,8 @@
</span><span class="cx">
</span><span class="cx"> bool startsWith(const String& s) const
</span><span class="cx"> { return m_impl ? m_impl->startsWith(s.impl()) : s.isEmpty(); }
</span><ins>+ bool startsWithIgnoringASCIICase(const String& s) const
+ { return m_impl ? m_impl->startsWithIgnoringASCIICase(s.impl()) : s.isEmpty(); }
</ins><span class="cx"> bool startsWith(const String& s, bool caseSensitive) const
</span><span class="cx"> { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); }
</span><span class="cx"> bool startsWith(UChar character) const
</span><span class="lines">@@ -273,7 +275,11 @@
</span><span class="cx"> bool hasInfixStartingAt(const String& prefix, unsigned startOffset) const
</span><span class="cx"> { return m_impl && prefix.impl() ? m_impl->hasInfixStartingAt(*prefix.impl(), startOffset) : false; }
</span><span class="cx">
</span><del>- bool endsWith(const String& s, bool caseSensitive = true) const
</del><ins>+ bool endsWith(const String& s) const
+ { return m_impl ? m_impl->endsWith(s.impl()) : s.isEmpty(); }
+ bool endsWithIgnoringASCIICase(const String& s) const
+ { return m_impl ? m_impl->endsWithIgnoringASCIICase(s.impl()) : s.isEmpty(); }
+ bool endsWith(const String& s, bool caseSensitive) const
</ins><span class="cx"> { return m_impl ? m_impl->endsWith(s.impl(), caseSensitive) : s.isEmpty(); }
</span><span class="cx"> bool endsWith(UChar character) const
</span><span class="cx"> { return m_impl ? m_impl->endsWith(character) : false; }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WebCore/ChangeLog        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2015-03-15 Benjamin Poulain <benjamin@webkit.org>
+
+ CSS: fix the case-insensitive matching of the attribute selectors Begin, End and Hyphen
+ https://bugs.webkit.org/show_bug.cgi?id=142715
+
+ Reviewed by Brent Fulgham.
+
+ Fix attribute matching with:
+ -Begin: [a^=b].
+ -End: [a$=b].
+ -Hyphen: [a|=b].
+
+ Tests: fast/selectors/attribute-endswith-value-matching-is-ascii-case-insensitive.html
+ fast/selectors/attribute-hyphen-value-matching-is-ascii-case-insensitive.html
+ fast/selectors/attribute-startswith-value-matching-is-ascii-case-insensitive.html
+
+ * css/SelectorChecker.cpp:
+ (WebCore::attributeValueMatches):
+ I forgot to change CSSSelector::Exact in my last patch.
+ The tests could not catch that since we use the CSS JIT almost everywhere.
+
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::attributeValueBeginsWith):
+ (WebCore::SelectorCompiler::attributeValueEndsWith):
+ (WebCore::SelectorCompiler::attributeValueMatchHyphenRule):
+
</ins><span class="cx"> 2015-03-15 Dan Bernstein <mitz@apple.com>
</span><span class="cx">
</span><span class="cx"> Fixed the iOS build after r181522.
</span></span></pre></div>
<a id="trunkSourceWebCorecssSelectorCheckercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SelectorChecker.cpp        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -420,7 +420,7 @@
</span><span class="cx"> case CSSSelector::Set:
</span><span class="cx"> break;
</span><span class="cx"> case CSSSelector::Exact:
</span><del>- if (caseSensitive ? selectorValue != value : !equalIgnoringCase(selectorValue, value))
</del><ins>+ if (caseSensitive ? selectorValue != value : !equalIgnoringASCIICase(selectorValue, value))
</ins><span class="cx"> return false;
</span><span class="cx"> break;
</span><span class="cx"> case CSSSelector::List:
</span><span class="lines">@@ -450,18 +450,37 @@
</span><span class="cx"> return false;
</span><span class="cx"> break;
</span><span class="cx"> case CSSSelector::Begin:
</span><del>- if (!value.startsWith(selectorValue, caseSensitive) || selectorValue.isEmpty())
</del><ins>+ if (selectorValue.isEmpty())
</ins><span class="cx"> return false;
</span><ins>+ if (caseSensitive) {
+ if (!value.startsWith(selectorValue))
+ return false;
+ } else {
+ if (!value.startsWithIgnoringASCIICase(selectorValue))
+ return false;
+ }
</ins><span class="cx"> break;
</span><span class="cx"> case CSSSelector::End:
</span><del>- if (!value.endsWith(selectorValue, caseSensitive) || selectorValue.isEmpty())
</del><ins>+ if (selectorValue.isEmpty())
</ins><span class="cx"> return false;
</span><ins>+ if (caseSensitive) {
+ if (!value.endsWith(selectorValue))
+ return false;
+ } else {
+ if (!value.endsWithIgnoringASCIICase(selectorValue))
+ return false;
+ }
</ins><span class="cx"> break;
</span><span class="cx"> case CSSSelector::Hyphen:
</span><span class="cx"> if (value.length() < selectorValue.length())
</span><span class="cx"> return false;
</span><del>- if (!value.startsWith(selectorValue, caseSensitive))
- return false;
</del><ins>+ if (caseSensitive) {
+ if (!value.startsWith(selectorValue))
+ return false;
+ } else {
+ if (!value.startsWithIgnoringASCIICase(selectorValue))
+ return false;
+ }
</ins><span class="cx"> // It they start the same, check for exact match or following '-':
</span><span class="cx"> if (value.length() != selectorValue.length() && value[selectorValue.length()] != '-')
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -2803,10 +2803,12 @@
</span><span class="cx"> template<CaseSensitivity caseSensitivity>
</span><span class="cx"> static bool attributeValueBeginsWith(const Attribute* attribute, AtomicStringImpl* expectedString)
</span><span class="cx"> {
</span><ins>+ ASSERT(expectedString);
+
</ins><span class="cx"> AtomicStringImpl& valueImpl = *attribute->value().impl();
</span><span class="cx"> if (caseSensitivity == CaseSensitive)
</span><del>- return valueImpl.startsWith(expectedString);
- return valueImpl.startsWith(expectedString, false);
</del><ins>+ return valueImpl.startsWith(*expectedString);
+ return valueImpl.startsWithIgnoringASCIICase(*expectedString);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<CaseSensitivity caseSensitivity>
</span><span class="lines">@@ -2821,24 +2823,28 @@
</span><span class="cx"> template<CaseSensitivity caseSensitivity>
</span><span class="cx"> static bool attributeValueEndsWith(const Attribute* attribute, AtomicStringImpl* expectedString)
</span><span class="cx"> {
</span><ins>+ ASSERT(expectedString);
+
</ins><span class="cx"> AtomicStringImpl& valueImpl = *attribute->value().impl();
</span><span class="cx"> if (caseSensitivity == CaseSensitive)
</span><del>- return valueImpl.endsWith(expectedString);
- return valueImpl.endsWith(expectedString, false);
</del><ins>+ return valueImpl.endsWith(*expectedString);
+ return valueImpl.endsWithIgnoringASCIICase(*expectedString);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<CaseSensitivity caseSensitivity>
</span><span class="cx"> static bool attributeValueMatchHyphenRule(const Attribute* attribute, AtomicStringImpl* expectedString)
</span><span class="cx"> {
</span><ins>+ ASSERT(expectedString);
+
</ins><span class="cx"> AtomicStringImpl& valueImpl = *attribute->value().impl();
</span><span class="cx"> if (valueImpl.length() < expectedString->length())
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> bool valueStartsWithExpectedString;
</span><span class="cx"> if (caseSensitivity == CaseSensitive)
</span><del>- valueStartsWithExpectedString = valueImpl.startsWith(expectedString);
</del><ins>+ valueStartsWithExpectedString = valueImpl.startsWith(*expectedString);
</ins><span class="cx"> else
</span><del>- valueStartsWithExpectedString = valueImpl.startsWith(expectedString, false);
</del><ins>+ valueStartsWithExpectedString = valueImpl.startsWithIgnoringASCIICase(*expectedString);
</ins><span class="cx">
</span><span class="cx"> if (!valueStartsWithExpectedString)
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Tools/ChangeLog        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-03-15 Benjamin Poulain <benjamin@webkit.org>
+
+ CSS: fix the case-insensitive matching of the attribute selectors Begin, End and Hyphen
+ https://bugs.webkit.org/show_bug.cgi?id=142715
+
+ Reviewed by Brent Fulgham.
+
+ * TestWebKitAPI/Tests/WTF/StringImpl.cpp:
+ (TestWebKitAPI::TEST):
+
</ins><span class="cx"> 2015-03-15 Benjamin Poulain <bpoulain@apple.com>
</span><span class="cx">
</span><span class="cx"> Change the exact attribute matching to be ASCII case-insensitive
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFStringImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp (181524 => 181525)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp        2015-03-16 06:28:46 UTC (rev 181524)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp        2015-03-16 06:51:44 UTC (rev 181525)
</span><span class="lines">@@ -164,4 +164,152 @@
</span><span class="cx"> ASSERT_TRUE(equalIgnoringASCIICase(c.get(), d.get()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+TEST(WTF, StringImplStartsWithIgnoringASCIICaseBasic)
+{
+ RefPtr<StringImpl> reference = StringImpl::create(reinterpret_cast<const LChar*>("aBcéX"));
+ RefPtr<StringImpl> referenceEquivalent = StringImpl::create(reinterpret_cast<const LChar*>("AbCéx"));
+
+ // Identity.
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(reference.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*reference.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(referenceEquivalent.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*referenceEquivalent.get()));
+ ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(reference.get()));
+ ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(*reference.get()));
+ ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(referenceEquivalent.get()));
+ ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(*referenceEquivalent.get()));
+
+ // Proper prefixes.
+ RefPtr<StringImpl> aLower = StringImpl::createFromLiteral("a");
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(aLower.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*aLower.get()));
+ RefPtr<StringImpl> aUpper = StringImpl::createFromLiteral("A");
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(aUpper.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*aUpper.get()));
+
+ RefPtr<StringImpl> abcLower = StringImpl::createFromLiteral("abc");
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcLower.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcLower.get()));
+ RefPtr<StringImpl> abcUpper = StringImpl::createFromLiteral("ABC");
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcUpper.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcUpper.get()));
+
+ RefPtr<StringImpl> abcAccentLower = StringImpl::create(reinterpret_cast<const LChar*>("abcé"));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcAccentLower.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcAccentLower.get()));
+ RefPtr<StringImpl> abcAccentUpper = StringImpl::create(reinterpret_cast<const LChar*>("ABCé"));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcAccentUpper.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcAccentUpper.get()));
+
+ // Negative cases.
+ RefPtr<StringImpl> differentFirstChar = StringImpl::create(reinterpret_cast<const LChar*>("bBcéX"));
+ RefPtr<StringImpl> differentFirstCharProperPrefix = StringImpl::create(reinterpret_cast<const LChar*>("CBcé"));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(differentFirstChar.get()));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*differentFirstChar.get()));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(differentFirstCharProperPrefix.get()));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*differentFirstCharProperPrefix.get()));
+
+ RefPtr<StringImpl> uppercaseAccent = StringImpl::create(reinterpret_cast<const LChar*>("aBcÉX"));
+ RefPtr<StringImpl> uppercaseAccentProperPrefix = StringImpl::create(reinterpret_cast<const LChar*>("aBcÉX"));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(uppercaseAccent.get()));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*uppercaseAccent.get()));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(uppercaseAccentProperPrefix.get()));
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*uppercaseAccentProperPrefix.get()));
+}
+
+TEST(WTF, StringImplStartsWithIgnoringASCIICaseWithNull)
+{
+ RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
+ ASSERT_FALSE(reference->startsWithIgnoringASCIICase(nullptr));
+
+ RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
+ ASSERT_FALSE(empty->startsWithIgnoringASCIICase(nullptr));
+}
+
+TEST(WTF, StringImplStartsWithIgnoringASCIICaseWithEmpty)
+{
+ RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
+ RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(empty.get()));
+ ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*empty.get()));
+ ASSERT_TRUE(empty->startsWithIgnoringASCIICase(empty.get()));
+ ASSERT_TRUE(empty->startsWithIgnoringASCIICase(*empty.get()));
+ ASSERT_FALSE(empty->startsWithIgnoringASCIICase(reference.get()));
+ ASSERT_FALSE(empty->startsWithIgnoringASCIICase(*reference.get()));
+}
+
+TEST(WTF, StringImplEndsWithIgnoringASCIICaseBasic)
+{
+ RefPtr<StringImpl> reference = StringImpl::create(reinterpret_cast<const LChar*>("XÉCbA"));
+ RefPtr<StringImpl> referenceEquivalent = StringImpl::create(reinterpret_cast<const LChar*>("xÉcBa"));
+
+ // Identity.
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(reference.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*reference.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(referenceEquivalent.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*referenceEquivalent.get()));
+ ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(reference.get()));
+ ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(*reference.get()));
+ ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(referenceEquivalent.get()));
+ ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(*referenceEquivalent.get()));
+
+ // Proper suffixes.
+ RefPtr<StringImpl> aLower = StringImpl::createFromLiteral("a");
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(aLower.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*aLower.get()));
+ RefPtr<StringImpl> aUpper = StringImpl::createFromLiteral("a");
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(aUpper.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*aUpper.get()));
+
+ RefPtr<StringImpl> abcLower = StringImpl::createFromLiteral("cba");
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcLower.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcLower.get()));
+ RefPtr<StringImpl> abcUpper = StringImpl::createFromLiteral("CBA");
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcUpper.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcUpper.get()));
+
+ RefPtr<StringImpl> abcAccentLower = StringImpl::create(reinterpret_cast<const LChar*>("Écba"));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcAccentLower.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcAccentLower.get()));
+ RefPtr<StringImpl> abcAccentUpper = StringImpl::create(reinterpret_cast<const LChar*>("ÉCBA"));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcAccentUpper.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcAccentUpper.get()));
+
+ // Negative cases.
+ RefPtr<StringImpl> differentLastChar = StringImpl::create(reinterpret_cast<const LChar*>("XÉCbB"));
+ RefPtr<StringImpl> differentLastCharProperSuffix = StringImpl::create(reinterpret_cast<const LChar*>("ÉCbb"));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(differentLastChar.get()));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*differentLastChar.get()));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(differentLastCharProperSuffix.get()));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*differentLastCharProperSuffix.get()));
+
+ RefPtr<StringImpl> lowercaseAccent = StringImpl::create(reinterpret_cast<const LChar*>("aBcéX"));
+ RefPtr<StringImpl> loweraseAccentProperSuffix = StringImpl::create(reinterpret_cast<const LChar*>("aBcéX"));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(lowercaseAccent.get()));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*lowercaseAccent.get()));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(loweraseAccentProperSuffix.get()));
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*loweraseAccentProperSuffix.get()));
+}
+
+TEST(WTF, StringImplEndsWithIgnoringASCIICaseWithNull)
+{
+ RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
+ ASSERT_FALSE(reference->endsWithIgnoringASCIICase(nullptr));
+
+ RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
+ ASSERT_FALSE(empty->endsWithIgnoringASCIICase(nullptr));
+}
+
+TEST(WTF, StringImplEndsWithIgnoringASCIICaseWithEmpty)
+{
+ RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
+ RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(empty.get()));
+ ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*empty.get()));
+ ASSERT_TRUE(empty->endsWithIgnoringASCIICase(empty.get()));
+ ASSERT_TRUE(empty->endsWithIgnoringASCIICase(*empty.get()));
+ ASSERT_FALSE(empty->endsWithIgnoringASCIICase(reference.get()));
+ ASSERT_FALSE(empty->endsWithIgnoringASCIICase(*reference.get()));
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre>
</div>
</div>
</body>
</html>