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

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