Bug 1463628 [wpt PR 11114] - Refactor :focus-visible implementation, a=testonly
authorAlice Boxhall <aboxhall@chromium.org>
Wed, 06 Jun 2018 14:48:20 +0000
changeset 478872 b8097a5e336b0f018be678af7b0ec5138f6af1ca
parent 478871 6801a998b9dd4e159b80a4f3ab47e007e27de695
child 478873 f9f09e6c50ed8275e030439d0d89551bce1e9a61
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1463628, 11114, 1060717, 561746
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1463628 [wpt PR 11114] - Refactor :focus-visible implementation, a=testonly Automatic update from web-platform-testsRefactor :focus-visible implementation - Rename "ShouldShowFocusRingOnMouseFocus" to "MayTriggerVirtualKeyboard" - Remove UserActionElementSet::WasFocusedByMouse() and replace with Document::LastFocusType() - Move WillCallDefaultEventHandler() implementation, which checks whether the most recent event was from the keyboard and forces style recalculation if one has occurred, up to Node from HTMLFormControlElement - Tracks HadKeyboardEvent() on Document as well - Adds many more tests for the existing :focus-visible behaviour This lays the groundwork for some future changes: - Triggering :focus-visible matching on keyboard events when an element is already focused - Potentially moving the default focus ring drawing logic out of LayoutTheme and delegating to the :focus-visible matching logic instead. Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2 Change-Id: I5dc0a00c9068dc16bcd36a1c52c706646378ca50 Reviewed-on: https://chromium-review.googlesource.com/1060717 Commit-Queue: Alice Boxhall <aboxhall@chromium.org> Reviewed-by: Kent Tamura <tkent@chromium.org> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/master@{#561746} -- wpt-commits: 5057b3cee61ca468cd4e8247ea59f5c7d323aa82 wpt-pr: 11114
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/css/selectors/focus-visible-001-manual.html
testing/web-platform/tests/css/selectors/focus-visible-002-manual.html
testing/web-platform/tests/css/selectors/focus-visible-003-manual.html
testing/web-platform/tests/css/selectors/focus-visible-004-manual.html
testing/web-platform/tests/css/selectors/focus-visible-005-manual.html
testing/web-platform/tests/css/selectors/focus-visible-005.html
testing/web-platform/tests/css/selectors/focus-visible-006-manual.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -10514,16 +10514,46 @@
     ]
    ],
    "css/selectors/focus-visible-001-manual.html": [
     [
      "/css/selectors/focus-visible-001-manual.html",
      {}
     ]
    ],
+   "css/selectors/focus-visible-002-manual.html": [
+    [
+     "/css/selectors/focus-visible-002-manual.html",
+     {}
+    ]
+   ],
+   "css/selectors/focus-visible-003-manual.html": [
+    [
+     "/css/selectors/focus-visible-003-manual.html",
+     {}
+    ]
+   ],
+   "css/selectors/focus-visible-004-manual.html": [
+    [
+     "/css/selectors/focus-visible-004-manual.html",
+     {}
+    ]
+   ],
+   "css/selectors/focus-visible-005-manual.html": [
+    [
+     "/css/selectors/focus-visible-005-manual.html",
+     {}
+    ]
+   ],
+   "css/selectors/focus-visible-006-manual.html": [
+    [
+     "/css/selectors/focus-visible-006-manual.html",
+     {}
+    ]
+   ],
    "css/selectors/hover-001-manual.html": [
     [
      "/css/selectors/hover-001-manual.html",
      {}
     ]
    ],
    "css/selectors/hover-002-manual.html": [
     [
@@ -327921,16 +327951,22 @@
     ]
    ],
    "css/selectors/focus-display-none-001.html": [
     [
      "/css/selectors/focus-display-none-001.html",
      {}
     ]
    ],
+   "css/selectors/focus-visible-005.html": [
+    [
+     "/css/selectors/focus-visible-005.html",
+     {}
+    ]
+   ],
    "css/selectors/focus-within-009.html": [
     [
      "/css/selectors/focus-within-009.html",
      {}
     ]
    ],
    "css/selectors/focus-within-display-none-001.html": [
     [
@@ -549159,17 +549195,41 @@
    "29ddfde38b6b90dd684907ba06f71691ab7bd06d",
    "support"
   ],
   "css/selectors/focus-display-none-001.html": [
    "b56479be3f0c6cdf9e59f54d197526e6d66c9b54",
    "testharness"
   ],
   "css/selectors/focus-visible-001-manual.html": [
-   "ba97353214ebd26847347a2cbb6dd726144b6a31",
+   "a799c1db06badf8c2cfc099abaccba030800baf5",
+   "manual"
+  ],
+  "css/selectors/focus-visible-002-manual.html": [
+   "ec59bff328bcc56fdeeb1d79751f54ebb914cf74",
+   "manual"
+  ],
+  "css/selectors/focus-visible-003-manual.html": [
+   "465c96ddab271c867fdf2a6dfdd13a2130b0fe02",
+   "manual"
+  ],
+  "css/selectors/focus-visible-004-manual.html": [
+   "7cb093267b5ca0201619259e92f463545cfdbd36",
+   "manual"
+  ],
+  "css/selectors/focus-visible-005-manual.html": [
+   "746be74e0fa4d0b32fe3e8a6227be0bb77acd88b",
+   "manual"
+  ],
+  "css/selectors/focus-visible-005.html": [
+   "562f4fe036dc9598a01bdec045d0f101fdda91fc",
+   "testharness"
+  ],
+  "css/selectors/focus-visible-006-manual.html": [
+   "5f52d44b36429f1ec8bb9158a6afd397fde85e6b",
    "manual"
   ],
   "css/selectors/focus-within-001-ref.html": [
    "cd36270f1a34ea74b10b761cb153a7eb85b221bc",
    "support"
   ],
   "css/selectors/focus-within-001.html": [
    "61fb66bfe4c7340dc5c6b464f77def47372b7ba2",
--- a/testing/web-platform/tests/css/selectors/focus-visible-001-manual.html
+++ b/testing/web-platform/tests/css/selectors/focus-visible-001-manual.html
@@ -3,29 +3,29 @@
 <head>
   <meta charset="utf-8" />
   <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
   <link rel="author" title="Rob Dodson" href="robdodson@chromium.org" />
   <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
   <style>
-    :focus-visible { color: rgb(0, 128, 0); }
+    :focus-visible { background-color: rgb(128, 196, 128); }
   </style>
 </head>
 <body>
   <ol id="instructions">
     <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
     <li>Use the TAB key on the keyboard to focus the element below that says "Focus me."</li>
-    <li>If the element does not have green text, then the test result is FAILURE. If the element has green text, then the test result is SUCCESS.</li>
+    <li>If the element does not have a green background, then the test result is FAILURE. If the element has a green background, then the test result is SUCCESS.</li>
   </ol>
   <br />
   <div id="el" tabindex="0">Focus me.</div>
   <script>
     async_test(function(t) {
       el.addEventListener("focus", t.step_func(function() {
-        assert_equals(getComputedStyle(el).color, "rgb(0, 128, 0)");
+          assert_equals(getComputedStyle(el).backgroundColor, "rgb(128, 196, 128)");
         t.done();
       }));
     }, "Keyboard focus should match :focus-visible");
   </script>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/focus-visible-002-manual.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8" />
+  <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
+  <link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" />
+  <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <style>
+    :focus-visible { background-color: rgb(128, 196, 128); }
+  </style>
+</head>
+<body>
+  <ol id="instructions">
+    <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
+    <li><strong>Click</strong> each form element below to focus it.</li>
+    <li>If the element does not have a green background, then the test result is FAILURE. If the element has a green background, then the test result is SUCCESS.</li>
+  </ol>
+  <br />
+  <div>
+    <input data-tested="false" id="input1" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input2" type="text" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input3" type="email" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input4" type="password" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input5" type="search" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input6" type="telephone" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input7" type="url" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input8" type="number" value="10000"></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input9" type="date"></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input10" type="datetime-local"></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input11" type="month"></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input12" type="time"></input>
+  </div>
+  <div>
+    <input data-tested="false" id="input13" type="week"></input>
+  </div>
+  <div>
+    <textarea data-tested="false" id="input14">Focus me.</textarea>
+  </div>
+  <div>
+    <select data-tested="false" id="input15">
+      <option>Focus me.</option>
+      <option>Focus me.</option>
+    </select>
+  </div>
+  <script>
+    async_test(function(t) {
+        function testNextTarget(e) {
+            let el = e.target;
+            assert_equals(getComputedStyle(el).backgroundColor,
+                          "rgb(128, 196, 128)");
+            el.dataset.tested = true;
+            let nextTarget = document.querySelector("[data-tested=false]");
+            if (nextTarget) {
+                nextTarget.addEventListener("click", testNextTarget);
+                mouseClickInTarget("[data-tested=false]");
+            } else {
+                t.done();
+            }
+        }
+        input1.addEventListener("click", t.step_func(testNextTarget));
+    }, "Mouse focus on elements which would show a virtual keyboard should match :focus-visible");
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/focus-visible-003-manual.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8" />
+  <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
+  <link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" />
+  <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <style>
+    :focus:not(:focus-visible) { background-color: rgb(128, 196, 128); }
+    label:focus-within:not(:focus-visible) { background-color: rgb(128, 196, 128); }
+  </style>
+</head>
+<body>
+  <ol id="instructions">
+    <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
+    <li>Click each element element below to focus it.</li>
+    <li>If the element does not have a green background, then the test result is FAILURE. If the element has a green background, then the test result is SUCCESS.</li>
+  </ol>
+  <br />
+  <div>
+    <span data-tested="false" id="el-1" tabindex="1">Focus me</span>
+  </div>
+  <div>
+    <span data-tested="false" id="el-2" tabindex="-1">Focus me</span>
+  </div>
+  <div>
+    <span data-tested="false" id="el-3" tabindex="0">Focus me</span>
+  </div>
+  <div>
+    <button data-tested="false" id="el-4">Focus me</span>
+  </div>
+  <div>
+    <input data-tested="false" id="el-5" type="button" value="Focus me"</input>
+  </div>
+  <div>
+    <input data-tested="false" id="el-6" type="image" alt="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="el-7" type="reset" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="el-8" type="submit" value="Focus me."></input>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-9" type="checkbox"></input> Focus me.</label>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-10" type="radio"></input> Focus me.</label>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-11" type="color"></input> Focus me.</label>
+  </div>
+  <div>
+    <!-- Focusing file input triggers a modal, so only test manually -->
+    <input id="el-12" type="file" value="Focus me."></input>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-13" type="range"></input> Focus me.</label>
+  </div>
+  <script>
+    async_test(function(t) {
+        document.querySelectorAll("[data-tested]").forEach((el) => {
+            el.addEventListener("click", t.step_func((e) => {
+                let el = e.target;
+                assert_equals(getComputedStyle(el).backgroundColor,
+                              "rgb(128, 196, 128)");
+                el.dataset.tested = true;
+                if (document.querySelector("[data-tested=false]")) {
+                    mouseClickInTarget("[data-tested=false]");
+                } else {
+                    t.done();
+                }
+            }));
+        });
+    }, "Mouse focus on input elements which do not show a virtual keyboard should NOT match :focus-visible");
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/focus-visible-004-manual.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8" />
+  <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
+  <link rel="author" title="Rob Dodson" href="robdodson@chromium.org" />
+  <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <style>
+    :focus:not(:focus-visible) { background-color: rgb(128, 196, 128); }
+    label:focus-within:not(:focus-visible) { background-color: rgb(128, 196, 128); }
+    * { -webkit-appearance: none }
+  </style>
+</head>
+<body>
+  <ol id="instructions">
+    <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
+    <li>Click each element element below to focus it.</li>
+    <li>If the element does not have a green background, then the test result is FAILURE. If the element has a green background, then the test result is SUCCESS.</li>
+  </ol>
+  <br />
+  <div>
+    <span data-tested="false" id="el-1" tabindex="1">Focus me</span>
+  </div>
+  <div>
+    <span data-tested="false" id="el-2" tabindex="-1">Focus me</span>
+  </div>
+  <div>
+    <span data-tested="false" id="el-3" tabindex="0">Focus me</span>
+  </div>
+  <div>
+    <button data-tested="false" id="el-4">Focus me</span>
+  </div>
+  <div>
+    <input data-tested="false" id="el-5" type="button" value="Focus me"</input>
+  </div>
+  <div>
+    <input data-tested="false" id="el-6" type="image" alt="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="el-7" type="reset" value="Focus me."></input>
+  </div>
+  <div>
+    <input data-tested="false" id="el-8" type="submit" value="Focus me."></input>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-9" type="checkbox"></input> Focus me.</label>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-10" type="radio"></input> Focus me.</label>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-11" type="color"></input> Focus me.</label>
+  </div>
+  <div>
+    <!-- Focusing file input triggers a modal, so only test manually -->
+    <input id="el-12" type="file" value="Focus me."></input>
+  </div>
+  <div>
+    <label><input data-tested="false" id="el-13" type="range"></input> Focus me.</label>
+  </div>
+  <script>
+    async_test(function(t) {
+        document.querySelectorAll("[data-tested]").forEach((el) => {
+            el.addEventListener("click", t.step_func((e) => {
+                let el = e.target;
+                assert_equals(getComputedStyle(el).backgroundColor,
+                              "rgb(128, 196, 128)");
+                el.dataset.tested = true;
+                if (document.querySelector("[data-tested=false]")) {
+                    mouseClickInTarget("[data-tested=false]");
+                } else {
+                    t.done();
+                }
+            }));
+        });
+    }, "Mouse focus on input elements which do not show a virtual keyboard should NOT match :focus-visible - not affected by -webkit-appearance");
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/focus-visible-005-manual.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8" />
+  <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
+  <link rel="author" title="Rob Dodson" href="robdodson@chromium.org" />
+  <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <style>
+    :focus-visible { background-color: rgb(128, 196, 128); }
+    :focus:not(:focus-visible) { background-color: rgb(196, 128, 128); }
+  </style>
+</head>
+<body>
+  <ol id="instructions">
+    <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
+    <li>Click the button below that says "Click me."</li>
+    <li>If the element that says "I will be focused programmatically." does not have a green background, then the test result is FAILURE. If the element has green background, then the test result is SUCCESS.</li>
+  </ol>
+  <br />
+  <button id="button">Click me.</button>
+  <div id="el" tabindex="-1">I will be focused programmatically.</el>
+  <script>
+    button.addEventListener("click", () => {
+        el.focus();
+    });
+    async_test(function(t) {
+        el.addEventListener("focus", t.step_func(() => {
+            assert_equals(getComputedStyle(el).backgroundColor,
+                          "rgb(128, 196, 128)");
+            t.done();
+        }));
+        el.focus();
+    }, "Programmatic focus should always match :focus-visible");
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/focus-visible-005.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8" />
+  <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
+  <link rel="author" title="Rob Dodson" href="robdodson@chromium.org" />
+  <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <style>
+    :focus-visible { background-color: rgb(128, 196, 128); }
+    :focus:not(:focus-visible) { background-color: rgb(196, 128, 128); }
+  </style>
+</head>
+<body>
+  <ol id="instructions">
+    <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
+    <li>Click the button below that says "Click me."</li>
+    <li>If the element that says "I will be focused programmatically." does not have a <strong>green</strong> background, then the test result is FAILURE. If the element <em>has</em> a <strong>green</strong> background, then the test result is SUCCESS.</li>
+  </ol>
+  <br />
+  <button id="button">Click me.</button>
+  <div id="el" tabindex="-1">I will be focused programmatically.</el>
+  <script>
+    button.addEventListener("click", () => {
+        el.focus();
+    });
+    async_test(function(t) {
+        el.addEventListener("focus", t.step_func(() => {
+            assert_equals(getComputedStyle(el).backgroundColor,
+                          "rgb(128, 196, 128)");
+            t.done();
+        }));
+        el.focus();
+    }, "Programmatic focus should always match :focus-visible");
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/selectors/focus-visible-006-manual.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8" />
+  <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
+  <link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" />
+  <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <style>
+    span[contenteditable] {
+        border: 1px solid black;
+        background-color: white;
+        padding: 2px 5px;
+    }
+    span[contenteditable]:focus-visible { background-color: rgb(128, 196, 128); }
+  </style>
+</head>
+<body>
+  <ol id="instructions">
+    <li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
+    <li><strong>Click</strong> the content editable span below to focus it.</li>
+    <li>If the element does not have a green background, then the test result is FAILURE. If the element has a green background, then the test result is SUCCESS.</li>
+  </ol>
+  <br />
+  <div>
+    <span id="el" contenteditable>Focus me</span>
+  </div>
+  <script>
+    async_test(function(t) {
+      el.addEventListener("focus", t.step_func(function() {
+        assert_equals(getComputedStyle(el).backgroundColor, "rgb(128, 196, 128)");
+        t.done();
+      }));
+    }, "Focus should always match :focus-visible on content editable divs");
+  </script>
+</body>
+</html>