10 "./css/var/getStyles",
19 "./selector" // contains
20 ], function( jQuery, pnum, access, camelCase, document, rcssNum, rnumnonpx, cssExpand,
21 getStyles, swap, curCSS, adjustCSS, addGetHookIf, support ) {
27 // Swappable if display is none or starts with table
28 // except "table", "table-cell", or "table-caption"
29 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
30 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
32 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
33 cssNormalTransform = {
38 cssPrefixes = [ "Webkit", "Moz", "ms" ],
39 emptyStyle = document.createElement( "div" ).style;
41 // Return a css property mapped to a potentially vendor prefixed property
42 function vendorPropName( name ) {
44 // Shortcut for names that are not vendor prefixed
45 if ( name in emptyStyle ) {
49 // Check for vendor prefixed names
50 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
51 i = cssPrefixes.length;
54 name = cssPrefixes[ i ] + capName;
55 if ( name in emptyStyle ) {
61 // Return a property mapped along what jQuery.cssProps suggests or to
62 // a vendor prefixed property.
63 function finalPropName( name ) {
64 var ret = jQuery.cssProps[ name ];
66 ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
71 function setPositiveNumber( elem, value, subtract ) {
73 // Any relative (+/-) values have already been
74 // normalized at this point
75 var matches = rcssNum.exec( value );
78 // Guard against undefined "subtract", e.g., when used as in cssHooks
79 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
83 function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
84 var i = dimension === "width" ? 1 : 0,
88 // Adjustment may not be necessary
89 if ( box === ( isBorderBox ? "border" : "content" ) ) {
93 for ( ; i < 4; i += 2 ) {
95 // Both box models exclude margin
96 if ( box === "margin" ) {
97 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
100 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
101 if ( !isBorderBox ) {
104 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
106 // For "border" or "margin", add border
107 if ( box !== "padding" ) {
108 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
110 // But still keep track of it otherwise
112 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
115 // If we get here with a border-box (content + padding + border), we're seeking "content" or
116 // "padding" or "margin"
119 // For "content", subtract padding
120 if ( box === "content" ) {
121 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
124 // For "content" or "padding", subtract border
125 if ( box !== "margin" ) {
126 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
131 // Account for positive content-box scroll gutter when requested by providing computedVal
132 if ( !isBorderBox && computedVal >= 0 ) {
134 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
135 // Assuming integer scroll gutter, subtract the rest and round down
136 delta += Math.max( 0, Math.ceil(
137 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
148 function getWidthOrHeight( elem, dimension, extra ) {
150 // Start with computed style
151 var styles = getStyles( elem ),
152 val = curCSS( elem, dimension, styles ),
153 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
154 valueIsBorderBox = isBorderBox;
156 // Support: Firefox <=54
157 // Return a confounding non-pixel value or feign ignorance, as appropriate.
158 if ( rnumnonpx.test( val ) ) {
165 // Check for style in case a browser which returns unreliable values
166 // for getComputedStyle silently falls back to the reliable elem.style
167 valueIsBorderBox = valueIsBorderBox &&
168 ( support.boxSizingReliable() || val === elem.style[ dimension ] );
170 // Fall back to offsetWidth/offsetHeight when value is "auto"
171 // This happens for inline elements with no explicit setting (gh-3571)
172 // Support: Android <=4.1 - 4.3 only
173 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
174 if ( val === "auto" ||
175 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) {
177 val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];
179 // offsetWidth/offsetHeight provide border-box values
180 valueIsBorderBox = true;
183 // Normalize "" and auto
184 val = parseFloat( val ) || 0;
186 // Adjust for the element's box model
191 extra || ( isBorderBox ? "border" : "content" ),
195 // Provide the current computed size to request scroll gutter calculation (gh-3589)
203 // Add in style property hooks for overriding the default
204 // behavior of getting and setting a style property
207 get: function( elem, computed ) {
210 // We should always get a number back from opacity
211 var ret = curCSS( elem, "opacity" );
212 return ret === "" ? "1" : ret;
218 // Don't automatically add "px" to these possibly-unitless properties
220 "animationIterationCount": true,
235 // Add in properties whose names you wish to fix before
236 // setting or getting the value
239 // Get and set the style property on a DOM Node
240 style: function( elem, name, value, extra ) {
242 // Don't set styles on text and comment nodes
243 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
247 // Make sure that we're working with the right name
248 var ret, type, hooks,
249 origName = camelCase( name ),
250 isCustomProp = rcustomProp.test( name ),
253 // Make sure that we're working with the right name. We don't
254 // want to query the value if it is a CSS custom property
255 // since they are user-defined.
256 if ( !isCustomProp ) {
257 name = finalPropName( origName );
260 // Gets hook for the prefixed version, then unprefixed version
261 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
263 // Check if we're setting a value
264 if ( value !== undefined ) {
267 // Convert "+=" or "-=" to relative numbers (#7345)
268 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
269 value = adjustCSS( elem, name, ret );
275 // Make sure that null and NaN values aren't set (#7116)
276 if ( value == null || value !== value ) {
280 // If a number was passed in, add the unit (except for certain CSS properties)
281 if ( type === "number" ) {
282 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
285 // background-* props affect original clone's values
286 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
287 style[ name ] = "inherit";
290 // If a hook was provided, use that value, otherwise just set the specified value
291 if ( !hooks || !( "set" in hooks ) ||
292 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
294 if ( isCustomProp ) {
295 style.setProperty( name, value );
297 style[ name ] = value;
303 // If a hook was provided get the non-computed value from there
304 if ( hooks && "get" in hooks &&
305 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
310 // Otherwise just get the value from the style object
311 return style[ name ];
315 css: function( elem, name, extra, styles ) {
317 origName = camelCase( name ),
318 isCustomProp = rcustomProp.test( name );
320 // Make sure that we're working with the right name. We don't
321 // want to modify the value if it is a CSS custom property
322 // since they are user-defined.
323 if ( !isCustomProp ) {
324 name = finalPropName( origName );
327 // Try prefixed name followed by the unprefixed name
328 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
330 // If a hook was provided get the computed value from there
331 if ( hooks && "get" in hooks ) {
332 val = hooks.get( elem, true, extra );
335 // Otherwise, if a way to get the computed value exists, use that
336 if ( val === undefined ) {
337 val = curCSS( elem, name, styles );
340 // Convert "normal" to computed value
341 if ( val === "normal" && name in cssNormalTransform ) {
342 val = cssNormalTransform[ name ];
345 // Make numeric if forced or a qualifier was provided and val looks numeric
346 if ( extra === "" || extra ) {
347 num = parseFloat( val );
348 return extra === true || isFinite( num ) ? num || 0 : val;
355 jQuery.each( [ "height", "width" ], function( i, dimension ) {
356 jQuery.cssHooks[ dimension ] = {
357 get: function( elem, computed, extra ) {
360 // Certain elements can have dimension info if we invisibly show them
361 // but it must have a current display style that would benefit
362 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
364 // Support: Safari 8+
365 // Table columns in Safari have non-zero offsetWidth & zero
366 // getBoundingClientRect().width unless display is changed.
367 // Support: IE <=11 only
368 // Running getBoundingClientRect on a disconnected node
369 // in IE throws an error.
370 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
371 swap( elem, cssShow, function() {
372 return getWidthOrHeight( elem, dimension, extra );
374 getWidthOrHeight( elem, dimension, extra );
378 set: function( elem, value, extra ) {
380 styles = getStyles( elem ),
381 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
382 subtract = extra && boxModelAdjustment(
390 // Account for unreliable border-box dimensions by comparing offset* to computed and
391 // faking a content-box to get border and padding (gh-3699)
392 if ( isBorderBox && support.scrollboxSize() === styles.position ) {
393 subtract -= Math.ceil(
394 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
395 parseFloat( styles[ dimension ] ) -
396 boxModelAdjustment( elem, dimension, "border", false, styles ) -
401 // Convert to pixels if value adjustment is needed
402 if ( subtract && ( matches = rcssNum.exec( value ) ) &&
403 ( matches[ 3 ] || "px" ) !== "px" ) {
405 elem.style[ dimension ] = value;
406 value = jQuery.css( elem, dimension );
409 return setPositiveNumber( elem, value, subtract );
414 jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
415 function( elem, computed ) {
417 return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
418 elem.getBoundingClientRect().left -
419 swap( elem, { marginLeft: 0 }, function() {
420 return elem.getBoundingClientRect().left;
427 // These hooks are used by animate to expand properties
432 }, function( prefix, suffix ) {
433 jQuery.cssHooks[ prefix + suffix ] = {
434 expand: function( value ) {
438 // Assumes a single number if not a string
439 parts = typeof value === "string" ? value.split( " " ) : [ value ];
441 for ( ; i < 4; i++ ) {
442 expanded[ prefix + cssExpand[ i ] + suffix ] =
443 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
450 if ( prefix !== "margin" ) {
451 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
456 css: function( name, value ) {
457 return access( this, function( elem, name, value ) {
462 if ( Array.isArray( name ) ) {
463 styles = getStyles( elem );
466 for ( ; i < len; i++ ) {
467 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
473 return value !== undefined ?
474 jQuery.style( elem, name, value ) :
475 jQuery.css( elem, name );
476 }, name, value, arguments.length > 1 );