mobile_template 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/lib/mobile_template/version.rb +1 -1
  2. data/mobile_template.gemspec +1 -1
  3. data/templates/assets/Gemfile +1 -1
  4. data/templates/assets/source/javascripts/vendor/cordova.js +2106 -1975
  5. data/templates/assets/source/javascripts/vendor/jquery.js +614 -477
  6. data/templates/assets/source/javascripts/vendor/jquery.mobile.js +519 -378
  7. data/templates/assets/source/stylesheets/vendor/jquery.mobile.css.scss +683 -502
  8. data/templates/cordova_android/VERSION +1 -1
  9. data/templates/cordova_android/bin/create +5 -1
  10. data/templates/cordova_android/bin/templates/project/cordova/create +5 -0
  11. data/templates/cordova_android/bin/templates/project/cordova/debug +1 -1
  12. data/templates/cordova_android/bin/templates/project/cordova/templates/project/AndroidManifest.xml +18 -25
  13. data/templates/cordova_android/bin/templates/project/cordova/templates/project/assets/www/index.html +6 -6
  14. data/templates/cordova_android/framework/assets/js/cordova.android.js +2106 -1975
  15. data/templates/cordova_android/framework/assets/www/index.html +1 -1
  16. data/templates/cordova_android/framework/build.xml +2 -42
  17. data/templates/cordova_android/framework/project.properties +1 -1
  18. data/templates/cordova_android/framework/res/drawable/splash.png +0 -0
  19. data/templates/cordova_android/framework/res/drawable-hdpi/icon.png +0 -0
  20. data/templates/cordova_android/framework/res/drawable-ldpi/icon.png +0 -0
  21. data/templates/cordova_android/framework/res/drawable-mdpi/icon.png +0 -0
  22. data/templates/cordova_android/framework/res/xml/plugins.xml +2 -1
  23. data/templates/cordova_android/framework/src/com/phonegap/api/PluginManager.java +1 -0
  24. data/templates/cordova_android/framework/src/org/apache/cordova/AudioPlayer.java +24 -16
  25. data/templates/cordova_android/framework/src/org/apache/cordova/CameraLauncher.java +35 -10
  26. data/templates/cordova_android/framework/src/org/apache/cordova/ContactAccessor.java +2 -1
  27. data/templates/cordova_android/framework/src/org/apache/cordova/ContactAccessorSdk5.java +67 -65
  28. data/templates/cordova_android/framework/src/org/apache/cordova/ContactManager.java +51 -63
  29. data/templates/cordova_android/framework/src/org/apache/cordova/CordovaChromeClient.java +3 -0
  30. data/templates/cordova_android/framework/src/org/apache/cordova/CordovaWebViewClient.java +6 -2
  31. data/templates/cordova_android/framework/src/org/apache/cordova/Device.java +108 -108
  32. data/templates/cordova_android/framework/src/org/apache/cordova/DroidGap.java +110 -77
  33. data/templates/cordova_android/framework/src/org/apache/cordova/FileTransfer.java +90 -44
  34. data/templates/cordova_android/framework/src/org/apache/cordova/FileUtils.java +20 -20
  35. data/templates/cordova_android/framework/src/org/apache/cordova/LinearLayoutSoftKeyboardDetect.java +2 -2
  36. data/templates/cordova_android/framework/src/org/apache/cordova/NetworkManager.java +7 -8
  37. data/templates/cordova_android/framework/src/org/apache/cordova/Notification.java +2 -2
  38. data/templates/cordova_android/framework/src/org/apache/cordova/SplashScreen.java +23 -0
  39. data/templates/cordova_android/framework/src/org/apache/cordova/Storage.java +3 -3
  40. data/templates/cordova_android/framework/src/org/apache/cordova/api/CordovaInterface.java +2 -0
  41. data/templates/cordova_android/framework/src/org/apache/cordova/api/PluginEntry.java +119 -0
  42. data/templates/cordova_android/framework/src/org/apache/cordova/api/PluginManager.java +260 -258
  43. data/templates/cordova_android/framework/src/org/apache/cordova/api/PluginResult.java +2 -2
  44. data/templates/cordova_android/releasenotes.md +42 -0
  45. data/templates/cordova_android/test/.classpath +8 -0
  46. data/templates/cordova_android/test/.project +33 -0
  47. data/templates/cordova_android/test/AndroidManifest.xml +87 -0
  48. data/templates/cordova_android/test/README.md +23 -0
  49. data/templates/cordova_android/test/ant.properties +17 -0
  50. data/templates/cordova_android/test/assets/www/backbuttonmultipage/index.html +23 -0
  51. data/templates/cordova_android/test/assets/www/backbuttonmultipage/sample2.html +23 -0
  52. data/templates/cordova_android/test/assets/www/backbuttonmultipage/sample3.html +26 -0
  53. data/templates/cordova_android/test/assets/www/background/index.html +99 -0
  54. data/templates/cordova_android/test/assets/www/background/index2.html +98 -0
  55. data/templates/cordova_android/test/assets/www/cordova-1.6.0.js +4985 -0
  56. data/templates/cordova_android/test/assets/www/cordova.js +2 -0
  57. data/templates/cordova_android/test/assets/www/htmlnotfound/error.html +1 -0
  58. data/templates/cordova_android/test/assets/www/iframe/index.html +33 -0
  59. data/templates/cordova_android/test/assets/www/iframe/index2.html +24 -0
  60. data/templates/cordova_android/test/assets/www/index.html +47 -0
  61. data/templates/cordova_android/test/assets/www/jqmtabbackbutton/index.html +49 -0
  62. data/templates/cordova_android/test/assets/www/jqmtabbackbutton/tab1.html +29 -0
  63. data/templates/cordova_android/test/assets/www/jqmtabbackbutton/tab2.html +30 -0
  64. data/templates/cordova_android/test/assets/www/jqmtabbackbutton/tab3.html +30 -0
  65. data/templates/cordova_android/test/assets/www/lifecycle/index.html +108 -0
  66. data/templates/cordova_android/test/assets/www/lifecycle/index2.html +104 -0
  67. data/templates/cordova_android/test/assets/www/main.js +150 -0
  68. data/templates/cordova_android/test/assets/www/master.css +117 -0
  69. data/templates/cordova_android/test/assets/www/menus/index.html +29 -0
  70. data/templates/cordova_android/test/assets/www/splashscreen/index.html +22 -0
  71. data/templates/cordova_android/test/assets/www/userwebview/index.html +49 -0
  72. data/templates/cordova_android/test/assets/www/whitelist/index.html +29 -0
  73. data/templates/cordova_android/test/assets/www/whitelist/index2.html +23 -0
  74. data/templates/cordova_android/test/assets/www/xhr/index.html +48 -0
  75. data/templates/cordova_android/test/build.xml +85 -0
  76. data/templates/cordova_android/test/libs/cordova-1.6.0.jar +0 -0
  77. data/templates/cordova_android/test/project.properties +11 -0
  78. data/templates/cordova_android/{framework → test}/res/drawable/icon.png +0 -0
  79. data/templates/cordova_android/test/res/drawable/sandy.jpg +0 -0
  80. data/templates/cordova_android/test/res/drawable-hdpi/ic_launcher.png +0 -0
  81. data/templates/cordova_android/test/res/drawable-ldpi/ic_launcher.png +0 -0
  82. data/templates/cordova_android/test/res/drawable-mdpi/ic_launcher.png +0 -0
  83. data/templates/cordova_android/test/res/layout/main.xml +13 -0
  84. data/templates/cordova_android/test/res/values/strings.xml +4 -0
  85. data/templates/cordova_android/{bin/templates/project/cordova/templates/project → test}/res/xml/cordova.xml +0 -0
  86. data/templates/cordova_android/{bin/templates/project/cordova/templates/project → test}/res/xml/plugins.xml +1 -1
  87. data/templates/cordova_android/test/src/org/apache/cordova/test/ActivityPlugin.java +81 -0
  88. data/templates/cordova_android/test/src/org/apache/cordova/test/FixWebView.java +43 -0
  89. data/templates/cordova_android/test/src/org/apache/cordova/test/backbuttonmultipage.java +30 -0
  90. data/templates/cordova_android/test/src/org/apache/cordova/test/background.java +34 -0
  91. data/templates/cordova_android/test/src/org/apache/cordova/test/errorurl.java +32 -0
  92. data/templates/cordova_android/test/src/org/apache/cordova/test/htmlnotfound.java +31 -0
  93. data/templates/cordova_android/test/src/org/apache/cordova/test/iframe.java +30 -0
  94. data/templates/cordova_android/test/src/org/apache/cordova/test/jqmtabbackbutton.java +30 -0
  95. data/templates/cordova_android/test/src/org/apache/cordova/test/lifecycle.java +30 -0
  96. data/templates/cordova_android/test/src/org/apache/cordova/test/loading.java +31 -0
  97. data/templates/cordova_android/test/src/org/apache/cordova/test/menus.java +80 -0
  98. data/templates/cordova_android/test/src/org/apache/cordova/test/splashscreen.java +35 -0
  99. data/templates/cordova_android/test/src/org/apache/cordova/test/tests.java +32 -0
  100. data/templates/cordova_android/test/src/org/apache/cordova/test/timeout.java +34 -0
  101. data/templates/cordova_android/test/src/org/apache/cordova/test/userwebview.java +72 -0
  102. data/templates/cordova_android/test/src/org/apache/cordova/test/whitelist.java +51 -0
  103. data/templates/cordova_android/test/src/org/apache/cordova/test/xhr.java +30 -0
  104. metadata +83 -30
  105. data/templates/cordova_android/framework/assets/js/accelerometer.js +0 -137
  106. data/templates/cordova_android/framework/assets/js/app.js +0 -89
  107. data/templates/cordova_android/framework/assets/js/battery.js +0 -134
  108. data/templates/cordova_android/framework/assets/js/camera.js +0 -168
  109. data/templates/cordova_android/framework/assets/js/capture.js +0 -203
  110. data/templates/cordova_android/framework/assets/js/compass.js +0 -168
  111. data/templates/cordova_android/framework/assets/js/contact.js +0 -310
  112. data/templates/cordova_android/framework/assets/js/cordova.js.base +0 -924
  113. data/templates/cordova_android/framework/assets/js/crypto.js +0 -54
  114. data/templates/cordova_android/framework/assets/js/device.js +0 -83
  115. data/templates/cordova_android/framework/assets/js/file.js +0 -1082
  116. data/templates/cordova_android/framework/assets/js/filetransfer.js +0 -125
  117. data/templates/cordova_android/framework/assets/js/geolocation.js +0 -209
  118. data/templates/cordova_android/framework/assets/js/header.txt +0 -19
  119. data/templates/cordova_android/framework/assets/js/media.js +0 -233
  120. data/templates/cordova_android/framework/assets/js/network.js +0 -100
  121. data/templates/cordova_android/framework/assets/js/notification.js +0 -133
  122. data/templates/cordova_android/framework/assets/js/position.js +0 -100
  123. data/templates/cordova_android/framework/assets/js/storage.js +0 -439
@@ -1,5 +1,5 @@
1
1
  /*
2
- * jQuery Mobile Framework 1.1.0-rc.1
2
+ * jQuery Mobile Framework 1.1.0 db342b1f315c282692791aa870455901fdb46a55
3
3
  * http://jquerymobile.com
4
4
  *
5
5
  * Copyright 2011 (c) jQuery Project
@@ -84,7 +84,7 @@ function createVirtualEvent( event, eventType ) {
84
84
 
85
85
  // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280
86
86
  // https://github.com/jquery/jquery-mobile/issues/3280
87
- if ( t.search(/mouse/) >-1 ) {
87
+ if ( t.search( /^(mouse|click)/ ) > -1 ) {
88
88
  props = mouseEventProps;
89
89
  }
90
90
 
@@ -1223,6 +1223,10 @@ $.widget( "mobile.widget", {
1223
1223
  }
1224
1224
 
1225
1225
  $widgetElements[ this.widgetName ]();
1226
+ },
1227
+
1228
+ raise: function( msg ) {
1229
+ throw "Widget [" + this.widgetName + "]: " + msg;
1226
1230
  }
1227
1231
  });
1228
1232
 
@@ -1236,7 +1240,7 @@ $.widget( "mobile.widget", {
1236
1240
  $.mobile = $.extend( {}, {
1237
1241
 
1238
1242
  // Version of the jQuery Mobile Framework
1239
- version: "1.1.0-rc.1",
1243
+ version: "1.1.0",
1240
1244
 
1241
1245
  // Namespace used framework-wide for data-attrs. Default is no namespace
1242
1246
  ns: "",
@@ -1271,7 +1275,7 @@ $.widget( "mobile.widget", {
1271
1275
  maxTransitionWidth: false,
1272
1276
 
1273
1277
  // Minimum scroll distance that will be remembered when returning to a page
1274
- minScrollBack: 10,
1278
+ minScrollBack: 250,
1275
1279
 
1276
1280
  // DEPRECATED: the following property is no longer in use, but defined until 2.0 to prevent conflicts
1277
1281
  touchOverflowEnabled: false,
@@ -1307,6 +1311,10 @@ $.widget( "mobile.widget", {
1307
1311
  // turn of binding to the native orientationchange due to android orientation behavior
1308
1312
  orientationChangeEnabled: true,
1309
1313
 
1314
+ buttonMarkup: {
1315
+ hoverDelay: 200
1316
+ },
1317
+
1310
1318
  // TODO might be useful upstream in jquery itself ?
1311
1319
  keyCode: {
1312
1320
  ALT: 18,
@@ -1385,7 +1393,7 @@ $.widget( "mobile.widget", {
1385
1393
 
1386
1394
  var e = el[ 0 ],
1387
1395
  ltr = "",
1388
- re = /ui-(bar|body)-([a-z])\b/,
1396
+ re = /ui-(bar|body|overlay)-([a-z])\b/,
1389
1397
  c, m;
1390
1398
 
1391
1399
  while ( e ) {
@@ -1464,7 +1472,10 @@ $.widget( "mobile.widget", {
1464
1472
  $.fn.jqmData = function( prop, value ) {
1465
1473
  var result;
1466
1474
  if ( typeof prop != "undefined" ) {
1467
- result = this.data( prop ? $.mobile.nsNormalize( prop ) : prop, value );
1475
+ if ( prop ) {
1476
+ prop = $.mobile.nsNormalize( prop );
1477
+ }
1478
+ result = this.data.apply( this, arguments.length < 2 ? [ prop ] : [ prop, value ] );
1468
1479
  }
1469
1480
  return result;
1470
1481
  };
@@ -1932,17 +1943,37 @@ $.event.special.swipe = {
1932
1943
  // It seems that some device/browser vendors use window.orientation values 0 and 180 to
1933
1944
  // denote the "default" orientation. For iOS devices, and most other smart-phones tested,
1934
1945
  // the default orientation is always "portrait", but in some Android and RIM based tablets,
1935
- // the default orientation is "landscape". The following code injects a landscape orientation
1936
- // media query into the document to figure out what the current orientation is, and then
1937
- // makes adjustments to the portrait_map if necessary, so that we can properly
1938
- // decode the window.orientation value whenever get_orientation() is called.
1946
+ // the default orientation is "landscape". The following code attempts to use the window
1947
+ // dimensions to figure out what the current orientation is, and then makes adjustments
1948
+ // to the to the portrait_map if necessary, so that we can properly decode the
1949
+ // window.orientation value whenever get_orientation() is called.
1950
+ //
1951
+ // Note that we used to use a media query to figure out what the orientation the browser
1952
+ // thinks it is in:
1953
+ //
1954
+ // initial_orientation_is_landscape = $.mobile.media("all and (orientation: landscape)");
1955
+ //
1956
+ // but there was an iPhone/iPod Touch bug beginning with iOS 4.2, up through iOS 5.1,
1957
+ // where the browser *ALWAYS* applied the landscape media query. This bug does not
1958
+ // happen on iPad.
1959
+
1939
1960
  if ( $.support.orientation ) {
1940
1961
 
1941
- // Use a media query to figure out the true orientation of the device at this moment.
1942
- // Note that we've initialized the portrait map values to 0 and 180, *AND* we purposely
1943
- // use a landscape media query so that if the device/browser does not support this particular
1944
- // media query, we default to the assumption that portrait is the default orientation.
1945
- initial_orientation_is_landscape = $.mobile.media("all and (orientation: landscape)");
1962
+ // Check the window width and height to figure out what the current orientation
1963
+ // of the device is at this moment. Note that we've initialized the portrait map
1964
+ // values to 0 and 180, *AND* we purposely check for landscape so that if we guess
1965
+ // wrong, , we default to the assumption that portrait is the default orientation.
1966
+ // We use a threshold check below because on some platforms like iOS, the iPhone
1967
+ // form-factor can report a larger width than height if the user turns on the
1968
+ // developer console. The actual threshold value is somewhat arbitrary, we just
1969
+ // need to make sure it is large enough to exclude the developer console case.
1970
+
1971
+ var ww = window.innerWidth || $( window ).width(),
1972
+ wh = window.innerHeight || $( window ).height(),
1973
+ landscape_threshold = 50;
1974
+
1975
+ initial_orientation_is_landscape = ww > wh && ( ww - wh ) > landscape_threshold;
1976
+
1946
1977
 
1947
1978
  // Now check to see if the current window.orientation is 0 or 180.
1948
1979
  initial_orientation_is_default = portrait_map[ window.orientation ];
@@ -2099,15 +2130,35 @@ $.widget( "mobile.page", $.mobile.widget, {
2099
2130
  },
2100
2131
 
2101
2132
  _create: function() {
2102
-
2133
+
2134
+ var self = this;
2135
+
2103
2136
  // if false is returned by the callbacks do not create the page
2104
- if( this._trigger( "beforecreate" ) === false ){
2137
+ if( self._trigger( "beforecreate" ) === false ){
2105
2138
  return false;
2106
2139
  }
2107
2140
 
2108
- this.element
2141
+ self.element
2109
2142
  .attr( "tabindex", "0" )
2110
- .addClass( "ui-page ui-body-" + this.options.theme );
2143
+ .addClass( "ui-page ui-body-" + self.options.theme )
2144
+ .bind( "pagebeforehide", function(){
2145
+ self.removeContainerBackground();
2146
+ } )
2147
+ .bind( "pagebeforeshow", function(){
2148
+ self.setContainerBackground();
2149
+ } );
2150
+
2151
+ },
2152
+
2153
+ removeContainerBackground: function(){
2154
+ $.mobile.pageContainer.removeClass( "ui-overlay-" + $.mobile.getInheritedTheme( this.element.parent() ) );
2155
+ },
2156
+
2157
+ // set the page container background to the page theme
2158
+ setContainerBackground: function( theme ){
2159
+ if( this.options.theme ){
2160
+ $.mobile.pageContainer.addClass( "ui-overlay-" + ( theme || this.options.theme ) );
2161
+ }
2111
2162
  },
2112
2163
 
2113
2164
  keepNativeSelector: function() {
@@ -2126,82 +2177,140 @@ $.widget( "mobile.page", $.mobile.widget, {
2126
2177
 
2127
2178
  (function( $, window, undefined ) {
2128
2179
 
2129
- function outInTransitionHandler( name, reverse, $to, $from ) {
2180
+ var createHandler = function( sequential ){
2130
2181
 
2131
- // override name if there's no 3D transform support and a fallback is defined, or if not, to "none"
2132
- if( name && !$.support.cssTransform3d && $.mobile.transitionFallbacks[ name ] ){
2133
- name = $.mobile.transitionFallbacks[ name ];
2182
+ // Default to sequential
2183
+ if( sequential === undefined ){
2184
+ sequential = true;
2134
2185
  }
2135
2186
 
2136
- var deferred = new $.Deferred(),
2137
- reverseClass = reverse ? " reverse" : "",
2138
- active = $.mobile.urlHistory.getActive(),
2139
- toScroll = active.lastScroll || $.mobile.defaultHomeScroll,
2140
- screenHeight = $.mobile.getScreenHeight(),
2141
- viewportClass = "ui-mobile-viewport-transitioning viewport-" + name,
2142
- maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $( window ).width() > $.mobile.maxTransitionWidth,
2143
- none = !$.support.cssTransitions || maxTransitionOverride || !name || name === "none",
2144
- doneOut = function() {
2145
-
2146
- if ( $from ) {
2187
+ return function( name, reverse, $to, $from ) {
2188
+
2189
+ var deferred = new $.Deferred(),
2190
+ reverseClass = reverse ? " reverse" : "",
2191
+ active = $.mobile.urlHistory.getActive(),
2192
+ toScroll = active.lastScroll || $.mobile.defaultHomeScroll,
2193
+ screenHeight = $.mobile.getScreenHeight(),
2194
+ maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $( window ).width() > $.mobile.maxTransitionWidth,
2195
+ none = !$.support.cssTransitions || maxTransitionOverride || !name || name === "none",
2196
+ toggleViewportClass = function(){
2197
+ $.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + name );
2198
+ },
2199
+ scrollPage = function(){
2200
+ // By using scrollTo instead of silentScroll, we can keep things better in order
2201
+ // Just to be precautios, disable scrollstart listening like silentScroll would
2202
+ $.event.special.scrollstart.enabled = false;
2203
+
2204
+ window.scrollTo( 0, toScroll );
2205
+
2206
+ // reenable scrollstart listening like silentScroll would
2207
+ setTimeout(function() {
2208
+ $.event.special.scrollstart.enabled = true;
2209
+ }, 150 );
2210
+ },
2211
+ cleanFrom = function(){
2147
2212
  $from
2148
2213
  .removeClass( $.mobile.activePageClass + " out in reverse " + name )
2149
2214
  .height( "" );
2150
- }
2151
-
2152
- $to.addClass( $.mobile.activePageClass );
2153
-
2154
- if( !none ){
2155
- $to.animationComplete( doneIn );
2156
- }
2215
+ },
2216
+ startOut = function(){
2217
+ // if it's not sequential, call the doneOut transition to start the TO page animating in simultaneously
2218
+ if( !sequential ){
2219
+ doneOut();
2220
+ }
2221
+ else {
2222
+ $from.animationComplete( doneOut );
2223
+ }
2224
+
2225
+ // Set the from page's height and start it transitioning out
2226
+ // Note: setting an explicit height helps eliminate tiling in the transitions
2227
+ $from
2228
+ .height( screenHeight + $(window ).scrollTop() )
2229
+ .addClass( name + " out" + reverseClass );
2230
+ },
2157
2231
 
2158
- // Send focus to page as it is now display: block
2159
- $.mobile.focusPage( $to );
2232
+ doneOut = function() {
2160
2233
 
2161
- // Jump to top or prev scroll, sometimes on iOS the page has not rendered yet.
2162
- $to.height( screenHeight + toScroll );
2234
+ if ( $from && sequential ) {
2235
+ cleanFrom();
2236
+ }
2163
2237
 
2164
- $.mobile.silentScroll( toScroll );
2238
+ startIn();
2239
+ },
2165
2240
 
2166
- $to.addClass( name + " in" + reverseClass );
2241
+ startIn = function(){
2167
2242
 
2168
- if( none ){
2169
- doneIn();
2170
- }
2243
+ $to.addClass( $.mobile.activePageClass );
2171
2244
 
2172
- },
2173
-
2174
- doneIn = function() {
2175
- $to
2176
- .removeClass( "out in reverse " + name )
2177
- .height( "" )
2178
- .parent().removeClass( viewportClass );
2245
+ // Send focus to page as it is now display: block
2246
+ $.mobile.focusPage( $to );
2179
2247
 
2180
- deferred.resolve( name, reverse, $to, $from, true );
2181
- };
2248
+ // Set to page height
2249
+ $to.height( screenHeight + toScroll );
2250
+
2251
+ scrollPage();
2252
+
2253
+ if( !none ){
2254
+ $to.animationComplete( doneIn );
2255
+ }
2256
+
2257
+ $to.addClass( name + " in" + reverseClass );
2258
+
2259
+ if( none ){
2260
+ doneIn();
2261
+ }
2262
+
2263
+ },
2182
2264
 
2183
- $to
2184
- .parent().addClass( viewportClass );
2265
+ doneIn = function() {
2266
+
2267
+ if ( !sequential ) {
2268
+
2269
+ if( $from ){
2270
+ cleanFrom();
2271
+ }
2272
+ }
2273
+
2274
+ $to
2275
+ .removeClass( "out in reverse " + name )
2276
+ .height( "" );
2277
+
2278
+ toggleViewportClass();
2279
+
2280
+ // In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
2281
+ // This ensures we jump to that spot after the fact, if we aren't there already.
2282
+ if( $( window ).scrollTop() !== toScroll ){
2283
+ scrollPage();
2284
+ }
2285
+
2286
+ deferred.resolve( name, reverse, $to, $from, true );
2287
+ };
2288
+
2289
+ toggleViewportClass();
2185
2290
 
2186
- if ( $from && !none ) {
2187
- $from
2188
- .animationComplete( doneOut )
2189
- .height( screenHeight + $(window ).scrollTop() )
2190
- .addClass( name + " out" + reverseClass );
2191
- }
2192
- else {
2193
- doneOut();
2194
- }
2291
+ if ( $from && !none ) {
2292
+ startOut();
2293
+ }
2294
+ else {
2295
+ doneOut();
2296
+ }
2195
2297
 
2196
- return deferred.promise();
2298
+ return deferred.promise();
2299
+ };
2197
2300
  }
2198
2301
 
2302
+ // generate the handlers from the above
2303
+ var sequentialHandler = createHandler(),
2304
+ simultaneousHandler = createHandler( false );
2305
+
2199
2306
  // Make our transition handler the public default.
2200
- $.mobile.defaultTransitionHandler = outInTransitionHandler;
2307
+ $.mobile.defaultTransitionHandler = sequentialHandler;
2201
2308
 
2202
2309
  //transition handler dictionary for 3rd party transitions
2203
2310
  $.mobile.transitionHandlers = {
2204
- "default": $.mobile.defaultTransitionHandler
2311
+ "default": $.mobile.defaultTransitionHandler,
2312
+ "sequential": sequentialHandler,
2313
+ "simultaneous": simultaneousHandler
2205
2314
  };
2206
2315
 
2207
2316
  $.mobile.transitionFallbacks = {};
@@ -2683,7 +2792,12 @@ $.mobile.transitionFallbacks = {};
2683
2792
 
2684
2793
  //clear page loader
2685
2794
  $.mobile.hidePageLoadingMsg();
2686
-
2795
+
2796
+ // If transition is defined, check if css 3D transforms are supported, and if not, if a fallback is specified
2797
+ if( transition && !$.support.cssTransform3d && $.mobile.transitionFallbacks[ transition ] ){
2798
+ transition = $.mobile.transitionFallbacks[ transition ];
2799
+ }
2800
+
2687
2801
  //find the transition handler for the specified transition. If there
2688
2802
  //isn't one in our transitionHandlers dictionary, use the default one.
2689
2803
  //call the handler immediately to kick-off the transition.
@@ -2706,21 +2820,20 @@ $.mobile.transitionFallbacks = {};
2706
2820
 
2707
2821
  //simply set the active page's minimum height to screen height, depending on orientation
2708
2822
  function getScreenHeight(){
2709
- var orientation = $.event.special.orientationchange.orientation(),
2710
- port = orientation === "portrait",
2711
- winMin = port ? 480 : 320,
2712
- screenHeight = port ? screen.availHeight : screen.availWidth,
2713
- winHeight = Math.max( winMin, $( window ).height() ),
2714
- pageMin = Math.min( screenHeight, winHeight );
2715
-
2716
- return pageMin;
2823
+ // Native innerHeight returns more accurate value for this across platforms,
2824
+ // jQuery version is here as a normalized fallback for platforms like Symbian
2825
+ return window.innerHeight || $( window ).height();
2717
2826
  }
2718
2827
 
2719
2828
  $.mobile.getScreenHeight = getScreenHeight;
2720
2829
 
2721
2830
  //simply set the active page's minimum height to screen height, depending on orientation
2722
2831
  function resetActivePageHeight(){
2723
- $( "." + $.mobile.activePageClass ).css( "min-height", getScreenHeight() );
2832
+ var aPage = $( "." + $.mobile.activePageClass ),
2833
+ aPagePadT = parseFloat( aPage.css( "padding-top" ) ),
2834
+ aPagePadB = parseFloat( aPage.css( "padding-bottom" ) );
2835
+
2836
+ aPage.css( "min-height", getScreenHeight() - aPagePadT - aPagePadB );
2724
2837
  }
2725
2838
 
2726
2839
  //shared page enhancements
@@ -3815,6 +3928,10 @@ $.mobile.transitionFallbacks.pop = "fade";
3815
3928
 
3816
3929
  (function( $, window, undefined ) {
3817
3930
 
3931
+ // Use the simultaneous transition handler for slide transitions
3932
+ $.mobile.transitionHandlers.slide = $.mobile.transitionHandlers.simultaneous;
3933
+
3934
+ // Set the slide transition's fallback to "fade"
3818
3935
  $.mobile.transitionFallbacks.slide = "fade";
3819
3936
 
3820
3937
  })( jQuery, this );
@@ -3943,14 +4060,15 @@ $.widget( "mobile.dialog", $.mobile.widget, {
3943
4060
  // Set aria role
3944
4061
  $el
3945
4062
  .wrapInner( dialogWrap )
3946
- .find( ":jqmData(role='header')" )
3947
- .prepend( headerCloseButton )
3948
- .end()
3949
- .find(':first-child')
3950
- .addClass( "ui-corner-top" )
3951
- .end()
3952
- .find( ":last-child" )
3953
- .addClass( "ui-corner-bottom" );
4063
+ .children()
4064
+ .find( ":jqmData(role='header')" )
4065
+ .prepend( headerCloseButton )
4066
+ .end()
4067
+ .children( ':first-child')
4068
+ .addClass( "ui-corner-top" )
4069
+ .end()
4070
+ .children( ":last-child" )
4071
+ .addClass( "ui-corner-bottom" );
3954
4072
 
3955
4073
  // this must be an anonymous function so that select menu dialogs can replace
3956
4074
  // the close method. This is a change from previously just defining data-rel=back
@@ -3981,18 +4099,13 @@ $.widget( "mobile.dialog", $.mobile.widget, {
3981
4099
  })
3982
4100
  .bind( "pagehide", function( e, ui ) {
3983
4101
  $( this ).find( "." + $.mobile.activeBtnClass ).removeClass( $.mobile.activeBtnClass );
3984
-
3985
- // if there's an overlay theme, we're going to remove it from the page container.
3986
- // First though, check that the incoming page isn't a dialog with the same theme. If so, don't remove.
3987
- if( self.options.overlayTheme ){
3988
- if( !ui.nextPage || !ui.nextPage.is( ".ui-dialog.ui-overlay-" + self.options.overlayTheme ) ){
3989
- $.mobile.pageContainer.removeClass( "ui-overlay-" + self.options.overlayTheme );
3990
- }
3991
- }
3992
4102
  })
4103
+ // Override the theme set by the page plugin on pageshow
3993
4104
  .bind( "pagebeforeshow", function(){
3994
4105
  if( self.options.overlayTheme ){
3995
- $.mobile.pageContainer.addClass( "ui-overlay-" + self.options.overlayTheme );
4106
+ self.element
4107
+ .page( "removeContainerBackground" )
4108
+ .page( "setContainerBackground", self.options.overlayTheme );
3996
4109
  }
3997
4110
  });
3998
4111
  },
@@ -4092,7 +4205,7 @@ $.fn.buttonMarkup = function( options ) {
4092
4205
  o = $.extend( {}, $.fn.buttonMarkup.defaults, {
4093
4206
  icon: options.icon !== undefined ? options.icon : el.jqmData( "icon" ),
4094
4207
  iconpos: options.iconpos !== undefined ? options.iconpos : el.jqmData( "iconpos" ),
4095
- theme: options.theme !== undefined ? options.theme : el.jqmData( "theme" ),
4208
+ theme: options.theme !== undefined ? options.theme : el.jqmData( "theme" ) || $.mobile.getInheritedTheme( el, "c" ),
4096
4209
  inline: options.inline !== undefined ? options.inline : el.jqmData( "inline" ),
4097
4210
  shadow: options.shadow !== undefined ? options.shadow : el.jqmData( "shadow" ),
4098
4211
  corners: options.corners !== undefined ? options.corners : el.jqmData( "corners" ),
@@ -4116,7 +4229,7 @@ $.fn.buttonMarkup = function( options ) {
4116
4229
  });
4117
4230
 
4118
4231
  // Check if this element is already enhanced
4119
- buttonElements = $.data(((e.tagName === "INPUT" || e.tagName === "BUTTON") ? e.parentNode : e), "buttonElements")
4232
+ buttonElements = $.data(((e.tagName === "INPUT" || e.tagName === "BUTTON") ? e.parentNode : e), "buttonElements");
4120
4233
 
4121
4234
  if (buttonElements) {
4122
4235
  e = buttonElements.outer;
@@ -4136,24 +4249,28 @@ $.fn.buttonMarkup = function( options ) {
4136
4249
  if ( attachEvents && !buttonElements) {
4137
4250
  attachEvents();
4138
4251
  }
4139
-
4140
- // if not, try to find closest theme container
4252
+
4253
+ // if not, try to find closest theme container
4141
4254
  if ( !o.theme ) {
4142
- o.theme = $.mobile.getInheritedTheme( el, "c" );
4143
- }
4255
+ o.theme = $.mobile.getInheritedTheme( el, "c" );
4256
+ }
4144
4257
 
4145
4258
  buttonClass = "ui-btn ui-btn-up-" + o.theme;
4259
+ buttonClass += o.inline ? " ui-btn-inline" : "";
4260
+ buttonClass += o.shadow ? " ui-shadow" : "";
4261
+ buttonClass += o.corners ? " ui-btn-corner-all" : "";
4146
4262
 
4147
- if ( o.inline ) {
4148
- buttonClass += " ui-btn-inline";
4263
+ if ( o.mini !== undefined ) {
4264
+ // Used to control styling in headers/footers, where buttons default to `mini` style.
4265
+ buttonClass += o.mini ? " ui-mini" : " ui-fullsize";
4149
4266
  }
4150
-
4151
- if ( o.mini ) {
4152
- buttonClass += " ui-mini";
4153
- } else if ( o.mini && o.mini === false ) {
4154
- buttonClass += " ui-fullsize"; // Used to control styling in headers/footers, where buttons default to `mini` style.
4267
+
4268
+ if ( o.inline !== undefined ) {
4269
+ // Used to control styling in headers/footers, where buttons default to `mini` style.
4270
+ buttonClass += o.inline === false ? " ui-btn-block" : " ui-btn-inline";
4155
4271
  }
4156
-
4272
+
4273
+
4157
4274
  if ( o.icon ) {
4158
4275
  o.icon = "ui-icon-" + o.icon;
4159
4276
  o.iconpos = o.iconpos || "left";
@@ -4172,37 +4289,39 @@ $.fn.buttonMarkup = function( options ) {
4172
4289
  el.attr( "title", el.getEncodedText() );
4173
4290
  }
4174
4291
  }
4292
+
4293
+ innerClass += o.corners ? " ui-btn-corner-all" : "";
4175
4294
 
4176
- if ( o.corners ) {
4177
- buttonClass += " ui-btn-corner-all";
4178
- innerClass += " ui-btn-corner-all";
4295
+ if ( o.iconpos && o.iconpos === "notext" && !el.attr( "title" ) ) {
4296
+ el.attr( "title", el.getEncodedText() );
4179
4297
  }
4180
4298
 
4181
- if ( o.shadow ) {
4182
- buttonClass += " ui-shadow";
4299
+ if ( buttonElements ) {
4300
+ el.removeClass( buttonElements.bcls || "" );
4183
4301
  }
4184
-
4185
- if (buttonElements)
4186
- el.removeClass((buttonElements.bcls || ""));
4187
4302
  el.removeClass( "ui-link" ).addClass( buttonClass );
4188
4303
 
4189
4304
  buttonInner.className = innerClass;
4190
4305
 
4191
4306
  buttonText.className = textClass;
4192
- if (!buttonElements)
4307
+ if ( !buttonElements ) {
4193
4308
  buttonInner.appendChild( buttonText );
4309
+ }
4194
4310
  if ( buttonIcon ) {
4195
4311
  buttonIcon.className = iconClass;
4196
- if (!(buttonElements && buttonElements.icon))
4312
+ if ( !(buttonElements && buttonElements.icon) ) {
4313
+ buttonIcon.appendChild( document.createTextNode("\u00a0") );
4197
4314
  buttonInner.appendChild( buttonIcon );
4315
+ }
4198
4316
  }
4199
4317
 
4200
4318
  while ( e.firstChild && !buttonElements) {
4201
4319
  buttonText.appendChild( e.firstChild );
4202
4320
  }
4203
4321
 
4204
- if (!buttonElements)
4322
+ if ( !buttonElements ) {
4205
4323
  e.appendChild( buttonInner );
4324
+ }
4206
4325
 
4207
4326
  // Assign a structure containing the elements of this button to the elements of this button. This
4208
4327
  // will allow us to recognize this as an already-enhanced button in future calls to buttonMarkup().
@@ -4217,8 +4336,9 @@ $.fn.buttonMarkup = function( options ) {
4217
4336
  $.data(e, 'buttonElements', buttonElements);
4218
4337
  $.data(buttonInner, 'buttonElements', buttonElements);
4219
4338
  $.data(buttonText, 'buttonElements', buttonElements);
4220
- if (buttonIcon)
4339
+ if (buttonIcon) {
4221
4340
  $.data(buttonIcon, 'buttonElements', buttonElements);
4341
+ }
4222
4342
  }
4223
4343
 
4224
4344
  return this;
@@ -4228,7 +4348,6 @@ $.fn.buttonMarkup.defaults = {
4228
4348
  corners: true,
4229
4349
  shadow: true,
4230
4350
  iconshadow: true,
4231
- inline: false,
4232
4351
  wrapperEls: "span"
4233
4352
  };
4234
4353
 
@@ -4252,65 +4371,51 @@ function closestEnabledButton( element ) {
4252
4371
  }
4253
4372
 
4254
4373
  var attachEvents = function() {
4255
- var hoverDelay = 200,
4256
- hov, foc;
4257
- $( document ).bind( {
4258
- "vmousedown": function( event ) {
4259
- var btn = closestEnabledButton( event.target ),
4260
- $btn, theme;
4374
+ var hoverDelay = $.mobile.buttonMarkup.hoverDelay, hov, foc;
4261
4375
 
4262
- if ( btn ) {
4263
- $btn = $( btn );
4376
+ $( document ).bind( {
4377
+ "vmousedown vmousecancel vmouseup vmouseover vmouseout focus blur scrollstart": function( event ) {
4378
+ var theme,
4379
+ $btn = $( closestEnabledButton( event.target ) ),
4380
+ evt = event.type;
4381
+
4382
+ if ( $btn.length ) {
4264
4383
  theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
4265
-
4266
- if( $.support.touch ) {
4267
- hov = setTimeout(function() {
4384
+
4385
+ if ( evt === "vmousedown" ) {
4386
+ if ( $.support.touch ) {
4387
+ hov = setTimeout(function() {
4388
+ $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme );
4389
+ }, hoverDelay );
4390
+ } else {
4268
4391
  $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme );
4269
- }, hoverDelay );
4270
- } else {
4271
- $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme );
4272
- }
4273
- }
4274
- },
4275
- "vmousecancel vmouseup": function( event ) {
4276
- var btn = closestEnabledButton( event.target ),
4277
- $btn, theme;
4278
-
4279
- if ( btn ) {
4280
- $btn = $( btn );
4281
- theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
4282
- $btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
4283
- }
4284
- },
4285
- "vmouseover focus": function( event ) {
4286
- var btn = closestEnabledButton( event.target ),
4287
- $btn, theme;
4288
-
4289
- if ( btn ) {
4290
- $btn = $( btn );
4291
- theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
4292
-
4293
- if( $.support.touch ) {
4294
- foc = setTimeout(function() {
4392
+ }
4393
+ } else if ( evt === "vmousecancel" || evt === "vmouseup" ) {
4394
+ $btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
4395
+ } else if ( evt === "vmouseover" || evt === "focus" ) {
4396
+ if ( $.support.touch ) {
4397
+ foc = setTimeout(function() {
4398
+ $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme );
4399
+ }, hoverDelay );
4400
+ } else {
4295
4401
  $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme );
4296
- }, hoverDelay );
4297
- } else {
4298
- $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme );
4402
+ }
4403
+ } else if ( evt === "vmouseout" || evt === "blur" || evt === "scrollstart" ) {
4404
+ $btn.removeClass( "ui-btn-hover-" + theme + " ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
4405
+ if ( hov ) {
4406
+ clearTimeout( hov );
4407
+ }
4408
+ if ( foc ) {
4409
+ clearTimeout( foc );
4410
+ }
4299
4411
  }
4300
4412
  }
4301
4413
  },
4302
- "vmouseout blur scrollstart": function( event ) {
4303
- var btn = closestEnabledButton( event.target ),
4304
- $btn, theme;
4305
-
4306
- if ( btn ) {
4307
- $btn = $( btn );
4308
- theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
4309
- $btn.removeClass( "ui-btn-hover-" + theme + " ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
4310
-
4311
- hov && clearTimeout( hov );
4312
- foc && clearTimeout( foc );
4313
- }
4414
+ "focusin focus": function( event ){
4415
+ $( closestEnabledButton( event.target ) ).addClass( $.mobile.focusClass );
4416
+ },
4417
+ "focusout blur": function( event ){
4418
+ $( closestEnabledButton( event.target ) ).removeClass( $.mobile.focusClass );
4314
4419
  }
4315
4420
  });
4316
4421
 
@@ -4371,20 +4476,22 @@ $( document ).delegate( ":jqmData(role='page'), :jqmData(role='dialog')", "pagec
4371
4476
  // Add ARIA role
4372
4477
  .attr( "role", role === "header" ? "banner" : "contentinfo" );
4373
4478
 
4374
- // Right,left buttons
4375
- $headeranchors = $this.children( "a" );
4376
- leftbtn = $headeranchors.hasClass( "ui-btn-left" );
4377
- rightbtn = $headeranchors.hasClass( "ui-btn-right" );
4479
+ if( role === "header") {
4480
+ // Right,left buttons
4481
+ $headeranchors = $this.children( "a" );
4482
+ leftbtn = $headeranchors.hasClass( "ui-btn-left" );
4483
+ rightbtn = $headeranchors.hasClass( "ui-btn-right" );
4378
4484
 
4379
- leftbtn = leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;
4485
+ leftbtn = leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;
4380
4486
 
4381
- rightbtn = rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;
4487
+ rightbtn = rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;
4488
+ }
4382
4489
 
4383
4490
  // Auto-add back btn on pages beyond first view
4384
4491
  if ( o.addBackBtn &&
4385
4492
  role === "header" &&
4386
4493
  $( ".ui-page" ).length > 1 &&
4387
- $this.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) &&
4494
+ $page.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) &&
4388
4495
  !leftbtn ) {
4389
4496
 
4390
4497
  backBtn = $( "<a href='#' class='ui-btn-left' data-"+ $.mobile.ns +"rel='back' data-"+ $.mobile.ns +"icon='arrow-l'>"+ o.backBtnText +"</a>" )
@@ -4398,7 +4505,6 @@ $( document ).delegate( ":jqmData(role='page'), :jqmData(role='dialog')", "pagec
4398
4505
  .addClass( "ui-title" )
4399
4506
  // Regardless of h element number in src, it becomes h1 for the enhanced page
4400
4507
  .attr({
4401
- "tabindex": "0",
4402
4508
  "role": "heading",
4403
4509
  "aria-level": "1"
4404
4510
  });
@@ -4449,18 +4555,18 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
4449
4555
  if ( collapsibleSet.length ) {
4450
4556
  // Inherit the theme from collapsible-set
4451
4557
  if ( !o.theme ) {
4452
- o.theme = collapsibleSet.jqmData( "theme" );
4558
+ o.theme = collapsibleSet.jqmData("theme") || $.mobile.getInheritedTheme( collapsibleSet, "c" );
4453
4559
  }
4454
4560
  // Inherit the content-theme from collapsible-set
4455
4561
  if ( !o.contentTheme ) {
4456
4562
  o.contentTheme = collapsibleSet.jqmData( "content-theme" );
4457
4563
  }
4458
-
4459
- // Gets the preference icon position in the set
4460
- if ( !o.iconPos ) {
4461
- o.iconPos = collapsibleSet.jqmData( "iconpos" );
4462
- }
4463
-
4564
+
4565
+ // Gets the preference icon position in the set
4566
+ if ( !o.iconPos ) {
4567
+ o.iconPos = collapsibleSet.jqmData( "iconpos" );
4568
+ }
4569
+
4464
4570
  if( !o.mini ) {
4465
4571
  o.mini = collapsibleSet.jqmData( "mini" );
4466
4572
  }
@@ -4484,7 +4590,7 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
4484
4590
  mini: o.mini,
4485
4591
  theme: o.theme
4486
4592
  })
4487
- .add( ".ui-btn-inner" )
4593
+ .add( ".ui-btn-inner", $el )
4488
4594
  .addClass( "ui-corner-top ui-corner-bottom" );
4489
4595
 
4490
4596
  //events
@@ -4553,13 +4659,17 @@ $.widget( "mobile.collapsibleset", $.mobile.widget, {
4553
4659
 
4554
4660
  // Inherit the theme from collapsible-set
4555
4661
  if ( !o.theme ) {
4556
- o.theme = $el.jqmData( "theme" );
4662
+ o.theme = $.mobile.getInheritedTheme( $el, "c" );
4557
4663
  }
4558
4664
  // Inherit the content-theme from collapsible-set
4559
4665
  if ( !o.contentTheme ) {
4560
4666
  o.contentTheme = $el.jqmData( "content-theme" );
4561
4667
  }
4562
4668
 
4669
+ if ( !o.corners ) {
4670
+ o.corners = $el.jqmData( "corners" ) === undefined ? true : false;
4671
+ }
4672
+
4563
4673
  // Initialize the collapsible set if it's not already initialized
4564
4674
  if ( !$el.jqmData( "collapsiblebound" ) ) {
4565
4675
  $el
@@ -4592,6 +4702,7 @@ $.widget( "mobile.collapsibleset", $.mobile.widget, {
4592
4702
 
4593
4703
  refresh: function() {
4594
4704
  var $el = this.element,
4705
+ o = this.options,
4595
4706
  collapsiblesInSet = $el.children( ":jqmData(role='collapsible')" );
4596
4707
 
4597
4708
  $.mobile.collapsible.prototype.enhance( collapsiblesInSet.not( ".ui-collapsible" ) );
@@ -4607,7 +4718,7 @@ $.widget( "mobile.collapsibleset", $.mobile.widget, {
4607
4718
  collapsiblesInSet.first()
4608
4719
  .find( "a" )
4609
4720
  .first()
4610
- .addClass( "ui-corner-top" )
4721
+ .addClass( o.corners ? "ui-corner-top" : "" )
4611
4722
  .find( ".ui-btn-inner" )
4612
4723
  .addClass( "ui-corner-top" );
4613
4724
 
@@ -4615,7 +4726,7 @@ $.widget( "mobile.collapsibleset", $.mobile.widget, {
4615
4726
  .jqmData( "collapsible-last", true )
4616
4727
  .find( "a" )
4617
4728
  .first()
4618
- .addClass( "ui-corner-bottom" )
4729
+ .addClass( o.corners ? "ui-corner-bottom" : "" )
4619
4730
  .find( ".ui-btn-inner" )
4620
4731
  .addClass( "ui-corner-bottom" );
4621
4732
  }
@@ -4657,6 +4768,7 @@ $.widget( "mobile.navbar", $.mobile.widget, {
4657
4768
  $navbtns.buttonMarkup({
4658
4769
  corners: false,
4659
4770
  shadow: false,
4771
+ inline: true,
4660
4772
  iconpos: iconpos
4661
4773
  });
4662
4774
 
@@ -4689,6 +4801,7 @@ $( document ).bind( "pagecreate create", function( e ){
4689
4801
  var listCountPerPage = {};
4690
4802
 
4691
4803
  $.widget( "mobile.listview", $.mobile.widget, {
4804
+
4692
4805
  options: {
4693
4806
  theme: null,
4694
4807
  countTheme: "c",
@@ -4696,16 +4809,21 @@ $.widget( "mobile.listview", $.mobile.widget, {
4696
4809
  dividerTheme: "b",
4697
4810
  splitIcon: "arrow-r",
4698
4811
  splitTheme: "b",
4812
+ mini: false,
4699
4813
  inset: false,
4700
4814
  initSelector: ":jqmData(role='listview')"
4701
4815
  },
4702
4816
 
4703
4817
  _create: function() {
4704
- var t = this;
4705
-
4818
+ var t = this,
4819
+ listviewClasses = "";
4820
+
4821
+ listviewClasses += t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "";
4822
+ listviewClasses += t.element.jqmData( "mini" ) || t.options.mini === true ? " ui-mini" : "";
4823
+
4706
4824
  // create listview markup
4707
4825
  t.element.addClass(function( i, orig ) {
4708
- return orig + " ui-listview " + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" );
4826
+ return orig + " ui-listview " + listviewClasses;
4709
4827
  });
4710
4828
 
4711
4829
  t.refresh( true );
@@ -4835,12 +4953,12 @@ $.widget( "mobile.listview", $.mobile.widget, {
4835
4953
  counter = $.support.cssPseudoElement || !$.nodeName( $list[ 0 ], "ol" ) ? 0 : 1,
4836
4954
  itemClassDict = {},
4837
4955
  item, itemClass, itemTheme,
4838
- a, last, splittheme, countParent, icon, imgParents, img;
4956
+ a, last, splittheme, countParent, icon, imgParents, img, linkIcon;
4839
4957
 
4840
4958
  if ( counter ) {
4841
4959
  $list.find( ".ui-li-dec" ).remove();
4842
4960
  }
4843
-
4961
+
4844
4962
  if ( !o.theme ) {
4845
4963
  o.theme = $.mobile.getInheritedTheme( this.element, "c" );
4846
4964
  }
@@ -4877,6 +4995,7 @@ $.widget( "mobile.listview", $.mobile.widget, {
4877
4995
 
4878
4996
  last = a.last();
4879
4997
  splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme;
4998
+ linkIcon = last.jqmData("icon");
4880
4999
 
4881
5000
  last.appendTo(item)
4882
5001
  .attr( "title", last.getEncodedText() )
@@ -4896,13 +5015,14 @@ $.widget( "mobile.listview", $.mobile.widget, {
4896
5015
  corners: true,
4897
5016
  theme: splittheme,
4898
5017
  iconpos: "notext",
4899
- icon: listspliticon || last.jqmData( "icon" ) || o.splitIcon
5018
+ // link icon overrides list item icon overrides ul element overrides options
5019
+ icon: linkIcon || icon || listspliticon || o.splitIcon
4900
5020
  })
4901
5021
  );
4902
5022
  }
4903
5023
  } else if ( item.jqmData( "role" ) === "list-divider" ) {
4904
5024
 
4905
- itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme;
5025
+ itemClass += " ui-li-divider ui-bar-" + dividertheme;
4906
5026
  item.attr( "role", "heading" );
4907
5027
 
4908
5028
  //reset counter when a divider heading is encountered
@@ -5091,14 +5211,19 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5091
5211
  _create: function() {
5092
5212
  var self = this,
5093
5213
  input = this.element,
5214
+ inheritAttr = function( input, dataAttr ) {
5215
+ return input.jqmData( dataAttr ) || input.closest( "form,fieldset" ).jqmData( dataAttr )
5216
+ },
5094
5217
  // NOTE: Windows Phone could not find the label through a selector
5095
5218
  // filter works though.
5096
- label = $( input ).closest( "form,fieldset,:jqmData(role='page'),:jqmData(role='dialog')" ).find( "label" ).filter( "[for='" + input[ 0 ].id + "']" ),
5097
- inputtype = input.attr( "type" ),
5098
- mini = input.closest( "form,fieldset" ).jqmData('mini'),
5219
+ parentLabel = $( input ).closest( "label" ),
5220
+ label = parentLabel.length ? parentLabel : $( input ).closest( "form,fieldset,:jqmData(role='page'),:jqmData(role='dialog')" ).find( "label" ).filter( "[for='" + input[0].id + "']" ),
5221
+ inputtype = input[0].type,
5222
+ mini = inheritAttr( input, "mini" ),
5099
5223
  checkedState = inputtype + "-on",
5100
5224
  uncheckedState = inputtype + "-off",
5101
5225
  icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState,
5226
+ iconpos = inheritAttr( input, "iconpos" ),
5102
5227
  activeBtn = icon ? "" : " " + $.mobile.activeBtnClass,
5103
5228
  checkedClass = "ui-" + checkedState + activeBtn,
5104
5229
  uncheckedClass = "ui-" + uncheckedState,
@@ -5119,24 +5244,24 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5119
5244
  uncheckedicon: uncheckedicon
5120
5245
  });
5121
5246
 
5122
- // If there's no selected theme...
5247
+ // If there's no selected theme check the data attr
5123
5248
  if( !this.options.theme ) {
5124
- this.options.theme = this.element.jqmData( "theme" );
5249
+ this.options.theme = $.mobile.getInheritedTheme( this.element, "c" );
5125
5250
  }
5126
5251
 
5127
5252
  label.buttonMarkup({
5128
5253
  theme: this.options.theme,
5129
5254
  icon: icon,
5130
5255
  shadow: false,
5131
- mini: mini
5256
+ mini: mini,
5257
+ iconpos: iconpos
5132
5258
  });
5133
5259
 
5134
5260
  // Wrap the input + label in a div
5135
- var wrapper = document.createElement('div');
5136
- wrapper.className = 'ui-' + inputtype;
5137
- input[0].parentNode.insertBefore(wrapper,input[0]);
5138
- wrapper.appendChild(input[0]);
5139
- wrapper.appendChild(label[0]);
5261
+ var wrapper = document.createElement('div');
5262
+ wrapper.className = 'ui-' + inputtype;
5263
+
5264
+ input.add( label ).wrapAll( wrapper );
5140
5265
 
5141
5266
  label.bind({
5142
5267
  vmouseover: function( event ) {
@@ -5152,8 +5277,8 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5152
5277
  }
5153
5278
 
5154
5279
  self._cacheVals();
5155
- input.attr( "checked", inputtype === "radio" && true || !input.attr( "checked" ) );
5156
- //input.prop( "checked", inputtype === "radio" && true || !input.attr( "checked" ) );
5280
+
5281
+ input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );
5157
5282
 
5158
5283
  // trigger click handler's bound directly to the input as a substitute for
5159
5284
  // how label clicks behave normally in the browsers
@@ -5165,12 +5290,11 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5165
5290
  // Input set for common radio buttons will contain all the radio
5166
5291
  // buttons, but will not for checkboxes. clearing the checked status
5167
5292
  // of other radios ensures the active button state is applied properly
5168
- self._getInputSet().not( input ).removeAttr( "checked" );
5293
+ self._getInputSet().not( input ).prop( "checked", false );
5169
5294
 
5170
5295
  self._updateAll();
5171
5296
  return false;
5172
5297
  }
5173
-
5174
5298
  });
5175
5299
 
5176
5300
  input
@@ -5185,11 +5309,11 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5185
5309
  // Adds checked attribute to checked input when keyboard is used
5186
5310
  if ( $this.is( ":checked" ) ) {
5187
5311
 
5188
- $this.attr( "checked", "checked" );
5189
- self._getInputSet().not($this).removeAttr( "checked" );
5312
+ $this.prop( "checked", true);
5313
+ self._getInputSet().not($this).prop( "checked", false );
5190
5314
  } else {
5191
5315
 
5192
- $this.removeAttr( "checked" );
5316
+ $this.prop( "checked", false );
5193
5317
  }
5194
5318
 
5195
5319
  self._updateAll();
@@ -5209,20 +5333,18 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5209
5333
 
5210
5334
  _cacheVals: function() {
5211
5335
  this._getInputSet().each(function() {
5212
- var $this = $(this);
5213
-
5214
- $this.jqmData( "cacheVal", $this.is( ":checked" ) );
5336
+ $(this).jqmData( "cacheVal", this.checked );
5215
5337
  });
5216
5338
  },
5217
5339
 
5218
5340
  //returns either a set of radios with the same name attribute, or a single checkbox
5219
5341
  _getInputSet: function(){
5220
- if(this.inputtype == "checkbox") {
5342
+ if(this.inputtype === "checkbox") {
5221
5343
  return this.element;
5222
5344
  }
5223
5345
 
5224
5346
  return this.element.closest( "form,fieldset,:jqmData(role='page')" )
5225
- .find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" );
5347
+ .find( "input[name='"+ this.element[0].name +"'][type='"+ this.inputtype +"']" );
5226
5348
  },
5227
5349
 
5228
5350
  _updateAll: function() {
@@ -5231,9 +5353,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5231
5353
  this._getInputSet().each(function() {
5232
5354
  var $this = $(this);
5233
5355
 
5234
- // NOTE getAttribute is used here to deal with an issue with the :checked
5235
- // selector. see #3597
5236
- if ( this.getAttribute( "checked" ) || self.inputtype === "checkbox" ) {
5356
+ if ( this.checked || self.inputtype === "checkbox" ) {
5237
5357
  $this.trigger( "change" );
5238
5358
  }
5239
5359
  })
@@ -5241,14 +5361,11 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5241
5361
  },
5242
5362
 
5243
5363
  refresh: function() {
5244
- var input = this.element,
5364
+ var input = this.element[0],
5245
5365
  label = this.label,
5246
5366
  icon = label.find( ".ui-icon" );
5247
5367
 
5248
- // input[0].checked expando doesn't always report the proper value
5249
- // for checked='checked'
5250
-
5251
- if ( input[ 0 ].getAttribute( "checked" ) ) {
5368
+ if ( input.checked ) {
5252
5369
  label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
5253
5370
  icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );
5254
5371
  } else {
@@ -5256,7 +5373,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5256
5373
  icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
5257
5374
  }
5258
5375
 
5259
- if ( input.is( ":disabled" ) ) {
5376
+ if ( input.disabled ) {
5260
5377
  this.disable();
5261
5378
  } else {
5262
5379
  this.enable();
@@ -5264,7 +5381,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
5264
5381
  },
5265
5382
 
5266
5383
  disable: function() {
5267
- this.element.attr( "disabled", true ).parent().addClass( "ui-disabled" );
5384
+ this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
5268
5385
  },
5269
5386
 
5270
5387
  enable: function() {
@@ -5286,7 +5403,7 @@ $.widget( "mobile.button", $.mobile.widget, {
5286
5403
  theme: null,
5287
5404
  icon: null,
5288
5405
  iconpos: null,
5289
- inline: null,
5406
+ inline: false,
5290
5407
  corners: true,
5291
5408
  shadow: true,
5292
5409
  iconshadow: true,
@@ -5307,8 +5424,13 @@ $.widget( "mobile.button", $.mobile.widget, {
5307
5424
  !$el.hasClass( "ui-btn" ) && $el.buttonMarkup();
5308
5425
  return;
5309
5426
  }
5310
-
5311
-
5427
+
5428
+ // get the inherited theme
5429
+ // TODO centralize for all widgets
5430
+ if ( !this.options.theme ) {
5431
+ this.options.theme = $.mobile.getInheritedTheme( this.element, "c" );
5432
+ }
5433
+
5312
5434
  // TODO: Post 1.1--once we have time to test thoroughly--any classes manually applied to the original element should be carried over to the enhanced element, with an `-enhanced` suffix. See https://github.com/jquery/jquery-mobile/issues/3577
5313
5435
  /* if( $el[0].className.length ) {
5314
5436
  classes = $el[0].className;
@@ -5316,7 +5438,7 @@ $.widget( "mobile.button", $.mobile.widget, {
5316
5438
  if( !!~$el[0].className.indexOf( "ui-btn-left" ) ) {
5317
5439
  classes = "ui-btn-left";
5318
5440
  }
5319
-
5441
+
5320
5442
  if( !!~$el[0].className.indexOf( "ui-btn-right" ) ) {
5321
5443
  classes = "ui-btn-right";
5322
5444
  }
@@ -5399,8 +5521,8 @@ $.widget( "mobile.button", $.mobile.widget, {
5399
5521
  this.enable();
5400
5522
  }
5401
5523
 
5402
- // Grab the button's text element from its implementation-independent data item
5403
- $(this.button.data( 'buttonElements' ).text).text( $el.text() || $el.val() );
5524
+ // Grab the button's text element from its implementation-independent data item
5525
+ $( this.button.data( 'buttonElements' ).text ).text( $el.text() || $el.val() );
5404
5526
  }
5405
5527
  });
5406
5528
 
@@ -5480,28 +5602,31 @@ $( document ).bind( "pagecreate create", function( e ){
5480
5602
  var meta = $( "meta[name=viewport]" ),
5481
5603
  initialContent = meta.attr( "content" ),
5482
5604
  disabledZoom = initialContent + ",maximum-scale=1, user-scalable=no",
5483
- enabledZoom = initialContent + ",maximum-scale=10, user-scalable=yes";
5605
+ enabledZoom = initialContent + ",maximum-scale=10, user-scalable=yes",
5606
+ disabledInitially = /(user-scalable[\s]*=[\s]*no)|(maximum-scale[\s]*=[\s]*1)[$,\s]/.test( initialContent );
5484
5607
 
5485
5608
  $.mobile.zoom = $.extend( {}, {
5486
- enabled: true,
5609
+ enabled: !disabledInitially,
5487
5610
  locked: false,
5488
5611
  disable: function( lock ) {
5489
- if( !$.mobile.zoom.locked ){
5612
+ if( !disabledInitially && !$.mobile.zoom.locked ){
5490
5613
  meta.attr( "content", disabledZoom );
5491
5614
  $.mobile.zoom.enabled = false;
5492
5615
  $.mobile.zoom.locked = lock || false;
5493
5616
  }
5494
5617
  },
5495
5618
  enable: function( unlock ) {
5496
- if( !$.mobile.zoom.locked || unlock ){
5619
+ if( !disabledInitially && ( !$.mobile.zoom.locked || unlock === true ) ){
5497
5620
  meta.attr( "content", enabledZoom );
5498
5621
  $.mobile.zoom.enabled = true;
5499
5622
  $.mobile.zoom.locked = false;
5500
5623
  }
5501
5624
  },
5502
5625
  restore: function() {
5503
- meta.attr( "content", initialContent );
5504
- $.mobile.zoom.enabled = true;
5626
+ if( !disabledInitially ){
5627
+ meta.attr( "content", initialContent );
5628
+ $.mobile.zoom.enabled = true;
5629
+ }
5505
5630
  }
5506
5631
  });
5507
5632
 
@@ -5514,7 +5639,8 @@ $.widget( "mobile.textinput", $.mobile.widget, {
5514
5639
  theme: null,
5515
5640
  // This option defaults to true on iOS devices.
5516
5641
  preventFocusZoom: /iPhone|iPad|iPod/.test( navigator.platform ) && navigator.userAgent.indexOf( "AppleWebKit" ) > -1,
5517
- initSelector: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type])"
5642
+ initSelector: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type])",
5643
+ clearSearchButtonText: "clear text"
5518
5644
  },
5519
5645
 
5520
5646
  _create: function() {
@@ -5550,10 +5676,12 @@ $.widget( "mobile.textinput", $.mobile.widget, {
5550
5676
  if ( input.is( "[type='search'],:jqmData(type='search')" ) ) {
5551
5677
 
5552
5678
  focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield" + themeclass + miniclass + "'></div>" ).parent();
5553
- clearbtn = $( "<a href='#' class='ui-input-clear' title='clear text'>clear text</a>" )
5554
- .tap(function( event ) {
5555
- input.val( "" ).focus();
5556
- input.trigger( "change" );
5679
+ clearbtn = $( "<a href='#' class='ui-input-clear' title='" + o.clearSearchButtonText + "'>" + o.clearSearchButtonText + "</a>" )
5680
+ .bind('click', function( event ) {
5681
+ input
5682
+ .val( "" )
5683
+ .focus()
5684
+ .trigger( "change" );
5557
5685
  clearbtn.addClass( "ui-input-clear-hidden" );
5558
5686
  event.preventDefault();
5559
5687
  })
@@ -5745,7 +5873,7 @@ $( document ).delegate( ":jqmData(role='listview')", "listviewcreate", function(
5745
5873
  .appendTo( wrapper )
5746
5874
  .textinput();
5747
5875
 
5748
- if ( $( this ).jqmData( "inset" ) ) {
5876
+ if ( listview.options.inset ) {
5749
5877
  wrapper.addClass( "ui-listview-filter-inset" );
5750
5878
  }
5751
5879
 
@@ -6173,11 +6301,10 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
6173
6301
  disabled: false,
6174
6302
  icon: "arrow-d",
6175
6303
  iconpos: "right",
6176
- inline: null,
6304
+ inline: false,
6177
6305
  corners: true,
6178
6306
  shadow: true,
6179
6307
  iconshadow: true,
6180
- menuPageTheme: "b",
6181
6308
  overlayTheme: "a",
6182
6309
  hidePlaceholderMenuItems: true,
6183
6310
  closeText: "Close",
@@ -6442,16 +6569,17 @@ $( document ).bind( "pagecreate create", function( e ){
6442
6569
  "class": "ui-title"
6443
6570
  }).appendTo( header ),
6444
6571
 
6572
+ menuPageContent,
6573
+ menuPageClose,
6574
+ headerClose;
6575
+
6576
+ if( widget.isMultiple ) {
6445
6577
  headerClose = $( "<a>", {
6446
6578
  "text": widget.options.closeText,
6447
6579
  "href": "#",
6448
6580
  "class": "ui-btn-left"
6449
- }).attr( "data-" + $.mobile.ns + "iconpos", "notext" ).attr( "data-" + $.mobile.ns + "icon", "delete" ).appendTo( header ).buttonMarkup(),
6450
-
6451
- menuPageContent,
6452
-
6453
- menuPageClose;
6454
-
6581
+ }).attr( "data-" + $.mobile.ns + "iconpos", "notext" ).attr( "data-" + $.mobile.ns + "icon", "delete" ).appendTo( header ).buttonMarkup();
6582
+ }
6455
6583
 
6456
6584
  $.extend( widget, {
6457
6585
  select: widget.select,
@@ -6502,7 +6630,7 @@ $( document ).bind( "pagecreate create", function( e ){
6502
6630
  $( e.target )
6503
6631
  .attr( "tabindex", "0" )
6504
6632
  .trigger( "vmouseover" );
6505
-
6633
+
6506
6634
  })
6507
6635
  .bind( "focusout", function( e ){
6508
6636
  $( e.target )
@@ -6547,7 +6675,11 @@ $( document ).bind( "pagecreate create", function( e ){
6547
6675
  switch ( event.keyCode ) {
6548
6676
  // up or left arrow keys
6549
6677
  case 38:
6550
- prev = li.prev();
6678
+ prev = li.prev().not( ".ui-selectmenu-placeholder" );
6679
+
6680
+ if( prev.is( ".ui-li-divider" ) ) {
6681
+ prev = prev.prev();
6682
+ }
6551
6683
 
6552
6684
  // if there's a previous option, focus it
6553
6685
  if ( prev.length ) {
@@ -6555,7 +6687,7 @@ $( document ).bind( "pagecreate create", function( e ){
6555
6687
  .blur()
6556
6688
  .attr( "tabindex", "-1" );
6557
6689
 
6558
- prev.find( "a" ).first().focus();
6690
+ prev.addClass( "ui-btn-down-" + widget.options.theme ).find( "a" ).first().focus();
6559
6691
  }
6560
6692
 
6561
6693
  return false;
@@ -6565,13 +6697,17 @@ $( document ).bind( "pagecreate create", function( e ){
6565
6697
  case 40:
6566
6698
  next = li.next();
6567
6699
 
6700
+ if( next.is( ".ui-li-divider" ) ) {
6701
+ next = next.next();
6702
+ }
6703
+
6568
6704
  // if there's a next option, focus it
6569
6705
  if ( next.length ) {
6570
6706
  target
6571
6707
  .blur()
6572
6708
  .attr( "tabindex", "-1" );
6573
6709
 
6574
- next.find( "a" ).first().focus();
6710
+ next.addClass( "ui-btn-down-" + widget.options.theme ).find( "a" ).first().focus();
6575
6711
  }
6576
6712
 
6577
6713
  return false;
@@ -6614,12 +6750,14 @@ $( document ).bind( "pagecreate create", function( e ){
6614
6750
  });
6615
6751
 
6616
6752
  // Close button on small overlays
6617
- self.headerClose.click( function() {
6618
- if ( self.menuType == "overlay" ) {
6619
- self.close();
6620
- return false;
6621
- }
6622
- });
6753
+ if( self.isMultiple ){
6754
+ self.headerClose.click( function() {
6755
+ if ( self.menuType == "overlay" ) {
6756
+ self.close();
6757
+ return false;
6758
+ }
6759
+ });
6760
+ }
6623
6761
 
6624
6762
  // track this dependency so that when the parent page
6625
6763
  // is removed on pagehide it will also remove the menupage
@@ -6667,7 +6805,11 @@ $( document ).bind( "pagecreate create", function( e ){
6667
6805
  if ( self.isMultiple ) {
6668
6806
  item.find( ".ui-icon" ).removeClass( "ui-icon-checkbox-off" ).addClass( "ui-icon-checkbox-on" );
6669
6807
  } else {
6670
- item.addClass( $.mobile.activeBtnClass );
6808
+ if( item.is( ".ui-selectmenu-placeholder" ) ) {
6809
+ item.next().addClass( $.mobile.activeBtnClass );
6810
+ } else {
6811
+ item.addClass( $.mobile.activeBtnClass );
6812
+ }
6671
6813
  }
6672
6814
  }
6673
6815
  });
@@ -6726,11 +6868,11 @@ $( document ).bind( "pagecreate create", function( e ){
6726
6868
  }
6727
6869
 
6728
6870
  if ( menuHeight > screenHeight - 80 || !$.support.scrollTop ) {
6729
-
6730
- self.menuPage.appendTo( $.mobile.pageContainer ).page();
6871
+
6872
+ self.menuPage.appendTo( $.mobile.pageContainer ).page();
6731
6873
  self.menuPageContent = menuPage.find( ".ui-content" );
6732
6874
  self.menuPageClose = menuPage.find( ".ui-header a" );
6733
-
6875
+
6734
6876
  // prevent the parent page from being removed from the DOM,
6735
6877
  // otherwise the results of selecting a list item in the dialog
6736
6878
  // fall into a black hole
@@ -6744,15 +6886,7 @@ $( document ).bind( "pagecreate create", function( e ){
6744
6886
  }
6745
6887
 
6746
6888
  self.menuPage.one( "pageshow", function() {
6747
- // silentScroll() is called whenever a page is shown to restore
6748
- // any previous scroll position the page may have had. We need to
6749
- // wait for the "silentscroll" event before setting focus to avoid
6750
- // the browser"s "feature" which offsets rendering to make sure
6751
- // whatever has focus is in view.
6752
- $( window ).one( "silentscroll", function() {
6753
- focusMenuItem();
6754
- });
6755
-
6889
+ focusMenuItem();
6756
6890
  self.isOpen = true;
6757
6891
  });
6758
6892
 
@@ -6817,6 +6951,7 @@ $( document ).bind( "pagecreate create", function( e ){
6817
6951
  var self = this,
6818
6952
  o = this.options,
6819
6953
  placeholder = this.placeholder,
6954
+ needPlaceholder = true,
6820
6955
  optgroups = [],
6821
6956
  lis = [],
6822
6957
  dataIcon = self.isMultiple ? "checkbox-off" : "false";
@@ -6824,30 +6959,30 @@ $( document ).bind( "pagecreate create", function( e ){
6824
6959
  self.list.empty().filter( ".ui-listview" ).listview( "destroy" );
6825
6960
 
6826
6961
  var $options = self.select.find("option"),
6827
- numOptions = $options.length,
6828
- select = this.select[ 0 ],
6829
- dataPrefix = 'data-' + $.mobile.ns,
6830
- dataIndexAttr = dataPrefix + 'option-index',
6962
+ numOptions = $options.length,
6963
+ select = this.select[ 0 ],
6964
+ dataPrefix = 'data-' + $.mobile.ns,
6965
+ dataIndexAttr = dataPrefix + 'option-index',
6831
6966
  dataIconAttr = dataPrefix + 'icon',
6832
6967
  dataRoleAttr = dataPrefix + 'role',
6833
6968
  fragment = document.createDocumentFragment(),
6834
6969
  optGroup;
6835
-
6836
- for (var i = 0; i < numOptions;i++){
6970
+
6971
+ for (var i = 0; i < numOptions;i++){
6837
6972
  var option = $options[i],
6838
6973
  $option = $(option),
6839
6974
  parent = option.parentNode,
6840
- text = $option.text(),
6841
- anchor = document.createElement('a');
6842
- classes = [];
6843
-
6844
- anchor.setAttribute('href','#');
6845
- anchor.appendChild(document.createTextNode(text));
6846
-
6847
- // Are we inside an optgroup?
6975
+ text = $option.text(),
6976
+ anchor = document.createElement('a'),
6977
+ classes = [];
6978
+
6979
+ anchor.setAttribute('href','#');
6980
+ anchor.appendChild(document.createTextNode(text));
6981
+
6982
+ // Are we inside an optgroup?
6848
6983
  if (parent !== select && parent.nodeName.toLowerCase() === "optgroup"){
6849
6984
  var optLabel = parent.getAttribute('label');
6850
- if ( optLabel != optGroup) {
6985
+ if ( optLabel != optGroup) {
6851
6986
  var divider = document.createElement('li');
6852
6987
  divider.setAttribute(dataRoleAttr,'list-divider');
6853
6988
  divider.setAttribute('role','option');
@@ -6856,36 +6991,34 @@ $( document ).bind( "pagecreate create", function( e ){
6856
6991
  fragment.appendChild(divider);
6857
6992
  optGroup = optLabel;
6858
6993
  }
6859
- }
6860
-
6861
- if (!placeholder && (!option.getAttribute( "value" ) || text.length == 0 || $option.jqmData( "placeholder" )) ) {
6994
+ }
6995
+
6996
+ if (needPlaceholder && (!option.getAttribute( "value" ) || text.length == 0 || $option.jqmData( "placeholder" ))) {
6997
+ needPlaceholder = false;
6862
6998
  if ( o.hidePlaceholderMenuItems ) {
6863
6999
  classes.push( "ui-selectmenu-placeholder" );
6864
- }
6865
- placeholder = self.placeholder = text;
7000
+ }
7001
+ if (!placeholder) {
7002
+ placeholder = self.placeholder = text;
7003
+ }
6866
7004
  }
6867
-
6868
- var item = document.createElement('li');
7005
+
7006
+ var item = document.createElement('li');
6869
7007
  if ( option.disabled ) {
6870
7008
  classes.push( "ui-disabled" );
6871
7009
  item.setAttribute('aria-disabled',true);
6872
7010
  }
6873
7011
  item.setAttribute(dataIndexAttr,i);
6874
- item.setAttribute(dataIconAttr,dataIcon);
7012
+ item.setAttribute(dataIconAttr,dataIcon);
6875
7013
  item.className = classes.join(" ");
6876
7014
  item.setAttribute('role','option');
6877
7015
  anchor.setAttribute('tabindex','-1');
6878
- item.appendChild(anchor);
7016
+ item.appendChild(anchor);
6879
7017
  fragment.appendChild(item);
6880
- }
7018
+ }
6881
7019
 
6882
7020
  self.list[0].appendChild(fragment);
6883
7021
 
6884
- // Hide header close link for single selects
6885
- if ( !this.isMultiple ) {
6886
- this.headerClose.hide();
6887
- }
6888
-
6889
7022
  // Hide header if it's not a multiselect and there's no placeholder
6890
7023
  if ( !this.isMultiple && !placeholder.length ) {
6891
7024
  this.header.hide();
@@ -6912,8 +7045,9 @@ $( document ).bind( "pagecreate create", function( e ){
6912
7045
  });
6913
7046
  };
6914
7047
 
6915
- $( document ).delegate( "select", "selectmenubeforecreate", function(){
6916
- var selectmenuWidget = $( this ).data( "selectmenu" );
7048
+ // issue #3894 - core doesn't triggered events on disabled delegates
7049
+ $( document ).bind( "selectmenubeforecreate", function( event ){
7050
+ var selectmenuWidget = $( event.target ).data( "selectmenu" );
6917
7051
 
6918
7052
  if( !selectmenuWidget.options.nativeMenu ){
6919
7053
  extendSelect( selectmenuWidget );
@@ -6951,11 +7085,9 @@ $( document ).bind( "pagecreate create", function( e ){
6951
7085
  wkversion = !!wkmatch && wkmatch[ 1 ],
6952
7086
  ffmatch = ua.match( /Fennec\/([0-9]+)/ ),
6953
7087
  ffversion = !!ffmatch && ffmatch[ 1 ],
6954
- operammobilematch = ua.match( /Opera Mobile\/([0-9]+)/ ),
6955
- bbmatch = w.blackberry && w.navigator.appVersion.match( /Version\/([0-9]+)/ ),
6956
- bbversion = !!bbmatch && parseInt( bbmatch[ 1 ], 10 ),
7088
+ operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ ),
6957
7089
  omversion = !!operammobilematch && operammobilematch[ 1 ];
6958
-
7090
+
6959
7091
  if(
6960
7092
  // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
6961
7093
  ( ( platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1 || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534 )
@@ -6963,7 +7095,7 @@ $( document ).bind( "pagecreate create", function( e ){
6963
7095
  // Opera Mini
6964
7096
  ( w.operamini && ({}).toString.call( w.operamini ) === "[object OperaMini]" )
6965
7097
  ||
6966
- ( operammobilematch && omverson < 7458 )
7098
+ ( operammobilematch && omversion < 7458 )
6967
7099
  ||
6968
7100
  //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
6969
7101
  ( ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533 )
@@ -6974,9 +7106,6 @@ $( document ).bind( "pagecreate create", function( e ){
6974
7106
  // WebOS less than 3
6975
7107
  ( "palmGetResource" in window && wkversion && wkversion < 534 )
6976
7108
  ||
6977
- // BlackBerry six and below.
6978
- ( w.blackberry && bbversion < 7 )
6979
- ||
6980
7109
  // MeeGo
6981
7110
  ( ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1 )
6982
7111
  ){
@@ -6993,7 +7122,7 @@ $( document ).bind( "pagecreate create", function( e ){
6993
7122
  var self = this,
6994
7123
  o = self.options,
6995
7124
  $el = self.element,
6996
- tbtype = $el.is( ".ui-header" ) ? "header" : "footer",
7125
+ tbtype = $el.is( ":jqmData(role='header')" ) ? "header" : "footer",
6997
7126
  $page = $el.closest(".ui-page");
6998
7127
 
6999
7128
  // Feature detecting support for
@@ -7005,7 +7134,7 @@ $( document ).bind( "pagecreate create", function( e ){
7005
7134
  $el.addClass( "ui-"+ tbtype +"-fixed" );
7006
7135
 
7007
7136
  // "fullscreen" overlay positioning
7008
- if( $el.jqmData( "fullscreen" ) ){
7137
+ if( o.fullscreen ){
7009
7138
  $el.addClass( "ui-"+ tbtype +"-fullscreen" );
7010
7139
  $page.addClass( "ui-page-" + tbtype + "-fullscreen" );
7011
7140
  }
@@ -7045,8 +7174,8 @@ $( document ).bind( "pagecreate create", function( e ){
7045
7174
  if( o.disablePageZoom ){
7046
7175
  $.mobile.zoom.disable( true );
7047
7176
  }
7048
- if( o.visibleOnPageShow ){
7049
- self.show( true );
7177
+ if( !o.visibleOnPageShow ){
7178
+ self.hide( true );
7050
7179
  }
7051
7180
  } )
7052
7181
  .bind( "webkitAnimationStart animationstart updatelayout", function(){
@@ -7076,20 +7205,21 @@ $( document ).bind( "pagecreate create", function( e ){
7076
7205
  nextFooter = thisFooter.length && ui.nextPage && $( ".ui-footer-fixed:jqmData(id='" + thisFooter.jqmData( "id" ) + "')", ui.nextPage ),
7077
7206
  nextHeader = thisHeader.length && ui.nextPage && $( ".ui-header-fixed:jqmData(id='" + thisHeader.jqmData( "id" ) + "')", ui.nextPage );
7078
7207
 
7208
+ nextFooter = nextFooter || $();
7209
+
7079
7210
  if( nextFooter.length || nextHeader.length ){
7080
7211
 
7081
7212
  nextFooter.add( nextHeader ).appendTo( $.mobile.pageContainer );
7082
7213
 
7083
7214
  ui.nextPage.one( "pageshow", function(){
7084
7215
  nextFooter.add( nextHeader ).appendTo( this );
7085
- } );
7216
+ });
7086
7217
  }
7087
7218
  }
7088
-
7089
7219
  });
7090
7220
  },
7091
7221
 
7092
- _visible: false,
7222
+ _visible: true,
7093
7223
 
7094
7224
  // This will set the content element's top or bottom padding equal to the toolbar's height
7095
7225
  updatePagePadding: function() {
@@ -7101,22 +7231,30 @@ $( document ).bind( "pagecreate create", function( e ){
7101
7231
 
7102
7232
  $el.closest( ".ui-page" ).css( "padding-" + ( header ? "top" : "bottom" ), $el.outerHeight() );
7103
7233
  },
7104
-
7105
- show: function( notransition ){
7106
- var hideClass = "ui-fixed-hidden",
7234
+
7235
+ _useTransition: function( notransition ){
7236
+ var $win = $( window ),
7107
7237
  $el = this.element,
7108
- $win = $( window ),
7109
7238
  scroll = $win.scrollTop(),
7110
7239
  elHeight = $el.height(),
7111
7240
  pHeight = $el.closest( ".ui-page" ).height(),
7112
- viewportHeight = Math.min( screen.height, $win.height() ),
7113
- tbtype = $el.is( ".ui-header" ) ? "header" : "footer";
7114
-
7115
- if( !notransition && ( this.options.transition && this.options.transition !== "none" &&
7116
- (
7241
+ viewportHeight = $.mobile.getScreenHeight(),
7242
+ tbtype = $el.is( ":jqmData(role='header')" ) ? "header" : "footer";
7243
+
7244
+ return !notransition &&
7245
+ ( this.options.transition && this.options.transition !== "none" &&
7246
+ (
7117
7247
  ( tbtype === "header" && !this.options.fullscreen && scroll > elHeight ) ||
7118
7248
  ( tbtype === "footer" && !this.options.fullscreen && scroll + viewportHeight < pHeight - elHeight )
7119
- ) || this.options.fullscreen ) ){
7249
+ ) || this.options.fullscreen
7250
+ );
7251
+ },
7252
+
7253
+ show: function( notransition ){
7254
+ var hideClass = "ui-fixed-hidden",
7255
+ $el = this.element;
7256
+
7257
+ if( this._useTransition( notransition ) ){
7120
7258
  $el
7121
7259
  .removeClass( "out " + hideClass )
7122
7260
  .addClass( "in" );
@@ -7130,20 +7268,10 @@ $( document ).bind( "pagecreate create", function( e ){
7130
7268
  hide: function( notransition ){
7131
7269
  var hideClass = "ui-fixed-hidden",
7132
7270
  $el = this.element,
7133
- $win = $( window ),
7134
- scroll = $win.scrollTop(),
7135
- elHeight = $el.height(),
7136
- pHeight = $el.closest( ".ui-page" ).height(),
7137
- viewportHeight = Math.min( screen.height, $win.height() ),
7138
- tbtype = $el.is( ".ui-header" ) ? "header" : "footer",
7139
7271
  // if it's a slide transition, our new transitions need the reverse class as well to slide outward
7140
7272
  outclass = "out" + ( this.options.transition === "slide" ? " reverse" : "" );
7141
7273
 
7142
- if( !notransition && ( this.options.transition && this.options.transition !== "none" &&
7143
- (
7144
- ( tbtype === "header" && !this.options.fullscreen && scroll > elHeight ) ||
7145
- ( tbtype === "footer" && !this.options.fullscreen && scroll + viewportHeight < pHeight - elHeight )
7146
- ) || this.options.fullscreen ) ){
7274
+ if( this._useTransition( notransition ) ){
7147
7275
  $el
7148
7276
  .addClass( outclass )
7149
7277
  .removeClass( "in" )
@@ -7188,9 +7316,17 @@ $( document ).bind( "pagecreate create", function( e ){
7188
7316
  });
7189
7317
 
7190
7318
  //auto self-init widgets
7191
- $( document ).bind( "pagecreate create", function( e ){
7192
- $.mobile.fixedtoolbar.prototype.enhanceWithin( e.target );
7193
- });
7319
+ $( document )
7320
+ .bind( "pagecreate create", function( e ){
7321
+
7322
+ // DEPRECATED in 1.1: support for data-fullscreen=true|false on the page element.
7323
+ // This line ensures it still works, but we recommend moving the attribute to the toolbars themselves.
7324
+ if( $( e.target ).jqmData( "fullscreen" ) ){
7325
+ $( $.mobile.fixedtoolbar.prototype.options.initSelector, e.target ).not( ":jqmData(fullscreen)" ).jqmData( "fullscreen", true );
7326
+ }
7327
+
7328
+ $.mobile.fixedtoolbar.prototype.enhanceWithin( e.target );
7329
+ });
7194
7330
 
7195
7331
  })( jQuery );
7196
7332
 
@@ -7252,8 +7388,8 @@ $( document ).bind( "pagecreate create", function( e ){
7252
7388
 
7253
7389
  // Add mobile, initial load "rendering" classes to docEl
7254
7390
  $html.addClass( "ui-mobile ui-mobile-rendering" );
7255
-
7256
- // This is a fallback. If anything goes wrong (JS errors, etc), or events don't fire,
7391
+
7392
+ // This is a fallback. If anything goes wrong (JS errors, etc), or events don't fire,
7257
7393
  // this ensures the rendering class is removed after 5 seconds, so content is visible and accessible
7258
7394
  setTimeout( hideRenderingClass, 5000 );
7259
7395
 
@@ -7261,20 +7397,26 @@ $( document ).bind( "pagecreate create", function( e ){
7261
7397
  // will not appear if $.mobile.loadingMessage is false
7262
7398
  var loaderClass = "ui-loader",
7263
7399
  $loader = $( "<div class='" + loaderClass + "'><span class='ui-icon ui-icon-loading'></span><h1></h1></div>" );
7264
-
7400
+
7265
7401
  // For non-fixed supportin browsers. Position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top
7266
7402
  function fakeFixLoader(){
7403
+ var activeBtn = $( "." + $.mobile.activeBtnClass ).first();
7404
+
7267
7405
  $loader
7268
7406
  .css({
7269
7407
  top: $.support.scrollTop && $window.scrollTop() + $window.height() / 2 ||
7270
7408
  activeBtn.length && activeBtn.offset().top || 100
7271
- });
7409
+ });
7272
7410
  }
7273
-
7411
+
7274
7412
  // check position of loader to see if it appears to be "fixed" to center
7275
7413
  // if not, use abs positioning
7276
7414
  function checkLoaderPosition(){
7277
- if( $loader.offset().top < $window.scrollTop() ){
7415
+ var offset = $loader.offset(),
7416
+ scrollTop = $window.scrollTop(),
7417
+ screenHeight = $.mobile.getScreenHeight();
7418
+
7419
+ if( offset.top < scrollTop || (offset.top - scrollTop) > screenHeight ) {
7278
7420
  $loader.addClass( "ui-loader-fakefix" );
7279
7421
  fakeFixLoader();
7280
7422
  $window
@@ -7282,24 +7424,22 @@ $( document ).bind( "pagecreate create", function( e ){
7282
7424
  .bind( "scroll", fakeFixLoader );
7283
7425
  }
7284
7426
  }
7285
-
7427
+
7286
7428
  //remove initial build class (only present on first pageshow)
7287
7429
  function hideRenderingClass(){
7288
7430
  $html.removeClass( "ui-mobile-rendering" );
7289
7431
  }
7290
-
7291
7432
 
7292
7433
  $.extend($.mobile, {
7293
7434
  // turn on/off page loading message.
7294
7435
  showPageLoadingMsg: function( theme, msgText, textonly ) {
7295
7436
  $html.addClass( "ui-loading" );
7296
-
7437
+
7297
7438
  if ( $.mobile.loadingMessage ) {
7298
- var activeBtn = $( "." + $.mobile.activeBtnClass ).first(),
7299
- theme = theme || $.mobile.loadingMessageTheme,
7300
- // text visibility from argument takes priority
7301
- textVisible = textonly || $.mobile.loadingMessageTextVisible;
7302
-
7439
+ // text visibility from argument takes priority
7440
+ var textVisible = textonly || $.mobile.loadingMessageTextVisible;
7441
+
7442
+ theme = theme || $.mobile.loadingMessageTheme,
7303
7443
 
7304
7444
  $loader
7305
7445
  .attr( "class", loaderClass + " ui-corner-all ui-body-" + ( theme || "a" ) + " ui-loader-" + ( textVisible ? "verbose" : "default" ) + ( textonly ? " ui-loader-textonly" : "" ) )
@@ -7307,7 +7447,7 @@ $( document ).bind( "pagecreate create", function( e ){
7307
7447
  .text( msgText || $.mobile.loadingMessage )
7308
7448
  .end()
7309
7449
  .appendTo( $.mobile.pageContainer );
7310
-
7450
+
7311
7451
  checkLoaderPosition();
7312
7452
  $window.bind( "scroll", checkLoaderPosition );
7313
7453
  }
@@ -7315,24 +7455,25 @@ $( document ).bind( "pagecreate create", function( e ){
7315
7455
 
7316
7456
  hidePageLoadingMsg: function() {
7317
7457
  $html.removeClass( "ui-loading" );
7318
-
7458
+
7319
7459
  if( $.mobile.loadingMessage ){
7320
7460
  $loader.removeClass( "ui-loader-fakefix" );
7321
7461
  }
7322
-
7462
+
7323
7463
  $( window ).unbind( "scroll", fakeFixLoader );
7464
+ $( window ).unbind( "scroll", checkLoaderPosition );
7324
7465
  },
7325
7466
 
7326
7467
  // find and enhance the pages in the dom and transition to the first page.
7327
7468
  initializePage: function() {
7328
7469
  // find present pages
7329
7470
  var $pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" );
7330
-
7471
+
7331
7472
  // if no pages are found, create one with body's inner html
7332
7473
  if ( !$pages.length ) {
7333
7474
  $pages = $( "body" ).wrapInner( "<div data-" + $.mobile.ns + "role='page'></div>" ).children( 0 );
7334
7475
  }
7335
-
7476
+
7336
7477
  // add dialogs, set data-url attrs
7337
7478
  $pages.each(function() {
7338
7479
  var $this = $(this);
@@ -7355,7 +7496,7 @@ $( document ).bind( "pagecreate create", function( e ){
7355
7496
 
7356
7497
  // cue page loading message
7357
7498
  $.mobile.showPageLoadingMsg();
7358
-
7499
+
7359
7500
  //remove initial build class (only present on first pageshow)
7360
7501
  hideRenderingClass();
7361
7502