vendor: 12,157 bytes, lines 1-471
1 2(function() { 3'use strict'; 4 5if (typeof window !== 'object') { 6return; 7} 8 9 10if ('IntersectionObserver' in window && 11'IntersectionObserverEntry' in window && 12'intersectionRatio' in window.IntersectionObserverEntry.prototype) { 13 14 15 if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) { 16Object.defineProperty(window.IntersectionObserverEntry.prototype, 17'isIntersecting', { 18get: function () { 19return this.intersectionRatio > 0; 20} 21}); 22} 23return; 24} 25 26var document = window.document; 27 28var registry = []; 29 30function IntersectionObserverEntry(entry) { 31this.time = entry.time; 32this.target = entry.target; 33this.rootBounds = entry.rootBounds; 34this.boundingClientRect = entry.boundingClientRect; 35this.intersectionRect = entry.intersectionRect || getEmptyRect(); 36this.isIntersecting = !!entry.intersectionRect; 37 38 var targetRect = this.boundingClientRect; 39var targetArea = targetRect.width * targetRect.height; 40var intersectionRect = this.intersectionRect; 41var intersectionArea = intersectionRect.width * intersectionRect.height; 42 43 if (targetArea) { 44 45 46 this.intersectionRatio = Number((intersectionArea / targetArea).toFixed(4)); 47} else { 48 49 this.intersectionRatio = this.isIntersecting ? 1 : 0; 50} 51} 52 53function IntersectionObserver(callback, opt_options) { 54var options = opt_options || {}; 55if (typeof callback != 'function') { 56throw new Error('callback must be a function'); 57} 58if (options.root && options.root.nodeType != 1) { 59throw new Error('root must be an Element'); 60} 61 62 this._checkForIntersections = throttle( 63this._checkForIntersections.bind(this), this.THROTTLE_TIMEOUT); 64 65 this._callback = callback; 66this._observationTargets = []; 67this._queuedEntries = []; 68this._rootMarginValues = this._parseRootMargin(options.rootMargin); 69 70 this.thresholds = this._initThresholds(options.threshold); 71this.root = options.root || null; 72this.rootMargin = this._rootMarginValues.map(function(margin) { 73return margin.value + margin.unit; 74}).join(' '); 75 76this._monitoringDocuments = []; 77 78this._monitoringUnsubscribes = []; 79} 80 81IntersectionObserver.prototype.THROTTLE_TIMEOUT = 100; 82 83IntersectionObserver.prototype.POLL_INTERVAL = null; 84 85IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true; 86 87IntersectionObserver.prototype.observe = function(target) { 88var isTargetAlreadyObserved = this._observationTargets.some(function(item) { 89return item.element == target; 90}); 91if (isTargetAlreadyObserved) { 92return; 93} 94if (!(target && target.nodeType == 1)) { 95throw new Error('target must be an Element'); 96} 97this._registerInstance(); 98this._observationTargets.push({element: target, entry: null}); 99this._monitorIntersections(target.ownerDocument); 100this._checkForIntersections(); 101}; 102 103IntersectionObserver.prototype.unobserve = function(target) { 104this._observationTargets = 105this._observationTargets.filter(function(item) { 106return item.element != target; 107}); 108this._unmonitorIntersections(target.ownerDocument); 109if (this._observationTargets.length == 0) { 110this._unregisterInstance(); 111} 112}; 113 114IntersectionObserver.prototype.disconnect = function() { 115this._observationTargets = []; 116this._unmonitorAllIntersections(); 117this._unregisterInstance(); 118}; 119 120IntersectionObserver.prototype.takeRecords = function() { 121var records = this._queuedEntries.slice(); 122this._queuedEntries = []; 123return records; 124}; 125 126IntersectionObserver.prototype._initThresholds = function(opt_threshold) { 127var threshold = opt_threshold || [0]; 128if (!Array.isArray(threshold)) threshold = [threshold]; 129return threshold.sort().filter(function(t, i, a) { 130if (typeof t != 'number' || isNaN(t) || t < 0 || t > 1) { 131throw new Error('threshold must be a number between 0 and 1 inclusively'); 132} 133return t !== a[i - 1]; 134}); 135}; 136 137IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) { 138var marginString = opt_rootMargin || '0px'; 139var margins = marginString.split(/\s+/).map(function(margin) { 140var parts = /^(-?\d*\.?\d+)(px|%)$/.exec(margin); 141if (!parts) { 142throw new Error('rootMargin must be specified in pixels or percent'); 143} 144return {value: parseFloat(parts[1]), unit: parts[2]}; 145}); 146 147 margins[1] = margins[1] || margins[0]; 148margins[2] = margins[2] || margins[0]; 149margins[3] = margins[3] || margins[1]; 150return margins; 151}; 152 153IntersectionObserver.prototype._monitorIntersections = function(doc) { 154var win = doc.defaultView; 155if (!win) { 156 157 return; 158} 159if (this._monitoringDocuments.indexOf(doc) != -1) { 160 161 return; 162} 163 164 var callback = this._checkForIntersections; 165var monitoringInterval = null; 166var domObserver = null; 167 168 169 if (this.POLL_INTERVAL) { 170monitoringInterval = win.setInterval(callback, this.POLL_INTERVAL); 171} else { 172addEvent(win, 'resize', callback, true); 173addEvent(doc, 'scroll', callback, true); 174if (this.USE_MUTATION_OBSERVER && 'MutationObserver' in win) { 175domObserver = new win.MutationObserver(callback); 176domObserver.observe(doc, { 177attributes: true, 178childList: true, 179characterData: true, 180subtree: true 181}); 182} 183} 184this._monitoringDocuments.push(doc); 185this._monitoringUnsubscribes.push(function() { 186 187 188 var win = doc.defaultView; 189if (win) { 190if (monitoringInterval) { 191win.clearInterval(monitoringInterval); 192} 193removeEvent(win, 'resize', callback, true); 194} 195removeEvent(doc, 'scroll', callback, true); 196if (domObserver) { 197domObserver.disconnect(); 198} 199}); 200 201 if (doc != (this.root && this.root.ownerDocument || document)) { 202var frame = getFrameElement(doc); 203if (frame) { 204this._monitorIntersections(frame.ownerDocument); 205} 206} 207}; 208 209IntersectionObserver.prototype._unmonitorIntersections = function(doc) { 210var index = this._monitoringDocuments.indexOf(doc); 211if (index == -1) { 212return; 213} 214var rootDoc = (this.root && this.root.ownerDocument || document); 215 216 var hasDependentTargets = 217this._observationTargets.some(function(item) { 218var itemDoc = item.element.ownerDocument; 219 220 if (itemDoc == doc) { 221return true; 222} 223 224 while (itemDoc && itemDoc != rootDoc) { 225var frame = getFrameElement(itemDoc); 226itemDoc = frame && frame.ownerDocument; 227if (itemDoc == doc) { 228return true; 229} 230} 231return false; 232}); 233if (hasDependentTargets) { 234return; 235} 236 237 var unsubscribe = this._monitoringUnsubscribes[index]; 238this._monitoringDocuments.splice(index, 1); 239this._monitoringUnsubscribes.splice(index, 1); 240unsubscribe(); 241 242 if (doc != rootDoc) { 243var frame = getFrameElement(doc); 244if (frame) { 245this._unmonitorIntersections(frame.ownerDocument); 246} 247} 248}; 249 250IntersectionObserver.prototype._unmonitorAllIntersections = function() { 251var unsubscribes = this._monitoringUnsubscribes.slice(0); 252this._monitoringDocuments.length = 0; 253this._monitoringUnsubscribes.length = 0; 254for (var i = 0; i < unsubscribes.length; i++) { 255unsubscribes[i](); 256} 257}; 258 259IntersectionObserver.prototype._checkForIntersections = function() { 260var rootIsInDom = this._rootIsInDom(); 261var rootRect = rootIsInDom ? this._getRootRect() : getEmptyRect(); 262this._observationTargets.forEach(function(item) { 263var target = item.element; 264var targetRect = getBoundingClientRect(target); 265var rootContainsTarget = this._rootContainsTarget(target); 266var oldEntry = item.entry; 267var intersectionRect = rootIsInDom && rootContainsTarget && 268this._computeTargetAndRootIntersection(target, targetRect, rootRect); 269var newEntry = item.entry = new IntersectionObserverEntry({ 270time: now(), 271target: target, 272boundingClientRect: targetRect, 273rootBounds: rootRect, 274intersectionRect: intersectionRect 275}); 276if (!oldEntry) { 277this._queuedEntries.push(newEntry); 278} else if (rootIsInDom && rootContainsTarget) { 279 280 281 if (this._hasCrossedThreshold(oldEntry, newEntry)) { 282this._queuedEntries.push(newEntry); 283} 284} else { 285 286 287 288 if (oldEntry && oldEntry.isIntersecting) { 289this._queuedEntries.push(newEntry); 290} 291} 292}, this); 293if (this._queuedEntries.length) { 294this._callback(this.takeRecords(), this); 295} 296}; 297 298IntersectionObserver.prototype._computeTargetAndRootIntersection = 299function(target, targetRect, rootRect) { 300 301 if (window.getComputedStyle(target).display == 'none') return; 302var intersectionRect = targetRect; 303var parent = getParentNode(target); 304var atRoot = false; 305while (!atRoot && parent) { 306var parentRect = null; 307var parentComputedStyle = parent.nodeType == 1 ? 308window.getComputedStyle(parent) : {}; 309 310 if (parentComputedStyle.display == 'none') return null; 311if (parent == this.root || parent.nodeType == 9) { 312atRoot = true; 313if (parent == this.root || parent == document) { 314parentRect = rootRect; 315} else { 316 317 var frame = getParentNode(parent); 318var frameRect = frame && getBoundingClientRect(frame); 319var frameIntersect = 320frame && 321this._computeTargetAndRootIntersection(frame, frameRect, rootRect); 322if (frameRect && frameIntersect) { 323parent = frame; 324parentRect = convertFromParentRect(frameRect, frameIntersect); 325} else { 326parent = null; 327intersectionRect = null; 328} 329} 330} else { 331 332 333 334 335 var doc = parent.ownerDocument; 336if (parent != doc.body && 337parent != doc.documentElement && 338parentComputedStyle.overflow != 'visible') { 339parentRect = getBoundingClientRect(parent); 340} 341} 342 343 344 if (parentRect) { 345intersectionRect = computeRectIntersection(parentRect, intersectionRect); 346} 347if (!intersectionRect) break; 348parent = parent && getParentNode(parent); 349} 350return intersectionRect; 351}; 352 353IntersectionObserver.prototype._getRootRect = function() { 354var rootRect; 355if (this.root) { 356rootRect = getBoundingClientRect(this.root); 357} else { 358 359 var html = document.documentElement; 360var body = document.body; 361rootRect = { 362top: 0, 363left: 0, 364right: html.clientWidth || body.clientWidth, 365width: html.clientWidth || body.clientWidth, 366bottom: html.clientHeight || body.clientHeight, 367height: html.clientHeight || body.clientHeight 368}; 369} 370return this._expandRectByRootMargin(rootRect); 371}; 372 373IntersectionObserver.prototype._expandRectByRootMargin = function(rect) { 374var margins = this._rootMarginValues.map(function(margin, i) { 375return margin.unit == 'px' ? margin.value : 376margin.value * (i % 2 ? rect.width : rect.height) / 100; 377}); 378var newRect = { 379top: rect.top - margins[0], 380right: rect.right + margins[1], 381bottom: rect.bottom + margins[2], 382left: rect.left - margins[3] 383}; 384newRect.width = newRect.right - newRect.left; 385newRect.height = newRect.bottom - newRect.top; 386return newRect; 387}; 388 389IntersectionObserver.prototype._hasCrossedThreshold = 390function(oldEntry, newEntry) { 391 392 393 var oldRatio = oldEntry && oldEntry.isIntersecting ? 394oldEntry.intersectionRatio || 0 : -1; 395var newRatio = newEntry.isIntersecting ? 396newEntry.intersectionRatio || 0 : -1; 397 398 if (oldRatio === newRatio) return; 399for (var i = 0; i < this.thresholds.length; i++) { 400var threshold = this.thresholds[i]; 401 402 403 if (threshold == oldRatio || threshold == newRatio || 404threshold < oldRatio !== threshold < newRatio) { 405return true; 406} 407} 408}; 409 410IntersectionObserver.prototype._rootIsInDom = function() { 411return !this.root || containsDeep(document, this.root); 412}; 413 414IntersectionObserver.prototype._rootContainsTarget = function(target) { 415return containsDeep(this.root || document, target) && 416(!this.root || this.root.ownerDocument == target.ownerDocument); 417}; 418 419IntersectionObserver.prototype._registerInstance = function() { 420if (registry.indexOf(this) < 0) { 421registry.push(this); 422} 423}; 424 425IntersectionObserver.prototype._unregisterInstance = function() { 426var index = registry.indexOf(this); 427if (index != -1) registry.splice(index, 1); 428}; 429 430function now() { 431return window.performance && performance.now && performance.now(); 432} 433 434function throttle(fn, timeout) { 435var timer = null; 436return function () { 437if (!timer) { 438timer = setTimeout(function() { 439fn(); 440timer = null; 441}, timeout); 442} 443}; 444} 445 446function addEvent(node, event, fn, opt_useCapture) { 447if (typeof node.addEventListener == 'function') { 448node.addEventListener(event, fn, opt_useCapture || false); 449} 450else if (typeof node.attachEvent == 'function') { 451node.attachEvent('on' + event, fn); 452} 453} 454 455function removeEvent(node, event, fn, opt_useCapture) { 456if (typeof node.removeEventListener == 'function') { 457node.removeEventListener(event, fn, opt_useCapture || false); 458} 459else if (typeof node.detatchEvent == 'function') { 460node.detatchEvent('on' + event, fn); 461} 462} 463 464function computeRectIntersection(rect1, rect2) { 465var top = Math.max(rect1.top, rect2.top); 466var bottom = Math.min(rect1.bottom, rect2.bottom); 467var left = Math.max(rect1.left, rect2.left); 468var right = Math.min(rect1.right, rect2.right); 469var width = right - left; 470var height = bottom - top; 471return (width >= 0 && height >= 0) && {
472top: top, 473bottom: bottom, 474left: left, 475right: right, 476width: width, 477height: height 478} || null; 479} 480 481function getBoundingClientRect(el) { 482var rect; 483try { 484rect = el.getBoundingClientRect(); 485} catch (err) { 486 487 488 } 489if (!rect) return getEmptyRect(); 490 491 if (!(rect.width && rect.height)) { 492rect = { 493top: rect.top, 494right: rect.right, 495bottom: rect.bottom, 496left: rect.left, 497width: rect.right - rect.left, 498height: rect.bottom - rect.top 499}; 500} 501return rect; 502} 503 504function getEmptyRect() { 505return { 506top: 0, 507bottom: 0, 508left: 0, 509right: 0, 510width: 0, 511height: 0 512}; 513} 514 515function convertFromParentRect(parentBoundingRect, parentIntersectionRect) { 516var top = parentIntersectionRect.top - parentBoundingRect.top; 517var left = parentIntersectionRect.left - parentBoundingRect.left; 518return { 519top: top, 520left: left, 521height: parentIntersectionRect.height, 522width: parentIntersectionRect.width, 523bottom: top + parentIntersectionRect.height, 524right: left + parentIntersectionRect.width 525}; 526} 527 528function containsDeep(parent, child) { 529var node = child; 530while (node) { 531if (node == parent) return true; 532node = getParentNode(node); 533} 534return false; 535} 536 537function getParentNode(node) { 538var parent = node.parentNode; 539if (node.nodeType == 9 && node != document) { 540 541 return getFrameElement(node); 542} 543if (parent && parent.nodeType == 11 && parent.host) { 544 545 return parent.host; 546} 547if (parent && parent.assignedSlot) { 548 549 return parent.assignedSlot.parentNode; 550} 551return parent; 552} 553 554function getFrameElement(doc) { 555try { 556return doc.defaultView && doc.defaultView.frameElement || null; 557} catch (e) { 558 559 return null; 560} 561} 562 563window.IntersectionObserver = IntersectionObserver; 564window.IntersectionObserverEntry = IntersectionObserverEntry; 565}());
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.