Passed
Push — master ( a6f69c...a5f6f2 )
by Tony
01:22
created

always.js (6 issues)

1
"use strict";
2
(function ($) {
3
    var Always = (function () {
4
        function Always($element) {
5
            var _this = this;
6
            this.insertedCallbacks = {};
7
            this.removedCallbacks = {};
8
            this.$element = $element;
9
            (this.observer = new ('undefined' !== typeof MutationObserver ? MutationObserver : WebKitMutationObserver)(function (mutations) {
0 ignored issues
show
The variable WebKitMutationObserver seems to be never declared. If this is a global, consider adding a /** global: WebKitMutationObserver */ 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...
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...
10
                mutations.forEach(function (mutation) {
11
                    if ('childList' !== mutation.type) {
12
                        return;
13
                    }
14
                    [].forEach.call(mutation.addedNodes, function (node) {
15
                        if (Node.ELEMENT_NODE !== node.nodeType) {
0 ignored issues
show
The variable Node seems to be never declared. If this is a global, consider adding a /** global: Node */ 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...
16
                            return;
17
                        }
18
                        _this.notifyInserted(node);
19
                    });
20
                    [].forEach.call(mutation.removedNodes, function (node) {
21
                        if (Node.ELEMENT_NODE !== node.nodeType) {
0 ignored issues
show
The variable Node seems to be never declared. If this is a global, consider adding a /** global: Node */ 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...
22
                            return;
23
                        }
24
                        _this.notifyRemoved(node);
25
                    });
26
                });
27
            })).observe(this.$element.get(0), {
28
                childList: true,
29
                subtree: true
30
            });
31
        }
32
        Always.attach = function ($element) {
33
            var instance = $element.data('jquery-always');
34
            if (!(instance instanceof Always)) {
35
                instance = new Always($element);
36
                $element.data('jquery-always', instance);
37
            }
38
            return instance;
39
        };
40
        Always.detach = function ($element) {
41
            Always.attach($element).observer.disconnect();
42
            return $element.removeData('jquery-always');
43
        };
44
        Always.normalizeSelector = function (selector) {
45
            return selector.split(',').map(function (part) {
46
                return part.trim();
47
            }).sort().join(',');
48
        };
49
        Always.prototype.addCallback = function (callbacks, selector, callback) {
50
            selector = Always.normalizeSelector(selector);
51
            if (!callbacks.hasOwnProperty(selector)) {
52
                callbacks[selector] = [];
53
            }
54
            callbacks[selector].push(callback);
55
            return this;
56
        };
57
        Always.prototype.removeCallback = function (callbacks, selector, callback) {
58
            selector = Always.normalizeSelector(selector);
59
            if (!callbacks.hasOwnProperty(selector)) {
60
                return this;
61
            }
62
            if (callback) {
63
                var index = void 0;
0 ignored issues
show
The assignment to variable index seems to be never used. Consider removing it.
Loading history...
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
64
                while (-1 < (index = callbacks[selector].indexOf(callback))) {
65
                    callbacks[selector].splice(index, 1);
66
                }
67
            }
68
            else {
69
                delete callbacks[selector];
70
            }
71
            return this;
72
        };
73
        Always.prototype.addInsertedCallback = function (selector, callback) {
74
            return this.addCallback(this.insertedCallbacks, selector, callback);
75
        };
76
        Always.prototype.addRemovedCallback = function (selector, callback) {
77
            return this.addCallback(this.removedCallbacks, selector, callback);
78
        };
79
        Always.prototype.removeInsertedCallback = function (selector, callback) {
80
            return this.removeCallback(this.insertedCallbacks, selector, callback);
81
        };
82
        Always.prototype.removeRemovedCallback = function (selector, callback) {
83
            return this.removeCallback(this.removedCallbacks, selector, callback);
84
        };
85
        Always.prototype.notifyInserted = function (node) {
86
            var _this = this;
87
            var $node = $(node), _ = this;
88
            Object.keys(this.insertedCallbacks).forEach(function (selector) {
89
                if ($node.is(selector)) {
90
                    _this.insertedCallbacks[selector].forEach(function (callback) {
91
                        callback.call(node);
92
                    });
93
                }
94
            });
95
            $node.children().each(function () {
96
                _.notifyInserted(this);
97
            });
98
            return this;
99
        };
100
        Always.prototype.notifyRemoved = function (node) {
101
            var _this = this;
102
            var $node = $(node), _ = this;
103
            $node.children().each(function () {
104
                _.notifyRemoved(this);
105
            });
106
            Object.keys(this.removedCallbacks).forEach(function (selector) {
107
                if ($node.is(selector)) {
108
                    _this.removedCallbacks[selector].forEach(function (callback) {
109
                        callback.call(node);
110
                    });
111
                }
112
            });
113
            return this;
114
        };
115
        return Always;
116
    }());
117
    $.extend($.fn, {
118
        always: function (selector, onInserted, onRemoved) {
119
            return $(this).each(function () {
120
                var $this = $(this), always = Always.attach($this);
121
                if ('function' === typeof onInserted) {
122
                    always.addInsertedCallback(selector, onInserted);
123
                    $this.find(selector).each(function () {
124
                        onInserted.call(this);
125
                    });
126
                }
127
                if ('function' === typeof onRemoved) {
128
                    always.addRemovedCallback(selector, onRemoved);
129
                }
130
            });
131
        },
132
        never: function (selector, onInserted, onRemoved) {
133
            return $(this).each(function () {
134
                var $this = $(this), always = Always.attach($this);
135
                if (!selector) {
136
                    Always.detach($this);
137
                    return;
138
                }
139
                if (!onInserted && !onRemoved) {
140
                    always.removeInsertedCallback(selector);
141
                    always.removeRemovedCallback(selector);
142
                    return;
143
                }
144
                if (onInserted) {
145
                    always.removeInsertedCallback(selector, onInserted);
146
                }
147
                if (onRemoved) {
148
                    always.removeRemovedCallback(selector, onRemoved);
149
                }
150
            });
151
        }
152
    });
153
})(jQuery);
154