-
Notifications
You must be signed in to change notification settings - Fork 8
/
events.js
102 lines (92 loc) · 3.22 KB
/
events.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
'use strict';
var getDocument = require('can-globals/document/document');
var isBrowserWindow = require('can-globals/is-browser-window/is-browser-window');
var isPlainObject = require('../../js/is-plain-object/is-plain-object');
var fixSyntheticEventsOnDisabled = false;
var dev = require('can-log/dev/dev');
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
* @description Allows you to listen to a domEvent and special domEvents as well as dispatch domEvents.
*
* ```js
* var domEvents = require("can-util/dom/events/events");
* ```
*/
module.exports = {
addEventListener: function(){
this.addEventListener.apply(this, arguments);
},
removeEventListener: function(){
this.removeEventListener.apply(this, arguments);
},
canAddEventListener: function(){
return (this.nodeName && (this.nodeType === 1 || this.nodeType === 9)) || this === window;
},
dispatch: function(event, args, bubbles){
var ret;
var dispatchingOnDisabled = fixSyntheticEventsOnDisabled && isDispatchingOnDisabled(this, event);
var doc = this.ownerDocument || getDocument();
var ev = doc.createEvent('HTMLEvents');
var isString = typeof event === "string";
// removed / inserted events should not bubble
ev.initEvent(isString ? event : event.type, bubbles === undefined ? true : bubbles, false);
if(!isString) {
for (var prop in event) {
if (ev[prop] === undefined) {
ev[prop] = event[prop];
}
}
}
// ignore events from feature detection below
if(this.disabled === true && ev.type !== 'fix_synthetic_events_on_disabled_test') {
//!steal-remove-start
dev.warn(
"can-util/dom/events::dispatch: Dispatching a synthetic event on a disabled is " +
"problematic in FireFox and Internet Explorer. We recommend avoiding this if at " +
"all possible. see https://github.com/canjs/can-util/issues/294"
);
//!steal-remove-end
}
ev.args = args;
if(dispatchingOnDisabled) {
this.disabled = false;
}
ret = this.dispatchEvent(ev);
if(dispatchingOnDisabled) {
this.disabled = true;
}
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() {
if(!isBrowserWindow()) {
return;
}
var testEventName = 'fix_synthetic_events_on_disabled_test';
var input = document.createElement("input");
input.disabled = true;
var timer = setTimeout(function() {
fixSyntheticEventsOnDisabled = true;
}, 50);
var onTest = function onTest (){
clearTimeout(timer);
module.exports.removeEventListener.call(input, testEventName, onTest);
};
module.exports.addEventListener.call(input, testEventName, onTest);
try {
module.exports.dispatch.call(input, testEventName, [], false);
} catch(e) {
onTest();
fixSyntheticEventsOnDisabled = true;
}
})();