PageSourceSearch

https://www.team-rsr.com/jtlshop/templates/TACHION/js/app/views/header.js

js team-rsr.com collected 2026-10-08 22:38:32 UTC 8,337 bytes, 282 lines download raw bytes

1
2/* imports */
3
4import {
5    debounce, isMobile, onMobile, onDesktop, hasTouch,
6    isDesktop, lockScreen, unlockScreen, backdrop
7} from './../helpers.js'
8
9import './../plugins/navscrollbar.js'
10
11/* vars */
12
13const header					= '#jtl-nav-wrapper'
14const search					= '#search'
15const mainNavigation			= '#mainNavigation'
16const navRightDropdowns			= `${header} .nav-right .dropdown`
17const navbarNav					= `${mainNavigation} .navbar-nav`
18const mobileBackLink			= '[data-menu-back]'
19
20const $document					= $(document)
21const $window					= $(window)
22const $backdropDropdowns		= backdrop()
23const $backdropMobileNav		= backdrop()
24const $header					= $(header)
25const $mainNavigation			= $(mainNavigation)
26const $navRightDropdowns		= $(navRightDropdowns)
27const $navbarNav				= $(navbarNav)
28const $consentManager           = $('#consent-manager')
29
30const delayDropdownFadeIn		= 400
31const delayDropdownFadeOut		= 200
32
33let mobileCurrentLevel			= 0
34let dropdownInTo				= null
35let dropdownOutTo				= null
36let $activeDropdown				= null
37let activeDropdowns				= []
38let isDropdownActive			= false
39let isMenuActive				= false
40let categoryID   				= $('#category-id').val() || 0;
41let mobileLevels                = [];
42
43/* functions */
44
45const hasNavScrollbar = () => $mainNavigation.data('jtl.navscrollbar') !== undefined
46
47const onInitOrResize = () => {
48    updateVH()
49
50    if(isMobile()) {
51        if(hasNavScrollbar())
52            $mainNavigation.navscrollbar('destroy')
53    } else {
54        $mainNavigation.collapse('hide')
55        resetMobileNavigation()
56
57        if(!hasNavScrollbar())
58            $mainNavigation.navscrollbar()
59    }
60}
61
62const showDropdown = (dropdown) => {
63    $activeDropdown = $(dropdown)
64    $activeDropdown.parent().addClass('show')
65    $activeDropdown.next().addClass('show')
66    $activeDropdown.attr('aria-expanded', true)
67    isMenuActive = true
68
69    activeDropdowns.push($activeDropdown)
70}
71
72const hideDropdown = () => {
73    if($activeDropdown === null)
74        return
75
76    $activeDropdown.parent().removeClass('show')
77    $activeDropdown.next().removeClass('show')
78    $activeDropdown.attr('aria-expanded', false)
79
80    activeDropdowns.splice(-1, 1)
81
82    if(activeDropdowns.length === 0) {
83        $activeDropdown = null
84        isMenuActive = false
85    } else {
86        $activeDropdown = activeDropdowns[activeDropdowns.length - 1]
87    }
88}
89
90const showMobileLevel = (level) => {
91    mobileCurrentLevel = level < 0 ? 0 : mobileCurrentLevel
92    $navbarNav.css('transform', `translateX(${mobileCurrentLevel * -100}%)`)
93    $(`${mainNavigation} .nav-mobile-body`).scrollTop(0)
94    updateMenuTitle()
95}
96
97const updateMenuTitle = () => {
98    if(mobileCurrentLevel === 0) {
99        $('span.nav-offcanvas-title').removeClass('d-none')
100        $('a.nav-offcanvas-title').addClass('d-none')
101    } else {
102        $('span.nav-offcanvas-title').addClass('d-none')
103        $('a.nav-offcanvas-title').removeClass('d-none')
104    }
105}
106
107const resetMobileNavigation = () => {
108    mobileCurrentLevel = 0
109    updateMenuTitle()
110    $(`${mainNavigation} .show`).removeClass('show')
111    $(`${mainNavigation} .dropdown-toggle`).attr('aria-expanded', false)
112    $navbarNav.removeAttr('style')
113}
114
115const updateVH = () => {
116    let vh = window.innerHeight * .01
117    document.documentElement.style.setProperty('--vh', `${vh}px`)
118}
119
120const openCurrentCategory = () => {
121    let $initialCategory = $(mainNavigation + ' [data-category-id="' + categoryID + '"]');
122    setMobileLevels($initialCategory, 1);
123    //add last (current) level if it has children
124    if ($initialCategory.hasClass('dropdown-toggle')) {
125        mobileLevels.push($initialCategory.next());
126    }
127    $.each(mobileLevels, function(depth, mobileLevel) {
128        mobileCurrentLevel = depth + 1;
129        // all dropdowns have link as previous element
130        showDropdown(mobileLevel.prev()[0]);
131        showMobileLevel(mobileCurrentLevel);
132    });
133}
134
135function setMobileLevels (stuff, depth) {
136    let closestDropdown = stuff.parent().closest('.dropdown-menu');
137    if (closestDropdown.length) {
138        mobileLevels.unshift(closestDropdown);
139        return setMobileLevels(closestDropdown, ++depth);
140    }
141    return depth;
142}
143
144onInitOrResize()
145updateVH()
146
147/* global events */
148
149$window.on('resize', debounce(onInitOrResize))
150$document.on('focus blur', search, () => setTimeout(() => { if(hasNavScrollbar()) $mainNavigation.navscrollbar('update') }, 250))
151
152$document.on('show.bs.dropdown', navRightDropdowns, (e) => {
153    isDropdownActive = true
154    $backdropDropdowns.insertBefore($header)
155})
156
157$document.on('shown.bs.dropdown', navRightDropdowns, () => {
158    $backdropDropdowns.addClass('show zindex-dropdown')
159})
160
161$document.on('hide.bs.dropdown', navRightDropdowns, () => {
162    isDropdownActive = false
163
164    if(!isMenuActive)
165        $backdropDropdowns.removeClass('show')
166})
167
168$document.on('hidden.bs.dropdown', navRightDropdowns, () => {
169    if(!isMenuActive)
170        $backdropDropdowns.removeClass('zindex-dropdown').detach()
171})
172
173/* mobile events */
174
175$document.on('shown.bs.dropdown', `.search-mobile`, (e) => {
176    $(e.currentTarget).find('input').focus()
177})
178
179$backdropMobileNav.on('click', onMobile(() => {
180    $mainNavigation.collapse('hide')
181}))
182
183$document.on('show.bs.collapse', mainNavigation, () => {
184    lockScreen()
185    $backdropMobileNav.insertBefore($mainNavigation)
186    $consentManager.addClass('d-none');
187})
188
189$document.on('shown.bs.collapse', mainNavigation, () => {
190    $backdropMobileNav.addClass('show')
191    $(`${mainNavigation} .nav-mobile-body`).scrollTop(0)
192    if (categoryID > 0 && mobileLevels.length === 0) {
193        openCurrentCategory();
194    }
195})
196
197$document.on('hide.bs.collapse', mainNavigation, () => {
198    $backdropMobileNav.removeClass('show')
199    $consentManager.removeClass('d-none');
200})
201
202$document.on('hidden.bs.collapse', mainNavigation, () => {
203    unlockScreen()
204    $backdropMobileNav.detach()
205})
206
207$document.on('click', mobileBackLink, onMobile((e) => {
208    e.preventDefault()
209
210    showMobileLevel(--mobileCurrentLevel)
211    hideDropdown()
212}))
213
214$document.on('click', `${mainNavigation} .dropdown-toggle`, onMobile((e) => {
215    e.preventDefault()
216
217    showDropdown(e.currentTarget)
218    showMobileLevel(++mobileCurrentLevel)
219}))
220
221/* desktop events */
222
223if(hasTouch()) {
224    $document.on('click', `${mainNavigation} .dropdown-toggle:not(.categories-recursive-link)`, onDesktop((e) => {
225        e.preventDefault()
226
227        if($activeDropdown !== null && $activeDropdown.get(0) === e.currentTarget) {
228            hideDropdown()
229            $backdropDropdowns.removeClass('show').detach()
230            return
231        }
232
233        if($activeDropdown !== null) {
234            hideDropdown()
235            $backdropDropdowns.removeClass('show').detach()
236        }
237
238        showDropdown(e.currentTarget)
239        $backdropDropdowns.insertBefore($header).addClass('show zindex-dropdown')
240    }))
241
242    $backdropDropdowns.on('click', onDesktop(() => {
243        if($activeDropdown !== null) {
244            hideDropdown()
245            $backdropDropdowns.removeClass('show').detach()
246        }
247    }))
248
249    $document.on('show.bs.dropdown', navRightDropdowns, () => {
250        if($activeDropdown !== null)
251            hideDropdown()
252    })
253}
254
255$document.on('mouseenter', `${mainNavigation} .navbar-nav > .dropdown`, onDesktop((e) => {
256    if(hasTouch())
257        return
258
259    if(dropdownOutTo != undefined)
260        clearTimeout(dropdownOutTo)
261
262    dropdownInTo = setTimeout(() => {
263        if($activeDropdown !== null) {
264            hideDropdown()
265        }
266        showDropdown($(e.currentTarget).find('> .dropdown-toggle'))
267        $backdropDropdowns.insertBefore($header).addClass('show zindex-dropdown')
268    }, delayDropdownFadeIn)
269})).on('mouseleave', `${mainNavigation} .navbar-nav > .dropdown`, onDesktop((e) => {
270    if(hasTouch())
271        return
272
273    if(dropdownInTo != undefined)
274        clearTimeout(dropdownInTo)
275
276    dropdownOutTo = setTimeout(() => {
277        hideDropdown()
278
279        if(!isDropdownActive)
280            $backdropDropdowns.removeClass('show').detach()
281    }, delayDropdownFadeOut)
282}))

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.