Skip to content

Commit

Permalink
support oncancel and onclose
Browse files Browse the repository at this point in the history
  • Loading branch information
samthor committed Jul 27, 2020
1 parent aa1dbd3 commit a9a4ea4
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 15 deletions.
28 changes: 23 additions & 5 deletions dist/dialog-polyfill.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ if (!supportCustomEvent || typeof supportCustomEvent === 'object') {
supportCustomEvent.prototype = window.Event.prototype;
}

/**
* Dispatches the passed event to both an "on<type>" handler as well as via the
* normal dispatch operation. Does not bubble.
*
* @param {!EventTarget} target
* @param {!Event} event
* @return {boolean}
*/
function safeDispatchEvent(target, event) {
var check = 'on' + event.type.toLowerCase();
if (typeof target[check] === 'function') {
target[check](event);
}
return target.dispatchEvent(event);
}

/**
* @param {Element} el to check for stacking context
* @return {boolean} whether this el or its parents creates a stacking context
Expand Down Expand Up @@ -193,7 +209,9 @@ function dialogPolyfillInfo(dialog) {

this.backdrop_ = document.createElement('div');
this.backdrop_.className = 'backdrop';
this.backdrop_.addEventListener('click', this.backdropClick_.bind(this));
this.backdrop_.addEventListener('mouseup' , this.backdropMouseEvent_.bind(this));
this.backdrop_.addEventListener('mousedown', this.backdropMouseEvent_.bind(this));
this.backdrop_.addEventListener('click' , this.backdropMouseEvent_.bind(this));
}

dialogPolyfillInfo.prototype = /** @type {HTMLDialogElement.prototype} */ ({
Expand Down Expand Up @@ -246,12 +264,12 @@ dialogPolyfillInfo.prototype = /** @type {HTMLDialogElement.prototype} */ ({
},

/**
* Handles clicks on the fake .backdrop element, redirecting them as if
* Handles mouse events ('mouseup', 'mousedown', 'click') on the fake .backdrop element, redirecting them as if
* they were on the dialog itself.
*
* @param {!Event} e to redirect
*/
backdropClick_: function(e) {
backdropMouseEvent_: function(e) {
if (!this.dialog_.hasAttribute('tabindex')) {
// Clicking on the backdrop should move the implicit cursor, even if dialog cannot be
// focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this
Expand Down Expand Up @@ -374,7 +392,7 @@ dialogPolyfillInfo.prototype = /** @type {HTMLDialogElement.prototype} */ ({
bubbles: false,
cancelable: false
});
this.dialog_.dispatchEvent(closeEvent);
safeDispatchEvent(this.dialog_, closeEvent);
}

});
Expand Down Expand Up @@ -602,7 +620,7 @@ dialogPolyfill.DialogManager.prototype.handleKey_ = function(event) {
cancelable: true
});
var dpi = this.pendingDialogStack[0];
if (dpi && dpi.dialog.dispatchEvent(cancelEvent)) {
if (dpi && safeDispatchEvent(dpi.dialog, cancelEvent)) {
dpi.dialog.close();
}
} else if (event.keyCode === 9) {
Expand Down
32 changes: 25 additions & 7 deletions dist/dialog-polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -16,6 +16,22 @@
supportCustomEvent.prototype = window.Event.prototype;
}

/**
* Dispatches the passed event to both an "on<type>" handler as well as via the
* normal dispatch operation. Does not bubble.
*
* @param {!EventTarget} target
* @param {!Event} event
* @return {boolean}
*/
function safeDispatchEvent(target, event) {
var check = 'on' + event.type.toLowerCase();
if (typeof target[check] === 'function') {
target[check](event);
}
return target.dispatchEvent(event);
}

/**
* @param {Element} el to check for stacking context
* @return {boolean} whether this el or its parents creates a stacking context
Expand Down Expand Up @@ -199,7 +215,9 @@

this.backdrop_ = document.createElement('div');
this.backdrop_.className = 'backdrop';
this.backdrop_.addEventListener('click', this.backdropClick_.bind(this));
this.backdrop_.addEventListener('mouseup' , this.backdropMouseEvent_.bind(this));
this.backdrop_.addEventListener('mousedown', this.backdropMouseEvent_.bind(this));
this.backdrop_.addEventListener('click' , this.backdropMouseEvent_.bind(this));
}

dialogPolyfillInfo.prototype = /** @type {HTMLDialogElement.prototype} */ ({
Expand Down Expand Up @@ -252,12 +270,12 @@
},

/**
* Handles clicks on the fake .backdrop element, redirecting them as if
* Handles mouse events ('mouseup', 'mousedown', 'click') on the fake .backdrop element, redirecting them as if
* they were on the dialog itself.
*
* @param {!Event} e to redirect
*/
backdropClick_: function(e) {
backdropMouseEvent_: function(e) {
if (!this.dialog_.hasAttribute('tabindex')) {
// Clicking on the backdrop should move the implicit cursor, even if dialog cannot be
// focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this
Expand Down Expand Up @@ -380,7 +398,7 @@
bubbles: false,
cancelable: false
});
this.dialog_.dispatchEvent(closeEvent);
safeDispatchEvent(this.dialog_, closeEvent);
}

});
Expand Down Expand Up @@ -608,7 +626,7 @@
cancelable: true
});
var dpi = this.pendingDialogStack[0];
if (dpi && dpi.dialog.dispatchEvent(cancelEvent)) {
if (dpi && safeDispatchEvent(dpi.dialog, cancelEvent)) {
dpi.dialog.close();
}
} else if (event.keyCode === 9) {
Expand Down Expand Up @@ -776,4 +794,4 @@

return dialogPolyfill;

}));
})));
20 changes: 18 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ if (!supportCustomEvent || typeof supportCustomEvent === 'object') {
supportCustomEvent.prototype = window.Event.prototype;
}

/**
* Dispatches the passed event to both an "on<type>" handler as well as via the
* normal dispatch operation. Does not bubble.
*
* @param {!EventTarget} target
* @param {!Event} event
* @return {boolean}
*/
function safeDispatchEvent(target, event) {
var check = 'on' + event.type.toLowerCase();
if (typeof target[check] === 'function') {
target[check](event);
}
return target.dispatchEvent(event);
}

/**
* @param {Element} el to check for stacking context
* @return {boolean} whether this el or its parents creates a stacking context
Expand Down Expand Up @@ -377,7 +393,7 @@ dialogPolyfillInfo.prototype = /** @type {HTMLDialogElement.prototype} */ ({
bubbles: false,
cancelable: false
});
this.dialog_.dispatchEvent(closeEvent);
safeDispatchEvent(this.dialog_, closeEvent);
}

});
Expand Down Expand Up @@ -607,7 +623,7 @@ dialogPolyfill.DialogManager.prototype.handleKey_ = function(event) {
cancelable: true
});
var dpi = this.pendingDialogStack[0];
if (dpi && dpi.dialog.dispatchEvent(cancelEvent)) {
if (dpi && safeDispatchEvent(dpi.dialog, cancelEvent)) {
dpi.dialog.close();
}
} else if (event.keyCode === 9) {
Expand Down
15 changes: 14 additions & 1 deletion suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,14 +532,27 @@ void function() {
dialog.showModal();
dialog.dispatchEvent(createKeyboardEvent(27));
assert.equal(cancelFired, 1, 'expected cancel to be fired');
assert.isFalse(dialog.open), 'esc should close modal again';
assert.isFalse(dialog.open, 'esc should close modal again');

// Sanity-check that non-modals aren't effected.
dialog.show();
dialog.dispatchEvent(createKeyboardEvent(27));
assert.isTrue(dialog.open, 'esc should only close modal dialog');
assert.equal(cancelFired, 1);
});
test('cancel event via oncancel', function() {
dialog.showModal();

var cancelFired = 0;
dialog.oncancel = function(event) {
++cancelFired;
event.preventDefault();
};

dialog.dispatchEvent(createKeyboardEvent(27));
assert.equal(cancelFired, 1, 'expected cancel to be fired');
assert.isTrue(dialog.open, 'behavior should be prevented');
});
test('overlay click is prevented', function() {
dialog.showModal();

Expand Down

0 comments on commit a9a4ea4

Please sign in to comment.