-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.js
142 lines (109 loc) · 4.72 KB
/
index.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import Ember from 'ember';
const ActionManager = Ember.__loader.require('ember-views/system/action_manager').default;
const { merge, get, set, isNone, getOwner } = Ember;
const ROOT_ELEMENT_CLASS = 'ember-application';
const ROOT_ELEMENT_SELECTOR = '.' + ROOT_ELEMENT_CLASS;
export default Ember.EventDispatcher.extend({
init() {
this._super(...arguments);
this._eventHandlers = Object.create(null);
},
/*
Override the implementation in Ember itself
*/
setup(addedEvents, rootElement) {
let event;
let events = {};
merge(events, get(this, 'events'));
merge(events, addedEvents);
this._finalEvents = events;
if (!isNone(rootElement)) {
set(this, 'rootElement', rootElement);
}
let rootElementSelector = get(this, 'rootElement');
rootElement = document.querySelector(rootElementSelector);
//assert(`You cannot use the same root element (${rootElement.selector || rootElement[0].tagName}) multiple times in an Ember.Application`, !rootElement.is(ROOT_ELEMENT_SELECTOR));
//assert('You cannot make a new Ember.Application using a root element that is a descendent of an existing Ember.Application', !rootElement.closest(ROOT_ELEMENT_SELECTOR).length);
//assert('You cannot make a new Ember.Application using a root element that is an ancestor of an existing Ember.Application', !rootElement.find(ROOT_ELEMENT_SELECTOR).length);
rootElement.className += ' ' + ROOT_ELEMENT_SELECTOR;
//if (!rootElement.is(ROOT_ELEMENT_SELECTOR)) {
// throw new TypeError(`Unable to add '${ROOT_ELEMENT_CLASS}' class to root element (${rootElement.selector || rootElement[0].tagName}). Make sure you set rootElement to the body or an element in the body.`);
//}
for (event in events) {
if (events.hasOwnProperty(event)) {
this.setupHandler(rootElement, event, events[event]);
}
}
},
setupHandler(rootElement, event, eventName) {
let owner = getOwner ? getOwner(this) : this.container;
let viewRegistry = owner && owner.lookup('-view-registry:main');
if (eventName === null) {
return;
}
let viewHandler = (event, triggeringManager) => {
let view = viewRegistry[event.target.id];
let result = true;
let manager = this.canDispatchToEventManager ? this._findNearestEventManager(view, eventName) : null;
if (manager && manager !== triggeringManager) {
result = this._dispatchEvent(manager, event, eventName, view);
} else if (view) {
result = this._bubbleEvent(view, event, eventName);
}
return result;
};
let actionHandler = (event) => {
let actionId = event.target.getAttribute('data-ember-action');
let actions = ActionManager.registeredActions[actionId];
// In Glimmer2 this attribute is set to an empty string and an additional
// attribute it set for each action on a given element. In this case, the
// attributes need to be read so that a proper set of action handlers can
// be coalesced.
if (actionId === '') {
let attributes = event.target.attributes;
let attributeCount = attributes.length;
actions = [];
for (let i = 0; i < attributeCount; i++) {
let attr = attributes.item(i);
let attrName = attr.name;
if (attrName.indexOf('data-ember-action-') === 0) {
actions = actions.concat(ActionManager.registeredActions[attr.value]);
}
}
}
// We have to check for actions here since in some cases, jQuery will trigger
// an event on `removeChild` (i.e. focusout) after we've already torn down the
// action handlers for the view.
if (!actions) {
return;
}
for (let index = 0; index < actions.length; index++) {
let action = actions[index];
if (action && action.eventName === eventName) {
return action.handler(event);
}
}
};
let handleEvent = this._eventHandlers[event] = (event) => {
let target = event.target;
if (viewRegistry[target.id]) {
return viewHandler(event);
} else if (target.hasAttribute('data-ember-action')) {
return actionHandler(event);
}
};
rootElement.addEventListener(event, handleEvent);
},
destroy() {
let rootElement = get(this, 'rootElement');
rootElement = document.querySelector(rootElement);
for (let event in this._eventHandlers) {
rootElement.removeEventListener(event, this._eventHandlers[event]);
}
if (rootElement.classList) {
rootElement.classList.remove(ROOT_ELEMENT_CLASS);
} else {
rootElement.className = rootElement.className.replace(new RegExp('(^|\\b)' + ROOT_ELEMENT_CLASS.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
});