PageSourceSearch

https://mason360.gmu.edu/static/js/metisMenuCustom.js?v=1

js gmu.edu collected 2026-09-24 07:03:27 UTC 18,153 bytes, 452 lines download raw bytes

1/*------------------------------------*\
2    @UTILITIES
3\*------------------------------------*/
4var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? 
5    function (obj) {
6        return typeof obj;
7    } 
8    : 
9    function (obj) {
10        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
11    };
12
13var _extends = Object.assign || function (target) {
14    for (var i = 1; i < arguments.length; i++) {
15        var source = arguments[i];
16        for (var key in source) {
17            if (Object.prototype.hasOwnProperty.call(source, key)) {
18                target[key] = source[key];
19            }
20        }
21    }
22    return target;
23};
24
25var _createClass = function () {
26    function defineProperties(target, props) {
27        for (var i = 0; i < props.length; i++) {
28            var descriptor = props[i];
29            descriptor.enumerable = descriptor.enumerable || false;
30            descriptor.configurable = true;
31            if ("value" in descriptor) descriptor.writable = true;
32            Object.defineProperty(target, descriptor.key, descriptor);
33        }
34    }
35    return function (Constructor, protoProps, staticProps) {
36        if (protoProps) defineProperties(Constructor.prototype, protoProps);
37        if (staticProps) defineProperties(Constructor, staticProps);
38        return Constructor;
39    };
40}();
41
42function _classCallCheck(instance, Constructor) {
43    if (!(instance instanceof Constructor)) {
44        throw new TypeError("Cannot call a class as a function");
45    }
46}
47
48function hasActiveChild(element) {
49  return $(element).parent().find('.active').length > 0;
50}
51
52
53var Util = function ($) {
54    // eslint-disable-line no-shadow
55    var TRANSITION_END = 'transitionend';
56
57    var Util = { // eslint-disable-line no-shadow
58        TRANSITION_END: 'mmTransitionEnd',
59
60        triggerTransitionEnd: function triggerTransitionEnd(element) {
61            $(element).trigger(TRANSITION_END);
62        },
63        supportsTransitionEnd: function supportsTransitionEnd() {
64            return Boolean(TRANSITION_END);
65        }
66    };
67
68    function getSpecialTransitionEndEvent() {
69        return {
70            bindType: TRANSITION_END,
71            delegateType: TRANSITION_END,
72            handle: function handle(event) {
73                if ($(event.target).is(this)) {
74                    return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
75                }
76                return undefined;
77            }
78        };
79    }
80
81    function transitionEndEmulator(duration) {
82        var _this = this;
83
84        var called = false;
85
86        $(this).one(Util.TRANSITION_END, function () {
87            called = true;
88        });
89
90        setTimeout(function () {
91            if (!called) {
92                Util.triggerTransitionEnd(_this);
93            }
94        }, duration);
95
96        return this;
97    }
98
99    function setTransitionEndSupport() {
100        $.fn.mmEmulateTransitionEnd = transitionEndEmulator; // eslint-disable-line no-param-reassign
101        // eslint-disable-next-line no-param-reassign
102        $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
103    }
104
105    setTransitionEndSupport();
106
107    return Util;
108}($);
109
110var MetisMenu = function ($) {
111    // eslint-disable-line no-shadow
112    var NAME = 'metisMenu';
113    var DATA_KEY = 'metisMenu';
114    var EVENT_KEY = '.' + DATA_KEY;
115    var DATA_API_KEY = '.data-api';
116    var JQUERY_NO_CONFLICT = $.fn[NAME];
117    var TRANSITION_DURATION = 350;
118
119    var Default = {
120        toggle: true,
121        preventDefault: true,
122        activeClass: 'active',
123        collapseClass: 'collapse',
124        collapseInClass: 'in',
125        collapsingClass: 'collapsing',
126        triggerElement: 'a',
127        parentTrigger: 'li',
128        subMenu: 'ul',
129        hashtag: false,
130        url: '',
131        ajaxContainerId: ''
132    };
133
134    var Event = {
135        SHOW: 'show' + EVENT_KEY,
136        SHOWN: 'shown' + EVENT_KEY,
137        HIDE: 'hide' + EVENT_KEY,
138        HIDDEN: 'hidden' + EVENT_KEY,
139        CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
140    };
141
142    var MetisMenu = function () {
143        // eslint-disable-line no-shadow
144        function MetisMenu(element, config) {
145            _classCallCheck(this, MetisMenu);
146
147            this.element = element;
148            this.config = _extends({}, Default, config);
149            this.transitioning = null;
150
151            this.init();
152        }
153
154        _createClass(MetisMenu, [{
155            key: 'init',
156            value: function init() {
157                var self = this;
158                var conf = this.config;
159                var matchingMenuElement = $(self.getActiveLink());
160
161                // First Load
162                if (matchingMenuElement != null) {
163                    matchingMenuElement.addClass("active");
164                    matchingMenuElement.parent().addClass("active"); // add active to li of the current link
165                    matchingMenuElement.parent().parent().addClass("in");
166                    matchingMenuElement.parent().parent().prev().addClass("active"); // add active class to an anchor
167                    matchingMenuElement.parent().parent().parent().addClass("active");
168                }
169
170                //Create hashchange binding
171                $(window).on('hashchange', function (e, hasActiveChild) {
172                    matchingMenuElement = $(self.getActiveLink());
173
174                    if (matchingMenuElement === null || matchingMenuElement.length === 0) {
175                        //Menu not found.
176                    } else {
177                        var isRootElement = !matchingMenuElement.parent().parent().hasClass("nav-second-level");
178
179                        if (isRootElement) {
180                            var List = matchingMenuElement.parent("li").siblings("li").children("ul.in");
181                            self.hide(List);
182                        } else {
183                            if (!matchingMenuElement.parent("li").parent("ul").hasClass("in")) {
184                                self.show(matchingMenuElement.parent("li").parent("ul"));
185                                const transitionSidebarEvent = new CustomEvent('transitionSidebar');
186                                document.dispatchEvent(transitionSidebarEvent);
187                            } else if (hasActiveChild) {
188                                //Hide parent if already shown.
189                                self.hide(matchingMenuElement.parent("li").parent("ul"));
190                                matchingMenuElement.parent("li").removeClass("active");
191                                const transitionSidebarEvent = new CustomEvent('transitionSidebar');
192                                document.dispatchEvent(transitionSidebarEvent);
193                                return;
194                            }
195                        }
196
197                        self.deactivateActiveElement();
198                        self.activateElement(matchingMenuElement);
199                    }
200                });
201
202                //
203                // adjust aria content of parent menu container
204                //
205                if (typeof linkElement !== 'undefined' && linkElement !== null) {
206                    updateLeftNavigationParentMenuAriaAttributes(linkElement);
207                }
208
209            }
210        }, {
211            key: 'activateElement',
212            value: function activateElement(element) {
213                element.addClass("active").parent().addClass("active").parent().prev().addClass("active");
214                element.parent().parent().parent().addClass("active").parent().parent().addClass("active");
215            }
216        }, {
217            key: 'deactivateActiveElement',
218            value: function deactivateActiveElement() {
219                var element = $("#sidebar-menu a.axid.active");
220                element.removeClass("active").parent().removeClass("active").parent().prev().removeClass("active").parent().removeClass("active");
221            }
222        }, {
223            key: 'getActiveLink',
224            value: function getActiveLink() {
225                let self = this;
226                let potentialMatchingMenuElements = $("#" + self.element.id + " a[href^='" + new URL(location.href).pathname + "']");
227                let matchingMenuElements = [];
228                Array.from(potentialMatchingMenuElements).forEach(item => { 
229                    if ((new URL(location.href).pathname + new URL(location.href).search).indexOf(item.attributes.href.value) >= 0) {
230                        matchingMenuElements.push(item);
231                    }
232                });
233
234                if (matchingMenuElements.length != 0) {
235                    return matchingMenuElements.reduce(function (a, b) { return a.getAttribute("href").length > b.getAttribute("href").length ? a : b; });
236                }
237                else {
238                    let defaultMenuElement = $("#side-menu a[href^='" + $("body").attr("data-menu") + "']");
239                    if (defaultMenuElement.length != 0) { 
240                        return Array.from(defaultMenuElement).reduce(function (a, b) { return $(a).parentsUntil("#" + self.element.i
240d).length >= $(b).parentsUntil("#" + self.element.id).length ? a : b; });
241                    }
242                    else {
243                        return null;
244                    }
245                }
246            }
247        }, {
248            key: 'show',
249            value: function show(element) {
250                var _this2 = this;
251
252                if (this.transitioning || $(element).hasClass(this.config.collapsingClass)) {
253                    return;
254                }
255                var elem = $(element);
256
257                var startEvent = $.Event(Event.SHOW);
258                elem.trigger(startEvent);
259
260                if (startEvent.isDefaultPrevented()) {
261                    return;
262                }
263
264                elem.parent(this.config.parentTrigger).addClass(this.config.activeClass);
265
266                if (this.config.toggle) {
267                    this.hide(elem.parent(this.config.parentTrigger).siblings().children(this.config.subMenu + '.' + this.config.collapseInClass).attr('aria-expanded', false));
268                }
269
270                elem.removeClass(this.config.collapseClass).addClass(this.config.collapsingClass).height(0);
271
272                this.setTransitioning(true);
273
274                var complete = function complete() {
275                    // check if disposed
276                    if (!_this2.config || !_this2.element) {
277                        return;
278                    }
279                    elem.removeClass(_this2.config.collapsingClass).addClass(_this2.config.collapseClass + ' ' + _this2.config.collapseInClass).height('').attr('aria-expanded', true);
280
281                    _this2.setTransitioning(false);
282
283                    elem.trigger(Event.SHOWN);
284                };
285
286                if (!Util.supportsTransitionEnd()) {
287                    complete();
288                    return;
289                }
290
291                elem.height(element[0].scrollHeight).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
292            }
293        }, {
294            key: 'hide',
295            value: function hide(element) {
296                var _this3 = this;
297
298                if (this.transitioning || !$(element).hasClass(this.config.collapseInClass)) {
299                    return;
300                }
301
302                var elem = $(element);
303
304                var startEvent = $.Event(Event.HIDE);
305                elem.trigger(startEvent);
306
307                if (startEvent.isDefaultPrevented()) {
308                    return;
309                }
310
311                elem.parent(this.config.parentTrigger).removeClass(this.config.activeClass);
312                // eslint-disable-next-line no-unused-expressions
313                elem.height(elem.height())[0].offsetHeight;
314
315                elem.addClass(this.config.collapsingClass).removeClass(this.config.collapseClass).removeClass(this.config.collapseInClass);
316
317                this.setTransitioning(true);
318
319                var complete = function complete() {
320                    // check if disposed
321                    if (!_this3.config || !_this3.element) {
322                        return;
323                    }
324                    if (_this3.transitioning && _this3.config.onTransitionEnd) {
325                        _this3.config.onTransitionEnd();
326                    }
327
328                    _this3.setTransitioning(false);
329                    elem.trigger(Event.HIDDEN);
330
331                    elem.removeClass(_this3.config.collapsingClass).addClass(_this3.config.collapseClass).attr('aria-expanded', false);
332                };
333
334                if (!Util.supportsTransitionEnd()) {
335                    complete();
336                    return;
337                }
338
339                if (elem.height() === 0 || elem.css('display') === 'none') {
340                    complete();
341                } else {
342                    elem.height(0).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
343                }
344            }
345        }, {
346            key: 'setTransitioning',
347            value: function setTransitioning(isTransitioning) {
348                this.transitioning = isTransitioning;
349            }
350        }, {
351            key: 'dispose',
352            value: function dispose() {
353                $.removeData(this.element, DATA_KEY);
354
355                $(this.element).find(this.config.parentTrigger).has(this.config.subMenu).
355children(this.config.triggerElement).off('click');
356
357                this.transitioning = null;
358                this.config = null;
359                this.element = null;
360            }
361        }], [{
362            key: 'jQueryInterface',
363            value: function jQueryInterface(config) {
364                // eslint-disable-next-line func-names
365                return this.each(function () {
366                    var $this = $(this);
367                    var data = $this.data(DATA_KEY);
368                    var conf = _extends({}, Default, $this.data(), (typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object' && config ? config : {});
369
370                    if (!data && /dispose/.test(config)) {
371                        this.dispose();
372                    }
373
374                    if (!data) {
375                        data = new MetisMenu(this, conf);
376                        $this.data(DATA_KEY, data);
377                    }
378
379                    if (typeof config === 'string') {
380                        if (data[config] === undefined) {
381                            throw new Error('No method named "' + config + '"');
382                        }
383                        data[config]();
384                    }
385                });
386            }
387        }]);
388
389        return MetisMenu;
390    }();
391    /**
392     * ------------------------------------------------------------------------
393     * jQuery
394     * ------------------------------------------------------------------------
395     */
396
397    $.fn[NAME] = MetisMenu.jQueryInterface; // eslint-disable-line no-param-reassign
398    $.fn[NAME].Constructor = MetisMenu; // eslint-disable-line no-param-reassign
399    $.fn[NAME].noConflict = function () {
400        // eslint-disable-line no-param-reassign
401        $.fn[NAME] = JQUERY_NO_CONFLICT; // eslint-disable-line no-param-reassign
402        return MetisMenu.jQueryInterface;
403    };
404    return MetisMenu;
405}($);
406
407// ----------------------------------------------------------------------------------
408// update left menu expandable elements after state change (or after initial load complete)
409// - set aria-expanded=true/false depending on state and append message to aria-label when expanded
410//   ... This item is currently expanded.
411// ----------------------------------------------------------------------------------
412function updateLeftNavigationParentMenuAriaAttributes(jqLinkElement) {
413
414    // console.log('updateLeftNavigationParentMenuAriaAttributes() begins...');
415
416    if (typeof jqLinkElement === 'undefined' || jqLinkElement === null) {
417        console.error('jqLinkElement is empty');
418        return;
419    }
420
421    var eZero = $(jqLinkElement).get(0);
422    var pZero = jqLinkElement.parent().parent().prev();
423    if (typeof pZero !== 'undefined' && pZero !== null) {
424        var eParentMenu = $(pZero).get(0);
425        if (typeof eParentMenu !== 'undefined' && eParentMenu !== null) {
426
427            var eParentMenuAriaLabel = eParentMenu.getAttribute('aria-label');
428            if (typeof eParentMenuAriaLabel === 'undefined' || eParentMenuAriaLabel === null) {
429                eParentMenuAriaLabel = '';
430            }
431
432            if (eParentMenu.classList.contains('active')) {
433                eParentMenu.setAttribute('aria-expanded', 'true');
434                var sx = eParentMenuAriaLabel.indexOf('This item is');
435                if (sx > 0) {
436                    eParentMenuAriaLabel = eParentMenuAriaLabel.substring(0, sx).trim();
437                }
438                eParentMenuAriaLabel = eParentMenuAriaLabel + ' This item is currently expanded.';
439            } else {
440                eParentMenu.setAttribute('aria-expanded', 'false');
441                eParentMenu.setAttribute('aria-expanded', 'true');
442                var sx = eParentMenuAriaLabel.indexOf('This item is');
443                if (sx > 0) {
444                    eParentMenuAriaLabel = eParentMenuAriaLabel.substring(0, sx).trim();
445                }
446                eParentMenuAriaLabel = eParentMenuAriaLabel + ' This item is currently collapsed.';
447            }
448
449            eParentMenu.setAttribute('aria-label', eParentMenuAriaLabel);
450        }
451    }
452}

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.