From 5bd074dd46afed1a66adaa01621a2fe7397d7ab5 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Tue, 10 Sep 2013 19:24:26 -0500 Subject: [PATCH] Remove offset dependency from css. Move curCSS and getStyles to their own module. --- build/tasks/build.js | 8 ++- src/css.js | 124 ++------------------------------------- src/css/curCSS.js | 110 ++++++++++++++++++++++++++++++++++ src/css/var/getStyles.js | 5 ++ src/css/var/rmargin.js | 3 + src/css/var/rnumnonpx.js | 5 ++ src/offset.js | 43 ++++++++++---- 7 files changed, 166 insertions(+), 132 deletions(-) create mode 100644 src/css/curCSS.js create mode 100644 src/css/var/getStyles.js create mode 100644 src/css/var/rmargin.js create mode 100644 src/css/var/rnumnonpx.js diff --git a/build/tasks/build.js b/build/tasks/build.js index aab7ae084..97aae4e0d 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -57,10 +57,12 @@ module.exports = function( grunt ) { } else { - // Ignore jQuery's return statement (the only necessary one) + // Ignore jQuery's exports (the only necessary one) if ( name !== "jquery" ) { contents = contents - .replace( /\s*return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" ); + .replace( /\s*return\s+[^\}]+(\}\);[^\w\}]*)$/, "$1" ) + // Multiple exports + .replace( /\s*exports\.\w+\s*=\s*\w+;/g, "" ); } // Remove define wrappers, closure ends, and empty declarations @@ -71,7 +73,7 @@ module.exports = function( grunt ) { // Remove CommonJS-style require calls // Keep an ending semicolon contents = contents - .replace( /(\s+\w+ = )?\s*require\(\s*(")[\w\.\/]+\2\s*\)([,;])/g, + .replace( /(\s+\w+ = )?\s*require\(\s*(")[\w\.\/]+\2\s*\)[\.\w]*([,;])/g, function( all, isVar, quote, commaSemicolon ) { return isVar && commaSemicolon === ";" ? ";" : ""; }); diff --git a/src/css.js b/src/css.js index 18815ca0d..93c55f574 100644 --- a/src/css.js +++ b/src/css.js @@ -6,23 +6,24 @@ var jQuery = require( "./core" ), pnum = require( "./var/pnum" ), access = require( "./core/access" ), + rmargin = require( "./css/var/rmargin" ), + rnumnonpx = require( "./css/var/rnumnonpx" ), cssExpand = require( "./css/var/cssExpand" ), isHidden = require( "./css/var/isHidden" ), + // This format is here to facilitate easy removal when building + getStyles = require( "./css/curCSS" ).getStyles, + curCSS = require( "./css/curCSS" ).curCSS, support = require( "./css/support" ), defaultDisplay = require( "./css/defaultDisplay" ), addGetHookIf = require( "./css/addGetHookIf" ), - getStyles, curCSS, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/, - rposition = /^(top|right|bottom|left)$/, // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rmargin = /^margin/, rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), - rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ), rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), cssShow = { position: "absolute", visibility: "hidden", display: "block" }, @@ -38,103 +39,6 @@ require( "./core/init" ); require( "./css/swap" ); require( "./core/ready" ); require( "./selector" ); // contains -// Optional -require( "./offset" ); - - -// NOTE: we've included the "window" in window.getComputedStyle -// because jsdom on node.js will break without it. -if ( window.getComputedStyle ) { - getStyles = function( elem ) { - return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); - }; - - curCSS = function( elem, name, _computed ) { - var width, minWidth, maxWidth, - computed = _computed || getStyles( elem ), - - // getPropertyValue is only needed for .css('filter') in IE9, see #12537 - ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, - style = elem.style; - - if ( computed ) { - - if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right - // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels - // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values - if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret; - }; -} else if ( document.documentElement.currentStyle ) { - getStyles = function( elem ) { - return elem.currentStyle; - }; - - curCSS = function( elem, name, _computed ) { - var left, rs, rsLeft, - computed = _computed || getStyles( elem ), - ret = computed ? computed[ name ] : undefined, - style = elem.style; - - // Avoid setting ret to empty string here - // so we don't default to auto - if ( ret == null && style && style[ name ] ) { - ret = style[ name ]; - } - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - // but not position css attributes, as those are proportional to the parent element instead - // and we can't measure the parent instead because it might trigger a "stacking dolls" problem - if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { - - // Remember the original values - left = style.left; - rs = elem.runtimeStyle; - rsLeft = rs && rs.left; - - // Put in the new values to get a computed value out - if ( rsLeft ) { - rs.left = elem.currentStyle.left; - } - style.left = name === "fontSize" ? "1em" : ret; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - if ( rsLeft ) { - rs.left = rsLeft; - } - } - - return ret === "" ? "auto" : ret; - }; -} // return a css property mapped to a potentially vendor prefixed property function vendorPropName( style, name ) { @@ -524,24 +428,6 @@ addGetHookIf( jQuery.cssHooks.marginRight, support.reliableMarginRight, } ); -// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 -// getComputedStyle returns percent when specified for top/left/bottom/right -// rather than make the css module depend on the offset module, we just check for it here -jQuery.each( [ "top", "left" ], function( i, prop ) { - addGetHookIf( jQuery.cssHooks[ prop ], support.pixelPosition, - function ( elem, computed ) { - if ( computed ) { - computed = curCSS( elem, prop ); - // if curCSS returns percentage, fallback to offset - return rnumnonpx.test( computed ) ? - jQuery( elem ).position()[ prop ] + "px" : - computed; - } - } - ); -}); - - // These hooks are used by animate to expand properties jQuery.each({ margin: "", diff --git a/src/css/curCSS.js b/src/css/curCSS.js new file mode 100644 index 000000000..9b010f56b --- /dev/null +++ b/src/css/curCSS.js @@ -0,0 +1,110 @@ +define([ + "exports", + "../core", + "./var/rnumnonpx", + "./var/rmargin", + "../css", // Circular, but needs jQuery.style + "../selector" // contains +], function( exports, jQuery, rnumnonpx, rmargin ) { + +var getStyles, curCSS, + rposition = /^(top|right|bottom|left)$/; + +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + style = elem.style; + + computed = computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, computed ) { + var left, rs, rsLeft, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + ret = computed ? computed[ name ] : undefined; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +exports.getStyles = getStyles; +exports.curCSS = curCSS; + +}); diff --git a/src/css/var/getStyles.js b/src/css/var/getStyles.js new file mode 100644 index 000000000..bcbd22017 --- /dev/null +++ b/src/css/var/getStyles.js @@ -0,0 +1,5 @@ +define(function() { + return function( elem ) { + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + }; +}); \ No newline at end of file diff --git a/src/css/var/rmargin.js b/src/css/var/rmargin.js new file mode 100644 index 000000000..7597cd311 --- /dev/null +++ b/src/css/var/rmargin.js @@ -0,0 +1,3 @@ +define(function() { + return (/^margin/); +}); \ No newline at end of file diff --git a/src/css/var/rnumnonpx.js b/src/css/var/rnumnonpx.js new file mode 100644 index 000000000..ec4fd615c --- /dev/null +++ b/src/css/var/rnumnonpx.js @@ -0,0 +1,5 @@ +define([ + "../../var/pnum" +], function( pnum ) { + return new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); +}); \ No newline at end of file diff --git a/src/offset.js b/src/offset.js index cfc260da2..d73166a99 100644 --- a/src/offset.js +++ b/src/offset.js @@ -1,13 +1,18 @@ -define([ - "./core", - "./var/strundefined", - "./core/access", - "./core/init", - "./css", - "./selector" // contains -], function( jQuery, strundefined, access ) { - -var docElem = window.document.documentElement; +define(function( require ) { + +var + jQuery = require( "./core" ), + strundefined = require( "./var/strundefined" ), + access = require( "./core/access" ), + rnumnonpx = require( "./css/var/rnumnonpx" ), + curCSS = require( "./css/curCSS" ).curCSS, + addGetHookIf = require( "./css/addGetHookIf" ), + support = require( "./css/support" ), + docElem = window.document.documentElement; + +require( "./core/init" ); +require( "./css" ); +require( "./selector" ); // contains /** * Gets a window from an element @@ -181,5 +186,23 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me }; }); +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// getComputedStyle returns percent when specified for top/left/bottom/right +// rather than make the css module depend on the offset module, we just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + addGetHookIf( jQuery.cssHooks[ prop ], support.pixelPosition, + function ( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +}); + return jQuery; }); -- 2.39.5