PageSourceSearch

https://titusb.nl/media/vendor/metismenujs/js/metismenujs.js?1.4.0

js titusb.nl collected 2026-10-08 08:26:19 UTC 8,722 bytes, 232 lines download raw bytes

vendor: 8,722 bytes, lines 1-232
1/*!
2* metismenujs - v1.4.0
3* MetisMenu: Collapsible menu plugin with Vanilla-JS
4* https://github.com/onokumus/metismenujs#readme
5*
6* Made by Osman Nuri Okumus <[email protected]> (https://github.com/onokumus)
7* Under MIT License
8*/
9(function (global, factory) {
10    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11    typeof define === 'function' && define.amd ? define(factory) :
12    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MetisMenu = factory());
13})(this, (function () { 'use strict';
14
15    const Default = {
16        parentTrigger: 'li',
17        subMenu: 'ul',
18        toggle: true,
19        triggerElement: 'a',
20    };
21    const ClassName = {
22        ACTIVE: 'mm-active',
23        COLLAPSE: 'mm-collapse',
24        COLLAPSED: 'mm-collapsed',
25        COLLAPSING: 'mm-collapsing',
26        METIS: 'metismenu',
27        SHOW: 'mm-show',
28    };
29
30    /* eslint-disable max-len */
31    class MetisMenu {
32        /**
33         * Creates an instance of MetisMenu.
34         *
35         * @constructor
36         * @param {Element | string} element
37         * @param {IMMOptions} [options]
38         * @memberof MetisMenu
39         */
40        constructor(element, options) {
41            this.element = MetisMenu.isElement(element) ? element : document.querySelector(element);
42            this.config = Object.assign(Object.assign({}, Default), options);
43            this.disposed = false;
44            this.triggerArr = [];
45            this.boundEventHandler = this.clickEvent.bind(this);
46            this.init();
47        }
48        static attach(el, opt) {
49            return new MetisMenu(el, opt);
50        }
51        /**
52         * @internal
53         */
54        init() {
55            const { METIS, ACTIVE, COLLAPSE } = ClassName;
56            this.element.classList.add(METIS);
57            const uls = [...this.element.querySelectorAll(this.config.subMenu)];
58            if (uls.length === 0) {
59                return;
60            }
61            uls.forEach((ul) => {
62                ul.classList.add(COLLAPSE);
63                const li = ul.closest(this.config.parentTrigger);
64                if (li === null || li === void 0 ? void 0 : li.classList.contains(ACTIVE)) {
65                    this.show(ul);
66                }
67                else {
68                    this.hide(ul);
69                }
70                const a = li === null || li === void 0 ? void 0 : li.querySelector(this.config.triggerElement);
71                if ((a === null || a === void 0 ? void 0 : a.getAttribute("aria-disabled")) === "true") {
72                    return;
73                }
74                a === null || a === void 0 ? void 0 : a.setAttribute("aria-expanded", "false");
75                a === null || a === void 0 ? void 0 : a.addEventListener("click", this.boundEventHandler);
76                this.triggerArr.push(a);
77            });
78        }
79        /**
80         * @internal
81         */
82        clickEvent(evt) {
83            if (!this.disposed) {
84                const target = evt === null || evt === void 0 ? void 0 : evt.currentTarget;
85                if (target && target.tagName === "A") {
86                    evt.preventDefault();
87                }
88                const li = target.closest(this.config.parentTrigger);
89                const ul = li === null || li === void 0 ? void 0 : li.querySelector(this.config.subMenu);
90                this.toggle(ul);
91            }
92        }
93        update() {
94            this.disposed = false;
95            this.init();
96        }
97        dispose() {
98            this.triggerArr.forEach((arr) => {
99                arr.removeEventListener("click", this.boundEventHandler);
100            });
101            this.disposed = true;
102        }
103        on(evtType, handler, options) {
104            this.element.addEventListener(evtType, handler, options);
105            return this;
106        }
107        off(evtType, handler, options) {
108            this.element.removeEventListener(evtType, handler, options);
109            return this;
110        }
111        /**
112         * @internal
113         */
114        emit(evtType, evtData, shouldBubble = false) {
115            const evt = new CustomEvent(evtType, {
116                bubbles: shouldBubble,
117                detail: evtData,
118            });
119            this.element.dispatchEvent(evt);
120        }
121        /**
122         * @internal
123         */
124        toggle(ul) {
125            const li = ul.closest(this.config.parentTrigger);
126            if (li === null || li === void 0 ? void 0 : li.classList.contains(ClassName.ACTIVE)) {
127                this.hide(ul);
128            }
129            else {
130                this.show(ul);
131            }
132        }
133        /**
134         * @internal
135         */
136        show(el) {
137            var _a;
138            const ul = el;
139            const { ACTIVE, COLLAPSE, COLLAPSED, COLLAPSING, SHOW } = ClassName;
140            if (this.isTransitioning || ul.classList.contains(COLLAPSING)) {
141                return;
142            }
143            const complete = () => {
144                ul.classList.remove(COLLAPSING);
145                ul.style.height = "";
146                ul.removeEventListener("transitionend", complete);
147                this.setTransitioning(false);
148                this.emit("shown.metisMenu", {
149                    shownElement: ul,
150                });
151            };
152            const li = ul.closest(this.config.parentTrigger);
153            li === null || li === void 0 ? void 0 : li.classList.add(ACTIVE);
154            const a = li === null || li === void 0 ? void 0 : li.querySelector(this.config.triggerElement);
155            a === null || a === void 0 ? void 0 : a.setAttribute("aria-expanded", "true");
156            a === null || a === void 0 ? void 0 : a.classList.remove(COLLAPSED);
157            ul.style.height = "0px";
158            ul.classList.remove(COLLAPSE);
159            ul.classList.remove(SHOW);
160            ul.classList.add(COLLAPSING);
161            const eleParentSiblins = [].slice.call((_a = li === null || li === void 0 ? void 0 : li.parentNode) === null || _a === void 0 ? void 0 : _a.children).filter((c) => c !== li);
162            if (this.config.toggle && eleParentSiblins.length > 0) {
163                eleParentSiblins.forEach((sibli) => {
164                    const sibUl = sibli.querySelector(this.config.subMenu);
165                    if (sibUl) {
166                        this.hide(sibUl);
167                    }
168                });
169            }
170            this.setTransitioning(true);
171            ul.classList.add(COLLAPSE);
172            ul.classList.add(SHOW);
173            ul.style.height = `${ul.scrollHeight}px`;
174            this.emit("show.metisMenu", {
175                showElement: ul,
176            });
177            ul.addEventListener("transitionend", complete);
178        }
179        /**
180         * @internal
181         */
182        hide(el) {
183            const { ACTIVE, COLLAPSE, COLLAPSED, COLLAPSING, SHOW } = ClassName;
184            const ul = el;
185            if (this.isTransitioning || !ul.classList.contains(SHOW)) {
186                return;
187            }
188            this.emit("hide.metisMenu", {
189                hideElement: ul,
190            });
191            const li = ul.closest(this.config.parentTrigger);
192            li === null || li === void 0 ? void 0 : li.classList.remove(ACTIVE);
193            const complete = () => {
194                ul.classList.remove(COLLAPSING);
195                ul.classList.add(COLLAPSE);
196                ul.style.height = "";
197                ul.removeEventListener("transitionend", complete);
198                this.setTransitioning(false);
199                this.emit("hidden.metisMenu", {
200                    hiddenElement: ul,
201                });
202            };
203            ul.style.height = `${ul.getBoundingClientRect().height}px`;
204            ul.style.height = `${ul.offsetHeight}px`;
205            ul.classList.add(COLLAPSING);
206            ul.classList.remove(COLLAPSE);
207            ul.classList.remove(SHOW);
208            this.setTransitioning(true);
209            ul.addEventListener("transitionend", complete);
210            ul.style.height = "0px";
211            const a = li === null || li === void 0 ? void 0 : li.querySelector(this.config.triggerElement);
212            a === null || a === void 0 ? void 0 : a.setAttribute("aria-expanded", "false");
213            a === null || a === void 0 ? void 0 : a.classList.add(COLLAPSED);
214        }
215        /**
216         * @internal
217         */
218        setTransitioning(isTransitioning) {
219            this.isTransitioning = isTransitioning;
220        }
221        /**
222         * @internal
223         */
224        static isElement(element) {
225            return Boolean(element.classList);
226        }
227    }
228
229    return MetisMenu;
230
231}));
232//# sourceMappingURL=metismenujs.js.map

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.