Passed
Push — master ( c7dc0e...f45dbd )
by Tony
02:27
created

always.js (2 issues)

Labels
Severity
1
(function (jQuery) {
2
'use strict';
3
4
jQuery = jQuery && jQuery.hasOwnProperty('default') ? jQuery['default'] : jQuery;
5
6
var AlwaysData = (function () {
7
    function AlwaysData() {
8
    }
9
    AlwaysData.OPERATION_INSERTION = 0;
10
    AlwaysData.OPERATION_REMOVAL = 1;
11
    return AlwaysData;
12
}());
13
14
var Always = (function () {
15
    function Always(element) {
16
        var _this = this;
17
        this.insertedCallbacks = {};
18
        this.removedCallbacks = {};
19
        this.element = element;
20
        this.observer = new MutationObserver(function (mutations) { return mutations.forEach(function (mutation) {
0 ignored issues
show
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
21
            if ('childList' !== mutation.type) {
22
                return;
23
            }
24
            [].forEach.call(mutation.addedNodes, function (node) {
25
                if (!(node instanceof HTMLElement)) {
26
                    return;
27
                }
28
                _this.notifyInserted(node);
29
            });
30
            [].forEach.call(mutation.removedNodes, function (node) {
31
                if (!(node instanceof HTMLElement)) {
32
                    return;
33
                }
34
                _this.notifyRemoved(node);
35
            });
36
        }); });
37
        this.observer.observe(this.element, {
38
            childList: true,
39
            subtree: true
40
        });
41
    }
42
    Always.data = function (element) {
43
        if (!element.hasOwnProperty('jQueryAlways')) {
44
            Object.defineProperty(element, 'jQueryAlways', {
45
                value: new AlwaysData(),
46
                configurable: true
47
            });
48
        }
49
        return element.jQueryAlways;
50
    };
51
    Always.attach = function (element) {
52
        var data = this.data(element);
53
        if (!data.instance) {
54
            data.instance = new Always(element);
55
        }
56
        return data.instance;
57
    };
58
    Always.detach = function (element) {
59
        Always.attach(element).observer.disconnect();
60
        delete element.jQueryAlways;
61
    };
62
    Always.normalizeSelector = function (selector) {
63
        return selector.split(',').map(function (part) {
64
            return part.trim();
65
        }).sort().join(',');
66
    };
67
    Always.always = function (element, selector, onInserted, onRemoved) {
68
        var instance = Always.attach(element);
69
        if ('function' === typeof onInserted) {
70
            instance.addInsertedCallback(selector, onInserted);
71
            [].forEach.call(element.querySelectorAll(selector), function (node) {
72
                onInserted.call(node);
73
            });
74
        }
75
        if ('function' === typeof onRemoved) {
76
            instance.addRemovedCallback(selector, onRemoved);
77
        }
78
    };
79
    Always.never = function (element, selector, onInserted, onRemoved) {
80
        if (!selector) {
81
            Always.detach(element);
82
            return;
83
        }
84
        var instance = Always.attach(element);
85
        if (!onInserted && !onRemoved) {
86
            instance.removeInsertedCallback(selector);
87
            instance.removeRemovedCallback(selector);
88
            return;
89
        }
90
        if (onInserted) {
91
            instance.removeInsertedCallback(selector, onInserted);
92
        }
93
        if (onRemoved) {
94
            instance.removeRemovedCallback(selector, onRemoved);
95
        }
96
    };
97
    Always.prototype.addCallback = function (callbacks, selector, callback) {
98
        selector = Always.normalizeSelector(selector);
99
        if (!callbacks.hasOwnProperty(selector)) {
100
            callbacks[selector] = [];
101
        }
102
        callbacks[selector].push(callback);
103
        return this;
104
    };
105
    Always.prototype.removeCallback = function (callbacks, selector, callback) {
106
        selector = Always.normalizeSelector(selector);
107
        if (!callbacks.hasOwnProperty(selector)) {
108
            return this;
109
        }
110
        if (callback) {
111
            var index = void 0;
112
            while (-1 < (index = callbacks[selector].indexOf(callback))) {
113
                callbacks[selector].splice(index, 1);
114
            }
115
        }
116
        else {
117
            delete callbacks[selector];
118
        }
119
        return this;
120
    };
121
    Always.prototype.notifyInserted = function (element) {
122
        var _this = this;
123
        var data = Always.data(element);
124
        if (AlwaysData.OPERATION_INSERTION === data.lastOperation) {
125
            return this;
126
        }
127
        data.lastOperation = AlwaysData.OPERATION_INSERTION;
128
        Object.keys(this.insertedCallbacks).forEach(function (selector) {
129
            if (element.matches(selector)) {
130
                _this.insertedCallbacks[selector].forEach(function (callback) {
131
                    callback.call(element);
132
                });
133
            }
134
        });
135
        [].forEach.call(element.querySelectorAll('*'), function (node) {
136
            _this.notifyInserted(node);
137
        });
138
        return this;
139
    };
140
    Always.prototype.notifyRemoved = function (element) {
141
        var _this = this;
142
        var data = Always.data(element);
143
        if (AlwaysData.OPERATION_REMOVAL === data.lastOperation) {
144
            return this;
145
        }
146
        data.lastOperation = AlwaysData.OPERATION_REMOVAL;
147
        [].forEach.call(element.querySelectorAll('*'), function (node) {
148
            _this.notifyRemoved(node);
149
        });
150
        Object.keys(this.removedCallbacks).forEach(function (selector) {
151
            if (element.matches(selector)) {
152
                _this.removedCallbacks[selector].forEach(function (callback) {
153
                    callback.call(element);
154
                });
155
            }
156
        });
157
        return this;
158
    };
159
    Always.prototype.addInsertedCallback = function (selector, callback) {
160
        return this.addCallback(this.insertedCallbacks, selector, callback);
161
    };
162
    Always.prototype.addRemovedCallback = function (selector, callback) {
163
        return this.addCallback(this.removedCallbacks, selector, callback);
164
    };
165
    Always.prototype.removeInsertedCallback = function (selector, callback) {
166
        return this.removeCallback(this.insertedCallbacks, selector, callback);
167
    };
168
    Always.prototype.removeRemovedCallback = function (selector, callback) {
169
        return this.removeCallback(this.removedCallbacks, selector, callback);
170
    };
171
    return Always;
172
}());
173
174
function bindingNative() {
175
    window.Always = {
176
        always: Always.always,
177
        never: Always.never
178
    };
179
}
180
181
function bindingJQuery() {
182
    if ('undefined' === typeof jQuery) {
183
        return;
184
    }
185
    (function ($) {
186
        $.extend($.fn, {
187
            always: function (selector, onInserted, onRemoved) {
188
                return $(this).each(function () {
189
                    Always.always(this, selector, onInserted, onRemoved);
190
                });
191
            },
192
            never: function (selector, onInserted, onRemoved) {
193
                return $(this).each(function () {
194
                    Always.never(this, selector, onInserted, onRemoved);
195
                });
196
            }
197
        });
198
    })(jQuery);
199
}
200
201
var Bindings = (function () {
202
    function Bindings() {
203
    }
204
    Bindings.native = bindingNative;
205
    Bindings.jQuery = bindingJQuery;
206
    return Bindings;
207
}());
208
209
function polyfillMutationObserver() {
210
    if (window.MutationObserver) {
211
        return;
212
    }
213
    window.MutationObserver = window.WebKitMutationObserver;
214
}
215
216
function polyfillElementMatches() {
217
    var _this = this;
218
    var prototype = Element.prototype;
0 ignored issues
show
The variable Element seems to be never declared. If this is a global, consider adding a /** global: Element */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
219
    if (prototype.matches) {
220
        return;
221
    }
222
    prototype.matches =
223
        prototype.matchesSelector ||
224
            prototype.mozMatchesSelector ||
225
            prototype.msMatchesSelector ||
226
            prototype.oMatchesSelector ||
227
            prototype.webkitMatchesSelector ||
228
            (function (s) {
229
                var matches = (_this.document || _this.ownerDocument).querySelectorAll(s), i = matches.length;
230
                while (--i >= 0 && matches.item(i) !== _this) { }
231
                return i > -1;
232
            });
233
}
234
235
var Polyfills = (function () {
236
    function Polyfills() {
237
    }
238
    Polyfills.elementMatches = polyfillElementMatches;
239
    Polyfills.mutationObserver = polyfillMutationObserver;
240
    return Polyfills;
241
}());
242
243
Polyfills.elementMatches();
244
Polyfills.mutationObserver();
245
Bindings.native();
246
Bindings.jQuery();
247
248
}(jQuery));
249