Skip to content

Commit

Permalink
Merge pull request #220 from canjs/fix-infinite-disable-mutations
Browse files Browse the repository at this point in the history
Limit disabled dispatching fix to inserted and removed events
  • Loading branch information
phillipskevin committed Mar 28, 2017
2 parents 12a4f0f + b061ba2 commit 450983f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
13 changes: 0 additions & 13 deletions dom/dispatch/dispatch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,6 @@ test("basic synthetic events", function () {

});

test("synthetic events on disabled element", function () {
expect(1);
var input = document.createElement("input");
input.disabled = true;

domEvents.addEventListener.call(input, "foo", function(){
ok(true, "called back");
});

document.getElementById("qunit-fixture").appendChild(input);
domDispatch.call(input, "foo", [], false);
});

test("more complex synthetic events", function () {
var div = document.createElement("div");
var arr = [];
Expand Down
33 changes: 29 additions & 4 deletions dom/events/events.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
var assign = require("../../js/assign/assign");
var _document = require("../document/document");
var isPlainObject = require("../../js/is-plain-object/is-plain-object");
var fixSyntheticEventsOnDisabled = false;

function isDispatchingOnDisabled(element, ev) {
var isInsertedOrRemoved = isPlainObject(ev) ? (ev.type === 'inserted' || ev.type === 'removed') : (ev === 'inserted' || ev === 'removed');
var isDisabled = !!element.disabled;
return isInsertedOrRemoved && isDisabled;
}
/**
* @module {{}} can-util/dom/events/events events
* @parent can-util/dom
Expand All @@ -23,7 +30,7 @@ module.exports = {
dispatch: function(event, args, bubbles){
var doc = _document();
var ret;
var dispatchingOnDisabled = this.disabled;
var dispatchingOnDisabled = fixSyntheticEventsOnDisabled && isDispatchingOnDisabled(this, event);

var ev = doc.createEvent('HTMLEvents');
var isString = typeof event === "string";
Expand All @@ -35,9 +42,6 @@ module.exports = {
assign(ev, event);
}
ev.args = args;
// In FireFox, dispatching an event on a disabled element throws an error.
// So ensure the mutatedNode is not disabled.
// https://bugzilla.mozilla.org/show_bug.cgi?id=329509
if(dispatchingOnDisabled) {
this.disabled = false;
}
Expand All @@ -48,3 +52,24 @@ module.exports = {
return ret;
}
};

// In FireFox, dispatching a synthetic event on a disabled element throws an error.
// Other browsers, like IE 10 do not dispatch synthetic events on disabled elements at all.
// This determines if we have to work around that when dispatching events.
// https://bugzilla.mozilla.org/show_bug.cgi?id=329509
(function() {
var input = document.createElement("input");
input.disabled = true;
var timer = setTimeout(function() {
fixSyntheticEventsOnDisabled = true;
}, 50);
module.exports.addEventListener.call(input, 'foo', function(){
clearTimeout(timer);
});
try {
module.exports.dispatch.call(input, 'foo', [], false);
} catch(e) {
clearTimeout(timer);
fixSyntheticEventsOnDisabled = true;
}
})();
3 changes: 2 additions & 1 deletion dom/events/inserted/inserted-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ function runTest(name, MUT_OBS) {
});

// With no mutation observer this test will not pass without a setTimeout
// There is a setTimeout, 0 in the non-mutation observer code path
setTimeout(function(){
domMutate.appendChild.call(document.getElementById("qunit-fixture"), input);
}, 20);
}, 50);
});
asyncTest("parent then child inserted - appendChild", function () {
expect(1);
Expand Down

0 comments on commit 450983f

Please sign in to comment.