1/*! 2 SimpleModal.js 3 version: 2.6.8 4 author: Alex Fischer 5 homepage: https://github.com/a-p-f/SimpleModal 6*/ 7var SimpleModal = (function (exports) { 8 'use strict'; 9 10 /* 11 Read "configuration" from data-simple-modal-config attribute on html element 12 Intended mainly for features on child pages, but we might add optional parent page features here, too. 13 */ 14 var opts = (document.documentElement.getAttribute('simple-modal-config') || '').split(' '); 15 var config = { 16 autofocus: opts.indexOf('autofocus') != -1, 17 animate: opts.indexOf('animate') != -1 18 }; 19 20 function _typeof(obj) { 21 "@babel/helpers - typeof"; 22 23 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 24 _typeof = function (obj) { 25 return typeof obj; 26 }; 27 } else { 28 _typeof = function (obj) { 29 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 30 }; 31 } 32 33 return _typeof(obj); 34 } 35 36 function isObject(anything) { 37 return anything !== null && _typeof(anything) == 'object'; 38 } 39 function getMessage(anything) { 40 return isObject(anything) && anything.message; 41 } 42 function postMessage(target, message) { 43 target.postMessage({ 44 message: message 45 }, '*'); 46 } 47 function initPreviousSiblings(iframe, initFunction) { 48 var cursor = iframe; 49 50 while (cursor = cursor.previousElementSibling) { 51 initFunction(cursor); 52 } 53 } 54 function releasePreviousSiblings(iframe, releaseFunction) { 55 var cursor = iframe; // If there are any other SimpleModal layers on top of this one, we're not ready to release previous siblings 56 57 while (cursor = cursor.nextElementSibling) { 58 if (cursor._isSimpleModalIframe) return; 59 } 60 61 cursor = iframe; 62 63 while (cursor = cursor.previousElementSibling) { 64 releaseFunction(cursor); // We've reached a previous modal layer. Release it, but no more previous elements. 65 66 if (cursor._isSimpleModalIframe) return; 67 } 68 } 69 function afterAnimation(element, then) { 70 setTimeout(then, parseFloat(getComputedStyle(element).animationDuration) * 1000); 71 } 72 function resolve(url) { 73 var a = document.createElement('a'); 74 a.href = url; 75 return a.href; 76 } 77 78 var ae = document.activeElement; // Listen to messages from parent 79 80 if (window.parent != window) { 81 addEventListener('message', function (event) { 82 if (event.source != window.parent) return; 83 var data = event.data; 84 85 if (getMessage(data) == 'CANCEL_SIMPLE_MODAL_ANIMATIONS') { 86 if (config.animate) { 87 cancel_animations(); 88 } 89 90 postMessage(window.parent, 'SIMPLE_MODAL_ANIMATIONS_CANCELED'); 91 } 92 93 if (getMessage(data) == 'SIMPLE_MODAL_LOADED_AND_REFOCUSED') { 94 // If we're animating this window, don't autofocus until animation done 95 if (config.autofocus && !config.animate) autofocus(); 96 } 97 }); 98 trackAndRestoreFocus(); 99 } 100 101 function trackAndRestoreFocus() { 102 // track active element within this iframe 103 document.documentElement.addEventListener('focus', function () { 104 ae = document.activeElement; 105 }, true); // when iframe regains focus, re-focus the correct element 106 107 addEventListener('focus', function () { 108 ae && ae.focus(); 109 }); 110 } 111 112 function custom_event(name, params) { 113 // Modern browsers 114 if (typeof window.CustomEvent === "function") return new CustomEvent(name, params); // IE 9+ support 115 116 params = params || { 117 bubbles: false, 118 cancelable: false, 119 detail: undefined 120 }; 121 var event = document.createEvent('CustomEvent'); 122 event.initCustomEvent(name, params.bubbles, params.cancelable, params.detail); 123 return event; 124 } 125 126 function fire_load() { 127 window.dispatchEvent(custom_event('simplemodal-load')); 128 } 129 130 function autofocus() { 131 var target = document.querySelector('[simple-modal-autofocus]'); 132 133 if (target) {
134 target.focus(); 135 ae = target; 136 } 137 } 138 139 function after_html_animation(callback) { 140 var h = document.documentElement; 141 var animation_seconds = parseFloat(getComputedStyle(h).animationDuration); 142 setTimeout(callback, animation_seconds * 1000); 143 } 144 /* 145 Wait for load event for multiple reasons: 146 - ensure layout is finished before we start animation 147 - getComputedStyle in after_html_animation may block (waiting on stylesheets), blocking all "before-load" scripts 148 - support autofocusing of dynamically added elements (as long as they are present before we run) 149 */ 150 151 152 var animations_canceled = false; 153 154 function cancel_animations() { 155 if (animations_canceled) return; 156 animations_canceled = true; 157 var h = document.documentElement; 158 h.classList.remove('SimpleModal-opening'); 159 h.classList.remove('SimpleModal-animating'); 160 config.autofocus && autofocus(); 161 } 162 163 addEventListener('load', function () { 164 if (config.animate) { 165 if (document.querySelector('[autofocus]')) { 166 /* 167 Note - Safari seems to focus [autofocus] elements, even though this is an iframe. That broke our entrance animation on another site, but we haven't yet been able to replicate it. Seems to depend on page structure. 168 */ 169 console.warn('autofocus not recommended when using SimpleModal animations. Can sometimes break animations in Safari, but only in certain situations.'); 170 } 171 172 var h = document.documentElement; 173 h.classList.add('SimpleModal-opening'); 174 h.classList.add('SimpleModal-animating'); 175 after_html_animation(function () { 176 cancel_animations(); 177 fire_load(); 178 }); 179 } else { 180 config.autofocus && autofocus(); 181 fire_load(); 182 } 183 }); 184 function animateOut(then) { 185 var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 186 _ref$leaveBackdrop = _ref.leaveBackdrop, 187 leaveBackdrop = _ref$leaveBackdrop === void 0 ? false : _ref$leaveBackdrop; 188 189 if (!leaveBackdrop) postMessage(parent, 'ANIMATE_SIMPLE_MODAL_BACKDROP_OUT'); 190 var h = document.documentElement; 191 h.classList.add('SimpleModal-closing'); 192 h.classList.add('SimpleModal-animating'); 193 if (then) after_html_animation(then); 194 } 195 196 function assertIframed() { 197 if (window.parent == window) throw new Error('This is not a SimpleModal child window (it\'s not even in iframe)'); 198 } 199 200 function isSameOrigin() { 201 try { 202 return Boolean(window.parent.location.hostname); 203 } catch (e) { 204 return false; 205 } 206 } 207 208 function requiredLayerInParent() { 209 var layer = window.parent.SimpleModal && window.parent.SimpleModal.layerForWindow(window); 210 if (!layer) throw new Error("This is not a SimpleModal child window"); 211 return layer; 212 } 213 214 function _close() { 215 var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 216 var then = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 217 assertIframed(); 218 219 if (isSameOrigin()) { 220 var layer = requiredLayerInParent(); 221 window.parent.SimpleModal.resolveLayer(layer, value); 222 then && then(); 223 return; 224 } 225 /* 226 Parent is x-origin. 227 Can't be sure we're a SimpleModal child. 228 Just try to close. 229 If we're not a SimpleModal child, parent will (probably) just ignore this message, and nothing will happen. 230 */ 231 232 233 if (then) { 234 /* 235 For same-origin, we can invoke the callback synchronously. 236 For x-origin, we tried using postMessage to have the child call the function, but that doesn't work. 237 The child window seems to get cleaned up as soon as we post the message. 238 _perhaps_ we could support it if we stored a reference to the child window after we posted the message, but I don't think we should rely on a disconnected iframe receiving message events and running code. 239 Also, there isn't much useful that a cross-origin iframe could do in this state, anyway. The main purpose of "then" is to allow the (closed) child to navigate the parent. 240 */ 241 throw new Error('"then" callback to SimpleModal.close is not supported in cross origin layers.'); 242 } 243 244 parent.postMessage({ 245 value: value, 246 message: 'CLOSE_SIMPLE_MODAL_CHILD' 247 }, '*'); 248 } 249 250 function close() { 251 var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 252 var then = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 253 254 function do_close() { 255 _close(value, then); 256 } 257 258 if (config.animate) { 259 animateOut(do_close); 260 } else { 261 do_close(); 262 } 263 } 264 function replace(url) { 265 var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 266 _ref2$animated = _ref2.animated, 267 animated = _ref2$animated === void 0 ? false : _ref2$animated; 268 269 // Be sure to resolve urls relative to the child location, not the parent 270 url = resolve(url); 271 272 function do_replace() { 273 parent.postMessage({ 274 message: 'REPLACE_SIMPLE_MODAL', 275 url: url, 276 animated: animated 277 }, '*'); 278 } 279 280 if (animated) { 281 animateOut(do_replace, { 282 leaveBackdrop: true 283 }); 284 } else { 285 do_replace(); 286 } 287 } 288 function reload() { 289 replace(location.href); 290 } 291
292 function hide_element(element) { 293 if (element._SimpleModalAriaInitialized) return; 294 element._SimpleModalAriaInitialized = true; 295 element._SimpleModalInitialAriaHidden = element.getAttribute('aria-hidden'); 296 element.setAttribute('aria-hidden', 'true'); 297 } 298 299 function release_element(element) { 300 if (!element._SimpleModalAriaInitialized) return; 301 var hidden = element._SimpleModalInitialAriaHidden; 302 303 if (hidden === null) { 304 element.removeAttribute('aria-hidden'); 305 } else { 306 element.setAttribute('aria-hidden', hidden); 307 } 308 309 delete element._SimpleModalAriaInitialized; 310 delete element._SimpleModalInitialAriaHidden; 311 } 312 313 function init(layer) { 314 var iframe = layer.iframe; 315 iframe.setAttribute('role', 'dialog'); // Set aria-hidden on each previous sibling of iframe, storing initial values 316 317 initPreviousSiblings(layer.iframe, hide_element); 318 } 319 function release(layer) { 320 // restore initial aria-hidden values (unless still locked by another layer) 321 releasePreviousSiblings(layer.iframe, release_element); 322 } 323 324 // Responsible for putting in DOM, and positioning on screen 325 function cover(iframe, container) { 326 var rect = container.getBoundingClientRect(); 327 var s = iframe.style; 328 var h = document.documentElement; 329 var left = Math.max(0, rect.left); 330 s.left = left + 'px'; 331 s.width = Math.min(rect.right - left, h.clientWidth - left) + 'px'; 332 var top = Math.max(0, rect.top); 333 s.top = top + 'px'; 334 s.height = Math.min(rect.bottom - top, h.clientHeight - top) + 'px'; 335 } 336 337 function init$1(element, container) { 338 (container || document.body).appendChild(element); 339 var s = element.style; 340 s.position = 'fixed'; 341 s.border = 'none'; 342 s.padding = 0; // This is the maximum supported z-index in current browsers (max 32 bit signed int), but the CSS spec doesn't actually specify this 343 // We need to set this value for IE, which doesn't work when you set z-index to any higher number 344 345 s.zIndex = 2147483647; // This is MAX_SAFE_INTEGER in JS 346 // This is larger than the maximum supported z-index in any current browser 347 // In IE, this has no effect. 348 // In other browsers, this always seems to set z-index to the highest supported value, and should protect against future increases in that value. 349 350 s.zIndex = 9007199254740991; 351 352 if (container) { 353 var position = cover.bind(null, element, container); 354 element._simple_modal_position = position; 355 position(); 356 addEventListener('scroll', position, true); 357 addEventListener('resize', position); 358 } else { 359 s.left = s.top = '0px'; 360 s.width = s.height = '100%'; 361 } 362 } // layer manager can tell us to update explicitly 363 364 function update(element, container) { 365 if (container) { 366 element._simple_modal_position(); 367 } 368 } 369 function release$1(element, container) { 370 element.parentElement && element.parentElement.removeChild(element); 371 372 if (container) { 373 var position = element._simple_modal_position; 374 removeEventListener('scroll', position, true); 375 removeEventListener('resize', position); 376 } 377 } 378 379 /* 380 This may be overly complicated. 381 In most situations, we just want to replicate the behaviour of 382 overscroll-behaviour: contain 383 but browser support isn't great yet, and I don't know if it even works on iframes. 384 385 In certain situtations, that isn't even the behaviour we want. 386 Imagine: 387 HEADER 388 -------------------------- 389 | 390 SIDEBAR | MAIN 391 | 392 | 393 | 394 395 And the modal is set to cover MAIN. 396 Here, if the entire page scrolls (ie. because sidebar is long), we want to let the page scroll. 397 If MAIN scrolls, however, we _do_ want to lock it. 398 */ 399 function ScrollLock(element) { 400 var style = element.style; 401 var count = 0; 402 var scrollTop, scrollLeft, overflowX, overflowY, maxWidth; 403 404 function fixScroll() { 405 element.scrollTop = scrollTop; 406 element.scrollLeft = scrollLeft; 407 } 408 409 function increment() { 410 count++; 411 if (count == 1) lock(); 412 } 413
414 function decrement() { 415 count--; 416 if (count == 0) unlock(); 417 } 418 419 function lock() { 420 scrollTop = element.scrollTop; 421 scrollLeft = element.scrollLeft; // Save values so we can restore 422 423 overflowX = style.overflowX; 424 overflowY = style.overflowY; 425 maxWidth = style.maxWidth; 426 /* 427 Lock element dimensions. 428 In some browsers/configurations, toggling overflow will cause scrollbars to hide. 429 Lock dimensions so that the document doesn't reflow. 430 */ 431 432 style.maxWidth = element.clientWidth + 'px'; // Lock scrolling 433 // ONLY lock if element actually "has a scrollbar" 434 // Otherwise, we can change how margin collapsing works, if the element currently has no overflow 435 436 if (element.scrollWidth > element.clientWidth) style.overflowX = 'hidden'; 437 if (element.scrollHeight > element.clientHeight) style.overflowY = 'hidden'; 438 /* 439 Note - even though we've set overflow hidden, that doesn't stop programmatic scrolling.
440 If the modal's initial content is positioned offscreen (ie. if it is going to animate into view), then some browsers (safari) may try to scroll the container to put the child window in view. 441 So we still need a scroll listener to reset such browser-induced scrolling. 442 */ 443 444 element.addEventListener('scroll', fixScroll); 445 } 446 447 function unlock() { 448 style.maxWidth = maxWidth; 449 style.overflowX = overflowX; 450 style.overflowY = overflowY; 451 element.removeEventListener('scroll', fixScroll); 452 } 453 454 return { 455 increment: increment, 456 decrement: decrement 457 }; 458 } 459 460 function increment_lock(element) { 461 element._SimpleModalScrollLock = element._SimpleModalScrollLock || ScrollLock(element); 462 463 element._SimpleModalScrollLock.increment(); 464 } 465 466 function decrement_lock(element) { 467 element._SimpleModalScrollLock.decrement(); 468 } 469 470 function elements_to_lock(layer) { 471 /* 472 In the "normal" situation, we're appending iframe to body, but "covering" the entire <html> element. 473 Depending on style/layout, scrollbar could be on <html>, <body>, or both. 474 So we need to lock both. 475 */ 476 if (layer.container) return [layer.container]; 477 return [document.documentElement, document.body]; 478 } 479 480 function init$2(layer) { 481 elements_to_lock(layer).forEach(increment_lock); 482 } 483 function release$2(layer) { 484 elements_to_lock(layer).forEach(decrement_lock); 485 } 486 487 /* 488 Responsible for: 489 - preventing focus of "covered" elements 490 - focusing layers when opened/reloaded 491 - restoring focus when layers are closed 492 */ 493 /* 494 Prevent programmatic/browser-automatic focusing of covered elements. 495 496 We shouldn't have to do this, but we found a case (hard to reproduce), where Safari was focusing a username input on the parent page when it had a modal open. This feature is mainly to protect against that. 497 */ 498 499 addEventListener('focus', function (event) { 500 if (event.target.hasOwnProperty('_SimpleModalInitialTabIndex')) { 501 event.target.blur(); 502 } 503 }, true); // Fairly inclusive list of (potentially) focusable elements. 504 // I used this for guidance: https://allyjs.io/data-tables/focusable.html 505 506 var POTENTIALLY_FOCUSABLE = 'a,button,input,textarea,select,summary,[contenteditable],area,audio,video,object,embed,svg,iframe'; 507 508 function getPotentiallyFocusableChildren(layer) { 509 return (layer.container || document.body).querySelectorAll(POTENTIALLY_FOCUSABLE); 510 } 511 512 function block(e) { 513 // Do nothing if already blocked 514 if (e.hasOwnProperty('_SimpleModalInitialTabIndex')) return; 515 e._SimpleModalInitialTabIndex = e.getAttribute('tabindex'); 516 e.setAttribute('tabindex', -1); 517 } 518 519 function unblock(e) { 520 var v = e._SimpleModalInitialTabIndex; // This element wasn't blocked by us. Leave tabindex alone. 521 522 if (typeof v == 'undefined') return; 523 if (v == null) e.removeAttribute('tabindex');else e.setAttribute('tabindex', v); 524 delete e._SimpleModalInitialTabIndex; 525 } 526 527 function init$3(layer, isFirstLayer) { 528 /* 529 TODO - users might not be happy to have us messing with tabindex (even if only temporarily). 530 We should offer an option to opt-out 531 */ 532 var focusable = getPotentiallyFocusableChildren(layer); 533 534 for (var i = focusable.length - 1; i >= 0; i--) { 535 if (focusable[i] != layer.iframe) block(focusable[i]); 536 } 537 538 if (layer.replaces) { 539 layer.initialActiveElement = layer.replaces.initialActiveElement; // This one shouldn't change focus when it's released 540 541 layer.replaces.initialActiveElement = null; 542 } else { 543 layer.initialActiveElement = document.activeElement; 544 } 545 546 layer.iframe.focus(); 547 } 548 549 function is_covered(e, excluding) { 550 var cursor = e; 551 552 while (cursor = cursor.nextElementSibling) { 553 if (cursor._isSimpleModalIframe && cursor != excluding) return true; 554 } 555 556 if (e.parentElement) return is_covered(e.parentElement, excluding); 557 return false;
558 } // TODO - more efficient algorithm? Could work top-down/backwards 559 // Getting it right in all scenarios (including concurrent modals, in different containers) isn't straight-forward 560 // This is a bit of a brute-force approach, but it should be correct 561 562 563 function release$3(layer) { 564 var focusable = document.querySelectorAll(POTENTIALLY_FOCUSABLE); 565 566 for (var i = focusable.length - 1; i >= 0; i--) { 567 var e = focusable[i]; // Note - our iframe might not have been removed yet. Be sure we don't count it in the is_covered check 568 569 if (!is_covered(e, layer.iframe)) unblock(e); 570 } 571 572 var ae = layer.initialActiveElement; 573 if (ae // exclude anything we've explicitly disabled 574 // We can't naively check against tabindex (property or attribute), because the previous ae might actually have had a negative tab index. 575 && !ae.hasOwnProperty('_SimpleModalInitialTabIndex') // Some browsers report document.body as document.activeElement when nothing is focused 576 // We don't want to focus that (might cause scrolling) 577 && ae != document.body) ae.focus(); 578 } 579 580 var layers = []; 581 582 function makeIframe(sandbox) { 583 var iframe = document.createElement('iframe'); // Not used by us anywhere, but can be useful for external code to identify our iframes 584 585 iframe.classList.add('SimpleModalIframe'); 586 iframe._isSimpleModalIframe = true; 587 var s = iframe.style; // Don't make the iframe visible until it has loaded 588 // This makes it easier to animate in 589 // Use opacity, rather than visibility, because browser don't let you focus hidden elements 590 // May be more performant to toggle opacity, too 591 // s.visibility = 'hidden'; 592 593 s.opacity = 0; 594 /* 595 Chrome rendering bug work around. 596 In very specific cases, Chrome (v99) is not showing our iframe when we later set opacity back to 1. 597 This happens when: 598 - the iframe loads a x-origin url 599 - the domain of the iframe page is not open in any other tab 600 Setting "will-change: opacity" seems to resolve this. 601 Should really file bug report with Chrome. 602 */ 603 604 s.willChange = 'opacity'; 605 606 if (sandbox !== null) { 607 iframe.setAttribute('sandbox', sandbox); 608 } 609 610 return iframe; 611 } 612 613 function reveal(iframe) { 614 iframe.style.opacity = ''; 615 } 616 617 function is_same_origin(iframe) { 618 try { 619 return Boolean(iframe.contentDocument); 620 } catch (e) { 621 return false; 622 } 623 } 624 625 function should_set_opaque_background(iframe) { 626 // If the iframe is x-origin, we cannot test the html element. 627 // Have to assume the users have set it properly. 628 if (!is_same_origin(iframe)) return false; 629 var s = getComputedStyle(iframe.contentDocument.documentElement); 630 var bc = s.backgroundColor; 631 return (bc == 'transparent' || bc == 'rgba(0, 0, 0, 0)') && s.backgroundImage == 'none'; 632 } 633 634 function layerLoaded(layer) { 635 var iframe = layer.iframe; // Server-generated error pages won't have any background color. 636 // It's really confusing when these load as a modal layer. 637 // To help with that, if the background of the <html> element is totally transparent, we'll set a background color on the iframe 638 639 iframe.style.backgroundColor = should_set_opaque_background(iframe) ? 'white' : ''; 640 641 if (layer.replaces) { 642 postMessage(iframe.contentWindow, 'CANCEL_SIMPLE_MODAL_ANIMATIONS'); // Don't reveal until it tells us it has canceled animations 643 } else { 644 // Only needed on first load, but no harm running every load 645 reveal(iframe); 646 } // Seems to be needed in IE - iframe blurs when it reloads 647 // We want to be sure to focus it now, before we call the onload callback (rather than waiting for our focus listener) 648 649 650 if (iframe != document.activeElement && iframe.tabindex != -1) { 651 iframe.focus(); 652 } 653 654 postMessage(iframe.contentWindow, 'SIMPLE_MODAL_LOADED_AND_REFOCUSED'); 655 layer.onload && layer.onload(layer.iframe.contentWindow); 656 } 657 658 function layerForWindow(w) { 659 for (var i = 0; i < layers.length; i++) { 660 if (layers[i].iframe.contentWindow == w) return layers[i]; 661 } 662 }
663 function top() { 664 // Notice - will be undefined if no layers open 665 return layers[layers.length - 1]; 666 } 667 668 function addBackdrop(layer) { 669 var backdrop = document.createElement('div'); 670 backdrop.classList.add('SimpleModalBackdrop'); 671 backdrop.classList.add('animating'); 672 init$1(backdrop, layer.container); 673 afterAnimation(backdrop, function () { 674 backdrop.classList.remove('animating'); 675 }); 676 layer.backdrop = backdrop; 677 } 678 679 function open(layer, src) { 680 // If this layer is replacing another, it will already have a backdrop 681 if (!layer.backdrop) addBackdrop(layer); 682 var iframe = makeIframe(layer.sandbox); 683 layer.iframe = iframe; 684 layers.push(layer); 685 init$2(layer); 686 iframe.src = src; 687 init$1(layer.iframe, layer.container); 688 init$3(layer); 689 init(layer); 690 /* 691 We _should_ be able to do this. 692 However, we've run into issues when integrating on external sites, where 3rd party code call stopPropagation on the load event. 693 By using a capturing event listener (on document), this issue is less likely to arise. 694 */ 695 // iframe.addEventListener('load', layerLoaded.bind(null, layer)); 696 } 697 document.addEventListener('load', function (e) { 698 var w = e.target.contentWindow; 699 var layer = w && layerForWindow(w); 700 if (layer) layerLoaded(layer); 701 }, true); 702 function resolve$1(layer, value) { 703 // Remove it from list 704 var index = layers.indexOf(layer); 705 if (index == -1) throw new Error('Layer is not in layers.'); 706 layers.splice(index, 1); // If the layer still has a backdrop, remove it 707 708 var backdrop = layer.backdrop; 709 if (backdrop) removeBackdrop(backdrop, layer.container); 710 release(layer); 711 release$3(layer); 712 release$1(layer.iframe, layer.container); 713 release$2(layer); 714 layer.onclose && layer.onclose(value); 715 layer.promiseResolver && layer.promiseResolver(value); 716 } 717 function replace$1(layer, url) { 718 var animated = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 719 var next = { 720 sandbox: layer.sandbox, 721 onload: layer.onload, 722 onclose: layer.onclose, 723 promiseResolver: layer.promiseResolver, 724 container: layer.container, 725 backdrop: layer.backdrop 726 }; // Ensure nothing happens when remove current, or if it loads again 727 728 layer.onload = null; 729 layer.onclose = null; 730 layer.promiseResolver = null; 731 layer.backdrop = null; 732 733 if (animated) { 734 // Close current layer, opening the next one after exit animation runs 735 layer.onclose = open.bind(null, next, url); 736 resolve$1(layer); 737 } else { 738 // Open the next layer, and have it replace the current one without animation once loaded 739 next.replaces = layer; 740 open(next, url); 741 } 742 } 743 function updatePositions() { 744 for (var i = 0; i < layers.length; i++) { 745 update(layers[i].iframe, layers[i].container); 746 } 747 } 748 749 function animateBackdropOut(layer) { 750 var backdrop = layer.backdrop; 751 if (!backdrop) return; // tell resolve not remove the backdrop - let the exit animation finish 752 753 layer.backdrop = null; 754 backdrop.classList.add('animating'); 755 backdrop.classList.add('closing'); 756 afterAnimation(backdrop, removeBackdrop.bind(null, backdrop, layer.container)); 757 } 758 759 function removeBackdrop(backdrop, container) { 760 release$1(backdrop, container); 761 } 762 763 addEventListener('message', function (event) { 764 var layer = layerForWindow(event.source); 765 if (!layer) return; 766 var data = event.data; // x-origin child explicitly asked to be closed 767 768 if (getMessage(data) == 'CLOSE_SIMPLE_MODAL_CHILD') { 769 resolve$1(layer, event.data.value); 770 } 771 772 if (getMessage(data) == 'REPLACE_SIMPLE_MODAL') { 773 replace$1(layer, data.url, data.animated); 774 } 775 776 if (getMessage(data) == 'SIMPLE_MODAL_ANIMATIONS_CANCELED') { 777 reveal(layer.iframe); 778 resolve$1(layer.replaces); 779 layer.replaces = null; 780 } 781 782 if (getMessage(data) == 'ANIMATE_SIMPLE_MODAL_BACKDROP_OUT') { 783 animateBackdropOut(layer); 784 } 785 }); 786 787 // child.js adds global event listeners 788 789 function open$1(url) { 790 var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 791 _ref$onload = _ref.onload, 792 onload = _ref$onload === void 0 ? null : _ref$onload, 793 _ref$onclose = _ref.onclose, 794 onclose = _ref$onclose === void 0 ? null : _ref$onclose, 795 _ref$sandbox = _ref.sandbox, 796 sandbox = _ref$sandbox === void 0 ? null : _ref$sandbox, 797 _ref$container = _ref.container, 798 container = _ref$container === void 0 ? null : _ref$container; 799 800 var layer = { 801 sandbox: sandbox, 802 onload: onload, 803 onclose: onclose, 804 promiseResolver: null, 805 container: container 806 }; 807 open(layer, url); // Return a promise, but only if Promise() is implemented in browser 808
809 try { 810 return new Promise(function (resolve, reject) { 811 layer.promiseResolver = resolve; 812 }); 813 } catch (e) {} 814 } 815 function closeChild(value) { 816 var layer = top(); 817 if (!layer) throw new Error('No modal window is open'); 818 resolve$1(layer, value); 819 } // public child window API 820 821 exports.animateOut = animateOut; 822 exports.close = close; 823 exports.closeChild = closeChild; 824 exports.layerForWindow = layerForWindow; 825 exports.open = open$1; 826 exports.reload = reload; 827 exports.replace = replace; 828 exports.replaceLayer = replace$1; 829 exports.resolveLayer = resolve$1; 830 exports.updatePositions = updatePositions; 831 832 return exports; 833 834}({})); 835//# sourceMappingURL=SimpleModal.js.ad1e0190fd9e.map
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.