Update web-platform-tests to revision b'468d01bbd84da2babf265c6af46947be68713440'

This commit is contained in:
WPT Sync Bot 2021-09-07 11:16:33 +00:00 committed by cybai
parent 35e95f55a1
commit 58e8ee674b
9438 changed files with 266112 additions and 106976 deletions

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<link rel="author" title="Joey Arhar" href="mailto:jarhar@chromium.org">
<link rel="help" href="https://github.com/whatwg/html/pull/6466">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div style="height:2000px">spacer</div>
<details id=details>
<div id=target>target</div>
</details>
<script>
async_test(t => {
assert_false(details.hasAttribute('open'),
`The <details> should be closed at the start of the test.`);
assert_equals(window.pageYOffset, 0,
`The page should be scrolled to the top at the start of the test.`);
window.location.hash = '#target';
requestAnimationFrame(t.step_func_done(() => {
assert_true(details.hasAttribute('open'),
`<details> should be opened by navigating to an element inside it.`);
assert_not_equals(window.pageYOffset, 0,
`The page should be scrolled down to the <details> element.`);
}));
});
</script>

View file

@ -40,11 +40,6 @@ dialog {
<script>
"use strict";
function checkNotVerticallyCentered(dialog) {
var centeredTop = (document.documentElement.clientHeight - dialog.offsetHeight) / 2;
assert_not_equals(dialog.getBoundingClientRect().top, centeredTop);
}
function checkVerticallyCentered(dialog) {
var centeredTop = (document.documentElement.clientHeight - dialog.offsetHeight) / 2;
// Using approx equals because getBoundingClientRect() and centeredTop
@ -155,8 +150,8 @@ test(function() {
dialog.remove();
relativeContainer.appendChild(dialog);
checkVerticallyCentered(dialog);
}, "Dialog should still be centered when removed, and re-added to the document.");
assert_equals(relativeContainer.getBoundingClientRect().top, dialog.getBoundingClientRect().top);
}, "Dialog should not still be centered when removed, and re-added to the document.");
test(function() {
this.add_cleanup(reset);

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<style>
.backdrop {
position: absolute;
height: 100px;
width: 100px;
background: green;
}
</style>
</head>
<body>
Test ::backdrop used in descendant selectors. The test passes if there are two green boxes and no red.
<div class="backdrop" style="top: 100px; left: 100px"></div>
<div class="backdrop" style="top: 100px; left: 300px"></div>
</body>
</html>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="backdrop-descendant-selector-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
visibility: hidden;
}
::backdrop {
position: absolute;
height: 100px;
width: 100px;
background: red;
}
/* This shouldn't be matched, dialog is not the parent of ::backdrop.
* It is given high specificity so we actually test something.
*/
#dialog-parent > #dialog > ::backdrop,
#dialog-parent > #dialog ::backdrop {
background: red;
}
#dialog-parent > ::backdrop {
top: 100px;
left: 100px;
background: green;
}
#backdrop-ancestor ::backdrop {
top: 100px;
left: 300px;
background: green;
}
</style>
</head>
<body>
Test ::backdrop used in descendant selectors. The test passes if there are two green boxes and no red.
<div id="dialog-parent">
<dialog id="dialog"></dialog>
</div>
<div id="backdrop-ancestor">
<p><span><dialog></dialog></span></p>
</div>
<script>
var dialogs = document.querySelectorAll('dialog');
for (var i = 0; i < dialogs.length; ++i)
dialogs[i].showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<style>
#backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background: green;
}
</style>
<body>
Test that ::backdrop does not inherit from anything. The test passes if there is
a green box and no red.
<div id="backdrop"></div>
</body>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<link rel="match" href="backdrop-does-not-inherit-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
visibility: inherit;
background: red;
}
dialog::backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
visibility: inherit;
background: green;
}
</style>
<body>
Test that ::backdrop does not inherit from anything. The test passes if there is
a green box and no red.
<div style="visibility: hidden">
<dialog></dialog>
</div>
<script>
document.querySelector('dialog').showModal();
</script>
</body>

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<title>Reference: Test that adding display: none; dynamically on ::backdrop makes it disappear</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<p>Test passes if there is no red.</p>
</html>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<title>Test that adding display: none; dynamically on ::backdrop makes it disappear</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="match" href="backdrop-dynamic-display-none-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<p>Test passes if there is no red.</p>
<dialog></dialog>
<style>
dialog { visibility: hidden; }
::backdrop { background-color: red; }
.hidden-backdrop::backdrop {
display: none;
}
</style>
<script>
dialog = document.querySelector("dialog");
dialog.showModal();
requestAnimationFrame(() => {
dialog.classList.add("hidden-backdrop");
});
</script>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<style>
.backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background-color: green;
}
</style>
</head>
<body>
Test dynamic changes to ::backdrop style. The test passes if there is a green box below.
<div class="backdrop"></div>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="backdrop-dynamic-style-change-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
visibility: hidden;
}
::backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background-color: red;
}
.green::backdrop {
background-color: green;
}
</style>
</head>
<body>
Test dynamic changes to ::backdrop style. The test passes if there is a green box below.
<dialog></dialog>
<script>
dialog = document.querySelector('dialog');
dialog.showModal();
dialog.classList.add('green');
</script>
</body>
</html>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<style>
#backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background: green;
}
</style>
<body>
Test that position 'static' or 'relative' for ::backdrop computes to 'absolute'.
The test passes if there is a single green box.
<div id="backdrop"></div>
</body>

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<link rel="match" href="backdrop-in-flow-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
visibility: hidden;
}
dialog::backdrop {
height: 100px;
width: 50px;
}
#left::backdrop {
position: static;
top: 100px;
left: 100px;
background: green;
}
#right::backdrop {
position: relative;
background: green;
top: 100px;
left: 150px;
}
</style>
<body>
Test that position 'static' or 'relative' for ::backdrop computes to 'absolute'.
The test passes if there is a single green box.
<dialog id="left"></dialog>
<dialog id="right"></dialog>
</div>
<script>
document.querySelector('#left').showModal();
document.querySelector('#right').showModal();
</script>
</body>

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<style>
div {
position: absolute;
}
#bottom-backdrop {
top: 100px;
left: 100px;
height: 300px;
width: 300px;
background-color: rgb(0, 50, 0);
}
#bottom {
top: 125px;
left: 125px;
height: 250px;
width: 250px;
background-color: rgb(0, 90, 0);
}
#middle-backdrop {
top: 150px;
left: 150px;
height: 200px;
width: 200px;
background-color: rgb(0, 130, 0);
}
#middle {
top: 175px;
left: 175px;
height: 150px;
width: 150px;
background-color: rgb(0, 170, 0);
}
#top-backdrop {
top: 200px;
left: 200px;
height: 100px;
width: 100px;
background-color: rgb(0, 210, 0);
}
#top {
top: 225px;
left: 225px;
height: 50px;
width: 50px;
background-color: rgb(0, 255, 0);
}
</style>
<body>
Test for dialog::backdrop stacking order. The test passes if there are 6
boxes enclosed in each other, becoming increasingly smaller and brighter
green.
<div id="bottom-backdrop"></div>
<div id="bottom"></div>
<div id="middle-backdrop"></div>
<div id="middle"></div>
<div id="top-backdrop"></div>
<div id="top"></div>
</body>

View file

@ -0,0 +1,80 @@
<!DOCTYPE html>
<link rel="match" href="backdrop-stacking-order-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
padding: 0px;
border: none;
margin: 0px;
}
#bottom::backdrop {
top: 100px;
left: 100px;
height: 300px;
width: 300px;
background-color: rgb(0, 50, 0);
z-index: 100; /* z-index has no effect. */
}
#bottom {
top: 125px;
left: 125px;
height: 250px;
width: 250px;
background-color: rgb(0, 90, 0);
}
#middle::backdrop {
top: 150px;
left: 150px;
height: 200px;
width: 200px;
background-color: rgb(0, 130, 0);
z-index: -100; /* z-index has no effect. */
}
#middle {
top: 175px;
left: 175px;
height: 150px;
width: 150px;
background-color: rgb(0, 170, 0);
}
#top::backdrop {
top: 200px;
left: 200px;
height: 100px;
width: 100px;
background-color: rgb(0, 210, 0);
z-index: 0; /* z-index has no effect. */
}
#top {
top: 225px;
left: 225px;
height: 50px;
width: 50px;
background-color: rgb(0, 255, 0);
z-index: -1000; /* z-index has no effect. */
}
</style>
<body>
Test for dialog::backdrop stacking order. The test passes if there are 6
boxes enclosed in each other, becoming increasingly smaller and brighter
green.
<dialog id="top"></dialog>
<dialog id="middle"></dialog>
<dialog id="bottom"></dialog>
<script>
var topDialog = document.getElementById('top');
var middleDialog = document.getElementById('middle');
var bottomDialog = document.getElementById('bottom');
topDialog.showModal();
bottomDialog.showModal();
topDialog.close(); // Just to shuffle the top layer order around a little.
middleDialog.showModal();
topDialog.showModal();
</script>
</body>

View file

@ -16,11 +16,13 @@
padding: 0;
max-width: initial;
max-height: initial;
width: {{GET[dialog-width]}};
height: {{GET[dialog-height]}};
}
</style>
<div id="container">
<dialog style="width: 20px; height: 10px;">X</dialog> <!-- sync width and height with centering.html -->
<dialog>X</dialog>
</div>
<script>

View file

@ -2,7 +2,7 @@
<meta charset=utf-8>
<title>dialog element: centered alignment</title>
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
<link rel=help href="https://html.spec.whatwg.org/multipage/#centered-alignment">
<link rel="help" href="https://html.spec.whatwg.org/#flow-content-3">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
@ -14,44 +14,56 @@
const dialogWidth = 20;
const dialogHeight = 10;
const widthOffset100 = 100 / 2 - dialogWidth / 2;
const widthOffset40 = 40 / 2 - dialogWidth / 2;
testDialogCentering("horizontal-tb", "", "", "tall viewport", 40, 100);
testDialogCentering("horizontal-tb", "", "", "wide viewport", 100, 40);
testDialogCentering("horizontal-tb", "", "", "square viewport", 100, 100);
testDialogCentering("horizontal-tb", "", "", "dialog and viewport match", dialogWidth, dialogHeight);
const heightOffset100 = 100 / 2 - dialogHeight / 2;
const heightOffset40 = 40 / 2 - dialogHeight / 2;
testDialogCentering("vertical-rl", "", "", "tall viewport", 40, 100);
testDialogCentering("vertical-lr", "", "", "tall viewport", 40, 100);
testDialogCentering("horizontal-tb", "", "", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("horizontal-tb", "", "", "wide viewport", 100, 40, widthOffset100, heightOffset40);
testDialogCentering("horizontal-tb", "", "", "square viewport", 100, 100, widthOffset100, heightOffset100);
testDialogCentering("horizontal-tb", "", "", "dialog and viewport match", dialogWidth, dialogHeight, 0, 0);
testDialogCentering("vertical-rl", "", "horizontal-tb", "tall viewport", 40, 100);
testDialogCentering("vertical-lr", "", "horizontal-tb", "tall viewport", 40, 100);
testDialogCentering("vertical-rl", "", "", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("vertical-lr", "", "", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("horizontal-tb", "vertical-rl", "", "tall viewport", 40, 100);
testDialogCentering("vertical-rl", "horizontal-tb", "", "tall viewport", 40, 100);
testDialogCentering("vertical-rl", "", "horizontal-tb", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("vertical-lr", "", "horizontal-tb", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("horizontal-tb", "vertical-rl", "horizontal-tb", "tall viewport", 40, 100);
testDialogCentering("vertical-rl", "horizontal-tb", "vertical-rl", "tall viewport", 40, 100);
testDialogCentering("horizontal-tb", "vertical-rl", "", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("vertical-rl", "horizontal-tb", "", "tall viewport", 40, 100, widthOffset40, heightOffset100);
function testDialogCentering(writingMode, containerWritingMode, dialogWritingMode, label, iframeWidth, iframeHeight) {
const dialogSizesToTest = [["", ""], [dialogWidth.toString()+'px', dialogHeight.toString()+'px']];
for (const dialogSizes of dialogSizesToTest) {
const isDefaultSize = dialogSizes[0] == "";
// This test doesn't make sense if the dialog sizes are default
if (isDefaultSize && label == "dialog and viewport match") {
continue;
}
testDialogCentering("horizontal-tb", "vertical-rl", "horizontal-tb", "tall viewport", 40, 100, widthOffset40, heightOffset100);
testDialogCentering("vertical-rl", "horizontal-tb", "vertical-rl", "tall viewport", 40, 100, widthOffset40, heightOffset100);
async_test(t => {
const iframe = document.createElement("iframe");
iframe.src = `centering-iframe.sub.html?html-writing-mode=${writingMode}&container-writing-mode=${containerWritingMode}&dialog-writing-mode=${dialogWritingMode}&dialog-width=${dialogSizes[0]}&dialog-height=${dialogSizes[1]}`;
iframe.width = iframeWidth;
iframe.height = iframeHeight;
iframe.onload = t.step_func_done(() => {
const dialog = iframe.contentDocument.querySelector("dialog");
const dialogRect = dialog.getBoundingClientRect();
function testDialogCentering(writingMode, containerWritingMode, dialogWritingMode, label, iframeWidth, iframeHeight, leftOffset, topOffset) {
async_test(t => {
const iframe = document.createElement("iframe");
iframe.src = `centering-iframe.sub.html?html-writing-mode=${writingMode}&container-writing-mode=${containerWritingMode}&dialog-writing-mode=${dialogWritingMode}`;
iframe.width = iframeWidth;
iframe.height = iframeHeight;
iframe.onload = t.step_func_done(() => {
const dialog = iframe.contentDocument.querySelector("dialog");
const dialogRect = dialog.getBoundingClientRect();
const expectedLeftOffset = iframeWidth / 2 - dialogRect.width / 2;
const expectedTopOffset = Math.max(iframeHeight / 2 - dialogRect.height / 2, 0);
assert_equals(dialogRect.left, leftOffset, 'left');
assert_equals(dialogRect.top, topOffset, 'top');
});
document.body.appendChild(iframe);
}, writingMode + (containerWritingMode ? ` (container ${containerWritingMode})` : "") +
(dialogWritingMode ? ` (dialog ${dialogWritingMode})` : "") + `: ${label}`);
if (isDefaultSize) {
assert_approx_equals(dialogRect.left, expectedLeftOffset, 1/60);
assert_approx_equals(dialogRect.top, expectedTopOffset, 1/60);
} else {
assert_equals(dialogRect.left, expectedLeftOffset);
assert_equals(dialogRect.top, expectedTopOffset);
}
});
document.body.appendChild(iframe);
}, writingMode + (containerWritingMode ? ` (container ${containerWritingMode})` : "") +
(dialogWritingMode ? ` (dialog ${dialogWritingMode})` : "") + `: ${label}` + `, default-sizes: ${isDefaultSize}`);
}
}
</script>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1206122">
<body onload=dlg.show()>
<dialog id="dlg">
<audio></audio>
<video></video>
</dialog>
This test passes if it does not crash.

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Test cancel event is fired when the dialog is closed by user interaction</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
</head>
<body>
<p>Test cancel event is fired when the dialog is closed by user interaction</p>
<dialog>
<p>Hello World</p>
</dialog>
<script>
setup({ single_test: true });
var hasCancelEventFired = false;
var hasCloseEventFired = false;
const dialog = document.querySelector("dialog");
dialog.addEventListener("cancel", function(event) {
assert_true(true, "cancel event is fired");
assert_true(event.cancelable, "cancel event should be cancelable");
assert_false(hasCancelEventFired, "cancel event should only be fired once");
assert_false(hasCloseEventFired, "close event should be fired after cancel event");
hasCancelEventFired = true;
});
dialog.addEventListener("close", function() {
assert_true(true, "close event is fired");
assert_false(hasCloseEventFired, "close event should only be fired once");
assert_true(hasCancelEventFired, "cancel event should be fired before close event");
hasCloseEventFired = true;
done();
});
dialog.showModal();
test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
</script>
</body>
</html>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Test cancel event with preventDefault on cancel event for dialog element</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
</head>
<body>
<p>Test cancel event with preventDefault on cancel event for dialog element</p>
<dialog>
<p>Hello World</p>
</dialog>
<script>
setup({ single_test: true });
var hasCancelEventFired = false;
const dialog = document.querySelector("dialog");
const verify = () => {
assert_true(hasCancelEventFired, "cancel is fired");
done();
};
dialog.addEventListener("cancel", function(event) {
hasCancelEventFired = true;
event.preventDefault();
step_timeout(function() {
verify();
}, 0)
});
dialog.addEventListener("close", function() {
assert_true(false, "close event should not be fired");
});
dialog.showModal();
test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
</script>
</body>
</html>

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<title>Test dialog modal is closed by escape key with input focused</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
</head>
<body>
<p>Test dialog modal is closed by escape key with input focused</p>
<dialog id="dialog">
<p>Hello World</p>
</dialog>
<dialog id="dialogWithAutofocus">
<input autofocus/>
</dialog>
<script>
setup({ single_test: true });
const triggerEscKey = () => {
test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
};
/* Make sure we still cancel the dialog even if the input element is focused */
function runTestCancelWhenInputFocused() {
const dialog = document.getElementById("dialogWithAutofocus");
const input = document.querySelector("input");
dialog.addEventListener("close", function() {
assert_false(dialog.open, "dialog with input autofocused is closed");
done();
});
dialog.showModal();
assert_true(input == document.activeElement, "input element should be focused");
triggerEscKey();
}
const dialog = document.getElementById("dialog");
dialog.addEventListener("close", function() {
assert_false(dialog.open, "dialog closed");
step_timeout(function() {
runTestCancelWhenInputFocused();
}, 0);
});
dialog.showModal();
triggerEscKey();
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Test dialog modal is closed by escape key with select focused</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
</head>
<body>
<p>Test dialog modal is closed by escape key with select focused</p>
<dialog id="dialog">
<select>
<option value="one">one</option>
<option value="two">two</option>
</select>
</dialog>
<script>
setup({ single_test: true });
const dialog = document.getElementById("dialog");
const select = document.querySelector("select");
dialog.addEventListener("close", function() {
assert_false(dialog.open, "dialog with select is closed");
done();
});
dialog.showModal();
assert_true(select == document.activeElement, "select element should be focused");
test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
</script>
</body>
</html>

View file

@ -69,7 +69,7 @@ promise_test(async () => {
assert_false(dialog.open, "dialog should be closed now");
assert_not_equals(dialog.returnValue, "", "returnValue shouldn't be empty string");
assert_equals(dialog.returnValue, expectedReturnValue, "returnValue should be the offsets of the click");
}, "input image button should return the coordianates");
}, "input image button should return the coordinates");
promise_test(async () => {
const dialog = document.querySelector('dialog');
@ -99,5 +99,33 @@ promise_test(async () => {
assert_equals(dialog.returnValue, "", "dialog's returnValue remains the same");
}, "closing the dialog while submitting should stop the submission");
promise_test(async () => {
const dialog = document.querySelector('dialog');
dialog.returnValue = undefined;
dialog.showModal();
let submitEvent = false;
const dialogForm = document.getElementById('dialogForm');
dialogForm.onsubmit = function() {
submitEvent = true;
assert_false(dialog.open, "dialog should be closed");
assert_equals(dialog.returnValue, "", "dialog's returnValue remains the same");
};
const button = document.querySelector('button');
button.value = "sushi";
button.onclick = function() {
dialogForm.submit();
assert_false(dialog.open, "dialog should be closed now");
// The returnValue should be "" because there is no submitter
assert_equals(dialog.returnValue, "", "returnValue shouldn be empty string");
};
button.click();
assert_true(submitEvent, "Should have submit event");
assert_false(dialog.open, "dialog should be closed");
assert_equals(dialog.returnValue, "", "dialog's returnValue remains the same");
}, "calling form.submit() in click handler of submit button should start the submission synchronously");
</script>
</body>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Test cancel event with preventDefault on keydown event for dialog element</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
</head>
<body>
<p>Test cancel event with preventDefault on keydown event for dialog element</p>
<dialog>
<p>Hello World</p>
</dialog>
<script>
setup({ single_test: true });
var hasCancelEventFired = false;
const dialog = document.querySelector("dialog");
const verify = () => {
assert_false(hasCancelEventFired, "cancel should not be fired");
assert_true(hasKeydownEventFired, "document level keydown event should be fired");
done();
};
dialog.addEventListener("cancel", function(event) {
hasCancelEventFired = true;
});
document.addEventListener("keydown", function(event) {
hasKeydownEventFired = true;
event.preventDefault();
step_timeout(function() {
verify();
}, 0);
});
dialog.showModal();
test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
</script>
</body>
</html>

View file

@ -0,0 +1,5 @@
<!DOCTYPE html>
<script>
const dialog = document.createElement("dialog");
dialog.show();
</script>

View file

@ -27,4 +27,17 @@
d2.open = false;
assert_false(d2.hasAttribute("open"));
}, "On setting, the content open attribute must be removed if the IDL open attribute is set to false, and must be present if the IDL open attribute is set to true.");
async_test(function(t){
d2.open = true;
assert_true(d2.hasAttribute("open"));
d2.onclose = t.unreached_func("close event should not be fired when just setting the open attribute");
d2.open = false;
assert_false(d2.hasAttribute("open"));
// close event is async, give it a chance to be fired
t.step_timeout(function() {
t.done();
}, 0);
}, "On setting it to false, the close event should not be fired");
</script>

View file

@ -0,0 +1,5 @@
<!DOCTYPE html>
<body>
Test that ::backdrop is not shown for non-open or non-modal dialogs.
The test passes if there is no red shown.
</body>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<link rel="match" href="dialogs-with-no-backdrop-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
<style>
dialog::backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background: red;
}
#display-none-backdrop::backdrop {
display: none;
}
</style>
<body>
Test that ::backdrop is not shown for non-open or non-modal dialogs.
The test passes if there is no red shown.
<dialog id="never-opened-dialog"></dialog>
<dialog id="display-none-dialog" style="display: none"></dialog>
<dialog id="non-modal-dialog" style="visibility: hidden"></dialog>
<dialog id="display-none-backdrop" style="visibility: hidden"></dialog>
<dialog id="closed-dialog"></dialog>
<dialog id="removed-dialog"></dialog>
<script>
document.getElementById('display-none-dialog').showModal();
document.getElementById('non-modal-dialog').show();
document.getElementById('display-none-backdrop').showModal();
var closedDialog = document.getElementById('closed-dialog');
closedDialog.showModal();
closedDialog.close();
var removedDialog = document.getElementById('removed-dialog');
removedDialog.showModal();
removedDialog.parentNode.removeChild(removedDialog);
</script>
</body>

View file

@ -0,0 +1,13 @@
<!doctype html>
<style>
#non-modal {
position: static;
}
</style>
<p>Test that a non-top layer element doesn't share style with a top layer
element. The test passes if you see two boxes.</p>
<dialog id="non-modal" open></dialog>
<dialog id="modal"></dialog>
<script>
document.querySelector('#modal').showModal();
</script>

View file

@ -0,0 +1,15 @@
<!doctype html>
<link rel="match" href="dont-share-style-to-top-layer-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
position: static;
}
</style>
<p>Test that a non-top layer element doesn't share style with a top layer
element. The test passes if you see two boxes.</p>
<dialog open></dialog>
<dialog id="modal"></dialog>
<script>
document.querySelector('#modal').showModal();
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<style>
.green {
color: green;
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/106538">106538</a>: Top layer fails for inline elements</p>
<p>This tests that position 'static' no longer computes to 'absolute' for an
element that has been removed from the top layer. The test passes if you see
a single line of text.</p>
<span class="green">This is the span.</span>
<span class="green">This is the dialog following it.</span>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="element-removed-from-top-layer-has-original-position-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
.green {
color: green;
}
#right-dialog {
display: inline;
position: static;
border: none;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/106538">106538</a>: Top layer fails for inline elements</p>
<p>This tests that position 'static' no longer computes to 'absolute' for an
element that has been removed from the top layer. The test passes if you see
a single line of text.</p>
<span class="green">This is the span.</span>
<dialog class="green" id="right-dialog">This is the dialog following it.</dialog>
<script>
var dialog = document.getElementById('right-dialog');
dialog.showModal();
dialog.close();
dialog.show();
</script>
</body>
</html>

View file

@ -0,0 +1,156 @@
<!DOCTYPE html>
<meta charset=urf-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>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<body>
<input />
<dialog>
<button id="button1">This is a button1</button>
<button id="button2">This is a button2</button>
<button id="button3">This is a button3</button>
</dialog>
<script>
// Test focus is moved to the previously focused element
function test_move_to_previously_focused(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector('dialog');
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
dialog.close();
assert_equals(document.activeElement, input);
}
// Test focus is moved to the previously focused element with some complex dialog usage
async function test_move_to_previously_focused_with_complex_dialog_usage(showModal) {
const input = document.querySelector("input");
input.focus();
const dialog = document.querySelector('dialog');
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
const button1 = document.getElementById("button1");
const button2 = document.getElementById("button2");
const button3 = document.getElementById("button3");
await test_driver.click(button1);
await test_driver.click(button2);
await test_driver.click(button3);
dialog.close();
assert_equals(document.activeElement, input);
}
// 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');
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
dialog.close();
input.remove();
assert_equals(document.activeElement, document.body);
document.body.appendChild(input);
}
// Test focus is moved to shadow host if the previously
// focused element is a shadow node.
function test_move_to_shadow_host(showModal) {
const shadowHost = document.createElement("div");
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
shadowRoot.appendChild(document.createElement("input"));
document.body.appendChild(shadowHost);
const inputElement = shadowRoot.querySelector("input");
inputElement.focus();
assert_equals(document.activeElement, shadowHost);
assert_equals(shadowRoot.activeElement, inputElement);
const dialog = document.querySelector('dialog');
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
dialog.close();
assert_equals(document.activeElement, shadowHost);
assert_equals(shadowRoot.activeElement, inputElement);
}
// Test moving the focus doesn't scroll the viewport
function test_move_focus_dont_scroll_viewport(showModal) {
const outViewPortButton = document.createElement("button");
outViewPortButton.style.top = (window.innerHeight + 10).toString() + "px";
outViewPortButton.style.position = "absolute";
document.body.appendChild(outViewPortButton);
outViewPortButton.focus();
// Since the outViewPortButton is focused, so the viewport should be
// scrolled to it
assert_true(document.documentElement.scrollTop > 0 );
const dialog = document.querySelector('dialog');
if (showModal) {
dialog.showModal();
} else {
dialog.show();
}
window.scrollTo(0, 0);
assert_equals(document.documentElement.scrollTop, 0);
dialog.close();
assert_equals(document.documentElement.scrollTop, 0);
assert_equals(document.activeElement, outViewPortButton);
}
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)');
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)');
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');
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');
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');
</script>
</body>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<style>
body p, span {
-webkit-user-select: none;
user-select: none;
}
::backdrop {
display: none;
}
</style>
</head>
<body>
<p>Test that inert nodes are not painted as being selected. The test passes if
none of the text outside the dialog is highlighted when selected.</p>
<p>Although not shown as selected, the inert nodes are in window.getSelection()
and copied to the clipboard, which is the same behavior as user-select:
none (crbug.com/147490).</p>
<br><span>This text shouldn't be highlighted as selected.</span>
<dialog>
<div id="selectable">I'm selectable.</div>
</dialog>
<script>
dialog = document.querySelector('dialog');
dialog.showModal();
selectable = document.querySelector('#selectable');
window.getSelection().selectAllChildren(selectable);
</script>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="inert-node-is-not-highlighted-ref.html">
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#inert-subtrees">
<style>
::backdrop {
display: none;
}
</style>
</head>
<body>
<p>Test that inert nodes are not painted as being selected. The test passes if
none of the text outside the dialog is highlighted when selected.</p>
<p>Although not shown as selected, the inert nodes are in window.getSelection()
and copied to the clipboard, which is the same behavior as user-select:
none (crbug.com/147490).</p>
<br> <!-- Needed to the trigger the bug. -->
This text shouldn't be highlighted as selected.
<dialog>
<div id="selectable">I'm selectable.</div>
</dialog>
<script>
dialog = document.querySelector('dialog');
dialog.showModal();
document.execCommand('SelectAll');
</script>
</body>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<style>
.dialog-default-ua-style {
position: absolute;
overflow: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
border: solid;
padding: 1em;
background: white;
color: black;
}
#dialog {
margin: auto;
height: 100px;
width: 100px;
top: 100px;
z-index: 1000;
background: green;
}
#backdrop {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.1);
z-index: 100;
}
</style>
<body>
Test for the default user agent style of dialog::backdrop. The test passes if
there is a green box, above a very lightly translucent gray box spanning the
viewport.
<div id="backdrop"></div>
<div class="dialog-default-ua-style" id="dialog"></div>
</body>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<link rel="match" href="modal-dialog-backdrop-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#user-agent-level-style-sheet-defaults">
<style>
dialog {
top: 100px;
height: 100px;
width: 100px;
background: green;
}
</style>
<body>
Test for the default user agent style of dialog::backdrop. The test passes if
there is a green box, above a very lightly translucent gray box spanning the
viewport.
<dialog></dialog>
<script>
document.querySelector('dialog').showModal();
</script>
</body>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<title>Reference: Test that display: contents; on modal dialog & ::backdrop acts like display: block</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<p>Test passes if there is a green dialog</p>
<p>Dialog is display:block</p>
<p>Dialog::backdrop is display:block</p>
<dialog>Dialog Contents</dialog>
<style>
dialog {
background-color: green;
}
</style>
<script>
document.querySelector("dialog").showModal();
</script>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<title>Test that display: contents; on modal dialog & ::backdrop acts like display: block</title>
<meta charset="utf-8">
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<link rel="help" href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element">
<link rel="match" href="modal-dialog-display-contents-ref.html">
<p>Test passes if there is a green dialog</p>
<p>Dialog is display:<span id="computed-value"></span></p>
<p>Dialog::backdrop is display:<span id="computed-value-backdrop"></span></p>
<dialog>Dialog Contents</dialog>
<style>
dialog {
display: contents;
background-color: green;
}
dialog::backdrop {
display: contents;
}
</style>
<script>
dialog = document.querySelector("dialog");
dialog.showModal();
document.getElementById("computed-value").textContent = getComputedStyle(dialog).display;
document.getElementById("computed-value-backdrop").textContent = getComputedStyle(dialog, "::backdrop").display;
</script>
</html>

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<style>
#dialog {
position: absolute;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background: green;
}
#dialog-before {
position: absolute;
top: 0px;
}
#dialog-after {
position: absolute;
bottom: 0px;
}
#dialog-backdrop {
position: absolute;
top: 100px;
left: 300px;
height: 100px;
width: 100px;
background: green;
}
</style>
<body>
Test for a modal dialog with ::before, ::after, and ::backdrop. The test passes
if there are two green boxes, one with the texts "::before" and "::after" in it.
<div id="dialog">
<div id="dialog-before">::before</div>
<div id="dialog-after">::after</div>
</div>
<div id="dialog-backdrop"></div>
<script>
document.querySelector('dialog').showModal();
</script>
</body>

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<link rel="match" href="modal-dialog-generated-content-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
padding: 0px;
border: none;
margin: 0px;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background: green;
}
dialog::before {
content: '::before';
position: absolute;
top: 0px;
}
dialog::after {
content: '::after';
position: absolute;
bottom: 0px;
}
dialog::backdrop {
position: absolute;
top: 100px;
left: 300px;
height: 100px;
width: 100px;
background: green;
content: 'THIS TEXT SHOULD NOT BE SEEN';
}
dialog::backdrop::before {
content: '::backdrop::before';
position: absolute;
top: 0px;
background: red;
}
dialog::backdrop::after {
content: '::backdrop::after';
position: absolute;
bottom: 0px;
background: red;
}
</style>
<body>
Test for a modal dialog with ::before, ::after, and ::backdrop. The test passes
if there are two green boxes, one with the texts "::before" and "::after" in it.
<dialog></dialog>
<script>
document.querySelector('dialog').showModal();
</script>
</body>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<style>
dialog {
background: green;
border-color: green;
}
div {
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPAQMAAAABGAcJAAAAA1BMVEUAgACc+aWRAAAADElEQVR42mNgIAEAAAAtAAH7KhMqAAAAAElFTkSuQmCC);
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/103477">103477</a>: Make
NodeRenderingContext::parentRenderer and nextRenderer top layer aware
<p>The test passes if you see a green square near the top and green rectangle in the center of the viewport.
<div></div>
<dialog id="dialog"></dialog>
<script>
document.getElementById('dialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="modal-dialog-in-replaced-renderer-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
background: green;
border-color: green;
}
div {
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPAQMAAAABGAcJAAAAA1BMVEUAgACc+aWRAAAADElEQVR42mNgIAEAAAAtAAH7KhMqAAAAAElFTkSuQmCC);
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/103477">103477</a>: Make
NodeRenderingContext::parentRenderer and nextRenderer top layer aware
<p>The test passes if you see a green square near the top and green rectangle in the center of the viewport.
<div>
<dialog id="dialog"></dialog>
</div>
<script>
document.getElementById('dialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<style>
dialog {
background: green;
border-color: green;
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/103477">103477</a>: Make
NodeRenderingContext::parentRenderer and nextRenderer top layer aware
<p>The test passes if you see a green rectangle in the center of the viewport.
<dialog id="dialog"></dialog>
<script>
document.getElementById('dialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="modal-dialog-in-table-column-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
background: green;
border-color: green;
}
div {
display: table-column;
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/103477">103477</a>: Make
NodeRenderingContext::parentRenderer and nextRenderer top layer aware
<p>The test passes if you see a green rectangle in the center of the viewport.
<div>
<dialog id="dialog"></dialog>
</div>
<script>
document.getElementById('dialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<style>
dialog {
background: green;
border-color: green;
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/103477">103477</a>: Make
NodeRenderingContext::parentRenderer and nextRenderer top layer aware
<p>The test passes if you see a green rectangle in the center of the viewport.
<dialog id="dialog"></dialog>
<script>
document.getElementById('dialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="modal-dialog-sibling-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
background: green;
border-color: green;
}
</style>
</head>
<body>
<p>Bug <a href="http://webkit.org/b/103477">103477</a>: Make
NodeRenderingContext::parentRenderer and nextRenderer top layer aware
<p>The test passes if you see a green rectangle in the center of the viewport.
<div style="display: none" id="div"></div>
<dialog id="dialog"></dialog>
<script>
document.getElementById('dialog').showModal();
document.getElementById('dialog').offsetTop; // force a layout/renderer creation
document.getElementById('div').style.display = 'block';
</script>
</body>
</html>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/dialog.css">
<style>
.pseudodialog {
height: 100px;
width: 100px;
}
#bottomDialog {
background-color: blue;
top: 0px;
}
#topDialog {
background-color: green;
top: 50px;
left: 50px;
}
</style>
</head>
<body>
<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=105489">105489</a>: Elements must be reattached when inserted/removed from top layer
<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
<div id="bottomDialog" class="pseudodialog"></div>
<div id="topDialog" class="pseudodialog"></div>
</body>
</html>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="removed-element-is-removed-from-top-layer-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
height: 100px;
width: 100px;
}
::backdrop {
display: none;
}
#bottomDialog {
background-color: blue;
top: 231px;
}
#topDialog {
background-color: green;
top: 50px;
left: 50px;
}
</style>
</head>
<body>
<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=105489">105489</a>: Elements must be reattached when inserted/removed from top layer
<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
<dialog id="bottomDialog"></dialog>
<dialog id="topDialog"></dialog>
<script>
document.getElementById('topDialog').showModal();
var bottomDialog = document.getElementById('bottomDialog');
bottomDialog.showModal();
bottomDialog.offsetTop; // force a layout
var parent = bottomDialog.parentNode;
parent.removeChild(bottomDialog);
parent.appendChild(bottomDialog);
</script>
</body>
</html>

View file

@ -0,0 +1,16 @@
.pseudodialog {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: -moz-fit-content;
width: fit-content;
height: -moz-fit-content;
height: fit-content;
margin: auto;
border: solid;
padding: 1em;
background: white;
color: black;
}

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/dialog.css">
</head>
<body>
<p>
This tests that a modal dialog's containing block is in the initial containing block and that it is unaffected by
ancestor elements with overflow or opacity.
<div class="pseudodialog" style="position: absolute; top: 100px; height: 250px; width: 90%; background-color: yellow">
This dialog should be onscreen with a width of 90% of the page. It is the child of an narrow element
positioned off screen, but the containing block of a top layer element is the initial containing block, so its
position and percent lengths are relative to that.
</div>
<div class="pseudodialog" style="position: absolute; top: 200px; left: 0px; height: 100px; background-color: cyan">
This dialog should be unaffected by its ancestor with overflow. It should not be clipped.
</div>
<div class="pseudodialog" style="position: absolute; top: 250px; left: 0px; background-color: magenta">
This dialog should be unaffected by its ancestor with opacity.
</div>
</body>
</html>

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="top-layer-containing-block-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
::backdrop {
display: none;
}
</style>
</head>
<body>
<p>
This tests that a modal dialog's containing block is in the initial containing block and that it is unaffected by
ancestor elements with overflow or opacity.
<div style="position: absolute; top: 400px; opacity: 0.3">
<dialog id="opaqueDialog" style="position: absolute; top: 250px; left: 0px; background-color: magenta">
This dialog should be unaffected by its ancestor with opacity.
</dialog>
</div>
<div style="position: absolute; overflow: hidden; width: 500px; height: 150px; top: 400px; left: 300px">
<dialog id="unclippedDialog" style="position: absolute; top: 200px; left: 0px; height: 100px; background-color: cyan">
This dialog should be unaffected by its ancestor with overflow. It should not be clipped.
</dialog>
</div>
<div style="position: absolute; top: 1000px; left: 1000px; width: 20px;">
<dialog id="bottomDialog" style="position: absolute; top: 100px; height: 250px; width: 90%; background-color: yellow">
This dialog should be onscreen with a width of 90% of the page. It is the child of an narrow element
positioned off screen, but the containing block of a top layer element is the initial containing block, so its
position and percent lengths are relative to that.
</dialog>
</div>
<script>
document.getElementById('bottomDialog').showModal();
document.getElementById('unclippedDialog').showModal();
document.getElementById('opaqueDialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/dialog.css">
<style>
.pseudodialog {
height: 150px;
width: 150px;
}
</style>
</head>
<body>
This tests that a top layer element is not rendered if it, or an ancestor, has display: none.
It passes if you see a green rectangle stacked on top of a blue rectangle, and see no red rectangles.
<div class="pseudodialog" style="top: 50px; background-color: blue"></div>
<div class="pseudodialog" style="top: 100px; left: 50px; background-color: green"></div>
</body>
</html>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="top-layer-display-none-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
height: 150px;
width: 150px;
}
::backdrop {
display: none;
}
.red {
background-color: red;
top: 200px;
}
#bottomDialog {
background-color: blue;
top: 50px;
display: none;
}
#topDialog {
background-color: green;
top: 100px;
left: 50px;
}
</style>
</head>
<body>
This tests that a top layer element is not rendered if it, or an ancestor, has display: none.
It passes if you see a green rectangle stacked on top of a blue rectangle, and see no red rectangles.
<dialog id="hiddenDialog" class="red" style="display: none;"></dialog>
<div id="container">
<div>
<dialog id="displayNoneChild1" class="red"></dialog>
<dialog id="displayNoneChild2" class="red"></dialog>
</div>
</div>
<dialog id="bottomDialog"></dialog>
<dialog id="topDialog"></dialog>
<script>
document.getElementById('hiddenDialog').showModal();
document.getElementById('displayNoneChild1').showModal();
document.getElementById('container').style.display = 'none';
document.getElementById('displayNoneChild2').showModal();
// Test that stacking works even if an element is added to the top layer when it has no renderer.
document.getElementById('bottomDialog').showModal();
document.getElementById('topDialog').showModal();
document.getElementById('bottomDialog').style.display = 'block';
</script>
</body>
</html>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<style>
.pseudodialog {
height: 150px;
width: 150px;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
margin: auto;
border: solid;
padding: 1em;
background: white;
color: black;
}
</style>
</head>
<body>
This tests that top layer elements are stacked correctly even if nested in the DOM tree.
The test passes if you see no red rectangles and see 3 rectangles stacked in the following order (from bottom to top): yellow, blue, green.
<div class="pseudodialog" style="top: 100px; background-color: yellow"></div>
<div class="pseudodialog" style="top: 150px; left: 50px; background-color: blue"></div>
<div class="pseudodialog" style="top: 200px; left: 100px; background-color: green"></div>
</body>
</html>

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="top-layer-nesting-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
dialog {
height: 150px;
width: 150px;
}
::backdrop {
display: none;
}
#bottomDialog {
background-color: yellow;
top: 100px;
z-index: 1000;
}
#middleDialog {
background-color: blue;
top: 150px;
left: 50px;
z-index: -500;
}
#topDialog {
background-color: green;
top: 200px;
left: 100px;
z-index: -1000;
}
.red {
background-color: red;
top: 250px;
left: 0px;
}
</style>
</head>
<body>
This tests that top layer elements are stacked correctly even if nested in the DOM tree.
The test passes if you see no red rectangles and see 3 rectangles stacked in the following order (from bottom to top): yellow, blue, green.
<dialog id="topDialog">
<dialog id="middleDialog">
<dialog id="bottomDialog">
<dialog id="hiddenDialog" class="red">
<dialog id="hiddenDialogChild" class="red"></dialog>
</dialog>
</dialog>
</dialog>
</dialog>
<script>
document.getElementById('hiddenDialogChild').showModal();
document.getElementById('hiddenDialog').showModal();
document.getElementById('bottomDialog').showModal();
document.getElementById('middleDialog').showModal();
document.getElementById('topDialog').showModal();
document.getElementById('hiddenDialog').close();
</script>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!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

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<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="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=229317">
<style>
#parent {
opacity: 0;
}
dialog {
width: 100px;
height: 100px;
background: green;
}
</style>
<body>
<p>PASS if you see a green square</p>
<div id="parent">
<dialog></dialog>
</div>
<script>
document.querySelector("dialog").showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/dialog.css">
<style>
.pseudodialog {
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=105489">105489</a>: Elements must be reattached when inserted/removed from top layer
<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
<div class="pseudodialog" style="top: 100px; background-color: blue"></div>
<div class="pseudodialog" style="top: 150px; left: 50px; background-color: green"></div>
</body>
</html>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="top-layer-stacking-correct-order-remove-readd-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
<style>
dialog {
height: 100px;
width: 100px;
}
::backdrop {
display: none;
}
#bottomDialog {
background-color: blue;
top: 100px;
}
#topDialog {
background-color: green;
top: 150px;
left: 50px;
}
</style>
</head>
<body>
<p>Bug <a href="https://bugs.webkit.org/show_bug.cgi?id=105489">105489</a>: Elements must be reattached when inserted/removed from top layer
<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
<dialog id="topDialog"></dialog>
<dialog id="bottomDialog"></dialog>
<script>
var topDialog = document.getElementById('topDialog');
var bottomDialog = document.getElementById('bottomDialog');
topDialog.showModal();
bottomDialog.showModal();
topDialog.offsetTop; // force a layout
topDialog.close();
topDialog.showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/dialog.css">
<style>
.pseudodialog {
height: 150px;
width: 150px;
}
</style>
</head>
<body>
This tests top layer element stacking order after dynamically calling show/close and removal from the DOM tree.
The test passes if you see a green rectangle stacked on top of a blue rectangle, and see no red rectangles.
<div class="pseudodialog" style="top: 50px; background-color: blue"></div>
<div class="pseudodialog" style="top: 100px; left: 50px; background-color: green"></div>
</body>
</html>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="top-layer-stacking-dynamic-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
<style>
dialog {
height: 150px;
width: 150px;
}
::backdrop {
display: none;
}
.red {
background-color: red;
top: 200px;
}
#bottomDialog {
background-color: blue;
top: 50px;
}
#topDialog {
background-color: green;
top: 100px;
left: 50px;
}
</style>
</head>
<body>
This tests top layer element stacking order after dynamically calling show/close and removal from the DOM tree.
The test passes if you see a green rectangle stacked on top of a blue rectangle, and see no red rectangles.
<dialog id="topDialog"></dialog>
<dialog id="bottomDialog"></dialog>
<dialog id="removedDialog" class="red">
<dialog id="removedDialogChild" class="red"></dialog>
</dialog>
<script>
document.getElementById('topDialog').showModal();
var removedDialog = document.getElementById('removedDialog');
removedDialog.showModal();
document.getElementById('bottomDialog').showModal();
document.getElementById('removedDialogChild').showModal();
removedDialog.parentNode.removeChild(removedDialog);
document.getElementById('topDialog').close();
document.getElementById('topDialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="resources/dialog.css">
</head>
<style>
.box {
height: 150px;
width: 150px;
}
.container {
perspective: 500px;
border: 1px solid black;
background-color: magenta;
}
.transformed {
transform: rotateY(45deg);
background-color: cyan;
}
</style>
<body>
<div class="pseudodialog" style="position: fixed; top: 10px; z-index:3000">
This white box is the topmost modal dialog. It should be on top of everything.
</div>
<div style="position: absolute; top: 0px; z-index: 3; background-color: red; left: 0; right: 0; height: 200px;"></div>
<div class="pseudodialog" style="position: absolute; top: 50px; background-color: green; width: 75%; height: 400px; z-index:2000; overflow: auto;">
This green box is also a modal dialog. It should be rendered above the red and yellow regions.
<div class="container box">
<div class="transformed box">A transform within the dialog's subtree.</div>
</div>
<div class="box" style="position: absolute; top:300px; z-index: 2; background-color: cyan">
This shows z-index stacking within the dialog's subtree. The cyan box should be on top of the magenta one.
</div>
<div class="box" style="position: absolute; top:350px; left:50px; z-index: 1; background-color: magenta"></div>
<div style="position: fixed; top: 90px; left: 30px; background-color: green">This is part of the green dialog.</div>
</div>
<div style="position: absolute; top: 100px; left: 0px; right: 0px; height: 200em; background-color: yellow; z-index:1000">
</div>
</body>
</html>

View file

@ -0,0 +1,56 @@
<!DOCTYPE html>
<!-- This tests that top layer elements are rendered above z-indexed elements
and stacked in the correct order amongst themselves. Also, layer features like
transforms and z-index are tested inside a top layer element subtree. -->
<html>
<head>
<link rel="match" href="top-layer-stacking-ref.html">
<link rel="help" href="https://fullscreen.spec.whatwg.org/#new-stacking-layer">
<style>
.box {
height:150px;
width:150px;
}
::backdrop {
display: none;
}
.container {
perspective: 500px;
border: 1px solid black;
background-color: magenta;
}
.transformed {
transform: rotateY(45deg);
background-color: cyan;
}
</style>
</head>
<body>
<dialog id="hiddenDialog" style="display: none; color: red">This should not be displayed.</dialog>
<dialog id="topDialog" style="position: fixed; top: 10px; z-index: -10;">
This white box is the topmost modal dialog. It should be on top of everything.
</dialog>
<div style="position: absolute; top: 0px; z-index: 3; background-color: red; left: 0; right: 0; height: 200px;">
<dialog id="bottomDialog" style="position: absolute; top: 50px; background-color: green; width: 75%; height: 400px;">
This green box is also a modal dialog. It should be rendered above the red and yellow regions.
<div class="container box">
<div class="transformed box">A transform within the dialog's subtree.</div>
</div>
<div class="box" style="position: absolute; top:300px; z-index: 2; background-color: cyan">
This shows z-index stacking within the dialog's subtree. The cyan box should be on top of the magenta one.
</div>
<div class="box" style="position: absolute; top:350px; left:50px; z-index: 1; background-color: magenta"></div>
<div style="position: fixed; top: 90px; left: 30px; background-color: green">This is part of the green dialog.</div>
</dialog>
</div>
<div style="position: absolute; top: 100px; left: 0px; right: 0px; height: 200em; background-color: yellow; z-index:1000">
</div>
<script>
document.getElementById('bottomDialog').showModal();
document.getElementById('topDialog').showModal();
document.getElementById('hiddenDialog').showModal();
</script>
</body>
</html>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<button id=b1>This is an anchor button</button>
<popup id=p1 anchor=b1>This is a popup</popup>
<button id=b2 popup=p1>This button invokes the popup but isn't an anchor</button>
<script>
test(function() {
assert_equals(p1.anchor,b1);
}, "popup anchor IDL property returns the anchor element");
</script>

View file

@ -1,8 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Popup anchor nesting</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
@ -45,11 +45,9 @@
(async function() {
setup({ explicit_done: true });
popup1.show();
assert_true(popup1.open);
popup2.show();
assert_false(popup1.open);
assert_true(popup2.open);
assert_false(popup1.open,'Popups are not nested, so popup1 should close');
await clickOn(button1);
test(t => {
// Button1 is the anchor for popup1, and an ancestor of popup2.

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Popup keyboard focus behaviors</title>
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<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>
<button id=firstfocus>Button 1</button>
<popup>
<p>This is a popup without a focusable element</p>
</popup>
<button id=secondfocus>Button 2</button>
<script>
promise_test(async () => {
const b1 = document.getElementById('firstfocus');
const b2 = document.getElementById('secondfocus');
const popup = document.querySelector('popup');
b1.focus();
assert_equals(document.activeElement,b1);
popup.show();
assert_true(popup.open);
assert_equals(document.activeElement,b1);
// Tab once
await new test_driver.send_keys(document.body,'\uE004'); // Tab
assert_equals(document.activeElement, b2, 'Keyboard focus should skip the open popup');
popup.hide();
// Add a focusable button to the popup and make sure we can focus that
const button = document.createElement('button');
popup.appendChild(button);
b1.focus();
popup.show();
assert_equals(document.activeElement,b1);
// Tab once
await new test_driver.send_keys(document.body,'\uE004'); // Tab
assert_equals(document.activeElement, button, 'Keyboard focus should go to the contained button');
popup.hide();
}, "Popup should not be keyboard focusable");
</script>

View file

@ -0,0 +1,145 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Popup focus behaviors</title>
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<popup data-test='default behavior - popup is not focused' data-no-focus>
<p>This is a popup</p>
<button>first button</button>
</popup>
<popup data-test='autofocus popup' autofocus class=should-be-focused>
<p>This is a popup</p>
</popup>
<popup data-test='autofocus empty popup' autofocus class=should-be-focused></popup>
<popup data-test='autofocus popup with button' autofocus class=should-be-focused>
<p>This is a popup</p>
<button>button</button>
</popup>
<popup data-test='autofocus child'>
<p>This is a popup</p>
<button autofocus class=should-be-focused>autofocus button</button>
</popup>
<popup data-test='autofocus on tabindex=0 element'>
<p autofocus tabindex=0 class=should-be-focused>This is a popup with autofocus on a tabindex=0 element</p>
<button>button</button>
</popup>
<popup data-test='autofocus multiple children'>
<p>This is a popup</p>
<button autofocus class=should-be-focused>autofocus button</button>
<button autofocus>second autofocus button</button>
</popup>
<popup autofocus data-test='autofocus popup and multiple autofocus children' class=should-be-focused>
<p>This is a popup</p>
<button autofocus>autofocus button</button>
<button autofocus>second autofocus button</button>
</popup>
<popup delegatesfocus data-test='delegatesfocus popup'>
<p>This is a popup</p>
<button class=should-be-focused>first button should be focused</button>
<button>second button</button>
</popup>
<popup delegatesfocus data-test='delegatesfocus takes precedence over autofocus'>
<p>This is a popup</p>
<button class=should-be-focused>first button</button>
<button autofocus>autofocus button should NOT be focused</button>
</popup>
<popup delegatesfocus autofocus data-test='delegatesfocus takes precedence over autofocus 2'>
<p>This is a popup</p>
<button class=should-be-focused>first button</button>
<button>autofocus button should NOT be focused</button>
</popup>
<popup delegatesfocus data-test='delegatesfocus on empty popup has no effect' data-no-focus></popup>
<popup data-test='delegatesfocus on child has no effect' data-no-focus>
<p>This is a popup</p>
<button delegatesfocus>first button</button>
</popup>
<popup delegatesfocus data-test='delegatesfocus skips contained popups'>
<p>This is a popup</p>
<popup>
<button>Contained popup button</button>
</popup>
<button class=should-be-focused>first button</button>
<button>autofocus button should NOT be focused</button>
</popup>
<popup delegatesfocus data-test='delegatesfocus skips contained dialogs'>
<p>This is a popup</p>
<dialog>
<button>Contained dialog button</button>
</dialog>
<button class=should-be-focused>first button</button>
<button>autofocus button should NOT be focused</button>
</popup>
<style>
popup {
border: 2px solid black;
top:150px;
left:150px;
}
:focus-within { border: 5px dashed red; }
:focus { border: 5px solid lime; }
</style>
<script>
function activateAndVerify(popup) {
const testName = popup.getAttribute('data-test');
const priorFocus = document.createElement('button');
priorFocus.id = 'prior-focus';
document.body.appendChild(priorFocus);
let expectedFocusedElement = popup.matches('.should-be-focused') ? popup : popup.querySelector('.should-be-focused');
if (popup.hasAttribute('data-no-focus')) {
expectedFocusedElement = priorFocus;
}
test(t => {
t.add_cleanup(() => priorFocus.remove());
assert_true(!!expectedFocusedElement);
assert_false(popup.open);
priorFocus.focus();
assert_equals(document.activeElement,priorFocus);
// Directly show the popup:
popup.show();
assert_equals(document.activeElement, expectedFocusedElement, `${testName} activated by popup.show()`);
popup.hide();
// Use an activating element:
const button = document.createElement('button');
const popupId = 'popup-id';
assert_equals(document.querySelectorAll('#' + popupId).length,0);
document.body.appendChild(button);
t.add_cleanup(function() {
popup.removeAttribute('id');
button.remove();
});
popup.id = popupId;
button.setAttribute('popup', popupId);
priorFocus.focus();
button.click();
assert_equals(document.activeElement, expectedFocusedElement, `${testName} activated by button.click()`);
// Make sure we can directly focus the (already open) popup:
popup.focus();
assert_equals(document.activeElement, popup.hasAttribute('delegatesfocus') ? expectedFocusedElement : popup, `${testName} directly focus with popup.focus()`);
popup.hide();
}, "Popup focus test: " + testName);
}
document.querySelectorAll('body > popup').forEach(popup => activateAndVerify(popup));
</script>

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=author href="mailto:masonf@chromium.org">
No popup should be displayed here.<p>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popup-hidden-display-ref.tentative.html">
No popup should be displayed here.<p>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author href="mailto:masonf@chromium.org">
<div>This is a popup, which should be open upon load</div>
<style>
div {
/* Per spec: */
display: block;
position: fixed;
top: 0;
left: 0;
/* Per settings in test file: */
width: fit-content;
height: fit-content;
border: 1px solid;
padding: 1em;
background: -internal-light-dark(white, black);
color: -internal-light-dark(black, white);
}
</style>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popup-initiallyopen-display-ref.tentative.html">
<popup id=p1 initiallyopen>This is a popup, which should be open upon load</popup>
<popup id=p2 initiallyopen>This is a second popup with initiallyopen, which should NOT be open upon load</popup>
<style>
popup {
width: fit-content;
height: fit-content;
border: 1px solid;
padding: 1em;
background: white;
color: black;
}
#p1 {
top:0;
}
#p2 {
top:100px;
}
</style>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<popup id=p1 initiallyopen>This is a popup, which should be open upon load</popup>
<popup id=p2 initiallyopen>This is a second popup with initiallyopen, which should NOT be open upon load</popup>
<popup id=p3>Also not visible</popup>
<script>
test(function(){
assert_true(p1.open,'initiallyopen should open the popup');
assert_true(p1.hasAttribute('initiallyopen'));
assert_true(p1.initiallyOpen,'initiallyopen should be reflected in the IDL attribute');
assert_false(p2.open, 'Only the first popup with initiallyopen should be open on load');
assert_true(p2.hasAttribute('initiallyopen'),'initiallyopen should be present/true, even if not opened');
assert_true(p2.initiallyOpen,'initiallyopen should be present/true, even if not opened');
assert_false(p3.open);
p3.setAttribute('initiallyopen','');
assert_false(p3.open, 'Changing initiallyopen should not affect open status');
assert_true(p3.hasAttribute('initiallyopen'));
assert_true(p3.initiallyOpen,'initiallyopen should still reflect to IDL');
p1.removeAttribute('initiallyopen');
assert_true(p1.open,'removing initiallyopen should not close the popup');
assert_false(p1.hasAttribute('initiallyopen'),'...but it should reflect to IDL');
}, "The initiallyopen attribute should affect page load only");
</script>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popup-hidden-display-ref.tentative.html">
No popup should be displayed here.<p>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Popup invoking attribute</title>
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<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>
<button id=b1 popup=p1>Open Popup 1</button>
<popup id=p1 anchor=b1><p>This is popup #1</p></popup>
<style>
popup { border: 5px solid red; }
</style>
<script>
function clickOn(element) {
const actions = new test_driver.Actions();
return actions.pointerMove(0, 0, {origin: element})
.pointerDown({button: actions.ButtonType.LEFT})
.pointerUp({button: actions.ButtonType.LEFT})
.send();
}
const popup1 = document.querySelector('#p1');
const button1 = document.querySelector('#b1');
promise_test(async () => {
assert_false(popup1.open);
await clickOn(button1);
assert_true(popup1.open);
popup1.hide();
assert_false(popup1.open);
button1.click();
assert_true(popup1.open);
}, "Basic test of the 'popup' attribute on a button");
</script>

View file

@ -2,8 +2,8 @@
<html lang="en">
<meta charset="utf-8" />
<title>Popup light dismiss on scroll</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Popup light dismiss behavior</title>
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<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>
<button popup=popup>Popup 1</button>
<popup id=popup><span>Inside popup 1</span></popup>
<style>
popup { border: 5px solid red; top: 50px; }
</style>
<script>
const popup = document.querySelector('#popup');
function waitForHide() {
return new Promise(function(resolve) {
popup.addEventListener('hide', () => resolve(), {'once': true});
});
}
promise_test(async () => {
return new Promise(async resolve => {
popup.show();
assert_true(popup.open,'popup should be open');
popup.style.width = "250px";
assert_true(popup.open,'popup should be hidden asynchronously');
await waitForHide(); // Wait for the popup to be hidden
assert_false(popup.open,'popup should close when resized');
popup.style.width = ""; // Reset
resolve();
});
},'Popup should be closed by an explicit resize of the popup');
promise_test(async () => {
return new Promise(async resolve => {
popup.show();
assert_true(popup.open,'popup should be open');
const popupText = popup.querySelector('span');
const originalText = popupText.textContent;
popupText.textContent = "This is a test, which is longer than the original";
assert_true(popup.open,'popup should be hidden asynchronously');
await waitForHide(); // Wait for the popup to be hidden
assert_false(popup.open,'popup should close when text content forces its size to change');
popupText.textContent = originalText; // Reset
resolve();
});
},'Popup should be closed by an implicit resize of the popup');
</script>

View file

@ -1,17 +1,14 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Popup light dismiss behavior</title>
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<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>
<body>
<button id=b1 onclick='p1.show()'>Popup 1</button>
<span id=outside>Outside all popups</span>
<popup id=p1 anchor=b1>
@ -22,9 +19,33 @@
<span id=inside2>Inside popup 2</span>
</popup>
<button id=b3 popup=p3>Popup 3 - button 3
<popup id=p4>Inside popup 4</popup>
</button>
<popup id=p3>Inside popup 3</popup>
<button id=b4 popup=p3>Popup 3 - button 4
<popup id=p5>Inside popup 5</popup>
</button>
<popup id=p6>Inside popup 6
<div style="height:2000px;background:lightgreen"></div>
Bottom of popup6
</popup>
<button popup=p6>Popup 6</button>
<style>
#p1 { top:50px; }
#p2 { top:50px; left:250px; }
#p3 { top:150px;}
#p4 { top:150px; left:250px;}
#p5 { top:250px;}
#p6 {
top: 50px;
left:150px;
width: 300px;
height: 300px;
overflow-y: scroll;
}
popup { border: 5px solid red; }
</style>
@ -44,6 +65,12 @@
const outside = document.querySelector('#outside');
const inside1 = document.querySelector('#inside1');
const inside2 = document.querySelector('#inside2');
const button3 = document.querySelector('#b3');
const button4 = document.querySelector('#b4');
const popup3 = document.querySelector('#p3');
const popup4 = document.querySelector('#p4');
const popup5 = document.querySelector('#p5');
const popup6 = document.querySelector('#p6');
(async function() {
setup({ explicit_done: true });
@ -100,13 +127,63 @@
assert_equals(popup2HideCount,p2HideCount+1);
},'Clicking inside a parent popup should close child popup');
assert_true(popup1.open);
p1HideCount = popup1HideCount;
await clickOn(button1);
test(t => {
assert_true(popup1.open);
assert_true(popup1.open,'popup1 not open');
assert_equals(popup1HideCount,p1HideCount);
popup1.hide(); // Cleanup
assert_false(popup1.open);
},'Clicking on anchor element shouldn\'t close its popup');
await clickOn(button3);
test(t => {
assert_true(popup3.open,'invoking element should open popup');
popup4.show();
assert_true(popup4.open);
assert_true(popup3.open);
},'An invoking element should be part of the ancestor chain');
await clickOn(button3);
assert_true(popup3.open);
assert_false(popup4.open);
assert_false(popup5.open);
popup5.show();
test(t => {
assert_true(popup5.open);
assert_false(popup3.open);
},'An invoking element that was not used to invoke the popup should NOT be part of the ancestor chain');
popup1.show();
popup2.show(); // Popup1 is an ancestral element for popup2.
assert_true(popup1.open);
assert_true(popup2.open);
const drag_actions = new test_driver.Actions();
// Drag *from* popup2 *to* popup1 (its ancestor).
await drag_actions.pointerMove(0,0,{origin: popup2})
.pointerDown({button: drag_actions.ButtonType.LEFT})
.pointerMove(0,0,{origin: popup1})
.pointerUp({button: drag_actions.ButtonType.LEFT})
.send();
test(t => {
assert_true(popup1.open,'popup1 should be open');
assert_true(popup2.open,'popup1 should be open');
popup1.hide();
assert_false(popup2.open);
},'Dragging from an open popup outside an open popup should leave the popup open');
popup6.show();
assert_equals(popup6.scrollTop,0,'popup6 should start non-scrolled');
await new test_driver.Actions()
.scroll(0, 0, 0, 50, {origin: popup6})
.send();
test(t => {
assert_true(popup6.open,'popup6 should stay open');
assert_equals(popup6.scrollTop,50,'popup6 should be scrolled');
popup6.hide();
},'Scrolling within a popup should not close the popup');
done();
})();
</script>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=author href="mailto:masonf@chromium.org">
<div>This is a popup</div>
@ -16,7 +16,7 @@
height: fit-content;
border: 1px solid;
padding: 1em;
background: -internal-light-dark(white, black);
color: -internal-light-dark(black, white);
background: white;
color: black;
}
</style>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popup-open-display-ref.tentative.html">
<popup>This is a popup</popup>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=author href="mailto:masonf@chromium.org">
<popup id=p1>This is popup 1<div id=anchor2></div></popup>
<popup id=p2 anchor=anchor2>This is popup 2<div id=anchor3></div></popup>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popup-open-overflow-display-ref.tentative.html">
<div id=container>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@ -69,18 +69,15 @@
<popup anchor=t2b1 style="top: 400px;">
<p>Popup 1</p>
<button id=t2b2 onclick='showPopup("test2",1)'>Test 2 Popup 2</button>
<my-element>
<template shadowroot=open>
<popup anchor=t2b2 style="top: 400px;">
<p>This popup can never be visible:</p>
<p>Hiding this popup will hide *all* open popups,</p>
<p>because t2b2 doesn't exist in this context.</p>
<p>And since popup 1 is not shown, it is display:none,</p>
<p>which means no child content is shown at all.</p>
</popup>
</template>
</my-element>
</popup>
<my-element>
<template shadowroot=open>
<popup anchor=t2b2 style="top: 400px;">
<p>Hiding this popup will hide *all* open popups,</p>
<p>because t2b2 doesn't exist in this context.</p>
</popup>
</template>
</my-element>
</div>
<script>
@ -90,10 +87,10 @@
assert_true(popup1.open);
assert_true(popupVisible(popup1));
popup2.show();
assert_false(popup1.open); // P1 was closed by P2
assert_true(popup2.open); // P2 thinks it is open
assert_false(popupVisible(popup1)); // But neither is visible
assert_false(popupVisible(popup2));
assert_false(popup1.open, 'popup1 open'); // P1 was closed by P2
assert_false(popupVisible(popup1), 'popup1 visible');
assert_true(popup2.open, 'popup2 open'); // P2 is open
assert_true(popupVisible(popup2), 'popup2 visible');
}, "anchor references do not cross shadow boundaries");
</script>
@ -103,7 +100,7 @@
<template shadowroot=open>
<button id=t3b1 onclick='showPopup("test3",0)'>Test 3 Popup 1</button>
<popup anchor=t3b1>
<p>This popup will be hidden when popup2 shows.</p>
<p>This popup will stay open when popup2 shows.</p>
<slot></slot>
</popup>
</template>
@ -118,15 +115,17 @@
popup1.show();
assert_true(popup1.open);
assert_true(popupVisible(popup1));
// Showing popup2 will close popup1, since it is not a DOM
// Showing popup2 should not close popup1, since it is a flat
// tree ancestor of popup2's anchor button.
popup2.show();
assert_true(popup2.open);
assert_true(popupVisible(popup2));
assert_true(popup1.open);
assert_true(popupVisible(popup1));
popup1.hide();
assert_false(popup2.open);
assert_false(popup1.open);
assert_false(popupVisible(popup1));
popup2.hide();
}, "anchor references use the DOM tree not the flat tree");
}, "anchor references use the flat tree not the DOM tree");
</script>
@ -151,9 +150,9 @@
popup1.show();
popup2.show();
// Both 1 and 2 should be open at this point.
assert_true(popup1.open);
assert_true(popup1.open, 'popup1 not open');
assert_true(popupVisible(popup1));
assert_true(popup2.open);
assert_true(popup2.open, 'popup2 not open');
assert_true(popupVisible(popup2));
// This should hide both of them.
popup1.hide();

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" href="mailto:masonf@chromium.org">
<div id=popup>
Inside popup
<div class=z style="z-index: 2; background:lightgreen">z-index 2
<div class=z style="z-index: 3; background:lightblue; left: 20px;">z-index 3</div>
<div class=z style="z-index: 1; background:pink; top:-20px; left: 10px;">z-index 1</div>
</div>
<div class=z style="background:green; top:-100px; left: 250px; width: 100px;">Outside</div>
Bottom of popup
</div>
<style>
#popup {
/* Per spec: */
display: block;
position: fixed;
top: 0;
left: 0;
/* Per settings in test file: */
width: 200px;
height: 230px;
border: 1px solid red;
padding: 1em;
background: white;
color: black;
top:50px;
left:50px;
}
.z {
position: relative;
border: 1px solid black;
padding: 1em;
}
</style>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popup-stacking-context-ref.tentative.html">
<popup>
Inside popup
<div class=z style="z-index: 2; background:lightgreen">z-index 2
<div class=z style="z-index: 3; background:lightblue; left: 20px;">z-index 3</div>
<div class=z style="z-index: 1; background:pink; top:-20px; left: 10px;">z-index 1</div>
</div>
<div class=z style="background:green; top:-100px; left: 250px; width: 100px;">Outside</div>
Bottom of popup
</popup>
<style>
popup {
width: 200px;
height: 230px;
border: 1px solid red;
padding: 1em;
background: white;
color: black;
top:50px;
left:50px;
}
.z {
position: relative;
border: 1px solid black;
padding: 1em;
}
</style>
<script>
document.querySelector('popup').show();
</script>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="Mason Freed" href="mailto:masonfreed@chromium.org">
<link rel=help href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md">
<link rel="author" href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>