vendor: 29,885 bytes, lines 1-1034
1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 typeof define === 'function' && define.amd ? define(factory) : 4 (global.ResizeObserver = factory()); 5}(this, (function () { 'use strict'; 6 7/** 8 * A collection of shims that provide minimal functionality of the ES6 collections. 9 * 10 * These implementations are not meant to be used outside of the ResizeObserver 11 * modules as they cover only a limited range of use cases. 12 */ 13/* eslint-disable require-jsdoc, valid-jsdoc */ 14var MapShim = (function () { 15 if (typeof Map !== 'undefined') { 16 return Map; 17 } 18 19 /** 20 * Returns index in provided array that matches the specified key. 21 * 22 * @param {Array<Array>} arr 23 * @param {*} key 24 * @returns {number} 25 */ 26 function getIndex(arr, key) { 27 var result = -1; 28 29 arr.some(function (entry, index) { 30 if (entry[0] === key) { 31 result = index; 32 33 return true; 34 } 35 36 return false; 37 }); 38 39 return result; 40 } 41 42 return (function () { 43 function anonymous() { 44 this.__entries__ = []; 45 } 46 47 var prototypeAccessors = { size: { configurable: true } }; 48 49 /** 50 * @returns {boolean} 51 */ 52 prototypeAccessors.size.get = function () { 53 return this.__entries__.length; 54 }; 55 56 /** 57 * @param {*} key 58 * @returns {*} 59 */ 60 anonymous.prototype.get = function (key) { 61 var index = getIndex(this.__entries__, key); 62 var entry = this.__entries__[index]; 63 64 return entry && entry[1]; 65 }; 66 67 /** 68 * @param {*} key 69 * @param {*} value 70 * @returns {void} 71 */ 72 anonymous.prototype.set = function (key, value) { 73 var index = getIndex(this.__entries__, key); 74 75 if (~index) { 76 this.__entries__[index][1] = value; 77 } else { 78 this.__entries__.push([key, value]); 79 } 80 }; 81 82 /** 83 * @param {*} key 84 * @returns {void} 85 */ 86 anonymous.prototype.delete = function (key) { 87 var entries = this.__entries__; 88 var index = getIndex(entries, key); 89 90 if (~index) { 91 entries.splice(index, 1); 92 } 93 }; 94 95 /** 96 * @param {*} key 97 * @returns {void} 98 */ 99 anonymous.prototype.has = function (key) { 100 return !!~getIndex(this.__entries__, key); 101 }; 102 103 /** 104 * @returns {void} 105 */ 106 anonymous.prototype.clear = function () { 107 this.__entries__.splice(0); 108 }; 109 110 /** 111 * @param {Function} callback 112 * @param {*} [ctx=null] 113 * @returns {void} 114 */ 115 anonymous.prototype.forEach = function (callback, ctx) { 116 var this$1 = this; 117 if ( ctx === void 0 ) ctx = null; 118 119 for (var i = 0, list = this$1.__entries__; i < list.length; i += 1) { 120 var entry = list[i]; 121 122 callback.call(ctx, entry[1], entry[0]); 123 } 124 }; 125 126 Object.defineProperties( anonymous.prototype, prototypeAccessors ); 127 128 return anonymous; 129 }()); 130})(); 131 132/** 133 * Detects whether window and document objects are available in current environment. 134 */ 135var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document; 136 137// Returns global object of a current environment. 138var global$1 = (function () { 139 if (typeof global !== 'undefined' && global.Math === Math) { 140 return global; 141 } 142 143 if (typeof self !== 'undefined' && self.Math === Math) { 144 return self; 145 } 146 147 if (typeof window !== 'undefined' && window.Math === Math) { 148 return window; 149 } 150 151 // eslint-disable-next-line no-new-func 152 return Function('return this')(); 153})(); 154 155/** 156 * A shim for the requestAnimationFrame which falls back to the setTimeout if 157 * first one is not supported. 158 * 159 * @returns {number} Requests' identifier. 160 */ 161var requestAnimationFrame$1 = (function () { 162 if (typeof requestAnimationFrame === 'function') { 163 // It's required to use a bounded function because IE sometimes throws 164 // an "Invalid calling object" error if rAF is invoked without the global 165 // object on the left hand side. 166 return requestAnimationFrame.bind(global$1); 167 } 168 169 return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); }; 170})(); 171 172// Defines minimum timeout before adding a trailing call. 173var trailingTimeout = 2; 174 175/** 176 * Creates a wrapper function which ensures that provided callback will be 177 * invoked only once during the specified delay period. 178 * 179 * @param {Function} callback - Function to be invoked after the delay period. 180 * @param {number} delay - Delay after which to invoke callback. 181 * @returns {Function} 182 */ 183var throttle = function (callback, delay) { 184 var leadingCall = false, 185 trailingCall = false, 186 lastCallTime = 0; 187 188 /** 189 * Invokes the original callback function and schedules new invocation if 190 * the "proxy" was called during current request. 191 * 192 * @returns {void} 193 */ 194 function resolvePending() { 195 if (leadingCall) { 196 leadingCall = false; 197 198 callback(); 199 } 200 201 if (trailingCall) { 202 proxy(); 203 } 204 } 205 206 /** 207 * Callback invoked after the specified delay. It will further postpone 208 * invocation of the original function delegating it to the 209 * requestAnimationFrame. 210 * 211 * @returns {void} 212 */ 213 function timeoutCallback() { 214 requestAnimationFrame$1(resolvePending); 215 } 216 217 /** 218 * Schedules invocation of the original function. 219 * 220 * @returns {void} 221 */ 222 function proxy() { 223 var timeStamp = Date.now(); 224 225 if (leadingCall) { 226 // Reject immediately following calls. 227 if (timeStamp - lastCallTime < trailingTimeout) { 228 return; 229 } 230 231 // Schedule new call to be in invoked when the pending one is resolved. 232 // This is important for "transitions" which never actually start 233 // immediately so there is a chance that we might miss one if change 234 // happens amids the pending invocation. 235 trailingCall = true; 236 } else { 237 leadingCall = true; 238 trailingCall = false; 239 240 setTimeout(timeoutCallback, delay); 241 } 242 243 lastCallTime = timeStamp; 244 } 245 246 return proxy; 247}; 248 249// Minimum delay before invoking the update of observers. 250var REFRESH_DELAY = 20; 251 252// A list of substrings of CSS properties used to find transition events that 253// might affect dimensions of observed elements. 254var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight']; 255 256// Check if MutationObserver is available. 257var mutationObserverSupported = typeof MutationObserver !== 'undefined'; 258 259/** 260 * Singleton controller class which handles updates of ResizeObserver instances. 261 */ 262var ResizeObserverController = function() { 263 this.connected_ = false; 264 this.mutationEventsAdded_ = false; 265 this.mutationsObserver_ = null; 266 this.observers_ = []; 267 268 this.onTransitionEnd_ = this.onTransitionEnd_.bind(this); 269 this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY); 270}; 271 272/** 273 * Adds observer to observers list. 274 * 275 * @param {ResizeObserverSPI} observer - Observer to be added. 276 * @returns {void} 277 */ 278 279 280/** 281 * Holds reference to the controller's instance. 282 * 283 * @private {ResizeObserverController} 284 */ 285 286 287/** 288 * Keeps reference to the instance of MutationObserver. 289 * 290 * @private {MutationObserver} 291 */ 292 293/** 294 * Indicates whether DOM listeners have been added. 295 * 296 * @private {boolean} 297 */ 298ResizeObserverController.prototype.addObserver = function (observer) { 299 if (!~this.observers_.indexOf(observer)) { 300 this.observers_.push(observer); 301 } 302 303 // Add listeners if they haven't been added yet. 304 if (!this.connected_) { 305 this.connect_(); 306 } 307}; 308 309/** 310 * Removes observer from observers list. 311 * 312 * @param {ResizeObserverSPI} observer - Observer to be removed. 313 * @returns {void} 314 */ 315ResizeObserverController.prototype.removeObserver = function (observer) { 316 var observers = this.observers_; 317 var index = observers.indexOf(observer); 318 319 // Remove observer if it's present in registry. 320 if (~index) { 321 observers.splice(index, 1); 322 } 323 324 // Remove listeners if controller has no connected observers. 325 if (!observers.length && this.connected_) { 326 this.disconnect_(); 327 } 328}; 329 330/** 331 * Invokes the update of observers. It will continue running updates insofar 332 * it detects changes. 333 * 334 * @returns {void} 335 */ 336ResizeObserverController.prototype.refresh = function () { 337 var changesDetected = this.updateObservers_(); 338 339 // Continue running updates if changes have been detected as there might 340 // be future ones caused by CSS transitions. 341 if (changesDetected) { 342 this.refresh(); 343 } 344}; 345 346/** 347 * Updates every observer from observers list and notifies them of queued 348 * entries. 349 * 350 * @private 351 * @returns {boolean} Returns "true" if any observer has detected changes in 352 * dimensions of it's elements. 353 */ 354ResizeObserverController.prototype.updateObservers_ = function () { 355 // Collect observers that have active observations. 356 var activeObservers = this.observers_.filter(function (observer) { 357 return observer.gatherActive(), observer.hasActive(); 358 }); 359 360 // Deliver notifications in a separate cycle in order to avoid any 361 // collisions between observers, e.g. when multiple instances of 362 // ResizeObserver are tracking the same element and the callback of one 363 // of them changes content dimensions of the observed target. Sometimes 364 // this may result in notifications being blocked for the rest of observers. 365 activeObservers.forEach(function (observer) { return observer.broadcastActive(); }); 366 367 return activeObservers.length > 0; 368}; 369 370/** 371 * Initializes DOM listeners. 372 * 373 * @private 374 * @returns {void} 375 */ 376ResizeObserverController.prototype.connect_ = function () { 377 // Do nothing if running in a non-browser environment or if listeners 378 // have been already added. 379 if (!isBrowser || this.connected_) { 380 return; 381 } 382 383 // Subscription to the "Transitionend" event is used as a workaround for 384 // delayed transitions. This way it's possible to capture at least the 385 // final state of an element. 386 document.addEventListener('transitionend', this.onTransitionEnd_); 387 388 window.addEventListener('resize', this.refresh); 389 390 if (mutationObserverSupported) { 391 this.mutationsObserver_ = new MutationObserver(this.refresh); 392 393 this.mutationsObserver_.observe(document, { 394 attributes: true, 395 childList: true, 396 characterData: true, 397 subtree: true 398 }); 399 } else { 400 document.addEventListener('DOMSubtreeModified', this.refresh); 401 402 this.mutationEventsAdded_ = true; 403 } 404 405 this.connected_ = true; 406}; 407 408/** 409 * Removes DOM listeners. 410 * 411 * @private 412 * @returns {void} 413 */ 414ResizeObserverController.prototype.disconnect_ = function () { 415 // Do nothing if running in a non-browser environment or if listeners 416 // have been already removed. 417 if (!isBrowser || !this.connected_) { 418 return; 419 } 420 421 document.removeEventListener('transitionend', this.onTransitionEnd_); 422 window.removeEventListener('resize', this.refresh); 423 424 if (this.mutationsObserver_) { 425 this.mutationsObserver_.disconnect(); 426 } 427 428 if (this.mutationEventsAdded_) { 429 document.removeEventListener('DOMSubtreeModified', this.refresh); 430 } 431 432 this.mutationsObserver_ = null; 433 this.mutationEventsAdded_ = false; 434 this.connected_ = false; 435}; 436 437/** 438 * "Transitionend" event handler. 439 * 440 * @private 441 * @param {TransitionEvent} event 442 * @returns {void} 443 */ 444ResizeObserverController.prototype.onTransitionEnd_ = function (ref) { 445 var propertyName = ref.propertyName; if ( propertyName === void 0 ) propertyName = ''; 446 447 // Detect whether transition may affect dimensions of an element. 448 var isReflowProperty = transitionKeys.some(function (key) { 449 return !!~propertyName.indexOf(key); 450 }); 451 452 if (isReflowProperty) { 453 this.refresh(); 454 } 455}; 456 457/** 458 * Returns instance of the ResizeObserverController. 459 * 460 * @returns {ResizeObserverController} 461 */ 462ResizeObserverController.getInstance = function () { 463 if (!this.instance_) { 464 this.instance_ = new ResizeObserverController(); 465 } 466 467 return this.instance_; 468}; 469 470ResizeObserverController.instance_ = null; 471 472/** 473 * Defines non-writable/enumerable properties of the provided target object. 474 * 475 * @param {Object} target - Object for which to define properties. 476 * @param {Object} props - Properties to be defined. 477 * @returns {Object} Target object. 478 */ 479var defineConfigurable = (function (target, props) { 480 for (var i = 0, list = Object.keys(props); i < list.length; i += 1) { 481 var key = list[i]; 482 483 Object.defineProperty(target, key, { 484 value: props[key], 485 enumerable: false, 486 writable: false, 487 configurable: true 488 }); 489 } 490 491 return target; 492}); 493 494/** 495 * Returns the global object associated with provided element. 496 * 497 * @param {Object} target 498 * @returns {Object} 499 */ 500var getWindowOf = (function (target) { 501 // Assume that the element is an instance of Node, which means that it 502 // has the "ownerDocument" property from which we can retrieve a 503 // corresponding global object. 504 var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView; 505 506 // Return the local global object if it's not possible extract one from 507 // provided element. 508 return ownerGlobal || global$1; 509}); 510 511// Placeholder of an empty content rectangle. 512var emptyRect = createRectInit(0, 0, 0, 0); 513 514/** 515 * Converts provided string to a number. 516 * 517 * @param {number|string} value 518 * @returns {number} 519 */ 520function toFloat(value) { 521 return parseFloat(value) || 0; 522} 523 524/** 525 * Extracts borders size from provided styles. 526 * 527 * @param {CSSStyleDeclaration} styles 528 * @param {...string} positions - Borders positions (top, right, ...) 529 * @returns {number} 530 */ 531function getBordersSize(styles) { 532 var positions = [], len = arguments.length - 1; 533 while ( len-- > 0 ) positions[ len ] = arguments[ len + 1 ]; 534 535 return positions.reduce(function (size, position) { 536 var value = styles['border-' + position + '-width']; 537 538 return size + toFloat(value); 539 }, 0); 540} 541 542/** 543 * Extracts paddings sizes from provided styles. 544 * 545 * @param {CSSStyleDeclaration} styles 546 * @returns {Object} Paddings box. 547 */ 548function getPaddings(styles) { 549 var positions = ['top', 'right', 'bottom', 'left']; 550 var paddings = {}; 551 552 for (var i = 0, list = positions; i < list.length; i += 1) { 553 var position = list[i]; 554 555 var value = styles['padding-' + position]; 556 557 paddings[position] = toFloat(value); 558 } 559 560 return paddings; 561} 562 563/** 564 * Calculates content rectangle of provided SVG element. 565 * 566 * @param {SVGGraphicsElement} target - Element content rectangle of which needs 567 * to be calculated. 568 * @returns {DOMRectInit} 569 */ 570function getSVGContentRect(target) { 571 var bbox = target.getBBox(); 572 573 return createRectInit(0, 0, bbox.width, bbox.height); 574} 575 576/** 577 * Calculates content rectangle of provided HTMLElement. 578 * 579 * @param {HTMLElement} target - Element for which to calculate the content rectangle. 580 * @returns {DOMRectInit} 581 */ 582function getHTMLElementContentRect(target) { 583 // Client width & height properties can't be 584 // used exclusively as they provide rounded values. 585 var clientWidth = target.clientWidth; 586 var clientHeight = target.clientHeight; 587 588 // By this condition we can catch all non-replaced inline, hidden and 589 // detached elements. Though elements with width & height properties less 590 // than 0.5 will be discarded as well. 591 // 592 // Without it we would need to implement separate methods for each of 593 // those cases and it's not possible to perform a precise and performance 594 // effective test for hidden elements. E.g. even jQuery's ':visible' filter 595 // gives wrong results for elements with width & height less than 0.5. 596 if (!clientWidth && !clientHeight) { 597 return emptyRect; 598 } 599 600 var styles = getWindowOf(target).getComputedStyle(target); 601 var paddings = getPaddings(styles); 602 var horizPad = paddings.left + paddings.right; 603 var vertPad = paddings.top + paddings.bottom; 604 605 // Computed styles of width & height are being used because they are the 606 // only dimensions available to JS that contain non-rounded values. It could 607 // be possible to utilize the getBoundingClientRect if only it's data wasn't 608 // affected by CSS transformations let alone paddings, borders and scroll bars. 609 var width = toFloat(styles.width), 610 height = toFloat(styles.height); 611 612 // Width & height include paddings and borders when the 'border-box' box 613 // model is applied (except for IE). 614 if (styles.boxSizing === 'border-box') { 615 // Following conditions are required to handle Internet Explorer which 616 // doesn't include paddings and borders to computed CSS dimensions. 617 // 618 // We can say that if CSS dimensions + paddings are equal to the "client" 619 // properties then it's either IE, and thus we don't need to subtract 620 // anything, or an element merely doesn't have paddings/borders styles. 621 if (Math.round(width + horizPad) !== clientWidth) { 622 width -= getBordersSize(styles, 'left', 'right') + horizPad; 623 } 624 625 if (Math.round(height + vertPad) !== clientHeight) { 626 height -= getBordersSize(styles, 'top', 'bottom') + vertPad; 627 } 628 } 629 630 // Following steps can't be applied to the document's root element as its 631 // client[Width/Height] properties represent viewport area of the window. 632 // Besides, it's as well not necessary as the <html> itself neither has 633 // rendered scroll bars nor it can be clipped. 634 if (!isDocumentElement(target)) { 635 // In some browsers (only in Firefox, actually) CSS width & height 636 // include scroll bars size which can be removed at this step as scroll 637 // bars are the only difference between rounded dimensions + paddings 638 // and "client" properties, though that is not always true in Chrome. 639 var vertScrollbar = Math.round(width + horizPad) - clientWidth; 640 var horizScrollbar = Math.round(height + vertPad) - clientHeight; 641 642 // Chrome has a rather weird rounding of "client" properties. 643 // E.g. for an element with content width of 314.2px it sometimes gives 644 // the client width of 315px and for the width of 314.7px it may give 645 // 314px. And it doesn't happen all the time. So just ignore this delta 646 // as a non-relevant. 647 if (Math.abs(vertScrollbar) !== 1) { 648 width -= vertScrollbar; 649 } 650 651 if (Math.abs(horizScrollbar) !== 1) { 652 height -= horizScrollbar; 653 } 654 } 655 656 return createRectInit(paddings.left, paddings.top, width, height); 657} 658 659/** 660 * Checks whether provided element is an instance of the SVGGraphicsElement. 661 * 662 * @param {Element} target - Element to be checked. 663 * @returns {boolean} 664 */ 665var isSVGGraphicsElement = (function () { 666 // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement 667 // interface. 668 if (typeof SVGGraphicsElement !== 'undefined') { 669 return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; }; 670 } 671 672 // If it's so, then check that element is at least an instance of the 673 // SVGElement and that it has the "getBBox" method. 674 // eslint-disable-next-line no-extra-parens 675 return function (target) { return target instanceof getWindowOf(target).SVGElement && typeof target.getBBox === 'function'; }; 676})(); 677 678/** 679 * Checks whether provided element is a document element (<html>). 680 * 681 * @param {Element} target - Element to be checked. 682 * @returns {boolean} 683 */ 684function isDocumentElement(target) { 685 return target === getWindowOf(target).document.documentElement; 686} 687 688/** 689 * Calculates an appropriate content rectangle for provided html or svg element. 690 * 691 * @param {Element} target - Element content rectangle of which needs to be calculated. 692 * @returns {DOMRectInit} 693 */ 694function getContentRect(target) { 695 if (!isBrowser) { 696 return emptyRect; 697 } 698 699 if (isSVGGraphicsElement(target)) { 700 return getSVGContentRect(target); 701 } 702 703 return getHTMLElementContentRect(target); 704} 705 706/** 707 * Creates rectangle with an interface of the DOMRectReadOnly. 708 * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly 709 * 710 * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions. 711 * @returns {DOMRectReadOnly} 712 */ 713function createReadOnlyRect(ref) { 714 var x = ref.x; 715 var y = ref.y; 716 var width = ref.width; 717 var height = ref.height; 718 719 // If DOMRectReadOnly is available use it as a prototype for the rectangle. 720 var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object; 721 var rect = Object.create(Constr.prototype); 722 723 // Rectangle's properties are not writable and non-enumerable. 724 defineConfigurable(rect, { 725 x: x, y: y, width: width, height: height, 726 top: y, 727 right: x + width, 728 bottom: height + y, 729 left: x 730 }); 731 732 return rect; 733} 734 735/** 736 * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates. 737 * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit 738 * 739 * @param {number} x - X coordinate. 740 * @param {number} y - Y coordinate. 741 * @param {number} width - Rectangle's width. 742 * @param {number} height - Rectangle's height. 743 * @returns {DOMRectInit} 744 */ 745function createRectInit(x, y, width, height) { 746 return { x: x, y: y, width: width, height: height }; 747} 748 749/** 750 * Class that is responsible for computations of the content rectangle of 751 * provided DOM element and for keeping track of it's changes. 752 */ 753var ResizeObservation = function(target) { 754 this.broadcastWidth = 0; 755 this.broadcastHeight = 0; 756 this.contentRect_ = createRectInit(0, 0, 0, 0); 757 758 this.target = target; 759}; 760 761/** 762 * Updates content rectangle and tells whether it's width or height properties 763 * have changed since the last broadcast. 764 * 765 * @returns {boolean} 766 */ 767 768 769/** 770 * Reference to the last observed content rectangle. 771 * 772 * @private {DOMRectInit} 773 */ 774 775 776/** 777 * Broadcasted width of content rectangle. 778 * 779 * @type {number} 780 */ 781ResizeObservation.prototype.isActive = function () { 782 var rect = getContentRect(this.target); 783 784 this.contentRect_ = rect; 785 786 return rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight; 787}; 788 789/** 790 * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data 791 * from the corresponding properties of the last observed content rectangle. 792 * 793 * @returns {DOMRectInit} Last observed content rectangle. 794 */ 795ResizeObservation.prototype.broadcastRect = function () { 796 var rect = this.contentRect_; 797 798 this.broadcastWidth = rect.width; 799 this.broadcastHeight = rect.height; 800 801 return rect; 802}; 803 804var ResizeObserverEntry = function(target, rectInit) { 805 var contentRect = createReadOnlyRect(rectInit); 806 807 // According to the specification following properties are not writable 808 // and are also not enumerable in the native implementation. 809 // 810 // Property accessors are not being used as they'd require to define a 811 // private WeakMap storage which may cause memory leaks in browsers that 812 // don't support this type of collections. 813 defineConfigurable(this, { target: target, contentRect: contentRect }); 814}; 815 816var ResizeObserverSPI = function(callback, controller, callbackCtx) { 817 this.activeObservations_ = []; 818 this.observations_ = new MapShim(); 819 820 if (typeof callback !== 'function') { 821 throw new TypeError('The callback provided as parameter 1 is not a function.'); 822 } 823 824 this.callback_ = callback; 825 this.controller_ = controller; 826 this.callbackCtx_ = callbackCtx; 827}; 828 829/** 830 * Starts observing provided element. 831 * 832 * @param {Element} target - Element to be observed. 833 * @returns {void} 834 */ 835 836 837/** 838 * Registry of the ResizeObservation instances. 839 * 840 * @private {Map<Element, ResizeObservation>} 841 */ 842 843 844/** 845 * Public ResizeObserver instance which will be passed to the callback 846 * function and used as a value of it's "this" binding. 847 * 848 * @private {ResizeObserver} 849 */ 850 851/** 852 * Collection of resize observations that have detected changes in dimensions 853 * of elements. 854 * 855 * @private {Array<ResizeObservation>} 856 */ 857ResizeObserverSPI.prototype.observe = function (target) { 858 if (!arguments.length) { 859 throw new TypeError('1 argument required, but only 0 present.'); 860 } 861 862 // Do nothing if current environment doesn't have the Element interface. 863 if (typeof Element === 'undefined' || !(Element instanceof Object)) { 864 return; 865 } 866 867 if (!(target instanceof getWindowOf(target).Element)) { 868 throw new TypeError('parameter 1 is not of type "Element".'); 869 } 870 871 var observations = this.observations_; 872 873 // Do nothing if element is already being observed. 874 if (observations.has(target)) { 875 return; 876 } 877 878 observations.set(target, new ResizeObservation(target)); 879 880 this.controller_.addObserver(this); 881 882 // Force the update of observations. 883 this.controller_.refresh(); 884}; 885 886/** 887 * Stops observing provided element. 888 * 889 * @param {Element} target - Element to stop observing. 890 * @returns {void} 891 */ 892ResizeObserverSPI.prototype.unobserve = function (target) { 893 if (!arguments.length) { 894 throw new TypeError('1 argument required, but only 0 present.'); 895 } 896 897 // Do nothing if current environment doesn't have the Element interface. 898 if (typeof Element === 'undefined' || !(Element instanceof Object)) { 899 return; 900 } 901 902 if (!(target instanceof getWindowOf(target).Element)) { 903 throw new TypeError('parameter 1 is not of type "Element".'); 904 } 905 906 var observations = this.observations_; 907 908 // Do nothing if element is not being observed. 909 if (!observations.has(target)) { 910 return; 911 } 912 913 observations.delete(target); 914 915 if (!observations.size) { 916 this.controller_.removeObserver(this); 917 } 918}; 919 920/** 921 * Stops observing all elements. 922 * 923 * @returns {void} 924 */ 925ResizeObserverSPI.prototype.disconnect = function () { 926 this.clearActive(); 927 this.observations_.clear(); 928 this.controller_.removeObserver(this); 929}; 930 931/** 932 * Collects observation instances the associated element of which has changed 933 * it's content rectangle. 934 * 935 * @returns {void} 936 */ 937ResizeObserverSPI.prototype.gatherActive = function () { 938 var this$1 = this; 939 940 this.clearActive(); 941 942 this.observations_.forEach(function (observation) { 943 if (observation.isActive()) { 944 this$1.activeObservations_.push(observation); 945 } 946 }); 947}; 948 949/** 950 * Invokes initial callback function with a list of ResizeObserverEntry 951 * instances collected from active resize observations. 952 * 953 * @returns {void} 954 */ 955ResizeObserverSPI.prototype.broadcastActive = function () { 956 // Do nothing if observer doesn't have active observations. 957 if (!this.hasActive()) { 958 return; 959 } 960 961 var ctx = this.callbackCtx_; 962 963 // Create ResizeObserverEntry instance for every active observation. 964 var entries = this.activeObservations_.map(function (observation) { 965 return new ResizeObserverEntry(observation.target, observation.broadcastRect()); 966 }); 967 968 this.callback_.call(ctx, entries, ctx); 969 this.clearActive(); 970}; 971 972/** 973 * Clears the collection of active observations. 974 * 975 * @returns {void} 976 */ 977ResizeObserverSPI.prototype.clearActive = function () { 978 this.activeObservations_.splice(0); 979}; 980 981/** 982 * Tells whether observer has active observations. 983 * 984 * @returns {boolean} 985 */ 986ResizeObserverSPI.prototype.hasActive = function () { 987 return this.activeObservations_.length > 0; 988}; 989 990// Registry of internal observers. If WeakMap is not available use current shim 991// for the Map collection as it has all required methods and because WeakMap 992// can't be fully polyfilled anyway. 993var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim(); 994 995/** 996 * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation 997 * exposing only those methods and properties that are defined in the spec. 998 */ 999var ResizeObserver = function(callback) { 1000 if (!(this instanceof ResizeObserver)) { 1001 throw new TypeError('Cannot call a class as a function.'); 1002 } 1003 if (!arguments.length) { 1004 throw new TypeError('1 argument required, but only 0 present.'); 1005 } 1006 1007 var controller = ResizeObserverController.getInstance(); 1008 var observer = new ResizeObserverSPI(callback, controller, this); 1009 1010 observers.set(this, observer); 1011}; 1012 1013// Expose public methods of ResizeObserver. 1014['observe', 'unobserve', 'disconnect'].forEach(function (method) { 1015 ResizeObserver.prototype[method] = function () { 1016 return (ref = observers.get(this))[method].apply(ref, arguments); 1017 var ref; 1018 }; 1019}); 1020 1021var index = (function () { 1022 // Export existing implementation if available. 1023 if (typeof global$1.ResizeObserver !== 'undefined') { 1024 return global$1.ResizeObserver; 1025 } 1026 1027 global$1.ResizeObserver = ResizeObserver; 1028 1029 return ResizeObserver; 1030})(); 1031 1032return index; 1033 1034})));
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.