From b161c5e2ad2b0152fd7412f784f4f72af4819c7e Mon Sep 17 00:00:00 2001 From: hashchange Date: Wed, 5 Aug 2015 00:34:04 +0200 Subject: [PATCH] Updated build --- bower.json | 2 +- dist/amd/jquery.documentsize.js | 453 +++++++++++++++++++++++- dist/amd/jquery.documentsize.min.js | 4 +- dist/amd/jquery.documentsize.min.js.map | 2 +- dist/jquery.documentsize.js | 453 +++++++++++++++++++++++- dist/jquery.documentsize.min.js | 4 +- dist/jquery.documentsize.min.js.map | 2 +- package.json | 2 +- 8 files changed, 882 insertions(+), 40 deletions(-) diff --git a/bower.json b/bower.json index 9c17c97..0b7e187 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery.documentsize", - "version": "1.1.0", + "version": "1.2.0", "homepage": "https://github.com/hashchange/jquery.documentsize", "authors": [ "Michael Heim " diff --git a/dist/amd/jquery.documentsize.js b/dist/amd/jquery.documentsize.js index d249a6a..28f0ac1 100644 --- a/dist/amd/jquery.documentsize.js +++ b/dist/amd/jquery.documentsize.js @@ -1,4 +1,4 @@ -// jQuery.documentSize, v1.1.0 +// jQuery.documentSize, v1.2.0 // Copyright (c)2015 Michael Heim, Zeilenwechsel.de // Distributed under MIT license // http://github.com/hashchange/jquery.documentsize @@ -37,6 +37,8 @@ // Given the purpose of the functions, they won't be called until after the opening body tag has been parsed. var _scrollbarWidth, + _supportsWindowInnerWidth, + _supportsSubpixelAccuracy, elementNameForDocSizeQuery, useGetComputedStyle = !! window.getComputedStyle; @@ -61,21 +63,47 @@ }; /** - * @param {Window} [_window=window] + * @param {string|Object|Window} [options="visual"] (a) viewport option: strings "visual", "layout" (case- + * insensitive), or a hash with a `viewport` property + * (b) the window argument + * @param {string|Object|Window} [_window=window] same as first argument; positions for window and viewport + * argument are interchangeable + * @returns {number} + */ + $.windowWidth = function ( options, _window ) { + var config = getWindowQueryConfig( arguments ); + return getWindowSize( "Width", config ); + }; + + /** + * @param {string|Object|Window} [options="visual"] (a) viewport option: strings "visual", "layout" (case- + * insensitive), or a hash with a `viewport` property + * (b) the window argument + * @param {string|Object|Window} [_window=window] same as first argument; positions for window and viewport + * argument are interchangeable * @returns {number} */ - $.windowWidth = function ( _window ) { - _window || ( _window = window ); - return ( browserScrollbarWidth() || window.innerWidth === undefined ) ? _window.document.documentElement.clientWidth : _window.innerWidth; + $.windowHeight = function ( options, _window ) { + var config = getWindowQueryConfig( arguments ); + return getWindowSize( "Height", config ); }; /** * @param {Window} [_window=window] * @returns {number} */ - $.windowHeight = function ( _window ) { - _window || ( _window = window ); - return ( browserScrollbarWidth() || window.innerWidth === undefined ) ? _window.document.documentElement.clientHeight : _window.innerHeight; + $.pinchZoomFactor = function ( _window ) { + + // Calculate the zoom factor based on the width, not the height. getPinchZoomFactor() does just that. + // + // It would be more accurate to use the longest side for the calculation, keeping the effect of rounding errors + // low (unless the browser supports sub-pixel accuracy anyway). + // + // Unfortunately, iOS does not allow that approach. Switching from normal to minimal UI is not reflected in the + // clientHeight, so the zoom factor would seem to change when the UI disappears (even though in reality, it + // doesn't). We have to use the width, irrespective of orientation. + + return getPinchZoomFactor( _window ); }; /** @@ -84,16 +112,250 @@ $.scrollbarWidth = browserScrollbarWidth; - // Let's prime $.documentWidth(), $.documentHeight() and $.scrollbarWidth() immediately after the DOM is ready. It - // is best to do it up front because the test touches the DOM, so let's get it over with before people set up - // handlers for mutation events and such. - if ( typeof $ === "function" ) { - $( function () { - if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll(); - browserScrollbarWidth(); - } ); + /** + * Returns the window width or height. Does the actual work of $.windowWidth() and $.windowHeight(). + * + * Handles minimal UI in iOS properly. Returns the size of either the visual viewport (default) or the layout + * viewport. + * + * Precision: + * + * - The maximum rounding error for the visual viewport is +/- 1px. + * - Layout viewport width is precise. + * - Layout viewport height would potentially be prone to larger rounding errors (though in practice they rarely + * seem to exceed +/- 2px). Additional logic is employed to detect and correct these errors. As a result, the + * layout viewport height is precise as well. + * + * @param {string} dimension must be "Width" or "Height" (upper case!) + * @param {WindowQueryConfig} config + * @returns {number} + */ + function getWindowSize ( dimension, config ) { + var ddeClientHeight, visualSize, zoomFactor, snapToKnownHeight, lBound, uBound, + _window = config.window, + + scrollbarsConsumeSpace = browserScrollbarWidth() !== 0, + getLayoutViewportWidth = config.useLayoutViewport && dimension === "Width", + + useClientSize = scrollbarsConsumeSpace || !supportsWindowInnerWidth() || getLayoutViewportWidth, + size = useClientSize ? _window.document.documentElement[ "client" + dimension ] : getWindowInnerSize( dimension, _window ); + + if ( config.useLayoutViewport && ! useClientSize ) { + + // Looking for the layout viewport height on mobile. Calculate it from window.innerHeight and the zoom + // factor, so as to capture the real height when the browser is in minimal UI on iOS. + // + // NB The layout viewport has a size in full CSS pixels (unaffected by zooming, hence no sub pixels). + + visualSize = size; + zoomFactor = getPinchZoomFactor( _window, { asRange: true } ); + + size = Math.round( visualSize * zoomFactor.calculated ); + + // Fix rounding errors, caused by the visual height ignoring sub-pixel fractions. If we know we are near a + // known layout viewport height, use that. + if ( !supportsSubpixelAccuracy() ) { + + ddeClientHeight = _window.document.documentElement.clientHeight; + + // In Android, the height we get from ddE.clientHeight and the one calculated from window.innerHeight + // should be the same, except for rounding errors in the calculation. So basically, we could just set + // any calculated value to the clientHeight, no matter how large the difference is. (That is, if we even + // end up here - in some versions of Chrome on Android, for instance, we have sub-pixel accuracy.) + // + // Not so in iOS. In minimal UI, the real layout viewport may be larger than the one reported by + // clientHeight, by about 60px. So we need to impose reasonable limits on what is considered to be near + // the clientHeight. + // + // - If the calculated value is within 3px of the clientHeight, we consider it to be a clear case of a + // rounding error. + // - Alternatively, the clientHeight must be between the theoretical maximum and minimum values of the + // computation, assuming maximum rounding errors at every stage. + // - If we use that range, its upper bound is capped at 30px above the clientHeight - keeping a safe + // distance from current minimal UI heights, or possible future ones. + + lBound = ( visualSize - 1 ) * zoomFactor.min; + uBound = ( visualSize + 1 ) * zoomFactor.max; + + snapToKnownHeight = ( size <= ddeClientHeight + 3 && size >= ddeClientHeight - 3 ) || + ( lBound <= ddeClientHeight && uBound >= ddeClientHeight && uBound < ddeClientHeight + 30 ); + + if ( snapToKnownHeight ) size = ddeClientHeight; + + } + } + + return size; } + /** + * Calculates the zoom factor for pinch zooming on mobile. A factor > 1 means that the page is zoomed in (content + * enlarged). + * + * The zoom factor returned here measures the size of the visual viewport with respect to the size of the layout + * viewport. Note that browsers usually calculate their zoom level with respect to the ideal viewport, not the + * layout viewport (see Peter-Paul Koch, The Mobile Web Handbook, Chapter 3: Viewports, Section "Minimum and Maximum + * Zoom"). + * + * Ignores page zoom on the desktop (returning a zoom factor of 1). For the distinction between pinch and page zoom, + * again see Chapter 3 in PPK's book. + * + * @param {Window} [_window=window] + * @param {Object} [options] + * @param {boolean} [options.asRange=false] + * @returns {number|ZoomAccuracyRange} + */ + function getPinchZoomFactor ( _window, options ) { + var ddeClientWidth, windowInnerWidth, + asRange = options && options.asRange, + factors = { + calculated: 1, + min: 1, + max: 1 + }, + skip = browserScrollbarWidth() !== 0 || !supportsWindowInnerWidth(); + + if ( !skip ) { + + _window || ( _window = window ); + ddeClientWidth = _window.document.documentElement.clientWidth; + windowInnerWidth = getWindowInnerWidth( _window ); + + // Calculate the zoom factor, assuming window.innerWidth is precise (no rounding errors). + factors.calculated = ddeClientWidth / windowInnerWidth; + + // If requested, determine the minimum and maximum value of the zoom factor in the presence of rounding errors. + if ( asRange ) { + if ( supportsSubpixelAccuracy() ) { + // No need to take rounding errors into account + factors.min = factors.max = factors.calculated; + } else { + factors.min = ddeClientWidth / ( windowInnerWidth + 1 ); + factors.max = ddeClientWidth / ( windowInnerWidth - 1 ); + } + } + + } + + return asRange ? factors : factors.calculated; + } + + /** + * Handles the argument juggling for $.windowWidth() and $.windowHeight(). Extracts the window and viewport settings + * from the arguments, applying the defaults (use global window, use visual viewport) where necessary. + * + * Examines the first two arguments. The window and the viewport setting can appear in either position, + * interchangeably. The viewport setting can be passed in as a string, or as part of an options hash, + * `{ viewport: ... }`. + * + * Recognized viewport names are "visual" and "layout" (case-insensitive). + * + * @param {Array|Arguments} args + * @returns {WindowQueryConfig} + */ + function getWindowQueryConfig( args ) { + var isWindowArg0, isOptionArg0, isOptionArg1, + + // Defaults + _window = window, + _useVisualViewport = true; + + if ( args && args.length ) { + + // Coerce to a real array + args = Array.prototype.slice.call( args ); + + // Examine the first argument. Cast strings to an options hash with a `viewport` property. + isWindowArg0 = isWindow( args[0] ); + if( !isWindowArg0 ) args[0] = castStringToViewportOption( args[0] ); + isOptionArg0 = !isWindowArg0 && args[0]; + + // Examine the second argument. Again, cast strings to an options hash with a `viewport` property. + if ( !isOptionArg0 ) args[1] = castStringToViewportOption( args[1] ); + isOptionArg1 = !isOptionArg0 && args[1]; + + // Extract window and viewport option, if available. + if ( isWindowArg0 ) { + + _window = args[0]; + if( isOptionArg1 && args[1].viewport ) _useVisualViewport = isVisualViewport( args[1].viewport ); + + } else if ( isOptionArg0 ) { + + if( args[0].viewport ) _useVisualViewport = isVisualViewport( args[0].viewport ); + if ( isWindow( args[1] ) ) _window = args[1]; + + } else if ( !args[0] && args[1] ) { + + // First argument was falsy, e.g. undefined, null. Ignore it. But process the second, non-falsy argument. + if( isOptionArg1 && args[1].viewport ) { + _useVisualViewport = isVisualViewport( args[1].viewport ); + } else if ( isWindow( args[1] ) ) { + _window = args[1]; + } + + } + } + + return { + window: _window, + useVisualViewport: _useVisualViewport, + useLayoutViewport: !_useVisualViewport + }; + } + + /** + * Checks if the argument is the name of the visual viewport. The check is case-insensitive. + * + * Expects a string. Tolerates falsy values, returning false then (argument is not naming the visual viewport). + * Throws an error for everything else. Also throws an error if the viewport name is a string but not recognized + * (typo alert). + * + * Helper for getWindowQueryConfig(). + * + * @param {string} [name] strings "visual", "layout" (case-insensitive) + * @returns {boolean} + */ + function isVisualViewport ( name ) { + var viewport = isString( name ) && name.toLowerCase(); + + if ( name && !viewport ) throw new Error( "Invalid viewport option: " + name ); + if ( viewport && viewport !== "visual" && viewport !== "layout" ) throw new Error( "Invalid viewport name: " + name ); + + return viewport === "visual"; + } + + /** + * Examines a value and casts a string to a hash with a `viewport` property (the string being its value). If the + * value is not a string, or if the string is empty, it is returned as-is. Helper for getWindowQueryConfig(). + * + * @param {*} arg + * @returns {*} + */ + function castStringToViewportOption ( arg ) { + return ( isString( arg ) && arg !== "" ) ? { viewport: arg } : arg; + } + + /** + * Checks if the browser supports window.innerWidth and window.innerHeight. + * + * The check is run on demand, rather than up front while loading the component, because the window properties can + * behave strangely in the early stages of opening a window. The component might be loaded in the document head, + * which could potentially be early enough to run into these oddities. So we wait until the first call. + * + * IE 8 does not support window.innerWidth and .innerHeight. FF has a bug which as only been fixed in FF25 (released + * 29 Oct 2013). It manifests itself in a fictional return value of 10 for these properties. See + * + * - https://developer.mozilla.org/en-US/docs/Web/API/Window.innerWidth + * - https://developer.mozilla.org/en-US/docs/Web/API/Window.innerHeight + * - https://bugzilla.mozilla.org/show_bug.cgi?id=641188 + * + * @returns {boolean} + */ + function supportsWindowInnerWidth () { + if ( _supportsWindowInnerWidth === undefined ) _supportsWindowInnerWidth = getWindowInnerWidth() > 10; + return _supportsWindowInnerWidth; + } /** * Does the actual work of $.scrollbarWidth. Protected from external modification. See $.scrollbarWidth for details. @@ -278,6 +540,165 @@ } + /** + * Returns window.innerWidth. + * + * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point + * values). + * + * @param {Window} [_window=window] + * @returns {number} + */ + function getWindowInnerWidth ( _window ) { + return getWindowInnerSize( "Width", _window ); + } + + /** + * Returns window.innerHeight. + * + * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point + * values). + * + * @param {Window} [_window=window] + * @returns {number} + */ + function getWindowInnerHeight ( _window ) { + return getWindowInnerSize( "Height", _window ); + } + + /** + * Returns window.innerWidth or window.innerHeight, depending on the dimension argument. + * + * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point + * values). + * + * @param {string} dimension must be "Width" or "Height" (upper case!) + * @param {Window} [_window=window] + * @returns {number} + */ + function getWindowInnerSize ( dimension, _window ) { + var size = ( _window || window )[ "inner" + dimension]; + + // Check for fractions. Exclude undefined return values in browsers which don't support window.innerWidth/Height. + if ( size ) checkForFractions( size ); + return size; + } + + /** + * Accepts an observed value of window.innerWidth or window.innerHeight and examines it for fractional values. + * Caches the finding if there is one. Helper for getWindowInnerWidth() and friends. + * + * See supportsSubpixelAccuracy() for more. + * + * @param {number} sizeMeasurement + */ + function checkForFractions ( sizeMeasurement ) { + + // When checking the cached value, we can't accept false as a definitive answer. We have to continue checking + // unless the cached value is `true`. + // + // See supportsSubpixelAccuracy(). + if ( !_supportsSubpixelAccuracy && isFloat( sizeMeasurement ) ) _supportsSubpixelAccuracy = true; + + } + + /** + * Returns whether or not the browser supports sub-pixel accuracy (floating-point values) for window.innerWidth and + * window.innerHeight - as far as we know yet. + * + * The browser behaviour can't be tested directly, and must be figured out by continuous observation. We have to + * monitor the return values of window.innerWidth/Height for fractions. That is done with getWindowInnerWidth etc. + * As soon as we find a fraction, we know that the browser supports floating-point accuracy. + * + * However, we can never be sure of the opposite. If we haven't encountered a fraction yet, it could simply mean + * that we are at 100% zoom, and integers have indeed been the correct return value so far. + * + * So when the method here answers with true, it is definitive. When it returns false, that just means "maybe not, + * but we don't know". And the the return value might flip to true in a future query. + * + * @returns {boolean} + */ + function supportsSubpixelAccuracy () { + return !!_supportsSubpixelAccuracy; + } + + function isWindow ( value ) { + // Identical to jQuery.isWindow() + return value != null && value.window == value; // jshint ignore:line + } + + function isString ( value ) { + // Done as in the Lodash compatibility build + return typeof value === 'string' || value && typeof value === 'object' && Object.prototype.toString.call(value) === '[object String]' || false; + } + + /** + * Returns whether or not a value is of type number. Also rejects NaN as a number. + * + * NB This is not the same as $.isNumeric because $.isNumeric( "3" ) is true while isNumber( "3" ) is false. + * + * @param {*} value + * @returns {boolean} + */ + function isNumber ( value ) { + // Done as in the Lodash compatibility build, but rejecting NaN as a number. + var isNumeric = typeof value === 'number' || value && typeof value === 'object' && Object.prototype.toString.call( value ) === '[object Number]' || false; + + // Reject NaN before returning + return isNumeric && value === +value; + } + + /** + * Returns whether or not a number is a float, ie has decimals. + * + * Requires the argument to be a number. If unsure, guard against false detections with + * `isNumber( value ) && isFloat ( value )`. + * + * For the technique, see http://stackoverflow.com/a/3885844/508355 + * + * @param {number} num + * @returns {boolean} + */ + function isFloat ( num ) { + return num === +num && num !== ( num | 0 ); // jshint ignore:line + } + + + // Let's prime $.documentWidth(), $.documentHeight() and $.scrollbarWidth() immediately after the DOM is ready. It + // is best to do it up front because the test touches the DOM, so let's get it over with before people set up + // handlers for mutation events and such. + if ( typeof $ === "function" ) { + $( function () { + if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll(); + browserScrollbarWidth(); + } ); + } + + + /** + * Custom types. + * + * For easier documentation and type inference. + */ + + /** + * @name ZoomAccuracyRange + * @type {Object} + * + * @property {number} calculated + * @property {number} min + * @property {number} max + */ + + /** + * @name WindowQueryConfig + * @type {Object} + * + * @property {Window} window + * @property {boolean} useVisualViewport + * @property {boolean} useLayoutViewport + */ + }( typeof jQuery !== "undefined" ? jQuery : typeof Zepto !== "undefined" ? Zepto : diff --git a/dist/amd/jquery.documentsize.min.js b/dist/amd/jquery.documentsize.min.js index 22e274d..9e9664b 100644 --- a/dist/amd/jquery.documentsize.min.js +++ b/dist/amd/jquery.documentsize.min.js @@ -1,8 +1,8 @@ -// jQuery.documentSize, v1.1.0 +// jQuery.documentSize, v1.2.0 // Copyright (c)2015 Michael Heim, Zeilenwechsel.de // Distributed under MIT license // http://github.com/hashchange/jquery.documentsize -!function(a,b){"use strict";"object"==typeof exports?module.exports=b(require("jquery")):"function"==typeof define&&define.amd&&define(["jquery"],b)}(this,function(jQuery){"use strict";return function(a){function b(){var a;return void 0===g&&(a=document.createElement("div"),a.style.cssText="width: 100px; height: 100px; overflow: scroll; position: absolute; top: -500px; left: -500px; margin: 0px; padding: 0px; border: none;",document.body.appendChild(a),g=a.offsetWidth-a.clientWidth,document.body.removeChild(a)),g}function c(){var a,b,c,g,i=d(),j=i&&i.contentDocument||document,k=j.body,l=j!==document;b=j.createElement("div"),b.style.cssText="width: 1px; height: 1px; position: relative; top: 0px; left: 32000px;",l||(a=e()),c=k.scrollWidth,k.appendChild(b),g=c!==k.scrollWidth,k.removeChild(b),l||f(a),h=g?"documentElement":"body",document.body.removeChild(i)}function d(){var a=document.createElement("iframe"),b=document.body;return a.style.cssText="position: absolute; top: -600px; left: -600px; width: 500px; height: 500px; margin: 0px; padding: 0px; border: none; display: block;",a.frameborder="0",b.appendChild(a),a.src="about:blank",a.contentDocument?(a.contentDocument.write(''),a):void 0}function e(){var a,b,c=document.documentElement,d=document.body,e=i?window.getComputedStyle(c,null):c.currentStyle,f=i?window.getComputedStyle(d,null):d.currentStyle,g=(e.overflowX||e.overflow||"visible").toLowerCase(),h=(f.overflowX||f.overflow||"visible").toLowerCase(),j="hidden"!==h,k="visible"===g,l={documentElement:{modified:k},body:{modified:j}};return k&&(a=c.style,l.documentElement.styleOverflowX=a.overflowX,a.overflowX="auto"),j&&(b=d.style,l.body.styleOverflowX=b.overflowX,b.overflowX="hidden"),l}function f(a){a.documentElement.modified&&(document.documentElement.style.overflowX=a.documentElement.styleOverflowX),a.body.modified&&(document.body.style.overflowX=a.body.styleOverflowX)}var g,h,i=!!window.getComputedStyle;a.documentWidth=function(a){return a||(a=document),void 0===h&&c(),a[h].scrollWidth},a.documentHeight=function(a){return a||(a=document),void 0===h&&c(),a[h].scrollHeight},a.windowWidth=function(a){return a||(a=window),b()||void 0===window.innerWidth?a.document.documentElement.clientWidth:a.innerWidth},a.windowHeight=function(a){return a||(a=window),b()||void 0===window.innerWidth?a.document.documentElement.clientHeight:a.innerHeight},a.scrollbarWidth=b,"function"==typeof a&&a(function(){void 0===h&&c(),b()})}("undefined"!=typeof jQuery?jQuery:"undefined"!=typeof Zepto?Zepto:$),jQuery.documentSize}); +!function(a,b){"use strict";"object"==typeof exports?module.exports=b(require("jquery")):"function"==typeof define&&define.amd&&define(["jquery"],b)}(this,function(jQuery){"use strict";return function(a){function b(a,b){var d,e,f,i,j,k,l=b.window,m=0!==h(),o=b.useLayoutViewport&&"Width"===a,q=m||!g()||o,r=q?l.document.documentElement["client"+a]:n(a,l);return b.useLayoutViewport&&!q&&(e=r,f=c(l,{asRange:!0}),r=Math.round(e*f.calculated),p()||(d=l.document.documentElement.clientHeight,j=(e-1)*f.min,k=(e+1)*f.max,i=d+3>=r&&r>=d-3||d>=j&&k>=d&&d+30>k,i&&(r=d))),r}function c(a,b){var c,d,e=b&&b.asRange,f={calculated:1,min:1,max:1},i=0!==h()||!g();return i||(a||(a=window),c=a.document.documentElement.clientWidth,d=m(a),f.calculated=c/d,e&&(p()?f.min=f.max=f.calculated:(f.min=c/(d+1),f.max=c/(d-1)))),e?f:f.calculated}function d(a){var b,c,d,g=window,h=!0;return a&&a.length&&(a=Array.prototype.slice.call(a),b=q(a[0]),b||(a[0]=f(a[0])),c=!b&&a[0],c||(a[1]=f(a[1])),d=!c&&a[1],b?(g=a[0],d&&a[1].viewport&&(h=e(a[1].viewport))):c?(a[0].viewport&&(h=e(a[0].viewport)),q(a[1])&&(g=a[1])):!a[0]&&a[1]&&(d&&a[1].viewport?h=e(a[1].viewport):q(a[1])&&(g=a[1]))),{window:g,useVisualViewport:h,useLayoutViewport:!h}}function e(a){var b=r(a)&&a.toLowerCase();if(a&&!b)throw new Error("Invalid viewport option: "+a);if(b&&"visual"!==b&&"layout"!==b)throw new Error("Invalid viewport name: "+a);return"visual"===b}function f(a){return r(a)&&""!==a?{viewport:a}:a}function g(){return void 0===u&&(u=m()>10),u}function h(){var a;return void 0===t&&(a=document.createElement("div"),a.style.cssText="width: 100px; height: 100px; overflow: scroll; position: absolute; top: -500px; left: -500px; margin: 0px; padding: 0px; border: none;",document.body.appendChild(a),t=a.offsetWidth-a.clientWidth,document.body.removeChild(a)),t}function i(){var a,b,c,d,e=j(),f=e&&e.contentDocument||document,g=f.body,h=f!==document;b=f.createElement("div"),b.style.cssText="width: 1px; height: 1px; position: relative; top: 0px; left: 32000px;",h||(a=k()),c=g.scrollWidth,g.appendChild(b),d=c!==g.scrollWidth,g.removeChild(b),h||l(a),w=d?"documentElement":"body",document.body.removeChild(e)}function j(){var a=document.createElement("iframe"),b=document.body;return a.style.cssText="position: absolute; top: -600px; left: -600px; width: 500px; height: 500px; margin: 0px; padding: 0px; border: none; display: block;",a.frameborder="0",b.appendChild(a),a.src="about:blank",a.contentDocument?(a.contentDocument.write(''),a):void 0}function k(){var a,b,c=document.documentElement,d=document.body,e=x?window.getComputedStyle(c,null):c.currentStyle,f=x?window.getComputedStyle(d,null):d.currentStyle,g=(e.overflowX||e.overflow||"visible").toLowerCase(),h=(f.overflowX||f.overflow||"visible").toLowerCase(),i="hidden"!==h,j="visible"===g,k={documentElement:{modified:j},body:{modified:i}};return j&&(a=c.style,k.documentElement.styleOverflowX=a.overflowX,a.overflowX="auto"),i&&(b=d.style,k.body.styleOverflowX=b.overflowX,b.overflowX="hidden"),k}function l(a){a.documentElement.modified&&(document.documentElement.style.overflowX=a.documentElement.styleOverflowX),a.body.modified&&(document.body.style.overflowX=a.body.styleOverflowX)}function m(a){return n("Width",a)}function n(a,b){var c=(b||window)["inner"+a];return c&&o(c),c}function o(a){!v&&s(a)&&(v=!0)}function p(){return!!v}function q(a){return null!=a&&a.window==a}function r(a){return"string"==typeof a||a&&"object"==typeof a&&"[object String]"===Object.prototype.toString.call(a)||!1}function s(a){return a===+a&&a!==(0|a)}var t,u,v,w,x=!!window.getComputedStyle;a.documentWidth=function(a){return a||(a=document),void 0===w&&i(),a[w].scrollWidth},a.documentHeight=function(a){return a||(a=document),void 0===w&&i(),a[w].scrollHeight},a.windowWidth=function(){var a=d(arguments);return b("Width",a)},a.windowHeight=function(){var a=d(arguments);return b("Height",a)},a.pinchZoomFactor=function(a){return c(a)},a.scrollbarWidth=h,"function"==typeof a&&a(function(){void 0===w&&i(),h()})}("undefined"!=typeof jQuery?jQuery:"undefined"!=typeof Zepto?Zepto:$),jQuery.documentSize}); //# sourceMappingURL=jquery.documentsize.min.js.map \ No newline at end of file diff --git a/dist/amd/jquery.documentsize.min.js.map b/dist/amd/jquery.documentsize.min.js.map index ddfce84..c6b956e 100644 --- a/dist/amd/jquery.documentsize.min.js.map +++ b/dist/amd/jquery.documentsize.min.js.map @@ -1 +1 @@ -{"version":3,"file":"jquery.documentsize.min.js","sources":["jquery.documentsize.js"],"names":["root","factory","exports","module","require","define","amd","this","jQuery","$","browserScrollbarWidth","testEl","undefined","_scrollbarWidth","document","createElement","style","cssText","body","appendChild","offsetWidth","clientWidth","removeChild","testDocumentScroll","initialDocumentState","_testEl","initialScrollWidth","responds","iframe","createTestIframe","_document","contentDocument","_body","inIframe","prepareGlobalDocument","scrollWidth","restoreGlobalDocument","elementNameForDocSizeQuery","frameborder","src","write","ddEStyle","bodyStyle","ddE","documentElement","ddEComputedStyles","useGetComputedStyle","window","getComputedStyle","currentStyle","bodyComputedStyles","ddEOverflowX","overflowX","overflow","toLowerCase","bodyOverflowX","modifyBody","modifyDocumentElement","initialState","modified","styleOverflowX","previousState","documentWidth","documentHeight","scrollHeight","windowWidth","_window","innerWidth","windowHeight","clientHeight","innerHeight","scrollbarWidth","Zepto","documentSize"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"jquery.documentsize.min.js","sources":["jquery.documentsize.js"],"names":["root","factory","exports","module","require","define","amd","this","jQuery","$","getWindowSize","dimension","config","ddeClientHeight","visualSize","zoomFactor","snapToKnownHeight","lBound","uBound","_window","window","scrollbarsConsumeSpace","browserScrollbarWidth","getLayoutViewportWidth","useLayoutViewport","useClientSize","supportsWindowInnerWidth","size","document","documentElement","getWindowInnerSize","getPinchZoomFactor","asRange","Math","round","calculated","supportsSubpixelAccuracy","clientHeight","min","max","options","ddeClientWidth","windowInnerWidth","factors","skip","clientWidth","getWindowInnerWidth","getWindowQueryConfig","args","isWindowArg0","isOptionArg0","isOptionArg1","_useVisualViewport","length","Array","prototype","slice","call","isWindow","castStringToViewportOption","viewport","isVisualViewport","useVisualViewport","name","isString","toLowerCase","Error","arg","undefined","_supportsWindowInnerWidth","testEl","_scrollbarWidth","createElement","style","cssText","body","appendChild","offsetWidth","removeChild","testDocumentScroll","initialDocumentState","_testEl","initialScrollWidth","responds","iframe","createTestIframe","_document","contentDocument","_body","inIframe","prepareGlobalDocument","scrollWidth","restoreGlobalDocument","elementNameForDocSizeQuery","frameborder","src","write","ddEStyle","bodyStyle","ddE","ddEComputedStyles","useGetComputedStyle","getComputedStyle","currentStyle","bodyComputedStyles","ddEOverflowX","overflowX","overflow","bodyOverflowX","modifyBody","modifyDocumentElement","initialState","modified","styleOverflowX","previousState","checkForFractions","sizeMeasurement","_supportsSubpixelAccuracy","isFloat","value","Object","toString","num","documentWidth","documentHeight","scrollHeight","windowWidth","arguments","windowHeight","pinchZoomFactor","scrollbarWidth","Zepto","documentSize"],"mappings":"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"} \ No newline at end of file diff --git a/dist/jquery.documentsize.js b/dist/jquery.documentsize.js index 8b5cda0..e2415fc 100644 --- a/dist/jquery.documentsize.js +++ b/dist/jquery.documentsize.js @@ -1,4 +1,4 @@ -// jQuery.documentSize, v1.1.0 +// jQuery.documentSize, v1.2.0 // Copyright (c)2015 Michael Heim, Zeilenwechsel.de // Distributed under MIT license // http://github.com/hashchange/jquery.documentsize @@ -18,6 +18,8 @@ // Given the purpose of the functions, they won't be called until after the opening body tag has been parsed. var _scrollbarWidth, + _supportsWindowInnerWidth, + _supportsSubpixelAccuracy, elementNameForDocSizeQuery, useGetComputedStyle = !! window.getComputedStyle; @@ -42,21 +44,47 @@ }; /** - * @param {Window} [_window=window] + * @param {string|Object|Window} [options="visual"] (a) viewport option: strings "visual", "layout" (case- + * insensitive), or a hash with a `viewport` property + * (b) the window argument + * @param {string|Object|Window} [_window=window] same as first argument; positions for window and viewport + * argument are interchangeable + * @returns {number} + */ + $.windowWidth = function ( options, _window ) { + var config = getWindowQueryConfig( arguments ); + return getWindowSize( "Width", config ); + }; + + /** + * @param {string|Object|Window} [options="visual"] (a) viewport option: strings "visual", "layout" (case- + * insensitive), or a hash with a `viewport` property + * (b) the window argument + * @param {string|Object|Window} [_window=window] same as first argument; positions for window and viewport + * argument are interchangeable * @returns {number} */ - $.windowWidth = function ( _window ) { - _window || ( _window = window ); - return ( browserScrollbarWidth() || window.innerWidth === undefined ) ? _window.document.documentElement.clientWidth : _window.innerWidth; + $.windowHeight = function ( options, _window ) { + var config = getWindowQueryConfig( arguments ); + return getWindowSize( "Height", config ); }; /** * @param {Window} [_window=window] * @returns {number} */ - $.windowHeight = function ( _window ) { - _window || ( _window = window ); - return ( browserScrollbarWidth() || window.innerWidth === undefined ) ? _window.document.documentElement.clientHeight : _window.innerHeight; + $.pinchZoomFactor = function ( _window ) { + + // Calculate the zoom factor based on the width, not the height. getPinchZoomFactor() does just that. + // + // It would be more accurate to use the longest side for the calculation, keeping the effect of rounding errors + // low (unless the browser supports sub-pixel accuracy anyway). + // + // Unfortunately, iOS does not allow that approach. Switching from normal to minimal UI is not reflected in the + // clientHeight, so the zoom factor would seem to change when the UI disappears (even though in reality, it + // doesn't). We have to use the width, irrespective of orientation. + + return getPinchZoomFactor( _window ); }; /** @@ -65,16 +93,250 @@ $.scrollbarWidth = browserScrollbarWidth; - // Let's prime $.documentWidth(), $.documentHeight() and $.scrollbarWidth() immediately after the DOM is ready. It - // is best to do it up front because the test touches the DOM, so let's get it over with before people set up - // handlers for mutation events and such. - if ( typeof $ === "function" ) { - $( function () { - if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll(); - browserScrollbarWidth(); - } ); + /** + * Returns the window width or height. Does the actual work of $.windowWidth() and $.windowHeight(). + * + * Handles minimal UI in iOS properly. Returns the size of either the visual viewport (default) or the layout + * viewport. + * + * Precision: + * + * - The maximum rounding error for the visual viewport is +/- 1px. + * - Layout viewport width is precise. + * - Layout viewport height would potentially be prone to larger rounding errors (though in practice they rarely + * seem to exceed +/- 2px). Additional logic is employed to detect and correct these errors. As a result, the + * layout viewport height is precise as well. + * + * @param {string} dimension must be "Width" or "Height" (upper case!) + * @param {WindowQueryConfig} config + * @returns {number} + */ + function getWindowSize ( dimension, config ) { + var ddeClientHeight, visualSize, zoomFactor, snapToKnownHeight, lBound, uBound, + _window = config.window, + + scrollbarsConsumeSpace = browserScrollbarWidth() !== 0, + getLayoutViewportWidth = config.useLayoutViewport && dimension === "Width", + + useClientSize = scrollbarsConsumeSpace || !supportsWindowInnerWidth() || getLayoutViewportWidth, + size = useClientSize ? _window.document.documentElement[ "client" + dimension ] : getWindowInnerSize( dimension, _window ); + + if ( config.useLayoutViewport && ! useClientSize ) { + + // Looking for the layout viewport height on mobile. Calculate it from window.innerHeight and the zoom + // factor, so as to capture the real height when the browser is in minimal UI on iOS. + // + // NB The layout viewport has a size in full CSS pixels (unaffected by zooming, hence no sub pixels). + + visualSize = size; + zoomFactor = getPinchZoomFactor( _window, { asRange: true } ); + + size = Math.round( visualSize * zoomFactor.calculated ); + + // Fix rounding errors, caused by the visual height ignoring sub-pixel fractions. If we know we are near a + // known layout viewport height, use that. + if ( !supportsSubpixelAccuracy() ) { + + ddeClientHeight = _window.document.documentElement.clientHeight; + + // In Android, the height we get from ddE.clientHeight and the one calculated from window.innerHeight + // should be the same, except for rounding errors in the calculation. So basically, we could just set + // any calculated value to the clientHeight, no matter how large the difference is. (That is, if we even + // end up here - in some versions of Chrome on Android, for instance, we have sub-pixel accuracy.) + // + // Not so in iOS. In minimal UI, the real layout viewport may be larger than the one reported by + // clientHeight, by about 60px. So we need to impose reasonable limits on what is considered to be near + // the clientHeight. + // + // - If the calculated value is within 3px of the clientHeight, we consider it to be a clear case of a + // rounding error. + // - Alternatively, the clientHeight must be between the theoretical maximum and minimum values of the + // computation, assuming maximum rounding errors at every stage. + // - If we use that range, its upper bound is capped at 30px above the clientHeight - keeping a safe + // distance from current minimal UI heights, or possible future ones. + + lBound = ( visualSize - 1 ) * zoomFactor.min; + uBound = ( visualSize + 1 ) * zoomFactor.max; + + snapToKnownHeight = ( size <= ddeClientHeight + 3 && size >= ddeClientHeight - 3 ) || + ( lBound <= ddeClientHeight && uBound >= ddeClientHeight && uBound < ddeClientHeight + 30 ); + + if ( snapToKnownHeight ) size = ddeClientHeight; + + } + } + + return size; } + /** + * Calculates the zoom factor for pinch zooming on mobile. A factor > 1 means that the page is zoomed in (content + * enlarged). + * + * The zoom factor returned here measures the size of the visual viewport with respect to the size of the layout + * viewport. Note that browsers usually calculate their zoom level with respect to the ideal viewport, not the + * layout viewport (see Peter-Paul Koch, The Mobile Web Handbook, Chapter 3: Viewports, Section "Minimum and Maximum + * Zoom"). + * + * Ignores page zoom on the desktop (returning a zoom factor of 1). For the distinction between pinch and page zoom, + * again see Chapter 3 in PPK's book. + * + * @param {Window} [_window=window] + * @param {Object} [options] + * @param {boolean} [options.asRange=false] + * @returns {number|ZoomAccuracyRange} + */ + function getPinchZoomFactor ( _window, options ) { + var ddeClientWidth, windowInnerWidth, + asRange = options && options.asRange, + factors = { + calculated: 1, + min: 1, + max: 1 + }, + skip = browserScrollbarWidth() !== 0 || !supportsWindowInnerWidth(); + + if ( !skip ) { + + _window || ( _window = window ); + ddeClientWidth = _window.document.documentElement.clientWidth; + windowInnerWidth = getWindowInnerWidth( _window ); + + // Calculate the zoom factor, assuming window.innerWidth is precise (no rounding errors). + factors.calculated = ddeClientWidth / windowInnerWidth; + + // If requested, determine the minimum and maximum value of the zoom factor in the presence of rounding errors. + if ( asRange ) { + if ( supportsSubpixelAccuracy() ) { + // No need to take rounding errors into account + factors.min = factors.max = factors.calculated; + } else { + factors.min = ddeClientWidth / ( windowInnerWidth + 1 ); + factors.max = ddeClientWidth / ( windowInnerWidth - 1 ); + } + } + + } + + return asRange ? factors : factors.calculated; + } + + /** + * Handles the argument juggling for $.windowWidth() and $.windowHeight(). Extracts the window and viewport settings + * from the arguments, applying the defaults (use global window, use visual viewport) where necessary. + * + * Examines the first two arguments. The window and the viewport setting can appear in either position, + * interchangeably. The viewport setting can be passed in as a string, or as part of an options hash, + * `{ viewport: ... }`. + * + * Recognized viewport names are "visual" and "layout" (case-insensitive). + * + * @param {Array|Arguments} args + * @returns {WindowQueryConfig} + */ + function getWindowQueryConfig( args ) { + var isWindowArg0, isOptionArg0, isOptionArg1, + + // Defaults + _window = window, + _useVisualViewport = true; + + if ( args && args.length ) { + + // Coerce to a real array + args = Array.prototype.slice.call( args ); + + // Examine the first argument. Cast strings to an options hash with a `viewport` property. + isWindowArg0 = isWindow( args[0] ); + if( !isWindowArg0 ) args[0] = castStringToViewportOption( args[0] ); + isOptionArg0 = !isWindowArg0 && args[0]; + + // Examine the second argument. Again, cast strings to an options hash with a `viewport` property. + if ( !isOptionArg0 ) args[1] = castStringToViewportOption( args[1] ); + isOptionArg1 = !isOptionArg0 && args[1]; + + // Extract window and viewport option, if available. + if ( isWindowArg0 ) { + + _window = args[0]; + if( isOptionArg1 && args[1].viewport ) _useVisualViewport = isVisualViewport( args[1].viewport ); + + } else if ( isOptionArg0 ) { + + if( args[0].viewport ) _useVisualViewport = isVisualViewport( args[0].viewport ); + if ( isWindow( args[1] ) ) _window = args[1]; + + } else if ( !args[0] && args[1] ) { + + // First argument was falsy, e.g. undefined, null. Ignore it. But process the second, non-falsy argument. + if( isOptionArg1 && args[1].viewport ) { + _useVisualViewport = isVisualViewport( args[1].viewport ); + } else if ( isWindow( args[1] ) ) { + _window = args[1]; + } + + } + } + + return { + window: _window, + useVisualViewport: _useVisualViewport, + useLayoutViewport: !_useVisualViewport + }; + } + + /** + * Checks if the argument is the name of the visual viewport. The check is case-insensitive. + * + * Expects a string. Tolerates falsy values, returning false then (argument is not naming the visual viewport). + * Throws an error for everything else. Also throws an error if the viewport name is a string but not recognized + * (typo alert). + * + * Helper for getWindowQueryConfig(). + * + * @param {string} [name] strings "visual", "layout" (case-insensitive) + * @returns {boolean} + */ + function isVisualViewport ( name ) { + var viewport = isString( name ) && name.toLowerCase(); + + if ( name && !viewport ) throw new Error( "Invalid viewport option: " + name ); + if ( viewport && viewport !== "visual" && viewport !== "layout" ) throw new Error( "Invalid viewport name: " + name ); + + return viewport === "visual"; + } + + /** + * Examines a value and casts a string to a hash with a `viewport` property (the string being its value). If the + * value is not a string, or if the string is empty, it is returned as-is. Helper for getWindowQueryConfig(). + * + * @param {*} arg + * @returns {*} + */ + function castStringToViewportOption ( arg ) { + return ( isString( arg ) && arg !== "" ) ? { viewport: arg } : arg; + } + + /** + * Checks if the browser supports window.innerWidth and window.innerHeight. + * + * The check is run on demand, rather than up front while loading the component, because the window properties can + * behave strangely in the early stages of opening a window. The component might be loaded in the document head, + * which could potentially be early enough to run into these oddities. So we wait until the first call. + * + * IE 8 does not support window.innerWidth and .innerHeight. FF has a bug which as only been fixed in FF25 (released + * 29 Oct 2013). It manifests itself in a fictional return value of 10 for these properties. See + * + * - https://developer.mozilla.org/en-US/docs/Web/API/Window.innerWidth + * - https://developer.mozilla.org/en-US/docs/Web/API/Window.innerHeight + * - https://bugzilla.mozilla.org/show_bug.cgi?id=641188 + * + * @returns {boolean} + */ + function supportsWindowInnerWidth () { + if ( _supportsWindowInnerWidth === undefined ) _supportsWindowInnerWidth = getWindowInnerWidth() > 10; + return _supportsWindowInnerWidth; + } /** * Does the actual work of $.scrollbarWidth. Protected from external modification. See $.scrollbarWidth for details. @@ -259,6 +521,165 @@ } + /** + * Returns window.innerWidth. + * + * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point + * values). + * + * @param {Window} [_window=window] + * @returns {number} + */ + function getWindowInnerWidth ( _window ) { + return getWindowInnerSize( "Width", _window ); + } + + /** + * Returns window.innerHeight. + * + * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point + * values). + * + * @param {Window} [_window=window] + * @returns {number} + */ + function getWindowInnerHeight ( _window ) { + return getWindowInnerSize( "Height", _window ); + } + + /** + * Returns window.innerWidth or window.innerHeight, depending on the dimension argument. + * + * Along the way, the return value is examined to see if the browser supports sub-pixel accuracy (floating-point + * values). + * + * @param {string} dimension must be "Width" or "Height" (upper case!) + * @param {Window} [_window=window] + * @returns {number} + */ + function getWindowInnerSize ( dimension, _window ) { + var size = ( _window || window )[ "inner" + dimension]; + + // Check for fractions. Exclude undefined return values in browsers which don't support window.innerWidth/Height. + if ( size ) checkForFractions( size ); + return size; + } + + /** + * Accepts an observed value of window.innerWidth or window.innerHeight and examines it for fractional values. + * Caches the finding if there is one. Helper for getWindowInnerWidth() and friends. + * + * See supportsSubpixelAccuracy() for more. + * + * @param {number} sizeMeasurement + */ + function checkForFractions ( sizeMeasurement ) { + + // When checking the cached value, we can't accept false as a definitive answer. We have to continue checking + // unless the cached value is `true`. + // + // See supportsSubpixelAccuracy(). + if ( !_supportsSubpixelAccuracy && isFloat( sizeMeasurement ) ) _supportsSubpixelAccuracy = true; + + } + + /** + * Returns whether or not the browser supports sub-pixel accuracy (floating-point values) for window.innerWidth and + * window.innerHeight - as far as we know yet. + * + * The browser behaviour can't be tested directly, and must be figured out by continuous observation. We have to + * monitor the return values of window.innerWidth/Height for fractions. That is done with getWindowInnerWidth etc. + * As soon as we find a fraction, we know that the browser supports floating-point accuracy. + * + * However, we can never be sure of the opposite. If we haven't encountered a fraction yet, it could simply mean + * that we are at 100% zoom, and integers have indeed been the correct return value so far. + * + * So when the method here answers with true, it is definitive. When it returns false, that just means "maybe not, + * but we don't know". And the the return value might flip to true in a future query. + * + * @returns {boolean} + */ + function supportsSubpixelAccuracy () { + return !!_supportsSubpixelAccuracy; + } + + function isWindow ( value ) { + // Identical to jQuery.isWindow() + return value != null && value.window == value; // jshint ignore:line + } + + function isString ( value ) { + // Done as in the Lodash compatibility build + return typeof value === 'string' || value && typeof value === 'object' && Object.prototype.toString.call(value) === '[object String]' || false; + } + + /** + * Returns whether or not a value is of type number. Also rejects NaN as a number. + * + * NB This is not the same as $.isNumeric because $.isNumeric( "3" ) is true while isNumber( "3" ) is false. + * + * @param {*} value + * @returns {boolean} + */ + function isNumber ( value ) { + // Done as in the Lodash compatibility build, but rejecting NaN as a number. + var isNumeric = typeof value === 'number' || value && typeof value === 'object' && Object.prototype.toString.call( value ) === '[object Number]' || false; + + // Reject NaN before returning + return isNumeric && value === +value; + } + + /** + * Returns whether or not a number is a float, ie has decimals. + * + * Requires the argument to be a number. If unsure, guard against false detections with + * `isNumber( value ) && isFloat ( value )`. + * + * For the technique, see http://stackoverflow.com/a/3885844/508355 + * + * @param {number} num + * @returns {boolean} + */ + function isFloat ( num ) { + return num === +num && num !== ( num | 0 ); // jshint ignore:line + } + + + // Let's prime $.documentWidth(), $.documentHeight() and $.scrollbarWidth() immediately after the DOM is ready. It + // is best to do it up front because the test touches the DOM, so let's get it over with before people set up + // handlers for mutation events and such. + if ( typeof $ === "function" ) { + $( function () { + if ( elementNameForDocSizeQuery === undefined ) testDocumentScroll(); + browserScrollbarWidth(); + } ); + } + + + /** + * Custom types. + * + * For easier documentation and type inference. + */ + + /** + * @name ZoomAccuracyRange + * @type {Object} + * + * @property {number} calculated + * @property {number} min + * @property {number} max + */ + + /** + * @name WindowQueryConfig + * @type {Object} + * + * @property {Window} window + * @property {boolean} useVisualViewport + * @property {boolean} useLayoutViewport + */ + }( typeof jQuery !== "undefined" ? jQuery : typeof Zepto !== "undefined" ? Zepto : diff --git a/dist/jquery.documentsize.min.js b/dist/jquery.documentsize.min.js index 3016e8a..51ff644 100644 --- a/dist/jquery.documentsize.min.js +++ b/dist/jquery.documentsize.min.js @@ -1,8 +1,8 @@ -// jQuery.documentSize, v1.1.0 +// jQuery.documentSize, v1.2.0 // Copyright (c)2015 Michael Heim, Zeilenwechsel.de // Distributed under MIT license // http://github.com/hashchange/jquery.documentsize -!function(a){"use strict";function b(){var a;return void 0===g&&(a=document.createElement("div"),a.style.cssText="width: 100px; height: 100px; overflow: scroll; position: absolute; top: -500px; left: -500px; margin: 0px; padding: 0px; border: none;",document.body.appendChild(a),g=a.offsetWidth-a.clientWidth,document.body.removeChild(a)),g}function c(){var a,b,c,g,i=d(),j=i&&i.contentDocument||document,k=j.body,l=j!==document;b=j.createElement("div"),b.style.cssText="width: 1px; height: 1px; position: relative; top: 0px; left: 32000px;",l||(a=e()),c=k.scrollWidth,k.appendChild(b),g=c!==k.scrollWidth,k.removeChild(b),l||f(a),h=g?"documentElement":"body",document.body.removeChild(i)}function d(){var a=document.createElement("iframe"),b=document.body;return a.style.cssText="position: absolute; top: -600px; left: -600px; width: 500px; height: 500px; margin: 0px; padding: 0px; border: none; display: block;",a.frameborder="0",b.appendChild(a),a.src="about:blank",a.contentDocument?(a.contentDocument.write(''),a):void 0}function e(){var a,b,c=document.documentElement,d=document.body,e=i?window.getComputedStyle(c,null):c.currentStyle,f=i?window.getComputedStyle(d,null):d.currentStyle,g=(e.overflowX||e.overflow||"visible").toLowerCase(),h=(f.overflowX||f.overflow||"visible").toLowerCase(),j="hidden"!==h,k="visible"===g,l={documentElement:{modified:k},body:{modified:j}};return k&&(a=c.style,l.documentElement.styleOverflowX=a.overflowX,a.overflowX="auto"),j&&(b=d.style,l.body.styleOverflowX=b.overflowX,b.overflowX="hidden"),l}function f(a){a.documentElement.modified&&(document.documentElement.style.overflowX=a.documentElement.styleOverflowX),a.body.modified&&(document.body.style.overflowX=a.body.styleOverflowX)}var g,h,i=!!window.getComputedStyle;a.documentWidth=function(a){return a||(a=document),void 0===h&&c(),a[h].scrollWidth},a.documentHeight=function(a){return a||(a=document),void 0===h&&c(),a[h].scrollHeight},a.windowWidth=function(a){return a||(a=window),b()||void 0===window.innerWidth?a.document.documentElement.clientWidth:a.innerWidth},a.windowHeight=function(a){return a||(a=window),b()||void 0===window.innerWidth?a.document.documentElement.clientHeight:a.innerHeight},a.scrollbarWidth=b,"function"==typeof a&&a(function(){void 0===h&&c(),b()})}("undefined"!=typeof jQuery?jQuery:"undefined"!=typeof Zepto?Zepto:$); +!function(a){"use strict";function b(a,b){var d,e,f,i,j,k,l=b.window,m=0!==h(),o=b.useLayoutViewport&&"Width"===a,q=m||!g()||o,r=q?l.document.documentElement["client"+a]:n(a,l);return b.useLayoutViewport&&!q&&(e=r,f=c(l,{asRange:!0}),r=Math.round(e*f.calculated),p()||(d=l.document.documentElement.clientHeight,j=(e-1)*f.min,k=(e+1)*f.max,i=d+3>=r&&r>=d-3||d>=j&&k>=d&&d+30>k,i&&(r=d))),r}function c(a,b){var c,d,e=b&&b.asRange,f={calculated:1,min:1,max:1},i=0!==h()||!g();return i||(a||(a=window),c=a.document.documentElement.clientWidth,d=m(a),f.calculated=c/d,e&&(p()?f.min=f.max=f.calculated:(f.min=c/(d+1),f.max=c/(d-1)))),e?f:f.calculated}function d(a){var b,c,d,g=window,h=!0;return a&&a.length&&(a=Array.prototype.slice.call(a),b=q(a[0]),b||(a[0]=f(a[0])),c=!b&&a[0],c||(a[1]=f(a[1])),d=!c&&a[1],b?(g=a[0],d&&a[1].viewport&&(h=e(a[1].viewport))):c?(a[0].viewport&&(h=e(a[0].viewport)),q(a[1])&&(g=a[1])):!a[0]&&a[1]&&(d&&a[1].viewport?h=e(a[1].viewport):q(a[1])&&(g=a[1]))),{window:g,useVisualViewport:h,useLayoutViewport:!h}}function e(a){var b=r(a)&&a.toLowerCase();if(a&&!b)throw new Error("Invalid viewport option: "+a);if(b&&"visual"!==b&&"layout"!==b)throw new Error("Invalid viewport name: "+a);return"visual"===b}function f(a){return r(a)&&""!==a?{viewport:a}:a}function g(){return void 0===u&&(u=m()>10),u}function h(){var a;return void 0===t&&(a=document.createElement("div"),a.style.cssText="width: 100px; height: 100px; overflow: scroll; position: absolute; top: -500px; left: -500px; margin: 0px; padding: 0px; border: none;",document.body.appendChild(a),t=a.offsetWidth-a.clientWidth,document.body.removeChild(a)),t}function i(){var a,b,c,d,e=j(),f=e&&e.contentDocument||document,g=f.body,h=f!==document;b=f.createElement("div"),b.style.cssText="width: 1px; height: 1px; position: relative; top: 0px; left: 32000px;",h||(a=k()),c=g.scrollWidth,g.appendChild(b),d=c!==g.scrollWidth,g.removeChild(b),h||l(a),w=d?"documentElement":"body",document.body.removeChild(e)}function j(){var a=document.createElement("iframe"),b=document.body;return a.style.cssText="position: absolute; top: -600px; left: -600px; width: 500px; height: 500px; margin: 0px; padding: 0px; border: none; display: block;",a.frameborder="0",b.appendChild(a),a.src="about:blank",a.contentDocument?(a.contentDocument.write(''),a):void 0}function k(){var a,b,c=document.documentElement,d=document.body,e=x?window.getComputedStyle(c,null):c.currentStyle,f=x?window.getComputedStyle(d,null):d.currentStyle,g=(e.overflowX||e.overflow||"visible").toLowerCase(),h=(f.overflowX||f.overflow||"visible").toLowerCase(),i="hidden"!==h,j="visible"===g,k={documentElement:{modified:j},body:{modified:i}};return j&&(a=c.style,k.documentElement.styleOverflowX=a.overflowX,a.overflowX="auto"),i&&(b=d.style,k.body.styleOverflowX=b.overflowX,b.overflowX="hidden"),k}function l(a){a.documentElement.modified&&(document.documentElement.style.overflowX=a.documentElement.styleOverflowX),a.body.modified&&(document.body.style.overflowX=a.body.styleOverflowX)}function m(a){return n("Width",a)}function n(a,b){var c=(b||window)["inner"+a];return c&&o(c),c}function o(a){!v&&s(a)&&(v=!0)}function p(){return!!v}function q(a){return null!=a&&a.window==a}function r(a){return"string"==typeof a||a&&"object"==typeof a&&"[object String]"===Object.prototype.toString.call(a)||!1}function s(a){return a===+a&&a!==(0|a)}var t,u,v,w,x=!!window.getComputedStyle;a.documentWidth=function(a){return a||(a=document),void 0===w&&i(),a[w].scrollWidth},a.documentHeight=function(a){return a||(a=document),void 0===w&&i(),a[w].scrollHeight},a.windowWidth=function(){var a=d(arguments);return b("Width",a)},a.windowHeight=function(){var a=d(arguments);return b("Height",a)},a.pinchZoomFactor=function(a){return c(a)},a.scrollbarWidth=h,"function"==typeof a&&a(function(){void 0===w&&i(),h()})}("undefined"!=typeof jQuery?jQuery:"undefined"!=typeof Zepto?Zepto:$); //# sourceMappingURL=jquery.documentsize.min.js.map \ No newline at end of file diff --git a/dist/jquery.documentsize.min.js.map b/dist/jquery.documentsize.min.js.map index d0aa59c..1d9a726 100644 --- a/dist/jquery.documentsize.min.js.map +++ b/dist/jquery.documentsize.min.js.map @@ -1 +1 @@ -{"version":3,"file":"jquery.documentsize.min.js","sources":["jquery.documentsize.js"],"names":["$","browserScrollbarWidth","testEl","undefined","_scrollbarWidth","document","createElement","style","cssText","body","appendChild","offsetWidth","clientWidth","removeChild","testDocumentScroll","initialDocumentState","_testEl","initialScrollWidth","responds","iframe","createTestIframe","_document","contentDocument","_body","inIframe","prepareGlobalDocument","scrollWidth","restoreGlobalDocument","elementNameForDocSizeQuery","frameborder","src","write","ddEStyle","bodyStyle","ddE","documentElement","ddEComputedStyles","useGetComputedStyle","window","getComputedStyle","currentStyle","bodyComputedStyles","ddEOverflowX","overflowX","overflow","toLowerCase","bodyOverflowX","modifyBody","modifyDocumentElement","initialState","modified","styleOverflowX","previousState","documentWidth","documentHeight","scrollHeight","windowWidth","_window","innerWidth","windowHeight","clientHeight","innerHeight","scrollbarWidth","jQuery","Zepto"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"jquery.documentsize.min.js","sources":["jquery.documentsize.js"],"names":["$","getWindowSize","dimension","config","ddeClientHeight","visualSize","zoomFactor","snapToKnownHeight","lBound","uBound","_window","window","scrollbarsConsumeSpace","browserScrollbarWidth","getLayoutViewportWidth","useLayoutViewport","useClientSize","supportsWindowInnerWidth","size","document","documentElement","getWindowInnerSize","getPinchZoomFactor","asRange","Math","round","calculated","supportsSubpixelAccuracy","clientHeight","min","max","options","ddeClientWidth","windowInnerWidth","factors","skip","clientWidth","getWindowInnerWidth","getWindowQueryConfig","args","isWindowArg0","isOptionArg0","isOptionArg1","_useVisualViewport","length","Array","prototype","slice","call","isWindow","castStringToViewportOption","viewport","isVisualViewport","useVisualViewport","name","isString","toLowerCase","Error","arg","undefined","_supportsWindowInnerWidth","testEl","_scrollbarWidth","createElement","style","cssText","body","appendChild","offsetWidth","removeChild","testDocumentScroll","initialDocumentState","_testEl","initialScrollWidth","responds","iframe","createTestIframe","_document","contentDocument","_body","inIframe","prepareGlobalDocument","scrollWidth","restoreGlobalDocument","elementNameForDocSizeQuery","frameborder","src","write","ddEStyle","bodyStyle","ddE","ddEComputedStyles","useGetComputedStyle","getComputedStyle","currentStyle","bodyComputedStyles","ddEOverflowX","overflowX","overflow","bodyOverflowX","modifyBody","modifyDocumentElement","initialState","modified","styleOverflowX","previousState","checkForFractions","sizeMeasurement","_supportsSubpixelAccuracy","isFloat","value","Object","toString","num","documentWidth","documentHeight","scrollHeight","windowWidth","arguments","windowHeight","pinchZoomFactor","scrollbarWidth","jQuery","Zepto"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index ddc4dac..a315405 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery.documentsize", - "version": "1.1.0", + "version": "1.2.0", "homepage": "https://github.com/hashchange/jquery.documentsize", "bugs": "https://github.com/hashchange/jquery.documentsize/issues", "repository": {