html5-boilerplate 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);