This commit is contained in:
Matt Falkenhagen 2013-07-26 10:29:52 +09:00
Родитель 821568ef6b
Коммит 7429e58f8a
13 изменённых файлов: 886 добавлений и 3 удалений

27
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,27 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Просмотреть файл

@ -1,4 +1,40 @@
dialog-polyfill
===============
dialog-polyfill.js is a polyfill for `<dialog>`.
Polyfill for the &lt;dialog> element
### Example
<head>
<script src="dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="dialog-polyfill.css">
</head>
<body>
<dialog>I'm a dialog!</dialog>
<script>
var dialog = document.querySelector('dialog');
dialogPolyfill.registerDialog(dialog);
// Now dialog acts like a native <dialog>.
dialog.showModal();
</script>
</body>
### ::backdrop
In native `<dialog>`, the backdrop is a pseudo-element:
#mydialog::backdrop {
background-color: green;
}
With the polyfill, you do it like:
#mydialog + .backdrop {
background-color: green;
}
### Known limitations
- Modality isn't bulletproof (you can tab to inert elements)
- The polyfill `<dialog>` should always be a child of `<body>`
- Polyfill top layer stacking can be ruined by playing with z-index.
- The polyfill `<dialog>` does not retain dynamically set CSS top/bottom values
upon close

16
dialog-polyfill.css Normal file
Просмотреть файл

@ -0,0 +1,16 @@
dialog {
position: absolute;
left: 0; right: 0;
margin: auto;
border: solid;
padding: 1em;
background: white;
color: black;
display: none;
}
.backdrop {
position: absolute;
background: rgba(0,0,0,0.1);
}

185
dialog-polyfill.js Normal file
Просмотреть файл

@ -0,0 +1,185 @@
var dialogPolyfill = {}
dialogPolyfill.reposition = function(element) {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;
element.style.top = topValue + 'px';
element.dialogPolyfillInfo.isTopOverridden = true;
}
dialogPolyfill.inNodeList = function(nodeList, node) {
for (var i = 0; i < nodeList.length; ++i) {
if (nodeList[i] == node)
return true;
}
return false;
}
dialogPolyfill.isInlinePositionSetByStylesheet = function(element) {
for (var i = 0; i < document.styleSheets.length; ++i) {
var styleSheet = document.styleSheets[i];
var cssRules = null;
// Some browsers throw on cssRules.
try {
cssRules = styleSheet.cssRules;
} catch (e) {}
if (!cssRules)
continue;
for (var j = 0; j < cssRules.length; ++j) {
var rule = cssRules[j];
var selectedNodes = document.querySelectorAll(rule.selectorText);
if (!dialogPolyfill.inNodeList(selectedNodes, element))
continue;
var cssTop = rule.style.getPropertyValue('top');
var cssBottom = rule.style.getPropertyValue('bottom');
if ((cssTop && cssTop != 'auto') || (cssBottom && cssBottom != 'auto'))
return true;
}
}
return false;
}
dialogPolyfill.needsCentering = function(dialog) {
var computedStyle = getComputedStyle(dialog);
if (computedStyle.position != 'absolute')
return false;
// We must determine whether the top/bottom specified value is non-auto. In
// WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but
// Firefox returns the used value. So we do this crazy thing instead: check
// the inline style and then go through CSS rules.
if ((dialog.style.top != 'auto' && dialog.style.top != '') ||
(dialog.style.bottom != 'auto' && dialog.style.bottom != ''))
return false;
return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);
}
dialogPolyfill.showDialog = function(isModal) {
if (this.open) {
throw 'InvalidStateError: showDialog called on open dialog';
}
this.open = true;
this.style.display = 'block';
if (dialogPolyfill.needsCentering(this))
dialogPolyfill.reposition(this);
if (isModal) {
this.dialogPolyfillInfo.modal = true;
dialogPolyfill.dm.pushDialog(this);
}
};
dialogPolyfill.close = function(retval) {
if (!this.open)
throw new InvalidStateError;
this.open = false;
this.style.display = 'none';
// This won't match the native <dialog> exactly because if the user sets top
// on a centered polyfill dialog, that top gets thrown away when the dialog is
// closed. Not sure it's possible to polyfill this perfectly.
if (this.dialogPolyfillInfo.isTopOverridden) {
this.style.top = 'auto';
}
if (this.dialogPolyfillInfo.modal) {
dialogPolyfill.dm.removeDialog(this);
}
if (typeof retval != 'undefined')
return retval;
}
dialogPolyfill.registerDialog = function(element) {
element.show = dialogPolyfill.showDialog.bind(element, false);
element.showModal = dialogPolyfill.showDialog.bind(element, true);
element.close = dialogPolyfill.close.bind(element);
element.dialogPolyfillInfo = {};
};
// The overlay is used to simulate how a modal dialog blocks the document. The
// blocking dialog is positioned on top of the overlay, and the rest of the
// dialogs on the pending dialog stack are positioned below it. In the actual
// implementation, the modal dialog stacking is controlled by the top layer,
// where z-index has no effect.
TOP_LAYER_ZINDEX = 100000;
MAX_PENDING_DIALOGS = 100000;
dialogPolyfill.DialogManager = function() {
this.pendingDialogStack = [];
this.overlay = document.createElement('div');
this.overlay.style.width = '100%';
this.overlay.style.height = '100%';
this.overlay.style.position = 'fixed';
this.overlay.style.left = '0px';
this.overlay.style.top = '0px';
this.overlay.style.background = 'rgba(0,0,0,0.0)';
this.overlay.addEventListener('click', function(e) {
var redirectedEvent = document.createEvent('MouseEvents');
redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,
e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,
e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
document.body.dispatchEvent(redirectedEvent);
});
}
dialogPolyfill.dm = new dialogPolyfill.DialogManager();
dialogPolyfill.DialogManager.prototype.blockDocument = function() {
if (!document.body.contains(this.overlay))
document.body.appendChild(this.overlay);
}
dialogPolyfill.DialogManager.prototype.unblockDocument = function() {
document.body.removeChild(this.overlay);
}
dialogPolyfill.DialogManager.prototype.updateStacking = function() {
if (this.pendingDialogStack.length == 0) {
this.unblockDocument();
return;
}
this.blockDocument();
var zIndex = TOP_LAYER_ZINDEX;
for (var i = 0; i < this.pendingDialogStack.length; i++) {
if (i == this.pendingDialogStack.length - 1)
this.overlay.style.zIndex = zIndex++;
var dialog = this.pendingDialogStack[i];
dialog.dialogPolyfillInfo.backdrop.style.zIndex = zIndex++;
dialog.style.zIndex = zIndex++;
}
}
dialogPolyfill.DialogManager.prototype.pushDialog = function(dialog) {
if (this.pendingDialogStack.length >= MAX_PENDING_DIALOGS) {
throw "Too many modal dialogs";
}
var backdrop = document.createElement('div');
backdrop.classList.add('backdrop');
backdrop.addEventListener('click', function(e) {
var redirectedEvent = document.createEvent('MouseEvents');
redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,
e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,
e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
dialog.dispatchEvent(redirectedEvent);
});
dialog.parentNode.insertBefore(backdrop, dialog.nextSibling);
dialog.dialogPolyfillInfo.backdrop = backdrop;
this.pendingDialogStack.push(dialog);
this.updateStacking();
}
dialogPolyfill.DialogManager.prototype.removeDialog = function(dialog) {
var index = this.pendingDialogStack.indexOf(dialog);
if (index == -1)
return;
this.pendingDialogStack.splice(index, 1);
var backdrop = dialog.dialogPolyfillInfo.backdrop;
backdrop.parentNode.removeChild(backdrop);
dialog.dialogPolyfillInfo.backdrop = null;
this.updateStacking();
}

43
tests/backdrop.html Normal file
Просмотреть файл

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<style>
dialog {
height: 100px;
width: 100px;
}
.backdrop {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0,255,0,0.5);
}
</style>
</head>
<body>
<p>Test for backdrop. The test passes if you see a green background behind the
box.</p>
<div id="console"></div>
<dialog></dialog>
<button id="inert-button">Can't click me</button>
<script>
function writeToConsole(s) {
var console = document.getElementById('console');
var span = document.createElement('span');
span.textContent = s;
console.appendChild(span);
console.appendChild(document.createElement('br'));
}
var dialog = document.querySelector('dialog');
dialogPolyfill.registerDialog(dialog);
dialog.showModal();
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<style>
dialog {
width: 100px;
}
</style>
</head>
<body>
<p>Test that dialog is centered in the viewport. The test passes if you see a
box in the center of the screen.</p>
<div id="console"></div>
<dialog></dialog>
<script>
function writeToConsole(s) {
var console = document.getElementById('console');
var span = document.createElement('span');
span.textContent = s;
console.appendChild(span);
console.appendChild(document.createElement('br'));
}
function checkCentered(dialog) {
var expectedTop = (window.innerHeight - dialog.offsetHeight) / 2;
var expectedLeft = (window.innerWidth - dialog.offsetWidth) / 2;
var rect = dialog.getBoundingClientRect();
if (rect.top == expectedTop && rect.left == expectedLeft) {
writeToConsole('SUCCESS');
} else {
writeToConsole('FAIL: expected dialog top,left to be ' +
expectedTop + ',' + expectedLeft + ' and was actually ' +
rect.top + ',' + rect.left);
}
}
var dialog = document.querySelector('dialog');
dialogPolyfill.registerDialog(dialog);
dialog.show();
checkCentered(dialog);
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<style>
body {
height: 10000px;
}
dialog {
width: 100px;
}
#console {
position: fixed;
}
#ruler {
position: absolute;
left: 0;
width: 100%;
}
</style>
</head>
<body>
<p>Test that dialog is recentered if reopened. The test passes if you see a
box in the center of the screen.</p>
<div id="ruler"></div>
<div id="console"></div>
<dialog></dialog>
<script>
function writeToConsole(s) {
var console = document.getElementById('console');
var span = document.createElement('span');
span.textContent = s;
console.appendChild(span);
console.appendChild(document.createElement('br'));
}
function windowWidthMinusScrollbar() {
return document.getElementById('ruler').offsetWidth;
}
function checkCentered(dialog) {
var expectedTop = (window.innerHeight - dialog.offsetHeight) / 2;
var expectedLeft = (windowWidthMinusScrollbar() - dialog.offsetWidth) / 2;
var rect = dialog.getBoundingClientRect();
if (rect.top == expectedTop && rect.left == expectedLeft) {
writeToConsole('SUCCESS');
} else {
writeToConsole('FAIL: expected dialog top,left to be ' +
expectedTop + ',' + expectedLeft + ' and was actually ' +
rect.top + ',' + rect.left);
}
}
var dialog = document.querySelector('dialog');
dialogPolyfill.registerDialog(dialog);
dialog.show();
dialog.close();
window.scrollTo(0, 500);
dialog.show();
checkCentered(dialog);
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,272 @@
<!DOCTYPE html>
<html>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<style>
#close-button {
position: absolute;
top: 7px;
right: 7px;
height: 14px;
width: 14px;
margin: 0;
background-image: url('resources/close_dialog.png');
}
#close-button:hover {
background-image: url('resources/close_dialog_hover.png');
}
dialog {
width: 50%;
-webkit-border-radius: 3px;
-webkit-box-orient: vertical;
opacity: 0;
background: white;
box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0,0,0,0.15);
color: #333;
min-width: 400px;
padding: 0;
z-index: 100;
border: 0;
padding: 15px;
}
dialog + .backdrop {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
dialog.no-backdrop + .backdrop {
display: none;
}
.dialog-setting {
margin: 30px;
}
/* keyframes used to pulse the overlay */
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1);
}
40% {
-webkit-transform: scale(1.05);
}
60% {
-webkit-transform: scale(1.05);
}
100% {
-webkit-transform: scale(1);
}
}
.pulse {
-webkit-animation-duration: 180ms;
-webkit-animation-iteration-count: 1;
-webkit-animation-name: pulse;
-webkit-animation-timing-function: ease-in-out;
}
#messages {
background-color: red;
}
body {
font-family: sans-serif;
}
#open-button {
position: fixed;
bottom: 0;
left: 0;
background-color: lightgray;
border: 1px solid;
margin: 10px;
padding: 15px;
}
#open-button:active {
background-color: lime;
margin: 9px;
}
#backdrop {
display: none;
position: fixed;
top:0;
right:0;
bottom:0;
left:0;
background: rgba(0,0,0,0.5);
z-index: 10;
}
.post {
margin: 10px;
padding: 5px;
border: 2px solid;
}
.post-buttons {
margin: 5px;
text-align: right;
}
.post-button:hover {
color: green;
font-weight: bold;
}
</style>
<body>
<div id="messages"></div>
<dialog id="dialog">
<h3>Reshare</h3>
<input type="text" style="width: 75%" value="I am resharing this."><br>
<div class="dialog-setting">
<input id="click-outside-to-close" type="checkbox">
<label for="click-outside-to-close">Close dialog upon clicking outside</label>
</div>
<div class="dialog-setting">
<input id="enable-backdrop" type="checkbox" checked>
<label for="enable-backdrop">Enable ::backdrop</label>
</div>
<div id="close-button"></div>
</dialog>
<div id="post-container"></div>
<script>
var dialog = document.getElementById('dialog');
dialogPolyfill.registerDialog(dialog);
function createPostButton(container, text) {
var link = document.createElement('a');
link.href = 'javascript:void(0)';
link.textContent = text;
link.className = 'post-button';
container.appendChild(link);
var span = document.createElement('span');
span.textContent = ' ';
container.appendChild(span);
return link;
}
SampleText = 'From this spot I rise not, valiant knight, until your ' +
'courtesy grants me the boon I seek, one that will redound ' +
'to your praise and the benefit of the human race.';
function createPost(container) {
var post = document.createElement('div');
post.className = 'post';
var postContent = document.createElement('div');
postContent.className = 'post-content';
postContent.textContent = SampleText;
post.appendChild(postContent);
var postButtons = document.createElement('div');
postButtons.className = 'post-buttons';
post.appendChild(postButtons);
var reshare = createPostButton(postButtons, 'Reshare');
reshare.addEventListener('click', openDialog);
var reply = createPostButton(postButtons, 'Reply');
reply.addEventListener('click', openDialog);
createPostButton(postButtons, 'Enjoyed this post');
container.appendChild(post);
return post;
}
function initPosts() {
var container = document.getElementById('post-container');
for (var i = 0; i < 25; ++i) {
var post = createPost(container);
}
}
function shouldCloseDialogOnClickOutside() {
return document.getElementById('click-outside-to-close').checked;
}
function closeDialog() {
if (dialog.open)
dialog.close();
}
function computeCenteredTop(dialog) {
dialog.style.top = 'auto';
dialog.style.webkitTransition = '';
dialog.showModal();
var computedTopPx = window.getComputedStyle(dialog).top;
var computedTop = parseInt(computedTopPx.substring(0, computedTopPx.length - 2), 10);
dialog.close();
return computedTop;
}
function openDialog() {
centerTop = computeCenteredTop(dialog);
dialog.style.top = window.scrollY + 'px';
dialog.style.opacity = 0;
dialog.style.webkitTransition = 'all 250ms ease';
dialog.showModal();
dialog.style.top = centerTop + 'px';
dialog.style.opacity = 1;
}
function pulseDialog() {
dialog.classList.add('pulse');
dialog.addEventListener('webkitAnimationEnd', function(e) {
dialog.classList.remove('pulse');
});
}
function clickedInDialog(mouseEvent) {
var rect = dialog.getBoundingClientRect();
return rect.top <= mouseEvent.clientY && mouseEvent.clientY <= rect.top + rect.height
&& rect.left <= mouseEvent.clientX && mouseEvent.clientX <= rect.left + rect.width;
}
function handleClickOutsideDialog() {
if (!shouldCloseDialogOnClickOutside()) {
pulseDialog();
return
}
closeDialog();
}
document.body.addEventListener('keydown', function(e) {
if (e.keyCode == 27)
closeDialog();
});
var enableBackdrop = document.getElementById('enable-backdrop');
enableBackdrop.addEventListener('change', function(e) {
if (document.getElementById('enable-backdrop').checked)
dialog.classList.remove('no-backdrop');
else
dialog.classList.add('no-backdrop');
// FIXME: Without this ::backdrop is not redrawn. crbug.com/258759
dialog.close();
dialog.showModal();
});
var closeButton = document.getElementById('close-button');
closeButton.addEventListener('click', function(e) { closeDialog(); });
document.body.addEventListener('click', function(e) {
if (!dialog.open)
return;
if (e.target != document.body)
return;
handleClickOutsideDialog();
});
dialog.addEventListener('click', function(e) {
if (clickedInDialog(e))
return;
handleClickOutsideDialog();
});
initPosts();
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<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>
</head>
<body>
Test for modal dialog and 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');
dialogPolyfill.registerDialog(topDialog);
var middleDialog = document.getElementById('middle');
dialogPolyfill.registerDialog(middleDialog);
var bottomDialog = document.getElementById('bottom');
dialogPolyfill.registerDialog(bottomDialog);
topDialog.showModal();
bottomDialog.showModal();
topDialog.close(); // Just to shuffle the top layer order around a little.
middleDialog.showModal();
topDialog.showModal();
</script>
</body>
</html>

45
tests/modal-dialog.html Normal file
Просмотреть файл

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<style>
dialog {
width: 100px;
}
</style>
</head>
<body>
<p>Test for modal dialog. The test passes if you can click on "Click me" button,
but can't click or tab to the "Can't click me!" button</p>
<div id="console"></div>
<dialog>
<button id="dialog-button">Click me</button>
</dialog>
<button id="inert-button">Can't click me</button>
<script>
function writeToConsole(s) {
var console = document.getElementById('console');
var span = document.createElement('span');
span.textContent = s;
console.appendChild(span);
console.appendChild(document.createElement('br'));
}
var dialog = document.querySelector('dialog');
dialogPolyfill.registerDialog(dialog);
dialog.showModal();
var dialogButton = document.getElementById('dialog-button');
dialogButton.addEventListener('click', function(e) {
writeToConsole("SUCCESS: dialog's button was clicked");
});
var inertButton = document.getElementById('inert-button');
inertButton.addEventListener('click', function(e) {
writeToConsole('FAIL: inert button was clicked');
});
</script>
</body>
</html>

Двоичные данные
tests/resources/close_dialog.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 140 B

Двоичные данные
tests/resources/close_dialog_hover.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 215 B

Просмотреть файл

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<meta charset='utf-8'>
<head>
<script src="../dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="../dialog-polyfill.css">
<style>
dialog {
display: none;
height: 50px;
width: 50px;
padding: 0;
margin: 0;
}
dialog.left {
top: 100px;
left: 100px;
}
#middle {
top: 100px;
left: 200px;
}
</style>
</head>
<body>
<p>Test that dialogs with an explicit static position don't get auto-centered.
The test passes if there are three boxes aligned in a single row.</p>
<div id="console"></div>
<dialog id="left" class="left"></dialog>
<dialog id="middle"></dialog>
<dialog id="right"></dialog>
<script>
function writeToConsole(s) {
var console = document.getElementById('console');
var span = document.createElement('span');
span.textContent = s;
console.appendChild(span);
console.appendChild(document.createElement('br'));
}
var dialogs = document.querySelectorAll('dialog');
for (var i = 0; i < dialogs.length; ++i)
dialogPolyfill.registerDialog(dialogs[i]);
var leftDialog = document.getElementById('left');
leftDialog.show();
var middleDialog = document.getElementById('middle');
middleDialog.show();
var rightDialog = document.getElementById('right');
rightDialog.style.top = '100px';
rightDialog.style.left = '300px';
rightDialog.show();
</script>
</body>
</html>