1PRH = {}; 2 3// Wait for jQuery before executing this entire module 4;(function() { 5 var waitForJQuery = function(callback) { 6 if (window.$ || window.jQuery) { 7 callback(); 8 } else { 9 var checkInterval = setInterval(function() { 10 if (window.$ || window.jQuery) { 11 clearInterval(checkInterval); 12 callback(); 13 } 14 }, 50); 15 } 16 }; 17 18 waitForJQuery(function() { 19 (function( $, PRH ) { 20 21 PRH.minicart = { 22 23 firstLoad: false, // Have we loaded the cart for the first time on this page 24 25 cartRequestTimer: null, // Timer ID for the cart request timeout 26 cartRequestTimeout: 30000, // Timeout duration (30 seconds) 27 pendingCartRequest: false, // Flag to track if a request is pending 28 isInOutageMode: false, // Flag to ignore late responses after showing outage 29 30 // Create DOM elements, initialize values 31 init: function () { 32 33 // console.log('minicart init'); 34 35 if ($('#prh-minicart').length) return false; 36 37 $(window).on("message", PRH.minicart.messages); 38 39 var cartUrl = window[$('#prh-minicart-js').data('cart-url-var')]; 40 var cartCookieDomain = cartUrl.replace(/^.*\.([^\.]+)\.([^\.]+)$/, '.$1.$2'); 41 42 var cartTypeHTML = '<div class="minicart-carttype-ribbon" tabindex="0">\ 43 <span>You\'re shopping as a PRH employee!</span> <div class="minicart-carttype-tooltip-icon img-info-icon" tabindex="0"></div>\ 44 <div class="minicart-carttype-tooltip">\ 45 Please see the <a href="https://igloo.penguinrandomhouse.com/human-resources/discounts/books/penguin-random-house-employee-discounted-book-order/" target="_blank">FAQ</a> for further ordering details.\ 46 <div class="minicart-carttype-tooltip-post"></div>\ 47 </div>\ 48 </div>'; 49 50 var minicartSrc = 'about:blank'; 51 52 $('<div id="prh-minicart" style="display: none;" tabindex="0" aria-hidden="true" aria-labelledby="prh-minicart-description">\ 53 <div class="minicart-screenreader-text" id="prh-minicart-description">\ 54 Shopping cart\ 55 </div>\ 56 <div class="minicart-outer-wrap">\ 57 <div class="minicart-inner-wrap">\ 58 <div class="minicart-header">\ 59 <div class="minicart-close-x img-close-x" tabindex="0" aria-label="Close shopping cart button"></div>Shopping Cart (<span class="minicart-qty">0</span>)\ 60 </div>\ 61 <div class="minicart-body">\ 62 <iframe id="prh-minicart-iframe" name="prh-minicart-iframe" src="' + minicartSrc + '"></iframe>\ 63 <div class="minicart-lineitems">' + cartTypeHTML + '</div>\ 64 <div class="minicart-empty img-empty-mini-cart"></div>\ 65 <div class="minicart-empty-text" tabindex="0">Your cart is empty.</div>\ 66 <div class="minicart-down img-down-mini-cart"></div>\ 67 <div class="minicart-down-text" tabindex="0"><b>OUR SHOPPING CART IS TEMPORARILY UNDERGOING MAINTENANCE.</b><br/><br/>We apologize for any<br>inconvenience.</div>\ 68 </div>' 69 + cartTypeHTML + 70 '<div class="minicart-footer">\ 71 <div class="minicart-checkout">\ 72 <div class="minicart-total-price">$<span>0.00</span></div>\ 73 <div class="minicart-total">Total <span class="minicart-total-qty">(<span class="minicart-qty">0</span> item<span class="minicart-total-qty-plural">s</span>)</span></div>\ 74 <button style="display: block;">CHECKOUT</button>\ 75 </div>\ 76 <div class="minicart-free-shipping"><div class="img-shipping-fast"></div>Spend <span>$3 more</span> for free shipping!</div>\ 77 <div class="minicart-continue-shopping">\ 78 <button>CONTINUE SHOPPING</button>\ 79 </div>\ 80 </div>\ 81 </div>\ 82 </div>\ 83 <template id="minicart-lineitem">\ 84 <div class="minicart-lineitem">\ 85 <div class="minicart-lineitem-cover"><a><img></a><div class="minicart-lineitem-qty"></div></div>\ 86 <div class="minicart-lineitem-right">\
87 <div class="minicart-lineitem-title"></div>\ 88 <div class="minicart-lineitem-author"></div>\ 89 <div class="minicart-lineitem-format"></div>\ 90 <div class="minicart-lineitem-orig-price"></div>\ 91 <div class="minicart-lineitem-cmd" role="button" tabindex="0" aria-label="Remove"><div class="img-remove-x"></div>Remove</div>\ 92 <div class="minicart-lineitem-price"></div>\ 93 </div>\ 94 <div class="minicart-lineitem-bottom"></div>\ 95 </div>\ 96 </template>\ 97 </div>\ 98 <div id="prh-minicart-overlay" style="display: none;"></div>').appendTo('body'); 99 100 if (!$('#prh-minicart-js').data('no-css')) { 101 var version = $( '#prh-minicart-js' ).data( 'css-version' ); 102 $('<link rel="stylesheet" id="minicart-css" href="/wp-content/themes/penguinrandomhouse/css/minicart.css?ver=' + version + '" type="text/css" media="all" />').appendTo('head'); 103 } 104 105 $('#prh-minicart .minicart-header .minicart-close-x, #prh-minicart .minicart-continue-shopping button').on('click', function (e) { 106 PRH.minicart.hide(); 107 }).on('keyup', PRH.minicart.clickIfEnter); 108 109 $('#prh-minicart .minicart-footer .minicart-checkout button').on('click', function (e) { 110 PRH.minicart.analytics('checkout'); 111 PRH.minicart.hide(); 112 document.cookie = 'siteReturnURL='+window.escape(window.location.href)+';expires=0;path=/;domain='+cartCookieDomain+';secure;samesite=None'; 113 var cartUrl = window[$('#prh-minicart-js').data('cart-url-var')]; 114 window.location.href = cartUrl + '/prhcart/prhcart.php'; 115 }).on('keyup', PRH.minicart.clickIfEnter); 116 117 $('#prh-minicart .minicart-carttype-tooltip-icon, #prh-minicart .minicart-carttype-tooltip').hover( 118 function (e) { 119 if (!(window.matchMedia('(hover: none)').matches || window.matchMedia('(pointer: coarse)').matches || window.matchMedia('(max-width: 600px)').matches)) 120 PRH.minicart.showCartTypeTooltip(e); 121 }, 122 function (e) { 123 if (!(window.matchMedia('(hover: none)').matches || window.matchMedia('(pointer: coarse)').matches || window.matchMedia('(max-width: 600px)').matches)) 124 PRH.minicart.hideCartTypeTooltip(e); 125 } 126 ); 127 128 $('#prh-minicart .minicart-carttype-tooltip-icon, #prh-minicart .minicart-carttype-tooltip').on('click', PRH.minicart.toggleCartTypeTooltip).on('keyup', PRH.minicart.toggleCartTypeTooltip); 129 130 // REMOVE ITEM 131 $('body').on('click', '#prh-minicart .minicart-lineitem-cmd', function (e) { 132 var isbn = $(this).closest('.minicart-lineitem').data('productCode'); 133 // console.log('Removing '+isbn); 134 var cartUrl = window[$('#prh-minicart-js').data('cart-url-var')]; 135 136 var title = $(this).closest('.minicart-lineitem').find('.minicart-lineitem-title').text(); 137 var qty = parseInt($(this).closest('.minicart-lineitem').find('.minicart-lineitem-qty').html()) - 1; 138 // console.log('Item Quantity: ' + qty); 139 var line = $(this).closest('.minicart-lineitem').data('line'); 140 var say = ''; 141 if (qty < 1) { 142 say = 'Removed.'; 143 $(this).closest('.minicart-lineitem').fadeOut(function () { 144 $(this).remove(); 145 }); 146 } else { 147 say = '1 removed.'; 148 $(this).closest('.minicart-lineitem').find('.minicart-lineitem-qty').html(qty); 149 if (qty < 2) $(this).closest('.minicart-lineitem').find('.minicart-lineitem-qty').hide(); 150 line.quantity = qty; 151 $(this).closest('.minicart-lineitem').data('line', line); 152 } 153 PRH.minicart.screenreaderSpeak(say, 'assertive'); 154 155 // Do remove into the iframe & make the lineitem disappear - moved later 156 // so it doesn't interfere with the screenreader speech 157 $('#prh-minicart iframe#prh-minicart-iframe').attr('src', cartUrl + '/prhcart/prhcart.php?minicart=1&cancel='+isbn); 158 159 // Start timeout for remove-item request (cart is already open) 160 PRH.minicart.startCartRequestTimeout(false); 161 162 var cartQty = parseInt($(this).closest('#prh-minicart').find('.minicart-qty').first().html()) - 1; 163 $(this).closest('#prh-minicart').find('.minicart-qty').html(cartQty); 164 165 // Remove analytics call 166 line.quantity = 1; 167 PRH.minicart.analytics('cart_remove', line); 168 169 }).on('keyup', '#prh-minicart .minicart-lineitem-cmd', PRH.minicart.clickIfEnter); 170 171 // hijack cart forms 172 $('body').on('submit', 'form[action*="prhcart.php"]', function (e) { 173 if ($(this).attr('target') != 'prh-minicart-iframe') { 174 $(this).append('<input type="hidden" name="minicart" value="1">') 175 $(this).attr('target', 'prh-minicart-iframe'); 176 } 177 178 // Start timeout for add-to-cart request (should open cart on timeout) 179 PRH.minicart.startCartRequestTimeout(true); 180 181 return true; 182 }); 183 $('body').on('click', 'form[action*="prhcart.php"] button[type="submit"]', function (e) { 184 185 PRH.minicart.screenreaderSpeak('Adding', 'assertive'); 186 187 if (!(e.screenX && e.screenY)) 188 $(this).closest('form').append('<input type="hidden" name="keyboard" value="1">'); 189 else 190 $(this).closest('form').find('input[name="keyboard"]').remove(); 191 192 return true; 193 }); 194 195 $('body').on('click', '#prh-minicart .minicart-carttype-tooltip a', function (e) { 196 var nextPageObj = { 197 'nav_element': 'minicart' 198 }; 199 document.cookie = 'next_page_teal=' + JSON.stringify(nextPageObj) + ';path=/;max-age=30;'; 200 return true; 201 }).on('keyup', '#prh-minicart .minicart-carttype-tooltip a', PRH.minicart.clickIfEnter); 202 203 var hover = $('#prh-minicart-js').data('hover-open'); 204 if (hover && $(hover).length) { 205 (function () { 206 207 let timer = null; 208 209 $(hover).hover( 210 function() { 211 // console.log('minicart mousein'); 212 if (!(window.matchMedia('(hover: none)').matches || window.matchMedia('(pointer: coarse)').matches || window.matchMedia('(max-width: 600px)').matches)) { 213 if (timer) { 214 clearTimeout(timer); 215 timer = null; 216 } 217 timer = setTimeout(function () { 218 PRH.minicart.show(); 219 }, 1000); 220 } 221 }, 222 function() { 223 // console.log('minicart mouseout'); 224 if (timer) { 225 clearTimeout(timer); 226 timer = null; 227 } 228 } 229 ); 230 })(); 231 } 232 233 PRH.minicart.tabTrap.initEvents(); 234 235 var clickObj = $('#prh-minicart-js').data('click-open'); 236 if (clickObj && $(clickObj).length) { 237 if ((window.matchMedia('(hover: none)').matches || window.matchMedia('(pointer: coarse)').matches || window.matchMedia('(max-width: 600px)').matches)) { // Mobile 238 $(clickObj).on('click', PRH.minicart.show).on('keyup', PRH.minicart.clickIfEnter); 239 } else { 240 $(clickObj).on('click', function (e) { 241 PRH.minicart.analytics('checkout'); 242 PRH.minicart.hide(); 243 document.cookie = 'siteReturnURL='+window.escape(window.location.href)+';expires=0;path=/;domain='+cartCookieDomain+';secure;samesite=None'; 244 var cartUrl = window[$('#prh-minicart-js').data('cart-url-var')]; 245 window.location.href = cartUrl + '/prhcart/prhcart.php'; 246 }); 247 } 248 } 249 250 $('#prh-minicart').on('mouseenter mousemove click', function () { 251 if (PRH.minicart.closeCartTimer != null) { 252 clearTimeout(PRH.minicart.closeCartTimer); 253 PRH.minicart.closeCartTimer = null; 254 } 255 }).on('keyup', PRH.minicart.clickIfEnter); 256 257 $('#prh-minicart .minicart-body').on('scroll', PRH.minicart.scroll); 258 259 var cartData = null; 260 var cartDataJson = sessionStorage.getItem('PRHcart'); 261 if (cartDataJson) { 262 cartData = JSON.parse(cartDataJson); 263 PRH.minicart.buildCartDOM(cartData); 264 } 265 266 var nci = PRH.minicart.getCookieVal('NumberofCartItems'); 267 // console.log(nci); 268 if ((nci && nci.length && nci[1] > 0) || (cartData && cartData.data && cartData.data.numberOfItems
268InShoppingCart > 0)) { 269 // console.log('refresh cart on load'); 270 PRH.minicart.refresh(); 271 } 272 273 PRH.minicart.scroll(); 274 PRH.minicart.displayEmpAuthWarning(); 275 }, 276 277 scroll: function (e) { 278 if (window.matchMedia('(min-width: 601px)')) { 279 // Show fixed version of cart type ribbon 280 $('#prh-minicart .minicart-outer-wrap .minicart-inner-wrap .minicart-body .minicart-carttype-ribbon').addClass('hide'); 281 $('#prh-minicart .minicart-outer-wrap .minicart-inner-wrap > .minicart-carttype-ribbon').removeClass('hide'); 282 return; 283 } 284 var ht = 0; 285 $('.minicart-body .minicart-lineitems .minicart-lineitem').each(function (idx, li) { 286 ht += $(li).outerHeight(); 287 }); 288 if (ht < $('#prh-minicart .minicart-body').outerHeight()) { 289 // Show fixed version of cart type ribbon 290 $('#prh-minicart .minicart-outer-wrap .minicart-inner-wrap .minicart-body .minicart-carttype-ribbon').addClass('hide'); 291 $('#prh-minicart .minicart-outer-wrap .minicart-inner-wrap > .minicart-carttype-ribbon').removeClass('hide'); 292 } else { 293 // Show moving version of cart type ribbon 294 $('#prh-minicart .minicart-outer-wrap .minicart-inner-wrap > .minicart-carttype-ribbon').addClass('hide'); 295 $('#prh-minicart .minicart-outer-wrap .minicart-inner-wrap .minicart-body .minicart-carttype-ribbon').removeClass('hide'); 296 } 297 }, 298 299 messages: function (e) { 300 301 if (!e.originalEvent.origin.match(/cart/) && !e.originalEvent.origin.match(/penguinrandomhouse\.com$/)) return; 302 303 var data = e.originalEvent.data; 304 if (!data.substr) return; 305 306 // Clear timeout on any valid cart message 307 PRH.minicart.clearCartRequestTimeout(); 308 309 if (data.match(/^maintenance/)) { 310 PRH.minicart.maintenance(); 311 if (data.match(/Open/)) { 312 PRH.minicart.show(); 313 } 314 return; 315 } 316 317 if (data.match(/^speak::/)) { 318 PRH.minicart.screenreaderSpeak(data.substr(7)); 319 return; 320 } 321 322 // Ignore cart data messages if we're showing the outage screen 323 if (PRH.minicart.isInOutageMode && data.match(/^updateCart/)) { 324 return; 325 } 326 327 var cartData = null; 328 if (!data.match(/^updateCart::/) && !data.match(/^updateCartOpen::/) && !data.match(/^updateCartKeepOpen::/)) 329 return; 330 331 try { 332 if (data.match(/^updateCart::/)) 333 cartData = JSON.parse(data.substr(12)); 334 if (data.match(/^updateCartOpen::/)) 335 cartData = JSON.parse(data.substr(16)); 336 if (data.match(/^updateCartKeepOpen::/)) 337 cartData = JSON.parse(data.substr(20)); 338 } catch (e) { 339 console.log(e); 340 } 341 342 // Purge and rebuild iframe to clear history 343 var iFrame = $('#prh-minicart-iframe').prop('outerHTML'); 344 $('#prh-minicart-iframe').remove(); 345 $(iFrame).attr('src', 'about:blank').appendTo('#prh-minicart .minicart-body'); 346 347 if (!cartData) cartData = {}; 348 cartData.now = Date.now(); 349 sessionStorage.setItem('PRHcart', JSON.stringify(cartData)); 350 PRH.minicart.buildCartDOM(cartData); 351 352 if (data.match(/^updateCart.*Open::/)) { 353 $('#prh-minicart .minicart-body').scrollTop($('#prh-minicart .minicart-body')[0].scrollHeight); 354 PRH.minicart.show(true, !data.match(/KeepOpen/)); 355 } 356 357 PRH.minicart.scroll(); 358 }, 359 360 buildCartDOM: function (cartData) { 361 362 // console.log(cartData); 363 if (!cartData || cartData.status != 'ok') { 364 PRH.minicart.setQuantity(0); 365 PRH.minicart.setTotal(0); 366 PRH.minicart.setFreeShipping('null'); 367 PRH.minicart.setRewards(-1); 368 if (cartData && cartData.data && cartData.data.cartType) { 369 PRH.minicart.setCartType(cartData.data.cartType); 370 } else { 371 PRH.minicart.setCartType(); 372 } 373 return; 374 } 375 376 PRH.minicart.setQuantity(cartData.data.numberOfItems
376InShoppingCart); 377 PRH.minicart.setTotal(cartData.data.adjustedCartSubTotal); 378 PRH.minicart.setCartType(cartData.data.cartType); 379 380 if (cartData.data.numberOfItemsInShoppingCart > 0) { 381 $('#prh-minicart .minicart-checkout').attr('tabindex', '0').attr('aria-label', 'Cart total ' + cartData.data.numberOfItemsInShoppingCart + ' items $' + cartData.data.adjustedCartTotal.toFixed(2)); 382 } else { 383 $('#prh-minicart .minicart-checkout').attr('tabindex', null).attr('aria-label', null); 384 } 385 386 // Free shipping? 387 switch (cartData.data.cartType) { 388 case 'employee': 389 case 'author': 390 if (cartData.data.numberOfItemsInShoppingCart == 0) 391 PRH.minicart.setFreeShipping('null'); 392 else 393 PRH.minicart.setFreeShipping(0); 394 PRH.minicart.setRewards(-1); 395 break; 396 default: 397 if (cartData.data.numberOfItemsInShoppingCart == 0) 398 PRH.minicart.setFreeShipping('null'); 399 else { 400 if (cartData.data.discount && cartData.data.discount.isFreeShipping) 401 PRH.minicart.setFreeShipping(0); 402 else 403 // $20 for free shipping OR $50 on goodnightbooks TBD 404 PRH.minicart.setFreeShipping(20 - cartData.data.adjustedCartSubTotal); 405 } 406 407 // Reward points eligibility? 408 if (cartData.data.numberOfItemsInShoppingCart == 0 || (cartData.data.discount && cartData.data.discount.discountCode == 'LOYALTY')) 409 PRH.minicart.setRewards(0); 410 else 411 PRH.minicart.setRewards(cartData.data.rewards); 412 } 413 414 // Walk lineitems (if any) and display 415 var productCodes = cartData.data.lines.map(function (y) { return y.productCode; }); 416 417 // console.log('incoming'); 418 // console.log(productCodes); 419 420 // Remove any items not in cart but in DOM 421 $('#prh-minicart .minicart-lineitem').each(function (n, lineitem) { 422 // console.log('Checking ' + $(lineitem).data('productCode')); 423 if (!productCodes.includes($(lineitem).data('productCode'))) { 424 $(lineitem).remove(); 425 } 426 }); 427 428 // Update items in DOM 429 cartData.data.lines.forEach(function (line) { 430 PRH.minicart.showItem(line, cartData.data.discount); 431 }); 432 433 }, 434 435 removeItem: function (productCode) { 436 $('#prh-minicart .minicart-lineitem').filter(function (n,v) { 437 return ($(v).data('productCode') == productCode); 438 }).remove(); 439 }, 440 441 showItem: function (line, discount) { 442 // console.log('showItem'); 443 // console.log(discount); 444 // console.log(line); 445 446 if (discount && discount.discountType == 'cart' && discount.discountPct > 0) { 447 if (line.adjustedPriceSingle == line.priceSingle) { 448 line.adjustedPriceSingle = line.priceSingle * ((100-discount.discountPct) / 100.0); 449 // console.log(line); 450 } 451 // console.log(line); 452 } 453 454 var $item = $('#prh-minicart .minicart-lineitem').filter(function (n,v) { 455 return ($(v).data('productCode') == line.productCode); 456 }); 457 if (!$item.length) { 458 // console.log('new item: ' + line.productCode); 459 $item = $($('template#minicart-lineitem').html()); 460 $item.data('productCode', line.productCode); 461 // console.log($item.data('productCode')); 462 $('#prh-minicart .minicart-lineitems').append($item); 463 } else {
464 // console.log('old item: ' + line.productCode); 465 // console.log($item); 466 } 467 $item.data('line', line); 468 $item.find('.minicart-lineitem-cover a').attr('href', line.navURL); 469 $item.find('.minicart-lineitem-cover a').attr('aria-label', line.product.name + ' by ' + line.product.authorWeb + ' in ' + line.product.formatName + (line.quantity > 1 ? ' quantity '+line.quantity : '') + (line.available ? ' for $' + line.adjustedPriceSingle + ' each' : ' ' + line.status)); 470 $item.find('.minicart-lineitem-cover a').attr('title', line.product.name); 471 $item.find('.minicart-lineitem-cover a').attr('alt', line.product.name); 472 $item.find('.minicart-lineitem-cover a img').attr('src', "//images.penguinrandomhouse.com/cover/"+line.productCode+"?width=168"); 473 $item.find('.minicart-lineitem-cover a img').attr('alt', line.product.name+" cover"); 474 if (line.quantity > 1) { 475 $item.find('.minicart-lineitem-qty').html(line.quantity).show(); 476 } else { 477 $item.find('.minicart-lineitem-qty').hide(); 478 } 479 $item.find('.minicart-lineitem-title').html(line.product.name); 480 $item.find('.minicart-lineitem-author').html(line.product.authorWeb); 481 $item.find('.minicart-lineitem-format').html(line.product.formatName); 482 $item.find('.minicart-lineitem-cmd').attr('aria-label', 'Remove'); 483 484 if (line.available) { 485 if (line.adjustedPriceSingle != line.priceSingle) { 486 $item.find('.minicart-lineitem-orig-price').html('$'+parseFloat(line.priceSingle).toFixed(2)).show(); 487 } else { 488 $item.find('.minicart-lineitem-orig-price').hide(); 489 } 490 $item.find('.minicart-lineitem-price').html('$'+parseFloat(line.adjustedPriceSingle).toFixed(2)); 491 } else { 492 $item.find('.minicart-lineitem-price').html(line.status); 493 } 494 }, 495 496 maintenance: function () { 497 $('#prh-minicart').find('.minicart-empty, .minicart-empty-text, .minicart-lineitems, .minicart-checkout').hide(); 498 $('#prh-minicart').find('.minicart-down, .minicart-down-text, .minicart-continue-shopping').show(); 499 }, 500 501 // Start timeout for cart request - triggers outage UI if no response received 502 startCartRequestTimeout: function (shouldOpenCart) { 503 PRH.minicart.clearCartRequestTimeout(); 504 PRH.minicart.pendingCartRequest = true; 505 PRH.minicart.cartRequestTimer = setTimeout(function () { 506 if (PRH.minicart.pendingCartRequest) { 507 PRH.minicart.pendingCartRequest = false; 508 PRH.minicart.cartRequestTimer = null; 509 PRH.minicart.isInOutageMode = true; // Ignore late responses 510 PRH.minicart.maintenance(); 511 if (shouldOpenCart) { 512 PRH.minicart.show(); 513 } 514 } 515 }, PRH.minicart.cartRequestTimeout); 516 }, 517 518 // Clear the cart request timeout (called when valid response received) 519 clearCartRequestTimeout: function () { 520 if (PRH.minicart.cartRequestTimer !== null) { 521 clearTimeout(PRH.minicart.cartRequestTimer); 522 PRH.minicart.cartRequestTimer = null; 523 } 524 PRH.minicart.pendingCartRequest = false; 525 }, 526 527 // Reset outage mode flag (called when minicart is closed) 528 resetOutageMode: function () { 529 PRH.minicart.isInOutageMode = false; 530 }, 531 532 setQuantity: function (qty) { 533 qty = parseInt(qty) || 0; 534 $('#prh-minicart span.minicart-qty').html(qty); 535 $('#prh-minicart').find('.minicart-down, .minicart-down-text').hide(); 536 if (qty > 0) { 537 // Show list, totals, checkout btn, etc 538 $('#prh-minicart').find('.minicart-lineitems').css('display', 'flex'); 539 $('#prh-minicart').find('.minicart-checkout').show(); 540 $('#prh-minicart').find('.minicart-empty, .minicart-empty-text, .minicart-continue-shopping').hide(); 541 } else { 542 // Show empty cart divs and buttons 543 $('#prh-minicart').find('.minicart-lineitems, .minicart-checkout').hide(); 544 $('#prh-minicart').find('.minicart-empty, .minicart-empty-text, .minicart-continue-shopping').show(); 545 $('#prh-minicart').find('.minicart-empty-text').focus(); 546 } 547 if (qty == 1) { 548 $('.minicart-total-qty-plural').css('display', 'none'); 549 } else { 550 $('.minicart-total-qty-plural').css('display', ''); 551 } 552 553 // Update quantity in areas outside of minicart 554 if ($('#prh-minicart-js').data('cart-quantity')) 555 $($('#prh-minicart-js').data('cart-quantity')).html(qty); 556 }, 557 558 setTotal: function (total) { 559 total = parseFloat(total) || 0.0; 560 $('#prh-minicart .minicart-total-price span').html(total.toFixed(2)); 561 }, 562 563 setFreeShipping: function (more) { 564 if (more == 'null') 565 $('#prh-minicart .minicart-free-shipping').hide(); 566 else 567 $('#prh-minicart .minicart-free-shipping').show(); 568 569 if (more > 0) 570 $('#prh-minicart .minicart-free-shipping').html('<div class="img-shipping-fast"></div>Spend <span>
570$'+ Math.ceil(more) +' more</span> for free shipping!'); 571 else 572 $('#prh-minicart .minicart-free-shipping').html('<div class="img-shipping-fast"></div>You qualify for <span>FREE</span> shipping!'); 573 }, 574 575 setRewards: function (rewards) { 576 }, 577 578 setCartType: function (cartType) { 579 switch (cartType) { 580 case 'employee': 581 $('#prh-minicart .minicart-carttype-ribbon span').html('You\'re shopping as a PRH employee!'); 582 $('#prh-minicart .minicart-carttype-tooltip a').attr('href', 'https://igloo.penguinrandomhouse.com/human-resources/discounts/books/penguin-random-house-employee-discounted-book-order/'); 583 $('#prh-minicart .minicart-carttype-ribbon').show(); 584 PRH.minicart.displayEmpAuthWarning(); 585 break; 586 case 'author': 587 $('#prh-minicart .minicart-carttype-ribbon span').html('This cart is for eligible authors only.'); 588 $('#prh-minicart .minicart-carttype-tooltip a').attr('href', '/faqs/'); 589 $('#prh-minicart .minicart-carttype-ribbon').show(); 590 PRH.minicart.displayEmpAuthWarning(); 591 break; 592 default: 593 $('#prh-minicart .minicart-carttype-ribbon').hide(); 594 PRH.minicart.displayEmpAuthWarning(); 595 break; 596 } 597 }, 598 599 // Display warning to employee or authors that are logged into user account 600 displayEmpAuthWarning: function () { 601 var cookieArr = PRH.minicart.getCookieVal('couponCode'); 602 var couponCodeValue = Array.isArray(cookieArr) && cookieArr.length > 1 ? cookieArr[1] : null; 603 604 if (couponCodeValue && (couponCodeValue == 'EMP50' || couponCodeValue == 'AUT50')) { 605 var discountType = (couponCodeValue == 'EMP50') ? 'employee' : 'author'; 606 var isEmpAuthSession = sessionStorage.getItem('fe_s') && sessionStorage.getItem('fe_s') != 'false'; 607 608 if (isEmpAuthSession && $('#prh-minicart .emp-auth-warning').length == 0) { 609 var empAuthWarning = '<div class="emp-auth-warning">\ 610 <img class="account-icon" src="/wp-content/themes/penguinrandomhouse/images/warning.svg" alt="" />\ 611 <p>To receive your ' + discountType + ' discount, <a href="/signoff/">log out</a> of your account to proceed.</p>\ 612 </div>'; 613 614 $('#prh-minicart .minicart-body').before(empAuthWarning); 615 } else if(!isEmpAuthSession) { 616 if ($('#prh-minicart .emp-auth-warning').length > 0) { 617 $('#prh-minicart .emp-auth-warning').remove(); 618 } 619 } 620 } else { 621 if ($('#prh-minicart .emp-auth-warning').length > 0) { 622 $('#prh-minicart .emp-auth-warning').remove(); 623 } 624 } 625 }, 626 627 // Clean minicart from browser (opposite of init) 628 clean: function () { 629 630 }, 631 632 closeCartTimer: null, 633 634 // Show the minicart 635 show: function (noRefresh, autoClose) { 636 if (!noRefresh) PRH.minicart.refresh(); 637 638 if ($('#prh-minicart').is(':visible')) return false; 639 640 // Send every time minicart opens 641 PRH.minicart.analytics('minicart_load'); 642 PRH.minicart.firstLoad = true; // In case we need to track firstLoad 643 644 PRH.minicart.scrollToggle(false); 645 646 $('#prh-minicart-overlay').off('click mouseenter').show().animate({'opacity': 0.5}, { duration: 100, queue: false }); 647 $('#prh-minicart').show().animate({'right': '0px'}, { duration: 100, queue: false, complete: function () { 648 $('#prh-minicart-overlay').off('click mouseenter').on('click mouseenter', function (e) { 649 PRH.minicart.hide(); 650 }); 651 if (autoClose && PRH.minicart.closeCartTimer == null && ('undefined' == typeof window.View.Utils.tabTrap.fromTab || !window.View.Utils.tabTrap.fromTab)) {//never auto hide if on prh and from tab indexin 652 PRH.minicart.closeCartTimer = setTimeout(function () { PRH.minicart.hide(); }, 5000); 653 } 654 } }); 655 PRH.minicart.tabTrap.init($('#prh-minicart'), true, $(':focus')); 656 PRH.minicart.tabTrap.closeFunc = function () { }; 657 if('undefined' != typeof window.View.Utils.tabTrap.fromTab && window.View.Utils.tabTrap.fromTab) 658 PRH.minicart.tabTrap.closeFunc = 'PRH.minicart.hide'; 659 660 $('main#mainblock').attr('aria-hidden', 'true'); 661 $('#prh-minicart').attr('aria-hidden', 'false').focus(); 662 return false;
663 }, 664 665 // Hide the minicart 666 hide: function () { 667 if (!$('#prh-minicart').is(':visible')) return; 668 669 if (PRH.minicart.closeCartTimer != null) { 670 clearTimeout(PRH.minicart.closeCartTimer); 671 PRH.minicart.closeCartTimer = null; 672 } 673 674 // Reset outage mode when closing the minicart 675 PRH.minicart.resetOutageMode(); 676 677 $('#prh-minicart').off('click mouseenter').animate({'right': '-340px'}, { duration: 200, queue: false, complete: function () { $('#prh-minicart').hide(); } }); 678 $('#prh-minicart-overlay').animate({'opacity': 0}, { duration: 200, queue: false, complete: function () { $('#prh-minicart-overlay').hide(); } }); 679 PRH.minicart.scrollToggle(true); 680 681 if (PRH.minicart.tabTrap.closeFunc !== null) { 682 if ( typeof PRH.minicart.tabTrap.closeFunc === 'string' ) { 683 PRH.minicart.executeFunctionByName(PRH.minicart.tabTrap.closeFunc,window); 684 } else if ( typeof PRH.minicart.tabTrap.closeFunc === 'function' ) { 685 PRH.minicart.tabTrap.closeFunc(); 686 } 687 PRH.minicart.tabTrap.closeFunc = null; 688 } 689 PRH.minicart.tabTrap.end(); 690 691 $('#prh-minicart').attr('aria-hidden', 'true'); 692 $('main#mainblock').attr('aria-hidden', 'false'); 693 }, 694 695 tooltipTimer: null, 696 697 // This is used as a click event if hover is not available AND as a keyup event for accessibility 698 toggleTooltip: function (e) { 699 }, 700 701 showTooltip: function (e) { 702 }, 703 704 hideTooltip: function (e) { 705 }, 706 707 cartTypeTooltipTimer: null, 708 709 // This is used as a click event if hover is not available AND as a keyup event for accessibility 710 toggleCartTypeTooltip: function (e) { 711 if (e.keyCode == 13 || 712 (e.target.tagName != 'A' && (window.matchMedia('(hover: none)').matches || window.matchMedia('(pointer: coarse)').matches || window.matchMedia('(max-width: 600px)').matches))) { 713 if ($('#prh-minicart .minicart-carttype-tooltip:visible').length) 714 PRH.minicart.hideCartTypeTooltip(true); 715 else 716 PRH.minicart.showCartTypeTooltip(e); 717 return false; 718 } 719 return true; 720 }, 721 722 showCartTypeTooltip: function (e) { 723 // console.log('showCartTypeTooltip'); 724 if (PRH.minicart.cartTypeTooltipTimer != null) { 725 clearTimeout(PRH.minicart.cartTypeTooltipTimer); 726 PRH.minicart.cartTypeTooltipTimer = null; 727 } 728 if ($('#prh-minicart .minicart-carttype-tooltip:visible').length) return; 729 // console.log('showing'); 730 /* 731 var btm = $('#prh-minicart .minicart-footer').outerHeight() + $('#prh-minicart .minicart-carttype-ribbon:visible').outerHeight() + 10; 732 $('#prh-minicart .minicart-carttype-tooltip').css('bottom', btm+'px'); 733 */ 734 $('#prh-minicart .minicart-carttype-tooltip').show(); 735 }, 736 737 hideCartTypeTooltip: function (e) { 738 // console.log('hideCartTypeTooltip'); 739 if (PRH.minicart.cartTypeTooltipTimer == null) { 740 // console.log('hidingTooltip'); 741 PRH.minicart.cartTypeTooltipTimer = setTimeout( function () { 742 $('#prh-minicart .minicart-carttype-tooltip').hide(); 743 //$('#prh-minicart .minicart-carttype-tooltip').css('bottom', ''); 744 PRH.minicart.cartTypeTooltipTimer = null; 745 }, (e === true ? 1 : 500)); 746 } 747 }, 748 749 lastRefresh: 0, 750 751 // Refresh cart contents and counts if not refreshed in last five minutes 752 refresh: function () { 753 if ($('#prh-minicart-iframe').length && ((new Date().getTime() / 1000) - PRH.minicart.lastRefresh) > 300) { 754 if ($('#prh-minicart-iframe').attr('src') == 'about:blank') 755 $('#prh-minicart-iframe').attr('src', PRH.minicart.escapeHtml(cartUrl) + '/prhcart/common/api.php?cmd=PRHcartData&r=' + Math.random()); 756 else { 757 $('#prh-minicart-iframe')[0].contentWindow.postMessage('reload', '*'); 758 } 759 PRH.minicart.lastRefresh = new Date().getTime() / 1000; 760 761 // Start timeout for refresh request (don't open cart automatically) 762 PRH.minicart.startCartRequestTimeout(false); 763 } 764 }, 765 766 analytics: function (event_type, line) { 767 if (!$('#prh-minicart-js').data('analytics-func')) { 768 return; 769 } 770 // console.log('line'); 771 // console.log(line); 772 var cartLines = []; 773 try { 774 if (line) 775 cartLines = $([ line ]); 776 else 777 cartLines = $('#prh-minicart .minicart-lineitem').map(function (idx, line) { return $(line).data('line'); }); 778 779 // console.log(cartLines); 780 var sendFunc = eval($('#prh-minicart-js').data('analytics-func')); 781 sendFunc(cartLines, event_type); 782 } catch (e) { 783 console.log(e); 784 } 785 return; 786 }, 787 788 escapeHtml: function (text) { 789 var map = { 790 '&': '&', 791 '<': '<', 792 '>': '>', 793 '"': '"', 794 "'": ''' 795 }; 796 797 return text.replace(/[&<>"']/g, function(m) { return map[m]; }); 798 }, 799 800 scrollToggle: function (turnOn, noScroll) { 801 if (turnOn) { 802 var html = $('html'); 803 var scrollPosition = html.data('minicart-scroll-position'); 804 if (html.data('minicart-previous-overflow')) 805 html.css('overflow', html.data('minicart-previous-overflow')); 806 807 html.css('margin-right', ''); 808 window.setTimeout( function () { $('html').css('transition', ''); }, 10); 809 810 if (scrollPosition && scrollPosition.length > 0) 811 window.scrollTo(scrollPosition[0], scrollPosition[1]) 812 813 html.data('minicart-previous-overflow', null); 814 html.data('minicart-scroll-position', null); 815 816 } else { 817 if ($('html').css('overflow') == 'hidden') return; 818 var scrollPosition = [ 819 self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, 820 self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop 821 ]; 822 let mr = $(window).outerWidth() - $(window).width(); 823 var html = $('html'); // it would make more sense to apply this to body, but IE7 won't have that 824 html.data('minicart-scroll-position', scrollPosition); 825 html.data('minicart-previous-overflow', html.css('overflow')); 826 html.css('overflow', 'hidden'); 827 html.css('transition', 'none').css('margin-right', mr+'px'); 828 if (scrollPosition.length > 0 && !noScroll) 829 window.scrollTo(scrollPosition[0], scrollPosition[1]); 830 } 831 }, 832 833 getCookieVal: function( name ) { 834 var cookieList = document.cookie.split( ';' ); 835 var cookieFound = 0; 836 837 $.each( cookieList, function( index, value ) { 838 var cookie = value.trim().split( '=' ); 839 840 if ( cookie[0] === name ) { 841 cookieFound = cookie; 842 } 843 } ); 844 845 return cookieFound; 846 }, 847 // When this is updated, check global.View.Utils.js to see if that needs the same change -KM - ECOMMERCE-802 848 tabTrap: { 849 init: function(modalObj, updateFocus, clickObj){ 850 if(typeof modalObj !== 'undefined'){ 851 modalObj.addClass('tabTrap'); 852 this.modalObj = modalObj[0]; 853 }else{//assume some method gave the modal the tabTrap class 854 this.modalObj = $('.tabTrap:visible:first')[0]; 855 } 856 // store for focus when modal closes 857 if(typeof clickObj !== 'undefined' && clickObj !== null){ 858 this.clickObj = clickObj[0]; 859 }else{ 860 this.clickObj = document.activeElement; 861 } 862 if($(this.clickObj).attr('close-function')) 863 this.closeFunc = $(this.clickObj).attr('close-function'); 864 865 if (modalObj.find('.forcefoc').length > -1){ 866 modalObj.find('.forcefoc').focus(); 867 }else if ( updateFocus && this.modalObj.querySelectorAll(this.focusableElsQ).length ) { 868 this.modalObj.querySelectorAll(this.focusableElsQ)[0].focus(); 869 } 870 }, 871 end: function(modalObj){ 872 if(typeof modalObj !== 'undefined') 873 modalObj.removeClass('tabTrap'); 874 else 875 $('.tabTrap').removeClass('tabTrap'); 876 this.modalObj = null; 877 878 if(this.clickObj!=null) 879 this.clickObj.focus(); 880 881 this.clickObj = null; 882 if('undefined' != typeof window.View.Utils.tabTrap.fromTab) 883 window.View.Utils.tabTrap.fromTab = false;
884 }, 885 modalObj: null, 886 clickObj: null, 887 closeFunc: null, 888 focusableElsQ: 'a[href]:not([disabled]), a.media, button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="email"]:not([disabled]), input[type="password"]:not([disabled]), input[type="search"]:not([disabled]), input[type="submit"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])', 889 890 initEvents: function () { 891 //trap tab focus in modal 892 $('#prh-minicart').on('keydown', function (event) { 893 var tabPressed = event.key === 'Tab' || event.keyCode === 9; 894 var escPressed = event.key === 'Esc' || event.keyCode === 27; 895 var entrPressed = event.key === 'Enter' || event.keyCode === 13; 896 if (!tabPressed && !escPressed && !entrPressed) {//if not tab/esc bye 897 return; 898 } 899 if ($('#prh-minicart.tabTrap:visible').length == 0 && !entrPressed) {//no element with tabTrap or enter 900 return; 901 } 902 if (tabPressed) { 903 var modalObj = $('#prh-minicart.tabTrap:visible:first')[0], 904 focusableEls = modalObj.querySelectorAll(PRH.minicart.tabTrap.focusableElsQ); 905 focusableEls = $(focusableEls).filter(function () { 906 return $(this).attr('tabindex') !== '-1' && $(this).is(':visible'); 907 }); 908 var firstFocusable = focusableEls[0], 909 lastFocusable = focusableEls[focusableEls.length - 1], 910 tabInModal = false; 911 for (var i = 0; i < focusableEls.length; i++) { 912 if (document.activeElement === focusableEls[i]) { 913 tabInModal = true; 914 break; 915 } 916 } 917 if (event.shiftKey) { 918 if (document.activeElement === firstFocusable) { 919 lastFocusable.focus(); 920 event.preventDefault(); 921 return; 922 } 923 } else { 924 if (document.activeElement === lastFocusable || !tabInModal) { 925 firstFocusable.focus(); 926 event.preventDefault(); 927 return; 928 } 929 } 930 } 931 if (escPressed) { 932 //see if there is a closed function stored 933 PRH.minicart.hide(); 934 } 935 if (entrPressed) { 936 if ($(document.activeElement).attr('open-modal') && $('#' + $(document.activeElement).attr('open-modal')).length) { // or just show modal if exists 937 //$('#'+$(document.activeElement).attr('open-modal')).show(); 938 PRH.minicart.tabTrap.init($('#' + $(document.activeElement).attr('open-modal'))); 939 } else if ($(document.activeElement).attr('close-function')) { //run open function if exists 940 PRH.minicart.tabTrap.closeFunc = $(document.activeElement).attr('close-function'); 941 PRH.minicart.tabTrap.clickObj = $(document.activeElement); 942 } 943 944 if ($(document.activeElement).attr('open-function')) //run open function if exists 945 PRH.minicart.executeFunctionByName($(document.activeElement).attr('open-function'), window); 946 } 947 }); 948 } 949 }, 950 951 clickIfEnter: function (e) { 952 if (e.keyCode == 13) { $(this).trigger('click'); } 953 }, 954 955 executeFunctionByName: function (functionName, context) { 956 var args = Array.prototype.slice.call(arguments, 2), 957 namespaces = functionName.split("."), 958 func = namespaces.pop(); 959 for(var i = 0; i < namespaces.length; i++) { 960 context = context[namespaces[i]]; 961 }
962 return context[func].apply(context, args); 963 }, 964 965 screenreaderSpeak: function (text, priority) { 966 var id = "speak-" + Date.now(); 967 $('<div/>', { id: id, 'aria-live': priority || 'polite', class: 'visually-hidden' }).appendTo('body'); 968 window.setTimeout(function () { 969 $('#' + id).html(text); 970 }, 100); 971 window.setTimeout(function () { 972 document.body.removeChild(document.getElementById(id)); 973 }, 10000); 974 console.log('say: ' + text); 975 } 976 } 977 978 })( jQuery, PRH ); 979 980 $(document).ready(function (e) { 981 PRH.minicart.init(); 982 }); 983 }); // end waitForJQuery 984})();
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.