Implemented CSS Selectors 4 :matches()

Design doc: https://docs.google.com/document/d/1dfbT1mnIuwm9HTyUWDe5PS5FygZgMuQGsyw49oxBcXk/edit?usp=sharing

Intent to implement: https://groups.google.com/a/chromium.org/d/msg/blink-dev/kqD_G4sxfZE/6CJM01X2BwAJ

Bug: 568705
Change-Id: I57e619e462f8323496aad477c50c45f9537003c4
Reviewed-on: https://chromium-review.googlesource.com/879982
Reviewed-by: nainar <nainar@chromium.org>
Reviewed-by: Eric Willigers <ericwilligers@chromium.org>
Commit-Queue: Victoria Su <victoriaytsu@google.com>
Cr-Commit-Position: refs/heads/master@{#533969}
diff --git a/css/selectors/invalidation/matches.html b/css/selectors/invalidation/matches.html
index 6fd5b1f..ae5531a 100644
--- a/css/selectors/invalidation/matches.html
+++ b/css/selectors/invalidation/matches.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
   <head>
-    <title>CSS Selectors Invalidation: :any-link</title>
+    <title>CSS Selectors Invalidation: :matches()</title>
     <link rel="author" title="Victoria Su" href="mailto:victoriaytsu@google.com">
     <link rel="help" href="https://drafts.csswg.org/selectors-4/#matches">
     <meta name="assert" content="This tests that the :matches() selector is effective">
@@ -9,15 +9,38 @@
     <script src="/resources/testharnessreport.js"></script>
     <style>
       .b {
-        color: rgb(255, 255, 0); /* yellow */
+        color: yellow;
       }
       /*Simple selector arguments */
       .a :matches(.b, .c) {
-        color: rgb(255, 0, 0); /* red */
+        color: red;
       }
       /*Compound selector arguments */
       .a :matches(.c#d, .e) {
-        color: rgb(0, 255, 0); /* green */
+        color: green;
+      }
+      /* Complex selector arguments */
+      .a .g>.b {
+        color: black;
+      }
+      .a :matches(.e+.f, .g>.b, .h) {
+        color: blue;
+      }
+      .g>.b {
+        color: black;
+      }
+      .a .h {
+        color: black;
+      }
+      /* Nested */
+      .a+.c>.e {
+        color: black;
+      }
+      .a+:matches(.b+.f, :matches(.c>.e, .g)) {
+        color: red;
+      }
+      .c>.e {
+        color: black;
       }
     </style>
   </head>
@@ -38,29 +61,73 @@
       <div class="f" id="f1">
         Blue
       </div>
+      <div class="g">
+        <div class="b" id="b2">
+          Blue
+          <div class="b" id="b3">
+            Red
+          </div>
+        </div>
+      </div>
+      <div class="h" id="h1">
+        Black
+      </div>
+    </div>
+    <div class="c" id="c2">
+      <div class="e" id="e2">
+        Red
+      </div>
     </div>
     <script>
       document.body.offsetTop;
 
+      var black = "rgb(0, 0, 0)";
+      var blue = "rgb(0, 0, 255)";
+      var green = "rgb(0, 128, 0)";
+      var red = "rgb(255, 0, 0)";
+      var yellow = "rgb(255, 255, 0)";
+
       test(() => {
-        assert_equals(getComputedStyle(b1).color, "rgb(255, 255, 0)");
-        assert_equals(getComputedStyle(c1).color, "rgb(0, 0, 0)");
-        assert_equals(getComputedStyle(d).color, "rgb(0, 0, 0)");
-        assert_equals(getComputedStyle(e1).color, "rgb(0, 0, 0)");
-        assert_equals(getComputedStyle(f1).color, "rgb(0, 0, 0)");
+        assert_equals(getComputedStyle(b1).color, yellow);
+        assert_equals(getComputedStyle(b2).color, black);
+        assert_equals(getComputedStyle(b3).color, yellow);
+        assert_equals(getComputedStyle(c1).color, black);
+        assert_equals(getComputedStyle(d).color, black);
+        assert_equals(getComputedStyle(e1).color, black);
+        assert_equals(getComputedStyle(e2).color, black);
+        assert_equals(getComputedStyle(f1).color, black);
+        assert_equals(getComputedStyle(h1).color, black);
       }, "Preconditions.");
 
       test(() => {
         a1.className = "a";
-        assert_equals(getComputedStyle(b1).color, "rgb(255, 0, 0)");
-        assert_equals(getComputedStyle(c1).color, "rgb(255, 0, 0)");
+        assert_equals(getComputedStyle(b1).color, red);
+        assert_equals(getComputedStyle(b3).color, red);
+        assert_equals(getComputedStyle(c1).color, red);
       }, "Invalidate :matches() for simple selector arguments.");
 
       test(() => {
         a1.className = "a";
-        assert_equals(getComputedStyle(d).color, "rgb(0, 255, 0)");
+        assert_equals(getComputedStyle(d).color, green);
       }, "Invalidate :matches() for compound selector arguments.");
 
+      test(() => {
+        a1.className = "a";
+        assert_equals(getComputedStyle(b2).color, blue);
+        assert_equals(getComputedStyle(b3).color, red);
+        assert_equals(getComputedStyle(f1).color, blue);
+      }, "Invalidate :matches() for complex selector arguments.");
+
+      test(() => {
+        a1.className = "a";
+        assert_equals(getComputedStyle(e2).color, red);
+      }, "Invalidate nested :matches().");
+
+      test(() => {
+        a1.className = "a";
+        assert_equals(getComputedStyle(b2).color, blue);
+        assert_equals(getComputedStyle(h1).color, black);
+      }, "Test specificity of :matches().");
     </script>
   </body>
 </html>
\ No newline at end of file