@@ -231,7 +231,7 @@ <h2>Preventing auto-initialization of form elements</h2>

<p>If you'd like to prevent auto-initialization without adding attributes to your markup, you can customize the selector that is used for preventing auto-initialization by setting the page plugin's <code>keepNative</code> option (which defaults to <code>[data-role="none"]</code>). Be sure to configure this option inside an event handler bound to the <code>mobileinit</code> event, so that it applies to the first page as well as subsequent pages that are loaded.</p>
<pre><code>
$(document).bind('mobileinit',function(){
$(document).on('mobileinit',function(){
<strong>$.mobile.page.prototype.options.keepNative = "select, input.foo, textarea.bar";</strong>
});
</code></pre>
@@ -38,7 +38,7 @@ <h2>Radio buttons</h2>

<p>Bind events directly to the <code>input</code> element. Use jQuery Mobile's <a href="../../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$("input[type='radio']").bind( "change", function(event, ui) {
$("input[type='radio']").on( "change", function(event, ui) {
...
});
</code></pre>
@@ -37,7 +37,7 @@ <h2>Search input</h2>

<p>Bind events directly to the <code>input</code> element. Use jQuery Mobile's <a href="../../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$(".mySearchInput").bind( "change", function(event, ui) {
$(".mySearchInput").on( "change", function(event, ui) {
...
});
</code></pre>
@@ -56,7 +56,7 @@ <h2>Search input</h2>
<dd>
<p class="default">default: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input:not([type])"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as textinputs. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.textinput.prototype.options.initSelector = ".myInputs";</strong>
});
</code></pre>
@@ -45,7 +45,7 @@ <h2>Custom select menus</h2>

<code>
<pre>
$(document).bind('mobileinit',function(){
$(document).on('mobileinit',function(){
$.mobile.selectmenu.prototype.options.nativeMenu = false;
});
</pre>
@@ -38,7 +38,7 @@ <h2>Select menus</h2>

<p>Bind events directly to the <code>select</code> element. Use jQuery Mobile's <a href="../../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$(".mySelect").bind( "change", function(event, ui) {
$(".mySelect").on( "change", function(event, ui) {
...
});
</code></pre>
@@ -50,7 +50,7 @@ <h2>Select menus</h2>
<dd>
<p class="default">default: "b"</p>
<p>Sets the color scheme (swatch) for dividers in popup-based custom select menus when using the <code>optgroup</code> support. It accepts a single letter from a-z that maps to the swatches included in your theme. To set the value for all instances of this widget, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.dividerTheme = "a";</strong>
});
</code></pre>
@@ -85,7 +85,7 @@ <h2>Select menus</h2>
<dd>
<p class="default">default: "select:not(:jqmData(role='slider'))"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as select menus. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.selectmenu.prototype.options.initSelector = ".myselect";</strong>
});
</code></pre>
@@ -37,7 +37,7 @@ <h2>Slider</h2>

<p>Bind events directly to the <code>input</code> element. Use jQuery Mobile's <a href="../../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$( ".selector" ).bind( "change", function(event, ui) {
$( ".selector" ).on( "change", function(event, ui) {
...
});
</code></pre>
@@ -56,7 +56,7 @@ <h2>Slider</h2>
<dd>
<p class="default">default: "input[type='range'], :jqmData(type='range'), :jqmData(role='slider')"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as sliders. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.slider.prototype.options.initSelector = ".myslider";</strong>
});
</code></pre>
@@ -37,7 +37,7 @@ <h2>Flip toggle switch</h2>

<p>Bind events directly to the <code>select</code> element. Use jQuery Mobile's <a href="../../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$( ".selector" ).bind( "change", function(event, ui) {
$( ".selector" ).on( "change", function(event, ui) {
...
});
</code></pre>
@@ -49,7 +49,7 @@ <h2>Flip toggle switch</h2>
<dd>
<p class="default">default: "input[type='range'], :jqmData(type='range'), :jqmData(role='slider')"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as sliders. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.slider.prototype.options.initSelector = ".myslider";</strong>
});
</code></pre>
@@ -37,7 +37,7 @@ <h2>Text inputs</h2>

<p>Bind events directly to the <code>input</code> element. Use jQuery Mobile's <a href="../../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$( ".selector" ).bind( "change", function(event, ui) {
$( ".selector" ).on( "change", function(event, ui) {
...
});
</code></pre>
@@ -49,7 +49,7 @@ <h2>Text inputs</h2>
<dd>
<p class="default">default: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='file'], input:not([type])"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as textinputs. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.textinput.prototype.options.initSelector = ".myInputs";</strong>
});
</code></pre>
@@ -35,7 +35,7 @@ <h2>Listviews</h2>

<p>Bind events directly to the <code>ol</code> or <code>ul</code> element. Use jQuery Mobile's <a href="../api/events.html">virtual events</a>, or bind standard JavaScript events, like change, focus, blur, etc.:</p>
<pre><code>
$( ".selector" ).bind( "change", function(event, ui) {
$( ".selector" ).on( "change", function(event, ui) {
...
});
</code></pre>
@@ -40,7 +40,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "c"</p>
<p>Sets the color scheme (swatch) for list item <a href="lists-count.html">count bubbles</a>. It accepts a single letter from a-z that maps to one of the swatches included in your theme. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.countTheme = "a";</strong>
});
</code></pre>
@@ -51,7 +51,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "b"</p>
<p>Sets the color scheme (swatch) for list <a href="lists-divider.html">dividers</a>. It accepts a single letter from a-z that maps to one of the swatches included in your theme. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.dividerTheme = "a";</strong>
});
</code></pre>
@@ -62,7 +62,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: false</p>
<p>Adds a <a href="lists-search.html">search filter bar</a> to listviews. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.filter = true;</strong>
});
</code></pre>
@@ -72,7 +72,7 @@ <h2>Listviews</h2>
<dt><code>filterCallback</code> <em>function</em></dt>
<dd>
<p>The function to determine which rows to hide when the <a href="lists-search.html">search filter</a> textbox changes. The function accepts two arguments -- the text of the list item (or <code>data-filtertext</code> value if present), and the search string. Return <code>true</code> to hide the item, <code>false</code> to leave it visible. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.filterCallback = function( text, searchValue ) {
// only show items that *begin* with the search string
return text.toLowerCase().substring( 0, searchValue.length ) !== searchValue;
@@ -85,7 +85,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "Filter items..."</p>
<p>The placeholder text used in <a href="lists-search.html">search filter bars</a>. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.filterPlaceholder = "Search...";</strong>
});
</code></pre>
@@ -96,7 +96,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "c"</p>
<p>Sets the color scheme (swatch) for the <a href="lists-search.html">search filter bar</a>. It accepts a single letter from a-z that maps to one of the swatches included in your theme. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.filterTheme = "a";</strong>
});
</code></pre>
@@ -107,7 +107,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "b"</p>
<p>Sets the color scheme (swatch) for headers of <a href="lists-nested.html">nested list</a> sub pages. It accepts a single letter from a-z that maps to one of the swatches included in your theme. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.headerTheme = "a";</strong>
});
</code></pre>
@@ -118,7 +118,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "arrow-r"</p>
<p>Applies an icon from the <a href="../buttons/buttons-icons.html">icon set</a> to all <a href="lists-ul.html">linked list buttons</a>. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.icon = "star";</strong>
});
</code></pre>
@@ -129,7 +129,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: ":jqmData(role='listview')"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as listviews. To change which elements are initialized, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.initSelector = ".mylistview";</strong>
});
</code></pre>
@@ -139,7 +139,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: false</p>
<p>Adds <a href="lists-inset.html">inset list</a> styles. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.inset = true;</strong>
});
</code></pre>
@@ -150,7 +150,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "arrow-r"</p>
<p>Applies an icon from the <a href="../buttons/buttons-icons.html">icon set</a> to all <a href="lists-split.html">split list buttons</a>. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.splitIcon = "star";</strong>
});
</code></pre>
@@ -161,7 +161,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: "b"</p>
<p>Sets the color scheme (swatch) for <a href="lists-split.html">split list buttons</a>. It accepts a single letter from a-z that maps to one of the swatches included in your theme. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.splitTheme = "a";</strong>
});
</code></pre>
@@ -172,7 +172,7 @@ <h2>Listviews</h2>
<dd>
<p class="default">default: null, inherited from parent</p>
<p>Sets the color scheme (swatch) for this widget. It accepts a single letter from a-z that maps to one of the swatches included in your theme. By default, it will inherit the same swatch color as its parent container if not explicitly set. To set the value for all instances of this widget, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.listview.prototype.options.theme = "a";</strong>
});
</code></pre>
@@ -1014,9 +1014,9 @@
// Depending on whether we're using pushState or hashes, and whether
// 'onhashchange' is supported, determine how we check the URL state.
if (this._hasPushState) {
$(window).bind('popstate', this.checkUrl);
$(window).on('popstate', this.checkUrl);
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
$(window).bind('hashchange', this.checkUrl);
$(window).on('hashchange', this.checkUrl);
} else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
}
@@ -2686,7 +2686,7 @@ jQuery.event = {
}

// Handle multiple events separated by a space
// jQuery(...).bind("mouseover mouseout", fn);
// jQuery(...).on("mouseover mouseout", fn);
types = jQuery.trim( hoverHack(types) ).split( " " );
for ( t = 0; t < types.length; t++ ) {

@@ -1447,7 +1447,7 @@ function getSpecialEventObject( eventType ) {
// for elements unless they actually have handlers registered on them.
// To get around this, we register dummy handlers on the elements.

$( this ).bind( realType, dummyMouseHandler );
$( this ).on( realType, dummyMouseHandler );

// For now, if event capture is not supported, we rely on mouse handlers.
if ( eventCaptureSupported ) {
@@ -1716,7 +1716,7 @@ if ( eventCaptureSupported ) {

$this.bind( "vmouseup", clearTapTimer )
.bind( "vclick", clickHandler );
$( document ).bind( "vmousecancel", clearTapHandlers );
$( document ).on( "vmousecancel", clearTapHandlers );

timer = setTimeout( function() {
triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
@@ -1796,7 +1796,7 @@ if ( eventCaptureSupported ) {

$.event.special[ event ] = {
setup: function() {
$( this ).bind( sourceEvent, $.noop );
$( this ).on( sourceEvent, $.noop );
}
};
});
@@ -1814,7 +1814,7 @@ if ( eventCaptureSupported ) {
(function( $ ) {
$.event.special.throttledresize = {
setup: function() {
$( this ).bind( "resize", handler );
$( this ).on( "resize", handler );
},
teardown: function() {
$( this ).unbind( "resize", handler );
@@ -2386,7 +2386,7 @@ $.widget( "mobile.page", $.mobile.widget, {
//
// handler - (Function) Optional handler to be bound to the hashchange
// event. This is a "shortcut" for the more verbose form:
// jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
// jQuery(window).on( 'hashchange', handler ). If handler is omitted,
// all bound window.onhashchange event handlers will be triggered. This
// is a shortcut for the more verbose
// jQuery(window).trigger( 'hashchange' ). These forms are described in
@@ -2466,7 +2466,7 @@ $.widget( "mobile.page", $.mobile.widget, {
// A more verbose usage that allows for event namespacing:
//
// > // Bind an event handler.
// > jQuery(window).bind( 'hashchange', function(e) {
// > jQuery(window).on( 'hashchange', function(e) {
// > var hash = location.hash;
// > ...
// > });
@@ -4111,7 +4111,7 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau
});

//add active state on vclick
$( document ).bind( "vclick", function( event ) {
$( document ).on( "vclick", function( event ) {
// if this isn't a left click we don't care. Its important to note
// that when the virtual event is generated it will create the which attr
if ( event.which > 1 || !$.mobile.linkBindingEnabled ) {
@@ -4137,7 +4137,7 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau
});

// click routing - direct to HTTP or Ajax, accordingly
$( document ).bind( "click", function( event ) {
$( document ).on( "click", function( event ) {
if ( !$.mobile.linkBindingEnabled ) {
return;
}
@@ -4355,8 +4355,8 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau
});

//set page min-heights to be device specific
$( document ).bind( "pageshow", resetActivePageHeight );
$( window ).bind( "throttledresize", resetActivePageHeight );
$( document ).on( "pageshow", resetActivePageHeight );
$( window ).on( "throttledresize", resetActivePageHeight );

});//navreadyDeferred done callback

@@ -4609,7 +4609,7 @@ $.mobile.page.prototype.options.degradeInputs = {


//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {

var page = $.mobile.closestPageData( $( e.target ) ), options;

@@ -4754,7 +4754,7 @@ $.mobile.page.prototype.options.contentTheme = null;
// which expects .ui-footer top be applied in its gigantic selector
// TODO remove the buttonMarkup giant selector and move it to the various modules
// on which it depends
$( document ).bind( "pagecreate", function( e ) {
$( document ).on( "pagecreate", function( e ) {
var $page = $( e.target ),
o = $page.data( "page" ).options,
pageRole = $page.jqmData( "role" ),
@@ -4844,7 +4844,7 @@ $.fn.fieldcontain = function( options ) {
};

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$( ":jqmData(role='fieldcontain')", e.target ).jqmEnhanceable().fieldcontain();
});

@@ -4900,7 +4900,7 @@ $.fn.grid = function( options ) {

(function( $, undefined ) {

$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$( ":jqmData(role='nojs')", e.target ).addClass( "ui-nojs" );

});
@@ -5092,7 +5092,7 @@ function closestEnabledButton( element ) {
var attachEvents = function() {
var hoverDelay = $.mobile.buttonMarkup.hoverDelay, hov, foc;

$( document ).bind( {
$( document ).on( {
"vmousedown vmousecancel vmouseup vmouseover vmouseout focus blur scrollstart": function( event ) {
var theme,
$btn = $( closestEnabledButton( event.target ) ),
@@ -5146,7 +5146,7 @@ var attachEvents = function() {

//links in bars, or those with data-role become buttons
//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {

$( ":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a, .ui-bar > :jqmData(role='controlgroup') > a", e.target )
.jqmEnhanceable()
@@ -5314,7 +5314,7 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.collapsible.prototype.enhanceWithin( e.target );
});

@@ -5421,7 +5421,7 @@ $.widget( "mobile.collapsibleset", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.collapsibleset.prototype.enhanceWithin( e.target );
});

@@ -5464,14 +5464,14 @@ $.widget( "mobile.navbar", $.mobile.widget, {
});

// Buttons in the navbar with ui-state-persist class should regain their active state before page show
$navbar.closest( ".ui-page" ).bind( "pagebeforeshow", function() {
$navbar.closest( ".ui-page" ).on( "pagebeforeshow", function() {
$navbtns.filter( ".ui-state-persist" ).addClass( $.mobile.activeBtnClass );
});
}
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.navbar.prototype.enhanceWithin( e.target );
});

@@ -5908,7 +5908,7 @@ $.widget( "mobile.listview", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.listview.prototype.enhanceWithin( e.target );
});

@@ -6166,7 +6166,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.checkboxradio.prototype.enhanceWithin( e.target, true );
});

@@ -6311,7 +6311,7 @@ $.widget( "mobile.button", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.button.prototype.enhanceWithin( e.target, true );
});

@@ -6378,7 +6378,7 @@ $.fn.controlgroup = function( options ) {

(function( $, undefined ) {

$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {

//links within content areas, tests included with page
$( e.target )
@@ -7188,14 +7188,14 @@ $( document ).bind( "pagecreate create", function( e ) {
};

// TODO move inside _create
$( document ).bind( "pagebeforechange", function( e, data ) {
$( document ).on( "pagebeforechange", function( e, data ) {
if ( data.options.role === "popup" ) {
$.mobile.popup.handleLink( data.options.link );
e.preventDefault();
}
});

$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.popup.prototype.enhanceWithin( e.target, true );
});

@@ -7393,7 +7393,7 @@ $.widget( "mobile.textinput", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.textinput.prototype.enhanceWithin( e.target, true );
});

@@ -7953,7 +7953,7 @@ $.widget( "mobile.slider", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.slider.prototype.enhanceWithin( e.target, true );
});

@@ -8130,7 +8130,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
if ( self.options.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
}).bind( "mouseup", function() {
}).on( "mouseup", function() {
if ( self.options.preventFocusZoom ) {
setTimeout(function() {
$.mobile.zoom.enable( true );
@@ -8204,7 +8204,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$.mobile.selectmenu.prototype.enhanceWithin( e.target, true );
});
})( jQuery );
@@ -8702,7 +8702,7 @@ $( document ).bind( "pagecreate create", function( e ) {
};

// issue #3894 - core doesn't trigger events on disabled delegates
$( document ).bind( "selectmenubeforecreate", function( event ) {
$( document ).on( "selectmenubeforecreate", function( event ) {
var selectmenuWidget = $( event.target ).data( "selectmenu" );

if ( !selectmenuWidget.options.nativeMenu &&
@@ -8838,7 +8838,7 @@ $( document ).bind( "pagecreate create", function( e ) {
var thisPage = this;
self.updatePagePadding( thisPage );
if ( o.updatePagePadding ) {
$( window ).bind( "throttledresize." + self.widgetName, function() {
$( window ).on( "throttledresize." + self.widgetName, function() {
self.updatePagePadding( thisPage );
});
}
@@ -9128,7 +9128,7 @@ $( document ).bind( "pagecreate create", function( e ) {
// TODO: Implement a proper registration mechanism with dependency handling in order to not have exceptions like the one below
//auto self-init widgets for those widgets that have a soft dependency on others
if ( $.fn.controlgroup ) {
$( document ).bind( "pagecreate create", function( e ) {
$( document ).on( "pagecreate create", function( e ) {
$( ":jqmData(role='controlgroup')", e.target )
.jqmEnhanceable()
.controlgroup({ excludeInvisible: false });
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile Framework - Dialog Example</title>
<link rel="stylesheet" href="../../css/themes/default/jquery.mobile.css" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>

<script src="../../js/jquery.js"></script>
<script src="../../docs/_assets/js/jqm-docs.js"></script>
<script src="../../js/"></script>

</head>
<body>

<div data-role="page" data-corners="false">
<div data-role="header">
<h1>Dialog</h1>
</div>

<div data-role="content">
<h1>No rounded corners</h1>
<p>This is a regular page, styled as a dialog. To create a dialog, just link to a normal page and include a transition and <code>data-rel="dialog"</code> attribute.</p>
<a href="docs-dialogs.html" data-role="button" data-rel="back" data-theme="b">Ok, I get it</a>
</div>
</div>


</body>
</html>
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile Framework - Dialog Example</title>
<link rel="stylesheet" href="../../css/themes/default/jquery.mobile.css" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>

<script src="../../js/jquery.js"></script>
<script src="../../docs/_assets/js/jqm-docs.js"></script>
<script src="../../js/"></script>

</head>
<body>

<div data-role="page" data-close-btn="none">
<div data-role="header">
<h1>Dialog</h1>
</div>

<div data-role="content">
<h1>No close button</h1>
<p>This is a regular page, styled as a dialog. To create a dialog, just link to a normal page and include a transition and <code>data-rel="dialog"</code> attribute.</p>
<a href="docs-dialogs.html" data-role="button" data-rel="back" data-theme="b">Ok, I get it</a>
</div>
</div>


</body>
</html>
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile Framework - Dialog Example</title>
<link rel="stylesheet" href="../../css/themes/default/jquery.mobile.css" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>

<script src="../../js/jquery.js"></script>
<script src="../../docs/_assets/js/jqm-docs.js"></script>
<script src="../../js/"></script>

</head>
<body>

<div data-role="page" data-close-btn="right">
<div data-role="header">
<h1>Dialog</h1>
</div>

<div data-role="content">
<h1>Right close button</h1>
<p>This is a regular page, styled as a dialog. To create a dialog, just link to a normal page and include a transition and <code>data-rel="dialog"</code> attribute.</p>
<a href="docs-dialogs.html" data-role="button" data-rel="back" data-theme="b">Ok, I get it</a>
</div>
</div>


</body>
</html>
@@ -43,7 +43,7 @@ <h2>Dialog</h2>
<dd>

<pre><code>
$( ".selector" ).bind({
$( ".selector" ).on({
create: function(event, ui) { ... }
});
</code></pre>
@@ -35,7 +35,7 @@ <h2>Dialog</h2>
<li><a href="events.html" data-role="button" data-transition="fade">Events</a></li>
</ul>

<p>Any page can be presented as a modal dialog by adding the <code>data-rel="dialog"</code> attribute to the page anchor link. When the "dialog" attribute is applied, the framework adds styles to add rounded corners, margins around the page and a dark background to make the "dialog" appear to be suspended above the page. If the dialog has a header the framework will also add a close button at the left side of the header.</p>
<p>Any page can be presented as a modal dialog by adding the <code>data-rel="dialog"</code> attribute to the page anchor link. When the "dialog" attribute is applied, the framework adds styles to add rounded corners, margins around the page and a dark background to make the "dialog" appear to be suspended above the page. By default the framework will also add a close button if the dialog has a header.</p>

<p>
<code>
@@ -63,6 +63,11 @@ <h2>Transitions</h2>

<h2>Closing dialogs</h2>
<p>When any link is clicked within a dialog, the framework will automatically close the dialog and transition to the requested page, just as if the dialog were a normal page. Nevertheless, dialogs can also be chained, as explained below under <strong>"Chaining Dialogs"</strong>. Similarly, a link that opens a popup will also leave the dialog in place.</p>

<p>If the dialog has a header the framework will add a close button at the left side of the header. You can change the position by adding <code>data-close-btn="right"</code> to the dialog container. If you don't want a close button in the header or add a custom close button, you can use <code>data-close-btn="none"</code>.</p>
<a href="../dialog-rightclosebtn.html" data-role="button" data-inline="true" data-rel="dialog" data-transition="pop">Right close button</a>
<a href="../dialog-noclosebtn.html" data-role="button" data-inline="true" data-rel="dialog" data-transition="pop">No close button</a>

<p>To create a "cancel" button in a dialog, just link to the page that triggered the dialog to open and add the <code>data-rel="back"</code> attribute to your link. This pattern of linking to the previous page is also usable in non-JS devices as well.</p>
<p>For JavaScript-generated links, you can simply set the href attribute to "#" and use the <code>data-rel="back"</code> attribute. You can also call the dialog's <code>close()</code> method to programmatically close dialogs, for example: <code>$('.ui-dialog').dialog('close')</code>. </p>

@@ -82,6 +87,9 @@ <h2>Styling &amp; theming</h2>
<p>Dialogs can be styled with different theme swatches, just like any page by adding <code>data-theme</code> attributes to the header, content, or footer containers. Here is an example of a different dialog design:</p>
<a href="../dialog-alt.html" data-role="button" data-inline="true" data-rel="dialog" data-transition="pop">An alternate color scheme</a>

<p>By default dialogs have rounded corners. The option <code>corners</code> can be set to <code>false</code> by adding <code>data-corners="false"</code> to the dialog container:</p>
<a href="../dialog-corners.html" data-role="button" data-inline="true" data-rel="dialog" data-transition="pop">No rounded corners</a>

<p>Dialogs appear to be floating above an overlay layer. This overlay adopts the swatch "a" content color by default, but the <code>data-overlay-theme</code> attribute can be added to the page wrapper to set the overlay to any swatch letter. Here is an example of a dialog with the overlay set to swatch "e":</p>
<a href="../dialog-overlay.html" data-role="button" data-inline="true" data-rel="dialog" data-transition="pop">Custom overlay swatch</a>

@@ -40,6 +40,15 @@ <h2>Dialog</h2>

<dl>

<dt><code>closeBtn</code> <em>string</em></dt>
<dd>
<p class="default">default: "left"</p>
<p>Sets the position of the dialog close button in the header (left or right) or prevents the framework from adding a close button (none).</p>
<p>This option is also exposed as a data attribute: <code>data-close-btn</code>.</p>

<pre><code>$( ".selector" ).dialog(<strong>{ closeBtn: "none" }</strong>);</code></pre>
</dd>

<dt><code>closeBtnText</code> <em>string</em></dt>
<dd>
<p class="default">default: "Close"</p>
@@ -49,11 +58,20 @@ <h2>Dialog</h2>
<pre><code>$( ".selector" ).dialog(<strong>{ closeBtnText: "Fermer" }</strong>);</code></pre>
</dd>

<dt><code>corners</code> <em>boolean</em></dt>
<dd>
<p class="default">default: true</p>
<p>Sets whether to draw the dialo with rounded corners.</p>
<p>This option is also exposed as a data attribute: <code>data-corners="false"</code>.</p>

<pre><code>$( ".selector" ).dialog(<strong>{ corners: false }</strong>);</code></pre>
</dd>

<dt><code>initSelector</code> <em>CSS selector string</em></dt>
<dd>
<p class="default">default: ":jqmData(role='dialog')"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as dialogs. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.dialog.prototype.options.initSelector = ".mydialog";</strong>
});
</code></pre>
@@ -77,7 +77,7 @@


// Listen for any attempts to call changePage().
$(document).bind( "pagebeforechange", function( e, data ) {
$(document).on( "pagebeforechange", function( e, data ) {
// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
if ( typeof data.toPage === "string" ) {
@@ -150,7 +150,7 @@


// Listen for any attempts to call changePage().
$(document).bind( "pagebeforechange", function( e, data ) {
$(document).on( "pagebeforechange", function( e, data ) {
// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
if ( typeof data.toPage === "string" ) {
@@ -55,7 +55,7 @@ <h2>The Page Loading Widget</h2>

<pre>
<code>
$( document ).bind( 'mobileinit', function(){
$( document ).on( 'mobileinit', function(){
$.mobile.loader.prototype.options.text = "loading";
$.mobile.loader.prototype.options.textVisible = false;
$.mobile.loader.prototype.options.theme = "a";
@@ -127,7 +127,7 @@ <h2>jQuery Mobile and Dynamic Page Generation</h2>
<pre>
<code>
// Listen for any attempts to call changePage().
$(document).bind( &quot;pagebeforechange&quot;, function( e, data ) {
$(document).on( &quot;pagebeforechange&quot;, function( e, data ) {

// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
@@ -50,7 +50,7 @@ <h2>$.mobile.allowCrossDomainPages</h2>

<p>So in PhoneGap apps that must "phone home" by loading assets off a remote server, both the <code>$.support.cors</code> AND <code>$.mobile.allowCrossDomainPages</code> must be set to <code>true</code>. The <code>$.mobile.allowCrossDomainPages</code> option must be set before any cross-domain request is made so we recommend wrapping this in a <code>mobileinit</code> handler:</p>

<pre><code>$( document ).bind( "mobileinit", function() {
<pre><code>$( document ).on( "mobileinit", function() {
// Make your jQuery Mobile framework configuration changes here!

$.mobile.allowCrossDomainPages = true;
@@ -44,7 +44,7 @@ <h2>Popup</h2>
<dd>

<pre><code>
$( ".selector" ).bind({
$( ".selector" ).on({
popupbeforeposition: function(event, ui) { ... }
});
</code></pre>
@@ -55,7 +55,7 @@ <h2>Popup</h2>
<dd>

<pre><code>
$( ".selector" ).bind({
$( ".selector" ).on({
popupafteropen: function(event, ui) { ... }
});
</code></pre>
@@ -66,7 +66,7 @@ <h2>Popup</h2>
<dd>

<pre><code>
$( ".selector" ).bind({
$( ".selector" ).on({
popupafterclose: function(event, ui) { ... }
});
</code></pre>
@@ -174,7 +174,7 @@ <h2>Opening popups</h2>
</code></pre>

<h2>Closing popups</h2>
<p>By default popups can be closed either by clicking outside the popup widget or by pressing the <code>Esc</code> key. To prevent this, the <code>data-dismissable="false"</code> attribute can be added to the popup. Popups can also be closed via the <code>close</code> method:</p>
<p>By default popups can be closed either by clicking outside the popup widget or by pressing the <code>Esc</code> key. To prevent this, the <code>data-dismissible="false"</code> attribute can be added to the popup. Popups can also be closed via the <code>close</code> method:</p>

<pre><code>
$( "#myPopupDiv" ).popup( "close" )
@@ -192,7 +192,7 @@ <h2>Closing popups</h2>

<a href="#popupCloseRight" data-rel="popup" data-role="button" data-inline="true">Popup with close button right</a>
<a href="#popupCloseLeft" data-rel="popup" data-role="button" data-inline="true">Popup with close button left</a>
<a href="#popupUndismissable" data-rel="popup" data-role="button" data-inline="true">Undismissable Popup</a>
<a href="#popupUndismissible" data-rel="popup" data-role="button" data-inline="true">Undismissible Popup</a>

<div data-role="popup" id="popupCloseRight" class="ui-content" style="max-width:280px">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
@@ -204,9 +204,9 @@ <h2>Closing popups</h2>
<p>I have a close button at the top left corner with simple HTML markup.</p>
</div>

<div data-role="popup" id="popupUndismissable" class="ui-content" style="max-width:280px" data-dismissable="false">
<div data-role="popup" id="popupUndismissible" class="ui-content" style="max-width:280px" data-dismissible="false">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-left">Close</a>
<p>I have the <code>data-dismissable</code> attribute set to <code>false</code>. I'm not closeable by clicking outside of me.</p>
<p>I have the <code>data-dismissible</code> attribute set to <code>false</code>. I'm not closeable by clicking outside of me.</p>
</div>

<h2>Adding padding</h2>
@@ -47,12 +47,12 @@ <h2>Popup</h2>
<pre><code>$( ".selector" ).popup(<strong>{ corners: false }</strong>);</code></pre>
</dd>

<dt><code>dismissable</code> <em>boolean</em></dt>
<dt><code>dismissible</code> <em>boolean</em></dt>
<dd>
<p class="default">default: true</p>
<p>Sets whether clicking outside the popup or pressing Escape while the popup is open will close the popup. This option is also exposed as a data attribute: <code>data-dismissable=&quot;false&quot;</code></p>
<p>Sets whether clicking outside the popup or pressing Escape while the popup is open will close the popup. This option is also exposed as a data attribute: <code>data-dismissible=&quot;false&quot;</code></p>
<p><em>Note:</em> When history support is turned on, pressing the browser's "Back" button will dismiss the popup even if this option is set to false.
<pre><code>$( ".selector" ).popup(<strong>{ dismissable: false }</strong>);</code></pre>
<pre><code>$( ".selector" ).popup(<strong>{ dismissible: false }</strong>);</code></pre>
</dd>

<dt><code>history</code> <em>boolean</em></dt>
@@ -66,7 +66,7 @@ <h2>Popup</h2>
<dd>
<p class="default">default: ":jqmData(role='popup')"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as popups. To change which elements are initialized, bind this option to the <a href="../../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.popup.prototype.options.initSelector = ".mypopup";</strong>
});
</code></pre>
@@ -44,7 +44,7 @@ <h2>How it works</h2>
<p>A feature called <code>touchOverflowEnabled</code> is designed to leverage the upcoming wave of browsers that support overflow scrolling in CSS. Note that this feature is off by default to give us more time to test and debug this for best performance but we hope to turn it on by default at a later point. Here's how to enable this <a href="../api/globalconfig.html">global option</a>:</p>

<pre><code>&lt;script&gt;
$(document).bind(&quot;mobileinit&quot;, function(){
$(document).on(&quot;mobileinit&quot;, function(){
<strong> $.mobile.touchOverflowEnabled = true;
</strong>});
&lt;/script&gt;</code></pre>
@@ -79,7 +79,7 @@ <h2>Debugging touchOverflow</h2>
<p>Generally touchOverflow is only enabled on devices that support touch-scrolling of overflow areas, not desktop browsers. This can make it difficult to debug problems with the touchOverflow feature. To enable touchOverflow on all browsers, use the following code:

<pre><code>&lt;script&gt;
$(document).bind(&quot;mobileinit&quot;, function() {
$(document).on(&quot;mobileinit&quot;, function() {
<strong>$.support.touchOverflow = true;</strong>
$.mobile.touchOverflowEnabled = true;
});
@@ -117,7 +117,7 @@ <h2>Fixed toolbars</h2>
<p class="default">default: function that returns a boolean value</p>
<p>CSS <code>position: fixed</code> support is very difficult to test; in fact, at the time of version 1.1 release, there was no known way to reasonably test for fixed support without turning up false positives or negatives in certain popular browsers. This option is a function that attempts to opt-out some popular platforms that are known to be troublesome with <code>position: fixed</code> . Often, these platforms support <code>position: fixed</code> partially, which can be worse than not supporting it at all. If overriding this option with your own blacklist logic, you simply need to provide a function that returns a true or false result when called upon initialization. You must set it on mobileinit, so that it applies when the plugin is initially created.</p>
<pre><code>
$( document ).bind("mobileinit", function(){
$( document ).on("mobileinit", function(){
$.mobile.fixedtoolbar.prototype.options.supportBlacklist = function(){
var result;
// logic to determine whether result should be true or false
@@ -131,7 +131,7 @@ <h2>Fixed toolbars</h2>
<dd>
<p class="default">default: ":jqmData(position='fixed')"</p>
<p>This is used to define the selectors (element types, data roles, etc.) that will automatically be initialized as fixed toolbars. To change which elements are initialized, bind this option to the <a href="../api/globalconfig.html">mobileinit event</a>:</p>
<pre><code>$( document ).bind( "mobileinit", function(){
<pre><code>$( document ).on( "mobileinit", function(){
<strong>$.mobile.fixedtoolbar.prototype.options.initSelector = ".myselector";</strong>
});
</code></pre>
@@ -133,33 +133,49 @@ define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch"

verticalDistanceThreshold: 75, // Swipe vertical displacement must be less than this.

start: function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;
return {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ],
origin: $( event.target )
};
},

stop: function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;
return {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ]
};
},

handleSwipe: function( start, stop ) {
if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {

start.origin.trigger( "swipe" )
.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
}
},

setup: function() {
var thisObject = this,
$this = $( thisObject );

$this.bind( touchStartEvent, function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event,
start = {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ],
origin: $( event.target )
},
var start = $.event.special.swipe.start( event ),
stop;

function moveHandler( event ) {

if ( !start ) {
return;
}

var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;

stop = {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ]
};
stop = $.event.special.swipe.stop( event );

// prevent scrolling
if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
@@ -168,17 +184,11 @@ define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch"
}

$this.bind( touchMoveEvent, moveHandler )
.one( touchStopEvent, function( event ) {
.one( touchStopEvent, function() {
$this.unbind( touchMoveEvent, moveHandler );

if ( start && stop ) {
if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {

start.origin.trigger( "swipe" )
.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
}
$.event.special.swipe.handleSwipe( start, stop );
}
start = stop = undefined;
});

Large diffs are not rendered by default.

@@ -1264,22 +1264,19 @@ define( [
//the following deferred is resolved in the init file
$.mobile.navreadyDeferred = $.Deferred();
$.mobile._registerInternalEvents = function() {
//bind to form submit events, handle with Ajax
$( document ).delegate( "form", "submit", function( event ) {
var $this = $( this );

var getAjaxFormData = function( $form, calculateOnly ) {
var type, target, url, ret = true;
if ( !$.mobile.ajaxEnabled ||
// test that the form is, itself, ajax false
$this.is( ":jqmData(ajax='false')" ) ||
$form.is( ":jqmData(ajax='false')" ) ||
// test that $.mobile.ignoreContentEnabled is set and
// the form or one of it's parents is ajax=false
!$this.jqmHijackable().length ) {
return;
!$form.jqmHijackable().length ) {
return false;
}

var type = $this.attr( "method" ),
target = $this.attr( "target" ),
url = $this.attr( "action" );
target = $form.attr( "target" );
url = $form.attr( "action" );

// If no action is specified, browsers default to using the
// URL of the document containing the form. Since we dynamically
@@ -1288,7 +1285,7 @@ define( [
// the form.
if ( !url ) {
// Get the @data-url for the page containing the form.
url = getClosestBaseUrl( $this );
url = getClosestBaseUrl( $form );
if ( url === documentBase.hrefNoHash ) {
// The url we got back matches the document base,
// which means the page must be an internal/embedded page,
@@ -1298,49 +1295,99 @@ define( [
}
}

url = path.makeUrlAbsolute( url, getClosestBaseUrl( $this ) );
url = path.makeUrlAbsolute( url, getClosestBaseUrl( $form ) );

if ( ( path.isExternal( url ) && !path.isPermittedCrossDomainRequest( documentUrl, url ) ) || target ) {
return;
return false;
}

$.mobile.changePage(
url,
{
type: type && type.length && type.toLowerCase() || "get",
data: $this.serialize(),
transition: $this.jqmData( "transition" ),
reverse: $this.jqmData( "direction" ) === "reverse",
reloadPage: true
}
);
event.preventDefault();
if ( !calculateOnly ) {
type = $form.attr( "method" );
ret = {
url: url,
options: {
type: type && type.length && type.toLowerCase() || "get",
data: $form.serialize(),
transition: $form.jqmData( "transition" ),
reverse: $form.jqmData( "direction" ) === "reverse",
reloadPage: true
}
};
}

return ret;
};

//bind to form submit events, handle with Ajax
$( document ).delegate( "form", "submit", function( event ) {
var formData = getAjaxFormData( $( this ) );

if ( formData ) {
$.mobile.changePage( formData.url, formData.options );
event.preventDefault();
}
});

//add active state on vclick
$( document ).bind( "vclick", function( event ) {
var $btn, btnEls, target = event.target, needClosest = false;
// if this isn't a left click we don't care. Its important to note
// that when the virtual event is generated it will create the which attr
if ( event.which > 1 || !$.mobile.linkBindingEnabled ) {
return;
}

var link = findClosestLink( event.target ), $btn;
// Try to find a target element to which the active class will be applied
if ( $.data( target, "mobile-button" ) ) {
// If the form will not be submitted via AJAX, do not add active class
if ( !getAjaxFormData( $( target ).closest( "form" ), true ) ) {
return;
}
// We will apply the active state to this button widget - the parent
// of the input that was clicked will have the associated data
if ( target.parentNode ) {
target = target.parentNode;
}
} else {
target = findClosestLink( target );
if ( !( target && path.parseUrl( target.getAttribute( "href" ) || "#" ).hash !== "#" ) ) {
return;
}

// split from the previous return logic to avoid find closest where possible
// TODO teach $.mobile.hijackable to operate on raw dom elements so the link wrapping
// can be avoided
if ( !$( link ).jqmHijackable().length ) {
return;
// TODO teach $.mobile.hijackable to operate on raw dom elements so the
// link wrapping can be avoided
if ( !$( target ).jqmHijackable().length ) {
return;
}
}

if ( link ) {
$btn = $( link ).closest( ".ui-btn" ).not( ".ui-disabled" );
if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" && !$btn.hasClass( $.mobile.activeBtnClass ) ) {
removeActiveLinkClass( true );
$activeClickedLink = $btn;
$activeClickedLink.addClass( $.mobile.activeBtnClass );
// Avoid calling .closest by using the data set during .buttonMarkup()
// List items have the button data in the parent of the element clicked
if ( !!~target.className.indexOf( "ui-link-inherit" ) ) {
if ( target.parentNode ) {
btnEls = $.data( target.parentNode, "buttonElements" );
}
// Otherwise, look for the data on the target itself
} else {
btnEls = $.data( target, "buttonElements" );
}
// If found, grab the button's outer element
if ( btnEls ) {
target = btnEls.outer;
} else {
needClosest = true;
}

$btn = $( target );
// If the outer element wasn't found by the our heuristics, use .closest()
if ( needClosest ) {
$btn = $btn.closest( ".ui-btn" );
}

if ( $btn.length > 0 && !( $btn.hasClass( $.mobile.activeBtnClass ) || $btn.hasClass( "ui-disabled" ) ) ) {
removeActiveLinkClass( true );
$activeClickedLink = $btn;
$activeClickedLink.addClass( $.mobile.activeBtnClass );
}
});

@@ -15,6 +15,9 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
collapseCueText: " click to collapse contents",
collapsed: true,
heading: "h1,h2,h3,h4,h5,h6,legend",
collapsedIcon: "plus",
expandedIcon: "minus",
iconpos: "left",
theme: null,
contentTheme: null,
inset: true,
@@ -28,8 +31,6 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
o = this.options,
collapsible = $el.addClass( "ui-collapsible" ),
collapsibleHeading = $el.children( o.heading ).first(),
collapsedIcon = $el.jqmData( "collapsed-icon" ) || o.collapsedIcon,
expandedIcon = $el.jqmData( "expanded-icon" ) || o.expandedIcon,
collapsibleContent = collapsible.wrapInner( "<div class='ui-collapsible-content'></div>" ).children( ".ui-collapsible-content" ),
collapsibleSet = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" ),
collapsibleClasses = "";
@@ -51,18 +52,15 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
o.contentTheme = collapsibleSet.jqmData( "content-theme" );
}

// Get the preference for collapsed icon in the set
if ( !o.collapsedIcon ) {
o.collapsedIcon = collapsibleSet.jqmData( "collapsed-icon" );
}
// Get the preference for expanded icon in the set
if ( !o.expandedIcon ) {
o.expandedIcon = collapsibleSet.jqmData( "expanded-icon" );
}
// Gets the preference icon position in the set
if ( !o.iconpos ) {
o.iconpos = collapsibleSet.jqmData( "iconpos" );
}
// Get the preference for collapsed icon in the set, but override with data- attribute on the individual collapsible
o.collapsedIcon = $el.jqmData( "collapsed-icon" ) || collapsibleSet.jqmData( "collapsed-icon" ) || o.collapsedIcon;

// Get the preference for expanded icon in the set, but override with data- attribute on the individual collapsible
o.expandedIcon = $el.jqmData( "expanded-icon" ) || collapsibleSet.jqmData( "expanded-icon" ) || o.expandedIcon;

// Gets the preference icon position in the set, but override with data- attribute on the individual collapsible
o.iconpos = $el.jqmData( "iconpos" ) || collapsibleSet.jqmData( "iconpos" ) || o.iconpos;

// Inherit the preference for inset from collapsible-set or set the default value to ensure equalty within a set
if ( collapsibleSet.jqmData( "inset" ) !== undefined ) {
o.inset = collapsibleSet.jqmData( "inset" );
@@ -96,9 +94,6 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
collapsible.addClass( collapsibleClasses );
}

collapsedIcon = $el.jqmData( "collapsed-icon" ) || o.collapsedIcon || "plus";
expandedIcon = $el.jqmData( "expanded-icon" ) || o.expandedIcon || "minus";

collapsibleHeading
//drop heading in before content
.insertBefore( collapsibleContent )
@@ -111,8 +106,8 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
.buttonMarkup({
shadow: false,
corners: false,
iconpos: $el.jqmData( "iconpos" ) || o.iconpos || "left",
icon: collapsedIcon,
iconpos: o.iconpos,
icon: o.collapsedIcon,
mini: o.mini,
theme: o.theme
});
@@ -132,9 +127,9 @@ $.widget( "mobile.collapsible", $.mobile.widget, {
.text( isCollapse ? o.expandCueText : o.collapseCueText )
.end()
.find( ".ui-icon" )
.toggleClass( "ui-icon-" + expandedIcon, !isCollapse )
.toggleClass( "ui-icon-" + o.expandedIcon, !isCollapse )
// logic or cause same icon for expanded/collapsed state would remove the ui-icon-class
.toggleClass( "ui-icon-" + collapsedIcon, ( isCollapse || expandedIcon === collapsedIcon ) )
.toggleClass( "ui-icon-" + o.collapsedIcon, ( isCollapse || o.expandedIcon === o.collapsedIcon ) )
.end()
.find( "a" ).first().removeClass( $.mobile.activeBtnClass );

@@ -25,7 +25,11 @@ $.widget( "mobile.collapsibleset", $.mobile.widget, {
if ( !o.contentTheme ) {
o.contentTheme = $el.jqmData( "content-theme" );
}

// Inherit the corner styling from collapsible-set
if ( !o.corners ) {
o.corners = $el.jqmData( "corners" );
}

if ( $el.jqmData( "inset" ) !== undefined ) {
o.inset = $el.jqmData( "inset" );
}
@@ -101,7 +101,6 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
self._getInputSet().not( input ).prop( "checked", false );

self._updateAll();
return false;
}
});

@@ -473,7 +473,7 @@ define( [
if ( o.hidePlaceholderMenuItems ) {
classes.push( "ui-selectmenu-placeholder" );
}
if (!placeholder) {
if ( placeholder !== text ) {
placeholder = self.placeholder = text;
}
}
@@ -188,15 +188,32 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
// In many situations, iOS will zoom into the select upon tap, this prevents that from happening
self.button.bind( "vmousedown", function() {
if ( self.options.preventFocusZoom ) {
$.mobile.zoom.disable( true );
$.mobile.zoom.disable( true );
}
}).bind( "mouseup", function() {
});
self.label.bind( "click focus", function() {
if ( self.options.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
});
self.select.bind( "focus", function() {
if ( self.options.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
});
self.button.bind( "mouseup", function() {
if ( self.options.preventFocusZoom ) {
setTimeout(function() {
$.mobile.zoom.enable( true );
}, 0);
}, 0 );
}
});
self.select.bind( "blur", function() {
if ( self.options.preventFocusZoom ) {
$.mobile.zoom.enable( true );
}
});

},

selected: function() {
@@ -35,7 +35,8 @@ $.widget( "mobile.textinput", $.mobile.widget, {
clearbtn,
clearBtnText = o.clearSearchButtonText || o.clearBtnText,
clearBtnBlacklist = input.is( "textarea, :jqmData(type='range')" ),
inputNeedsClearBtn = !!o.clearBtn && !clearBtnBlacklist;
inputNeedsClearBtn = !!o.clearBtn && !clearBtnBlacklist,
inputNeedsWrap = input.is( "input" ) && !input.is( ":jqmData(type='range')" );

function toggleClear() {
setTimeout( function() {
@@ -64,7 +65,7 @@ $.widget( "mobile.textinput", $.mobile.widget, {
//"search" and "text" input widgets
if ( isSearch ) {
focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield" + themeclass + miniclass + "'></div>" ).parent();
} else if ( inputNeedsClearBtn ) {
} else if ( inputNeedsWrap ) {
focusedEl = input.wrap( "<div class='ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow" + themeclass + miniclass + "'></div>" ).parent();
}

@@ -89,29 +90,25 @@ $.widget( "mobile.textinput", $.mobile.widget, {

toggleClear();

input.bind( "paste cut keyup focus change blur", toggleClear );
input.bind( "paste cut keyup input focus change blur", toggleClear );
}
else if ( !inputNeedsClearBtn && !isSearch ) {
else if ( !inputNeedsWrap && !isSearch ) {
input.addClass( "ui-corner-all ui-shadow-inset" + themeclass + miniclass );
}

input.focus(function() {
// In many situations, iOS will zoom into the input upon tap, this prevents that from happening
if ( o.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
focusedEl.addClass( $.mobile.focusClass );
})
.blur(function() {
focusedEl.removeClass( $.mobile.focusClass );
})
// In many situations, iOS will zoom into the select upon tap, this prevents that from happening
.bind( "focus", function() {
if ( o.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
})
.bind( "blur", function() {
if ( o.preventFocusZoom ) {
$.mobile.zoom.enable( true );
}
});
}
})

// Autogrow
if ( input.is( "textarea" ) ) {
@@ -124,11 +121,11 @@ $.widget( "mobile.textinput", $.mobile.widget, {
clientHeight = input[ 0 ].clientHeight;

if ( clientHeight < scrollHeight ) {
input.height(scrollHeight + extraLineHeight);
input.height( scrollHeight + extraLineHeight );
}
};

input.keyup(function() {
input.on( "keyup change input paste", function() {
clearTimeout( keyupTimeout );
keyupTimeout = setTimeout( self._keyup, keyupTimeoutBuffer );
});
@@ -151,7 +148,10 @@ $.widget( "mobile.textinput", $.mobile.widget, {

disable: function() {
var $el,
parentNeedsDisabled = this.element.attr( "disabled", true ) && ( this.element.is( "[type='search'], :jqmData(type='search')" ) || ( this.element.is( "[type='text'],textarea" ) && !!this.options.clearBtn ) );
isSearch = this.element.is( "[type='search'], :jqmData(type='search')" ),
inputNeedsWrap = this.element.is( "input" ) && !this.element.is( ":jqmData(type='range')" ),
parentNeedsDisabled = this.element.attr( "disabled", true ) && ( inputNeedsWrap || isSearch );

if ( parentNeedsDisabled ) {
$el = this.element.parent();
} else {
@@ -163,9 +163,10 @@ $.widget( "mobile.textinput", $.mobile.widget, {

enable: function() {
var $el,
parentNeedsDisabled = this.element.attr( "disabled", true ) && ( this.element.is( "[type='search'], :jqmData(type='search')" ) || ( this.element.is( "[type='text'],textarea" ) && !!this.options.clearBtn ) );
isSearch = this.element.is( "[type='search'], :jqmData(type='search')" ),
inputNeedsWrap = this.element.is( "input" ) && !this.element.is( ":jqmData(type='range')" ),
parentNeedsDisabled = this.element.attr( "disabled", true ) && ( inputNeedsWrap || isSearch );

// TODO using more than one line of code is acceptable ;)
if ( parentNeedsDisabled ) {
$el = this.element.parent();
} else {
@@ -44,7 +44,7 @@ $( document ).delegate( "ul, ol", "listviewcreate", function() {
})
.attr( "data-" + $.mobile.ns + "type", "search" )
.jqmData( "lastval", "" )
.bind( "keyup change", function() {
.bind( "keyup change input", function() {

var $this = $( this ),
val = this.value.toLowerCase(),
@@ -5,6 +5,12 @@
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css
//>>css.structure: ../css/structure/jquery.mobile.popup.css,../css/structure/jquery.mobile.transition.css,../css/structure/jquery.mobile.transition.fade.css

// Lessons:
// You must remove nav bindings even if there is no history. Make sure you
// remove nav bindings in the same frame as the beginning of the close process
// if there is no history. If there is history, remove nav bindings from the nav
// bindings handler - that way, only one of them can fire per close process.

define( [ "jquery",
"../jquery.mobile.widget",
"../jquery.mobile.support",
@@ -52,7 +58,7 @@ define( [ "jquery",
closeLinkEvents: "click.popup",
navigateEvents: "navigate.popup",
closeEvents: "navigate.popup pagebeforechange.popup",
dismissable: true,
dismissible: true,

// NOTE Windows Phone 7 has a scroll position caching issue that
// requires us to disable popup history management by default
@@ -65,7 +71,7 @@ define( [ "jquery",
_eatEventAndClose: function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
if ( this.options.dismissable ) {
if ( this.options.dismissible ) {
this.close();
}
return false;
@@ -203,6 +209,7 @@ define( [ "jquery",

// Define instance variables
$.extend( this, {
_scrollTop: 0,
_page: thisPage,
_ui: ui,
_fallbackTransition: "",
@@ -299,7 +306,7 @@ define( [ "jquery",
_setTolerance: function( value ) {
var tol = { t: 30, r: 15, b: 30, l: 15 };

if ( value ) {
if ( value !== undefined ) {
var ar = String( value ).split( "," );

$.each( ar, function( idx, val ) { ar[ idx ] = parseInt( val, 10 ); } );
@@ -533,7 +540,8 @@ define( [ "jquery",
},

_open: function( options ) {
var coords, transition,
var coords,
o = $.extend( {}, this.options, options ),
androidBlacklist = ( function() {
var w = window,
ua = navigator.userAgent,
@@ -551,16 +559,10 @@ define( [ "jquery",
return false;
}());

// Make sure options is defined
options = ( options || {} );

// Copy out the transition, because we may be overwriting it later and we don't want to pass that change back to the caller
transition = options.transition || this.options.transition;

// Give applications a chance to modify the contents of the container before it appears
this._trigger( "beforeposition" );

coords = this._placementCoords( this._desiredCoords( options.x, options.y, options.positionTo || this.options.positionTo || "origin" ) );
coords = this._placementCoords( this._desiredCoords( o.x, o.y, o.positionTo ) );

// Count down to triggering "popupafteropen" - we have two prerequisites:
// 1. The popup window animation completes (container())
@@ -570,12 +572,8 @@ define( [ "jquery",
$.noop,
$.proxy( this, "_openPrereqsComplete" ) );

if ( transition ) {
this._currentTransition = transition;
this._applyTransition( transition );
} else {
transition = this.options.transition;
}
this._currentTransition = o.transition;
this._applyTransition( o.transition );

if ( !this.options.theme ) {
this._setTheme( this._page.jqmData( "theme" ) || $.mobile.getInheritedTheme( this._page, "c" ) );
@@ -606,7 +604,7 @@ define( [ "jquery",
}
this._animate({
additionalCondition: true,
transition: transition,
transition: o.transition,
classToRemove: "",
screenClassToAdd: "in",
containerClassToAdd: "in",
@@ -633,12 +631,6 @@ define( [ "jquery",

this._ui.container.removeAttr( "tabindex" );

// remove nav bindings if they are still present
opts.container.unbind( opts.closeEvents );

// unbind click handlers added when history is disabled
this.element.undelegate( opts.closeLinkSelector, opts.closeLinkEvents );

// remove the global mutex for popups
$.mobile.popup.active = undefined;

@@ -662,7 +654,7 @@ define( [ "jquery",

this._animate( {
additionalCondition: this._ui.screen.hasClass( "in" ),
transition: ( immediate ? "none" : ( this._currentTransition || this.options.transition ) ),
transition: ( immediate ? "none" : ( this._currentTransition ) ),
classToRemove: "in",
screenClassToAdd: "out",
containerClassToAdd: "reverse out",
@@ -699,9 +691,18 @@ define( [ "jquery",
},

_closePopup: function( e, data ) {
var parsedDst, toUrl;
var parsedDst, toUrl, o = this.options;

// restore location on screen
window.scrollTo( 0, this._scrollTop );

// remove nav bindings
o.container.unbind( o.closeEvents );

if ( e.type === "pagebeforechange" && data ) {
// unbind click handlers added when history is disabled
this.element.undelegate( o.closeLinkSelector, o.closeLinkEvents );

if ( e && e.type === "pagebeforechange" && data ) {
// Determine whether we need to rapid-close the popup, or whether we can
// take the time to run the closing transition
if ( typeof data.toPage === "string" ) {
@@ -714,10 +715,10 @@ define( [ "jquery",

if ( this._myUrl !== toUrl ) {
// Going to a different page - close immediately
this.options.container.unbind( this.options.closeEvents );
this._close( true );
} else {
this._close();
this.close();
e.preventDefault();
}

return;
@@ -746,6 +747,7 @@ define( [ "jquery",

// set the global popup mutex
$.mobile.popup.active = this;
this._scrollTop = $( window ).scrollTop();

// if history alteration is disabled close on navigate events
// and leave the url as is
@@ -758,7 +760,7 @@ define( [ "jquery",
// relying on history to do it for us
self.element
.delegate( opts.closeLinkSelector, opts.closeLinkEvents, function( e ) {
self._close();
self.close();

// NOTE prevent the browser and navigation handlers from
// working with the link's rel=back. This may cause
@@ -812,10 +814,13 @@ define( [ "jquery",
return;
}

this._scrollTop = $( window ).scrollTop();

if( this.options.history ) {
$.mobile.back();
} else {
this._close();
// simulate the nav bindings having fired
this._closePopup();
}
}
});
@@ -836,8 +841,7 @@ define( [ "jquery",
x: offset.left + $link.outerWidth() / 2,
y: offset.top + $link.outerHeight() / 2,
transition: $link.jqmData( "transition" ),
positionTo: $link.jqmData( "position-to" ),
link: $link
positionTo: $link.jqmData( "position-to" )
});
}

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"></meta>
</head>
<body>
<div data-nstest-role="page" id="another-page">
<div data-nstest-role="popup" id="back-twice-test-popup">
<p>Back twice test popup</p>
</div>
<a id="open-back-twice-test-popup" href="#back-twice-test-popup" data-nstest-rel="popup">Pop</a>
</div>
</body>
</html>
@@ -14,6 +14,16 @@
<link rel="stylesheet" href="../../../css/themes/default/jquery.mobile.css"/>
<link rel="stylesheet" href="../../../external/qunit.css"/>
<script src="../../../external/qunit.js"></script>
<script>
( function( $, undefined ) {
// Set the default transition to "fade" if specified in the query
if ( !!~location.search.indexOf( "setFadeTransition" ) ) {
$( document ).one( "mobileinit", function() {
$.mobile.popup.prototype.options.transition = "fade";
});
}
})( jQuery );
</script>
<script>
$.testHelper.asyncLoad([
[
@@ -33,7 +43,7 @@
<body>
<div id="qunit"></div>

<div data-nstest-role="page">
<div data-nstest-role="page" id="start-page">
<div data-nstest-role="content" id="page-content">
<div data-nstest-role="popup" id="test-popup">
<p>This is the test popup</p>
@@ -63,9 +73,10 @@
<p>This is the test popup</p>
</div>

<div data-nstest-role="popup" id="test-popup-dismissable" data-nstest-dismissable="false">
<div data-nstest-role="popup" id="test-popup-dismissible" data-nstest-dismissible="false">
<p>This is the test popup</p>
</div>
<a id="go-to-another-page" href="back-two.html">Go</a>
</div>
</div>

@@ -78,6 +78,52 @@
ok( $container.children().is( $payload ), "After destroying on-the-fly popup, its payload is returned to its original location" );
});

asyncTest( "Popup does not go back in history twice when opening on separate page", function() {
var eventNs = ".backTwice", popup = function() { return $( "#back-twice-test-popup" ); };
$.testHelper.detailedEventCascade([
function() {
$( "#go-to-another-page" ).click();
},
{
navigate: { src: $( document ), event: "navigate" + eventNs + "1" },
pagechange: { src: $.mobile.pageContainer, event: "pagechange" + eventNs + "1" }
},
function() {
deepEqual( $.mobile.activePage.attr( "id" ), "another-page", "Reached another page" );
$( "#open-back-twice-test-popup" ).click();
},
{
popupafteropen: { src: popup, event: "popupafteropen" + eventNs + "2" },
navigate: { src: $(document), event: "navigate" + eventNs + "2" }
},
function( result ) {
deepEqual( result.popupafteropen.timedOut, false, "popupafteropen event did arrive" );
deepEqual( result.navigate.timedOut, false, "navigate event did arrive" );
$( "#back-twice-test-popup-screen" ).click();
},
{
popupafterclose: { src: popup, event: "popupafterclose" + eventNs + "3" },
navigate: { src: $( document ), event: "navigate" + eventNs + "3" },
pagechange: { src: $( document ), event: "pagechange" + eventNs + "3" }
},
function( result ) {
deepEqual( result.popupafterclose.timedOut, false, "popupafterclose event did arrive" );
deepEqual( result.navigate.timedOut, false, "navigate event did arrived" );
deepEqual( result.pagechange.timedOut, false, "pagechange event did arrive" );
deepEqual( $.mobile.activePage.attr( "id" ), "another-page", "Back to another page" );
$.mobile.back();
},
{
navigate: { src: $( document ), event: "navigate" + eventNs + "4" }
},
function( result ) {
deepEqual( result.navigate.timedOut, false, "navigate event did arrive" );
deepEqual( $.mobile.activePage.attr( "id" ), "start-page", "Back to start page" );
start();
}
]);
});

asyncTest( "Popup opens and closes", function() {
var $popup = $( "#test-popup" );
expect( 9 );
@@ -475,8 +521,8 @@
]);
});

asyncTest( "Cannot close a non-dismissable popup by clicking on the screen", function() {
var $popup = $( "#test-popup-dismissable" ), eventNs = ".cannotCloseNonDismissablePopup";
asyncTest( "Cannot close a non-dismissible popup by clicking on the screen", function() {
var $popup = $( "#test-popup-dismissible" ), eventNs = ".cannotCloseNonDismissiblePopup";

$.testHelper.detailedEventCascade([
function() {
@@ -424,6 +424,14 @@ <h2 id="qunit-userAgent"></h2>
<option value="overnight">Overnight</option>
</select>

<select name="test-placeholder-update" id="test-placeholder-update" data-nstest-native-menu="false">
<option>Placeholder</option>
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>

<select name="select-default-option-text" id="select-default-option-text">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
@@ -515,4 +515,11 @@
]);
});

test( "changing the placeholder text for a non-native select will update the placeholder list item", function() {
var newText = "Updated placeholder";
$( "#test-placeholder-update option:first-child" ).text( newText );
$( "#test-placeholder-update" ).selectmenu( "refresh", true );
deepEqual ( $( "#test-placeholder-update-menu li:first-child .ui-btn-text" ).text(), newText, "Placeholder list item reflects new value after refresh( true )" );
});

})(jQuery);
@@ -12,8 +12,10 @@
<script src="../../../tests/jquery.testHelper.js"></script>
<script>
$.testHelper.asyncLoad([
[ "settings.js" ],
[
"widgets/forms/slider"
"widgets/forms/slider",
"widgets/forms/textinput"
],
[
"slider_events.js",
@@ -107,10 +109,16 @@ <h2 id="qunit-userAgent"></h2>
<input type="range" name="slider" id="mouseup-refresh" value="25" min="0" max="100"/>
</div>

<div data-role="fieldcontain">
<label for="remove-events-slider">Input slider:</label>
<input type="range" name="remove-events-slider" id="remove-events-slider" value="25" min="0" max="100"/>
</div>
<div data-role="fieldcontain">
<label for="remove-events-slider">Input slider:</label>
<input type="range" name="remove-events-slider" id="remove-events-slider" value="25" min="0" max="100"/>
</div>

<div data-role="fieldcontain" class="textinput-test">
<label for="textinput-test">Input slider:</label>
<input type="range" data-clear-btn="true" name="slider" id="textinput-test" value="25" min="0" max="100"/>
</div>

</div>

<div id="enhancetest">
@@ -0,0 +1,3 @@
$( document ).bind( "mobileinit", function() {
$.mobile.textinput.prototype.options.clearBtn = true;
});
@@ -3,7 +3,7 @@
*/
(function($){
$.mobile.page.prototype.options.keepNative = "input.should-be-native";

module( "jquery.mobile.slider.js core" );

// not testing the positive case here since's it's obviously tested elsewhere
@@ -58,6 +58,15 @@
equal(label.attr( "id" ), slider.attr( "id" ) + "-label", "the label id is based off the slider id" );
});

// NOTE init binding to alter the setting is in settings.js
test( "slider input does not get clear button", function() {
deepEqual( $( ".textinput-test" ).find( ".ui-input-clear" ).length, 0, "slider input does not get clear button" );
});

test( "slider input is not wrapped in div.ui-input-text", function() {
ok( ! $( "#textinput-test" ).parents().is( "div.ui-input-text" ), "slider input is not wrapped in div.ui-input-text" );
});

test( "refresh is triggered on mouseup", function() {
expect( 1 );
var slider = $( "#mouseup-refresh" );