UPDATE 4.4.0.0
[phpmyadmin.git] / js / jquery / src / jquery / css.js
blob2c88f2bc3c0eb319ae463fe4d69f21a3d50b329d
1 define([
2         "./core",
3         "./var/pnum",
4         "./core/access",
5         "./css/var/rmargin",
6         "./css/var/rnumnonpx",
7         "./css/var/cssExpand",
8         "./css/var/isHidden",
9         "./css/curCSS",
10         "./css/defaultDisplay",
11         "./css/addGetHookIf",
12         "./css/support",
14         "./core/init",
15         "./css/swap",
16         "./core/ready",
17         "./selector" // contains
18 ], function( jQuery, pnum, access, rmargin, rnumnonpx, cssExpand, isHidden,
19         curCSS, defaultDisplay, addGetHookIf, support ) {
21 var
22         // BuildExclude
23         getStyles = curCSS.getStyles,
24         ralpha = /alpha\([^)]*\)/i,
25         ropacity = /opacity\s*=\s*([^)]*)/,
27         // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
28         // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
29         rdisplayswap = /^(none|table(?!-c[ea]).+)/,
30         rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
31         rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
33         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
34         cssNormalTransform = {
35                 letterSpacing: "0",
36                 fontWeight: "400"
37         },
39         cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
41 // BuildExclude
42 curCSS = curCSS.curCSS;
44 // return a css property mapped to a potentially vendor prefixed property
45 function vendorPropName( style, name ) {
47         // shortcut for names that are not vendor prefixed
48         if ( name in style ) {
49                 return name;
50         }
52         // check for vendor prefixed names
53         var capName = name.charAt(0).toUpperCase() + name.slice(1),
54                 origName = name,
55                 i = cssPrefixes.length;
57         while ( i-- ) {
58                 name = cssPrefixes[ i ] + capName;
59                 if ( name in style ) {
60                         return name;
61                 }
62         }
64         return origName;
67 function showHide( elements, show ) {
68         var display, elem, hidden,
69                 values = [],
70                 index = 0,
71                 length = elements.length;
73         for ( ; index < length; index++ ) {
74                 elem = elements[ index ];
75                 if ( !elem.style ) {
76                         continue;
77                 }
79                 values[ index ] = jQuery._data( elem, "olddisplay" );
80                 display = elem.style.display;
81                 if ( show ) {
82                         // Reset the inline display of this element to learn if it is
83                         // being hidden by cascaded rules or not
84                         if ( !values[ index ] && display === "none" ) {
85                                 elem.style.display = "";
86                         }
88                         // Set elements which have been overridden with display: none
89                         // in a stylesheet to whatever the default browser style is
90                         // for such an element
91                         if ( elem.style.display === "" && isHidden( elem ) ) {
92                                 values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
93                         }
94                 } else {
95                         hidden = isHidden( elem );
97                         if ( display && display !== "none" || !hidden ) {
98                                 jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
99                         }
100                 }
101         }
103         // Set the display of most of the elements in a second loop
104         // to avoid the constant reflow
105         for ( index = 0; index < length; index++ ) {
106                 elem = elements[ index ];
107                 if ( !elem.style ) {
108                         continue;
109                 }
110                 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
111                         elem.style.display = show ? values[ index ] || "" : "none";
112                 }
113         }
115         return elements;
118 function setPositiveNumber( elem, value, subtract ) {
119         var matches = rnumsplit.exec( value );
120         return matches ?
121                 // Guard against undefined "subtract", e.g., when used as in cssHooks
122                 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
123                 value;
126 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
127         var i = extra === ( isBorderBox ? "border" : "content" ) ?
128                 // If we already have the right measurement, avoid augmentation
129                 4 :
130                 // Otherwise initialize for horizontal or vertical properties
131                 name === "width" ? 1 : 0,
133                 val = 0;
135         for ( ; i < 4; i += 2 ) {
136                 // both box models exclude margin, so add it if we want it
137                 if ( extra === "margin" ) {
138                         val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
139                 }
141                 if ( isBorderBox ) {
142                         // border-box includes padding, so remove it if we want content
143                         if ( extra === "content" ) {
144                                 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
145                         }
147                         // at this point, extra isn't border nor margin, so remove border
148                         if ( extra !== "margin" ) {
149                                 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
150                         }
151                 } else {
152                         // at this point, extra isn't content, so add padding
153                         val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
155                         // at this point, extra isn't content nor padding, so add border
156                         if ( extra !== "padding" ) {
157                                 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
158                         }
159                 }
160         }
162         return val;
165 function getWidthOrHeight( elem, name, extra ) {
167         // Start with offset property, which is equivalent to the border-box value
168         var valueIsBorderBox = true,
169                 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
170                 styles = getStyles( elem ),
171                 isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
173         // some non-html elements return undefined for offsetWidth, so check for null/undefined
174         // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
175         // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
176         if ( val <= 0 || val == null ) {
177                 // Fall back to computed then uncomputed css if necessary
178                 val = curCSS( elem, name, styles );
179                 if ( val < 0 || val == null ) {
180                         val = elem.style[ name ];
181                 }
183                 // Computed unit is not pixels. Stop here and return.
184                 if ( rnumnonpx.test(val) ) {
185                         return val;
186                 }
188                 // we need the check for style in case a browser which returns unreliable values
189                 // for getComputedStyle silently falls back to the reliable elem.style
190                 valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
192                 // Normalize "", auto, and prepare for extra
193                 val = parseFloat( val ) || 0;
194         }
196         // use the active box-sizing model to add/subtract irrelevant styles
197         return ( val +
198                 augmentWidthOrHeight(
199                         elem,
200                         name,
201                         extra || ( isBorderBox ? "border" : "content" ),
202                         valueIsBorderBox,
203                         styles
204                 )
205         ) + "px";
208 jQuery.extend({
209         // Add in style property hooks for overriding the default
210         // behavior of getting and setting a style property
211         cssHooks: {
212                 opacity: {
213                         get: function( elem, computed ) {
214                                 if ( computed ) {
215                                         // We should always get a number back from opacity
216                                         var ret = curCSS( elem, "opacity" );
217                                         return ret === "" ? "1" : ret;
218                                 }
219                         }
220                 }
221         },
223         // Don't automatically add "px" to these possibly-unitless properties
224         cssNumber: {
225                 "columnCount": true,
226                 "fillOpacity": true,
227                 "flexGrow": true,
228                 "flexShrink": true,
229                 "fontWeight": true,
230                 "lineHeight": true,
231                 "opacity": true,
232                 "order": true,
233                 "orphans": true,
234                 "widows": true,
235                 "zIndex": true,
236                 "zoom": true
237         },
239         // Add in properties whose names you wish to fix before
240         // setting or getting the value
241         cssProps: {
242                 // normalize float css property
243                 "float": support.cssFloat ? "cssFloat" : "styleFloat"
244         },
246         // Get and set the style property on a DOM Node
247         style: function( elem, name, value, extra ) {
248                 // Don't set styles on text and comment nodes
249                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
250                         return;
251                 }
253                 // Make sure that we're working with the right name
254                 var ret, type, hooks,
255                         origName = jQuery.camelCase( name ),
256                         style = elem.style;
258                 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
260                 // gets hook for the prefixed version
261                 // followed by the unprefixed version
262                 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
264                 // Check if we're setting a value
265                 if ( value !== undefined ) {
266                         type = typeof value;
268                         // convert relative number strings (+= or -=) to relative numbers. #7345
269                         if ( type === "string" && (ret = rrelNum.exec( value )) ) {
270                                 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
271                                 // Fixes bug #9237
272                                 type = "number";
273                         }
275                         // Make sure that null and NaN values aren't set. See: #7116
276                         if ( value == null || value !== value ) {
277                                 return;
278                         }
280                         // If a number was passed in, add 'px' to the (except for certain CSS properties)
281                         if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
282                                 value += "px";
283                         }
285                         // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
286                         // but it would mean to define eight (for every problematic property) identical functions
287                         if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
288                                 style[ name ] = "inherit";
289                         }
291                         // If a hook was provided, use that value, otherwise just set the specified value
292                         if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
294                                 // Support: IE
295                                 // Swallow errors from 'invalid' CSS values (#5509)
296                                 try {
297                                         style[ name ] = value;
298                                 } catch(e) {}
299                         }
301                 } else {
302                         // If a hook was provided get the non-computed value from there
303                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
304                                 return ret;
305                         }
307                         // Otherwise just get the value from the style object
308                         return style[ name ];
309                 }
310         },
312         css: function( elem, name, extra, styles ) {
313                 var num, val, hooks,
314                         origName = jQuery.camelCase( name );
316                 // Make sure that we're working with the right name
317                 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
319                 // gets hook for the prefixed version
320                 // followed by the unprefixed version
321                 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
323                 // If a hook was provided get the computed value from there
324                 if ( hooks && "get" in hooks ) {
325                         val = hooks.get( elem, true, extra );
326                 }
328                 // Otherwise, if a way to get the computed value exists, use that
329                 if ( val === undefined ) {
330                         val = curCSS( elem, name, styles );
331                 }
333                 //convert "normal" to computed value
334                 if ( val === "normal" && name in cssNormalTransform ) {
335                         val = cssNormalTransform[ name ];
336                 }
338                 // Return, converting to number if forced or a qualifier was provided and val looks numeric
339                 if ( extra === "" || extra ) {
340                         num = parseFloat( val );
341                         return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
342                 }
343                 return val;
344         }
347 jQuery.each([ "height", "width" ], function( i, name ) {
348         jQuery.cssHooks[ name ] = {
349                 get: function( elem, computed, extra ) {
350                         if ( computed ) {
351                                 // certain elements can have dimension info if we invisibly show them
352                                 // however, it must have a current display style that would benefit from this
353                                 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
354                                         jQuery.swap( elem, cssShow, function() {
355                                                 return getWidthOrHeight( elem, name, extra );
356                                         }) :
357                                         getWidthOrHeight( elem, name, extra );
358                         }
359                 },
361                 set: function( elem, value, extra ) {
362                         var styles = extra && getStyles( elem );
363                         return setPositiveNumber( elem, value, extra ?
364                                 augmentWidthOrHeight(
365                                         elem,
366                                         name,
367                                         extra,
368                                         support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
369                                         styles
370                                 ) : 0
371                         );
372                 }
373         };
376 if ( !support.opacity ) {
377         jQuery.cssHooks.opacity = {
378                 get: function( elem, computed ) {
379                         // IE uses filters for opacity
380                         return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
381                                 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
382                                 computed ? "1" : "";
383                 },
385                 set: function( elem, value ) {
386                         var style = elem.style,
387                                 currentStyle = elem.currentStyle,
388                                 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
389                                 filter = currentStyle && currentStyle.filter || style.filter || "";
391                         // IE has trouble with opacity if it does not have layout
392                         // Force it by setting the zoom level
393                         style.zoom = 1;
395                         // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
396                         // if value === "", then remove inline opacity #12685
397                         if ( ( value >= 1 || value === "" ) &&
398                                         jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
399                                         style.removeAttribute ) {
401                                 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
402                                 // if "filter:" is present at all, clearType is disabled, we want to avoid this
403                                 // style.removeAttribute is IE Only, but so apparently is this code path...
404                                 style.removeAttribute( "filter" );
406                                 // if there is no filter style applied in a css rule or unset inline opacity, we are done
407                                 if ( value === "" || currentStyle && !currentStyle.filter ) {
408                                         return;
409                                 }
410                         }
412                         // otherwise, set new filter values
413                         style.filter = ralpha.test( filter ) ?
414                                 filter.replace( ralpha, opacity ) :
415                                 filter + " " + opacity;
416                 }
417         };
420 jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
421         function( elem, computed ) {
422                 if ( computed ) {
423                         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
424                         // Work around by temporarily setting element display to inline-block
425                         return jQuery.swap( elem, { "display": "inline-block" },
426                                 curCSS, [ elem, "marginRight" ] );
427                 }
428         }
431 // These hooks are used by animate to expand properties
432 jQuery.each({
433         margin: "",
434         padding: "",
435         border: "Width"
436 }, function( prefix, suffix ) {
437         jQuery.cssHooks[ prefix + suffix ] = {
438                 expand: function( value ) {
439                         var i = 0,
440                                 expanded = {},
442                                 // assumes a single number if not a string
443                                 parts = typeof value === "string" ? value.split(" ") : [ value ];
445                         for ( ; i < 4; i++ ) {
446                                 expanded[ prefix + cssExpand[ i ] + suffix ] =
447                                         parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
448                         }
450                         return expanded;
451                 }
452         };
454         if ( !rmargin.test( prefix ) ) {
455                 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
456         }
459 jQuery.fn.extend({
460         css: function( name, value ) {
461                 return access( this, function( elem, name, value ) {
462                         var styles, len,
463                                 map = {},
464                                 i = 0;
466                         if ( jQuery.isArray( name ) ) {
467                                 styles = getStyles( elem );
468                                 len = name.length;
470                                 for ( ; i < len; i++ ) {
471                                         map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
472                                 }
474                                 return map;
475                         }
477                         return value !== undefined ?
478                                 jQuery.style( elem, name, value ) :
479                                 jQuery.css( elem, name );
480                 }, name, value, arguments.length > 1 );
481         },
482         show: function() {
483                 return showHide( this, true );
484         },
485         hide: function() {
486                 return showHide( this );
487         },
488         toggle: function( state ) {
489                 if ( typeof state === "boolean" ) {
490                         return state ? this.show() : this.hide();
491                 }
493                 return this.each(function() {
494                         if ( isHidden( this ) ) {
495                                 jQuery( this ).show();
496                         } else {
497                                 jQuery( this ).hide();
498                         }
499                 });
500         }
503 return jQuery;