1jQuery(document).ready(function($){ 2 3 var isCartPage = xoo_wsc_params.isCart == '1', 4 isCheckoutPage = xoo_wsc_params.isCheckout == '1'; 5 6 7 var get_wcurl = function( endpoint ) { 8 return xoo_wsc_params.wc_ajax_url.toString().replace( 9 '%%endpoint%%', 10 endpoint 11 ); 12 }; 13 14 var markupTimeout = null; 15 16 class Notice{ 17 18 constructor( $modal ){ 19 this.$modal = $modal; 20 this.timeout = null; 21 } 22 23 add( notice, type = 'success', clearPrevious = true ){ 24 25 var $noticeCont = this.$modal.find('.xoo-wsc-notice-container'); 26 27 if( clearPrevious ){ 28 $noticeCont.html(''); 29 } 30 31 var noticeHTML = type === 'success' ? xoo_wsc_params.html.successNotice.toString().replace( '%s%', notice ) : xoo_wsc_params.html.errorNotice.toString().replace( '%s%', notice ); 32 33 $noticeCont.html( noticeHTML ); 34 35 } 36 37 showNotification(){ 38 39 Notice.showMarkupNotice(); 40 41 var $noticeCont = this.$modal.find('.xoo-wsc-notice-container'); 42 43 if( !$noticeCont.length || $noticeCont.children().length === 0 ) return; 44 45 $noticeCont.slideDown(); 46 47 clearTimeout(this.timeout); 48 49 this.timeout = setTimeout(function(){ 50 $noticeCont.slideUp('slow',function(){ 51 //$noticeCont.html(''); 52 }); 53 },xoo_wsc_params.notificationTime ) 54 55 } 56 57 58 59 hideNotification(){ 60 this.$modal.find('.xoo-wsc-notice-container').hide(); 61 } 62 63 static hideMarkupNotice(){ 64 Notice.$noticeContainer().removeClass('xoo-wsc-active'); 65 } 66 67 static $noticeContainer(){ 68 return $('.xoo-wsc-markup-notices') 69 } 70 71 static showMarkupNotice(){ 72 73 if( cart.isOpen() ) return; 74 75 var $markupNotice = Notice.$noticeContainer(); 76 77 var $noticeCont = $markupNotice.find('.xoo-wsc-notice-container .xoo-wsc-notices'); 78 79 if( !$noticeCont.length || $noticeCont.children().length === 0 ) return; 80 81 setTimeout(function(){$markupNotice.addClass('xoo-wsc-active')},10); 82 83 clearTimeout(markupTimeout); 84 85 markupTimeout = setTimeout(function(){ 86 $markupNotice.removeClass('xoo-wsc-active'); 87 },xoo_wsc_params.notificationTime ) 88 } 89 } 90 91 var masonryInitialised = {}; 92 93 function initMasonryLayout( type = '' ){ 94 95 var layouts = { 96 saveLater: {'.xoo-wsc-savl-column': '.xoo-wsc-savl-prod-cont'}, 97 cart: {'.xoo-wsc-pattern-card': '.xoo-wsc-product-cont'}, 98 suggested: {'.xoo-wsc-sp-column ul.xoo-wsc-sp-slider': '.xoo-wsc-sp-prod-cont'} 99 }; 100 101 var initLayouts = {}; 102 103 if( type ){ 104 if( Array.isArray( type ) ){ 105 $.each( type, function(index, type_val ){ 106 initLayouts[ type_val ] = layouts[ type_val ]; 107 } ) 108 } 109 else{ 110 initLayouts[type] = layouts[type]; 111 } 112 113 }else{ 114 initLayouts = layouts; 115 } 116 117 118 $.each( initLayouts, function(type, layout){ 119 120 if( masonryInitialised[type] && document.body.contains( masonryInitialised[type][0] ) ) return true; 121 122 $.each( layout, function(cont, childClass){ 123 if( $(cont).length && $(cont).is(':visible') ){ 124 $(cont).masonry({ 125 // options 126 itemSelector: childClass, 127 columnWidth: childClass, /* Each column takes 50% */ 128 percentPosition: true 129 }); 130 masonryInitialised[type] = $(cont); 131 } 132 }) 133 }) 134 135 136 } 137 138 class Container{ 139 140 static eventHandlerCalled = false; 141 142 constructor( $modal, container ){ 143 this.$modal = $modal; 144 this.container = container || 'cart'; 145 this.notice = new Notice( this.$modal ); 146 } 147 148 149 isOpen(){ 150 return this.$modal.hasClass('xoo-wsc-'+this.container+'-active'); 151 } 152 153 eventHandlers(){ 154 $(document.body).on( 'wc_fragments_loaded updated_checkout', this.onCartUpdate.bind(this) ); 155 } 156 157 onCartUpdate(){ 158 this.unblock(); 159 this.notice.showNotification(); 160 } 161 162 setAjaxData( data, noticeSection ){ 163 164 var ajaxData = { 165 container: this.container, 166 noticeSection: noticeSection || this.noticeSection || this.container, 167 isCheckout: isCheckoutPage, 168 isCart: isCartPage 169 } 170 171 172 if( typeof data === 'object' ){ 173 174 $.extend( ajaxData, data ); 175 176 } 177 else{ 178 179 var serializedData = data; 180 181 $.each( ajaxData, function( key, value ){ 182 serializedData += ( '&'+key+'='+value ); 183 } ) 184 185 ajaxData = serializedData; 186 187 } 188 189 return ajaxData; 190 } 191 192 193 toggle( type ){ 194 195 var $activeEls = this.$modal.add( 'body' ).add('html'), 196 activeClass = 'xoo-wsc-'+ this.container +'-active'; 197 198 if( type === 'show' ){ 199 $activeEls.addClass(activeClass); 200 } 201 else if( type === 'hide' ){ 202 $activeEls.removeClass(activeClass); 203 this.notice.hideNotification(); 204 } 205 else{ 206 $activeEls.toggleClass(activeClass); 207 } 208 209 210 $(document.body).trigger( 'xoo_wsc_' + this.container + '_toggled', [ type ] ); 211 212 } 213 214 215 block(){ 216 this.$modal.addClass('xoo-wsc-loading'); 217 } 218 219 unblock(){ 220 this.$modal.removeClass('xoo-wsc-loading'); 221 } 222 223 224 refreshMyFragments(){ 225 226 if( xoo_wsc_params.refreshCart === "yes" && typeof wc_cart_fragments_params !== 'undefined' ){ 227 $( document.body ).trigger( 'wc_fragment_refresh' ); 228 return; 229 } 230 231 this.block(); 232 233 $.ajax({
234 url: get_wcurl( 'xoo_wsc_refresh_fragments' ), 235 type: 'POST', 236 context: this, 237 data: {}, 238 success: function( response ){ 239 this.updateFragments(response); 240 $( document.body ).trigger( 'wc_fragments_refreshed' ); 241 }, 242 complete: function(){ 243 this.unblock(); 244 } 245 }) 246 247 } 248 249 250 updateCartCheckoutPage(){ 251 252 //Refresh checkout page 253 if( isCheckoutPage ){ 254 if( $( 'form.checkout' ).length === 0 ){ 255 location.reload(); 256 return; 257 } 258 $(document.body).trigger("update_checkout"); 259 } 260 261 //Refresh Cart page 262 if( isCartPage ){ 263 $(document.body).trigger("wc_update_cart"); 264 } 265 266 } 267 268 updateFragments( response ){ 269 270 if( response.fragments ){ 271 272 $( document.body ).trigger( 'xoo_wsc_before_loading_fragments', [ response ] ); 273 274 this.block(); 275 276 //Set fragments 277 $.each( response.fragments, function( key, value ) { 278 $( key ).replaceWith( value ); 279 }); 280 281 if( typeof wc_cart_fragments_params !== 'undefined' && ( 'sessionStorage' in window && window.sessionStorage !== null ) ){ 282 283 sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( response.fragments ) ); 284 localStorage.setItem( wc_cart_fragments_params.cart_hash_key, response.cart_hash ); 285 sessionStorage.setItem( wc_cart_fragments_params.cart_hash_key, response.cart_hash ); 286 287 if ( response.cart_hash ) { 288 sessionStorage.setItem( 'wc_cart_created', ( new Date() ).getTime() ); 289 } 290 291 } 292 293 $( document.body ).trigger( 'wc_fragments_loaded' ); 294 295 this.unblock(); 296 297 } 298 299 if( xoo_wsc_params.refreshCart === "yes" && typeof wc_cart_fragments_params !== 'undefined' ){ 300 this.block(); 301 $( document.body ).trigger( 'wc_fragment_refresh' ); 302 return; 303 } 304 305 } 306 307 } 308 309 310 class Cart extends Container{ 311 312 static isWCAjaxAddToCart = false; 313 314 constructor( $modal ){ 315 316 super( $modal, 'cart' ); 317 318 this.baseQty = 1; 319 this.qtyUpdateDelay = null; 320 this.bodyPosition = false; 321 this.cartLoaded = false; 322 this.blockAddedToCartCalled = false; 323 this.barsData = {}; 324 this.barsWidth = {}; 325 326 this.refreshFragmentsOnPageLoad(); 327 this.eventHandlers(); 328 this.initSlider(); 329 this.toggleBasket(); 330 331 } 332 333 334 refreshFragmentsOnPageLoad(){ 335 if( xoo_wsc_params.fetchCart === 'page_load' ){ 336 setTimeout(function(){ 337 this.refreshMyFragments(); 338 }.bind(this), xoo_wsc_params.fetchDelay ) 339 } 340 } 341 342 eventHandlers(){ 343 344 super.eventHandlers(); 345 346 this.$modal.on( 'click', '.xoo-wsc-chng', this.toggleQty.bind(this) ); 347 this.$modal.on( 'change', '.xoo-wsc-qty', this.changeInputQty.bind(this) ); 348 this.$modal.on( 'click', '.xoo-wsc-undo-item', this.undoItem.bind(this) ); 349 this.$modal.on( 'focusin', '.xoo-wsc-qty', this.saveQtyFocus.bind(this) ); 350 this.$modal.on( 'click', '.xoo-wsc-smr-del', this.deleteIconClick.bind(this) ); 351 this.$modal.on( 'click', '.xoo-wsch-close, .xoo-wsc-opac, .xoo-wsc-cart-close', this.closeCartOnClick.bind(this) ); 352 this.$modal.on( 'click', '.xoo-wsc-basket', this.toggleCart.bind(this) ); 353 354 $( document.body ).on( 'click', '.xoo-wsc-ecl', this.emptyCart.bind(this) ); 355 356 $(document.body).on( 'xoo_wsc_cart_updated', this.updateCartCheckoutPage.bind(this) ); 357 $(document.body).on( 'click', 'a.added_to_cart, .xoo-wsc-cart-trigger', this.openCart.bind(this) ); 358 $(document.body).on( 'added_to_cart ', this.addedToCart.bind(this) ); 359 360 if( xoo_wsc_params.ajaxAddToCart === 'yes' ){ 361 $(document.body).on( 'submit', 'form.cart', this.addToCartFormSubmit.bind(this) ); 362 } 363 364 if( typeof wc_cart_fragments_params === 'undefined' ){ 365 $( window ).on( 'pageshow' , this.onPageShow.bind(this) ); 366 } 367 368 if( xoo_wsc_params.triggerClass ){ 369 $(document.body).on( 'click', '.'+xoo_wsc_params.triggerClass, this.openCart.bind(this) ); 370 } 371 372 373 374 if( isCheckoutPage || isCartPage ){ 375 $(document.body).on( 'updated_shipping_method', this.refreshMyFragments.bind(this) ); 376 } 377 378 $(document.body).on( 'wc-blocks_added_to_cart', this.blockAddedToCart.bind(this) ); 379 380 $(document.body).on( 'adding_to_cart', this.checkIfWCAjaxAddToCart.bind(this) ); 381 382 //Animate shipping bar 383 $(document.body).on( 'xoo_wsc_before_loading_fragments adding_to_cart wc_fragment_refresh', this.storeProgressBarWidth.bind(this) ); 384 385 //$(document.body).on( 'wc_fragments_loaded', this.checkIfWCAjaxAddToCartUnset.bind(this) ); 386 387 initMasonryLayout( ['cart', 'suggested' ] ); 388 389 if( xoo_wsc_params.autoOpenCart === 'yes' && xoo_wsc_params.addedToCart === 'yes'){ 390 this.openCart(); 391 } 392 393 394 this.$modal.on( 'click', '.xoo-wsc-save', this.saveForLater.bind(this) ); 395 396 } 397 398 399 saveForLater(e){ 400 401 if( xoo_wsc_params.saveForLaterNeedsLogin ) return; 402 403 var $product = $(e.currentTarget).closest('.xoo-wsc-product'), 404 cartKey = $product.data('key'), 405 formData = { 406 cart_key: cartKey, 407 } 408 409 this.block(); 410 this.saveScrollPosition(); 411 412 413 $.ajax({
414 url: get_wcurl( 'xoo_wsc_save_for_later' ), 415 type: 'POST', 416 context: this, 417 data: this.setAjaxData(formData), 418 success: function(response){ 419 420 this.updateFragments( response ); 421 422 $(document.body).trigger( 'xoo_wsc_added_to_save_list', [response, cartKey] ); 423 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 424 425 this.setScrollPosition(); 426 this.unblock(); 427 428 var $saveLaterIcon = this.$modal.find('.xoo-wsch-savelater'); 429 430 if( $saveLaterIcon.length ){ 431 $saveLaterIcon.addClass('xoo-wsc-shake-animate'); 432 setTimeout(function(){ 433 $saveLaterIcon.removeClass('xoo-wsc-shake-animate'); 434 },1200); 435 } 436 437 } 438 439 }) 440 441 } 442 443 checkIfWCAjaxAddToCartUnset(){ 444 this.isWCAjaxAddToCart = false; 445 } 446 447 checkIfWCAjaxAddToCart(e, $button, data){ 448 449 Cart.isWCAjaxAddToCart = true; 450 451 if( ( !(data instanceof FormData) || !data.has('action') || !data.get('action') === 'xoo_wsc_add_to_cart' ) && $button.hasClass('ajax_add_to_cart') ){ 452 this.isWCAjaxAddToCart = true; 453 } 454 } 455 456 457 toggleCart(e){ 458 if( this.isOpen() ){ 459 this.closeCartOnClick(e); 460 } 461 else{ 462 this.openCart(e); 463 } 464 465 } 466 467 468 openCart(e){ 469 if( e ){ 470 e.preventDefault(); 471 e.stopImmediatePropagation(); 472 } 473 474 if( !this.cartLoaded && xoo_wsc_params.fetchCart === 'cart_open' ){ 475 this.refreshMyFragments(); 476 this.cartLoaded = true; 477 } 478 479 this.toggle('show'); 480 this.animateProgressBar(); 481 Notice.hideMarkupNotice(); 482 483 } 484 485 addToCartFormSubmit(e){ 486 487 var $form = $(e.currentTarget); 488 489 if( $form.closest('.product').hasClass('product-type-external') || $form.siblings('.xoo-wsc-disable-atc').length ) return; 490 491 var $button = e.originalEvent && e.originalEvent.submitter ? $(e.originalEvent.submitter) : $form.find( 'button[type="submit"]'), 492 formData = new FormData($form.get(0)), 493 productData = $form.serializeArray(), 494 hasProductId = false; 495 496 //Check for woocommerce custom quantity code 497 //https://docs.woocommerce.com/document/override-loop-template-and-show-quantities-next-to-add-to-cart-buttons/ 498 $.each( productData, function( key, form_item ){ 499 if( form_item.name === 'productID' || form_item.name === 'add-to-cart' ){ 500 if( form_item.value ){ 501 hasProductId = true; 502 return false; 503 } 504 } 505 }) 506 507 //If no product id found , look for the form action URL 508 if( !hasProductId && $form.attr('action') ){ 509 var is_url = $form.attr('action').match(/add-to-cart=([0-9]+)/), 510 productID = is_url ? is_url[1] : false; 511 } 512 513 // Add submitted button value 514 if( $button.attr('name') && $button.attr('value') ){ 515 formData.append( $button.attr('name'), $button.attr('value') ); 516 } 517 518 if( productID ){ 519 formData.append( 'add-to-cart', productID ); 520 } 521 522 formData.append( 'action', 'xoo_wsc_add_to_cart' ); 523 524 var doAjaxAddToCart = true; 525 526 527 $.each( xoo_wsc_params.skipAjaxForData, function( key, value ){ 528 if( formData.has(key) && ( !value || formData.get(key) == value ) ){ 529 doAjaxAddToCart = false; 530 return false; 531 } 532 } ) 533 534 535 if( doAjaxAddToCart ){ 536 e.preventDefault(); 537 this.addToCartAjax( $button, formData );//Ajax add to cart 538 } 539 540 } 541 542 543 addToCartAjax( $button, formData ){ 544 545 this.block(); 546 547 $button.addClass('loading'); 548 549 // Trigger event. 550 $( document.body ).trigger( 'adding_to_cart', [ $button, formData ] ); 551 552 $.ajax({ 553 url: get_wcurl( 'xoo_wsc_add_to_cart' ), 554 type: 'POST', 555 context: this, 556 cache: false, 557 contentType: false, 558 processData: false, 559 data: formData, 560 success: function(response){ 561 562 if(response.fragments){ 563 // Trigger event so themes can refresh other areas. 564 $( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $button ] ); 565 }else if(response.error){ 566 Notice.$noticeContainer().html(response.notice); 567 Notice.showMarkupNotice(); 568 } 569 else{ 570 window.location.reload(); 571 } 572 573 }, 574 complete: function(){ 575 this.unblock(); 576 $button 577 .removeClass('loading') 578 .addClass('added'); 579 } 580 }) 581 } 582 583 addedToCart( e, response, hash, $button ){ 584 585 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 586 587 var _this = this; 588 589 this.flyToCart( $button, function(){ 590 if( xoo_wsc_params.autoOpenCart === "yes" ){ 591 setTimeout(function(){ 592 _this.openCart(); 593 },20 ) 594 } 595 } ); 596 } 597 598 599 blockAddedToCart(){ 600 601 if( !Cart.isWCAjaxAddToCart && !this.blockAddedToCartCalled ){ 602 603 this.refreshMyFragments(); 604 605 var _this = this; 606 607 if( xoo_wsc_params.autoOpenCart === "yes" ){ 608 setTimeout(function(){ 609 _this.openCart(); 610 },20 ) 611 } 612 613 this.blockAddedToCartCalled = true; 614 615 setTimeout( function(){ 616 _this.blockAddedToCartCalled = false; 617 }, 200 ); 618 619 Cart.isWCAjaxAddToCart = false; 620 621 } 622 623 624 625 } 626 627 628 flyToCart( $atcEL, callback ){ 629 630 var $basket = this.$modal.find('.xoo-wsc-basket').length ? this.$modal.find('.xoo-wsc-basket') : $(document.body).find('.xoo-wsc-sc-cont'); 631 632 if( !$basket.length || xoo_wsc_params.flyToCart !== 'yes' || !$atcEL || !$atcEL.length ){ 633 callback(); 634 return; 635 } 636 637 var customDragImgClass = xoo_wsc_params.productFlyClass, 638 $dragIMG = null, 639 $product = $atcEL.closest('.product'); 640 641 642 //If has product container 643 if( $product.length ){ 644 645 $product = $($product[0]); 646 647 var $productGallery = $product.find('.woocommerce-product-gallery'); 648 649 if( customDragImgClass && $product.find( customDragImgClass ).length ){ 650 $dragIMG = $product.find( customDragImgClass ); 651 }
652 else if( $product.find( 'img[data-xooWscFly="fly"]' ).length ){ 653 if( $productGallery.length ){ 654 $dragIMG = $productGallery.find( '.flex-active-slide img[data-xooWscFly="fly"]' ).length ? $productGallery.find( '.flex-active-slide img[data-xooWscFly="fly"]' ) : $productGallery.find( 'img[data-xooWscFly="fly"]' ) 655 } 656 else{ 657 $dragIMG = $product.find( 'img[data-xooWscFly="fly"]' ); 658 } 659 } 660 else if( $productGallery.length ){ 661 $dragIMG = $productGallery; 662 } 663 else{ 664 $dragIMG = $product; 665 } 666 667 } 668 else if( customDragImgClass ){ 669 var moveUp = 4; 670 for ( var i = moveUp; i >= 0; i-- ) { 671 var $foundImg = $atcEL.parent().find( customDragImgClass ); 672 if( $foundImg.length ){ 673 $dragIMG = $foundImg; 674 return false; 675 } 676 } 677 } 678 679 680 if( !$dragIMG || !$dragIMG.length ){ 681 callback(); 682 return; 683 } 684 685 $dragIMG = $dragIMG.eq(0); 686 687 var $imgclone = $dragIMG 688 .clone() 689 .offset({ 690 top: $dragIMG.offset().top, 691 left: $dragIMG.offset().left 692 }) 693 .addClass( 'xoo-wsc-fly-animating' ) 694 .appendTo( $('body') ) 695 .animate({ 696 'top': $basket.offset().top - 20, 697 'left': $basket.offset().left - 20, 698 'width': 75, 699 'height': 75 700 }, parseInt( xoo_wsc_params.flyToCartTime ), 'easeInOutExpo' ); 701 702 setTimeout(function () { 703 callback() 704 }, parseInt( xoo_wsc_params.flyToCartTime ) ); 705 706 $imgclone.animate({ 707 'width': 0, 708 'height': 0 709 }, function () { 710 $(this).detach(); 711 }); 712 713 } 714 715 716 toggleQty(e){ 717 718 var $toggler = $(e.currentTarget), 719 $input = $toggler.siblings('.xoo-wsc-qty'); 720 721 if( !$input.length ) return; 722 723 var baseQty = this.baseQty = parseFloat( $input.val() ), 724 step = parseFloat( $input.attr('step') ), 725 action = $toggler.hasClass( 'xoo-wsc-plus' ) ? 'add' : 'less', 726 newQty = action === 'add' ? baseQty + step : baseQty - step; 727 728 729 $input.val(newQty).trigger('change'); 730 731 } 732 733 changeInputQty(e){ 734 735 this.notice.hideNotification(); 736 737 var $_this = this, 738 $input = $(e.currentTarget), 739 newQty = parseFloat( $input.val() ), 740 step = parseFloat( $input.attr('step') ), 741 min = parseFloat( $input.attr('min') ), 742 max = parseFloat( $input.attr('max') ), 743 invalid = false, 744 message = false; 745 746 //Validation 747 748 if( isNaN( newQty ) || newQty < 0 || newQty < min ){ 749 invalid = true; 750 } 751 else if( newQty > max ){ 752 invalid = true; 753 message = xoo_wsc_params.strings.maxQtyError.replace( '%s%', max ); 754 } 755 else if( !Number.isInteger(newQty/step ) ){ 756 invalid = true; 757 message = xoo_wsc_params.strings.stepQtyError.replace( '%s%', step ); 758 } 759 760 //Set back to default quantity 761 if( invalid ){ 762 $input.val( this.baseQty ); 763 if( message ){ 764 this.notice.add( message, 'error' ); 765 this.notice.showNotification(); 766 } 767 return; 768 } 769 770 //Update 771 $input.val( newQty ); 772 773 clearTimeout( this.qtyUpdateDelay ); 774 775 this.qtyUpdateDelay = setTimeout(function(){ 776 $_this.updateItemQty( $input.parents('.xoo-wsc-product').data('key'), newQty ) 777 }, xoo_wsc_params.qtyUpdateDelay ); 778 779 780 } 781 782 783 saveScrollPosition(){ 784 this.bodyPosition = this.$modal.find('.xoo-wsc-body').length ? this.$modal.find('.xoo-wsc-body').scrollTop() : false; 785 } 786 787 setScrollPosition(){ 788 if( this.bodyPosition !== false ){ 789 this.$modal.find( '.xoo-wsc-body' ).scrollTop( this.bodyPosition ); 790 this.bodyPosition = false; //reset 791 } 792 } 793 794 updateItemQty( cart_key, qty ){ 795 796 if( !cart_key || qty === undefined ) return; 797 798 this.block(); 799 800 this.saveScrollPosition(); 801 802 var formData = { 803 cart_key: cart_key, 804 qty: qty 805 } 806 807 $.ajax({ 808 url: get_wcurl( 'xoo_wsc_update_item_quantity' ), 809 type: 'POST', 810 context: this, 811 data: this.setAjaxData(formData), 812 success: function(response){ 813 this.updateFragments( response ); 814 $(document.body).trigger( 'xoo_wsc_quantity_updated', [response] ); 815 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 816 this.setScrollPosition(); 817 this.unblock(); 818 } 819 820 }) 821 } 822 823 824 closeCartOnClick(e){
825 e.preventDefault(); 826 if( drawer.isOpen() ){ 827 drawer.toggle('hide'); 828 setTimeout( function(){ 829 cart.toggle( 'hide' ) 830 }, 500 ); 831 } 832 else{ 833 cart.toggle('hide'); 834 } 835 836 } 837 838 839 saveQtyFocus(e){ 840 this.baseQty = $(e.currentTarget).val(); 841 } 842 843 844 onPageShow(e){ 845 if ( e.originalEvent.persisted ) { 846 this.refreshMyFragments(); 847 $( document.body ).trigger( 'wc_fragment_refresh' ); 848 } 849 } 850 851 deleteIconClick(e){ 852 this.updateItemQty( $( e.currentTarget ).parents('.xoo-wsc-product').data('key'), 0 ); 853 } 854 855 undoItem(e){ 856 857 var $undo = $(e.currentTarget), 858 formData = { 859 cart_key: $undo.data('key') 860 } 861 862 this.block(); 863 864 $.ajax({ 865 url: get_wcurl('xoo_wsc_undo_item'), 866 type: 'POST', 867 context: this, 868 data: this.setAjaxData(formData), 869 success: function(response){ 870 this.updateFragments( response ); 871 $(document.body).trigger( 'xoo_wsc_item_restored', [response] ); 872 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 873 this.unblock(); 874 } 875 876 }) 877 } 878 879 storeProgressBarWidth( e ){ 880 881 var $bars = $(document.body).find( '.xoo-wsc-bar-cont' ), 882 self = this; 883 884 if( !$bars.length ) return; 885 886 $.each( $bars, function( index, el ){ 887 888 var $bar = $(el), 889 $filled = $bar.find('.xoo-wsc-bar-filled'), 890 id = $bar.attr('id'); 891 892 self.barsWidth[ id ] = $filled.prop('style').width; 893 self.barsData[ id ] = $bar.data('bardata') 894 895 } ); 896 897 898 } 899 900 onCartUpdate(){ 901 super.onCartUpdate(); 902 this.cartLoaded = true; 903 this.initAnimateProgressBar = true; 904 if( this.isOpen() ){ 905 this.animateProgressBar(); 906 } 907 this.initSlider(); 908 this.toggleBasket(); 909 initMasonryLayout( ['cart','suggested'] ); 910 } 911 912 913 914 toggleBasket(){ 915 916 var $basket = $('.xoo-wsc-basket'), 917 show = xoo_wsc_params.showBasket, 918 hasProducts = this.$modal.find('.xoo-wsc-product').length; 919 920 if( show === "always_show" ){ 921 $basket.show(); 922 } 923 else if( show === "hide_empty" ){ 924 if( hasProducts ){ 925 $basket.show(); 926 } 927 else{ 928 $basket.hide(); 929 } 930 } 931 else{ 932 $basket.hide(); 933 } 934 935 var $shortcode = $('.xoo-wsc-sc-cont'); 936 937 if( $shortcode.length && xoo_wsc_params.menuCartHideOnEmpty.length ){ 938 939 var shortcodeEls = xoo_wsc_params.shortcodeEls; 940 941 $.each( xoo_wsc_params.menuCartHideOnEmpty, function( index, val ){ 942 943 if( shortcodeEls[val] ){ 944 if( hasProducts ){ 945 $(shortcodeEls[val]).show(); 946 } 947 else{ 948 $(shortcodeEls[val]).hide(); 949 } 950 } 951 952 }) 953 954 } 955 956 } 957 958 animateProgressBar(){ 959 960 if( isCartPage || isCheckoutPage || !this.initAnimateProgressBar ) return; 961 962 var $bars = $(document.body).find( '.xoo-wsc-bar-cont' ), 963 self = this; 964 965 if( !$bars.length ) return; 966 967 $.each( $bars, function( index, el ){ 968 969 var $bar = $(el), 970 $filled = $bar.find('.xoo-wsc-bar-filled'), 971 id = $bar.attr('id'); 972 973 if( !self.barsWidth[ id ] ) return true; 974 975 var newWidth = $filled.prop('style').width; 976 977 $filled 978 .width( self.barsWidth[ id ] ) 979 .animate({ width: newWidth }, 400, 'linear'); 980 981 } ); 982 983 this.checkPointAchievedAnimate(); 984 985 this.initAnimateProgressBar = false; 986 } 987 988 checkPointAchievedAnimate(){ 989 990 var $bars = $(document.body).find( '.xoo-wsc-bar-cont' ), 991 self = this; 992 993 if( !this.barsData || !$bars.length ) return; 994 995 996 $.each( $bars, function( index, el ){ 997 998 var $bar = $(el), 999 $filled = $bar.find('.xoo-wsc-bar-filled'), 1000 id = $bar.attr('id'), 1001 barData = $bar.data('bardata'), 1002 pastBarData = self.barsData[ id ]; 1003 1004 if( !pastBarData ) return true; 1005 1006 var pastPointsReached = [], 1007 newPointsReached = [], 1008 allPointsReached = false; 1009 1010 $.each( pastBarData.points, function( point_index, point ){ 1011 if( point.reached == true ){ 1012 pastPointsReached.push('id_'+point_index); 1013 } 1014 } ) 1015 1016 $.each( barData.points, function( point_index, point ){ 1017 if( point.reached == true && !pastPointsReached.includes('id_'+point_index) ){ 1018 newPointsReached.push('id_'+point_index); 1019 } 1020 1021 if( point.reached == true && (point_index + 1) === barData.points.length ){ 1022 allPointsReached = true; 1023 } 1024 } ) 1025 1026 1027 1028 if( newPointsReached.length ){ 1029 setTimeout( function(){ 1030 Celebrate.Celebrate( $bar, allPointsReached && xoo_wsc_params.bar.fullCelebration !== 'none' ? xoo_wsc_params.bar.fullCelebration : xoo_wsc_params.bar.singleCelebration ); 1031 }, 200 ); 1032 } 1033 1034 self.barsData[id] = barData; 1035 1036 1037 }) 1038 1039 1040 } 1041 1042 1043 emptyCart(){ 1044 1045 this.block(); 1046 1047 $.ajax({
1048 url: get_wcurl( 'xoo_wsc_empty_cart' ), 1049 type: 'POST', 1050 context: this, 1051 data: {}, 1052 success: function(response){ 1053 1054 this.updateFragments( response ); 1055 // Trigger event. 1056 $( document.body ).trigger( 'xoo_wsc_cart_emptied' ); 1057 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 1058 }, 1059 complete: function(){ 1060 this.unblock(); 1061 } 1062 }) 1063 } 1064 1065 1066 initSlider(){ 1067 1068 if( typeof $.fn.lightSlider !== 'function' || xoo_wsc_params.spSlide.enable !== 'yes' ) return; 1069 1070 $('ul.xoo-wsc-sp-slider').each( function( index, el ){ 1071 var $el = $(el); 1072 1073 if( $(this).parents('.xoo-wsc-drawer').length ) return; 1074 1075 $el.lightSlider(xoo_wsc_params.spSlide); 1076 1077 } ); 1078 1079 } 1080 1081 } 1082 1083 1084 class Drawer extends Container{ 1085 1086 constructor( $modal ){ 1087 1088 super( $modal, 'drawer' ); 1089 1090 this.setHeaderHeight(); 1091 1092 this.eventHandlers(); 1093 1094 } 1095 1096 eventHandlers(){ 1097 1098 super.eventHandlers(); 1099 1100 $(document.body).on( 'xoo_wsc_cart_toggled', this.drawOutOnCartOpen.bind(this) ); 1101 $(document.body).on( 'click', '.xoo-wsc-toggle-drawer', this.toggleDrawer.bind(this) ); 1102 $(document.body).on( 'click', '.xoo-wscdh-close', this.close.bind(this) ); 1103 //$(document.body).on( 'wc_fragments_loaded', this.onCartUpdate.bind(this) ); 1104 } 1105 1106 onCartUpdate(){ 1107 super.onCartUpdate(); 1108 this.setHeaderHeight(); 1109 setTimeout(function(){ 1110 drawer.toggleOnContentBasis(); 1111 }, 0); 1112 1113 } 1114 1115 1116 toggleOnContentBasis(){ 1117 1118 var hasContent = !this.isDrawerEmpty(); 1119 1120 if( this.isOpen() ){ 1121 if( !hasContent ){ 1122 this.toggle('hide'); 1123 this.$modal.find('.xoo-wsc-dtg-icon').addClass('xoo-wsc-disabled'); 1124 this.emptyClosed = true; 1125 } 1126 } 1127 else{ 1128 if( hasContent && cart.isOpen() && this.emptyClosed ){ 1129 this.toggle('show'); 1130 this.$modal.find('.xoo-wsc-dtg-icon').removeClass('xoo-wsc-disabled'); 1131 this.emptyClosed = false; 1132 } 1133 } 1134 } 1135 1136 setHeaderHeight(){ 1137 var $cartHeader = $('.xoo-wsch-top'); 1138 if( !$cartHeader.length ) return; 1139 1140 var cartHeaderHeight = $cartHeader.height(); 1141 1142 this.$modal.closest('.xoo-wsc-markup').find('.xoo-wsc-drawer-header, .xoo-wsc-sl-heading').each(function( index, el ){ 1143 1144 var $el = $(el); 1145 1146 if( $el.height() < $cartHeader.height() ){ 1147 $el.height( cartHeaderHeight ); 1148 } 1149 }) 1150 1151 1152 } 1153 1154 isDrawerEmpty(){ 1155 return !this.$modal.find('.xoo-wsc-dr-content').length; 1156 } 1157 1158 1159 toggleDrawer(){ 1160 this.toggle(); 1161 } 1162 1163 1164 drawOutOnCartOpen(e,type){ 1165 1166 if( !cart.isOpen() || this.isDrawerEmpty() ) return; 1167 1168 setTimeout( function(){ 1169 drawer.toggle('show'); 1170 initMasonryLayout('suggested'); 1171 }, xoo_wsc_params.drawerWait ); 1172 1173 } 1174 1175 1176 close(e){ 1177 this.toggle('hide'); 1178 } 1179 1180 getDataType(){ 1181 return this.$modal.find('.xoo-wsc-dr-content').data('drawer'); 1182 } 1183 1184 1185 } 1186 1187 1188 1189 class Slider extends Container{ 1190 1191 constructor( $modal ){ 1192 1193 super( $modal, 'slider' ); 1194 1195 if( xoo_wsc_params.sliderAutoClose ) this.noticeSection = 'cart'; 1196 1197 this.eventHandlers(); 1198 1199 this.shipping = xoo_wsc_params.shippingEnabled ? Shipping.init( this ) : null; 1200 1201 } 1202 1203 eventHandlers(){ 1204 1205 super.eventHandlers(); 1206 1207 1208 $( document.body ).on( 'click', '.xoo-wsc-toggle-slider', this.triggerSlider.bind(this) ); 1209 $( document.body ).on( 'xoo_wsc_cart_toggled', this.closeSliderOnCartClose.bind(this) ); 1210 1211 if( xoo_wsc_params.sliderAutoClose ){ 1212 $( document.body ).on( 'xoo_wsc_coupon_applied xoo_wsc_shipping_calculated updated_shipping_method xoo_wsc_coupon_removed xoo_wsc_moved_from_save_list', this.closeSlider.bind(this) ); 1213 } 1214 1215 $(document.body).on( 'submit', 'form.xoo-wsc-sl-apply-coupon', this.submitCouponForm.bind(this) ); 1216 $(document.body).on( 'click', '.xoo-wsc-coupon-apply-btn', this.applyCouponFromBtn.bind(this) ); 1217 $(document.body).on( 'click', '.xoo-wsc-remove-coupon', this.removeCoupon.bind(this) ); 1218 $(document.body).on( 'click', '.xoo-wsc-savl-del', this.deleteSavedForLaterItem.bind(this) ); 1219 $(document.body).on( 'click', '.xoo-wsc-savl-atc', this.moveSavedForLaterItemToCart.bind(this) ); 1220 1221 } 1222 1223 1224 moveSavedForLaterItemToCart(e){ 1225 1226 var $item = $(e.currentTarget).closest('.xoo-wsc-savl-product'), 1227 cartKey = $item.data('ckey'), 1228 formData = { 1229 cart_key: cartKey, 1230 } 1231 1232 this.block(); 1233 1234 $.ajax({
1235 url: get_wcurl( 'xoo_wsc_move_save_for_later_item' ), 1236 type: 'POST', 1237 context: this, 1238 data: this.setAjaxData(formData), 1239 success: function(response){ 1240 1241 this.updateFragments( response ); 1242 1243 $(document.body).trigger( 'xoo_wsc_moved_from_save_list', [response, cartKey] ); 1244 1245 this.unblock(); 1246 1247 } 1248 1249 }) 1250 } 1251 1252 deleteSavedForLaterItem(e){ 1253 1254 var $item = $(e.currentTarget).closest('.xoo-wsc-savl-product'), 1255 cartKey = $item.data('ckey'), 1256 formData = { 1257 cart_key: cartKey, 1258 } 1259 1260 this.block(); 1261 1262 $.ajax({ 1263 url: get_wcurl( 'xoo_wsc_delete_save_for_later_item' ), 1264 type: 'POST', 1265 context: this, 1266 data: this.setAjaxData(formData, 'slider' ), 1267 success: function(response){ 1268 1269 this.updateFragments( response ); 1270 1271 $(document.body).trigger( 'xoo_wsc_delete_from_save_list', [response, cartKey] ); 1272 1273 this.unblock(); 1274 1275 } 1276 1277 }) 1278 } 1279 1280 1281 removeCoupon(e){ 1282 1283 e.preventDefault(); 1284 1285 var $removeEl = $(e.currentTarget), 1286 coupon = $removeEl.data('code'), 1287 formData = { 1288 coupon: coupon 1289 }; 1290 1291 this.block(); 1292 1293 $.ajax( { 1294 url: get_wcurl( 'xoo_wsc_remove_coupon' ), 1295 type: 'POST', 1296 context: this, 1297 data: this.setAjaxData( formData, cart.$modal.find( $removeEl ).length ? 'cart' : 'slider' ), 1298 success: function( response ) { 1299 this.updateFragments(response); 1300 }, 1301 complete: function() { 1302 this.unblock(); 1303 this.updateCartCheckoutPage(); 1304 $( document.body ).trigger( 'xoo_wsc_coupon_removed' ); 1305 } 1306 } ); 1307 } 1308 1309 onCartUpdate(){ 1310 super.onCartUpdate(); 1311 this.toggleContent(); 1312 } 1313 1314 closeSlider(){ 1315 this.toggle('hide'); 1316 } 1317 1318 1319 applyCouponFromBtn(e){ 1320 this.applyCoupon( $(e.currentTarget).val() ); 1321 } 1322 1323 submitCouponForm(e){ 1324 1325 e.preventDefault(); 1326 1327 var $form = $(e.currentTarget); 1328 1329 this.applyCoupon( $form.find('input[name="xoo-wsc-slcf-input"]').val() ); 1330 1331 } 1332 1333 1334 closeSliderOnCartClose(e){ 1335 1336 var $this = $(e.currentTarget); 1337 1338 if( !cart.$modal.hasClass('xoo-wsc-cart-active') ){ 1339 this.toggle('hide'); 1340 } 1341 1342 } 1343 1344 1345 triggerSlider(e){ 1346 1347 var $toggler = $(e.currentTarget), 1348 slider = $toggler.data('slider'); 1349 1350 if( slider === 'shipping' && isCheckoutPage ){ 1351 this.notice.add( xoo_wsc_params.strings.calculateCheckout, 'error' ); 1352 this.notice.showNotification(); 1353 return; 1354 } 1355 1356 1357 this.$modal.attr( 'data-slider', slider ); 1358 1359 this.toggle(); 1360 1361 this.toggleContent(); 1362 } 1363 1364 1365 toggleContent(){ 1366 1367 var activeSlider = ''; 1368 1369 $('.xoo-wsc-sl-content').hide(); 1370 1371 var activeSlider = this.$modal.attr('data-slider'), 1372 $toggleEl = $('.xoo-wsc-sl-content[data-slider="'+activeSlider+'"]'); 1373 1374 if( $toggleEl.length ) $toggleEl.show(); 1375 1376 if( activeSlider === 'savelater' && this.isOpen() ){ 1377 initMasonryLayout('saveLater'); 1378 } 1379 1380 $( document.body ).trigger( 'xoo_wsc_slider_data_toggled', [activeSlider] ); 1381 } 1382 1383 1384 applyCoupon( coupon ){ 1385 1386 if( !coupon ){ 1387 this.notice.add( xoo_wsc_params.strings.couponEmpty, 'error' ); 1388 this.notice.showNotification(); 1389 return; 1390 } 1391 1392 this.block(); 1393 1394 var formData = { 1395 'coupon': coupon, 1396 } 1397 1398 $.ajax( { 1399 url: get_wcurl('xoo_wsc_apply_coupon'), 1400 type: 'POST', 1401 context: this, 1402 data: this.setAjaxData( formData ), 1403 success: function( response ) { 1404 this.updateFragments(response); 1405 }, 1406 complete: function() { 1407 this.unblock(); 1408 this.updateCartCheckoutPage(); 1409 $( document.body ).trigger( 'xoo_wsc_coupon_applied' ); 1410 } 1411 } ); 1412 1413 } 1414 1415 } 1416 1417 1418 1419 var Shipping = { 1420 1421 init: function( slider ){ 1422 slider.$modal.on( 'change', 'input.xoo-wsc-shipping-method', this.shippingMethodChange ); 1423 slider.$modal.on( 'submit', 'form.woocommerce-shipping-calculator', this.shippingCalculatorSubmit ); 1424 slider.$modal.on( 'click', '.shipping-calculator-button', this.toggleCalculator ); 1425 $(document.body).on( 'wc_fragments_loaded xoo_wsc_slider_data_toggled', this.initSelect2 ); 1426 }, 1427 1428 toggleCalculator: function(e){
1429 1430 e.preventDefault(); 1431 e.stopImmediatePropagation(); 1432 1433 $(this).siblings('.shipping-calculator-form').slideToggle(); 1434 $( document.body ).trigger( 'country_to_state_changed' ); 1435 }, 1436 1437 shippingCalculatorSubmit: function(e){ 1438 1439 e.preventDefault(); 1440 e.stopImmediatePropagation(); 1441 1442 var $form = $(this); 1443 1444 slider.block(); 1445 1446 // Provide the submit button value because wc-form-handler expects it. 1447 $( '<input />' ) 1448 .attr( 'type', 'hidden' ) 1449 .attr( 'name', 'calc_shipping' ) 1450 .attr( 'value', 'x' ) 1451 .appendTo( $form ); 1452 1453 var formData = $form.serialize(); 1454 1455 // Make call to actual form post URL. 1456 $.ajax( { 1457 url: get_wcurl( 'xoo_wsc_calculate_shipping' ), 1458 type: 'POST', 1459 context: this, 1460 data: slider.setAjaxData(formData), 1461 success: function( response ) { 1462 slider.updateFragments(response); 1463 }, 1464 complete: function() { 1465 slider.unblock(); 1466 slider.updateCartCheckoutPage(); 1467 $( document.body ).trigger( 'xoo_wsc_shipping_calculated' ); 1468 } 1469 } ); 1470 1471 }, 1472 1473 shippingMethodChange: function(e){ 1474 1475 e.preventDefault(); 1476 e.stopImmediatePropagation(); 1477 1478 var shipping_methods = {}; 1479 1480 slider.block(); 1481 1482 $( 'select.shipping_method, :input[name^=xoo-wsc-shipping_method][type=radio]:checked, :input[name^=shipping_method][type=hidden]' ).each( function() { 1483 shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val(); 1484 } ); 1485 1486 var formData = { 1487 shipping_method: shipping_methods, 1488 } 1489 1490 $.ajax( { 1491 type: 'POST', 1492 url: get_wcurl( 'xoo_wsc_update_shipping_method' ), 1493 data: slider.setAjaxData( formData ), 1494 success: function( response ) { 1495 slider.updateFragments(response); 1496 }, 1497 complete: function() { 1498 slider.unblock(); 1499 slider.updateCartCheckoutPage(); 1500 $( document.body ).trigger( 'updated_shipping_method' ); 1501 } 1502 } ); 1503 1504 }, 1505 1506 initSelect2: function(e){ 1507 $( document.body ).trigger( 'country_to_state_changed' ); 1508 }, 1509 } 1510 1511 1512 var cart = new Cart( $('.xoo-wsc-modal') ), 1513 slider = new Slider( $('.xoo-wsc-slider-modal') ); 1514 drawer = new Drawer( $('.xoo-wsc-drawer-modal') ); 1515 1516 1517 var AnimateCard = { 1518 1519 type: xoo_wsc_params.cardAnimate.type, 1520 duration: xoo_wsc_params.cardAnimate.duration, 1521 1522 init: function(){ 1523 1524 var onEvent = xoo_wsc_params.cardAnimate.event === 'back_hover' ? 'mouseenter' : 'click'; 1525 1526 $('body').on( onEvent, '.xoo-wsc-has-back', this.animate ); 1527 $('body').on( 'mouseleave', '.xoo-wsc-has-back', this.reverseAnimate ); 1528 1529 }, 1530 animate: function(e){ 1531 1532 if( e.target.classList.contains('xoo-wsc-smr-del') ) return; 1533 1534 var $img = $(this).find('.xoo-wsc-img-col'); 1535 1536 if( !$img.hasClass('xoo-wsc-caniming') ){ 1537 e.preventDefault(); 1538 } 1539 else{ 1540 return; 1541 } 1542 1543 $img.attr('data-exclasses', $img.attr('class') ); 1544 1545 $img.removeClass() 1546 $img.addClass($img.attr('data-exclasses')); 1547 1548 $img.addClass( 'xoo-wsc-caniming' + ' ' + AnimateCard.type ); 1549 1550 }, 1551 reverseAnimate: function(){ 1552 1553 var $img = $(this).find('.xoo-wsc-img-col'); 1554 1555 if( !$img.hasClass( 'xoo-wsc-caniming' ) ) return; 1556 1557 $img.addClass(AnimateCard.type+'Return'); 1558 1559 AnimateCard.clear = setTimeout(function(){ 1560 $img.removeClass().addClass( $img.attr('data-exclasses') ); 1561 }, AnimateCard.duration * 1000); 1562 1563 } 1564 } 1565 1566 if( xoo_wsc_params.cardAnimate.enable === "yes" ){ 1567 AnimateCard.init(); 1568 } 1569 1570 1571 1572 var Celebrate = { 1573 1574 canvasIndex: 0, 1575 1576 myconfetti: '', 1577 1578 Celebrate: async function( $bar, celebrationName ){ 1579 1580 if (typeof Celebrate[celebrationName] !== 'function') return; 1581 1582 const index = Celebrate.canvasIndex++; 1583 1584 const myconfetti = await Celebrate.CreateCanvas(index); 1585 1586 const barPos = Celebrate.BarPosition( $bar ); 1587 1588 Celebrate[celebrationName](myconfetti, barPos); 1589 1590 }, 1591 1592 CreateCanvas: async function(index){ 1593 1594 const canvasID = 'xoo_canvas_' + index; 1595 1596 // Append a fresh canvas for this celebration 1597 $('.xoo-wsc-container').append('<canvas id="'+canvasID+'"></canvas>').show(); 1598 1599 const canvas = document.getElementById(canvasID); 1600 1601 // Create a separate confetti instance for this canvas 1602 return await confetti.create(canvas, { resize: true });
1603 1604 }, 1605 1606 BarPosition: function( $bar ){ 1607 1608 var windowHeight = $(window).height(), 1609 $barPole = $bar.find('.xoo-wsc-bar'); 1610 1611 var barPosition = $barPole.offset().top - $(window).scrollTop(); 1612 1613 Celebrate.barPosition = barPosition/windowHeight; 1614 1615 return Celebrate.barPosition; 1616 1617 }, 1618 1619 Fireworks: function( myconfetti, barPos ){ 1620 const duration = 3 * 1000, 1621 animationEnd = Date.now() + duration, 1622 defaults = { startVelocity: 30, spread: 100, ticks: 60, zIndex: 0 }; 1623 1624 function randomInRange(min, max) { 1625 return Math.random() * (max - min) + min; 1626 } 1627 1628 const interval = setInterval(function(){ 1629 const timeLeft = animationEnd - Date.now(); 1630 if (timeLeft <= 0) return clearInterval(interval); 1631 1632 const particleCount = 50 * (timeLeft / duration); 1633 1634 myconfetti(Object.assign({}, defaults, { 1635 particleCount, 1636 origin: { x: randomInRange(0.1, 0.3), y: barPos } 1637 })); 1638 1639 myconfetti(Object.assign({}, defaults, { 1640 particleCount, 1641 origin: { x: randomInRange(0.7, 0.9), y: barPos } 1642 })); 1643 1644 }, 250); 1645 }, 1646 1647 Stars: function( myconfetti, barPos ){ 1648 1649 const defaults = { 1650 origin: { x: 0.5, y: barPos }, 1651 spread: 360, 1652 ticks: 50, 1653 gravity: 0, 1654 decay: 0.94, 1655 startVelocity: 30, 1656 shapes: ["star"], 1657 colors: ["FFE400", "FFBD00", "E89400", "FFCA6C", "FDFFB8"], 1658 }; 1659 1660 function shoot() { 1661 myconfetti({ 1662 ...defaults, 1663 particleCount: 40, 1664 scalar: 1, 1665 shapes: ["star"], 1666 }); 1667 1668 myconfetti({ 1669 ...defaults, 1670 particleCount: 10, 1671 scalar: 0.75, 1672 shapes: ["circle"], 1673 }); 1674 } 1675 1676 setTimeout(shoot, 0); 1677 setTimeout(shoot, 100); 1678 setTimeout(shoot, 200); 1679 }, 1680 1681 SchoolPride: function( myconfetti, barPos ){ 1682 1683 const end = Date.now() + 1.5 * 1000; 1684 1685 // go Buckeyes! 1686 const colors = ["#bb0000", "#ffffff"]; 1687 1688 (function frame() { 1689 myconfetti({ 1690 particleCount: 2, 1691 angle: 60, 1692 spread: 55, 1693 origin: { x: 0, y: barPos }, 1694 colors: colors, 1695 }); 1696 1697 myconfetti({ 1698 particleCount: 2, 1699 angle: 120, 1700 spread: 55, 1701 origin: { x: 1, y: barPos }, 1702 colors: colors, 1703 }); 1704 1705 if (Date.now() < end) { 1706 requestAnimationFrame(frame); 1707 } 1708 })(); 1709 }, 1710 1711 RealisticLook: function( myconfetti, barPos ){ 1712 1713 const count = 1000, 1714 1715 defaults = { 1716 origin: { y: barPos }, 1717 }; 1718 1719 function fire(particleRatio, opts) { 1720 myconfetti( 1721 Object.assign({}, defaults, opts, { 1722 particleCount: Math.floor(count * particleRatio), 1723 }) 1724 ); 1725 } 1726 1727 fire(0.25, { 1728 spread: 26, 1729 startVelocity: 55, 1730 }); 1731 1732 fire(0.2, { 1733 spread: 60, 1734 }); 1735 1736 fire(0.35, { 1737 spread: 100, 1738 decay: 0.91, 1739 scalar: 0.8, 1740 }); 1741 1742 fire(0.1, { 1743 spread: 120, 1744 startVelocity: 25, 1745 decay: 0.92, 1746 scalar: 1.2, 1747 }); 1748 1749 fire(0.1, { 1750 spread: 120, 1751 startVelocity: 45, 1752 }); 1753 }, 1754 1755 BasicCannon: function( myconfetti, barPos ){ 1756 myconfetti({ 1757 particleCount: 400, 1758 spread: 70, 1759 origin: { y: barPos }, 1760 }); 1761 } 1762 1763 } 1764 1765 1766 1767 var scrollBarWidth = window.innerWidth - document.documentElement.clientWidth; 1768 1769 $('<style>') 1770 .prop('type', 'text/css') 1771 .html('body.xoo-wsc-cart-active { padding-right: ' + scrollBarWidth + 'px; }') 1772 .appendTo('head'); 1773 }) 1774
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.