1/** 2 * jQuery PageLoad by Artlogic 3 * 4 * Copyright 2018, Artlogic Media Ltd, http://www.artlogic.net/ 5 */ 6 7 8export default (function($) { 9 10 // Module-load-time defaults â available immediately when the plugin module loads, 11 // before any call to $.pageload({...}). Protects consumers from race conditions 12 // where they reference $.pageload.options.X before the constructor runs. 13 var DEFAULT_OPTIONS = { 14 'splash_screen_enabled': false, 15 'splash_screen_always_enabled': false, 16 'splash_screen_cookie_expiry': 900, 17 'splash_screen_click_to_close': false, 18 'popup_content_enabled': false, 19 'popup_content_force_open': false, // Force popup content to open in fallback mode - when you arrive directly on a page with content ordinarily opened in a popup 20 'popup_content_update_url': true, 21 'ajax_navigation_enabled': true, 22 'disable_ajax_param': true, // Removes ajax post parameter from each page load, improves server performance enabling cached pages 23 'development_mode': false, 24 'development_mode_pause_splash_screen': false, 25 'development_mode_show_splash_screen_on_refresh': false, 26 'loader_orientation': 'width', 27 'verbose': false, 28 'content_area_selector': '#container_inner', 29 'content_load_adjacent': false, 30 'preloader_additional_html': '', 31 'body_classes_to_retain_defaults': 'browser-js-enabled, first-load-complete, ajax-loading, page-transition-active, loader-active, overlay-visible, overlay-active, loader-incoming-type-standard, show-image-alt-tags, core-accessibility-stylesheet-checked, tabbing-listener-added, clicking-detected, website-editor-mode', 32 'body_classes_to_retain': '', 33 'url_params_to_retain_defaults': ['_cms-website-editor=1'], 34 'url_params_to_retain': [], 35 'splash_screen_primary_preload_images_selector': '#loader_logo', // Previously splash_logo_selector 36 'splash_screen_secondary_preload_images_selector': '#preloader', // Previously splash_background_selector 37 'splash_screen_delay_after_complete': 200, 38 'splash_screen_auto_delays_enabled': true, 39 'page_transition_delay': 0, 40 'preload_images_selector': '', 41 'popstate_custom_functions': {}, 42 'page_scroll_history': false, 43 'destroy_after_load': function() {}, 44 'after_load_function_calls': function() { 45 if(window.theme) { 46 window.theme.init(); 47 } 48 if(window.cart) { 49 window.cart.init(); 50 } 51 if (window.archimedes && typeof window.archimedes != 'undefined') { 52 window.archimedes.archimedes_core.init(); 53 } 54 if(window.feature_panels) { 55 window.feature_panels.init(); 56 } 57 if (window.modules && typeof window.modules != 'undefined') { 58 window.modules.init_all(); 59 } 60 if(window.site) { 61 window.site.init(); 62 } 63 try { 64 h.accessibility.init(); 65 } catch (error) { 66 console.log(error); 67 } 68 try { 69 h.accessibility.role_button(); 70 } catch (error) { 71 console.log(error); 72 } 73 74 // for footer mailing form 75 if (typeof google_captcha_onload != 'undefined') { 76 google_captcha_onload(); 77 } 78 79 }, 80 'init_after_load': function() { 81 var obj_scope = this; 82 if(window.galleries) { 83 window.galleries.init().then(function(){ 84 obj_scope.after_load_function_calls(); 85 }); 86 } else { 87 obj_scope.after_load_function_calls(); 88 } 89 }, 90 'before_load': function() { 91 if ($('body').hasClass('navigation-open')) { 92 $('body').removeClass('navigation-open'); 93 $('#top_nav_section').fadeOut(500); 94 $('#top_nav_section_reveal').removeClass('open'); 95 $('#top_nav_section li').removeClass('show'); 96 } 97 }, 98 'on_page_transition': function() {}, 99 'after_load_complete': function() {}, 100 'preloader_in': function() {}, 101 'splash_screen_in': function() {}, 102 'splash_screen_out': function() {}, 103 'popup_before': function() {}, 104 'popup_after': function() {}, 105 'popup_after_close': function() {}, 106 'page_transition_start': function() {}, 107 'page_transition_end': function() {}, 108 'pageview': function() {} 109 }; 110 111 // Queue of stub calls that fired before the constructor ran. Each entry is 112 // { path: 'fn.popup.close_popup', args: <arguments> }. Replayed on the real 113 // implementations at the end of the constructor (queue-and-replay pattern). 114 // Capped at 50 to prevent unbounded growth if the constructor never runs. 115 var _pendingCalls = []; 116 117 function _waitFor(methodPath) { 118 return function() { 119 if (_pendingCalls.length < 50) { 120 _pendingCalls.push({ path: methodPath, args: arguments }); 121 } 122 }; 123 } 124 125 // Only assign $.pageload if it doesn't already exist as a function. Guards against 126 // IIFE re-execution (e.g., AJAX navigation re-injecting <script>
126 tags) which would 127 // otherwise create a NEW function and lose all properties set by a previous 128 // constructor call (real .options, .fn, click handler closures, etc.). 129 if (typeof $.pageload !== 'function') { 130 $.pageload = function(user_options) { 131 // Options setup 132 133 // Deep extend so the at-risk array/object defaults (url_params_to_retain*, 134 // popstate_custom_functions) are cloned per-call. Without `true`, a shallow 135 // extend would share inner references with DEFAULT_OPTIONS â any future 136 // call-site that mutates an array/object option (e.g. .push) would corrupt 137 // DEFAULT_OPTIONS and affect every subsequent $.pageload({...}) invocation. 138 var options = $.extend(true, {}, DEFAULT_OPTIONS, user_options); 139 $.pageload.options = options; 140 141 142 // Setup aliases 143 144 $.pageload.load = function(element_href, pushstate, callback, navigation_type, element, page_scroll_top_value, incoming_content_type, inner_content_selector, post_data) { 145 $.pageload.fn.pages.load(element_href, pushstate, callback, navigation_type, element, page_scroll_top_value, incoming_content_type, inner_content_selector, post_data); 146 } 147 148 $.pageload.refresh = function(element_context) { 149 $.pageload.fn.pages.add_click_events(element_context); 150 } 151 152 $.pageload.popup_close = function(forced) { 153 forced = forced && typeof forced != 'undefined' ? true : false; 154 $.pageload.fn.popup.close_popup(forced); 155 } 156 157 $.pageload.popup_open = function(content) { 158 var content_exists = content && typeof content != 'undefined' ? true : false; 159 if (content_exists) { 160 $.pageload.fn.popup.open(content); 161 } 162 } 163 $.pageload.slidein = function(content) { 164 var content_exists = content && typeof content != 'undefined' ? true : false; 165 if (content_exists) { 166 $.pageload.fn.slidein.init(content); 167 } 168 } 169 170 171 // Functions 172 173 $.pageload.fn = { 174 175 init: function() { 176 if ($.pageload.options.popup_content_enabled) { 177 $.pageload.fn.popup.init(); 178 } 179 $.pageload.fn.preloader.init(); 180 $.pageload.fn.pages.init(); 181 }, 182 183 _fetchBackgroundImages: function(images_to_load_selector) { 184 // Put background images in place to initiate load 185 $(images_to_load_selector).each(function() { 186 if ($(this).filter('[data-style]').length) { 187 var new_style_value = $(this).attr('data-style'); 188 if ($(this).attr('style') && typeof $(this).attr('style') != 'undefined') { 189 new_style_value = new_style_value + $(this).attr('style'); 190 // console.log(new_style_value); 191 } 192 $(this).attr('style', new_style_value); 193 $(this).removeAttr('data-style'); 194 } 195 }); 196 }, 197 198 199 _decryptContent: function(encryptedContent, salt) { 200 201 if (!encryptedContent || !salt) { 202 console.info('_decryptContent - no encryptedcontent or salt.') 203 return ''; 204 } 205 206 // Decode the base64 cacheData so we can separate iv and crypt text. 207 var rawData = atob(encryptedContent); 208 var iv = rawData.slice(0,16); 209 var crypttext = rawData.slice(16); 210 211 // Decrypt... 212 var plaintextArray = CryptoJS.AES.decrypt( 213 { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) }, 214 CryptoJS.enc.Latin1.parse(salt), 215 { iv: CryptoJS.enc.Latin1.parse(iv) } 216 ); 217 218 var decryptedContent = CryptoJS.enc.Utf8.stringify(plaintextArray); 219 return decryptedContent; 220 }, 221 222 223 _replace_main_content: function(originalContent, newContent){ 224 225 var regex = /([\s\S]*)<!--contentstart-->([\s\S]*)<!--contentend-->([\s\S]*)/gm; 226 227 var m, 228 preContent, 229 mainContent, 230 postContent; 231 232 while ((m = regex.exec(originalContent)) !== null) { 233 // This is necessary to avoid infinite loops with zero-width matches 234 if (m.index === regex.lastIndex) { 235 regex.lastIndex++; 236 } 237 238 // The result can be accessed through the `m`-variable. 239 m.forEach(function (match, groupIndex) { 240 if (groupIndex == 1) { 241 preContent = match; 242 } 243 if (groupIndex == 2) { 244 mainContent = match; 245 } 246 if (groupIndex == 3) { 247 postContent = match; 248 } 249 // console.log(`Found match, group ${groupIndex}: ${match}`); 250 }); 251 } 252 var result = preContent + newContent + postContent; 253 return result; 254 255 }, 256 257 preloader: { 258 259 init: function() { 260 var preloader_html = '<div id="preloader"><div id="preloader_mask"></div>' + $.pageload.options.preloader_additional_html + '<div id="loader_wrapper"><div id="loader"></div></div><div id="loader_logo"></div></div>'; 261 262 var first_page_load = $('body').hasClass('first-load-complete'); 263 var internal_link = document.referrer && typeof document.referrer != 'undefined' ? true : false;
264 265 266 var load_type = ''; 267 268 if (!$.pageload.options.development_mode_show_splash_screen_on_refresh) { 269 if (typeof window.performance !== 'undefined' && typeof window.performance.getEntriesByType !== 'undefined') { 270 if (performance.getEntriesByType("navigation").length && typeof performance.getEntriesByType("navigation") !== 'undefined') { 271 if (performance.getEntriesByType("navigation")[0].type && typeof performance.getEntriesByType("navigation")[0].type != 'undefined') { 272 if (performance.getEntriesByType("navigation")[0].type == 'reload'){ 273 load_type = 'reload'; 274 } 275 } 276 } 277 } 278 } 279 280 var show_splash_screen = (($.pageload.options.splash_screen_always_enabled && !internal_link && load_type != 'reload') || ($.pageload.options.splash_screen_enabled && !h.getCookie('splash_screen_disabled') && load_type != 'reload' )); // (!h.getCookie('splash_screen_disabled')) 281 // Force splash screen in development mode 282 283 if ($.pageload.options.development_mode || window.location.search == '?pageloaddevmode=1') { 284 show_splash_screen = true; 285 } 286 287 // Only show the preloader on the first page load 288 if (!first_page_load) { 289 290 if (!$('body').attr('data-pathname')) { 291 $('body').attr('data-pathname', window.location.pathname + window.location.search); 292 } 293 294 $('body').attr('data-page-title', document.title); 295 if ($('body').find('#preloader').length === 0) { 296 //console.info("Splash screen loader via javascript"); 297 $('body').append(preloader_html); 298 } 299 history.replaceState({'firstPageLoad': true}, null, window.location.pathname + window.location.hash + location.search); 300 if (show_splash_screen) { 301 // Show splash screen if its the very first page load, otherwise a cookie is set for 15 minutes and will stop the splash screen showing again during the same website visit 302 $.pageload.fn.preloader.start_load(); 303 } else { 304 // If the splash screen is not displayed, only add the first-load-complete class to the body and don't fire the loader script 305 $.pageload.fn.preloader.start_load(true); 306 } 307 } 308 309 // Set a cookie so the splash screen doesn't show again in the same visit 310 h.setCookie('splash_screen_disabled', 'true', '', $.pageload.options.splash_screen_cookie_expiry); // Set cookie for 15 minutes 311 312 }, 313 314 start_load: function(short_load) { 315 // debugger; 316 // Start loader 317 if (short_load) { 318 $('body').addClass('loader-active first-load-complete skip-splash-screen content-load-waiting'); 319 $('body') 320 .addClass('loader-active ajax-links-disabled') 321 .delay(50) 322 .queue(function() { 323 $('body').addClass('ajax-loading ajax-initial-loading'); 324 $(this).dequeue(); 325 }) 326 ; 327 $.pageload.fn.preloader.preload_images(short_load); 328 } else { 329 $('body').addClass('loader-active splash-loader-active content-load-waiting'); 330 // debugger; 331 $.pageload.options.preloader_in(); 332 333 $('#preloader') 334 .delay(20) 335 .queue(function() { 336 $(this).addClass('loading-start'); 337 $(this).dequeue(); 338 // debugger; 339 }) 340 .delay($.pageload.options.splash_screen_auto_delays_enabled ? 200 : 0) 341 .queue(function() { 342 $(this).addClass('loading-bar-start'); 343 $(this).dequeue(); 344 // debugger; 345 }) 346 .delay($.pageload.options.splash_screen_auto_delays_enabled ? 300 : 0) 347 .queue(function() { 348 $(this).dequeue(); 349 $.pageload.fn.preloader.preload_images(); 350 // debugger; 351 }) 352 ; 353 } 354 355 }, 356 357 preload_images: function(short_load) { 358 359 // Define the images/backgrounds which should be preloaded on first page load 360 // We preload the first two images of the hero slider, and the generic sidebar image for the full detail page of each record 361 362 var images_to_load_selector = $.pageload.options.preload_images_selector; 363 364 if ($(images_to_load_selector).length) { 365 366 // IMPORTANT: Images to be preloaded must be supplied as a selector string to the 'mutliple_elements' parameter. 367 // Otherwise if you use the normal method the script will go through each of the selector items individually and the 'progress' and 'done' callbacks will NOT be run in one single process. 368 // $('body').pageLoadwaitForImages({ 369 // waitForAll: true,
370 // multiple_elements: images_to_load_selector 371 // }); 372 373 // Check the logo image is loaded before displaying the splash screen. 374 // If there isn't a logo image it should fall through to done. 375 376 // Put logo image in place to initiate load 377 $.pageload.fn._fetchBackgroundImages($.pageload.options.splash_screen_primary_preload_images_selector); 378 $('body').pageLoadwaitForImages({ 379 waitForAll: true, 380 multiple_elements: $.pageload.options.splash_screen_primary_preload_images_selector 381 }).done(function(e){ 382 $('body').addClass('pageload-splash-primary-images-preloaded'); 383 $($.pageload.options.splash_screen_primary_preload_images_selector).css('opacity', 1); 384 385 if ($.pageload.options.verbose) { 386 console.log('#########'); 387 console.log('Preloading images:'); 388 } 389 var percentCounter = 0; 390 var percentIncrements = (100 / $(images_to_load_selector).length); 391 392 393 // Put background images in place to initiate load 394 $.pageload.fn._fetchBackgroundImages(images_to_load_selector); 395 // console.log() 396 397 $('body').pageLoadwaitForImages({ 398 waitForAll: true, 399 multiple_elements: images_to_load_selector 400 }) 401 .progress(function(loaded, count, success) { 402 percentIncrements = (100 / count); 403 percentCounter = percentCounter + percentIncrements; 404 var currentPercentage = percentCounter + '%'; 405 $('#loader').css($.pageload.options.loader_orientation, currentPercentage); 406 // Connect stuff to the loader here!!! 407 // var superpathPercentage = 327.86 * (Math.round(percentCounter) / 100); 408 // $('.superpath').css('stroke-dashoffset', Math.round(327.86 - superpathPercentage)); 409 410 if ($.pageload.options.verbose) { 411 console.log('#########'); 412 console.log('Status:'); 413 console.log(currentPercentage); 414 } 415 }) 416 .done(function() { 417 if ($.pageload.options.verbose) { 418 console.log('#########'); 419 console.log('Status:'); 420 console.log('complete'); 421 } 422 423 $('#loader') 424 .delay(500) 425 .queue(function() { 426 $.pageload.fn.preloader.load_complete(short_load); 427 $(this).dequeue(); 428 }) 429 ; 430 }); 431 ; 432 433 // Fade in the background image once it's finished downloading. 434 // Put logo image in place to initiate load 435 $.pageload.fn._fetchBackgroundImages($.pageload.options.splash_screen_secondary_preload_images_selector); 436 // This has no effect if the page content is loaded before the background image, this is by design! 437 $('body').pageLoadwaitForImages({ 438 waitForAll: true, 439 multiple_elements: $.pageload.options.splash_screen_secondary_preload_images_selector 440 }) 441 .done(function(e){ 442 $('body').addClass('pageload-splash-secondary-images-preloaded'); 443 $('#home_splash_image_container').css({ 444 'opacity': 1 445 }); 446 }); 447 448 449 }); 450 } else { 451 // Fade in the background image once it's finished downloading. 452 // Put logo image in place to initiate load
453 $.pageload.fn._fetchBackgroundImages($.pageload.options.splash_screen_secondary_preload_images_selector); 454 // This has no effect if the page content is loaded before the background image, this is by design! 455 $('body').pageLoadwaitForImages({ 456 waitForAll: true, 457 multiple_elements: $.pageload.options.splash_screen_secondary_preload_images_selector 458 }) 459 .done(function(e){ 460 $('body').addClass('pageload-splash-secondary-images-preloaded'); 461 $('#bk-img-container').css('opacity', 1); 462 $('#home_splash_image_container').css({ 463 'opacity': 1 464 }); 465 }); 466 467 $('#loader') 468 .delay($.pageload.options.splash_screen_auto_delays_enabled ? 100 : 0) 469 .queue(function() { 470 $(this).css($.pageload.options.loader_orientation, '100%'); 471 $(this).dequeue(); 472 }) 473 .delay($.pageload.options.splash_screen_auto_delays_enabled ? 300 : 0) 474 .queue(function() { 475 $.pageload.fn.preloader.load_complete(short_load); 476 $(this).dequeue(); 477 }) 478 ; 479 } 480 }, 481 482 load_complete: function(short_load) { 483 // Finish the preloader animations 484 if (short_load) { 485 486 $('body').removeClass('content-load-waiting skip-splash-screen'); 487 $.pageload.fn.preloader.end_ajax(); 488 489 } else { 490 if (!$('body').hasClass('first-load-complete')) { 491 if ($.pageload.options.development_mode || $.pageload.options.splash_screen_click_to_close) { 492 $('#preloader').click(function() { 493 $(this).dequeue(); 494 }); 495 } 496 $('#preloader') 497 .queue(function() { 498 $(this).addClass('loading-complete'); 499 $('#loader').css($.pageload.options.loader_orientation, '100.1%'); // Important: Setting the width as 100.1 (or anything other than 100) forces CSS transitions to update if one has specifically been set for .loading-complete (e.g. we usually speed up the progress bar at the end) 500 if (!$.pageload.options.development_mode) { 501 $(this).dequeue(); 502 } 503 }) 504 .delay($.pageload.options.splash_screen_auto_delays_enabled ? 400 : 0) 505 .queue(function() { 506 $(this).addClass('loading-bar-end'); 507 $('#loader').css($.pageload.options.loader_orientation, ''); 508 if (!$.pageload.options.development_mode) { 509 $(this).dequeue(); 510 } 511 }) 512 .delay($.pageload.options.splash_screen_auto_delays_enabled ? 500 : 0) 513 .queue(function() { 514 $(this).addClass('splash-screen-in'); 515 $.pageload.options.splash_screen_in(); 516 if (!$.pageload.options.development_mode && !$.pageload.options.development_mode_pause_splash_screen && !$.pageload.options.splash_screen_click_to_close) { 517 $(this).dequeue(); 518 } 519 }) 520 .delay($.pageload.options.splash_screen_click_to_close ? 0 : $.pageload.options.splash_screen_delay_after_complete) 521 .queue(function() { 522 $('body').addClass('pageload-splash-page-content-in'); 523 $(this).dequeue(); 524 }) 525 .delay(400) 526 .queue(function() { 527 $(this).addClass('splash-screen-out'); 528 $.pageload.options.splash_screen_out(); 529 $('body').removeClass('content-load-waiting'); 530 $('body').removeClass('pageload-splash-page-content-hidden'); 531 if (!$.pageload.options.development_mode) { 532 $(this).dequeue(); 533 } 534 }) 535 .delay(400) 536 .queue(function() { 537 $('body').addClass('first-load-complete'); 538 $('body').removeClass('loader-active ajax-loading splash-loader-active pageload-splash-page-content-in'); 539 $(this).removeClass('loading-start loading-bar-start loading-complete loading-bar-end splash-screen-in
539splash-screen-out'); 540 $('#loader').css($.pageload.options.loader_orientation, ''); 541 $(this).dequeue(); 542 }) 543 ; 544 } 545 } 546 547 // After preload has completed, load the rest of the hero images (only the first 2 are preloaded) 548 549 $('#hero_slider .hero_item .image div[data-style]').each(function() { 550 $(this).attr('style', $(this).attr('data-style')); 551 $(this).removeAttr('data-style'); 552 }); 553 554 }, 555 556 start_ajax: function(clicked_element, incoming_content_type) { 557 558 var clicked_element = (clicked_element && typeof clicked_element != 'undefined' ? clicked_element : false); 559 560 var assumed_incoming_content_type = 'standard'; // A class can be added to the original clicked element which allows us to assume the content type before it arrives, if this exists use it to add certain classes 561 var content_type_body_class = 'loader-incoming-type-standard'; 562 563 if (incoming_content_type && typeof incoming_content_type != 'undefined') { 564 assumed_incoming_content_type = incoming_content_type; 565 } 566 567 if (clicked_element) { 568 if (clicked_element.hasClass('pageload-link-type-ajax-enabled-content')) { 569 assumed_incoming_content_type = 'inner'; 570 content_type_body_class = 'loader-incoming-type-inner'; 571 } else if (clicked_element.hasClass('pageload-link-type-popup-enabled-content')) { 572 assumed_incoming_content_type = 'popup'; 573 } 574 } 575 576 if (assumed_incoming_content_type == 'inner') { 577 content_type_body_class = 'loader-incoming-type-inner'; 578 } else if (assumed_incoming_content_type == 'popup') { 579 content_type_body_class = 'loader-incoming-type-popup'; 580 } 581 582 // Reset some things first, if the end of the last load has not completely finished 583 $('body').removeClass('loader-active ajax-loading-complete'); 584 $(this).removeClass('loading-start loading-bar-start loading-complete loading-bar-end splash-screen-in splash-screen-out'); 585 $('#loader').css($.pageload.options.loader_orientation, ''); 586 587 // Start loading of new page 588 $('body') 589 .clearQueue() 590 .addClass('loader-active ajax-links-disabled page-transition-active ' + content_type_body_class) 591 .delay(50) 592 .queue(function() { 593 $('body').addClass('ajax-loading ajax-initial-loading'); 594 $(this).dequeue(); 595 }) 596 ; 597 $.pageload.options.page_transition_start(); 598 if (assumed_incoming_content_type == 'popup') { 599 $.pageload.options.popup_before(); 600 } 601 $('body') 602 .clearQueue('pageload-disable-links') 603 .addClass('pageload-links-disabled-temporarily') 604 .delay(500, 'pageload-disable-links') 605 .queue('pageload-disable-links', function() { 606 $('body').removeClass('pageload-links-disabled-temporarily'); 607 $(this).dequeue('pageload-disable-links'); 608 }) 609 ; 610 611 612 }, 613 614 end_ajax: function() { 615 $('body') 616 .removeClass('ajax-initial-loading ajax-links-disabled pageload-links-disabled-temporarily') 617 .removeClass('page-transition page-transition2') 618 .queue(function() { 619 $('body').removeClass('page-transition ajax-loading').removeClass('page-transition2').addClass('ajax-loading-complete'); 620 $(this).dequeue(); 621 }) 622 .delay(400) 623 .queue(function() { 624 $.pageload.options.page_transition_end(); 625 $('body').removeClass('page-transition-active loader-active ajax-loading-complete loader-incoming-type-standard loader-incoming-type-inner loader-incoming-type-popup'); 626 $(this).removeClass('complete4').removeClass('loading'); 627 $('#loader').css($.pageload.options.loader_orientation, ''); 628 $(this).dequeue(); 629 }) 630 ; 631 632 } 633 634 }, 635 636 popup: { 637 638 settings: { 639 fallback_close_path: typeof $.pageload.fn != 'undefined' ? (typeof $.pageload.fn.popup.settings != 'undefined' ? (typeof $.pageload.fn.popup.settings.fallback_close_path != 'undefined' ? $.pageload.fn.popup.settings.fallback_close_path : '') : '') : '' 640 }, 641 642 init: function() { 643 644 // if the popup doesn't have a title with an id of 'popup_regi
644on' give a generic aria label of 'popup' 645 if ($('#popup_container #popup_region').length) { 646 var popup_region_aria_label = 'aria-labelledby="popup_region"' 647 } else { 648 var popup_region_aria_label = 'aria-label="modal"' 649 } 650 651 if (!$('#popup_container').length) { 652 $('body').append('<div id="popup_container"><div id="popup_overlay"></div><div id="popup_box"><div class="inner" role="dialog" aria-modal="true" aria-live="polite" ' + popup_region_aria_label + '><div id="popup_content"></div><div class="pagination_controls"><div class="previous pagination_controls_previous"><a href="#" role="button">Previous</a></div><div class="next pagination_controls_next"><a href="#" role="button">Next</a></div></div><div class="close"><a href="javascript:;" role="button">Close</a></div></div></div></div>'); 653 } 654 655 if ($('.site-popup-enabled-content').length) { 656 if ($.pageload.options.popup_content_force_open) { 657 var popup_content_html = $('.site-popup-enabled-content').html(); 658 var forced_close_path = $('.site-popup-enabled-content').attr('data-pageload-popup-fallback-close-path'); 659 660 $('.site-popup-enabled-content').remove(); 661 662 $.pageload.popup_open(popup_content_html); 663 664 $('body').addClass('site-popup-fallback-forced-open'); 665 666 if (forced_close_path && typeof forced_close_path != 'undefined') { 667 $.pageload.fn.popup.settings.fallback_close_path = forced_close_path; 668 } else { 669 $.pageload.fn.popup.settings.fallback_close_path = '/'; 670 } 671 } else { 672 $('body').addClass('site-popup-fallback-mode'); 673 } 674 } else { 675 if (!$('body').hasClass('page-popup-active')) { 676 $('body').removeClass('site-popup-fallback-mode site-popup-fallback-forced-open'); 677 } 678 } 679 680 $('#popup_box .close').off('click.closefunction').on('click.closefunction', function() { 681 $.pageload.fn.popup.close_popup(); 682 }); 683 684 $('#popup_overlay').click(function() { 685 $('#popup_box .close').trigger('click'); 686 }); 687 688 }, 689 690 open: function(content) { 691 $('#popup_content').html(content); 692 $('html').addClass('page-popup-active'); 693 $('body') 694 .clearQueue() 695 .addClass('page-popup-active') 696 .removeClass('ajax-initial-loading') 697 .delay(50) 698 .queue(function() { 699 $(this).addClass('page-popup-visible'); 700 $(this).dequeue(); 701 }) 702 ; 703 $.pageload.fn.popup.after_load(); 704 $.pageload.fn.preloader.end_ajax(); 705 706 }, 707 708 close_popup: function(forced) { 709 if (typeof pageload_xhr != 'undefined') { 710 pageload_xhr.abort('forced_abort'); 711 } 712 forced = forced && typeof forced != 'undefined' ? true : false; 713 if ($('body').hasClass('page-popup-force-close')) { 714 forced = true; 715 } 716 717 var forced_close_path = $.pageload.fn.popup.settings.fallback_close_path; 718 719 if ($('body').hasClass('site-popup-fallback-forced-open') && forced_close_path && !forced) { 720 721 $.pageload.load(forced_close_path, true); 722 723 } else { 724 if (!forced) { 725 $('body').addClass('page-popup-clicked-close'); 726 if ($.pageload.options.popup_content_update_url){ 727 window.history.back(); 728 } 729 } 730 $('body') 731 .clearQueue() 732 .removeClass('page-popup-visible loader-incoming-type-popup') 733 .delay(600) 734 .queue(function() { 735 $.pageload.options.popup_after_close(); 736 737 // remove keyboard pagination listener 738 $(window).off('keydown.popup_pagination'); 739 740 //if (!$('body').hasClass('page-popup-force-close')) { 741 // history.replaceState({'ajaxPageLoad': true}, null, $('body').attr('data-pathname')); 742 //} 743 744 // change url used in seo edit screen 745 if ($('#cms-frontend-toolbar-seo-admin .seo-tools-btn').length) { 746 $('#cms-frontend-toolbar-seo-admin .seo-tools-btn').attr("href", window.location.pathname) 747 try { 748 window.seo.init(); 749 } catch (error) { 750 console.error(error); 751 } 752 } 753 if ($('#popup_box iframe').length > 0) { 754 $('#popup_box iframe').remove(); 755 } 756 $('html').removeClass('page-popup-active'); 757 758 //Return non-popup page title 759 var base_page_title = $('body').attr('data-page-title'); 760 if (base_page_title && typeof base_page_title != 'undefined') { 761 document.title = base_page_title; 762 } 763 764 $('html').removeClass('page-popup-active'); 765 $(this).removeClass('page-popup-active page-popup-force-close page-popup-clicked-close'); 766 $(this).dequeue(); 767 }) 768 ; 769 try { 770 h.accessibility.on_popup_closing(); 771 } 772 catch(error) { 773 console.log(error); 774 } 775 } 776 777 $.pageload.fn.popup.settings.fallback_close_path = ''; 778 779 }, 780 781 after_load: function() { 782 783 // Previous/Next buttons 784 785 $('#popup_box').delay(400).queue(function() { 786 $('body').removeClass('page-popup-transition-initial'); 787 $(this).removeClass('popup-direction-left popup-direction-right'); 788 $(this).dequeue(); 789 }); 790 791 var link_suffix = ''; 792 if (window.location.search != '') { 793 if (window.location.search.indexOf('?_preview_uid') == 0 || window.location.search.indexOf('?_cmspreview=1') == 0) { 794 link_suffix = window.location.search; 795 } 796 } 797 var previous_link = $('#popup_content .pagination_controls .pagination_controls_prev a').attr('href'); 798 var previous_clicked_element = $('#popup_content .pagination_controls .pagination_controls_prev a'); 799 var next_link = $('#popup_content .pagination_controls .pagination_controls_next a').attr('href'); 800 var next_clicked_element = $('#popup_content .pagination_controls .pagination_controls_next a'); 801 802 // Add language in front of link if it exists 803 if (window.archimedes.proxy_dir && typeof window.archimedes.proxy_dir != 'undefined' && previous_link && typeof previous_link != 'undefined' && !previous_link.startsWith(window.archimedes.proxy_dir + '/')) { 804 previous_link = window.archimedes.proxy_dir + previous_link; 805 } 806 if (window.archimedes.proxy_dir && typeof window.archimedes.proxy_dir != 'undefined' && next_link && typeof next_link != 'undefined' && !next_link.startsWith(window.archimedes.proxy_dir + '/')) { 807 next_link = window.archimedes.proxy_dir + next_link; 808 } 809 810 if (previous_link && typeof previous_link != 'undefined') { 811 $('#popup_box > .inner .pagination_controls .previous') 812 .off() 813 .attr('data-href', previous_link + link_suffix) 814 .removeClass('disabled') 815 .click(function() { 816 $('body').addClass('page-popup-transition-initial'); 817 $('#popup_box').addClass('popup-direction-left'); 818 819 $.pageload.fn.pages.load($(this).attr('data-href'), false, null, null, previous_clicked_element, null, 'popup'); 820 return false;
821 }) 822 ; 823 $('#popup_box > .inner .pagination_controls .previous a').removeAttr("data-disabled aria-label").attr('tabindex', 0); 824 } else { 825 $('#popup_box > .inner .pagination_controls .previous').off().attr('data-href', '').addClass('disabled'); 826 $('#popup_box > .inner .pagination_controls .previous a').attr({"data-disabled": true, "tabindex": -1, "aria-label": "disabled"}); 827 } 828 829 if (next_link && typeof next_link != 'undefined') { 830 $('#popup_box > .inner .pagination_controls .next') 831 .off() 832 .attr('data-href', next_link + link_suffix) 833 .removeClass('disabled') 834 .click(function() { 835 $('body').addClass('page-popup-transition-initial'); 836 $('#popup_box').addClass('popup-direction-right'); 837 $.pageload.fn.pages.load($(this).attr('data-href'), false, null, null, next_clicked_element, null, 'popup'); 838 return false; 839 }) 840 ; 841 $('#popup_box > .inner .pagination_controls .next a').removeAttr("data-disabled aria-label").attr('tabindex', 0); 842 } else { 843 $('#popup_box > .inner .pagination_controls .next').off().attr('data-href', '').addClass('disabled'); 844 $('#popup_box > .inner .pagination_controls .next a').attr({"data-disabled": true, "tabindex": -1, "aria-label": "disabled"}); 845 } 846 847 848 // Run functions required in the popup 849 850 $.pageload.options.popup_after(); 851 852 // Popup key listeners 853 854 if ($('#popup_container .pagination_controls').length) { 855 var next_btn = $('#popup_container .pagination_controls .next').not('.disabled').eq(0); 856 var prev_btn = $('#popup_container .pagination_controls .previous').not('.disabled').eq(0); 857 858 $(window).off('keydown.popup_pagination').on('keydown.popup_pagination', function(e) { 859 860 // isTopPopup variable is to determine which popup is the current popup / top layered popup. 861 try { 862 var isTopPopup = h.accessibility.is_current_popup("#popup_box .inner"); 863 } catch(error) { 864 var isTopPopup = true; 865 } 866 867 if(e.keyCode == 39 && isTopPopup) { 868 if(next_btn.length ) {// right 869 $(window).off('keydown.popup_pagination'); 870 next_btn.trigger('click'); 871 } 872 } else if(e.keyCode == 37 && isTopPopup) { 873 if(prev_btn.length) { 874 $(window).off('keydown.popup_pagination'); 875 prev_btn.trigger('click'); 876 } 877 } 878 }); 879 } 880 881 882 // Accessibility - add id for region label & focus on popup content 883 if ($('#popup_content .title:first').length) { 884 $('#popup_content .title:first').attr("id", "popup_region"); 885 } else if ($('#popup_content .artist').length) { 886 $('#popup_content .artist').attr("id", "popup_region"); 887 } 888 889 try { 890 if ($("#popup_box.popup-direction-right").length || $("#popup_box.popup-direction-left").length) { 891 h.accessibility.focus_untrap(); 892 h.accessibility.focus_trap('#popup_box .inner', false, '#popup_container .close'); 893 } else { 894 h.accessibility.on_popup_opening('#popup_box .inner', '#popup_box .focu
894strap-first', '#popup_container .close'); 895 } 896 } 897 catch(error) { 898 899 console.log(error); 900 901 // backup escape key functionality 902 $(window).off('keydown.popup_close'); 903 if ($('#popup_container .close').length) { 904 $(window).on('keydown.popup_close', function(e) { 905 if(e.keyCode == 27) { 906 $(window).off('keydown.popup_close'); 907 $('#popup_container .close').trigger('click'); 908 } 909 }); 910 } 911 912 } 913 914 // Set focus on popup inner container on open or next/previous 915 if ( $('#popup_box .inner:first').length ) { 916 $('#popup_box .inner:first').attr('tabindex', -1)[0].focus({preventScroll:true}); 917 } 918 919 try { 920 h.accessibility.role_button(); 921 } catch (error) { 922 console.log(error); 923 } 924 925 } 926 927 }, 928 slidein: { 929 init: function(element_href){ 930 console.log("slidein open") 931 var post_params = {}; 932 if (!$.pageload.options.disable_ajax_param) { 933 post_params['ajax'] = true; 934 } 935 936 var pageload_save_attempts = 0; 937 var pageload_save_attempt_limit = 5; 938 var xhr = new XMLHttpRequest(); 939 var pageload_xhr = $.ajax({ 940 url: element_href, 941 data: post_params, 942 method: 'GET', 943 cache: true, 944 dataType: 'html', 945 xhr: function() { 946 return xhr; 947 }, 948 error: function(e) { 949 var error_status_code = e.status; 950 var load_attempt_limit_reached = pageload_save_attempts >= pageload_save_attempt_limit ? true : false; 951 if (e.statusText == 'forced_abort') { 952 // User forced the request to be cancelled, dont show an error 953 $.pageload.fn.preloader.end_ajax(); 954 } else { 955 if (String(error_status_code) == '0') { 956 window.location.href = element_href; 957 } else if (String(error_status_code) != '404' && !load_attempt_limit_reached) { 958 // Retry loading after a timeout 959 return Promise.resolve().then(() => { 960 pageload_load_new_page(element_href); 961 }); 962 } else { 963 // When load attempts have been exchausted or if it the error is a 404 964 h.alert('Sorry, that page could not be loaded. Please try again later.'); 965 $.pageload.fn.preloader.end_ajax(); 966 } 967 pageload_save_attempts = pageload_save_attempts + 1; 968 } 969 }, 970 success: function (new_page_html) { 971 if (new_page_html) { 972 973 $(".buy_enquire_quick_view .buy_enquire_quick_view_content").html(''); 974 new_page_html = new_page_html; 975 976 // Create 'parsed' version of the incoming HTML so we can interact as a jQuery object 977 var new_page_html_parsed = $.parseHTML(new_page_html); 978 // Change instances of 'data-style' to 'style' so we can preload these images later on 979 new_page_html = new_page_html.replace(/data-style=/g, 'style='); 980 981 // Parse the body of the new page HTML so we can interact with it with jQuery 982 var new_page_html_body = $.parseHTML('<div id="ajax_container">' + new_page_html.replace(/^[\S\s]*<body[^>]*?>/i, "").replace(/<\/body[\S\s]*$/i, "") + '</div>'); 983 984 if (new_page_html_body.length > 1) { 985 // This is to fix an issue where more than one element was being returned by new_page_html_body - #ajax_container is the only element we want. Other elements included comment tags. 986 new_page_html_body = $(new_page_html_body).filter('#ajax_container'); 987 } 988 // Find the container_inner of the new page content 989 var new_page_main_content = $(".site-slidein-enabled-content", new_page_html_body).html(); 990 991 $('.buy_enquire_quick_view .buy_enquire_quick_view_content').html(new_page_main_content); 992 993 $.pageload.fn.slidein.slidein_after(new_page_main_content); 994 $.pageload.fn.preloader.end_ajax(); 995 $('.buy_enquire_quick_view .quick-view-information ,.buy_enquire_quick_view .quick-view-buy-enquire-button').addClass('show-content'); 996 997 998 } 999 1000 1001 } 1002 }); 1003 1004 1005 //$.pageload.load(content); 1006 //$.pageload.fn.preloader.end_ajax(); 1007 }, 1008 slidein_after: function(){ 1009 // Initialise everything again 1010 //$.pageload.options.init_after_load(); 1011 1012 $.pageload.options.popup_after(); 1013 h.accessibility.on_popup_opening('.buy_enquire_quick_view', '.buy_enquire_quick_view .store_item_buy_now .button', '.buy_enquire_quick_view .close'); 1014 1015 1016 } 1017 }, 1018 1019 pages: { 1020 1021 init: function() { 1022 1023 $.pageload.fn.pages.add_click_events(); 1024 1025 if ($.pageload.options.page_scroll_history) { 1026 // If page scroll history is enabled, block automatic browser scroll restoration until loading has completed 1027 if ('scrollRestoration' in history) { 1028 history.scrollRestoration = 'manual'; 1029 } 1030 } 1031 1032 $(window).on("popstate", function (ev) { 1033 1034 if (ev.originalEvent.state) { 1035 if (ev.originalEvent.state.ajaxPageLoad || ev.originalEvent.state.firstPageLoad) { 1036 if (!window.location.hash || typeof window.location.hash == 'undefined') { 1037 // Tom: In development: check custom functions 1038 if (window.location.pathname in $.pageload.options.popstate_custom_functions) { 1039 var custom_function = $.pageload.options.popstate_custom_functions[window.location.pathname]; 1040 custom_function(ev); 1041 } else if (($('body').hasClass('page-popup-active') || $('body').hasClass('page-popup-clicked-close')) && !$('body').hasClass('site-popup-fallback-forced-open')) { 1042 if (!$('body').hasClass('page-popup-force-close') && !$('body').hasClass('page-popup-clicked-close')) { 1043 $('body').addClass('page-popup-force-close'); 1044 $('#popup_box .close').trigger('click'); 1045 } 1046 } else { 1047 var page_scroll_top_value = 0; 1048 if ($.pageload.options.page_scroll_history && ev.originalEvent.state.scrollTop && typeof ev.originalEvent.state.scrollTop != 'undefined') { 1049 page_scroll_top_value = ev.originalEvent.state.scrollTop; 1050 } 1051 $.pageload.fn.pages.load(window.location.pathname + window.location.search, false, null, 'history_change', null, page_scroll_top_value); 1052 } 1053 } 1054 } 1055 } 1056 }); 1057 1058 $(window).on("beforeunload", function(){ 1059 if ($.pageload.options.page_scroll_history) { 1060 history.scrollRestoration = 'auto'; 1061 } 1062 }); 1063 1064 }, 1065 1066
1067 add_click_events: function(element_context) { 1068 if (!element_context || typeof element_context == 'undefined') { 1069 element_context = '#container'; 1070 } 1071 1072 if ($.pageload.options.ajax_navigation_enabled){ 1073 $('a', element_context).off('click.pageload').on('click.pageload', function() { 1074 1075 // For accessibility - tracks which element to refocus on 1076 try { 1077 h.accessibility.global_variables.element_to_refocus_to = $(this); 1078 } catch(error) { 1079 console.log(error); 1080 } 1081 1082 var element = $(this); 1083 var element_href = $(this).attr('href'); 1084 1085 if (element_href) { 1086 if (!$(this).hasClass('link-no-ajax') && !$(this).hasClass('page-load-within') && !$('body').hasClass('slider-drag') && element_href != '#' && element_href.indexOf('/') == 0 && (element_href.indexOf('#') < 0 || (element_href.indexOf('#') > -1 && element_href != window.location.pathname)) && element_href.indexOf('/custom_images/') < 0 && element_href.indexOf('/usr/') < 0 && element.attr('target') != '_blank') { 1087 // console.log(element_href); 1088 if ($('body').hasClass('pageload-links-disabled-temporarily')) { 1089 // Links temporarily disabled, this is to avoid double clicks making pages load twice 1090 return false; 1091 } else if ($('body').hasClass('ajax-links-disabled')) { 1092 // Already loading page content, we could also cancel the request and start a new one. Currently we are allowing standard navigation in this case. 1093 } else if ($('body').hasClass('website-editor-mode') && window.parent.website_editor && $.isFunction(window.parent.website_editor.init)) { 1094 1095 function success_callback() { 1096 $.pageload.fn.pages.load(element_href, true, null, null, element); 1097 } 1098 window.parent.website_editor.warnings_and_notifications.check_for_unsaved_changes(success_callback); 1099 return false; 1100 1101 } else { 1102 $.pageload.fn.pages.load(element_href, true, null, null, element); 1103 return false; 1104 } 1105 } else if ($('body').hasClass('slider-drag')) { 1106 return false; 1107 } 1108 } 1109 }); 1110 } 1111 1112 1113// to be moved into other js file 1114 $('.buy_enquire_button .button').off('click').on('click', function () { 1115 //console.log("click buy enquire button"); 1116 try { 1117 h.accessibility.global_variables.element_to_refocus_to = $(this); 1118 1119 } catch(error) { 1120 console.error(error); 1121 } 1122 1123 1124 if(!$(".buy_enquire_quick_view, .buy_enquire_overlay").hasClass("active")){ 1125 $(".buy_enquire_quick_view, .buy_enquire_overlay").addClass("active"); 1126 $("body").addClass("quick-view-active"); 1127 var slidein_url = $(this).parent().attr('data-url') + '?buy_enquire_quick_view=1'; 1128 1129 $.pageload.slidein(slidein_url); 1130 1131 }else{ 1132 1133 $("body").removeClass("quick-view-active"); 1134 $(".buy_enquire_quick_view ,.buy_enquire_overlay").removeClass("active"); 1135 } 1136 }); 1137 1138 $(".buy_enquire_overlay, .buy_enquire_quick_view .close").off('click').on('click', function () { 1139 h.accessibility.on_popup_closing(); 1140 1141 $("body").removeClass("quick-view-active"); 1142 $(".buy_enquire_quick_view ,.buy_enquire_overlay").removeClass("active"); 1143 $(".buy_enquire_button button").attr("disabled",true); 1144 1145 1146 return Promise.resolve().then(() => { 1147 $(".buy_enquire_quick_view .buy_enquire_quick_view_content").html(''); 1148 $(".buy_enquire_button button").attr("disabled",fal
1148se); 1149 }); 1150 }); 1151 1152 1153 1154 1155 }, 1156 1157 load: function(element_href, pushstate, callback, navigation_type, element, page_scroll_top_value, incoming_content_type, inner_content_selector, post_data) { 1158 1159 $.pageload.options.before_load(element_href, pushstate, callback, navigation_type, element, page_scroll_top_value, incoming_content_type, inner_content_selector); 1160 1161 if (window.history.state && typeof window.history.state != 'undefined' && typeof window.history.state != 'null') { 1162 var current_page_history_state = window.history.state; 1163 var previous_page_scroll_top = $(window).scrollTop(); 1164 current_page_history_state['scrollTop'] = previous_page_scroll_top; 1165 history.replaceState(current_page_history_state, null); 1166 } 1167 1168 if (element_href != '#' && element_href.indexOf('/') == 0 && (element_href.indexOf('#') < 0 || (element_href.indexOf('#') > -1 && element_href != window.location.pathname)) && (element_href.indexOf('/custom_images/') < 0 || element_href.indexOf('?') > -1 && element_href.indexOf('/custom_images/') > element_href.indexOf('?')) && element_href.indexOf('/usr/') < 0) { 1169 var target_top_level; 1170 if (element_href == '/') { 1171 target_top_level = '[href="' + element_href + '"]'; 1172 } else { 1173 if (typeof $(element).attr('data-original-url') != 'undefined') { 1174 target_top_level = $(element).attr('data-original-url').split('/')[1]; 1175 target_top_level = '/' + target_top_level + '/'; 1176 target_top_level = '[data-original-url^="' + target_top_level + '"]'; 1177 } else { 1178 target_top_level = element_href.split('/')[1]; 1179 target_top_level = '/' + target_top_level + '/'; 1180 target_top_level = '[href^="' + target_top_level + '"]'; 1181 } 1182 } 1183 $.pageload.fn.preloader.start_ajax(element, incoming_content_type); 1184 1185 if ($.pageload.options.verbose) { 1186 console.log('#########'); 1187 console.log('Starting page load:'); 1188 console.log(element_href); 1189 } 1190 1191 var pageload_save_attempts = 0; 1192 var pageload_save_attempt_limit = 5; 1193 1194 var pageload_load_new_page = function(element_href) { 1195 1196 var url_params_to_retain_defaults = $.pageload.options.url_params_to_retain_defaults; 1197 var url_params_to_retain = $.pageload.options.url_params_to_retain; 1198 var combined_list_of_url_params_to_retain = url_params_to_retain_defaults.concat(url_params_to_retain); 1199 var current_path = window.location.pathname + window.location.search; 1200 1201 if (combined_list_of_url_params_to_retain) { 1202 var href_contains_params = false; 1203 if (element_href.indexOf('?') >= 0) { 1204 href_contains_params = true; 1205 } 1206 1207 // Append params to be retained to element href 1208 $.each(combined_list_of_url_params_to_retain, function( index, param_to_retain ) { 1209 if (current_path.indexOf(param_to_retain) >= 0) { 1210 if (element_href.indexOf(param_to_retain) < 0) { 1211 element_href += (href_contains_params ? '&' : '?') + param_to_retain; 1212 href_contains_params = true; 1213 } 1214 } 1215 }); 1216 } 1217 1218 var post_params = {}; 1219 var load_method = 'GET'; 1220 1221 if (post_data) { 1222 load_method = 'POST'; 1223 post_params = post_data; 1224 } 1225 1226 if (!$.pageload.options.disable_ajax_param) { 1227 post_params['ajax'] = true; 1228 } 1229 1230 var xhr = new XMLHttpRequest(); 1231 1232 var pageload_xhr = $.ajax({ 1233 url: element_href, 1234 data: post_params, 1235 method: load_method, 1236 cache: true, 1237 dataType: 'html', 1238 xhr: function() { 1239 return xhr; 1240 }, 1241 error: function(e) { 1242 var error_status_code = e.status; 1243 var load_attempt_limit_reached = pageload_save_attempts >= pageload_save_attempt_limit ? true : false;
1244 if (e.statusText == 'forced_abort') { 1245 // User forced the request to be cancelled, dont show an error 1246 $.pageload.fn.preloader.end_ajax(); 1247 } else { 1248 if (String(error_status_code) == '0') { 1249 window.location.href = element_href; 1250 } else if (String(error_status_code) != '404' && !load_attempt_limit_reached) { 1251 pageload_load_new_page(element_href); 1252 } else { 1253 // When load attempts have been exchausted or if it the error is a 404 1254 h.alert('Sorry, that page could not be loaded. Please try again later.'); 1255 $.pageload.fn.preloader.end_ajax(); 1256 } 1257 pageload_save_attempts = pageload_save_attempts + 1; 1258 } 1259 }, 1260 success: function (new_page_html) { 1261 if (new_page_html) { 1262 if ($.pageload.options.verbose) { 1263 console.log('#########'); 1264 console.log('PAGE LOAD COMPLETE'); 1265 } 1266 1267 new_page_html = new_page_html; 1268 1269 var body_classes_remembered = '' 1270 function add_to_body_classes_remembered(classes) { 1271 var additional_classes_to_remember = classes.split(','); 1272 for (var i = 0; i < additional_classes_to_remember.length; i++) { 1273 var classname = $.trim(additional_classes_to_remember[i]).replace('.', ''); 1274 if ($('body').hasClass(classname)) { 1275 body_classes_remembered += ' ' + classname; 1276 } 1277 } 1278 } 1279 1280 if ($.pageload.options.body_classes_to_retain_defaults) { 1281 add_to_body_classes_remembered($.pageload.options.body_classes_to_retain_defaults); 1282 } 1283 if ($.pageload.options.body_classes_to_retain) { 1284 add_to_body_classes_remembered($.pageload.options.body_classes_to_retain); 1285 } 1286 1287 1288 // Create 'parsed' version of the incoming HTML so we can interact as a jQuery object 1289 var new_page_html_parsed = $.parseHTML(new_page_html); 1290 // Change instances of 'data-style' to 'style' so we can preload these images later on 1291 new_page_html = new_page_html.replace(/data-style=/g, 'style='); 1292 1293 // Grab the title of the new page 1294 var new_page_title = $(new_page_html_parsed).filter('title').text(); 1295 1296 // Grab the canonical of the new page 1297 var new_page_canonical = $(new_page_html_parsed).filter('link[rel="canonical"]').attr('href'); 1298 1299 if (new_page_canonical){ 1300 if ($('link[rel="canonical"]').length){ 1301 // Amend the skin's existing canonical tag to match the new page canonical 1302 $('link[rel="canonical"]').attr('href', new_page_canonical); 1303 } else { 1304 // The skin doesn't have a canonical tag so let's add one 1305 $('head').append('<link rel="canonical" href="'+new_page_canonical+'">') 1306 } 1307 } 1308 else { 1309 // The new page doesn't have a canonical set so let's remove the tag from the skin 1310 $('link[rel="canonical"]').remove(); 1311 } 1312 1313 // Grab the robots of the new page 1314 var new_page_robots = $(new_page_html_parsed).filter('meta[name="robots"]').attr('content'); 1315 if (new_page_robots){ 1316 if ($('meta[name="robots"]').length){ 1317 // Amend the skin's existing robots tag to match the new page canonical 1318 $('meta[name="robots"]').attr('content', new_page_robots); 1319 } else { 1320 // The skin doesn't have a robots tag so let's add one 1321 $('head').append('<meta name="robots" content="'+new_page_robots+'">') 1322 } 1323 } else { 1324 // The new page doesn't have a robot set so let's remove the tag from the skin 1325 $('meta[name="robots"]').remove(); 1326 } 1327 1328 // Grab meta objects and replicate on this page 1329 $(new_page_html_parsed).filter('meta[property]').each(function() { 1330 var meta_property_attr = $(this).attr('property'); 1331 var meta_content_attr = $(this).attr('content'); 1332 if (meta_property_attr && typeof meta_property_attr != 'undefined' && typeof meta_content_attr != 'undefined') { 1333 $('meta[property="' + meta_property_attr + '"]').attr('content', meta_content_attr); 1334 } 1335 }); 1336 1337 // Grab the body classes of the new page 1338 var new_page_body_class = (new_page_html.match(/body class=\"(.*?)\"/) ? new_page_html.match(/body class=\"(.*?)\"/)[1] : '') + ' ' + body_classes_remembered; 1339 1340 // Parse the body of the new page HTML so we can interact with it with jQuery 1341 var new_page_html_body = $.parseHTML('<div id="ajax_container">' + new_page_html.replace(/^[\S\s]*<body[^>]*?>/i, "").replace(/<\/body[\S\s]*$/i, "") + '</div>'); 1342 1343 if (new_page_html_body.length > 1) { 1344 // This is to fix an issue where more than one element was being returned by new_page_html_body - #ajax_container is the only element we want. Other elements included comment tags. 1345 new_page_html_body = $(new_page_html_body).filter('#ajax_container'); 1346 } 1347 1348 // Find the container_inner of the new page content 1349 var new_page_main_content = $($.pageload.options.content_area_selector, new_page_html_body).html(); 1350 1351 if (typeof new_page_main_content == 'undefined') { 1352 // Force the page to reload if the main content area has not been found 1353 window.location.href = element_href; 1354 return false;
1355 } 1356 1357 1358 if (new_page_main_content.indexOf('cachedata') > -1) { 1359 1360 var protected_path_data = localStorage.getItem('protected_paths_access') ? JSON.parse(localStorage.getItem('protected_paths_access')) : false; 1361 var check_type = 'localstorage'; // Options: 'localstorage', 'backend' 1362 if (protected_path_data) { 1363 if (typeof protected_path_data[$('#protected_path_login_form', new_page_html_body).attr('data-protected-path-id')] != 'undefined') { 1364 1365 var access_token = protected_path_data[$('#protected_path_login_form',new_page_html_body).attr('data-protected-path-id')]['access_token']; 1366 var private_area_access_key = protected_path_data[$('#protected_path_login_form',new_page_html_body).attr('data-protected-path-id')]['private_area_access_key']; 1367 var uid = protected_path_data[$('#protected_path_login_form',new_page_html_body).attr('data-protected-path-id')]['uid']; 1368 } 1369 } 1370 var cacheData = $('#cachedata', new_page_html_body).val() 1371 var salt = private_area_access_key; 1372 var decryptedContent = $.pageload.fn._decryptContent(cacheData, salt) 1373 1374 //REPLACE EVERYWHERE 1375 if (decryptedContent.indexOf('protected page access allowed') > 0) { 1376 $('#cachedata', new_page_main_content).replaceWith(decryptedContent) 1377 $('#cachedata', new_page_html_body).replaceWith(decryptedContent) 1378 new_page_main_content = $.pageload.fn._replace_main_content(new_page_main_content, decryptedContent); 1379 } else { 1380 console.error('Encrypted content - access forbidden'); 1381 } 1382 1383 } 1384 1385 1386 if (new_page_main_content.indexOf('pageload-force-hard-reload') > -1) { 1387 1388 // Force the page to reload on location change 1389 window.location.href = element_href; 1390 1391 } else { 1392 // Find out if the content of the new page is popup enabled content (popup mode) 1393 var new_page_popup_mode_enabled = new_page_main_content.indexOf('site-popup-enabled-content') > -1; // Seemed to slow performance: $(new_page_main_content).find('.site-popup-enabled-content').length; 1394 var new_page_popup_content = (new_page_popup_mode_enabled ? $('.site-popup-enabled-content', new_page_html_body).html() : ''); 1395 1396 1397 // Find out if the content of the new page can be displayed 'within' the current page (e.g. inner mode) 1398 var new_page_inner_mode_enabled = new_page_main_content.indexOf('site-ajax-enabled-inner-content') > -1; // $(new_page_main_content).find('.site-ajax-enabled-inner-content').length; 1399 var new_page_inner_content = (new_page_inner_mode_enabled ? $('.site-ajax-enabled-inner-content', new_page_html_body).html() : ''); 1400 1401 1402 // Forced 'inner' mode coming directly from external param passed to load event 1403 if (incoming_content_type == 'inner') {
1404 if (inner_content_selector && typeof inner_content_selector != 'null' && typeof inner_content_selector != 'undefined') { 1405 //If custom selector is supplied, check for this and load 1406 new_page_inner_mode_enabled = $(new_page_main_content).find(inner_content_selector).length; 1407 new_page_inner_content = (new_page_inner_mode_enabled ? $(inner_content_selector, new_page_html_body).html() : ''); 1408 } else { 1409 //Otherwise load entire page 1410 new_page_inner_mode_enabled = true; 1411 new_page_inner_content = (new_page_inner_mode_enabled ? $(new_page_html_body).html() : ''); 1412 } 1413 } 1414 1415 var new_page_requires_protection = new_page_body_class.indexOf('page-requires-frontend-protection') > -1; 1416 var new_page_protection_login = (new_page_requires_protection ? $('#protected_path_login', new_page_html_body).wrap('<div>').parent().html() : ''); 1417 1418 // Preload images for new page 1419 var images_to_load_selector = $.pageload.options.preload_images_selector; 1420 1421 // Wait for the images to load 1422 if ($(images_to_load_selector, new_page_html_body).length) { 1423 if ($.pageload.options.verbose) { 1424 console.log('#########'); 1425 console.log('Preloading images:'); 1426 } 1427 1428 var percentCounter = 0; 1429 var percentIncrements = (100 / $(images_to_load_selector, new_page_html_body).length); 1430 1431 // IMPORTANT: Images to be preloaded must be supplied as a selector string to the 'mutliple_elements' parameter. 1432 // Otherwise if you use the normal method the script will go through each of the selector items individually and the 'progress' and 'done' callbacks will NOT be run in one single process. 1433 1434 $(new_page_html_body).pageLoadwaitForImages({ 1435 waitForAll: true, 1436 multiple_elements: images_to_load_selector 1437 }) 1438 .progress(function(loaded, count, success) { 1439 var percentIncrements = (100 / count); 1440 var percentCounter = percentCounter + percentIncrements; 1441 var currentPercentage = percentCounter + '%'; 1442 $('#loader').css($.pageload.options.loader_orientation, currentPercentage); 1443 1444 if ($.pageload.options.verbose) { 1445 console.log('#########'); 1446 console.log('Status:'); 1447 console.log(currentPercentage); 1448 } 1449 }) 1450 .done(function() { 1451 if ($.pageload.options.verbose) { 1452 console.log('#########'); 1453 console.log('Status:'); 1454 console.log('complete'); 1455 } 1456 $.pageload.fn.preloader.load_complete(); 1457 $.pageload.fn.pages.after_load(new_page_title, new_page_body_class, new_page_html_body, new_page_main_content, new_page_popup_content, target_top_level, element_href, new_page_popup_mode_enabled, new_page_inner_mode_enabled, new_page_inner_content, callback, pushstate, navigation_type, page_scroll_top_value, new_page_requires_protection, new_page_protection_login, new_page_html); 1458 }) 1459 ; 1460 } else { 1461 // No images to preload 1462 if ($.pageload.options.verbose) { 1463 console.log('#########'); 1464 console.log('No images to load'); 1465 } 1466 return Promise.resolve().then(() => { 1467 $('#loader').css($.pageload.options.loader_orientation, '100%'); 1468 $.pageload.fn.preloader.load_complete(); 1469 $.pageload.fn.pages.after_load(new_page_title, new_page_body_class, new_page_html_body, new_page_main_content, new_page_popup_content, target_top_level, element_href, new_page_popup_mode_enabled, new_page_inner_mode_enabled, new_page_inner_content, callback, pushstate, navigation_type, page_scroll_top_value, new_page_requires_protection, new_page_protection_login, new_page_html); 1470 }); 1471 } 1472 1473 } 1474 1475 // If a redirect happens in the AJAX call element_href needs updated 1476 var response_url = new URL(xhr.responseURL) 1477 1478 const [uri,] = element_href.split('?'); 1479 1480 if (uri !== response_url.pathname) { 1481 element_href = response_url.pathname; 1482 } 1483 } 1484 } 1485 }); 1486 }; 1487 1488 // Start loading new page 1489 pageload_load_new_page(element_href); 1490 } 1491 1492 }, 1493 1494 after_load: function(new_page_title, new_page_body_class, new_page_html_body, new_page_main_content, new_page_popup_content, target_top_level, element_href, new_page_popup_mode_enabled, new_page_inner_mode_enabled, new_page_inner_content, callback, pushstate, navigation_type, page_scroll_top_value, new_page_requires_protection, new_page_protection_login, new_page_html) { 1495 1496 // Show new page content 1497 1498 if (new_page_popup_mode_enabled && !$('body').hasClass('site-popup-fallback-mode')) { // Skip this
1498step if we are on a full page where the content usually opens as popup content, continue to open in fallback mode - not in a popup 1499 // Popup mode content 1500 1501 if ($('body').hasClass('page-popup-active')) { 1502 // If a popup is already open 1503 if ($.pageload.options.popup_content_update_url ){ 1504 history.replaceState({'ajaxPageLoad': true}, null, element_href); 1505 } 1506 $('body') 1507 .addClass('page-popup-transition') 1508 .delay(400) 1509 .queue(function() { 1510 $('#popup_content').html(new_page_popup_content); 1511 $.pageload.fn.popup.after_load(); 1512 $.pageload.fn.preloader.end_ajax(); 1513 $(this).addClass('page-popup-transition2'); 1514 $(this).dequeue(); 1515 }) 1516 .delay(10) 1517 .queue(function() { 1518 $(this).removeClass('page-popup-transition page-popup-transition2'); 1519 $(this).dequeue(); 1520 }) 1521 ; 1522 // change url used in seo edit screen 1523 if ($('#cms-frontend-toolbar-seo-admin .seo-tools-btn').length) { 1524 $('#cms-frontend-toolbar-seo-admin .seo-tools-btn').attr("href", element_href) 1525 try { 1526 window.seo.init(); 1527 } catch (error) { 1528 console.error(error); 1529 } 1530 } 1531 } else { 1532 // If there is no existing popup, open a new one 1533 if ($.pageload.options.popup_content_update_url ){ 1534 history.pushState({'ajaxPageLoad': true}, null, element_href); 1535 } 1536 // Open the popup 1537 $.pageload.fn.popup.open(new_page_popup_content); 1538 // change url used in seo edit screen 1539 if ($('#cms-frontend-toolbar-seo-admin .seo-tools-btn')) { 1540 $('#cms-frontend-toolbar-seo-admin .seo-tools-btn').attr("href", element_href) 1541 if (window.seo && typeof window.seo != 'undefined') { 1542 window.seo.init(); 1543 } 1544 } 1545 } 1546 1547 if (new_page_title) { 1548 document.title = new_page_title; 1549 } 1550 1551 $.pageload.fn.pages.track_pageview(element_href); 1552 1553 } else if (new_page_inner_mode_enabled && callback) { 1554 console.log("inner mode"); 1555 1556 // Inner ajax content mode 1557 1558 callback(new_page_inner_content, element_href, new_page_main_content); 1559 1560 $('body') 1561 .clearQueue() 1562 .removeClass('ajax-initial-loading') 1563 .delay(10) 1564 .queue(function() { 1565 $(this).dequeue(); 1566 }) 1567 ; 1568 1569 $.pageload.fn.preloader.end_ajax(); 1570 1571 if (pushstate) { 1572 history.pushState({'ajaxPageLoad': true}, null, element_href); 1573 } 1574 1575 $.pageload.fn.pages.track_pageview(element_href); 1576 1577 } else { 1578 // Standard page content 1579 if (callback && typeof callback != 'null' && typeof callback != 'undefined') { 1580 callback(); 1581 } 1582 1583 1584 if ($.pageload.options.content_load_adjacent) { 1585 // Content load adjacent loads the content into a duplicate element which is a
1585ppended after the current element 1586 // This allows two pages to be visible at the same time and transition between them 1587 // Unbind all events 1588 $.pageload.options.destroy_after_load(); 1589 $(window).off(); 1590 $('#container *, #cms-frontend-toolbar *').off().off(); 1591 1592 // Clone and build the new objects 1593 var cloned_content_area = $($.pageload.options.content_area_selector).get(0).cloneNode(); 1594 $($.pageload.options.content_area_selector).addClass('pageload-old-content-area'); 1595 $($.pageload.options.content_area_selector).after(cloned_content_area); 1596 $($.pageload.options.content_area_selector).filter(':eq(1)').html(new_page_main_content).addClass('pageload-new-content-area'); 1597 1598 // Initialise everything again 1599 $.pageload.options.init_after_load(); 1600 1601 // Do the page transition 1602 return Promise.resolve().then(() => { 1603 1604 $.pageload.options.on_page_transition(); 1605 $('body') 1606 .clearQueue() 1607 .addClass('page-transition') 1608 .removeClass('ajax-initial-loading') 1609 .delay($.pageload.options.page_transition_delay) 1610 .queue(function() { 1611 $(this).addClass('page-transition2'); 1612 $(this).dequeue(); 1613 }) 1614 ; 1615 }); 1616 1617 return Promise.resolve().then(() => { 1618 $($.pageload.options.content_area_selector).filter(':eq(0)').remove(); 1619 $($.pageload.options.content_area_selector).removeClass('pageload-new-content-area'); 1620 }); 1621 } 1622 1623 if (navigation_type == 'history_change') { 1624 // If navigation_type has been set as 'history_change', instantly show the content 1625 $('body') 1626 .clearQueue() 1627 .removeClass('ajax-initial-loading') 1628 ; 1629 } else { 1630 // If navigation_type has been set as default, show the page transition effects 1631 if (!$.pageload.options.content_load_adjacent) { 1632 $.pageload.options.on_page_transition(); 1633 $('body') 1634 .clearQueue() 1635 .addClass('page-transition') 1636 .removeClass('ajax-initial-loading') 1637 .delay($.pageload.options.page_transition_delay) 1638 .queue(function() { 1639 $(this).addClass('page-transition2'); 1640 $(this).dequeue(); 1641 }) 1642 ; 1643 } 1644 } 1645 1646 return Promise.resolve().then(() => { 1647 1648 // Scroll page to top 1649 $('html,body').animate( 1650 {scrollTop: 0}, 1651 0, 1652 'easeInOutQuad' 1653 ); 1654 1655 if (!$.pageload.options.content_load_adjacent) { 1656 // This is done earlier with this option 1657 1658 // Unbind all events 1659 $.pageload.options.destroy_after_load(); 1660 $(window).off(); 1661 $('#container *, #cms-frontend-toolbar *').off().off(); 1662 } 1663 1664 // Destroy jQuery plugin instances 1665 $('#slideshow ul, #ig_slideshow, .lists ul li .panel_image_slideshow').cycle('destroy'); 1666 1667 // Update CMS toolbar 1668 $('#cms-frontend-toolbar').html($('#cms-frontend-toolbar', new_page_html_body).html()); 1669 1670 // init axe accessibility audit 1671 try { 1672 h.accessibility.axe_automatic_audit() 1673 } catch(error) { 1674 console.log(error); 1675 } 1676 1677 $('#top_nav.navigation ul li').removeClass('active'); 1678 $('#top_nav.navigation ul li a').removeAttr('aria-label'); 1679 $('#top_nav.navigation ul li a' + target_top_level + '').parent().addClass('active'); 1680 var nav_label = $('#top_nav.navigation ul li a' + target_top_level + '').text(); 1681 $('#top_nav.navigation ul li a' + target_top_level + '').attr('aria-label', ( nav_label + ' (current nav item)' )); 1682 1683 1684 1685 if ($('body').hasClass('page-transition')) { 1686 new_page_body_class = new_page_body_class + ' page-transition'; 1687 } 1688 $('body').attr('class', new_page_body_class); 1689 1690 if (!$.pageload.options.content_load_adjacent) { 1691 // Adjacent pageload will add the content in an alternative way, see above 1692 if ($($.pageload.options.content_area_selector).length) { 1693 // console.log('CHANGING HTML') 1694 $($.pageload.options.content_area_selector).html(new_page_main_content).css('margin-top', ''); 1695 } else { 1696 1697 // Content area does not exist, try to force load the page manually 1698 window.location.href = element_href; 1699 } 1700 } 1701 1702 // If the page requires protection, add the login form 1703 1704 if (new_page_requires_protection) { 1705 $('body').append(new_page_protection_login); 1706 } else { 1707 if (new_page_body_class.indexOf('page-requires-protection') < 0) { 1708 $('#protected_path_login').remove(); 1709 } 1710 } 1711 1712 if (pushstate) { 1713 history.pushState({'ajaxPageLoad': true}, null, element_href); 1714 } 1715 1716 if (new_page_title) { 1717 document.title = new_page_title; 1718 } 1719 1720 // Grab pathname data attribute from new page and update it 1721 var new_page_pathname = (new_page_html.match(/data-pathname=\"(.*?)\"/) ? new_page_html.match(/data-pathname=\"(.*?)\"/)[1] : '') 1722 if (new_page_pathname) { 1723 $('body').attr('data-pathname', new_page_pathname); 1724 } else { 1725 $('body').attr('data-pathname', window.location.pathname + window.location.search); 1726 } 1727 1728 $('body').attr('data-page-title', document.title); 1729 1730 if (!$.pageload.options.content_load_adjacent) { 1731 // This is done earlier with this option 1732 $.pageload.options.init_after_load(); 1733 } 1734 1735 if (window.cms_toolbar) { 1736 window.cms_toolbar.init(); 1737 } 1738 1739 $.pageload.options.after_load_complete(); 1740 1741 if (!$('body').hasClass('site-generic-overlay-fallback-mode')) { 1742 $('#overlay-close').trigger('click'); 1743 } 1744 1745 // Scroll page to top 1746 $('html,body').animate( 1747 {scrollTop: 0}, 1748 0, 1749 'easeInOutQuad' 1750 ); 1751 1752 $(window).trigger('resize'); 1753 1754 $('html,body').scrollTop(page_scroll_top_value); 1755 1756 $.pageload.fn.preloader.end_ajax(); 1757 1758 $.pageload.fn.pages.track_pageview(element_href); 1759 1760 1761 }); 1762 } 1763 1764 }, 1765 1766 track_pageview: function(element_href) { 1767 1768 $.pageload.options.pageview(); 1769 1770 // Track pageview with Analytics if it is installed 1771 1772 if (window._gaq || window.ga) { 1773 if (window.ga) { 1774 // Universal analytics 1775 ga('send', 'pageview', element_href); 1776 // Send tracker2 pageview if a secondary tracker has been installed 1777 ga('tracker2.send', 'pageview', element_href); 1778 ga('tracker3.send', 'pageview', element_href); 1779 ga('artlogic_tracker.send', 'pageview', element_href); 1780 } else if (window._gaq) { 1781 // Legacy analytics
1782 _gaq.push(['_trackPageview', element_href]); 1783 } 1784 } 1785 } 1786 1787 } 1788 }; 1789 1790 1791 // Initialise function 1792 1793 //$(window).ready(function() { 1794 $.pageload.fn.init(); 1795 1796 // Replay any calls queued by _waitFor() stubs before this constructor ran. 1797 // Each entry resolves its dotted path against $.pageload and invokes the 1798 // (now real) function with the original arguments. Failures swallowed â 1799 // a stub call that becomes invalid by replay time shouldn't break init. 1800 while (_pendingCalls.length > 0) { 1801 var _call = _pendingCalls.shift(); 1802 var _parts = _call.path.split('.'); 1803 var _target = $.pageload; 1804 for (var _i = 0; _i < _parts.length - 1 && _target; _i++) { 1805 _target = _target[_parts[_i]]; 1806 } 1807 if (_target) { 1808 var _realFn = _target[_parts[_parts.length - 1]]; 1809 if (typeof _realFn === 'function') { 1810 try { _realFn.apply(_target, _call.args); } catch (e) { /* swallow */ } 1811 } 1812 } 1813 } 1814 //}); 1815 1816 }; 1817 } // close the if (typeof $.pageload !== 'function') guard 1818 1819 // Module-load-time stubs â populate $.pageload.options, $.pageload.fn, and top-level 1820 // methods with safe defaults/no-ops so references before $.pageload({...}) is called 1821 // don't crash. The constructor REPLACES these with real implementations when invoked. 1822 // 1823 // Idempotent: only set stubs where the property doesn't already exist. This guards 1824 // against IIFE re-execution (e.g., AJAX navigation re-injecting the script tag), which 1825 // would otherwise overwrite real implementations from a previous constructor call. 1826 // Deep extend so nested array/object defaults are cloned (see comment in the constructor) 1827 if (!$.pageload.options) $.pageload.options = $.extend(true, {}, DEFAULT_OPTIONS); 1828 if (!$.pageload.fn) $.pageload.fn = { 1829 init: _waitFor('fn.init'), 1830 _fetchBackgroundImages: _waitFor('fn._fetchBackgroundImages'), 1831 _decryptContent: function() { return ''; }, // returns a value, keep as no-op (can't queue+return synchronously) 1832 _replace_main_content: _waitFor('fn._replace_main_content'), 1833 preloader: { 1834 init: _waitFor('fn.preloader.init'), 1835 start_load: _waitFor('fn.preloader.start_load'), 1836 preload_images: _waitFor('fn.preloader.preload_images'), 1837 load_complete: _waitFor('fn.preloader.load_complete'), 1838 start_ajax: _waitFor('fn.preloader.start_ajax'), 1839 end_ajax: _waitFor('fn.preloader.end_ajax') 1840 }, 1841 popup: { 1842 settings: { fallback_close_path: '' }, 1843 init: _waitFor('fn.popup.init'), 1844 open: _waitFor('fn.popup.open'), 1845 close_popup: _waitFor('fn.popup.close_popup'), 1846 after_load: _waitFor('fn.popup.after_load') 1847 }, 1848 slidein: { 1849 init: _waitFor('fn.slidein.init'), 1850 slidein_after: _waitFor('fn.slidein.slidein_after') 1851 }, 1852 pages: { 1853 init: _waitFor('fn.pages.init'), 1854 add_click_events: _waitFor('fn.pages.add_click_events'), 1855 load: _waitFor('fn.pages.load'), 1856 after_load: _waitFor('fn.pages.after_load'), 1857 track_pageview: _waitFor('fn.pages.track_pageview') 1858 } 1859 }; 1860 if (!$.pageload.load) $.pageload.load = _waitFor('load'); 1861 if (!$.pageload.refresh) $.pageload.refresh = _waitFor('refresh'); 1862 if (!$.pageload.popup_close) $.pageload.popup_close = _waitFor('popup_close'); 1863 if (!$.pageload.popup_open) $.pageload.popup_open = _waitFor('popup_open'); 1864 if (!$.pageload.slidein) $.pageload.slidein = _waitFor('slidein'); 1865 1866})(window.jQuery); 1867 1868 1869 1870 1871/** 1872 * jQuery PageLoadWaitForImages 1873 * 1874 * Copyright 2016, Artlogic Media Ltd, http://www.artlogic.net/ 1875 */ 1876 1877(function (factory) { 1878 if (typeof define === 'function' && define.amd) { 1879 // AMD. Register as an anonymous module. 1880 define(['jquery'], factory); 1881 } else if (typeof exports === 'object') { 1882 // CommonJS / nodejs module 1883 module.exports = factory(require('jquery')); 1884 } else { 1885 // Browser globals 1886 factory(jQuery); 1887 } 1888}(function ($) { 1889 // Namespace all events. 1890 var eventNamespace = 'pageLoadwaitForImages'; 1891 1892 // CSS properties which contain references to images. 1893 $.pageLoadwaitForImages = { 1894 hasImageProperties: [ 1895 'backgroundImage', 1896 'listStyleImage', 1897 'borderImage', 1898 'borderCornerImage', 1899 'cursor' 1900 ], 1901 hasImageAttributes: ['srcset'], 1902 notImageClasses: [ 1903 '.lazyload_wrapper', 1904 '.no_pageload', 1905 ], 1906 }; 1907 1908 // Custom selector to find all `img` elements with a valid `src` attribute. 1909 $.expr[':']['has-src'] = function (obj) { 1910 // Ensure we are dealing with an `img` element with a valid 1911 // `src` attribute. 1912 return $(obj).is('img[src][src!=""]'); 1913 }; 1914 1915 // Custom selector to find images which are not already cached by the 1916 // browser. 1917 $.expr[':'].uncached = function (obj) { 1918 // Ensure we are dealing with an `img` element with a valid 1919 // `src` attribute. 1920 if (!$(obj).is(':has-src')) { 1921 return false;
1922 } 1923 1924 return !obj.complete; 1925 }; 1926 1927 $.fn.pageLoadwaitForImages = function () { 1928 1929 var allImgsLength = 0; 1930 var allImgsLoaded = 0; 1931 var deferred = $.Deferred(); 1932 1933 var finishedCallback; 1934 var eachCallback; 1935 var waitForAll; 1936 var multiple_elements; 1937 1938 // Handle options object (if passed). 1939 if ($.isPlainObject(arguments[0])) { 1940 1941 multiple_elements = arguments[0].multiple_elements; 1942 waitForAll = arguments[0].waitForAll; 1943 eachCallback = arguments[0].each; 1944 finishedCallback = arguments[0].finished; 1945 1946 } else { 1947 1948 // Handle if using deferred object and only one param was passed in. 1949 if (arguments.length === 1 && $.type(arguments[0]) === 'boolean') { 1950 waitForAll = arguments[0]; 1951 } else { 1952 finishedCallback = arguments[0]; 1953 eachCallback = arguments[1]; 1954 waitForAll = arguments[2]; 1955 } 1956 1957 } 1958 1959 // Handle missing callbacks. 1960 finishedCallback = finishedCallback || $.noop; 1961 eachCallback = eachCallback || $.noop; 1962 1963 // Convert waitForAll to Boolean 1964 waitForAll = !! waitForAll; 1965 1966 // Ensure callbacks are functions. 1967 if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) { 1968 throw new TypeError('An invalid callback was supplied.'); 1969 } 1970 1971 this.each(function () { 1972 // Build a list of all imgs, dependent on what images will 1973 // be considered. 1974 if (multiple_elements) { 1975 // If the 'multiple_elements' parameter has been suplied, use this, otherwise use the original element specified 1976 var obj = $(multiple_elements, this); 1977 } else { 1978 var obj = $(this); 1979 } 1980 var allImgs = []; 1981 // CSS properties which may contain an image. 1982 var hasImgProperties = $.pageLoadwaitForImages.hasImageProperties || []; 1983 // Element attributes which may contain an image. 1984 var hasImageAttributes = $.pageLoadwaitForImages.hasImageAttributes || []; 1985 // To match `url()` references. 1986 // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri 1987 var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g; 1988 1989 let notImageClasses = $.pageLoadwaitForImages.notImageClasses || []; 1990 1991 let selectorString; 1992 if(notImageClasses.length){ 1993 selectorString = "*:not(\"" + notImageClasses.join(", ") + "\")"; 1994 } else { 1995 selectorString = "\"*\""; 1996 } 1997 1998 if (waitForAll) {; 1999 // Get all elements (including the original), as any one of 2000 // them could have a background image. 2001 obj.find(selectorString).addBack().each(function () { 2002 var element = $(this); 2003 // If an `img` element, add it. But keep iterating in 2004 // case it has a background image too. 2005 if (element.is('img:has-src') && 2006 !element.is('[srcset]')) { 2007 allImgs.push({ 2008 src: element.attr('src'), 2009 element: element[0] 2010 }); 2011 } 2012 2013 $.each(hasImgProperties, function (i, property) { 2014 var propertyValue = element.css(property); 2015 var match; 2016 // If it doesn't contain this property, skip. 2017 if (!propertyValue) { 2018 return true; 2019 } 2020 2021 // Get all url() of this element. 2022 while (match = matchUrl.exec(propertyValue)) { 2023 allImgs.push({ 2024 src: match[2], 2025 element: element[0] 2026 }); 2027 } 2028 }); 2029 2030 $.each(hasImageAttributes, function (i, attribute) { 2031 var attributeValue = element.attr(attribute); 2032 var attributeValues; 2033 2034 // If it doesn't contain this property, skip. 2035 if (!attributeValue) { 2036 return true; 2037 } 2038 2039 allImgs.push({ 2040 src: element.attr('src'), 2041 srcset: element.attr('srcset'), 2042 element: element[0] 2043 }); 2044 2045 }); 2046 2047 }); 2048 } else { 2049 // For images only, the task is simpler. 2050 obj.find('img:has-src') 2051 .each(function () { 2052 allImgs.push({ 2053 src: this.src, 2054 element: this 2055 }); 2056 }); 2057 } 2058 2059 return Promise.resolve().then(() => { 2060 allImgsLength = allImgs.length; 2061 allImgsLoaded = 0; 2062 2063 2064 if (allImgsLength === 0) { 2065 finishedCallback.call(obj[0]); 2066 deferred.resolveWith(obj[0]); 2067 } 2068 2069 $.each(allImgs, function (i, img) { 2070 2071 var image = new Image(); 2072 var events = 2073 'load.' + eventNamespace + ' error.' + eventNamespace; 2074 2075 // Handle the image loading and error with the same callback. 2076 $(image).one(events, function me (event) { 2077 // If an error occurred with loading the image, set the 2078 // third argument accordingly. 2079 var eachArguments = [ 2080 allImgsLoaded, 2081 allImgsLength,
2082 event.type == 'load' 2083 ]; 2084 allImgsLoaded++; 2085 2086 eachCallback.apply(img.element, eachArguments); 2087 deferred.notifyWith(img.element, eachArguments); 2088 2089 // Unbind the event listeners. I use this in addition to 2090 // `one` as one of those events won't be called (either 2091 // 'load' or 'error' will be called). 2092 $(this).off(events, me); 2093 2094 if (allImgsLoaded == allImgsLength) { 2095 finishedCallback.call(obj[0]); 2096 deferred.resolveWith(obj[0]); 2097 return false; 2098 } 2099 2100 }); 2101 2102 if (img.srcset) { 2103 image.srcset = img.srcset; 2104 } 2105 image.src = img.src; 2106 }); 2107 }); 2108 }); 2109 2110 return deferred.promise(); 2111 2112 }; 2113}));
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.