PageSourceSearch

https://www.kareenaprivate.com.au/common/js/Menu/slide-menu.js

js kareenaprivate.com.au collected 2026-10-04 23:03:10 UTC 12,908 bytes, 386 lines download raw bytes

1'use strict';
2
3var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4
5function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7// TODO: make this library agnostic
8// TODO: document the events
9
10(function ($) {
11
12    var PLUGIN_NAME = 'slideMenu';
13    var DEFAULT_OPTIONS = {
14        position: 'right',
15        showBackLink: true,
16        keycodeOpen: null,
17        keycodeClose: 27, //esc
18        submenuLinkBefore: '',
19        submenuLinkAfter: '',
20        backLinkBefore: '',
21        backLinkAfter: ''
22    };
23
24    var SlideMenu = function () {
25        function SlideMenu(options) {
26            _classCallCheck(this, SlideMenu);
27
28            this.options = options;
29
30            this._menu = options.elem;
31
32            // Add wrapper
33            this._menu.find('ul:first').wrap('<div class="slider">');
34
35            this._anchors = this._menu.find('a');
36            this._slider = this._menu.find('.slider:first');
37
38            this._level = 0;
39            this._isOpen = false;
40            this._isAnimating = false;
41            this._hasMenu = this._anchors.length > 0;
42            this._lastAction = null;
43
44            this._setupEventHandlers();
45            this._setupMenu();
46
47            if (this._hasMenu) this._setupSubmenus();
48        }
49
50        /**
51         * Toggle the menu
52         * @param {boolean|null} open
53         * @param {boolean} animate
54         */
55
56
57        _createClass(SlideMenu, [{
58            key: 'toggle',
59            value: function toggle() {
60                var open = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
61                var animate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
62
63                var offset = void 0;
64
65                if (open === null) {
66                    if (this._isOpen) {
67                        this.close();
68                    } else {
69                        this.open();
70                    }
71                    return;
72                } else if (open) {
73                    offset = 0;
74                    this._isOpen = true;
75                } else {
76                    offset = this.options.position === 'left' ? '-100%' : '100%';
77                    this._isOpen = false;
78                }
79
80                this._triggerEvent();
81
82                if (animate) this._triggerAnimation(this._menu, offset);else {
83                    this._pauseAnimations(this._triggerAnimation.bind(this, this._menu, offset));
84                    this._isAnimating = false;
85                }
86            }
87
88            /**
89             * Open the menu
90             * @param {boolean} animate Use CSS transitions
91             */
92
93        }, {
94            key: 'open',
95            value: function open() {
96                var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
97
98                this._lastAction = 'open';
99                this.toggle(true, animate);
100            }
101
102            /**
103             * Close the menu
104             * @param {boolean} animate Use CSS transitions
105             */
106
107        }, {
108            key: 'close',
109            value: function close() {
110                var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
111
112                this._lastAction = 'close';
113                this.toggle(false, animate);
114            }
115
116            /**
117             * Navigate one menu hierarchy back if possible
118             */
119
120        }, {
121            key: 'back',
122            value: function back() {
123                this._lastAction = 'back';
124                this._navigate(null, -1);
125            }
126
127            /**
128             * Navigate to a specific link on any level (useful to open the correct hierarchy directly)
129             * @param {string|object}
129 target A string selector a plain DOM object or a jQuery instance
130             */
131
132        }, {
133            key: 'navigateTo',
134            value: function navigateTo(target) {
135                var _this = this;
136
137                target = this._menu.find($(target)).first();
138
139                if (!target.length) return false;
140
141                var parents = target.parents('ul');
142                var level = parents.length - 1;
143
144                if (level === 0) return false;
145
146                this._pauseAnimations(function () {
147                    _this._level = level;
148                    parents.show().first().addClass('active');
149                    _this._triggerAnimation(_this._slider, -_this._level * 100);
150                });
151            }
152
153            /**
154             * Set up all event handlers
155             * @private
156             */
157
158        }, {
159            key: '_setupEventHandlers',
160            value: function _setupEventHandlers() {
161                var _this2 = this;
162
163                if (this._hasMenu) {
164                    this._anchors.click(function (event) {
165                        var anchor = $(event.target).is('a') ? $(event.target) : $(event.target).parents('a:first');
166                        _this2._navigate(anchor);
167                    });
168                }
169
170                $(this._menu.add(this._slider)).on('transitionend msTransitionEnd', function () {
171                    _this2._isAnimating = false;
172                    _this2._triggerEvent(true);
173                });
174
175                $(document).keydown(function (e) {
176                    switch (e.which) {
177                        case _this2.options.keycodeClose:
178                            _this2.close();
179                            break;
180
181                        case _this2.options.keycodeOpen:
182                            _this2.open();
183                            break;
184
185                        default:
186                            return;
187                    }
188                    e.preventDefault();
189                });
190
191                this._menu.on('sm.back-after', function () {
192                    var lastActiveUl = 'ul ' + '.active '.repeat(_this2._level + 1);
193                    _this2._menu.find(lastActiveUl).removeClass('active').hide();
194                });
195            }
196
197            /**
198             * Trigger a custom event to support callbacks
199             * @param {boolean} afterAnimation Mark this event as `before` or `after` callback
200             * @private
201             */
202
203        }, {
204            key: '_triggerEvent',
205            value: function _triggerEvent() {
206                var afterAnimation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
207
208                var eventName = 'sm.' + this._lastAction;
209                if (afterAnimation) eventName += '-after';
210                this._menu.trigger(eventName);
211            }
212
213            /**
214             * Navigate the _menu - that is slide it one step left or right
215             * @param {jQuery} anchor The clicked anchor or button element
216             * @param {int} dir Navigation direction: 1 = forward, 0 = backwards
217             * @private
218             */
219
220        }, {
221            key: '_navigate',
222            value: function _navigate(anchor) {
223                var dir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
224
225                // Abort if an animation is still running
226                if (this._isAnimating) {
227                    return;
228                }
229
230                var offset = (this._level + dir) * -100;
231
232                if (dir > 0) {
233                    if (!anchor.next('ul').length) return;
234
235                    anchor.next('ul').addClass('active').show();
236                } else if (this._level === 0) {
237                    return;
238                }
239
240                this._lastAction = dir > 0 ? 'forward' : 'back';
241                this._level = this._level + dir;
242
243                this._triggerAnimation(this._slider, offset);
244            }
245
246            /**
247             * Start the animation (the CSS transition)
248             * @param elem
249             * @param offset
250             * @private
251             */
252
253        }, {
254            key: '_triggerAnimation',
255            value: function _triggerAnimation(elem, offset) {
256                this._triggerEvent();
257
258                if (!(String(offset).indexOf('%') !== -1)) offset += '%';
259
260                elem.css('transform', 'translateX(' + offset + ')');
261                this._isAnimating = true;
262            }
263
264            /**
265             * Initialize the menu
266             * @private
267             */
268
269        }, {
270            key: '_setupMenu',
271            value: function _setupMenu() {
272                var _this3 = this;
273
274                this._pauseAnimations(function () {
275                    switch (_this3.options.position) {
276                        case 'left':
277                            _this3._menu.css({
278                                left: 0,
279                                right: 'auto',
280                                transform: 'translateX(-100%)'
281                            });
282                            break;
283                        default:
284                            _this3._menu.css({
285                                left: 'auto',
286                                right: 0
287                            });
288                            break;
289                    }
290                    _this3._menu.show();
291                });
292            }
293
294            /**
295             * Pause the CSS transitions, to apply CSS changes directly without an animation
296             * @param work
297             * @private
298             */
299
300        }, {
301            key: '_pauseAnimations',
302            value: function _pauseAnimations(work) {
303                this._menu.addClass('no-transition');
304                work();
305                this._menu[0].offsetHeight; // trigger a reflow, flushing the CSS changes
306                this._menu.removeClass('no-transition');
307            }
308
309            /**
310             * Enhance the markup of menu items which contain a submenu
311             * @private
312             */
313
314        }, {
315            key: '_setupSubmenus',
316            value: function _setupSubmenus() {
317                var _this4 = this;
318
319                this._anchors.each(function (i, anchor) {
320                    anchor = $(anchor);
321                    if (anchor.next('ul').length) {
322                        // prevent default behaviour (use link just to navigate)
323                        anchor.click(function (ev) {
324                            ev.preventDefault();
325                        });
326
327                        // add `before` and `after` text
328                        var anchorTitle = anchor.text();
329                        anchor.html(_this4.options.submenuLinkBefore + anchorTitle + _this4.options.submenuLinkAfter);
330
331                        // add a back button
332                        if (_this4.options.showBackLink) {
333                            var backLink = $('<a href class="slide-menu-control" data-action="back">' + anchorTitle + '</a>');
334                            backLink.html(_this4.options.backLinkBefore + backLink.text() + _this4.options.backLinkAfter);
335                            anchor.next('ul').prepend($('<li>').append(backLink));
336                        }
337                    }
338                });
339            }
340        }]);
341
342        return SlideMenu;
343    }();
344
345    // Link control buttons with the API
346
347
348    $('body').on('click', '.slide-menu-control', function (e) {
349        var menu = void 0;
350        var target = $(this).data('target');
351
352        if (!target || target === 'this') {
353            menu = $(this).parents('.slide-menu:first');
354        } else {
355            menu = $('#' + target);
356        }
357
358        if (!menu.length) return;
359
360        var instance = menu.data(PLUGIN_NAME);
361        var action = $(this).data('action');
362
363        if (instance && typeof instance[action] === 'function') {
364            instance[action]();
365        }
366
367        return false;
368    });
369
370    // Register the jQuery plugin
371    $.fn[PLUGIN_NAME] = function (options) {
372        if (!$(this).length) {
373            console.warn('Slide Menu: Unable to find menu DOM element. Maybe a typo?');
374            return;
375        }
376
377        options = $.extend({}, DEFAULT_OPTIONS, options);
378        options.elem = $(this);
379
380        var instance = new SlideMenu(options);
381        $(this).data(PLUGIN_NAME, instance);
382
383        return instance;
384    };
385})(jQuery);
386//# sourceMappingURL=slide-menu.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.