Acid3 *-of-type test fails Test 40: expected: 0, got: 1 - part 9:1 This will need further reduction. function () { // test 40: :first-of-type, :last-of-type, :only-of-type, :nth-of-type, :nth-last-of-type var elements; var builder = function(doc) { elements = [ doc.createElement('p'), doc.createElement('div'), doc.createElement('div'), doc.createElement('p'), doc.createElement('p'), doc.createElement('p'), doc.createElement('div'), doc.createElement('address'), doc.createElement('div'), doc.createElement('div'), doc.createElement('div'), doc.createElement('p'), doc.createElement('div'), doc.createElement('p') ]; for (var i = 0; i < elements.length; i += 1) doc.body.appendChild(elements[i]); }; selectorTest(function (doc, add, expect) { builder(doc); var match = add(":first-of-type"); var values = [1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 1:" + i); }); selectorTest(function (doc, add, expect) { builder(doc); var match = add(":last-of-type"); var values = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 2:" + i); }); selectorTest(function (doc, add, expect) { builder(doc); var match = add(":only-of-type"); var values = [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 3:" + i); }); selectorTest(function (doc, add, expect) { builder(doc); var match = add(":nth-of-type(3n-1)"); var values = [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 4:" + i); }); selectorTest(function (doc, add, expect) { builder(doc); var match = add(":nth-of-type(3n+1)"); var values = [1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 5:" + i); }); selectorTest(function (doc, add, expect) { builder(doc); var match = add(":nth-last-of-type(2n)"); var values = [1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 6:" + i); }); selectorTest(function (doc, add, expect) { builder(doc); var match = add(":nth-last-of-type(-5n+3)"); var values; values = [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 7:" + i); doc.body.appendChild(doc.createElement('blockquote')); values = [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 8:" + i); doc.body.appendChild(doc.createElement('div')); values = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]; for (var i = 0; i < elements.length; i += 1) expect(elements[i], values[i] ? match : 0, "part 9:" + i); }); return 3; },
The bug is with the parseNth function. It incorrectly treats negative coefficients of n as positive. a = nth.substring(0, n).toInt(); The above is the correction. Instead of 1, n-1 it was supposed to be 0, n. I'll get a patch up once I've landed my other changes to CSSStyleSelector.cpp.
<rdar://problem/5733886>
There is more to this. Even fixing the coefficient to be properly parsed as negative, the matchNth function is also buggy.
Created attachment 19024 [details] Patch to fix the problem.
I was wrong. matchNth is fine. :)
Comment on attachment 19024 [details] Patch to fix the problem. Could have just added a "-" there... r=me
Fixed in r30116.