PageSourceSearch

https://www.aerotech.com/wp-content/mu-plugins/aerotech-behaviors/behaviors.js?ver=1790490048

js aerotech.com collected 2026-10-01 15:13:53 UTC 12,048 bytes, 351 lines download raw bytes

1/*global define, window, document*/
2
3//Polyfill for Object.create.
4if (typeof Object.create !== 'function') {
5    Object.create = (function () {
6        "use strict";
7        var Temp = function () {};
8        return function (prototype) {
9            if (arguments.length > 1) {
10                throw new Error('Second argument not supported');
11            }
12            if (typeof prototype !== 'object') {
13                throw new TypeError('Argument must be an object');
14            }
15            Temp.prototype = prototype;
16            var result = new Temp();
17            Temp.prototype = null;
18            return result;
19        };
20    }());
21}
22
23(function (root, factory) {
24    "use strict";
25    if (typeof define === 'function' && define.amd) {
26        define("Behaviors", ["jquery"], factory);
27    } else {
28        root.Behaviors = factory(root.jQuery);
29    }
30}(this, function ($) {
31    "use strict";
32
33    var module = {},
34        behavior_registry = {},
35        content_ready_listeners = [],
36        ElementMissingError = error("ElementMissingError");
37    
38    /* Throttle an event handler.
39     *
40     * Returns a function which, no matter how frequently it's called, will
41     * only trigger a maximum of once per timeout period. More specifically,
42     * the first event will always be processed, then, no events will process
43     * until the end of the timeout period. If one or more events occurred
44     * during this period, the last event recieved will trigger immediately
45     * after the end of the timeout period, as well as restart the throttling
46     * period. Any preceding events will be discarded.
47     *
48     * Not to be confused with a debounce, which only fires the event handler
49     * at the end of a string of events spaced closer than the timeout period.
50     *
51     * The nature of this function means that any passed in function's return
52     * value will be discarded.
53     */
54    function throttle_single(func, timeout) {
55        var lastTimeout, afterLastArgs, afterLastThis;
56
57        function unthrottle() {
58            if (afterLastArgs !== undefined) {
59                func.apply(afterLastThis, afterLastArgs);
60                afterLastArgs = undefined;
61                lastTimeout = window.setTimeout(unthrottle, timeout);
62            } else {
63                lastTimeout = undefined;
64            }
65        }
66
67        return function () {
68            var myThis = this, myArgs = [], i;
69
70            for (i = 0; i < arguments.length; i += 1) {
71                myArgs.push(arguments[i]);
72            }
73
74            if (lastTimeout === undefined) {
75                func.apply(myThis, myArgs);
76                lastTimeout = window.setTimeout(unthrottle, timeout);
77            } else {
78                afterLastArgs = myArgs;
79                afterLastThis = myThis;
80            }
81        };
82    }
83
84    function Behavior(elem) {
85        //Do something to elem
86        this.$elem = $(elem);
87    }
88
89    /* Find a behavior's markup.
90     *
91     * The $context argument passed to this function is the jQuery element that
92     * will be searched for behaviors. Any additional arguments will be passed
93     * to Behavior.locate and ultimately to the behavior's constructor.
94     */
95    Behavior.find_markup = function ($context) {
96        var results = [], i, splitArgs = [], Class = this;
97
98        for (i = 1; i < arguments.length; i += 1) {
99            splitArgs.push(arguments[i]);
100        }
101        
102        function processElem(index, elem) {
103            var locateArgs = [elem].concat(splitArgs);
104
105            results.push(Class.locate.apply(Class, locateArgs));
106        }
107        
108        $context.filter(Class.QUERY).each(processElem);
109        $context.find(Class.QUERY).each(processElem);
110
111        return results;
112    };
113
114    /* Locate a behavior onto an element, returning an instance of that
115     * behavior that you can work with.
116     *
117     * A behavior locates onto an element by instantiating an instance of
118     * itself and installing it onto the markup's jQuery data. Therefore, we
119     * will only instantiate that behavior once; and further calls to .locate
120     * instead return the same object. Thus, it is safe to use .locate as a
121     * general accessor - it is idempotent.
122     *
123     * The elem argument indicates the element that the behavior should locate
124     * onto. Further arguments are passed onto the constructor.
125     *
126     * TODO: Is there a non-jQuery way of handling this?
127     */
128    Behavior.locate = function (elem) {
129        var $elem = $(elem), new_object, i, objectArgs = [elem], Class = this,
130            rc = $elem.data("behaviors-registered-classes");
131        
132        if ($elem.length === 0) {
133            throw new ElementMissingError("Attempted to locate a Behavior onto an empty element query.");
134        }
135
136        if (rc === undefined) {
137            rc = {};
138        }
139
140        if (rc[Class.name] === undefined) {
141            //Grab the other arguments
142            for (i = 1; i < arguments.length; i += 1) {
143                objectArgs.push(arguments[i]);
144            }
145
146            new_object = Object.create(Class.prototype);
147            Class.apply(new_object, objectArgs);
148            rc[Class.name] = new_object;
149        } else {
150            new_object = rc[Class.name];
151        }
152
153        $elem.data("behaviors-registered-classes", rc);
154
155        return new_object;
156    };
157
158    /* Respond to the presence of new content on the page.
159     *
160     * By default, we attempt to find markup on all children of the context.
161     * Subclasses may do something crazier, like say delay behavior processing
162     * until some third-party API is loaded.
163     *
164     * Consider this roughly equivalent to $(document).ready() callbacks.
165     */
166    Behavior.content_ready = function ($context) {
167        var Class = this;
168
169        Class.find_markup($context);
170    };
171    
172    /* Respond to the impending removal of content from the page.
173     * 
174     * Most behaviors that only attach event handlers to their own content are
175     * safe and do not need to implement content removal support: they will
176     * inherently "fall away".
177     * 
178     * However, behaviors that run a constant animation kernel or attach event
179     * handlers to elements outside of their own ownership must provide a
180     * mechanism to detach those event handlers and stop those kernels.
181     */
182    Behavior.content_removal = function ($context) {
183        var Class = this,
184            $attached_elems = $context.find(Class.QUERY);
185        
186        //Iterate through each element and see if our behavior has located upon
187        //them. We don't just call .find_markup/.locate since we don't want to
188        //risk initializing something just to tear it down one cycle later.
189        $attached_elems.each(function (index, attach_elem) {
190            var $elem = $(attach_elem),
191                rc = $elem.data("behaviors-registered-classes");
192            
193            if (rc === undefined) {
194                return;
195            }
196            
197            if (rc[Class.name] === undefined) {
198                return;
199            }
200            
201            if (rc[Class.name].deinitialize === undefined) {
202                return;
203            }
204            
205            rc[Class.name].deinitialize();
206        });
207    };
208
209    /* Register a behavior so that it can respond to global events such as new
210     * content becoming ready.
211     *
212     * It is not always appropriate to register your behavior to re
212cieve load
213     * events. Generally, if this is a behavior you would initialize yourself,
214     * perhaps with special arguments, then you should not register that here.
215     */
216    function register_behavior(Class, name) {
217        if (name === undefined) {
218            name = Class.name;
219        }
220
221        behavior_registry[name] = Class;
222    }
223    
224    /* Register a function that is called when content is ready.
225     * 
226     * This function should only be used for things that are not a Behavior.
227     * Proper behaviors should be registered using register_behavior for future
228     * uses. Non-behavior listeners get registered here so that future uses of
229     * behavior registration do not conflict with non-Behavior listeners.
230     */
231    function register_content_listener(func) {
232        content_ready_listeners.push(func);
233    }
234
235    /* Indicate that some new content is ready.
236     *
237     * The given content will be passed onto all registered behaviors.
238     *
239     * CMS/frameworks with their own ready mechanism will need to ship their
240     * own replacement/wrapper for this function that pushes calls to this
241     * function over to that mechanism; and calls from that mechanism need to
242     * come back here.
243     */
244    function content_ready($context) {
245        var k, i;
246        
247        function do_later(obj, func) {
248            window.setTimeout(func.bind(obj, $context), 0);
249        }
250        
251        for (i = 0; i < content_ready_listeners.length; i += 1) {
252            do_later(undefined, content_ready_listeners[i]);
253        }
254
255        for (k in behavior_registry) {
256            if (behavior_registry.hasOwnProperty(k)) {
257                do_later(behavior_registry[k], behavior_registry[k].content_ready);
258            }
259        }
260    }
261    
262    /* Indicate that content is about to be removed.
263     * 
264     * Registered behaviors with destructors will be called upon to remove any
265     * external event handlers or animation kernels preventing them from being
266     * terminated by the JS runtime.
267     * 
268     * TODO: Add content_removal listener functions.
269     */
270    function content_removal($context) {
271        var k, i;
272        
273        function do_later(obj, func) {
274            window.setTimeout(func.bind(obj, $context), 0);
275        }
276        
277        for (k in behavior_registry) {
278            if (behavior_registry.hasOwnProperty(k)) {
279                do_later(behavior_registry[k], behavior_registry[k].content_removal);
280            }
281        }
282    }
283    
284    function error(error_class_name, ParentClass) {
285        if (error_class_name === undefined) {
286            throw new Error("Please name your error subclass.");
287        }
288
289        if (!(ParentClass instanceof Function)) {
290            ParentClass = Error;
291        }
292
293        var SubError = function (message) {
294            var err = new Error(message);
295            err.name = error_class_name;
296
297            this.name = error_class_name;
298            this.message = err.message;
299            if (err.stack) {
300                this.stack = err.stack;
301            }
302        };
303
304        SubError.prototype = new ParentClass("u dont c me");
305        SubError.prototype.constructor = SubError;
306        SubError.prototype.name = error_class_name;
307
308        delete SubError.prototype.stack;
309
310        return SubError;
311    }
312    
313    function inherit(ChildClass, ParentClass) {
314        var k;
315
316        //Use the prototyping system to copy methods from parent to child.
317        ChildClass.prototype = Object.create(ParentClass.prototype);
318        ChildClass.prototype.constructor = ChildClass;
319        ChildClass.prototype.parent = ParentClass.prototype;
320
321        //Manually copy class-level methods from parent to child.
322        for (k in ParentClass) {
323            if (ParentClass.hasOwnProperty(k)) {
324                ChildClass[k] = ParentClass[k];
325            }
326        }
327    }
328
329    function init(ChildClass, object, args) {
330        ChildClass.prototype.parent.constructor.apply(object, args);
331    }
332    
333    /* By default, report the initial page load to registered behaviors.
334     */
335    $(document).ready(function () {
336        content_ready($(document));
337    });
338    
339    module.ElementMissingError = ElementMissingError;
340    module.throttle_single = throttle_single;
341    module.Behavior = Behavior;
342    module.error = error;
343    module.inherit = inherit;
344    module.init = init;
345    module.register_behavior = register_behavior;
346    module.content_ready = content_ready;
347    module.content_removal = content_removal;
348    module.register_content_listener = register_content_listener;
349
350    return module;
351}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.