diff --git a/dom/dispatch/dispatch-test.js b/dom/dispatch/dispatch-test.js index a90ea980..72d82c24 100644 --- a/dom/dispatch/dispatch-test.js +++ b/dom/dispatch/dispatch-test.js @@ -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 = []; diff --git a/dom/events/events.js b/dom/events/events.js index a8046238..7e3c9561 100644 --- a/dom/events/events.js +++ b/dom/events/events.js @@ -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 @@ -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"; @@ -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; } @@ -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; + } +})(); diff --git a/dom/events/inserted/inserted-test.js b/dom/events/inserted/inserted-test.js index cf113e9b..f675a427 100644 --- a/dom/events/inserted/inserted-test.js +++ b/dom/events/inserted/inserted-test.js @@ -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);