You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

503 lines
13 KiB

  1. define( [
  2. "./core",
  3. "./var/pnum",
  4. "./core/access",
  5. "./css/var/rmargin",
  6. "./var/document",
  7. "./var/rcssNum",
  8. "./css/var/rnumnonpx",
  9. "./css/var/cssExpand",
  10. "./css/var/isHidden",
  11. "./css/var/getStyles",
  12. "./css/var/swap",
  13. "./css/curCSS",
  14. "./css/adjustCSS",
  15. "./css/defaultDisplay",
  16. "./css/addGetHookIf",
  17. "./css/support",
  18. "./data/var/dataPriv",
  19. "./core/init",
  20. "./core/ready",
  21. "./selector" // contains
  22. ], function( jQuery, pnum, access, rmargin, document, rcssNum, rnumnonpx, cssExpand, isHidden,
  23. getStyles, swap, curCSS, adjustCSS, defaultDisplay, addGetHookIf, support, dataPriv ) {
  24. var
  25. // Swappable if display is none or starts with table
  26. // except "table", "table-cell", or "table-caption"
  27. // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  28. rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  29. cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  30. cssNormalTransform = {
  31. letterSpacing: "0",
  32. fontWeight: "400"
  33. },
  34. cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
  35. emptyStyle = document.createElement( "div" ).style;
  36. // Return a css property mapped to a potentially vendor prefixed property
  37. function vendorPropName( name ) {
  38. // Shortcut for names that are not vendor prefixed
  39. if ( name in emptyStyle ) {
  40. return name;
  41. }
  42. // Check for vendor prefixed names
  43. var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
  44. i = cssPrefixes.length;
  45. while ( i-- ) {
  46. name = cssPrefixes[ i ] + capName;
  47. if ( name in emptyStyle ) {
  48. return name;
  49. }
  50. }
  51. }
  52. function setPositiveNumber( elem, value, subtract ) {
  53. // Any relative (+/-) values have already been
  54. // normalized at this point
  55. var matches = rcssNum.exec( value );
  56. return matches ?
  57. // Guard against undefined "subtract", e.g., when used as in cssHooks
  58. Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
  59. value;
  60. }
  61. function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  62. var i = extra === ( isBorderBox ? "border" : "content" ) ?
  63. // If we already have the right measurement, avoid augmentation
  64. 4 :
  65. // Otherwise initialize for horizontal or vertical properties
  66. name === "width" ? 1 : 0,
  67. val = 0;
  68. for ( ; i < 4; i += 2 ) {
  69. // Both box models exclude margin, so add it if we want it
  70. if ( extra === "margin" ) {
  71. val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  72. }
  73. if ( isBorderBox ) {
  74. // border-box includes padding, so remove it if we want content
  75. if ( extra === "content" ) {
  76. val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  77. }
  78. // At this point, extra isn't border nor margin, so remove border
  79. if ( extra !== "margin" ) {
  80. val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  81. }
  82. } else {
  83. // At this point, extra isn't content, so add padding
  84. val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  85. // At this point, extra isn't content nor padding, so add border
  86. if ( extra !== "padding" ) {
  87. val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  88. }
  89. }
  90. }
  91. return val;
  92. }
  93. function getWidthOrHeight( elem, name, extra ) {
  94. // Start with offset property, which is equivalent to the border-box value
  95. var valueIsBorderBox = true,
  96. val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  97. styles = getStyles( elem ),
  98. isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  99. // Some non-html elements return undefined for offsetWidth, so check for null/undefined
  100. // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  101. // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  102. if ( val <= 0 || val == null ) {
  103. // Fall back to computed then uncomputed css if necessary
  104. val = curCSS( elem, name, styles );
  105. if ( val < 0 || val == null ) {
  106. val = elem.style[ name ];
  107. }
  108. // Computed unit is not pixels. Stop here and return.
  109. if ( rnumnonpx.test( val ) ) {
  110. return val;
  111. }
  112. // Check for style in case a browser which returns unreliable values
  113. // for getComputedStyle silently falls back to the reliable elem.style
  114. valueIsBorderBox = isBorderBox &&
  115. ( support.boxSizingReliable() || val === elem.style[ name ] );
  116. // Normalize "", auto, and prepare for extra
  117. val = parseFloat( val ) || 0;
  118. }
  119. // Use the active box-sizing model to add/subtract irrelevant styles
  120. return ( val +
  121. augmentWidthOrHeight(
  122. elem,
  123. name,
  124. extra || ( isBorderBox ? "border" : "content" ),
  125. valueIsBorderBox,
  126. styles
  127. )
  128. ) + "px";
  129. }
  130. function showHide( elements, show ) {
  131. var display, elem, hidden,
  132. values = [],
  133. index = 0,
  134. length = elements.length;
  135. for ( ; index < length; index++ ) {
  136. elem = elements[ index ];
  137. if ( !elem.style ) {
  138. continue;
  139. }
  140. values[ index ] = dataPriv.get( elem, "olddisplay" );
  141. display = elem.style.display;
  142. if ( show ) {
  143. // Reset the inline display of this element to learn if it is
  144. // being hidden by cascaded rules or not
  145. if ( !values[ index ] && display === "none" ) {
  146. elem.style.display = "";
  147. }
  148. // Set elements which have been overridden with display: none
  149. // in a stylesheet to whatever the default browser style is
  150. // for such an element
  151. if ( elem.style.display === "" && isHidden( elem ) ) {
  152. values[ index ] = dataPriv.access(
  153. elem,
  154. "olddisplay",
  155. defaultDisplay( elem.nodeName )
  156. );
  157. }
  158. } else {
  159. hidden = isHidden( elem );
  160. if ( display !== "none" || !hidden ) {
  161. dataPriv.set(
  162. elem,
  163. "olddisplay",
  164. hidden ? display : jQuery.css( elem, "display" )
  165. );
  166. }
  167. }
  168. }
  169. // Set the display of most of the elements in a second loop
  170. // to avoid the constant reflow
  171. for ( index = 0; index < length; index++ ) {
  172. elem = elements[ index ];
  173. if ( !elem.style ) {
  174. continue;
  175. }
  176. if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  177. elem.style.display = show ? values[ index ] || "" : "none";
  178. }
  179. }
  180. return elements;
  181. }
  182. jQuery.extend( {
  183. // Add in style property hooks for overriding the default
  184. // behavior of getting and setting a style property
  185. cssHooks: {
  186. opacity: {
  187. get: function( elem, computed ) {
  188. if ( computed ) {
  189. // We should always get a number back from opacity
  190. var ret = curCSS( elem, "opacity" );
  191. return ret === "" ? "1" : ret;
  192. }
  193. }
  194. }
  195. },
  196. // Don't automatically add "px" to these possibly-unitless properties
  197. cssNumber: {
  198. "animationIterationCount": true,
  199. "columnCount": true,
  200. "fillOpacity": true,
  201. "flexGrow": true,
  202. "flexShrink": true,
  203. "fontWeight": true,
  204. "lineHeight": true,
  205. "opacity": true,
  206. "order": true,
  207. "orphans": true,
  208. "widows": true,
  209. "zIndex": true,
  210. "zoom": true
  211. },
  212. // Add in properties whose names you wish to fix before
  213. // setting or getting the value
  214. cssProps: {
  215. "float": "cssFloat"
  216. },
  217. // Get and set the style property on a DOM Node
  218. style: function( elem, name, value, extra ) {
  219. // Don't set styles on text and comment nodes
  220. if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  221. return;
  222. }
  223. // Make sure that we're working with the right name
  224. var ret, type, hooks,
  225. origName = jQuery.camelCase( name ),
  226. style = elem.style;
  227. name = jQuery.cssProps[ origName ] ||
  228. ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
  229. // Gets hook for the prefixed version, then unprefixed version
  230. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  231. // Check if we're setting a value
  232. if ( value !== undefined ) {
  233. type = typeof value;
  234. // Convert "+=" or "-=" to relative numbers (#7345)
  235. if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
  236. value = adjustCSS( elem, name, ret );
  237. // Fixes bug #9237
  238. type = "number";
  239. }
  240. // Make sure that null and NaN values aren't set (#7116)
  241. if ( value == null || value !== value ) {
  242. return;
  243. }
  244. // If a number was passed in, add the unit (except for certain CSS properties)
  245. if ( type === "number" ) {
  246. value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
  247. }
  248. // Support: IE9-11+
  249. // background-* props affect original clone's values
  250. if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
  251. style[ name ] = "inherit";
  252. }
  253. // If a hook was provided, use that value, otherwise just set the specified value
  254. if ( !hooks || !( "set" in hooks ) ||
  255. ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
  256. style[ name ] = value;
  257. }
  258. } else {
  259. // If a hook was provided get the non-computed value from there
  260. if ( hooks && "get" in hooks &&
  261. ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
  262. return ret;
  263. }
  264. // Otherwise just get the value from the style object
  265. return style[ name ];
  266. }
  267. },
  268. css: function( elem, name, extra, styles ) {
  269. var val, num, hooks,
  270. origName = jQuery.camelCase( name );
  271. // Make sure that we're working with the right name
  272. name = jQuery.cssProps[ origName ] ||
  273. ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
  274. // Try prefixed name followed by the unprefixed name
  275. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  276. // If a hook was provided get the computed value from there
  277. if ( hooks && "get" in hooks ) {
  278. val = hooks.get( elem, true, extra );
  279. }
  280. // Otherwise, if a way to get the computed value exists, use that
  281. if ( val === undefined ) {
  282. val = curCSS( elem, name, styles );
  283. }
  284. // Convert "normal" to computed value
  285. if ( val === "normal" && name in cssNormalTransform ) {
  286. val = cssNormalTransform[ name ];
  287. }
  288. // Make numeric if forced or a qualifier was provided and val looks numeric
  289. if ( extra === "" || extra ) {
  290. num = parseFloat( val );
  291. return extra === true || isFinite( num ) ? num || 0 : val;
  292. }
  293. return val;
  294. }
  295. } );
  296. jQuery.each( [ "height", "width" ], function( i, name ) {
  297. jQuery.cssHooks[ name ] = {
  298. get: function( elem, computed, extra ) {
  299. if ( computed ) {
  300. // Certain elements can have dimension info if we invisibly show them
  301. // but it must have a current display style that would benefit
  302. return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
  303. elem.offsetWidth === 0 ?
  304. swap( elem, cssShow, function() {
  305. return getWidthOrHeight( elem, name, extra );
  306. } ) :
  307. getWidthOrHeight( elem, name, extra );
  308. }
  309. },
  310. set: function( elem, value, extra ) {
  311. var matches,
  312. styles = extra && getStyles( elem ),
  313. subtract = extra && augmentWidthOrHeight(
  314. elem,
  315. name,
  316. extra,
  317. jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  318. styles
  319. );
  320. // Convert to pixels if value adjustment is needed
  321. if ( subtract && ( matches = rcssNum.exec( value ) ) &&
  322. ( matches[ 3 ] || "px" ) !== "px" ) {
  323. elem.style[ name ] = value;
  324. value = jQuery.css( elem, name );
  325. }
  326. return setPositiveNumber( elem, value, subtract );
  327. }
  328. };
  329. } );
  330. jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
  331. function( elem, computed ) {
  332. if ( computed ) {
  333. return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
  334. elem.getBoundingClientRect().left -
  335. swap( elem, { marginLeft: 0 }, function() {
  336. return elem.getBoundingClientRect().left;
  337. } )
  338. ) + "px";
  339. }
  340. }
  341. );
  342. // Support: Android 2.3
  343. jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
  344. function( elem, computed ) {
  345. if ( computed ) {
  346. return swap( elem, { "display": "inline-block" },
  347. curCSS, [ elem, "marginRight" ] );
  348. }
  349. }
  350. );
  351. // These hooks are used by animate to expand properties
  352. jQuery.each( {
  353. margin: "",
  354. padding: "",
  355. border: "Width"
  356. }, function( prefix, suffix ) {
  357. jQuery.cssHooks[ prefix + suffix ] = {
  358. expand: function( value ) {
  359. var i = 0,
  360. expanded = {},
  361. // Assumes a single number if not a string
  362. parts = typeof value === "string" ? value.split( " " ) : [ value ];
  363. for ( ; i < 4; i++ ) {
  364. expanded[ prefix + cssExpand[ i ] + suffix ] =
  365. parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  366. }
  367. return expanded;
  368. }
  369. };
  370. if ( !rmargin.test( prefix ) ) {
  371. jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  372. }
  373. } );
  374. jQuery.fn.extend( {
  375. css: function( name, value ) {
  376. return access( this, function( elem, name, value ) {
  377. var styles, len,
  378. map = {},
  379. i = 0;
  380. if ( jQuery.isArray( name ) ) {
  381. styles = getStyles( elem );
  382. len = name.length;
  383. for ( ; i < len; i++ ) {
  384. map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  385. }
  386. return map;
  387. }
  388. return value !== undefined ?
  389. jQuery.style( elem, name, value ) :
  390. jQuery.css( elem, name );
  391. }, name, value, arguments.length > 1 );
  392. },
  393. show: function() {
  394. return showHide( this, true );
  395. },
  396. hide: function() {
  397. return showHide( this );
  398. },
  399. toggle: function( state ) {
  400. if ( typeof state === "boolean" ) {
  401. return state ? this.show() : this.hide();
  402. }
  403. return this.each( function() {
  404. if ( isHidden( this ) ) {
  405. jQuery( this ).show();
  406. } else {
  407. jQuery( this ).hide();
  408. }
  409. } );
  410. }
  411. } );
  412. return jQuery;
  413. } );