jquery_mobile_rails 1.4.0.beta.1 → 1.4.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a848bc15ac00019ffac2e76936d4c6de768aac2e
4
- data.tar.gz: 28fc2f344eb0b31010451dfde2678d2d748baf92
3
+ metadata.gz: 2849c0fcb907b563114d84298a3e2f93fefb3749
4
+ data.tar.gz: a211a49324cf75aee28972e1c199aead19b30f57
5
5
  SHA512:
6
- metadata.gz: 1c3588a093c082c1d3a3fe895d579b6be18093be87f05d54f7456f4209321c7c3b60ba729e6b9c35556af036d2224a5de4854c5b950d70a80e25cca9bb03ec25
7
- data.tar.gz: 1ed87fc8161de05d539448cc7785ab0fd0f7ca362d6f89684f0eba87517283446c55126b760e30a1866117a5fd501c0c4b4fa05d79b5ce1782bd7f4e7a938dff
6
+ metadata.gz: 80e51369a07979616d974dcc3a1bb15157b065b0bc741be99967bdcc5e05fcd156d0b54cf9261ba433682bbaa2407b3abaf20d593ccaba875819461a8b3ba36d
7
+ data.tar.gz: 9f3affaceb0252b28b41ecc57730eb9675ad757063d17598ab825665407c45ca5d8e52fc536e76b2917cf19fe6afb9d4566b9eca9622a9fda59e3328a77015fe
@@ -1,3 +1,3 @@
1
1
  module JqueryMobileRails
2
- VERSION = "1.4.0.beta.1"
2
+ VERSION = "1.4.0.rc.1"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * jQuery Mobile 1.4.0-beta.1
3
- * Git HEAD hash: f39417f72a5c14fc039a626dfa2419d41c9c4a72 <> Date: Tue Sep 24 2013 20:03:42 UTC
2
+ * jQuery Mobile 1.4.0-rc.1
3
+ * Git HEAD hash: 4b6462bccfe0e4fc3337bd24f17c76c6b5cb0e62 <> Date: Thu Oct 24 2013 20:08:54 UTC
4
4
  * http://jquerymobile.com
5
5
  *
6
6
  * Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
@@ -25,11 +25,12 @@
25
25
  (function( $ ) {
26
26
  $.mobile = {};
27
27
  }( jQuery ));
28
+
28
29
  (function( $, window, undefined ) {
29
30
  $.extend( $.mobile, {
30
31
 
31
32
  // Version of the jQuery Mobile Framework
32
- version: "1.4.0-beta.1",
33
+ version: "1.4.0-rc.1",
33
34
 
34
35
  // Deprecated and no longer used in 1.4 remove in 1.5
35
36
  // Define the url parameter used for referencing widget-generated sub-pages.
@@ -70,12 +71,9 @@
70
71
  maxTransitionWidth: false,
71
72
 
72
73
  // Minimum scroll distance that will be remembered when returning to a page
73
- // Deprecated remove in 1.5
74
+ // Deprecated remove in 1.5
74
75
  minScrollBack: 0,
75
76
 
76
- // DEPRECATED: the following property is no longer in use, but defined until 2.0 to prevent conflicts
77
- touchOverflowEnabled: false,
78
-
79
77
  // Set default dialog transition - 'none' for no transitions
80
78
  defaultDialogTransition: "pop",
81
79
 
@@ -135,7 +133,7 @@
135
133
 
136
134
  element = element.jquery ? element[0] : element;
137
135
 
138
- if( element && element.getAttribute ){
136
+ if ( element && element.getAttribute ) {
139
137
  data = element.getAttribute( "data-" + $.mobile.ns + key );
140
138
  }
141
139
 
@@ -189,7 +187,7 @@
189
187
 
190
188
  // undefined is permitted as an explicit input for the second param
191
189
  // in this case it returns the value and does not set it to undefined
192
- if ( arguments.length < 2 || value === undefined ){
190
+ if ( arguments.length < 2 || value === undefined ) {
193
191
  result = this.data( prop );
194
192
  } else {
195
193
  result = this.data( prop, value );
@@ -685,7 +683,9 @@ $.ui.plugin = {
685
683
 
686
684
  // Enhance child elements
687
685
  enhanceWithin: function() {
688
- var widgetElements,
686
+ var index,
687
+ widgetElements = {},
688
+ keepNative = $.mobile.page.prototype.keepNativeSelector(),
689
689
  that = this;
690
690
 
691
691
  // Add no js class to elements
@@ -705,12 +705,14 @@ $.ui.plugin = {
705
705
 
706
706
  // Run buttonmarkup
707
707
  if ( $.fn.buttonMarkup ) {
708
- $( $.fn.buttonMarkup.initSelector ).buttonMarkup();
708
+ this.find( $.fn.buttonMarkup.initSelector ).not( keepNative )
709
+ .jqmEnhanceable().buttonMarkup();
709
710
  }
710
711
 
711
712
  // Add classes for fieldContain
712
713
  if ( $.fn.fieldcontain ) {
713
- this.find( ":jqmData(role='fieldcontain')" ).jqmEnhanceable().fieldcontain();
714
+ this.find( ":jqmData(role='fieldcontain')" ).not( keepNative )
715
+ .jqmEnhanceable().fieldcontain();
714
716
  }
715
717
 
716
718
  // Enhance widgets
@@ -720,21 +722,27 @@ $.ui.plugin = {
720
722
  if ( constructor.initSelector ) {
721
723
 
722
724
  // Filter elements that should not be enhanced based on parents
723
- widgetElements = $.mobile.enhanceable( that.find( constructor.initSelector ) );
725
+ var elements = $.mobile.enhanceable( that.find( constructor.initSelector ) );
724
726
 
725
727
  // If any matching elements remain filter ones with keepNativeSelector
726
- if ( widgetElements.length ) {
728
+ if ( elements.length > 0 ) {
727
729
 
728
730
  // $.mobile.page.prototype.keepNativeSelector is deprecated this is just for backcompat
729
731
  // Switch to $.mobile.keepNative in 1.5 which is just a value not a function
730
- widgetElements = widgetElements.not( $.mobile.page.prototype.keepNativeSelector() );
732
+ elements = elements.not( keepNative );
731
733
  }
732
734
 
733
735
  // Enhance whatever is left
734
- widgetElements[ constructor.prototype.widgetName ]();
736
+ if ( elements.length > 0 ) {
737
+ widgetElements[ constructor.prototype.widgetName ] = elements;
738
+ }
735
739
  }
736
740
  });
737
741
 
742
+ for ( index in widgetElements ) {
743
+ widgetElements[ index ][ index ]();
744
+ }
745
+
738
746
  return this;
739
747
  },
740
748
 
@@ -1321,9 +1329,10 @@ $.extend( $.Widget.prototype, {
1321
1329
  options = {};
1322
1330
 
1323
1331
  //
1324
- if( !$.mobile.getAttribute( elem, "defaults" ) ){
1332
+ if ( !$.mobile.getAttribute( elem, "defaults" ) ) {
1325
1333
  for ( option in this.options ) {
1326
1334
  value = $.mobile.getAttribute( elem, option.replace( rcapitals, replaceFunction ) );
1335
+
1327
1336
  if ( value != null ) {
1328
1337
  options[ option ] = value;
1329
1338
  }
@@ -1936,7 +1945,6 @@ var fakeBody = $( "<body>" ).prependTo( "html" ),
1936
1945
  bb = window.blackberry && !propExists( "-webkit-transform" ), //only used to rule out box shadow, as it's filled opaque on BB 5 and lower
1937
1946
  nokiaLTE7_3;
1938
1947
 
1939
-
1940
1948
  function validStyle( prop, value, check_vend ) {
1941
1949
  var div = document.createElement( "div" ),
1942
1950
  uc = function( txt ) {
@@ -2010,7 +2018,7 @@ function transform3dTest() {
2010
2018
  fakeBody.append( el );
2011
2019
 
2012
2020
  for ( t in transforms ) {
2013
- if ( el.style[ t ] !== undefined ){
2021
+ if ( el.style[ t ] !== undefined ) {
2014
2022
  el.style[ t ] = "translate3d( 100px, 1px, 1px )";
2015
2023
  ret = window.getComputedStyle( el ).getPropertyValue( transforms[ t ] );
2016
2024
  }
@@ -2148,7 +2156,6 @@ $.extend( $.support, {
2148
2156
 
2149
2157
  fakeBody.remove();
2150
2158
 
2151
-
2152
2159
  // $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian)
2153
2160
  // or that generally work better browsing in regular http for full page refreshes (Opera Mini)
2154
2161
  // Note: This detection below is used as a last resort.
@@ -2240,11 +2247,11 @@ if ( !$.support.boxShadow ) {
2240
2247
  beforeNavigate.originalEvent = event;
2241
2248
  $win.trigger( beforeNavigate );
2242
2249
 
2243
- if ( beforeNavigate.isDefaultPrevented() ){
2250
+ if ( beforeNavigate.isDefaultPrevented() ) {
2244
2251
  return;
2245
2252
  }
2246
2253
 
2247
- if ( event.historyState ){
2254
+ if ( event.historyState ) {
2248
2255
  $.extend(state, event.historyState);
2249
2256
  }
2250
2257
 
@@ -2270,7 +2277,7 @@ if ( !$.support.boxShadow ) {
2270
2277
  beforeNavigate.originalEvent = event;
2271
2278
  $win.trigger( beforeNavigate );
2272
2279
 
2273
- if ( beforeNavigate.isDefaultPrevented() ){
2280
+ if ( beforeNavigate.isDefaultPrevented() ) {
2274
2281
  return;
2275
2282
  }
2276
2283
 
@@ -2303,7 +2310,7 @@ if ( !$.support.boxShadow ) {
2303
2310
  if ( self.isPushStateEnabled() ) {
2304
2311
  self.originalEventName = "popstate";
2305
2312
  $win.bind( "popstate.navigate", self.popstate );
2306
- } else if ( self.isHashChangeEnabled() ){
2313
+ } else if ( self.isHashChangeEnabled() ) {
2307
2314
  self.originalEventName = "hashchange";
2308
2315
  $win.bind( "hashchange.navigate", self.hashchange );
2309
2316
  }
@@ -2597,7 +2604,7 @@ if ( !$.support.boxShadow ) {
2597
2604
  stateIndex = cleanedUrl.indexOf( this.uiStateKey );
2598
2605
 
2599
2606
  // store the ui state keys for use
2600
- if ( stateIndex > -1 ){
2607
+ if ( stateIndex > -1 ) {
2601
2608
  uiState = cleanedUrl.slice( stateIndex );
2602
2609
  cleanedUrl = cleanedUrl.slice( 0, stateIndex );
2603
2610
  }
@@ -2618,12 +2625,12 @@ if ( !$.support.boxShadow ) {
2618
2625
 
2619
2626
  // Append the UI State keys where it exists and it's been removed
2620
2627
  // from the url
2621
- if ( uiState && preservedHash.indexOf( this.uiStateKey ) === -1){
2628
+ if ( uiState && preservedHash.indexOf( this.uiStateKey ) === -1) {
2622
2629
  preservedHash += uiState;
2623
2630
  }
2624
2631
 
2625
2632
  // make sure that pound is on the front of the hash
2626
- if ( preservedHash.indexOf( "#" ) === -1 && preservedHash !== "" ){
2633
+ if ( preservedHash.indexOf( "#" ) === -1 && preservedHash !== "" ) {
2627
2634
  preservedHash = "#" + preservedHash;
2628
2635
  }
2629
2636
 
@@ -2749,7 +2756,7 @@ if ( !$.support.boxShadow ) {
2749
2756
  },
2750
2757
 
2751
2758
  // addNew is used whenever a new page is added
2752
- add: function( url, data ){
2759
+ add: function( url, data ) {
2753
2760
  data = data || {};
2754
2761
 
2755
2762
  //if there's forward history, wipe it
@@ -2836,7 +2843,7 @@ if ( !$.support.boxShadow ) {
2836
2843
  ( opts.present || opts.back || $.noop )( this.getActive(), "back" );
2837
2844
  } else if ( newActiveIndex > a ) {
2838
2845
  ( opts.present || opts.forward || $.noop )( this.getActive(), "forward" );
2839
- } else if ( newActiveIndex === undefined && opts.missing ){
2846
+ } else if ( newActiveIndex === undefined && opts.missing ) {
2840
2847
  opts.missing( this.getActive() );
2841
2848
  }
2842
2849
  }
@@ -2844,6 +2851,7 @@ if ( !$.support.boxShadow ) {
2844
2851
  })( jQuery );
2845
2852
 
2846
2853
 
2854
+
2847
2855
  (function( $, undefined ) {
2848
2856
  var path = $.mobile.path,
2849
2857
  initialHref = location.href;
@@ -2980,7 +2988,6 @@ if ( !$.support.boxShadow ) {
2980
2988
  this.history.add( state.url, state );
2981
2989
  },
2982
2990
 
2983
-
2984
2991
  // This binding is intended to catch the popstate events that are fired
2985
2992
  // when execution of the `$.navigate` method stops at window.location.hash = url;
2986
2993
  // and completely prevent them from propagating. The popstate event will then be
@@ -2993,7 +3000,7 @@ if ( !$.support.boxShadow ) {
2993
3000
 
2994
3001
  // Partly to support our test suite which manually alters the support
2995
3002
  // value to test hashchange. Partly to prevent all around weirdness
2996
- if ( !$.event.special.navigate.isPushStateEnabled() ){
3003
+ if ( !$.event.special.navigate.isPushStateEnabled() ) {
2997
3004
  return;
2998
3005
  }
2999
3006
 
@@ -3085,7 +3092,7 @@ if ( !$.support.boxShadow ) {
3085
3092
 
3086
3093
  // On occasion explicitly want to prevent the next hash from propogating because we only
3087
3094
  // with to alter the url to represent the new state do so here
3088
- if ( this.preventNextHashChange ){
3095
+ if ( this.preventNextHashChange ) {
3089
3096
  this.preventNextHashChange = false;
3090
3097
  event.stopImmediatePropagation();
3091
3098
  return;
@@ -3412,7 +3419,6 @@ function handleTouchMove( event ) {
3412
3419
  ( Math.abs( t.pageX - startX ) > moveThreshold ||
3413
3420
  Math.abs( t.pageY - startY ) > moveThreshold );
3414
3421
 
3415
-
3416
3422
  if ( didScroll && !didCancel ) {
3417
3423
  triggerVirtualEvent( "vmousecancel", event, flags );
3418
3424
  }
@@ -3611,7 +3617,7 @@ if ( eventCaptureSupported ) {
3611
3617
  //
3612
3618
  // Because the target of the touch event that triggered the vclick
3613
3619
  // can be different from the target of the click event synthesized
3614
- // by the browser. The target of a mouse/click event that is syntehsized
3620
+ // by the browser. The target of a mouse/click event that is synthesized
3615
3621
  // from a touch event seems to be implementation specific. For example,
3616
3622
  // some browsers will fire mouse/click events for a link that is near
3617
3623
  // a touch event, even though the target of the touchstart/touchend event
@@ -3841,7 +3847,7 @@ if ( eventCaptureSupported ) {
3841
3847
  }
3842
3848
 
3843
3849
  stop = $.event.special.swipe.stop( event );
3844
- if ( !emitted ){
3850
+ if ( !emitted ) {
3845
3851
  emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget );
3846
3852
  }
3847
3853
  // prevent scrolling
@@ -3919,6 +3925,7 @@ if ( eventCaptureSupported ) {
3919
3925
  diff;
3920
3926
  })( jQuery );
3921
3927
 
3928
+
3922
3929
  (function( $, window ) {
3923
3930
  var win = $( window ),
3924
3931
  event_name = "orientationchange",
@@ -3963,7 +3970,6 @@ if ( eventCaptureSupported ) {
3963
3970
 
3964
3971
  initial_orientation_is_landscape = ww > wh && ( ww - wh ) > landscape_threshold;
3965
3972
 
3966
-
3967
3973
  // Now check to see if the current window.orientation is 0 or 180.
3968
3974
  initial_orientation_is_default = portrait_map[ window.orientation ];
3969
3975
 
@@ -4006,7 +4012,6 @@ if ( eventCaptureSupported ) {
4006
4012
  // Save a reference to the bound event handler.
4007
4013
  var old_handler = handleObj.handler;
4008
4014
 
4009
-
4010
4015
  handleObj.handler = function( event ) {
4011
4016
  // Modify event object, adding the .orientation property.
4012
4017
  event.orientation = get_orientation();
@@ -4127,6 +4132,7 @@ if ( eventCaptureSupported ) {
4127
4132
 
4128
4133
  })( jQuery );
4129
4134
 
4135
+
4130
4136
  (function( $, undefined ) {
4131
4137
  $.mobile.widgets = {};
4132
4138
 
@@ -4154,7 +4160,7 @@ $.widget = (function( orig ) {
4154
4160
  $.extend( $.widget, originalWidget );
4155
4161
 
4156
4162
  // For backcompat remove in 1.5
4157
- $.mobile.document.on( "create", function( event ){
4163
+ $.mobile.document.on( "create", function( event ) {
4158
4164
  $( event.target ).enhanceWithin();
4159
4165
  });
4160
4166
 
@@ -4165,6 +4171,8 @@ $.widget( "mobile.page", {
4165
4171
 
4166
4172
  // Deprecated in 1.4 remove in 1.5
4167
4173
  keepNativeDefault: $.mobile.keepNative,
4174
+
4175
+ // Deprecated in 1.4 remove in 1.5
4168
4176
  contentTheme: null,
4169
4177
  enhanced: false
4170
4178
  },
@@ -4193,12 +4201,12 @@ $.widget( "mobile.page", {
4193
4201
 
4194
4202
  this.element.enhanceWithin();
4195
4203
  // Dialog widget is deprecated in 1.4 remove this in 1.5
4196
- if( $.mobile.getAttribute( this.element[0], "role" ) === "dialog" && $.mobile.dialog ){
4204
+ if ( $.mobile.getAttribute( this.element[0], "role" ) === "dialog" && $.mobile.dialog ) {
4197
4205
  this.element.dialog();
4198
4206
  }
4199
4207
  },
4200
4208
 
4201
- _enhance: function (){
4209
+ _enhance: function () {
4202
4210
  var attrPrefix = "data-" + $.mobile.ns,
4203
4211
  self = this;
4204
4212
 
@@ -4232,14 +4240,18 @@ $.widget( "mobile.page", {
4232
4240
  page.is( ":jqmData(external-page='true')" ) ) {
4233
4241
 
4234
4242
  // TODO use _on - that is, sort out why it doesn't work in this case
4235
- page.bind( "pagehide.remove", callback || function(/* e */) {
4236
- var $this = $( this ),
4237
- prEvent = new $.Event( "pageremove" );
4243
+ page.bind( "pagehide.remove", callback || function( e, data ) {
4244
+
4245
+ //check if this is a same page transition and if so don't remove the page
4246
+ if( !data.samePage ){
4247
+ var $this = $( this ),
4248
+ prEvent = new $.Event( "pageremove" );
4238
4249
 
4239
- $this.trigger( prEvent );
4250
+ $this.trigger( prEvent );
4240
4251
 
4241
- if ( !prEvent.isDefaultPrevented() ) {
4242
- $this.removeWithDependents();
4252
+ if ( !prEvent.isDefaultPrevented() ) {
4253
+ $this.removeWithDependents();
4254
+ }
4243
4255
  }
4244
4256
  });
4245
4257
  }
@@ -4330,7 +4342,7 @@ $.widget( "mobile.page", {
4330
4342
  }, this));
4331
4343
  },
4332
4344
 
4333
- _setOptions: function( options ){
4345
+ _setOptions: function( options ) {
4334
4346
  if ( options.theme !== undefined && options.theme !== "none" ) {
4335
4347
  this.element.removeClass( "ui-overlay-" + this.options.theme )
4336
4348
  .addClass( "ui-overlay-" + options.theme );
@@ -4414,7 +4426,7 @@ $.widget( "mobile.page", {
4414
4426
  url = this._getHash();
4415
4427
  }
4416
4428
 
4417
- if ( !url || url === "#" || url.indexOf( "#" + $.mobile.path.uiStateKey ) === 0 ){
4429
+ if ( !url || url === "#" || url.indexOf( "#" + $.mobile.path.uiStateKey ) === 0 ) {
4418
4430
  url = location.href;
4419
4431
  }
4420
4432
 
@@ -4451,12 +4463,34 @@ $.widget( "mobile.page", {
4451
4463
  return $.mobile.path.documentBase;
4452
4464
  },
4453
4465
 
4454
- _back: function() {
4455
- $.mobile.back();
4466
+ back: function() {
4467
+ this.go( -1 );
4468
+ },
4469
+
4470
+ forward: function() {
4471
+ this.go( 1 );
4456
4472
  },
4457
4473
 
4458
- _forward: function() {
4459
- window.history.forward();
4474
+ go: function( steps ) {
4475
+
4476
+ //if hashlistening is enabled use native history method
4477
+ if ( $.mobile.hashListeningEnabled ) {
4478
+ window.history.go( steps );
4479
+ } else {
4480
+
4481
+ //we are not listening to the hash so handle history internally
4482
+ var activeIndex = $.mobile.navigate.history.activeIndex,
4483
+ index = activeIndex + parseInt( steps, 10 ),
4484
+ url = $.mobile.navigate.history.stack[ index ].url,
4485
+ direction = ( steps >= 1 )? "forward" : "back";
4486
+
4487
+ //update the history object
4488
+ $.mobile.navigate.history.activeIndex = index;
4489
+ $.mobile.navigate.history.previousIndex = activeIndex;
4490
+
4491
+ //change to the new page
4492
+ this.change( url, { direction: direction, changeHash: false, fromHashChange: true } );
4493
+ }
4460
4494
  },
4461
4495
 
4462
4496
  // TODO rename _handleDestination
@@ -4506,9 +4540,9 @@ $.widget( "mobile.page", {
4506
4540
  // determine if we're heading forward or backward and continue
4507
4541
  // accordingly past the current dialog
4508
4542
  if ( data.direction === "back" ) {
4509
- this._back();
4543
+ this.back();
4510
4544
  } else {
4511
- this._forward();
4545
+ this.forward();
4512
4546
  }
4513
4547
 
4514
4548
  // prevent changePage call
@@ -4645,14 +4679,20 @@ $.widget( "mobile.page", {
4645
4679
  _showLoading: function( delay, theme, msg, textonly ) {
4646
4680
  // This configurable timeout allows cached pages a brief
4647
4681
  // delay to load without showing a message
4682
+ if ( this._loadMsg ) {
4683
+ return;
4684
+ }
4685
+
4648
4686
  this._loadMsg = setTimeout($.proxy(function() {
4649
4687
  this._getLoader().loader( "show", theme, msg, textonly );
4688
+ this._loadMsg = 0;
4650
4689
  }, this), delay );
4651
4690
  },
4652
4691
 
4653
4692
  _hideLoading: function() {
4654
4693
  // Stop message show timer
4655
4694
  clearTimeout( this._loadMsg );
4695
+ this._loadMsg = 0;
4656
4696
 
4657
4697
  // Hide loading message
4658
4698
  this._getLoader().loader( "hide" );
@@ -4762,7 +4802,7 @@ $.widget( "mobile.page", {
4762
4802
  }
4763
4803
 
4764
4804
  //dont update the base tag if we are prefetching
4765
- if ( settings.prefetch === undefined ){
4805
+ if ( settings.prefetch === undefined ) {
4766
4806
  this._getBase().set( fileUrl );
4767
4807
  }
4768
4808
 
@@ -4770,6 +4810,23 @@ $.widget( "mobile.page", {
4770
4810
 
4771
4811
  this._setLoadedTitle( content, html );
4772
4812
 
4813
+ // Add the content reference and xhr to our triggerData.
4814
+ triggerData.xhr = xhr;
4815
+ triggerData.textStatus = textStatus;
4816
+
4817
+ // DEPRECATED
4818
+ triggerData.page = content;
4819
+
4820
+ triggerData.content = content;
4821
+
4822
+ // If the default behavior is prevented, stop here!
4823
+ // Note that it is the responsibility of the listener/handler
4824
+ // that called preventDefault(), to resolve/reject the
4825
+ // deferred object within the triggerData.
4826
+ if ( !this._trigger( "load", undefined, triggerData ) ) {
4827
+ return;
4828
+ }
4829
+
4773
4830
  // rewrite src and href attrs to use a base url if the base tag won't work
4774
4831
  if ( this._isRewritableBaseTag() && content ) {
4775
4832
  this._getBase().rewrite( fileUrl, content );
@@ -4789,17 +4846,10 @@ $.widget( "mobile.page", {
4789
4846
  this._hideLoading();
4790
4847
  }
4791
4848
 
4792
- // Add the content reference and xhr to our triggerData.
4793
- triggerData.xhr = xhr;
4794
- triggerData.textStatus = textStatus;
4795
-
4796
- // DEPRECATED
4797
- triggerData.page = content;
4798
-
4799
- triggerData.content = content;
4800
-
4849
+ // BEGIN DEPRECATED ---------------------------------------------------
4801
4850
  // Let listeners know the content loaded successfully.
4802
- this._triggerWithDeprecated( "load", triggerData );
4851
+ this.element.trigger( "pageload" );
4852
+ // END DEPRECATED -----------------------------------------------------
4803
4853
 
4804
4854
  deferred.resolve( absUrl, settings, content );
4805
4855
  }, this);
@@ -4827,7 +4877,7 @@ $.widget( "mobile.page", {
4827
4877
  load: function( url, options ) {
4828
4878
  // This function uses deferred notifications to let callers
4829
4879
  // know when the content is done loading, or if an error has occurred.
4830
- var deferred = options.deferred || $.Deferred(),
4880
+ var deferred = ( options && options.deferred ) || $.Deferred(),
4831
4881
 
4832
4882
  // The default load options with overrides specified by the caller.
4833
4883
  settings = $.extend( {}, this._loadDefaults, options ),
@@ -4891,7 +4941,7 @@ $.widget( "mobile.page", {
4891
4941
 
4892
4942
  //if we are reloading the content make sure we update
4893
4943
  // the base if its not a prefetch
4894
- if ( !settings.prefetch ){
4944
+ if ( !settings.prefetch ) {
4895
4945
  this._getBase().set(url);
4896
4946
  }
4897
4947
 
@@ -4985,13 +5035,21 @@ $.widget( "mobile.page", {
4985
5035
 
4986
5036
  // TODO move into transition handlers?
4987
5037
  _triggerCssTransitionEvents: function( to, from, prefix ) {
5038
+ var samePage = false;
5039
+
4988
5040
  prefix = prefix || "";
4989
5041
 
4990
5042
  // TODO decide if these events should in fact be triggered on the container
4991
5043
  if ( from ) {
5044
+
5045
+ //Check if this is a same page transition and tell the handler in page
5046
+ if( to[0] === from[0] ){
5047
+ samePage = true;
5048
+ }
5049
+
4992
5050
  //trigger before show/hide events
4993
5051
  // TODO deprecate nextPage in favor of next
4994
- this._triggerWithDeprecated( prefix + "hide", { nextPage: to }, from );
5052
+ this._triggerWithDeprecated( prefix + "hide", { nextPage: to, samePage: samePage }, from );
4995
5053
  }
4996
5054
 
4997
5055
  // TODO deprecate prevPage in favor of previous
@@ -5472,10 +5530,10 @@ $.widget( "mobile.page", {
5472
5530
  if ( this.phonegapNavigationEnabled &&
5473
5531
  nav &&
5474
5532
  nav.app &&
5475
- nav.app.backHistory ){
5533
+ nav.app.backHistory ) {
5476
5534
  nav.app.backHistory();
5477
5535
  } else {
5478
- window.history.back();
5536
+ $.mobile.pageContainer.pagecontainer( "back" );
5479
5537
  }
5480
5538
  };
5481
5539
 
@@ -5708,11 +5766,21 @@ $.widget( "mobile.page", {
5708
5766
 
5709
5767
  var link = findClosestLink( event.target ),
5710
5768
  $link = $( link ),
5711
- httpCleanup,
5769
+
5770
+ //remove active link class if external (then it won't be there if you come back)
5771
+ httpCleanup = function() {
5772
+ window.setTimeout(function() { $.mobile.removeActiveLinkClass( true ); }, 200 );
5773
+ },
5712
5774
  baseUrl, href,
5713
5775
  useDefaultUrlHandling, isExternal,
5714
5776
  transition, reverse, role;
5715
5777
 
5778
+ // If a button was clicked, clean up the active class added by vclick above
5779
+ if ( $.mobile.activeClickedLink &&
5780
+ $.mobile.activeClickedLink[ 0 ] === event.target.parentNode ) {
5781
+ httpCleanup();
5782
+ }
5783
+
5716
5784
  // If there is no link associated with the click or its not a left
5717
5785
  // click we want to ignore the click
5718
5786
  // TODO teach $.mobile.hijackable to operate on raw dom elements so the link wrapping
@@ -5721,11 +5789,6 @@ $.widget( "mobile.page", {
5721
5789
  return;
5722
5790
  }
5723
5791
 
5724
- //remove active link class if external (then it won't be there if you come back)
5725
- httpCleanup = function() {
5726
- window.setTimeout(function() { $.mobile.removeActiveLinkClass( true ); }, 200 );
5727
- };
5728
-
5729
5792
  //if there's a data-rel=back attr, go back in history
5730
5793
  if ( $link.is( ":jqmData(rel='back')" ) ) {
5731
5794
  $.mobile.back();
@@ -5877,7 +5940,7 @@ $.widget( "mobile.page", {
5877
5940
  if ( $.mobile.window.scrollTop() !== this.toScroll ) {
5878
5941
  this.scrollPage();
5879
5942
  }
5880
- if( !this.sequential ){
5943
+ if ( !this.sequential ) {
5881
5944
  this.$to.addClass( $.mobile.activePageClass );
5882
5945
  }
5883
5946
  this.deferred.resolve( this.name, this.reverse, this.$to, this.$from, true );
@@ -5915,7 +5978,7 @@ $.widget( "mobile.page", {
5915
5978
  this.$to.addClass( $.mobile.activePageClass + this.toPreClass );
5916
5979
 
5917
5980
  // Send focus to page as it is now display: block
5918
- if( !preventFocus ){
5981
+ if ( !preventFocus ) {
5919
5982
  $.mobile.focusPage( this.$to );
5920
5983
  }
5921
5984
 
@@ -5953,7 +6016,6 @@ $.widget( "mobile.page", {
5953
6016
  .addClass( this.name + " out" + reverseClass );
5954
6017
  },
5955
6018
 
5956
-
5957
6019
  toggleViewportClass: function() {
5958
6020
  $.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + this.name );
5959
6021
  },
@@ -6073,6 +6135,7 @@ $.widget( "mobile.page", {
6073
6135
  $.mobile.transitionFallbacks.flip = "fade";
6074
6136
 
6075
6137
  })( jQuery, this );
6138
+
6076
6139
  /*
6077
6140
  * fallback transition for flow in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6078
6141
  */
@@ -6082,6 +6145,7 @@ $.mobile.transitionFallbacks.flip = "fade";
6082
6145
  $.mobile.transitionFallbacks.flow = "fade";
6083
6146
 
6084
6147
  })( jQuery, this );
6148
+
6085
6149
  /*
6086
6150
  * fallback transition for pop in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6087
6151
  */
@@ -6091,6 +6155,7 @@ $.mobile.transitionFallbacks.flow = "fade";
6091
6155
  $.mobile.transitionFallbacks.pop = "fade";
6092
6156
 
6093
6157
  })( jQuery, this );
6158
+
6094
6159
  /*
6095
6160
  * fallback transition for slide in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6096
6161
  */
@@ -6104,6 +6169,7 @@ $.mobile.transitionHandlers.slide = $.mobile.transitionHandlers.simultaneous;
6104
6169
  $.mobile.transitionFallbacks.slide = "fade";
6105
6170
 
6106
6171
  })( jQuery, this );
6172
+
6107
6173
  /*
6108
6174
  * fallback transition for slidedown in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6109
6175
  */
@@ -6113,6 +6179,7 @@ $.mobile.transitionFallbacks.slide = "fade";
6113
6179
  $.mobile.transitionFallbacks.slidedown = "fade";
6114
6180
 
6115
6181
  })( jQuery, this );
6182
+
6116
6183
  /*
6117
6184
  * fallback transition for slidefade in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6118
6185
  */
@@ -6123,6 +6190,7 @@ $.mobile.transitionFallbacks.slidedown = "fade";
6123
6190
  $.mobile.transitionFallbacks.slidefade = "fade";
6124
6191
 
6125
6192
  })( jQuery, this );
6193
+
6126
6194
  /*
6127
6195
  * fallback transition for slideup in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6128
6196
  */
@@ -6132,6 +6200,7 @@ $.mobile.transitionFallbacks.slidefade = "fade";
6132
6200
  $.mobile.transitionFallbacks.slideup = "fade";
6133
6201
 
6134
6202
  })( jQuery, this );
6203
+
6135
6204
  /*
6136
6205
  * fallback transition for turn in non-3D supporting browsers (which tend to handle complex transitions poorly in general
6137
6206
  */
@@ -6142,6 +6211,7 @@ $.mobile.transitionFallbacks.turn = "fade";
6142
6211
 
6143
6212
  })( jQuery, this );
6144
6213
 
6214
+
6145
6215
  (function( $, undefined ) {
6146
6216
 
6147
6217
  $.mobile.degradeInputs = {
@@ -6204,15 +6274,14 @@ $.widget( "mobile.page", $.mobile.page, {
6204
6274
 
6205
6275
  _create: function() {
6206
6276
  this._super();
6207
- if( this.options.dialog ){
6277
+ if ( this.options.dialog ) {
6208
6278
 
6209
6279
  $.extend( this, {
6210
- _isCloseable: false,
6211
6280
  _inner: this.element.children(),
6212
6281
  _headerCloseButton: null
6213
6282
  });
6214
6283
 
6215
- if( !this.options.enhanced ) {
6284
+ if ( !this.options.enhanced ) {
6216
6285
  this._setCloseBtn( this.options.closeBtn );
6217
6286
  }
6218
6287
  }
@@ -6222,7 +6291,7 @@ $.widget( "mobile.page", $.mobile.page, {
6222
6291
  this._super();
6223
6292
 
6224
6293
  // Class the markup for dialog styling and wrap interior
6225
- if( this.options.dialog ){
6294
+ if ( this.options.dialog ) {
6226
6295
  this.element.addClass( "ui-dialog" )
6227
6296
  .wrapInner( $( "<div/>", {
6228
6297
 
@@ -6294,35 +6363,16 @@ $.widget( "mobile.page", $.mobile.page, {
6294
6363
  } else {
6295
6364
  dst = this._inner.find( ":jqmData(role='header')" ).first();
6296
6365
  btn = $( "<a></a>", {
6297
- "role": "button",
6298
6366
  "href": "#",
6299
6367
  "class": "ui-btn ui-corner-all ui-icon-delete ui-btn-icon-notext ui-btn-" + location
6300
6368
  })
6369
+ .attr( "data-" + $.mobile.ns + "rel", "back" )
6301
6370
  .text( text || this.options.closeBtnText || "" )
6302
6371
  .prependTo( dst );
6303
6372
  this._on( btn, { click: "close" } );
6304
6373
  }
6305
6374
 
6306
6375
  this._headerCloseButton = btn;
6307
- },
6308
-
6309
- // Close method goes back in history
6310
- close: function() {
6311
- var idx, dst, hist = $.mobile.navigate.history;
6312
-
6313
- if ( $.mobile.hashListeningEnabled && hist.activeIndex > 0 ) {
6314
- $.mobile.back();
6315
- } else {
6316
- idx = Math.max( 0, hist.activeIndex - 1 );
6317
- dst = hist.stack[ idx ].pageUrl || hist.stack[ idx ].url;
6318
- hist.previousIndex = hist.activeIndex;
6319
- hist.activeIndex = idx;
6320
- if ( !$.mobile.path.isPath( dst ) ) {
6321
- dst = $.mobile.path.makeUrlAbsolute( "#" + dst );
6322
- }
6323
-
6324
- $.mobile.changePage( dst, { direction: "back", changeHash: false, fromHashChange: true } );
6325
- }
6326
6376
  }
6327
6377
  });
6328
6378
 
@@ -6468,7 +6518,7 @@ $.widget( "mobile.dialog", {
6468
6518
 
6469
6519
  // Close method goes back in history
6470
6520
  close: function() {
6471
- var idx, dst, hist = $.mobile.navigate.history;
6521
+ var hist = $.mobile.navigate.history;
6472
6522
 
6473
6523
  if ( this._isCloseable ) {
6474
6524
  this._isCloseable = false;
@@ -6478,21 +6528,14 @@ $.widget( "mobile.dialog", {
6478
6528
  if ( $.mobile.hashListeningEnabled && hist.activeIndex > 0 ) {
6479
6529
  $.mobile.back();
6480
6530
  } else {
6481
- idx = Math.max( 0, hist.activeIndex - 1 );
6482
- dst = hist.stack[ idx ].pageUrl || hist.stack[ idx ].url;
6483
- hist.previousIndex = hist.activeIndex;
6484
- hist.activeIndex = idx;
6485
- if ( !$.mobile.path.isPath( dst ) ) {
6486
- dst = $.mobile.path.makeUrlAbsolute( "#" + dst );
6487
- }
6488
-
6489
- $.mobile.changePage( dst, { direction: "back", changeHash: false, fromHashChange: true } );
6531
+ $.mobile.pageContainer.pagecontainer( "back" );
6490
6532
  }
6491
6533
  }
6492
6534
  }
6493
6535
  });
6494
6536
 
6495
6537
  })( jQuery, this );
6538
+
6496
6539
  (function( $, undefined ) {
6497
6540
 
6498
6541
  var rInitialLetter = /([A-Z])/g;
@@ -6805,6 +6848,7 @@ $.mobile.collapsible.defaults = {
6805
6848
  iconpos: "left",
6806
6849
  inset: true,
6807
6850
  corners: true,
6851
+ theme: "inherit",
6808
6852
  mini: false
6809
6853
  };
6810
6854
 
@@ -6935,7 +6979,7 @@ $.widget( "mobile.collapsibleset", $.extend( {
6935
6979
  this._removeFirstLastClasses( el.children( childCollapsiblesSelector ) );
6936
6980
  el
6937
6981
  .removeClass( "ui-collapsible-set ui-corner-all " +
6938
- this._themeClassFromOption( "ui-group-theme", this.options.theme ) )
6982
+ this._themeClassFromOption( "ui-group-theme-", this.options.theme ) )
6939
6983
  .children( ":mobile-collapsible" )
6940
6984
  .collapsible( "destroy" );
6941
6985
  },
@@ -7279,470 +7323,102 @@ $.widget( "mobile.listview", $.extend( {
7279
7323
 
7280
7324
  (function( $, undefined ) {
7281
7325
 
7282
- // TODO rename filterCallback/deprecate and default to the item itself as the first argument
7283
- var defaultFilterCallback = function( index, searchValue ) {
7284
- return ( ( "" + ( $.mobile.getAttribute( this, "filtertext" ) || $( this ).text() ) )
7285
- .toLowerCase().indexOf( searchValue ) === -1 );
7286
- };
7326
+ function defaultAutodividersSelector( elt ) {
7327
+ // look for the text in the given element
7328
+ var text = $.trim( elt.text() ) || null;
7287
7329
 
7288
- $.widget( "mobile.filterable", {
7330
+ if ( !text ) {
7331
+ return null;
7332
+ }
7289
7333
 
7290
- initSelector: ":jqmData(filter='true')",
7334
+ // create the text for the divider (first uppercased letter)
7335
+ text = text.slice( 0, 1 ).toUpperCase();
7291
7336
 
7337
+ return text;
7338
+ }
7339
+
7340
+ $.widget( "mobile.listview", $.mobile.listview, {
7292
7341
  options: {
7293
- filterReveal: false,
7294
- filterCallback: defaultFilterCallback,
7295
- enhanced: false,
7296
- input: null,
7297
- children: "> li, > option, > optgroup option, > tbody tr, > .ui-controlgroup-controls > .ui-btn, > .ui-controlgroup-controls > .ui-checkbox, > .ui-controlgroup-controls > .ui-radio"
7342
+ autodividers: false,
7343
+ autodividersSelector: defaultAutodividersSelector
7298
7344
  },
7299
7345
 
7300
- _create: function() {
7301
- var opts = this.options;
7302
-
7303
- $.extend( this, {
7304
- _search: null,
7305
- _timer: 0
7306
- });
7307
-
7308
- this._setInput( opts.input );
7309
- if ( !opts.enhanced ) {
7310
- this._filterItems( ( ( this._search && this._search.val() ) || "" ).toLowerCase() );
7346
+ _beforeListviewRefresh: function() {
7347
+ if ( this.options.autodividers ) {
7348
+ this._replaceDividers();
7349
+ this._superApply( arguments );
7311
7350
  }
7312
7351
  },
7313
7352
 
7314
- _onKeyUp: function() {
7315
- var val, lastval,
7316
- search = this._search;
7317
-
7318
- if ( search ) {
7319
- val = search.val().toLowerCase(),
7320
- lastval = $.mobile.getAttribute( search[ 0 ], "lastval" ) + "";
7353
+ _replaceDividers: function() {
7354
+ var i, lis, li, dividerText,
7355
+ lastDividerText = null,
7356
+ list = this.element,
7357
+ divider;
7321
7358
 
7322
- if ( lastval && lastval === val ) {
7323
- // Execute the handler only once per value change
7324
- return;
7325
- }
7359
+ list.children( "li:jqmData(role='list-divider')" ).remove();
7326
7360
 
7327
- if ( this._timer ) {
7328
- window.clearTimeout( this._timer );
7329
- this._timer = 0;
7330
- }
7361
+ lis = list.children( "li" );
7331
7362
 
7332
- this._timer = this._delay( function() {
7333
- this._trigger( "beforefilter", "beforefilter", { input: search } );
7363
+ for ( i = 0; i < lis.length ; i++ ) {
7364
+ li = lis[ i ];
7365
+ dividerText = this.options.autodividersSelector( $( li ) );
7334
7366
 
7335
- // Change val as lastval for next execution
7336
- search[ 0 ].setAttribute( "data-" + $.mobile.ns + "lastval", val );
7367
+ if ( dividerText && lastDividerText !== dividerText ) {
7368
+ divider = document.createElement( "li" );
7369
+ divider.appendChild( document.createTextNode( dividerText ) );
7370
+ divider.setAttribute( "data-" + $.mobile.ns + "role", "list-divider" );
7371
+ li.parentNode.insertBefore( divider, li );
7372
+ }
7337
7373
 
7338
- this._filterItems( val );
7339
- this._timer = 0;
7340
- }, 250 );
7374
+ lastDividerText = dividerText;
7341
7375
  }
7342
- },
7376
+ }
7377
+ });
7343
7378
 
7344
- _getFilterableItems: function() {
7345
- var elem = this.element,
7346
- children = this.options.children,
7347
- items = !children ? { length: 0 }:
7348
- $.isFunction( children ) ? children():
7349
- children.nodeName ? $( children ):
7350
- children.jquery ? children:
7351
- this.element.find( children );
7379
+ })( jQuery );
7352
7380
 
7353
- if ( items.length === 0 ) {
7354
- items = elem.children();
7355
- }
7381
+ (function( $, undefined ) {
7356
7382
 
7357
- return items;
7383
+ var rdivider = /(^|\s)ui-li-divider($|\s)/,
7384
+ rhidden = /(^|\s)ui-screen-hidden($|\s)/;
7385
+
7386
+ $.widget( "mobile.listview", $.mobile.listview, {
7387
+ options: {
7388
+ hideDividers: false
7358
7389
  },
7359
7390
 
7360
- _filterItems: function( val ) {
7361
- var idx, callback, length, dst,
7362
- show = [],
7363
- hide = [],
7364
- opts = this.options,
7365
- filterItems = this._getFilterableItems();
7391
+ _afterListviewRefresh: function() {
7392
+ var items, idx, item, hideDivider = true;
7366
7393
 
7367
- if ( val != null ) {
7368
- callback = opts.filterCallback || defaultFilterCallback;
7369
- length = filterItems.length;
7394
+ this._superApply( arguments );
7370
7395
 
7371
- // Partition the items into those to be hidden and those to be shown
7372
- for ( idx = 0 ; idx < length ; idx++ ) {
7373
- dst = ( callback.call( filterItems[ idx ], idx, val ) ) ? hide : show;
7374
- dst.push( filterItems[ idx ] );
7396
+ if ( this.options.hideDividers ) {
7397
+ items = this._getChildrenByTagName( this.element[ 0 ], "li", "LI" );
7398
+ for ( idx = items.length - 1 ; idx > -1 ; idx-- ) {
7399
+ item = items[ idx ];
7400
+ if ( item.className.match( rdivider ) ) {
7401
+ if ( hideDivider ) {
7402
+ item.className = item.className + " ui-screen-hidden";
7403
+ }
7404
+ hideDivider = true;
7405
+ } else {
7406
+ if ( !item.className.match( rhidden ) ) {
7407
+ hideDivider = false;
7408
+ }
7409
+ }
7375
7410
  }
7376
7411
  }
7412
+ }
7413
+ });
7377
7414
 
7378
- // If nothing is hidden, then the decision whether to hide or show the items
7379
- // is based on the "filterReveal" option.
7380
- if ( hide.length === 0 ) {
7381
- filterItems[ opts.filterReveal ? "addClass" : "removeClass" ]( "ui-screen-hidden" );
7382
- } else {
7383
- $( hide ).addClass( "ui-screen-hidden" );
7384
- $( show ).removeClass( "ui-screen-hidden" );
7385
- }
7415
+ })( jQuery );
7386
7416
 
7387
- this._refreshChildWidget();
7388
- },
7417
+ (function( $, undefined ) {
7389
7418
 
7390
- // The Default implementation of _refreshChildWidget attempts to call
7391
- // refresh on collapsibleset, controlgroup, selectmenu, or listview
7392
- _refreshChildWidget: function() {
7393
- var widget, idx,
7394
- recognizedWidgets = [ "collapsibleset", "selectmenu", "controlgroup", "listview" ];
7395
-
7396
- for ( idx = recognizedWidgets.length - 1 ; idx > -1 ; idx-- ) {
7397
- widget = recognizedWidgets[ idx ];
7398
- if ( $.mobile[ widget ] ) {
7399
- widget = this.element.data( "mobile-" + widget );
7400
- if ( widget && $.isFunction( widget.refresh ) ) {
7401
- widget.refresh();
7402
- }
7403
- }
7404
- }
7405
- },
7406
-
7407
- // TODO: When the input is not internal, do not even store it in this._search
7408
- _setInput: function ( selector ) {
7409
- var search = this._search;
7410
-
7411
- // Stop a pending filter operation
7412
- if ( this._timer ) {
7413
- window.clearTimeout( this._timer );
7414
- this._timer = 0;
7415
- }
7416
-
7417
- if ( search ) {
7418
- this._off( search, "keyup change input" );
7419
- search = null;
7420
- }
7421
-
7422
- if ( selector ) {
7423
- search = selector.jquery ? selector:
7424
- selector.nodeName ? $( selector ):
7425
- this.document.find( selector );
7426
-
7427
- this._on( search, {
7428
- keyup: "_onKeyUp",
7429
- change: "_onKeyUp",
7430
- input: "_onKeyUp"
7431
- });
7432
- }
7433
-
7434
- this._search = search;
7435
- },
7436
-
7437
- _setOptions: function( options ) {
7438
- var refilter = !( ( options.filterReveal === undefined ) &&
7439
- ( options.filterCallback === undefined ) &&
7440
- ( options.children === undefined ) );
7441
-
7442
- this._super( options );
7443
-
7444
- if ( options.input !== undefined ) {
7445
- this._setInput( options.input );
7446
- refilter = true;
7447
- }
7448
-
7449
- if ( refilter ) {
7450
- this.refresh();
7451
- }
7452
- },
7453
-
7454
- _destroy: function() {
7455
- var opts = this.options,
7456
- items = this._getFilterableItems();
7457
-
7458
- if ( opts.enhanced ) {
7459
- items.toggleClass( "ui-screen-hidden", opts.filterReveal );
7460
- } else {
7461
- items.removeClass( "ui-screen-hidden" );
7462
- }
7463
- },
7464
-
7465
- refresh: function() {
7466
- if ( this._timer ) {
7467
- window.clearTimeout( this._timer );
7468
- this._timer = 0;
7469
- }
7470
- this._filterItems( ( ( this._search && this._search.val() ) || "" ).toLowerCase() );
7471
- }
7472
- });
7473
-
7474
- })( jQuery );
7475
-
7476
- (function( $, undefined ) {
7477
-
7478
- // Create a function that will replace the _setOptions function of a widget,
7479
- // and will pass the options on to the input of the filterable.
7480
- var replaceSetOptions = function( self, orig ) {
7481
- return function( options ) {
7482
- orig.call( this, options );
7483
- self._syncTextInputOptions( options );
7484
- };
7485
- },
7486
- rDividerListItem = /(^|\s)ui-li-divider(\s|$)/,
7487
- origDefaultFilterCallback = $.mobile.filterable.prototype.options.filterCallback;
7488
-
7489
- // Override the default filter callback with one that does not hide list dividers
7490
- $.mobile.filterable.prototype.options.filterCallback = function( index, searchValue ) {
7491
- return !this.className.match( rDividerListItem ) &&
7492
- origDefaultFilterCallback.call( this, index, searchValue );
7493
- };
7494
-
7495
- $.widget( "mobile.filterable", $.mobile.filterable, {
7496
- options: {
7497
- filterPlaceholder: "Filter items...",
7498
- filterTheme: null
7499
- },
7500
-
7501
-
7502
- _create: function() {
7503
- var idx, widgetName,
7504
- elem = this.element,
7505
- recognizedWidgets = [ "collapsibleset", "selectmenu", "controlgroup", "listview" ],
7506
- createHandlers = {};
7507
-
7508
- this._super();
7509
-
7510
- $.extend( this, {
7511
- _widget: null
7512
- });
7513
-
7514
- for ( idx = recognizedWidgets.length - 1 ; idx > -1 ; idx-- ) {
7515
- widgetName = recognizedWidgets[ idx ];
7516
- if ( $.mobile[ widgetName ] ) {
7517
- if ( this._setWidget( elem.data( "mobile-" + widgetName ) ) ) {
7518
- break;
7519
- } else {
7520
- createHandlers[ widgetName + "create" ] = "_handleCreate";
7521
- }
7522
- }
7523
- }
7524
-
7525
- if ( !this._widget ) {
7526
- this._on( elem, createHandlers );
7527
- }
7528
- },
7529
-
7530
- _handleCreate: function( evt ) {
7531
- this._setWidget( this.element.data( "mobile-" + evt.type.substring( 0, evt.type.length - 6 ) ) );
7532
- },
7533
-
7534
- _setWidget: function( widget ) {
7535
- if ( !this._widget && widget ) {
7536
- this._widget = widget;
7537
- this._widget._setOptions = replaceSetOptions( this, this._widget._setOptions );
7538
- }
7539
-
7540
- if ( !!this._widget ) {
7541
- this._syncTextInputOptions( this._widget.options );
7542
- if ( this._widget.widgetName === "listview" ) {
7543
- this._widget.options.hidedividers = true;
7544
- this._widget.element.listview( "refresh" );
7545
- }
7546
- }
7547
-
7548
- return !!this._widget;
7549
- },
7550
-
7551
- _isSearchInternal: function() {
7552
- return ( this._search && this._search.jqmData( "ui-filterable-" + this.uuid + "-internal" ) );
7553
- },
7554
-
7555
- _setInput: function( selector ) {
7556
- var opts = this.options,
7557
- updatePlaceholder = true,
7558
- textinputOpts = {};
7559
-
7560
- if ( !selector ) {
7561
- if ( this._isSearchInternal() ) {
7562
-
7563
- // Ignore the call to set a new input if the selector goes to falsy and
7564
- // the current textinput is already of the internally generated variety.
7565
- return;
7566
- } else {
7567
-
7568
- // Generating a new textinput widget. No need to set the placeholder
7569
- // further down the function.
7570
- updatePlaceholder = false;
7571
- selector = $( "<input " +
7572
- "data-" + $.mobile.ns + "type='search' " +
7573
- "placeholder='" + opts.filterPlaceholder + "'></input>" )
7574
- .jqmData( "ui-filterable-" + this.uuid + "-internal", true );
7575
- $( "<form class='ui-filterable'></form>" )
7576
- .append( selector )
7577
- .submit( function( evt ) {
7578
- evt.preventDefault();
7579
- selector.blur();
7580
- })
7581
- .insertBefore( this.element );
7582
- if ( $.mobile.textinput ) {
7583
- if ( this.options.filterTheme != null ) {
7584
- textinputOpts[ "theme" ] = opts.filterTheme;
7585
- }
7586
-
7587
- selector.textinput( textinputOpts );
7588
- }
7589
- }
7590
- }
7591
-
7592
- this._super( selector );
7593
-
7594
- if ( this._isSearchInternal() && updatePlaceholder ) {
7595
- this._search.attr( "placeholder", this.options.filterPlaceholder );
7596
- }
7597
- },
7598
-
7599
- _setOptions: function( options ) {
7600
- var ret = this._super( options );
7601
-
7602
- // Need to set the filterPlaceholder after having established the search input
7603
- if ( options.filterPlaceholder !== undefined ) {
7604
- if ( this._isSearchInternal() ) {
7605
- this._search.attr( "placeholder", options.filterPlaceholder );
7606
- }
7607
- }
7608
-
7609
- if ( options.filterTheme !== undefined && this._search && $.mobile.textinput ) {
7610
- this._search.textinput( "option", "theme", options.filterTheme );
7611
- }
7612
-
7613
- return ret;
7614
- },
7615
-
7616
- _destroy: function() {
7617
- if ( this._isSearchInternal() ) {
7618
- this._search.remove();
7619
- }
7620
- this._super();
7621
- },
7622
-
7623
- _syncTextInputOptions: function( options ) {
7624
- var idx,
7625
- textinputOptions = {};
7626
-
7627
- // We only sync options if the filterable's textinput is of the internally
7628
- // generated variety, rather than one specified by the user.
7629
- if ( this._isSearchInternal() && $.mobile.textinput ) {
7630
-
7631
- // Apply only the options understood by textinput
7632
- for ( idx in $.mobile.textinput.prototype.options ) {
7633
- if ( options[ idx ] !== undefined ) {
7634
- if ( idx === "theme" && this.options.filterTheme != null ) {
7635
- textinputOptions[ idx ] = this.options.filterTheme;
7636
- } else {
7637
- textinputOptions[ idx ] = options[ idx ];
7638
- }
7639
- }
7640
- }
7641
- this._search.textinput( "option", textinputOptions );
7642
- }
7643
- }
7644
- });
7645
-
7646
- })( jQuery );
7647
-
7648
- (function( $, undefined ) {
7649
-
7650
- function defaultAutodividersSelector( elt ) {
7651
- // look for the text in the given element
7652
- var text = $.trim( elt.text() ) || null;
7653
-
7654
- if ( !text ) {
7655
- return null;
7656
- }
7657
-
7658
- // create the text for the divider (first uppercased letter)
7659
- text = text.slice( 0, 1 ).toUpperCase();
7660
-
7661
- return text;
7662
- }
7663
-
7664
- $.widget( "mobile.listview", $.mobile.listview, {
7665
- options: {
7666
- autodividers: false,
7667
- autodividersSelector: defaultAutodividersSelector
7668
- },
7669
-
7670
- _beforeListviewRefresh: function() {
7671
- if ( this.options.autodividers ) {
7672
- this._replaceDividers();
7673
- this._superApply( arguments );
7674
- }
7675
- },
7676
-
7677
- _replaceDividers: function() {
7678
- var i, lis, li, dividerText,
7679
- lastDividerText = null,
7680
- list = this.element,
7681
- divider;
7682
-
7683
- list.children( "li:jqmData(role='list-divider')" ).remove();
7684
-
7685
- lis = list.children( "li" );
7686
-
7687
- for ( i = 0; i < lis.length ; i++ ) {
7688
- li = lis[ i ];
7689
- dividerText = this.options.autodividersSelector( $( li ) );
7690
-
7691
- if ( dividerText && lastDividerText !== dividerText ) {
7692
- divider = document.createElement( "li" );
7693
- divider.appendChild( document.createTextNode( dividerText ) );
7694
- divider.setAttribute( "data-" + $.mobile.ns + "role", "list-divider" );
7695
- li.parentNode.insertBefore( divider, li );
7696
- }
7697
-
7698
- lastDividerText = dividerText;
7699
- }
7700
- }
7701
- });
7702
-
7703
- })( jQuery );
7704
-
7705
- (function( $, undefined ) {
7706
-
7707
- var rdivider = /(^|\s)ui-li-divider($|\s)/,
7708
- rhidden = /(^|\s)ui-screen-hidden($|\s)/;
7709
-
7710
- $.widget( "mobile.listview", $.mobile.listview, {
7711
- options: {
7712
- hidedividers: false
7713
- },
7714
-
7715
- _afterListviewRefresh: function() {
7716
- var items, idx, item, hideDivider = true;
7717
-
7718
- this._superApply( arguments );
7719
-
7720
- if ( this.options.hidedividers ) {
7721
- items = this._getChildrenByTagName( this.element[ 0 ], "li", "LI" );
7722
- for ( idx = items.length - 1 ; idx > -1 ; idx-- ) {
7723
- item = items[ idx ];
7724
- if ( item.className.match( rdivider ) ) {
7725
- if ( hideDivider ) {
7726
- item.className = item.className + " ui-screen-hidden";
7727
- }
7728
- hideDivider = true;
7729
- } else {
7730
- if ( !item.className.match( rhidden ) ) {
7731
- hideDivider = false;
7732
- }
7733
- }
7734
- }
7735
- }
7736
- }
7737
- });
7738
-
7739
- })( jQuery );
7740
-
7741
- (function( $, undefined ) {
7742
-
7743
- $.mobile.nojs = function( target ) {
7744
- $( ":jqmData(role='nojs')", target ).addClass( "ui-nojs" );
7745
- };
7419
+ $.mobile.nojs = function( target ) {
7420
+ $( ":jqmData(role='nojs')", target ).addClass( "ui-nojs" );
7421
+ };
7746
7422
 
7747
7423
  })( jQuery );
7748
7424
 
@@ -7795,16 +7471,14 @@ $.widget( "mobile.checkboxradio", $.extend( {
7795
7471
  .filter( "[for='" + $.mobile.path.hashToSelector( input[0].id ) + "']" )
7796
7472
  .first(),
7797
7473
  inputtype = input[0].type,
7798
- checkedState = inputtype + "-on",
7799
- uncheckedState = inputtype + "-off",
7800
- checkedClass = "ui-" + checkedState,
7801
- uncheckedClass = "ui-" + uncheckedState;
7474
+ checkedClass = "ui-" + inputtype + "-on",
7475
+ uncheckedClass = "ui-" + inputtype + "-off";
7802
7476
 
7803
7477
  if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
7804
7478
  return;
7805
7479
  }
7806
7480
 
7807
- if ( this.element[0].disabled ){
7481
+ if ( this.element[0].disabled ) {
7808
7482
  this.options.disabled = true;
7809
7483
  }
7810
7484
 
@@ -7820,9 +7494,7 @@ $.widget( "mobile.checkboxradio", $.extend( {
7820
7494
  parentLabel: parentLabel,
7821
7495
  inputtype: inputtype,
7822
7496
  checkedClass: checkedClass,
7823
- uncheckedClass: uncheckedClass,
7824
- checkedicon: checkedState,
7825
- uncheckedicon: uncheckedState
7497
+ uncheckedClass: uncheckedClass
7826
7498
  });
7827
7499
 
7828
7500
  if ( !this.options.enhanced ) {
@@ -7848,16 +7520,16 @@ $.widget( "mobile.checkboxradio", $.extend( {
7848
7520
  _enhance: function() {
7849
7521
  this.label.addClass( "ui-btn ui-corner-all");
7850
7522
 
7851
- if( this.parentLabel.length > 0 ){
7523
+ if ( this.parentLabel.length > 0 ) {
7852
7524
  this.input.add( this.label ).wrapAll( this._wrapper() );
7853
7525
  } else {
7854
7526
  //this.element.replaceWith( this.input.add( this.label ).wrapAll( this._wrapper() ) );
7855
7527
  this.element.wrap( this._wrapper() );
7856
7528
  this.element.parent().prepend( this.label );
7857
7529
  }
7858
-
7530
+
7859
7531
  // Wrap the input + label in a div
7860
-
7532
+
7861
7533
  this._setOptions({
7862
7534
  "theme": this.options.theme,
7863
7535
  "iconpos": this.options.iconpos,
@@ -7963,21 +7635,62 @@ $.widget( "mobile.checkboxradio", $.extend( {
7963
7635
  this.refresh();
7964
7636
  },
7965
7637
 
7638
+ // Is the widget supposed to display an icon?
7639
+ _hasIcon: function() {
7640
+ var controlgroup, controlgroupWidget,
7641
+ controlgroupConstructor = $.mobile.controlgroup;
7642
+
7643
+ // If the controlgroup widget is defined ...
7644
+ if ( controlgroupConstructor ) {
7645
+ controlgroup = this.element.closest(
7646
+ ":mobile-controlgroup," +
7647
+ controlgroupConstructor.prototype.initSelector );
7648
+
7649
+ // ... and the checkbox is in a controlgroup ...
7650
+ if ( controlgroup.length > 0 ) {
7651
+
7652
+ // ... look for a controlgroup widget instance, and ...
7653
+ controlgroupWidget = $.data( controlgroup[ 0 ], "mobile-controlgroup" );
7654
+
7655
+ // ... if found, decide based on the option value, ...
7656
+ return ( ( controlgroupWidget ? controlgroupWidget.options.type :
7657
+
7658
+ // ... otherwise decide based on the "type" data attribute.
7659
+ controlgroup.attr( "data-" + $.mobile.ns + "type" ) ) !== "horizontal" );
7660
+ }
7661
+ }
7662
+
7663
+ // Normally, the widget displays an icon.
7664
+ return true;
7665
+ },
7666
+
7966
7667
  refresh: function() {
7967
- var input = this.element[ 0 ],
7968
- active = " " + $.mobile.activeBtnClass,
7969
- hasIcon = ( this.element.parents( ".ui-controlgroup-horizontal" ).length === 0 ),
7970
- checkedClass = this.checkedClass + ( hasIcon ? "" : active ),
7971
- label = this.label;
7972
-
7973
- label
7974
- .toggleClass( "ui-icon-" + this.checkedicon, input.checked )
7975
- .toggleClass( "ui-icon-" + this.uncheckedicon, !input.checked );
7976
- if ( input.checked ) {
7977
- label.removeClass( this.uncheckedClass + active ).addClass( checkedClass );
7668
+ var hasIcon = this._hasIcon(),
7669
+ isChecked = this.element[ 0 ].checked,
7670
+ active = $.mobile.activeBtnClass,
7671
+ iconposClass = "ui-btn-icon-" + this.options.iconpos,
7672
+ addClasses = [],
7673
+ removeClasses = [];
7674
+
7675
+ if ( hasIcon ) {
7676
+ removeClasses.push( active );
7677
+ addClasses.push( iconposClass );
7978
7678
  } else {
7979
- label.removeClass( checkedClass ).addClass( this.uncheckedClass );
7679
+ removeClasses.push( iconposClass );
7680
+ ( isChecked ? addClasses : removeClasses ).push( active );
7980
7681
  }
7682
+
7683
+ if ( isChecked ) {
7684
+ addClasses.push( this.checkedClass );
7685
+ removeClasses.push( this.uncheckedClass );
7686
+ } else {
7687
+ addClasses.push( this.uncheckedClass );
7688
+ removeClasses.push( this.checkedClass );
7689
+ }
7690
+
7691
+ this.label
7692
+ .addClass( addClasses.join( " " ) )
7693
+ .removeClass( removeClasses.join( " " ) );
7981
7694
  },
7982
7695
 
7983
7696
  widget: function() {
@@ -7986,14 +7699,16 @@ $.widget( "mobile.checkboxradio", $.extend( {
7986
7699
 
7987
7700
  _setOptions: function( options ) {
7988
7701
  var label = this.label,
7989
- currentOptions = this.options;
7702
+ currentOptions = this.options,
7703
+ outer = this.widget(),
7704
+ hasIcon = this._hasIcon();
7990
7705
 
7991
7706
  if ( options.disabled !== undefined ) {
7992
7707
  this.input.prop( "disabled", !!options.disabled );
7993
- this.widget().toggleClass( "ui-state-disabled", !!options.disabled );
7708
+ outer.toggleClass( "ui-state-disabled", !!options.disabled );
7994
7709
  }
7995
7710
  if ( options.mini !== undefined ) {
7996
- label.parent().toggleClass( "ui-mini", !!options.mini );
7711
+ outer.toggleClass( "ui-mini", !!options.mini );
7997
7712
  }
7998
7713
  if ( options.theme !== undefined ) {
7999
7714
  label
@@ -8001,14 +7716,13 @@ $.widget( "mobile.checkboxradio", $.extend( {
8001
7716
  .addClass( "ui-btn-" + options.theme );
8002
7717
  }
8003
7718
  if ( options.wrapperClass !== undefined ) {
8004
- this.widget()
7719
+ outer
8005
7720
  .removeClass( currentOptions.wrapperClass )
8006
7721
  .addClass( options.wrapperClass );
8007
7722
  }
8008
- if ( options.iconpos !== undefined &&
8009
- ( this.element.parents( "[data-" + $.mobile.ns + "type='horizontal']" ).length === 0 ) ) {
7723
+ if ( options.iconpos !== undefined && hasIcon ) {
8010
7724
  label.removeClass( "ui-btn-icon-" + currentOptions.iconpos ).addClass( "ui-btn-icon-" + options.iconpos );
8011
- } else if ( this.element.parents( "[data-" + $.mobile.ns + "type='horizontal']" ).length !== 0 ){
7725
+ } else if ( !hasIcon ) {
8012
7726
  label.removeClass( "ui-btn-icon-" + currentOptions.iconpos );
8013
7727
  }
8014
7728
  this._super( options );
@@ -8060,7 +7774,7 @@ $.widget( "mobile.button", {
8060
7774
  this.widget().removeClass( $.mobile.focusClass );
8061
7775
  }
8062
7776
  });
8063
-
7777
+
8064
7778
  this.refresh( true );
8065
7779
  },
8066
7780
 
@@ -8069,7 +7783,8 @@ $.widget( "mobile.button", {
8069
7783
  },
8070
7784
 
8071
7785
  _button: function() {
8072
- var options = this.options;
7786
+ var options = this.options,
7787
+ iconClasses = this._getIconClasses( this.options );
8073
7788
 
8074
7789
  return $("<div class='ui-btn ui-input-btn" +
8075
7790
  ( options.wrapperClass ? " " + options.wrapperClass : "" ) +
@@ -8079,11 +7794,8 @@ $.widget( "mobile.button", {
8079
7794
  ( options.inline ? " ui-btn-inline" : "" ) +
8080
7795
  ( options.mini ? " ui-mini" : "" ) +
8081
7796
  ( options.disabled ? " ui-state-disabled" : "" ) +
8082
- ( ( options.iconpos && options.icon ) ?
8083
- " ui-btn-icon-" + options.iconpos :
8084
- ( options.icon ? " ui-btn-icon-left" : "" ) ) +
8085
- ( options.icon ? " ui-icon-" + options.icon : "" ) +
8086
- "' >" + this.element.val() + "</div>");
7797
+ ( iconClasses ? ( " " + iconClasses ) : "" ) +
7798
+ "' >" + this.element.val() + "</div>" );
8087
7799
  },
8088
7800
 
8089
7801
  widget: function() {
@@ -8095,6 +7807,12 @@ $.widget( "mobile.button", {
8095
7807
  this.button.remove();
8096
7808
  },
8097
7809
 
7810
+ _getIconClasses: function( options ) {
7811
+ return ( options.icon ? ( "ui-icon-" + options.icon +
7812
+ ( options.iconshadow ? " ui-shadow-icon" : "" ) + /* TODO: Deprecated in 1.4, remove in 1.5. */
7813
+ " ui-btn-icon-" + options.iconpos ) : "" );
7814
+ },
7815
+
8098
7816
  _setOptions: function( options ) {
8099
7817
  var outer = this.widget();
8100
7818
 
@@ -8115,22 +7833,20 @@ $.widget( "mobile.button", {
8115
7833
  if ( options.mini !== undefined ) {
8116
7834
  outer.toggleClass( "ui-mini", options.mini );
8117
7835
  }
8118
- if ( options.iconpos !== undefined ) {
8119
- outer.removeClass( "ui-btn-icon-" + options.iconpos );
8120
- }
8121
- if ( options.icon !== undefined ) {
8122
- if ( !this.options.iconpos && !options.iconpos ) {
8123
- outer.toggleClass( "ui-btn-icon-left", options.icon );
8124
- }
8125
- outer
8126
- .removeClass( "ui-icon-" + this.options.icon )
8127
- .toggleClass( "ui-icon-" + options.icon, options.icon );
8128
- }
8129
- if( options.disabled !== undefined ) {
7836
+ if ( options.disabled !== undefined ) {
8130
7837
  this.element.prop( "disabled", options.disabled );
8131
7838
  outer.toggleClass( "ui-state-disabled", options.disabled );
8132
7839
  }
8133
7840
 
7841
+ if ( options.icon !== undefined ||
7842
+ options.iconshadow !== undefined || /* TODO: Deprecated in 1.4, remove in 1.5. */
7843
+ options.iconpos !== undefined ) {
7844
+ outer
7845
+ .removeClass( this._getIconClasses( this.options ) )
7846
+ .addClass( this._getIconClasses(
7847
+ $.extend( {}, this.options, options ) ) );
7848
+ }
7849
+
8134
7850
  this._super( options );
8135
7851
  },
8136
7852
 
@@ -8184,7 +7900,25 @@ $.widget( "mobile.button", {
8184
7900
  (function( $, undefined ) {
8185
7901
 
8186
7902
  $.widget( "mobile.textinput", {
8187
- 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]), input[type='file']",
7903
+ initSelector: "input[type='text']," +
7904
+ "input[type='search']," +
7905
+ ":jqmData(type='search')," +
7906
+ "input[type='number']," +
7907
+ ":jqmData(type='number')," +
7908
+ "input[type='password']," +
7909
+ "input[type='email']," +
7910
+ "input[type='url']," +
7911
+ "input[type='tel']," +
7912
+ "textarea," +
7913
+ "input[type='time']," +
7914
+ "input[type='date']," +
7915
+ "input[type='month']," +
7916
+ "input[type='week']," +
7917
+ "input[type='datetime']," +
7918
+ "input[type='datetime-local']," +
7919
+ "input[type='color']," +
7920
+ "input:not([type])," +
7921
+ "input[type='file']",
8188
7922
 
8189
7923
  options: {
8190
7924
  theme: null,
@@ -8205,7 +7939,11 @@ $.widget( "mobile.textinput", {
8205
7939
  inputNeedsWrap = ( (this.element.is( "input" ) ||
8206
7940
  this.element.is( "[data-" + ( $.mobile.ns || "" ) + "type='search']" ) ) &&
8207
7941
  !isRange );
8208
-
7942
+
7943
+ if ( this.element.prop( "disabled" ) ) {
7944
+ options.disabled = true;
7945
+ }
7946
+
8209
7947
  $.extend( this, {
8210
7948
  classes: this._classesFromOptions(),
8211
7949
  isSearch: isSearch,
@@ -8216,10 +7954,6 @@ $.widget( "mobile.textinput", {
8216
7954
 
8217
7955
  this._autoCorrect();
8218
7956
 
8219
- if ( this.element[ 0 ].disabled ) {
8220
- options.disabled = true;
8221
- }
8222
-
8223
7957
  if ( !options.enhanced ) {
8224
7958
  this._enhance();
8225
7959
  }
@@ -8720,7 +8454,6 @@ $.widget( "mobile.slider", $.extend( {
8720
8454
  return this.isToggleSwitch ? this.element[0].selectedIndex : parseFloat( this.element.val() ) ;
8721
8455
  },
8722
8456
 
8723
-
8724
8457
  _reset: function() {
8725
8458
  this.refresh( undefined, false, true );
8726
8459
  },
@@ -9061,6 +8794,7 @@ $.widget( "mobile.flipswitch", $.extend({
9061
8794
  theme: null,
9062
8795
  enhanced: false,
9063
8796
  wrapperClass: null,
8797
+ corners: true,
9064
8798
  mini: false
9065
8799
  },
9066
8800
 
@@ -9076,7 +8810,9 @@ $.widget( "mobile.flipswitch", $.extend({
9076
8810
  });
9077
8811
  }
9078
8812
 
9079
- if( this.element.is( ":disabled" ) ){
8813
+ this._handleFormReset();
8814
+
8815
+ if ( this.element.is( ":disabled" ) ) {
9080
8816
  this._setOptions({
9081
8817
  "disabled": true
9082
8818
  });
@@ -9091,6 +8827,10 @@ $.widget( "mobile.flipswitch", $.extend({
9091
8827
  this._on( this.on, {
9092
8828
  "keydown": "_keydown"
9093
8829
  });
8830
+
8831
+ this._on( {
8832
+ "change": "refresh"
8833
+ });
9094
8834
  },
9095
8835
 
9096
8836
  widget: function() {
@@ -9102,9 +8842,9 @@ $.widget( "mobile.flipswitch", $.extend({
9102
8842
  if ( this.type === "SELECT" ) {
9103
8843
  this.element.get( 0 ).selectedIndex = 0;
9104
8844
  } else {
9105
- this.element.prop( "checked", true );
8845
+ this.element.prop( "checked", false );
9106
8846
  }
9107
- this._trigger( "change" );
8847
+ this.element.trigger( "change" );
9108
8848
  },
9109
8849
 
9110
8850
  _right: function() {
@@ -9112,27 +8852,49 @@ $.widget( "mobile.flipswitch", $.extend({
9112
8852
  if ( this.type === "SELECT" ) {
9113
8853
  this.element.get( 0 ).selectedIndex = 1;
9114
8854
  } else {
9115
- this.element.prop( "checked", false );
8855
+ this.element.prop( "checked", true );
9116
8856
  }
9117
- this._trigger( "change" );
8857
+ this.element.trigger( "change" );
9118
8858
  },
9119
8859
 
9120
8860
  _enhance: function() {
9121
8861
  var flipswitch = $( "<div>" ),
9122
- theme = this.options.theme ? this.options.theme : "inherit",
9123
- on = $( "<span tabindex='1'></span>" ),
8862
+ options = this.options,
8863
+ element = this.element,
8864
+ theme = options.theme ? options.theme : "inherit",
8865
+ on = $( "<span></span>", { tabindex: 1 } ),
9124
8866
  off = $( "<span></span>" ),
9125
- type = this.element.get( 0 ).tagName,
9126
- onText = ( type === "INPUT" ) ? this.options.onText : this.element.find( "option" ).eq( 1 ).text(),
9127
- offText = ( type === "INPUT" ) ? this.options.offText : this.element.find( "option" ).eq( 0 ).text();
9128
-
9129
- on.addClass( "ui-flipswitch-on ui-btn ui-shadow ui-btn-inherit" ).text( onText );
9130
- off.addClass( "ui-flipswitch-off" ).text( offText );
9131
-
9132
- flipswitch.addClass( "ui-flipswitch ui-shadow-inset ui-corner-all ui-bar-" + theme + " " + ( this.options.wrapperClass ? this.options.wrapperClass : "" ) + " " + ( ( this.element.is( ":checked" ) || this.element.find("option").eq(1).is(":selected") ) ? "ui-flipswitch-active" : "" ) + ( this.element.is(":disabled") ? " ui-state-disabled": "") + ( this.options.mini ? " ui-mini": "" ) ).append( on, off );
9133
-
9134
- this.element.addClass( "ui-flipswitch-input" );
9135
- this.element.after( flipswitch ).appendTo( flipswitch );
8867
+ type = element.get( 0 ).tagName,
8868
+ onText = ( type === "INPUT" ) ?
8869
+ options.onText : element.find( "option" ).eq( 1 ).text(),
8870
+ offText = ( type === "INPUT" ) ?
8871
+ options.offText : element.find( "option" ).eq( 0 ).text();
8872
+
8873
+ on
8874
+ .addClass( "ui-flipswitch-on ui-btn ui-shadow ui-btn-inherit" )
8875
+ .text( onText );
8876
+ off
8877
+ .addClass( "ui-flipswitch-off" )
8878
+ .text( offText );
8879
+
8880
+ flipswitch
8881
+ .addClass( "ui-flipswitch ui-shadow-inset " +
8882
+ "ui-bar-" + theme + " " +
8883
+ ( options.wrapperClass ? options.wrapperClass : "" ) + " " +
8884
+ ( ( element.is( ":checked" ) ||
8885
+ element
8886
+ .find( "option" )
8887
+ .eq( 1 )
8888
+ .is( ":selected" ) ) ? "ui-flipswitch-active" : "" ) +
8889
+ ( element.is(":disabled") ? " ui-state-disabled": "") +
8890
+ ( options.corners ? " ui-corner-all": "" ) +
8891
+ ( options.mini ? " ui-mini": "" ) )
8892
+ .append( on, off );
8893
+
8894
+ element
8895
+ .addClass( "ui-flipswitch-input" )
8896
+ .after( flipswitch )
8897
+ .appendTo( flipswitch );
9136
8898
 
9137
8899
  $.extend( this, {
9138
8900
  flipswitch: flipswitch,
@@ -9142,21 +8904,29 @@ $.widget( "mobile.flipswitch", $.extend({
9142
8904
  });
9143
8905
  },
9144
8906
 
9145
- _change: function() {
9146
- var direction;
9147
-
8907
+ _reset: function() {
8908
+ this.refresh();
8909
+ },
8910
+
8911
+ refresh: function() {
8912
+ var direction,
8913
+ existingDirection = this.flipswitch.hasClass( "ui-flipswitch-active" ) ? "_right" : "_left";
8914
+
9148
8915
  if ( this.type === "SELECT" ) {
9149
- direction = ( this.element.get( 0 ).selectedIndex > 0 )? "_right": "_left";
8916
+ direction = ( this.element.get( 0 ).selectedIndex > 0 ) ? "_right": "_left";
9150
8917
  } else {
9151
- direction = this.element.is( ":checked" )? "_right": "_left";
8918
+ direction = this.element.prop( "checked" ) ? "_right": "_left";
8919
+ }
8920
+
8921
+ if ( direction !== existingDirection ) {
8922
+ this[ direction ]();
9152
8923
  }
9153
- this[ direction ]();
9154
8924
  },
9155
8925
 
9156
8926
  _toggle: function() {
9157
8927
  var direction = this.flipswitch.hasClass( "ui-flipswitch-active" ) ? "_left" : "_right";
9158
-
9159
- this[direction]();
8928
+
8929
+ this[ direction ]();
9160
8930
  },
9161
8931
 
9162
8932
  _keydown: function( e ) {
@@ -9188,10 +8958,13 @@ $.widget( "mobile.flipswitch", $.extend({
9188
8958
  if ( options.disabled !== undefined ) {
9189
8959
  this.widget().toggleClass( "ui-state-disabled", options.disabled );
9190
8960
  }
9191
- if( options.mini !== undefined ) {
8961
+ if ( options.mini !== undefined ) {
9192
8962
  this.widget().toggleClass( "ui-mini", options.mini );
9193
8963
  }
9194
-
8964
+ if ( options.corners !== undefined ) {
8965
+ this.widget().toggleClass( "ui-corner-all", options.corners );
8966
+ }
8967
+
9195
8968
  this._super( options );
9196
8969
  },
9197
8970
 
@@ -9227,9 +9000,13 @@ $.widget( "mobile.flipswitch", $.extend({
9227
9000
  _inputFirst = $el.find( "input" ).first(),
9228
9001
  _inputLast = $el.find( "input" ).last(),
9229
9002
  _label = $el.find( "label" ).first(),
9230
- _sliderFirst = $.data( _inputFirst.get(0), "mobile-slider" ).slider,
9231
- _sliderLast = $.data( _inputLast.get(0), "mobile-slider" ).slider,
9232
- firstHandle = $.data( _inputFirst.get(0), "mobile-slider" ).handle,
9003
+ _sliderWidgetFirst = $.data( _inputFirst.get( 0 ), "mobile-slider" ) ||
9004
+ $.data( _inputFirst.slider().get( 0 ), "mobile-slider" ),
9005
+ _sliderWidgetLast = $.data( _inputLast.get(0), "mobile-slider" ) ||
9006
+ $.data( _inputLast.slider().get( 0 ), "mobile-slider" ),
9007
+ _sliderFirst = _sliderWidgetFirst.slider,
9008
+ _sliderLast = _sliderWidgetLast.slider,
9009
+ firstHandle = _sliderWidgetFirst.handle,
9233
9010
  _sliders = $( "<div class='ui-rangeslider-sliders' />" ).appendTo( $el );
9234
9011
 
9235
9012
  _inputFirst.addClass( "ui-rangeslider-first" );
@@ -9344,7 +9121,7 @@ $.widget( "mobile.flipswitch", $.extend({
9344
9121
  var $el = this.element,
9345
9122
  o = this.options;
9346
9123
 
9347
- if( this._inputFirst.is( ":disabled" ) || this._inputLast.is( ":disabled" ) ){
9124
+ if ( this._inputFirst.is( ":disabled" ) || this._inputLast.is( ":disabled" ) ) {
9348
9125
  this.options.disabled = true;
9349
9126
  }
9350
9127
 
@@ -9372,10 +9149,9 @@ $.widget( "mobile.flipswitch", $.extend({
9372
9149
  thisSlider = first ? this._inputFirst : this._inputLast,
9373
9150
  otherSlider = first ? this._inputLast : this._inputFirst;
9374
9151
 
9375
-
9376
- if ( ( this._inputFirst.val() > this._inputLast.val() && event.type === "mousedown" && !$(event.target).hasClass("ui-slider-handle")) ){
9152
+ if ( ( this._inputFirst.val() > this._inputLast.val() && event.type === "mousedown" && !$(event.target).hasClass("ui-slider-handle")) ) {
9377
9153
  thisSlider.blur();
9378
- } else if ( event.type === "mousedown" ){
9154
+ } else if ( event.type === "mousedown" ) {
9379
9155
  return;
9380
9156
  }
9381
9157
  if ( min > max && !this._sliderTarget ) {
@@ -9467,7 +9243,7 @@ $.widget( "mobile.flipswitch", $.extend({
9467
9243
  _create: function() {
9468
9244
  this._super();
9469
9245
 
9470
- if ( !!this.options.clearBtn || this.isSearch ){
9246
+ if ( !!this.options.clearBtn || this.isSearch ) {
9471
9247
  this._addClearBtn();
9472
9248
  }
9473
9249
  },
@@ -9535,11 +9311,11 @@ $.widget( "mobile.flipswitch", $.extend({
9535
9311
  this._off( this.element, "keyup change input focus blur cut paste" );
9536
9312
  },
9537
9313
 
9538
- _setOptions:function( options ) {
9314
+ _setOptions: function( options ) {
9539
9315
  this._super( options );
9540
9316
 
9541
9317
  if ( options.clearbtn !== undefined && !this.element.is( "textarea, :jqmData(type='range')" ) ) {
9542
- if ( options.clearBtn ){
9318
+ if ( options.clearBtn ) {
9543
9319
  this._addClearBtn();
9544
9320
  } else {
9545
9321
  this._destroyClear();
@@ -9571,7 +9347,6 @@ $.widget( "mobile.flipswitch", $.extend({
9571
9347
 
9572
9348
  });
9573
9349
 
9574
-
9575
9350
  })( jQuery );
9576
9351
 
9577
9352
  (function( $, undefined ) {
@@ -9725,7 +9500,6 @@ $.widget( "mobile.selectmenu", $.extend( {
9725
9500
 
9726
9501
  options: {
9727
9502
  theme: null,
9728
- disabled: false,
9729
9503
  icon: "carat-d",
9730
9504
  iconpos: "right",
9731
9505
  inline: false,
@@ -10022,21 +9796,14 @@ $.mobile.links = function( target ) {
10022
9796
  .filter( ":jqmData(rel='popup')[href][href!='']" )
10023
9797
  .each( function() {
10024
9798
  // Accessibility info for popups
10025
- var e = this,
10026
- href = $( this ).attr( "href" ),
10027
- sel = $.mobile.path.hashToSelector( href ),
10028
- idref = href.substring( 1 );
10029
-
10030
- e.setAttribute( "aria-haspopup", true );
10031
- e.setAttribute( "aria-owns", idref );
10032
- e.setAttribute( "aria-expanded", false );
10033
- $( document )
10034
- .on( "popupafteropen", sel, function() {
10035
- e.setAttribute( "aria-expanded", true );
10036
- })
10037
- .on( "popupafterclose", sel, function() {
10038
- e.setAttribute( "aria-expanded", false );
10039
- });
9799
+ var element = this,
9800
+ idref = element.getAttribute( "href" ).substring( 1 );
9801
+
9802
+ if ( idref ) {
9803
+ element.setAttribute( "aria-haspopup", true );
9804
+ element.setAttribute( "aria-owns", idref );
9805
+ element.setAttribute( "aria-expanded", false );
9806
+ }
10040
9807
  })
10041
9808
  .end()
10042
9809
  .not( ".ui-btn, :jqmData(role='none'), :jqmData(role='nojs')" )
@@ -10197,13 +9964,21 @@ $.widget( "mobile.popup", {
10197
9964
  return false;
10198
9965
  },
10199
9966
 
10200
- // Make sure the screen size is increased beyond the page height if the popup's causes the document to increase in height
9967
+ // Make sure the screen covers the entire document - CSS is sometimes not
9968
+ // enough to accomplish this.
10201
9969
  _resizeScreen: function() {
10202
- var popupHeight = this._ui.container.outerHeight( true );
9970
+ var screen = this._ui.screen,
9971
+ popupHeight = this._ui.container.outerHeight( true ),
9972
+ screenHeight = screen.removeAttr( "style" ).height(),
10203
9973
 
10204
- this._ui.screen.removeAttr( "style" );
10205
- if ( popupHeight > this._ui.screen.height() ) {
10206
- this._ui.screen.height( popupHeight );
9974
+ // Subtracting 1 here is necessary for an obscure Andrdoid 4.0 bug where
9975
+ // the browser hangs if the screen covers the entire document :/
9976
+ documentHeight = this.document.height() - 1;
9977
+
9978
+ if ( screenHeight < documentHeight ) {
9979
+ screen.height( documentHeight );
9980
+ } else if ( popupHeight > screenHeight ) {
9981
+ screen.height( popupHeight );
10207
9982
  }
10208
9983
  },
10209
9984
 
@@ -10470,7 +10245,6 @@ $.widget( "mobile.popup", {
10470
10245
  rectangle = clampInfo.rc,
10471
10246
  menuSize = clampInfo.menuSize;
10472
10247
 
10473
-
10474
10248
  // Center the menu over the desired coordinates, while not going outside
10475
10249
  // the window tolerances. This will center wrt. the window if the popup is
10476
10250
  // too large.
@@ -10636,11 +10410,16 @@ $.widget( "mobile.popup", {
10636
10410
  },
10637
10411
 
10638
10412
  _openPrerequisitesComplete: function() {
10413
+ var id = this.element.attr( "id" );
10414
+
10639
10415
  this._ui.container.addClass( "ui-popup-active" );
10640
10416
  this._isOpen = true;
10641
10417
  this._resizeScreen();
10642
10418
  this._ui.container.attr( "tabindex", "0" ).focus();
10643
10419
  this._ignoreResizeEvents();
10420
+ if ( id ) {
10421
+ this.document.find( "[aria-haspopup='true'][aria-owns='" + id + "']" ).attr( "aria-expanded", true );
10422
+ }
10644
10423
  this._trigger( "afteropen" );
10645
10424
  },
10646
10425
 
@@ -10718,7 +10497,8 @@ $.widget( "mobile.popup", {
10718
10497
  },
10719
10498
 
10720
10499
  _closePrerequisitesDone: function() {
10721
- var container = this._ui.container;
10500
+ var container = this._ui.container,
10501
+ id = this.element.attr( "id" );
10722
10502
 
10723
10503
  container.removeAttr( "tabindex" );
10724
10504
 
@@ -10728,6 +10508,10 @@ $.widget( "mobile.popup", {
10728
10508
  // Blur elements inside the container, including the container
10729
10509
  $( ":focus", container[ 0 ] ).add( container[ 0 ] ).blur();
10730
10510
 
10511
+ if ( id ) {
10512
+ this.document.find( "[aria-haspopup='true'][aria-owns='" + id + "']" ).attr( "aria-expanded", false );
10513
+ }
10514
+
10731
10515
  // alert users that the popup is closed
10732
10516
  this._trigger( "afterclose" );
10733
10517
  },
@@ -10891,7 +10675,7 @@ $.widget( "mobile.popup", {
10891
10675
 
10892
10676
  // if the current url has no dialog hash key proceed as normal
10893
10677
  // otherwise, if the page is a dialog simply tack on the hash key
10894
- if ( url.indexOf( hashkey ) === -1 && !currentIsDialog ){
10678
+ if ( url.indexOf( hashkey ) === -1 && !currentIsDialog ) {
10895
10679
  url = url + (url.indexOf( "#" ) > -1 ? hashkey : "#" + hashkey);
10896
10680
  } else {
10897
10681
  url = $.mobile.path.parseLocation().hash + hashkey;
@@ -10935,7 +10719,6 @@ $.widget( "mobile.popup", {
10935
10719
  }
10936
10720
  });
10937
10721
 
10938
-
10939
10722
  // TODO this can be moved inside the widget
10940
10723
  $.mobile.popup.handleLink = function( $link ) {
10941
10724
  var offset,
@@ -11188,8 +10971,8 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
11188
10971
  // toggle checkbox class for multiple selects
11189
10972
  if ( self.isMultiple ) {
11190
10973
  $( this ).find( "a" )
11191
- .toggleClass( "ui-icon-checkbox-on", option.selected )
11192
- .toggleClass( "ui-icon-checkbox-off", !option.selected );
10974
+ .toggleClass( "ui-checkbox-on", option.selected )
10975
+ .toggleClass( "ui-checkbox-off", !option.selected );
11193
10976
  }
11194
10977
 
11195
10978
  // trigger change if value changed
@@ -11269,7 +11052,7 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
11269
11052
 
11270
11053
  // Multiple selects: add the "on" checkbox state to the icon
11271
11054
  if ( self.isMultiple ) {
11272
- item.find( "a" ).removeClass( "ui-icon-checkbox-off" ).addClass( "ui-icon-checkbox-on" );
11055
+ item.find( "a" ).removeClass( "ui-checkbox-off" ).addClass( "ui-checkbox-on" );
11273
11056
  } else {
11274
11057
  if ( item.hasClass( "ui-screen-hidden" ) ) {
11275
11058
  item.next().find( "a" ).addClass( $.mobile.activeBtnClass );
@@ -11359,7 +11142,7 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
11359
11142
  o = this.options,
11360
11143
  placeholder = this.placeholder,
11361
11144
  needPlaceholder = true,
11362
- dataIcon = this.isMultiple ? "checkbox-off" : "false",
11145
+ dataIcon = "false",
11363
11146
  $options, numOptions, select,
11364
11147
  dataPrefix = "data-" + $.mobile.ns,
11365
11148
  dataIndexAttr = dataPrefix + "option-index",
@@ -11430,7 +11213,7 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
11430
11213
 
11431
11214
  item = document.createElement( "li" );
11432
11215
  if ( option.disabled ) {
11433
- classes.push( "ui-disabled" );
11216
+ classes.push( "ui-state-disabled" );
11434
11217
  item.setAttribute( "aria-disabled", true );
11435
11218
  }
11436
11219
  item.setAttribute( dataIndexAttr, i );
@@ -11441,6 +11224,10 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
11441
11224
  item.className = classes.join( " " );
11442
11225
  item.setAttribute( "role", "option" );
11443
11226
  anchor.setAttribute( "tabindex", "-1" );
11227
+ if ( this.isMultiple ) {
11228
+ $( anchor ).addClass( "ui-btn ui-checkbox-off ui-btn-icon-right" );
11229
+ }
11230
+
11444
11231
  item.appendChild( anchor );
11445
11232
  fragment.appendChild( item );
11446
11233
  }
@@ -11783,13 +11570,13 @@ $.widget( "mobile.controlgroup", $.extend( {
11783
11570
  opts = this.options;
11784
11571
 
11785
11572
  // Run buttonmarkup
11786
- if( $.fn.buttonMarkup ){
11573
+ if ( $.fn.buttonMarkup ) {
11787
11574
  this.element.find( $.fn.buttonMarkup.initSelector ).buttonMarkup();
11788
11575
  }
11789
11576
  // Enhance child widgets
11790
11577
  $.each( this._childWidgets, $.proxy( function( number, widgetName ) {
11791
- if( $.mobile[ widgetName ] ) {
11792
- this.element.find( $.mobile[ widgetName ].initSelector )[ widgetName ]();
11578
+ if ( $.mobile[ widgetName ] ) {
11579
+ this.element.find( $.mobile[ widgetName ].initSelector ).not( $.mobile.page.prototype.keepNativeSelector() )[ widgetName ]();
11793
11580
  }
11794
11581
  }, this ));
11795
11582
 
@@ -11806,7 +11593,7 @@ $.widget( "mobile.controlgroup", $.extend( {
11806
11593
  } else {
11807
11594
  this._ui = this._enhance();
11808
11595
  }
11809
-
11596
+
11810
11597
  },
11811
11598
 
11812
11599
  _childWidgets: [ "checkboxradio", "selectmenu", "button" ],
@@ -11847,7 +11634,7 @@ $.widget( "mobile.controlgroup", $.extend( {
11847
11634
  },
11848
11635
 
11849
11636
  _setOptions: function( options ) {
11850
- var callRefresh,
11637
+ var callRefresh, returnValue,
11851
11638
  elem = this.element;
11852
11639
 
11853
11640
  // Must have one of horizontal or vertical
@@ -11881,11 +11668,13 @@ $.widget( "mobile.controlgroup", $.extend( {
11881
11668
  callRefresh = true;
11882
11669
  }
11883
11670
 
11671
+ returnValue = this._super( options );
11672
+
11884
11673
  if ( callRefresh ) {
11885
11674
  this.refresh();
11886
11675
  }
11887
11676
 
11888
- return this._super( options );
11677
+ return returnValue;
11889
11678
  },
11890
11679
 
11891
11680
  container: function() {
@@ -11934,7 +11723,6 @@ $.widget( "mobile.controlgroup", $.extend( {
11934
11723
 
11935
11724
  (function( $, undefined ) {
11936
11725
 
11937
-
11938
11726
  $.widget( "mobile.toolbar", {
11939
11727
  initSelector: ":jqmData(role='footer'), :jqmData(role='header')",
11940
11728
 
@@ -11946,10 +11734,10 @@ $.widget( "mobile.controlgroup", $.extend( {
11946
11734
  },
11947
11735
 
11948
11736
  _create: function() {
11949
- var leftbtn, rightbtn, backBtn,
11737
+ var leftbtn, rightbtn,
11950
11738
  role = this.element.is( ":jqmData(role='header')" ) ? "header" : "footer",
11951
11739
  page = this.element.closest( ".ui-page" );
11952
- if ( page.length === 0 ){
11740
+ if ( page.length === 0 ) {
11953
11741
  page = false;
11954
11742
  this._on( this.document, {
11955
11743
  "pageshow": "refresh"
@@ -11960,7 +11748,7 @@ $.widget( "mobile.controlgroup", $.extend( {
11960
11748
  page: page,
11961
11749
  leftbtn: leftbtn,
11962
11750
  rightbtn: rightbtn,
11963
- backBtn: backBtn
11751
+ backBtn: null
11964
11752
  });
11965
11753
  this.element.attr( "role", role === "header" ? "banner" : "contentinfo" ).addClass( "ui-" + role );
11966
11754
  this.refresh();
@@ -11978,7 +11766,7 @@ $.widget( "mobile.controlgroup", $.extend( {
11978
11766
  this.element.find( ".ui-toolbar-back-btn" ).remove();
11979
11767
  }
11980
11768
  }
11981
- if ( o.backBtnTheme !== undefined ) {
11769
+ if ( o.backBtnTheme != null ) {
11982
11770
  this.element
11983
11771
  .find( ".ui-toolbar-back-btn" )
11984
11772
  .addClass( "ui-btn ui-btn-" + o.backBtnTheme );
@@ -12000,7 +11788,7 @@ $.widget( "mobile.controlgroup", $.extend( {
12000
11788
  this._addHeaderButtonClasses();
12001
11789
  }
12002
11790
  if ( !this.page ) {
12003
- $( "[data-"+ $.mobile.ns +"role='page']" ).css({"position":"relative"});
11791
+ this._setRelative();
12004
11792
  if ( this.role === "footer" ) {
12005
11793
  this.element.appendTo( "body" );
12006
11794
  }
@@ -12008,11 +11796,18 @@ $.widget( "mobile.controlgroup", $.extend( {
12008
11796
  this._addHeadingClasses();
12009
11797
  this._btnMarkup();
12010
11798
  },
12011
- // Deprecated in 1.4. As from 1.5 data-role="button" has to be present in the markup.
11799
+
11800
+ //we only want this to run on non fixed toolbars so make it easy to override
11801
+ _setRelative: function() {
11802
+ $( "[data-"+ $.mobile.ns + "role='page']" ).css({ "position": "relative" });
11803
+ },
11804
+
11805
+ // Deprecated in 1.4. As from 1.5 button classes have to be present in the markup.
12012
11806
  _btnMarkup: function() {
12013
11807
  this.element.children( "a" ).attr( "data-" + $.mobile.ns + "role", "button" );
12014
11808
  this.element.trigger( "create" );
12015
11809
  },
11810
+ // Deprecated in 1.4. As from 1.5 ui-btn-left/right classes have to be present in the markup.
12016
11811
  _addHeaderButtonClasses: function() {
12017
11812
  var $headeranchors = this.element.children( "a, button" );
12018
11813
  this.leftbtn = $headeranchors.hasClass( "ui-btn-left" );
@@ -12024,10 +11819,18 @@ $.widget( "mobile.controlgroup", $.extend( {
12024
11819
 
12025
11820
  },
12026
11821
  _addBackButton: function() {
12027
- this.backBtn = $( "<a role='button' href='javascript:void(0);' class='ui-btn-left ui-toolbar-back-btn' data-" + $.mobile.ns + "rel='back' data-" + $.mobile.ns + "icon='carat-l'>" + this.options.backBtnText + "</a>" )
12028
- // If theme is provided, override default inheritance
12029
- .attr( "data-" + $.mobile.ns + "theme", this.options.backBtnTheme || this.options.theme )
12030
- .prependTo( this.element );
11822
+ var theme,
11823
+ options = this.options;
11824
+
11825
+ if ( !this.backBtn ) {
11826
+ theme = options.backBtnTheme || options.theme;
11827
+ this.backBtn = $( "<a role='button' href='javascript:void(0);' " +
11828
+ "class='ui-btn ui-corner-all ui-shadow ui-btn-left " +
11829
+ ( theme ? "ui-btn-" + theme + " " : "" ) +
11830
+ "ui-toolbar-back-btn ui-icon-carat-l ui-btn-icon-left' " +
11831
+ "data-" + $.mobile.ns + "rel='back'>" + options.backBtnText + "</a>" )
11832
+ .prependTo( this.element );
11833
+ }
12031
11834
  },
12032
11835
  _addHeadingClasses: function() {
12033
11836
  this.element.children( "h1, h2, h3, h4, h5, h6" )
@@ -12039,12 +11842,11 @@ $.widget( "mobile.controlgroup", $.extend( {
12039
11842
  });
12040
11843
  }
12041
11844
  });
12042
-
11845
+
12043
11846
  })( jQuery );
12044
11847
 
12045
11848
  (function( $, undefined ) {
12046
11849
 
12047
-
12048
11850
  $.widget( "mobile.toolbar", $.mobile.toolbar, {
12049
11851
  options: {
12050
11852
  position:null,
@@ -12071,12 +11873,12 @@ $.widget( "mobile.controlgroup", $.extend( {
12071
11873
 
12072
11874
  _create: function() {
12073
11875
  this._super();
12074
- if ( this.options.position === "fixed" && !this.options.supportBlacklist() ){
11876
+ if ( this.options.position === "fixed" && !this.options.supportBlacklist() ) {
12075
11877
  this._makeFixed();
12076
11878
  }
12077
11879
  },
12078
11880
 
12079
- _makeFixed: function(){
11881
+ _makeFixed: function() {
12080
11882
  this.element.addClass( "ui-"+ this.role +"-fixed" );
12081
11883
  this.updatePagePadding();
12082
11884
  this._addTransitionClass();
@@ -12085,14 +11887,14 @@ $.widget( "mobile.controlgroup", $.extend( {
12085
11887
  this._setOptions( this.options );
12086
11888
  },
12087
11889
 
12088
- _setOptions: function( o ){
12089
- if( o.position === "fixed" && this.options.position !== "fixed" ) {
11890
+ _setOptions: function( o ) {
11891
+ if ( o.position === "fixed" && this.options.position !== "fixed" ) {
12090
11892
  this._makeFixed();
12091
11893
  }
12092
- if ( this.options.position === "fixed" && !this.options.supportBlacklist() ){
11894
+ if ( this.options.position === "fixed" && !this.options.supportBlacklist() ) {
12093
11895
  var $page = ( !!this.page )? this.page: ( $(".ui-page-active").length > 0 )? $(".ui-page-active"): $(".ui-page").eq(0);
12094
11896
 
12095
- if ( o.fullscreen !== undefined){
11897
+ if ( o.fullscreen !== undefined) {
12096
11898
  if ( o.fullscreen ) {
12097
11899
  this.element.addClass( "ui-"+ this.role +"-fullscreen" );
12098
11900
  $page.addClass( "ui-page-" + this.role + "-fullscreen" );
@@ -12162,7 +11964,6 @@ $.widget( "mobile.controlgroup", $.extend( {
12162
11964
  var o = this.options,
12163
11965
  thisFooter, thisHeader, nextFooter, nextHeader;
12164
11966
 
12165
-
12166
11967
  if ( o.disablePageZoom ) {
12167
11968
  $.mobile.zoom.enable( true );
12168
11969
  }
@@ -12308,6 +12109,12 @@ $.widget( "mobile.controlgroup", $.extend( {
12308
12109
  });
12309
12110
  },
12310
12111
 
12112
+ _setRelative: function() {
12113
+ if( this.options.position !== "fixed" ){
12114
+ $( "[data-"+ $.mobile.ns + "role='page']" ).css({ "position": "relative" });
12115
+ }
12116
+ },
12117
+
12311
12118
  _destroy: function() {
12312
12119
  var $el = this.element,
12313
12120
  header = $el.hasClass( "ui-header" );
@@ -12323,7 +12130,7 @@ $.widget( "mobile.controlgroup", $.extend( {
12323
12130
  (function( $, undefined ) {
12324
12131
  $.widget( "mobile.toolbar", $.mobile.toolbar, {
12325
12132
 
12326
- _create: function() {
12133
+ _makeFixed: function() {
12327
12134
  this._super();
12328
12135
  this._workarounds();
12329
12136
  },
@@ -12708,7 +12515,7 @@ $.widget( "mobile.panel", {
12708
12515
  _wrapper: this._getWrapper,
12709
12516
  _fixedToolbars: this._getFixedToolbars
12710
12517
  });
12711
-
12518
+
12712
12519
  this._addPanelClasses();
12713
12520
 
12714
12521
  // if animating, add the class to do so
@@ -12727,17 +12534,17 @@ $.widget( "mobile.panel", {
12727
12534
 
12728
12535
  this._bindSwipeEvents();
12729
12536
  },
12730
-
12537
+
12731
12538
  _getPanelInner: function() {
12732
12539
  var panelInner = this.element.find( "." + this.options.classes.panelInner );
12733
-
12540
+
12734
12541
  if ( panelInner.length === 0 ) {
12735
12542
  panelInner = this.element.children().wrapAll( "<div class='" + this.options.classes.panelInner + "' />" ).parent();
12736
12543
  }
12737
-
12544
+
12738
12545
  return panelInner;
12739
12546
  },
12740
-
12547
+
12741
12548
  _createModal: function() {
12742
12549
  var self = this,
12743
12550
  target = self._parentPage ? self._parentPage.parent() : self.element.parent();
@@ -12748,29 +12555,28 @@ $.widget( "mobile.panel", {
12748
12555
  })
12749
12556
  .appendTo( target );
12750
12557
  },
12751
-
12558
+
12752
12559
  _getPage: function() {
12753
12560
  var page = this._parentPage ? this._parentPage : $( "." + $.mobile.activePageClass );
12754
-
12561
+
12755
12562
  return page;
12756
12563
  },
12757
-
12564
+
12758
12565
  _getWrapper: function() {
12759
- var wrapper = this._page().find( "." + this.options.classes.pageWrapper ),
12760
- animateClass = ( $.support.cssTransform3d && !!this.options.animate ) ? " " + this.options.classes.animate : "";
12566
+ var wrapper = this._page().find( "." + this.options.classes.pageWrapper );
12761
12567
 
12762
12568
  if ( wrapper.length === 0 ) {
12763
- wrapper = this._page().children( ".ui-header:not(:jqmData(position='fixed')), .ui-content:not(:jqmData(role='popup')), .ui-footer:not(:jqmData(position='fixed'))" )
12764
- .wrapAll( "<div class='" + this.options.classes.pageWrapper + animateClass + "' /></div>" )
12569
+ wrapper = this._page().children( ".ui-header:not(.ui-header-fixed), .ui-content:not(.ui-popup), .ui-footer:not(.ui-footer-fixed)" )
12570
+ .wrapAll( "<div class='" + this.options.classes.pageWrapper + "'></div>" )
12765
12571
  .parent();
12766
12572
  }
12767
12573
 
12768
12574
  return wrapper;
12769
12575
  },
12770
-
12576
+
12771
12577
  _getFixedToolbars: function() {
12772
- var extFixedToolbars = $( "body" ).children( ".ui-header:jqmData(position='fixed'), .ui-footer:jqmData(position='fixed')" ),
12773
- intFixedToolbars = this._page().find( ".ui-header:jqmData(position='fixed'), .ui-footer:jqmData(position='fixed')" ),
12578
+ var extFixedToolbars = $( "body" ).children( ".ui-header-fixed, .ui-footer-fixed" ),
12579
+ intFixedToolbars = this._page().find( ".ui-header-fixed, .ui-footer-fixed" ),
12774
12580
  fixedToolbars = extFixedToolbars.add( intFixedToolbars ).addClass( this.options.classes.pageFixedToolbar );
12775
12581
 
12776
12582
  return fixedToolbars;
@@ -12860,10 +12666,10 @@ $.widget( "mobile.panel", {
12860
12666
  this._on( "body", {
12861
12667
  "click a": "_handleClick"
12862
12668
  });
12863
-
12669
+
12864
12670
  },
12865
12671
 
12866
- _handleClick: function( e ){
12672
+ _handleClick: function( e ) {
12867
12673
  if ( e.currentTarget.href.split( "#" )[ 1 ] === this._panelID && this._panelID !== undefined ) {
12868
12674
  e.preventDefault();
12869
12675
  var link = $( e.target );
@@ -12912,7 +12718,7 @@ $.widget( "mobile.panel", {
12912
12718
  self.close();
12913
12719
  }
12914
12720
  });
12915
-
12721
+
12916
12722
  // Clean up open panels after page hide
12917
12723
  if ( self._parentPage ) {
12918
12724
  this.document.on( "pagehide", ":jqmData(role='page')", function() {
@@ -12938,11 +12744,11 @@ $.widget( "mobile.panel", {
12938
12744
  if ( !this._open ) {
12939
12745
  var self = this,
12940
12746
  o = self.options,
12941
-
12747
+
12942
12748
  _openPanel = function() {
12943
12749
  self.document.off( "panelclose" );
12944
12750
  self._page().jqmData( "panel", "open" );
12945
-
12751
+
12946
12752
  if ( $.support.cssTransform3d && !!o.animate && o.display !== "overlay" ) {
12947
12753
  self._wrapper().addClass( o.classes.animate );
12948
12754
  self._fixedToolbars().addClass( o.classes.animate );
@@ -12966,7 +12772,7 @@ $.widget( "mobile.panel", {
12966
12772
  self._positionPanel();
12967
12773
 
12968
12774
  self._pageContentOpenClasses = self._getPosDisplayClasses( o.classes.pageContentPrefix );
12969
-
12775
+
12970
12776
  if ( o.display !== "overlay" ) {
12971
12777
  self._page().parent().addClass( o.classes.pageContainer );
12972
12778
  self._wrapper().addClass( self._pageContentOpenClasses );
@@ -12982,7 +12788,7 @@ $.widget( "mobile.panel", {
12982
12788
  },
12983
12789
  complete = function() {
12984
12790
  self.document.off( self._transitionEndEvents, complete );
12985
-
12791
+
12986
12792
  if ( o.display !== "overlay" ) {
12987
12793
  self._wrapper().addClass( o.classes.pageContentPrefix + "-open" );
12988
12794
  self._fixedToolbars().addClass( o.classes.pageContentPrefix + "-open" );
@@ -12994,7 +12800,7 @@ $.widget( "mobile.panel", {
12994
12800
  };
12995
12801
 
12996
12802
  self._trigger( "beforeopen" );
12997
-
12803
+
12998
12804
  if ( self._page().jqmData( "panel" ) === "open" ) {
12999
12805
  self.document.on( "panelclose", function() {
13000
12806
  _openPanel();
@@ -13011,7 +12817,7 @@ $.widget( "mobile.panel", {
13011
12817
  if ( this._open ) {
13012
12818
  var self = this,
13013
12819
  o = this.options,
13014
-
12820
+
13015
12821
  _closePanel = function() {
13016
12822
  if ( !immediate && $.support.cssTransform3d && !!o.animate ) {
13017
12823
  self.document.on( self._transitionEndEvents, complete );
@@ -13020,23 +12826,23 @@ $.widget( "mobile.panel", {
13020
12826
  }
13021
12827
 
13022
12828
  self.element.removeClass( o.classes.panelOpen );
13023
-
12829
+
13024
12830
  if ( o.display !== "overlay" ) {
13025
12831
  self._wrapper().removeClass( self._pageContentOpenClasses );
13026
12832
  self._fixedToolbars().removeClass( self._pageContentOpenClasses );
13027
12833
  }
13028
-
12834
+
13029
12835
  if ( self._modal ) {
13030
12836
  self._modal.removeClass( self._modalOpenClasses );
13031
12837
  }
13032
12838
  },
13033
12839
  complete = function() {
13034
12840
  self.document.off( self._transitionEndEvents, complete );
13035
-
12841
+
13036
12842
  if ( o.theme && o.display !== "overlay" ) {
13037
12843
  self._page().parent().removeClass( o.classes.pageContainer + "-themed " + o.classes.pageContainer + "-" + o.theme );
13038
12844
  }
13039
-
12845
+
13040
12846
  self.element.addClass( o.classes.panelClosed );
13041
12847
 
13042
12848
  if ( o.display !== "overlay" ) {
@@ -13055,7 +12861,7 @@ $.widget( "mobile.panel", {
13055
12861
  $.mobile.resetActivePageHeight();
13056
12862
 
13057
12863
  self._page().jqmRemoveData( "panel" );
13058
-
12864
+
13059
12865
  self._trigger( "close" );
13060
12866
  };
13061
12867
 
@@ -13074,23 +12880,28 @@ $.widget( "mobile.panel", {
13074
12880
  _transitionEndEvents: "webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd",
13075
12881
 
13076
12882
  _destroy: function() {
13077
- var o = this.options,
13078
- multiplePanels = ( $( "body > :mobile-panel" ).length + $.mobile.activePage.find( ":mobile-panel" ).length ) > 1;
12883
+ var otherPanels,
12884
+ o = this.options,
12885
+ multiplePanels = ( $( "body > :mobile-panel" ).length + $.mobile.activePage.find( ":mobile-panel" ).length ) > 1;
13079
12886
 
13080
12887
  if ( o.display !== "overlay" ) {
13081
- // Destroy the wrapper even if there are still other panels, because we don't know if they use a wrapper
13082
- this._wrapper().children().unwrap();
12888
+
12889
+ // remove the wrapper if not in use by another panel
12890
+ otherPanels = $( "body > :mobile-panel" ).add( $.mobile.activePage.find( ":mobile-panel" ) );
12891
+ if ( otherPanels.not( ".ui-panel-display-overlay" ).not( this.element ).length === 0 ) {
12892
+ this._wrapper().children().unwrap();
12893
+ }
13083
12894
 
13084
12895
  if ( this._open ) {
13085
-
12896
+
13086
12897
  this._fixedToolbars().removeClass( o.classes.pageContentPrefix + "-open" );
13087
-
12898
+
13088
12899
  if ( $.support.cssTransform3d && !!o.animate ) {
13089
12900
  this._fixedToolbars().removeClass( o.classes.animate );
13090
12901
  }
13091
-
12902
+
13092
12903
  this._page().parent().removeClass( o.classes.pageContainer );
13093
-
12904
+
13094
12905
  if ( o.theme ) {
13095
12906
  this._page().parent().removeClass( o.classes.pageContainer + "-themed " + o.classes.pageContainer + "-" + o.theme );
13096
12907
  }
@@ -13100,17 +12911,17 @@ $.widget( "mobile.panel", {
13100
12911
  if ( !multiplePanels ) {
13101
12912
 
13102
12913
  this.document.off( "panelopen panelclose" );
13103
-
12914
+
13104
12915
  if ( this._open ) {
13105
12916
  this.document.off( this._transitionEndEvents );
13106
12917
  $.mobile.resetActivePageHeight();
13107
12918
  }
13108
12919
  }
13109
-
12920
+
13110
12921
  if ( this._open ) {
13111
12922
  this._page().jqmRemoveData( "panel" );
13112
12923
  }
13113
-
12924
+
13114
12925
  this._panelInner.children().unwrap();
13115
12926
 
13116
12927
  this.element
@@ -13201,206 +13012,490 @@ $.widget( "mobile.table", {
13201
13012
  }
13202
13013
  }
13203
13014
 
13204
- // Store "cells" data on header as a reference to all cells in the
13205
- // same column as this TH
13206
- $( this ).jqmData( "cells", table.find( "tr" ).not( trs.eq( 0 ) ).not( this ).children( selector ) );
13015
+ // Store "cells" data on header as a reference to all cells in the
13016
+ // same column as this TH
13017
+ $( this ).jqmData( "cells", table.find( "tr" ).not( trs.eq( 0 ) ).not( this ).children( selector ) );
13018
+
13019
+ columnCount++;
13020
+ });
13021
+ });
13022
+ }
13023
+ });
13024
+
13025
+ })( jQuery );
13026
+
13027
+
13028
+ (function( $, undefined ) {
13029
+
13030
+ $.widget( "mobile.table", $.mobile.table, {
13031
+ options: {
13032
+ mode: "columntoggle",
13033
+ columnBtnTheme: null,
13034
+ columnPopupTheme: null,
13035
+ columnBtnText: "Columns...",
13036
+ classes: $.extend( $.mobile.table.prototype.options.classes, {
13037
+ popup: "ui-table-columntoggle-popup",
13038
+ columnBtn: "ui-table-columntoggle-btn",
13039
+ priorityPrefix: "ui-table-priority-",
13040
+ columnToggleTable: "ui-table-columntoggle"
13041
+ })
13042
+ },
13043
+
13044
+ _create: function() {
13045
+ this._super();
13046
+
13047
+ if ( this.options.mode !== "columntoggle" ) {
13048
+ return;
13049
+ }
13050
+
13051
+ $.extend( this, {
13052
+ _menu: null
13053
+ });
13054
+
13055
+ if ( this.options.enhanced ) {
13056
+ this._menu = $( this.document[ 0 ].getElementById( this._id() + "-popup" ) ).children().first();
13057
+ this._addToggles( this._menu, true );
13058
+ this._bindToggles( this._menu );
13059
+ } else {
13060
+ this._menu = this._enhanceColToggle();
13061
+ this.element.addClass( this.options.classes.columnToggleTable );
13062
+ }
13063
+
13064
+ this._setupEvents();
13065
+
13066
+ this._setToggleState();
13067
+ },
13068
+
13069
+ _id: function() {
13070
+ return ( this.element.attr( "id" ) || ( this.widgetName + this.uuid ) );
13071
+ },
13072
+
13073
+ _setupEvents: function() {
13074
+ //NOTE: inputs are bound in bindToggles,
13075
+ // so it can be called on refresh, too
13076
+
13077
+ // update column toggles on resize
13078
+ this._on( this.window, {
13079
+ throttledresize: "_setToggleState"
13080
+ });
13081
+ },
13082
+
13083
+ _bindToggles: function( menu ) {
13084
+ var inputs = menu.find( "input" );
13085
+
13086
+ this._on( inputs, {
13087
+ change: "_menuInputChange"
13088
+ });
13089
+ },
13090
+
13091
+ _addToggles: function( menu, keep ) {
13092
+ var inputs,
13093
+ checkboxIndex = 0,
13094
+ opts = this.options,
13095
+ container = menu.controlgroup( "container" );
13096
+
13097
+ // allow update of menu on refresh (fixes #5880)
13098
+ if ( keep ) {
13099
+ inputs = menu.find( "input" );
13100
+ } else {
13101
+ container.empty();
13102
+ }
13103
+
13104
+ // create the hide/show toggles
13105
+ this.headers.not( "td" ).each( function() {
13106
+ var header = $( this ),
13107
+ priority = $.mobile.getAttribute( this, "priority" ),
13108
+ cells = header.add( header.jqmData( "cells" ) );
13109
+
13110
+ if ( priority ) {
13111
+ cells.addClass( opts.classes.priorityPrefix + priority );
13112
+
13113
+ ( keep ? inputs.eq( checkboxIndex++ ) :
13114
+ $("<label><input type='checkbox' checked />" +
13115
+ ( header.children( "abbr" ).first().attr( "title" ) ||
13116
+ header.text() ) +
13117
+ "</label>" )
13118
+ .appendTo( container )
13119
+ .children( 0 )
13120
+ .checkboxradio( {
13121
+ theme: opts.columnPopupTheme
13122
+ }) )
13123
+ .jqmData( "cells", cells );
13124
+ }
13125
+ });
13126
+
13127
+ // set bindings here
13128
+ if ( !keep ) {
13129
+ menu.controlgroup( "refresh" );
13130
+ this._bindToggles( menu );
13131
+ }
13132
+ },
13133
+
13134
+ _menuInputChange: function( evt ) {
13135
+ var input = $( evt.target ),
13136
+ checked = input[ 0 ].checked;
13137
+
13138
+ input.jqmData( "cells" )
13139
+ .toggleClass( "ui-table-cell-hidden", !checked )
13140
+ .toggleClass( "ui-table-cell-visible", checked );
13141
+
13142
+ if ( input[ 0 ].getAttribute( "locked" ) ) {
13143
+ input.removeAttr( "locked" );
13144
+
13145
+ this._unlockCells( input.jqmData( "cells" ) );
13146
+ } else {
13147
+ input.attr( "locked", true );
13148
+ }
13149
+ },
13150
+
13151
+ _unlockCells: function( cells ) {
13152
+ // allow hide/show via CSS only = remove all toggle-locks
13153
+ cells.removeClass( "ui-table-cell-hidden ui-table-cell-visible");
13154
+ },
13155
+
13156
+ _enhanceColToggle: function() {
13157
+ var id , menuButton, popup, menu,
13158
+ table = this.element,
13159
+ opts = this.options,
13160
+ ns = $.mobile.ns,
13161
+ fragment = this.document[ 0 ].createDocumentFragment();
13162
+
13163
+ id = this._id() + "-popup";
13164
+ menuButton = $( "<a href='#" + id + "' " +
13165
+ "class='" + opts.classes.columnBtn + " ui-btn " +
13166
+ "ui-btn-" + ( opts.columnBtnTheme || "a" ) +
13167
+ " ui-corner-all ui-shadow ui-mini' " +
13168
+ "data-" + ns + "rel='popup'>" + opts.columnBtnText + "</a>" );
13169
+ popup = $( "<div class='" + opts.classes.popup + "' id='" + id + "'></div>" );
13170
+ menu = $( "<fieldset></fieldset>" ).controlgroup();
13171
+
13172
+ // set extension here, send "false" to trigger build/rebuild
13173
+ this._addToggles( menu, false );
13174
+
13175
+ menu.appendTo( popup );
13176
+
13177
+ fragment.appendChild( popup[ 0 ] );
13178
+ fragment.appendChild( menuButton[ 0 ] );
13179
+ table.before( fragment );
13180
+
13181
+ popup.popup();
13182
+
13183
+ return menu;
13184
+ },
13185
+
13186
+ rebuild: function() {
13187
+ this._super();
13188
+
13189
+ if ( this.options.mode === "columntoggle" ) {
13190
+ // NOTE: rebuild passes "false", while refresh passes "undefined"
13191
+ // both refresh the table, but inside addToggles, !false will be true,
13192
+ // so a rebuild call can be indentified
13193
+ this._refresh( false );
13194
+ }
13195
+ },
13196
+
13197
+ _refresh: function( create ) {
13198
+ this._super( create );
13199
+
13200
+ if ( !create && this.options.mode === "columntoggle" ) {
13201
+ // columns not being replaced must be cleared from input toggle-locks
13202
+ this._unlockCells( this.allHeaders );
13203
+
13204
+ // update columntoggles and cells
13205
+ this._addToggles( this._menu, create );
13206
+
13207
+ // check/uncheck
13208
+ this._setToggleState();
13209
+ }
13210
+ },
13211
+
13212
+ _setToggleState: function() {
13213
+ this._menu.find( "input" ).each( function() {
13214
+ var checkbox = $( this );
13207
13215
 
13208
- columnCount++;
13209
- });
13216
+ this.checked = checkbox.jqmData( "cells" ).eq( 0 ).css( "display" ) === "table-cell";
13217
+ checkbox.checkboxradio( "refresh" );
13210
13218
  });
13219
+ },
13220
+
13221
+ _destroy: function() {
13222
+ this._super();
13211
13223
  }
13212
13224
  });
13213
13225
 
13214
13226
  })( jQuery );
13215
13227
 
13216
-
13217
13228
  (function( $, undefined ) {
13218
13229
 
13219
13230
  $.widget( "mobile.table", $.mobile.table, {
13220
13231
  options: {
13221
- mode: "columntoggle",
13222
- columnBtnTheme: null,
13223
- columnPopupTheme: null,
13224
- columnBtnText: "Columns...",
13232
+ mode: "reflow",
13225
13233
  classes: $.extend( $.mobile.table.prototype.options.classes, {
13226
- popup: "ui-table-columntoggle-popup",
13227
- columnBtn: "ui-table-columntoggle-btn",
13228
- priorityPrefix: "ui-table-priority-",
13229
- columnToggleTable: "ui-table-columntoggle"
13234
+ reflowTable: "ui-table-reflow",
13235
+ cellLabels: "ui-table-cell-label"
13230
13236
  })
13231
13237
  },
13232
13238
 
13233
13239
  _create: function() {
13234
13240
  this._super();
13235
13241
 
13236
- if( this.options.mode !== "columntoggle" ) {
13242
+ // If it's not reflow mode, return here.
13243
+ if ( this.options.mode !== "reflow" ) {
13237
13244
  return;
13238
13245
  }
13239
13246
 
13240
- $.extend( this, {
13241
- _menu: null
13242
- });
13247
+ if ( !this.options.enhanced ) {
13248
+ this.element.addClass( this.options.classes.reflowTable );
13243
13249
 
13244
- if( this.options.enhanced ) {
13245
- this._menu = this.document.find( this._id() + "-popup" ).children().first();
13246
- } else {
13247
- this._menu = this._enhanceColToggle();
13248
- this.element.addClass( this.options.classes.columnToggleTable );
13250
+ this._updateReflow();
13249
13251
  }
13252
+ },
13250
13253
 
13251
- this._setupEvents();
13254
+ rebuild: function() {
13255
+ this._super();
13252
13256
 
13253
- this._setToggleState();
13257
+ if ( this.options.mode === "reflow" ) {
13258
+ this._refresh( false );
13259
+ }
13254
13260
  },
13255
13261
 
13256
- _id: function() {
13257
- return ( this.element.attr( "id" ) || ( this.widgetName + this.uuid ) );
13262
+ _refresh: function( create ) {
13263
+ this._super( create );
13264
+ if ( !create && this.options.mode === "reflow" ) {
13265
+ this._updateReflow( );
13266
+ }
13258
13267
  },
13259
13268
 
13260
- _setupEvents: function() {
13261
- //NOTE: inputs are bound in bindToggles,
13262
- // so it can be called on refresh, too
13269
+ _updateReflow: function() {
13270
+ var table = this,
13271
+ opts = this.options;
13263
13272
 
13264
- // update column toggles on resize
13265
- this._on( this.window, {
13266
- throttledresize: "_setToggleState"
13267
- });
13268
- },
13273
+ // get headers in reverse order so that top-level headers are appended last
13274
+ $( table.allHeaders.get().reverse() ).each( function() {
13275
+ var cells = $( this ).jqmData( "cells" ),
13276
+ colstart = $.mobile.getAttribute( this, "colstart" ),
13277
+ hierarchyClass = cells.not( this ).filter( "thead th" ).length && " ui-table-cell-label-top",
13278
+ text = $( this ).text(),
13279
+ iteration, filter;
13269
13280
 
13270
- _bindToggles: function( menu ) {
13271
- var inputs = menu.find( "input" );
13281
+ if ( text !== "" ) {
13272
13282
 
13273
- this._on( inputs, {
13274
- change: "_menuInputChange"
13283
+ if ( hierarchyClass ) {
13284
+ iteration = parseInt( this.getAttribute( "colspan" ), 10 );
13285
+ filter = "";
13286
+
13287
+ if ( iteration ) {
13288
+ filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
13289
+ }
13290
+
13291
+ table._addLabels( cells.filter( filter ), opts.classes.cellLabels + hierarchyClass, text );
13292
+ } else {
13293
+ table._addLabels( cells, opts.classes.cellLabels, text );
13294
+ }
13295
+
13296
+ }
13275
13297
  });
13276
13298
  },
13277
13299
 
13278
- _addToggles: function( menu, keep ) {
13279
- var opts = this.options;
13300
+ _addLabels: function( cells, label, text ) {
13301
+ // .not fixes #6006
13302
+ cells.not( ":has(b." + label + ")" ).prepend( "<b class='" + label + "'>" + text + "</b>" );
13303
+ }
13304
+ });
13280
13305
 
13281
- // allow update of menu on refresh (fixes #5880)
13282
- if ( !keep ) {
13283
- menu.empty();
13284
- }
13306
+ })( jQuery );
13285
13307
 
13286
- // create the hide/show toggles
13287
- this.headers.not( "td" ).each( function() {
13288
- var header = $( this ),
13289
- priority = $.mobile.getAttribute( this, "priority" ),
13290
- cells = header.add( header.jqmData( "cells" ) );
13308
+ (function( $, undefined ) {
13291
13309
 
13292
- if( priority ) {
13293
- cells.addClass( opts.classes.priorityPrefix + priority );
13310
+ // TODO rename filterCallback/deprecate and default to the item itself as the first argument
13311
+ var defaultFilterCallback = function( index, searchValue ) {
13312
+ return ( ( "" + ( $.mobile.getAttribute( this, "filtertext" ) || $( this ).text() ) )
13313
+ .toLowerCase().indexOf( searchValue ) === -1 );
13314
+ };
13294
13315
 
13295
- if ( !keep ) {
13296
- $("<label><input type='checkbox' checked />" +
13297
- ( header.children( "abbr" ).first().attr( "title" ) ||
13298
- header.text() ) +
13299
- "</label>" )
13300
- .appendTo( menu )
13301
- .children( 0 )
13302
- .jqmData( "cells", cells )
13303
- .checkboxradio( {
13304
- theme: opts.columnPopupTheme
13305
- });
13306
- }
13307
- }
13316
+ $.widget( "mobile.filterable", {
13317
+
13318
+ initSelector: ":jqmData(filter='true')",
13319
+
13320
+ options: {
13321
+ filterReveal: false,
13322
+ filterCallback: defaultFilterCallback,
13323
+ enhanced: false,
13324
+ input: null,
13325
+ children: "> li, > option, > optgroup option, > tbody tr, > .ui-controlgroup-controls > .ui-btn, > .ui-controlgroup-controls > .ui-checkbox, > .ui-controlgroup-controls > .ui-radio"
13326
+ },
13327
+
13328
+ _create: function() {
13329
+ var opts = this.options;
13330
+
13331
+ $.extend( this, {
13332
+ _search: null,
13333
+ _timer: 0
13308
13334
  });
13309
13335
 
13310
- // set bindings here
13311
- if ( !keep ) {
13312
- this._bindToggles( menu );
13336
+ this._setInput( opts.input );
13337
+ if ( !opts.enhanced ) {
13338
+ this._filterItems( ( ( this._search && this._search.val() ) || "" ).toLowerCase() );
13313
13339
  }
13314
13340
  },
13315
13341
 
13316
- _menuInputChange: function( evt ) {
13317
- var input = $( evt.target ),
13318
- checked = input[ 0 ].checked;
13342
+ _onKeyUp: function() {
13343
+ var val, lastval,
13344
+ search = this._search;
13319
13345
 
13320
- input.jqmData( "cells" )
13321
- .toggleClass( "ui-table-cell-hidden", !checked )
13322
- .toggleClass( "ui-table-cell-visible", checked );
13346
+ if ( search ) {
13347
+ val = search.val().toLowerCase(),
13348
+ lastval = $.mobile.getAttribute( search[ 0 ], "lastval" ) + "";
13323
13349
 
13324
- if ( input[ 0 ].getAttribute( "locked" ) ) {
13325
- input.removeAttr( "locked" );
13350
+ if ( lastval && lastval === val ) {
13351
+ // Execute the handler only once per value change
13352
+ return;
13353
+ }
13326
13354
 
13327
- this._unlockCells( input.jqmData( "cells" ) );
13328
- } else {
13329
- input.attr( "locked", true );
13355
+ if ( this._timer ) {
13356
+ window.clearTimeout( this._timer );
13357
+ this._timer = 0;
13358
+ }
13359
+
13360
+ this._timer = this._delay( function() {
13361
+ this._trigger( "beforefilter", "beforefilter", { input: search } );
13362
+
13363
+ // Change val as lastval for next execution
13364
+ search[ 0 ].setAttribute( "data-" + $.mobile.ns + "lastval", val );
13365
+
13366
+ this._filterItems( val );
13367
+ this._timer = 0;
13368
+ }, 250 );
13330
13369
  }
13331
13370
  },
13332
13371
 
13333
- _unlockCells: function( cells ) {
13334
- // allow hide/show via CSS only = remove all toggle-locks
13335
- cells.removeClass( "ui-table-cell-hidden ui-table-cell-visible");
13372
+ _getFilterableItems: function() {
13373
+ var elem = this.element,
13374
+ children = this.options.children,
13375
+ items = !children ? { length: 0 }:
13376
+ $.isFunction( children ) ? children():
13377
+ children.nodeName ? $( children ):
13378
+ children.jquery ? children:
13379
+ this.element.find( children );
13380
+
13381
+ if ( items.length === 0 ) {
13382
+ items = elem.children();
13383
+ }
13384
+
13385
+ return items;
13336
13386
  },
13337
13387
 
13338
- _enhanceColToggle: function() {
13339
- var id , menuButton, popup, menu,
13340
- table = this.element,
13388
+ _filterItems: function( val ) {
13389
+ var idx, callback, length, dst,
13390
+ show = [],
13391
+ hide = [],
13341
13392
  opts = this.options,
13342
- ns = $.mobile.ns,
13343
- fragment = this.document[ 0 ].createDocumentFragment();
13393
+ filterItems = this._getFilterableItems();
13344
13394
 
13345
- id = this._id() + "-popup";
13346
- menuButton = $( "<a role='button' href='#" + id + "' " +
13347
- "class='" + opts.classes.columnBtn + " ui-btn ui-btn-" + ( opts.columnBtnTheme || "a" ) + " ui-corner-all ui-shadow ui-mini' " +
13348
- "data-" + ns + "rel='popup' " +
13349
- "data-" + ns + "mini='true'>" + opts.columnBtnText + "</a>" );
13350
- popup = $( "<div data-" + ns + "role='popup' data-" + ns + "role='fieldcontain' class='" + opts.classes.popup + "' id='" + id + "'></div>" );
13351
- menu = $( "<fieldset data-" + ns + "role='controlgroup'></fieldset>" );
13395
+ if ( val != null ) {
13396
+ callback = opts.filterCallback || defaultFilterCallback;
13397
+ length = filterItems.length;
13352
13398
 
13353
- // set extension here, send "false" to trigger build/rebuild
13354
- this._addToggles( menu, false );
13399
+ // Partition the items into those to be hidden and those to be shown
13400
+ for ( idx = 0 ; idx < length ; idx++ ) {
13401
+ dst = ( callback.call( filterItems[ idx ], idx, val ) ) ? hide : show;
13402
+ dst.push( filterItems[ idx ] );
13403
+ }
13404
+ }
13355
13405
 
13356
- menu.appendTo( popup );
13406
+ // If nothing is hidden, then the decision whether to hide or show the items
13407
+ // is based on the "filterReveal" option.
13408
+ if ( hide.length === 0 ) {
13409
+ filterItems[ opts.filterReveal ? "addClass" : "removeClass" ]( "ui-screen-hidden" );
13410
+ } else {
13411
+ $( hide ).addClass( "ui-screen-hidden" );
13412
+ $( show ).removeClass( "ui-screen-hidden" );
13413
+ }
13357
13414
 
13358
- fragment.appendChild( popup[ 0 ] );
13359
- fragment.appendChild( menuButton[ 0 ] );
13360
- table.before( fragment );
13415
+ this._refreshChildWidget();
13416
+ },
13417
+
13418
+ // The Default implementation of _refreshChildWidget attempts to call
13419
+ // refresh on collapsibleset, controlgroup, selectmenu, or listview
13420
+ _refreshChildWidget: function() {
13421
+ var widget, idx,
13422
+ recognizedWidgets = [ "collapsibleset", "selectmenu", "controlgroup", "listview" ];
13361
13423
 
13362
- popup.popup().enhanceWithin();
13424
+ for ( idx = recognizedWidgets.length - 1 ; idx > -1 ; idx-- ) {
13425
+ widget = recognizedWidgets[ idx ];
13426
+ if ( $.mobile[ widget ] ) {
13427
+ widget = this.element.data( "mobile-" + widget );
13428
+ if ( widget && $.isFunction( widget.refresh ) ) {
13429
+ widget.refresh();
13430
+ }
13431
+ }
13432
+ }
13433
+ },
13434
+
13435
+ // TODO: When the input is not internal, do not even store it in this._search
13436
+ _setInput: function ( selector ) {
13437
+ var search = this._search;
13438
+
13439
+ // Stop a pending filter operation
13440
+ if ( this._timer ) {
13441
+ window.clearTimeout( this._timer );
13442
+ this._timer = 0;
13443
+ }
13363
13444
 
13364
- return menu;
13365
- },
13445
+ if ( search ) {
13446
+ this._off( search, "keyup change input" );
13447
+ search = null;
13448
+ }
13366
13449
 
13367
- rebuild: function() {
13368
- this._super();
13450
+ if ( selector ) {
13451
+ search = selector.jquery ? selector:
13452
+ selector.nodeName ? $( selector ):
13453
+ this.document.find( selector );
13369
13454
 
13370
- if ( this.options.mode === "columntoggle" ) {
13371
- // NOTE: rebuild passes "false", while refresh passes "undefined"
13372
- // both refresh the table, but inside addToggles, !false will be true,
13373
- // so a rebuild call can be indentified
13374
- this._refresh( false );
13455
+ this._on( search, {
13456
+ keyup: "_onKeyUp",
13457
+ change: "_onKeyUp",
13458
+ input: "_onKeyUp"
13459
+ });
13375
13460
  }
13461
+
13462
+ this._search = search;
13376
13463
  },
13377
13464
 
13378
- _refresh: function( create ) {
13379
- this._super( create );
13465
+ _setOptions: function( options ) {
13466
+ var refilter = !( ( options.filterReveal === undefined ) &&
13467
+ ( options.filterCallback === undefined ) &&
13468
+ ( options.children === undefined ) );
13380
13469
 
13381
- if ( !create && this.options.mode === "columntoggle" ) {
13382
- // columns not being replaced must be cleared from input toggle-locks
13383
- this._unlockCells( this.allHeaders );
13470
+ this._super( options );
13384
13471
 
13385
- // update columntoggles and cells
13386
- this._addToggles( this._menu, create );
13472
+ if ( options.input !== undefined ) {
13473
+ this._setInput( options.input );
13474
+ refilter = true;
13475
+ }
13387
13476
 
13388
- // check/uncheck
13389
- this._setToggleState();
13477
+ if ( refilter ) {
13478
+ this.refresh();
13390
13479
  }
13391
13480
  },
13392
13481
 
13393
- _setToggleState: function() {
13394
- this._menu.find( "input" ).each( function() {
13395
- var checkbox = $( this );
13482
+ _destroy: function() {
13483
+ var opts = this.options,
13484
+ items = this._getFilterableItems();
13396
13485
 
13397
- this.checked = checkbox.jqmData( "cells" ).eq( 0 ).css( "display" ) === "table-cell";
13398
- checkbox.checkboxradio( "refresh" );
13399
- });
13486
+ if ( opts.enhanced ) {
13487
+ items.toggleClass( "ui-screen-hidden", opts.filterReveal );
13488
+ } else {
13489
+ items.removeClass( "ui-screen-hidden" );
13490
+ }
13400
13491
  },
13401
13492
 
13402
- _destroy: function() {
13403
- this._super();
13493
+ refresh: function() {
13494
+ if ( this._timer ) {
13495
+ window.clearTimeout( this._timer );
13496
+ this._timer = 0;
13497
+ }
13498
+ this._filterItems( ( ( this._search && this._search.val() ) || "" ).toLowerCase() );
13404
13499
  }
13405
13500
  });
13406
13501
 
@@ -13408,79 +13503,170 @@ $.widget( "mobile.table", $.mobile.table, {
13408
13503
 
13409
13504
  (function( $, undefined ) {
13410
13505
 
13411
- $.widget( "mobile.table", $.mobile.table, {
13506
+ // Create a function that will replace the _setOptions function of a widget,
13507
+ // and will pass the options on to the input of the filterable.
13508
+ var replaceSetOptions = function( self, orig ) {
13509
+ return function( options ) {
13510
+ orig.call( this, options );
13511
+ self._syncTextInputOptions( options );
13512
+ };
13513
+ },
13514
+ rDividerListItem = /(^|\s)ui-li-divider(\s|$)/,
13515
+ origDefaultFilterCallback = $.mobile.filterable.prototype.options.filterCallback;
13516
+
13517
+ // Override the default filter callback with one that does not hide list dividers
13518
+ $.mobile.filterable.prototype.options.filterCallback = function( index, searchValue ) {
13519
+ return !this.className.match( rDividerListItem ) &&
13520
+ origDefaultFilterCallback.call( this, index, searchValue );
13521
+ };
13522
+
13523
+ $.widget( "mobile.filterable", $.mobile.filterable, {
13412
13524
  options: {
13413
- mode: "reflow",
13414
- classes: $.extend( $.mobile.table.prototype.options.classes, {
13415
- reflowTable: "ui-table-reflow",
13416
- cellLabels: "ui-table-cell-label"
13417
- })
13525
+ filterPlaceholder: "Filter items...",
13526
+ filterTheme: null
13418
13527
  },
13419
13528
 
13420
13529
  _create: function() {
13530
+ var idx, widgetName,
13531
+ elem = this.element,
13532
+ recognizedWidgets = [ "collapsibleset", "selectmenu", "controlgroup", "listview" ],
13533
+ createHandlers = {};
13534
+
13421
13535
  this._super();
13422
13536
 
13423
- // If it's not reflow mode, return here.
13424
- if( this.options.mode !== "reflow" ) {
13425
- return;
13426
- }
13537
+ $.extend( this, {
13538
+ _widget: null
13539
+ });
13427
13540
 
13428
- if( !this.options.enhanced ) {
13429
- this.element.addClass( this.options.classes.reflowTable );
13541
+ for ( idx = recognizedWidgets.length - 1 ; idx > -1 ; idx-- ) {
13542
+ widgetName = recognizedWidgets[ idx ];
13543
+ if ( $.mobile[ widgetName ] ) {
13544
+ if ( this._setWidget( elem.data( "mobile-" + widgetName ) ) ) {
13545
+ break;
13546
+ } else {
13547
+ createHandlers[ widgetName + "create" ] = "_handleCreate";
13548
+ }
13549
+ }
13550
+ }
13430
13551
 
13431
- this._updateReflow();
13552
+ if ( !this._widget ) {
13553
+ this._on( elem, createHandlers );
13432
13554
  }
13433
13555
  },
13434
13556
 
13435
- rebuild: function() {
13436
- this._super();
13557
+ _handleCreate: function( evt ) {
13558
+ this._setWidget( this.element.data( "mobile-" + evt.type.substring( 0, evt.type.length - 6 ) ) );
13559
+ },
13437
13560
 
13438
- if ( this.options.mode === "reflow" ) {
13439
- this._refresh( false );
13561
+ _setWidget: function( widget ) {
13562
+ if ( !this._widget && widget ) {
13563
+ this._widget = widget;
13564
+ this._widget._setOptions = replaceSetOptions( this, this._widget._setOptions );
13440
13565
  }
13441
- },
13442
13566
 
13443
- _refresh: function( create ) {
13444
- this._super( create );
13445
- if ( !create && this.options.mode === "reflow" ) {
13446
- this._updateReflow( );
13567
+ if ( !!this._widget ) {
13568
+ this._syncTextInputOptions( this._widget.options );
13569
+ if ( this._widget.widgetName === "listview" ) {
13570
+ this._widget.options.hidedividers = true;
13571
+ this._widget.element.listview( "refresh" );
13572
+ }
13447
13573
  }
13448
- },
13449
13574
 
13450
- _updateReflow: function() {
13451
- var table = this,
13452
- opts = this.options;
13575
+ return !!this._widget;
13576
+ },
13453
13577
 
13454
- // get headers in reverse order so that top-level headers are appended last
13455
- $( table.allHeaders.get().reverse() ).each( function() {
13456
- var cells = $( this ).jqmData( "cells" ),
13457
- colstart = $.mobile.getAttribute( this, "colstart" ),
13458
- hierarchyClass = cells.not( this ).filter( "thead th" ).length && " ui-table-cell-label-top",
13459
- text = $( this ).text(),
13460
- iteration, filter;
13578
+ _isSearchInternal: function() {
13579
+ return ( this._search && this._search.jqmData( "ui-filterable-" + this.uuid + "-internal" ) );
13580
+ },
13461
13581
 
13462
- if ( text !== "" ) {
13582
+ _setInput: function( selector ) {
13583
+ var opts = this.options,
13584
+ updatePlaceholder = true,
13585
+ textinputOpts = {};
13463
13586
 
13464
- if( hierarchyClass ) {
13465
- iteration = parseInt( this.getAttribute( "colspan" ), 10 );
13466
- filter = "";
13587
+ if ( !selector ) {
13588
+ if ( this._isSearchInternal() ) {
13467
13589
 
13468
- if ( iteration ){
13469
- filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
13470
- }
13590
+ // Ignore the call to set a new input if the selector goes to falsy and
13591
+ // the current textinput is already of the internally generated variety.
13592
+ return;
13593
+ } else {
13471
13594
 
13472
- table._addLabels( cells.filter( filter ), opts.classes.cellLabels + hierarchyClass, text );
13473
- } else {
13474
- table._addLabels( cells, opts.classes.cellLabels, text );
13595
+ // Generating a new textinput widget. No need to set the placeholder
13596
+ // further down the function.
13597
+ updatePlaceholder = false;
13598
+ selector = $( "<input " +
13599
+ "data-" + $.mobile.ns + "type='search' " +
13600
+ "placeholder='" + opts.filterPlaceholder + "'></input>" )
13601
+ .jqmData( "ui-filterable-" + this.uuid + "-internal", true );
13602
+ $( "<form class='ui-filterable'></form>" )
13603
+ .append( selector )
13604
+ .submit( function( evt ) {
13605
+ evt.preventDefault();
13606
+ selector.blur();
13607
+ })
13608
+ .insertBefore( this.element );
13609
+ if ( $.mobile.textinput ) {
13610
+ if ( this.options.filterTheme != null ) {
13611
+ textinputOpts[ "theme" ] = opts.filterTheme;
13475
13612
  }
13476
13613
 
13614
+ selector.textinput( textinputOpts );
13477
13615
  }
13478
- });
13616
+ }
13617
+ }
13618
+
13619
+ this._super( selector );
13620
+
13621
+ if ( this._isSearchInternal() && updatePlaceholder ) {
13622
+ this._search.attr( "placeholder", this.options.filterPlaceholder );
13623
+ }
13479
13624
  },
13480
13625
 
13481
- _addLabels: function( cells, label, text ) {
13482
- // .not fixes #6006
13483
- cells.not( ":has(b." + label + ")" ).prepend( "<b class='" + label + "'>" + text + "</b>" );
13626
+ _setOptions: function( options ) {
13627
+ var ret = this._super( options );
13628
+
13629
+ // Need to set the filterPlaceholder after having established the search input
13630
+ if ( options.filterPlaceholder !== undefined ) {
13631
+ if ( this._isSearchInternal() ) {
13632
+ this._search.attr( "placeholder", options.filterPlaceholder );
13633
+ }
13634
+ }
13635
+
13636
+ if ( options.filterTheme !== undefined && this._search && $.mobile.textinput ) {
13637
+ this._search.textinput( "option", "theme", options.filterTheme );
13638
+ }
13639
+
13640
+ return ret;
13641
+ },
13642
+
13643
+ _destroy: function() {
13644
+ if ( this._isSearchInternal() ) {
13645
+ this._search.remove();
13646
+ }
13647
+ this._super();
13648
+ },
13649
+
13650
+ _syncTextInputOptions: function( options ) {
13651
+ var idx,
13652
+ textinputOptions = {};
13653
+
13654
+ // We only sync options if the filterable's textinput is of the internally
13655
+ // generated variety, rather than one specified by the user.
13656
+ if ( this._isSearchInternal() && $.mobile.textinput ) {
13657
+
13658
+ // Apply only the options understood by textinput
13659
+ for ( idx in $.mobile.textinput.prototype.options ) {
13660
+ if ( options[ idx ] !== undefined ) {
13661
+ if ( idx === "theme" && this.options.filterTheme != null ) {
13662
+ textinputOptions[ idx ] = this.options.filterTheme;
13663
+ } else {
13664
+ textinputOptions[ idx ] = options[ idx ];
13665
+ }
13666
+ }
13667
+ }
13668
+ this._search.textinput( "option", textinputOptions );
13669
+ }
13484
13670
  }
13485
13671
  });
13486
13672
 
@@ -14331,6 +14517,7 @@ $.widget( "ui.tabs", {
14331
14517
  });
14332
14518
 
14333
14519
  })( jQuery );
14520
+
14334
14521
  (function( $, undefined ) {
14335
14522
 
14336
14523
  })( jQuery );
@@ -14343,7 +14530,7 @@ $.widget( "ui.tabs", {
14343
14530
  var ua = navigator.userAgent,
14344
14531
  zoom,
14345
14532
  evt, x, y, z, aig;
14346
- if ( !( /iPhone|iPad|iPod/.test( navigator.platform ) && /OS [1-5]_[0-9_]* like Mac OS X/i.test( ua ) && ua.indexOf( "AppleWebKit" ) > -1 ) ){
14533
+ if ( !( /iPhone|iPad|iPod/.test( navigator.platform ) && /OS [1-5]_[0-9_]* like Mac OS X/i.test( ua ) && ua.indexOf( "AppleWebKit" ) > -1 ) ) {
14347
14534
  $.mobile.iosorientationfixEnabled = false;
14348
14535
  return;
14349
14536
  }
@@ -14369,7 +14556,7 @@ $.widget( "ui.tabs", {
14369
14556
  }
14370
14557
 
14371
14558
  $.mobile.document.on( "mobileinit", function() {
14372
- if ( $.mobile.iosorientationfixEnabled ){
14559
+ if ( $.mobile.iosorientationfixEnabled ) {
14373
14560
  $.mobile.window
14374
14561
  .bind( "orientationchange.iosorientationfix", zoom.enable )
14375
14562
  .bind( "devicemotion.iosorientationfix", checkTilt );
@@ -14502,11 +14689,11 @@ $.widget( "ui.tabs", {
14502
14689
  $(function() {
14503
14690
  //Run inlineSVG support test
14504
14691
  $.support.inlineSVG();
14505
-
14692
+
14506
14693
  // check which scrollTop value should be used by scrolling to 1 immediately at domready
14507
14694
  // then check what the scroll top is. Android will report 0... others 1
14508
14695
  // note that this initial scroll won't hide the address bar. It's just for the check.
14509
-
14696
+
14510
14697
  // hide iOS browser chrome on load if hideUrlBar is true this is to try and do it as soon as possible
14511
14698
  if ( $.mobile.hideUrlBar ) {
14512
14699
  window.scrollTo( 0, 1 );