Diff
Modified: trunk/LayoutTests/ChangeLog (176622 => 176623)
--- trunk/LayoutTests/ChangeLog 2014-12-02 02:21:16 UTC (rev 176622)
+++ trunk/LayoutTests/ChangeLog 2014-12-02 02:29:53 UTC (rev 176623)
@@ -1,3 +1,28 @@
+2014-12-01 Benjamin Poulain <[email protected]>
+
+ Add the dynamic specificity of the selector list argument when matching :nth-child() and :nth-last-child()
+ https://bugs.webkit.org/show_bug.cgi?id=139001
+
+ Reviewed by Andreas Kling.
+
+ * fast/css/nth-child-specificity-1-expected.html: Added.
+ * fast/css/nth-child-specificity-1.html: Added.
+ * fast/css/nth-child-specificity-2-expected.html: Added.
+ * fast/css/nth-child-specificity-2.html: Added.
+ * fast/css/nth-child-specificity-3-expected.html: Added.
+ * fast/css/nth-child-specificity-3.html: Added.
+ * fast/css/nth-child-specificity-4-expected.html: Added.
+ * fast/css/nth-child-specificity-4.html: Added.
+ * fast/css/nth-last-child-specificity-1-expected.html: Added.
+ * fast/css/nth-last-child-specificity-1.html: Added.
+ * fast/css/nth-last-child-specificity-2-expected.html: Added.
+ * fast/css/nth-last-child-specificity-2.html: Added.
+ * fast/css/nth-last-child-specificity-3-expected.html: Added.
+ * fast/css/nth-last-child-specificity-3.html: Added.
+ * fast/css/nth-last-child-specificity-4-expected.html: Added.
+ * fast/css/nth-last-child-specificity-4.html: Added.
+
+
2014-12-01 Zalan Bujtas <[email protected]>
Twitter avatar moves when hovering/unhovering the "follow" button.
Added: trunk/LayoutTests/fast/css/nth-child-specificity-1-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-1-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-1-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,17 @@
+<!doctype html>
+<html>
+<body>
+ <p>This test the specificity of :nth-child() with static specificity. The test passes if the text "target" is displayed white on green background. There should be 2 red rects on each side.</p>
+ <div>
+ <foo style="color: red; background-color: red;">Not target</foo>
+ <padding></padding>
+ <bar style="color: red; background-color: red;">Not target</bar>
+ <more-padding></more-padding>
+ <target style="color: white; background-color: green;">Target</target>
+ <more-padding></more-padding>
+ <foo style="color: red; background-color: red;">Not target</foo>
+ <padding></padding>
+ <bar style="color: red; background-color: red;">Not target</bar>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css/nth-child-specificity-1.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-1.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-1.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The following 3 rules should all have the same specificity when matching <target>. They should be be applied in order. */
+ foo:nth-child(n), bar:nth-child(n), target:nth-child(n) {
+ background-color: red;
+ color: red;
+ }
+ :nth-child(3n of foo, bar, target) {
+ background-color: green;
+ color: blue;
+ }
+ foo.target, bar.target, target.target {
+ color: white;
+ }
+ * {
+ background-color: white;
+ color: black;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with static specificity. The test passes if the text "target" is displayed white on green background. There should be 2 red rects on each side.</p>
+ <div>
+ <foo>Not target</foo>
+ <padding></padding>
+ <bar>Not target</bar>
+ <more-padding></more-padding>
+ <target class="target">Target</target>
+ <more-padding></more-padding>
+ <foo>Not target</foo>
+ <padding></padding>
+ <bar>Not target</bar>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css/nth-child-specificity-2-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-2-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-2-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with dynamic specificity. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target style="background-color: white; color: black; border: none;">Black text on white background.</target>
+ <target style="background-color: red; color: white; border: 5px solid purple;">White text on red background with a purple border.</target>
+ <target style="background-color: green; color: red; border: none;">Red text on green background.</target>
+ <target style="background-color: green; color: white; border: 5px solid purple;">White text on green background with a purple border.</target>
+ <target style="background-color: white; color: black; border: 5px solid blue;">Black text on white background with a blue border.</target>
+ <target style="background-color: red; color: white; border: 5px solid purple;">White text on red background with a purple border.</target>
+ <target style="background-color: green; color: red; border: 5px solid blue;">Red text on green background with a blue border.</target>
+ <target style="background-color: red; color: white; border: 5px solid purple;">White text on red background with a purple border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-child-specificity-2.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-2.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-2.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The specifity varies with the element being matched. */
+ :nth-child(even of .foo, #bar, target) {
+ background-color: red;
+ color: white;
+ border: 5px solid purple;
+ }
+
+ /* (0, 1, 1) */
+ target.foo {
+ color: red;
+ }
+
+ /* (0, 2, 0) */
+ .foo.foo {
+ background-color: green;
+ }
+ /* (1, 0, 1) */
+ target#bar {
+ border: 5px solid blue;
+ }
+
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with dynamic specificity. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text on white background.</target>
+ <target>White text on red background with a purple border.</target>
+ <target class="foo">Red text on green background.</target>
+ <target class="foo">White text on green background with a purple border.</target>
+ <target id="bar">Black text on white background with a blue border.</target>
+ <target id="bar">White text on red background with a purple border.</target>
+ <target class="foo" id="bar">Red text on green background with a blue border.</target>
+ <target class="foo" id="bar">White text on red background with a purple border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-child-specificity-3-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-3-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-3-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with dynamic specificity of compound selectors. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target style="color:red; border: 5px solid black;">Red text with black border.</target>
+ <target style="color:white; background-color:red; border: 5px solid black;">White text on red background with black border.</target>
+ <target style="border: 5px solid blue;">Black text with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ <target style="color:red; background-color:green; border: 5px solid blue;">Red text on green background with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-child-specificity-3.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-3.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-3.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The specifity varies with the element being matched. */
+ :nth-child(even of target.foo, .foo#bar, target.foo#bar, target#bar) {
+ background-color: red;
+ color: white;
+ border: 5px solid purple;
+ }
+
+ /* (0, 1, 1) */
+ target.foo {
+ color: red;
+ }
+ /* (0, 2, 1) */
+ target.foo.foo {
+ border: 5px solid black;
+ }
+
+ /* (1, 1, 0) */
+ .foo#bar {
+ background-color: green;
+ }
+ /* (1, 0, 1) */
+ target#bar {
+ border: 5px solid blue;
+ }
+
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with dynamic specificity of compound selectors. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target class="foo">Red text with black border.</target>
+ <target class="foo">White text on red background with black border.</target>
+ <target id="bar">Black text with blue border.</target>
+ <target id="bar">White text on red background with purple border.</target>
+ <target class="foo" id="bar">Red text on green background with blue border.</target>
+ <target class="foo" id="bar">White text on red background with purple border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-child-specificity-4-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-4-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-4-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with dynamic specificity of compound selectors. In this case, we verify the matching of siblings does not affect the specificity of the current element. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target style="border: 5px solid blue;">Black text with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid black;">White text on red background with black border.</target>
+ <target style="color:red; background-color:green; border: 5px solid blue;">Red text on green background with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ <target style="color:red; border: 5px solid black;">Red text with black border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-child-specificity-4.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-child-specificity-4.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-child-specificity-4.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The specifity varies with the element being matched. */
+ :nth-child(even of target.foo, .foo#bar, target.foo#bar, target#bar) {
+ background-color: red;
+ color: white;
+ border: 5px solid purple;
+ }
+
+ /* (0, 1, 1) */
+ target.foo {
+ color: red;
+ }
+ /* (0, 2, 1) */
+ target.foo.foo {
+ border: 5px solid black;
+ }
+
+ /* (1, 1, 0) */
+ .foo#bar {
+ background-color: green;
+ }
+ /* (1, 0, 1) */
+ target#bar {
+ border: 5px solid blue;
+ }
+
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-child() with dynamic specificity of compound selectors. In this case, we verify the matching of siblings does not affect the specificity of the current element. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target id="bar">Black text with blue border.</target>
+ <target class="foo">White text on red background with black border.</target>
+ <target class="foo" id="bar">Red text on green background with blue border.</target>
+ <target id="bar">White text on red background with purple border.</target>
+ <target class="foo">Red text with black border.</target>
+ <target class="foo" id="bar">White text on red background with purple border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-1-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-1-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-1-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,17 @@
+<!doctype html>
+<html>
+<body>
+ <p>This test the specificity of :nth-last-child() with static specificity. The test passes if the text "target" is displayed white on green background. There should be 2 red rects on each side.</p>
+ <div>
+ <foo style="color: red; background-color: red;">Not target</foo>
+ <padding></padding>
+ <bar style="color: red; background-color: red;">Not target</bar>
+ <more-padding></more-padding>
+ <target style="color: white; background-color: green;">Target</target>
+ <more-padding></more-padding>
+ <foo style="color: red; background-color: red;">Not target</foo>
+ <padding></padding>
+ <bar style="color: red; background-color: red;">Not target</bar>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-1.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-1.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-1.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The following 3 rules should all have the same specificity when matching <target>. They should be be applied in order. */
+ foo:nth-last-child(n), bar:nth-last-child(n), target:nth-last-child(n) {
+ background-color: red;
+ color: red;
+ }
+ :nth-last-child(3n of foo, bar, target) {
+ background-color: green;
+ color: blue;
+ }
+ foo.target, bar.target, target.target {
+ color: white;
+ }
+ * {
+ background-color: white;
+ color: black;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with static specificity. The test passes if the text "target" is displayed white on green background. There should be 2 red rects on each side.</p>
+ <div>
+ <foo>Not target</foo>
+ <padding></padding>
+ <bar>Not target</bar>
+ <more-padding></more-padding>
+ <target class="target">Target</target>
+ <more-padding></more-padding>
+ <foo>Not target</foo>
+ <padding></padding>
+ <bar>Not target</bar>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-2-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-2-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-2-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with dynamic specificity. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target style="background-color: red; color: white; border: 5px solid purple;">White text on red background with a purple border.</target>
+ <target style="background-color: white; color: black; border: none;">Black text on white background.</target>
+ <target style="background-color: green; color: white; border: 5px solid purple;">White text on green background with a purple border.</target>
+ <target style="background-color: green; color: red; border: none;">Red text on green background.</target>
+ <target style="background-color: red; color: white; border: 5px solid purple;">White text on red background with a purple border.</target>
+ <target style="background-color: white; color: black; border: 5px solid blue;">Black text on white background with a blue border.</target>
+ <target style="background-color: red; color: white; border: 5px solid purple;">White text on red background with a purple border.</target>
+ <target style="background-color: green; color: red; border: 5px solid blue;">Red text on green background with a blue border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-2.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-2.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-2.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The specifity varies with the element being matched. */
+ :nth-last-child(even of .foo, #bar, target) {
+ background-color: red;
+ color: white;
+ border: 5px solid purple;
+ }
+
+ /* (0, 1, 1) */
+ target.foo {
+ color: red;
+ }
+
+ /* (0, 2, 0) */
+ .foo.foo {
+ background-color: green;
+ }
+ /* (1, 0, 1) */
+ target#bar {
+ border: 5px solid blue;
+ }
+
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with dynamic specificity. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>White text on red background with a purple border.</target>
+ <target>Black text on white background.</target>
+ <target class="foo">White text on green background with a purple border.</target>
+ <target class="foo">Red text on green background.</target>
+ <target id="bar">White text on red background with a purple border.</target>
+ <target id="bar">Black text on white background with a blue border.</target>
+ <target class="foo" id="bar">White text on red background with a purple border.</target>
+ <target class="foo" id="bar">Red text on green background with a blue border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-3-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-3-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-3-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with dynamic specificity of compound selectors. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target style="color:white; background-color:red; border: 5px solid black;">White text on red background with black border.</target>
+ <target style="color:red; border: 5px solid black;">Red text with black border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ <target style="border: 5px solid blue;">Black text with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ <target style="color:red; background-color:green; border: 5px solid blue;">Red text on green background with blue border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-3.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-3.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-3.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The specifity varies with the element being matched. */
+ :nth-last-child(even of target.foo, .foo#bar, target.foo#bar, target#bar) {
+ background-color: red;
+ color: white;
+ border: 5px solid purple;
+ }
+
+ /* (0, 1, 1) */
+ target.foo {
+ color: red;
+ }
+ /* (0, 2, 1) */
+ target.foo.foo {
+ border: 5px solid black;
+ }
+
+ /* (1, 1, 0) */
+ .foo#bar {
+ background-color: green;
+ }
+ /* (1, 0, 1) */
+ target#bar {
+ border: 5px solid blue;
+ }
+
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with dynamic specificity of compound selectors. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target class="foo">White text on red background with black border.</target>
+ <target class="foo">Red text with black border.</target>
+ <target id="bar">White text on red background with purple border.</target>
+ <target id="bar">Black text with blue border.</target>
+ <target class="foo" id="bar">White text on red background with purple border.</target>
+ <target class="foo" id="bar">Red text on green background with blue border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-4-expected.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-4-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-4-expected.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with dynamic specificity of compound selectors. In this case, we verify the matching of siblings does not affect the specificity of the current element. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target style="color:white; background-color:red; border: 5px solid black;">White text on red background with black border.</target>
+ <target style="border: 5px solid blue;">Black text with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ <target style="color:red; background-color:green; border: 5px solid blue;">Red text on green background with blue border.</target>
+ <target style="color:white; background-color:red; border: 5px solid purple;">White text on red background with purple border.</target>
+ <target style="color:red; border: 5px solid black;">Red text with black border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/css/nth-last-child-specificity-4.html (0 => 176623)
--- trunk/LayoutTests/fast/css/nth-last-child-specificity-4.html (rev 0)
+++ trunk/LayoutTests/fast/css/nth-last-child-specificity-4.html 2014-12-02 02:29:53 UTC (rev 176623)
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+<head>
+<style>
+ /* The specifity varies with the element being matched. */
+ :nth-last-child(even of target.foo, .foo#bar, target.foo#bar, target#bar) {
+ background-color: red;
+ color: white;
+ border: 5px solid purple;
+ }
+
+ /* (0, 1, 1) */
+ target.foo {
+ color: red;
+ }
+ /* (0, 2, 1) */
+ target.foo.foo {
+ border: 5px solid black;
+ }
+
+ /* (1, 1, 0) */
+ .foo#bar {
+ background-color: green;
+ }
+ /* (1, 0, 1) */
+ target#bar {
+ border: 5px solid blue;
+ }
+
+ target {
+ display: block;
+ margin: 2px;
+ }
+</style>
+</head>
+<body>
+ <p>This test the specificity of :nth-last-child() with dynamic specificity of compound selectors. In this case, we verify the matching of siblings does not affect the specificity of the current element. If the test pass, the style of each line should match its text description.</p>
+ <div>
+ <target>Black text.</target>
+ <target>Black text.</target>
+ <target class="foo">White text on red background with black border.</target>
+ <target id="bar">Black text with blue border.</target>
+ <target id="bar">White text on red background with purple border.</target>
+ <target class="foo" id="bar">Red text on green background with blue border.</target>
+ <target class="foo" id="bar">White text on red background with purple border.</target>
+ <target class="foo">Red text with black border.</target>
+ </div>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (176622 => 176623)
--- trunk/Source/WebCore/ChangeLog 2014-12-02 02:21:16 UTC (rev 176622)
+++ trunk/Source/WebCore/ChangeLog 2014-12-02 02:29:53 UTC (rev 176623)
@@ -1,3 +1,35 @@
+2014-12-01 Benjamin Poulain <[email protected]>
+
+ Add the dynamic specificity of the selector list argument when matching :nth-child() and :nth-last-child()
+ https://bugs.webkit.org/show_bug.cgi?id=139001
+
+ Reviewed by Andreas Kling.
+
+ When matching :nth-child(An+B of selector list) or :nth-last-child(An+B of selector list),
+ we were previously ignoring the arguments.
+
+ That behavior seems to be confusing for users. We made the proposal to include the selector list
+ like when using :matches():
+ http://lists.w3.org/Archives/Public/www-style/2014Oct/0533.html
+ David Baron also agrees with this behavior:
+ http://lists.w3.org/Archives/Public/www-style/2014Oct/0534.html
+
+ This patch adds the specificity computation.
+
+ Tests: fast/css/nth-child-specificity-1.html
+ fast/css/nth-child-specificity-2.html
+ fast/css/nth-last-child-specificity-1.html
+ fast/css/nth-last-child-specificity-2.html
+
+ * css/CSSSelector.cpp:
+ (WebCore::simpleSelectorFunctionalPseudoClassStaticSpecificity):
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::checkOne):
+ (WebCore::SelectorChecker::matchSelectorList):
+ * css/SelectorChecker.h:
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::addPseudoClassType):
+
2014-12-01 Chris Dumez <[email protected]>
Move 'text-shadow' / 'box-shadow' / '-webkit-box-shadow' to the new StyleBuilder
Modified: trunk/Source/WebCore/css/CSSSelector.cpp (176622 => 176623)
--- trunk/Source/WebCore/css/CSSSelector.cpp 2014-12-02 02:21:16 UTC (rev 176622)
+++ trunk/Source/WebCore/css/CSSSelector.cpp 2014-12-02 02:29:53 UTC (rev 176623)
@@ -131,10 +131,16 @@
static unsigned simpleSelectorFunctionalPseudoClassStaticSpecificity(const CSSSelector& simpleSelector, bool& ok)
{
if (simpleSelector.match() == CSSSelector::PseudoClass) {
- if (simpleSelector.pseudoClassType() == CSSSelector::PseudoClassMatches) {
- const CSSSelectorList& selectorList = *simpleSelector.selectorList();
- const CSSSelector& firstSubselector = *selectorList.first();
+ CSSSelector::PseudoClassType pseudoClassType = simpleSelector.pseudoClassType();
+ if (pseudoClassType == CSSSelector::PseudoClassMatches || pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild) {
+ const CSSSelectorList* selectorList = simpleSelector.selectorList();
+ if (!selectorList) {
+ ASSERT_WITH_MESSAGE(pseudoClassType != CSSSelector::PseudoClassMatches, ":matches() should never be created without a valid selector list.");
+ return 0;
+ }
+ const CSSSelector& firstSubselector = *selectorList->first();
+
unsigned initialSpecificity = staticSpecificityInternal(firstSubselector, ok);
if (!ok)
return 0;
Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (176622 => 176623)
--- trunk/Source/WebCore/css/SelectorChecker.cpp 2014-12-02 02:21:16 UTC (rev 176622)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp 2014-12-02 02:29:53 UTC (rev 176623)
@@ -744,7 +744,10 @@
if (element->parentElement()) {
#if ENABLE(CSS_SELECTORS_LEVEL4)
if (const CSSSelectorList* selectorList = selector->selectorList()) {
- if (!matchSelectorList(context, *element, *selectorList))
+ unsigned selectorListSpecificity;
+ if (matchSelectorList(context, *element, *selectorList, selectorListSpecificity))
+ specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity);
+ else
return false;
}
#endif
@@ -759,7 +762,8 @@
if (context.resolvingMode == Mode::ResolvingStyle)
sibling->setAffectsNextSiblingElementStyle();
- if (matchSelectorList(context, *sibling, *selectorList))
+ unsigned ignoredSpecificity;
+ if (matchSelectorList(context, *sibling, *selectorList, ignoredSpecificity))
++count;
}
} else
@@ -796,7 +800,10 @@
#if ENABLE(CSS_SELECTORS_LEVEL4)
if (const CSSSelectorList* selectorList = selector->selectorList()) {
- if (!matchSelectorList(context, *element, *selectorList))
+ unsigned selectorListSpecificity;
+ if (matchSelectorList(context, *element, *selectorList, selectorListSpecificity))
+ specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity);
+ else
return false;
if (context.resolvingMode == Mode::ResolvingStyle) {
@@ -812,7 +819,8 @@
#if ENABLE(CSS_SELECTORS_LEVEL4)
if (const CSSSelectorList* selectorList = selector->selectorList()) {
for (Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(sibling)) {
- if (matchSelectorList(context, *sibling, *selectorList))
+ unsigned ignoredSpecificity;
+ if (matchSelectorList(context, *sibling, *selectorList, ignoredSpecificity))
++count;
}
} else
@@ -1029,8 +1037,11 @@
return true;
}
-bool SelectorChecker::matchSelectorList(const CheckingContextWithStatus& baseContext, Element& element, const CSSSelectorList& selectorList) const
+bool SelectorChecker::matchSelectorList(const CheckingContextWithStatus& baseContext, Element& element, const CSSSelectorList& selectorList, unsigned& specificity) const
{
+ specificity = 0;
+ bool hasMatchedAnything = false;
+
for (const CSSSelector* subselector = selectorList.first(); subselector; subselector = CSSSelectorList::next(subselector)) {
CheckingContextWithStatus subcontext(baseContext);
subcontext.element = &element;
@@ -1042,10 +1053,12 @@
unsigned localSpecificity = 0;
if (matchRecursively(subcontext, ignoreDynamicPseudo, localSpecificity).match == Match::SelectorMatches) {
ASSERT(!ignoreDynamicPseudo);
- return true;
+
+ hasMatchedAnything = true;
+ specificity = std::max(specificity, localSpecificity);
}
}
- return false;
+ return hasMatchedAnything;
}
bool SelectorChecker::checkScrollbarPseudoClass(const CheckingContextWithStatus& context, const CSSSelector* selector) const
Modified: trunk/Source/WebCore/css/SelectorChecker.h (176622 => 176623)
--- trunk/Source/WebCore/css/SelectorChecker.h 2014-12-02 02:21:16 UTC (rev 176622)
+++ trunk/Source/WebCore/css/SelectorChecker.h 2014-12-02 02:29:53 UTC (rev 176623)
@@ -109,7 +109,7 @@
private:
MatchResult matchRecursively(const CheckingContextWithStatus&, PseudoIdSet&, unsigned& specificity) const;
bool checkOne(const CheckingContextWithStatus&, PseudoIdSet&, MatchType&, unsigned& specificity) const;
- bool matchSelectorList(const CheckingContextWithStatus&, Element&, const CSSSelectorList&) const;
+ bool matchSelectorList(const CheckingContextWithStatus&, Element&, const CSSSelectorList&, unsigned& specificity) const;
bool checkScrollbarPseudoClass(const CheckingContextWithStatus&, const CSSSelector*) const;
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (176622 => 176623)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2014-12-02 02:21:16 UTC (rev 176622)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2014-12-02 02:29:53 UTC (rev 176623)
@@ -636,6 +636,9 @@
if (selectorContext != SelectorContext::QuerySelector)
globalFunctionType = FunctionType::SelectorCheckerWithCheckingContext;
+ unsigned firstFragmentListSpecificity = 0;
+ bool firstFragmentListSpecificitySet = false;
+
for (const CSSSelector* subselector = selectorList->first(); subselector; subselector = CSSSelectorList::next(subselector)) {
SelectorFragmentList selectorFragments;
VisitedMode ignoreVisitedMode = VisitedMode::None;
@@ -651,8 +654,19 @@
case FunctionType::CannotCompile:
return FunctionType::CannotCompile;
}
+
+ if (firstFragmentListSpecificitySet) {
+ // The CSS JIT does not handle dynamic specificity yet.
+ if (selectorContext == SelectorContext::RuleCollector && selectorFragments.staticSpecificity != firstFragmentListSpecificity)
+ return FunctionType::CannotCompile;
+ } else {
+ firstFragmentListSpecificitySet = true;
+ firstFragmentListSpecificity = selectorFragments.staticSpecificity;
+ }
+
globalFunctionType = mostRestrictiveFunctionType(globalFunctionType, functionType);
}
+ internalSpecificity = firstFragmentListSpecificity;
fragment.nthChildOfFilters.append(nthChildOfSelectorInfo);
return globalFunctionType;
}