UNPKG

3.28 kBJavaScriptView Raw
1module.exports = Dom;
2
3function Dom(controller) {
4 this.controller = controller;
5 this._listeners = null;
6}
7
8Dom.prototype._initListeners = function() {
9 var dom = this;
10 this.controller.on('destroy', function domOnDestroy() {
11 var listeners = dom._listeners;
12 if (!listeners) return;
13 for (var i = listeners.length; i--;) {
14 listeners[i].remove();
15 }
16 dom._listeners = null;
17 });
18 return this._listeners = [];
19};
20
21Dom.prototype._listenerIndex = function(domListener) {
22 var listeners = this._listeners;
23 if (!listeners) return -1;
24 for (var i = listeners.length; i--;) {
25 if (listeners[i].equals(domListener)) return i;
26 }
27 return -1;
28};
29
30Dom.prototype.addListener = function(type, target, listener, useCapture) {
31 if (typeof target === 'function') {
32 useCapture = listener;
33 listener = target;
34 target = document;
35 }
36 var domListener =
37 (type === 'destroy') ? new DestroyListener(target, listener) :
38 new DomListener(type, target, listener, useCapture);
39 if (-1 === this._listenerIndex(domListener)) {
40 var listeners = this._listeners || this._initListeners();
41 listeners.push(domListener);
42 }
43 domListener.add();
44};
45Dom.prototype.on = Dom.prototype.addListener;
46
47Dom.prototype.once = function(type, target, listener, useCapture) {
48 if (typeof target === 'function') {
49 useCapture = listener;
50 listener = target;
51 target = document;
52 }
53 this.addListener(type, target, wrappedListener, useCapture);
54 var dom = this;
55 function wrappedListener() {
56 dom.removeListener(type, target, wrappedListener, useCapture);
57 return listener.apply(this, arguments);
58 }
59};
60
61Dom.prototype.removeListener = function(type, target, listener, useCapture) {
62 if (typeof target === 'function') {
63 useCapture = listener;
64 listener = target;
65 target = document;
66 }
67 var domListener = new DomListener(type, target, listener, useCapture);
68 domListener.remove();
69 var i = this._listenerIndex(domListener);
70 if (i > -1) this._listeners.splice(i, 1);
71};
72
73function DomListener(type, target, listener, useCapture) {
74 this.type = type;
75 this.target = target;
76 this.listener = listener;
77 this.useCapture = !!useCapture;
78}
79DomListener.prototype.equals = function(domListener) {
80 return this.listener === domListener.listener &&
81 this.target === domListener.target &&
82 this.type === domListener.type &&
83 this.useCapture === domListener.useCapture;
84};
85DomListener.prototype.add = function() {
86 this.target.addEventListener(this.type, this.listener, this.useCapture);
87};
88DomListener.prototype.remove = function() {
89 this.target.removeEventListener(this.type, this.listener, this.useCapture);
90};
91
92function DestroyListener(target, listener) {
93 DomListener.call(this, 'destroy', target, listener);
94}
95DestroyListener.prototype = new DomListener();
96DestroyListener.prototype.add = function() {
97 var listeners = this.target.$destroyListeners || (this.target.$destroyListeners = []);
98 if (listeners.indexOf(this.listener) === -1) {
99 listeners.push(this.listener);
100 }
101};
102DestroyListener.prototype.remove = function() {
103 var listeners = this.target.$destroyListeners;
104 if (!listeners) return;
105 var index = listeners.indexOf(this.listener);
106 if (index !== -1) {
107 listeners.splice(index, 1);
108 }
109};