jquery_mobile_rails 1.0.3 → 1.0.4

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 (33) hide show
  1. data/README.rdoc +1 -1
  2. data/lib/jquery_mobile_rails/version.rb +1 -1
  3. data/test/dummy/db/development.sqlite3 +0 -0
  4. data/test/dummy/log/development.log +470 -0
  5. data/test/dummy/tmp/cache/assets/C8E/8B0/sprockets%2F52156458f704751589bb6d29ec84a52e +0 -0
  6. data/test/dummy/tmp/cache/assets/CB1/D10/sprockets%2F5827a2184097ddeeb4158ef641f00085 +0 -0
  7. data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  8. data/test/dummy/tmp/cache/assets/CDE/910/sprockets%2F8af59305547610b5be0e9e038bb58f21 +0 -0
  9. data/test/dummy/tmp/cache/assets/D20/330/sprockets%2Fe76bd3b1395773eefc19cb17743e5846 +0 -0
  10. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  11. data/test/dummy/tmp/cache/assets/D38/BD0/sprockets%2Ffe52d2d1bcf248d028108d0c513e6d79 +0 -0
  12. data/test/dummy/tmp/cache/assets/D40/4D0/sprockets%2F20f705b59cf5abf8a0a7938b887b11f1 +0 -0
  13. data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  14. data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  15. data/test/dummy/tmp/cache/assets/D5F/7B0/sprockets%2F1792255ae34105be22fabed9ba5e4d15 +0 -0
  16. data/test/dummy/tmp/cache/assets/D6C/7A0/sprockets%2Ff25aa7e262f1ff93154f29dc914afc20 +0 -0
  17. data/test/dummy/tmp/cache/assets/D9B/360/sprockets%2Fbb7052d2ba9883c28d4db137e1fb9b6c +0 -0
  18. data/test/dummy/tmp/cache/assets/DB7/390/sprockets%2Ff800b3c4a4a306067fea026fc7b2bbde +0 -0
  19. data/test/dummy/tmp/cache/assets/DDC/0B0/sprockets%2F63d8cfc5e184b372b7ec77cca69d4db7 +0 -0
  20. data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  21. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  22. data/test/dummy/tmp/cache/assets/E08/030/sprockets%2F21255d26ce8eda2e2e0e69dfbea8cf99 +0 -0
  23. data/test/dummy/tmp/cache/assets/E1F/BB0/sprockets%2F222d4a2c95dbe3c58acdb1df2a04bff9 +0 -0
  24. data/test/dummy/tmp/cache/assets/E9D/620/sprockets%2Fcbde7d2f6466ed4a7dddefc773f63eae +0 -0
  25. data/vendor/assets/images/jquery-mobile/icons-18-black.png +0 -0
  26. data/vendor/assets/images/jquery-mobile/icons-36-black.png +0 -0
  27. data/vendor/assets/javascripts/jquery.mobile.js +245 -77
  28. data/vendor/assets/javascripts/jquery.mobile.min.js +123 -117
  29. data/vendor/assets/stylesheets/jquery.mobile.css.scss +42 -42
  30. data/vendor/assets/stylesheets/jquery.mobile.min.css.scss +1 -1
  31. data/vendor/assets/stylesheets/jquery.mobile.structure.css +33 -11
  32. data/vendor/assets/stylesheets/jquery.mobile.structure.min.css +2 -2
  33. metadata +52 -8
@@ -1,8 +1,8 @@
1
1
  /*
2
- * jQuery Mobile Framework 1.0
2
+ * jQuery Mobile Framework 1.0.1
3
3
  * http://jquerymobile.com
4
4
  *
5
- * Copyright 2011 (c) jQuery Project
5
+ * Copyright 2011-2012 (c) jQuery Project
6
6
  * Dual licensed under the MIT or GPL Version 2 licenses.
7
7
  * http://jquery.org/license
8
8
  *
@@ -311,7 +311,7 @@ $.widget( "mobile.widget", {
311
311
  // TODO remove dependency on the page widget for the keepNative.
312
312
  // Currently the keepNative value is defined on the page prototype so
313
313
  // the method is as well
314
- var page = $(target).closest(":jqmData(role='page')").data( "page" ),
314
+ var page = $.mobile.closestPageData( $(target) ),
315
315
  keepNative = (page && page.keepNativeSelector()) || "";
316
316
 
317
317
  $( this.options.initSelector, target ).not( keepNative )[ this.widgetName ]();
@@ -422,7 +422,9 @@ $.mobile.browser.ie = (function() {
422
422
  div = document.createElement( "div" ),
423
423
  a = div.all || [];
424
424
 
425
- while ( div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->", a[ 0 ] );
425
+ // added {} to silence closure compiler warnings. registering my dislike of all things
426
+ // overly clever here for future reference
427
+ while ( div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->", a[ 0 ] ){};
426
428
 
427
429
  return v > 4 ? v : !v;
428
430
  })();
@@ -1161,7 +1163,37 @@ $.event.special.swipe = {
1161
1163
  var win = $( window ),
1162
1164
  special_event,
1163
1165
  get_orientation,
1164
- last_orientation;
1166
+ last_orientation,
1167
+ initial_orientation_is_landscape,
1168
+ initial_orientation_is_default,
1169
+ portrait_map = { "0": true, "180": true };
1170
+
1171
+ // It seems that some device/browser vendors use window.orientation values 0 and 180 to
1172
+ // denote the "default" orientation. For iOS devices, and most other smart-phones tested,
1173
+ // the default orientation is always "portrait", but in some Android and RIM based tablets,
1174
+ // the default orientation is "landscape". The following code injects a landscape orientation
1175
+ // media query into the document to figure out what the current orientation is, and then
1176
+ // makes adjustments to the portrait_map if necessary, so that we can properly
1177
+ // decode the window.orientation value whenever get_orientation() is called.
1178
+ if ( $.support.orientation ) {
1179
+
1180
+ // Use a media query to figure out the true orientation of the device at this moment.
1181
+ // Note that we've initialized the portrait map values to 0 and 180, *AND* we purposely
1182
+ // use a landscape media query so that if the device/browser does not support this particular
1183
+ // media query, we default to the assumption that portrait is the default orientation.
1184
+ initial_orientation_is_landscape = $.mobile.media("all and (orientation: landscape)");
1185
+
1186
+ // Now check to see if the current window.orientation is 0 or 180.
1187
+ initial_orientation_is_default = portrait_map[ window.orientation ];
1188
+
1189
+ // If the initial orientation is landscape, but window.orientation reports 0 or 180, *OR*
1190
+ // if the initial orientation is portrait, but window.orientation reports 90 or -90, we
1191
+ // need to flip our portrait_map values because landscape is the default orientation for
1192
+ // this device/browser.
1193
+ if ( ( initial_orientation_is_landscape && initial_orientation_is_default ) || ( !initial_orientation_is_landscape && !initial_orientation_is_default ) ) {
1194
+ portrait_map = { "-90": true, "90": true };
1195
+ }
1196
+ }
1165
1197
 
1166
1198
  $.event.special.orientationchange = special_event = {
1167
1199
  setup: function() {
@@ -1230,7 +1262,7 @@ $.event.special.swipe = {
1230
1262
  if ( $.support.orientation ) {
1231
1263
  // if the window orientation registers as 0 or 180 degrees report
1232
1264
  // portrait, otherwise landscape
1233
- isPortrait = window.orientation % 180 == 0;
1265
+ isPortrait = portrait_map[ window.orientation ];
1234
1266
  } else {
1235
1267
  isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1;
1236
1268
  }
@@ -1374,8 +1406,6 @@ $.each({
1374
1406
  // part of jQuery BBQ, but also be available separately.
1375
1407
 
1376
1408
  (function($,window,undefined){
1377
- '$:nomunge'; // Used by YUI compressor.
1378
-
1379
1409
  // Reused string.
1380
1410
  var str_hashchange = 'hashchange',
1381
1411
 
@@ -1710,7 +1740,7 @@ $.widget( "mobile.page", $.mobile.widget, {
1710
1740
  }
1711
1741
  });
1712
1742
  })( jQuery );
1713
- /*
1743
+ /*
1714
1744
  * "core" - The base file for jQm
1715
1745
  */
1716
1746
 
@@ -1864,11 +1894,24 @@ $.widget( "mobile.page", $.mobile.widget, {
1864
1894
  }
1865
1895
  e = e.parentNode;
1866
1896
  }
1867
-
1897
+
1868
1898
  // Return the theme letter we found, if none, return the
1869
1899
  // specified default.
1870
1900
 
1871
1901
  return ltr || defaultTheme || "a";
1902
+ },
1903
+
1904
+ // TODO the following $ and $.fn extensions can/probably should be moved into jquery.mobile.core.helpers
1905
+ //
1906
+ // Find the closest javascript page element to gather settings data jsperf test
1907
+ // http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit
1908
+ // possibly naive, but it shows that the parsing overhead for *just* the page selector vs
1909
+ // the page and dialog selector is negligable. This could probably be speed up by
1910
+ // doing a similar parent node traversal to the one found in the inherited theme code above
1911
+ closestPageData: function( $target ) {
1912
+ return $target
1913
+ .closest(':jqmData(role="page"), :jqmData(role="dialog")')
1914
+ .data("page");
1872
1915
  }
1873
1916
  });
1874
1917
 
@@ -2194,6 +2237,19 @@ $.widget( "mobile.page", $.mobile.widget, {
2194
2237
  return ( u.hash && ( u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ) ) );
2195
2238
  }
2196
2239
  return (/^#/).test( u.href );
2240
+ },
2241
+
2242
+
2243
+ // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR
2244
+ // requests if the document doing the request was loaded via the file:// protocol.
2245
+ // This is usually to allow the application to "phone home" and fetch app specific
2246
+ // data. We normally let the browser handle external/cross-domain urls, but if the
2247
+ // allowCrossDomainPages option is true, we will allow cross-domain http/https
2248
+ // requests to go through our page loading logic.
2249
+ isPermittedCrossDomainRequest: function( docUrl, reqUrl ) {
2250
+ return $.mobile.allowCrossDomainPages
2251
+ && docUrl.protocol === "file:"
2252
+ && reqUrl.search( /^https?:/ ) != -1;
2197
2253
  }
2198
2254
  },
2199
2255
 
@@ -3043,7 +3099,7 @@ $.widget( "mobile.page", $.mobile.widget, {
3043
3099
 
3044
3100
  // Kill the keyboard.
3045
3101
  // XXX_jblas: We need to stop crawling the entire document to kill focus. Instead,
3046
- // we should be tracking focus with a live() handler so we already have
3102
+ // we should be tracking focus with a delegate() handler so we already have
3047
3103
  // the element in hand at this point.
3048
3104
  // Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement
3049
3105
  // is undefined when we are in an IFrame.
@@ -3169,13 +3225,12 @@ $.widget( "mobile.page", $.mobile.widget, {
3169
3225
  return path.makeUrlAbsolute( url, base);
3170
3226
  }
3171
3227
 
3172
-
3173
3228
  //The following event bindings should be bound after mobileinit has been triggered
3174
3229
  //the following function is called in the init file
3175
3230
  $.mobile._registerInternalEvents = function(){
3176
3231
 
3177
3232
  //bind to form submit events, handle with Ajax
3178
- $( "form" ).live('submit', function( event ) {
3233
+ $( document ).delegate( "form", "submit", function( event ) {
3179
3234
  var $this = $( this );
3180
3235
  if( !$.mobile.ajaxEnabled ||
3181
3236
  $this.is( ":jqmData(ajax='false')" ) ) {
@@ -3205,8 +3260,7 @@ $.widget( "mobile.page", $.mobile.widget, {
3205
3260
 
3206
3261
  url = path.makeUrlAbsolute( url, getClosestBaseUrl($this) );
3207
3262
 
3208
- //external submits use regular HTTP
3209
- if( path.isExternal( url ) || target ) {
3263
+ if(( path.isExternal( url ) && !path.isPermittedCrossDomainRequest(documentUrl, url)) || target ) {
3210
3264
  return;
3211
3265
  }
3212
3266
 
@@ -3314,12 +3368,11 @@ $.widget( "mobile.page", $.mobile.widget, {
3314
3368
  // data. We normally let the browser handle external/cross-domain urls, but if the
3315
3369
  // allowCrossDomainPages option is true, we will allow cross-domain http/https
3316
3370
  // requests to go through our page loading logic.
3317
- isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && href.search( /^https?:/ ) != -1 ),
3318
3371
 
3319
3372
  //check for protocol or rel and its not an embedded page
3320
3373
  //TODO overlap in logic from isExternal, rel=external check should be
3321
3374
  // moved into more comprehensive isExternalLink
3322
- isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !isCrossDomainPageLoad );
3375
+ isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !path.isPermittedCrossDomainRequest(documentUrl, href) );
3323
3376
 
3324
3377
  if( isExternal ) {
3325
3378
  httpCleanup();
@@ -3342,7 +3395,7 @@ $.widget( "mobile.page", $.mobile.widget, {
3342
3395
  });
3343
3396
 
3344
3397
  //prefetch pages when anchors with data-prefetch are encountered
3345
- $( ".ui-page" ).live( "pageshow.prefetch", function() {
3398
+ $( document ).delegate( ".ui-page", "pageshow.prefetch", function() {
3346
3399
  var urls = [];
3347
3400
  $( this ).find( "a:jqmData(prefetch)" ).each(function(){
3348
3401
  var $link = $(this),
@@ -3649,7 +3702,7 @@ $.mobile.page.prototype.options.degradeInputs = {
3649
3702
  //auto self-init widgets
3650
3703
  $( document ).bind( "pagecreate create", function( e ){
3651
3704
 
3652
- var page = $(e.target).closest(':jqmData(role="page")').data("page"), options;
3705
+ var page = $.mobile.closestPageData( $(e.target) );
3653
3706
 
3654
3707
  if( !page ) {
3655
3708
  return;
@@ -3711,7 +3764,10 @@ $.widget( "mobile.dialog", $.mobile.widget, {
3711
3764
  // this must be an anonymous function so that select menu dialogs can replace
3712
3765
  // the close method. This is a change from previously just defining data-rel=back
3713
3766
  // on the button and letting nav handle it
3714
- headerCloseButton.bind( "vclick", function() {
3767
+ //
3768
+ // Use click rather than vclick in order to prevent the possibility of unintentionally
3769
+ // reopening the dialog if the dialog opening item was directly under the close button.
3770
+ headerCloseButton.bind( "click", function() {
3715
3771
  self.close();
3716
3772
  });
3717
3773
 
@@ -3744,7 +3800,7 @@ $.widget( "mobile.dialog", $.mobile.widget, {
3744
3800
  });
3745
3801
 
3746
3802
  //auto self-init widgets
3747
- $( $.mobile.dialog.prototype.options.initSelector ).live( "pagecreate", function(){
3803
+ $( document ).delegate( $.mobile.dialog.prototype.options.initSelector, "pagecreate", function(){
3748
3804
  $( this ).dialog();
3749
3805
  });
3750
3806
 
@@ -3762,7 +3818,7 @@ $.mobile.page.prototype.options.headerTheme = "a";
3762
3818
  $.mobile.page.prototype.options.footerTheme = "a";
3763
3819
  $.mobile.page.prototype.options.contentTheme = null;
3764
3820
 
3765
- $( ":jqmData(role='page'), :jqmData(role='dialog')" ).live( "pagecreate", function( e ) {
3821
+ $( document ).delegate( ":jqmData(role='page'), :jqmData(role='dialog')", "pagecreate", function( e ) {
3766
3822
 
3767
3823
  var $page = $( this ),
3768
3824
  o = $page.data( "page" ).options,
@@ -3952,6 +4008,88 @@ $( document ).bind( "pagecreate create", function( e ){
3952
4008
  $( $.mobile.collapsible.prototype.options.initSelector, e.target ).collapsible();
3953
4009
  });
3954
4010
 
4011
+ })( jQuery );
4012
+ /*
4013
+ * "collapsibleset" plugin
4014
+ */
4015
+
4016
+ (function( $, undefined ) {
4017
+
4018
+ $.widget( "mobile.collapsibleset", $.mobile.widget, {
4019
+ options: {
4020
+ initSelector: ":jqmData(role='collapsible-set')"
4021
+ },
4022
+ _create: function() {
4023
+ var $el = this.element.addClass( "ui-collapsible-set" ),
4024
+ o = this.options,
4025
+ collapsiblesInSet = $el.children( ":jqmData(role='collapsible')" );
4026
+
4027
+ // Inherit the theme from collapsible-set
4028
+ if ( !o.theme ) {
4029
+ o.theme = $el.jqmData( "theme" );
4030
+ }
4031
+ // Inherit the content-theme from collapsible-set
4032
+ if ( !o.contentTheme ) {
4033
+ o.contentTheme = $el.jqmData( "content-theme" );
4034
+ }
4035
+
4036
+ // Initialize the collapsible set if it's not already initialized
4037
+ if ( !$el.jqmData( "collapsiblebound" ) ) {
4038
+
4039
+ $el
4040
+ .jqmData( "collapsiblebound", true )
4041
+ .bind( "expand collapse", function( event ) {
4042
+ var isCollapse = ( event.type === "collapse" ),
4043
+ collapsible = $( event.target ).closest( ".ui-collapsible" ),
4044
+ widget = collapsible.data( "collapsible" ),
4045
+ contentTheme = widget.options.contentTheme;
4046
+ if ( contentTheme && collapsible.jqmData( "collapsible-last" ) ) {
4047
+ collapsible.find( widget.options.heading ).first()
4048
+ .find( "a" ).first()
4049
+ .add( ".ui-btn-inner" )
4050
+ .toggleClass( "ui-corner-bottom", isCollapse );
4051
+ collapsible.find( ".ui-collapsible-content" ).toggleClass( "ui-corner-bottom", !isCollapse );
4052
+ }
4053
+ })
4054
+ .bind( "expand", function( event ) {
4055
+ $( event.target )
4056
+ .closest( ".ui-collapsible" )
4057
+ .siblings( ".ui-collapsible" )
4058
+ .trigger( "collapse" );
4059
+
4060
+ });
4061
+
4062
+ // clean up borders
4063
+ collapsiblesInSet.each( function() {
4064
+ $( this ).find( $.mobile.collapsible.prototype.options.heading )
4065
+ .find( "a" ).first()
4066
+ .add( ".ui-btn-inner" )
4067
+ .removeClass( "ui-corner-top ui-corner-bottom" );
4068
+ });
4069
+
4070
+ collapsiblesInSet.first()
4071
+ .find( "a" )
4072
+ .first()
4073
+ .addClass( "ui-corner-top" )
4074
+ .find( ".ui-btn-inner" )
4075
+ .addClass( "ui-corner-top" );
4076
+
4077
+ collapsiblesInSet.last()
4078
+ .jqmData( "collapsible-last", true )
4079
+ .find( "a" )
4080
+ .first()
4081
+ .addClass( "ui-corner-bottom" )
4082
+ .find( ".ui-btn-inner" )
4083
+ .addClass( "ui-corner-bottom" );
4084
+ }
4085
+ }
4086
+ });
4087
+
4088
+ //auto self-init widgets
4089
+ $( document ).bind( "pagecreate create", function( e ){
4090
+ $( $.mobile.collapsibleset.prototype.options.initSelector, e.target ).collapsibleset();
4091
+ });
4092
+
3955
4093
  })( jQuery );
3956
4094
  /*
3957
4095
  * "fieldcontain" plugin - simple class additions to make form row separators
@@ -4053,8 +4191,10 @@ $.widget( "mobile.navbar", $.mobile.widget, {
4053
4191
  });
4054
4192
 
4055
4193
  $navbar.delegate( "a", "vclick", function( event ) {
4056
- $navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass );
4057
- $( this ).addClass( $.mobile.activeBtnClass );
4194
+ if( !$(event.target).hasClass("ui-disabled") ) {
4195
+ $navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass );
4196
+ $( this ).addClass( $.mobile.activeBtnClass );
4197
+ }
4058
4198
  });
4059
4199
  }
4060
4200
  });
@@ -4477,7 +4617,7 @@ $.mobile.listview.prototype.options.filterCallback = function( text, searchValue
4477
4617
  return text.toLowerCase().indexOf( searchValue ) === -1;
4478
4618
  };
4479
4619
 
4480
- $( ":jqmData(role='listview')" ).live( "listviewcreate", function() {
4620
+ $( document ).delegate( ":jqmData(role='listview')", "listviewcreate", function() {
4481
4621
 
4482
4622
  var list = $( this ),
4483
4623
  listview = list.data( "listview" );
@@ -4503,13 +4643,11 @@ $( ":jqmData(role='listview')" ).live( "listviewcreate", function() {
4503
4643
  lastval = $this.jqmData( "lastval" ) + "",
4504
4644
  childItems = false,
4505
4645
  itemtext = "",
4506
- item, change;
4646
+ item;
4507
4647
 
4508
4648
  // Change val as lastval for next execution
4509
4649
  $this.jqmData( "lastval" , val );
4510
- change = val.substr( 0 , lastval.length - 1 ).replace( lastval , "" );
4511
-
4512
- if ( val.length < lastval.length || change.length != ( val.length - lastval.length ) ) {
4650
+ if ( val.length < lastval.length || val.indexOf(lastval) !== 0 ) {
4513
4651
 
4514
4652
  // Removed chars or pasted something totally different, check all items
4515
4653
  listItems = list.children();
@@ -4604,7 +4742,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
4604
4742
  input = this.element,
4605
4743
  // NOTE: Windows Phone could not find the label through a selector
4606
4744
  // filter works though.
4607
- label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label[for='" + input[ 0 ].id + "']"),
4745
+ label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label" ).filter( "[for='" + input[ 0 ].id + "']" ),
4608
4746
  inputtype = input.attr( "type" ),
4609
4747
  checkedState = inputtype + "-on",
4610
4748
  uncheckedState = inputtype + "-off",
@@ -4808,6 +4946,12 @@ $.widget( "mobile.button", $.mobile.widget, {
4808
4946
  name,
4809
4947
  $buttonPlaceholder;
4810
4948
 
4949
+ // if this is a link, check if it's been enhanced and, if not, use the right function
4950
+ if( $el[ 0 ].tagName === "A" ) {
4951
+ if ( !$el.hasClass( "ui-btn" ) ) $el.buttonMarkup();
4952
+ return;
4953
+ }
4954
+
4811
4955
  // Add ARIA role
4812
4956
  this.button = $( "<div></div>" )
4813
4957
  .text( $el.text() || $el.val() )
@@ -4960,7 +5104,7 @@ $.widget( "mobile.slider", $.mobile.widget, {
4960
5104
  if ( cType == "select" ) {
4961
5105
 
4962
5106
  slider.wrapInner( "<div class='ui-slider-inneroffset'></div>" );
4963
-
5107
+
4964
5108
  // make the handle move with a smooth transition
4965
5109
  handle.addClass( "ui-slider-handle-snapping" );
4966
5110
 
@@ -5003,14 +5147,14 @@ $.widget( "mobile.slider", $.mobile.widget, {
5003
5147
  if ( self.dragging ) {
5004
5148
  // self.mouseMoved must be updated before refresh() because it will be used in the control "change" event
5005
5149
  self.mouseMoved = true;
5006
-
5150
+
5007
5151
  if ( cType === "select" ) {
5008
5152
  // make the handle move in sync with the mouse
5009
5153
  handle.removeClass( "ui-slider-handle-snapping" );
5010
5154
  }
5011
-
5155
+
5012
5156
  self.refresh( event );
5013
-
5157
+
5014
5158
  // only after refresh() you can calculate self.userModified
5015
5159
  self.userModified = self.beforeStart !== control[0].selectedIndex;
5016
5160
  return false;
@@ -5025,7 +5169,7 @@ $.widget( "mobile.slider", $.mobile.widget, {
5025
5169
  if ( cType === "select" ) {
5026
5170
  self.beforeStart = control[0].selectedIndex;
5027
5171
  }
5028
-
5172
+
5029
5173
  self.refresh( event );
5030
5174
  return false;
5031
5175
  });
@@ -5037,12 +5181,12 @@ $.widget( "mobile.slider", $.mobile.widget, {
5037
5181
  self.dragging = false;
5038
5182
 
5039
5183
  if ( cType === "select") {
5040
-
5184
+
5041
5185
  // make the handle move with a smooth transition
5042
5186
  handle.addClass( "ui-slider-handle-snapping" );
5043
-
5187
+
5044
5188
  if ( self.mouseMoved ) {
5045
-
5189
+
5046
5190
  // this is a drag, change the value only if user dragged enough
5047
5191
  if ( self.userModified ) {
5048
5192
  self.refresh( self.beforeStart == 0 ? 1 : 0 );
@@ -5050,17 +5194,17 @@ $.widget( "mobile.slider", $.mobile.widget, {
5050
5194
  else {
5051
5195
  self.refresh( self.beforeStart );
5052
5196
  }
5053
-
5197
+
5054
5198
  }
5055
5199
  else {
5056
5200
  // this is just a click, change the value
5057
5201
  self.refresh( self.beforeStart == 0 ? 1 : 0 );
5058
5202
  }
5059
-
5203
+
5060
5204
  }
5061
-
5205
+
5062
5206
  self.mouseMoved = false;
5063
-
5207
+
5064
5208
  return false;
5065
5209
  }
5066
5210
  });
@@ -5133,14 +5277,15 @@ $.widget( "mobile.slider", $.mobile.widget, {
5133
5277
 
5134
5278
  refresh: function( val, isfromControl, preventInputUpdate ) {
5135
5279
 
5136
- if ( this.options.disabled || this.element.attr('disabled')) {
5280
+ if ( this.options.disabled || this.element.attr('disabled')) {
5137
5281
  this.disable();
5138
5282
  }
5139
5283
 
5140
5284
  var control = this.element, percent,
5141
5285
  cType = control[0].nodeName.toLowerCase(),
5142
5286
  min = cType === "input" ? parseFloat( control.attr( "min" ) ) : 0,
5143
- max = cType === "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length - 1;
5287
+ max = cType === "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length - 1,
5288
+ step = (cType === "input" && parseFloat( control.attr( "step" ) ) > 0) ? parseFloat(control.attr("step")) : 1;
5144
5289
 
5145
5290
  if ( typeof val === "object" ) {
5146
5291
  var data = val,
@@ -5154,7 +5299,7 @@ $.widget( "mobile.slider", $.mobile.widget, {
5154
5299
  percent = Math.round( ( ( data.pageX - this.slider.offset().left ) / this.slider.width() ) * 100 );
5155
5300
  } else {
5156
5301
  if ( val == null ) {
5157
- val = cType === "input" ? parseFloat( control.val() ) : control[0].selectedIndex;
5302
+ val = cType === "input" ? parseFloat( control.val() || 0 ) : control[0].selectedIndex;
5158
5303
  }
5159
5304
  percent = ( parseFloat( val ) - min ) / ( max - min ) * 100;
5160
5305
  }
@@ -5171,7 +5316,18 @@ $.widget( "mobile.slider", $.mobile.widget, {
5171
5316
  percent = 100;
5172
5317
  }
5173
5318
 
5174
- var newval = Math.round( ( percent / 100 ) * ( max - min ) ) + min;
5319
+ var newval = ( percent / 100 ) * ( max - min ) + min;
5320
+
5321
+ //from jQuery UI slider, the following source will round to the nearest step
5322
+ var valModStep = ( newval - min ) % step;
5323
+ var alignValue = newval - valModStep;
5324
+
5325
+ if ( Math.abs( valModStep ) * 2 >= step ) {
5326
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
5327
+ }
5328
+ // Since JavaScript has problems with large floats, round
5329
+ // the final value to 5 digits after the decimal point (see jQueryUI: #4124)
5330
+ newval = parseFloat( alignValue.toFixed(5) );
5175
5331
 
5176
5332
  if ( newval < min ) {
5177
5333
  newval = min;
@@ -5181,15 +5337,11 @@ $.widget( "mobile.slider", $.mobile.widget, {
5181
5337
  newval = max;
5182
5338
  }
5183
5339
 
5184
- // Flip the stack of the bg colors
5185
- if ( percent > 60 && cType === "select" ) {
5186
- // TODO: Dead path?
5187
- }
5188
5340
  this.handle.css( "left", percent + "%" );
5189
5341
  this.handle.attr( {
5190
5342
  "aria-valuenow": cType === "input" ? newval : control.find( "option" ).eq( newval ).attr( "value" ),
5191
5343
  "aria-valuetext": cType === "input" ? newval : control.find( "option" ).eq( newval ).getEncodedText(),
5192
- title: newval
5344
+ title: cType === "input" ? newval : control.find( "option" ).eq( newval ).getEncodedText()
5193
5345
  });
5194
5346
 
5195
5347
  // add/remove classes for flip toggle switch
@@ -5338,15 +5490,15 @@ $.widget( "mobile.textinput", $.mobile.widget, {
5338
5490
  keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer );
5339
5491
  });
5340
5492
 
5493
+ // binding to pagechange here ensures that for pages loaded via
5494
+ // ajax the height is recalculated without user input
5495
+ $( document ).one( "pagechange", keyup );
5496
+
5341
5497
  // Issue 509: the browser is not providing scrollHeight properly until the styles load
5342
5498
  if ( $.trim( input.val() ) ) {
5343
5499
  // bind to the window load to make sure the height is calculated based on BOTH
5344
5500
  // the DOM and CSS
5345
5501
  $( window ).load( keyup );
5346
-
5347
- // binding to pagechange here ensures that for pages loaded via
5348
- // ajax the height is recalculated without user input
5349
- $( document ).one( "pagechange", keyup );
5350
5502
  }
5351
5503
  }
5352
5504
  },
@@ -5667,11 +5819,11 @@ $( document ).bind( "pagecreate create", function( e ){
5667
5819
  menuWidth = self.list.parent().outerWidth(),
5668
5820
  activePage = $( ".ui-page-active" ),
5669
5821
  tOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled,
5670
- tScrollElem = activePage.is( ".ui-native-fixed" ) ? activePage.find( ".ui-content" ) : activePage;
5822
+ tScrollElem = activePage.is( ".ui-native-fixed" ) ? activePage.find( ".ui-content" ) : activePage,
5671
5823
  scrollTop = tOverflow ? tScrollElem.scrollTop() : $( window ).scrollTop(),
5672
5824
  btnOffset = self.button.offset().top,
5673
- screenHeight = window.innerHeight,
5674
- screenWidth = window.innerWidth;
5825
+ screenHeight = $(window).height(),
5826
+ screenWidth = $(window).width();
5675
5827
 
5676
5828
  //add active class to button
5677
5829
  self.button.addClass( $.mobile.activeBtnClass );
@@ -5853,7 +6005,7 @@ $( document ).bind( "pagecreate create", function( e ){
5853
6005
  });
5854
6006
  };
5855
6007
 
5856
- $( "select" ).live( "selectmenubeforecreate", function(){
6008
+ $( document ).delegate( "select", "selectmenubeforecreate", function(){
5857
6009
  var selectmenuWidget = $( this ).data( "selectmenu" );
5858
6010
 
5859
6011
  if( !selectmenuWidget.options.nativeMenu ){
@@ -6074,7 +6226,6 @@ $( document ).bind( "pagecreate create", function( e ){
6074
6226
 
6075
6227
  $.fn.buttonMarkup = function( options ) {
6076
6228
  options = options || {};
6077
-
6078
6229
  for ( var i = 0; i < this.length; i++ ) {
6079
6230
  var el = this.eq( i ),
6080
6231
  e = el[ 0 ],
@@ -6098,6 +6249,15 @@ $.fn.buttonMarkup = function( options ) {
6098
6249
  buttonText = document.createElement( o.wrapperEls ),
6099
6250
  buttonIcon = o.icon ? document.createElement( "span" ) : null;
6100
6251
 
6252
+ // if so, prevent double enhancement, and continue with rest of the elements.
6253
+ if( e.tagName === "INPUT" && el.jqmData('role') === "button" ) continue;
6254
+
6255
+ // if this is a button, check if it's been enhanced and, if not, use the right function
6256
+ if( e.tagName === "BUTTON" ) {
6257
+ if ( !$( e.parentNode ).hasClass( "ui-btn" ) ) $( e ).button();
6258
+ continue;
6259
+ }
6260
+
6101
6261
  if ( attachEvents ) {
6102
6262
  attachEvents();
6103
6263
  }
@@ -6145,7 +6305,6 @@ $.fn.buttonMarkup = function( options ) {
6145
6305
  el.addClass( buttonClass );
6146
6306
 
6147
6307
  buttonInner.className = innerClass;
6148
- buttonInner.setAttribute("aria-hidden", "true");
6149
6308
 
6150
6309
  buttonText.className = textClass;
6151
6310
  buttonInner.appendChild( buttonText );
@@ -6160,7 +6319,7 @@ $.fn.buttonMarkup = function( options ) {
6160
6319
  }
6161
6320
 
6162
6321
  e.appendChild( buttonInner );
6163
-
6322
+
6164
6323
  // TODO obviously it would be nice to pull this element out instead of
6165
6324
  // retrieving it from the DOM again, but this change is much less obtrusive
6166
6325
  // and 1.0 draws nigh
@@ -6186,12 +6345,11 @@ function closestEnabledButton( element ) {
6186
6345
  // handed could be in an SVG DOM where className on SVG elements is defined to
6187
6346
  // be of a different type (SVGAnimatedString). We only operate on HTML DOM
6188
6347
  // elements, so we look for plain "string".
6189
-
6190
- cname = ( typeof element.className === 'string' ) && element.className.split(' ');
6191
-
6192
- if ( cname && $.inArray( "ui-btn", cname ) > -1 && $.inArray( "ui-disabled", cname ) < 0 ) {
6348
+ cname = ( typeof element.className === 'string' ) && (element.className + ' ');
6349
+ if ( cname && cname.indexOf("ui-btn ") > -1 && cname.indexOf("ui-disabled ") < 0 ) {
6193
6350
  break;
6194
6351
  }
6352
+
6195
6353
  element = element.parentNode;
6196
6354
  }
6197
6355
 
@@ -6475,9 +6633,7 @@ $.mobile.fixedToolbars = (function() {
6475
6633
 
6476
6634
  // 1. Before page is shown, check for duplicate footer
6477
6635
  // 2. After page is shown, append footer to new page
6478
- $( ".ui-page" )
6479
- .live( "pagebeforeshow", function( event, ui ) {
6480
-
6636
+ $( document ).delegate( ".ui-page", "pagebeforeshow", function( event, ui ) {
6481
6637
  var page = $( event.target ),
6482
6638
  footer = page.find( ":jqmData(role='footer')" ),
6483
6639
  id = footer.data( "id" ),
@@ -6490,12 +6646,10 @@ $.mobile.fixedToolbars = (function() {
6490
6646
  setTop( stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer ) );
6491
6647
  }
6492
6648
  })
6493
- .live( "pageshow", function( event, ui ) {
6494
-
6649
+ .delegate( ".ui-page", "pageshow", function( event, ui ) {
6495
6650
  var $this = $( this );
6496
6651
 
6497
6652
  if ( stickyFooter && stickyFooter.length ) {
6498
-
6499
6653
  setTimeout(function() {
6500
6654
  setTop( stickyFooter.appendTo( $this ).addClass( "fade" ) );
6501
6655
  stickyFooter = null;
@@ -6505,8 +6659,8 @@ $.mobile.fixedToolbars = (function() {
6505
6659
  $.mobile.fixedToolbars.show( true, this );
6506
6660
  });
6507
6661
 
6508
- // When a collapsiable is hidden or shown we need to trigger the fixed toolbar to reposition itself (#1635)
6509
- $( ".ui-collapsible-contain" ).live( "collapse expand", showEventCallback );
6662
+ // When a collapsible is hidden or shown we need to trigger the fixed toolbar to reposition itself (#1635)
6663
+ $( document ).delegate( ".ui-collapsible-contain", "collapse expand", showEventCallback );
6510
6664
 
6511
6665
  // element.getBoundingClientRect() is broken in iOS 3.2.1 on the iPad. The
6512
6666
  // coordinates inside of the rect it returns don't have the page scroll position
@@ -6822,13 +6976,27 @@ $( document ).bind( "pagecreate", function( event ) {
6822
6976
  // find and enhance the pages in the dom and transition to the first page.
6823
6977
  initializePage: function() {
6824
6978
  // find present pages
6825
- var $pages = $( ":jqmData(role='page')" );
6979
+ var $dialogs, $pages = $( ":jqmData(role='page')" );
6826
6980
 
6827
- // if no pages are found, create one with body's inner html
6981
+ // if no pages are found, check for dialogs or create one with body's inner html
6828
6982
  if ( !$pages.length ) {
6829
- $pages = $( "body" ).wrapInner( "<div data-" + $.mobile.ns + "role='page'></div>" ).children( 0 );
6983
+ $dialogs = $( ":jqmData(role='dialog')" );
6984
+
6985
+ // if there are no pages but a dialog is present, load it as a page
6986
+ if( $dialogs.length ) {
6987
+ // alter the attribute so it will be treated as a page unpon enhancement
6988
+ // TODO allow for the loading of a dialog as the first page (many considerations)
6989
+ $dialogs.first().attr( "data-" + $.mobile.ns + "role", "page" );
6990
+
6991
+ // remove the first dialog from the set of dialogs since it's now a page
6992
+ // add it to the empty set of pages to be loaded by the initial changepage
6993
+ $pages = $pages.add( $dialogs.get().shift() );
6994
+ } else {
6995
+ $pages = $( "body" ).wrapInner( "<div data-" + $.mobile.ns + "role='page'></div>" ).children( 0 );
6996
+ }
6830
6997
  }
6831
6998
 
6999
+
6832
7000
  // add dialogs, set data-url attrs
6833
7001
  $pages.add( ":jqmData(role='dialog')" ).each(function() {
6834
7002
  var $this = $(this);