11 "./css/defaultDisplay",
14 "./data/var/dataPriv",
19 "./selector" // contains
20 ], function( jQuery, pnum, access, rmargin, rnumnonpx, cssExpand, isHidden,
21 getStyles, curCSS, defaultDisplay, addGetHookIf, support, dataPriv ) {
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 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
29 rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
31 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
32 cssNormalTransform = {
37 cssPrefixes = [ "Webkit", "Moz", "ms" ];
39 // Return a css property mapped to a potentially vendor prefixed property
40 function vendorPropName( style, name ) {
42 // Shortcut for names that are not vendor prefixed
43 if ( name in style ) {
47 // Check for vendor prefixed names
48 var capName = name[0].toUpperCase() + name.slice(1),
50 i = cssPrefixes.length;
53 name = cssPrefixes[ i ] + capName;
54 if ( name in style ) {
62 function setPositiveNumber( elem, value, subtract ) {
63 var matches = rnumsplit.exec( value );
65 // Guard against undefined "subtract", e.g., when used as in cssHooks
66 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
70 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
71 var i = extra === ( isBorderBox ? "border" : "content" ) ?
72 // If we already have the right measurement, avoid augmentation
74 // Otherwise initialize for horizontal or vertical properties
75 name === "width" ? 1 : 0,
79 for ( ; i < 4; i += 2 ) {
80 // Both box models exclude margin, so add it if we want it
81 if ( extra === "margin" ) {
82 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
86 // border-box includes padding, so remove it if we want content
87 if ( extra === "content" ) {
88 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
91 // At this point, extra isn't border nor margin, so remove border
92 if ( extra !== "margin" ) {
93 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
96 // At this point, extra isn't content, so add padding
97 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
99 // At this point, extra isn't content nor padding, so add border
100 if ( extra !== "padding" ) {
101 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
109 function getWidthOrHeight( elem, name, extra ) {
111 // Start with offset property, which is equivalent to the border-box value
112 var valueIsBorderBox = true,
113 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
114 styles = getStyles( elem ),
115 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
117 // Some non-html elements return undefined for offsetWidth, so check for null/undefined
118 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
119 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
120 if ( val <= 0 || val == null ) {
121 // Fall back to computed then uncomputed css if necessary
122 val = curCSS( elem, name, styles );
123 if ( val < 0 || val == null ) {
124 val = elem.style[ name ];
127 // Computed unit is not pixels. Stop here and return.
128 if ( rnumnonpx.test(val) ) {
132 // Check for style in case a browser which returns unreliable values
133 // for getComputedStyle silently falls back to the reliable elem.style
134 valueIsBorderBox = isBorderBox &&
135 ( support.boxSizingReliable() || val === elem.style[ name ] );
137 // Normalize "", auto, and prepare for extra
138 val = parseFloat( val ) || 0;
141 // Use the active box-sizing model to add/subtract irrelevant styles
143 augmentWidthOrHeight(
146 extra || ( isBorderBox ? "border" : "content" ),
153 function showHide( elements, show ) {
154 var display, elem, hidden,
157 length = elements.length;
159 for ( ; index < length; index++ ) {
160 elem = elements[ index ];
165 values[ index ] = dataPriv.get( elem, "olddisplay" );
166 display = elem.style.display;
168 // Reset the inline display of this element to learn if it is
169 // being hidden by cascaded rules or not
170 if ( !values[ index ] && display === "none" ) {
171 elem.style.display = "";
174 // Set elements which have been overridden with display: none
175 // in a stylesheet to whatever the default browser style is
176 // for such an element
177 if ( elem.style.display === "" && isHidden( elem ) ) {
178 values[ index ] = dataPriv.access(
181 defaultDisplay(elem.nodeName)
185 hidden = isHidden( elem );
187 if ( display !== "none" || !hidden ) {
191 hidden ? display : jQuery.css( elem, "display" )
197 // Set the display of most of the elements in a second loop
198 // to avoid the constant reflow
199 for ( index = 0; index < length; index++ ) {
200 elem = elements[ index ];
204 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
205 elem.style.display = show ? values[ index ] || "" : "none";
214 // Add in style property hooks for overriding the default
215 // behavior of getting and setting a style property
218 get: function( elem, computed ) {
221 // We should always get a number back from opacity
222 var ret = curCSS( elem, "opacity" );
223 return ret === "" ? "1" : ret;
229 // Don't automatically add "px" to these possibly-unitless properties
245 // Add in properties whose names you wish to fix before
246 // setting or getting the value
251 // Get and set the style property on a DOM Node
252 style: function( elem, name, value, extra ) {
254 // Don't set styles on text and comment nodes
255 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
259 // Make sure that we're working with the right name
260 var ret, type, hooks,
261 origName = jQuery.camelCase( name ),
264 name = jQuery.cssProps[ origName ] ||
265 ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
267 // Gets hook for the prefixed version, then unprefixed version
268 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
270 // Check if we're setting a value
271 if ( value !== undefined ) {
274 // Convert "+=" or "-=" to relative numbers (#7345)
275 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
276 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
281 // Make sure that null and NaN values aren't set (#7116)
282 if ( value == null || value !== value ) {
286 // If a number was passed in, add 'px' (except for certain CSS properties)
287 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
292 // background-* props affect original clone's values
293 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
294 style[ name ] = "inherit";
297 // If a hook was provided, use that value, otherwise just set the specified value
298 if ( !hooks || !("set" in hooks) ||
299 (value = hooks.set( elem, value, extra )) !== undefined ) {
301 style[ name ] = value;
305 // If a hook was provided get the non-computed value from there
306 if ( hooks && "get" in hooks &&
307 (ret = hooks.get( elem, false, extra )) !== undefined ) {
312 // Otherwise just get the value from the style object
313 return style[ name ];
317 css: function( elem, name, extra, styles ) {
319 origName = jQuery.camelCase( name );
321 // Make sure that we're working with the right name
322 name = jQuery.cssProps[ origName ] ||
323 ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
325 // Try prefixed name followed by the unprefixed name
326 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
328 // If a hook was provided get the computed value from there
329 if ( hooks && "get" in hooks ) {
330 val = hooks.get( elem, true, extra );
333 // Otherwise, if a way to get the computed value exists, use that
334 if ( val === undefined ) {
335 val = curCSS( elem, name, styles );
338 // Convert "normal" to computed value
339 if ( val === "normal" && name in cssNormalTransform ) {
340 val = cssNormalTransform[ name ];
343 // Make numeric if forced or a qualifier was provided and val looks numeric
344 if ( extra === "" || extra ) {
345 num = parseFloat( val );
346 return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
352 jQuery.each([ "height", "width" ], function( i, name ) {
353 jQuery.cssHooks[ name ] = {
354 get: function( elem, computed, extra ) {
357 // Certain elements can have dimension info if we invisibly show them
358 // but it must have a current display style that would benefit
359 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
360 elem.offsetWidth === 0 ?
361 jQuery.swap( elem, cssShow, function() {
362 return getWidthOrHeight( elem, name, extra );
364 getWidthOrHeight( elem, name, extra );
368 set: function( elem, value, extra ) {
369 var styles = extra && getStyles( elem );
370 return setPositiveNumber( elem, value, extra ?
371 augmentWidthOrHeight(
375 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
383 // Support: Android 2.3
384 jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
385 function( elem, computed ) {
387 return jQuery.swap( elem, { "display": "inline-block" },
388 curCSS, [ elem, "marginRight" ] );
393 // These hooks are used by animate to expand properties
398 }, function( prefix, suffix ) {
399 jQuery.cssHooks[ prefix + suffix ] = {
400 expand: function( value ) {
404 // Assumes a single number if not a string
405 parts = typeof value === "string" ? value.split(" ") : [ value ];
407 for ( ; i < 4; i++ ) {
408 expanded[ prefix + cssExpand[ i ] + suffix ] =
409 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
416 if ( !rmargin.test( prefix ) ) {
417 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
422 css: function( name, value ) {
423 return access( this, function( elem, name, value ) {
428 if ( jQuery.isArray( name ) ) {
429 styles = getStyles( elem );
432 for ( ; i < len; i++ ) {
433 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
439 return value !== undefined ?
440 jQuery.style( elem, name, value ) :
441 jQuery.css( elem, name );
442 }, name, value, arguments.length > 1 );
445 return showHide( this, true );
448 return showHide( this );
450 toggle: function( state ) {
451 if ( typeof state === "boolean" ) {
452 return state ? this.show() : this.hide();
455 return this.each(function() {
456 if ( isHidden( this ) ) {
457 jQuery( this ).show();
459 jQuery( this ).hide();