10 "./css/var/getStyles",
16 "./css/finalPropName",
20 "./selector" // contains
21 ], function( jQuery
, pnum
, access
, camelCase
, document
, rcssNum
, rnumnonpx
, cssExpand
,
22 getStyles
, swap
, curCSS
, adjustCSS
, addGetHookIf
, support
, finalPropName
) {
28 // Swappable if display is none or starts with table
29 // except "table", "table-cell", or "table-caption"
30 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
31 rdisplayswap
= /^(none|table(?!-c[ea]).+)/,
33 cssShow
= { position
: "absolute", visibility
: "hidden", display
: "block" },
34 cssNormalTransform
= {
39 function setPositiveNumber( elem
, value
, subtract
) {
41 // Any relative (+/-) values have already been
42 // normalized at this point
43 var matches
= rcssNum
.exec( value
);
46 // Guard against undefined "subtract", e.g., when used as in cssHooks
47 Math
.max( 0, matches
[ 2 ] - ( subtract
|| 0 ) ) + ( matches
[ 3 ] || "px" ) :
51 function boxModelAdjustment( elem
, dimension
, box
, isBorderBox
, styles
, computedVal
) {
52 var i
= dimension
=== "width" ? 1 : 0,
56 // Adjustment may not be necessary
57 if ( box
=== ( isBorderBox
? "border" : "content" ) ) {
61 for ( ; i
< 4; i
+= 2 ) {
63 // Both box models exclude margin
64 if ( box
=== "margin" ) {
65 delta
+= jQuery
.css( elem
, box
+ cssExpand
[ i
], true, styles
);
68 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
72 delta
+= jQuery
.css( elem
, "padding" + cssExpand
[ i
], true, styles
);
74 // For "border" or "margin", add border
75 if ( box
!== "padding" ) {
76 delta
+= jQuery
.css( elem
, "border" + cssExpand
[ i
] + "Width", true, styles
);
78 // But still keep track of it otherwise
80 extra
+= jQuery
.css( elem
, "border" + cssExpand
[ i
] + "Width", true, styles
);
83 // If we get here with a border-box (content + padding + border), we're seeking "content" or
84 // "padding" or "margin"
87 // For "content", subtract padding
88 if ( box
=== "content" ) {
89 delta
-= jQuery
.css( elem
, "padding" + cssExpand
[ i
], true, styles
);
92 // For "content" or "padding", subtract border
93 if ( box
!== "margin" ) {
94 delta
-= jQuery
.css( elem
, "border" + cssExpand
[ i
] + "Width", true, styles
);
99 // Account for positive content-box scroll gutter when requested by providing computedVal
100 if ( !isBorderBox
&& computedVal
>= 0 ) {
102 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
103 // Assuming integer scroll gutter, subtract the rest and round down
104 delta
+= Math
.max( 0, Math
.ceil(
105 elem
[ "offset" + dimension
[ 0 ].toUpperCase() + dimension
.slice( 1 ) ] -
116 function getWidthOrHeight( elem
, dimension
, extra
) {
118 // Start with computed style
119 var styles
= getStyles( elem
),
120 val
= curCSS( elem
, dimension
, styles
),
121 isBorderBox
= jQuery
.css( elem
, "boxSizing", false, styles
) === "border-box",
122 valueIsBorderBox
= isBorderBox
;
124 // Support: Firefox <=54
125 // Return a confounding non-pixel value or feign ignorance, as appropriate.
126 if ( rnumnonpx
.test( val
) ) {
133 // Check for style in case a browser which returns unreliable values
134 // for getComputedStyle silently falls back to the reliable elem.style
135 valueIsBorderBox
= valueIsBorderBox
&&
136 ( support
.boxSizingReliable() || val
=== elem
.style
[ dimension
] );
138 // Fall back to offsetWidth/offsetHeight when value is "auto"
139 // This happens for inline elements with no explicit setting (gh-3571)
140 // Support: Android <=4.1 - 4.3 only
141 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
142 if ( val
=== "auto" ||
143 !parseFloat( val
) && jQuery
.css( elem
, "display", false, styles
) === "inline" ) {
145 val
= elem
[ "offset" + dimension
[ 0 ].toUpperCase() + dimension
.slice( 1 ) ];
147 // offsetWidth/offsetHeight provide border-box values
148 valueIsBorderBox
= true;
151 // Normalize "" and auto
152 val
= parseFloat( val
) || 0;
154 // Adjust for the element's box model
159 extra
|| ( isBorderBox
? "border" : "content" ),
163 // Provide the current computed size to request scroll gutter calculation (gh-3589)
171 // Add in style property hooks for overriding the default
172 // behavior of getting and setting a style property
175 get: function( elem
, computed
) {
178 // We should always get a number back from opacity
179 var ret
= curCSS( elem
, "opacity" );
180 return ret
=== "" ? "1" : ret
;
186 // Don't automatically add "px" to these possibly-unitless properties
188 "animationIterationCount": true,
203 // Add in properties whose names you wish to fix before
204 // setting or getting the value
207 // Get and set the style property on a DOM Node
208 style: function( elem
, name
, value
, extra
) {
210 // Don't set styles on text and comment nodes
211 if ( !elem
|| elem
.nodeType
=== 3 || elem
.nodeType
=== 8 || !elem
.style
) {
215 // Make sure that we're working with the right name
216 var ret
, type
, hooks
,
217 origName
= camelCase( name
),
218 isCustomProp
= rcustomProp
.test( name
),
221 // Make sure that we're working with the right name. We don't
222 // want to query the value if it is a CSS custom property
223 // since they are user-defined.
224 if ( !isCustomProp
) {
225 name
= finalPropName( origName
);
228 // Gets hook for the prefixed version, then unprefixed version
229 hooks
= jQuery
.cssHooks
[ name
] || jQuery
.cssHooks
[ origName
];
231 // Check if we're setting a value
232 if ( value
!== undefined ) {
235 // Convert "+=" or "-=" to relative numbers (#7345)
236 if ( type
=== "string" && ( ret
= rcssNum
.exec( value
) ) && ret
[ 1 ] ) {
237 value
= adjustCSS( elem
, name
, ret
);
243 // Make sure that null and NaN values aren't set (#7116)
244 if ( value
== null || value
!== value
) {
248 // If a number was passed in, add the unit (except for certain CSS properties)
249 if ( type
=== "number" ) {
250 value
+= ret
&& ret
[ 3 ] || ( jQuery
.cssNumber
[ origName
] ? "" : "px" );
253 // background-* props affect original clone's values
254 if ( !support
.clearCloneStyle
&& value
=== "" && name
.indexOf( "background" ) === 0 ) {
255 style
[ name
] = "inherit";
258 // If a hook was provided, use that value, otherwise just set the specified value
259 if ( !hooks
|| !( "set" in hooks
) ||
260 ( value
= hooks
.set( elem
, value
, extra
) ) !== undefined ) {
262 if ( isCustomProp
) {
263 style
.setProperty( name
, value
);
265 style
[ name
] = value
;
271 // If a hook was provided get the non-computed value from there
272 if ( hooks
&& "get" in hooks
&&
273 ( ret
= hooks
.get( elem
, false, extra
) ) !== undefined ) {
278 // Otherwise just get the value from the style object
279 return style
[ name
];
283 css: function( elem
, name
, extra
, styles
) {
285 origName
= camelCase( name
),
286 isCustomProp
= rcustomProp
.test( name
);
288 // Make sure that we're working with the right name. We don't
289 // want to modify the value if it is a CSS custom property
290 // since they are user-defined.
291 if ( !isCustomProp
) {
292 name
= finalPropName( origName
);
295 // Try prefixed name followed by the unprefixed name
296 hooks
= jQuery
.cssHooks
[ name
] || jQuery
.cssHooks
[ origName
];
298 // If a hook was provided get the computed value from there
299 if ( hooks
&& "get" in hooks
) {
300 val
= hooks
.get( elem
, true, extra
);
303 // Otherwise, if a way to get the computed value exists, use that
304 if ( val
=== undefined ) {
305 val
= curCSS( elem
, name
, styles
);
308 // Convert "normal" to computed value
309 if ( val
=== "normal" && name
in cssNormalTransform
) {
310 val
= cssNormalTransform
[ name
];
313 // Make numeric if forced or a qualifier was provided and val looks numeric
314 if ( extra
=== "" || extra
) {
315 num
= parseFloat( val
);
316 return extra
=== true || isFinite( num
) ? num
|| 0 : val
;
323 jQuery
.each( [ "height", "width" ], function( i
, dimension
) {
324 jQuery
.cssHooks
[ dimension
] = {
325 get: function( elem
, computed
, extra
) {
328 // Certain elements can have dimension info if we invisibly show them
329 // but it must have a current display style that would benefit
330 return rdisplayswap
.test( jQuery
.css( elem
, "display" ) ) &&
332 // Support: Safari 8+
333 // Table columns in Safari have non-zero offsetWidth & zero
334 // getBoundingClientRect().width unless display is changed.
335 // Support: IE <=11 only
336 // Running getBoundingClientRect on a disconnected node
337 // in IE throws an error.
338 ( !elem
.getClientRects().length
|| !elem
.getBoundingClientRect().width
) ?
339 swap( elem
, cssShow
, function() {
340 return getWidthOrHeight( elem
, dimension
, extra
);
342 getWidthOrHeight( elem
, dimension
, extra
);
346 set: function( elem
, value
, extra
) {
348 styles
= getStyles( elem
),
349 scrollBoxSize
= support
.scrollboxSize() === styles
.position
,
351 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
352 boxSizingNeeded
= scrollBoxSize
|| extra
,
353 isBorderBox
= boxSizingNeeded
&&
354 jQuery
.css( elem
, "boxSizing", false, styles
) === "border-box",
355 subtract
= extra
&& boxModelAdjustment(
363 // Account for unreliable border-box dimensions by comparing offset* to computed and
364 // faking a content-box to get border and padding (gh-3699)
365 if ( isBorderBox
&& scrollBoxSize
) {
366 subtract
-= Math
.ceil(
367 elem
[ "offset" + dimension
[ 0 ].toUpperCase() + dimension
.slice( 1 ) ] -
368 parseFloat( styles
[ dimension
] ) -
369 boxModelAdjustment( elem
, dimension
, "border", false, styles
) -
374 // Convert to pixels if value adjustment is needed
375 if ( subtract
&& ( matches
= rcssNum
.exec( value
) ) &&
376 ( matches
[ 3 ] || "px" ) !== "px" ) {
378 elem
.style
[ dimension
] = value
;
379 value
= jQuery
.css( elem
, dimension
);
382 return setPositiveNumber( elem
, value
, subtract
);
387 jQuery
.cssHooks
.marginLeft
= addGetHookIf( support
.reliableMarginLeft
,
388 function( elem
, computed
) {
390 return ( parseFloat( curCSS( elem
, "marginLeft" ) ) ||
391 elem
.getBoundingClientRect().left
-
392 swap( elem
, { marginLeft
: 0 }, function() {
393 return elem
.getBoundingClientRect().left
;
400 // These hooks are used by animate to expand properties
405 }, function( prefix
, suffix
) {
406 jQuery
.cssHooks
[ prefix
+ suffix
] = {
407 expand: function( value
) {
411 // Assumes a single number if not a string
412 parts
= typeof value
=== "string" ? value
.split( " " ) : [ value
];
414 for ( ; i
< 4; i
++ ) {
415 expanded
[ prefix
+ cssExpand
[ i
] + suffix
] =
416 parts
[ i
] || parts
[ i
- 2 ] || parts
[ 0 ];
423 if ( prefix
!== "margin" ) {
424 jQuery
.cssHooks
[ prefix
+ suffix
].set = setPositiveNumber
;
429 css: function( name
, value
) {
430 return access( this, function( elem
, name
, value
) {
435 if ( Array
.isArray( name
) ) {
436 styles
= getStyles( elem
);
439 for ( ; i
< len
; i
++ ) {
440 map
[ name
[ i
] ] = jQuery
.css( elem
, name
[ i
], false, styles
);
446 return value
!== undefined ?
447 jQuery
.style( elem
, name
, value
) :
448 jQuery
.css( elem
, name
);
449 }, name
, value
, arguments
.length
> 1 );