html5-boilerplate 1.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.md +30 -94
  2. data/VERSION +1 -1
  3. data/lib/app/helpers/html5_boilerplate_helper.rb +1 -0
  4. data/lib/html5-boilerplate.rb +1 -1
  5. data/templates/project/_head.html.haml +8 -5
  6. data/templates/project/_javascripts.html.haml +16 -6
  7. data/templates/project/_stylesheets.html.haml +1 -1
  8. data/templates/project/application.html.haml +1 -1
  9. data/templates/project/files/apple-touch-icon-114x114-precomposed.png +0 -0
  10. data/templates/project/files/apple-touch-icon-57x57-precomposed.png +0 -0
  11. data/templates/project/files/apple-touch-icon-72x72-precomposed.png +0 -0
  12. data/templates/project/files/apple-touch-icon-precomposed.png +0 -0
  13. data/templates/project/files/apple-touch-icon.png +0 -0
  14. data/templates/project/files/htaccess +135 -110
  15. data/templates/project/index.html.haml +37 -20
  16. data/templates/project/javascripts/{jquery-1.6.js → jquery-1.6.2.js} +369 -253
  17. data/templates/project/javascripts/jquery-1.6.2.min.js +18 -0
  18. data/templates/project/javascripts/modernizr-2.0.6.min.js +4 -0
  19. data/templates/project/javascripts/plugins.js +7 -3
  20. data/templates/project/javascripts/rails.js +90 -37
  21. data/templates/project/manifest.rb +10 -7
  22. data/templates/project/partials/_base.scss +9 -18
  23. data/templates/project/partials/_media.scss +20 -14
  24. data/templates/project/partials/_overrides.scss +47 -57
  25. data/templates/project/partials/_page.scss +0 -32
  26. data/templates/project/style.scss +6 -10
  27. metadata +50 -61
  28. data/stylesheets/_html5-boilerplate.scss +0 -20
  29. data/stylesheets/html5-boilerplate/_fonts.scss +0 -42
  30. data/stylesheets/html5-boilerplate/_helpers.scss +0 -71
  31. data/stylesheets/html5-boilerplate/_media.scss +0 -35
  32. data/stylesheets/html5-boilerplate/_reset.scss +0 -43
  33. data/stylesheets/html5-boilerplate/_styles.scss +0 -126
  34. data/templates/project/handheld.scss +0 -8
  35. data/templates/project/javascripts/jquery-1.6.min.js +0 -16
  36. data/templates/project/javascripts/modernizr-1.7.min.js +0 -2
  37. data/templates/project/javascripts/respond.min.js +0 -7
@@ -1,16 +1,18 @@
1
1
  !!! 5
2
2
  -# paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/
3
- <!--[if lt IE 7]> <html lang="en" class="no-js ie6"> <![endif]-->
4
- <!--[if IE 7]> <html lang="en" class="no-js ie7"> <![endif]-->
5
- <!--[if IE 8]> <html lang="en" class="no-js ie8"> <![endif]-->
3
+ <!--[if lt IE 7]> <html lang="en" class="no-js ie6 oldie"> <![endif]-->
4
+ <!--[if IE 7]> <html lang="en" class="no-js ie7 oldie"> <![endif]-->
5
+ <!--[if IE 8]> <html lang="en" class="no-js ie8 oldie"> <![endif]-->
6
+ -# Consider adding an manifest.appcache: h5bp.com/d/Offline
6
7
  <!--[if gt IE 8]><!-->
7
8
  %html.no-js{ :lang => "en" }
8
9
  <!--<![endif]-->
9
10
  %head
10
11
  %meta{ :charset => "utf-8" }/
11
12
 
12
- -# Always force latest IE rendering engine (even in intranet) & Chrome Frame
13
- -# Remove this if you use the .htaccess
13
+ -#
14
+ Use the .htaccess and remove these lines to avoid edge case issues.
15
+ More info: h5bp.com/b/378
14
16
  %meta{ "http-equiv" => "X-UA-Compatible", :content => "IE=edge,chrome=1" }/
15
17
 
16
18
  %title
@@ -23,33 +25,48 @@
23
25
  -# Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons
24
26
 
25
27
  -# CSS: implied media="all"
26
- %link{ :href => "css/style.css?v=1", :media => "all", :rel => "stylesheet" }/
28
+ -# CSS concatenated and minified via ant build script
29
+ %link{ :rel => "stylesheet", :href => "css/style.css"}/
27
30
 
28
- -# All JavaScript at the bottom, except for Modernizr and Respond.
29
- -# Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries
30
- %script{ :src => "js/modernizr.min.js" }
31
- %script{ :src => "js/respond.min.js" }
31
+ -#
32
+ All JavaScript at the bottom, except for Modernizr / Respond.
33
+ Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries
34
+ For optimal performance, use a custom Modernizr build: www.modernizr.com/download/
35
+ %script{ :src => "js/modernizr-2.0.6.min.js" }
32
36
 
33
37
  %body
34
38
  #container
35
39
  %header
36
40
  #main{ :role => 'main' }
37
41
  %footer
38
-
39
- -#
40
- Javascript at the bottom for fast page loading
41
- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if necessary
42
- %script{ :src => "//ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.js" }
43
- :javascript
44
- window.jQuery || document.write("<script src='js/jquery.min.js'>\x3C/script>")
42
+ -# end of #container
43
+
44
+ -# Javascript at the bottom for fast page loading
45
+
46
+ -# Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline
47
+ %script{ :src => "//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" }
48
+ %script
49
+ window.jQuery || document.write("<script src='js/jquery-1.6.2.min.js'>\x3C/script>")
45
50
 
46
- %script{ :src => "js/plugins.js?v=1" }
47
- %script{ :src => "js/script.js?v=1" }
51
+ -# scripts concatenated and minified via ant build script
52
+ %script{ :src => "js/plugins.js" }
53
+ %script{ :src => "js/script.js" }
54
+ -# end scripts
48
55
 
49
56
  -# asynchronous google analytics: mathiasbynens.be/notes/async-analytics-snippet
50
57
  -# change the UA-XXXXX-X to be your site's ID
51
- :javascript
58
+ %script
52
59
  var _gaq=[["_setAccount","UA-XXXXX-X"],["_trackPageview"],["_trackPageLoadTime"]];
53
60
  (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.async=1;
54
61
  g.src=("https:"==location.protocol?"//ssl":"//www")+".google-analytics.com/ga.js";
55
62
  s.parentNode.insertBefore(g,s)}(document,"script"));
63
+
64
+ -#
65
+ Prompt IE 6 users to install Chrome Frame. Remove this if you want to support IE 6.
66
+ chromium.org/developers/how-tos/chrome-frame-getting-started
67
+
68
+ <!--[if lt IE 7]>
69
+ %script{ :src => "//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js" }
70
+ %script
71
+ window.attachEvent('onload',function(){CFInstall.check({mode:'overlay'})});
72
+ <![endif]-->
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * jQuery JavaScript Library v1.6
2
+ * jQuery JavaScript Library v1.6.2
3
3
  * http://jquery.com/
4
4
  *
5
5
  * Copyright 2011, John Resig
@@ -11,7 +11,7 @@
11
11
  * Copyright 2011, The Dojo Foundation
12
12
  * Released under the MIT, BSD, and GPL Licenses.
13
13
  *
14
- * Date: Mon May 2 13:50:00 2011 -0400
14
+ * Date: Thu Jun 30 14:16:56 2011 -0400
15
15
  */
16
16
  (function( window, undefined ) {
17
17
 
@@ -65,6 +65,14 @@ var jQuery = function( selector, context ) {
65
65
  rmsie = /(msie) ([\w.]+)/,
66
66
  rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
67
67
 
68
+ // Matches dashed string for camelizing
69
+ rdashAlpha = /-([a-z])/ig,
70
+
71
+ // Used by jQuery.camelCase as callback to replace()
72
+ fcamelCase = function( all, letter ) {
73
+ return letter.toUpperCase();
74
+ },
75
+
68
76
  // Keep a UserAgent string for use with jQuery.browser
69
77
  userAgent = navigator.userAgent,
70
78
 
@@ -204,7 +212,7 @@ jQuery.fn = jQuery.prototype = {
204
212
  selector: "",
205
213
 
206
214
  // The current version of jQuery being used
207
- jquery: "1.6",
215
+ jquery: "1.6.2",
208
216
 
209
217
  // The default length of a jQuery object is 0
210
218
  length: 0,
@@ -603,6 +611,12 @@ jQuery.extend({
603
611
  }
604
612
  },
605
613
 
614
+ // Converts a dashed string to camelCased string;
615
+ // Used by both the css and data modules
616
+ camelCase: function( string ) {
617
+ return string.replace( rdashAlpha, fcamelCase );
618
+ },
619
+
606
620
  nodeName: function( elem, name ) {
607
621
  return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
608
622
  },
@@ -799,7 +813,7 @@ jQuery.extend({
799
813
  },
800
814
 
801
815
  // Mutifunctional method to get and set values to a collection
802
- // The value/s can be optionally by executed if its a function
816
+ // The value/s can optionally be executed if it's a function
803
817
  access: function( elems, key, value, exec, fn, pass ) {
804
818
  var length = elems.length;
805
819
 
@@ -930,7 +944,6 @@ function doScrollCheck() {
930
944
  jQuery.ready();
931
945
  }
932
946
 
933
- // Expose jQuery to the global object
934
947
  return jQuery;
935
948
 
936
949
  })();
@@ -1055,7 +1068,7 @@ jQuery.extend({
1055
1068
  if ( jQuery.isFunction( fn ) ) {
1056
1069
  deferred[ handler ](function() {
1057
1070
  returned = fn.apply( this, arguments );
1058
- if ( jQuery.isFunction( returned.promise ) ) {
1071
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
1059
1072
  returned.promise().then( newDefer.resolve, newDefer.reject );
1060
1073
  } else {
1061
1074
  newDefer[ action ]( returned );
@@ -1137,6 +1150,7 @@ jQuery.extend({
1137
1150
  jQuery.support = (function() {
1138
1151
 
1139
1152
  var div = document.createElement( "div" ),
1153
+ documentElement = document.documentElement,
1140
1154
  all,
1141
1155
  a,
1142
1156
  select,
@@ -1146,7 +1160,9 @@ jQuery.support = (function() {
1146
1160
  support,
1147
1161
  fragment,
1148
1162
  body,
1149
- bodyStyle,
1163
+ testElementParent,
1164
+ testElement,
1165
+ testElementStyle,
1150
1166
  tds,
1151
1167
  events,
1152
1168
  eventName,
@@ -1240,11 +1256,10 @@ jQuery.support = (function() {
1240
1256
  }
1241
1257
 
1242
1258
  if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1243
- div.attachEvent( "onclick", function click() {
1259
+ div.attachEvent( "onclick", function() {
1244
1260
  // Cloning a node shouldn't copy over any
1245
1261
  // bound event handlers (IE does this)
1246
1262
  support.noCloneEvent = false;
1247
- div.detachEvent( "onclick", click );
1248
1263
  });
1249
1264
  div.cloneNode( true ).fireEvent( "onclick" );
1250
1265
  }
@@ -1269,22 +1284,30 @@ jQuery.support = (function() {
1269
1284
  // Figure out if the W3C box model works as expected
1270
1285
  div.style.width = div.style.paddingLeft = "1px";
1271
1286
 
1272
- // We use our own, invisible, body
1273
- body = document.createElement( "body" );
1274
- bodyStyle = {
1287
+ body = document.getElementsByTagName( "body" )[ 0 ];
1288
+ // We use our own, invisible, body unless the body is already present
1289
+ // in which case we use a div (#9239)
1290
+ testElement = document.createElement( body ? "div" : "body" );
1291
+ testElementStyle = {
1275
1292
  visibility: "hidden",
1276
1293
  width: 0,
1277
1294
  height: 0,
1278
1295
  border: 0,
1279
- margin: 0,
1280
- // Set background to avoid IE crashes when removing (#9028)
1281
- background: "none"
1296
+ margin: 0
1282
1297
  };
1283
- for ( i in bodyStyle ) {
1284
- body.style[ i ] = bodyStyle[ i ];
1298
+ if ( body ) {
1299
+ jQuery.extend( testElementStyle, {
1300
+ position: "absolute",
1301
+ left: -1000,
1302
+ top: -1000
1303
+ });
1304
+ }
1305
+ for ( i in testElementStyle ) {
1306
+ testElement.style[ i ] = testElementStyle[ i ];
1285
1307
  }
1286
- body.appendChild( div );
1287
- document.documentElement.appendChild( body );
1308
+ testElement.appendChild( div );
1309
+ testElementParent = body || documentElement;
1310
+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
1288
1311
 
1289
1312
  // Check if a disconnected checkbox will retain its checked
1290
1313
  // value of true after appended to the DOM (IE6/7)
@@ -1339,12 +1362,12 @@ jQuery.support = (function() {
1339
1362
  marginDiv.style.marginRight = "0";
1340
1363
  div.appendChild( marginDiv );
1341
1364
  support.reliableMarginRight =
1342
- ( parseInt( document.defaultView.getComputedStyle( marginDiv, null ).marginRight, 10 ) || 0 ) === 0;
1365
+ ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1343
1366
  }
1344
1367
 
1345
1368
  // Remove the body element we added
1346
- body.innerHTML = "";
1347
- document.documentElement.removeChild( body );
1369
+ testElement.innerHTML = "";
1370
+ testElementParent.removeChild( testElement );
1348
1371
 
1349
1372
  // Technique from Juriy Zaytsev
1350
1373
  // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
@@ -1368,6 +1391,9 @@ jQuery.support = (function() {
1368
1391
  }
1369
1392
  }
1370
1393
 
1394
+ // Null connected elements to avoid leaks in IE
1395
+ testElement = fragment = select = opt = body = marginDiv = div = input = null;
1396
+
1371
1397
  return support;
1372
1398
  })();
1373
1399
 
@@ -1475,7 +1501,7 @@ jQuery.extend({
1475
1501
  }
1476
1502
 
1477
1503
  if ( data !== undefined ) {
1478
- thisCache[ name ] = data;
1504
+ thisCache[ jQuery.camelCase( name ) ] = data;
1479
1505
  }
1480
1506
 
1481
1507
  // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
@@ -1485,7 +1511,10 @@ jQuery.extend({
1485
1511
  return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1486
1512
  }
1487
1513
 
1488
- return getByName ? thisCache[ name ] : thisCache;
1514
+ return getByName ?
1515
+ // Check for both converted-to-camel and non-converted data property names
1516
+ thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] :
1517
+ thisCache;
1489
1518
  },
1490
1519
 
1491
1520
  removeData: function( elem, name, pvt /* Internal Use Only */ ) {
@@ -1661,7 +1690,7 @@ function dataAttr( elem, key, data ) {
1661
1690
  // If nothing was found internally, try to fetch any
1662
1691
  // data from the HTML5 data-* attribute
1663
1692
  if ( data === undefined && elem.nodeType === 1 ) {
1664
- name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1693
+ var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1665
1694
 
1666
1695
  data = elem.getAttribute( name );
1667
1696
 
@@ -1850,7 +1879,8 @@ jQuery.fn.extend({
1850
1879
  count = 1,
1851
1880
  deferDataKey = type + "defer",
1852
1881
  queueDataKey = type + "queue",
1853
- markDataKey = type + "mark";
1882
+ markDataKey = type + "mark",
1883
+ tmp;
1854
1884
  function resolve() {
1855
1885
  if ( !( --count ) ) {
1856
1886
  defer.resolveWith( elements, [ elements ] );
@@ -1879,9 +1909,9 @@ var rclass = /[\n\t\r]/g,
1879
1909
  rtype = /^(?:button|input)$/i,
1880
1910
  rfocusable = /^(?:button|input|object|select|textarea)$/i,
1881
1911
  rclickable = /^a(?:rea)?$/i,
1882
- rspecial = /^(?:data-|aria-)/,
1883
- rinvalidChar = /\:/,
1884
- formHook;
1912
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1913
+ rinvalidChar = /\:|^on/,
1914
+ formHook, boolHook;
1885
1915
 
1886
1916
  jQuery.fn.extend({
1887
1917
  attr: function( name, value ) {
@@ -1899,6 +1929,7 @@ jQuery.fn.extend({
1899
1929
  },
1900
1930
 
1901
1931
  removeProp: function( name ) {
1932
+ name = jQuery.propFix[ name ] || name;
1902
1933
  return this.each(function() {
1903
1934
  // try/catch handles cases where IE balks (such as removing a property on window)
1904
1935
  try {
@@ -1909,30 +1940,31 @@ jQuery.fn.extend({
1909
1940
  },
1910
1941
 
1911
1942
  addClass: function( value ) {
1943
+ var classNames, i, l, elem,
1944
+ setClass, c, cl;
1945
+
1912
1946
  if ( jQuery.isFunction( value ) ) {
1913
- return this.each(function(i) {
1914
- var self = jQuery(this);
1915
- self.addClass( value.call(this, i, self.attr("class") || "") );
1947
+ return this.each(function( j ) {
1948
+ jQuery( this ).addClass( value.call(this, j, this.className) );
1916
1949
  });
1917
1950
  }
1918
1951
 
1919
1952
  if ( value && typeof value === "string" ) {
1920
- var classNames = (value || "").split( rspace );
1953
+ classNames = value.split( rspace );
1921
1954
 
1922
- for ( var i = 0, l = this.length; i < l; i++ ) {
1923
- var elem = this[i];
1955
+ for ( i = 0, l = this.length; i < l; i++ ) {
1956
+ elem = this[ i ];
1924
1957
 
1925
1958
  if ( elem.nodeType === 1 ) {
1926
- if ( !elem.className ) {
1959
+ if ( !elem.className && classNames.length === 1 ) {
1927
1960
  elem.className = value;
1928
1961
 
1929
1962
  } else {
1930
- var className = " " + elem.className + " ",
1931
- setClass = elem.className;
1963
+ setClass = " " + elem.className + " ";
1932
1964
 
1933
- for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1934
- if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1935
- setClass += " " + classNames[c];
1965
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
1966
+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
1967
+ setClass += classNames[ c ] + " ";
1936
1968
  }
1937
1969
  }
1938
1970
  elem.className = jQuery.trim( setClass );
@@ -1945,24 +1977,25 @@ jQuery.fn.extend({
1945
1977
  },
1946
1978
 
1947
1979
  removeClass: function( value ) {
1948
- if ( jQuery.isFunction(value) ) {
1949
- return this.each(function(i) {
1950
- var self = jQuery(this);
1951
- self.removeClass( value.call(this, i, self.attr("class")) );
1980
+ var classNames, i, l, elem, className, c, cl;
1981
+
1982
+ if ( jQuery.isFunction( value ) ) {
1983
+ return this.each(function( j ) {
1984
+ jQuery( this ).removeClass( value.call(this, j, this.className) );
1952
1985
  });
1953
1986
  }
1954
1987
 
1955
1988
  if ( (value && typeof value === "string") || value === undefined ) {
1956
- var classNames = (value || "").split( rspace );
1989
+ classNames = (value || "").split( rspace );
1957
1990
 
1958
- for ( var i = 0, l = this.length; i < l; i++ ) {
1959
- var elem = this[i];
1991
+ for ( i = 0, l = this.length; i < l; i++ ) {
1992
+ elem = this[ i ];
1960
1993
 
1961
1994
  if ( elem.nodeType === 1 && elem.className ) {
1962
1995
  if ( value ) {
1963
- var className = (" " + elem.className + " ").replace(rclass, " ");
1964
- for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1965
- className = className.replace(" " + classNames[c] + " ", " ");
1996
+ className = (" " + elem.className + " ").replace( rclass, " " );
1997
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
1998
+ className = className.replace(" " + classNames[ c ] + " ", " ");
1966
1999
  }
1967
2000
  elem.className = jQuery.trim( className );
1968
2001
 
@@ -1981,9 +2014,8 @@ jQuery.fn.extend({
1981
2014
  isBool = typeof stateVal === "boolean";
1982
2015
 
1983
2016
  if ( jQuery.isFunction( value ) ) {
1984
- return this.each(function(i) {
1985
- var self = jQuery(this);
1986
- self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
2017
+ return this.each(function( i ) {
2018
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
1987
2019
  });
1988
2020
  }
1989
2021
 
@@ -2037,7 +2069,13 @@ jQuery.fn.extend({
2037
2069
  return ret;
2038
2070
  }
2039
2071
 
2040
- return (elem.value || "").replace(rreturn, "");
2072
+ ret = elem.value;
2073
+
2074
+ return typeof ret === "string" ?
2075
+ // handle most common string cases
2076
+ ret.replace(rreturn, "") :
2077
+ // handle cases where value is null/undef or number
2078
+ ret == null ? "" : ret;
2041
2079
  }
2042
2080
 
2043
2081
  return undefined;
@@ -2072,7 +2110,7 @@ jQuery.fn.extend({
2072
2110
  hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2073
2111
 
2074
2112
  // If set returns undefined, fall back to normal setting
2075
- if ( !hooks || ("set" in hooks && hooks.set( this, val, "value" ) === undefined) ) {
2113
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2076
2114
  this.value = val;
2077
2115
  }
2078
2116
  });
@@ -2091,7 +2129,8 @@ jQuery.extend({
2091
2129
  },
2092
2130
  select: {
2093
2131
  get: function( elem ) {
2094
- var index = elem.selectedIndex,
2132
+ var value,
2133
+ index = elem.selectedIndex,
2095
2134
  values = [],
2096
2135
  options = elem.options,
2097
2136
  one = elem.type === "select-one";
@@ -2158,8 +2197,7 @@ jQuery.extend({
2158
2197
 
2159
2198
  attrFix: {
2160
2199
  // Always normalize to ensure hook usage
2161
- tabindex: "tabIndex",
2162
- readonly: "readOnly"
2200
+ tabindex: "tabIndex"
2163
2201
  },
2164
2202
 
2165
2203
  attr: function( elem, name, value, pass ) {
@@ -2173,23 +2211,39 @@ jQuery.extend({
2173
2211
  if ( pass && name in jQuery.attrFn ) {
2174
2212
  return jQuery( elem )[ name ]( value );
2175
2213
  }
2176
-
2214
+
2215
+ // Fallback to prop when attributes are not supported
2216
+ if ( !("getAttribute" in elem) ) {
2217
+ return jQuery.prop( elem, name, value );
2218
+ }
2219
+
2177
2220
  var ret, hooks,
2178
2221
  notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2179
-
2222
+
2180
2223
  // Normalize the name if needed
2181
- name = notxml && jQuery.attrFix[ name ] || name;
2224
+ if ( notxml ) {
2225
+ name = jQuery.attrFix[ name ] || name;
2226
+
2227
+ hooks = jQuery.attrHooks[ name ];
2182
2228
 
2183
- // Get the appropriate hook, or the formHook
2184
- // if getSetAttribute is not supported and we have form objects in IE6/7
2185
- hooks = jQuery.attrHooks[ name ] ||
2186
- ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ?
2187
- formHook :
2188
- undefined );
2229
+ if ( !hooks ) {
2230
+ // Use boolHook for boolean attributes
2231
+ if ( rboolean.test( name ) ) {
2232
+
2233
+ hooks = boolHook;
2234
+
2235
+ // Use formHook for forms and if the name contains certain characters
2236
+ } else if ( formHook && name !== "className" &&
2237
+ (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2238
+
2239
+ hooks = formHook;
2240
+ }
2241
+ }
2242
+ }
2189
2243
 
2190
2244
  if ( value !== undefined ) {
2191
2245
 
2192
- if ( value === null || (value === false && !rspecial.test( name )) ) {
2246
+ if ( value === null ) {
2193
2247
  jQuery.removeAttr( elem, name );
2194
2248
  return undefined;
2195
2249
 
@@ -2197,34 +2251,26 @@ jQuery.extend({
2197
2251
  return ret;
2198
2252
 
2199
2253
  } else {
2200
-
2201
- // Set boolean attributes to the same name
2202
- if ( value === true && !rspecial.test( name ) ) {
2203
- value = name;
2204
- }
2205
-
2206
2254
  elem.setAttribute( name, "" + value );
2207
2255
  return value;
2208
2256
  }
2209
2257
 
2210
- } else {
2211
-
2212
- if ( hooks && "get" in hooks && notxml ) {
2213
- return hooks.get( elem, name );
2258
+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2259
+ return ret;
2214
2260
 
2215
- } else {
2261
+ } else {
2216
2262
 
2217
- ret = elem.getAttribute( name );
2263
+ ret = elem.getAttribute( name );
2218
2264
 
2219
- // Non-existent attributes return null, we normalize to undefined
2220
- return ret === null ?
2221
- undefined :
2222
- ret;
2223
- }
2265
+ // Non-existent attributes return null, we normalize to undefined
2266
+ return ret === null ?
2267
+ undefined :
2268
+ ret;
2224
2269
  }
2225
2270
  },
2226
-
2271
+
2227
2272
  removeAttr: function( elem, name ) {
2273
+ var propName;
2228
2274
  if ( elem.nodeType === 1 ) {
2229
2275
  name = jQuery.attrFix[ name ] || name;
2230
2276
 
@@ -2235,6 +2281,11 @@ jQuery.extend({
2235
2281
  jQuery.attr( elem, name, "" );
2236
2282
  elem.removeAttributeNode( elem.getAttributeNode( name ) );
2237
2283
  }
2284
+
2285
+ // Set corresponding property to false for boolean attributes
2286
+ if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2287
+ elem[ propName ] = false;
2288
+ }
2238
2289
  }
2239
2290
  },
2240
2291
 
@@ -2248,7 +2299,7 @@ jQuery.extend({
2248
2299
  // Setting the type on a radio button after the value resets the value in IE6-9
2249
2300
  // Reset value to it's default in case type is set after value
2250
2301
  // This is for element creation
2251
- var val = elem.getAttribute("value");
2302
+ var val = elem.value;
2252
2303
  elem.setAttribute( "type", value );
2253
2304
  if ( val ) {
2254
2305
  elem.value = val;
@@ -2269,39 +2320,72 @@ jQuery.extend({
2269
2320
  0 :
2270
2321
  undefined;
2271
2322
  }
2323
+ },
2324
+ // Use the value property for back compat
2325
+ // Use the formHook for button elements in IE6/7 (#1954)
2326
+ value: {
2327
+ get: function( elem, name ) {
2328
+ if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2329
+ return formHook.get( elem, name );
2330
+ }
2331
+ return name in elem ?
2332
+ elem.value :
2333
+ null;
2334
+ },
2335
+ set: function( elem, value, name ) {
2336
+ if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2337
+ return formHook.set( elem, value, name );
2338
+ }
2339
+ // Does not return so that setAttribute is also used
2340
+ elem.value = value;
2341
+ }
2272
2342
  }
2273
2343
  },
2274
-
2275
- propFix: {},
2344
+
2345
+ propFix: {
2346
+ tabindex: "tabIndex",
2347
+ readonly: "readOnly",
2348
+ "for": "htmlFor",
2349
+ "class": "className",
2350
+ maxlength: "maxLength",
2351
+ cellspacing: "cellSpacing",
2352
+ cellpadding: "cellPadding",
2353
+ rowspan: "rowSpan",
2354
+ colspan: "colSpan",
2355
+ usemap: "useMap",
2356
+ frameborder: "frameBorder",
2357
+ contenteditable: "contentEditable"
2358
+ },
2276
2359
 
2277
2360
  prop: function( elem, name, value ) {
2278
2361
  var nType = elem.nodeType;
2279
-
2362
+
2280
2363
  // don't get/set properties on text, comment and attribute nodes
2281
2364
  if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2282
2365
  return undefined;
2283
2366
  }
2284
-
2367
+
2285
2368
  var ret, hooks,
2286
2369
  notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2287
-
2288
- // Try to normalize/fix the name
2289
- name = notxml && jQuery.propFix[ name ] || name;
2290
-
2291
- hooks = jQuery.propHooks[ name ];
2292
-
2370
+
2371
+ if ( notxml ) {
2372
+ // Fix name and attach hooks
2373
+ name = jQuery.propFix[ name ] || name;
2374
+ hooks = jQuery.propHooks[ name ];
2375
+ }
2376
+
2293
2377
  if ( value !== undefined ) {
2294
2378
  if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2295
2379
  return ret;
2296
-
2380
+
2297
2381
  } else {
2298
2382
  return (elem[ name ] = value);
2299
2383
  }
2300
-
2384
+
2301
2385
  } else {
2302
2386
  if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2303
2387
  return ret;
2304
-
2388
+
2305
2389
  } else {
2306
2390
  return elem[ name ];
2307
2391
  }
@@ -2311,30 +2395,47 @@ jQuery.extend({
2311
2395
  propHooks: {}
2312
2396
  });
2313
2397
 
2398
+ // Hook for boolean attributes
2399
+ boolHook = {
2400
+ get: function( elem, name ) {
2401
+ // Align boolean attributes with corresponding properties
2402
+ return jQuery.prop( elem, name ) ?
2403
+ name.toLowerCase() :
2404
+ undefined;
2405
+ },
2406
+ set: function( elem, value, name ) {
2407
+ var propName;
2408
+ if ( value === false ) {
2409
+ // Remove boolean attributes when set to false
2410
+ jQuery.removeAttr( elem, name );
2411
+ } else {
2412
+ // value is true since we know at this point it's type boolean and not false
2413
+ // Set boolean attributes to the same name and set the DOM property
2414
+ propName = jQuery.propFix[ name ] || name;
2415
+ if ( propName in elem ) {
2416
+ // Only set the IDL specifically if it already exists on the element
2417
+ elem[ propName ] = true;
2418
+ }
2419
+
2420
+ elem.setAttribute( name, name.toLowerCase() );
2421
+ }
2422
+ return name;
2423
+ }
2424
+ };
2425
+
2314
2426
  // IE6/7 do not support getting/setting some attributes with get/setAttribute
2315
2427
  if ( !jQuery.support.getSetAttribute ) {
2316
- jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
2317
- "for": "htmlFor",
2318
- "class": "className",
2319
- maxlength: "maxLength",
2320
- cellspacing: "cellSpacing",
2321
- cellpadding: "cellPadding",
2322
- rowspan: "rowSpan",
2323
- colspan: "colSpan",
2324
- usemap: "useMap",
2325
- frameborder: "frameBorder"
2326
- });
2428
+
2429
+ // propFix is more comprehensive and contains all fixes
2430
+ jQuery.attrFix = jQuery.propFix;
2327
2431
 
2328
2432
  // Use this for any attribute on a form in IE6/7
2329
- formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
2433
+ formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {
2330
2434
  get: function( elem, name ) {
2331
2435
  var ret;
2332
- if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
2333
- return elem.getAttribute( name );
2334
- }
2335
2436
  ret = elem.getAttributeNode( name );
2336
- // Return undefined if not specified instead of empty string
2337
- return ret && ret.specified ?
2437
+ // Return undefined if nodeValue is empty string
2438
+ return ret && ret.nodeValue !== "" ?
2338
2439
  ret.nodeValue :
2339
2440
  undefined;
2340
2441
  },
@@ -2432,8 +2533,7 @@ jQuery.each([ "radio", "checkbox" ], function() {
2432
2533
 
2433
2534
 
2434
2535
 
2435
- var hasOwn = Object.prototype.hasOwnProperty,
2436
- rnamespaces = /\.(.*)$/,
2536
+ var rnamespaces = /\.(.*)$/,
2437
2537
  rformElems = /^(?:textarea|input|select)$/i,
2438
2538
  rperiod = /\./g,
2439
2539
  rspaces = / /g,
@@ -2777,7 +2877,7 @@ jQuery.event = {
2777
2877
  event.target = elem;
2778
2878
 
2779
2879
  // Clone any incoming data and prepend the event, creating the handler arg list
2780
- data = data ? jQuery.makeArray( data ) : [];
2880
+ data = data != null ? jQuery.makeArray( data ) : [];
2781
2881
  data.unshift( event );
2782
2882
 
2783
2883
  var cur = elem,
@@ -3083,33 +3183,27 @@ jQuery.Event.prototype = {
3083
3183
  // Checks if an event happened on an element within another element
3084
3184
  // Used in jQuery.event.special.mouseenter and mouseleave handlers
3085
3185
  var withinElement = function( event ) {
3186
+
3086
3187
  // Check if mouse(over|out) are still within the same parent element
3087
- var parent = event.relatedTarget;
3188
+ var related = event.relatedTarget,
3189
+ inside = false,
3190
+ eventType = event.type;
3088
3191
 
3089
- // Firefox sometimes assigns relatedTarget a XUL element
3090
- // which we cannot access the parentNode property of
3091
- try {
3192
+ event.type = event.data;
3092
3193
 
3093
- // Chrome does something similar, the parentNode property
3094
- // can be accessed but is null.
3095
- if ( parent && parent !== document && !parent.parentNode ) {
3096
- return;
3097
- }
3098
- // Traverse up the tree
3099
- while ( parent && parent !== this ) {
3100
- parent = parent.parentNode;
3194
+ if ( related !== this ) {
3195
+
3196
+ if ( related ) {
3197
+ inside = jQuery.contains( this, related );
3101
3198
  }
3102
3199
 
3103
- if ( parent !== this ) {
3104
- // set the correct event type
3105
- event.type = event.data;
3200
+ if ( !inside ) {
3106
3201
 
3107
- // handle event if we actually just moused on to a non sub-element
3108
3202
  jQuery.event.handle.apply( this, arguments );
3109
- }
3110
3203
 
3111
- // assuming we've left the element since we most likely mousedover a xul element
3112
- } catch(e) { }
3204
+ event.type = eventType;
3205
+ }
3206
+ }
3113
3207
  },
3114
3208
 
3115
3209
  // In case of event delegation, we only need to rename the event.type,
@@ -4291,7 +4385,8 @@ var Expr = Sizzle.selectors = {
4291
4385
  },
4292
4386
 
4293
4387
  reset: function( elem ) {
4294
- return elem.nodeName.toLowerCase() === "input" && "reset" === elem.type;
4388
+ var name = elem.nodeName.toLowerCase();
4389
+ return (name === "input" || name === "button") && "reset" === elem.type;
4295
4390
  },
4296
4391
 
4297
4392
  button: function( elem ) {
@@ -4557,6 +4652,16 @@ if ( document.documentElement.compareDocumentPosition ) {
4557
4652
 
4558
4653
  } else {
4559
4654
  sortOrder = function( a, b ) {
4655
+ // The nodes are identical, we can exit early
4656
+ if ( a === b ) {
4657
+ hasDuplicate = true;
4658
+ return 0;
4659
+
4660
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
4661
+ } else if ( a.sourceIndex && b.sourceIndex ) {
4662
+ return a.sourceIndex - b.sourceIndex;
4663
+ }
4664
+
4560
4665
  var al, bl,
4561
4666
  ap = [],
4562
4667
  bp = [],
@@ -4564,13 +4669,8 @@ if ( document.documentElement.compareDocumentPosition ) {
4564
4669
  bup = b.parentNode,
4565
4670
  cur = aup;
4566
4671
 
4567
- // The nodes are identical, we can exit early
4568
- if ( a === b ) {
4569
- hasDuplicate = true;
4570
- return 0;
4571
-
4572
4672
  // If the nodes are siblings (or identical) we can do a quick check
4573
- } else if ( aup === bup ) {
4673
+ if ( aup === bup ) {
4574
4674
  return siblingCheck( a, b );
4575
4675
 
4576
4676
  // If no parents were found then the nodes are disconnected
@@ -5394,6 +5494,7 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5394
5494
  // checked="checked" or checked
5395
5495
  rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5396
5496
  rscriptType = /\/(java|ecma)script/i,
5497
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5397
5498
  wrapMap = {
5398
5499
  option: [ 1, "<select multiple='multiple'>", "</select>" ],
5399
5500
  legend: [ 1, "<fieldset>", "</fieldset>" ],
@@ -5821,8 +5922,21 @@ function cloneFixAttributes( src, dest ) {
5821
5922
  }
5822
5923
 
5823
5924
  jQuery.buildFragment = function( args, nodes, scripts ) {
5824
- var fragment, cacheable, cacheresults,
5825
- doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5925
+ var fragment, cacheable, cacheresults, doc;
5926
+
5927
+ // nodes may contain either an explicit document object,
5928
+ // a jQuery collection or context object.
5929
+ // If nodes[0] contains a valid object to assign to doc
5930
+ if ( nodes && nodes[0] ) {
5931
+ doc = nodes[0].ownerDocument || nodes[0];
5932
+ }
5933
+
5934
+ // Ensure that an attr object doesn't incorrectly stand in as a document object
5935
+ // Chrome and Firefox seem to allow this to occur and will throw exception
5936
+ // Fixes #8950
5937
+ if ( !doc.createDocumentFragment ) {
5938
+ doc = document;
5939
+ }
5826
5940
 
5827
5941
  // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5828
5942
  // Cloning options loses the selected state, so don't cache them
@@ -5884,7 +5998,7 @@ jQuery.each({
5884
5998
  function getAll( elem ) {
5885
5999
  if ( "getElementsByTagName" in elem ) {
5886
6000
  return elem.getElementsByTagName( "*" );
5887
-
6001
+
5888
6002
  } else if ( "querySelectorAll" in elem ) {
5889
6003
  return elem.querySelectorAll( "*" );
5890
6004
 
@@ -5903,7 +6017,7 @@ function fixDefaultChecked( elem ) {
5903
6017
  function findInputs( elem ) {
5904
6018
  if ( jQuery.nodeName( elem, "input" ) ) {
5905
6019
  fixDefaultChecked( elem );
5906
- } else if ( elem.getElementsByTagName ) {
6020
+ } else if ( "getElementsByTagName" in elem ) {
5907
6021
  jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5908
6022
  }
5909
6023
  }
@@ -5952,6 +6066,8 @@ jQuery.extend({
5952
6066
  }
5953
6067
  }
5954
6068
 
6069
+ srcElements = destElements = null;
6070
+
5955
6071
  // Return the cloned set
5956
6072
  return clone;
5957
6073
  },
@@ -5966,7 +6082,7 @@ jQuery.extend({
5966
6082
  context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5967
6083
  }
5968
6084
 
5969
- var ret = [];
6085
+ var ret = [], j;
5970
6086
 
5971
6087
  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5972
6088
  if ( typeof elem === "number" ) {
@@ -6012,7 +6128,7 @@ jQuery.extend({
6012
6128
  div.childNodes :
6013
6129
  [];
6014
6130
 
6015
- for ( var j = tbody.length - 1; j >= 0 ; --j ) {
6131
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
6016
6132
  if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6017
6133
  tbody[ j ].parentNode.removeChild( tbody[ j ] );
6018
6134
  }
@@ -6033,8 +6149,8 @@ jQuery.extend({
6033
6149
  var len;
6034
6150
  if ( !jQuery.support.appendChecked ) {
6035
6151
  if ( elem[0] && typeof (len = elem.length) === "number" ) {
6036
- for ( i = 0; i < len; i++ ) {
6037
- findInputs( elem[i] );
6152
+ for ( j = 0; j < len; j++ ) {
6153
+ findInputs( elem[j] );
6038
6154
  }
6039
6155
  } else {
6040
6156
  findInputs( elem );
@@ -6122,7 +6238,7 @@ function evalScript( i, elem ) {
6122
6238
  dataType: "script"
6123
6239
  });
6124
6240
  } else {
6125
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
6241
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6126
6242
  }
6127
6243
 
6128
6244
  if ( elem.parentNode ) {
@@ -6132,10 +6248,8 @@ function evalScript( i, elem ) {
6132
6248
 
6133
6249
 
6134
6250
 
6135
-
6136
6251
  var ralpha = /alpha\([^)]*\)/i,
6137
6252
  ropacity = /opacity=([^)]*)/,
6138
- rdashAlpha = /-([a-z])/ig,
6139
6253
  // fixed for IE9, see #8346
6140
6254
  rupper = /([A-Z]|^ms)/g,
6141
6255
  rnumpx = /^-?\d+(?:px)?$/i,
@@ -6149,11 +6263,7 @@ var ralpha = /alpha\([^)]*\)/i,
6149
6263
  curCSS,
6150
6264
 
6151
6265
  getComputedStyle,
6152
- currentStyle,
6153
-
6154
- fcamelCase = function( all, letter ) {
6155
- return letter.toUpperCase();
6156
- };
6266
+ currentStyle;
6157
6267
 
6158
6268
  jQuery.fn.css = function( name, value ) {
6159
6269
  // Setting 'undefined' is a no-op
@@ -6188,13 +6298,14 @@ jQuery.extend({
6188
6298
 
6189
6299
  // Exclude the following css properties to add px
6190
6300
  cssNumber: {
6191
- "zIndex": true,
6301
+ "fillOpacity": true,
6192
6302
  "fontWeight": true,
6193
- "opacity": true,
6194
- "zoom": true,
6195
6303
  "lineHeight": true,
6304
+ "opacity": true,
6305
+ "orphans": true,
6196
6306
  "widows": true,
6197
- "orphans": true
6307
+ "zIndex": true,
6308
+ "zoom": true
6198
6309
  },
6199
6310
 
6200
6311
  // Add in properties whose names you wish to fix before
@@ -6229,6 +6340,8 @@ jQuery.extend({
6229
6340
  // convert relative number strings (+= or -=) to relative numbers. #7345
6230
6341
  if ( type === "string" && rrelNum.test( value ) ) {
6231
6342
  value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6343
+ // Fixes bug #9237
6344
+ type = "number";
6232
6345
  }
6233
6346
 
6234
6347
  // If a number was passed in, add 'px' to the (except for certain CSS properties)
@@ -6295,10 +6408,6 @@ jQuery.extend({
6295
6408
  for ( name in options ) {
6296
6409
  elem.style[ name ] = old[ name ];
6297
6410
  }
6298
- },
6299
-
6300
- camelCase: function( string ) {
6301
- return string.replace( rdashAlpha, fcamelCase );
6302
6411
  }
6303
6412
  });
6304
6413
 
@@ -6312,44 +6421,21 @@ jQuery.each(["height", "width"], function( i, name ) {
6312
6421
 
6313
6422
  if ( computed ) {
6314
6423
  if ( elem.offsetWidth !== 0 ) {
6315
- val = getWH( elem, name, extra );
6316
-
6424
+ return getWH( elem, name, extra );
6317
6425
  } else {
6318
6426
  jQuery.swap( elem, cssShow, function() {
6319
6427
  val = getWH( elem, name, extra );
6320
6428
  });
6321
6429
  }
6322
6430
 
6323
- if ( val <= 0 ) {
6324
- val = curCSS( elem, name, name );
6325
-
6326
- if ( val === "0px" && currentStyle ) {
6327
- val = currentStyle( elem, name, name );
6328
- }
6329
-
6330
- if ( val != null ) {
6331
- // Should return "auto" instead of 0, use 0 for
6332
- // temporary backwards-compat
6333
- return val === "" || val === "auto" ? "0px" : val;
6334
- }
6335
- }
6336
-
6337
- if ( val < 0 || val == null ) {
6338
- val = elem.style[ name ];
6339
-
6340
- // Should return "auto" instead of 0, use 0 for
6341
- // temporary backwards-compat
6342
- return val === "" || val === "auto" ? "0px" : val;
6343
- }
6344
-
6345
- return typeof val === "string" ? val : val + "px";
6431
+ return val;
6346
6432
  }
6347
6433
  },
6348
6434
 
6349
6435
  set: function( elem, value ) {
6350
6436
  if ( rnumpx.test( value ) ) {
6351
6437
  // ignore negative width and height values #1599
6352
- value = parseFloat(value);
6438
+ value = parseFloat( value );
6353
6439
 
6354
6440
  if ( value >= 0 ) {
6355
6441
  return value + "px";
@@ -6472,27 +6558,50 @@ if ( document.documentElement.currentStyle ) {
6472
6558
  curCSS = getComputedStyle || currentStyle;
6473
6559
 
6474
6560
  function getWH( elem, name, extra ) {
6475
- var which = name === "width" ? cssWidth : cssHeight,
6476
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6477
6561
 
6478
- if ( extra === "border" ) {
6479
- return val;
6480
- }
6562
+ // Start with offset property
6563
+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6564
+ which = name === "width" ? cssWidth : cssHeight;
6481
6565
 
6482
- jQuery.each( which, function() {
6483
- if ( !extra ) {
6484
- val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6566
+ if ( val > 0 ) {
6567
+ if ( extra !== "border" ) {
6568
+ jQuery.each( which, function() {
6569
+ if ( !extra ) {
6570
+ val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6571
+ }
6572
+ if ( extra === "margin" ) {
6573
+ val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6574
+ } else {
6575
+ val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6576
+ }
6577
+ });
6485
6578
  }
6486
6579
 
6487
- if ( extra === "margin" ) {
6488
- val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6580
+ return val + "px";
6581
+ }
6489
6582
 
6490
- } else {
6491
- val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6492
- }
6493
- });
6583
+ // Fall back to computed then uncomputed css if necessary
6584
+ val = curCSS( elem, name, name );
6585
+ if ( val < 0 || val == null ) {
6586
+ val = elem.style[ name ] || 0;
6587
+ }
6588
+ // Normalize "", auto, and prepare for extra
6589
+ val = parseFloat( val ) || 0;
6590
+
6591
+ // Add padding, border, margin
6592
+ if ( extra ) {
6593
+ jQuery.each( which, function() {
6594
+ val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6595
+ if ( extra !== "padding" ) {
6596
+ val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6597
+ }
6598
+ if ( extra === "margin" ) {
6599
+ val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6600
+ }
6601
+ });
6602
+ }
6494
6603
 
6495
- return val;
6604
+ return val + "px";
6496
6605
  }
6497
6606
 
6498
6607
  if ( jQuery.expr && jQuery.expr.filters ) {
@@ -7888,8 +7997,8 @@ var elemdisplay = {},
7888
7997
  ],
7889
7998
  fxNow,
7890
7999
  requestAnimationFrame = window.webkitRequestAnimationFrame ||
7891
- window.mozRequestAnimationFrame ||
7892
- window.oRequestAnimationFrame;
8000
+ window.mozRequestAnimationFrame ||
8001
+ window.oRequestAnimationFrame;
7893
8002
 
7894
8003
  jQuery.fn.extend({
7895
8004
  show: function( speed, easing, callback ) {
@@ -7999,6 +8108,9 @@ jQuery.fn.extend({
7999
8108
  return this.each( optall.complete, [ false ] );
8000
8109
  }
8001
8110
 
8111
+ // Do not change referenced properties as per-property easing will be lost
8112
+ prop = jQuery.extend( {}, prop );
8113
+
8002
8114
  return this[ optall.queue === false ? "each" : "queue" ](function() {
8003
8115
  // XXX 'this' does not always have a nodeName when running the
8004
8116
  // test suite
@@ -8007,7 +8119,7 @@ jQuery.fn.extend({
8007
8119
  jQuery._mark( this );
8008
8120
  }
8009
8121
 
8010
- var opt = jQuery.extend({}, optall),
8122
+ var opt = jQuery.extend( {}, optall ),
8011
8123
  isElement = this.nodeType === 1,
8012
8124
  hidden = isElement && jQuery(this).is(":hidden"),
8013
8125
  name, val, p,
@@ -8026,10 +8138,18 @@ jQuery.fn.extend({
8026
8138
  delete prop[ p ];
8027
8139
  }
8028
8140
 
8029
- val = prop[name];
8141
+ val = prop[ name ];
8142
+
8143
+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8144
+ if ( jQuery.isArray( val ) ) {
8145
+ opt.animatedProperties[ name ] = val[ 1 ];
8146
+ val = prop[ name ] = val[ 0 ];
8147
+ } else {
8148
+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8149
+ }
8030
8150
 
8031
8151
  if ( val === "hide" && hidden || val === "show" && !hidden ) {
8032
- return opt.complete.call(this);
8152
+ return opt.complete.call( this );
8033
8153
  }
8034
8154
 
8035
8155
  if ( isElement && ( name === "height" || name === "width" ) ) {
@@ -8048,7 +8168,7 @@ jQuery.fn.extend({
8048
8168
  this.style.display = "inline-block";
8049
8169
 
8050
8170
  } else {
8051
- display = defaultDisplay(this.nodeName);
8171
+ display = defaultDisplay( this.nodeName );
8052
8172
 
8053
8173
  // inline-level elements accept inline-block;
8054
8174
  // block-level elements need to be inline with layout
@@ -8062,11 +8182,6 @@ jQuery.fn.extend({
8062
8182
  }
8063
8183
  }
8064
8184
  }
8065
-
8066
- // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8067
- opt.animatedProperties[name] = jQuery.isArray( val ) ?
8068
- val[1]:
8069
- opt.specialEasing && opt.specialEasing[name] || opt.easing || 'swing';
8070
8185
  }
8071
8186
 
8072
8187
  if ( opt.overflow != null ) {
@@ -8075,19 +8190,18 @@ jQuery.fn.extend({
8075
8190
 
8076
8191
  for ( p in prop ) {
8077
8192
  e = new jQuery.fx( this, opt, p );
8078
-
8079
- val = prop[p];
8193
+ val = prop[ p ];
8080
8194
 
8081
8195
  if ( rfxtypes.test(val) ) {
8082
8196
  e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8083
8197
 
8084
8198
  } else {
8085
- parts = rfxnum.exec(val);
8199
+ parts = rfxnum.exec( val );
8086
8200
  start = e.cur();
8087
8201
 
8088
8202
  if ( parts ) {
8089
8203
  end = parseFloat( parts[2] );
8090
- unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
8204
+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8091
8205
 
8092
8206
  // We need to compute starting value
8093
8207
  if ( unit !== "px" ) {
@@ -8098,7 +8212,7 @@ jQuery.fn.extend({
8098
8212
 
8099
8213
  // If a +=/-= token was provided, we're doing a relative animation
8100
8214
  if ( parts[1] ) {
8101
- end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
8215
+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8102
8216
  }
8103
8217
 
8104
8218
  e.custom( start, end, unit );
@@ -8126,7 +8240,6 @@ jQuery.fn.extend({
8126
8240
  if ( !gotoEnd ) {
8127
8241
  jQuery._unmark( true, this );
8128
8242
  }
8129
- // go in reverse order so anything added to the queue during the loop is ignored
8130
8243
  while ( i-- ) {
8131
8244
  if ( timers[i].elem === this ) {
8132
8245
  if (gotoEnd) {
@@ -8199,15 +8312,15 @@ jQuery.extend({
8199
8312
  // Queueing
8200
8313
  opt.old = opt.complete;
8201
8314
  opt.complete = function( noUnmark ) {
8315
+ if ( jQuery.isFunction( opt.old ) ) {
8316
+ opt.old.call( this );
8317
+ }
8318
+
8202
8319
  if ( opt.queue !== false ) {
8203
8320
  jQuery.dequeue( this );
8204
8321
  } else if ( noUnmark !== false ) {
8205
8322
  jQuery._unmark( this );
8206
8323
  }
8207
-
8208
- if ( jQuery.isFunction( opt.old ) ) {
8209
- opt.old.call( this );
8210
- }
8211
8324
  };
8212
8325
 
8213
8326
  return opt;
@@ -8280,7 +8393,7 @@ jQuery.fx.prototype = {
8280
8393
  if ( t() && jQuery.timers.push(t) && !timerId ) {
8281
8394
  // Use requestAnimationFrame instead of setInterval if available
8282
8395
  if ( requestAnimationFrame ) {
8283
- timerId = 1;
8396
+ timerId = true;
8284
8397
  raf = function() {
8285
8398
  // When timerId gets set to null at any point, this stops
8286
8399
  if ( timerId ) {
@@ -8374,10 +8487,10 @@ jQuery.fx.prototype = {
8374
8487
  this.now = t;
8375
8488
  } else {
8376
8489
  n = t - this.startTime;
8377
-
8378
8490
  this.state = n / options.duration;
8491
+
8379
8492
  // Perform the easing function, defaults to swing
8380
- this.pos = jQuery.easing[options.animatedProperties[this.prop]](this.state, n, 0, 1, options.duration);
8493
+ this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8381
8494
  this.now = this.start + ((this.end - this.start) * this.pos);
8382
8495
  }
8383
8496
  // Perform the next step of the animation
@@ -8390,11 +8503,9 @@ jQuery.fx.prototype = {
8390
8503
 
8391
8504
  jQuery.extend( jQuery.fx, {
8392
8505
  tick: function() {
8393
- var timers = jQuery.timers,
8394
- i = timers.length;
8395
- while ( i-- ) {
8506
+ for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8396
8507
  if ( !timers[i]() ) {
8397
- timers.splice(i, 1);
8508
+ timers.splice(i--, 1);
8398
8509
  }
8399
8510
  }
8400
8511
 
@@ -8445,7 +8556,8 @@ function defaultDisplay( nodeName ) {
8445
8556
 
8446
8557
  if ( !elemdisplay[ nodeName ] ) {
8447
8558
 
8448
- var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8559
+ var body = document.body,
8560
+ elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8449
8561
  display = elem.css( "display" );
8450
8562
 
8451
8563
  elem.remove();
@@ -8459,14 +8571,15 @@ function defaultDisplay( nodeName ) {
8459
8571
  iframe.frameBorder = iframe.width = iframe.height = 0;
8460
8572
  }
8461
8573
 
8462
- document.body.appendChild( iframe );
8574
+ body.appendChild( iframe );
8463
8575
 
8464
8576
  // Create a cacheable copy of the iframe document on first call.
8465
- // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8466
- // document to it, Webkit & Firefox won't allow reusing the iframe document
8577
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8578
+ // document to it; WebKit & Firefox won't allow reusing the iframe document.
8467
8579
  if ( !iframeDoc || !iframe.createElement ) {
8468
8580
  iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8469
- iframeDoc.write( "<!doctype><html><body></body></html>" );
8581
+ iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8582
+ iframeDoc.close();
8470
8583
  }
8471
8584
 
8472
8585
  elem = iframeDoc.createElement( nodeName );
@@ -8475,7 +8588,7 @@ function defaultDisplay( nodeName ) {
8475
8588
 
8476
8589
  display = jQuery.css( elem, "display" );
8477
8590
 
8478
- document.body.removeChild( iframe );
8591
+ body.removeChild( iframe );
8479
8592
  }
8480
8593
 
8481
8594
  // Store the correct default display
@@ -8796,22 +8909,24 @@ function getWindow( elem ) {
8796
8909
 
8797
8910
 
8798
8911
 
8799
- // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8912
+ // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
8800
8913
  jQuery.each([ "Height", "Width" ], function( i, name ) {
8801
8914
 
8802
8915
  var type = name.toLowerCase();
8803
8916
 
8804
8917
  // innerHeight and innerWidth
8805
- jQuery.fn["inner" + name] = function() {
8806
- return this[0] ?
8807
- parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8918
+ jQuery.fn[ "inner" + name ] = function() {
8919
+ var elem = this[0];
8920
+ return elem && elem.style ?
8921
+ parseFloat( jQuery.css( elem, type, "padding" ) ) :
8808
8922
  null;
8809
8923
  };
8810
8924
 
8811
8925
  // outerHeight and outerWidth
8812
- jQuery.fn["outer" + name] = function( margin ) {
8813
- return this[0] ?
8814
- parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8926
+ jQuery.fn[ "outer" + name ] = function( margin ) {
8927
+ var elem = this[0];
8928
+ return elem && elem.style ?
8929
+ parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
8815
8930
  null;
8816
8931
  };
8817
8932
 
@@ -8861,5 +8976,6 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
8861
8976
  });
8862
8977
 
8863
8978
 
8979
+ // Expose jQuery to the global object
8864
8980
  window.jQuery = window.$ = jQuery;
8865
8981
  })(window);