PageSourceSearch

https://xn--80aesudagwf.xn--p1ai/g/templates/shop2/2.89.2/js/jquery.waslidemenu.min.js

js xn--80aesudagwf.xn--p1ai collected 2026-10-08 08:05:48 UTC 19,048 bytes, 451 lines download raw bytes

1/**
2 * waSlideMenu - jQuery plugin for menu organization like Facebook Help Page.
3 * @version v1.0.7
4 * @link https://github.com/webasyst/waslidemenu
5 * @license MIT
6 */
7/*global $, jQuery*/
8(function ($, window, document, undefined) {
9    "use strict";
10
11    $.waSlideMenu = function (el, options) {
12        var pluginName = 'SlideMenu',
13            base = this,
14            element = el;
15
16        // Apply namespace to css classes
17        base._addCssNamespace = function (attrNames, namespace) {
18            var obj = {};
19            $.each(attrNames, function (k, v) {
20                if (typeof v === 'string') {
21                    obj[k] = namespace + pluginName + v;
22                }
23            });
24
25            return obj;
26        };
27        // setup DOM elements, variables
28        base._setup = function () {
29            base.o = $.extend({}, $.waSlideMenu.defaults, options);
30
31            base.o.classNames = base._addCssNamespace(base.o.classNames, base.o.namespace);
32
33            // Access to jQuery and DOM versions of element
34            base.$waSlideMenu = $(el);
35
36            // Add reverse reference object
37            base.$waSlideMenu.data(pluginName, base);
38
39            base.$backs = []; // backlink menu items
40            base.$items = base.$waSlideMenu.find(base.o.itemSelector);
41            base.$waSlideMenu.addClass(base.o.classNames.navigationClass);
42
43            // wrap all navigation
44            base.$movable = $('<div/>', {
45                'class' : base.o.classNames.wrapperClass
46            });
47            // detach?
48            // root and all other inherited menus
49            base.$inheritedMenus = base.$waSlideMenu.find(base.o.menuSelector);
50            base.$rootMenu = $(base.$inheritedMenus.splice(0, 1));
51
52            base.$rootMenu
53                .addClass(base.o.classNames.allMenusClass)
54                .appendTo(base.$movable.prependTo(base.$waSlideMenu));
55            // add css to menus for floating left to right
56            base.$inheritedMenus.addClass(base.o.classNames.allMenusClass + ' ' + base.o.classNames.inheritedMenuClass);
57
58            var menu_item_tagname = base.$items.prop("tagName");
59
60            // add 'back' buttons
61            base.$inheritedMenus.each(function (i, val) {
62                var url = $(val)
63                        .closest(base.o.itemSelector)
64                        .children('a')
65                        .attr('href'),
66                    $li = $('<' + menu_item_tagname + '/>', {
67                        'class': base.o.classNames.menuItemBackClass
68                    });
69
70                if (base.o.backOnTop) {
71                    $li.prependTo($(val));
72                } else {
73                    $li.appendTo($(val));
74                }
75
76                base.$backs.push(
77                    $li.append($('<a>', {'href' : url})
78                        .html(base.o.backLinkContent))
79                );
80            });
81            // minimum height fix
82            if (base.o.minHeightMenu > 0) {
83                base.o.minHeightMenu = base.o.minHeightMenu > base.$waSlideMenu.height() ? base.o.minHeightMenu : base.$waSlideMenu.height();
84                base.$waSlideMenu.css('min-height', base.o.minHeightMenu);
85            }
86            base.o.previousHeight = 0;
87            base.o.nowSliding = false;
88        };
89        // go to selected item
90        base.gotoSelected = function (depth, animate) {
91            // we need to go deeper
92            base._hideOtherMenus(depth, base._scrollToTop);
93            // height fix
94            base._heightFix(depth);
95            // sliiiiide to other level
96            base._animateSlide(depth, animate);
97        };
98        // animate function
99        base._animateSlide = function (depth, animate) {
100            var amount = Math.abs(depth * 100),
101                callback_slide = depth > 0 ? base.o.onSlideForward : base.o.onSlideBack;
102
103            // onSlide or onSlideBack callback
104            if (callback_slide && typeof (callback_slide) === 'function') {
105                callback_slide(base);
106            }
107            if (animate) {
108                base.o.nowSliding = true;
109                base.$movable.animate(
110                    {
111                        'left': depth > 0 ? '-=' + amount + '%' : '+=' + amount + '%'
112                    },
113                    base.o.slideSpeed,
114                    base.o.slideEasing,
115                    function () {
116                        base.o.nowSliding = false;
117                        base._scrollToTop(depth);
118                        // afterSlide callback
119                        if (base.o.afterSlide && typeof (base.o.afterSlide) === 'function') {
120                            base.o.afterSlide(base);
121                        }
122                    }
123                );
124            } else {
125                base.$movable.css('left', '-' + amount + '%');
126            }
127        };
128        base._scrollToTop = function (depth) {
129            var $menu_children = base.$currentMenuElement.children(base.o.menuSelector),
130                back_link = base.$currentMenuElement.hasClass(base.o.classNames.menuItemBackClass) ? true : false;
131
132            // we need to understand, are backlink or previous link visible in viewport
133            if (base.o.scrollToTopSpeed && (back_link || $menu_children.length > 0)) {
134                var $back = depth > 0 ? $menu_children.children(base.o.itemSelector).last() : base.$currentMenuElement,
135                    $offset_elem = depth > 0 ? $back.closest(base.o.menuSelector) : base.$currentMenuElement,
136                    back_pos_top = $back.offset().top,
137                    win_pos_top = $(window).scrollTop();
138                if (back_pos_top - win_pos_top < 0) {
139                    $('html, body').animate({
140                        scrollTop: $offset_elem.offset().top
141                    }, base.o.scrollToTopSpeed);
142                }
143            }
144        };
145        base._heightFix = function (depth) {
146            if (base.o.autoHeightMenu) {
147                var h = 0,
148                    to_currentmenuelement_h = 0;
149                if (depth > 0) { // forward - height of inherited menu
150                    to_currentmenuelement_h = (base.$currentMenuElement.offset().top - base.$waSlideMenu.offset().top) + base.$currentMenuElement.outerHeight();
151                    h = base.$currentMenuElement
152                        .children(base.o.menuSelector)
153                        .height();
154                    // if children menu height is lower then currentMenuElement offset
155                    h = h < to_currentmenuelement_h ? h = to_currentmenuelement_h 
155: h;
156                } else { // height of current menu
157                    h = base.$currentMenuElement
158                        .closest(base.o.menuSelector)
159                        .height();
160                }
161                if (depth < 0) { // if backwards - prevent previous height
162                	h = h < to_currentmenuelement_h ? h = to_currentmenuelement_h : h;
163                    //h = h > base.o.previousHeight ? h : base.o.previousHeight;
164                }
165
166                h = h > base.o.minHeightMenu ? h : base.o.minHeightMenu;
167                base.o.previousHeight = h;
168                base.$waSlideMenu.css('height', h);
169            }
170        };
171        base._hideOtherMenus = function (depth) {
172            var $branchParent = base.$currentMenuElement.parentsUntil('.' + base.o.classNames.navigationClass).filter(base.o.itemSelector);
173
174            $branchParent.push(base.$currentMenuElement[0]);
175
176            if (depth > 0) {
177                // hide all menus branches
178                base.$inheritedMenus.css('visibility', 'hidden');
179                // show only our inherited menus
180                $branchParent.children(base.o.menuSelector).css('visibility', 'visible');
181            }
182        };
183        base.loadContent = function (loadContainer, url) {
184            var loading = $('<span/>', {
185                    'class' : base.o.classNames.loadingClass
186                }).html('&nbsp;'),
187                clear = '<div style="clear:both"></div>';
188
189            if (base.o.loadContainer.length > 0 && // check if we have place where load content
190                    loadContainer.length > 0 &&
191                    $.inArray(url, base.o.excludeUri) < 0 &&
192                    (location.origin + url) !== window.location.href) {
193
194                if (base.o.beforeLoad && typeof (base.o.beforeLoad) === 'function') {
195                    base.o.beforeLoad.apply(loadContainer);
196                } else {
197                    loadContainer.html(loading).append(clear);
198                }
199                // TODO: (?) save content if we will fail load next page
200                $.ajax(
201                    {
202                        url: url,
203                        type: 'get'
204                    }
205                )
206                    .done(function (data) {
207                        loadContainer.html(data + clear);
208                        // set page title
209                        base.changeTitle();
210                        // set new url
211                        base.changeUri(url);
212                        // afterLoadDone callback
213                        if (base.o.afterLoadDone && typeof (base.o.afterLoadDone) === 'function') {
214                            base.o.afterLoadDone.apply(loadContainer);
215                        }
216                        base.$waSlideMenu.trigger('afterLoadDone.' + base.o.namespace + pluginName);
217                    })
218                    .fail(function () {
219                        // do not remove content and slide menu
220                        base.$currentMenuElement
221                            .siblings()
222                            .children('.' + base.o.classNames.menuItemBackClass)
223                            .trigger('click');
224
225                        // afterLoadFail callback
226                        if (base.o.afterLoadFail && typeof (base.o.afterLoadFail) === 'function') {
227                            base.o.afterLoadFail.apply(loadContainer);
228                        }
229                        base.$waSlideMenu.trigger('afterLoadFail.' + base.o.namespace + pluginName);
230                    })
231                    .always(function () {
232                        // afterLoadAlways callback
233                        if (base.o.afterLoadAlways && typeof (base.o.afterLoadAlways) === 'function') {
234                            base.o.afterLoadAlways.apply(loadContainer);
235                        }
236                        base.$waSlideMenu.trigger('afterLoadAlways.' + base.o.namespace + pluginName);
237                    });
238            }
239        };
240        base.changeTitle = function () {
241            if (base.o.setTitle) {
242                $('title').text(base.$currentMenuElement.children('a').text());
243            }
244        };
245        base.changeUri = function (url) {
246            if (!!(window.history && history.pushState)) {
247                window.history.pushState({}, '', url);
248            }
249        };
250        base._menuItemClicked = function (element, event, depth) {
251            if ( $(element).parent().hasClass("sublevel") || $(element).parent().hasClass("waSlideMenu-back") ) {
252                event.preventDefault();
253                event.stopPropagation();
254            }
255
256            // disable click while we are sliding to next menu
257            if (base.o.nowSliding) {
258                return false;
259            }
260
261            base.$currentMenuElement = $(element).parent(base.o.itemSelector);
262
263            var url = $(element).attr('href'),
264                $menu_children = base.$currentMenuElement.children(base.o.menuSelector),
265                back_link = base.$currentMenuElement.hasClass(base.o.classNames.menuItemBackClass) ? true : false,
266                $load_container = $(base.o.loadContainer);
267
268            // change selected class
269            base.$waSlideMenu
270                .find(base.o.itemSelector)
271                .filter('.' + base.o.selectedClass)
272                .removeClass(base.o.selectedClass);
273
274            if (back_link) {
275                base.$currentMenuElement = base.$currentMenuElement
276                        .closest(base.o.menuSelector)
277                        .closest(base.o.itemSelector);
278            }
279            // add 'selected' class
280            base.$currentMenuElement.addClass(base.o.selectedClass);
281            
282            if (base.o.loadOnlyLatest === false) {
283                base.loadContent($load_container, url);
284            } else if (base.o.loadOnlyLatest && $menu_children.length === 0 && depth > 0) {
285                base.loadContent($load_container, url);
286            }
287
288            // onLatestClick callback
289            if ($menu_children.length === 0 && depth > 0) {
290                if (base.o.onLatestClick && typeof (base.o.onLatestClick) === 'function') {
291                    base.o.onLatestClick.apply(element);
292                }
293                base.$waSlideMenu.trigger('onLatestClick.' + base.o.namespace + pluginName);
294            }
295
296            // if we can go deeper or up
297            if ($menu_children.length > 0 || depth < 0) {
298                base.gotoSelected(depth, true);
299            }
300        };
301        base._menuDown = function (e) {
302            base._menuItemClicked(this, e, 1);
303        };
304        base._menuUp = function (e) {
305            base._menuItemClicked(this, e, -1);
306        };
307        base._remove = function () {
308            base.$items.off('click', 'a', base._menuDown);
309
310            base.$waSlideMenu.removeClass(base.o.classNames.navigationClass);
311            if (base.o.autoHeightMenu) {
312                base.$waSlideMenu.css('height', 'initial');
313            }
314            if (base.o.minHeightMenu > 0) {
315                base.$waSlideMenu.css('min-height', 'initial');
316            }
317            base.$rootMenu.removeClass(base.o.classNames.allMenusClass)
318                            .prependTo(base.$waSlideMenu);
319            base.$inheritedMenus.removeClass(base.o.classNames.allMenusClass + ' ' + base.o.classNames.inheritedMenuClass);
320            base.$inheritedMenus.css('visibility', '');
321            $.each(base.$backs, function (index, back) {
322                back.remove();
323            });
324            base.$movable.remove();
325            base.$waSlideMenu.removeData(pluginName);
326        };
327        base.exec = function(func) {
328            if (base.hasOwnProperty(func) && typeof base[func] === 'function') {
329                base[func].call();
330            }
331        };
332        base.destroy = function () {
333            base._remove();
334        };
335        base.init = function () {
336            base._setup();
337
338            $.each(base.$backs, function (index, back) {
339                back.on('click', 'a', base._menuUp);
340            });
341            base.$items.on('click', 'a', base._menuDown);
342
343            if (!!(window.history && history.pushState)) {
344                window.onpopstate = function (event) {
345                    if (event && event.state) {
346                        location.reload();
347                    }
348                };
349            }
350
351            var $selectedItem = base.$waSlideMenu
352                .find('.' + base.o.selectedClass)
353                .first();
354
355            if ($selectedItem.length) {
356                base.$currentMenuElement = $selectedItem;
357                var $url = base.$currentMenuElement.children('a').first(),
358                    depth = $selectedItem.parentsUntil('.' + base.o.classNames.navigationClass).filter(base.o.itemSelector).length,
359                    $selectedItemChildrenLen = $selectedItem.children(base.o.menuSelector).length;
360                if ($.inArray($url.attr('href'), base.o.excludeUri) < 0) {
361                    // if we have menus inside current element
362                    if ($selectedItemChildrenLen > 0) {
363                        // slide to them
364                        depth += 1;
365                    }
366                    base.gotoSelected(depth, false);
367                    // heightFix hack if we show last menu
368                    base._heightFix($selectedItemChildrenLen);
369                }
370            }
371
372            // onInit callback
373            if (base.o.onInit && typeof (base.o.onInit) === 'function') {
374                base.o.onInit(base);
375            }
376            base.$waSlideMenu.trigger('onInit.' + base.o.namespace + pluginName);
377        };
378
379        var oldBase = $(el).data(pluginName);
380        if (typeof oldBase === 'object') {
381            $.each(options, function (k, v) {
382                if (typeof oldBase[k] === 'function') {
383                    oldBase[k](v);
384                } else if (oldBase.o.hasOwnProperty(k)){
385                    oldBase.o[k] = v;
386                }
387            });
388        } else {
389            base.init();
390        }
391    };
392
393    $.waSlideMenu.defaults = {
394        namespace           : 'wa',
395
396        slideSpeed          : 400,
397        slideEasing         : 'linear',
398        backLinkContent     : 'Back',
399        backOnTop           : false,
400        selectedClass       : 'selected',
401        loadContainer       : '',
402        minHeightMenu       : 0,
403        autoHeightMenu      : true,
404        excludeUri          : ['/', '#'],
405        loadOnlyLatest      : false,
406        menuSelector        : 'ul',
407        itemSelector        : 'li',
408        setTitle            : false,
409        scrollToTopSpeed    : 0,
410
411        /* Callbacks */
412        onInit              : null,
413        onSlideForward      : null,
414        onSlideBack         : null,
415        onLatestClick       : null,
416        afterSlide          : null,
417        beforeLoad          : null,
418        afterLoadAlways     : null,
419        afterLoadDone       : null,
420        afterLoadFail       : null,
421
422        /* class names */
423        classNames: {
424            navigationClass         : '-nav',
425            wrapperClass            : '-wrapper',
426            allMenusClass           : '-menu',
427            inheritedMenuClass      : '-inheritedmenu',
428            menuItemBackClass       : '-back',
429            loadingClass            : '-loading'
430        }
431    }; // $.waSlideMenu.defaults
432
433    $.fn.waSlideMenu = function (key, val) {
434
435        return this.each(function () {
436            var options;
437
438            // Allow for passing in an object or a single key and value
439            if (typeof key !== 'object' && typeof val !== 'undefined') {
440                options = {};
441                options[key] = val;
442            } else {
443                options = key;
444            }
445
446            var t = new $.waSlideMenu(this, options);
447        }); // this.each
448
449    }; // $.fn.waSlideMenu
450
451}(jQuery, window, document));

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.