Update web-platform-tests to revision b'ee6da9d71d0268d7fdb04e8e5b26858f46ee0cc4'

This commit is contained in:
WPT Sync Bot 2022-01-20 04:38:55 +00:00 committed by cybai
parent 4401622eb1
commit b77ad115f6
16832 changed files with 270819 additions and 87621 deletions

View file

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name="viewport" content="user-scalable=no">
<title>Tests layout of absolutely positioned modal dialogs.</title>
<script src="/resources/testharness.js"></script>
@ -50,6 +51,8 @@ function checkVerticallyCentered(dialog) {
function reset() {
document.body.style.width = "auto";
dialog.style.top = null;
dialog.style.height = null;
if (dialog.open)
dialog.close();
dialog.remove();
@ -99,9 +102,6 @@ test(function() {
dialog.style.height = '20000px';
dialog.showModal();
assert_equals(dialog.getBoundingClientRect().top, 0);
// Set back original value to 'height'.
dialog.style.height = 'fit-content';
}, "A tall dialog should be positioned at the top of the viewport.");
test(function() {
@ -162,9 +162,6 @@ test(function() {
dialog.close();
dialog.showModal();
assert_equals(dialog.getBoundingClientRect().top, expectedTop);
// Set back original value to 'top'.
dialog.style.top = '0';
}, "Dialog's specified position should survive after close() and showModal().");
test(function() {

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<title>Test that ::backdrop receives events for the associated element</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<body>
<style>
/* ::backdrop takes up whole screen, actual <dialog> is hidden */
dialog {
visibility: hidden;
pointer-events: none;
}
dialog::backdrop {
background-color: red;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
dialog.clicked::backdrop {
background-color: green;
}
</style>
<dialog></dialog>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
setup({ single_test: true });
const dialog = document.querySelector("dialog");
dialog.showModal();
dialog.addEventListener("click", () => {
// Change style for debugging purposes, done() actually makes the test pass
dialog.className = "clicked";
done();
});
new test_driver.Actions()
.pointerMove(0, 0, {origin: "viewport"})
.pointerDown()
.pointerUp()
.send();
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@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=110952">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<style>
#div {
height: 100px;
width: 100px;
background: red;
}
</style>
<div id=div></div>
<dialog id="dialog"></dialog>
<dialog></dialog>
<script>
promise_test(async () => {
const dialog = document.getElementById('dialog');
dialog.showModal();
dialog.close();
const div = document.getElementById('div');
div.addEventListener('click', function(event) {
div.firedOn = true;
div.style.backgroundColor = 'green';
});
var absoluteTop = 0;
var absoluteLeft = 0;
for (var parentNode = div; parentNode; parentNode = parentNode.offsetParent) {
absoluteLeft += parentNode.offsetLeft;
absoluteTop += parentNode.offsetTop;
}
const x = absoluteLeft + div.offsetWidth / 2;
const y = absoluteTop + div.offsetHeight / 2;
const actions = new test_driver.Actions()
.pointerMove(x, y)
.pointerDown()
.pointerUp()
.pointerMove(0, 0);
await actions.send();
assert_true(div.firedOn, 'div should have gotten a click event.');
}, 'Ensure that closed dialogs do not block mouse events. To test manually, click the red box. The test succeeds if the red box turns green.');
</script>

View file

@ -0,0 +1,109 @@
<!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=253357">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<!--
To test manually, hit Escape once to see the topmost dialog turn green
then once again to close it. Repeat for the remaining dialog.
-->
<style>
#bottom {
top: 100px;
left: 100px;
height: 300px;
width: 300px;
margin: 0;
background: cyan;
}
#top {
top: 150px;
left: 150px;
height: 200px;
width: 200px;
margin: 0;
background: yellow;
}
</style>
<dialog id="bottom">
<span></span>
<div>You can't Escape when this textbox has focus: <input id="swallow-input" type="text"></div>
<div>You can Escape even if this textbox has focus: <input id="normal-input" type="text"></div>
</dialog>
<dialog id="top">
<span></span>
</dialog>
<script>
async function pressEscape() {
const actions = new test_driver.Actions()
.keyDown('\uE00C')
.keyUp('\uE00C');
await actions.send();
}
function handleCancel(event) {
this.style.background = 'green';
this.querySelector('span').textContent = 'I blocked the cancel! Try again to close me.';
event.preventDefault();
this.removeEventListener('cancel', handleCancel);
}
promise_test(async () => {
bottomDialog = document.getElementById('bottom');
bottomDialog.addEventListener('cancel', handleCancel);
topDialog = document.getElementById('top');
topDialog.addEventListener('cancel', handleCancel);
normalInput = document.getElementById('normal-input');
swallowInput = document.getElementById('swallow-input');
swallowInput.addEventListener('keydown', function(event) {
event.preventDefault();
});
bottomDialog.showModal();
topDialog.showModal();
await pressEscape();
assert_true(topDialog.open, 'Top dialog event listener should prevent closing.');
assert_true(bottomDialog.open, 'Top dialog event listener should prevent closing.');
await pressEscape();
assert_false(topDialog.open, 'Top dialog should close.');
assert_true(bottomDialog.open, 'Top dialog should close.');
swallowInput.focus();
await pressEscape();
await pressEscape();
await pressEscape();
assert_false(topDialog.open, 'Input should swallow Escape mechanism.');
assert_true(bottomDialog.open, 'Input should swallow Escape mechanism.');
normalInput.focus();
await pressEscape();
assert_false(topDialog.open, 'Bottom dialog event listener should prevent closing.');
assert_true(bottomDialog.open, 'Bottom dialog event listener should prevent closing.');
await pressEscape();
assert_false(topDialog.open, 'Bottom dialog should close.');
assert_false(bottomDialog.open, 'Bottom dialog should close.');
await pressEscape();
assert_false(topDialog.open, 'Pressing Escape now should do nothing.');
assert_false(bottomDialog.open, 'Pressing Escape now should do nothing.');
bottomDialog.remove();
topDialog.remove();
}, 'Modal dialogs should close when the escape key is pressed.');
</script>

View file

@ -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>

View file

@ -0,0 +1,47 @@
<!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=276785">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<dialog></dialog>
<script>
async_test(t => {
document.addEventListener('close', t.step_func_done(() => {
t.assert_unreached(`The 'close' event unexpectedly bubbled.`);
}));
closedCount = 0;
dialog = document.querySelector('dialog');
dialog.addEventListener('close', function(event) {
const selfDialog = this;
t.step(() => {
closedCount++;
assert_equals(selfDialog, dialog);
assert_false(dialog.open);
assert_false(event.cancelable);
event.preventDefault();
if (closedCount == 1) {
dialog.show();
dialog.close();
assert_equals(closedCount, 1, `dialog's close event handler shouldn't be called synchronously.`);
} else if (closedCount == 2) {
t.done();
}
});
});
dialog.show();
dialog.close();
// Verify that preventDefault() didn't cancel closing.
assert_false(dialog.open);
// dialog's close event handler shouldn't be called synchronously.
assert_equals(closedCount, 0);
}, "Test that dialog receives a close event upon closing.");
</script>

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>dialog focusing delegation with autofocus plus delegatesFocus inside the dialog</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<dialog>
<template class="turn-into-shadow-tree">
<button disabled>Non-focusable</button>
<template class="turn-into-shadow-tree delegates-focus">
<button tabindex="-1">Focusable</button>
<button tabindex="-1" autofocus>Focusable</button>
<button tabindex="-1">Focusable</button>
</template>
<button tabindex="-1">Focusable</button>
</template>
<button tabindex="-1">Focusable</button>
</dialog>
<script>
function turnIntoShadowTree(template) {
for (const subTemplate of template.content.querySelectorAll(".turn-into-shadow-tree")) {
turnIntoShadowTree(subTemplate);
}
const div = document.createElement("div");
div.attachShadow({ mode: "open", delegatesFocus: template.classList.contains("delegates-focus") });
div.shadowRoot.append(template.content);
template.replaceWith(div);
}
for (const template of document.querySelectorAll(".turn-into-shadow-tree")) {
turnIntoShadowTree(template);
}
for (const method of ["show", "showModal"]) {
test(t => {
const dialog = document.querySelector("dialog");
dialog[method]();
t.add_cleanup(() => dialog.close());
const shadowHostOuter = dialog.querySelector("div");
assert_equals(document.activeElement, shadowHostOuter, "document.activeElement");
const shadowHostInner = shadowHostOuter.shadowRoot.querySelector("div");
assert_equals(shadowHostOuter.shadowRoot.activeElement, shadowHostInner, "shadowHostOuter.shadowRoot.activeElement");
const button = shadowHostInner.shadowRoot.querySelector("[autofocus]");
assert_equals(shadowHostInner.shadowRoot.activeElement, button, "shadowHostInner.shadowRoot.activeElement");
}, `${method}()`);
}
</script>

View file

@ -0,0 +1,77 @@
<!DOCTYPE html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<dialog data-description="When autofocus is not present, the first focusable shadow-including descendant must be focused">
<template class="turn-into-shadow-tree">
<button disabled>Non-focusable</button>
<button tabindex="-1" class="focus-me">Focusable</button>
<button disabled>Non-focusable</button>
</template>
</dialog>
<dialog data-description="autofocus outside a shadow tree must take precedence over earlier in-shadow-tree focusable elements">
<button disabled>Non-focusable</button>
<template class="turn-into-shadow-tree">
<button tabindex="-1">Focusable</button>
</template>
<button tabindex="-1" autofocus>Focusable</button>
</dialog>
<dialog data-description="autofocus inside a shadow tree must be ignored: no focusable elements outside the shadow tree">
<template class="turn-into-shadow-tree">
<button tabindex="-1" class="focus-me">Focusable</button>
<button tabindex="-1" autofocus>Focusable</button>
<button tabindex="-1">Focusable</button>
</template>
</dialog>
<dialog data-description="autofocus inside a shadow tree must be ignored: focusable element before the shadow tree">
<button tabindex="-1" class="focus-me">Focusable</button>
<template class="turn-into-shadow-tree">
<button tabindex="-1">Focusable</button>
<button tabindex="-1" autofocus>Focusable</button>
<button tabindex="-1">Focusable</button>
</template>
</dialog>
<dialog data-description="autofocus inside a shadow tree must be ignored: focusable element after the shadow tree">
<template class="turn-into-shadow-tree">
<button tabindex="-1">Focusable</button>
<button tabindex="-1" autofocus>Focusable</button>
<button tabindex="-1">Focusable</button>
</template>
<button tabindex="-1" class="focus-me">Focusable</button>
</dialog>
<script>
for (const template of document.querySelectorAll(".turn-into-shadow-tree")) {
const div = document.createElement("div");
div.attachShadow({ mode: "open" });
div.shadowRoot.append(template.content);
template.replaceWith(div);
}
for (const dialog of document.querySelectorAll("dialog")) {
for (const method of ["show", "showModal"]) {
test(t => {
dialog[method]();
t.add_cleanup(() => dialog.close());
const expectedFocusOutsideShadowTree = dialog.querySelector(".focus-me");
if (expectedFocusOutsideShadowTree) {
assert_equals(document.activeElement, expectedFocusOutsideShadowTree);
} else {
const shadowHost = dialog.querySelector("div");
const expectedFocusInsideShadowTree = shadowHost.shadowRoot.querySelector(".focus-me");
assert_not_equals(expectedFocusInsideShadowTree, "Precondition check: the test was set up to expect a focused element, either outside the shadow tree or inside");
assert_equals(document.activeElement, shadowHost);
assert_equals(shadowHost.shadowRoot.activeElement, expectedFocusInsideShadowTree);
}
}, `${method}: ${dialog.dataset.description}`);
}
}
</script>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Test focusing steps when dialog is disconnected</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<input>
<script>
test(function() {
const outerInput = document.querySelector("input");
outerInput.focus();
assert_equals(document.activeElement, outerInput,
"Focus should be on element we just focused");
const dialog = document.createElement("dialog");
assert_false(dialog.open, "Dialog should initially be closed");
const innerInput = document.createElement("input");
innerInput.autofocus = true;
dialog.append(innerInput);
dialog.show();
this.add_cleanup(() => { dialog.close(); });
assert_equals(document.activeElement, outerInput, "Focusing steps should not change focus");
}, "dialog.show(): focusing steps should not change focus on disconnected <dialog>");
test(function() {
assert_throws_dom("InvalidStateError", () => {
document.createElement("dialog").showModal();
});
}, "dialog.showModal() should throw on disconnected <dialog>");
</script>
</body>
</html>

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<title>Test focusing steps when dialog is inert</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<input id="outer-input">
<dialog>
<input autofocus>
</dialog>
<script>
function test_focusing_steps_with_inert_dialog(test, isModal) {
const outerInput = document.querySelector("#outer-input");
outerInput.focus();
assert_equals(document.activeElement, outerInput,
"Focus should be on element we just focused");
const dialog = document.querySelector("dialog");
assert_false(dialog.open, "Dialog should initially be closed");
dialog.inert = true;
test.add_cleanup(() => { dialog.inert = false; });
if (isModal) {
dialog.showModal();
test.add_cleanup(() => { dialog.close(); });
assert_equals(document.activeElement, document.body,
"dialog.showModal(): focusing steps should apply focus fixup rule when dialog is inert");
} else {
dialog.show();
test.add_cleanup(() => { dialog.close(); });
assert_equals(document.activeElement, outerInput,
"dialog.show(): focusing steps should not change focus when dialog is inert");
}
}
test(function() {
test_focusing_steps_with_inert_dialog(this, false);
}, "dialog.show(): focusing steps should not change focus when dialog is inert");
test(function() {
test_focusing_steps_with_inert_dialog(this, true);
}, "dialog.showModal(): focusing steps should apply focus fixup rule when dialog is inert");
</script>
</body>
</html>

View file

@ -0,0 +1,45 @@
<!doctype html>
<meta charset=utf-8>
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body { margin: 0 }
dialog {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
box-sizing: border-box;
padding: 0;
}
dialog::backdrop {
display: none;
}
</style>
<dialog id=dialog>Something</dialog>
<script>
test(function() {
let dialog = document.getElementById("dialog");
dialog.showModal();
assert_equals(
document.elementFromPoint(10, 10),
dialog,
"Dialog is hittable by default",
);
dialog.inert = true;
assert_not_equals(
document.elementFromPoint(10, 10),
dialog,
"Dialog becomes inert dynamically",
);
dialog.close();
dialog.showModal();
assert_not_equals(
document.elementFromPoint(10, 10),
dialog,
"Dialog remains inert after open",
);
});
</script>

View file

@ -0,0 +1,27 @@
<!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=90931">
<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');
let computedStyle = window.getComputedStyle(dialog, null);
assert_equals(computedStyle.getPropertyValue('display'), 'none');
dialog.show();
computedStyle = window.getComputedStyle(dialog, null);
assert_equals(computedStyle.getPropertyValue('display'), 'block');
dialog.close();
computedStyle = window.getComputedStyle(dialog, null);
assert_equals(computedStyle.getPropertyValue('display'), 'none');
dialog.close();
}, "Tests that dialog is visible after show() is called and not visible after close() is called.");
</script>

View file

@ -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>

View file

@ -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>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<meta charset=urf-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Test focus is moved to the previously focused element when dialog is closed</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@ -21,7 +21,7 @@
function test_move_to_previously_focused(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector('dialog');
const dialog = document.querySelector("dialog");
if (showModal) {
dialog.showModal();
} else {
@ -36,7 +36,7 @@ function test_move_to_previously_focused(showModal) {
async function test_move_to_previously_focused_with_complex_dialog_usage(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector('dialog');
const dialog = document.querySelector("dialog");
if (showModal) {
dialog.showModal();
} else {
@ -56,12 +56,66 @@ async function test_move_to_previously_focused_with_complex_dialog_usage(showMod
assert_equals(document.activeElement, input);
}
// Test focus is moved to the previously focused element even if that element moved in between
function test_element_move_in_between_show_close(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector("dialog");
assert_equals(input.nextElementSibling, dialog, "Element is in correct position");
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
document.body.appendChild(input);
assert_not_equals(input.nextElementSibling, dialog, "Element should have moved");
dialog.close();
assert_equals(document.activeElement, input, "Focus should be restored to previously focused input");
// Clean up
document.body.insertBefore(input, dialog);
}
// Test focus is moved to the previously focused element even if that element moved to shadow root in between
function test_element_move_to_shadow_root_in_between_show_close(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector("dialog");
assert_equals(input.nextElementSibling, dialog, "Element is in correct position");
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
const shadowHost = document.createElement("div");
const shadowRoot = shadowHost.attachShadow({mode: "open"});
shadowRoot.appendChild(input);
document.body.appendChild(shadowHost);
assert_not_equals(input.nextElementSibling, dialog, "Element should have moved");
dialog.close();
assert_equals(shadowRoot.activeElement, input, "Focus should be restored to previously focused input");
assert_equals(document.activeElement, shadowHost, "document.activeElement should be previously focused input's shadow DOM host");
// Clean up
document.body.insertBefore(input, dialog);
shadowHost.remove();
}
// Test focus is moved to <body> if the previously focused
// element can't be focused
function test_move_to_body_if_fails(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector('dialog');
const dialog = document.querySelector("dialog");
if (showModal) {
dialog.showModal();
} else {
@ -70,7 +124,9 @@ function test_move_to_body_if_fails(showModal) {
dialog.close();
input.remove();
assert_equals(document.activeElement, document.body);
document.body.appendChild(input);
// Clean up
document.body.insertBefore(input, dialog);
}
// Test focus is moved to shadow host if the previously
@ -78,7 +134,7 @@ function test_move_to_body_if_fails(showModal) {
function test_move_to_shadow_host(showModal) {
const shadowHost = document.createElement("div");
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
const shadowRoot = shadowHost.attachShadow({mode: "open"});
shadowRoot.appendChild(document.createElement("input"));
document.body.appendChild(shadowHost);
@ -88,7 +144,7 @@ function test_move_to_shadow_host(showModal) {
assert_equals(document.activeElement, shadowHost);
assert_equals(shadowRoot.activeElement, inputElement);
const dialog = document.querySelector('dialog');
const dialog = document.querySelector("dialog");
if (showModal) {
dialog.showModal();
} else {
@ -98,6 +154,9 @@ function test_move_to_shadow_host(showModal) {
assert_equals(document.activeElement, shadowHost);
assert_equals(shadowRoot.activeElement, inputElement);
// Clean up
shadowHost.remove();
}
// Test moving the focus doesn't scroll the viewport
@ -112,7 +171,7 @@ function test_move_focus_dont_scroll_viewport(showModal) {
// scrolled to it
assert_true(document.documentElement.scrollTop > 0 );
const dialog = document.querySelector('dialog');
const dialog = document.querySelector("dialog");
if (showModal) {
dialog.showModal();
} else {
@ -131,26 +190,36 @@ function test_move_focus_dont_scroll_viewport(showModal) {
test(() => {
test_move_to_previously_focused(true);
test_move_to_previously_focused(false);
}, 'Focus should be moved to the previously focused element(Simple dialog usage)');
}, "Focus should be moved to the previously focused element (Simple dialog usage)");
promise_test(async () => {
await test_move_to_previously_focused_with_complex_dialog_usage(true);
await test_move_to_previously_focused_with_complex_dialog_usage(false);
}, 'Focus should be moved to the previously focused element(Complex dialog usage)');
}, "Focus should be moved to the previously focused element (Complex dialog usage)");
test(() => {
test_element_move_in_between_show_close(true);
test_element_move_in_between_show_close(false);
}, "Focus should be moved to the previously focused element even if it has moved in between show/close");
test(() => {
test_element_move_to_shadow_root_in_between_show_close(true);
test_element_move_to_shadow_root_in_between_show_close(false);
}, "Focus should be moved to the previously focused element even if it has moved to shadow DOM root in between show/close");
test(() => {
test_move_to_body_if_fails(true);
test_move_to_body_if_fails(false);
}, 'Focus should be moved to the body if the previously focused element is removed');
}, "Focus should be moved to the body if the previously focused element is removed");
test(() => {
test_move_to_shadow_host(true);
test_move_to_shadow_host(false);
}, 'Focus should be moved to the shadow DOM host if the previouly focused element is a shadow DOM node');
}, "Focus should be moved to the shadow DOM host if the previouly focused element is a shadow DOM node");
test(() => {
test_move_focus_dont_scroll_viewport(true);
test_move_focus_dont_scroll_viewport(false);
}, 'Focus should not scroll if the previously focused element is outside the viewport');
}, "Focus should not scroll if the previously focused element is outside the viewport");
</script>
</body>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<link rel="stylesheet" href="resources/dialog.css">
<style>
body { background: red; }
.backdrop {
display: block;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.backdrop,
.pseudodialog {
background: green;
}
</style>
<body>
<div class="backdrop"></div>
<div class="pseudodialog">PASS if no red shows</div>
</body>
</html>

View file

@ -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>

View file

@ -0,0 +1,85 @@
<!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=241699">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<p>
To test manually, click on all the "Click me"s.
The test fails if you see red.
</p>
<style>
dialog {
width: 50px;
}
</style>
<a id="a" href="javascript:void(0)">Click me</a>
<button id="button">Click me</button>
<div id="div" style="background-color: blue; width: 50px; height: 50px">Click meeee</div>
<span id="span">Click me</span>
<div id="dialog-parent" style="width: 50px; height: 50px">
<span id="dialog-sibling">Click meeee</span>
<dialog></dialog>
</div>
<script>
promise_test(async () => {
async function clickOn(element) {
let absoluteTop = 0;
let absoluteLeft = 0;
for (let parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
absoluteLeft += parentNode.offsetLeft;
absoluteTop += parentNode.offsetTop;
}
const x = Math.round(absoluteLeft + element.offsetWidth / 2);
const y = Math.round(absoluteTop + element.offsetHeight / 2);
const actions = new test_driver.Actions()
.pointerMove(x, y)
.pointerDown()
.pointerUp()
.pointerMove(0, 0);
await actions.send();
}
function eventFiredOnInertElement(e) {
e.target.style.background = 'red';
inertElementFiredOn = true;
}
inertElements = ['a', 'button', 'div', 'span']
inertElements.forEach(function(id) {
element = document.getElementById(id);
element.addEventListener('click', eventFiredOnInertElement);
element.addEventListener('mousemove', eventFiredOnInertElement);
});
document.addEventListener('click', function(e) {
document.firedOn = true;
});
document.getElementById('dialog-parent').addEventListener('click', function(e) {
e.target.firedOn = true;
});
document.querySelector('dialog').showModal();
for (const id of inertElements) {
expectedTarget = document;
if (id == 'dialog-sibling')
expectedTarget = document.getElementById('dialog-parent')
element = document.getElementById(id);
inertElementFiredOn = false;
expectedTarget.firedOn = false;
await clickOn(element);
assert_false(inertElementFiredOn, 'clicking on ' + id);
assert_true(expectedTarget.firedOn, 'clicking on ' + id);
}
}, 'Tests that inert inlines do not receive mouse events.');
</script>

View file

@ -0,0 +1,50 @@
<!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>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<label for="submit">Label for Submit</label>
<dialog>
<input id="text" type="text">
<input id="submit" type="submit">
</dialog>
<script>
promise_test(async () => {
async function clickOn(element) {
let absoluteTop = 0;
let absoluteLeft = 0;
for (let parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
absoluteLeft += parentNode.offsetLeft;
absoluteTop += parentNode.offsetTop;
}
const x = Math.round(absoluteLeft + element.offsetWidth / 2);
const y = Math.round(absoluteTop + element.offsetHeight / 2);
const actions = new test_driver.Actions()
.pointerMove(x, y)
.pointerDown()
.pointerUp()
.pointerMove(0, 0);
await actions.send();
}
document.querySelector('dialog').showModal();
document.querySelector('#text').focus();
label = document.querySelector('label');
label.focus();
assert_equals(document.activeElement, document.querySelector('#submit'),
'label.focus() should send focus to the target.');
await clickOn(label);
assert_equals(document.activeElement, document.body,
'Clicking the label should be the same as clicking the document body.');
}, 'Tests focusing of an inert label for a non-inert target.');
</script>

View file

@ -0,0 +1,55 @@
<!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=252071">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<span id="not-editable" contenteditable>I'm not editable while the dialog is showing.</span>
<dialog>
<span id="editable" contenteditable>I'm editable.</span>
</dialog>
<script>
promise_test(async () => {
async function clickOn(element) {
let absoluteTop = 0;
let absoluteLeft = 0;
for (let parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
absoluteLeft += parentNode.offsetLeft;
absoluteTop += parentNode.offsetTop;
}
const x = Math.round(absoluteLeft + element.offsetWidth / 2);
const y = Math.round(absoluteTop + element.offsetHeight / 2);
const actions = new test_driver.Actions()
.pointerMove(x, y)
.pointerDown()
.pointerUp()
.pointerMove(0, 0);
await actions.send();
}
dialog = document.querySelector('dialog');
dialog.showModal();
notEditable = document.querySelector('#not-editable');
editable = document.querySelector('#editable');
await clickOn(notEditable);
oldValue = notEditable.textContent;
await (new test_driver.Actions().keyDown('a').keyUp('a').send());
assert_equals(notEditable.textContent, oldValue);
await clickOn(editable);
oldValue = editable.textContent;
await (new test_driver.Actions().keyDown('a').keyUp('a').send());
assert_not_equals(editable.textContent, oldValue);
notEditable.remove();
editable.remove();
}, 'Test that inert nodes cannot be edited. The test passes if the only text you can edit is in the dialog.');
</script>

View file

@ -1,6 +1,8 @@
<!DOCTYPE html>
<html>
<html id="html" tabindex="1">
<head>
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#blocked-by-a-modal-dialog">
<meta name="assert" content="Checks that, when opening modal dialogs, inert nodes are not focusable.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
@ -26,11 +28,17 @@
// The test passses if only the topmost dialog and its button are focusable.
function testFocus(element, expectFocus) {
var focusedElement = null;
element.addEventListener('focus', function() { focusedElement = element; }, false);
element.focus();
var theElement = element;
assert_equals(focusedElement === theElement, expectFocus, element.id);
test(function() {
var focusedElement = null;
element.addEventListener('focus', function() { focusedElement = element; }, false);
element.focus();
var theElement = element;
if (expectFocus) {
assert_equals(focusedElement, theElement);
} else {
assert_not_equals(focusedElement, theElement);
}
}, `#${CSS.escape(element.id)} is ${expectFocus ? "" : "not "} focusable`);
}
function testTree(element, expectFocus) {
@ -41,18 +49,22 @@ function testTree(element, expectFocus) {
testTree(childNodes[i], expectFocus);
}
test(function() {
var bottomDialog = document.getElementById('bottom-dialog');
var bottomDialog = document.getElementById('bottom-dialog');
var topDialog = document.getElementById('top-dialog');
setup(function() {
bottomDialog.showModal();
var topDialog = document.getElementById('top-dialog');
topDialog.showModal();
add_completion_callback(function() {
topDialog.close();
bottomDialog.close();
});
});
testFocus(document.body, false);
testTree(topDialog, true);
testTree(bottomDialog, false);
testTree(document.getElementById('container'), false);
}, "Test that inert nodes are not focusable.");
testFocus(document.documentElement, false);
testFocus(document.body, false);
testTree(topDialog, true);
testTree(bottomDialog, false);
testTree(document.getElementById('container'), false);
</script>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!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=252071">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
Here is a text node you can't select while the dialog is open.
<dialog>I'm selectable.</dialog>
<script>
test(() => {
const dialog = document.querySelector('dialog');
dialog.showModal();
document.execCommand('SelectAll');
assert_equals(window.getSelection().toString(), "I'm selectable.");
}, 'Test that inert nodes cannot be selected. The test passes if the only text you can select is inside the dialog.');
</script>

View file

@ -0,0 +1,132 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Inertness with modal dialogs and iframes</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#inert">
<meta name="assert" content="Checks that a modal dialog marks outer nodes as inert,
but only in its document, not in the parent browsing context.
Also, when an iframe is marked as inert by a modal dialog,
all contents in the nested browsing context are marked as inert too.">
<div id="log"></div>
<div id="wrapper">
(main document: outer text)
<iframe id="outerIframe" srcdoc="
<div id='wrapper'>
(outer iframe: outer text)
<dialog id='dialog' style='display: block'>
(outer iframe: dialog)
</dialog>
</div>
"></iframe>
<dialog id="dialog" style="display: block">
(main document: dialog)
<iframe id="innerIframe" srcdoc="
<div id='wrapper'>
(inner iframe: outer text)
<dialog id='dialog' style='display: block'>
(inner iframe: dialog)
</dialog>
</div>
"></iframe>
</dialog>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const innerIframeWindow = innerIframe.contentWindow;
const outerIframeWindow = outerIframe.contentWindow;
promise_setup(async () => {
for (let global of [innerIframeWindow, outerIframeWindow]) {
if (global.location.href === "about:blank" ||
global.document.readyState !== "complete") {
await new Promise(resolve => {
global.frameElement.addEventListener("load", resolve, {once: true});
});
}
}
});
add_completion_callback(() => {
for (let global of [window, innerIframeWindow, outerIframeWindow]) {
global.getSelection().removeAllRanges();
}
});
function checkSelection(global, expectedText) {
const selection = global.getSelection();
selection.selectAllChildren(global.wrapper);
// Remove whitespace between parentheses since it varies among browsers,
// but that's not relevant to this test.
const actualText = selection.toString().replace(/\)\s*\(/g, ")(").trim();
assert_equals(actualText, expectedText);
}
function showModals(test, globals) {
for (let global of globals) {
global.dialog.showModal();
test.add_cleanup(() => { global.dialog.close(); });
}
}
promise_test(async function() {
checkSelection(window, "(main document: outer text)(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: outer text)(inner iframe: dialog)");
checkSelection(outerIframeWindow, "(outer iframe: outer text)(outer iframe: dialog)");
}, "Initially, no node is inert");
promise_test(async function() {
showModals(this, [outerIframeWindow]);
checkSelection(window, "(main document: outer text)(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: outer text)(inner iframe: dialog)");
checkSelection(outerIframeWindow, "(outer iframe: dialog)");
}, "Modal dialog in the outer iframe marks outer nodes in that iframe as inert.");
promise_test(async function() {
showModals(this, [innerIframeWindow]);
checkSelection(window, "(main document: outer text)(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: dialog)");
checkSelection(outerIframeWindow, "(outer iframe: outer text)(outer iframe: dialog)");
}, "Modal dialog in the inner iframe marks outer nodes in that iframe as inert.");
promise_test(async function() {
showModals(this, [innerIframeWindow, outerIframeWindow]);
checkSelection(window, "(main document: outer text)(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: dialog)");
checkSelection(outerIframeWindow, "(outer iframe: dialog)");
}, "Modal dialogs in both iframes mark outer nodes in these iframes as inert.");
promise_test(async function() {
showModals(this, [window]);
checkSelection(window, "(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: outer text)(inner iframe: dialog)");
checkSelection(outerIframeWindow, "");
}, "Modal dialog in the main document marks outer nodes as inert. All contents of the outer iframe are also marked as inert.");
promise_test(async function() {
showModals(this, [innerIframeWindow, window]);
checkSelection(window, "(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: dialog)");
checkSelection(outerIframeWindow, "");
}, "Modal dialogs in the main document and inner iframe mark outer nodes as inert. All contents of the outer iframe are also marked as inert.");
promise_test(async function() {
showModals(this, [outerIframeWindow, window]);
checkSelection(window, "(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: outer text)(inner iframe: dialog)");
checkSelection(outerIframeWindow, "");
}, "Modal dialogs in the main document and outer iframe mark outer nodes as inert. All contents of the outer iframe are also marked as inert.");
promise_test(async function() {
showModals(this, [innerIframeWindow, outerIframeWindow, window]);
checkSelection(window, "(main document: dialog)");
checkSelection(innerIframeWindow, "(inner iframe: dialog)");
checkSelection(outerIframeWindow, "");
}, "Modal dialogs in the main document and both iframes mark outer nodes as inert. All contents of the outer iframe are also marked as inert.");
</script>

View file

@ -0,0 +1,101 @@
<!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=329407">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<style>
#ancestor {
position: absolute;
height: 50px;
width: 50px;
top: 200px;
left: 100px;
border: 1px solid;
}
dialog {
height: 50px;
width: 50px;
top: 200px;
left: 200px;
margin: 0;
}
dialog::backdrop {
display: none;
}
</style>
<div id="ancestor">
<dialog></dialog>
</div>
<script>
promise_test(async () => {
async function clickOn(element) {
const rect = element.getBoundingClientRect();
const actions = new test_driver.Actions()
.pointerMove(rect.left + rect.width / 2, rect.top + rect.height / 2)
.pointerDown()
.pointerUp();
await actions.send();
}
const div = document.querySelector('#ancestor');
const dialog = document.querySelector('dialog');
dialog.showModal();
const handledEvent = {};
document.addEventListener('click', function(event) {
handledEvent['document'] = true;
});
document.body.addEventListener('click', function(event) {
handledEvent['body'] = true;
// body should get a event only via bubbling.
if (event.target != dialog) {
assert_unreached('body was targeted for an click event');
div.style.backgroundColor = 'red';
}
});
div.addEventListener('click', function(event) {
handledEvent['div'] = true;
// div should get a event only via bubbling.
if (event.target != dialog) {
assert_unreached('div was targeted for an click event');
div.style.backgroundColor = 'red';
}
});
dialog.addEventListener('click', function(event) {
handledEvent['dialog'] = true;
dialog.style.backgroundColor = 'green';
if (event.target != dialog) {
assert_unreached('dialog was not targeted for a click event');
dialog.style.backgroundColor = 'red';
}
});
const nodes = [ 'document', 'body', 'div', 'dialog' ];
nodes.map(function(node) { handledEvent[node] = false; });
await clickOn(div);
assert_true(handledEvent.document, 'Clicking on ancestor.');
assert_false(handledEvent.body, 'Clicking on ancestor.');
assert_false(handledEvent.dialog, 'Clicking on ancestor.');
assert_false(handledEvent.div, 'Clicking on ancestor.');
handledEvent.document = false;
await clickOn(dialog);
assert_true(handledEvent.document, 'Clicking on dialog.');
assert_true(handledEvent.body, 'Clicking on dialog.');
assert_true(handledEvent.dialog, 'Clicking on dialog.');
assert_true(handledEvent.div, 'Clicking on dialog.');
}, 'Test that ancestors of modal dialog are inert.');
</script>

View file

@ -0,0 +1,99 @@
<!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=110952">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<p>
To test manually, move the mouse to the blue box, click, and then move the
mouse outside. Then repeat for the red box. The test succeeds if both boxes
turn green
</p>
<style>
#inert-div {
height: 100px;
width: 100px;
background: blue;
}
dialog {
width: 100px;
}
dialog::backdrop {
display: none;
}
#dialog-div {
height: 100px;
width: 100px;
background: red;
}
</style>
<div id="inert-div"></div>
<dialog id="dialog">
<div id="dialog-div"></div>
</dialog>
<script>
promise_test(async () => {
async function clickOn(element) {
const rect = element.getBoundingClientRect();
const actions = new test_driver.Actions()
.pointerMove(rect.left + rect.width / 2, rect.top + rect.height / 2)
.pointerDown()
.pointerUp()
.pointerMove(0, 0);
await actions.send();
}
dialog.showModal();
inertDivHandledEvent = false;
inertDiv = document.getElementById('inert-div');
eventFiredOnInertNode = function(event) {
inertDivHandledEvent = true;
inertDiv.style.backgroundColor = 'red';
};
events = ['mousedown', 'mouseup', 'click', 'mousemove', 'mouseover', 'mouseout'];
dialogDiv = document.getElementById('dialog-div');
handledEvents = {};
handledEvents.dialogDiv = {};
eventFiredOnDialog = function(event) {
handledEvents.dialogDiv[event.type] = true;
if (Object.keys(handledEvents.dialogDiv).length == events.length)
dialogDiv.style.backgroundColor = 'green';
};
handledEvents.document = {};
expectedEventCountForDocument = events.length - 1; // document won't get 'mouseout'
eventFiredOnDocument = function(event) {
handledEvents.document[event.type] = true;
if (Object.keys(handledEvents.document).length == document.expectedEventCount && !inertDivHandledEvent) {
inertDiv.style.backgroundColor = 'green';
}
};
for (let i = 0; i < events.length; ++i) {
inertDiv.addEventListener(events[i], eventFiredOnInertNode);
dialogDiv.addEventListener(events[i], eventFiredOnDialog);
document.addEventListener(events[i], eventFiredOnDocument);
}
await clickOn(inertDiv);
assert_false(inertDivHandledEvent, 'Clicking on inert box');
assert_equals(Object.keys(handledEvents.document).length, expectedEventCountForDocument, 'Clicking on inert box');
await clickOn(dialogDiv);
assert_false(inertDivHandledEvent, 'Clicking on non-inert box');
assert_equals(Object.keys(handledEvents.dialogDiv).length, events.length, 'Clicking on non-inert box');
}, 'Ensure that mouse events are not dispatched to an inert node.');
</script>

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<title>Test that modal dialogs have visibility: visible set from the UA sheet</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3:is-modal">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div style="visibility: hidden">
<dialog>This is a dialog</dialog>
</div>
<script>
let dialog = document.querySelector("dialog");
test(t => {
dialog.show();
t.add_cleanup(() => dialog.close());
assert_equals(getComputedStyle(dialog).visibility, "hidden");
}, "Non-modal dialog should let parent visibility inherit");
test(t => {
dialog.showModal();
t.add_cleanup(() => dialog.close());
assert_equals(getComputedStyle(dialog).visibility, "visible");
}, "Modal dialog should have visibility: visible by default in UA sheet");
test(t => {
dialog.style.visibility = "hidden";
dialog.showModal();
t.add_cleanup(() => {
dialog.style.removeProperty("visibility");
dialog.close();
});
assert_equals(getComputedStyle(dialog).visibility, "hidden");
}, "Modal dialog visibility should be overridable");
</script>
</html>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=author href="mailto:skobes@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=403136">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
.spacer {
height: 500px;
}
dialog {
border: 0;
margin: 0;
padding: 1px;
}
</style>
<div class="spacer"></div>
<dialog>
<div class="spacer"></div>
</dialog>
<script>
test(() => {
document.querySelector('dialog').showModal();
assert_equals(document.scrollingElement.scrollHeight, window.innerHeight);
}, 'dialogs should be centered before computing overflow.');
</script>

View file

@ -0,0 +1,50 @@
<!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">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
height: 10000px;
}
dialog {
padding: 0;
height: 50px;
width: 50px;
}
#console {
position: fixed;
}
</style>
<dialog id="top-dialog"></dialog>
<dialog id="first-middle-dialog"></dialog>
<dialog id="second-middle-dialog" style="left: 100px"></dialog>
<dialog id="bottom-dialog"></dialog>
<script>
test(() => {
function expectedTop(dialog) {
return Math.floor((document.documentElement.clientHeight - dialog.offsetHeight) / 2);
}
function showAndTest(id) {
dialog = document.getElementById(id);
dialog.showModal();
assert_equals(dialog.offsetTop, expectedTop(dialog), id);
}
showAndTest('top-dialog');
window.scroll(0, 100);
showAndTest('first-middle-dialog');
showAndTest('second-middle-dialog');
window.scroll(0, 200);
showAndTest('bottom-dialog');
}, 'Test that multiple dialogs are centered properly.');
</script>

View file

@ -0,0 +1,52 @@
<!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=110952">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<p>
To test manually, click the red box. The test succeeds if the red box turns green.
</p>
<style>
#div {
height: 100px;
width: 100px;
background: red;
}
</style>
<div id="div"></div>
<dialog id="dialog"></dialog>
<script>
promise_test(async () => {
async function clickOn(element) {
const actions = new test_driver.Actions()
.pointerMove(0, 0, {origin: element})
.pointerDown()
.pointerUp()
.pointerMove(0, 0);
await actions.send();
}
const dialog = document.getElementById('dialog');
dialog.show();
const div = document.getElementById('div');
div.firedOn = false;
div.addEventListener('click', function(event) {
div.firedOn = true;
div.style.backgroundColor = 'green';
});
await clickOn(div);
assert_true(div.firedOn);
}, 'Ensure that non-modal dialogs do not block mouse events.');
</script>

View file

@ -0,0 +1,102 @@
<!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=382594">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
/* Remove body margin and dialog styles for easier positioning expected values */
body {
height: 10000px;
margin: 0;
}
dialog {
margin: 0;
border: 0;
padding: 0;
width: auto;
height: auto;
max-width: initial;
max-height: initial;
}
#absolute-div {
position: absolute;
top: 800px;
height: 50px;
width: 90%;
}
#relative-div {
position: relative;
top: 20px;
height: 30px;
}
</style>
<div id="absolute-div">
<div id="relative-div">
<dialog id="dialog">It is my dialog.</dialog>
</div>
</div>
<script>
test(() => {
const dialog = document.querySelector('#dialog');
const div = document.querySelector('#div-dialog');
const relativeContainer = document.querySelector('#relative-div');
const offset = 50;
dialog.style.top = offset + 'px';
dialog.style.left = offset + 'px';
dialog.style.position = 'absolute';
dialog.show();
assert_equals(
dialog.getBoundingClientRect().top,
relativeContainer.getBoundingClientRect().top + offset,
'Absolute position.');
assert_equals(
dialog.getBoundingClientRect().left,
relativeContainer.getBoundingClientRect().left + offset,
'Absolute position.');
dialog.style.position = 'static';
assert_true(dialog.open);
assert_equals(
dialog.getBoundingClientRect().top,
relativeContainer.getBoundingClientRect().top,
'Static position.');
assert_equals(
dialog.getBoundingClientRect().left,
relativeContainer.getBoundingClientRect().left,
'Static position.');
dialog.close();
dialog.style.position = 'relative';
dialog.show();
assert_equals(
dialog.getBoundingClientRect().top,
relativeContainer.getBoundingClientRect().top + offset,
'Relative position.');
assert_equals(
dialog.getBoundingClientRect().left,
relativeContainer.getBoundingClientRect().left + offset,
'Relative position.');
dialog.close();
dialog.style.position = 'fixed';
dialog.show();
assert_equals(
dialog.getBoundingClientRect().top,
offset,
'Fixed position.');
assert_equals(
dialog.getBoundingClientRect().left,
offset,
'Fixed position.');
dialog.close();
}, 'Tests layout of non-modal dialogs.');
</script>

View file

@ -4,9 +4,7 @@
right: 0;
bottom: 0;
left: 0;
width: -moz-fit-content;
width: fit-content;
height: -moz-fit-content;
height: fit-content;
margin: auto;
border: solid;

View file

@ -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>

View file

@ -0,0 +1 @@
<div id="frame2-div" class="target" tabindex="0">Hello</div>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=author href="mailto:futhark@chromium.org">
<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=850664">
<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=851384">
<div id="dialog">
<div id="item"></div>
</div>
<script>
const itemRoot = item.attachShadow({mode: 'open'});
const dialogRoot = dialog.attachShadow({mode: 'open'});
dialogRoot.innerHTML = '<dialog><slot></slot></dialog>';
dialog.offsetTop;
dialogRoot.firstChild.showModal();
</script>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html class=test-wait>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=author href="mailto:noel@chromium.org">
<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=804047">
<template>
<custom-dialog></custom-dialog>
</template>
<div id=shadow></div>
<iframe id=sibling></iframe>
<script>
customElements.define('custom-dialog',class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = '<dialog></dialog>';
}
show() {
this.shadowRoot.querySelector('dialog').showModal();
}
});
onload = () => {
const template = document.querySelector('template');
const content = document.importNode(template.content, true);
const dialog = content.querySelector('custom-dialog');
document.querySelector('div').appendChild(dialog);
dialog.show();
document.documentElement.classList.remove('test-wait');
};
</script>

View file

@ -0,0 +1,33 @@
<!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=241699">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<p>Ensure that simulated click is still dispatched to an inert node.
To test manually, click the CLICK ME label and verify it does change the value of the checkbox.</p>
<div>
</div>
<input type="checkbox" id="target">
<dialog><label for="target">CLICK ME</label></dialog>
<script>
promise_test(async () => {
async function clickOn(element) {
const actions = new test_driver.Actions()
.pointerMove(0, 0, {origin: element})
.pointerDown()
.pointerUp()
await actions.send();
}
document.querySelector('dialog').showModal();
await clickOn(document.querySelector('label'));
assert_true(document.getElementById('target').checked);
}, 'Ensure that simulated click is still dispatched to an inert node.');
</script>

View file

@ -0,0 +1,34 @@
<!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=304827">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<dialog>
<form method="dialog">
<input id="goodbye" type="submit" value="Goodbye">
<input id="hello" type="submit" value="Hello">
</form>
</dialog>
<script>
async_test(t => {
const dialog = document.querySelector('dialog');
dialog.show();
dialog.addEventListener('close', t.step_func(() => {
assert_false(dialog.open);
assert_equals(dialog.returnValue, 'Goodbye');
dialog.show();
dialog.addEventListener('close', t.step_func_done(() => {
assert_false(dialog.open);
assert_equals(dialog.returnValue, 'Hello');
}));
document.querySelector('#hello').click();
}), {once: true});
document.querySelector('#goodbye').click();
}, 'Tests submitting a dialog on a close event triggered by a previous submission.');
</script>

View file

@ -0,0 +1,40 @@
<!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=241699">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
dialog {
width: 50px;
}
</style>
<button>Click me</button>
<div id="div">Click me too</div>
<dialog></dialog>
<script>
test(() => {
dialog = document.querySelector('dialog');
dialog.showModal();
const button = document.querySelector('button');
const div = document.getElementById('div');
let clicked = false;
[button, div].forEach(function(element) {
element.addEventListener('click', () => clicked = true);
clicked = false;
element.click();
assert_true(clicked, 'Calling click() on ' + element.tagName);
clicked = false;
element.dispatchEvent(new Event('click'));
assert_true(clicked, 'Calling dispatchEvent() on ' + element.tagName);
});
}, 'Test that inert nodes still get programmatic click events');
</script>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<title>Test that parent clip-path does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
clip-path: circle(5%);
}
dialog::backdrop,
dialog {
background: green;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<title>Test that parent filter does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
filter: blur(100px) opacity(50%);
}
dialog::backdrop,
dialog {
background: green;
position: absolute;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<title>Test that parent mask does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
mask-image: radial-gradient(black, transparent);
mask-size: 100px;
}
dialog::backdrop,
dialog {
background: green;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html>
<title>Reference: Test that parent opacity does not affect top layer elements</title>
<meta charset="utf-8">
<style>
dialog {
width: 100px;
height: 100px;
background: green;
}
</style>
<body>
<p>PASS if you see a green square</p>
<dialog></dialog>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -3,23 +3,24 @@
<title>Test that parent opacity does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="top-layer-parent-opacity-ref.html">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=229317">
<style>
body { background: red; }
#parent {
opacity: 0;
}
dialog::backdrop,
dialog {
width: 100px;
height: 100px;
background: green;
}
</style>
<body>
<p>PASS if you see a green square</p>
<div id="parent">
<dialog></dialog>
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<title>Test that parent overflow: clip; does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
max-width: 0;
max-height: 0;
width: 0;
height: 0;
overflow: clip;
position: absolute;
}
dialog::backdrop,
dialog {
background: green;
position: absolute;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<title>Test that parent overflow: hidden; does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
max-width: 0;
max-height: 0;
width: 0;
height: 0;
overflow: hidden;
position: absolute;
}
dialog::backdrop,
dialog {
background: green;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<title>Test that parent overflow: scroll; does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
max-width: 0;
max-height: 0;
width: 0;
height: 0;
overflow: scroll;
position: absolute;
}
dialog::backdrop,
dialog {
background: green;
position: absolute;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<title>Test that parent transform does not affect top layer elements</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="green-dialog-and-backdrop.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
body { background: red; }
#parent {
transform: scale(0);
}
dialog::backdrop,
dialog {
background: green;
}
</style>
<body>
<div id="parent">
<dialog>PASS if no red shows</dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<style>
dialog {
background-color: green;
height: 50px;
width: 50px;
border: none;
padding: 0;
margin: 0;
position: absolute;
top: 100px;
left: 100px;
}
</style>
<dialog></dialog>
<script>
document.querySelector('dialog').showModal();
</script>

View file

@ -0,0 +1,28 @@
<!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=106538">
<link rel=match href="top-layer-position-ref.html">
<meta name=assert content="Position relative computes to absolute in the top layer for dialog elements.">
<style>
dialog {
background-color: green;
height: 50px;
width: 50px;
border: none;
padding: 0;
margin: 0;
position: relative;
top: 100px;
left: 100px;
}
</style>
<dialog></dialog>
<script>
document.querySelector('dialog').showModal();
</script>

View file

@ -0,0 +1,28 @@
<!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=106538">
<link rel=match href="top-layer-position-ref.html">
<meta name=assert content="Position static computes to absolute in the top layer for dialog elements.">
<style>
dialog {
background-color: green;
height: 50px;
width: 50px;
border: none;
padding: 0;
margin: 0;
position: static;
top: 100px;
left: 100px;
}
</style>
<dialog></dialog>
<script>
document.querySelector('dialog').showModal();
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
test(() => {
const dialog = document.createElement('dialog');
document.body.appendChild(dialog);
dialog.style = 'position:static';
assert_equals(getComputedStyle(dialog).position, 'static');
dialog.showModal();
assert_true(dialog.open);
assert_equals(getComputedStyle(dialog).position, 'absolute',
`dialog should be position:absolute when element.style has position:static.`);
dialog.close();
assert_false(dialog.open);
dialog.style = 'position:relative';
assert_equals(getComputedStyle(dialog).position, 'relative');
dialog.showModal();
assert_true(dialog.open);
assert_equals(getComputedStyle(dialog).position, 'absolute',
`dialog should be position:absolute when element.style has position:relative.`);
dialog.close();
assert_false(dialog.open);
}, `Verifies that position:static and position:relative computed to position:absolute in the top layer.`);
</script>