PageSourceSearch

https://www.circulomexicano.com/wp-content/themes/habita/js/jquery.documentsize.js

js circulomexicano.com collected 2026-10-04 07:08:29 UTC 35,826 bytes, 837 lines download raw bytes

1;( function ( $ ) {
2    "use strict";
3
4    // IIFE generating the functions $.documentWidth, $.documentHeight, $.windowWidth, $.windowHeight, and
5    // $.scrollbarWidth.
6    //
7    // These functions need to run feature detections which requires insertion of an iframe ($.documentWidth/Height) and
8    // a div ($.scrollbarWidth). The body element in the main document must be available when that happens (ie, the
9    // opening body tag must have been parsed).
10    //
11    // For that reason, the detection does not run instantly - after all, the code might be loaded and run while parsing
12    // the head. Instead, detection happens on DOM-ready, or when any of the functions is invoked for the first time.
13    // Given the purpose of the functions, they won't be called until after the opening body tag has been parsed.
14
15    var _scrollbarWidth,
16        _supportsWindowInnerWidth,
17        _supportsSubpixelAccuracy,
18        elementNameForDocSizeQuery,
19        ieVersion,
20        useGetComputedStyle = !! window.getComputedStyle;
21
22    /**
23     * @param   {Document} [_document=document]
24     * @returns {number}
25     */
26    $.documentWidth = function ( _document ) {
27        var width;
28
29        _document || ( _document = document );
30
31        try {
32
33            if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll();
34            width = _document[elementNameForDocSizeQuery].scrollWidth;
35
36        } catch ( e ) {
37
38            // Fallback for unsupported, broken browsers which can't run the behaviour test successfully
39            width = guessDocumentSize( "Width", _document );
40
41        }
42
43        return width;
44    };
45
46    /**
47     * @param   {Document} [_document=document]
48     * @returns {number}
49     */
50    $.documentHeight = function ( _document ) {
51        var height;
52
53        _document || ( _document = document );
54
55        try {
56
57            if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll();
58            height = _document[elementNameForDocSizeQuery].scrollHeight;
59
60        } catch ( e ) {
61
62            // Fallback for unsupported, broken browsers which can't run the behaviour test successfully
63            height = guessDocumentSize( "Height", _document );
64
65        }
66
67        return height;
68    };
69
70    /**
71     * @param   {string|Object|Window} [options="visual"]  (a) viewport option: strings "visual", "layout" (case-
72     *                                                         insensitive), or a hash with a `viewport` property
73     *                                                     (b) the window argument
74     * @param   {string|Object|Window} [_window=window]    same as first argument; positions for window and viewport
75     *                                                     argument are interchangeable
76     * @returns {number}
77     */
78    $.windowWidth = function ( options, _window ) {
79        var config = getWindowQueryConfig( arguments );
80        return getWindowSize( "Width", config );
81    };
82
83    /**
84     * @param   {string|Object|Window} [options="visual"]  (a) viewport option: strings "visual", "layout" (case-
85     *                                                         insensitive), or a hash with a `viewport` property
86     *                                                     (b) the window argument
87     * @param   {string|Object|Window} [_window=window]    same as first argument; positions for window and viewport
88     *                                                     argument are interchangeable
89     * @returns {number}
90     */
91    $.windowHeight = function ( options, _window ) {
92        var config = getWindowQueryConfig( arguments );
93        return getWindowSize( "Height", config );
94    };
95
96    /**
97     * @param   {Window} [_window=window]
98     * @returns {number}
99     */
100    $.pinchZoomFactor = function ( _window ) {
101
102        // Calculate the zoom factor based on the width, not the height. getPinchZoomFactor() does just that.
103        //
104        // It would be more accurate to use the longest side for the calculation, keeping the effect of rounding errors
105        // low (unless the browser supports sub-pixel accuracy anyway).
106        //
107        // Unfortunately, iOS does not allow that approach. Switching from normal to minimal UI is not reflected in the
108        // clientHeight, so the zoom factor would seem to change when the UI disappears (even though in reality, it
109        // doesn't). We have to use the width, irrespective of orientation.
110
111        return getPinchZoomFactor( _window );
112    };
113
114    /**
115     * @returns {number}
116     */
117    $.scrollbarWidth = browserScrollbarWidth;
118
119
120    /**
121     * Returns the window width or height. Does the actual work of $.windowWidth() and $.windowHeight().
122     *
123     * Handles minimal UI in iOS properly. Returns the size of either the visual viewport (default) or the layout
124     * viewport.
125     *
126     * Precision:
127     *
128     * - The maximum rounding error for the visual viewport is +/- 1px.
129     * - Layout viewport width is precise.
130     * - Layout viewport height would potentially be prone to larger rounding errors (though in practice they rarely
131     *   seem to exceed +/- 2px). Additional logic is employed to detect and correct these errors. As a result, the
132     *   layout viewport height is precise as well.
133     *
134     * @param   {string}            dimension  must be "Width" or "Height" (upper case!)
135     * @param   {WindowQueryConfig} config
136     * @returns {number}
137     */
138    function getWindowSize ( dimension, config ) {
139        var ddeClientHeight, visualSize, zoomFactor, snapToKnownHeight, lBound, uBound,
140            _window = config.window,
141
142            scrollbarsConsumeSpace = browserScrollbarWidth() !== 0,
143            getLayoutViewportWidth = config.useLayoutViewport && dimension === "Width",
144
145            useClientSize = scrollbarsConsumeSpace || !supportsWindowInnerWidth() || getLayoutViewportWidth,
146            size = useClientSize ? _window.document.documentElement[ "client" + dimension ] : getWindowInnerSize( dimension, _window );
147
148        if ( config.useLayoutViewport && ! useClientSize ) {
149
150            // Looking for the layout viewport height on mobile. Calculate it from window.innerHeight and the zoom
151            // factor, so as to capture the real height when the browser is in minimal UI on iOS.
152            //
153            // NB The layout viewport has a size in full CSS pixels (unaffected by zooming, hence no sub pixels).
154
155            visualSize = size;
156            zoomFactor = getPinchZoomFactor( _window, { asRange: true } );
157
158            size = Math.round( visualSize * zoomFactor.calculated );
159
160            // Fix rounding errors, caused by the visual height ignoring sub-pixel fractions. If we know 
160we are near a
161            // known layout viewport height, use that.
162            if ( !supportsSubpixelAccuracy() ) {
163
164                ddeClientHeight =  _window.document.documentElement.clientHeight;
165
166                // In Android, the height we get from ddE.clientHeight and the one calculated from window.innerHeight
167                // should be the same, except for rounding errors in the calculation. So basically, we could just set
168                // any calculated value to the clientHeight, no matter how large the difference is. (That is, if we even
169                // end up here - in some versions of Chrome on Android, for instance, we have sub-pixel accuracy.)
170                //
171                // Not so in iOS. In minimal UI, the real layout viewport may be larger than the one reported by
172                // clientHeight, by about 60px. So we need to impose reasonable limits on what is considered to be near
173                // the clientHeight.
174                //
175                // - If the calculated value is within 3px of the clientHeight, we consider it to be a clear case of a
176                //   rounding error.
177                // - Alternatively, the clientHeight must be between the theoretical maximum and minimum values of the
178                //   computation, assuming maximum rounding errors at every stage.
179                // - If we use that range, its upper bound is capped at 30px above the clientHeight - keeping a safe
180                //   distance from current minimal UI heights, or possible future ones.
181
182                lBound = ( visualSize - 1 ) * zoomFactor.min;
183                uBound = ( visualSize + 1 ) * zoomFactor.max;
184
185                snapToKnownHeight = ( size <= ddeClientHeight + 3 && size >= ddeClientHeight - 3 ) ||
186                                    ( lBound <= ddeClientHeight && uBound >= ddeClientHeight && uBound < ddeClientHeight + 30 );
187
188                if ( snapToKnownHeight ) size = ddeClientHeight;
189
190            }
191        }
192
193        return size;
194    }
195
196    /**
197     * Calculates the zoom factor for pinch zooming on mobile. A factor > 1 means that the page is zoomed in (content
198     * enlarged).
199     *
200     * The zoom factor returned here measures the size of the visual viewport with respect to the size of the layout
201     * viewport.
202     *
203     * Ignores page zoom on the desktop (returning a zoom factor of 1). For the distinction between pinch and page zoom,
204     * again see Chapter 3 in PPK's book.
205     *
206     * NB visualViewport.scale, part of the new visualViewport API, is not used here even if available. Browsers usually
207     * calculate their zoom level with respect to the ideal layout viewport, not the layout viewport actually in use
208     * (see Peter-Paul Koch, The Mobile Web Handbook, Chapter 3: Viewports, Section "Minimum and Maximum Zoom"). So, in
209     * Chrome for Android, visualViewport.scale returns that ratio, rather than the isolated effect of zooming into a
210     * part of the page.
211     *
212     * The distinction doesn't matter if the meta viewport tag makes the browser use its ideal viewport anyway
213     * (width=device-width, initial-scale=1.0). But it leads to confusing results if, for example, initial-scale is set
214     * to values < 1, or if the meta viewport tag is left out altogether. Then, the page shrinks visually _by default_,
215     * without the user zooming. The scale reported by the visualViewport API captures the effect and returns a value
216     * < 1. However, the pinch zoom factor should remain at 1 because the visual viewport is still identical to the
217     * layout viewport - never mind the diminutive size of its content.
218     *
219     * @param   {Window}  [_window=window]
220     * @param   {Object}  [options]
221     * @param   {boolean} [options.asRange=false]
222     * @returns {number|ZoomAccuracyRange}
223     */
224    function getPinchZoomFactor ( _window, options ) {
225        var ddeClientWidth, windowInnerWidth,
226            asRange = options && options.asRange,
227            factors = {
228                calculated: 1,
229                min: 1,
230                max: 1
231            },
232            skip = browserScrollbarWidth() !== 0 || !supportsWindowInnerWidth();
233
234        if ( !skip ) {
235
236            _window || ( _window = window );
237            ddeClientWidth = _window.document.documentElement.clientWidth;
238            windowInnerWidth = getWindowInnerWidth( _window );
239
240            // Calculate the zoom factor, assuming window.innerWidth is precise (no rounding errors).
241            factors.calculated = ddeClientWidth / windowInnerWidth;
242
243            // If requested, determine the minimum and maximum value of the zoom factor in the presence of rounding errors.
244            if ( asRange ) {
245                if ( supportsSubpixelAccuracy() ) {
246                    // No need to take rounding errors into account
247                    factors.min = factors.max = factors.calculated;
248                } else {
249                    factors.min = ddeClientWidth / ( windowInnerWidth + 1 );
250                    factors.max = ddeClientWidth / ( windowInnerWidth - 1 );
251                }
252            }
253
254        }
255
256        return asRange ? factors : factors.calculated;
257    }
258
259    /**
260     * Handles the argument juggling for $.windowWidth() and $.windowHeight(). Extracts the window and viewport settings
261     * from the arguments, applying the defaults (use global window, use visual viewport) where necessary.
262     *
263     * Examines the first two arguments. The window and the viewport setting can appear in either position,
264     * interchangeably. The viewport setting can be passed in as a string, or as part of an options hash,
265     * `{ viewport: ... }`.
266     *
267     * Recognized viewport names are "visual" and "layout" (case-insensitive).
268     *
269     * @param   {Array|Arguments} args
270     * @returns {WindowQueryConfig}
271     */
272    function getWindowQueryConfig( args ) {
273        var isWindowArg0, isOptionArg0, isOptionArg1,
274
275            // Defaults
276            _window = window,
277            _useVisualViewport = true;
278
279        if ( args && args.length ) {
280
281            // Coerce to a real array
282            args = Array.prototype.slice.call( args );
283
284            // Examine the first argument. Cast strings to an options hash with a `viewport` property.
285            isWindowArg0 = isWindow( args[0] );
286            if( !isWindowArg0 ) args[0] = castStringToViewportOption( args[0] );
287            isOptionArg0 = !isWindowArg0 && args[0];
288
289            // Examine the second argument. Again, cast strings to an options hash with a `viewport` property.
290            if ( !isOptionArg0 ) args[1] = castStringToViewportOption( args[1] );
291            isOptionArg1 = !isOptionArg0 && args[1];
292
293            // Extract window and viewport option, if available.
294            if ( isWindowArg0 ) {
295
296                _window = args[0];
297                if( isOptionArg1 && args[1].viewport ) _useVisualViewport = isVisualViewport( args[1].viewport );
298
299            } else if ( isOptionArg0 ) {
300
301                if( args[0].viewport ) _useVisualViewport = isVisualViewport( args[0].viewport );
302                if ( isWindow( args[1] ) ) _window = args[1];
303
304            } else if ( !args[0] && args[1] ) {
305
306                // First argument was falsy, e.g. undefined, null. Ignore it. But process the second, non-falsy argument.
307                if( isOptionArg1 && args[1].viewport ) {
308                    _useVisualViewport = isVisualViewport( args[1].viewport );
309                } else if ( isWindow( args[1] ) ) {
310                    _window = args[1];
311                }
312
313            }
314        }
315
316        return {
317            window: _window,
318            useVisualViewport: _useVisualViewport,
319            useLayoutViewport: !_useVisualViewport
320        };
321    }
322
323    /**
324     * Checks if the argument is the name of the visual viewport. The check is case-insensitive.
325     *
326     * Expects a string. Tolerates falsy values, returning false then (argument is not naming the visual viewport).
327     * Throws an error for everything else. Also throws an error if the viewport name is a string but not recognized
328     * (typo alert).
329     *
330     * Helper for getWindowQueryConfig().
331     *
332     * @param   {string} [name]  strings "visual", "layout" (case-insensitive)
333     * @returns {boolean}
334     */
335    function isVisualViewport ( name ) {
336        var viewport = isString( name ) && name.toLowerCase();
337
338        if ( name && !viewport ) throw new Error( "Invalid viewport option: " + name );
339        if ( viewport && viewport !== "visual" && viewport !== "layout" ) throw new Error( "Invalid viewport name: " + name );
340
341        return viewport === "visual";
342    }
343
344    /**
345     * Examines a value and casts a string to a hash with a `viewport` property (the string being its value). If the
346     * value is not a string, or if the string is empty, it is returned as-is. Helper for getWindowQueryConfig().
347     *
348     * @param   {*} arg
349     * @returns {*}
350     */
351    function castStringToViewportOption ( arg ) {
352        return ( isString( arg ) && arg !== "" ) ? { viewport: arg } : arg;
353    }
354
355    /**
356     * Checks if the browser supports window.visualViewport.width and window.visualViewport.height, or window.innerWidth
357     * and window.innerHeight otherwise.
358     *
359     * See getWindowInnerSize() for the distinction between the visualViewport API and window.innerWidth/Height.
360     *
361     * The check is run on demand, rather than up front while loading the component, because the window properties can
362     * behave strangely in the early stages of opening a window. The component might be loaded in the document head,
363     * which could potentially be early enough to run into these oddities. So we wait until the first call.
364     *
365     * IE 8 does not support window.innerWidth and .innerHeight. FF has a bug which as only been fixed in FF25 (released
366     * 29 Oct 2013). It manifests itself in a fictional return value of 10 for these properties. See
367     *
368     * - https://developer.mozilla.org/en-US/docs/Web/API/Window.innerWidth
369     * - https://developer.mozilla.org/en-US/docs/Web/API/Window.innerHeight
370     * - https://bugzilla.mozilla.org/show_bug.cgi?id=641188
371     *
372     * @returns {boolean}
373     */
374    function supportsWindowInnerWidth () {
375        if ( _supportsWindowInnerWidth === undefined ) _supportsWindowInnerWidth = getWindowInnerWidth() > 10;
376        return _supportsWindowInnerWidth;
377    }
378
379    /**
380     * Does the actual work of $.scrollbarWidth. Protected from external modification. See $.scrollbarWidth for details.
381     *
382     * Adapted from Ben Alman's scrollbarWidth plugin. See
383     * - http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
384     * - http://jsbin.com/zeliy/1
385     *
386     * @returns {number}
387     */
388    function browserScrollbarWidth () {
389        var testEl;
390
391        if ( _scrollbarWidth === undefined ) {
392
393            testEl = document.createElement( "div" );
394            testEl.style.cssText = "width: 100px; height: 100px; overflow: scroll; position: absolute; top: -500px; left: -500px; margin: 0px; padding: 0px; border: none;";
395
396            document.body.appendChild( testEl );
397            _scrollbarWidth = testEl.offsetWidth - testEl.clientWidth;
398            document.body.removeChild( testEl );
399
400        }
401
402        return _scrollbarWidth;
403    }
404
405    /**
406     * Detects which element to use for a document size query (body or documentElement).
407     *
408     * Sandbox
409     * -------
410     *
411     * The detection is sandboxed in an iframe element created for the purpose. If the iframe window can't be
412     * accessed because of some obscure policy restriction or browser bug, the main window and document is used
413     * as a fallback.
414     *
415     * The test is designed to minimize the visual and rendering impact in the test window, in case the fallback
416     * should ever be used.
417     *
418     * Test method
419     * -----------
420     *
421     * We can't test directly which call to use (at least not with an even worse amount of intervention than is
422     * already the case, which matters if the iframe is not accessible). But we can work by exclusion.
423     *
424     * In Chrome (desktop and mobile), Safari (also iOS), and Opera, body.scrollWidth returns the true document
425     * width. In Firefox and IE, body.scrollWidth responds to the body content size instead. In those browsers,
426     * true document width is returned by document.documentElement.scrollWidth.
427     *
428     * So we test the behaviour of body.scrollWidth by manipulating the body size, while keeping the document size
429     * constant.
430     *
431     * - We prepare for the test by making sure the body does not display its overflow.
432     * - Then we inject a small test element into the body and give it a relative position far outside the viewport.
433     *
434     * The body size is expanded, but the document size remains unaffected because the body hides the overflowing
435     * test element (either outright, or by putting it in a hidden part of the scroll pane). Then we check if
436     * body.scrollWidth has responded to the change. From that, we infer the right element to use for a document
437     * width query.
438     *
439     * The function does not return anything. It sets the elementNameForDocSizeQuery in the closure instead.
440     */
441    function testDocumentScroll () {
442
443        var initialDocumentState, _testEl, initialScrollWidth, responds,
444
445            iframe = createTestIframe(),
446            _document = iframe && iframe.contentDocument || document,
447            _body = _document.body,
448            inIframe = _document !== document;
449
450        // Create a test element which will be used to to expand the body content way to the right.
451        _testEl = _document.createElement( "div" );
452        _testEl.style.cssText = "width: 1px; height: 1px; position: relative; top: 0px; left: 32000px;";
453
454        // Make sure that the body (but not the window) hides its overflow. Only applies if the iframe is not
455        // accessible. The iframe document already contains the required styles.
456        if ( ! inIframe ) initialDocumentState = prepareGlobalDocument();
457
458        // Inject the test element, then test if the body.scrollWidth property responds
459        initialScrollWidth = _body.scrollWidth;
460        _body.appendChild( _testEl );
461        responds = initialScrollWidth !== _body.scrollWidth;
462        _body.removeChild( _testEl );
463
464        // Restore the overflow settings for window and body
465        if ( ! inIframe ) restoreGlobalDocument( initialDocumentState );
466
467        // If body.scrollWidth responded, it reacts to body content size, not document size. Default to
468        // ddE.scrollWidth. If it did not react, however, it is linked to the (unchanged) document size.
469        elementNameForDocSizeQuery = responds ? "documentElement" : "body";
470
471        if ( iframe ) document.body.removeChild( iframe );
472
473    }
474
475    /**
476     * Creates an iframe document with an HTML5 doctype and UTF-8 encoding and positions it off screen. Window size
477     * is 500px x 500px. Body and window (document element) are set to overflow: hidden.
478     *
479     * In case the content document of the iframe can't be accessed for some reason, the function returns undefined.
480     * This is unlikely to ever happen, though.
481     *
482     * @returns {HTMLIFrameElement|undefined}
483     */
484    function createTestIframe () {
485        var iframe = document.createElement( "iframe" ),
486            body = document.body;
487
488        iframe.style.cssText = "position: absolute; top: -600px; left: -600px; width: 500px; height: 500px; margin: 0px; padding: 0px; border: none; display: block;";
489        iframe.frameborder = "0";
490
491        body.appendChild( iframe );
492        iframe.src = 'about:blank';
493
494        if ( !iframe.contentDocument ) return;
495
496        iframe.contentDocument.write( '<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><style type="text/css">html, body { overflow: hidden; }</style></head><body></body></html>' );
497
498        return iframe;
499    }
500
501    /**
502     * Makes sure the body (but not the window) hides its overflow. Works with the global document, returns the initial
503     * state before manipulation (including properties indicating what has been modified).
504     *
505     * Used only if iframe creation or access has failed for some reason.
506     */
507    function prepareGlobalDocument () {
508        var ddEStyle, bodyStyle,
509
510            ddE = document.documentElement,
511            body = document.body,
512
513            ddEComputedStyles = useGetComputedStyle ? window.getComputedStyle( ddE, null ) : ddE.currentStyle,
514            bodyComputedStyles = useGetComputedStyle ? window.getComputedStyle( body, null ) : body.currentStyle,
515
516            ddEOverflowX = ( ddEComputedStyles.overflowX || ddEComputedStyles.overflow || "visible" ).toLowerCase(),
517            bodyOverflowX = ( bodyComputedStyles.overflowX || bodyComputedStyles.overflow || "visible" ).toLowerCase(),
518
519            modifyBody = bodyOverflowX !== "hidden",
520            modifyDocumentElement = ddEOverflowX === "visible",
521
522            initialState = {
523                documentElement: {
524                    modified: modifyDocumentElement
525                },
526                body: {
527                    modified: modifyBody
528                }
529            };
530
531        if ( modifyDocumentElement ) {
532            ddEStyle = ddE.style;
533            initialState.documentElement.styleOverflowX = ddEStyle.overflowX;
534            ddEStyle.overflowX = "auto";
535        }
536
537        if ( modifyBody ) {
538            bodyStyle = body.style;
539            initialState.body.styleOverflowX = bodyStyle.overflowX;
540            bodyStyle.overflowX = "hidden";
541        }
542
543        return initialState;
544
545    }
546
547    /**
548     * Restores the body and documentElement styles to their initial state, which is passed in as an argument. Works
549     * with the global document.
550     *
551     * Used only if iframe creation or access has failed for some reason.
552     *
553     * @param {Object} previousState  the initial state, as returned by prepareGlobalDocument()
554     */
555    function restoreGlobalDocument ( previousState ) {
556
557        if ( previousState.documentElement.modified ) document.documentElement.style.overflowX = previousState.documentElement.styleOverflowX;
558        if ( previousState.body.modified ) document.body.style.overflowX = previousState.body.styleOverflowX;
559
560    }
561
562    /**
563     * Returns a best guess for the window width or height. Used as a fallback for unsupported browsers which are too
564     * broken to even run the feature test.
565     *
566     * The conventional jQuery method of guessing the document size is used here: every conceivable value is queried and
567     * the largest one is picked.
568     *
569     * @param {string}   dimension    accepted values are "Width" or "Height" (capitalized first letter!)
570     * @param {Document} [_document]
571     */
572    function guessDocumentSize( dimension, _document ) {
573        var ddE = _document.documentElement;
574
575        return Math.max(
576            ddE.body[ "scroll" + dimension ], _document[ "scroll" + dimension ],
577            ddE.body[ "offset" + dimension ], _document[ "offset" + dimension ],
578            _document[ "client" + dimension ]
579        );
580    }
581
582    /**
583     * Returns window.visualViewport.width if available, or window.innerWidth otherwise.
584     *
585     * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point
586     * values).
587     *
588     * @param   {Window} [_window=window]
589     * @returns {number}
590     */
591    function getWindowInnerWidth ( _window ) {
592        return getWindowInnerSize( "Width", _window );
593    }
594
595    /**
596     * Returns window.visualViewport.height if available, or window.innerHeight otherwise.
597     *
598     * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point
599     * values).
600     *
601     * @param   {Window} [_window=window]
602     * @returns {number}
603     */
604    function getWindowInnerHeight ( _window ) {
605        return getWindowInnerSize( "Height", _window );
606    }
607
608    /**
609     * Returns window.visualViewport.width if available, or window.innerWidth otherwise, for width. Likewise, it
610     * returns window.visualViewport.height or window.innerHeight for height. The dimension argument determines whether
611     * width or height is returned.
612     *
613     * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point
614     * values).
615     *
616     * If the visualViewport API is available, it is preferred over window.innerWidth/Height. That's because Chrome,
617     * from version 62, has changed the behaviour of window.innerWidth/Height, which used to return the size of the
618     * visual viewport. In Chrome, it now returns the size of the layout viewport, breaking compatibility with all other
619     * browsers and its own past behaviour. Other browsers may follow suit, though. See
620     *
621     * - https://www.quirksmode.org/blog/archives/2017/09/chrome_breaks_v.html
622     * - https://developers.google.com/web/updates/2017/09/visual-viewport-api
623     * - https://bugs.chromium.org/p/chromium/issues/detail?id=767388#c8
624     *
625     * @param   {string} dimension  must be "Width" or "Height" (upper case!)
626     * @param   {Window} [_window=window]
627     * @returns {number}
628     */
629    function getWindowInnerSize ( dimension, _window ) {
630        var size =  ( _window || window ).visualViewport ?
631                    ( _window || window ).visualViewport[ dimension.toLowerCase() ] :
632                    ( _window || window )[ "inner" + dimension];
633
634        // Check for fractions. Exclude undefined return values in browsers which don't support window.innerWidth/Height.
635        if ( size ) checkForFractions( size );
636        return size;
637    }
638
639    /**
640     * Accepts an observed value of window.innerWidth or window.innerHeight and examines it for fractional values.
641     * Caches the finding if there is one. Helper for getWindowInnerWidth() and friends.
642     *
643     * See supportsSubpixelAccuracy() for more.
644     *
645     * @param {number} sizeMeasurement
646     */
647    function checkForFractions ( sizeMeasurement ) {
648
649        // When checking the cached value, we can't accept false as a definitive answer. We have to continue checking
650        // unless the cached value is `true`.
651        //
652        // See supportsSubpixelAccuracy().
653        if ( !_supportsSubpixelAccuracy && isFloat( sizeMeasurement ) ) _supportsSubpixelAccuracy = true;
654
655    }
656
657    /**
658     * Returns whether or not the browser supports sub-pixel accuracy (floating-point values) for window.innerWidth and
659     * window.innerHeight - as far as we know yet.
660     *
661     * The browser behaviour can't be tested directly, and must be figured out by continuous observation. We have to
662     * monitor the return values of window.innerWidth/Height for fractions. That is done with getWindowInnerWidth etc.
663     * As soon as we find a fraction, we know that the browser supports floating-point accuracy.
664     *
665     * However, we can never be sure of the opposite. If we haven't encountered a fraction yet, it could simply mean
666     * that we are at 100% zoom, and integers have indeed been the correct return value so far.
667     *
668     * So when the method here answers with true, it is definitive. When it returns false, that just means "maybe not,
669     * but we don't know". And the the return value might flip to true in a future query.
670     *
671     * @returns {boolean}
672     */
673    function supportsSubpixelAccuracy () {
674        return !!_supportsSubpixelAccuracy;
675    }
676
677    function isWindow ( value ) {
678        // Identical to jQuery.isWindow()
679        return value != null && value.window == value;         // jshint ignore:line
680    }
681
682    function isString ( value ) {
683        // Done as in the Lodash compatibility build
684        return typeof value === 'string' || value && typeof value === 'object' && Object.prototype.toString.call(value) === '[object String]' || false;
685    }
686
687    /**
688     * Returns whether or not a value is of type number. Also rejects NaN as a number.
689     *
690     * NB This is not the same as $.isNumeric because $.isNumeric( "3" ) is true while isNumber( "3" ) is false.
691     *
692     * @param   {*} value
693     * @returns {boolean}
694     */
695    function isNumber ( value ) {
696        // Done as in the Lodash compatibility build, but rejecting NaN as a number.
697        var isNumeric = typeof value === 'number' || value && typeof value === 'object' && Object.prototype.toString.call( value ) === '[object Number]' || false;
698
699        // Reject NaN before returning
700        return isNumeric && value === +value;
701    }
702
703    /**
704     * Returns whether or not a number is a float, ie has decimals.
705     *
706     * Requires the argument to be a number. If unsure, guard against false detections with
707     * `isNumber( value ) && isFloat ( value )`.
708     *
709     * For the technique, see http://stackoverflow.com/a/3885844/508355
710     *
711     * @param   {number} num
712     * @returns {boolean}
713     */
714    function isFloat ( num ) {
715        return num === +num && num !== ( num | 0 );         // jshint ignore:line
716    }
717
718    /**
719     * Returns the IE version, or false if the browser is not IE.
720     *
721     * The result is determined by browser sniffing, rather than a test tailored to the use case. The function must only
722     * be called as a last resort, for scenarios where there is no alternative to browser sniffing.
723     *
724     * These scenarios include:
725     *
726     * - Preventing IE6 and IE7 from crashing
727     * - Preventing IE9 from blocking or delaying the load event
728     *
729     * The test follows the MSDN recommendation at https://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#parsingua
730     * The result is cached.
731     *
732     * @returns {number|boolean}
733     */
734    function getIEVersion () {
735        var userAgent, userAgentTestRx;
736
737        if ( ieVersion === undefined ) {
738
739            ieVersion = false;
740            userAgent = navigator && navigator.userAgent;
741
742            if ( navigator && navigator.appName === "Microsoft Internet Explorer" && userAgent ) {
743                userAgentTestRx = new RegExp( "MSIE ([0-9]{1,}[\.0-9]{0,})" );                          // jshint ignore:line
744                if ( userAgentTestRx.exec( userAgent ) != null ) ieVersion = parseFloat( RegExp.$1 );
745            }
746
747        }
748
749        return ieVersion;
750    }
751
752    /**
753     * Checks if we are dealing with a truly ancient version of IE (< IE8).
754     *
755     * This is done by browser sniffing, rather than a test tailored to the use case. Use it only if there is no
756     * alternative.
757     *
758     * @returns {boolean}
759     */
760    function isAncientIE () {
761        var ieVersion = getIEVersion();
762        return ieVersion && ieVersion < 8;
763    }
764
765    /**
766     * Checks if the browser is IE9.
767     *
768     * This is done by browser sniffing, rather than a test tailored to the use case. Use it only if there is no
769     * alternative.
770     *
771     * @returns {boolean}
772     */
773    function isIE9 () {
774        return getIEVersion() === 9;
775    }
776
777
778    // Let's prime $.documentWidth(), $.documentHeight() and $.scrollbarWidth() immediately after the DOM is ready. It
779    // is best to do it up front because the test touches the DOM, so let's get it over with before people set up
780    // handlers for mutation events and such.
781    //
782    // This step has to be skipped for the following browsers:
783    //
784    // - ancient versions of IE (IE6, IE7).
785    //   IE6 and IE7 can't handle the feature tests on DOM ready - they crash right away. Later on, the tests are ok.
786    //
787    // - IE9.
788    //   If the feature tests were run on DOM ready, the window load event would become unreliable. The event might not
789    //   fire until the user moves the mouse over the document. This bug is rare and not triggered by jQuery.documentSize
790    //   alone; third-party code likely plays a role. The exact circumstances are not clear - see issue #3.
791    //
792    // For these browsers, we don't run the feature tests preemptively. Instead, we do it on demand, when the first
793    // document size query is made.
794    if ( typeof $ === "function" && !isAncientIE() && !isIE9() ) {
795
796        // Try-catch acts as a safety net for unsupported, broken browsers
797        try {
798
799            $( function () {
800                if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll();
801                browserScrollbarWidth();
802            } );
803
804        } catch ( e ) {}
805
806    }
807
808
809    /**
810     * Custom types.
811     *
812     * For easier documentation and type inference.
813     */
814
815    /**
816     * @name ZoomAccuracyRange
817     * @type {Object}
818     *
819     * @property {number} calculated
820     * @property {number} min
821     * @property {number} max
822     */
823
824    /**
825     * @name WindowQueryConfig
826     * @type {Object}
827     *
828     * @property {Window}  window
829     * @property {boolean} useVisualViewport
830     * @property {boolean} useLayoutViewport
831     */
832
833}(
834    typeof jQuery !== "undefined" ? jQuery :
835    typeof Zepto !== "undefined" ? Zepto :
836    $
837));

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.