mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-04-10 09:21:02 +00:00
- jquery.mobile.core.js no longer creates pages from every page and dialog in the DOM automatically at domready. Instead, pages are created as they are referenced via changePage, which can speed up pageload in multi-page documents, and means local "dialogs" referenced via data-rel="dialog" no longer need a data-role="dialog" attribute when served. - in changePage, "from" is now allowed to be undefined. This simplifies the logic involved in showing the first page, which never had a "from" page, and previously needed a custom pageChange workaround to accommodate that. - The pageshow event is no longer used as a callback for returning false and preventing the $.mobile.activePage from being set to the newly shown page. In other words, a page always becomes $.mobile.activePage once its shown now (the only reason this was optional before was because of a dialog restriction that's no longer true) - the hashchange event logic for showing a particular page is now greatly simplified. It either shows the page referenced in location.hash, or if there's no hash it changes to the first page in the dom. This means every pageshow (including the first one) now uses pageChange internally. - the hashchange event listener is no longer disabled when ajaxEnabled == false. Doing this before prevented local non-ajax page navigation from working properly. To disable hashchange listening, use $.mobile.urlHistory.listeningEnabled. We might consider defining (or moving) this on the $.mobile hash later as well for easier access. - The internal var $.mobile.startPage is now $.mobile.firstPage, because it's not necessarily the page you started on, but merely a reference to the first "page" in the dom. - Back buttons are auto-added to every page after the first one you first visit (this includes generated pages, such as those in a multipage document or nested listviews). Keep in mind that a "back" button does not take the place of a standard "home" link, and when building an app with jQuery Mobile, it's good to make use of both (particularly on deep-linked pages). Fixes #908
209 lines
6.2 KiB
JavaScript
209 lines
6.2 KiB
JavaScript
/*
|
|
* jQuery Mobile Framework : "page" plugin
|
|
* Copyright (c) jQuery Project
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://jquery.org/license
|
|
*/
|
|
(function($, undefined ) {
|
|
|
|
$.widget( "mobile.page", $.mobile.widget, {
|
|
options: {
|
|
backBtnText: "Back",
|
|
addBackBtn: true,
|
|
degradeInputs: {
|
|
color: false,
|
|
date: false,
|
|
datetime: false,
|
|
"datetime-local": false,
|
|
email: false,
|
|
month: false,
|
|
number: false,
|
|
range: "number",
|
|
search: true,
|
|
tel: false,
|
|
time: false,
|
|
url: false,
|
|
week: false
|
|
},
|
|
keepNative: null
|
|
},
|
|
|
|
_create: function() {
|
|
var $elem = this.element,
|
|
o = this.options;
|
|
|
|
this.keepNative = "[data-role='none'], [data-role='nojs']" + (o.keepNative ? ", " + o.keepNative : "");
|
|
|
|
if ( this._trigger( "beforeCreate" ) === false ) {
|
|
return;
|
|
}
|
|
|
|
if( $( "html" ).hasClass( 'portrait' ) ) {
|
|
$elem.css( 'minHeight', ( screen.availHeight >= screen.availWidth ) ? screen.availHeight : screen.availWidth);
|
|
} else {
|
|
$elem.css( 'minHeight', ( screen.availHeight <= screen.availWidth ) ? screen.availHeight : screen.availWidth);
|
|
}
|
|
|
|
//some of the form elements currently rely on the presence of ui-page and ui-content
|
|
// classes so we'll handle page and content roles outside of the main role processing
|
|
// loop below.
|
|
$elem.find( "[data-role='page'], [data-role='content']" ).andSelf().each(function() {
|
|
$(this).addClass( "ui-" + $(this).data( "role" ) );
|
|
});
|
|
|
|
$elem.find( "[data-role='nojs']" ).addClass( "ui-nojs" );
|
|
|
|
// pre-find data els
|
|
var $dataEls = $elem.find( "[data-role]" ).andSelf().each(function() {
|
|
var $this = $( this ),
|
|
role = $this.data( "role" ),
|
|
theme = $this.data( "theme" );
|
|
|
|
//apply theming and markup modifications to page,header,content,footer
|
|
if ( role === "header" || role === "footer" ) {
|
|
$this.addClass( "ui-bar-" + (theme || $this.parent('[data-role=page]').data( "theme" ) || "a") );
|
|
|
|
// add ARIA role
|
|
$this.attr( "role", role === "header" ? "banner" : "contentinfo" );
|
|
|
|
//right,left buttons
|
|
var $headeranchors = $this.children( "a" ),
|
|
leftbtn = $headeranchors.hasClass( "ui-btn-left" ),
|
|
rightbtn = $headeranchors.hasClass( "ui-btn-right" );
|
|
|
|
if ( !leftbtn ) {
|
|
leftbtn = $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;
|
|
}
|
|
|
|
if ( !rightbtn ) {
|
|
rightbtn = $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;
|
|
}
|
|
|
|
// auto-add back btn on pages beyond first view
|
|
if ( o.addBackBtn && role === "header" &&
|
|
$elem.data( "url" ) !== $.mobile.path.stripHash( location.hash ) &&
|
|
!leftbtn && $this.data( "backbtn" ) !== false ) {
|
|
|
|
$( "<a href='#' class='ui-btn-left' data-rel='back' data-icon='arrow-l'>"+ o.backBtnText +"</a>" ).prependTo( $this );
|
|
}
|
|
|
|
//page title
|
|
$this.children( "h1, h2, h3, h4, h5, h6" )
|
|
.addClass( "ui-title" )
|
|
//regardless of h element number in src, it becomes h1 for the enhanced page
|
|
.attr({ "tabindex": "0", "role": "heading", "aria-level": "1" });
|
|
|
|
} else if ( role === "content" ) {
|
|
if ( theme ) {
|
|
$this.addClass( "ui-body-" + theme );
|
|
}
|
|
|
|
// add ARIA role
|
|
$this.attr( "role", "main" );
|
|
|
|
} else if ( role === "page" ) {
|
|
$this.addClass( "ui-body-" + (theme || "c") );
|
|
}
|
|
|
|
switch(role) {
|
|
case "header":
|
|
case "footer":
|
|
case "page":
|
|
case "content":
|
|
$this.addClass( "ui-" + role );
|
|
break;
|
|
case "collapsible":
|
|
case "fieldcontain":
|
|
case "navbar":
|
|
case "listview":
|
|
case "dialog":
|
|
$this[ role ]();
|
|
break;
|
|
}
|
|
});
|
|
|
|
//enhance form controls
|
|
this._enhanceControls();
|
|
|
|
//links in bars, or those with data-role become buttons
|
|
$elem.find( "[data-role='button'], .ui-bar > a, .ui-header > a, .ui-footer > a" )
|
|
.not( ".ui-btn" )
|
|
.not(this.keepNative)
|
|
.buttonMarkup();
|
|
|
|
$elem
|
|
.find("[data-role='controlgroup']")
|
|
.controlgroup();
|
|
|
|
//links within content areas
|
|
$elem.find( "a:not(.ui-btn):not(.ui-link-inherit)" )
|
|
.not(this.keepNative)
|
|
.addClass( "ui-link" );
|
|
|
|
//fix toolbars
|
|
$elem.fixHeaderFooter();
|
|
},
|
|
|
|
_enhanceControls: function() {
|
|
var o = this.options;
|
|
|
|
// degrade inputs to avoid poorly implemented native functionality
|
|
this.element.find( "input" ).not(this.keepNative).each(function() {
|
|
var type = this.getAttribute( "type" ),
|
|
optType = o.degradeInputs[ type ] || "text";
|
|
|
|
if ( o.degradeInputs[ type ] ) {
|
|
$( this ).replaceWith(
|
|
$( "<div>" ).html( $(this).clone() ).html()
|
|
.replace( /type="([a-zA-Z]+)"/, "type="+ optType +" data-type='$1'" ) );
|
|
}
|
|
});
|
|
|
|
// We re-find form elements since the degredation code above
|
|
// may have injected new elements. We cache the non-native control
|
|
// query to reduce the number of times we search through the entire page.
|
|
|
|
var allControls = this.element.find("input, textarea, select, button"),
|
|
nonNativeControls = allControls.not(this.keepNative);
|
|
|
|
// XXX: Temporary workaround for issue 785. Turn off autocorrect and
|
|
// autocomplete since the popup they use can't be dismissed by
|
|
// the user. Note that we test for the presence of the feature
|
|
// by looking for the autocorrect property on the input element.
|
|
|
|
var textInputs = allControls.filter( "input[type=text]" );
|
|
if (textInputs.length && typeof textInputs[0].autocorrect !== "undefined") {
|
|
textInputs.each(function(){
|
|
// Set the attribute instead of the property just in case there
|
|
// is code that attempts to make modifications via HTML.
|
|
this.setAttribute("autocorrect", "off");
|
|
this.setAttribute("autocomplete", "off");
|
|
});
|
|
}
|
|
|
|
// enchance form controls
|
|
nonNativeControls
|
|
.filter( "[type='radio'], [type='checkbox']" )
|
|
.checkboxradio();
|
|
|
|
nonNativeControls
|
|
.filter( "button, [type='button'], [type='submit'], [type='reset'], [type='image']" )
|
|
.button();
|
|
|
|
nonNativeControls
|
|
.filter( "input, textarea" )
|
|
.not( "[type='radio'], [type='checkbox'], [type='button'], [type='submit'], [type='reset'], [type='image'], [type='hidden']" )
|
|
.textinput();
|
|
|
|
nonNativeControls
|
|
.filter( "input, select" )
|
|
.filter( "[data-role='slider'], [data-type='range']" )
|
|
.slider();
|
|
|
|
nonNativeControls
|
|
.filter( "select:not([data-role='slider'])" )
|
|
.selectmenu();
|
|
}
|
|
});
|
|
|
|
})( jQuery );
|