blob: c5c86ecef70c0e58310162d209f8de20d8fa32e6 [file] [log] [blame]
<!doctype html>
<html>
<head>
<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">
<testcaseA id="testcase1" type="foobar" attribute1="value1" class="bar baz bazoo" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase1"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase2" type="foobar" class="bar baz bazoo" attribute2="value2" attribute3="value3"></testcaseB>
<testcaseA id="testcase3" type="foobar" attribute1="value1" class="foo baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase2"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase4" type="foobar" attribute1="value1" class="foo bar bazoo"><span><span><span><span><span><innerTestCase id="innertestcase3"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase5" type="foobar" class="foo baz bazoo" attribute2="value2" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase4"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase6" type="foobar" attribute1="value1" class="foo bar baz" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase5"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase7" type="foobar" attribute1="value1" class="bar baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase6"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase8" type="foobar" attribute1="value1" class="foo baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase7"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase9" type="foobar" class="foo bar bazoo" attribute2="value2" attribute3="value3"></testcaseA>
<testcaseB id="testcase10" type="foobar" attribute1="value1" class="foo bar bazoo" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase8"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase11" type="foobar" attribute1="value1" class="foo bar baz"><span><span><span><span><span><innerTestCase id="innertestcase9"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase12" type="foobar" attribute1="value1" class="bar baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase10"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase13" type="foobar" attribute1="value1" class="foo baz bazoo" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase11"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase14" type="foobar" class="foo bar baz" attribute2="value2"><span><span><span><span><span><innerTestCase id="innertestcase12"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase15" type="foobar" attribute1="value1" class="foo bar bazoo"><span><span><span><span><span><innerTestCase id="innertestcase13"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase16" type="foobar" attribute1="value1" class="foo bar baz" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase14"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase17" type="foobar" attribute1="value1" class="bar baz bazoo" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase15"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase18" type="foobar" attribute1="value1" class="foo baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase16"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase19" type="foobar" attribute1="value1" class="foo bar bazoo"><span><span><span><span><span><innerTestCase id="innertestcase17"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase20" type="foobar" class="bar baz bazoo" attribute2="value2" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase18"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase21" type="foobar" attribute1="value1" class="foo bar baz" attribute3="value3"></testcaseA>
<testcaseB id="testcase22" type="foobar" attribute1="value1" class="bar baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase19"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase23" type="foobar" attribute1="value1" class="foo baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase20"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase24" type="foobar" attribute1="value1" class="foo bar bazoo" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase21"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase25" type="foobar" attribute1="value1" class="foo bar baz" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase22"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase26" type="foobar" attribute1="value1" class="bar baz bazoo"><span><span><span><span><span><innerTestCase id="innertestcase23"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase27" type="foobar" class="foo baz bazoo" attribute2="value2"></testcaseA>
<testcaseB id="testcase28" type="foobar" attribute1="value1" class="foo baz bazoo" attribute3="value3"><span><span><span><span><span><innerTestCase id="innertestcase24"></innerTestCase></span></span></span></span></span></testcaseB>
<testcaseA id="testcase29" type="foobar" attribute1="value1" class="foo bar bazoo"><span><span><span><span><span><innerTestCase id="innertestcase25"></innerTestCase></span></span></span></span></span></testcaseA>
<testcaseB id="testcase30" type="foobar" attribute1="value1" class="foo bar baz"><span><span><span><span><span><innerTestCase id="innertestcase26"></innerTestCase></span></span></span></span></span></testcaseB>
</div>
</body>
<script>
description('Check various cases of register pressure inside ":nth-last-child(An+B of selectorList)".');
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", 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(allTestCases[i].id) >= 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("");
}
// First, test various case of simple register pressure.
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class])", ["testcase1", "testcase4", "testcase7", "testcase10", "testcase12", "testcase15", "testcase17", "testcase19", "testcase22", "testcase24", "testcase26", "testcase29"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][type])", ["testcase1", "testcase4", "testcase7", "testcase10", "testcase12", "testcase15", "testcase17", "testcase19", "testcase22", "testcase24", "testcase26", "testcase29"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][type=foobar])", ["testcase1", "testcase4", "testcase7", "testcase10", "testcase12", "testcase15", "testcase17", "testcase19", "testcase22", "testcase24", "testcase26", "testcase29"]);
testSelector(":nth-last-child(2n of testcaseA:nth-last-child(2n+1))", []);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][type=foobar]:nth-last-child(2n+1))", ["testcase4", "testcase8", "testcase12", "testcase18", "testcase24", "testcase28"]);
// Next, let's check those are handed correctly if combined in a selector list.
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class])", ["testcase1", "testcase4", "testcase7", "testcase10", "testcase12", "testcase15", "testcase17", "testcase19", "testcase22", "testcase24", "testcase26", "testcase29"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][type])", ["testcase1", "testcase4", "testcase7", "testcase10", "testcase12", "testcase15", "testcase17", "testcase19", "testcase22", "testcase24", "testcase26", "testcase29"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][type=foobar])", ["testcase1", "testcase4", "testcase7", "testcase10", "testcase12", "testcase15", "testcase17", "testcase19", "testcase22", "testcase24", "testcase26", "testcase29"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), testcaseA:nth-last-child(2n+1))", []);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][type=foobar]:nth-last-child(2n+1))", ["testcase4", "testcase8", "testcase12", "testcase18", "testcase24", "testcase28"]);
// Let's add even more register pressure, let's add a backtracking chain.
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class]) > * > * innerTestCase", ["innertestcase1", "innertestcase3", "innertestcase6", "innertestcase8", "innertestcase10", "innertestcase13", "innertestcase15", "innertestcase17", "innertestcase19", "innertestcase21", "innertestcase23", "innertestcase25"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class]) + * + * ~ * > * > * innerTestCase", ["innertestcase3", "innertestcase4", "innertestcase5", "innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class][type]) > * > * innerTestCase", ["innertestcase1", "innertestcase3", "innertestcase6", "innertestcase8", "innertestcase10", "innertestcase13", "innertestcase15", "innertestcase17", "innertestcase19", "innertestcase21", "innertestcase23", "innertestcase25"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class][type]) + * + * ~ * > * > * innerTestCase", ["innertestcase3", "innertestcase4", "innertestcase5", "innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class][type=foobar]) > * > * innerTestCase", ["innertestcase1", "innertestcase3", "innertestcase6", "innertestcase8", "innertestcase10", "innertestcase13", "innertestcase15", "innertestcase17", "innertestcase19", "innertestcase21", "innertestcase23", "innertestcase25"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][class][type=foobar]) + * + * ~ * > * > * innerTestCase", ["innertestcase3", "innertestcase4", "innertestcase5", "innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of testcaseA:nth-last-child(2n+1)) > * > * innerTestCase", []);
testSelector(":nth-last-child(2n of testcaseA:nth-last-child(2n+1)) + * + * ~ * > * > * innerTestCase", []);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][type=foobar]:nth-last-child(2n+1)) > * > * innerTestCase", ["innertestcase3", "innertestcase7", "innertestcase10", "innertestcase16", "innertestcase21", "innertestcase24"]);
testSelector(":nth-last-child(2n of [id^=testcase][attribute1=value1][type=foobar]:nth-last-child(2n+1)) + * + * ~ * > * > * innerTestCase", ["innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class]) > * > * innerTestCase", ["innertestcase1", "innertestcase3", "innertestcase6", "innertestcase8", "innertestcase10", "innertestcase13", "innertestcase15", "innertestcase17", "innertestcase19", "innertestcase21", "innertestcase23", "innertestcase25"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class]) + * + * ~ * > * > * innerTestCase", ["innertestcase3", "innertestcase4", "innertestcase5", "innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class][type]) > * > * innerTestCase", ["innertestcase1", "innertestcase3", "innertestcase6", "innertestcase8", "innertestcase10", "innertestcase13", "innertestcase15", "innertestcase17", "innertestcase19", "innertestcase21", "innertestcase23", "innertestcase25"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class][type]) + * + * ~ * > * > * innerTestCase", ["innertestcase3", "innertestcase4", "innertestcase5", "innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class][type=foobar]) > * > * innerTestCase", ["innertestcase1", "innertestcase3", "innertestcase6", "innertestcase8", "innertestcase10", "innertestcase13", "innertestcase15", "innertestcase17", "innertestcase19", "innertestcase21", "innertestcase23", "innertestcase25"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][class][type=foobar]) + * + * ~ * > * > * innerTestCase", ["innertestcase3", "innertestcase4", "innertestcase5", "innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), testcaseA:nth-last-child(2n+1)) > * > * innerTestCase", []);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), testcaseA:nth-last-child(2n+1)) + * + * ~ * > * > * innerTestCase", []);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][type=foobar]:nth-last-child(2n+1)) > * > * innerTestCase", ["innertestcase3", "innertestcase7", "innertestcase10", "innertestcase16", "innertestcase21", "innertestcase24"]);
testSelector(":nth-last-child(2n of some, noise, those.selectors, are#not, matched.in#this:not(.tree), [id^=testcase][attribute1=value1][type=foobar]:nth-last-child(2n+1)) + * + * ~ * > * > * innerTestCase", ["innertestcase6", "innertestcase7", "innertestcase8", "innertestcase9", "innertestcase10", "innertestcase11", "innertestcase12", "innertestcase13", "innertestcase14", "innertestcase15", "innertestcase16", "innertestcase17", "innertestcase18", "innertestcase19", "innertestcase20", "innertestcase21", "innertestcase22", "innertestcase23", "innertestcase24", "innertestcase25", "innertestcase26"]);
</script>
<script src="../../resources/js-test-post.js"></script>
</html>