PageSourceSearch

https://eroomwp.com/wp-content/themes/sierra/assets/js/front-end.js?ver=2.1

js eroomwp.com collected 2026-09-25 21:14:58 UTC 23,113 bytes, 589 lines download raw bytes

1/* THIS JS WAS COMPILED AND OPTIMIZED, USING THE WP COMPILER PLUGIN */
2/* https://bytes.co */
3/* Last Compiled: 2023-03-14 11:12:34 UTC */
4
5/* @@ START FILE: comments.js*/
6jQuery(document).ready(function($) {
7    var form_validation = $(".comment-form-url input, .comment-form-author input, .comment-form-email input, .comment-form-comment textarea");
8    $(form_validation).blur(function() {
9        if (!$(this).val()) {
10            $(this).parent().removeClass("keydesign-not-empty");
11        } else {
12            $(this).parent().addClass("keydesign-not-empty");
13        }
14    });
15    var contact_form = $(".keydesign-label input, .keydesign-label textarea");
16    $(contact_form).blur(function() {
17        if (!$(this).val()) {
18            $(this).closest(".keydesign-label").removeClass("keydesign-not-empty");
19        } else {
20            $(this).closest(".keydesign-label").addClass("keydesign-not-empty");
21        }
22    });
23
24});
25/* @@ END FILE: comments.js*/
26
27;
28
29/* @@ START FILE: navigation.js*/
30/**
31 * @Author: Roni Laukkarinen
32 * @Date:   2021-04-23 13:10:51
33 * @Last Modified by:   Roni Laukkarinen
34 * @Last Modified time: 2022-05-12 15:10:04
35 */
36// TODO: Refactor file
37/* eslint-disable default-case, camelcase, eqeqeq, no-restricted-globals, no-undef, no-var, vars-on-top, max-len, prefer-destructuring, no-redeclare, no-plusplus, no-use-before-define, no-unused-vars, block-scoped-var, func-names */
38/*
39An accessible menu for WordPress
40
41https://github.com/theme-smith/accessible-nav-wp
42Kirsten Smith ([email protected])
43Licensed GPL v.2 (http://www.gnu.org/licenses/gpl-2.0.html)
44
45This work derived from:
46https://github.com/WordPress/twentysixteen (GPL v.2)
47https://github.com/wpaccessibility/a11ythemepatterns/tree/master/menu-keyboard-arrow-nav (GPL v.2)
48*/
49
50/*!
51 * Check if an element is out of the viewport
52 * (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
53 * @param  {Node}  elem The element to check
54 * @return {Object}     A set of booleans for each side of the element
55 * @source https://gomakethings.com/how-to-check-if-any-part-of-an-element-is-out-of-the-viewport-with-vanilla-js/
56 */
57var isOutOfViewport = function(elem) {
58    // Get element's bounding
59    var bounding = elem.getBoundingClientRect();
60
61    // Check if it's out of the viewport on each side
62    var out = {};
63    out.top = bounding.top < 0;
64    out.left = bounding.left < 0;
65    out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
66    out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
67    out.any = out.top || out.left || out.bottom || out.right;
68
69    return out;
70};
71
72// Navigation.js start
73(function($) {
74    // Responsive nav width
75    var responsivenav = 1025;
76    var html;
77    var body;
78    var container;
79    var button;
80    var menu;
81    var menuWrapper;
82    var links;
83    var subMenus;
84    var i;
85    var len;
86    var focusableElements;
87    var firstFocusableElement;
88    var lastFocusableElement;
89
90    // Hover intent
91    const menuItems = document.querySelectorAll('.menu-item');
92    // const hoverIntentTimeout = 1000;
93
94    menuItems.forEach((li) => {
95        li.addEventListener('mouseover', function() {
96            this.classList.add('hover-intent');
97            this.parentNode.classList.add('hover-intent');
98
99            document.addEventListener('keydown', (keydownMouseoverEvent) => {
100                if (keydownMouseoverEvent.key === 'Escape') {
101                    li.classList.remove('hover-intent');
102                    li.parentNode.classList.remove('hover-intent');
103                    li.parentNode.parentNode.classList.remove('hover-intent');
104                }
105            });
106        });
107
108        li.addEventListener('mouseleave', function() {
109            // setTimeout(() => {
110            this.classList.remove('hover-intent');
111            this.parentNode.classList.remove('hover-intent');
112            // }, hoverIntentTimeout);
113
114            document.addEventListener('keydown', (keydownMouseleaveEvent) => {
115                if (keydownMouseleaveEvent.key === 'Escape') {
116                    li.classList.remove('hover-intent');
117                    li.parentNode.classList.remove('hover-intent');
118                    li.parentNode.parentNode.classList.remove('hover-intent');
119                }
120            });
121        });
122    });
123
124    // Init isOut check
125    checkForSubmenuOverflow();
126
127    function checkForSubmenuOverflow() {
128        menuItems.forEach((li) => {
129            // Find sub menus
130            var subMenusUnderMenuItem = li.querySelectorAll('.sub-menu');
131
132            // Loop through sub menus
133            subMenusUnderMenuItem.forEach((subMenu) => {
134                // First let's check if submenu exists
135                if (typeof subMenusUnderMenuItem !== 'undefined') {
136                    // Check if the sub menu is out of viewport or not
137                    var isOut = isOutOfViewport(subMenu);
138
139                    // At least one side of the element is out of viewport
140                    if (isOut.right) {
141                        subMenu.classList.add('is-out-of-viewport');
142                        subMenu.parentElement.parentElement.classList.add('is-out-of-viewport');
143                    } else {
144                        subMenu.classList.remove('is-out-of-viewport');
145                        subMenu.parentElement.parentElement.classList.remove('is-out-of-viewport');
146                    }
147                }
148            });
149        });
150    }
151
152    // Reinit viewport check on resize event
153    window.addEventListener('resize', checkForSubmenuOverflow);
154
155    // Define menu items
156    var menuContainer = $('.nav-container');
157    var menuToggle = menuContainer.find('#nav-toggle');
158    var siteHeaderMenu = menuContainer.find('#main-navigation-wrapper');
159    var siteNavigation = menuContainer.find('#nav');
160
161    var screenReaderText = { "expand": "Expand child menu", "collapse": "Collapse child menu" };
162
163    // Close focused dropdowns when pressing esc
164    $('.menu-item a, .dropdown button').on('keyup', function(e) {
165        // Checking are menu items open or not
166        const isSubMenuDropdownOpen = $(this).parent().parent().parent()
167            .find('.sub-menu')
168            .prev('.dropdown-toggle')
169            .attr('aria-expanded');
170        const isMainMenuDropdownOpen = $(this).closest('.menu-item').find('.dropdown-toggle').attr('aria-expanded');
171        const areWeInDropdown = $(this).parent().parent().hasClass('sub-menu');
172
173        if (isSubMenuDropdownOpen === 'true' || isMainMenuDropdownOpen === 'true') {
174            if ($('.dropdown').find(':focus').length !== 0) {
175                // Close menu using Esc key but only if dropdown is open
176                if (e.code === 'Escape') {
177                    // Close the dropdown menu
178                    var thisDropdown = $(this).parent().parent().parent();
179
180                    var screenReaderSpan = thisDropdown.find('.screen-reader-text');
181                    var dropdownToggle = thisDropdown.find('.dropdown-toggle');
182                    thisDropdown.find('.sub-menu').removeClass('toggled-on');
183                    thisDropdown.find('.dropdown-toggle').removeClass('toggled-on');
184                    thisDropdown.find('.dropdown').removeClass('toggled-on');
185                    dropdownToggle.attr('aria-expanded', 'false');
186                    // jscs:enable
187                    screenReaderSpan.text(screenReaderText.expand);
188                    // Move focus back to previous dropdown select
189                    // But only if we are not already in the toggle of the first dropdown menu
190                    if (areWeInDropdown === true) {
191                        thisDropdown.find('.dropdown-toggle:first').trigger('focus');
192                    }
193                }
194            }
195        }
196
197        if (window.innerWidth > responsivenav) {
198            // Close previous dropdown if we are on main level
199            var prevDropdown = $(this).parent().prev();
200
201            var screenReaderSpanPrev = prevDropdown.find('.screen-reader-text');
202            var dropdownTogglePrev = prevDropdown.find('.dropdown-toggle');
203            prevDropdown.find('.sub-menu').removeClass('toggled-on');
204            prevDropdown.find('.dropdown-toggle').removeClass('toggled-on');
205            prevDropdown.find('.dropdown').removeClass('toggled-on');
206            dropdownTogglePrev.attr('aria-expanded', 'false');
207            screenReaderSpanPrev.text(screenReaderText.expand);
208
209            // Close next dropdown if we are on main level
210            var nextDropdown = $(this).parent().next();
211
212            var screenReaderSpanNext = nextDropdown.find('.screen-reader-text');
213            var dropdownToggleNext = nextDropdown.find('.dropdown-toggle');
214            nextDropdown.find('.sub-menu').removeClass('toggled-on');
215            nextDropdown.find('.dropdown-toggle').removeClass('toggled-on');
216            nextDropdown.find('.dropdown').removeClass('toggled-on');
217            dropdownToggleNext.attr('aria-expanded', 'false');
218            screenReaderSpanNext.text(screenReaderText.expand);
219        }
220    });
221
222    // Adds aria attribute
223    siteHeaderMenu.find('.menu-item-has-children').attr('aria-haspopup', 'true');
224
225    // Add default dropdown-toggle label
226    $('.dropdown-toggle').each(function() {
227        $(this).attr('aria-label', `${screenReaderText.expand_for} ${$(this).prev().text()}`);
228    });
229
230    // Toggles the sub-menu when dropdown toggle button accessed
231    siteHeaderMenu.find('.dropdown-toggle').on('click', function(e) {
232        var dropdownMenu = $(this).nextAll('.sub-menu');
233
234        $(this).toggleClass('toggled-on');
235        dropdownMenu.toggleClass('toggled-on');
236
237        // jscs:disable
238        $(this).attr(
239            'aria-expanded',
240            $(this).attr('aria-expanded') === 'false' ? 'true' : 'false',
241        );
242        // jscs:enable
243        // Change screen reader open/close labels
244
245        $(this).attr(
246            'aria-label',
247            $(this).attr('aria-label') === `${screenReaderText.collapse_for} ${$(this).prev().text()}` ?
248            `${screenReaderText.expand_for} ${$(this).prev().text()}` :
249            `${screenReaderText.collapse_for} ${$(this).prev().text()}`,
250        );
251    });
252
253    // Adds a class to sub-menus for styling
254    $('.sub-menu .menu-item-has-children')
255        .parent('.sub-menu')
256        .addClass('has-sub-menu');
257
258    // Keyboard navigation
259    $('.menu-item a, button.dropdown-toggle').on('keydown', function(e) {
260        if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].indexOf(e.code) == -1) {
261            return;
262        }
263
264        switch (e.code) {
265            case 'ArrowLeft': // Left key
266                e.stopPropagation();
267
268                if ($(this).hasClass('dropdown-toggle')) {
269                    $(this).prev('a').trigger('focus');
270                } else if (
271                    $(this).parent().prev().children('button.dropdown-toggle').length
272                ) {
273                    $(this).parent().prev().children('button.dropdown-toggle')
274                        .trigger('focus');
275                } else {
276                    $(this).parent().prev().children('a')
277                        .trigger('focus');
278                }
279
280                if ($(this).is('ul ul ul.sub-menu.toggled-on li:first-child a')) {
281                    $(this)
282                        .parents('ul.sub-menu.toggled-on li')
283                        .children('button.dropdown-toggle')
284                        .trigger('focus');
285                }
286
287                break;
288
289            case 'ArrowRight': // Right key
290                e.stopPropagation();
291
292                if ($(this).next('button.dropdown-toggle').length) {
293                    $(this).next('button.dropdown-toggle').trigger('focus');
294                } else if ($(this).parent().next().find('input').length) {
295                    $(this).parent().next().find('input')
296                        .trigger('focus');
297                } else {
298                    $(this).parent().next().children('a')
299                        .trigger('focus');
300                }
301
302                if ($(this).is('ul.sub-menu .dropdown-toggle.toggled-on')) {
303                    $(this).parent().find('ul.sub-menu li:first-child a').trigger('focus');
304                }
305
306                break;
307
308            case 'ArrowDown': // Down key
309                e.stopPropagation();
310
311                if ($(this).next().length) {
312                    $(this).next().find('li:first-child a').first()
313                        .trigger('focus');
314                } else if ($(this).parent().next().find('input').length) {
315                    $(this).parent().next().find('input')
316                        .trigger('focus');
317                } else {
318                    $(this).parent().next().children('a')
319                        .trigger('focus');
320                }
321
322                if (
323                    $(this).is('ul.sub-menu a') &&
324                    $(this).next('button.dropdown-toggle').length
325                ) {
326                    $(this).parent().next().children('a')
327                        .trigger('focus');
328                }
329
330                if (
331                    $(this).is('ul.sub-menu .dropdown-toggle') &&
332                    $(this).parent().next().children('.dropdown-toggle').length
333                ) {
334                    $(this).parent().next().children('.dropdown-toggle')
335                        .trigger('focus');
336                }
337
338                break;
339
340            case 'ArrowUp': // Up key
341                e.stopPropagation();
342
343                if ($(this).parent().prev().length) {
344                    $(this).parent().prev().children('a')
345                        .trigger('focus');
346                } else {
347                    $(this)
348                        .parents('ul')
349                        .first()
350                        .prev('.dropdown-toggle.toggled-on')
351                        .trigger('focus');
352                }
353
354                if (
355                    $(this).is('ul.sub-menu .dropdown-toggle') &&
356                    $(this).parent().prev().children('.dropdown-toggle').length
357                ) {
358                    $(this).parent().prev().children('.dropdown-toggle')
359                        .trigger('focus');
360                }
361
362                break;
363        }
364    });
365
366    container = document.getElementById('nav');
367    if (!container) {
368        return;
369    }
370
371    button = document.getElementById('nav-toggle');
372    if (typeof button === 'undefined') {
373        return;
374    }
375
376    // Set vars.
377    html = document.getElementsByTagName('html')[0];
378    body = document.getElementsByTagName('body')[0];
379    menu = container.getElementsByTagName('ul')[0];
380    menuWrapper = document.getElementById('main-navigation-wrapper');
381
382    function mobileNav() {
383        var mobileNavInstance;
384
385        // Toggles the menu button
386        if (!menuToggle.length) {
387            return;
388        }
389
390        // Do not set aria-expanded false on desktop
391        if (window.innerWidth < responsivenav) {
392            menuToggle.add(siteNavigation).attr('aria-expanded', 'false');
393        }
394
395        menuToggle.on('click', function() {
396            $(this).add(siteHeaderMenu).toggleClass('toggled-on');
397
398            // Change screen reader expanded state
399            $(this).attr(
400                'aria-expanded',
401                $(this).attr('aria-expanded') === 'false' ? 'true' : 'false',
402            );
403
404            // Change screen reader open/close labels
405            $('#nav-toggle-label').text(
406                // eslint-disable-next-line no-undef
407                $('#nav-toggle-label').text() === screenReaderText.expand_toggle ?
408                screenReaderText.collapse_toggle :
409                screenReaderText.expand_toggle,
410            );
411
412            $(this).attr(
413                'aria-label',
414                $(this).attr('aria-label') === screenReaderText.expand_toggle ?
415                screenReaderText.collapse_toggle :
416                screenReaderText.expand_toggle,
417            );
418
419            // jscs:disable
420            $(this)
421                .add(siteNavigation)
422                .attr(
423                    'aria-expanded',
424                    $(this).add(siteNavigation).attr('aria-expanded') === 'false' ?
425                    'true' :
426                    'false',
427                );
428
429            // Scroll to top when triggering mobile navigation
430            // to ensure no gaps are between header and navigation
431            // Please note, if you use sticky-nav, comment out the next line
432            window.scrollTo(0, 0);
433            // jscs:enable
434        });
435
436        // Hide menu toggle button if menu is empty and return early.
437        if (typeof menu === 'undefined') {
438            button.style.display = 'none';
439            return;
440        }
441
442        // Do not set aria-expanded false on desktop
443        if (window.innerWidth < responsivenav) {
444            menu.setAttribute('aria-expanded', 'false');
445        }
446
447        if (menu.className.indexOf('nav-menu') === -1) {
448            menu.className += ' nav-menu';
449        }
450
451        // Focus trap for mobile navigation
452        if (window.innerWidth < responsivenav) {
453            firstFocusableElement = null;
454            lastFocusableElement = null;
455
456            // Select nav items
457            var navElements = container.querySelectorAll([
458                '.nav-primary a[href]',
459                '.nav-primary button',
460            ]);
461
462            // Listen for key events on nav elements and the toggle button
463            // to trigger focus trap
464            for (var ii = 0; ii < navElements.length; ii++) {
465                navElements[ii].addEventListener('keydown', focusTrap);
466            }
467        }
468
469        // What happens when clicking menu toggle
470        button.onclick = function() {
471            if (container.className.indexOf('is-active') !== -1) {
472                closeMenu(); // Close menu.
473            } else {
474                html.className += ' disable-scroll';
475                body.className += ' js-nav-active';
476                container.className += ' is-active';
477                button.className += ' is-active';
478                button.setAttribute('aria-expanded', 'true');
479                menu.setAttribute('aria-expanded', 'true');
480
481                // Add focus trap when menu open
482                button.addEventListener('keydown', focusTrap, false);
483            }
484        };
485
486        // Close menu using Esc key.
487        document.addEventListener('keyup', (event) => {
488            if (event.code == 'Escape' || event.code == 'Esc') {
489                if (container.className.indexOf('is-active') !== -1) {
490                    closeMenu(); // Close menu.
491                }
492            }
493        });
494
495        // Close menu clicking menu wrapper area.
496        menuWrapper.onclick = function(e) {
497            if (
498                e.target == menuWrapper &&
499                container.className.indexOf('is-active') !== -1
500            ) {
501                closeMenu(); // Close menu.
502            }
503        };
504    }
505    if (window.innerWidth < responsivenav) {
506        mobileNav(); // fire right away for mobile devices
507    }
508
509    // Close menu function.
510    function closeMenu() {
511        button.removeEventListener('keydown', focusTrap, false);
512        html.className = html.className.replace(' disable-scroll', '');
513        body.className = body.className.replace(' js-nav-active', '');
514        container.className = container.className.replace(' is-active', '');
515        button.className = button.className.replace(' is-active', '');
516        button.setAttribute('aria-expanded', 'false');
517        menu.setAttribute('aria-expanded', 'false');
518        $('#nav-toggle-label').text(screenReaderText.expand_toggle);
519
520        // Return focus to nav-toggle
521        button.focus();
522    }
523
524    // Get all the link elements within the menu.
525    links = menu.getElementsByTagName('a');
526    subMenus = menu.getElementsByTagName('ul');
527
528    // Each time a menu link is focused or blurred, toggle focus.
529    for (i = 0, len = links.length; i < len; i++) {
530        links[i].addEventListener('focus', toggleFocus, true);
531        links[i].addEventListener('blur', toggleFocus, true);
532    }
533
534    /**
535     * Sets or removes .focus class on an element.
536     */
537    function toggleFocus() {
538        var self = this;
539
540        // Move up through the ancestors of the current link until we hit .nav-menu.
541        while (self.className.indexOf('nav-menu') === -1) {
542            // On li elements toggle the class .focus.
543            if (self.tagName.toLowerCase() === 'li') {
544                if (self.className.indexOf('focus') !== -1) {
545                    self.className = self.className.replace(' focus', '');
546                } else {
547                    self.className += ' focus';
548                }
549            }
550
551            self = self.parentElement;
552        }
553    }
554
555    function focusTrap(e) {
556        // Set focusable elements inside main navigation.
557        focusableElements = [...container.querySelectorAll(
558            'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])',
559        )].filter((el) => !el.hasAttribute('disabled')).filter((el) => !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length));
560
561        firstFocusableElement = focusableElements[0];
562        lastFocusableElement = focusableElements[focusableElements.length - 1];
563
564        // Redirect last Tab to first focusable element.
565        if (lastFocusableElement === e.target && e.code === 'Tab' && !e.shiftKey) {
566            button.focus(); // Set focus on first element - that's actually close menu button.
567        }
568
569        // Redirect first Shift+Tab to toggle button element.
570        if (firstFocusableElement === e.target && e.code === 'Tab' && e.shiftKey) {
571            button.focus(); // Set focus on last element.
572        }
573
574        // Redirect Shift+Tab from the toggle button to last focusable element.
575        if (button === e.target && e.code === 'Tab' && e.shiftKey) {
576            lastFocusableElement.focus(); // Set focus on last element.
577        }
578    }
579
580    $(window).on('resize', () => {
581        if (window.innerWidth > responsivenav && body.className.indexOf('js-nav-active') !== -1) {
582            closeMenu(); // Close menu.
583        } else if (window.innerWidth < responsivenav && typeof window.mobileNavInstance == 'undefined') {
584            mobileNav();
585        }
586    });
587}(jQuery));
588
589/* @@ END FILE: navigation.js*/

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.