1/* 2 * ************************* 3 * SITE JS 4 * REQUIRES: lib/js/jquery-3.1.1.min.js 5 * lib/js/jquery.easing.1.3.min.js 6 * ************************* 7*/ 8 9//Polyfill for URLSearchParams on IE. 10(function (w) { 11 12 w.URLSearchParams = w.URLSearchParams || function (searchString) { 13 var self = this; 14 self.searchString = searchString; 15 self.get = function (name) { 16 var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString); 17 if (results == null) { 18 return null; 19 } 20 else { 21 return decodeURI(results[1]) || 0; 22 } 23 }; 24 } 25 26})(window) 27 28jQuery(document).ready(function($) { 29 /* 30 * ************************* 31 * GET QUERYSTRING PARAMETER 32 * ************************* 33 */ 34 35 function getQueryStringParameterByName(name) { 36 name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); 37 var regexS = "[\\?&]" + name + "=([^&#]*)"; 38 var regex = new RegExp(regexS); 39 var results = regex.exec(window.location.search); 40 41 if (results == null) { 42 return ""; 43 } else { 44 return decodeURIComponent(results[1].replace(/\+/g, " ")); 45 } 46 } 47 48 var hash = '#section-' + window.location.hash.replace('#',''); 49 50 function pauseVideos() { 51 $("iframe").each(function() { 52 $(this)[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*') 53 }); 54 } 55 56 /* 57 * ************************* 58 * MAIN NAVIGATION 59 * ************************* 60 */ 61 62 $('#main-nav > li, #top-nav > li.follow').hoverIntent(function() { 63 if ($('#navicon').css('display') == 'none') { 64 $(this).children('a').toggleClass('hover'); 65 $(this).children('.dropdown').slideDown(600, 'easeOutExpo'); 66 } 67 }, function() { 68 if ($('#navicon').css('display') == 'none') { 69 $(this).children('a').toggleClass('hover'); 70 $(this).children('.dropdown').slideUp(400, 'easeOutExpo', function () { 71 $(this).css('display',''); 72 }); 73 } 74 }); 75 $('#top-nav > li.follow > a').click(function(e) { 76 e.preventDefault(); 77 }); 78 79 /* 80 * ************************* 81 * MAIN NAVIGATION (MOBILE) 82 * ************************* 83 */ 84 85 $('#main-nav > li > a').click(function (e) { 86 var $t = $(this); 87 var $parent = $t.parent(); 88 89 if ($('#navicon').css('display') != 'none' && $parent.find('.dropdown').length) { 90 if ($parent.hasClass('dropdown-mobile-open')) { 91 $parent.children('.dropdown').slideUp(400, 'easeOutExpo', function () { 92 $t.removeClass('mobile-active'); 93 $parent.removeClass('dropdown-mobile-open'); 94 }); 95 } else { 96 $t.addClass('mobile-active'); 97 $parent.children('.dropdown').slideDown(600, 'easeOutExpo', function () { 98 $parent.addClass('dropdown-mobile-open'); 99 $(this).css('display',''); 100 }); 101 } 102 e.preventDefault(); 103 } 104 }); 105 106 $(window).click(function () { 107 $('#searchicon.open').trigger('click'); 108 $('#navicon.open').trigger('click'); 109 $('#top-nav li.search > a.open').trigger('click'); 110 }); 111 112 $('#header, #navicon, #searchicon').click(function (e) { 113 /* stop event from bubbling up to the window (a window click event is used to close any open menu on click) */ 114 e.stopPropagation(); 115 }); 116 117 /* 118 * ************************* 119 * NAVICON 120 * ************************* 121 */ 122 123 $('#navicon').click(function (e) { 124 if (!$(this).hasClass('animating')) { 125 var $t = $(this); 126 $t.addClass('animating'); 127 $t.toggleClass('open'); 128 129 $('#searchicon.open').trigger('click'); 130 131 $('#nav-wrapper').slideToggle(600, 'easeOutExpo', function () { 132 if ($(this).css('display') == 'none') { 133 $(this).css('display', ''); 134 135 // CLOSE OPEN SUB-MENUS WHEN MAIN MENU IS COLLAPSED 136 $('#main-nav > li.dropdown-mobile-open > a').trigger('click'); 137 } 138 $t.toggleClass('animating'); 139 }); 140 } 141 e.preventDefault(); 142 }); 143 144 /* 145 * ************************* 146 * FIXED HEADER 147 * ************************* 148 */ 149 150 function check_if_in_view() { 151 /* show/hide back to top button */ 152 if ($(window).scrollTop() > 125 && $('#navicon').css('display') == 'none') { 153 $('body').addClass('small-header'); 154 $('#top-of-page-wrapper').fadeIn(300); 155 } else if ($(window).scrollTop() <= 125 && $('#navicon').css('display') == 'none') { 156 $('#top-of-page-wrapper').fadeOut(300);
157 $('body').removeClass('small-header'); 158 } 159 } 160 check_if_in_view(); 161 162 $(window).bind('scroll resize', check_if_in_view); 163 164 /* 165 * ************************* 166 * BACK TO TOP 167 * ************************* 168 */ 169 170 $('#top-of-page-wrapper').click(function () { 171 $('html,body').stop().animate({scrollTop: 0 }, 1500, 'easeOutExpo'); 172 }); 173 174 /* 175 * ************************* 176 * SEARCH BUTTON 177 * ************************* 178 */ 179 180 $('#top-nav li.search > a, #searchicon').click(function (e) { 181 var $t = $(this); 182 183 $('#navicon.open').trigger('click'); 184 185 if ($t.hasClass('open')) { 186 $('#header-search-form').find('.sf-input-text').blur(); 187 $('#header').removeClass('search-form-expanded'); 188 $t.removeClass('open').find('.icon').toggleClass('icon-times-circle icon-search'); 189 } else { 190 $t.addClass('open').find('.icon').toggleClass('icon-times-circle icon-search'); 191 $('#header').addClass('search-form-expanded'); 192 $('#header-search-form').find('.sf-input-text').focus(); 193 } 194 e.preventDefault(); 195 }); 196 197 /* 198 * ************************* 199 * LAZY LOAD IMAGES AND BACKGROUND IMAGES 200 * REQUIRES: lib/js/jquery.lazy.min.js 201 * ************************* 202 */ 203 204 $('.lazy').lazy(); 205 206 /* 207 * ************************* 208 * HOME PAGE CAROUSEL 209 * REQUIRES: lib/js/slick.min.js 210 * ************************* 211 */ 212
213 var $homeCarousel = $('#home-carousel'); 214 215 $homeCarousel.on('init', function (event, slick) { 216 var $slide = $(slick.$slides[0]); 217 var $video = $slide.find('.video-wrapper video'); 218 219 if ($video.length) { 220 /* workaround: video does not play in Chrome */ 221 $video.get(0).play(); 222 } 223 }); 224 225 $homeCarousel.slick({ 226 arrows: true, 227 autoplay: true, 228 autoplaySpeed: 8000, 229 draggable: false, 230 dots: false, 231 lazyLoad: 'ondemand', 232 slidesToShow: 1, 233 slidesToScroll: 1, 234 speed: 800 235 }); 236 237 /* 238 * ************************* 239 * RECIPE PAGE CAROUSELS 240 * REQUIRES: lib/js/slick.min.js 241 * ************************* 242 */ 243 244 $('#recipe-carousel').slick({ 245 arrows: true, 246 autoplay: false, 247 draggable: true, 248 dots: true, 249 lazyLoad: 'ondemand', 250 slidesToShow: 1, 251 slidesToScroll: 1 252 }); 253 $('#recipe-carousel').on('beforeChange', function(event, slick, currentSlide, nextSlide) { 254 pauseVideos(); 255 }); 256 $('#recipe-carousel').on('afterChange', function(event, slick, currentSlide, nextSlide) { 257 pauseVideos(); 258 259 /* reset video that has been loaded from YouTube (to circumvent flicker of cloned item in carousel that never loaded the video) */ 260 $.each($(this).find('.iframe-wrapper.video-loaded'), function(idx, val) { 261 var markup = ''; 262 markup += '<a href="' + $(this).attr('data-url') + '" target="_blank" class="ytframeloader">'; 263 markup += '<img src="' + $(this).attr('data-src') + '" alt="Video Poster" width="580" height="435">'; 264 markup += '<span class="icon icon-youtube-play"></span>'; 265 markup += '</a>'; 266 267 $(this).removeClass('video-loaded').html(markup); 268 }); 269 }); 270 271 $('.product-used-slideshow').slick({ 272 arrows: true, 273 autoplay: false, 274 draggable: true, 275 dots: true, 276 lazyLoad: 'ondemand', 277 slidesToShow: 1, 278 slidesToScroll: 1 279 }); 280 281 /* 282 * ************************* 283 * PRODUCT PAGE CAROUSELS 284 * REQUIRES: lib/js/slick.min.js 285 * ************************* 286 */ 287 288 $('#product-carousel').slick({ 289 arrows: true, 290 autoplay: false, 291 draggable: true, 292 dots: true, 293 lazyLoad: 'ondemand', 294 slidesToShow: 1, 295 slidesToScroll: 1 296 }); 297 298 /* 299 * ************************* 300 * NUTRTIION INFO - EXPAND/COLLAPSE 301 * ************************* 302 */ 303 304 $('.nutrition-info a').click(function (e) { 305 if (!$(this).hasClass('animating')) { 306 var $t = $(this) 307 308 $t.addClass('animating').toggleClass('open'); 309 310 if ($t.hasClass('open')) { 311 $t.attr('title','Hide Nutrition Information').children('.icon').addClass('icon-minus-circle').removeClass('icon-plus-circle'); 312 } else { 313 $t.attr('title','View Nutrition Information').children('.icon').addClass('icon-plus-circle').removeClass('icon-minus-circle'); 314 } 315 316 $t.parent().next().slideToggle(600, 'easeOutExpo', function () { 317 $t.toggleClass('animating'); 318 }); 319 } 320 e.preventDefault(); 321 }); 322 323 /* 324 * ************************* 325 * MODULE - EXPAND/COLLAPSE 326 * ************************* 327 */ 328 329 $('.ec-title a').click(function (e) { 330 if (!$(this).hasClass('animating')) { 331 var $t = $(this); 332 var val = 'Expand'; 333 var $ecDetailsDiv = $t.parent().next(); 334 335 $t.toggleClass('open').addClass('animating'); 336 337 if ($t.hasClass('open')) { 338 $t.attr('title','Hide Details').children('.icon-angle-down').addClass('icon-angle-up').removeClass('icon-angle-down'); 339 } else { 340 $t.attr('title','Show Details').children('.icon-angle-up').addClass('icon-angle-down').removeClass('icon-angle-up'); 341 val = 'Collapse'; 342 } 343 344 $ecDetailsDiv.slideToggle(400, 'easeOutExpo', function () { 345 $t.toggleClass('animating'); 346 }); 347 } 348 e.preventDefault(); 349 }); 350 351 /* 352 * ************************* 353 * MODULE - IMAGE SLIDESHOW 354 * REQUIRES: lib/js/slick.min.js 355 * ************************* 356 */ 357 358 if ($('.module-image-slideshow').length) { 359 $('.slideshow-image').slick({ 360 arrows: true, 361 asNavFor: '.slideshow-nav', 362 dots: false, 363 fade: false, 364 lazyLoad: 'ondemand', 365 slidesToShow: 1, 366 slidesToScroll: 1 367 }); 368 $('.slideshow-nav').slick({ 369 arrows: true, 370 asNavFor: '.slideshow-image', 371 dots: false, 372 focusOnSelect: true, 373 infinite: true, 374 lazyLoad: 'ondemand', 375 responsive: [ 376 { 377 breakpoint: 980, 378 settings: { 379 slidesToShow: 3 380 } 381 } 382 ], 383 slidesToShow: 4, 384 slidesToScroll: 1, 385 swipe: false 386 }); 387 } 388 389 /* 390 * ************************* 391 * POP STATE 392 * ************************* 393 */ 394 395 if (window.history && history.pushState) { 396 $(window).bind('popstate', function (e) { 397 showTabContent(); 398 }); 399 } 400 401 /* 402 * ************************* 403 * TAB CONTENT 404 * ************************* 405 */ 406 407 $('.product-category-filter-list a').click(function (e, skipPushState) { 408 if (!$(this).hasClass('active')) { 409 $('.product-category-filter-list a').removeClass('active'); 410 $('.tab-content').removeClass('tab-active'); 411 412 $(this).addClass('active'); 413 $('.tab-content:eq(' + $(this).index() + ')').addClass('tab-active'); 414 415 // load lazy images 416 $('.tab-content:eq(' + $(this).index() + ') .tablazy').lazy(); 417 418 // skip push state when history was popped 419 if (!skipPushState) { 420 history.pushState("", document.title, window.location.pathname + '?tab=' + $(this).attr('href').split('?tab=')[1]); 421 } 422 } 423 e.preventDefault(); 424 }); 425 426 $(window).on('load', function(event) { 427 showTabContent(); 428 }); 429 430 function showTabContent() { 431 // Pass 2nd parameter to skip push state when history was popped, see: http://api.jquery.com/trigger/ 432 $('.product-category-filter-list a[href="?tab=' + getQueryStringParameterByName('tab') + '"]').trigger('click', [true]); 433 } 434 435 /* 436 * ************************* 437 * SCROLL TO SPECIFIC LOCATION ON PAGE 438 * USING ANCHOR SUCH AS #foo BUT THERE IS NO DOM OBJECT W/ AN ID OF "foo", THIS WAY WE CAN USE THE ANIMATION EFFECT 439 * #foo BECOMES #section-foo 440 * ************************* 441 */ 442 443 function goToByScroll(id, speed) { 444 var offset = ($('#navicon').css('display') != 'none') ? 0 : 190; 445 446 $('html,body').stop().animate( { scrollTop: $(id).offset().top-offset }, speed, 'easeOutExpo'); 447 } 448 function jumpToAnchor(href) { 449 var hash = (href != undefined) ? href : window.location.hash.replace('#',''); 450 451 if (hash != '') { 452 if ($('#section-' + hash).length) { 453 $('#section-' + hash + ' .ec-title a').trigger('click'); 454 455 goToByScroll('#section-' + hash, 1200); 456 } 457 } 458 } 459 /* 460 * ************************* 461 * SCROLL TO HASH ID LOCATION ON PAGE LOAD 462 * ************************* 463 */ 464 465 $(window).on('hashchange', function() { 466 jumpToAnchor(); 467 }).trigger('hashchange'); 468 469 /* 470 * ************************* 471 * RATE AND REVIEW ANCHOR 472 * ************************* 473 */ 474 475 $('a#rate-and-review-link').click(function (e) { 476 goToByScroll('#section-rate-and-review', 1200); 477 }); 478 479 /* 480 * ************************* 481 * SOCIAL MEDIA LINKS 482 * ************************* 483 */ 484 485 function popupCenter(url, title, w, h) { 486 var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; 487 var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; 488 489 var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; 490 var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; 491 492 var left = Math.round( ((width / 2) - (w / 2)) + dualScreenLeft ); 493 var top = Math.round( ((height / 3) - (h / 3)) + dualScreenTop ); 494 495 var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top='
495+ top + ', left=' + left); 496 497 if (window.focus) { 498 newWindow.focus(); 499 } 500 }; 501 502 $('.share-recipe-list a.social').click(function (e) { 503 if ($('#navicon').css('display') == 'none') { 504 popupCenter($(this).attr('href'), 'share', $(this).attr('data-width'), $(this).attr('data-height')); 505 e.preventDefault(); 506 } 507 }); 508 509 /* 510 * ************************* 511 * PRINT 512 * ************************* 513 */ 514 515 $('.print-recipe > a').click(function (e) { 516 window.print(); 517 e.preventDefault(); 518 }); 519 520 /* 521 * ************************* 522 * RECIPE FILTERS 523 * ************************* 524 */ 525 526 $('.filter-category a').click(function (e) { 527 if (!$(this).hasClass('animating')) { 528 var $t = $(this).toggleClass('closed'); 529 530 if ($t.hasClass('closed')) { 531 $t.attr('title','View Options').children('.icon').addClass('icon-plus-circle').removeClass('icon-minus-circle'); 532 } else { 533 $t.attr('title','Hide Options').children('.icon').addClass('icon-minus-circle').removeClass('icon-plus-circle'); 534 } 535 536 $(this).addClass('animating'); 537 $(this).parent().next().slideToggle(400, 'easeOutQuad', function () { 538 $t.toggleClass('animating'); 539 }); 540 } 541 e.preventDefault(); 542 }); 543 544 $('#refine-recipe-filters .txt').click(function (e) { 545 if ($('#navicon').css('display') != 'none') { 546 $(this).children('.icon').toggleClass('icon-minus-circle icon-plus-circle'); 547 548 $('.filter-category a').not('.closed').addClass('closed').attr('title','View Options').children('.icon').addClass('icon-plus-circle').removeClass('icon-minus-circle'); 549 $('.filter-category-options').hide(); 550 551 $('.recipe-filters-wrapper').slideToggle(400, 'easeOutQuad'); 552 } 553 }); 554 555 $('#recipe-filters-form').submit(function (e) { 556 var query = ''; 557 558 var desserttypes = $('input.ckbx-desserttype:checked').map(function() { 559 return this.value; 560 }).get(); 561 var dishtypes = $('input.ckbx-dishtype:checked').map(function() { 562 return this.value; 563 }).get(); 564 var occasions = $('input.ckbx-occasion:checked').map(function() { 565 return this.value; 566 }).get(); 567 var fruitflavors = $('input.ckbx-fruitflavors:checked').map(function() { 568 return this.value; 569 }).get(); 570 var productcategories = $('#product_used').val(); 571 var video = $('input.ckbx-video:checked').val(); 572 573 if (desserttypes.length > 0) { 574 query += '&desserttype=' + desserttypes.join(); 575 } 576 if (dishtypes.length > 0) { 577 query += '&dishtype=' + dishtypes.join(); 578 } 579 if (occasions.length > 0) { 580 query += '&occasion=' + occasions.join(); 581 } 582 if (fruitflavors.length > 0) { 583 query += '&fruitflavors=' + fruitflavors.join(); 584 } 585 if (productcategories.length != '') { 586 query += '&productcategories=' + productcategories; 587 } 588 if (video) { 589 query += '&video=1'; 590 } 591 if (query != '') { 592 query = query.replace('&', '?'); 593 } 594 595 window.location = '/recipes/'+ query; 596 597 e.preventDefault(); 598 }); 599 600 $('#sortby').change(function() { 601 if ($(this).val() != '') { 602 window.location = $(this).val(); 603 } 604 }); 605 606 $('.tooltip').hover(function() { 607 $(this).find('.tooltip-text').remove(); 608 $('<div class="tooltip-text">' + $(this).attr('data-title') + '</div>').insertAfter($(this).find('.icon-wrapper')) 609 }, function() { 610 $(this).find('.tooltip-text').remove(); 611 }); 612 613 /* 614 * ************************* 615 * OFFERS PROMOTIONAL TRACKING BRUNNER REQUEST. 616 * ************************* 617 */ 618 $('li.promo > a').on('click',function(event){ 619 620 var entryName = $(this).children('.recipe-title').text().trim(); 621 622 var cleanName = entryName.replace(/â/,''); 623 624 window.dataLayer.push({'event': 'onClickEvent','eventCategory': 'Offers&Promos','eventAction': 'Coupons','eventLabel': cleanName}); 625 626 }); 627 628 $('.promo-wrapper a.btn').on('click',function(event){ 629 630 631 var entryName = $(this).closest('.copy').children('h2').text().trim(); 632 633 var cleanName = entryName.replace(/â/,''); 634 635 window.dataLayer.push({'event': 'onClickEvent','eventCategory': 'Offers&Promos','eventAction': 'Coupons','eventLabel': cleanName}); 636 637 }); 638 639 /* 640 * ************************* 641 * IF THERE IS A HASH, LET'S ANIMATE TO THAT SECTION (IF IT EXISTS) 642 * ************************* 643 */ 644 645 if ($(hash).length) { 646 goToByScroll(hash, 1200); 647 } 648 649 /* 650 * *************************
651 * YOUTUBE IFRAME LOADER 652 * ************************* 653 */ 654 655 $('body').on('click', '.ytframeloader', function (e) { 656 pauseVideos(); 657 $(this).parent().addClass('video-loaded').attr({ 'data-url': $(this).prop('href'), 'data-src': $(this).find('.video-poster').attr('src') }); 658 $(this).replaceWith('<iframe width="560" height="315" src="' + $(this).prop('href') + '" allowfullscreen></iframe>'); 659 e.preventDefault(); 660 }); 661 662});
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.