jquery-mobile-rails-assets 1.4.1 → 1.4.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +7 -3
- data/app/assets/javascripts/jquery.mobile.js +1094 -571
- data/app/assets/stylesheets/jquery.mobile.css.scss +68 -50
- data/jquery-mobile-rails-assets.gemspec +1 -1
- data/lib/jquery-mobile-rails-assets/version.rb +1 -1
- metadata +12 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d3720f92443e18e8dc329074ff206af8ba81851a55c37e788d6718ccb19c6820
|
4
|
+
data.tar.gz: 94d2f332b90756803484e2901ddd427a1c91aefac0b517482ba70a91819854f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c151d54f05af4b2c1e748647ab4235dacbe0a049cf53e32a36e4f9f23bbbc8ac7cc84ff246d2f68e58991fb011d70df3450558e80a0d9e36db2195b9f574b5d
|
7
|
+
data.tar.gz: 653c6183a311046e5e981e1accc4bd702a55bc474fec084b7a670aff88619320c21c2ce4e0bbc8500901da7869f542ffcd2baabfe1783c18a3057b12eacbe55c
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# THIS GEM IS NOT LONGER UPDATED
|
2
|
+
|
3
|
+
Suggest you check out the [jquery_mobile_rails gem](https://rubygems.org/gems/jquery_mobile_rails) instead.
|
4
|
+
|
5
|
+
## Intro
|
2
6
|
|
3
7
|
This gem vendors the jQuery Mobile assets for Rails 3.1 and greater.
|
4
8
|
The files will be added to the asset pipeline and available for you to use.
|
@@ -15,13 +19,13 @@ In your Gemfile add:
|
|
15
19
|
gem 'jquery-mobile-rails-assets'
|
16
20
|
```
|
17
21
|
|
18
|
-
You can then include it in your app by adding the following to your javascript file:
|
22
|
+
You can then include it in your app by adding the following to your javascript application file:
|
19
23
|
|
20
24
|
```javascript
|
21
25
|
//= require jquery.mobile
|
22
26
|
```
|
23
27
|
|
24
|
-
And to the css file:
|
28
|
+
And to the css application file:
|
25
29
|
|
26
30
|
```css
|
27
31
|
*= require jquery.mobile
|
@@ -1,9 +1,9 @@
|
|
1
1
|
/*!
|
2
|
-
* jQuery Mobile 1.4.
|
3
|
-
* Git HEAD hash:
|
2
|
+
* jQuery Mobile 1.4.5
|
3
|
+
* Git HEAD hash: 68e55e78b292634d3991c795f06f5e37a512decc <> Date: Fri Oct 31 2014 17:33:30 UTC
|
4
4
|
* http://jquerymobile.com
|
5
5
|
*
|
6
|
-
* Copyright 2010, 2014 jQuery Foundation, Inc. and
|
6
|
+
* Copyright 2010, 2014 jQuery Foundation, Inc. and othercontributors
|
7
7
|
* Released under the MIT license.
|
8
8
|
* http://jquery.org/license
|
9
9
|
*
|
@@ -26,204 +26,6 @@
|
|
26
26
|
$.mobile = {};
|
27
27
|
}( jQuery ));
|
28
28
|
|
29
|
-
(function( $, window, undefined ) {
|
30
|
-
$.extend( $.mobile, {
|
31
|
-
|
32
|
-
// Version of the jQuery Mobile Framework
|
33
|
-
version: "1.4.1",
|
34
|
-
|
35
|
-
// Deprecated and no longer used in 1.4 remove in 1.5
|
36
|
-
// Define the url parameter used for referencing widget-generated sub-pages.
|
37
|
-
// Translates to example.html&ui-page=subpageIdentifier
|
38
|
-
// hash segment before &ui-page= is used to make Ajax request
|
39
|
-
subPageUrlKey: "ui-page",
|
40
|
-
|
41
|
-
hideUrlBar: true,
|
42
|
-
|
43
|
-
// Keepnative Selector
|
44
|
-
keepNative: ":jqmData(role='none'), :jqmData(role='nojs')",
|
45
|
-
|
46
|
-
// Deprecated in 1.4 remove in 1.5
|
47
|
-
// Class assigned to page currently in view, and during transitions
|
48
|
-
activePageClass: "ui-page-active",
|
49
|
-
|
50
|
-
// Deprecated in 1.4 remove in 1.5
|
51
|
-
// Class used for "active" button state, from CSS framework
|
52
|
-
activeBtnClass: "ui-btn-active",
|
53
|
-
|
54
|
-
// Deprecated in 1.4 remove in 1.5
|
55
|
-
// Class used for "focus" form element state, from CSS framework
|
56
|
-
focusClass: "ui-focus",
|
57
|
-
|
58
|
-
// Automatically handle clicks and form submissions through Ajax, when same-domain
|
59
|
-
ajaxEnabled: true,
|
60
|
-
|
61
|
-
// Automatically load and show pages based on location.hash
|
62
|
-
hashListeningEnabled: true,
|
63
|
-
|
64
|
-
// disable to prevent jquery from bothering with links
|
65
|
-
linkBindingEnabled: true,
|
66
|
-
|
67
|
-
// Set default page transition - 'none' for no transitions
|
68
|
-
defaultPageTransition: "fade",
|
69
|
-
|
70
|
-
// Set maximum window width for transitions to apply - 'false' for no limit
|
71
|
-
maxTransitionWidth: false,
|
72
|
-
|
73
|
-
// Minimum scroll distance that will be remembered when returning to a page
|
74
|
-
// Deprecated remove in 1.5
|
75
|
-
minScrollBack: 0,
|
76
|
-
|
77
|
-
// Set default dialog transition - 'none' for no transitions
|
78
|
-
defaultDialogTransition: "pop",
|
79
|
-
|
80
|
-
// Error response message - appears when an Ajax page request fails
|
81
|
-
pageLoadErrorMessage: "Error Loading Page",
|
82
|
-
|
83
|
-
// For error messages, which theme does the box uses?
|
84
|
-
pageLoadErrorMessageTheme: "a",
|
85
|
-
|
86
|
-
// replace calls to window.history.back with phonegaps navigation helper
|
87
|
-
// where it is provided on the window object
|
88
|
-
phonegapNavigationEnabled: false,
|
89
|
-
|
90
|
-
//automatically initialize the DOM when it's ready
|
91
|
-
autoInitializePage: true,
|
92
|
-
|
93
|
-
pushStateEnabled: true,
|
94
|
-
|
95
|
-
// allows users to opt in to ignoring content by marking a parent element as
|
96
|
-
// data-ignored
|
97
|
-
ignoreContentEnabled: false,
|
98
|
-
|
99
|
-
buttonMarkup: {
|
100
|
-
hoverDelay: 200
|
101
|
-
},
|
102
|
-
|
103
|
-
// disable the alteration of the dynamic base tag or links in the case
|
104
|
-
// that a dynamic base tag isn't supported
|
105
|
-
dynamicBaseEnabled: true,
|
106
|
-
|
107
|
-
// default the property to remove dependency on assignment in init module
|
108
|
-
pageContainer: $(),
|
109
|
-
|
110
|
-
//enable cross-domain page support
|
111
|
-
allowCrossDomainPages: false,
|
112
|
-
|
113
|
-
dialogHashKey: "&ui-state=dialog"
|
114
|
-
});
|
115
|
-
})( jQuery, this );
|
116
|
-
|
117
|
-
(function( $, window, undefined ) {
|
118
|
-
var nsNormalizeDict = {},
|
119
|
-
oldFind = $.find,
|
120
|
-
rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
|
121
|
-
jqmDataRE = /:jqmData\(([^)]*)\)/g;
|
122
|
-
|
123
|
-
$.extend( $.mobile, {
|
124
|
-
|
125
|
-
// Namespace used framework-wide for data-attrs. Default is no namespace
|
126
|
-
|
127
|
-
ns: "",
|
128
|
-
|
129
|
-
// Retrieve an attribute from an element and perform some massaging of the value
|
130
|
-
|
131
|
-
getAttribute: function( element, key ) {
|
132
|
-
var data;
|
133
|
-
|
134
|
-
element = element.jquery ? element[0] : element;
|
135
|
-
|
136
|
-
if ( element && element.getAttribute ) {
|
137
|
-
data = element.getAttribute( "data-" + $.mobile.ns + key );
|
138
|
-
}
|
139
|
-
|
140
|
-
// Copied from core's src/data.js:dataAttr()
|
141
|
-
// Convert from a string to a proper data type
|
142
|
-
try {
|
143
|
-
data = data === "true" ? true :
|
144
|
-
data === "false" ? false :
|
145
|
-
data === "null" ? null :
|
146
|
-
// Only convert to a number if it doesn't change the string
|
147
|
-
+data + "" === data ? +data :
|
148
|
-
rbrace.test( data ) ? JSON.parse( data ) :
|
149
|
-
data;
|
150
|
-
} catch( err ) {}
|
151
|
-
|
152
|
-
return data;
|
153
|
-
},
|
154
|
-
|
155
|
-
// Expose our cache for testing purposes.
|
156
|
-
nsNormalizeDict: nsNormalizeDict,
|
157
|
-
|
158
|
-
// Take a data attribute property, prepend the namespace
|
159
|
-
// and then camel case the attribute string. Add the result
|
160
|
-
// to our nsNormalizeDict so we don't have to do this again.
|
161
|
-
nsNormalize: function( prop ) {
|
162
|
-
return nsNormalizeDict[ prop ] ||
|
163
|
-
( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) );
|
164
|
-
},
|
165
|
-
|
166
|
-
// Find the closest javascript page element to gather settings data jsperf test
|
167
|
-
// http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit
|
168
|
-
// possibly naive, but it shows that the parsing overhead for *just* the page selector vs
|
169
|
-
// the page and dialog selector is negligable. This could probably be speed up by
|
170
|
-
// doing a similar parent node traversal to the one found in the inherited theme code above
|
171
|
-
closestPageData: function( $target ) {
|
172
|
-
return $target
|
173
|
-
.closest( ":jqmData(role='page'), :jqmData(role='dialog')" )
|
174
|
-
.data( "mobile-page" );
|
175
|
-
}
|
176
|
-
|
177
|
-
});
|
178
|
-
|
179
|
-
// Mobile version of data and removeData and hasData methods
|
180
|
-
// ensures all data is set and retrieved using jQuery Mobile's data namespace
|
181
|
-
$.fn.jqmData = function( prop, value ) {
|
182
|
-
var result;
|
183
|
-
if ( typeof prop !== "undefined" ) {
|
184
|
-
if ( prop ) {
|
185
|
-
prop = $.mobile.nsNormalize( prop );
|
186
|
-
}
|
187
|
-
|
188
|
-
// undefined is permitted as an explicit input for the second param
|
189
|
-
// in this case it returns the value and does not set it to undefined
|
190
|
-
if ( arguments.length < 2 || value === undefined ) {
|
191
|
-
result = this.data( prop );
|
192
|
-
} else {
|
193
|
-
result = this.data( prop, value );
|
194
|
-
}
|
195
|
-
}
|
196
|
-
return result;
|
197
|
-
};
|
198
|
-
|
199
|
-
$.jqmData = function( elem, prop, value ) {
|
200
|
-
var result;
|
201
|
-
if ( typeof prop !== "undefined" ) {
|
202
|
-
result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value );
|
203
|
-
}
|
204
|
-
return result;
|
205
|
-
};
|
206
|
-
|
207
|
-
$.fn.jqmRemoveData = function( prop ) {
|
208
|
-
return this.removeData( $.mobile.nsNormalize( prop ) );
|
209
|
-
};
|
210
|
-
|
211
|
-
$.jqmRemoveData = function( elem, prop ) {
|
212
|
-
return $.removeData( elem, $.mobile.nsNormalize( prop ) );
|
213
|
-
};
|
214
|
-
|
215
|
-
$.find = function( selector, context, ret, extra ) {
|
216
|
-
if ( selector.indexOf( ":jqmData" ) > -1 ) {
|
217
|
-
selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" );
|
218
|
-
}
|
219
|
-
|
220
|
-
return oldFind.call( this, selector, context, ret, extra );
|
221
|
-
};
|
222
|
-
|
223
|
-
$.extend( $.find, oldFind );
|
224
|
-
|
225
|
-
})( jQuery, this );
|
226
|
-
|
227
29
|
/*!
|
228
30
|
* jQuery UI Core c0ab71056b936627e8a7821f03c044aec6280a40
|
229
31
|
* http://jqueryui.com
|
@@ -520,6 +322,55 @@ $.ui.plugin = {
|
|
520
322
|
|
521
323
|
(function( $, window, undefined ) {
|
522
324
|
|
325
|
+
// Subtract the height of external toolbars from the page height, if the page does not have
|
326
|
+
// internal toolbars of the same type. We take care to use the widget options if we find a
|
327
|
+
// widget instance and the element's data-attributes otherwise.
|
328
|
+
var compensateToolbars = function( page, desiredHeight ) {
|
329
|
+
var pageParent = page.parent(),
|
330
|
+
toolbarsAffectingHeight = [],
|
331
|
+
|
332
|
+
// We use this function to filter fixed toolbars with option updatePagePadding set to
|
333
|
+
// true (which is the default) from our height subtraction, because fixed toolbars with
|
334
|
+
// option updatePagePadding set to true compensate for their presence by adding padding
|
335
|
+
// to the active page. We want to avoid double-counting by also subtracting their
|
336
|
+
// height from the desired page height.
|
337
|
+
noPadders = function() {
|
338
|
+
var theElement = $( this ),
|
339
|
+
widgetOptions = $.mobile.toolbar && theElement.data( "mobile-toolbar" ) ?
|
340
|
+
theElement.toolbar( "option" ) : {
|
341
|
+
position: theElement.attr( "data-" + $.mobile.ns + "position" ),
|
342
|
+
updatePagePadding: ( theElement.attr( "data-" + $.mobile.ns +
|
343
|
+
"update-page-padding" ) !== false )
|
344
|
+
};
|
345
|
+
|
346
|
+
return !( widgetOptions.position === "fixed" &&
|
347
|
+
widgetOptions.updatePagePadding === true );
|
348
|
+
},
|
349
|
+
externalHeaders = pageParent.children( ":jqmData(role='header')" ).filter( noPadders ),
|
350
|
+
internalHeaders = page.children( ":jqmData(role='header')" ),
|
351
|
+
externalFooters = pageParent.children( ":jqmData(role='footer')" ).filter( noPadders ),
|
352
|
+
internalFooters = page.children( ":jqmData(role='footer')" );
|
353
|
+
|
354
|
+
// If we have no internal headers, but we do have external headers, then their height
|
355
|
+
// reduces the page height
|
356
|
+
if ( internalHeaders.length === 0 && externalHeaders.length > 0 ) {
|
357
|
+
toolbarsAffectingHeight = toolbarsAffectingHeight.concat( externalHeaders.toArray() );
|
358
|
+
}
|
359
|
+
|
360
|
+
// If we have no internal footers, but we do have external footers, then their height
|
361
|
+
// reduces the page height
|
362
|
+
if ( internalFooters.length === 0 && externalFooters.length > 0 ) {
|
363
|
+
toolbarsAffectingHeight = toolbarsAffectingHeight.concat( externalFooters.toArray() );
|
364
|
+
}
|
365
|
+
|
366
|
+
$.each( toolbarsAffectingHeight, function( index, value ) {
|
367
|
+
desiredHeight -= $( value ).outerHeight();
|
368
|
+
});
|
369
|
+
|
370
|
+
// Height must be at least zero
|
371
|
+
return Math.max( 0, desiredHeight );
|
372
|
+
};
|
373
|
+
|
523
374
|
$.extend( $.mobile, {
|
524
375
|
// define the window and the document objects
|
525
376
|
window: $( window ),
|
@@ -650,9 +501,16 @@ $.ui.plugin = {
|
|
650
501
|
pageHeight = page.height(),
|
651
502
|
pageOuterHeight = page.outerHeight( true );
|
652
503
|
|
653
|
-
height = (
|
504
|
+
height = compensateToolbars( page,
|
505
|
+
( typeof height === "number" ) ? height : $.mobile.getScreenHeight() );
|
506
|
+
|
507
|
+
// Remove any previous min-height setting
|
508
|
+
page.css( "min-height", "" );
|
654
509
|
|
655
|
-
|
510
|
+
// Set the minimum height only if the height as determined by CSS is insufficient
|
511
|
+
if ( page.height() < height ) {
|
512
|
+
page.css( "min-height", height - ( pageOuterHeight - pageHeight ) );
|
513
|
+
}
|
656
514
|
},
|
657
515
|
|
658
516
|
loading: function() {
|
@@ -791,6 +649,93 @@ $.ui.plugin = {
|
|
791
649
|
|
792
650
|
})( jQuery, this );
|
793
651
|
|
652
|
+
(function( $, window, undefined ) {
|
653
|
+
$.extend( $.mobile, {
|
654
|
+
|
655
|
+
// Version of the jQuery Mobile Framework
|
656
|
+
version: "1.4.5",
|
657
|
+
|
658
|
+
// Deprecated and no longer used in 1.4 remove in 1.5
|
659
|
+
// Define the url parameter used for referencing widget-generated sub-pages.
|
660
|
+
// Translates to example.html&ui-page=subpageIdentifier
|
661
|
+
// hash segment before &ui-page= is used to make Ajax request
|
662
|
+
subPageUrlKey: "ui-page",
|
663
|
+
|
664
|
+
hideUrlBar: true,
|
665
|
+
|
666
|
+
// Keepnative Selector
|
667
|
+
keepNative: ":jqmData(role='none'), :jqmData(role='nojs')",
|
668
|
+
|
669
|
+
// Deprecated in 1.4 remove in 1.5
|
670
|
+
// Class assigned to page currently in view, and during transitions
|
671
|
+
activePageClass: "ui-page-active",
|
672
|
+
|
673
|
+
// Deprecated in 1.4 remove in 1.5
|
674
|
+
// Class used for "active" button state, from CSS framework
|
675
|
+
activeBtnClass: "ui-btn-active",
|
676
|
+
|
677
|
+
// Deprecated in 1.4 remove in 1.5
|
678
|
+
// Class used for "focus" form element state, from CSS framework
|
679
|
+
focusClass: "ui-focus",
|
680
|
+
|
681
|
+
// Automatically handle clicks and form submissions through Ajax, when same-domain
|
682
|
+
ajaxEnabled: true,
|
683
|
+
|
684
|
+
// Automatically load and show pages based on location.hash
|
685
|
+
hashListeningEnabled: true,
|
686
|
+
|
687
|
+
// disable to prevent jquery from bothering with links
|
688
|
+
linkBindingEnabled: true,
|
689
|
+
|
690
|
+
// Set default page transition - 'none' for no transitions
|
691
|
+
defaultPageTransition: "fade",
|
692
|
+
|
693
|
+
// Set maximum window width for transitions to apply - 'false' for no limit
|
694
|
+
maxTransitionWidth: false,
|
695
|
+
|
696
|
+
// Minimum scroll distance that will be remembered when returning to a page
|
697
|
+
// Deprecated remove in 1.5
|
698
|
+
minScrollBack: 0,
|
699
|
+
|
700
|
+
// Set default dialog transition - 'none' for no transitions
|
701
|
+
defaultDialogTransition: "pop",
|
702
|
+
|
703
|
+
// Error response message - appears when an Ajax page request fails
|
704
|
+
pageLoadErrorMessage: "Error Loading Page",
|
705
|
+
|
706
|
+
// For error messages, which theme does the box use?
|
707
|
+
pageLoadErrorMessageTheme: "a",
|
708
|
+
|
709
|
+
// replace calls to window.history.back with phonegaps navigation helper
|
710
|
+
// where it is provided on the window object
|
711
|
+
phonegapNavigationEnabled: false,
|
712
|
+
|
713
|
+
//automatically initialize the DOM when it's ready
|
714
|
+
autoInitializePage: true,
|
715
|
+
|
716
|
+
pushStateEnabled: true,
|
717
|
+
|
718
|
+
// allows users to opt in to ignoring content by marking a parent element as
|
719
|
+
// data-ignored
|
720
|
+
ignoreContentEnabled: false,
|
721
|
+
|
722
|
+
buttonMarkup: {
|
723
|
+
hoverDelay: 200
|
724
|
+
},
|
725
|
+
|
726
|
+
// disable the alteration of the dynamic base tag or links in the case
|
727
|
+
// that a dynamic base tag isn't supported
|
728
|
+
dynamicBaseEnabled: true,
|
729
|
+
|
730
|
+
// default the property to remove dependency on assignment in init module
|
731
|
+
pageContainer: $(),
|
732
|
+
|
733
|
+
//enable cross-domain page support
|
734
|
+
allowCrossDomainPages: false,
|
735
|
+
|
736
|
+
dialogHashKey: "&ui-state=dialog"
|
737
|
+
});
|
738
|
+
})( jQuery, this );
|
794
739
|
|
795
740
|
/*!
|
796
741
|
* jQuery UI Widget c0ab71056b936627e8a7821f03c044aec6280a40
|
@@ -1316,6 +1261,116 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
|
|
1316
1261
|
|
1317
1262
|
})( jQuery );
|
1318
1263
|
|
1264
|
+
(function( $, window, undefined ) {
|
1265
|
+
var nsNormalizeDict = {},
|
1266
|
+
oldFind = $.find,
|
1267
|
+
rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
|
1268
|
+
jqmDataRE = /:jqmData\(([^)]*)\)/g;
|
1269
|
+
|
1270
|
+
$.extend( $.mobile, {
|
1271
|
+
|
1272
|
+
// Namespace used framework-wide for data-attrs. Default is no namespace
|
1273
|
+
|
1274
|
+
ns: "",
|
1275
|
+
|
1276
|
+
// Retrieve an attribute from an element and perform some massaging of the value
|
1277
|
+
|
1278
|
+
getAttribute: function( element, key ) {
|
1279
|
+
var data;
|
1280
|
+
|
1281
|
+
element = element.jquery ? element[0] : element;
|
1282
|
+
|
1283
|
+
if ( element && element.getAttribute ) {
|
1284
|
+
data = element.getAttribute( "data-" + $.mobile.ns + key );
|
1285
|
+
}
|
1286
|
+
|
1287
|
+
// Copied from core's src/data.js:dataAttr()
|
1288
|
+
// Convert from a string to a proper data type
|
1289
|
+
try {
|
1290
|
+
data = data === "true" ? true :
|
1291
|
+
data === "false" ? false :
|
1292
|
+
data === "null" ? null :
|
1293
|
+
// Only convert to a number if it doesn't change the string
|
1294
|
+
+data + "" === data ? +data :
|
1295
|
+
rbrace.test( data ) ? JSON.parse( data ) :
|
1296
|
+
data;
|
1297
|
+
} catch( err ) {}
|
1298
|
+
|
1299
|
+
return data;
|
1300
|
+
},
|
1301
|
+
|
1302
|
+
// Expose our cache for testing purposes.
|
1303
|
+
nsNormalizeDict: nsNormalizeDict,
|
1304
|
+
|
1305
|
+
// Take a data attribute property, prepend the namespace
|
1306
|
+
// and then camel case the attribute string. Add the result
|
1307
|
+
// to our nsNormalizeDict so we don't have to do this again.
|
1308
|
+
nsNormalize: function( prop ) {
|
1309
|
+
return nsNormalizeDict[ prop ] ||
|
1310
|
+
( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) );
|
1311
|
+
},
|
1312
|
+
|
1313
|
+
// Find the closest javascript page element to gather settings data jsperf test
|
1314
|
+
// http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit
|
1315
|
+
// possibly naive, but it shows that the parsing overhead for *just* the page selector vs
|
1316
|
+
// the page and dialog selector is negligable. This could probably be speed up by
|
1317
|
+
// doing a similar parent node traversal to the one found in the inherited theme code above
|
1318
|
+
closestPageData: function( $target ) {
|
1319
|
+
return $target
|
1320
|
+
.closest( ":jqmData(role='page'), :jqmData(role='dialog')" )
|
1321
|
+
.data( "mobile-page" );
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
});
|
1325
|
+
|
1326
|
+
// Mobile version of data and removeData and hasData methods
|
1327
|
+
// ensures all data is set and retrieved using jQuery Mobile's data namespace
|
1328
|
+
$.fn.jqmData = function( prop, value ) {
|
1329
|
+
var result;
|
1330
|
+
if ( typeof prop !== "undefined" ) {
|
1331
|
+
if ( prop ) {
|
1332
|
+
prop = $.mobile.nsNormalize( prop );
|
1333
|
+
}
|
1334
|
+
|
1335
|
+
// undefined is permitted as an explicit input for the second param
|
1336
|
+
// in this case it returns the value and does not set it to undefined
|
1337
|
+
if ( arguments.length < 2 || value === undefined ) {
|
1338
|
+
result = this.data( prop );
|
1339
|
+
} else {
|
1340
|
+
result = this.data( prop, value );
|
1341
|
+
}
|
1342
|
+
}
|
1343
|
+
return result;
|
1344
|
+
};
|
1345
|
+
|
1346
|
+
$.jqmData = function( elem, prop, value ) {
|
1347
|
+
var result;
|
1348
|
+
if ( typeof prop !== "undefined" ) {
|
1349
|
+
result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value );
|
1350
|
+
}
|
1351
|
+
return result;
|
1352
|
+
};
|
1353
|
+
|
1354
|
+
$.fn.jqmRemoveData = function( prop ) {
|
1355
|
+
return this.removeData( $.mobile.nsNormalize( prop ) );
|
1356
|
+
};
|
1357
|
+
|
1358
|
+
$.jqmRemoveData = function( elem, prop ) {
|
1359
|
+
return $.removeData( elem, $.mobile.nsNormalize( prop ) );
|
1360
|
+
};
|
1361
|
+
|
1362
|
+
$.find = function( selector, context, ret, extra ) {
|
1363
|
+
if ( selector.indexOf( ":jqmData" ) > -1 ) {
|
1364
|
+
selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" );
|
1365
|
+
}
|
1366
|
+
|
1367
|
+
return oldFind.call( this, selector, context, ret, extra );
|
1368
|
+
};
|
1369
|
+
|
1370
|
+
$.extend( $.find, oldFind );
|
1371
|
+
|
1372
|
+
})( jQuery, this );
|
1373
|
+
|
1319
1374
|
(function( $, undefined ) {
|
1320
1375
|
|
1321
1376
|
var rcapitals = /[A-Z]/g,
|
@@ -1458,8 +1513,11 @@ $.mobile.widget = $.Widget;
|
|
1458
1513
|
this.element.find( "h1" ).text( message );
|
1459
1514
|
}
|
1460
1515
|
|
1461
|
-
//
|
1462
|
-
|
1516
|
+
// If the pagecontainer widget has been defined we may use the :mobile-pagecontainer
|
1517
|
+
// and attach to the element on which the pagecontainer widget has been defined. If not,
|
1518
|
+
// we attach to the body.
|
1519
|
+
this.element.appendTo( $.mobile.pagecontainer ?
|
1520
|
+
$( ":mobile-pagecontainer" ) : $( "body" ) );
|
1463
1521
|
|
1464
1522
|
// check that the loader is visible
|
1465
1523
|
this.checkLoaderPosition();
|
@@ -1475,8 +1533,8 @@ $.mobile.widget = $.Widget;
|
|
1475
1533
|
this.element.removeClass( "ui-loader-fakefix" );
|
1476
1534
|
}
|
1477
1535
|
|
1478
|
-
|
1479
|
-
|
1536
|
+
this.window.unbind( "scroll", this.fakeFixLoader );
|
1537
|
+
this.window.unbind( "scroll", this.checkLoaderPosition );
|
1480
1538
|
}
|
1481
1539
|
});
|
1482
1540
|
|
@@ -1855,7 +1913,7 @@ $.mobile.widget = $.Widget;
|
|
1855
1913
|
iframe_doc.open();
|
1856
1914
|
|
1857
1915
|
// Set document.domain for the Iframe document as well, if necessary.
|
1858
|
-
domain && iframe_doc.write( '
|
1916
|
+
domain && iframe_doc.write( '\x3cscript>document.domain="' + domain + '"\x3c/script>' );
|
1859
1917
|
|
1860
1918
|
iframe_doc.close();
|
1861
1919
|
|
@@ -1874,6 +1932,7 @@ $.mobile.widget = $.Widget;
|
|
1874
1932
|
|
1875
1933
|
})(jQuery,this);
|
1876
1934
|
|
1935
|
+
|
1877
1936
|
(function( $, undefined ) {
|
1878
1937
|
|
1879
1938
|
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
|
@@ -2326,19 +2385,34 @@ if ( !$.support.boxShadow ) {
|
|
2326
2385
|
urlParseRE: /^\s*(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
|
2327
2386
|
|
2328
2387
|
// Abstraction to address xss (Issue #4787) by removing the authority in
|
2329
|
-
// browsers that auto
|
2388
|
+
// browsers that auto-decode it. All references to location.href should be
|
2330
2389
|
// replaced with a call to this method so that it can be dealt with properly here
|
2331
2390
|
getLocation: function( url ) {
|
2332
|
-
var
|
2333
|
-
|
2391
|
+
var parsedUrl = this.parseUrl( url || location.href ),
|
2392
|
+
uri = url ? parsedUrl : location,
|
2393
|
+
|
2394
|
+
// Make sure to parse the url or the location object for the hash because using
|
2395
|
+
// location.hash is autodecoded in firefox, the rest of the url should be from
|
2396
|
+
// the object (location unless we're testing) to avoid the inclusion of the
|
2397
|
+
// authority
|
2398
|
+
hash = parsedUrl.hash;
|
2334
2399
|
|
2335
2400
|
// mimic the browser with an empty string when the hash is empty
|
2336
2401
|
hash = hash === "#" ? "" : hash;
|
2337
2402
|
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2403
|
+
return uri.protocol +
|
2404
|
+
parsedUrl.doubleSlash +
|
2405
|
+
uri.host +
|
2406
|
+
|
2407
|
+
// The pathname must start with a slash if there's a protocol, because you
|
2408
|
+
// can't have a protocol followed by a relative path. Also, it's impossible to
|
2409
|
+
// calculate absolute URLs from relative ones if the absolute one doesn't have
|
2410
|
+
// a leading "/".
|
2411
|
+
( ( uri.protocol !== "" && uri.pathname.substring( 0, 1 ) !== "/" ) ?
|
2412
|
+
"/" : "" ) +
|
2413
|
+
uri.pathname +
|
2414
|
+
uri.search +
|
2415
|
+
hash;
|
2342
2416
|
},
|
2343
2417
|
|
2344
2418
|
//return the original document url
|
@@ -2424,7 +2498,8 @@ if ( !$.support.boxShadow ) {
|
|
2424
2498
|
|
2425
2499
|
//Returns true if both urls have the same domain.
|
2426
2500
|
isSameDomain: function( absUrl1, absUrl2 ) {
|
2427
|
-
return path.parseUrl( absUrl1 ).domain
|
2501
|
+
return path.parseUrl( absUrl1 ).domain.toLowerCase() ===
|
2502
|
+
path.parseUrl( absUrl2 ).domain.toLowerCase();
|
2428
2503
|
},
|
2429
2504
|
|
2430
2505
|
//Returns true for any relative variant.
|
@@ -2471,19 +2546,21 @@ if ( !$.support.boxShadow ) {
|
|
2471
2546
|
},
|
2472
2547
|
|
2473
2548
|
convertUrlToDataUrl: function( absUrl ) {
|
2474
|
-
var
|
2549
|
+
var result = absUrl,
|
2550
|
+
u = path.parseUrl( absUrl );
|
2551
|
+
|
2475
2552
|
if ( path.isEmbeddedPage( u ) ) {
|
2476
2553
|
// For embedded pages, remove the dialog hash key as in getFilePath(),
|
2477
2554
|
// and remove otherwise the Data Url won't match the id of the embedded Page.
|
2478
|
-
|
2555
|
+
result = u.hash
|
2479
2556
|
.split( dialogHashKey )[0]
|
2480
2557
|
.replace( /^#/, "" )
|
2481
2558
|
.replace( /\?.*$/, "" );
|
2482
2559
|
} else if ( path.isSameDomain( u, this.documentBase ) ) {
|
2483
|
-
|
2560
|
+
result = u.hrefNoHash.replace( this.documentBase.domain, "" ).split( dialogHashKey )[0];
|
2484
2561
|
}
|
2485
2562
|
|
2486
|
-
return window.decodeURIComponent(
|
2563
|
+
return window.decodeURIComponent( result );
|
2487
2564
|
},
|
2488
2565
|
|
2489
2566
|
//get path from current hash, or from a file path
|
@@ -2532,7 +2609,9 @@ if ( !$.support.boxShadow ) {
|
|
2532
2609
|
//could be mailto, etc
|
2533
2610
|
isExternal: function( url ) {
|
2534
2611
|
var u = path.parseUrl( url );
|
2535
|
-
|
2612
|
+
|
2613
|
+
return !!( u.protocol &&
|
2614
|
+
( u.domain.toLowerCase() !== this.documentUrl.domain.toLowerCase() ) );
|
2536
2615
|
},
|
2537
2616
|
|
2538
2617
|
hasProtocol: function( url ) {
|
@@ -2554,14 +2633,25 @@ if ( !$.support.boxShadow ) {
|
|
2554
2633
|
},
|
2555
2634
|
|
2556
2635
|
squash: function( url, resolutionUrl ) {
|
2557
|
-
var href, cleanedUrl, search, stateIndex,
|
2636
|
+
var href, cleanedUrl, search, stateIndex, docUrl,
|
2558
2637
|
isPath = this.isPath( url ),
|
2559
2638
|
uri = this.parseUrl( url ),
|
2560
2639
|
preservedHash = uri.hash,
|
2561
2640
|
uiState = "";
|
2562
2641
|
|
2563
|
-
// produce a url against which we can
|
2564
|
-
|
2642
|
+
// produce a url against which we can resolve the provided path
|
2643
|
+
if ( !resolutionUrl ) {
|
2644
|
+
if ( isPath ) {
|
2645
|
+
resolutionUrl = path.getLocation();
|
2646
|
+
} else {
|
2647
|
+
docUrl = path.getDocumentUrl( true );
|
2648
|
+
if ( path.isPath( docUrl.hash ) ) {
|
2649
|
+
resolutionUrl = path.squash( docUrl.href );
|
2650
|
+
} else {
|
2651
|
+
resolutionUrl = docUrl.href;
|
2652
|
+
}
|
2653
|
+
}
|
2654
|
+
}
|
2565
2655
|
|
2566
2656
|
// If the url is anything but a simple string, remove any preceding hash
|
2567
2657
|
// eg #foo/bar -> foo/bar
|
@@ -2608,7 +2698,8 @@ if ( !$.support.boxShadow ) {
|
|
2608
2698
|
|
2609
2699
|
// reconstruct each of the pieces with the new search string and hash
|
2610
2700
|
href = path.parseUrl( href );
|
2611
|
-
href = href.protocol +
|
2701
|
+
href = href.protocol + href.doubleSlash + href.host + href.pathname + search +
|
2702
|
+
preservedHash;
|
2612
2703
|
} else {
|
2613
2704
|
href += href.indexOf( "#" ) > -1 ? uiState : "#" + uiState;
|
2614
2705
|
}
|
@@ -2629,11 +2720,10 @@ if ( !$.support.boxShadow ) {
|
|
2629
2720
|
return ( hasHash ? "#" : "" ) + hash.replace( /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g, "\\$1" );
|
2630
2721
|
},
|
2631
2722
|
|
2632
|
-
// return the substring of a filepath before the
|
2633
|
-
//
|
2723
|
+
// return the substring of a filepath before the dialogHashKey, for making a server
|
2724
|
+
// request
|
2634
2725
|
getFilePath: function( path ) {
|
2635
|
-
|
2636
|
-
return path && path.split( splitkey )[0].split( dialogHashKey )[0];
|
2726
|
+
return path && path.split( dialogHashKey )[0];
|
2637
2727
|
},
|
2638
2728
|
|
2639
2729
|
// check if the specified url refers to the first page in the main
|
@@ -3155,7 +3245,6 @@ if ( !$.support.boxShadow ) {
|
|
3155
3245
|
|
3156
3246
|
// All lower case if not a vendor prop
|
3157
3247
|
if ( props[ test ][ "prefix" ] === "" ) {
|
3158
|
-
props[ test ][ "duration" ] = props[ test ][ "duration" ].toLowerCase();
|
3159
3248
|
props[ test ][ "event" ] = props[ test ][ "event" ].toLowerCase();
|
3160
3249
|
}
|
3161
3250
|
});
|
@@ -3171,6 +3260,12 @@ if ( !$.support.boxShadow ) {
|
|
3171
3260
|
$.fn.animationComplete = function( callback, type, fallbackTime ) {
|
3172
3261
|
var timer, duration,
|
3173
3262
|
that = this,
|
3263
|
+
eventBinding = function() {
|
3264
|
+
|
3265
|
+
// Clear the timer so we don't call callback twice
|
3266
|
+
clearTimeout( timer );
|
3267
|
+
callback.apply( this, arguments );
|
3268
|
+
},
|
3174
3269
|
animationType = ( !type || type === "animation" ) ? "animation" : "transition";
|
3175
3270
|
|
3176
3271
|
// Make sure selected type is supported by browser
|
@@ -3191,24 +3286,19 @@ if ( !$.support.boxShadow ) {
|
|
3191
3286
|
}
|
3192
3287
|
|
3193
3288
|
// If we could not read a duration use the default
|
3194
|
-
if ( duration === 0 || duration === undefined ) {
|
3195
|
-
duration = $.fn.animationComplete.
|
3289
|
+
if ( duration === 0 || duration === undefined || isNaN( duration ) ) {
|
3290
|
+
duration = $.fn.animationComplete.defaultDuration;
|
3196
3291
|
}
|
3197
3292
|
}
|
3198
3293
|
|
3199
3294
|
// Sets up the fallback if event never comes
|
3200
3295
|
timer = setTimeout( function() {
|
3201
|
-
$( that ).off( props[ animationType ].event );
|
3296
|
+
$( that ).off( props[ animationType ].event, eventBinding );
|
3202
3297
|
callback.apply( that );
|
3203
3298
|
}, duration );
|
3204
3299
|
|
3205
3300
|
// Bind the event
|
3206
|
-
return $( this ).one( props[ animationType ].event,
|
3207
|
-
|
3208
|
-
// Clear the timer so we dont call callback twice
|
3209
|
-
clearTimeout( timer );
|
3210
|
-
callback.call( this, arguments );
|
3211
|
-
});
|
3301
|
+
return $( this ).one( props[ animationType ].event, eventBinding );
|
3212
3302
|
} else {
|
3213
3303
|
|
3214
3304
|
// CSS animation / transitions not supported
|
@@ -3219,7 +3309,7 @@ if ( !$.support.boxShadow ) {
|
|
3219
3309
|
};
|
3220
3310
|
|
3221
3311
|
// Allow default callback to be configured on mobileInit
|
3222
|
-
$.fn.animationComplete.
|
3312
|
+
$.fn.animationComplete.defaultDuration = 1000;
|
3223
3313
|
})( jQuery );
|
3224
3314
|
|
3225
3315
|
// This plugin is an experiment for abstracting away the touch and mouse
|
@@ -3837,7 +3927,7 @@ if ( eventCaptureSupported ) {
|
|
3837
3927
|
if ( !isTaphold && origTarget === event.target ) {
|
3838
3928
|
triggerCustomEvent( thisObject, "tap", event );
|
3839
3929
|
} else if ( isTaphold ) {
|
3840
|
-
event.
|
3930
|
+
event.preventDefault();
|
3841
3931
|
}
|
3842
3932
|
}
|
3843
3933
|
|
@@ -3970,7 +4060,7 @@ if ( eventCaptureSupported ) {
|
|
3970
4060
|
emitted = false;
|
3971
4061
|
|
3972
4062
|
context.move = function( event ) {
|
3973
|
-
if ( !start ) {
|
4063
|
+
if ( !start || event.isDefaultPrevented() ) {
|
3974
4064
|
return;
|
3975
4065
|
}
|
3976
4066
|
|
@@ -4033,8 +4123,8 @@ if ( eventCaptureSupported ) {
|
|
4033
4123
|
$.each({
|
4034
4124
|
scrollstop: "scrollstart",
|
4035
4125
|
taphold: "tap",
|
4036
|
-
swipeleft: "swipe",
|
4037
|
-
swiperight: "swipe"
|
4126
|
+
swipeleft: "swipe.left",
|
4127
|
+
swiperight: "swipe.right"
|
4038
4128
|
}, function( event, sourceEvent ) {
|
4039
4129
|
|
4040
4130
|
$.event.special[ event ] = {
|
@@ -4270,13 +4360,14 @@ if ( eventCaptureSupported ) {
|
|
4270
4360
|
page.find( base.linkSelector ).each(function( i, link ) {
|
4271
4361
|
var thisAttr = $( link ).is( "[href]" ) ? "href" :
|
4272
4362
|
$( link ).is( "[src]" ) ? "src" : "action",
|
4363
|
+
theLocation = $.mobile.path.parseLocation(),
|
4273
4364
|
thisUrl = $( link ).attr( thisAttr );
|
4274
4365
|
|
4275
4366
|
// XXX_jblas: We need to fix this so that it removes the document
|
4276
4367
|
// base URL, and then prepends with the new page URL.
|
4277
4368
|
// if full path exists and is same, chop it - helps IE out
|
4278
|
-
thisUrl = thisUrl.replace(
|
4279
|
-
|
4369
|
+
thisUrl = thisUrl.replace( theLocation.protocol + theLocation.doubleSlash +
|
4370
|
+
theLocation.host + theLocation.pathname, "" );
|
4280
4371
|
|
4281
4372
|
if ( !/^(\w+:|#|\/)/.test( thisUrl ) ) {
|
4282
4373
|
$( link ).attr( thisAttr, newPath + thisUrl );
|
@@ -4476,13 +4567,9 @@ $.widget( "mobile.page", {
|
|
4476
4567
|
initSelector: false,
|
4477
4568
|
|
4478
4569
|
_create: function() {
|
4570
|
+
this._trigger( "beforecreate" );
|
4479
4571
|
this.setLastScrollEnabled = true;
|
4480
4572
|
|
4481
|
-
// TODO consider moving the navigation handler OUT of widget into
|
4482
|
-
// some other object as glue between the navigate event and the
|
4483
|
-
// content widget load and change methods
|
4484
|
-
this._on( this.window, { navigate: "_filterNavigateEvents" });
|
4485
|
-
|
4486
4573
|
this._on( this.window, {
|
4487
4574
|
// disable an scroll setting when a hashchange has been fired,
|
4488
4575
|
// this only works because the recording of the scroll position
|
@@ -4495,6 +4582,11 @@ $.widget( "mobile.page", {
|
|
4495
4582
|
scrollstop: "_delayedRecordScroll"
|
4496
4583
|
});
|
4497
4584
|
|
4585
|
+
// TODO consider moving the navigation handler OUT of widget into
|
4586
|
+
// some other object as glue between the navigate event and the
|
4587
|
+
// content widget load and change methods
|
4588
|
+
this._on( this.window, { navigate: "_filterNavigateEvents" });
|
4589
|
+
|
4498
4590
|
// TODO move from page* events to content* events
|
4499
4591
|
this._on({ pagechange: "_afterContentChange" });
|
4500
4592
|
|
@@ -4615,9 +4707,8 @@ $.widget( "mobile.page", {
|
|
4615
4707
|
return $.mobile.navigate.history;
|
4616
4708
|
},
|
4617
4709
|
|
4618
|
-
// TODO use _getHistory
|
4619
4710
|
_getActiveHistory: function() {
|
4620
|
-
return
|
4711
|
+
return this._getHistory().getActive();
|
4621
4712
|
},
|
4622
4713
|
|
4623
4714
|
// TODO the document base should be determined at creation
|
@@ -4677,28 +4768,26 @@ $.widget( "mobile.page", {
|
|
4677
4768
|
//
|
4678
4769
|
// TODO move check to history object or path object?
|
4679
4770
|
to = !$.mobile.path.isPath( to ) ? ( $.mobile.path.makeUrlAbsolute( "#" + to, this._getDocumentBase() ) ) : to;
|
4680
|
-
|
4681
|
-
// If we're about to go to an initial URL that contains a
|
4682
|
-
// reference to a non-existent internal page, go to the first
|
4683
|
-
// page instead. We know that the initial hash refers to a
|
4684
|
-
// non-existent page, because the initial hash did not end
|
4685
|
-
// up in the initial history entry
|
4686
|
-
// TODO move check to history object?
|
4687
|
-
if ( to === $.mobile.path.makeUrlAbsolute( "#" + history.initialDst, this._getDocumentBase() ) &&
|
4688
|
-
history.stack.length &&
|
4689
|
-
history.stack[0].url !== history.initialDst.replace( $.mobile.dialogHashKey, "" ) ) {
|
4690
|
-
to = this._getInitialContent();
|
4691
|
-
}
|
4692
4771
|
}
|
4693
4772
|
return to || this._getInitialContent();
|
4694
4773
|
},
|
4695
4774
|
|
4775
|
+
_transitionFromHistory: function( direction, defaultTransition ) {
|
4776
|
+
var history = this._getHistory(),
|
4777
|
+
entry = ( direction === "back" ? history.getLast() : history.getActive() );
|
4778
|
+
|
4779
|
+
return ( entry && entry.transition ) || defaultTransition;
|
4780
|
+
},
|
4781
|
+
|
4696
4782
|
_handleDialog: function( changePageOptions, data ) {
|
4697
4783
|
var to, active, activeContent = this.getActivePage();
|
4698
4784
|
|
4699
4785
|
// If current active page is not a dialog skip the dialog and continue
|
4700
4786
|
// in the same direction
|
4701
|
-
|
4787
|
+
// Note: The dialog widget is deprecated as of 1.4.0 and will be removed in 1.5.0.
|
4788
|
+
// Thus, as of 1.5.0 activeContent.data( "mobile-dialog" ) will always evaluate to
|
4789
|
+
// falsy, so the second condition in the if-statement below can be removed altogether.
|
4790
|
+
if ( activeContent && !activeContent.data( "mobile-dialog" ) ) {
|
4702
4791
|
// determine if we're heading forward or backward and continue
|
4703
4792
|
// accordingly past the current dialog
|
4704
4793
|
if ( data.direction === "back" ) {
|
@@ -4719,7 +4808,9 @@ $.widget( "mobile.page", {
|
|
4719
4808
|
// as most of this is lost by the domCache cleaning
|
4720
4809
|
$.extend( changePageOptions, {
|
4721
4810
|
role: active.role,
|
4722
|
-
transition:
|
4811
|
+
transition: this._transitionFromHistory(
|
4812
|
+
data.direction,
|
4813
|
+
changePageOptions.transition ),
|
4723
4814
|
reverse: data.direction === "back"
|
4724
4815
|
});
|
4725
4816
|
}
|
@@ -4734,7 +4825,8 @@ $.widget( "mobile.page", {
|
|
4734
4825
|
|
4735
4826
|
// transition is false if it's the first page, undefined
|
4736
4827
|
// otherwise (and may be overridden by default)
|
4737
|
-
transition = history.stack.length === 0 ? "none" :
|
4828
|
+
transition = history.stack.length === 0 ? "none" :
|
4829
|
+
this._transitionFromHistory( data.direction ),
|
4738
4830
|
|
4739
4831
|
// default options for the changPage calls made after examining
|
4740
4832
|
// the current state of the page and the hash, NOTE that the
|
@@ -4746,7 +4838,7 @@ $.widget( "mobile.page", {
|
|
4746
4838
|
};
|
4747
4839
|
|
4748
4840
|
$.extend( changePageOptions, data, {
|
4749
|
-
transition:
|
4841
|
+
transition: transition
|
4750
4842
|
});
|
4751
4843
|
|
4752
4844
|
// TODO move to _handleDestination ?
|
@@ -4754,8 +4846,7 @@ $.widget( "mobile.page", {
|
|
4754
4846
|
// key, and the initial destination isn't equal to the current target
|
4755
4847
|
// page, use the special dialog handling
|
4756
4848
|
if ( history.activeIndex > 0 &&
|
4757
|
-
to.indexOf( $.mobile.dialogHashKey ) > -1
|
4758
|
-
history.initialDst !== to ) {
|
4849
|
+
to.indexOf( $.mobile.dialogHashKey ) > -1 ) {
|
4759
4850
|
|
4760
4851
|
to = this._handleDialog( changePageOptions, data );
|
4761
4852
|
|
@@ -4806,7 +4897,8 @@ $.widget( "mobile.page", {
|
|
4806
4897
|
// NOTE do _not_ use the :jqmData pseudo selector because parenthesis
|
4807
4898
|
// are a valid url char and it breaks on the first occurence
|
4808
4899
|
page = this.element
|
4809
|
-
.children( "[data-" + this._getNs() +
|
4900
|
+
.children( "[data-" + this._getNs() +
|
4901
|
+
"url='" + $.mobile.path.hashToSelector( dataUrl ) + "']" );
|
4810
4902
|
|
4811
4903
|
// If we failed to find the page, check to see if the url is a
|
4812
4904
|
// reference to an embedded page. If so, it may have been dynamically
|
@@ -4891,7 +4983,7 @@ $.widget( "mobile.page", {
|
|
4891
4983
|
// TODO tagging a page with external to make sure that embedded pages aren't
|
4892
4984
|
// removed by the various page handling code is bad. Having page handling code
|
4893
4985
|
// in many places is bad. Solutions post 1.0
|
4894
|
-
page.attr( "data-" + this._getNs() + "url",
|
4986
|
+
page.attr( "data-" + this._getNs() + "url", this._createDataUrl( fileUrl ) )
|
4895
4987
|
.attr( "data-" + this._getNs() + "external-page", true );
|
4896
4988
|
|
4897
4989
|
return page;
|
@@ -4928,7 +5020,7 @@ $.widget( "mobile.page", {
|
|
4928
5020
|
( page || this.element ).trigger( deprecatedEvent, data );
|
4929
5021
|
|
4930
5022
|
// use the widget trigger method for the new content* event
|
4931
|
-
this.
|
5023
|
+
this._trigger( name, newEvent, data );
|
4932
5024
|
|
4933
5025
|
return {
|
4934
5026
|
deprecatedEvent: deprecatedEvent,
|
@@ -4940,8 +5032,7 @@ $.widget( "mobile.page", {
|
|
4940
5032
|
// or require ordering such that other bits are sprinkled in between parts that
|
4941
5033
|
// could be abstracted out as a group
|
4942
5034
|
_loadSuccess: function( absUrl, triggerData, settings, deferred ) {
|
4943
|
-
var fileUrl = this._createFileUrl( absUrl )
|
4944
|
-
dataUrl = this._createDataUrl( absUrl );
|
5035
|
+
var fileUrl = this._createFileUrl( absUrl );
|
4945
5036
|
|
4946
5037
|
return $.proxy(function( html, textStatus, xhr ) {
|
4947
5038
|
//pre-parse html to check for a data-url,
|
@@ -4961,6 +5052,11 @@ $.widget( "mobile.page", {
|
|
4961
5052
|
dataUrlRegex.test( RegExp.$1 ) &&
|
4962
5053
|
RegExp.$1 ) {
|
4963
5054
|
fileUrl = $.mobile.path.getFilePath( $("<div>" + RegExp.$1 + "</div>").text() );
|
5055
|
+
|
5056
|
+
// We specify that, if a data-url attribute is given on the page div, its value
|
5057
|
+
// must be given non-URL-encoded. However, in this part of the code, fileUrl is
|
5058
|
+
// assumed to be URL-encoded, so we URL-encode the retrieved value here
|
5059
|
+
fileUrl = this.window[ 0 ].encodeURIComponent( fileUrl );
|
4964
5060
|
}
|
4965
5061
|
|
4966
5062
|
//dont update the base tag if we are prefetching
|
@@ -4981,11 +5077,13 @@ $.widget( "mobile.page", {
|
|
4981
5077
|
|
4982
5078
|
triggerData.content = content;
|
4983
5079
|
|
5080
|
+
triggerData.toPage = content;
|
5081
|
+
|
4984
5082
|
// If the default behavior is prevented, stop here!
|
4985
5083
|
// Note that it is the responsibility of the listener/handler
|
4986
5084
|
// that called preventDefault(), to resolve/reject the
|
4987
5085
|
// deferred object within the triggerData.
|
4988
|
-
if (
|
5086
|
+
if ( this._triggerWithDeprecated( "load", triggerData ).event.isDefaultPrevented() ) {
|
4989
5087
|
return;
|
4990
5088
|
}
|
4991
5089
|
|
@@ -4996,23 +5094,11 @@ $.widget( "mobile.page", {
|
|
4996
5094
|
|
4997
5095
|
this._include( content, settings );
|
4998
5096
|
|
4999
|
-
// Enhancing the content may result in new dialogs/sub content being inserted
|
5000
|
-
// into the DOM. If the original absUrl refers to a sub-content, that is the
|
5001
|
-
// real content we are interested in.
|
5002
|
-
if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) {
|
5003
|
-
content = this.element.children( "[data-" + this._getNs() +"url='" + dataUrl + "']" );
|
5004
|
-
}
|
5005
|
-
|
5006
5097
|
// Remove loading message.
|
5007
5098
|
if ( settings.showLoadMsg ) {
|
5008
5099
|
this._hideLoading();
|
5009
5100
|
}
|
5010
5101
|
|
5011
|
-
// BEGIN DEPRECATED ---------------------------------------------------
|
5012
|
-
// Let listeners know the content loaded successfully.
|
5013
|
-
this.element.trigger( "pageload" );
|
5014
|
-
// END DEPRECATED -----------------------------------------------------
|
5015
|
-
|
5016
5102
|
deferred.resolve( absUrl, settings, content );
|
5017
5103
|
}, this);
|
5018
5104
|
},
|
@@ -5041,8 +5127,16 @@ $.widget( "mobile.page", {
|
|
5041
5127
|
// know when the content is done loading, or if an error has occurred.
|
5042
5128
|
var deferred = ( options && options.deferred ) || $.Deferred(),
|
5043
5129
|
|
5130
|
+
// Examining the option "reloadPage" passed by the user is deprecated as of 1.4.0
|
5131
|
+
// and will be removed in 1.5.0.
|
5132
|
+
// Copy option "reloadPage" to "reload", but only if option "reload" is not present
|
5133
|
+
reloadOptionExtension =
|
5134
|
+
( ( options && options.reload === undefined &&
|
5135
|
+
options.reloadPage !== undefined ) ?
|
5136
|
+
{ reload: options.reloadPage } : {} ),
|
5137
|
+
|
5044
5138
|
// The default load options with overrides specified by the caller.
|
5045
|
-
settings = $.extend( {}, this._loadDefaults, options ),
|
5139
|
+
settings = $.extend( {}, this._loadDefaults, options, reloadOptionExtension ),
|
5046
5140
|
|
5047
5141
|
// The DOM element for the content after it has been loaded.
|
5048
5142
|
content = null,
|
@@ -5052,9 +5146,6 @@ $.widget( "mobile.page", {
|
|
5052
5146
|
absUrl = $.mobile.path.makeUrlAbsolute( url, this._findBaseWithDefault() ),
|
5053
5147
|
fileUrl, dataUrl, pblEvent, triggerData;
|
5054
5148
|
|
5055
|
-
// DEPRECATED reloadPage
|
5056
|
-
settings.reload = settings.reloadPage;
|
5057
|
-
|
5058
5149
|
// If the caller provided data, and we're using "get" request,
|
5059
5150
|
// append the data to the URL.
|
5060
5151
|
if ( settings.data && settings.type === "get" ) {
|
@@ -5086,7 +5177,7 @@ $.widget( "mobile.page", {
|
|
5086
5177
|
$.mobile.path.isEmbeddedPage(fileUrl) &&
|
5087
5178
|
!$.mobile.path.isFirstPageUrl(fileUrl) ) {
|
5088
5179
|
deferred.reject( absUrl, settings );
|
5089
|
-
return;
|
5180
|
+
return deferred.promise();
|
5090
5181
|
}
|
5091
5182
|
|
5092
5183
|
// Reset base to the default document base
|
@@ -5107,12 +5198,14 @@ $.widget( "mobile.page", {
|
|
5107
5198
|
this._getBase().set(url);
|
5108
5199
|
}
|
5109
5200
|
|
5110
|
-
return;
|
5201
|
+
return deferred.promise();
|
5111
5202
|
}
|
5112
5203
|
|
5113
5204
|
triggerData = {
|
5114
5205
|
url: url,
|
5115
5206
|
absUrl: absUrl,
|
5207
|
+
toPage: url,
|
5208
|
+
prevPage: options ? options.fromPage : undefined,
|
5116
5209
|
dataUrl: dataUrl,
|
5117
5210
|
deferred: deferred,
|
5118
5211
|
options: settings
|
@@ -5124,7 +5217,7 @@ $.widget( "mobile.page", {
|
|
5124
5217
|
// If the default behavior is prevented, stop here!
|
5125
5218
|
if ( pblEvent.deprecatedEvent.isDefaultPrevented() ||
|
5126
5219
|
pblEvent.event.isDefaultPrevented() ) {
|
5127
|
-
return;
|
5220
|
+
return deferred.promise();
|
5128
5221
|
}
|
5129
5222
|
|
5130
5223
|
if ( settings.showLoadMsg ) {
|
@@ -5140,7 +5233,7 @@ $.widget( "mobile.page", {
|
|
5140
5233
|
if ( !( $.mobile.allowCrossDomainPages ||
|
5141
5234
|
$.mobile.path.isSameDomain($.mobile.path.documentUrl, absUrl ) ) ) {
|
5142
5235
|
deferred.reject( absUrl, settings );
|
5143
|
-
return;
|
5236
|
+
return deferred.promise();
|
5144
5237
|
}
|
5145
5238
|
|
5146
5239
|
// Load the new content.
|
@@ -5153,6 +5246,8 @@ $.widget( "mobile.page", {
|
|
5153
5246
|
success: this._loadSuccess( absUrl, triggerData, settings, deferred ),
|
5154
5247
|
error: this._loadError( absUrl, triggerData, settings, deferred )
|
5155
5248
|
});
|
5249
|
+
|
5250
|
+
return deferred.promise();
|
5156
5251
|
},
|
5157
5252
|
|
5158
5253
|
_loadError: function( absUrl, triggerData, settings, deferred ) {
|
@@ -5211,11 +5306,21 @@ $.widget( "mobile.page", {
|
|
5211
5306
|
|
5212
5307
|
//trigger before show/hide events
|
5213
5308
|
// TODO deprecate nextPage in favor of next
|
5214
|
-
this._triggerWithDeprecated( prefix + "hide", {
|
5309
|
+
this._triggerWithDeprecated( prefix + "hide", {
|
5310
|
+
|
5311
|
+
// Deprecated in 1.4 remove in 1.5
|
5312
|
+
nextPage: to,
|
5313
|
+
toPage: to,
|
5314
|
+
prevPage: from,
|
5315
|
+
samePage: samePage
|
5316
|
+
}, from );
|
5215
5317
|
}
|
5216
5318
|
|
5217
5319
|
// TODO deprecate prevPage in favor of previous
|
5218
|
-
this._triggerWithDeprecated( prefix + "show", {
|
5320
|
+
this._triggerWithDeprecated( prefix + "show", {
|
5321
|
+
prevPage: from || $( "" ),
|
5322
|
+
toPage: to
|
5323
|
+
}, to );
|
5219
5324
|
},
|
5220
5325
|
|
5221
5326
|
// TODO make private once change has been defined in the widget
|
@@ -5235,14 +5340,14 @@ $.widget( "mobile.page", {
|
|
5235
5340
|
|
5236
5341
|
promise = ( new TransitionHandler( transition, reverse, to, from ) ).transition();
|
5237
5342
|
|
5343
|
+
promise.done( $.proxy( function() {
|
5344
|
+
this._triggerCssTransitionEvents( to, from );
|
5345
|
+
}, this ));
|
5346
|
+
|
5238
5347
|
// TODO temporary accomodation of argument deferred
|
5239
5348
|
promise.done(function() {
|
5240
5349
|
deferred.resolve.apply( deferred, arguments );
|
5241
5350
|
});
|
5242
|
-
|
5243
|
-
promise.done($.proxy(function() {
|
5244
|
-
this._triggerCssTransitionEvents( to, from );
|
5245
|
-
}, this));
|
5246
5351
|
},
|
5247
5352
|
|
5248
5353
|
_releaseTransitionLock: function() {
|
@@ -5287,9 +5392,13 @@ $.widget( "mobile.page", {
|
|
5287
5392
|
},
|
5288
5393
|
|
5289
5394
|
_triggerPageBeforeChange: function( to, triggerData, settings ) {
|
5290
|
-
var
|
5395
|
+
var returnEvents;
|
5291
5396
|
|
5292
|
-
|
5397
|
+
triggerData.prevPage = this.activePage;
|
5398
|
+
$.extend( triggerData, {
|
5399
|
+
toPage: to,
|
5400
|
+
options: settings
|
5401
|
+
});
|
5293
5402
|
|
5294
5403
|
// NOTE: preserve the original target as the dataUrl value will be
|
5295
5404
|
// simplified eg, removing ui-state, and removing query params from
|
@@ -5306,10 +5415,11 @@ $.widget( "mobile.page", {
|
|
5306
5415
|
}
|
5307
5416
|
|
5308
5417
|
// Let listeners know we're about to change the current page.
|
5309
|
-
this.
|
5418
|
+
returnEvents = this._triggerWithDeprecated( "beforechange", triggerData );
|
5310
5419
|
|
5311
5420
|
// If the default behavior is prevented, stop here!
|
5312
|
-
if (
|
5421
|
+
if ( returnEvents.event.isDefaultPrevented() ||
|
5422
|
+
returnEvents.deprecatedEvent.isDefaultPrevented() ) {
|
5313
5423
|
return false;
|
5314
5424
|
}
|
5315
5425
|
|
@@ -5382,6 +5492,7 @@ $.widget( "mobile.page", {
|
|
5382
5492
|
return;
|
5383
5493
|
}
|
5384
5494
|
|
5495
|
+
triggerData.prevPage = settings.fromPage;
|
5385
5496
|
// if the (content|page)beforetransition default is prevented return early
|
5386
5497
|
// Note, we have to check for both the deprecated and new events
|
5387
5498
|
beforeTransition = this._triggerWithDeprecated( "beforetransition", triggerData );
|
@@ -5437,7 +5548,7 @@ $.widget( "mobile.page", {
|
|
5437
5548
|
|
5438
5549
|
isPageTransitioning = false;
|
5439
5550
|
this._triggerWithDeprecated( "transition", triggerData );
|
5440
|
-
this.
|
5551
|
+
this._triggerWithDeprecated( "change", triggerData );
|
5441
5552
|
|
5442
5553
|
// Even if there is no page change to be done, we should keep the
|
5443
5554
|
// urlHistory in sync with the hash changes
|
@@ -5515,12 +5626,6 @@ $.widget( "mobile.page", {
|
|
5515
5626
|
} else {
|
5516
5627
|
url += "#" + $.mobile.dialogHashKey;
|
5517
5628
|
}
|
5518
|
-
|
5519
|
-
// tack on another dialogHashKey if this is the same as the initial hash
|
5520
|
-
// this makes sure that a history entry is created for this dialog
|
5521
|
-
if ( $.mobile.navigate.history.activeIndex === 0 && url === $.mobile.navigate.history.initialDst ) {
|
5522
|
-
url += $.mobile.dialogHashKey;
|
5523
|
-
}
|
5524
5629
|
}
|
5525
5630
|
|
5526
5631
|
// if title element wasn't found, try the page div data attr too
|
@@ -5563,7 +5668,7 @@ $.widget( "mobile.page", {
|
|
5563
5668
|
};
|
5564
5669
|
|
5565
5670
|
if ( settings.changeHash !== false && $.mobile.hashListeningEnabled ) {
|
5566
|
-
$.mobile.navigate( url, params, true);
|
5671
|
+
$.mobile.navigate( this.window[ 0 ].encodeURI( url ), params, true);
|
5567
5672
|
} else if ( toPage[ 0 ] !== $.mobile.firstPage[ 0 ] ) {
|
5568
5673
|
$.mobile.navigate.history.add( url, params );
|
5569
5674
|
}
|
@@ -5604,8 +5709,8 @@ $.widget( "mobile.page", {
|
|
5604
5709
|
}
|
5605
5710
|
|
5606
5711
|
this._releaseTransitionLock();
|
5607
|
-
this.element.trigger( "pagechange", triggerData );
|
5608
5712
|
this._triggerWithDeprecated( "transition", triggerData );
|
5713
|
+
this._triggerWithDeprecated( "change", triggerData );
|
5609
5714
|
}, this));
|
5610
5715
|
},
|
5611
5716
|
|
@@ -5634,6 +5739,18 @@ $.widget( "mobile.page", {
|
|
5634
5739
|
|
5635
5740
|
// resolved on domready
|
5636
5741
|
var domreadyDeferred = $.Deferred(),
|
5742
|
+
|
5743
|
+
// resolved and nulled on window.load()
|
5744
|
+
loadDeferred = $.Deferred(),
|
5745
|
+
|
5746
|
+
// function that resolves the above deferred
|
5747
|
+
pageIsFullyLoaded = function() {
|
5748
|
+
|
5749
|
+
// Resolve and null the deferred
|
5750
|
+
loadDeferred.resolve();
|
5751
|
+
loadDeferred = null;
|
5752
|
+
},
|
5753
|
+
|
5637
5754
|
documentUrl = $.mobile.path.documentUrl,
|
5638
5755
|
|
5639
5756
|
// used to track last vclicked element to make sure its value is added to form data
|
@@ -5964,9 +6081,10 @@ $.widget( "mobile.page", {
|
|
5964
6081
|
// lists and select dialogs, just write a hash in the link they
|
5965
6082
|
// create. This means the actual URL path is based on whatever
|
5966
6083
|
// the current value of the base tag is at the time this code
|
5967
|
-
// is called.
|
5968
|
-
|
5969
|
-
|
6084
|
+
// is called.
|
6085
|
+
if ( href.search( "#" ) !== -1 &&
|
6086
|
+
!( $.mobile.path.isExternal( href ) && $.mobile.path.isAbsoluteUrl( href ) ) ) {
|
6087
|
+
|
5970
6088
|
href = href.replace( /[^#]*#/, "" );
|
5971
6089
|
if ( !href ) {
|
5972
6090
|
//link was an empty hash meant purely
|
@@ -6035,13 +6153,29 @@ $.widget( "mobile.page", {
|
|
6035
6153
|
$.mobile.pageContainer.pagecontainer();
|
6036
6154
|
|
6037
6155
|
//set page min-heights to be device specific
|
6038
|
-
$.mobile.document.bind( "pageshow",
|
6156
|
+
$.mobile.document.bind( "pageshow", function() {
|
6157
|
+
|
6158
|
+
// We need to wait for window.load to make sure that styles have already been rendered,
|
6159
|
+
// otherwise heights of external toolbars will have the wrong value
|
6160
|
+
if ( loadDeferred ) {
|
6161
|
+
loadDeferred.done( $.mobile.resetActivePageHeight );
|
6162
|
+
} else {
|
6163
|
+
$.mobile.resetActivePageHeight();
|
6164
|
+
}
|
6165
|
+
});
|
6039
6166
|
$.mobile.window.bind( "throttledresize", $.mobile.resetActivePageHeight );
|
6040
6167
|
|
6041
6168
|
};//navreadyDeferred done callback
|
6042
6169
|
|
6043
6170
|
$( function() { domreadyDeferred.resolve(); } );
|
6044
6171
|
|
6172
|
+
// Account for the possibility that the load event has already fired
|
6173
|
+
if ( document.readyState === "complete" ) {
|
6174
|
+
pageIsFullyLoaded();
|
6175
|
+
} else {
|
6176
|
+
$.mobile.window.load( pageIsFullyLoaded );
|
6177
|
+
}
|
6178
|
+
|
6045
6179
|
$.when( domreadyDeferred, $.mobile.navreadyDeferred ).done( function() { $.mobile._registerInternalEvents(); } );
|
6046
6180
|
})( jQuery );
|
6047
6181
|
|
@@ -6174,12 +6308,19 @@ $.widget( "mobile.page", {
|
|
6174
6308
|
// better transitions with fewer bugs. Ie, it's not guaranteed that the
|
6175
6309
|
// object will be created and transition will be run immediately after as
|
6176
6310
|
// it is today. So we wait until transition is invoked to gather the following
|
6177
|
-
var
|
6311
|
+
var none,
|
6312
|
+
reverseClass = this.reverse ? " reverse" : "",
|
6178
6313
|
screenHeight = $.mobile.getScreenHeight(),
|
6179
|
-
maxTransitionOverride = $.mobile.maxTransitionWidth !== false &&
|
6180
|
-
|
6314
|
+
maxTransitionOverride = $.mobile.maxTransitionWidth !== false &&
|
6315
|
+
$.mobile.window.width() > $.mobile.maxTransitionWidth;
|
6181
6316
|
|
6182
6317
|
this.toScroll = $.mobile.navigate.history.getActive().lastScroll || $.mobile.defaultHomeScroll;
|
6318
|
+
|
6319
|
+
none = !$.support.cssTransitions || !$.support.cssAnimations ||
|
6320
|
+
maxTransitionOverride || !this.name || this.name === "none" ||
|
6321
|
+
Math.max( $.mobile.window.scrollTop(), this.toScroll ) >
|
6322
|
+
$.mobile.getMaxScrollForTransition();
|
6323
|
+
|
6183
6324
|
this.toggleViewportClass();
|
6184
6325
|
|
6185
6326
|
if ( this.$from && !none ) {
|
@@ -6724,9 +6865,9 @@ $.widget( "mobile.collapsible", {
|
|
6724
6865
|
this._renderedOptions = this._getOptions( this.options );
|
6725
6866
|
|
6726
6867
|
if ( this.options.enhanced ) {
|
6727
|
-
ui.heading =
|
6868
|
+
ui.heading = this.element.children( ".ui-collapsible-heading" );
|
6728
6869
|
ui.content = ui.heading.next();
|
6729
|
-
ui.anchor =
|
6870
|
+
ui.anchor = ui.heading.children();
|
6730
6871
|
ui.status = ui.anchor.children( ".ui-collapsible-heading-status" );
|
6731
6872
|
} else {
|
6732
6873
|
this._enhance( elem, ui );
|
@@ -6840,7 +6981,7 @@ $.widget( "mobile.collapsible", {
|
|
6840
6981
|
},
|
6841
6982
|
|
6842
6983
|
_applyOptions: function( options ) {
|
6843
|
-
var isCollapsed, newTheme, oldTheme, hasCorners,
|
6984
|
+
var isCollapsed, newTheme, oldTheme, hasCorners, hasIcon,
|
6844
6985
|
elem = this.element,
|
6845
6986
|
currentOpts = this._renderedOptions,
|
6846
6987
|
ui = this._ui,
|
@@ -6857,38 +6998,61 @@ $.widget( "mobile.collapsible", {
|
|
6857
6998
|
|
6858
6999
|
isCollapsed = elem.hasClass( "ui-collapsible-collapsed" );
|
6859
7000
|
|
6860
|
-
//
|
6861
|
-
//
|
7001
|
+
// We only need to apply the cue text for the current state right away.
|
7002
|
+
// The cue text for the alternate state will be stored in the options
|
7003
|
+
// and applied the next time the collapsible's state is toggled
|
6862
7004
|
if ( isCollapsed ) {
|
6863
7005
|
if ( opts.expandCueText !== undefined ) {
|
6864
7006
|
status.text( opts.expandCueText );
|
6865
7007
|
}
|
6866
|
-
if ( opts.collapsedIcon !== undefined ) {
|
6867
|
-
if ( currentOpts.collapsedIcon ) {
|
6868
|
-
anchor.removeClass( "ui-icon-" + currentOpts.collapsedIcon );
|
6869
|
-
}
|
6870
|
-
if ( opts.collapsedIcon ) {
|
6871
|
-
anchor.addClass( "ui-icon-" + opts.collapsedIcon );
|
6872
|
-
}
|
6873
|
-
}
|
6874
7008
|
} else {
|
6875
7009
|
if ( opts.collapseCueText !== undefined ) {
|
6876
7010
|
status.text( opts.collapseCueText );
|
6877
7011
|
}
|
6878
|
-
if ( opts.expandedIcon !== undefined ) {
|
6879
|
-
if ( currentOpts.expandedIcon ) {
|
6880
|
-
anchor.removeClass( "ui-icon-" + currentOpts.expandedIcon );
|
6881
|
-
}
|
6882
|
-
if ( opts.expandedIcon ) {
|
6883
|
-
anchor.addClass( "ui-icon-" + opts.expandedIcon );
|
6884
|
-
}
|
6885
|
-
}
|
6886
7012
|
}
|
6887
7013
|
|
6888
|
-
|
6889
|
-
|
6890
|
-
|
6891
|
-
|
7014
|
+
// Update icon
|
7015
|
+
|
7016
|
+
// Is it supposed to have an icon?
|
7017
|
+
hasIcon =
|
7018
|
+
|
7019
|
+
// If the collapsedIcon is being set, consult that
|
7020
|
+
( opts.collapsedIcon !== undefined ? opts.collapsedIcon !== false :
|
7021
|
+
|
7022
|
+
// Otherwise consult the existing option value
|
7023
|
+
currentOpts.collapsedIcon !== false );
|
7024
|
+
|
7025
|
+
|
7026
|
+
// If any icon-related options have changed, make sure the new icon
|
7027
|
+
// state is reflected by first removing all icon-related classes
|
7028
|
+
// reflecting the current state and then adding all icon-related
|
7029
|
+
// classes for the new state
|
7030
|
+
if ( !( opts.iconpos === undefined &&
|
7031
|
+
opts.collapsedIcon === undefined &&
|
7032
|
+
opts.expandedIcon === undefined ) ) {
|
7033
|
+
|
7034
|
+
// Remove all current icon-related classes
|
7035
|
+
anchor.removeClass( [ iconposClass( currentOpts.iconpos ) ]
|
7036
|
+
.concat( ( currentOpts.expandedIcon ?
|
7037
|
+
[ "ui-icon-" + currentOpts.expandedIcon ] : [] ) )
|
7038
|
+
.concat( ( currentOpts.collapsedIcon ?
|
7039
|
+
[ "ui-icon-" + currentOpts.collapsedIcon ] : [] ) )
|
7040
|
+
.join( " " ) );
|
7041
|
+
|
7042
|
+
// Add new classes if an icon is supposed to be present
|
7043
|
+
if ( hasIcon ) {
|
7044
|
+
anchor.addClass(
|
7045
|
+
[ iconposClass( opts.iconpos !== undefined ?
|
7046
|
+
opts.iconpos : currentOpts.iconpos ) ]
|
7047
|
+
.concat( isCollapsed ?
|
7048
|
+
[ "ui-icon-" + ( opts.collapsedIcon !== undefined ?
|
7049
|
+
opts.collapsedIcon :
|
7050
|
+
currentOpts.collapsedIcon ) ] :
|
7051
|
+
[ "ui-icon-" + ( opts.expandedIcon !== undefined ?
|
7052
|
+
opts.expandedIcon :
|
7053
|
+
currentOpts.expandedIcon ) ] )
|
7054
|
+
.join( " " ) );
|
7055
|
+
}
|
6892
7056
|
}
|
6893
7057
|
|
6894
7058
|
if ( opts.theme !== undefined ) {
|
@@ -7010,16 +7174,31 @@ $.mobile.collapsible.defaults = {
|
|
7010
7174
|
|
7011
7175
|
(function( $, undefined ) {
|
7012
7176
|
|
7177
|
+
var uiScreenHiddenRegex = /\bui-screen-hidden\b/;
|
7178
|
+
function noHiddenClass( elements ) {
|
7179
|
+
var index,
|
7180
|
+
length = elements.length,
|
7181
|
+
result = [];
|
7182
|
+
|
7183
|
+
for ( index = 0; index < length; index++ ) {
|
7184
|
+
if ( !elements[ index ].className.match( uiScreenHiddenRegex ) ) {
|
7185
|
+
result.push( elements[ index ] );
|
7186
|
+
}
|
7187
|
+
}
|
7188
|
+
|
7189
|
+
return $( result );
|
7190
|
+
}
|
7191
|
+
|
7013
7192
|
$.mobile.behaviors.addFirstLastClasses = {
|
7014
7193
|
_getVisibles: function( $els, create ) {
|
7015
7194
|
var visibles;
|
7016
7195
|
|
7017
7196
|
if ( create ) {
|
7018
|
-
visibles = $els
|
7197
|
+
visibles = noHiddenClass( $els );
|
7019
7198
|
} else {
|
7020
7199
|
visibles = $els.filter( ":visible" );
|
7021
7200
|
if ( visibles.length === 0 ) {
|
7022
|
-
visibles = $els
|
7201
|
+
visibles = noHiddenClass( $els );
|
7023
7202
|
}
|
7024
7203
|
}
|
7025
7204
|
|
@@ -7222,7 +7401,7 @@ $.widget( "mobile.navbar", {
|
|
7222
7401
|
_create: function() {
|
7223
7402
|
|
7224
7403
|
var $navbar = this.element,
|
7225
|
-
$navbtns = $navbar.find( "a" ),
|
7404
|
+
$navbtns = $navbar.find( "a, button" ),
|
7226
7405
|
iconpos = $navbtns.filter( ":jqmData(icon)" ).length ? this.options.iconpos : undefined;
|
7227
7406
|
|
7228
7407
|
$navbar.addClass( "ui-navbar" )
|
@@ -7413,11 +7592,15 @@ $.widget( "mobile.listview", $.extend( {
|
|
7413
7592
|
.attr( "title", $.trim( last.getEncodedText() ) )
|
7414
7593
|
.addClass( altButtonClass )
|
7415
7594
|
.empty();
|
7595
|
+
|
7596
|
+
// Reduce to the first anchor, because only the first gets the buttonClass
|
7597
|
+
a = a.first();
|
7416
7598
|
} else if ( icon ) {
|
7417
7599
|
buttonClass += " ui-btn-icon-right ui-icon-" + icon;
|
7418
7600
|
}
|
7419
7601
|
|
7420
|
-
|
7602
|
+
// Apply buttonClass to the (first) anchor
|
7603
|
+
a.addClass( buttonClass );
|
7421
7604
|
} else if ( isDivider ) {
|
7422
7605
|
dividerTheme = ( getAttr( item[ 0 ], "theme" ) || o.dividerTheme || o.theme );
|
7423
7606
|
|
@@ -7460,7 +7643,7 @@ $.widget( "mobile.listview", $.extend( {
|
|
7460
7643
|
$( this ).closest( "li" ).addClass( "ui-li-has-count" );
|
7461
7644
|
});
|
7462
7645
|
if ( countThemeClass ) {
|
7463
|
-
countBubbles.addClass( countThemeClass );
|
7646
|
+
countBubbles.not( "[class*='ui-body-']" ).addClass( countThemeClass );
|
7464
7647
|
}
|
7465
7648
|
|
7466
7649
|
// Deprecated in 1.4. From 1.5 you have to add class ui-li-has-thumb or ui-li-has-icon to the LI.
|
@@ -7596,6 +7779,8 @@ $.mobile.behaviors.formReset = {
|
|
7596
7779
|
|
7597
7780
|
(function( $, undefined ) {
|
7598
7781
|
|
7782
|
+
var escapeId = $.mobile.path.hashToSelector;
|
7783
|
+
|
7599
7784
|
$.widget( "mobile.checkboxradio", $.extend( {
|
7600
7785
|
|
7601
7786
|
initSelector: "input:not( :jqmData(role='flipswitch' ) )[type='checkbox'],input[type='radio']:not( :jqmData(role='flipswitch' ))",
|
@@ -7615,15 +7800,12 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7615
7800
|
return input.jqmData( dataAttr ) ||
|
7616
7801
|
input.closest( "form, fieldset" ).jqmData( dataAttr );
|
7617
7802
|
},
|
7618
|
-
|
7619
|
-
|
7620
|
-
|
7621
|
-
|
7622
|
-
|
7623
|
-
|
7624
|
-
.find( "label" )
|
7625
|
-
.filter( "[for='" + $.mobile.path.hashToSelector( input[0].id ) + "']" )
|
7626
|
-
.first(),
|
7803
|
+
label = this.options.enhanced ?
|
7804
|
+
{
|
7805
|
+
element: this.element.siblings( "label" ),
|
7806
|
+
isParent: false
|
7807
|
+
} :
|
7808
|
+
this._findLabel(),
|
7627
7809
|
inputtype = input[0].type,
|
7628
7810
|
checkedClass = "ui-" + inputtype + "-on",
|
7629
7811
|
uncheckedClass = "ui-" + inputtype + "-off";
|
@@ -7636,7 +7818,8 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7636
7818
|
this.options.disabled = true;
|
7637
7819
|
}
|
7638
7820
|
|
7639
|
-
o.iconpos = inheritAttr( input, "iconpos" ) ||
|
7821
|
+
o.iconpos = inheritAttr( input, "iconpos" ) ||
|
7822
|
+
label.element.attr( "data-" + $.mobile.ns + "iconpos" ) || o.iconpos,
|
7640
7823
|
|
7641
7824
|
// Establish options
|
7642
7825
|
o.mini = inheritAttr( input, "mini" ) || o.mini;
|
@@ -7644,8 +7827,8 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7644
7827
|
// Expose for other methods
|
7645
7828
|
$.extend( this, {
|
7646
7829
|
input: input,
|
7647
|
-
label: label,
|
7648
|
-
|
7830
|
+
label: label.element,
|
7831
|
+
labelIsParent: label.isParent,
|
7649
7832
|
inputtype: inputtype,
|
7650
7833
|
checkedClass: checkedClass,
|
7651
7834
|
uncheckedClass: uncheckedClass
|
@@ -7655,7 +7838,7 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7655
7838
|
this._enhance();
|
7656
7839
|
}
|
7657
7840
|
|
7658
|
-
this._on( label, {
|
7841
|
+
this._on( label.element, {
|
7659
7842
|
vmouseover: "_handleLabelVMouseOver",
|
7660
7843
|
vclick: "_handleLabelVClick"
|
7661
7844
|
});
|
@@ -7671,10 +7854,36 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7671
7854
|
this.refresh();
|
7672
7855
|
},
|
7673
7856
|
|
7857
|
+
_findLabel: function() {
|
7858
|
+
var parentLabel, label, isParent,
|
7859
|
+
input = this.element,
|
7860
|
+
labelsList = input[ 0 ].labels;
|
7861
|
+
|
7862
|
+
if( labelsList && labelsList.length > 0 ) {
|
7863
|
+
label = $( labelsList[ 0 ] );
|
7864
|
+
isParent = $.contains( label[ 0 ], input[ 0 ] );
|
7865
|
+
} else {
|
7866
|
+
parentLabel = input.closest( "label" );
|
7867
|
+
isParent = ( parentLabel.length > 0 );
|
7868
|
+
|
7869
|
+
// NOTE: Windows Phone could not find the label through a selector
|
7870
|
+
// filter works though.
|
7871
|
+
label = isParent ? parentLabel :
|
7872
|
+
$( this.document[ 0 ].getElementsByTagName( "label" ) )
|
7873
|
+
.filter( "[for='" + escapeId( input[ 0 ].id ) + "']" )
|
7874
|
+
.first();
|
7875
|
+
}
|
7876
|
+
|
7877
|
+
return {
|
7878
|
+
element: label,
|
7879
|
+
isParent: isParent
|
7880
|
+
};
|
7881
|
+
},
|
7882
|
+
|
7674
7883
|
_enhance: function() {
|
7675
7884
|
this.label.addClass( "ui-btn ui-corner-all");
|
7676
7885
|
|
7677
|
-
if ( this.
|
7886
|
+
if ( this.labelIsParent ) {
|
7678
7887
|
this.input.add( this.label ).wrapAll( this._wrapper() );
|
7679
7888
|
} else {
|
7680
7889
|
//this.element.replaceWith( this.input.add( this.label ).wrapAll( this._wrapper() ) );
|
@@ -7708,18 +7917,10 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7708
7917
|
},
|
7709
7918
|
|
7710
7919
|
_handleInputVClick: function() {
|
7711
|
-
var $this = this.element;
|
7712
|
-
|
7713
7920
|
// Adds checked attribute to checked input when keyboard is used
|
7714
|
-
|
7715
|
-
|
7716
|
-
|
7717
|
-
this._getInputSet().not( $this ).prop( "checked", false );
|
7718
|
-
} else {
|
7719
|
-
$this.prop( "checked", false );
|
7720
|
-
}
|
7721
|
-
|
7722
|
-
this._updateAll();
|
7921
|
+
this.element.prop( "checked", this.element.is( ":checked" ) );
|
7922
|
+
this._getInputSet().not( this.element ).prop( "checked", false );
|
7923
|
+
this._updateAll( true );
|
7723
7924
|
},
|
7724
7925
|
|
7725
7926
|
_handleLabelVMouseOver: function( event ) {
|
@@ -7762,23 +7963,60 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7762
7963
|
});
|
7763
7964
|
},
|
7764
7965
|
|
7765
|
-
//
|
7966
|
+
// Returns those radio buttons that are supposed to be in the same group as
|
7967
|
+
// this radio button. In the case of a checkbox or a radio lacking a name
|
7968
|
+
// attribute, it returns this.element.
|
7766
7969
|
_getInputSet: function() {
|
7767
|
-
|
7768
|
-
|
7769
|
-
|
7970
|
+
var selector, formId,
|
7971
|
+
radio = this.element[ 0 ],
|
7972
|
+
name = radio.name,
|
7973
|
+
form = radio.form,
|
7974
|
+
doc = this.element.parents().last().get( 0 ),
|
7975
|
+
|
7976
|
+
// A radio is always a member of its own group
|
7977
|
+
radios = this.element;
|
7978
|
+
|
7979
|
+
// Only start running selectors if this is an attached radio button with a name
|
7980
|
+
if ( name && this.inputtype === "radio" && doc ) {
|
7981
|
+
selector = "input[type='radio'][name='" + escapeId( name ) + "']";
|
7982
|
+
|
7983
|
+
// If we're inside a form
|
7984
|
+
if ( form ) {
|
7985
|
+
formId = form.getAttribute( "id" );
|
7986
|
+
|
7987
|
+
// If the form has an ID, collect radios scattered throught the document which
|
7988
|
+
// nevertheless are part of the form by way of the value of their form attribute
|
7989
|
+
if ( formId ) {
|
7990
|
+
radios = $( selector + "[form='" + escapeId( formId ) + "']", doc );
|
7991
|
+
}
|
7992
|
+
|
7993
|
+
// Also add to those the radios in the form itself
|
7994
|
+
radios = $( form ).find( selector ).filter( function() {
|
7770
7995
|
|
7771
|
-
|
7772
|
-
|
7996
|
+
// Some radios inside the form may belong to some other form by virtue of
|
7997
|
+
// having a form attribute defined on them, so we must filter them out here
|
7998
|
+
return ( this.form === form );
|
7999
|
+
}).add( radios );
|
8000
|
+
|
8001
|
+
// If we're outside a form
|
8002
|
+
} else {
|
8003
|
+
|
8004
|
+
// Collect all those radios which are also outside of a form and match our name
|
8005
|
+
radios = $( selector, doc ).filter( function() {
|
8006
|
+
return !this.form;
|
8007
|
+
});
|
8008
|
+
}
|
8009
|
+
}
|
8010
|
+
return radios;
|
7773
8011
|
},
|
7774
8012
|
|
7775
|
-
_updateAll: function() {
|
8013
|
+
_updateAll: function( changeTriggered ) {
|
7776
8014
|
var self = this;
|
7777
8015
|
|
7778
8016
|
this._getInputSet().each( function() {
|
7779
8017
|
var $this = $( this );
|
7780
8018
|
|
7781
|
-
if ( this.checked || self.inputtype === "checkbox" ) {
|
8019
|
+
if ( ( this.checked || self.inputtype === "checkbox" ) && !changeTriggered ) {
|
7782
8020
|
$this.trigger( "change" );
|
7783
8021
|
}
|
7784
8022
|
})
|
@@ -7819,14 +8057,13 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7819
8057
|
},
|
7820
8058
|
|
7821
8059
|
refresh: function() {
|
7822
|
-
var
|
7823
|
-
isChecked = this.element[ 0 ].checked,
|
8060
|
+
var isChecked = this.element[ 0 ].checked,
|
7824
8061
|
active = $.mobile.activeBtnClass,
|
7825
8062
|
iconposClass = "ui-btn-icon-" + this.options.iconpos,
|
7826
8063
|
addClasses = [],
|
7827
8064
|
removeClasses = [];
|
7828
8065
|
|
7829
|
-
if (
|
8066
|
+
if ( this._hasIcon() ) {
|
7830
8067
|
removeClasses.push( active );
|
7831
8068
|
addClasses.push( iconposClass );
|
7832
8069
|
} else {
|
@@ -7842,6 +8079,8 @@ $.widget( "mobile.checkboxradio", $.extend( {
|
|
7842
8079
|
removeClasses.push( this.checkedClass );
|
7843
8080
|
}
|
7844
8081
|
|
8082
|
+
this.widget().toggleClass( "ui-state-disabled", this.element.prop( "disabled" ) );
|
8083
|
+
|
7845
8084
|
this.label
|
7846
8085
|
.addClass( addClasses.join( " " ) )
|
7847
8086
|
.removeClass( removeClasses.join( " " ) );
|
@@ -7957,8 +8196,8 @@ $.widget( "mobile.button", {
|
|
7957
8196
|
},
|
7958
8197
|
|
7959
8198
|
_destroy: function() {
|
7960
|
-
this.element.insertBefore( this.
|
7961
|
-
this.
|
8199
|
+
this.element.insertBefore( this.wrapper );
|
8200
|
+
this.wrapper.remove();
|
7962
8201
|
},
|
7963
8202
|
|
7964
8203
|
_getIconClasses: function( options ) {
|
@@ -8005,13 +8244,19 @@ $.widget( "mobile.button", {
|
|
8005
8244
|
},
|
8006
8245
|
|
8007
8246
|
refresh: function( create ) {
|
8247
|
+
var originalElement,
|
8248
|
+
isDisabled = this.element.prop( "disabled" );
|
8249
|
+
|
8008
8250
|
if ( this.options.icon && this.options.iconpos === "notext" && this.element.attr( "title" ) ) {
|
8009
8251
|
this.element.attr( "title", this.element.val() );
|
8010
8252
|
}
|
8011
8253
|
if ( !create ) {
|
8012
|
-
|
8254
|
+
originalElement = this.element.detach();
|
8013
8255
|
$( this.wrapper ).text( this.element.val() ).append( originalElement );
|
8014
8256
|
}
|
8257
|
+
if ( this.options.disabled !== isDisabled ) {
|
8258
|
+
this._setOptions({ disabled: isDisabled });
|
8259
|
+
}
|
8015
8260
|
}
|
8016
8261
|
});
|
8017
8262
|
|
@@ -8749,7 +8994,7 @@ $.widget( "mobile.slider", $.extend( {
|
|
8749
8994
|
|
8750
8995
|
// update control"s value
|
8751
8996
|
if ( isInput ) {
|
8752
|
-
valueChanged = control.val() !== newval;
|
8997
|
+
valueChanged = parseFloat( control.val() ) !== newval;
|
8753
8998
|
control.val( newval );
|
8754
8999
|
} else {
|
8755
9000
|
valueChanged = control[ 0 ].selectedIndex !== newval;
|
@@ -8820,6 +9065,8 @@ $.widget( "mobile.slider", $.extend( {
|
|
8820
9065
|
this.slider
|
8821
9066
|
.toggleClass( "ui-state-disabled", value )
|
8822
9067
|
.attr( "aria-disabled", value );
|
9068
|
+
|
9069
|
+
this.element.toggleClass( "ui-state-disabled", value );
|
8823
9070
|
}
|
8824
9071
|
|
8825
9072
|
}, $.mobile.behaviors.formReset ) );
|
@@ -8912,7 +9159,9 @@ $.widget( "mobile.slider", $.mobile.slider, {
|
|
8912
9159
|
if ( o.popupEnabled && this._popup ) {
|
8913
9160
|
this._positionPopup();
|
8914
9161
|
this._popup.html( newValue );
|
8915
|
-
}
|
9162
|
+
}
|
9163
|
+
|
9164
|
+
if ( o.showValue && !this.options.mini ) {
|
8916
9165
|
this.handle.html( newValue );
|
8917
9166
|
}
|
8918
9167
|
},
|
@@ -9241,6 +9490,7 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9241
9490
|
//if the first handle is dragged send the event to the first slider
|
9242
9491
|
$.data( this._inputFirst.get(0), "mobile-slider" ).dragging = true;
|
9243
9492
|
$.data( this._inputFirst.get(0), "mobile-slider" ).refresh( event );
|
9493
|
+
$.data( this._inputFirst.get(0), "mobile-slider" )._trigger( "start" );
|
9244
9494
|
return false;
|
9245
9495
|
},
|
9246
9496
|
|
@@ -9293,6 +9543,11 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9293
9543
|
if ( options.highlight !== undefined ) {
|
9294
9544
|
this._setHighlight( options.highlight );
|
9295
9545
|
}
|
9546
|
+
|
9547
|
+
if ( options.disabled !== undefined ) {
|
9548
|
+
this._setDisabled( options.disabled );
|
9549
|
+
}
|
9550
|
+
|
9296
9551
|
this._super( options );
|
9297
9552
|
this.refresh();
|
9298
9553
|
},
|
@@ -9399,6 +9654,11 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9399
9654
|
this._inputLast.slider( "option", "highlight", value );
|
9400
9655
|
},
|
9401
9656
|
|
9657
|
+
_setDisabled: function( value ) {
|
9658
|
+
this._inputFirst.prop( "disabled", value );
|
9659
|
+
this._inputLast.prop( "disabled", value );
|
9660
|
+
},
|
9661
|
+
|
9402
9662
|
_destroy: function() {
|
9403
9663
|
this._label.prependTo( this.element );
|
9404
9664
|
this.element.removeClass( "ui-rangeslider ui-mini" );
|
@@ -9423,16 +9683,21 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9423
9683
|
_create: function() {
|
9424
9684
|
this._super();
|
9425
9685
|
|
9426
|
-
if (
|
9686
|
+
if ( this.isSearch ) {
|
9687
|
+
this.options.clearBtn = true;
|
9688
|
+
}
|
9689
|
+
|
9690
|
+
if ( !!this.options.clearBtn && this.inputNeedsWrap ) {
|
9427
9691
|
this._addClearBtn();
|
9428
9692
|
}
|
9429
9693
|
},
|
9430
9694
|
|
9431
9695
|
clearButton: function() {
|
9432
|
-
|
9433
|
-
|
9434
|
-
|
9435
|
-
|
9696
|
+
return $( "<a href='#' tabindex='-1' aria-hidden='true' " +
|
9697
|
+
"class='ui-input-clear ui-btn ui-icon-delete ui-btn-icon-notext ui-corner-all'>" +
|
9698
|
+
"</a>" )
|
9699
|
+
.attr( "title", this.options.clearBtnText )
|
9700
|
+
.text( this.options.clearBtnText );
|
9436
9701
|
},
|
9437
9702
|
|
9438
9703
|
_clearBtnClick: function( event ) {
|
@@ -9525,7 +9790,9 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9525
9790
|
|
9526
9791
|
_destroy: function() {
|
9527
9792
|
this._super();
|
9528
|
-
this.
|
9793
|
+
if ( this.options.clearBtn ) {
|
9794
|
+
this._destroyClear();
|
9795
|
+
}
|
9529
9796
|
}
|
9530
9797
|
|
9531
9798
|
});
|
@@ -9555,7 +9822,7 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9555
9822
|
"keyup": "_timeout",
|
9556
9823
|
"change": "_timeout",
|
9557
9824
|
"input": "_timeout",
|
9558
|
-
"paste": "_timeout"
|
9825
|
+
"paste": "_timeout"
|
9559
9826
|
});
|
9560
9827
|
|
9561
9828
|
// Attach to the various you-have-become-visible notifications that the
|
@@ -9591,7 +9858,7 @@ $.widget( "mobile.flipswitch", $.extend({
|
|
9591
9858
|
}, this ),
|
9592
9859
|
"transition" );
|
9593
9860
|
}
|
9594
|
-
this.
|
9861
|
+
this._prepareHeightUpdate();
|
9595
9862
|
}
|
9596
9863
|
},
|
9597
9864
|
|
@@ -9822,7 +10089,9 @@ $.widget( "mobile.selectmenu", $.extend( {
|
|
9822
10089
|
self.refresh();
|
9823
10090
|
|
9824
10091
|
if ( !!options.nativeMenu ) {
|
9825
|
-
|
10092
|
+
self._delay( function() {
|
10093
|
+
self.select.blur();
|
10094
|
+
});
|
9826
10095
|
}
|
9827
10096
|
});
|
9828
10097
|
|
@@ -10059,6 +10328,14 @@ $.widget( "mobile.popup", {
|
|
10059
10328
|
history: !$.mobile.browser.oldIE
|
10060
10329
|
},
|
10061
10330
|
|
10331
|
+
// When the user depresses the mouse/finger on an element inside the popup while the popup is
|
10332
|
+
// open, we ignore resize events for a short while. This prevents #6961.
|
10333
|
+
_handleDocumentVmousedown: function( theEvent ) {
|
10334
|
+
if ( this._isOpen && $.contains( this._ui.container[ 0 ], theEvent.target ) ) {
|
10335
|
+
this._ignoreResizeEvents();
|
10336
|
+
}
|
10337
|
+
},
|
10338
|
+
|
10062
10339
|
_create: function() {
|
10063
10340
|
var theElement = this.element,
|
10064
10341
|
myId = theElement.attr( "id" ),
|
@@ -10069,6 +10346,10 @@ $.widget( "mobile.popup", {
|
|
10069
10346
|
// it is determined whether there shall be AJAX nav.
|
10070
10347
|
currentOptions.history = currentOptions.history && $.mobile.ajaxEnabled && $.mobile.hashListeningEnabled;
|
10071
10348
|
|
10349
|
+
this._on( this.document, {
|
10350
|
+
"vmousedown": "_handleDocumentVmousedown"
|
10351
|
+
});
|
10352
|
+
|
10072
10353
|
// Define instance variables
|
10073
10354
|
$.extend( this, {
|
10074
10355
|
_scrollTop: 0,
|
@@ -10270,10 +10551,10 @@ $.widget( "mobile.popup", {
|
|
10270
10551
|
|
10271
10552
|
if ( targetElement !== ui.container[ 0 ] ) {
|
10272
10553
|
target = $( targetElement );
|
10273
|
-
if (
|
10274
|
-
$( this.document[ 0 ].activeElement ).one( "focus", function(
|
10275
|
-
|
10276
|
-
});
|
10554
|
+
if ( !$.contains( ui.container[ 0 ], targetElement ) ) {
|
10555
|
+
$( this.document[ 0 ].activeElement ).one( "focus", $.proxy( function() {
|
10556
|
+
this._safelyBlur( targetElement );
|
10557
|
+
}, this ) );
|
10277
10558
|
ui.focusElement.focus();
|
10278
10559
|
theEvent.preventDefault();
|
10279
10560
|
theEvent.stopImmediatePropagation();
|
@@ -10604,13 +10885,28 @@ $.widget( "mobile.popup", {
|
|
10604
10885
|
}
|
10605
10886
|
},
|
10606
10887
|
|
10888
|
+
_safelyBlur: function( currentElement ){
|
10889
|
+
if ( currentElement !== this.window[ 0 ] &&
|
10890
|
+
currentElement.nodeName.toLowerCase() !== "body" ) {
|
10891
|
+
$( currentElement ).blur();
|
10892
|
+
}
|
10893
|
+
},
|
10894
|
+
|
10607
10895
|
_openPrerequisitesComplete: function() {
|
10608
|
-
var id = this.element.attr( "id" )
|
10896
|
+
var id = this.element.attr( "id" ),
|
10897
|
+
firstFocus = this._ui.container.find( ":focusable" ).first();
|
10609
10898
|
|
10610
10899
|
this._ui.container.addClass( "ui-popup-active" );
|
10611
10900
|
this._isOpen = true;
|
10612
10901
|
this._resizeScreen();
|
10613
|
-
|
10902
|
+
|
10903
|
+
// Check to see if currElement is not a child of the container. If it's not, blur
|
10904
|
+
if ( !$.contains( this._ui.container[ 0 ], this.document[ 0 ].activeElement ) ) {
|
10905
|
+
this._safelyBlur( this.document[ 0 ].activeElement );
|
10906
|
+
}
|
10907
|
+
if ( firstFocus.length > 0 ) {
|
10908
|
+
this._ui.focusElement = firstFocus;
|
10909
|
+
}
|
10614
10910
|
this._ignoreResizeEvents();
|
10615
10911
|
if ( id ) {
|
10616
10912
|
this.document.find( "[aria-haspopup='true'][aria-owns='" + id + "']" ).attr( "aria-expanded", true );
|
@@ -10695,8 +10991,6 @@ $.widget( "mobile.popup", {
|
|
10695
10991
|
var container = this._ui.container,
|
10696
10992
|
id = this.element.attr( "id" );
|
10697
10993
|
|
10698
|
-
container.removeAttr( "tabindex" );
|
10699
|
-
|
10700
10994
|
// remove the global mutex for popups
|
10701
10995
|
$.mobile.popup.active = undefined;
|
10702
10996
|
|
@@ -10876,11 +11170,6 @@ $.widget( "mobile.popup", {
|
|
10876
11170
|
url = $.mobile.path.parseLocation().hash + hashkey;
|
10877
11171
|
}
|
10878
11172
|
|
10879
|
-
// Tack on an extra hashkey if this is the first page and we've just reconstructed the initial hash
|
10880
|
-
if ( urlHistory.activeIndex === 0 && url === urlHistory.initialDst ) {
|
10881
|
-
url += hashkey;
|
10882
|
-
}
|
10883
|
-
|
10884
11173
|
// swallow the the initial navigation event, and bind for the next
|
10885
11174
|
this.window.one( "beforenavigate", function( theEvent ) {
|
10886
11175
|
theEvent.preventDefault();
|
@@ -10993,7 +11282,7 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
10993
11282
|
},
|
10994
11283
|
|
10995
11284
|
_handleButtonVclickKeydown: function( event ) {
|
10996
|
-
if ( this.options.disabled || this.isOpen ) {
|
11285
|
+
if ( this.options.disabled || this.isOpen || this.options.nativeMenu ) {
|
10997
11286
|
return;
|
10998
11287
|
}
|
10999
11288
|
|
@@ -11044,6 +11333,10 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11044
11333
|
},
|
11045
11334
|
|
11046
11335
|
_handleMenuPageHide: function() {
|
11336
|
+
|
11337
|
+
// After the dialog's done, we may want to trigger change if the value has actually changed
|
11338
|
+
this._delayedTrigger();
|
11339
|
+
|
11047
11340
|
// TODO centralize page removal binding / handling in the page plugin.
|
11048
11341
|
// Suggestion from @jblas to do refcounting
|
11049
11342
|
//
|
@@ -11066,18 +11359,55 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11066
11359
|
}
|
11067
11360
|
},
|
11068
11361
|
|
11362
|
+
_handleListItemClick: function( event ) {
|
11363
|
+
var listItem = $( event.target ).closest( "li" ),
|
11364
|
+
|
11365
|
+
// Index of option tag to be selected
|
11366
|
+
oldIndex = this.select[ 0 ].selectedIndex,
|
11367
|
+
newIndex = $.mobile.getAttribute( listItem, "option-index" ),
|
11368
|
+
option = this._selectOptions().eq( newIndex )[ 0 ];
|
11369
|
+
|
11370
|
+
// Toggle selected status on the tag for multi selects
|
11371
|
+
option.selected = this.isMultiple ? !option.selected : true;
|
11372
|
+
|
11373
|
+
// Toggle checkbox class for multiple selects
|
11374
|
+
if ( this.isMultiple ) {
|
11375
|
+
listItem.find( "a" )
|
11376
|
+
.toggleClass( "ui-checkbox-on", option.selected )
|
11377
|
+
.toggleClass( "ui-checkbox-off", !option.selected );
|
11378
|
+
}
|
11379
|
+
|
11380
|
+
// If it's not a multiple select, trigger change after it has finished closing
|
11381
|
+
if ( !this.isMultiple && oldIndex !== newIndex ) {
|
11382
|
+
this._triggerChange = true;
|
11383
|
+
}
|
11384
|
+
|
11385
|
+
// Trigger change if it's a multiple select
|
11386
|
+
// Hide custom select for single selects only - otherwise focus clicked item
|
11387
|
+
// We need to grab the clicked item the hard way, because the list may have been rebuilt
|
11388
|
+
if ( this.isMultiple ) {
|
11389
|
+
this.select.trigger( "change" );
|
11390
|
+
this.list.find( "li:not(.ui-li-divider)" ).eq( newIndex )
|
11391
|
+
.find( "a" ).first().focus();
|
11392
|
+
}
|
11393
|
+
else {
|
11394
|
+
this.close();
|
11395
|
+
}
|
11396
|
+
|
11397
|
+
event.preventDefault();
|
11398
|
+
},
|
11399
|
+
|
11069
11400
|
build: function() {
|
11070
11401
|
var selectId, popupId, dialogId, label, thisPage, isMultiple, menuId,
|
11071
11402
|
themeAttr, overlayTheme, overlayThemeAttr, dividerThemeAttr,
|
11072
11403
|
menuPage, listbox, list, header, headerTitle, menuPageContent,
|
11073
|
-
menuPageClose, headerClose,
|
11404
|
+
menuPageClose, headerClose,
|
11074
11405
|
o = this.options;
|
11075
11406
|
|
11076
11407
|
if ( o.nativeMenu ) {
|
11077
11408
|
return this._super();
|
11078
11409
|
}
|
11079
11410
|
|
11080
|
-
self = this;
|
11081
11411
|
selectId = this.selectId;
|
11082
11412
|
popupId = selectId + "-listbox";
|
11083
11413
|
dialogId = selectId + "-dialog";
|
@@ -11092,11 +11422,14 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11092
11422
|
dividerThemeAttr = ( o.dividerTheme && isMultiple ) ? ( " data-" + $.mobile.ns + "divider-theme='" + o.dividerTheme + "'" ) : "";
|
11093
11423
|
menuPage = $( "<div data-" + $.mobile.ns + "role='dialog' class='ui-selectmenu' id='" + dialogId + "'" + themeAttr + overlayThemeAttr + ">" +
|
11094
11424
|
"<div data-" + $.mobile.ns + "role='header'>" +
|
11095
|
-
"<div class='ui-title'
|
11425
|
+
"<div class='ui-title'></div>"+
|
11096
11426
|
"</div>"+
|
11097
11427
|
"<div data-" + $.mobile.ns + "role='content'></div>"+
|
11098
11428
|
"</div>" );
|
11099
|
-
listbox = $( "<div
|
11429
|
+
listbox = $( "<div" + themeAttr + overlayThemeAttr + " id='" + popupId +
|
11430
|
+
"' class='ui-selectmenu'></div>" )
|
11431
|
+
.insertAfter( this.select )
|
11432
|
+
.popup();
|
11100
11433
|
list = $( "<ul class='ui-selectmenu-list' id='" + menuId + "' role='listbox' aria-labelledby='" + this.buttonId + "'" + themeAttr + dividerThemeAttr + "></ul>" ).appendTo( listbox );
|
11101
11434
|
header = $( "<div class='ui-header ui-bar-" + ( o.theme ? o.theme : "inherit" ) + "'></div>" ).prependTo( listbox );
|
11102
11435
|
headerTitle = $( "<h1 class='ui-title'></h1>" ).appendTo( header );
|
@@ -11152,52 +11485,18 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11152
11485
|
// Events for list items
|
11153
11486
|
this.list.attr( "role", "listbox" );
|
11154
11487
|
this._on( this.list, {
|
11155
|
-
focusin
|
11156
|
-
focusout
|
11157
|
-
keydown: "_handleListKeydown"
|
11488
|
+
"focusin": "_handleListFocus",
|
11489
|
+
"focusout": "_handleListFocus",
|
11490
|
+
"keydown": "_handleListKeydown",
|
11491
|
+
"click li:not(.ui-disabled,.ui-state-disabled,.ui-li-divider)": "_handleListItemClick"
|
11158
11492
|
});
|
11159
|
-
this.list
|
11160
|
-
.delegate( "li:not(.ui-disabled,.ui-state-disabled,.ui-li-divider)", "click", function( event ) {
|
11161
|
-
|
11162
|
-
// index of option tag to be selected
|
11163
|
-
var oldIndex = self.select[ 0 ].selectedIndex,
|
11164
|
-
newIndex = $.mobile.getAttribute( this, "option-index" ),
|
11165
|
-
option = self._selectOptions().eq( newIndex )[ 0 ];
|
11166
|
-
|
11167
|
-
// toggle selected status on the tag for multi selects
|
11168
|
-
option.selected = self.isMultiple ? !option.selected : true;
|
11169
|
-
|
11170
|
-
// toggle checkbox class for multiple selects
|
11171
|
-
if ( self.isMultiple ) {
|
11172
|
-
$( this ).find( "a" )
|
11173
|
-
.toggleClass( "ui-checkbox-on", option.selected )
|
11174
|
-
.toggleClass( "ui-checkbox-off", !option.selected );
|
11175
|
-
}
|
11176
|
-
|
11177
|
-
// trigger change if value changed
|
11178
|
-
if ( self.isMultiple || oldIndex !== newIndex ) {
|
11179
|
-
self.select.trigger( "change" );
|
11180
|
-
}
|
11181
|
-
|
11182
|
-
// hide custom select for single selects only - otherwise focus clicked item
|
11183
|
-
// We need to grab the clicked item the hard way, because the list may have been rebuilt
|
11184
|
-
if ( self.isMultiple ) {
|
11185
|
-
self.list.find( "li:not(.ui-li-divider)" ).eq( newIndex )
|
11186
|
-
.find( "a" ).first().focus();
|
11187
|
-
}
|
11188
|
-
else {
|
11189
|
-
self.close();
|
11190
|
-
}
|
11191
|
-
|
11192
|
-
event.preventDefault();
|
11193
|
-
});
|
11194
11493
|
|
11195
11494
|
// button refocus ensures proper height calculation
|
11196
11495
|
// by removing the inline style and ensuring page inclusion
|
11197
11496
|
this._on( this.menuPage, { pagehide: "_handleMenuPageHide" } );
|
11198
11497
|
|
11199
11498
|
// Events on the popup
|
11200
|
-
this._on( this.listbox, { popupafterclose: "
|
11499
|
+
this._on( this.listbox, { popupafterclose: "_popupClosed" } );
|
11201
11500
|
|
11202
11501
|
// Close button on small overlays
|
11203
11502
|
if ( this.isMultiple ) {
|
@@ -11207,6 +11506,18 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11207
11506
|
return this;
|
11208
11507
|
},
|
11209
11508
|
|
11509
|
+
_popupClosed: function() {
|
11510
|
+
this.close();
|
11511
|
+
this._delayedTrigger();
|
11512
|
+
},
|
11513
|
+
|
11514
|
+
_delayedTrigger: function() {
|
11515
|
+
if ( this._triggerChange ) {
|
11516
|
+
this.element.trigger( "change" );
|
11517
|
+
}
|
11518
|
+
this._triggerChange = false;
|
11519
|
+
},
|
11520
|
+
|
11210
11521
|
_isRebuildRequired: function() {
|
11211
11522
|
var list = this.list.find( "li" ),
|
11212
11523
|
options = this._selectOptions().not( ".ui-screen-hidden" );
|
@@ -11242,9 +11553,8 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11242
11553
|
.find( "a" ).removeClass( $.mobile.activeBtnClass ).end()
|
11243
11554
|
.attr( "aria-selected", false )
|
11244
11555
|
.each(function( i ) {
|
11245
|
-
|
11556
|
+
var item = $( this );
|
11246
11557
|
if ( $.inArray( i, indices ) > -1 ) {
|
11247
|
-
var item = $( this );
|
11248
11558
|
|
11249
11559
|
// Aria selected attr
|
11250
11560
|
item.attr( "aria-selected", true );
|
@@ -11259,6 +11569,8 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11259
11569
|
item.find( "a" ).addClass( $.mobile.activeBtnClass );
|
11260
11570
|
}
|
11261
11571
|
}
|
11572
|
+
} else if ( self.isMultiple ) {
|
11573
|
+
item.find( "a" ).removeClass( "ui-checkbox-on" ).addClass( "ui-checkbox-off" );
|
11262
11574
|
}
|
11263
11575
|
});
|
11264
11576
|
},
|
@@ -11328,7 +11640,9 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11328
11640
|
|
11329
11641
|
self.menuType = "page";
|
11330
11642
|
self.menuPageContent.append( self.list );
|
11331
|
-
self.menuPage
|
11643
|
+
self.menuPage
|
11644
|
+
.find( "div .ui-title" )
|
11645
|
+
.text( self.label.getEncodedText() || self.placeholder );
|
11332
11646
|
} else {
|
11333
11647
|
self.menuType = "overlay";
|
11334
11648
|
|
@@ -11370,10 +11684,15 @@ $.widget( "mobile.selectmenu", $.mobile.selectmenu, {
|
|
11370
11684
|
}
|
11371
11685
|
|
11372
11686
|
parent = option.parentNode;
|
11373
|
-
text = $option.text();
|
11374
|
-
anchor = document.createElement( "a" );
|
11375
11687
|
classes = [];
|
11376
11688
|
|
11689
|
+
// Although using .text() here raises the risk that, when we later paste this into the
|
11690
|
+
// list item we end up pasting possibly malicious things like <script> tags, that risk
|
11691
|
+
// only arises if we do something like $( "<li><a href='#'>" + text + "</a></li>" ). We
|
11692
|
+
// don't do that. We do document.createTextNode( text ) instead, which guarantees that
|
11693
|
+
// whatever we paste in will end up as text, with characters like <, > and & escaped.
|
11694
|
+
text = $option.text();
|
11695
|
+
anchor = document.createElement( "a" );
|
11377
11696
|
anchor.setAttribute( "href", "#" );
|
11378
11697
|
anchor.appendChild( document.createTextNode( text ) );
|
11379
11698
|
|
@@ -11744,7 +12063,7 @@ $.fn.buttonMarkup.defaults = {
|
|
11744
12063
|
};
|
11745
12064
|
|
11746
12065
|
$.extend( $.fn.buttonMarkup, {
|
11747
|
-
initSelector: "a:jqmData(role='button'), .ui-bar > a, .ui-bar > :jqmData(role='controlgroup') > a, button"
|
12066
|
+
initSelector: "a:jqmData(role='button'), .ui-bar > a, .ui-bar > :jqmData(role='controlgroup') > a, button:not(:jqmData(role='navbar') button)"
|
11748
12067
|
});
|
11749
12068
|
|
11750
12069
|
})( jQuery );
|
@@ -11765,16 +12084,22 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
11765
12084
|
|
11766
12085
|
_create: function() {
|
11767
12086
|
var elem = this.element,
|
11768
|
-
opts = this.options
|
12087
|
+
opts = this.options,
|
12088
|
+
keepNative = $.mobile.page.prototype.keepNativeSelector();
|
11769
12089
|
|
11770
12090
|
// Run buttonmarkup
|
11771
12091
|
if ( $.fn.buttonMarkup ) {
|
11772
|
-
this.element
|
12092
|
+
this.element
|
12093
|
+
.find( $.fn.buttonMarkup.initSelector )
|
12094
|
+
.not( keepNative )
|
12095
|
+
.buttonMarkup();
|
11773
12096
|
}
|
11774
12097
|
// Enhance child widgets
|
11775
12098
|
$.each( this._childWidgets, $.proxy( function( number, widgetName ) {
|
11776
12099
|
if ( $.mobile[ widgetName ] ) {
|
11777
|
-
this.element
|
12100
|
+
this.element
|
12101
|
+
.find( $.mobile[ widgetName ].initSelector )
|
12102
|
+
.not( keepNative )[ widgetName ]();
|
11778
12103
|
}
|
11779
12104
|
}, this ));
|
11780
12105
|
|
@@ -11945,8 +12270,7 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
11945
12270
|
role: role,
|
11946
12271
|
page: page,
|
11947
12272
|
leftbtn: leftbtn,
|
11948
|
-
rightbtn: rightbtn
|
11949
|
-
backBtn: null
|
12273
|
+
rightbtn: rightbtn
|
11950
12274
|
});
|
11951
12275
|
this.element.attr( "role", role === "header" ? "banner" : "contentinfo" ).addClass( "ui-" + role );
|
11952
12276
|
this.refresh();
|
@@ -11954,15 +12278,7 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
11954
12278
|
},
|
11955
12279
|
_setOptions: function( o ) {
|
11956
12280
|
if ( o.addBackBtn !== undefined ) {
|
11957
|
-
|
11958
|
-
this.role === "header" &&
|
11959
|
-
$( ".ui-page" ).length > 1 &&
|
11960
|
-
this.page[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) !== $.mobile.path.stripHash( location.hash ) &&
|
11961
|
-
!this.leftbtn ) {
|
11962
|
-
this._addBackButton();
|
11963
|
-
} else {
|
11964
|
-
this.element.find( ".ui-toolbar-back-btn" ).remove();
|
11965
|
-
}
|
12281
|
+
this._updateBackButton();
|
11966
12282
|
}
|
11967
12283
|
if ( o.backBtnTheme != null ) {
|
11968
12284
|
this.element
|
@@ -11989,6 +12305,8 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
11989
12305
|
this._setRelative();
|
11990
12306
|
if ( this.role === "footer" ) {
|
11991
12307
|
this.element.appendTo( "body" );
|
12308
|
+
} else if ( this.role === "header" ) {
|
12309
|
+
this._updateBackButton();
|
11992
12310
|
}
|
11993
12311
|
}
|
11994
12312
|
this._addHeadingClasses();
|
@@ -12010,27 +12328,70 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
12010
12328
|
},
|
12011
12329
|
// Deprecated in 1.4. As from 1.5 ui-btn-left/right classes have to be present in the markup.
|
12012
12330
|
_addHeaderButtonClasses: function() {
|
12013
|
-
var
|
12014
|
-
this.leftbtn = $headeranchors.hasClass( "ui-btn-left" );
|
12015
|
-
this.rightbtn = $headeranchors.hasClass( "ui-btn-right" );
|
12331
|
+
var headerAnchors = this.element.children( "a, button" );
|
12016
12332
|
|
12017
|
-
|
12333
|
+
// Do not mistake a back button for a left toolbar button
|
12334
|
+
this.leftbtn = headerAnchors.hasClass( "ui-btn-left" ) &&
|
12335
|
+
!headerAnchors.hasClass( "ui-toolbar-back-btn" );
|
12018
12336
|
|
12019
|
-
this.rightbtn =
|
12337
|
+
this.rightbtn = headerAnchors.hasClass( "ui-btn-right" );
|
12020
12338
|
|
12021
|
-
|
12022
|
-
|
12023
|
-
|
12024
|
-
|
12339
|
+
// Filter out right buttons and back buttons
|
12340
|
+
this.leftbtn = this.leftbtn ||
|
12341
|
+
headerAnchors.eq( 0 )
|
12342
|
+
.not( ".ui-btn-right,.ui-toolbar-back-btn" )
|
12343
|
+
.addClass( "ui-btn-left" )
|
12344
|
+
.length;
|
12025
12345
|
|
12026
|
-
|
12346
|
+
this.rightbtn = this.rightbtn || headerAnchors.eq( 1 ).addClass( "ui-btn-right" ).length;
|
12347
|
+
},
|
12348
|
+
_updateBackButton: function() {
|
12349
|
+
var backButton,
|
12350
|
+
options = this.options,
|
12027
12351
|
theme = options.backBtnTheme || options.theme;
|
12028
|
-
|
12029
|
-
|
12030
|
-
|
12031
|
-
|
12032
|
-
|
12033
|
-
|
12352
|
+
|
12353
|
+
// Retrieve the back button or create a new, empty one
|
12354
|
+
backButton = this._backButton = ( this._backButton || {} );
|
12355
|
+
|
12356
|
+
// We add a back button only if the option to do so is on
|
12357
|
+
if ( this.options.addBackBtn &&
|
12358
|
+
|
12359
|
+
// This must also be a header toolbar
|
12360
|
+
this.role === "header" &&
|
12361
|
+
|
12362
|
+
// There must be multiple pages in the DOM
|
12363
|
+
$( ".ui-page" ).length > 1 &&
|
12364
|
+
( this.page ?
|
12365
|
+
|
12366
|
+
// If the toolbar is internal the page's URL must differ from the hash
|
12367
|
+
( this.page[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) !==
|
12368
|
+
$.mobile.path.stripHash( location.hash ) ) :
|
12369
|
+
|
12370
|
+
// Otherwise, if the toolbar is external there must be at least one
|
12371
|
+
// history item to which one can go back
|
12372
|
+
( $.mobile.navigate && $.mobile.navigate.history &&
|
12373
|
+
$.mobile.navigate.history.activeIndex > 0 ) ) &&
|
12374
|
+
|
12375
|
+
// The toolbar does not have a left button
|
12376
|
+
!this.leftbtn ) {
|
12377
|
+
|
12378
|
+
// Skip back button creation if one is already present
|
12379
|
+
if ( !backButton.attached ) {
|
12380
|
+
this.backButton = backButton.element = ( backButton.element ||
|
12381
|
+
$( "<a role='button' href='javascript:void(0);' " +
|
12382
|
+
"class='ui-btn ui-corner-all ui-shadow ui-btn-left " +
|
12383
|
+
( theme ? "ui-btn-" + theme + " " : "" ) +
|
12384
|
+
"ui-toolbar-back-btn ui-icon-carat-l ui-btn-icon-left' " +
|
12385
|
+
"data-" + $.mobile.ns + "rel='back'>" + options.backBtnText +
|
12386
|
+
"</a>" ) )
|
12387
|
+
.prependTo( this.element );
|
12388
|
+
backButton.attached = true;
|
12389
|
+
}
|
12390
|
+
|
12391
|
+
// If we are not adding a back button, then remove the one present, if any
|
12392
|
+
} else if ( backButton.element ) {
|
12393
|
+
backButton.element.detach();
|
12394
|
+
backButton.attached = false;
|
12034
12395
|
}
|
12035
12396
|
},
|
12036
12397
|
_addHeadingClasses: function() {
|
@@ -12041,6 +12402,27 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
12041
12402
|
"role": "heading",
|
12042
12403
|
"aria-level": "1"
|
12043
12404
|
});
|
12405
|
+
},
|
12406
|
+
_destroy: function() {
|
12407
|
+
var currentTheme;
|
12408
|
+
|
12409
|
+
this.element.children( "h1, h2, h3, h4, h5, h6" )
|
12410
|
+
.removeClass( "ui-title" )
|
12411
|
+
.removeAttr( "role" )
|
12412
|
+
.removeAttr( "aria-level" );
|
12413
|
+
|
12414
|
+
if ( this.role === "header" ) {
|
12415
|
+
this.element.children( "a, button" )
|
12416
|
+
.removeClass( "ui-btn-left ui-btn-right ui-btn ui-shadow ui-corner-all" );
|
12417
|
+
if ( this.backButton) {
|
12418
|
+
this.backButton.remove();
|
12419
|
+
}
|
12420
|
+
}
|
12421
|
+
|
12422
|
+
currentTheme = this.options.theme ? this.options.theme : "inherit";
|
12423
|
+
this.element.removeClass( "ui-bar-" + currentTheme );
|
12424
|
+
|
12425
|
+
this.element.removeClass( "ui-" + this.role ).removeAttr( "role" );
|
12044
12426
|
}
|
12045
12427
|
});
|
12046
12428
|
|
@@ -12074,6 +12456,7 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
12074
12456
|
|
12075
12457
|
_create: function() {
|
12076
12458
|
this._super();
|
12459
|
+
this.pagecontainer = $( ":mobile-pagecontainer" );
|
12077
12460
|
if ( this.options.position === "fixed" && !this.options.supportBlacklist() ) {
|
12078
12461
|
this._makeFixed();
|
12079
12462
|
}
|
@@ -12085,7 +12468,6 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
12085
12468
|
this._addTransitionClass();
|
12086
12469
|
this._bindPageEvents();
|
12087
12470
|
this._bindToggleHandlers();
|
12088
|
-
this._setOptions( this.options );
|
12089
12471
|
},
|
12090
12472
|
|
12091
12473
|
_setOptions: function( o ) {
|
@@ -12317,12 +12699,30 @@ $.widget( "mobile.controlgroup", $.extend( {
|
|
12317
12699
|
},
|
12318
12700
|
|
12319
12701
|
_destroy: function() {
|
12320
|
-
var
|
12321
|
-
|
12702
|
+
var pageClasses, toolbarClasses, hasFixed, header, hasFullscreen,
|
12703
|
+
page = this.pagecontainer.pagecontainer( "getActivePage" );
|
12322
12704
|
|
12323
|
-
|
12324
|
-
|
12325
|
-
|
12705
|
+
this._super();
|
12706
|
+
if ( this.options.position === "fixed" ) {
|
12707
|
+
hasFixed = $( "body>.ui-" + this.role + "-fixed" )
|
12708
|
+
.add( page.find( ".ui-" + this.options.role + "-fixed" ) )
|
12709
|
+
.not( this.element ).length > 0;
|
12710
|
+
hasFullscreen = $( "body>.ui-" + this.role + "-fixed" )
|
12711
|
+
.add( page.find( ".ui-" + this.options.role + "-fullscreen" ) )
|
12712
|
+
.not( this.element ).length > 0;
|
12713
|
+
toolbarClasses = "ui-header-fixed ui-footer-fixed ui-header-fullscreen in out" +
|
12714
|
+
" ui-footer-fullscreen fade slidedown slideup ui-fixed-hidden";
|
12715
|
+
this.element.removeClass( toolbarClasses );
|
12716
|
+
if ( !hasFullscreen ) {
|
12717
|
+
pageClasses = "ui-page-" + this.role + "-fullscreen";
|
12718
|
+
}
|
12719
|
+
if ( !hasFixed ) {
|
12720
|
+
header = this.role === "header";
|
12721
|
+
pageClasses += " ui-page-" + this.role + "-fixed";
|
12722
|
+
page.css( "padding-" + ( header ? "top" : "bottom" ), "" );
|
12723
|
+
}
|
12724
|
+
page.removeClass( pageClasses );
|
12725
|
+
}
|
12326
12726
|
}
|
12327
12727
|
|
12328
12728
|
});
|
@@ -12680,7 +13080,6 @@ $.widget( "mobile.panel", {
|
|
12680
13080
|
positionFixed: false
|
12681
13081
|
},
|
12682
13082
|
|
12683
|
-
_panelID: null,
|
12684
13083
|
_closeLink: null,
|
12685
13084
|
_parentPage: null,
|
12686
13085
|
_page: null,
|
@@ -12691,19 +13090,20 @@ $.widget( "mobile.panel", {
|
|
12691
13090
|
|
12692
13091
|
_create: function() {
|
12693
13092
|
var el = this.element,
|
12694
|
-
parentPage = el.closest( ":jqmData(role='page')" );
|
13093
|
+
parentPage = el.closest( ".ui-page, :jqmData(role='page')" );
|
12695
13094
|
|
12696
13095
|
// expose some private props to other methods
|
12697
13096
|
$.extend( this, {
|
12698
|
-
_panelID: el.attr( "id" ),
|
12699
13097
|
_closeLink: el.find( ":jqmData(rel='close')" ),
|
12700
13098
|
_parentPage: ( parentPage.length > 0 ) ? parentPage : false,
|
13099
|
+
_openedPage: null,
|
12701
13100
|
_page: this._getPage,
|
12702
13101
|
_panelInner: this._getPanelInner(),
|
12703
|
-
_wrapper: this._getWrapper,
|
12704
13102
|
_fixedToolbars: this._getFixedToolbars
|
12705
13103
|
});
|
12706
|
-
|
13104
|
+
if ( this.options.display !== "overlay" ){
|
13105
|
+
this._getWrapper();
|
13106
|
+
}
|
12707
13107
|
this._addPanelClasses();
|
12708
13108
|
|
12709
13109
|
// if animating, add the class to do so
|
@@ -12737,7 +13137,7 @@ $.widget( "mobile.panel", {
|
|
12737
13137
|
var self = this,
|
12738
13138
|
target = self._parentPage ? self._parentPage.parent() : self.element.parent();
|
12739
13139
|
|
12740
|
-
self._modal = $( "<div class='" + self.options.classes.modal + "'
|
13140
|
+
self._modal = $( "<div class='" + self.options.classes.modal + "'></div>" )
|
12741
13141
|
.on( "mousedown", function() {
|
12742
13142
|
self.close();
|
12743
13143
|
})
|
@@ -12745,21 +13145,20 @@ $.widget( "mobile.panel", {
|
|
12745
13145
|
},
|
12746
13146
|
|
12747
13147
|
_getPage: function() {
|
12748
|
-
var page = this.
|
13148
|
+
var page = this._openedPage || this._parentPage || $( "." + $.mobile.activePageClass );
|
12749
13149
|
|
12750
13150
|
return page;
|
12751
13151
|
},
|
12752
13152
|
|
12753
13153
|
_getWrapper: function() {
|
12754
13154
|
var wrapper = this._page().find( "." + this.options.classes.pageWrapper );
|
12755
|
-
|
12756
13155
|
if ( wrapper.length === 0 ) {
|
12757
13156
|
wrapper = this._page().children( ".ui-header:not(.ui-header-fixed), .ui-content:not(.ui-popup), .ui-footer:not(.ui-footer-fixed)" )
|
12758
13157
|
.wrapAll( "<div class='" + this.options.classes.pageWrapper + "'></div>" )
|
12759
13158
|
.parent();
|
12760
13159
|
}
|
12761
13160
|
|
12762
|
-
|
13161
|
+
this._wrapper = wrapper;
|
12763
13162
|
},
|
12764
13163
|
|
12765
13164
|
_getFixedToolbars: function() {
|
@@ -12791,14 +13190,6 @@ $.widget( "mobile.panel", {
|
|
12791
13190
|
this.element.addClass( this._getPanelClasses() );
|
12792
13191
|
},
|
12793
13192
|
|
12794
|
-
_handleCloseClickAndEatEvent: function( event ) {
|
12795
|
-
if ( !event.isDefaultPrevented() ) {
|
12796
|
-
event.preventDefault();
|
12797
|
-
this.close();
|
12798
|
-
return false;
|
12799
|
-
}
|
12800
|
-
},
|
12801
|
-
|
12802
13193
|
_handleCloseClick: function( event ) {
|
12803
13194
|
if ( !event.isDefaultPrevented() ) {
|
12804
13195
|
this.close();
|
@@ -12815,7 +13206,7 @@ $.widget( "mobile.panel", {
|
|
12815
13206
|
});
|
12816
13207
|
},
|
12817
13208
|
|
12818
|
-
_positionPanel: function() {
|
13209
|
+
_positionPanel: function( scrollToTop ) {
|
12819
13210
|
var self = this,
|
12820
13211
|
panelInnerHeight = self._panelInner.outerHeight(),
|
12821
13212
|
expand = panelInnerHeight > $.mobile.getScreenHeight();
|
@@ -12825,7 +13216,9 @@ $.widget( "mobile.panel", {
|
|
12825
13216
|
self._unfixPanel();
|
12826
13217
|
$.mobile.resetActivePageHeight( panelInnerHeight );
|
12827
13218
|
}
|
12828
|
-
|
13219
|
+
if ( scrollToTop ) {
|
13220
|
+
this.window[ 0 ].scrollTo( 0, $.mobile.defaultHomeScroll );
|
13221
|
+
}
|
12829
13222
|
} else {
|
12830
13223
|
self._fixPanel();
|
12831
13224
|
}
|
@@ -12869,9 +13262,13 @@ $.widget( "mobile.panel", {
|
|
12869
13262
|
},
|
12870
13263
|
|
12871
13264
|
_handleClick: function( e ) {
|
12872
|
-
|
13265
|
+
var link,
|
13266
|
+
panelId = this.element.attr( "id" );
|
13267
|
+
|
13268
|
+
if ( e.currentTarget.href.split( "#" )[ 1 ] === panelId && panelId !== undefined ) {
|
13269
|
+
|
12873
13270
|
e.preventDefault();
|
12874
|
-
|
13271
|
+
link = $( e.target );
|
12875
13272
|
if ( link.hasClass( "ui-btn" ) ) {
|
12876
13273
|
link.addClass( $.mobile.activeBtnClass );
|
12877
13274
|
this.element.one( "panelopen panelclose", function() {
|
@@ -12879,7 +13276,6 @@ $.widget( "mobile.panel", {
|
|
12879
13276
|
});
|
12880
13277
|
}
|
12881
13278
|
this.toggle();
|
12882
|
-
return false;
|
12883
13279
|
}
|
12884
13280
|
},
|
12885
13281
|
|
@@ -12917,7 +13313,14 @@ $.widget( "mobile.panel", {
|
|
12917
13313
|
self.close();
|
12918
13314
|
}
|
12919
13315
|
});
|
12920
|
-
|
13316
|
+
if ( !this._parentPage && this.options.display !== "overlay" ) {
|
13317
|
+
this._on( this.document, {
|
13318
|
+
"pageshow": function() {
|
13319
|
+
this._openedPage = null;
|
13320
|
+
this._getWrapper();
|
13321
|
+
}
|
13322
|
+
});
|
13323
|
+
}
|
12921
13324
|
// Clean up open panels after page hide
|
12922
13325
|
if ( self._parentPage ) {
|
12923
13326
|
this.document.on( "pagehide", ":jqmData(role='page')", function() {
|
@@ -12945,16 +13348,17 @@ $.widget( "mobile.panel", {
|
|
12945
13348
|
o = self.options,
|
12946
13349
|
|
12947
13350
|
_openPanel = function() {
|
12948
|
-
self.
|
13351
|
+
self._off( self.document , "panelclose" );
|
12949
13352
|
self._page().jqmData( "panel", "open" );
|
12950
13353
|
|
12951
13354
|
if ( $.support.cssTransform3d && !!o.animate && o.display !== "overlay" ) {
|
12952
|
-
self._wrapper
|
13355
|
+
self._wrapper.addClass( o.classes.animate );
|
12953
13356
|
self._fixedToolbars().addClass( o.classes.animate );
|
12954
13357
|
}
|
12955
13358
|
|
12956
13359
|
if ( !immediate && $.support.cssTransform3d && !!o.animate ) {
|
12957
|
-
self.
|
13360
|
+
( self._wrapper || self.element )
|
13361
|
+
.animationComplete( complete, "transition" );
|
12958
13362
|
} else {
|
12959
13363
|
setTimeout( complete, 0 );
|
12960
13364
|
}
|
@@ -12968,13 +13372,13 @@ $.widget( "mobile.panel", {
|
|
12968
13372
|
.removeClass( o.classes.panelClosed )
|
12969
13373
|
.addClass( o.classes.panelOpen );
|
12970
13374
|
|
12971
|
-
self._positionPanel();
|
13375
|
+
self._positionPanel( true );
|
12972
13376
|
|
12973
13377
|
self._pageContentOpenClasses = self._getPosDisplayClasses( o.classes.pageContentPrefix );
|
12974
13378
|
|
12975
13379
|
if ( o.display !== "overlay" ) {
|
12976
13380
|
self._page().parent().addClass( o.classes.pageContainer );
|
12977
|
-
self._wrapper
|
13381
|
+
self._wrapper.addClass( self._pageContentOpenClasses );
|
12978
13382
|
self._fixedToolbars().addClass( self._pageContentOpenClasses );
|
12979
13383
|
}
|
12980
13384
|
|
@@ -12987,21 +13391,28 @@ $.widget( "mobile.panel", {
|
|
12987
13391
|
},
|
12988
13392
|
complete = function() {
|
12989
13393
|
|
13394
|
+
// Bail if the panel was closed before the opening animation has completed
|
13395
|
+
if ( !self._open ) {
|
13396
|
+
return;
|
13397
|
+
}
|
13398
|
+
|
12990
13399
|
if ( o.display !== "overlay" ) {
|
12991
|
-
self._wrapper
|
13400
|
+
self._wrapper.addClass( o.classes.pageContentPrefix + "-open" );
|
12992
13401
|
self._fixedToolbars().addClass( o.classes.pageContentPrefix + "-open" );
|
12993
13402
|
}
|
12994
13403
|
|
12995
13404
|
self._bindFixListener();
|
12996
13405
|
|
12997
13406
|
self._trigger( "open" );
|
13407
|
+
|
13408
|
+
self._openedPage = self._page();
|
12998
13409
|
};
|
12999
13410
|
|
13000
13411
|
self._trigger( "beforeopen" );
|
13001
13412
|
|
13002
13413
|
if ( self._page().jqmData( "panel" ) === "open" ) {
|
13003
|
-
self.
|
13004
|
-
_openPanel
|
13414
|
+
self._on( self.document, {
|
13415
|
+
"panelclose": _openPanel
|
13005
13416
|
});
|
13006
13417
|
} else {
|
13007
13418
|
_openPanel();
|
@@ -13021,18 +13432,21 @@ $.widget( "mobile.panel", {
|
|
13021
13432
|
self.element.removeClass( o.classes.panelOpen );
|
13022
13433
|
|
13023
13434
|
if ( o.display !== "overlay" ) {
|
13024
|
-
self._wrapper
|
13435
|
+
self._wrapper.removeClass( self._pageContentOpenClasses );
|
13025
13436
|
self._fixedToolbars().removeClass( self._pageContentOpenClasses );
|
13026
13437
|
}
|
13027
13438
|
|
13028
13439
|
if ( !immediate && $.support.cssTransform3d && !!o.animate ) {
|
13029
|
-
self.
|
13440
|
+
( self._wrapper || self.element )
|
13441
|
+
.animationComplete( complete, "transition" );
|
13030
13442
|
} else {
|
13031
13443
|
setTimeout( complete, 0 );
|
13032
13444
|
}
|
13033
13445
|
|
13034
13446
|
if ( self._modal ) {
|
13035
|
-
self._modal
|
13447
|
+
self._modal
|
13448
|
+
.removeClass( self._modalOpenClasses )
|
13449
|
+
.height( "" );
|
13036
13450
|
}
|
13037
13451
|
},
|
13038
13452
|
complete = function() {
|
@@ -13044,12 +13458,12 @@ $.widget( "mobile.panel", {
|
|
13044
13458
|
|
13045
13459
|
if ( o.display !== "overlay" ) {
|
13046
13460
|
self._page().parent().removeClass( o.classes.pageContainer );
|
13047
|
-
self._wrapper
|
13461
|
+
self._wrapper.removeClass( o.classes.pageContentPrefix + "-open" );
|
13048
13462
|
self._fixedToolbars().removeClass( o.classes.pageContentPrefix + "-open" );
|
13049
13463
|
}
|
13050
13464
|
|
13051
13465
|
if ( $.support.cssTransform3d && !!o.animate && o.display !== "overlay" ) {
|
13052
|
-
self._wrapper
|
13466
|
+
self._wrapper.removeClass( o.classes.animate );
|
13053
13467
|
self._fixedToolbars().removeClass( o.classes.animate );
|
13054
13468
|
}
|
13055
13469
|
|
@@ -13060,6 +13474,8 @@ $.widget( "mobile.panel", {
|
|
13060
13474
|
self._page().jqmRemoveData( "panel" );
|
13061
13475
|
|
13062
13476
|
self._trigger( "close" );
|
13477
|
+
|
13478
|
+
self._openedPage = null;
|
13063
13479
|
};
|
13064
13480
|
|
13065
13481
|
self._trigger( "beforeclose" );
|
@@ -13084,7 +13500,7 @@ $.widget( "mobile.panel", {
|
|
13084
13500
|
// remove the wrapper if not in use by another panel
|
13085
13501
|
otherPanels = $( "body > :mobile-panel" ).add( $.mobile.activePage.find( ":mobile-panel" ) );
|
13086
13502
|
if ( otherPanels.not( ".ui-panel-display-overlay" ).not( this.element ).length === 0 ) {
|
13087
|
-
this._wrapper
|
13503
|
+
this._wrapper.children().unwrap();
|
13088
13504
|
}
|
13089
13505
|
|
13090
13506
|
if ( this._open ) {
|
@@ -13285,14 +13701,17 @@ $.widget( "mobile.table", $.mobile.table, {
|
|
13285
13701
|
|
13286
13702
|
// create the hide/show toggles
|
13287
13703
|
this.headers.not( "td" ).each( function() {
|
13288
|
-
var
|
13289
|
-
|
13290
|
-
|
13704
|
+
var input, cells,
|
13705
|
+
header = $( this ),
|
13706
|
+
priority = $.mobile.getAttribute( this, "priority" );
|
13291
13707
|
|
13292
13708
|
if ( priority ) {
|
13709
|
+
cells = header.add( header.jqmData( "cells" ) );
|
13293
13710
|
cells.addClass( opts.classes.priorityPrefix + priority );
|
13294
13711
|
|
13295
|
-
|
13712
|
+
// Make sure the (new?) checkbox is associated with its header via .jqmData() and
|
13713
|
+
// that, vice versa, the header is also associated with the checkbox
|
13714
|
+
input = ( keep ? inputs.eq( checkboxIndex++ ) :
|
13296
13715
|
$("<label><input type='checkbox' checked />" +
|
13297
13716
|
( header.children( "abbr" ).first().attr( "title" ) ||
|
13298
13717
|
header.text() ) +
|
@@ -13302,7 +13721,13 @@ $.widget( "mobile.table", $.mobile.table, {
|
|
13302
13721
|
.checkboxradio( {
|
13303
13722
|
theme: opts.columnPopupTheme
|
13304
13723
|
}) )
|
13305
|
-
|
13724
|
+
|
13725
|
+
// Associate the header with the checkbox
|
13726
|
+
.jqmData( "header", header )
|
13727
|
+
.jqmData( "cells", cells );
|
13728
|
+
|
13729
|
+
// Associate the checkbox with the header
|
13730
|
+
header.jqmData( "input", input );
|
13306
13731
|
}
|
13307
13732
|
});
|
13308
13733
|
|
@@ -13319,14 +13744,6 @@ $.widget( "mobile.table", $.mobile.table, {
|
|
13319
13744
|
input.jqmData( "cells" )
|
13320
13745
|
.toggleClass( "ui-table-cell-hidden", !checked )
|
13321
13746
|
.toggleClass( "ui-table-cell-visible", checked );
|
13322
|
-
|
13323
|
-
if ( input[ 0 ].getAttribute( "locked" ) ) {
|
13324
|
-
input.removeAttr( "locked" );
|
13325
|
-
|
13326
|
-
this._unlockCells( input.jqmData( "cells" ) );
|
13327
|
-
} else {
|
13328
|
-
input.attr( "locked", true );
|
13329
|
-
}
|
13330
13747
|
},
|
13331
13748
|
|
13332
13749
|
_unlockCells: function( cells ) {
|
@@ -13376,17 +13793,48 @@ $.widget( "mobile.table", $.mobile.table, {
|
|
13376
13793
|
},
|
13377
13794
|
|
13378
13795
|
_refresh: function( create ) {
|
13796
|
+
var headers, hiddenColumns, index;
|
13797
|
+
|
13798
|
+
// Calling _super() here updates this.headers
|
13379
13799
|
this._super( create );
|
13380
13800
|
|
13381
13801
|
if ( !create && this.options.mode === "columntoggle" ) {
|
13802
|
+
headers = this.headers;
|
13803
|
+
hiddenColumns = [];
|
13804
|
+
|
13805
|
+
// Find the index of the column header associated with each old checkbox among the
|
13806
|
+
// post-refresh headers and, if the header is still there, make sure the corresponding
|
13807
|
+
// column will be hidden if the pre-refresh checkbox indicates that the column is
|
13808
|
+
// hidden by recording its index in the array of hidden columns.
|
13809
|
+
this._menu.find( "input" ).each( function() {
|
13810
|
+
var input = $( this ),
|
13811
|
+
header = input.jqmData( "header" ),
|
13812
|
+
index = headers.index( header[ 0 ] );
|
13813
|
+
|
13814
|
+
if ( index > -1 && !input.prop( "checked" ) ) {
|
13815
|
+
|
13816
|
+
// The column header associated with /this/ checkbox is still present in the
|
13817
|
+
// post-refresh table and the checkbox is not checked, so the column associated
|
13818
|
+
// with this column header is currently hidden. Let's record that.
|
13819
|
+
hiddenColumns.push( index );
|
13820
|
+
}
|
13821
|
+
});
|
13822
|
+
|
13382
13823
|
// columns not being replaced must be cleared from input toggle-locks
|
13383
|
-
this._unlockCells( this.
|
13824
|
+
this._unlockCells( this.element.find( ".ui-table-cell-hidden, " +
|
13825
|
+
".ui-table-cell-visible" ) );
|
13384
13826
|
|
13385
13827
|
// update columntoggles and cells
|
13386
13828
|
this._addToggles( this._menu, create );
|
13387
13829
|
|
13388
|
-
//
|
13389
|
-
|
13830
|
+
// At this point all columns are visible, so uncheck the checkboxes that correspond to
|
13831
|
+
// those columns we've found to be hidden
|
13832
|
+
for ( index = hiddenColumns.length - 1 ; index > -1 ; index-- ) {
|
13833
|
+
headers.eq( hiddenColumns[ index ] ).jqmData( "input" )
|
13834
|
+
.prop( "checked", false )
|
13835
|
+
.checkboxradio( "refresh" )
|
13836
|
+
.trigger( "change" );
|
13837
|
+
}
|
13390
13838
|
}
|
13391
13839
|
},
|
13392
13840
|
|
@@ -13456,10 +13904,10 @@ $.widget( "mobile.table", $.mobile.table, {
|
|
13456
13904
|
var cells = $( this ).jqmData( "cells" ),
|
13457
13905
|
colstart = $.mobile.getAttribute( this, "colstart" ),
|
13458
13906
|
hierarchyClass = cells.not( this ).filter( "thead th" ).length && " ui-table-cell-label-top",
|
13459
|
-
|
13907
|
+
contents = $( this ).clone().contents(),
|
13460
13908
|
iteration, filter;
|
13461
13909
|
|
13462
|
-
if (
|
13910
|
+
if ( contents.length > 0 ) {
|
13463
13911
|
|
13464
13912
|
if ( hierarchyClass ) {
|
13465
13913
|
iteration = parseInt( this.getAttribute( "colspan" ), 10 );
|
@@ -13469,18 +13917,24 @@ $.widget( "mobile.table", $.mobile.table, {
|
|
13469
13917
|
filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
|
13470
13918
|
}
|
13471
13919
|
|
13472
|
-
table._addLabels( cells.filter( filter ),
|
13920
|
+
table._addLabels( cells.filter( filter ),
|
13921
|
+
opts.classes.cellLabels + hierarchyClass, contents );
|
13473
13922
|
} else {
|
13474
|
-
table._addLabels( cells, opts.classes.cellLabels,
|
13923
|
+
table._addLabels( cells, opts.classes.cellLabels, contents );
|
13475
13924
|
}
|
13476
13925
|
|
13477
13926
|
}
|
13478
13927
|
});
|
13479
13928
|
},
|
13480
13929
|
|
13481
|
-
_addLabels: function( cells, label,
|
13930
|
+
_addLabels: function( cells, label, contents ) {
|
13931
|
+
if ( contents.length === 1 && contents[ 0 ].nodeName.toLowerCase() === "abbr" ) {
|
13932
|
+
contents = contents.eq( 0 ).attr( "title" );
|
13933
|
+
}
|
13482
13934
|
// .not fixes #6006
|
13483
|
-
cells
|
13935
|
+
cells
|
13936
|
+
.not( ":has(b." + label + ")" )
|
13937
|
+
.prepend( $( "<b class='" + label + "'></b>" ).append( contents ) );
|
13484
13938
|
}
|
13485
13939
|
});
|
13486
13940
|
|
@@ -13539,7 +13993,9 @@ $.widget( "mobile.filterable", {
|
|
13539
13993
|
}
|
13540
13994
|
|
13541
13995
|
this._timer = this._delay( function() {
|
13542
|
-
this._trigger( "beforefilter", null, { input: search } )
|
13996
|
+
if ( this._trigger( "beforefilter", null, { input: search } ) === false ) {
|
13997
|
+
return false;
|
13998
|
+
}
|
13543
13999
|
|
13544
14000
|
// Change val as lastval for next execution
|
13545
14001
|
search[ 0 ].setAttribute( "data-" + $.mobile.ns + "lastval", val );
|
@@ -13587,7 +14043,8 @@ $.widget( "mobile.filterable", {
|
|
13587
14043
|
// If nothing is hidden, then the decision whether to hide or show the items
|
13588
14044
|
// is based on the "filterReveal" option.
|
13589
14045
|
if ( hide.length === 0 ) {
|
13590
|
-
filterItems[ opts.filterReveal
|
14046
|
+
filterItems[ ( opts.filterReveal && val.length === 0 ) ?
|
14047
|
+
"addClass" : "removeClass" ]( "ui-screen-hidden" );
|
13591
14048
|
} else {
|
13592
14049
|
$( hide ).addClass( "ui-screen-hidden" );
|
13593
14050
|
$( show ).removeClass( "ui-screen-hidden" );
|
@@ -13638,6 +14095,8 @@ $.widget( "mobile.filterable", {
|
|
13638
14095
|
this.document.find( selector );
|
13639
14096
|
|
13640
14097
|
this._on( search, {
|
14098
|
+
keydown: "_onKeyDown",
|
14099
|
+
keypress: "_onKeyPress",
|
13641
14100
|
keyup: "_onKeyUp",
|
13642
14101
|
change: "_onKeyUp",
|
13643
14102
|
input: "_onKeyUp"
|
@@ -13647,6 +14106,21 @@ $.widget( "mobile.filterable", {
|
|
13647
14106
|
this._search = search;
|
13648
14107
|
},
|
13649
14108
|
|
14109
|
+
// Prevent form submission
|
14110
|
+
_onKeyDown: function( event ) {
|
14111
|
+
if ( event.keyCode === $.ui.keyCode.ENTER ) {
|
14112
|
+
event.preventDefault();
|
14113
|
+
this._preventKeyPress = true;
|
14114
|
+
}
|
14115
|
+
},
|
14116
|
+
|
14117
|
+
_onKeyPress: function( event ) {
|
14118
|
+
if ( this._preventKeyPress ) {
|
14119
|
+
event.preventDefault();
|
14120
|
+
this._preventKeyPress = false;
|
14121
|
+
}
|
14122
|
+
},
|
14123
|
+
|
13650
14124
|
_setOptions: function( options ) {
|
13651
14125
|
var refilter = !( ( options.filterReveal === undefined ) &&
|
13652
14126
|
( options.filterCallback === undefined ) &&
|
@@ -13750,7 +14224,9 @@ $.widget( "mobile.filterable", $.mobile.filterable, {
|
|
13750
14224
|
// Also trigger listviewbeforefilter if this widget is also a listview
|
13751
14225
|
this._widget._trigger( "beforefilter", event, data );
|
13752
14226
|
}
|
13753
|
-
|
14227
|
+
|
14228
|
+
// Passing back the response enables calling preventDefault()
|
14229
|
+
return this._super( type, event, data );
|
13754
14230
|
},
|
13755
14231
|
|
13756
14232
|
_setWidget: function( widget ) {
|
@@ -13835,6 +14311,24 @@ $.widget( "mobile.filterable", $.mobile.filterable, {
|
|
13835
14311
|
return ret;
|
13836
14312
|
},
|
13837
14313
|
|
14314
|
+
// The listview implementation accompanying this filterable backcompat layer will call
|
14315
|
+
// filterable.refresh() after it's done refreshing the listview to make sure the filterable
|
14316
|
+
// filters out any new items added. However, when the listview refresh has been initiated by
|
14317
|
+
// the filterable itself, then such filtering has already taken place, and calling the
|
14318
|
+
// filterable's refresh() method will cause an infinite recursion. We stop this by setting a
|
14319
|
+
// flag that will cause the filterable's refresh() method to short-circuit.
|
14320
|
+
_refreshChildWidget: function() {
|
14321
|
+
this._refreshingChildWidget = true;
|
14322
|
+
this._superApply( arguments );
|
14323
|
+
this._refreshingChildWidget = false;
|
14324
|
+
},
|
14325
|
+
|
14326
|
+
refresh: function() {
|
14327
|
+
if ( !this._refreshingChildWidget ) {
|
14328
|
+
this._superApply( arguments );
|
14329
|
+
}
|
14330
|
+
},
|
14331
|
+
|
13838
14332
|
_destroy: function() {
|
13839
14333
|
if ( this._isSearchInternal() ) {
|
13840
14334
|
this._search.remove();
|
@@ -13865,6 +14359,38 @@ $.widget( "mobile.filterable", $.mobile.filterable, {
|
|
13865
14359
|
}
|
13866
14360
|
});
|
13867
14361
|
|
14362
|
+
// Instantiate a filterable on a listview that has the data-filter="true" attribute
|
14363
|
+
// This is not necessary for static content, because the auto-enhance takes care of instantiating
|
14364
|
+
// the filterable upon encountering data-filter="true". However, because of 1.3.x it is expected
|
14365
|
+
// that a listview with data-filter="true" will be filterable even if you just instantiate a
|
14366
|
+
// listview on it. The extension below ensures that this continues to happen in 1.4.x.
|
14367
|
+
$.widget( "mobile.listview", $.mobile.listview, {
|
14368
|
+
options: {
|
14369
|
+
filter: false
|
14370
|
+
},
|
14371
|
+
_create: function() {
|
14372
|
+
if ( this.options.filter === true &&
|
14373
|
+
!this.element.data( "mobile-filterable" ) ) {
|
14374
|
+
this.element.filterable();
|
14375
|
+
}
|
14376
|
+
return this._super();
|
14377
|
+
},
|
14378
|
+
|
14379
|
+
refresh: function() {
|
14380
|
+
var filterable;
|
14381
|
+
|
14382
|
+
this._superApply( arguments );
|
14383
|
+
|
14384
|
+
if ( this.options.filter === true ) {
|
14385
|
+
filterable = this.element.data( "mobile-filterable" );
|
14386
|
+
|
14387
|
+
if ( filterable ) {
|
14388
|
+
filterable.refresh();
|
14389
|
+
}
|
14390
|
+
}
|
14391
|
+
}
|
14392
|
+
});
|
14393
|
+
|
13868
14394
|
})( jQuery );
|
13869
14395
|
|
13870
14396
|
/*!
|
@@ -14799,7 +15325,8 @@ $.widget( "ui.tabs", {
|
|
14799
15325
|
var path = $.mobile.path,
|
14800
15326
|
$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
|
14801
15327
|
hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
|
14802
|
-
|
15328
|
+
theLocation = $.mobile.path.parseLocation(),
|
15329
|
+
hashPage = hash ? document.getElementById( hash ) : undefined;
|
14803
15330
|
|
14804
15331
|
// if no pages are found, create one with body's inner html
|
14805
15332
|
if ( !$pages.length ) {
|
@@ -14812,7 +15339,8 @@ $.widget( "ui.tabs", {
|
|
14812
15339
|
|
14813
15340
|
// unless the data url is already set set it to the pathname
|
14814
15341
|
if ( !$this[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) ) {
|
14815
|
-
$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) ||
|
15342
|
+
$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) ||
|
15343
|
+
path.convertUrlToDataUrl( theLocation.pathname + theLocation.search ) );
|
14816
15344
|
}
|
14817
15345
|
});
|
14818
15346
|
|
@@ -14849,11 +15377,6 @@ $.widget( "ui.tabs", {
|
|
14849
15377
|
$.mobile.path.isPath( hash ) ||
|
14850
15378
|
hash === $.mobile.dialogHashKey ) ) ) {
|
14851
15379
|
|
14852
|
-
// Store the initial destination
|
14853
|
-
if ( $.mobile.path.isHashValid( location.hash ) ) {
|
14854
|
-
$.mobile.navigate.history.initialDst = hash.replace( "#", "" );
|
14855
|
-
}
|
14856
|
-
|
14857
15380
|
// make sure to set initial popstate state if it exists
|
14858
15381
|
// so that navigation back to the initial page works properly
|
14859
15382
|
if ( $.event.special.navigate.isPushStateEnabled() ) {
|