Add html/interaction/focus/document-level-focus-apis/document-has-system-focus.html (#26845)

* Add html/interaction/focus/document-level-focus-apis/document-has-system-focus.html

* Ensure document has focus as precondition.

* Try to have popup steal focus in more browsers.

* Move event handlers earlier to avoid possible race.
diff --git a/html/interaction/focus/document-level-focus-apis/document-has-system-focus.html b/html/interaction/focus/document-level-focus-apis/document-has-system-focus.html
new file mode 100644
index 0000000..26f0bbb
--- /dev/null
+++ b/html/interaction/focus/document-level-focus-apis/document-has-system-focus.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: focus - document has system focus</title>
+<link rel="help" href="https://html.spec.whatwg.org/#has-focus-steps">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<input id="input">
+<script>
+
+promise_test(async t => {
+  await new Promise(r => window.onload = r);
+  // This test requires the document to have focus as a starting condition.
+  // Whether a newly loaded page receives focus or not, seems to be somewhat
+  // browser-dependent and situation-dependent. For instance, Firefox appears to
+  // focus the page immediately if the page was loaded with the refresh button,
+  // but not if it was loaded from pressing ENTER in the URL bar. To ensure a
+  // reliable starting condition for this test, we give an extra push for focus.
+  if (!document.hasFocus()) {
+    const input = document.getElementById("input");
+    input.focus();
+    await new Promise(r => input.onfocus = r);
+  }
+  assert_true(document.hasFocus(), "Document has focus as starting condition.");
+
+  let gotBlur = false;
+  window.onblur = () => gotBlur = true;
+  const popup = window.open("support/popup.html", "otherwindow", "resizable");
+  assert_not_equals(popup, null, "Test requires popup be opened");
+  t.add_cleanup(() => popup.close());
+  const msg = await new Promise(r => window.onmessage = ({data}) => r(data));
+  assert_equals(msg, "focus = true",
+                "Test requires popups be focused (may require harness flags)");
+  assert_true(gotBlur, "Document received blur event when popup opened");
+  assert_false(document.hasFocus(), "Document lost focus when popup opened");
+
+  const p = new Promise(r => window.onfocus = r);
+  popup.close();
+  await p;
+  assert_true(true, "Document received focus event when popup closed");
+  assert_true(document.hasFocus(), "Document regained focus when popup closed");
+}, "Top-level document receives blur/focus events and loses system focus " +
+   "during opening/closing of a popup");
+
+</script>
diff --git a/html/interaction/focus/document-level-focus-apis/support/popup.html b/html/interaction/focus/document-level-focus-apis/support/popup.html
new file mode 100644
index 0000000..3a44191
--- /dev/null
+++ b/html/interaction/focus/document-level-focus-apis/support/popup.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+Popup <input id="input">
+<script>
+window.onload = async () => {
+  try {
+    if (!document.hasFocus()) {
+      const input = document.getElementById("input");
+      input.focus();
+      await new Promise(r => input.onfocus = r);
+    }
+    opener.postMessage(`focus = ${document.hasFocus()}`, "*");
+  } catch(e) {
+    opener.postMessage(`${e.name}: $(e.message)`, "*");
+  }
+};
+</script>
+</html>