1jQuery(function($) { 2 3 // Mobile sidebars 4 $.fn.expandableSidebar = function(expandedClass) { 5 var $me = this; 6 7 $me.on('click', function() { 8 if(!$me.hasClass(expandedClass)) { 9 $me.addClass(expandedClass); 10 } else { 11 $me.removeClass(expandedClass); 12 } 13 }); 14 } 15 16 // Interval loop 17 $.fn.intervalLoop = function(condition, action, duration, limit) { 18 var counter = 0; 19 var looper = setInterval(function(){ 20 if (counter >= limit || $.fn.checkIfElementExists(condition)) { 21 clearInterval(looper); 22 } else { 23 action(); 24 counter++; 25 } 26 }, duration); 27 28 if (!condition) action(); 29 } 30 31 // Check if element exists 32 $.fn.checkIfElementExists = function(selector) { 33 return $(selector).length; 34 } 35 36 $.fn.hideDropdowns = function(dropdownClass) { 37 this 38 .removeClass(dropdownClass) 39 .find('.wsite-menu-wrap') 40 .revealer('hide') 41 .find('.' + dropdownClass) 42 .removeClass(dropdownClass); 43 44 return this; 45 } 46 47 var edisonController = { 48 init: function(opts) { 49 var base = this; 50 51 base._addClasses(); 52 base._headerSetup(); 53 54 $(window).on('resize', function() { 55 base._headerSetup(); 56 }); 57 58 base._moveUtils(); 59 base._navSetup(); 60 base._searchBox(); 61 base._miniCartSetup(); 62 base._productSetup(); 63 base._attachEvents(); 64 }, 65 66 _breakpoints: { 67 small: 768, 68 }, 69 70 _utils: { 71 onEscKey: function(callback) { 72 $(document).on('keyup', function(event) { 73 if (event.keyCode === 27) callback(); 74 }); 75 }, 76 onScrollDirection: function(Direction) { 77 var previousScrollTop = 0, 78 deltaThreshold = 5; 79 80 $(window).scroll(function() { 81 var currentScrollTop = $(this).scrollTop(); 82 83 //return if scroll hasn't met delta threshold 84 if (Math.abs(previousScrollTop - currentScrollTop) <= deltaThreshold) { 85 return; 86 } 87 88 //direction conditions 89 if (currentScrollTop > previousScrollTop){ 90 Direction.down(currentScrollTop); 91 } else { 92 Direction.up(currentScrollTop); 93 } 94 95 previousScrollTop = currentScrollTop; 96 }); 97 }, 98 }, 99 100 _addClasses: function() { 101 var base = this; 102 103 $(document.body).addClass('reveal-content'); 104 105 // Keep subnav open if submenu item is active 106 $('li.wsite-menu-subitem-wrap.wsite-nav-current').parents('.wsite-menu-wrap').addClass('open'); 107 108 // Add placeholder text to inputs 109 $('.wsite-form-sublabel').each(function(){ 110 var sublabel = $(this).text(); 111 $(this).prev('.wsite-form-input').attr('placeholder', sublabel); 112 }); 113 114 // Add fullwidth class to gallery thumbs if less than 6 115 $('.imageGallery').each(function(){ 116 if ($(this).children('div').length <= 6) { 117 $(this).children('div').addClass('fullwidth-mobile'); 118 } 119 }); 120 }, 121 122 _headerSetup: function() { 123 var base = this; 124 var $body = $(document.body); 125 var $header = $('.edison-header'); 126 var headerHeight; 127 128 // Wait for redraw to happen after appending 129 base._detectHeaderWrap(); 130 headerHeight = $header.outerHeight(); 131 132 if ($body.hasClass('header-sticky-up')) { 133 base._utils.onScrollDirection({ 134 down: function(currentScrollTop) { 135 $header 136 .removeClass('is-visible') 137 .toggleClass('is-sticky', (currentScrollTop > headerHeight * 2)); 138 139 base._closeAllDropdowns(); 140 }, 141 up: function() { 142 $header.addClass('is-visible'); 143 }, 144 }); 145 } 146 147 if ($body.hasClass('header-sticky')) { 148 $(window).on('scroll', function() { 149 $body.toggleClass('header-compressed', $(this).scrollTop() > headerHeight * 2); 150 }); 151 } 152 }, 153 154 _detectHeaderWrap: function() { 155 var headerHeight = $('.edison-header').outerHeight(); 156 157 $('body').toggleClass('header-multiline', (headerHeight > 100)); 158 159 // No logo 160 if ($('.wsite-logo').children('.wsite-title-placeholder').length) { 161 $('body').addClass('logo-hidden'); 162 } 163 164 // No Utils 165 166 $.fn.intervalLoop('', function() { 167 if ((!$('.wsite-search').length || $('.wsite-search').attr('style') === 'display: none;') && !$('#wsite-nav-cart-a').text().length) { 168 $('body').addClass('utils-hidden'); 169 } 170 else { 171 $('body').removeClass('utils-hidden'); 172 } 173 174 if ($('#wsite-nav-cart-a').length) { 175 var cartText = $('#wsite-nav-cart-a').html().replace(/["'()]/g,""); 176 $('#wsite-nav-cart-a').html(cartText).addClass("toggle-custom"); 177 } 178 179 if ($('.header-sticky:not(.header-compressed)').length || $('body').hasClass('header-sticky-up')) { 180 headerHeight = $('.edison-header').outerHeight(); 181 $('body').css({ paddingTop: headerHeight }); 182 } 183 }, 500, 8); 184 }, 185 186 _moveUtils: function() { 187 var base = this; 188 var winWidth = window.innerWidth; 189 var $login = $('#member-login'); 190 var $search = $('.wsite-search-wrap'); 191 var search = $("#wsite-header-search-form input").clone(false); 192 193 if (winWidth >= base._breakpoints.small) { 194 $login.appendTo('.desktop-nav .wsite-menu-default'); 195 $search.prependTo('.site-utils'); 196 } else { 197 $login.appendTo('.mobile-nav .wsite-menu-default'); 198 $search.prependTo('.mobile-nav'); 199 $('.wsite-search').show(); 200 } 201 202 base._observeDom($('.dummy-menu')[0], function(observer, target, config, mutation) { 203 // Remove the duplicate login link after it is added 204 if (mutation.addedNodes[0] === undefined || mutation.addedNodes[0].id !== 'member-login') return; 205 $('.dummy-menu #member-login').remove(); 206 }, { subtree: true }); 207 }, 208 209 _navSetup: function() { 210 var base = this; 211 var $submenuContainer = $('.nav .has-submenu'); 212 var dropdownClass = 'dropdown-open'; 213 var $desktopNav = $('.desktop-nav .wsite-menu-default'); 214 215 var bindNavEvents = function() { 216 $('.nav .has-submenu').each(function() { 217 $(this) 218 .off('click') 219 .children('a') 220 .off('click') 221 .on('click.edison', function(event) { 222 // Toggle submenu 223 $(this) 224 .parent() 225 .toggleClass(dropdownClass) 226 .children('.wsite-menu-wrap') 227 .revealer('toggle'); 228 229 // Hide children of other main nav items on desktop 230 if (!$('.hamburger').is(':visible')) { 231 $(this) 232 .closest('li') 233 .siblings('.has-submenu') 234 .hideDropdowns(dropdownClass); 235 } 236 237 return false;
238 }); 239 }); 240 241 $('.cloned-link > a').off('click.edison'); 242 } 243 244 if (typeof DISABLE_NAV_MORE == 'undefined' || !DISABLE_NAV_MORE) { 245 $desktopNav.pxuMenu({ 246 moreLinkHtml: 'More ', 247 }); 248 $.fn.intervalLoop('', function() { 249 if ($desktopNav.data('pxuMenu')) { 250 $desktopNav.data('pxuMenu').update(); 251 bindNavEvents(); 252 } 253 }, 500, 5); 254 } 255 256 bindNavEvents(); 257 // Unbind / bind after defaults have run 258 base._observeDom($('.wsite-menu-default')[0], function() { 259 bindNavEvents(); 260 }, { subtree: true }); 261 262 // Clone parent links into subnav 263 $submenuContainer.each(function() { 264 var $link = $(this).children('a'); 265 266 if ($link.attr('href') === undefined || $link.hasClass('dead-link')) return; 267 268 $link 269 .parent() 270 .clone() 271 .removeClass('has-submenu wsite-menu-item-wrap') 272 .addClass('wsite-menu-subitem-wrap cloned-link') 273 .children('a') 274 .removeClass('wsite-menu-item') 275 .addClass('wsite-menu-subitem') 276 .parent() 277 .prependTo($link.next('.wsite-menu-wrap').children('.wsite-menu')); 278 279 $('.cloned-link').find('.wsite-menu-wrap').remove(); 280 }); 281 282 // Close dropdowns if clicking outside nav 283 $(document).on('click', function(event) { 284 if ($(event.target).closest('.nav-wrap').length) { 285 event.stopPropagation(); 286 } else { 287 base._closeAllDropdowns(); 288 } 289 }); 290 291 // Close dropdowns on esc 292 base._utils.onEscKey(function() { 293 if (!$('.dropdown-open').length) return; 294 base._closeAllDropdowns(); 295 }); 296 }, 297 298 _closeAllDropdowns: function() { 299 $('.edison-header') 300 .find('.dropdown-open') 301 .hideDropdowns('dropdown-open'); 302 }, 303 304 _searchBox: function() { 305 var base = this; 306 var searchBox = '.wsite-search'; // Not available in editor on doc ready 307 var $searchToggle = $('.search-toggle'); 308 var searchPosition = $searchToggle.outerHeight() + $searchToggle.offset().top; 309 var searchText = $(".wsite-search-input").attr("placeholder"); 310 var winWidth = window.innerWidth; 311 $("#icontent .wsite-search").attr('data-search-text', searchText); 312 $searchToggle.text(searchText); 313 314 if (winWidth >= base._breakpoints.small) { 315 // Make sure the editor also gets the class 316 $.fn.intervalLoop('', function() { 317 if ($('.wsite-search').attr('style') === 'display: none;') return; 318 $('body').toggleClass('has-site-search', !!$('.wsite-search').length); 319 }, 800, 5); 320 321 $(searchBox) 322 .css({top: searchPosition}) 323 .on('revealer-show', function() { 324 $(searchBox).find('.wsite-search-input').focus(); 325 }) 326 .find('.wsite-search-input') 327 .attr('placeholder', $(".wsite-search-input").attr("placeholder")) 328 .on('blur', function() { 329 setTimeout(function() { 330 $(searchBox).revealer('hide'); 331 }, 300); 332 }); 333 334 base._utils.onEscKey(function() { 335 if ($(searchBox).revealer('isVisible')) { 336 $(searchBox).revealer('hide'); 337 } 338 }); 339 340 $searchToggle.on('click', function(event) { 341 event.preventDefault(); 342 $(searchBox).revealer('toggle'); 343 }); 344 } 345 }, 346 347 _miniCartSetup: function() { 348 var base = this; 349 var $minicart = $('#wsite-mini-cart'); 350 var cartOpenClass = 'mini-cart-open'; 351 var toggleMiniCart = function(state) { 352 var revealerState = state ? 'show' : 'hide'; 353 $('body').toggleClass(cartOpenClass, state); 354 $('.mini-cart-overlay').revealer(revealerState); 355 }; 356 var hijackMinicart = function() { 357 var toggleText = $('#wsite-nav-cart-a').html().replace(/["'()]/g,""); 358 359 $('#wsite-nav-cart-a') 360 .html(toggleText) 361 .off('click mouseenter mouseover mouseleave mouseout'); 362 363 $('#wsite-mini-cart') 364 .off('mouseenter mouseover mouseleave mouseout') 365 .removeClass('arrow-top') 366 .removeAttr('style') 367 .prepend($('.mini-cart-header')); 368
369 $('.mini-cart-toggle').toggleClass('has-mini-cart', !!$('.mini-cart-toggle').children().length); 370 371 // Update responsive menu since site-utils dimesions will change 372 if (typeof DISABLE_NAV_MORE == 'undefined' || !DISABLE_NAV_MORE) { 373 $('.desktop-nav .wsite-menu-default').data('pxuMenu').update(); 374 } 375 }; 376 var hijackMinicartToggle = function() { 377 var $toggle = $('#wsite-nav-cart-a'); 378 var toggleText = $toggle.html().replace(/["'()]/g,""); 379 var itemCount = parseInt($('#wsite-nav-cart-num').text(), 10); 380 var hasItems = isNaN(itemCount) || itemCount === 0 ? false : true; 381 382 $toggle 383 .html(toggleText) 384 .addClass('toggle-custom') 385 .off('click mouseenter mouseover mouseleave mouseout'); 386 387 setTimeout(function() { 388 $toggle.toggleClass('has-items', hasItems); 389 }, 100); 390 }; 391 392 $(document).on('click', '.wsite-nav-cart', function() { 393 toggleMiniCart(true); 394 }); 395 396 $(document).on('click', '.button-mini-cart-close, .mini-cart-overlay', function() { 397 toggleMiniCart(false); 398 }); 399 400 base._utils.onEscKey(function() { 401 if ($('body').hasClass(cartOpenClass)) { 402 toggleMiniCart(false); 403 } 404 }); 405 406 // Watch for minicart 407 base._observeDom(document, function(docObserver, target, config) { 408 // Bail if minicart not available yet 409 if (!$('#wsite-mini-cart').length || !$('#wsite-nav-cart-a').length) return; 410 411 // Watch minicart 412 base._observeDom($('#wsite-mini-cart')[0], function(observer, target, config) { 413 // Disconnect before making changes 414 observer.disconnect(); 415 416 // Unbind default handlers etc. 417 hijackMinicart(); 418 419 // Start watching again (for add / remove of items etc.) 420 observer.observe(target, config); 421 }); 422 423 // Watch toggle for childList changes (ie. when the text changes) 424 base._observeDom($('#wsite-nav-cart-a')[0], function(observer, target, config, mutation) { 425 observer.disconnect(); 426 hijackMinicartToggle(); 427 observer.observe(target, config); 428 }, { attributes: false, characterData: false }); 429 430 // $minicart available, so stop watching the doc 431 docObserver.disconnect(); 432 }, { subtree: true }); 433 }, 434 435 _productSetup: function() { 436 $('.product-grid-layout--above, .product-grid-layout--below').find('.product-grid__item').each(function() { 437 var $product = $(this); 438 $product.find('.product-grid__button').prependTo($product.find('.product-grid__images')); 439 }); 440 }, 441 442 _attachEvents: function() { 443 var base = this; 444 445 // Nav toggle 446 $('.hamburger').on('click', function() { 447 $('body').toggleClass('nav-open'); 448 $('.mobile-nav').revealer('toggle'); 449 }); 450 451 // Store category dropdown 452 $('.wsite-com-sidebar').expandableSidebar('sidebar-expanded'); 453 454 // Search filters dropdown 455 $('#wsite-search-sidebar').expandableSidebar('sidebar-expanded'); 456 457 // Init fancybox swipe on mobile 458 if ('ontouchstart' in window) { 459 $('body').on('click', 'a.w-fancybox', function() { 460 base._initSwipeGallery(); 461 }); 462 } 463 }, 464 465 _initSwipeGallery: function() { 466 var base = this; 467 468 setTimeout(function(){ 469 var touchGallery = document.getElementsByClassName('fancybox-wrap')[0]; 470 var mc = new Hammer(touchGallery); 471 mc.on("panleft panright", function(ev) { 472 if (ev.type == "panleft") { 473 $("a.fancybox-next").trigger("click"); 474 } else if (ev.type == "panright") { 475 $("a.fancybox-prev").trigger("click"); 476 } 477 base._initSwipeGallery(); 478 }); 479 }, 500); 480 }, 481 482 _observeDom: function(target, callback, config) { 483 var config = $.extend({ 484 attributes: true, 485 childList: true, 486 characterData: true 487 }, config); 488 489 // create an observer instance & callback 490 var observer = new MutationObserver(function(mutations) {
491 // Using every() instead of forEach() allows us to short-circuit the observer in the callback 492 mutations.every(function(mutation) { 493 callback(observer, target, config, mutation); 494 }); 495 }); 496 497 // pass in the target node, as well as the observer options 498 observer.observe(target, config); 499 } 500 } 501 502 $(document).ready(function(){ 503 edisonController.init(); 504 }); 505 506});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.