2 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
3 // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
4 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6 rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
7 rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
8 rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
9 elemdisplay = { BODY: "block" },
11 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
12 cssNormalTransform = {
17 cssExpand = [ "Top", "Right", "Bottom", "Left" ],
18 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
20 // return a css property mapped to a potentially vendor prefixed property
21 function vendorPropName( style, name ) {
23 // shortcut for names that are not vendor prefixed
24 if ( name in style ) {
28 // check for vendor prefixed names
29 var capName = name.charAt(0).toUpperCase() + name.slice(1),
31 i = cssPrefixes.length;
34 name = cssPrefixes[ i ] + capName;
35 if ( name in style ) {
43 function isHidden( elem, el ) {
44 // isHidden might be called from jQuery#filter function;
45 // in that case, element will be second argument
47 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
50 // NOTE: we've included the "window" in window.getComputedStyle
51 // because jsdom on node.js will break without it.
52 function getStyles( elem ) {
53 return window.getComputedStyle( elem, null );
56 function showHide( elements, show ) {
57 var display, elem, hidden,
60 length = elements.length;
62 for ( ; index < length; index++ ) {
63 elem = elements[ index ];
68 values[ index ] = jQuery._data( elem, "olddisplay" );
69 display = elem.style.display;
71 // Reset the inline display of this element to learn if it is
72 // being hidden by cascaded rules or not
73 if ( !values[ index ] && display === "none" ) {
74 elem.style.display = "";
77 // Set elements which have been overridden with display: none
78 // in a stylesheet to whatever the default browser style is
79 // for such an element
80 if ( elem.style.display === "" && isHidden( elem ) ) {
81 values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
85 if ( !values[ index ] ) {
86 hidden = isHidden( elem );
88 if ( display && display !== "none" || !hidden ) {
89 jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
95 // Set the display of most of the elements in a second loop
96 // to avoid the constant reflow
97 for ( index = 0; index < length; index++ ) {
98 elem = elements[ index ];
102 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
103 elem.style.display = show ? values[ index ] || "" : "none";
111 css: function( name, value ) {
112 return jQuery.access( this, function( elem, name, value ) {
117 if ( jQuery.isArray( name ) ) {
118 styles = getStyles( elem );
121 for ( ; i < len; i++ ) {
122 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
128 return value !== undefined ?
129 jQuery.style( elem, name, value ) :
130 jQuery.css( elem, name );
131 }, name, value, arguments.length > 1 );
134 return showHide( this, true );
137 return showHide( this );
139 toggle: function( state ) {
140 var bool = typeof state === "boolean";
142 return this.each(function() {
143 if ( bool ? state : isHidden( this ) ) {
144 jQuery( this ).show();
146 jQuery( this ).hide();
153 // Add in style property hooks for overriding the default
154 // behavior of getting and setting a style property
157 get: function( elem, computed ) {
159 // We should always get a number back from opacity
160 var ret = curCSS( elem, "opacity" );
161 return ret === "" ? "1" : ret;
167 // Exclude the following css properties to add px
180 // Add in properties whose names you wish to fix before
181 // setting or getting the value
183 // normalize float css property
187 // Get and set the style property on a DOM Node
188 style: function( elem, name, value, extra ) {
189 // Don't set styles on text and comment nodes
190 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
194 // Make sure that we're working with the right name
195 var ret, type, hooks,
196 origName = jQuery.camelCase( name ),
199 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
201 // gets hook for the prefixed version
202 // followed by the unprefixed version
203 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
205 // Check if we're setting a value
206 if ( value !== undefined ) {
209 // convert relative number strings (+= or -=) to relative numbers. #7345
210 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
211 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
216 // Make sure that NaN and null values aren't set. See: #7116
217 if ( value == null || type === "number" && isNaN( value ) ) {
221 // If a number was passed in, add 'px' to the (except for certain CSS properties)
222 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
226 // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
227 // but it would mean to define eight (for every problematic property) identical functions
228 if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
229 style[ name ] = "inherit";
232 // If a hook was provided, use that value, otherwise just set the specified value
233 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
234 style[ name ] = value;
238 // If a hook was provided get the non-computed value from there
239 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
243 // Otherwise just get the value from the style object
244 return style[ name ];
248 css: function( elem, name, extra, styles ) {
250 origName = jQuery.camelCase( name );
252 // Make sure that we're working with the right name
253 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
255 // gets hook for the prefixed version
256 // followed by the unprefixed version
257 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
259 // If a hook was provided get the computed value from there
260 if ( hooks && "get" in hooks ) {
261 val = hooks.get( elem, true, extra );
264 // Otherwise, if a way to get the computed value exists, use that
265 if ( val === undefined ) {
266 val = curCSS( elem, name, styles );
269 //convert "normal" to computed value
270 if ( val === "normal" && name in cssNormalTransform ) {
271 val = cssNormalTransform[ name ];
274 // Return, converting to number if forced or a qualifier was provided and val looks numeric
275 if ( extra === "" || extra ) {
276 num = parseFloat( val );
277 return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
283 curCSS = function( elem, name, _computed ) {
284 var width, minWidth, maxWidth,
285 computed = _computed || getStyles( elem ),
288 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
289 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
294 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
295 ret = jQuery.style( elem, name );
298 // Support: Chrome <17, Safari 5.1
299 // A tribute to the "awesome hack by Dean Edwards"
300 // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
301 // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
302 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
303 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
305 // Remember the original values
307 minWidth = style.minWidth;
308 maxWidth = style.maxWidth;
310 // Put in the new values to get a computed value out
311 style.minWidth = style.maxWidth = style.width = ret;
312 ret = computed.width;
314 // Revert the changed values
316 style.minWidth = minWidth;
317 style.maxWidth = maxWidth;
325 function setPositiveNumber( elem, value, subtract ) {
326 var matches = rnumsplit.exec( value );
328 // Guard against undefined "subtract", e.g., when used as in cssHooks
329 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
333 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
334 var i = extra === ( isBorderBox ? "border" : "content" ) ?
335 // If we already have the right measurement, avoid augmentation
337 // Otherwise initialize for horizontal or vertical properties
338 name === "width" ? 1 : 0,
342 for ( ; i < 4; i += 2 ) {
343 // both box models exclude margin, so add it if we want it
344 if ( extra === "margin" ) {
345 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
349 // border-box includes padding, so remove it if we want content
350 if ( extra === "content" ) {
351 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
354 // at this point, extra isn't border nor margin, so remove border
355 if ( extra !== "margin" ) {
356 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
359 // at this point, extra isn't content, so add padding
360 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
362 // at this point, extra isn't content nor padding, so add border
363 if ( extra !== "padding" ) {
364 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
372 function getWidthOrHeight( elem, name, extra ) {
374 // Start with offset property, which is equivalent to the border-box value
375 var valueIsBorderBox = true,
376 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
377 styles = getStyles( elem ),
378 isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
380 // some non-html elements return undefined for offsetWidth, so check for null/undefined
381 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
382 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
383 if ( val <= 0 || val == null ) {
384 // Fall back to computed then uncomputed css if necessary
385 val = curCSS( elem, name, styles );
386 if ( val < 0 || val == null ) {
387 val = elem.style[ name ];
390 // Computed unit is not pixels. Stop here and return.
391 if ( rnumnonpx.test(val) ) {
395 // we need the check for style in case a browser which returns unreliable values
396 // for getComputedStyle silently falls back to the reliable elem.style
397 valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
399 // Normalize "", auto, and prepare for extra
400 val = parseFloat( val ) || 0;
403 // use the active box-sizing model to add/subtract irrelevant styles
405 augmentWidthOrHeight(
408 extra || ( isBorderBox ? "border" : "content" ),
415 // Try to determine the default display value of an element
416 function css_defaultDisplay( nodeName ) {
418 display = elemdisplay[ nodeName ];
421 display = actualDisplay( nodeName, doc );
423 // If the simple way fails, read from inside an iframe
424 if ( display === "none" || !display ) {
425 // Use the already-created iframe if possible
427 jQuery("<iframe frameborder='0' width='0' height='0'/>")
428 .css( "cssText", "display:block !important" )
429 ).appendTo( doc.documentElement );
431 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
432 doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
433 doc.write("<!doctype html><html><body>");
436 display = actualDisplay( nodeName, doc );
440 // Store the correct default display
441 elemdisplay[ nodeName ] = display;
447 // Called ONLY from within css_defaultDisplay
448 function actualDisplay( name, doc ) {
449 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
450 display = jQuery.css( elem[0], "display" );
455 jQuery.each([ "height", "width" ], function( i, name ) {
456 jQuery.cssHooks[ name ] = {
457 get: function( elem, computed, extra ) {
459 // certain elements can have dimension info if we invisibly show them
460 // however, it must have a current display style that would benefit from this
461 return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
462 jQuery.swap( elem, cssShow, function() {
463 return getWidthOrHeight( elem, name, extra );
465 getWidthOrHeight( elem, name, extra );
469 set: function( elem, value, extra ) {
470 var styles = extra && getStyles( elem );
471 return setPositiveNumber( elem, value, extra ?
472 augmentWidthOrHeight(
476 jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
484 // These hooks cannot be added until DOM ready because the support test
485 // for it is not run until after DOM ready
487 if ( !jQuery.support.reliableMarginRight ) {
488 jQuery.cssHooks.marginRight = {
489 get: function( elem, computed ) {
491 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
492 // Work around by temporarily setting element display to inline-block
493 return jQuery.swap( elem, { "display": "inline-block" },
494 curCSS, [ elem, "marginRight" ] );
500 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
501 // getComputedStyle returns percent when specified for top/left/bottom/right
502 // rather than make the css module depend on the offset module, we just check for it here
503 if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
504 jQuery.each( [ "top", "left" ], function( i, prop ) {
505 jQuery.cssHooks[ prop ] = {
506 get: function( elem, computed ) {
508 computed = curCSS( elem, prop );
509 // if curCSS returns percentage, fallback to offset
510 return rnumnonpx.test( computed ) ?
511 jQuery( elem ).position()[ prop ] + "px" :
521 if ( jQuery.expr && jQuery.expr.filters ) {
522 jQuery.expr.filters.hidden = function( elem ) {
523 // Support: Opera <= 12.12
524 // Opera reports offsetWidths and offsetHeights less than zero on some elements
525 return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
528 jQuery.expr.filters.visible = function( elem ) {
529 return !jQuery.expr.filters.hidden( elem );
533 // These hooks are used by animate to expand properties
538 }, function( prefix, suffix ) {
539 jQuery.cssHooks[ prefix + suffix ] = {
540 expand: function( value ) {
544 // assumes a single number if not a string
545 parts = typeof value === "string" ? value.split(" ") : [ value ];
547 for ( ; i < 4; i++ ) {
548 expanded[ prefix + cssExpand[ i ] + suffix ] =
549 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
556 if ( !rmargin.test( prefix ) ) {
557 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;