https://www.obdlink.com/wp-content/plugins/side-cart-woocommerce/assets/js/xoo-wsc-main.js?ver=2.8.0
1jQuery(document).ready(function($){ 2 3 var isCartPage = xoo_wsc_params.isCart == '1', 4 isCheckoutPage = xoo_wsc_params.isCheckout == '1'; 5 6 var get_wcurl = function( endpoint ) { 7 return xoo_wsc_params.wc_ajax_url.toString().replace( 8 '%%endpoint%%', 9 endpoint 10 ); 11 }; 12 13 14 var markupTimeout = null; 15 16 var Notice = { 17 18 timeout: null, 19 20 markupTimeout: null, 21 22 $cartNoticeCont: function(){ 23 return $('.xoo-wsc-markup').find('.xoo-wsc-notice-container'); 24 }, 25 26 $markupNoticeCont: function(){ 27 return $('.xoo-wsc-markup-notices') 28 }, 29 30 add: function( notice, type = 'success', clearPrevious = true ){ 31 32 if( clearPrevious ){ 33 Notice.$cartNoticeCont().html(''); 34 } 35 36 var noticeHTML = type === 'success' ? xoo_wsc_params.html.successNotice.toString().replace( '%s%', notice ) : xoo_wsc_params.html.errorNotice.toString().replace( '%s%', notice ); 37 38 Notice.$cartNoticeCont().html( noticeHTML ); 39 40 }, 41 42 43 setHTML: function(noticeHTML){ 44 Notice.$cartNoticeCont().add( Notice.$markupNoticeCont() ).html(noticeHTML); 45 }, 46 47 showNotification: function(){ 48 49 if( !cart.isOpen() ){ 50 Notice.showMarkupNotice(); 51 return; 52 } 53 54 Notice.$cartNoticeCont().slideDown(); 55 56 clearTimeout(Notice.timeout); 57 58 Notice.timeout = setTimeout(function(){ 59 Notice.$cartNoticeCont().slideUp('slow'); 60 }, xoo_wsc_params.notificationTime ); 61 62 }, 63 64 65 hideNotification: function(){ 66 Notice.$cartNoticeCont().hide(); 67 }, 68 69 hideMarkupNotice: function(){ 70 Notice.$markupNoticeCont().removeClass('xoo-wsc-active'); 71 }, 72 73 74 showMarkupNotice: function(){ 75 76 var $markupNotice = Notice.$markupNoticeCont(); 77 78 var $noticeCont = $markupNotice.find('.xoo-wsc-notice-container .xoo-wsc-notices'); 79 80 if( !$noticeCont.length || $noticeCont.children().length === 0 ) return; 81 82 setTimeout(function(){$markupNotice.addClass('xoo-wsc-active')},10); 83 84 clearTimeout(Notice.markupTimeout); 85 86 Notice.markupTimeout = setTimeout(function(){ 87 $markupNotice.removeClass('xoo-wsc-active'); 88 },xoo_wsc_params.notificationTime ) 89 } 90 } 91 92 class Container{ 93 94 constructor( $modal, container ){ 95 this.$modal = $modal; 96 this.container = container || 'cart'; 97 } 98 99 isOpen(){ 100 return this.$modal.hasClass('xoo-wsc-'+this.container+'-active'); 101 } 102 103 eventHandlers(){ 104 $(document.body).on( 'wc_fragments_loaded updated_checkout', this.onCartUpdate.bind(this) ); 105 } 106 107 onCartUpdate(){ 108 this.unblock(); 109 Notice.showNotification(); 110 } 111 112 setAjaxData( data, noticeSection ){ 113 114 var ajaxData = { 115 container: this.container, 116 noticeSection: noticeSection || this.noticeSection || this.container, 117 isCheckout: isCheckoutPage, 118 isCart: isCartPage 119 } 120 121 122 if( typeof data === 'object' ){ 123 124 $.extend( ajaxData, data ); 125 126 } 127 else{ 128 129 var serializedData = data; 130 131 $.each( ajaxData, function( key, value ){ 132 serializedData += ( '&'+key+'='+value ); 133 } ) 134 135 ajaxData = serializedData; 136 137 } 138 139 return ajaxData; 140 } 141 142 143 toggle( type ){ 144 145 var $activeEls = this.$modal.add( 'body' ).add('html'), 146 activeClass = 'xoo-wsc-'+ this.container +'-active'; 147 148 if( type === 'show' ){ 149 $activeEls.addClass(activeClass); 150 } 151 else if( type === 'hide' ){ 152 $activeEls.removeClass(activeClass); 153 } 154 else{ 155 $activeEls.toggleClass(activeClass); 156 } 157 158 $(document.body).trigger( 'xoo_wsc_' + this.container + '_toggled', [ type ] ); 159 160 Notice.hideNotification(); 161 162 } 163 164 165 block(){ 166 this.$modal.addClass('xoo-wsc-loading'); 167 } 168 169 unblock(){ 170 this.$modal.removeClass('xoo-wsc-loading'); 171 } 172 173 174 refreshMyFragments(){ 175 176 if( xoo_wsc_params.refreshCart === "yes" && typeof wc_cart_fragments_params !== 'undefined' ){ 177 $( document.body ).trigger( 'wc_fragment_refresh' ); 178 return; 179 } 180 181 this.block(); 182 183 $.ajax({ 184 url: get_wcurl( 'xoo_wsc_refresh_fragments' ), 185 type: 'POST', 186 context: this, 187 data: {}, 188 success: function( response ){ 189 this.updateFragments(response); 190 }, 191 complete: function(){ 192 this.unblock(); 193 } 194 }) 195 196 } 197 198 199 updateCartCheckoutPage(){ 200 201 //Refresh checkout page 202 if( isCheckoutPage ){ 203 if( $( 'form.checkout' ).length === 0 ){ 204 location.reload(); 205 return; 206 } 207 $(document.body).trigger("update_checkout"); 208 } 209 210 //Refresh Cart page 211 if( isCartPage ){ 212 $(document.body).trigger("wc_update_cart"); 213 } 214 215 } 216 217 updateFragments( response ){ 218 219 if( response.fragments ){ 220 221 $( document.body ).trigger( 'xoo_wsc_before_loading_fragments', [ response ] ); 222 223 this.block(); 224 225 //Set fragments 226 $.each( response.fragments, function( key, value ) { 227 $( key ).replaceWith( value ); 228 }); 229 230 if( typeof wc_cart_fragments_params !== 'undefined' && ( 'sessionStorage' in window && window.sessionStorage !== null ) ){ 231 232 sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( response.fragments ) ); 233 localStorage.setItem( wc_cart_fragments_params.cart_hash_key, response.cart_hash ); 234 sessionStorage.setItem( wc_cart_fragments_params.cart_hash_key, response.cart_hash ); 235 236 if ( response.cart_hash ) { 237 sessionStorage.setItem( 'wc_cart_created', ( new Date() ).getTime() ); 238 } 239 240 } 241 242 $( document.body ).trigger( 'wc_fragments_loaded' ); 243 244 this.unblock(); 245 246 } 247 248 if( xoo_wsc_params.refreshCart === "yes" && typeof wc_cart_fragments_params !== 'undefined' ){ 249 this.block(); 250 $( document.body ).trigger( 'wc_fragment_refresh' ); 251 return; 252 } 253 254 } 255 256 } 257 258 259 class Cart extends Container{ 260 261 static isWCAjaxAddToCart = false; 262 263 constructor( $modal ){ 264 265 super( $modal, 'cart' ); 266 267 this.cartLoaded = false; 268 this.blockAddedToCartCalled = false; 269 this.baseQty = 1; 270 this.qtyUpdateDelay = null; 271 272 this.refreshFragmentsOnPageLoad(); 273 this.eventHandlers(); 274 275 } 276 277 278 refreshFragmentsOnPageLoad(){ 279 if( xoo_wsc_params.fetchCart === 'page_load' ){ 280 setTimeout(function(){ 281 this.refreshMyFragments(); 282 }.bind(this), xoo_wsc_params.fetchDelay ) 283 } 284 } 285 286 eventHandlers(){ 287 288 super.eventHandlers(); 289 290 this.$modal.on( 'click', '.xoo-wsc-chng', this.toggleQty.bind(this) ); 291 this.$modal.on( 'change', '.xoo-wsc-qty', this.changeInputQty.bind(this) ); 292 this.$modal.on( 'click', '.xoo-wsc-smr-del', this.deleteIconClick.bind(this) ); 293 this.$modal.on( 'click', '.xoo-wsch-close, .xoo-wsc-opac, .xoo-wsc-cart-close', this.closeCartOnClick.bind(this) ); 294 this.$modal.on( 'click', '.xoo-wsc-basket', this.toggleCart.bind(this) ); 295 296 $(document.body).on( 'xoo_wsc_cart_updated', this.updateCartCheckoutPage.bind(this) ); 297 $(document.body).on( 'click', 'a.added_to_cart, .xoo-wsc-cart-trigger', this.openCart.bind(this) ); 298 $(document.body).on( 'added_to_cart', this.addedToCart.bind(this) ); 299 300 $(document.body).on( 'wc-blocks_added_to_cart', this.blockAddedToCart.bind(this) ); 301 302 $(document.body).on( 'adding_to_cart', this.checkIfWCAjaxAddToCart.bind(this) ); 303 304 if( xoo_wsc_params.autoOpenCart === 'yes' && xoo_wsc_params.addedToCart === 'yes'){ 305 this.openCart(); 306 } 307 308 if( xoo_wsc_params.ajaxAddToCart === 'yes' ){ 309 $(document.body).on( 'submit', 'form.cart', this.addToCartFormSubmit.bind(this) ); 310 } 311 312 if( typeof wc_cart_fragments_params === 'undefined' ){ 313 $( window ).on( 'pageshow' , this.onPageShow.bind(this) ); 314 } 315 316 if( xoo_wsc_params.triggerClass ){ 317 $(document.body).on( 'click', '.'+xoo_wsc_params.triggerClass, this.openCart.bind(this) ); 318 } 319 320 321 if( isCheckoutPage || isCartPage ){ 322 $(document.body).on( 'updated_shipping_method', this.refreshMyFragments.bind(this) ); 323 } 324 325 this.initMasonryLayout(); 326 327 } 328 329 toggleQty(e){ 330 331 var $toggler = $(e.currentTarget), 332 $input = $toggler.siblings('.xoo-wsc-qty'); 333 334 if( !$input.length ) return; 335 336 var baseQty = this.baseQty = parseFloat( $input.val() ), 337 step = parseFloat( $input.attr('step') ), 338 action = $toggler.hasClass( 'xoo-wsc-plus' ) ? 'add' : 'less', 339 newQty = action === 'add' ? baseQty + step : baseQty - step; 340 341 342 $input.val(newQty).trigger('change'); 343 344 } 345 346 changeInputQty(e){ 347 348 Notice.hideNotification(); 349 350 var $_this = this, 351 $input = $(e.currentTarget), 352 newQty = parseFloat( $input.val() ), 353 step = parseFloat( $input.attr('step') ), 354 min = parseFloat( $input.attr('min') ), 355 max = parseFloat( $input.attr('max') ), 356 invalid = false, 357 message = false; 358 359 //Validation 360 361 if( isNaN( newQty ) || newQty < 0 || newQty < min ){ 362 invalid = true; 363 } 364 else if( newQty > max ){ 365 invalid = true;
366 message = xoo_wsc_params.strings.maxQtyError.replace( '%s%', max ); 367 } 368 else if( !Number.isInteger(newQty/step ) ){ 369 invalid = true; 370 message = xoo_wsc_params.strings.stepQtyError.replace( '%s%', step ); 371 } 372 373 //Set back to default quantity 374 if( invalid ){ 375 $input.val( this.baseQty ); 376 if( message ){ 377 Notice.add( message, 'error' ); 378 Notice.showNotification(); 379 } 380 return; 381 } 382 383 //Update 384 $input.val( newQty ); 385 386 clearTimeout( this.qtyUpdateDelay ); 387 388 this.qtyUpdateDelay = setTimeout(function(){ 389 $_this.updateItemQty( $input.parents('.xoo-wsc-product').data('key'), newQty ) 390 }, xoo_wsc_params.qtyUpdateDelay ); 391 392 393 } 394 395 updateItemQty( cart_key, qty ){ 396 397 if( !cart_key || qty === undefined ) return; 398 399 this.block(); 400 401 this.saveScrollPosition(); 402 403 var formData = { 404 cart_key: cart_key, 405 qty: qty 406 } 407 408 $.ajax({ 409 url: get_wcurl( 'xoo_wsc_update_item_quantity' ), 410 type: 'POST', 411 context: this, 412 data: this.setAjaxData(formData), 413 success: function(response){ 414 this.updateFragments( response ); 415 $(document.body).trigger( 'xoo_wsc_quantity_updated', [response] ); 416 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 417 this.setScrollPosition(); 418 this.unblock(); 419 } 420 421 }) 422 } 423 424 checkIfWCAjaxAddToCart(e, $button, data){ 425 426 Cart.isWCAjaxAddToCart = true; 427 428 if( ( !(data instanceof FormData) || !data.has('action') || !data.get('action') === 'xoo_wsc_add_to_cart' ) && $button.hasClass('ajax_add_to_cart') ){ 429 this.isWCAjaxAddToCart = true; 430 } 431 } 432 433 toggleCart(e){ 434 if( this.isOpen() ){ 435 this.closeCartOnClick(e); 436 } 437 else{ 438 this.openCart(e); 439 } 440 441 } 442 443 openCart(e){ 444 if( e ){ 445 e.preventDefault(); 446 e.stopImmediatePropagation(); 447 } 448 449 if( !this.cartLoaded && xoo_wsc_params.fetchCart === 'cart_open' ){ 450 this.refreshMyFragments(); 451 this.cartLoaded = true; 452 } 453 454 this.toggle('show'); 455 Notice.hideMarkupNotice(); 456 } 457 458 addToCartFormSubmit(e){ 459 460 var $form = $(e.currentTarget); 461 462 if( $form.closest('.product').hasClass('product-type-external') || $form.siblings('.xoo-wsc-disable-atc').length ) return; 463 464 var $button = e.originalEvent && e.originalEvent.submitter ? $(e.originalEvent.submitter) : $form.find( 'button[type="submit"]'), 465 formData = new FormData($form.get(0)), 466 productData = $form.serializeArray(), 467 hasProductId = false; 468 469 //Check for woocommerce custom quantity code 470 //https://docs.woocommerce.com/document/override-loop-template-and-show-quantities-next-to-add-to-cart-buttons/ 471 $.each( productData, function( key, form_item ){ 472 if( form_item.name === 'productID' || form_item.name === 'add-to-cart' ){ 473 if( form_item.value ){ 474 hasProductId = true; 475 return false; 476 } 477 } 478 }) 479 480 //If no product id found , look for the form action URL 481 if( !hasProductId && $form.attr('action') ){ 482 var is_url = $form.attr('action').match(/add-to-cart=([0-9]+)/), 483 productID = is_url ? is_url[1] : false; 484 } 485 486 // Add submitted button value 487 if( $button.attr('name') && $button.attr('value') ){ 488 formData.append( $button.attr('name'), $button.attr('value') ); 489 } 490 491 if( productID ){ 492 formData.append( 'add-to-cart', productID ); 493 } 494 495 formData.append( 'action', 'xoo_wsc_add_to_cart' ); 496 497 var doAjaxAddToCart = true; 498 499 500 $.each( xoo_wsc_params.skipAjaxForData, function( key, value ){ 501 if( formData.has(key) && ( !value || formData.get(key) == value ) ){ 502 doAjaxAddToCart = false; 503 return false; 504 } 505 } ) 506 507 508 if( doAjaxAddToCart ){ 509 e.preventDefault(); 510 this.addToCartAjax( $button, formData );//Ajax add to cart 511 } 512 513 } 514 515 516 addToCartAjax( $button, formData ){ 517 518 this.block(); 519 520 $button.addClass('loading'); 521 522 // Trigger event. 523 $( document.body ).trigger( 'adding_to_cart', [ $button, formData ] ); 524 525 $.ajax({
526 url: get_wcurl( 'xoo_wsc_add_to_cart' ), 527 type: 'POST', 528 context: this, 529 cache: false, 530 contentType: false, 531 processData: false, 532 data: formData, 533 success: function(response){ 534 535 if(response.fragments){ 536 // Trigger event so themes can refresh other areas. 537 $( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $button ] ); 538 }else if(response.error){ 539 Notice.setHTML(response.notice); 540 Notice.showNotification(); 541 } 542 else{ 543 window.location.reload(); 544 } 545 546 }, 547 complete: function(){ 548 this.unblock(); 549 $button 550 .removeClass('loading') 551 .addClass('added'); 552 } 553 }) 554 } 555 556 addedToCart( e, response, hash, $button ){ 557 558 var _this = this; 559 560 this.updateFragments( { fragments: response } ); 561 562 if( xoo_wsc_params.autoOpenCart === "yes" ){ 563 _this.openCart(); 564 } 565 566 this.onCartUpdate(); 567 568 } 569 570 blockAddedToCart(){ 571 572 if( !Cart.isWCAjaxAddToCart && !this.blockAddedToCartCalled ){ 573 574 this.refreshMyFragments(); 575 576 var _this = this; 577 578 if( xoo_wsc_params.autoOpenCart === "yes" ){ 579 setTimeout(function(){ 580 _this.openCart(); 581 },20 ) 582 } 583 584 this.blockAddedToCartCalled = true; 585 586 setTimeout( function(){ 587 _this.blockAddedToCartCalled = false; 588 }, 200 ); 589 590 Cart.isWCAjaxAddToCart = false; 591 592 } 593 594 595 596 } 597 598 599 closeCartOnClick(e){ 600 e.preventDefault(); 601 this.toggle( 'hide' ); 602 } 603 604 605 onPageShow(e){ 606 if ( e.originalEvent.persisted ) { 607 this.refreshMyFragments(); 608 $( document.body ).trigger( 'wc_fragment_refresh' ); 609 } 610 } 611 612 deleteIconClick(e){ 613 this.updateItemQty( $( e.currentTarget ).parents('.xoo-wsc-product').data('key'), 0 ); 614 } 615 616 updateItemQty( cart_key, qty ){ 617 618 if( !cart_key || qty === undefined ) return; 619 620 this.block(); 621 622 var formData = { 623 cart_key: cart_key, 624 qty: qty 625 } 626 627 $.ajax({ 628 url: get_wcurl( 'xoo_wsc_update_item_quantity' ), 629 type: 'POST', 630 context: this, 631 data: this.setAjaxData(formData), 632 success: function(response){ 633 this.updateFragments( response ); 634 $(document.body).trigger( 'xoo_wsc_quantity_updated', [response] ); 635 $(document.body).trigger( 'xoo_wsc_cart_updated', [response] ); 636 this.unblock(); 637 } 638 639 }) 640 } 641 642 onCartUpdate(){ 643 super.onCartUpdate(); 644 this.cartLoaded = true; 645 this.toggleBasket(); 646 this.initMasonryLayout(); 647 } 648 649 650 initMasonryLayout(){ 651 if( xoo_wsc_params.productLayout !== 'cards' ) return; 652 $('.xoo-wsc-products.xoo-wsc-pattern-card').masonry({ 653 // options 654 itemSelector: '.xoo-wsc-product-cont', 655 columnWidth: '.xoo-wsc-product-cont', /* Each column takes 50% */ 656 percentPosition: true 657 }); 658 } 659 660 661 toggleBasket(){ 662 663 var $basket = $('.xoo-wsc-basket'), 664 show = xoo_wsc_params.showBasket, 665 hasProducts = this.$modal.find('.xoo-wsc-product').length; 666 667 if( show === "always_show" ){ 668 $basket.show(); 669 } 670 else if( show === "hide_empty" ){ 671 if( hasProducts){ 672 $basket.show(); 673 } 674 else{ 675 $basket.hide(); 676 } 677 } 678 else{ 679 $basket.hide(); 680 } 681 682 var $shortcode = $('.xoo-wsc-sc-cont'); 683 684 if( $shortcode.length && xoo_wsc_params.menuCartHideOnEmpty.length ){ 685 686 var shortcodeEls = xoo_wsc_params.shortcodeEls; 687 688 $.each( xoo_wsc_params.menuCartHideOnEmpty, function( index, val ){ 689 690 if( shortcodeEls[val] ){ 691 if( hasProducts ){ 692 $(shortcodeEls[val]).show(); 693 } 694 else{ 695 $(shortcodeEls[val]).hide(); 696 } 697 } 698 699 }) 700 701 } 702 } 703 704 705 706 } 707 708 709 710 711 var cart = new Cart( $('.xoo-wsc-modal') ); 712 713 714 var AnimateCard = { 715 716 type: xoo_wsc_params.cardAnimate.type, 717 duration: xoo_wsc_params.cardAnimate.duration, 718 719 init: function(){ 720 721 var onEvent = xoo_wsc_params.cardAnimate.event === 'back_hover' ? 'mouseenter' : 'click'; 722 723 $('body').on( onEvent, '.xoo-wsc-has-back', this.animate ); 724 $('body').on( 'mouseleave', '.xoo-wsc-has-back', this.reverseAnimate ); 725 726 }, 727 animate: function(e){
728 729 if( e.target.classList.contains('xoo-wsc-smr-del') ) return; 730 731 var $img = $(this).find('.xoo-wsc-img-col'); 732 733 if( !$img.hasClass('xoo-wsc-caniming') ){ 734 e.preventDefault(); 735 } 736 else{ 737 return; 738 } 739 740 $img.attr('data-exclasses', $img.attr('class') ); 741 742 $img.removeClass() 743 $img.addClass($img.attr('data-exclasses')); 744 745 $img.addClass( 'xoo-wsc-caniming' + ' ' + AnimateCard.type ); 746 747 }, 748 reverseAnimate: function(){ 749 750 var $img = $(this).find('.xoo-wsc-img-col'); 751 752 if( !$img.hasClass( 'xoo-wsc-caniming' ) ) return; 753 754 $img.addClass(AnimateCard.type+'Return'); 755 756 AnimateCard.clear = setTimeout(function(){ 757 $img.removeClass().addClass( $img.attr('data-exclasses') ); 758 }, AnimateCard.duration * 1000); 759 760 } 761 } 762 763 if( xoo_wsc_params.cardAnimate.enable === "yes" ){ 764 AnimateCard.init(); 765 } 766 767 768})
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.