This commit is contained in:
Sam Thorogood 2020-11-12 15:36:55 +11:00
Родитель bf24e2351b
Коммит 982184d68c
6 изменённых файлов: 166 добавлений и 89 удалений

73
dist/dialog-polyfill.esm.js поставляемый
Просмотреть файл

@ -153,6 +153,47 @@ function isConnected(element) {
return element.isConnected || document.body.contains(element);
}
/**
* @param {!Event} event
*/
function maybeHandleSubmit(event) {
if (event.defaultPrevented) {
return;
}
var form = /** @type {!HTMLFormElement} */ (event.target);
if (!isFormMethodDialog(form)) {
return;
}
event.preventDefault();
// We'd have a value if we clicked on an imagemap.
var value = dialogPolyfill.useValue;
var submitter = dialogPolyfill.formSubmitter || event.submitter;
if (!value) {
if (!submitter) {
var root = ('getRootNode' in form && form.getRootNode() || document);
var activeElement = root.activeElement;
if (activeElement) {
submitter = event.submitter = activeElement;
}
}
if (submitter) {
value = submitter.value;
}
}
const dialog = findNearestDialog(form);
if (!dialog) {
return;
}
if (submitter) {
dialog.close(value);
} else {
dialog.close();
}
}
/**
* @param {!HTMLDialogElement} dialog to upgrade
* @constructor
@ -171,6 +212,8 @@ function dialogPolyfillInfo(dialog) {
dialog.showModal = this.showModal.bind(this);
dialog.close = this.close.bind(this);
dialog.addEventListener('submit', maybeHandleSubmit, false);
if (!('returnValue' in dialog)) {
dialog.returnValue = '';
}
@ -729,6 +772,10 @@ if (window.HTMLDialogElement === undefined) {
if (ev.defaultPrevented) { return; } // e.g. a submit which prevents default submission
var target = /** @type {Element} */ (ev.target);
if ('composedPath' in ev) {
var path = ev.composedPath();
target = path.shift() || target;
}
if (!target || !isFormMethodDialog(target.form)) { return; }
var valid = (target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1);
@ -758,32 +805,6 @@ if (window.HTMLDialogElement === undefined) {
dialog && dialog.close();
};
HTMLFormElement.prototype.submit = replacementFormSubmit;
/**
* Global form 'dialog' method handler. Closes a dialog correctly on submit
* and possibly sets its return value.
*/
document.addEventListener('submit', function(ev) {
if (ev.defaultPrevented) { return; } // e.g. a submit which prevents default submission
var form = /** @type {HTMLFormElement} */ (ev.target);
if (!isFormMethodDialog(form)) { return; }
ev.preventDefault();
var dialog = findNearestDialog(form);
if (!dialog) { return; }
// Forms can only be submitted via .submit() or a click (?), but anyway: sanity-check that
// the submitter is correct before using its value as .returnValue.
var s = dialogPolyfill.formSubmitter;
if (s && s.form === form) {
dialog.close(dialogPolyfill.useValue || s.value);
} else {
dialog.close();
}
dialogPolyfill.formSubmitter = null;
}, false);
}
export default dialogPolyfill;

77
dist/dialog-polyfill.js поставляемый
Просмотреть файл

@ -2,7 +2,7 @@
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.dialogPolyfill = factory());
}(this, (function () { 'use strict';
}(this, function () { 'use strict';
// nb. This is for IE10 and lower _only_.
var supportCustomEvent = window.CustomEvent;
@ -159,6 +159,47 @@
return element.isConnected || document.body.contains(element);
}
/**
* @param {!Event} event
*/
function maybeHandleSubmit(event) {
if (event.defaultPrevented) {
return;
}
var form = /** @type {!HTMLFormElement} */ (event.target);
if (!isFormMethodDialog(form)) {
return;
}
event.preventDefault();
// We'd have a value if we clicked on an imagemap.
var value = dialogPolyfill.useValue;
var submitter = dialogPolyfill.formSubmitter || event.submitter;
if (!value) {
if (!submitter) {
var root = ('getRootNode' in form && form.getRootNode() || document);
var activeElement = root.activeElement;
if (activeElement) {
submitter = event.submitter = activeElement;
}
}
if (submitter) {
value = submitter.value;
}
}
const dialog = findNearestDialog(form);
if (!dialog) {
return;
}
if (submitter) {
dialog.close(value);
} else {
dialog.close();
}
}
/**
* @param {!HTMLDialogElement} dialog to upgrade
* @constructor
@ -177,6 +218,8 @@
dialog.showModal = this.showModal.bind(this);
dialog.close = this.close.bind(this);
dialog.addEventListener('submit', maybeHandleSubmit, false);
if (!('returnValue' in dialog)) {
dialog.returnValue = '';
}
@ -735,6 +778,10 @@
if (ev.defaultPrevented) { return; } // e.g. a submit which prevents default submission
var target = /** @type {Element} */ (ev.target);
if ('composedPath' in ev) {
var path = ev.composedPath();
target = path.shift() || target;
}
if (!target || !isFormMethodDialog(target.form)) { return; }
var valid = (target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1);
@ -764,34 +811,8 @@
dialog && dialog.close();
};
HTMLFormElement.prototype.submit = replacementFormSubmit;
/**
* Global form 'dialog' method handler. Closes a dialog correctly on submit
* and possibly sets its return value.
*/
document.addEventListener('submit', function(ev) {
if (ev.defaultPrevented) { return; } // e.g. a submit which prevents default submission
var form = /** @type {HTMLFormElement} */ (ev.target);
if (!isFormMethodDialog(form)) { return; }
ev.preventDefault();
var dialog = findNearestDialog(form);
if (!dialog) { return; }
// Forms can only be submitted via .submit() or a click (?), but anyway: sanity-check that
// the submitter is correct before using its value as .returnValue.
var s = dialogPolyfill.formSubmitter;
if (s && s.form === form) {
dialog.close(dialogPolyfill.useValue || s.value);
} else {
dialog.close();
}
dialogPolyfill.formSubmitter = null;
}, false);
}
return dialogPolyfill;
})));
}));

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

@ -154,6 +154,47 @@ function isConnected(element) {
return element.isConnected || document.body.contains(element);
}
/**
* @param {!Event} event
*/
function maybeHandleSubmit(event) {
if (event.defaultPrevented) {
return;
}
var form = /** @type {!HTMLFormElement} */ (event.target);
if (!isFormMethodDialog(form)) {
return;
}
event.preventDefault();
// We'd have a value if we clicked on an imagemap.
var value = dialogPolyfill.useValue;
var submitter = dialogPolyfill.formSubmitter || event.submitter;
if (!value) {
if (!submitter) {
var root = ('getRootNode' in form && form.getRootNode() || document);
var activeElement = root.activeElement;
if (activeElement) {
submitter = event.submitter = activeElement;
}
}
if (submitter) {
value = submitter.value;
}
}
const dialog = findNearestDialog(form);
if (!dialog) {
return;
}
if (submitter) {
dialog.close(value);
} else {
dialog.close();
}
}
/**
* @param {!HTMLDialogElement} dialog to upgrade
* @constructor
@ -172,6 +213,8 @@ function dialogPolyfillInfo(dialog) {
dialog.showModal = this.showModal.bind(this);
dialog.close = this.close.bind(this);
dialog.addEventListener('submit', maybeHandleSubmit, false);
if (!('returnValue' in dialog)) {
dialog.returnValue = '';
}
@ -732,6 +775,10 @@ if (window.HTMLDialogElement === undefined) {
if (ev.defaultPrevented) { return; } // e.g. a submit which prevents default submission
var target = /** @type {Element} */ (ev.target);
if ('composedPath' in ev) {
var path = ev.composedPath();
target = path.shift() || target;
}
if (!target || !isFormMethodDialog(target.form)) { return; }
var valid = (target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1);
@ -761,32 +808,6 @@ if (window.HTMLDialogElement === undefined) {
dialog && dialog.close();
};
HTMLFormElement.prototype.submit = replacementFormSubmit;
/**
* Global form 'dialog' method handler. Closes a dialog correctly on submit
* and possibly sets its return value.
*/
document.addEventListener('submit', function(ev) {
if (ev.defaultPrevented) { return; } // e.g. a submit which prevents default submission
var form = /** @type {HTMLFormElement} */ (ev.target);
if (!isFormMethodDialog(form)) { return; }
ev.preventDefault();
var dialog = findNearestDialog(form);
if (!dialog) { return; }
// Forms can only be submitted via .submit() or a click (?), but anyway: sanity-check that
// the submitter is correct before using its value as .returnValue.
var s = dialogPolyfill.formSubmitter;
if (s && s.form === form) {
dialog.close(dialogPolyfill.useValue || s.value);
} else {
dialog.close();
}
dialogPolyfill.formSubmitter = null;
}, false);
}

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

@ -1,6 +1,6 @@
{
"name": "dialog-polyfill",
"version": "0.5.2",
"version": "0.5.3",
"description": "Polyfill for the dialog element",
"main": "dist/dialog-polyfill.js",
"module": "dist/dialog-polyfill.esm.js",

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

@ -351,7 +351,11 @@ void function() {
dialog.showModal();
sub.show();
// trick Safari into allowing focus
input.offsetLeft;
input.focus();
input.offsetLeft;
assert.equal(input, document.activeElement);
});
test('clear focus when nothing focusable in modal', function() {
@ -757,6 +761,7 @@ void function() {
if (!window.ShadowRoot) {
return;
}
const iframeName = 'iframe_secret_blah';
var holder = document.createElement('div');
document.body.append(holder);
@ -768,13 +773,13 @@ void function() {
rootHolder.append(dialog);
var iframe = document.createElement('iframe');
iframe.setAttribute('name', 'blah');
iframe.setAttribute('name', iframeName);
document.body.append(iframe);
cleanup(iframe);
var form = document.createElement('form');
form.setAttribute('method', 'dialog');
form.setAttribute('target', 'blah');
form.setAttribute('target', iframeName);
form.setAttribute('action', '/test-invalid.html');
dialog.append(form);
@ -783,14 +788,18 @@ void function() {
form.append(button);
dialog.showModal();
console.warn('before button pressed', iframe.contentWindow.location.href);
iframe.addEventListener('load', function() {
assert.fail('should not load a new page');
});
button.click();
// TODO(samthor): this is a bit gross as this will pass if the button is not pressed at all.
window.setTimeout(() => {
assert.notStrictEqual(iframe.contentWindow.location.pathname, '/test-invalid.html');
window.setTimeout(function() {
assert.isFalse(dialog.open, 'dialog should be closed by button');
if (iframe.contentWindow && iframe.contentWindow.location) {
assert.notStrictEqual(iframe.contentWindow.location.pathname, '/test-invalid.html');
}
done();
}, 500);
}, 50);
});
});

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

@ -19,7 +19,12 @@
<script src="node_modules/mocha/mocha.js"></script>
<script src="node_modules/chai/chai.js"></script>
<link rel="stylesheet" type="text/css" href="dist/dialog-polyfill.css" />
<script src="dist/dialog-polyfill.js"></script>
<script type="module">
import dialogPolyfill from './index.js';
window.dialogPolyfill = dialogPolyfill;
</script>
<script>
var assert = chai.assert;