1 import jQuery from "./core.js";
2 import access from "./core/access.js";
3 import nodeName from "./core/nodeName.js";
4 import rcssNum from "./var/rcssNum.js";
5 import isIE from "./var/isIE.js";
6 import rnumnonpx from "./css/var/rnumnonpx.js";
7 import rcustomProp from "./css/var/rcustomProp.js";
8 import cssExpand from "./css/var/cssExpand.js";
9 import isAutoPx from "./css/isAutoPx.js";
10 import cssCamelCase from "./css/cssCamelCase.js";
11 import getStyles from "./css/var/getStyles.js";
12 import swap from "./css/var/swap.js";
13 import curCSS from "./css/curCSS.js";
14 import adjustCSS from "./css/adjustCSS.js";
15 import finalPropName from "./css/finalPropName.js";
16 import support from "./css/support.js";
18 import "./core/init.js";
19 import "./core/ready.js";
20 import "./selector.js"; // contains
24 // Swappable if display is none or starts with table
25 // except "table", "table-cell", or "table-caption"
26 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
27 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
28 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
29 cssNormalTransform = {
34 function setPositiveNumber( _elem, value, subtract ) {
36 // Any relative (+/-) values have already been
37 // normalized at this point
38 var matches = rcssNum.exec( value );
41 // Guard against undefined "subtract", e.g., when used as in cssHooks
42 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
46 function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
47 var i = dimension === "width" ? 1 : 0,
52 // Adjustment may not be necessary
53 if ( box === ( isBorderBox ? "border" : "content" ) ) {
57 for ( ; i < 4; i += 2 ) {
59 // Both box models exclude margin
60 // Count margin delta separately to only add it after scroll gutter adjustment.
61 // This is needed to make negative margins work with `outerHeight( true )` (gh-3982).
62 if ( box === "margin" ) {
63 marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
66 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
70 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
72 // For "border" or "margin", add border
73 if ( box !== "padding" ) {
74 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
76 // But still keep track of it otherwise
78 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
81 // If we get here with a border-box (content + padding + border), we're seeking "content" or
82 // "padding" or "margin"
85 // For "content", subtract padding
86 if ( box === "content" ) {
87 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
90 // For "content" or "padding", subtract border
91 if ( box !== "margin" ) {
92 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
97 // Account for positive content-box scroll gutter when requested by providing computedVal
98 if ( !isBorderBox && computedVal >= 0 ) {
100 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
101 // Assuming integer scroll gutter, subtract the rest and round down
102 delta += Math.max( 0, Math.ceil(
103 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
109 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
110 // Use an explicit zero to avoid NaN (gh-3964)
114 return delta + marginDelta;
117 function getWidthOrHeight( elem, dimension, extra ) {
119 // Start with computed style
120 var styles = getStyles( elem ),
122 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
123 // Fake content-box until we know it's needed to know the true value.
124 boxSizingNeeded = isIE || extra,
125 isBorderBox = boxSizingNeeded &&
126 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
127 valueIsBorderBox = isBorderBox,
129 val = curCSS( elem, dimension, styles ),
130 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
132 // Return a confounding non-pixel value or feign ignorance, as appropriate.
133 if ( rnumnonpx.test( val ) ) {
143 // Fall back to offsetWidth/offsetHeight when value is "auto"
144 // This happens for inline elements with no explicit setting (gh-3571)
147 // Support: IE 9 - 11+
148 // Use offsetWidth/offsetHeight for when box sizing is unreliable.
149 // In those cases, the computed value can be trusted to be border-box.
150 ( isIE && isBorderBox ) ||
152 // Support: IE 10 - 11+
153 // IE misreports `getComputedStyle` of table rows with width/height
154 // set in CSS while `offset*` properties report correct values.
155 // Support: Firefox 70+
156 // Firefox includes border widths
157 // in computed dimensions for table rows. (gh-4529)
158 ( !support.reliableTrDimensions() && nodeName( elem, "tr" ) ) ) &&
160 // Make sure the element is visible & connected
161 elem.getClientRects().length ) {
163 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
165 // Where available, offsetWidth/offsetHeight approximate border box dimensions.
166 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
167 // retrieved value as a content box dimension.
168 valueIsBorderBox = offsetProp in elem;
169 if ( valueIsBorderBox ) {
170 val = elem[ offsetProp ];
174 // Normalize "" and auto
175 val = parseFloat( val ) || 0;
177 // Adjust for the element's box model
182 extra || ( isBorderBox ? "border" : "content" ),
186 // Provide the current computed size to request scroll gutter calculation (gh-3589)
194 // Add in style property hooks for overriding the default
195 // behavior of getting and setting a style property
198 // Get and set the style property on a DOM Node
199 style: function( elem, name, value, extra ) {
201 // Don't set styles on text and comment nodes
202 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
206 // Make sure that we're working with the right name
207 var ret, type, hooks,
208 origName = cssCamelCase( name ),
209 isCustomProp = rcustomProp.test( name ),
212 // Make sure that we're working with the right name. We don't
213 // want to query the value if it is a CSS custom property
214 // since they are user-defined.
215 if ( !isCustomProp ) {
216 name = finalPropName( origName );
219 // Gets hook for the prefixed version, then unprefixed version
220 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
222 // Check if we're setting a value
223 if ( value !== undefined ) {
226 // Convert "+=" or "-=" to relative numbers (trac-7345)
227 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
228 value = adjustCSS( elem, name, ret );
230 // Fixes bug trac-9237
234 // Make sure that null and NaN values aren't set (trac-7116)
235 if ( value == null || value !== value ) {
239 // If the value is a number, add `px` for certain CSS properties
240 if ( type === "number" ) {
241 value += ret && ret[ 3 ] || ( isAutoPx( origName ) ? "px" : "" );
244 // Support: IE <=9 - 11+
245 // background-* props of a cloned element affect the source element (trac-8908)
246 if ( isIE && value === "" && name.indexOf( "background" ) === 0 ) {
247 style[ name ] = "inherit";
250 // If a hook was provided, use that value, otherwise just set the specified value
251 if ( !hooks || !( "set" in hooks ) ||
252 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
254 if ( isCustomProp ) {
255 style.setProperty( name, value );
257 style[ name ] = value;
263 // If a hook was provided get the non-computed value from there
264 if ( hooks && "get" in hooks &&
265 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
270 // Otherwise just get the value from the style object
271 return style[ name ];
275 css: function( elem, name, extra, styles ) {
277 origName = cssCamelCase( name ),
278 isCustomProp = rcustomProp.test( name );
280 // Make sure that we're working with the right name. We don't
281 // want to modify the value if it is a CSS custom property
282 // since they are user-defined.
283 if ( !isCustomProp ) {
284 name = finalPropName( origName );
287 // Try prefixed name followed by the unprefixed name
288 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
290 // If a hook was provided get the computed value from there
291 if ( hooks && "get" in hooks ) {
292 val = hooks.get( elem, true, extra );
295 // Otherwise, if a way to get the computed value exists, use that
296 if ( val === undefined ) {
297 val = curCSS( elem, name, styles );
300 // Convert "normal" to computed value
301 if ( val === "normal" && name in cssNormalTransform ) {
302 val = cssNormalTransform[ name ];
305 // Make numeric if forced or a qualifier was provided and val looks numeric
306 if ( extra === "" || extra ) {
307 num = parseFloat( val );
308 return extra === true || isFinite( num ) ? num || 0 : val;
315 jQuery.each( [ "height", "width" ], function( _i, dimension ) {
316 jQuery.cssHooks[ dimension ] = {
317 get: function( elem, computed, extra ) {
320 // Certain elements can have dimension info if we invisibly show them
321 // but it must have a current display style that would benefit
322 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
324 // Support: Safari <=8 - 12+, Chrome <=73+
325 // Table columns in WebKit/Blink have non-zero offsetWidth & zero
326 // getBoundingClientRect().width unless display is changed.
328 // Running getBoundingClientRect on a disconnected node
329 // in IE throws an error.
330 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
331 swap( elem, cssShow, function() {
332 return getWidthOrHeight( elem, dimension, extra );
334 getWidthOrHeight( elem, dimension, extra );
338 set: function( elem, value, extra ) {
340 styles = getStyles( elem ),
342 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
343 isBorderBox = extra &&
344 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
355 // Convert to pixels if value adjustment is needed
356 if ( subtract && ( matches = rcssNum.exec( value ) ) &&
357 ( matches[ 3 ] || "px" ) !== "px" ) {
359 elem.style[ dimension ] = value;
360 value = jQuery.css( elem, dimension );
363 return setPositiveNumber( elem, value, subtract );
368 // These hooks are used by animate to expand properties
373 }, function( prefix, suffix ) {
374 jQuery.cssHooks[ prefix + suffix ] = {
375 expand: function( value ) {
379 // Assumes a single number if not a string
380 parts = typeof value === "string" ? value.split( " " ) : [ value ];
382 for ( ; i < 4; i++ ) {
383 expanded[ prefix + cssExpand[ i ] + suffix ] =
384 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
391 if ( prefix !== "margin" ) {
392 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
397 css: function( name, value ) {
398 return access( this, function( elem, name, value ) {
403 if ( Array.isArray( name ) ) {
404 styles = getStyles( elem );
407 for ( ; i < len; i++ ) {
408 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
414 return value !== undefined ?
415 jQuery.style( elem, name, value ) :
416 jQuery.css( elem, name );
417 }, name, value, arguments.length > 1 );
421 export default jQuery;