· 5 years ago · Oct 07, 2020, 04:42 AM
1
2
3window.theme = window.theme || {};
4
5/* ================ SLATE ================ */
6window.theme = window.theme || {};
7
8theme.Sections = function Sections() {
9 this.constructors = {};
10 this.instances = [];
11
12 $(document)
13 .on('shopify:section:load', this._onSectionLoad.bind(this))
14 .on('shopify:section:unload', this._onSectionUnload.bind(this))
15 .on('shopify:section:select', this._onSelect.bind(this))
16 .on('shopify:section:deselect', this._onDeselect.bind(this))
17 .on('shopify:block:select', this._onBlockSelect.bind(this))
18 .on('shopify:block:deselect', this._onBlockDeselect.bind(this));
19};
20
21theme.Sections.prototype = _.assignIn({}, theme.Sections.prototype, {
22 _createInstance: function(container, constructor) {
23 var $container = $(container);
24 var id = $container.attr('data-section-id');
25 var type = $container.attr('data-section-type');
26
27
28 constructor = constructor || this.constructors[type];
29
30 if (_.isUndefined(constructor) && data.type != false) {
31 return;
32 }
33
34 var instance = _.assignIn(new constructor(container), {
35 id: id,
36 type: type,
37 container: container
38 });
39
40 this.instances.push(instance);
41 },
42
43 _onSectionLoad: function(evt) {
44 var container = $('[data-section-id]', evt.target)[0];
45 if (container) {
46 this._createInstance(container);
47 }
48 },
49
50 _onSectionUnload: function(evt) {
51 this.instances = _.filter(this.instances, function(instance) {
52 var isEventInstance = (instance.id === evt.detail.sectionId);
53
54 if (isEventInstance) {
55 if (_.isFunction(instance.onUnload)) {
56 instance.onUnload(evt);
57 }
58 }
59
60 return !isEventInstance;
61 });
62 },
63
64 _onSelect: function(evt) {
65 // eslint-disable-next-line no-shadow
66 var instance = _.find(this.instances, function(instance) {
67 return instance.id === evt.detail.sectionId;
68 });
69
70 if (!_.isUndefined(instance) && _.isFunction(instance.onSelect)) {
71 instance.onSelect(evt);
72 }
73 },
74
75 _onDeselect: function(evt) {
76 // eslint-disable-next-line no-shadow
77 var instance = _.find(this.instances, function(instance) {
78 return instance.id === evt.detail.sectionId;
79 });
80
81 if (!_.isUndefined(instance) && _.isFunction(instance.onDeselect)) {
82 instance.onDeselect(evt);
83 }
84 },
85
86 _onBlockSelect: function(evt) {
87 // eslint-disable-next-line no-shadow
88 var instance = _.find(this.instances, function(instance) {
89 return instance.id === evt.detail.sectionId;
90 });
91
92 if (!_.isUndefined(instance) && _.isFunction(instance.onBlockSelect)) {
93 instance.onBlockSelect(evt);
94 }
95 },
96
97 _onBlockDeselect: function(evt) {
98 // eslint-disable-next-line no-shadow
99 var instance = _.find(this.instances, function(instance) {
100 return instance.id === evt.detail.sectionId;
101 });
102
103 if (!_.isUndefined(instance) && _.isFunction(instance.onBlockDeselect)) {
104 instance.onBlockDeselect(evt);
105 }
106 },
107
108 register: function(type, constructor) {
109 this.constructors[type] = constructor;
110
111 $('[data-section-type=' + type + ']').each(function(index, container) {
112 this._createInstance(container, constructor);
113 }.bind(this));
114 }
115});
116
117window.slate = window.slate || {};
118
119/**
120 * iFrames
121 * -----------------------------------------------------------------------------
122 * Wrap videos in div to force responsive layout.
123 *
124 * @namespace iframes
125 */
126
127slate.rte = {
128 wrapTable: function() {
129 $('.rte table').wrap('<div class="rte__table-wrapper"></div>');
130 },
131
132 iframeReset: function() {
133 var $iframeVideo = $('.rte iframe[src*="youtube.com/embed"], .rte iframe[src*="player.vimeo"]');
134 var $iframeReset = $iframeVideo.add('.rte iframe#admin_bar_iframe');
135
136 $iframeVideo.each(function() {
137 // Add wrapper to make video responsive
138 $(this).wrap('<div class="video-wrapper"></div>');
139 });
140
141 $iframeReset.each(function() {
142 // Re-set the src attribute on each iframe after page load
143 // for Chrome's "incorrect iFrame content on 'back'" bug.
144 // https://code.google.com/p/chromium/issues/detail?id=395791
145 // Need to specifically target video and admin bar
146 this.src = this.src;
147 });
148 }
149};
150
151window.slate = window.slate || {};
152
153/**
154 * A11y Helpers
155 * -----------------------------------------------------------------------------
156 * A collection of useful functions that help make your theme more accessible
157 * to users with visual impairments.
158 *
159 *
160 * @namespace a11y
161 */
162
163slate.a11y = {
164
165 /**
166 * For use when focus shifts to a container rather than a link
167 * eg for In-page links, after scroll, focus shifts to content area so that
168 * next `tab` is where user expects if focusing a link, just $link.focus();
169 *
170 * @param {JQuery} $element - The element to be acted upon
171 */
172 pageLinkFocus: function($element) {
173 var focusClass = 'js-focus-hidden';
174
175 $element.first()
176 .attr('tabIndex', '-1')
177 .focus()
178 .addClass(focusClass)
179 .one('blur', callback);
180
181 function callback() {
182 $element.first()
183 .removeClass(focusClass)
184 .removeAttr('tabindex');
185 }
186 },
187
188 /**
189 * If there's a hash in the url, focus the appropriate element
190 */
191 focusHash: function() {
192 var hash = window.location.hash;
193
194 // is there a hash in the url? is it an element on the page?
195 if (hash && document.getElementById(hash.slice(1))) {
196 this.pageLinkFocus($(hash));
197 }
198 },
199
200 /**
201 * When an in-page (url w/hash) link is clicked, focus the appropriate element
202 */
203 bindInPageLinks: function() {
204 $('a[href*=#]').on('click', function(evt) {
205 this.pageLinkFocus($(evt.currentTarget.hash));
206 }.bind(this));
207 },
208
209 /**
210 * Traps the focus in a particular container
211 *
212 * @param {object} options - Options to be used
213 * @param {jQuery} options.$container - Container to trap focus within
214 * @param {jQuery} options.$elementToFocus - Element to be focused when focus leaves container
215 * @param {string} options.namespace - Namespace used for new focus event handler
216 */
217 trapFocus: function(options) {
218 var eventName = options.eventNamespace
219 ? 'focusin.' + options.eventNamespace
220 : 'focusin';
221
222 if (!options.$elementToFocus) {
223 options.$elementToFocus = options.$container;
224 }
225
226 options.$container.attr('tabindex', '-1');
227 options.$elementToFocus.focus();
228
229 $(document).on(eventName, function(evt) {
230 if (options.$container[0] !== evt.target && !options.$container.has(evt.target).length) {
231 options.$container.focus();
232 }
233 });
234 },
235
236 /**
237 * Removes the trap of focus in a particular container
238 *
239 * @param {object} options - Options to be used
240 * @param {jQuery} options.$container - Container to trap focus within
241 * @param {string} options.namespace - Namespace used for new focus event handler
242 */
243 removeTrapFocus: function(options) {
244 var eventName = options.namespace
245 ? 'focusin.' + options.namespace
246 : 'focusin';
247
248 if (options.$container && options.$container.length) {
249 options.$container.removeAttr('tabindex');
250 }
251
252 $(document).off(eventName);
253 }
254};
255
256
257/* ================ GLOBAL ================ */
258/*============================================================================
259 Drawer modules
260==============================================================================*/
261theme.Drawers = (function() {
262 function Drawer(id, position, options) {
263 var defaults = {
264 close: '.js-drawer-close',
265 open: '.js-drawer-open-' + position,
266 openClass: 'js-drawer-open',
267 dirOpenClass: 'js-drawer-open-' + position
268 };
269
270 this.nodes = {
271 $parent: $('html').add('body'),
272 $page: $('#PageContainer')
273 };
274
275 this.config = $.extend(defaults, options);
276 this.position = position;
277
278 this.$drawer = $('#' + id);
279
280 if (!this.$drawer.length) {
281 return false;
282 }
283
284 this.drawerIsOpen = false;
285 this.init();
286 }
287
288 Drawer.prototype.init = function() {
289 $(this.config.open).on('click', $.proxy(this.open, this));
290 this.$drawer.on('click', this.config.close, $.proxy(this.close, this));
291 };
292
293 Drawer.prototype.open = function(evt) {
294 // Keep track if drawer was opened from a click, or called by another function
295 var externalCall = false;
296
297 // Prevent following href if link is clicked
298 if (evt) {
299 evt.preventDefault();
300 } else {
301 externalCall = true;
302 }
303
304 // Without this, the drawer opens, the click event bubbles up to nodes.$page
305 // which closes the drawer.
306 if (evt && evt.stopPropagation) {
307 evt.stopPropagation();
308 // save the source of the click, we'll focus to this on close
309 this.$activeSource = $(evt.currentTarget);
310 }
311
312 if (this.drawerIsOpen && !externalCall) {
313 return this.close();
314 }
315
316 // Add is-transitioning class to moved elements on open so drawer can have
317 // transition for close animation
318 this.$drawer.prepareTransition();
319
320 this.nodes.$parent.addClass(this.config.openClass + ' ' + this.config.dirOpenClass);
321 this.drawerIsOpen = true;
322
323 // Set focus on drawer
324 slate.a11y.trapFocus({
325 $container: this.$drawer,
326 namespace: 'drawer_focus'
327 });
328
329 // Run function when draw opens if set
330 if (this.config.onDrawerOpen && typeof this.config.onDrawerOpen === 'function') {
331 if (!externalCall) {
332 this.config.onDrawerOpen();
333 }
334 }
335
336 if (this.$activeSource && this.$activeSource.attr('aria-expanded')) {
337 this.$activeSource.attr('aria-expanded', 'true');
338 }
339
340 this.bindEvents();
341
342 return this;
343 };
344
345 Drawer.prototype.close = function() {
346 if (!this.drawerIsOpen) { // don't close a closed drawer
347 return;
348 }
349
350 // deselect any focused form elements
351 $(document.activeElement).trigger('blur');
352
353 // Ensure closing transition is applied to moved elements, like the nav
354 this.$drawer.prepareTransition();
355
356 this.nodes.$parent.removeClass(this.config.dirOpenClass + ' ' + this.config.openClass);
357
358 this.drawerIsOpen = false;
359
360 // Remove focus on drawer
361 slate.a11y.trapFocus({
362 $container: this.$drawer,
363 namespace: 'drawer_focus'
364 });
365
366 this.unbindEvents();
367 };
368
369 Drawer.prototype.bindEvents = function() {
370 this.nodes.$parent.on('keyup.drawer', $.proxy(function(evt) {
371 // close on 'esc' keypress
372 if (evt.keyCode === 27) {
373 this.close();
374 return false;
375 } else {
376 return true;
377 }
378 }, this));
379
380 // Lock scrolling on mobile
381 this.nodes.$page.on('touchmove.drawer', function() {
382 return false;
383 });
384
385 this.nodes.$page.on('click.drawer', $.proxy(function() {
386 this.close();
387 return false;
388 }, this));
389 };
390
391 Drawer.prototype.unbindEvents = function() {
392 this.nodes.$page.off('.drawer');
393 this.nodes.$parent.off('.drawer');
394 };
395
396 return Drawer;
397})();
398
399
400/* ================ MODULES ================ */
401window.theme = window.theme || {};
402
403theme.Header = (function() {
404 var selectors = {
405 body: 'body',
406 navigation: '#AccessibleNav',
407 siteNavHasDropdown: '.site-nav--has-dropdown',
408 siteNavChildLinks: '.site-nav__child-link',
409 siteNavActiveDropdown: '.site-nav--active-dropdown',
410 siteNavLinkMain: '.site-nav__link--main',
411 siteNavChildLink: '.site-nav__link--last'
412 };
413
414 var config = {
415 activeClass: 'site-nav--active-dropdown',
416 childLinkClass: 'site-nav__child-link'
417 };
418
419 var cache = {};
420
421 function init() {
422 cacheSelectors();
423
424 cache.$parents.on('click.siteNav', function(evt) {
425 var $el = $(this);
426
427 if (!$el.hasClass(config.activeClass)) {
428 // force stop the click from happening
429 evt.preventDefault();
430 evt.stopImmediatePropagation();
431 }
432
433 showDropdown($el);
434 });
435
436 // check when we're leaving a dropdown and close the active dropdown
437 $(selectors.siteNavChildLink).on('focusout.siteNav', function() {
438 setTimeout(function() {
439 if ($(document.activeElement).hasClass(config.childLinkClass) || !cache.$activeDropdown.length) {
440 return;
441 }
442
443 hideDropdown(cache.$activeDropdown);
444 });
445 });
446
447 // close dropdowns when on top level nav
448 cache.$topLevel.on('focus.siteNav', function() {
449 if (cache.$activeDropdown.length) {
450 hideDropdown(cache.$activeDropdown);
451 }
452 });
453
454 cache.$subMenuLinks.on('click.siteNav', function(evt) {
455 // Prevent click on body from firing instead of link
456 evt.stopImmediatePropagation();
457 });
458 }
459
460 function cacheSelectors() {
461 cache = {
462 $nav: $(selectors.navigation),
463 $topLevel: $(selectors.siteNavLinkMain),
464 $parents: $(selectors.navigation).find(selectors.siteNavHasDropdown),
465 $subMenuLinks: $(selectors.siteNavChildLinks),
466 $activeDropdown: $(selectors.siteNavActiveDropdown)
467 };
468 }
469
470 function showDropdown($el) {
471 $el.addClass(config.activeClass);
472
473 // close open dropdowns
474 if (cache.$activeDropdown.length) {
475 hideDropdown(cache.$activeDropdown);
476 }
477
478 cache.$activeDropdown = $el;
479
480 // set expanded on open dropdown
481 $el.find(selectors.siteNavLinkMain).attr('aria-expanded', 'true');
482
483 setTimeout(function() {
484 $(window).on('keyup.siteNav', function(evt) {
485 if (evt.keyCode === 27) {
486 hideDropdown($el);
487 }
488 });
489
490 $(selectors.body).on('click.siteNav', function() {
491 hideDropdown($el);
492 });
493 }, 250);
494 }
495
496 function hideDropdown($el) {
497 // remove aria on open dropdown
498 $el.find(selectors.siteNavLinkMain).attr('aria-expanded', 'false');
499 $el.removeClass(config.activeClass);
500
501 // reset active dropdown
502 cache.$activeDropdown = $(selectors.siteNavActiveDropdown);
503
504 $(selectors.body).off('click.siteNav');
505 $(window).off('keyup.siteNav');
506 }
507
508 function unload() {
509 $(window).off('.siteNav');
510 cache.$parents.off('.siteNav');
511 cache.$subMenuLinks.off('.siteNav');
512 cache.$topLevel.off('.siteNav');
513 $(selectors.siteNavChildLink).off('.siteNav');
514 $(selectors.body).off('.siteNav');
515 }
516
517 return {
518 init: init,
519 unload: unload
520 };
521})();
522
523window.theme = window.theme || {};
524
525theme.Search = (function() {
526 var selectors = {
527 search: '.search',
528 searchSubmit: '.search__submit',
529 searchInput: '.search__input',
530
531 siteHeader: '.site-header',
532 siteHeaderSearchToggle: '.site-header__search-toggle',
533 siteHeaderSearch: '.site-header__search',
534
535 searchDrawer: '.search-bar',
536 searchDrawerInput: '.search-bar__input',
537
538 searchHeader: '.search-header',
539 searchHeaderInput: '.search-header__input',
540 searchHeaderSubmit: '.search-header__submit'
541 };
542
543 var classes = {
544 focus: 'search--focus'
545 };
546
547 function init() {
548 if (!$(selectors.siteHeader).length) {
549 return;
550 }
551
552 initDrawer();
553 searchSubmit();
554
555 $(selectors.searchHeaderInput).add(selectors.searchHeaderSubmit).on('focus blur', function() {
556 $(selectors.searchHeader).toggleClass(classes.focus);
557 });
558
559 $(selectors.siteHeaderSearchToggle).on('click', function() {
560 var searchHeight = $(selectors.siteHeader).outerHeight();
561 var searchOffset = $(selectors.siteHeader).offset().top - searchHeight;
562
563 $(selectors.searchDrawer).css({
564 height: searchHeight + 'px',
565 top: searchOffset + 'px'
566 });
567 });
568 }
569
570 function initDrawer() {
571 // Add required classes to HTML
572 $('#PageContainer').addClass('drawer-page-content');
573 $('.js-drawer-open-top').attr('aria-controls', 'SearchDrawer').attr('aria-expanded', 'false');
574
575 theme.SearchDrawer = new theme.Drawers('SearchDrawer', 'top', {onDrawerOpen: searchDrawerFocus});
576 }
577
578 function searchDrawerFocus() {
579 searchFocus($(selectors.searchDrawerInput));
580 }
581
582 function searchFocus($el) {
583 $el.focus();
584 // set selection range hack for iOS
585 $el[0].setSelectionRange(0, $el[0].value.length);
586 }
587
588 function searchSubmit() {
589 $(selectors.searchSubmit).on('click', function(evt) {
590 var $el = $(evt.target);
591 var $input = $el.parents(selectors.search).find(selectors.searchInput);
592 if ($input.val().length === 0) {
593 evt.preventDefault();
594 searchFocus($input);
595 }
596 });
597 }
598
599 return {
600 init: init
601 };
602})();
603
604window.theme = window.theme || {};
605
606theme.MobileNav = (function() {
607 var classes = {
608 mobileNavOpenIcon: 'mobile-nav--open',
609 mobileNavCloseIcon: 'mobile-nav--close',
610 subNavLink: 'mobile-nav__sublist-link',
611 return: 'mobile-nav__return-btn',
612 subNavActive: 'is-active',
613 subNavClosing: 'is-closing',
614 navOpen: 'js-menu--is-open',
615 subNavShowing: 'sub-nav--is-open',
616 thirdNavShowing: 'third-nav--is-open',
617 subNavToggleBtn: 'js-toggle-submenu'
618 };
619 var cache = {};
620 var isTransitioning;
621 var $activeSubNav;
622 var $activeTrigger;
623 var menuLevel = 1;
624 // Breakpoints from src/stylesheets/global/variables.scss.liquid
625 var mediaQuerySmall = 'screen and (max-width: 749px)';
626
627 function init() {
628 cacheSelectors();
629
630 cache.$mobileNavToggle.on('click', toggleMobileNav);
631 cache.$subNavToggleBtn.on('click.subNav', toggleSubNav);
632
633 // Close mobile nav when unmatching mobile breakpoint
634 enquire.register(mediaQuerySmall, {
635 unmatch: function() {
636 closeMobileNav();
637 }
638 });
639 }
640
641 function toggleMobileNav() {
642 if (cache.$mobileNavToggle.hasClass(classes.mobileNavCloseIcon)) {
643 closeMobileNav();
644 } else {
645 openMobileNav();
646 }
647 }
648
649 function cacheSelectors() {
650 cache = {
651 $pageContainer: $('#PageContainer'),
652 $siteHeader: $('.site-header'),
653 $mobileNavToggle: $('.js-mobile-nav-toggle'),
654 $mobileNavContainer: $('.mobile-nav-wrapper'),
655 $mobileNav: $('#MobileNav'),
656 $subNavToggleBtn: $('.' + classes.subNavToggleBtn)
657 };
658 }
659
660 function openMobileNav() {
661 var translateHeaderHeight = cache.$siteHeader.outerHeight() + cache.$siteHeader.offset().top;
662
663 cache.$mobileNavContainer
664 .prepareTransition()
665 .addClass(classes.navOpen);
666
667 cache.$mobileNavContainer.css({
668 transform: 'translate3d(0, ' + translateHeaderHeight + 'px, 0)'
669 });
670 cache.$pageContainer.css({
671 transform: 'translate3d(0, ' + cache.$mobileNavContainer[0].scrollHeight + 'px, 0)'
672 });
673
674 slate.a11y.trapFocus({
675 $container: cache.$mobileNav,
676 namespace: 'navFocus'
677 });
678
679 cache.$mobileNavToggle
680 .addClass(classes.mobileNavCloseIcon)
681 .removeClass(classes.mobileNavOpenIcon);
682
683 // close on escape
684 $(window).on('keyup.mobileNav', function(evt) {
685 if (evt.which === 27) {
686 closeMobileNav();
687 }
688 });
689 }
690
691 function closeMobileNav() {
692 cache.$mobileNavContainer.prepareTransition().removeClass(classes.navOpen);
693
694 cache.$mobileNavContainer.css({
695 transform: 'translate3d(0, -100%, 0)'
696 });
697 cache.$pageContainer.removeAttr('style');
698
699 cache.$mobileNavContainer.one('TransitionEnd.navToggle webkitTransitionEnd.navToggle transitionend.navToggle oTransitionEnd.navToggle', function() {
700 slate.a11y.removeTrapFocus({
701 $container: cache.$mobileNav,
702 namespace: 'navFocus'
703 });
704 });
705
706 cache.$mobileNavToggle
707 .addClass(classes.mobileNavOpenIcon)
708 .removeClass(classes.mobileNavCloseIcon);
709
710 $(window).off('keyup.mobileNav');
711 }
712
713 function toggleSubNav(evt) {
714 if (isTransitioning) {
715 return;
716 }
717
718 var $toggleBtn = $(evt.currentTarget);
719 var isReturn = $toggleBtn.hasClass(classes.return);
720 isTransitioning = true;
721
722 if (isReturn) {
723 // Close all subnavs by removing active class on buttons
724 $('.' + classes.subNavToggleBtn + '[data-level="' + (menuLevel - 1) + '"]')
725 .removeClass(classes.subNavActive);
726
727 if ($activeTrigger && $activeTrigger.length) {
728 $activeTrigger.removeClass(classes.subNavActive);
729 }
730 } else {
731 $toggleBtn.addClass(classes.subNavActive);
732 }
733
734 $activeTrigger = $toggleBtn;
735
736 goToSubnav($toggleBtn.data('target'));
737 }
738
739 function goToSubnav(target) {
740
741 /*eslint-disable shopify/jquery-dollar-sign-reference */
742
743 var $targetMenu = target
744 ? $('.mobile-nav__dropdown[data-parent="' + target + '"]')
745 : cache.$mobileNav;
746
747 menuLevel = $targetMenu.data('level') ? $targetMenu.data('level') : 1;
748
749 if ($activeSubNav && $activeSubNav.length) {
750 $activeSubNav
751 .prepareTransition()
752 .addClass(classes.subNavClosing);
753 }
754
755 $activeSubNav = $targetMenu;
756
757 var $elementToFocus = target
758 ? $targetMenu.find('.' + classes.subNavLink + ':first')
759 : $activeTrigger;
760
761 /*eslint-enable shopify/jquery-dollar-sign-reference */
762
763 var translateMenuHeight = $targetMenu[0].scrollHeight;
764 if (!target) {
765 translateMenuHeight = $targetMenu.outerHeight();
766 }
767
768 var openNavClass = menuLevel > 2
769 ? classes.thirdNavShowing
770 : classes.subNavShowing;
771
772 cache.$mobileNavContainer
773 .css('height', translateMenuHeight)
774 .removeClass(classes.thirdNavShowing)
775 .addClass(openNavClass);
776
777 if (!target) {
778 // Show top level nav
779 cache.$mobileNavContainer
780 .removeClass(classes.thirdNavShowing)
781 .removeClass(classes.subNavShowing);
782 }
783
784 // Focusing an item in the subnav early forces element into view and breaks the animation.
785 cache.$mobileNavContainer.one('TransitionEnd.subnavToggle webkitTransitionEnd.subnavToggle transitionend.subnavToggle oTransitionEnd.subnavToggle', function() {
786 slate.a11y.trapFocus({
787 $container: $targetMenu,
788 $elementToFocus: $elementToFocus,
789 namespace: 'subNavFocus'
790 });
791
792 cache.$mobileNavContainer.off('.subnavToggle');
793 isTransitioning = false;
794 });
795
796 // Match height of subnav
797 cache.$pageContainer.css({
798 transform: 'translate3d(0, ' + translateMenuHeight + 'px, 0)'
799 });
800
801 $activeSubNav.removeClass(classes.subNavClosing);
802 }
803
804 return {
805 init: init
806 };
807})(jQuery);
808
809(function() {
810 var selectors = {
811 backButton: '.return-link'
812 };
813
814 var $backButton = $(selectors.backButton);
815
816 if (!document.referrer || !$backButton.length || !window.history.length) {
817 return;
818 }
819
820 $backButton.one('click', function(evt) {
821 evt.preventDefault();
822
823 var referrerDomain = urlDomain(document.referrer);
824 var shopDomain = urlDomain(window.location.href);
825
826 if (shopDomain === referrerDomain) {
827 history.back();
828 }
829
830 return false;
831 });
832
833 function urlDomain(url) {
834 var anchor = document.createElement('a');
835 anchor.ref = url;
836
837 return anchor.hostname;
838 }
839})();
840var checkrtl = false;
841var checkfade = true;
842if ($("html").hasClass("rtl")) {
843 var checkrtl = true;
844 var checkfade = false;
845}
846
847
848theme.Slideshow = (function() {
849 this.$slideshow = null;
850 var classes = {
851 wrapper: 'slideshow-wrapper',
852 slideshow: 'slideshow',
853 currentSlide: 'slick-current',
854 video: 'slideshow__video',
855 videoBackground: 'slideshow__video--background',
856 closeVideoBtn: 'slideshow__video-control--close',
857 pauseButton: 'slideshow__pause',
858 isPaused: 'is-paused'
859 };
860
861 function slideshow(el) {
862 if($('.slideshow').data('anima') == 'fade'){
863 var checkfade = true;
864 }
865 else{
866 var checkfade = false;
867 }
868 this.$slideshow = $(el);
869 this.$wrapper = this.$slideshow.closest('.' + classes.wrapper);
870 this.$pause = this.$wrapper.find('.' + classes.pauseButton);
871
872 this.settings = {
873 accessibility: true,
874 arrows: this.$slideshow.data('arrows'),
875 dots: this.$slideshow.data('dots'),
876 fade: checkfade,
877 draggable: true,
878 touchThreshold: 20,
879 autoplay: this.$slideshow.data('autoplay'),
880 autoplaySpeed: this.$slideshow.data('speed'),
881 rtl:checkrtl,
882 };
883
884 this.$slideshow.on('beforeChange', beforeChange.bind(this));
885 this.$slideshow.on('init', slideshowA11y.bind(this));
886 this.$slideshow.slick(this.settings);
887
888 this.$pause.on('click', this.togglePause.bind(this));
889 }
890
891 function slideshowA11y(event, obj) {
892 var $slider = obj.$slider;
893 var $list = obj.$list;
894 var $wrapper = this.$wrapper;
895 var autoplay = this.settings.autoplay;
896
897 // Remove default Slick aria-live attr until slider is focused
898 $list.removeAttr('aria-live');
899
900 // When an element in the slider is focused
901 // pause slideshow and set aria-live.
902 $wrapper.on('focusin', function(evt) {
903 if (!$wrapper.has(evt.target).length) {
904 return;
905 }
906
907 $list.attr('aria-live', 'polite');
908
909 if (autoplay) {
910 $slider.slick('slickPause');
911 }
912 });
913
914 // Resume autoplay
915 $wrapper.on('focusout', function(evt) {
916 if (!$wrapper.has(evt.target).length) {
917 return;
918 }
919
920 $list.removeAttr('aria-live');
921
922 if (autoplay) {
923 // Manual check if the focused element was the video close button
924 // to ensure autoplay does not resume when focus goes inside YouTube iframe
925 if ($(evt.target).hasClass(classes.closeVideoBtn)) {
926 return;
927 }
928
929 $slider.slick('slickPlay');
930 }
931 });
932
933 // Add arrow key support when focused
934 if (obj.$dots) {
935 obj.$dots.on('keydown', function(evt) {
936 if (evt.which === 37) {
937 $slider.slick('slickPrev');
938 }
939
940 if (evt.which === 39) {
941 $slider.slick('slickNext');
942 }
943
944 // Update focus on newly selected tab
945 if ((evt.which === 37) || (evt.which === 39)) {
946 obj.$dots.find('.slick-active button').focus();
947 }
948 });
949 }
950 }
951
952 function beforeChange(event, slick, currentSlide, nextSlide) {
953 var $slider = slick.$slider;
954 var $currentSlide = $slider.find('.' + classes.currentSlide);
955 var $nextSlide = $slider.find('.slideshow__slide[data-slick-index="' + nextSlide + '"]');
956
957 if (isVideoInSlide($currentSlide)) {
958 var $currentVideo = $currentSlide.find('.' + classes.video);
959 var currentVideoId = $currentVideo.attr('id');
960 theme.SlideshowVideo.pauseVideo(currentVideoId);
961 $currentVideo.attr('tabindex', '-1');
962 }
963
964 if (isVideoInSlide($nextSlide)) {
965 var $video = $nextSlide.find('.' + classes.video);
966 var videoId = $video.attr('id');
967 var isBackground = $video.hasClass(classes.videoBackground);
968 if (isBackground) {
969 theme.SlideshowVideo.playVideo(videoId);
970 } else {
971 $video.attr('tabindex', '0');
972 }
973 }
974 }
975
976 function isVideoInSlide($slide) {
977 return $slide.find('.' + classes.video).length;
978 }
979
980 slideshow.prototype.togglePause = function() {
981 var slideshowSelector = getSlideshowId(this.$pause);
982 if (this.$pause.hasClass(classes.isPaused)) {
983 this.$pause.removeClass(classes.isPaused);
984 $(slideshowSelector).slick('slickPlay');
985 } else {
986 this.$pause.addClass(classes.isPaused);
987 $(slideshowSelector).slick('slickPause');
988 }
989 };
990
991 function getSlideshowId($el) {
992 return '#Slideshow-' + $el.data('id');
993 }
994
995 return slideshow;
996})();
997
998// Youtube API callback
999// eslint-disable-next-line no-unused-vars
1000function onYouTubeIframeAPIReady() {
1001 theme.SlideshowVideo.loadVideos();
1002}
1003
1004theme.SlideshowVideo = (function() {
1005 var autoplayCheckComplete = false;
1006 var autoplayAvailable = false;
1007 var playOnClickChecked = false;
1008 var playOnClick = false;
1009 var youtubeLoaded = false;
1010 var videos = {};
1011 var videoPlayers = [];
1012 var videoOptions = {
1013 ratio: 16 / 9,
1014 playerVars: {
1015 // eslint-disable-next-line camelcase
1016 iv_load_policy: 3,
1017 modestbranding: 1,
1018 autoplay: 0,
1019 controls: 0,
1020 showinfo: 0,
1021 wmode: 'opaque',
1022 branding: 0,
1023 autohide: 0,
1024 rel: 0
1025 },
1026 events: {
1027 onReady: onPlayerReady,
1028 onStateChange: onPlayerChange
1029 }
1030 };
1031 var classes = {
1032 playing: 'video-is-playing',
1033 paused: 'video-is-paused',
1034 loading: 'video-is-loading',
1035 loaded: 'video-is-loaded',
1036 slideshowWrapper: 'slideshow-wrapper',
1037 slide: 'slideshow__slide',
1038 slideBackgroundVideo: 'slideshow__slide--background-video',
1039 slideDots: 'slick-dots',
1040 videoChrome: 'slideshow__video--chrome',
1041 videoBackground: 'slideshow__video--background',
1042 playVideoBtn: 'slideshow__video-control--play',
1043 closeVideoBtn: 'slideshow__video-control--close',
1044 currentSlide: 'slick-current',
1045 slickClone: 'slick-cloned',
1046 supportsAutoplay: 'autoplay',
1047 supportsNoAutoplay: 'no-autoplay'
1048 };
1049
1050 /**
1051 * Public functions
1052 */
1053 function init($video) {
1054 if (!$video.length) {
1055 return;
1056 }
1057
1058 videos[$video.attr('id')] = {
1059 id: $video.attr('id'),
1060 videoId: $video.data('id'),
1061 type: $video.data('type'),
1062 status: $video.data('type') === 'chrome' ? 'closed' : 'background', // closed, open, background
1063 videoSelector: $video.attr('id'),
1064 $parentSlide: $video.closest('.' + classes.slide),
1065 $parentSlideshowWrapper: $video.closest('.' + classes.slideshowWrapper),
1066 controls: $video.data('type') === 'background' ? 0 : 1,
1067 slideshow: $video.data('slideshow')
1068 };
1069
1070 if (!youtubeLoaded) {
1071 // This code loads the IFrame Player API code asynchronously.
1072 var tag = document.createElement('script');
1073 tag.src = 'https://www.youtube.com/iframe_api';
1074 var firstScriptTag = document.getElementsByTagName('script')[0];
1075 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
1076 }
1077 }
1078
1079 function customPlayVideo(playerId) {
1080 // Do not autoplay just because the slideshow asked you to.
1081 // If the slideshow asks to play a video, make sure
1082 // we have done the playOnClick check first
1083 if (!playOnClickChecked && !playOnClick) {
1084 return;
1085 }
1086
1087 if (playerId && typeof videoPlayers[playerId].playVideo === 'function') {
1088 privatePlayVideo(playerId);
1089 }
1090 }
1091
1092 function pauseVideo(playerId) {
1093 if (videoPlayers[playerId] && typeof videoPlayers[playerId].pauseVideo === 'function') {
1094 videoPlayers[playerId].pauseVideo();
1095 }
1096 }
1097
1098 function loadVideos() {
1099 for (var key in videos) {
1100 if (videos.hasOwnProperty(key)) {
1101 var args = $.extend({}, videoOptions, videos[key]);
1102 args.playerVars.controls = args.controls;
1103 videoPlayers[key] = new YT.Player(key, args);
1104 }
1105 }
1106
1107 initEvents();
1108 youtubeLoaded = true;
1109 }
1110
1111 function loadVideo(key) {
1112 if (!youtubeLoaded) {
1113 return;
1114 }
1115 var args = $.extend({}, videoOptions, videos[key]);
1116 args.playerVars.controls = args.controls;
1117 videoPlayers[key] = new YT.Player(key, args);
1118
1119 initEvents();
1120 }
1121
1122 /**
1123 * Private functions
1124 */
1125
1126 function privatePlayVideo(id, clicked) {
1127 var videoData = videos[id];
1128 var player = videoPlayers[id];
1129 var $slide = videos[id].$parentSlide;
1130
1131 if (playOnClick) {
1132 // playOnClick means we are probably on mobile (no autoplay).
1133 // setAsPlaying will show the iframe, requiring another click
1134 // to play the video.
1135 setAsPlaying(videoData);
1136 } else if (clicked || (autoplayCheckComplete && autoplayAvailable)) {
1137 // Play if autoplay is available or clicked to play
1138 $slide.removeClass(classes.loading);
1139 setAsPlaying(videoData);
1140 player.playVideo();
1141 return;
1142 }
1143
1144 // Check for autoplay if not already done
1145 if (!autoplayCheckComplete) {
1146 autoplayCheckFunction(player, $slide);
1147 }
1148 }
1149
1150 function setAutoplaySupport(supported) {
1151 var supportClass = supported ? classes.supportsAutoplay : classes.supportsNoAutoplay;
1152 $(document.documentElement).addClass(supportClass);
1153
1154 if (!supported) {
1155 playOnClick = true;
1156 }
1157
1158 autoplayCheckComplete = true;
1159 }
1160
1161 function autoplayCheckFunction(player, $slide) {
1162 // attempt to play video
1163 player.playVideo();
1164
1165 autoplayTest(player)
1166 .then(function() {
1167 setAutoplaySupport(true);
1168 })
1169 .fail(function() {
1170 // No autoplay available (or took too long to start playing).
1171 // Show fallback image. Stop video for safety.
1172 setAutoplaySupport(false);
1173 player.stopVideo();
1174 })
1175 .always(function() {
1176 autoplayCheckComplete = true;
1177 $slide.removeClass(classes.loading);
1178 });
1179 }
1180
1181 function autoplayTest(player) {
1182 var deferred = $.Deferred();
1183 var wait;
1184 var timeout;
1185
1186 wait = setInterval(function() {
1187 if (player.getCurrentTime() <= 0) {
1188 return;
1189 }
1190
1191 autoplayAvailable = true;
1192 clearInterval(wait);
1193 clearTimeout(timeout);
1194 deferred.resolve();
1195 }, 500);
1196
1197 timeout = setTimeout(function() {
1198 clearInterval(wait);
1199 deferred.reject();
1200 }, 4000); // subjective. test up to 8 times over 4 seconds
1201
1202 return deferred;
1203 }
1204
1205 function playOnClickCheck() {
1206 // Bail early for a few instances:
1207 // - small screen
1208 // - device sniff mobile browser
1209
1210 if (playOnClickChecked) {
1211 return;
1212 }
1213
1214 if ($(window).width() < 750) {
1215 playOnClick = true;
1216 } else if (window.mobileCheck()) {
1217 playOnClick = true;
1218 }
1219
1220 if (playOnClick) {
1221 // No need to also do the autoplay check
1222 setAutoplaySupport(false);
1223 }
1224
1225 playOnClickChecked = true;
1226 }
1227
1228 // The API will call this function when each video player is ready
1229 function onPlayerReady(evt) {
1230 evt.target.setPlaybackQuality('hd1080');
1231 var videoData = getVideoOptions(evt);
1232
1233 playOnClickCheck();
1234
1235 // Prevent tabbing through YouTube player controls until visible
1236 $('#' + videoData.id).attr('tabindex', '-1');
1237
1238 sizeBackgroundVideos();
1239
1240 // Customize based on options from the video ID
1241 switch (videoData.type) {
1242 case 'background-chrome':
1243 case 'background':
1244 evt.target.mute();
1245 // Only play the video if it is in the active slide
1246 if (videoData.$parentSlide.hasClass(classes.currentSlide)) {
1247 privatePlayVideo(videoData.id);
1248 }
1249 break;
1250 }
1251
1252 videoData.$parentSlide.addClass(classes.loaded);
1253 }
1254
1255 function onPlayerChange(evt) {
1256 var videoData = getVideoOptions(evt);
1257
1258 switch (evt.data) {
1259 case 0: // ended
1260 setAsFinished(videoData);
1261 break;
1262 case 1: // playing
1263 setAsPlaying(videoData);
1264 break;
1265 case 2: // paused
1266 setAsPaused(videoData);
1267 break;
1268 }
1269 }
1270
1271 function setAsFinished(videoData) {
1272 switch (videoData.type) {
1273 case 'background':
1274 videoPlayers[videoData.id].seekTo(0);
1275 break;
1276 case 'background-chrome':
1277 videoPlayers[videoData.id].seekTo(0);
1278 closeVideo(videoData.id);
1279 break;
1280 case 'chrome':
1281 closeVideo(videoData.id);
1282 break;
1283 }
1284 }
1285
1286 function setAsPlaying(videoData) {
1287 var $slideshow = videoData.$parentSlideshowWrapper;
1288 var $slide = videoData.$parentSlide;
1289
1290 $slide.removeClass(classes.loading);
1291
1292 // Do not change element visibility if it is a background video
1293 if (videoData.status === 'background') {
1294 return;
1295 }
1296
1297 $('#' + videoData.id).attr('tabindex', '0');
1298
1299 switch (videoData.type) {
1300 case 'chrome':
1301 case 'background-chrome':
1302 $slideshow
1303 .removeClass(classes.paused)
1304 .addClass(classes.playing);
1305 $slide
1306 .removeClass(classes.paused)
1307 .addClass(classes.playing);
1308 break;
1309 }
1310
1311 // Update focus to the close button so we stay within the slide
1312 $slide.find('.' + classes.closeVideoBtn).focus();
1313 }
1314
1315 function setAsPaused(videoData) {
1316 var $slideshow = videoData.$parentSlideshowWrapper;
1317 var $slide = videoData.$parentSlide;
1318
1319 if (videoData.type === 'background-chrome') {
1320 closeVideo(videoData.id);
1321 return;
1322 }
1323
1324 // YT's events fire after our click event. This status flag ensures
1325 // we don't interact with a closed or background video.
1326 if (videoData.status !== 'closed' && videoData.type !== 'background') {
1327 $slideshow.addClass(classes.paused);
1328 $slide.addClass(classes.paused);
1329 }
1330
1331 if (videoData.type === 'chrome' && videoData.status === 'closed') {
1332 $slideshow.removeClass(classes.paused);
1333 $slide.removeClass(classes.paused);
1334 }
1335
1336 $slideshow.removeClass(classes.playing);
1337 $slide.removeClass(classes.playing);
1338 }
1339
1340 function closeVideo(playerId) {
1341 var videoData = videos[playerId];
1342 var $slideshow = videoData.$parentSlideshowWrapper;
1343 var $slide = videoData.$parentSlide;
1344 var classesToRemove = [classes.pause, classes.playing].join(' ');
1345
1346 $('#' + videoData.id).attr('tabindex', '-1');
1347
1348 videoData.status = 'closed';
1349
1350 switch (videoData.type) {
1351 case 'background-chrome':
1352 videoPlayers[playerId].mute();
1353 setBackgroundVideo(playerId);
1354 break;
1355 case 'chrome':
1356 videoPlayers[playerId].stopVideo();
1357 setAsPaused(videoData); // in case the video is already paused
1358 break;
1359 }
1360
1361 $slideshow.removeClass(classesToRemove);
1362 $slide.removeClass(classesToRemove);
1363 }
1364
1365 function getVideoOptions(evt) {
1366 return videos[evt.target.h.id];
1367 }
1368
1369 function startVideoOnClick(playerId) {
1370 var videoData = videos[playerId];
1371 // add loading class to slide
1372 videoData.$parentSlide.addClass(classes.loading);
1373
1374 videoData.status = 'open';
1375
1376 switch (videoData.type) {
1377 case 'background-chrome':
1378 unsetBackgroundVideo(playerId, videoData);
1379 videoPlayers[playerId].unMute();
1380 privatePlayVideo(playerId, true);
1381 break;
1382 case 'chrome':
1383 privatePlayVideo(playerId, true);
1384 break;
1385 }
1386
1387 // esc to close video player
1388 $(document).on('keydown.videoPlayer', function(evt) {
1389 if (evt.keyCode === 27) {
1390 closeVideo(playerId);
1391 }
1392 });
1393 }
1394
1395 function sizeBackgroundVideos() {
1396 $('.' + classes.videoBackground).each(function(index, el) {
1397 sizeBackgroundVideo($(el));
1398 });
1399 }
1400
1401 function sizeBackgroundVideo($player) {
1402 var $slide = $player.closest('.' + classes.slide);
1403 // Ignore cloned slides
1404 if ($slide.hasClass(classes.slickClone)) {
1405 return;
1406 }
1407 var slideWidth = $slide.width();
1408 var playerWidth = $player.width();
1409 var playerHeight = $player.height();
1410
1411 // when screen aspect ratio differs from video, video must center and underlay one dimension
1412 if (slideWidth / videoOptions.ratio < playerHeight) {
1413 playerWidth = Math.ceil(playerHeight * videoOptions.ratio); // get new player width
1414 $player.width(playerWidth).height(playerHeight).css({
1415 left: (slideWidth - playerWidth) / 2,
1416 top: 0
1417 }); // player width is greater, offset left; reset top
1418 } else { // new video width < window width (gap to right)
1419 playerHeight = Math.ceil(slideWidth / videoOptions.ratio); // get new player height
1420 $player.width(slideWidth).height(playerHeight).css({
1421 left: 0,
1422 top: (playerHeight - playerHeight) / 2
1423 }); // player height is greater, offset top; reset left
1424 }
1425
1426 $player
1427 .prepareTransition()
1428 .addClass(classes.loaded);
1429 }
1430
1431 function unsetBackgroundVideo(playerId) {
1432 // Switch the background-chrome to a chrome-only player once played
1433 $('#' + playerId)
1434 .removeAttr('style')
1435 .removeClass(classes.videoBackground)
1436 .addClass(classes.videoChrome);
1437
1438 videos[playerId].$parentSlideshowWrapper
1439 .removeClass(classes.slideBackgroundVideo)
1440 .addClass(classes.playing);
1441
1442 videos[playerId].$parentSlide
1443 .removeClass(classes.slideBackgroundVideo)
1444 .addClass(classes.playing);
1445
1446 videos[playerId].status = 'open';
1447 }
1448
1449 function setBackgroundVideo(playerId) {
1450 // Switch back to background-chrome when closed
1451 var $player = $('#' + playerId)
1452 .addClass(classes.videoBackground)
1453 .removeClass(classes.videoChrome);
1454
1455 videos[playerId].$parentSlide
1456 .addClass(classes.slideBackgroundVideo);
1457
1458 videos[playerId].status = 'background';
1459 sizeBackgroundVideo($player);
1460 }
1461
1462 function initEvents() {
1463 $(document).on('click.videoPlayer', '.' + classes.playVideoBtn, function(evt) {
1464 var playerId = $(evt.currentTarget).data('controls');
1465 startVideoOnClick(playerId);
1466 });
1467
1468 $(document).on('click.videoPlayer', '.' + classes.closeVideoBtn, function(evt) {
1469 var playerId = $(evt.currentTarget).data('controls');
1470 closeVideo(playerId);
1471 });
1472
1473 // Listen to resize to keep a background-size:cover-like layout
1474 $(window).on('resize.videoPlayer', $.debounce(250, function() {
1475 if (youtubeLoaded) {
1476 sizeBackgroundVideos();
1477 }
1478 }));
1479 }
1480
1481 function removeEvents() {
1482 $(document).off('.videoPlayer');
1483 $(window).off('.videoPlayer');
1484 }
1485
1486 return {
1487 init: init,
1488 loadVideos: loadVideos,
1489 loadVideo: loadVideo,
1490 playVideo: customPlayVideo,
1491 pauseVideo: pauseVideo,
1492 removeEvents: removeEvents
1493 };
1494})();
1495
1496
1497/* ================ TEMPLATES ================ */
1498(function() {
1499 var $filterBy = $('#BlogTagFilter');
1500
1501 if (!$filterBy.length) {
1502 return;
1503 }
1504
1505 $filterBy.on('change', function() {
1506 location.href = $(this).val();
1507 });
1508
1509})();
1510
1511window.theme = theme || {};
1512
1513theme.customerTemplates = (function() {
1514
1515 function initEventListeners() {
1516 // Show reset password form
1517 $('#RecoverPassword').on('click', function(evt) {
1518 evt.preventDefault();
1519 toggleRecoverPasswordForm();
1520 });
1521
1522 // Hide reset password form
1523 $('#HideRecoverPasswordLink').on('click', function(evt) {
1524 evt.preventDefault();
1525 toggleRecoverPasswordForm();
1526 });
1527 }
1528
1529 /**
1530 *
1531 * Show/Hide recover password form
1532 *
1533 */
1534 function toggleRecoverPasswordForm() {
1535 $('#RecoverPasswordForm').toggleClass('hide');
1536 $('#CustomerLoginForm').toggleClass('hide');
1537 }
1538
1539 /**
1540 *
1541 * Show reset password success message
1542 *
1543 */
1544 function resetPasswordSuccess() {
1545 var $formState = $('.reset-password-success');
1546
1547 // check if reset password form was successfully submited.
1548 if (!$formState.length) {
1549 return;
1550 }
1551
1552 // show success message
1553 $('#ResetSuccess').removeClass('hide');
1554 }
1555
1556 /**
1557 *
1558 * Show/hide customer address forms
1559 *
1560 */
1561 function customerAddressForm() {
1562 var $newAddressForm = $('#AddressNewForm');
1563
1564 if (!$newAddressForm.length) {
1565 return;
1566 }
1567
1568 // Initialize observers on address selectors, defined in shopify_common.js
1569 if (Shopify) {
1570 // eslint-disable-next-line no-new
1571 new Shopify.CountryProvinceSelector('AddressCountryNew', 'AddressProvinceNew', {
1572 hideElement: 'AddressProvinceContainerNew'
1573 });
1574 }
1575
1576 // Initialize each edit form's country/province selector
1577 $('.address-country-option').each(function() {
1578 var formId = $(this).data('form-id');
1579 var countrySelector = 'AddressCountry_' + formId;
1580 var provinceSelector = 'AddressProvince_' + formId;
1581 var containerSelector = 'AddressProvinceContainer_' + formId;
1582
1583 // eslint-disable-next-line no-new
1584 new Shopify.CountryProvinceSelector(countrySelector, provinceSelector, {
1585 hideElement: containerSelector
1586 });
1587 });
1588
1589 // Toggle new/edit address forms
1590 $('.address-new-toggle').on('click', function() {
1591 $newAddressForm.toggleClass('hide');
1592 });
1593
1594 $('.address-edit-toggle').on('click', function() {
1595 var formId = $(this).data('form-id');
1596 $('#EditAddress_' + formId).toggleClass('hide');
1597 });
1598
1599 $('.address-delete').on('click', function() {
1600 var $el = $(this);
1601 var formId = $el.data('form-id');
1602 var confirmMessage = $el.data('confirm-message');
1603
1604 // eslint-disable-next-line no-alert
1605 if (confirm(confirmMessage || 'Are you sure you wish to delete this address?')) {
1606 Shopify.postLink('/account/addresses/' + formId, {parameters: {_method: 'delete'}});
1607 }
1608 });
1609 }
1610
1611 /**
1612 *
1613 * Check URL for reset password hash
1614 *
1615 */
1616 function checkUrlHash() {
1617 var hash = window.location.hash;
1618
1619 // Allow deep linking to recover password form
1620 if (hash === '#recover') {
1621 toggleRecoverPasswordForm();
1622 }
1623 }
1624
1625 return {
1626 init: function() {
1627 checkUrlHash();
1628 initEventListeners();
1629 resetPasswordSuccess();
1630 customerAddressForm();
1631 }
1632 };
1633})();
1634
1635
1636
1637
1638/*================ SECTIONS ================*/
1639window.theme = window.theme || {};
1640
1641theme.Cart = (function() {
1642 var selectors = {
1643 edit: '.js-edit-toggle'
1644 };
1645 var config = {
1646 showClass: 'cart__update--show',
1647 showEditClass: 'cart__edit--active'
1648 };
1649
1650 function Cart(container) {
1651 this.$container = $(container);
1652 this.$edit = $(selectors.edit, this.$container);
1653
1654 this.$edit.on('click', this._onEditClick.bind(this));
1655 }
1656
1657 Cart.prototype = _.assignIn({}, Cart.prototype, {
1658 onUnload: function() {
1659 this.$edit.off('click', this._onEditClick);
1660 },
1661
1662 _onEditClick: function(evt) {
1663 var $evtTarget = $(evt.target);
1664 var $updateLine = $('.' + $evtTarget.data('target'));
1665
1666 $evtTarget.toggleClass(config.showEditClass);
1667 $updateLine.toggleClass(config.showClass);
1668 }
1669 });
1670
1671 return Cart;
1672})();
1673
1674window.theme = window.theme || {};
1675
1676theme.Filters = (function() {
1677 var constants = {
1678 SORT_BY: 'sort_by',
1679 DEFAULT_SORT: 'title-ascending'
1680 };
1681 var selectors = {
1682 filterSelection: '.filters-toolbar__input--filter',
1683 sortSelection: '.filters-toolbar__input--sort',
1684 defaultSort: '.filters-toolbar__default-sort'
1685 };
1686
1687 function Filters(container) {
1688 var $container = this.$container = $(container);
1689
1690 this.$filterSelect = $(selectors.filterSelection, $container);
1691 this.$sortSelect = $(selectors.sortSelection, $container);
1692 this.$selects = $(selectors.filterSelection, $container).add($(selectors.sortSelection, $container));
1693
1694 this.defaultSort = this._getDefaultSortValue();
1695 this._resizeSelect(this.$selects);
1696 this.$selects.removeClass('hidden');
1697
1698 this.$filterSelect.on('change', this._onFilterChange.bind(this));
1699 this.$sortSelect.on('change', this._onSortChange.bind(this));
1700 }
1701
1702 Filters.prototype = _.assignIn({}, Filters.prototype, {
1703 _onSortChange: function(evt) {
1704 var query = '';
1705
1706 this.sort = this._getSortValue();
1707
1708 if (this.sort !== this.defaultSort) {
1709 query = [constants.SORT_BY + '=' + this.sort];
1710 }
1711
1712 var search = document.location.search = query.length ? '?' + query : '';
1713
1714 document.location.href = this.$filterSelect.val() + search;
1715 this._resizeSelect($(evt.target));
1716 },
1717
1718 _onFilterChange: function(evt) {
1719 document.location.href = this.$filterSelect.val() + document.location.search;
1720 this._resizeSelect($(evt.target));
1721 },
1722
1723 _getSortValue: function() {
1724 return this.$sortSelect.val() || this.defaultSort;
1725 },
1726
1727 _getDefaultSortValue: function() {
1728 return $(selectors.defaultSort, this.$container).val() || constants.DEFAULT_SORT;
1729 },
1730
1731 _resizeSelect: function($selection) {
1732 $selection.each(function() {
1733 var $this = $(this);
1734 var arrowWidth = 10;
1735 // create test element
1736 var text = $this.find('option:selected').text();
1737 var $test = $('<span>').html(text);
1738
1739 // add to body, get width, and get out
1740 $test.appendTo('body');
1741 var width = $test.width();
1742 $test.remove();
1743
1744 // set select width
1745 $this.width(width + arrowWidth);
1746 });
1747 },
1748
1749 onUnload: function() {
1750 this.$filterSelect.off('change', this._onFilterChange);
1751 this.$sortSelect.off('change', this._onSortChange);
1752 }
1753 });
1754
1755 return Filters;
1756})();
1757
1758window.theme = window.theme || {};
1759
1760theme.HeaderSection = (function() {
1761
1762 function Header() {
1763 theme.Header.init();
1764 theme.MobileNav.init();
1765 theme.Search.init();
1766 }
1767
1768 Header.prototype = _.assignIn({}, Header.prototype, {
1769 onUnload: function() {
1770 theme.Header.unload();
1771 }
1772 });
1773
1774 return Header;
1775})();
1776
1777theme.Maps = (function() {
1778 var config = {
1779 zoom: 14
1780 };
1781 var apiStatus = null;
1782 var mapsToLoad = [];
1783 var key = theme.mapKey ? theme.mapKey : '';
1784
1785 function Map(container) {
1786 this.$container = $(container);
1787
1788 if (apiStatus === 'loaded') {
1789 this.createMap();
1790 } else {
1791 mapsToLoad.push(this);
1792
1793 if (apiStatus !== 'loading') {
1794 apiStatus = 'loading';
1795 if (typeof window.google === 'undefined') {
1796 $.getScript('https://maps.googleapis.com/maps/api/js?key=' + key)
1797 .then(function() {
1798 apiStatus = 'loaded';
1799 initAllMaps();
1800 });
1801 }
1802 }
1803 }
1804 }
1805
1806 function initAllMaps() {
1807 // API has loaded, load all Map instances in queue
1808 $.each(mapsToLoad, function(index, instance) {
1809 instance.createMap();
1810 });
1811 }
1812
1813 function geolocate($map) {
1814 var deferred = $.Deferred();
1815 var geocoder = new google.maps.Geocoder();
1816 var address = $map.data('address-setting');
1817
1818 geocoder.geocode({address: address}, function(results, status) {
1819 if (status !== google.maps.GeocoderStatus.OK) {
1820 deferred.reject(status);
1821 }
1822
1823 deferred.resolve(results);
1824 });
1825
1826 return deferred;
1827 }
1828
1829 Map.prototype = _.assignIn({}, Map.prototype, {
1830 createMap: function() {
1831 var $map = this.$container.find('.map-section__container');
1832
1833 return geolocate($map)
1834 .then(function(results) {
1835 var mapOptions = {
1836 zoom: config.zoom,
1837 center: results[0].geometry.location,
1838 disableDefaultUI: true
1839 };
1840
1841 var map = this.map = new google.maps.Map($map[0], mapOptions);
1842 var center = this.center = map.getCenter();
1843
1844 //eslint-disable-next-line no-unused-vars
1845 var marker = new google.maps.Marker({
1846 map: map,
1847 position: map.getCenter()
1848 });
1849
1850 google.maps.event.addDomListener(window, 'resize', $.debounce(250, function() {
1851 google.maps.event.trigger(map, 'resize');
1852 map.setCenter(center);
1853 }));
1854 }.bind(this))
1855 .fail(function() {
1856 var errorMessage;
1857
1858 switch (status) {
1859 case 'ZERO_RESULTS':
1860 errorMessage = theme.strings.addressNoResults;
1861 break;
1862 case 'OVER_QUERY_LIMIT':
1863 errorMessage = theme.strings.addressQueryLimit;
1864 break;
1865 default:
1866 errorMessage = theme.strings.addressError;
1867 break;
1868 }
1869
1870 $map
1871 .parent()
1872 .addClass('page-width map-section--load-error')
1873 .html('<div class="errors text-center">' + errorMessage + '</div>');
1874 });
1875 },
1876
1877 onUnload: function() {
1878 google.maps.event.clearListeners(this.map, 'resize');
1879 }
1880 });
1881
1882 return Map;
1883})();
1884
1885// Global function called by Google on auth errors.
1886// Show an auto error message on all map instances.
1887// eslint-disable-next-line camelcase, no-unused-vars
1888function gm_authFailure() {
1889 $('.map-section').addClass('map-section--load-error');
1890 $('.map-section__container').remove();
1891 $('.map-section__link').remove();
1892 $('.map-section__overlay').after('<div class="errors text-center">' + theme.strings.authError + '</div>');
1893}
1894
1895/* eslint-disable no-new */
1896theme.Product = (function() {
1897 var defaults = {
1898 // Breakpoints from src/stylesheets/global/variables.scss.liquid
1899 mediaQuerySmall: 'screen and (max-width: 1920px)',
1900 bpSmall: false,
1901 sliderActive: false,
1902 zoomEnabled: false,
1903 imageSize: null,
1904 imageZoomSize: null,
1905 selectors: {
1906 addToCart: '#AddToCart',
1907 productPrice: '#ProductPrice',
1908 comparePrice: '#ComparePrice',
1909 addToCartText: '#AddToCartText',
1910 productFeaturedImage: '#FeaturedImage',
1911 productThumbImages: '.product-single__thumbnail',
1912 productThumbs: '.product-single__thumbnails',
1913 optionSelector: 'productSelect',
1914 saleLabel: '.product-price__sale-label',
1915 saleClasses: 'product-price__sale product-price__sale--single'
1916 }
1917 };
1918
1919 function enableZoom($el) {
1920 var zoomUrl = $el.data('zoom');
1921 $el.zoom({
1922 url: zoomUrl
1923 });
1924 }
1925
1926 function destroyZoom($el) {
1927 $el.trigger('zoom.destroy');
1928 }
1929
1930 function Product(container) {
1931 var $container = this.$container = $(container);
1932 var sectionId = $container.attr('data-section-id');
1933
1934 this.settings = $.extend({}, defaults, {
1935 sectionId: sectionId,
1936 enableHistoryState: $container.data('enable-history-state'),
1937 selectors: {
1938 originalSelectorId: 'productSelect-' + sectionId,
1939 addToCart: '#AddToCart-' + sectionId,
1940 productPrice: '#ProductPrice-' + sectionId,
1941 comparePrice: '#ComparePrice-' + sectionId,
1942 addToCartText: '#AddToCartText-' + sectionId,
1943 productFeaturedImage: '#FeaturedImage-' + sectionId,
1944 productImageWrap: '#FeaturedImageZoom-' + sectionId,
1945 productThumbImages: '.product-single__thumbnail--' + sectionId,
1946 productThumbs: '.product-single__thumbnails-' + sectionId,
1947 saleLabel: '.product-price__sale-label-' + sectionId,
1948 saleClasses: 'product-price__sale product-price__sale--single',
1949 price: '.product-price__price-' + sectionId
1950 }
1951 });
1952
1953 // Stop parsing if we don't have the product json script tag when loading
1954 // section in the Theme Editor
1955 if (!$('#ProductJson-' + sectionId).html()) {
1956 return;
1957 }
1958
1959 this.productSingleObject = JSON.parse(document.getElementById('ProductJson-' + sectionId).innerHTML);
1960
1961 this.settings.zoomEnabled = $(this.settings.selectors.productFeaturedImage).hasClass('js-zoom-enabled');
1962 this.settings.imageSize = Shopify.Image.imageSize($(this.settings.selectors.productFeaturedImage).attr('src'));
1963
1964 if (this.settings.zoomEnabled) {
1965 this.settings.imageZoomSize = Shopify.Image.imageSize($(this.settings.selectors.productImageWrap).data('zoom'));
1966 }
1967
1968 this.init();
1969
1970 // Pre-loading product images to avoid a lag when a thumbnail is clicked, or
1971 // when a variant is selected that has a variant image
1972 Shopify.Image.preload(this.productSingleObject.images, this.settings.imageSize);
1973 }
1974
1975 Product.prototype = _.assignIn({}, Product.prototype, {
1976 init: function() {
1977 this.initBreakpoints();
1978 this.stringOverrides();
1979 this.initProductVariant();
1980 this.initProductImageSwitch();
1981 this.setActiveThumbnail();
1982 },
1983
1984 stringOverrides: function() {
1985 // Override defaults in theme.strings with potential
1986 // template overrides
1987
1988 theme.productStrings = theme.productStrings || {};
1989 $.extend(theme.strings, theme.productStrings);
1990 },
1991
1992 initBreakpoints: function() {
1993 var self = this;
1994 enquire.register(this.settings.mediaQuerySmall, {
1995 match: function() {
1996 // initialize thumbnail slider on mobile if more than three thumbnails
1997 if ($(self.settings.selectors.productThumbImages).length > 3) {
1998 self.initProductThumbnailSlider();
1999 }
2000
2001 // destroy an image zooming that's enabled
2002 if (self.settings.zoomEnabled) {
2003 destroyZoom($(self.settings.selectors.productImageWrap));
2004 }
2005
2006 self.settings.bpSmall = true;
2007 },
2008 unmatch: function() {
2009 if (self.settings.sliderActive) {
2010 self.destroyProductThumbnailSlider();
2011 }
2012
2013 if (self.settings.zoomEnabled) {
2014 enableZoom($(self.settings.selectors.productImageWrap));
2015 }
2016
2017 self.settings.bpSmall = false;
2018 }
2019 });
2020 },
2021
2022 initProductVariant: function() {
2023 // this.productSingleObject is a global JSON object defined in theme.liquid
2024 if (!this.productSingleObject) {
2025 return;
2026 }
2027
2028 var self = this;
2029
2030 this.optionSelector = new Shopify.OptionSelectors(self.settings.selectors.originalSelectorId, {
2031 selectorClass: self.settings.selectors.optionSelectorClass,
2032 product: self.productSingleObject,
2033 onVariantSelected: self.productVariantCallback,
2034 enableHistoryState: self.settings.enableHistoryState,
2035 settings: self.settings,
2036 switchProductImage: self.switchProductImage,
2037 setActiveThumbnail: self.setActiveThumbnail
2038 });
2039
2040 // Clean up variant labels if the Shopify-defined
2041 // defaults are the only ones left
2042 this.simplifyVariantLabels(this.productSingleObject);
2043 this.productVariantStyles();
2044 },
2045
2046 simplifyVariantLabels: function(productObject) {
2047 // Hide variant dropdown if only one exists and title contains 'Default'
2048 if (productObject.variants.length && productObject.variants[0].title.indexOf('Default') >= 0) {
2049 $('.selector-wrapper').hide();
2050 }
2051 },
2052
2053 initProductImageSwitch: function() {
2054 if (!$(this.settings.selectors.productThumbImages).length) {
2055 return;
2056 }
2057
2058 var self = this;
2059
2060 $(this.settings.selectors.productThumbImages).on('click', function(evt) {
2061 evt.preventDefault();
2062 var $el = $(this);
2063 var imageSrc = $el.attr('href');
2064 var zoomSrc = $el.data('zoom');
2065
2066 self.switchProductImage(imageSrc, zoomSrc);
2067 self.setActiveThumbnail(imageSrc);
2068 });
2069 },
2070
2071 setActiveThumbnail: function(src) {
2072 var activeClass = 'active-thumb';
2073
2074 // If there is no element passed, find it by the current product image
2075 if (typeof src === 'undefined') {
2076 src = $(this.settings.selectors.productFeaturedImage).attr('src');
2077 }
2078
2079 // select all thumbnails (incl. slick cloned thumbs) with matching 'href'
2080 var $thumbnail = $(this.settings.selectors.productThumbImages + '[href="' + src + '"]');
2081 // Set active thumbnail classes
2082 $(this.settings.selectors.productThumbImages).removeClass(activeClass);
2083 $thumbnail.addClass(activeClass);
2084 },
2085
2086 switchProductImage: function(image, zoomImage) {
2087 $(this.settings.selectors.productFeaturedImage).attr('src', image);
2088
2089 // destroy any image zooming that might be enabled
2090 if (this.settings.zoomEnabled) {
2091 destroyZoom($(this.settings.selectors.productImageWrap));
2092 }
2093
2094 if (!this.settings.bpSmall && this.settings.zoomEnabled && zoomImage) {
2095 $(this.settings.selectors.productImageWrap).data('zoom', zoomImage);
2096 enableZoom($(this.settings.selectors.productImageWrap));
2097 }
2098 },
2099
2100 initProductThumbnailSlider: function() {
2101 var options = {
2102 slidesToShow: 4,
2103 slidesToScroll: 4,
2104 infinite: true,
2105 rtl:checkrtl,
2106 prevArrow: '.thumbnails-slider__prev--' + this.settings.sectionId,
2107 nextArrow: '.thumbnails-slider__next--' + this.settings.sectionId,
2108 responsive: [
2109 {
2110 breakpoint: 991,
2111 settings: {
2112 slidesToShow: 1,
2113 slidesToScroll: 1
2114 }
2115 }
2116 ]
2117 };
2118 $(this.settings.selectors.productThumbs).slick(options);
2119 this.settings.sliderActive = true;
2120
2121 },
2122
2123 destroyProductThumbnailSlider: function() {
2124 $(this.settings.selectors.productThumbs).slick('unslick');
2125 this.settings.sliderActive = false;
2126 },
2127
2128 productVariantStyles: function() {
2129 $('.selector-wrapper').addClass('product-form__item');
2130 $('.single-option-selector').addClass('product-form__input');
2131 },
2132
2133 // **WARNING** This function actually inherits `this` from `this.optionSelector` not
2134 // from `product` when passed in as a callback for `option_selection.js`
2135 productVariantCallback: function(variant) {
2136 var sizedImgUrl;
2137 var zoomSizedImgUrl;
2138
2139 if (variant) {
2140 // Update variant image, if one is set
2141 if (variant.featured_image) {
2142 sizedImgUrl = Shopify.Image.getSizedImageUrl(variant.featured_image.src, this.settings.imageSize);
2143 if (this.settings.zoomEnabled) {
2144 zoomSizedImgUrl = Shopify.Image.getSizedImageUrl(variant.featured_image.src, this.settings.imageZoomSize);
2145 }
2146 this.switchProductImage(sizedImgUrl, zoomSizedImgUrl);
2147 this.setActiveThumbnail(sizedImgUrl);
2148 } else {
2149 // No featured image so setup the zoom on the images loaded by liquid
2150 var self = this;
2151 enquire.register(this.settings.mediaQueryMediumUp, {
2152 match: function() {
2153 if (self.settings.zoomEnabled) {
2154 enableZoom($(self.settings.selectors.productImageWrap));
2155 }
2156 }
2157 });
2158 }
2159
2160 // Update the product price
2161 $(this.settings.selectors.productPrice).html(Shopify.formatMoney(variant.price, theme.moneyFormat));
2162
2163 // Update and show the product's compare price if necessary
2164 if (variant.compare_at_price > variant.price) {
2165 $(this.settings.selectors.comparePrice)
2166 .html(Shopify.formatMoney(variant.compare_at_price, theme.moneyFormat))
2167 .removeClass('hide');
2168
2169 $(this.settings.selectors.price).addClass(this.settings.selectors.saleClasses);
2170
2171 $(this.settings.selectors.saleLabel).removeClass('hide');
2172 } else {
2173 $(this.settings.selectors.comparePrice).addClass('hide');
2174 $(this.settings.selectors.saleLabel).addClass('hide');
2175 $(this.settings.selectors.price).removeClass(this.settings.selectors.saleClasses);
2176 }
2177
2178 // Select a valid variant if available
2179 if (variant.available) {
2180 // We have a valid product variant, so enable the submit button
2181 $(this.settings.selectors.addToCart).prop('disabled', false);
2182 $(this.settings.selectors.addToCartText).text(theme.strings.addToCart);
2183 } else {
2184 // Variant is sold out, disable the submit button and change the text
2185 $(this.settings.selectors.addToCart).prop('disabled', true);
2186 $(this.settings.selectors.addToCartText).text(theme.strings.soldOut);
2187 }
2188 } else {
2189 // The variant doesn't exist, disable submit button and change the text.
2190 // This may be an error or notice that a specific variant is not available.
2191 $(this.settings.selectors.addToCart).prop('disabled', true);
2192 $(this.settings.selectors.addToCartText).text(theme.strings.unavailable);
2193 }
2194 }
2195
2196 });
2197
2198 return Product;
2199})();
2200
2201
2202
2203theme.Quotes = (function() {
2204
2205 var config = {
2206 mediaQuerySmall: 'screen and (max-width: 749px)',
2207 mediaQueryMediumUp: 'screen and (min-width: 750px)',
2208 slideCount: 0,
2209 slidecol:1,
2210 };
2211 var defaults = {
2212 accessibility: true,
2213 arrows: false,
2214 dots: true,
2215 autoplay: false,
2216 touchThreshold: 20,
2217 slidesToShow: 1,
2218 slidesToScroll: 1,
2219 rtl:checkrtl,
2220 responsive: [
2221 {
2222 breakpoint: 992,
2223 settings: {
2224 autoplay: false,
2225 adaptiveHeight: true
2226 }
2227 }
2228 ]
2229 };
2230
2231 function Quotes(container) {
2232 var $container = this.$container = $(container);
2233 var sectionId = $container.attr('data-section-id');
2234 var wrapper = this.wrapper = '.quotes-wrapper';
2235 var slider = this.slider = '#Quotes-' + sectionId;
2236 var $slider = $(slider, wrapper);
2237 var sliderActive = false;
2238 var mobileOptions = $.extend({}, defaults, {
2239 slidesToShow: 1,
2240 slidesToScroll: 1,
2241 adaptiveHeight: true
2242 });
2243
2244 config.slideCount = $slider.data('count');
2245 // Override slidesToShow/Scroll if there are not enough blocks
2246 if (config.slideCount < defaults.slidesToShow) {
2247 defaults.slidesToShow = config.slideCount;
2248 defaults.slidesToScroll = config.slideCount;
2249 }
2250
2251 $slider.on('init', this.a11y.bind(this));
2252
2253 enquire.register(config.mediaQuerySmall, {
2254 match: function() {
2255 initSlider($slider, mobileOptions);
2256 }
2257 });
2258
2259 enquire.register(config.mediaQueryMediumUp, {
2260 match: function() {
2261 initSlider($slider, defaults);
2262 }
2263 });
2264
2265 function initSlider(sliderObj, args) {
2266 if (sliderActive) {
2267 sliderObj.slick('unslick');
2268 sliderActive = false;
2269 }
2270
2271 sliderObj.slick(args);
2272 sliderActive = true;
2273 }
2274 }
2275
2276 Quotes.prototype = _.assignIn({}, Quotes.prototype, {
2277 onUnload: function() {
2278 enquire.unregister(config.mediaQuerySmall);
2279 enquire.unregister(config.mediaQueryMediumUp);
2280
2281 $(this.slider, this.wrapper).slick('unslick');
2282 },
2283
2284 onBlockSelect: function(evt) {
2285 // Ignore the cloned version
2286 var $slide = $('.quotes-slide--' + evt.detail.blockId + ':not(.slick-cloned)');
2287 var slideIndex = $slide.data('slick-index');
2288
2289 // Go to selected slide, pause autoplay
2290 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
2291 },
2292
2293 a11y: function(event, obj) {
2294 var $list = obj.$list;
2295 var $wrapper = $(this.wrapper, this.$container);
2296
2297 // Remove default Slick aria-live attr until slider is focused
2298 $list.removeAttr('aria-live');
2299
2300 // When an element in the slider is focused set aria-live
2301 $wrapper.on('focusin', function(evt) {
2302 if ($wrapper.has(evt.target).length) {
2303 $list.attr('aria-live', 'polite');
2304 }
2305 });
2306
2307 // Remove aria-live
2308 $wrapper.on('focusout', function(evt) {
2309 if ($wrapper.has(evt.target).length) {
2310 $list.removeAttr('aria-live');
2311 }
2312 });
2313 }
2314 });
2315
2316 return Quotes;
2317})();
2318
2319//lookbook
2320theme.Look = (function() {
2321
2322 var config = {
2323 mediaQuerySmall: 'screen and (max-width: 749px)',
2324 mediaQueryMediumUp: 'screen and (min-width: 750px)',
2325 slideCount: 0,
2326 slidecol:1,
2327 };
2328 var defaults = {
2329 centerMode: true,
2330 infinite: true,
2331 centerPadding: '20%',
2332 slidesToShow: 1,
2333 speed: 500,
2334 variableWidth: false,
2335 responsive: [
2336 {
2337 breakpoint: 1199,
2338 settings: {
2339 centerMode: false,
2340 adaptiveHeight: true
2341 }
2342 }
2343 ]
2344 };
2345
2346 function Look(container) {
2347 var $container = this.$container = $(container);
2348 var sectionId = $container.attr('data-section-id');
2349 var wrapper = this.wrapper = '.look-wrapper';
2350 var slider = this.slider = '#look-' + sectionId;
2351 var $slider = $(slider, wrapper);
2352 var sliderActive = false;
2353 var mobileOptions = $.extend({}, defaults, {
2354 slidesToShow: 1,
2355 slidesToScroll: 1,
2356 adaptiveHeight: true,
2357 centerMode: false,
2358 });
2359
2360 config.slideCount = $slider.data('count');
2361 // Override slidesToShow/Scroll if there are not enough blocks
2362 if (config.slideCount < defaults.slidesToShow) {
2363 defaults.slidesToShow = config.slideCount;
2364 defaults.slidesToScroll = config.slideCount;
2365 }
2366
2367 $slider.on('init', this.a11y.bind(this));
2368
2369 enquire.register(config.mediaQuerySmall, {
2370 match: function() {
2371 initSlider($slider, mobileOptions);
2372 }
2373 });
2374
2375 enquire.register(config.mediaQueryMediumUp, {
2376 match: function() {
2377 initSlider($slider, defaults);
2378 }
2379 });
2380
2381 function initSlider(sliderObj, args) {
2382 if (sliderActive) {
2383 sliderObj.slick('unslick');
2384 sliderActive = false;
2385 }
2386
2387 sliderObj.slick(args);
2388 sliderActive = true;
2389 }
2390 }
2391
2392 Look.prototype = _.assignIn({}, Look.prototype, {
2393 onUnload: function() {
2394 enquire.unregister(config.mediaQuerySmall);
2395 enquire.unregister(config.mediaQueryMediumUp);
2396
2397 $(this.slider, this.wrapper).slick('unslick');
2398 },
2399
2400 onBlockSelect: function(evt) {
2401 // Ignore the cloned version
2402 var $slide = $('.look__b' + evt.detail.blockId + ':not(.slick-cloned)');
2403 var slideIndex = $slide.data('slick-index');
2404
2405 // Go to selected slide, pause autoplay
2406 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
2407 },
2408
2409 a11y: function(event, obj) {
2410 var $list = obj.$list;
2411 var $wrapper = $(this.wrapper, this.$container);
2412
2413 // Remove default Slick aria-live attr until slider is focused
2414 $list.removeAttr('aria-live');
2415
2416 // When an element in the slider is focused set aria-live
2417 $wrapper.on('focusin', function(evt) {
2418 if ($wrapper.has(evt.target).length) {
2419 $list.attr('aria-live', 'polite');
2420 }
2421 });
2422
2423 // Remove aria-live
2424 $wrapper.on('focusout', function(evt) {
2425 if ($wrapper.has(evt.target).length) {
2426 $list.removeAttr('aria-live');
2427 }
2428 });
2429 }
2430 });
2431
2432 return Look;
2433})();
2434
2435//lookbook
2436theme.Lookhome = (function() {
2437
2438 var config = {
2439 mediaQuerySmall: 'screen and (max-width: 749px)',
2440 mediaQueryMediumUp: 'screen and (min-width: 750px)',
2441 slideCount: 0,
2442 slidecol:1,
2443 };
2444
2445
2446 function Lookhome(container) {
2447 var $container = this.$container = $(container);
2448 var sectionId = $container.attr('data-section-id');
2449 var wrapper = this.wrapper = '.lookhome-wrapper';
2450 var slider = this.slider = '#Lookhome-' + sectionId;
2451 var $slider = $(slider, wrapper);
2452 var cols = $slider.data('col');
2453 var arrows = $slider.data('arrows');
2454 var dot = $slider.data('dot');
2455 var sliderActive = false;
2456 var defaults = {
2457 infinite: false,
2458 slidesToShow: cols,
2459 arrows: arrows,
2460 dots: dot,
2461 };
2462 var mobileOptions = $.extend({}, defaults, {
2463 slidesToShow: 1,
2464 slidesToScroll: 1,
2465 adaptiveHeight: true,
2466 centerMode: false,
2467 });
2468
2469 config.slideCount = $slider.data('col');
2470 // Override slidesToShow/Scroll if there are not enough blocks
2471 if (config.slideCount < defaults.slidesToShow) {
2472 defaults.slidesToShow = config.slideCount;
2473 defaults.slidesToScroll = config.slideCount;
2474 }
2475
2476 $slider.on('init', this.a11y.bind(this));
2477
2478 enquire.register(config.mediaQuerySmall, {
2479 match: function() {
2480 initSlider($slider, mobileOptions);
2481 }
2482 });
2483
2484 enquire.register(config.mediaQueryMediumUp, {
2485 match: function() {
2486 initSlider($slider, defaults);
2487 }
2488 });
2489
2490 function initSlider(sliderObj, args) {
2491 if (sliderActive) {
2492 sliderObj.slick('unslick');
2493 sliderActive = false;
2494 }
2495
2496 sliderObj.slick(args);
2497 sliderActive = true;
2498 }
2499 }
2500
2501 Lookhome.prototype = _.assignIn({}, Lookhome.prototype, {
2502 onUnload: function() {
2503 enquire.unregister(config.mediaQuerySmall);
2504 enquire.unregister(config.mediaQueryMediumUp);
2505
2506 $(this.slider, this.wrapper).slick('unslick');
2507 },
2508
2509 onBlockSelect: function(evt) {
2510 // Ignore the cloned version
2511 var $slide = $('.look__h' + evt.detail.blockId + ':not(.slick-cloned)');
2512 var slideIndex = $slide.data('slick-index');
2513
2514 // Go to selected slide, pause autoplay
2515 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
2516 },
2517
2518 a11y: function(event, obj) {
2519 var $list = obj.$list;
2520 var $wrapper = $(this.wrapper, this.$container);
2521
2522 // Remove default Slick aria-live attr until slider is focused
2523 $list.removeAttr('aria-live');
2524
2525 // When an element in the slider is focused set aria-live
2526 $wrapper.on('focusin', function(evt) {
2527 if ($wrapper.has(evt.target).length) {
2528 $list.attr('aria-live', 'polite');
2529 }
2530 });
2531
2532 // Remove aria-live
2533 $wrapper.on('focusout', function(evt) {
2534 if ($wrapper.has(evt.target).length) {
2535 $list.removeAttr('aria-live');
2536 }
2537 });
2538 }
2539 });
2540
2541 return Lookhome;
2542})();
2543
2544//lookbook 2
2545theme.Look2 = (function() {
2546 function Look2(container){
2547 var $container = this.$container = $(container);
2548 var sectionId = $container.attr('data-section-id');
2549
2550 var doAnimations = function() {
2551 // Calc current offset and get all animatables
2552 var offset = $(window).scrollTop() + $(window).height(),
2553 $animatables = $('.revealedBox');
2554 console.log(offset);
2555 // Unbind scroll handler if we have no animatables
2556 if ($animatables.size() == 0) {
2557 $(window).off('scroll', doAnimations);
2558 }
2559 // Check all animatables and animate them if necessary
2560 $animatables.each(function(i) {
2561 var $animatable = $(this);
2562 if (($animatable.offset().top + $animatable.height() - 20) < offset) {
2563 $animatable.addClass('revealedBox-in');
2564 console.log($animatable.offset().top + $animatable.height() - 20);
2565 }
2566 });
2567 };
2568 $("#lookver .look-image").hide();
2569 size_li = $("#lookver .look-image").size();
2570 x=5;
2571 $('#lookver .look-image:lt('+x+')').show();
2572 $('#loadMore').click(function () {
2573 x= (x+5 <= size_li) ? x+5 : size_li;
2574 $('#lookver .look-image:lt('+x+')').show();
2575 $('#showLess').css('display','inline-block');
2576 if(x == size_li){
2577 $('#loadMore').css('display','none');
2578 }
2579 });
2580 $('#showLess').click(function () {
2581 x=(x-5<0) ? 5 : x-5;
2582 $('#lookver .look-image').not(':lt('+x+')').hide();
2583 $('#loadMore').css('display','inline-block');
2584 $('#showLess').css('display','inline-block');
2585 if(x == 5){
2586 $('#showLess').css('display','none');
2587 }
2588 });
2589 // Hook doAnimations on scroll, and trigger a scroll
2590 $(window).on('scroll', doAnimations);
2591 $(window).trigger('scroll');
2592
2593
2594 }
2595 return Look2;
2596})();
2597
2598//List collection icon 3
2599theme.List = (function() {
2600
2601 var config = {
2602 mediaQuerySmall: 'screen and (max-width: 749px)',
2603 mediaQueryMediumUp: 'screen and (min-width: 750px)',
2604 slideCount: 0,
2605 slidecol:1,
2606 };
2607
2608
2609 function List(container) {
2610 var $container = this.$container = $(container);
2611 var sectionId = $container.attr('data-section-id');
2612 var wrapper = this.wrapper = '.list-wrapper';
2613 var slider = this.slider = '#list-' + sectionId;
2614 var $slider = $(slider, wrapper);
2615 var cols = $slider.data('count');
2616 var rows = $slider.data('row');
2617 var dot = $slider.data('dot');
2618 var nav = $slider.data('nav');
2619 var sliderActive = false;
2620 var defaults = {
2621 infinite: false,
2622 slidesToShow: cols,
2623 rows: rows,
2624 dots: dot,
2625 arrows:nav,
2626 speed: 500,
2627 variableWidth: false,
2628 adaptiveHeight: true,
2629 responsive: [
2630 {
2631 breakpoint: 1199,
2632 settings: {
2633 slidesToShow: 4,
2634 }
2635 },
2636 {
2637 breakpoint: 990,
2638 settings: {
2639 slidesToShow: 3,
2640 slidesToScroll: 1,
2641 }
2642 },
2643 {
2644 breakpoint: 767,
2645 settings: {
2646 slidesToShow: 2,
2647 slidesToScroll: 1,
2648 }
2649 },
2650 {
2651 breakpoint: 480,
2652 settings: {
2653 slidesToShow: 1,
2654 slidesToScroll: 1,
2655 }
2656 }
2657 ]
2658 };
2659 var mobileOptions = $.extend({}, defaults, {
2660 slidesToShow: 1,
2661 slidesToScroll: 1,
2662 adaptiveHeight: true,
2663 centerMode: false,
2664 });
2665
2666 config.slideCount = $slider.data('count');
2667 // Override slidesToShow/Scroll if there are not enough blocks
2668 if (config.slideCount < defaults.slidesToShow) {
2669 defaults.slidesToShow = config.slideCount;
2670 defaults.slidesToScroll = config.slideCount;
2671 }
2672
2673 $slider.on('init', this.a11y.bind(this));
2674
2675 enquire.register(config.mediaQuerySmall, {
2676 match: function() {
2677 initSlider($slider, mobileOptions);
2678 }
2679 });
2680
2681 enquire.register(config.mediaQueryMediumUp, {
2682 match: function() {
2683 initSlider($slider, defaults);
2684 }
2685 });
2686
2687 function initSlider(sliderObj, args) {
2688 if (sliderActive) {
2689 sliderObj.slick('unslick');
2690 sliderActive = false;
2691 }
2692
2693 sliderObj.slick(args);
2694 sliderActive = true;
2695 }
2696 }
2697
2698 List.prototype = _.assignIn({}, List.prototype, {
2699 onUnload: function() {
2700 enquire.unregister(config.mediaQuerySmall);
2701 enquire.unregister(config.mediaQueryMediumUp);
2702
2703 $(this.slider, this.wrapper).slick('unslick');
2704 },
2705
2706 onBlockSelect: function(evt) {
2707 // Ignore the cloned version
2708 var $slide = $('.list__b' + evt.detail.blockId + ':not(.slick-cloned)');
2709 var slideIndex = $slide.data('slick-index');
2710
2711 // Go to selected slide, pause autoplay
2712 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
2713 },
2714
2715 a11y: function(event, obj) {
2716 var $list = obj.$list;
2717 var $wrapper = $(this.wrapper, this.$container);
2718
2719 // Remove default Slick aria-live attr until slider is focused
2720 $list.removeAttr('aria-live');
2721
2722 // When an element in the slider is focused set aria-live
2723 $wrapper.on('focusin', function(evt) {
2724 if ($wrapper.has(evt.target).length) {
2725 $list.attr('aria-live', 'polite');
2726 }
2727 });
2728
2729 // Remove aria-live
2730 $wrapper.on('focusout', function(evt) {
2731 if ($wrapper.has(evt.target).length) {
2732 $list.removeAttr('aria-live');
2733 }
2734 });
2735 }
2736 });
2737
2738 return List;
2739})();
2740
2741//blog
2742
2743 theme.Blogs = (function() {
2744 var config = {
2745 mediaQuerySmall: 'screen and (max-width: 767px)',
2746 mediaQueryMediumUp: '(min-width: 768px) and (max-width: 991px)',
2747 mediaQueryDesk: 'screen and (min-width: 992px)',
2748 slideCount: 0
2749 };
2750 function Blogs(container) {
2751 var $container = this.$container = $(container);
2752 var sectionId = $container.attr('data-section-id');
2753 var wrapper = this.wrapper = '.blogs-wrapper';
2754 var slider = this.slider = '#Blogs-' + sectionId;
2755 var $slider = $(slider, wrapper);
2756 var sliderActive = false;
2757 var blog_per_page = $('.js-blogcolumn').data('blogcolumn');
2758 var blog_arrows = $('.js-blogcolumn').data('arrows');
2759 var blog_dot = $('.js-blogcolumn').data('dot');
2760 var blog_rows = $('.js-blogcolumn').data('rows');
2761 var defaults = {
2762 accessibility: true,
2763 arrows: blog_arrows,
2764 dots: blog_dot,
2765 rows: blog_rows,
2766 autoplay: false,
2767 touchThreshold: 20,
2768 slidesToShow: blog_per_page,
2769 slidesToScroll: 1,
2770 rtl:checkrtl,
2771 };
2772 var mobileOptions = $.extend({}, defaults, {
2773 slidesToShow: 1,
2774 slidesToScroll: 1,
2775 adaptiveHeight: true,
2776 autoplay: false,
2777
2778 });
2779 var tableOptions = $.extend({}, defaults, {
2780 slidesToShow: 2,
2781 slidesToScroll: 1,
2782 adaptiveHeight: true,
2783 autoplay: false,
2784
2785 });
2786
2787 config.slideCount = $slider.data('count');
2788
2789 // Override slidesToShow/Scroll if there are not enough blocks
2790 if (config.slideCount < defaults.slidesToShow) {
2791 defaults.slidesToShow = config.slideCount;
2792 defaults.slidesToScroll = config.slideCount;
2793 }
2794
2795 $slider.on('init', this.a11y.bind(this));
2796
2797 enquire.register(config.mediaQuerySmall, {
2798 match: function() {
2799 initSlider($slider, mobileOptions);
2800 }
2801 });
2802 enquire.register(config.mediaQueryMediumUp, {
2803 match: function() {
2804 initSlider($slider, tableOptions);
2805 }
2806 });
2807
2808 enquire.register(config.mediaQueryDesk, {
2809 match: function() {
2810 initSlider($slider, defaults);
2811 }
2812 });
2813
2814 function initSlider(sliderObj, args) {
2815 if (sliderActive) {
2816 sliderObj.slick('unslick');
2817 sliderActive = false;
2818 }
2819
2820 sliderObj.slick(args);
2821 sliderActive = true;
2822 }
2823 }
2824
2825 Blogs.prototype = _.assignIn({}, Blogs.prototype, {
2826 onUnload: function() {
2827 enquire.unregister(config.mediaQuerySmall);
2828 enquire.unregister(config.mediaQueryMediumUp);
2829 enquire.unregister(config.mediaQueryDesk);
2830
2831 $(this.slider, this.wrapper).slick('unslick');
2832 },
2833
2834 onBlockSelect: function(evt) {
2835 // Ignore the cloned version
2836 var $slide = $('.blogs-slide--' + evt.detail.blockId + ':not(.slick-cloned)');
2837 var slideIndex = $slide.data('slick-index');
2838
2839 // Go to selected slide, pause autoplay
2840 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
2841 },
2842
2843 a11y: function(event, obj) {
2844 var $list = obj.$list;
2845 var $wrapper = $(this.wrapper, this.$container);
2846
2847 // Remove default Slick aria-live attr until slider is focused
2848 $list.removeAttr('aria-live');
2849
2850 // When an element in the slider is focused set aria-live
2851 $wrapper.on('focusin', function(evt) {
2852 if ($wrapper.has(evt.target).length) {
2853 $list.attr('aria-live', 'polite');
2854 }
2855 });
2856
2857 // Remove aria-live
2858 $wrapper.on('focusout', function(evt) {
2859 if ($wrapper.has(evt.target).length) {
2860 $list.removeAttr('aria-live');
2861 }
2862 });
2863 }
2864 });
2865
2866 return Blogs;
2867})();
2868
2869//slick Product list
2870theme.Productlists = (function() {
2871 var config = {
2872 mediaQuerySmall: 'screen and (max-width: 749px)',
2873 mediaQueryMediumUp: '(min-width: 750px) and (max-width: 991px)',
2874 mediaQueryLarge: '(min-width: 992px) and (max-width: 1199px)',
2875 mediaQueryLargeDesk: 'screen and (min-width: 1200px)',
2876 slideShow: 0,
2877 scrollShow: 0,
2878 rowNumber: 0
2879 };
2880 var defaults = {
2881 accessibility: true,
2882 dots: false,
2883 autoplay: false,
2884 touchThreshold: 20,
2885 slidesToShow: 4,
2886 slidesToScroll: 4,
2887 rtl: checkrtl
2888 };
2889
2890 function Productlists(container) {
2891 var $container = (this.$container = $(container));
2892 var sectionId = $container.attr('data-section-id');
2893 var wrapper = (this.wrapper = '.productlists-wrapper');
2894 var slider = (this.slider = '#Productlists-' + sectionId);
2895 var $slider = $(slider, wrapper);
2896 config.slideShow = parseInt($slider.attr('data-toshow'));
2897 config.scrollShow = parseInt($slider.attr('data-scroll'));
2898 config.rowNumber = parseInt($slider.attr('data-row'));
2899 var play = $slider.data('play');
2900 var checkplay = $slider.data('autoplay');
2901 var arrows = $slider.data('arrows');
2902 var dot = $slider.data('dot');
2903 var laptop = $slider.data('laptop');
2904 var table = $slider.data('table');
2905 var phonemin = $slider.data('phonemin');
2906
2907 var sliderActive = false;
2908 var mobileOptions = $.extend({}, defaults, {
2909 arrows: arrows,
2910 dots:dot,
2911 slidesToShow: phonemin,
2912 slidesToScroll: phonemin,
2913 adaptiveHeight: true
2914 });
2915 var tableOptions = $.extend({}, defaults, {
2916 arrows: arrows,
2917 dots:dot,
2918 slidesToShow: table,
2919 slidesToScroll: table,
2920 adaptiveHeight: true
2921 });
2922 var desktopOptions = $.extend({}, defaults, {
2923 arrows: arrows,
2924 dots:dot,
2925 slidesToShow: laptop,
2926 slidesToScroll: laptop,
2927 adaptiveHeight: true
2928 });
2929 var desktopOptionsDesk = $.extend({}, defaults, {
2930 arrows: arrows,
2931 dots:dot,
2932 slidesToShow: config.slideShow,
2933 slidesToScroll: config.scrollShow,
2934 rows: config.rowNumber,
2935 adaptiveHeight: true,
2936 autoplay: checkplay,
2937 autoplaySpeed: play
2938 });
2939
2940 $slider.on('init', this.a11y.bind(this));
2941
2942 enquire.register(config.mediaQuerySmall, {
2943 match: function() {
2944 initSlider($slider, mobileOptions);
2945 }
2946 });
2947 enquire.register(config.mediaQueryMediumUp, {
2948 match: function() {
2949 initSlider($slider, tableOptions);
2950 }
2951 });
2952 enquire.register(config.mediaQueryLarge, {
2953 match: function() {
2954 initSlider($slider, desktopOptions);
2955 }
2956 });
2957 enquire.register(config.mediaQueryLargeDesk, {
2958 match: function() {
2959 initSlider($slider, desktopOptionsDesk);
2960 }
2961 });
2962
2963 function initSlider(sliderObj, args) {
2964 if (sliderActive) {
2965 sliderObj.slick('unslick');
2966 sliderActive = false;
2967 }
2968
2969 sliderObj.slick(args);
2970 sliderActive = true;
2971 }
2972 }
2973
2974 Productlists.prototype = _.assignIn({}, Productlists.prototype, {
2975 onUnload: function() {
2976 enquire.unregister(config.mediaQuerySmall);
2977 enquire.unregister(config.mediaQueryMediumUp);
2978 enquire.unregister(config.mediaQueryLarge);
2979 enquire.unregister(config.mediaQueryLargeDesk);
2980 $(this.slider, this.wrapper).slick('unslick');
2981 },
2982
2983 onBlockSelect: function(evt) {
2984 // Ignore the cloned version
2985 var $slide = $(
2986 '.productlists-slide--' + evt.detail.blockId + ':not(.slick-cloned)'
2987 );
2988 var slideIndex = $slide.data('slick-index');
2989
2990 // Go to selected slide, pause autoplay
2991 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
2992 },
2993
2994 a11y: function(event, obj) {
2995 var $list = obj.$list;
2996 var $wrapper = $(this.wrapper, this.$container);
2997
2998 // Remove default Slick aria-live attr until slider is focused
2999 $list.removeAttr('aria-live');
3000
3001 // When an element in the slider is focused set aria-live
3002 $wrapper.on('focusin', function(evt) {
3003 if ($wrapper.has(evt.target).length) {
3004 $list.attr('aria-live', 'polite');
3005 }
3006 });
3007
3008 // Remove aria-live
3009 $wrapper.on('focusout', function(evt) {
3010 if ($wrapper.has(evt.target).length) {
3011 $list.removeAttr('aria-live');
3012 }
3013 });
3014 }
3015 });
3016
3017 return Productlists;
3018})();
3019
3020//slick Product list
3021theme.Producttabs = (function() {
3022 var config = {
3023 mediaQuerySmall: 'screen and (max-width: 749px)',
3024 mediaQueryMediumUp: '(min-width: 750px) and (max-width: 991px)',
3025 mediaQueryLarge: '(min-width: 992px) and (max-width: 1199px)',
3026 mediaQueryLargeDesk: 'screen and (min-width: 1200px)',
3027 slideShow: 0,
3028 scrollShow: 0,
3029 rowNumber: 0
3030 };
3031 var defaults = {
3032 accessibility: true,
3033 dots: false,
3034 autoplay: false,
3035 touchThreshold: 20,
3036 slidesToShow: 4,
3037 slidesToScroll: 4,
3038 rtl: checkrtl
3039 };
3040
3041 function Producttabs(container) {
3042 var $container = (this.$container = $(container));
3043 var sectionId = $container.attr('data-section-id');
3044 var wrapper = (this.wrapper = '.producttabs-wrapper__item');
3045 $container.find('.producttabs-wrapper__item').children().each(function(){
3046 var blockid = $(this).attr('data-block-id');
3047 var slider = (this.slider = '#Producttabs-' + blockid);
3048 var $slider = $(slider, wrapper);
3049 config.slideShow = parseInt($slider.attr('data-toshow'));
3050 config.scrollShow = parseInt($slider.attr('data-scroll'));
3051 config.rowNumber = parseInt($slider.attr('data-row'));
3052 var play = $slider.data('play');
3053 var checkplay = $slider.data('autoplay');
3054 var arrows = $slider.data('arrows');
3055 var dot = $slider.data('dot');
3056 var laptop = $slider.data('laptop');
3057 var table = $slider.data('table');
3058 var phonemin = $slider.data('phonemin');
3059
3060 var sliderActive = false;
3061 var mobileOptions = $.extend({}, defaults, {
3062 arrows: arrows,
3063 dots:dot,
3064 slidesToShow: phonemin,
3065 slidesToScroll: phonemin,
3066 adaptiveHeight: true
3067 });
3068 var tableOptions = $.extend({}, defaults, {
3069 arrows: arrows,
3070 dots:dot,
3071 slidesToShow: table,
3072 slidesToScroll: table,
3073 adaptiveHeight: true
3074 });
3075 var desktopOptions = $.extend({}, defaults, {
3076 arrows: arrows,
3077 dots:dot,
3078 slidesToShow: laptop,
3079 slidesToScroll: laptop,
3080 adaptiveHeight: true
3081 });
3082 var desktopOptionsDesk = $.extend({}, defaults, {
3083 arrows: arrows,
3084 dots:dot,
3085 slidesToShow: config.slideShow,
3086 slidesToScroll: config.scrollShow,
3087 rows: config.rowNumber,
3088 adaptiveHeight: true,
3089 autoplay: checkplay,
3090 autoplaySpeed: play
3091 });
3092
3093 enquire.register(config.mediaQuerySmall, {
3094 match: function() {
3095 initSlider($slider, mobileOptions);
3096 }
3097 });
3098 enquire.register(config.mediaQueryMediumUp, {
3099 match: function() {
3100 initSlider($slider, tableOptions);
3101 }
3102 });
3103 enquire.register(config.mediaQueryLarge, {
3104 match: function() {
3105 initSlider($slider, desktopOptions);
3106 }
3107 });
3108 enquire.register(config.mediaQueryLargeDesk, {
3109 match: function() {
3110 initSlider($slider, desktopOptionsDesk);
3111 }
3112 });
3113
3114 function initSlider(sliderObj, args) {
3115 if (sliderActive) {
3116 sliderObj.slick('unslick');
3117 sliderActive = false;
3118 }
3119
3120 sliderObj.slick(args);
3121 sliderActive = true;
3122 }
3123 });
3124 }
3125 return Producttabs;
3126})();
3127
3128//slick Brand
3129theme.Brand = (function() {
3130 var config = {
3131 mediaQuerySmall: 'screen and (max-width: 749px)',
3132 mediaQueryMediumUp: '(min-width: 750px) and (max-width: 991px)',
3133 mediaQueryLarge: '(min-width: 992px) and (max-width: 1199px)',
3134 mediaQueryLargeDesk: 'screen and (min-width: 1200px)',
3135 slideShow: 0,
3136 scrollShow: 0,
3137 rowNumber: 0
3138 };
3139 var defaults = {
3140 accessibility: true,
3141 dots: false,
3142 autoplay: false,
3143 touchThreshold: 20,
3144 slidesToShow: 4,
3145 slidesToScroll: 4,
3146 rtl: checkrtl
3147 };
3148
3149 function Brand(container) {
3150 var $container = (this.$container = $(container));
3151 var sectionId = $container.attr('data-section-id');
3152 var wrapper = (this.wrapper = '.brand-wrapper');
3153 var slider = (this.slider = '#Brand-' + sectionId);
3154 var $slider = $(slider, wrapper);
3155 config.slideShow = parseInt($slider.attr('data-toshow'));
3156 config.scrollShow = parseInt($slider.attr('data-scroll'));
3157 config.rowNumber = parseInt($slider.attr('data-row'));
3158 var play = $slider.data('play');
3159 var checkplay = $slider.data('autoplay');
3160 var arrows = $slider.data('arrows');
3161 var dot = $slider.data('dot');
3162 var laptop = $slider.data('laptop');
3163 var table = $slider.data('table');
3164 var phonemin = $slider.data('phonemin');
3165
3166 var sliderActive = false;
3167 var mobileOptions = $.extend({}, defaults, {
3168 arrows: arrows,
3169 dots:dot,
3170 slidesToShow: phonemin,
3171 slidesToScroll: phonemin,
3172 adaptiveHeight: true
3173 });
3174 var tableOptions = $.extend({}, defaults, {
3175 arrows: arrows,
3176 dots:dot,
3177 slidesToShow: table,
3178 slidesToScroll: table,
3179 adaptiveHeight: true
3180 });
3181 var desktopOptions = $.extend({}, defaults, {
3182 arrows: arrows,
3183 dots:dot,
3184 slidesToShow: laptop,
3185 slidesToScroll: laptop,
3186 adaptiveHeight: true
3187 });
3188 var desktopOptionsDesk = $.extend({}, defaults, {
3189 arrows: arrows,
3190 dots:dot,
3191 slidesToShow: config.slideShow,
3192 slidesToScroll: config.scrollShow,
3193 rows: config.rowNumber,
3194 adaptiveHeight: true,
3195 autoplay: checkplay,
3196 autoplaySpeed: play
3197 });
3198
3199 $slider.on('init', this.a11y.bind(this));
3200
3201 enquire.register(config.mediaQuerySmall, {
3202 match: function() {
3203 initSlider($slider, mobileOptions);
3204 }
3205 });
3206 enquire.register(config.mediaQueryMediumUp, {
3207 match: function() {
3208 initSlider($slider, tableOptions);
3209 }
3210 });
3211 enquire.register(config.mediaQueryLarge, {
3212 match: function() {
3213 initSlider($slider, desktopOptions);
3214 }
3215 });
3216 enquire.register(config.mediaQueryLargeDesk, {
3217 match: function() {
3218 initSlider($slider, desktopOptionsDesk);
3219 }
3220 });
3221
3222 function initSlider(sliderObj, args) {
3223 if (sliderActive) {
3224 sliderObj.slick('unslick');
3225 sliderActive = false;
3226 }
3227
3228 sliderObj.slick(args);
3229 sliderActive = true;
3230 }
3231 }
3232
3233 Brand.prototype = _.assignIn({}, Brand.prototype, {
3234 onUnload: function() {
3235 enquire.unregister(config.mediaQuerySmall);
3236 enquire.unregister(config.mediaQueryMediumUp);
3237 enquire.unregister(config.mediaQueryLarge);
3238 enquire.unregister(config.mediaQueryLargeDesk);
3239 $(this.slider, this.wrapper).slick('unslick');
3240 },
3241
3242 onBlockSelect: function(evt) {
3243 // Ignore the cloned version
3244 var $slide = $(
3245 '.productlists-slide--' + evt.detail.blockId + ':not(.slick-cloned)'
3246 );
3247 var slideIndex = $slide.data('slick-index');
3248
3249 // Go to selected slide, pause autoplay
3250 $(this.slider, this.wrapper).slick('slickGoTo', slideIndex);
3251 },
3252
3253 a11y: function(event, obj) {
3254 var $list = obj.$list;
3255 var $wrapper = $(this.wrapper, this.$container);
3256
3257 // Remove default Slick aria-live attr until slider is focused
3258 $list.removeAttr('aria-live');
3259
3260 // When an element in the slider is focused set aria-live
3261 $wrapper.on('focusin', function(evt) {
3262 if ($wrapper.has(evt.target).length) {
3263 $list.attr('aria-live', 'polite');
3264 }
3265 });
3266
3267 // Remove aria-live
3268 $wrapper.on('focusout', function(evt) {
3269 if ($wrapper.has(evt.target).length) {
3270 $list.removeAttr('aria-live');
3271 }
3272 });
3273 }
3274 });
3275
3276 return Brand;
3277})();
3278
3279//Banner masonry
3280theme.Banner = (function(){
3281// init Isotope
3282 function Banner(container){
3283 var $container = this.$container = $(container);
3284 var sectionId = $container.attr('data-section-id');
3285 var enable_3d = $container.data('enable3d');
3286 var wrapper = this.wrapper = '.banner-wrapper';
3287 var slider = this.slider = '#Banner-' + sectionId;
3288 var project_anim = this.slider = '.project' + sectionId;
3289 var $pro = $(project_anim, wrapper);
3290 var $slider = $(slider, wrapper);
3291 var $grid = $slider.isotope({
3292 itemSelector: '.grid__item',
3293 percentPosition: true,
3294 masonry: {
3295 columnWidth: '.grid-sizer',
3296 isAnimated: true
3297 }
3298 });
3299 // layout Isotope after each image loads
3300 $grid.imagesLoaded().progress( function() {
3301 $grid.isotope('layout');
3302 });
3303 if(enable_3d == true){
3304 $pro.hover3d({
3305 selector: ".project__card",
3306 shine: true,
3307 sensitivity: 32,
3308 });
3309 }
3310 }
3311
3312 return Banner;
3313})();
3314
3315
3316
3317theme.slideshows = {};
3318
3319theme.SlideshowSection = (function() {
3320 function SlideshowSection(container) {
3321 var $container = this.$container = $(container);
3322 var sectionId = $container.attr('data-section-id');
3323 var slideshow = this.slideshow = '#Slideshow-' + sectionId;
3324
3325 $('.slideshow__video', slideshow).each(function() {
3326 var $el = $(this);
3327 theme.SlideshowVideo.init($el);
3328 theme.SlideshowVideo.loadVideo($el.attr('id'));
3329 });
3330
3331 theme.slideshows[slideshow] = new theme.Slideshow(slideshow);
3332 }
3333
3334 return SlideshowSection;
3335})();
3336
3337theme.SlideshowSection.prototype = _.assignIn({}, theme.SlideshowSection.prototype, {
3338 onUnload: function() {
3339 delete theme.slideshows[this.slideshow];
3340 },
3341
3342 onBlockSelect: function(evt) {
3343 var $slideshow = $(this.slideshow);
3344
3345 // Ignore the cloned version
3346 var $slide = $('.slideshow__slide--' + evt.detail.blockId + ':not(.slick-cloned)');
3347 var slideIndex = $slide.data('slick-index');
3348
3349 // Go to selected slide, pause autoplay
3350 $slideshow.slick('slickGoTo', slideIndex).slick('slickPause');
3351 },
3352
3353 onBlockDeselect: function() {
3354 // Resume autoplay
3355 $(this.slideshow).slick('slickPlay');
3356 }
3357});
3358
3359
3360
3361$(document).ready(function() {
3362 var a = new theme.Sections;
3363 a.register("cart-template", theme.Cart),
3364 a.register("product", theme.Product),
3365 a.register("collection-template", theme.Filters),
3366 a.register("product-template", theme.Product),
3367 a.register("header-section", theme.HeaderSection),
3368 a.register("map", theme.Maps),
3369 a.register("slideshow-section", theme.SlideshowSection),
3370 a.register("quotes", theme.Quotes),
3371 a.register("look", theme.Look),
3372 a.register("lookhome", theme.Lookhome),
3373 a.register("list", theme.List),
3374 a.register("blogs", theme.Blogs),
3375 a.register('productlists', theme.Productlists),
3376 a.register('producttabs', theme.Producttabs),
3377 a.register('brand', theme.Brand),
3378 a.register('look2', theme.Look2),
3379 a.register('banner', theme.Banner)
3380
3381});
3382theme.init = function() {
3383 theme.customerTemplates.init(), slate.rte.wrapTable(), slate.rte.iframeReset(), slate.a11y.pageLinkFocus($(window.location.hash)), $(".in-page-link").on("click", function(a) {
3384 slate.a11y.pageLinkFocus($(a.currentTarget.hash))
3385 }), $('a[href="#"]').on("click", function(a) {
3386 a.preventDefault()
3387 })
3388};
3389
3390
3391