1 | module.exports = Dom;
|
2 |
|
3 | function Dom(controller) {
|
4 | this.controller = controller;
|
5 | this._listeners = null;
|
6 | }
|
7 |
|
8 | Dom.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 |
|
21 | Dom.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 |
|
30 | Dom.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 | };
|
45 | Dom.prototype.on = Dom.prototype.addListener;
|
46 |
|
47 | Dom.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 |
|
61 | Dom.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 |
|
73 | function DomListener(type, target, listener, useCapture) {
|
74 | this.type = type;
|
75 | this.target = target;
|
76 | this.listener = listener;
|
77 | this.useCapture = !!useCapture;
|
78 | }
|
79 | DomListener.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 | };
|
85 | DomListener.prototype.add = function() {
|
86 | this.target.addEventListener(this.type, this.listener, this.useCapture);
|
87 | };
|
88 | DomListener.prototype.remove = function() {
|
89 | this.target.removeEventListener(this.type, this.listener, this.useCapture);
|
90 | };
|
91 |
|
92 | function DestroyListener(target, listener) {
|
93 | DomListener.call(this, 'destroy', target, listener);
|
94 | }
|
95 | DestroyListener.prototype = new DomListener();
|
96 | DestroyListener.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 | };
|
102 | DestroyListener.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 | };
|