Port chrome-only dialog tests to WPT part 2
Bug: 1240798
Change-Id: Id169e3ba4c0d80e9ec7a221075a78b369bc3623a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3313693
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#948157}
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-close-event-async.html b/html/semantics/interactive-elements/the-dialog-element/dialog-close-event-async.html
new file mode 100644
index 0000000..0f8d40a
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/dialog-close-event-async.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>dialog element: close()</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<dialog id="d1" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<script>
+ var d1 = document.getElementById('d1'),
+ t = async_test("close() fires a close event"),
+ was_queued = false;
+
+ d1.onclose = t.step_func_done(function(e) {
+ assert_true(was_queued, "close event should be queued");
+ assert_true(e.isTrusted, "close event is trusted");
+ assert_false(e.bubbles, "close event doesn't bubble");
+ assert_false(e.cancelable, "close event is not cancelable");
+ });
+
+ t.step(function() {
+ d1.close();
+ was_queued = true;
+ })
+</script>
+</body>
+</html>
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal-inert-crash.html b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal-inert-crash.html
new file mode 100644
index 0000000..54c2eda
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal-inert-crash.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<iframe id="frame"></iframe>
+<script>
+ async_test(function(t) {
+ onload = t.step_func(() => {
+ const host = document.createElement("div");
+ frame.appendChild(host);
+ frame.contentDocument.body.innerHTML = "<dialog></dialog>";
+ document.body.offsetTop;
+ const root = host.attachShadow({mode: 'open'});
+ root.innerHTML = "<content>";
+ const dialog = frame.contentDocument.querySelector("dialog");
+ dialog.showModal();
+ t.done();
+ });
+ }, "Dialog.showModal() called when we have a dirty shadow distribution should not crash.");
+</script>
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html
new file mode 100644
index 0000000..ed64375
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=author href="mailto:falken@chromium.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element">
+<link rel=help href="https://bugs.webkit.org/show_bug.cgi?id=97425">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<dialog id="mydialog">It's my dialog.</dialog>
+
+<script>
+test(() => {
+ const dialog = document.getElementById('mydialog');
+ const computedStyle = window.getComputedStyle(dialog, null);
+ assert_equals(computedStyle.display, 'none');
+
+ dialog.showModal();
+ assert_equals(computedStyle.display, 'block');
+
+ // The quoted texts output below are from <http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#dom-dialog-showmodal>.
+ assert_throws_dom('InvalidStateError', () => dialog.showModal());
+
+ dialog.close();
+ assert_equals(computedStyle.display, 'none');
+
+ dialog.parentNode.removeChild(dialog);
+ assert_throws_dom('InvalidStateError', () => dialog.showModal());
+
+ const doc = document.implementation.createHTMLDocument();
+ doc.body.appendChild(dialog);
+ assert_false(dialog.open);
+ dialog.showModal();
+ assert_true(dialog.open, 'Although the document is not attached to any pages, showModal() should execute as normal.');
+}, 'Tests that showModal() performs the steps specified in the HTML spec.');
+</script>
diff --git a/html/semantics/interactive-elements/the-dialog-element/inert-focus-in-frames.html b/html/semantics/interactive-elements/the-dialog-element/inert-focus-in-frames.html
new file mode 100644
index 0000000..12fa96a
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/inert-focus-in-frames.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=author href="mailto:falken@chromium.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=242848">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe height=400 width=600 id="main-iframe">
+ <frameset rows="*" cols="50,50">
+ <frame src="resources/inert-focus-in-frames-frame1.html">
+ <frame src="resources/inert-focus-in-frames-frame2.html">
+ </frameset>
+</iframe>
+
+<script>
+let framesLoadedResolver = null;
+const framesLoadedPromise = new Promise(resolve => framesLoadedResolver = resolve);
+framesLoaded = 0;
+numFrames = 4;
+
+function frameLoaded() {
+ framesLoaded++;
+ if (framesLoaded == numFrames)
+ framesLoadedResolver();
+}
+var mainIframe = document.getElementById('main-iframe');
+mainIframe.contentDocument.write(mainIframe.textContent);
+mainIframe.contentDocument.close();
+mainIframe.contentWindow.frames[1].window.onload = frameLoaded;
+window.onload = frameLoaded;
+
+promise_test(async () => {
+ await framesLoadedPromise;
+
+ function testFocus(element, expectFocus) {
+ let focusedElement = null;
+ element.addEventListener('focus', function() { focusedElement = element; }, false);
+ element.focus();
+ assert_equals(focusedElement === element, expectFocus, element.id);
+ }
+
+ // Opening a modal dialog in frame1. It blocks other nodes in its document.
+ const frame1 = mainIframe.contentWindow.frames[0].document;
+ frame1.querySelector('dialog').showModal();
+
+ testFocus(frame1.querySelector('.target'), false);
+ const iframe = frame1.querySelector('#iframe1').contentDocument;
+ testFocus(iframe.querySelector('.target'), false);
+
+ // Even a modal dialog in the iframe is blocked by the modal dialog in the parent frame1.
+ iframe.querySelector('dialog').showModal();
+ testFocus(iframe.querySelector('button'), false);
+
+ // An iframe within a modal dialog can still be focused.
+ var dialogIframe = frame1.querySelector('#iframe-in-dialog').contentDocument;
+ testFocus(dialogIframe.querySelector('.target'), true);
+
+ // A modal dialog does not block nodes in a sibling frame.
+ var frame2 = mainIframe.contentWindow.frames[1].document;
+ testFocus(frame2.querySelector('.target'), true);
+
+ // Closing the dialog in frame1. The modal dialog in the iframe does not block nodes in its parent.
+ frame1.querySelector('dialog').close();
+ testFocus(iframe.querySelector('.target'), false);
+ testFocus(frame1.querySelector('.target'), true);
+
+}, 'Tests inert node focusing across frames and iframes.');
+</script>
diff --git a/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame1.html b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame1.html
new file mode 100644
index 0000000..c5566bc
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+window.onload = parent.parent.frameLoaded;
+</script>
+</head>
+<body>
+<dialog id="dialog">
+ <button id="dialog-button" tabindex="0">Button</button>
+ <iframe id="iframe-in-dialog" srcdoc='
+ <input id="iframe-under-dialog-input" class="target" type="date">
+ '></iframe>
+</dialog>
+<input id="frame1-input" class="target" type="text">
+<iframe id="iframe1" srcdoc='
+ <dialog id="iframe-dialog">
+ <button id="iframe-dialog-button" tabindex="0">Button</button>
+ </dialog>
+ <input id="iframe-input" class="target" type="date">
+ <script>window.onload = parent.parent.parent.frameLoaded;</script>
+'>
+</body>
+</html>
diff --git a/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame2.html b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame2.html
new file mode 100644
index 0000000..167c569
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame2.html
@@ -0,0 +1 @@
+<div id="frame2-div" class="target" tabindex="0">Hello</div>