mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-03-17 06:20:26 +00:00
250 lines
7 KiB
JavaScript
250 lines
7 KiB
JavaScript
/*
|
|
* "core" - The base file for jQm
|
|
*/
|
|
|
|
(function( $, window, undefined ) {
|
|
|
|
var nsNormalizeDict = {};
|
|
|
|
// jQuery.mobile configurable options
|
|
$.extend( $.mobile, {
|
|
|
|
// Namespace used framework-wide for data-attrs. Default is no namespace
|
|
ns: "",
|
|
|
|
// Define the url parameter used for referencing widget-generated sub-pages.
|
|
// Translates to to example.html&ui-page=subpageIdentifier
|
|
// hash segment before &ui-page= is used to make Ajax request
|
|
subPageUrlKey: "ui-page",
|
|
|
|
// Class assigned to page currently in view, and during transitions
|
|
activePageClass: "ui-page-active",
|
|
|
|
// Class used for "active" button state, from CSS framework
|
|
activeBtnClass: "ui-btn-active",
|
|
|
|
// Automatically handle clicks and form submissions through Ajax, when same-domain
|
|
ajaxEnabled: true,
|
|
|
|
// Automatically load and show pages based on location.hash
|
|
hashListeningEnabled: true,
|
|
|
|
// disable to prevent jquery from bothering with links
|
|
linkBindingEnabled: true,
|
|
|
|
// Set default page transition - 'none' for no transitions
|
|
defaultPageTransition: "slide",
|
|
|
|
// Minimum scroll distance that will be remembered when returning to a page
|
|
minScrollBack: 250,
|
|
|
|
// Set default dialog transition - 'none' for no transitions
|
|
defaultDialogTransition: "pop",
|
|
|
|
// Show loading message during Ajax requests
|
|
// if false, message will not appear, but loading classes will still be toggled on html el
|
|
loadingMessage: "loading",
|
|
|
|
// Error response message - appears when an Ajax page request fails
|
|
pageLoadErrorMessage: "Error Loading Page",
|
|
|
|
//automatically initialize the DOM when it's ready
|
|
autoInitializePage: true,
|
|
|
|
pushStateEnabled: true,
|
|
|
|
// turn of binding to the native orientationchange due to android orientation behavior
|
|
orientationChangeEnabled: true,
|
|
|
|
// Support conditions that must be met in order to proceed
|
|
// default enhanced qualifications are media query support OR IE 7+
|
|
gradeA: function(){
|
|
return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7;
|
|
},
|
|
|
|
// TODO might be useful upstream in jquery itself ?
|
|
keyCode: {
|
|
ALT: 18,
|
|
BACKSPACE: 8,
|
|
CAPS_LOCK: 20,
|
|
COMMA: 188,
|
|
COMMAND: 91,
|
|
COMMAND_LEFT: 91, // COMMAND
|
|
COMMAND_RIGHT: 93,
|
|
CONTROL: 17,
|
|
DELETE: 46,
|
|
DOWN: 40,
|
|
END: 35,
|
|
ENTER: 13,
|
|
ESCAPE: 27,
|
|
HOME: 36,
|
|
INSERT: 45,
|
|
LEFT: 37,
|
|
MENU: 93, // COMMAND_RIGHT
|
|
NUMPAD_ADD: 107,
|
|
NUMPAD_DECIMAL: 110,
|
|
NUMPAD_DIVIDE: 111,
|
|
NUMPAD_ENTER: 108,
|
|
NUMPAD_MULTIPLY: 106,
|
|
NUMPAD_SUBTRACT: 109,
|
|
PAGE_DOWN: 34,
|
|
PAGE_UP: 33,
|
|
PERIOD: 190,
|
|
RIGHT: 39,
|
|
SHIFT: 16,
|
|
SPACE: 32,
|
|
TAB: 9,
|
|
UP: 38,
|
|
WINDOWS: 91 // COMMAND
|
|
},
|
|
|
|
// Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value
|
|
silentScroll: function( ypos ) {
|
|
if ( $.type( ypos ) !== "number" ) {
|
|
ypos = $.mobile.defaultHomeScroll;
|
|
}
|
|
|
|
// prevent scrollstart and scrollstop events
|
|
$.event.special.scrollstart.enabled = false;
|
|
|
|
setTimeout(function() {
|
|
window.scrollTo( 0, ypos );
|
|
$( document ).trigger( "silentscroll", { x: 0, y: ypos });
|
|
}, 20 );
|
|
|
|
setTimeout(function() {
|
|
$.event.special.scrollstart.enabled = true;
|
|
}, 150 );
|
|
},
|
|
|
|
// Expose our cache for testing purposes.
|
|
nsNormalizeDict: nsNormalizeDict,
|
|
|
|
// Take a data attribute property, prepend the namespace
|
|
// and then camel case the attribute string. Add the result
|
|
// to our nsNormalizeDict so we don't have to do this again.
|
|
nsNormalize: function( prop ) {
|
|
if ( !prop ) {
|
|
return;
|
|
}
|
|
|
|
return nsNormalizeDict[ prop ] || ( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) );
|
|
},
|
|
|
|
getInheritedTheme: function( el, defaultTheme ) {
|
|
|
|
// Find the closest parent with a theme class on it. Note that
|
|
// we are not using $.fn.closest() on purpose here because this
|
|
// method gets called quite a bit and we need it to be as fast
|
|
// as possible.
|
|
|
|
var e = el[ 0 ],
|
|
ltr = "",
|
|
re = /ui-(bar|body)-([a-z])\b/,
|
|
c, m;
|
|
|
|
while ( e ) {
|
|
var c = e.className || "";
|
|
if ( ( m = re.exec( c ) ) && ( ltr = m[ 2 ] ) ) {
|
|
// We found a parent with a theme class
|
|
// on it so bail from this loop.
|
|
break;
|
|
}
|
|
e = e.parentNode;
|
|
}
|
|
|
|
// Return the theme letter we found, if none, return the
|
|
// specified default.
|
|
|
|
return ltr || defaultTheme || "a";
|
|
},
|
|
|
|
// TODO the following $ and $.fn extensions can/probably should be moved into jquery.mobile.core.helpers
|
|
//
|
|
// Find the closest javascript page element to gather settings data jsperf test
|
|
// http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit
|
|
// possibly naive, but it shows that the parsing overhead for *just* the page selector vs
|
|
// the page and dialog selector is negligable. This could probably be speed up by
|
|
// doing a similar parent node traversal to the one found in the inherited theme code above
|
|
closestPageData: function( $target ) {
|
|
return $target
|
|
.closest(':jqmData(role="page"), :jqmData(role="dialog")')
|
|
.data("page");
|
|
}
|
|
});
|
|
|
|
// Mobile version of data and removeData and hasData methods
|
|
// ensures all data is set and retrieved using jQuery Mobile's data namespace
|
|
$.fn.jqmData = function( prop, value ) {
|
|
var result;
|
|
if ( typeof prop != "undefined" ) {
|
|
result = this.data( prop ? $.mobile.nsNormalize( prop ) : prop, value );
|
|
}
|
|
return result;
|
|
};
|
|
|
|
$.jqmData = function( elem, prop, value ) {
|
|
var result;
|
|
if ( typeof prop != "undefined" ) {
|
|
result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value );
|
|
}
|
|
return result;
|
|
};
|
|
|
|
$.fn.jqmRemoveData = function( prop ) {
|
|
return this.removeData( $.mobile.nsNormalize( prop ) );
|
|
};
|
|
|
|
$.jqmRemoveData = function( elem, prop ) {
|
|
return $.removeData( elem, $.mobile.nsNormalize( prop ) );
|
|
};
|
|
|
|
$.fn.removeWithDependents = function() {
|
|
$.removeWithDependents( this );
|
|
};
|
|
|
|
$.removeWithDependents = function( elem ) {
|
|
var $elem = $( elem );
|
|
|
|
( $elem.jqmData('dependents') || $() ).remove();
|
|
$elem.remove();
|
|
};
|
|
|
|
$.fn.addDependents = function( newDependents ) {
|
|
$.addDependents( $(this), newDependents );
|
|
};
|
|
|
|
$.addDependents = function( elem, newDependents ) {
|
|
var dependents = $(elem).jqmData( 'dependents' ) || $();
|
|
|
|
$(elem).jqmData( 'dependents', $.merge(dependents, newDependents) );
|
|
};
|
|
|
|
// note that this helper doesn't attempt to handle the callback
|
|
// or setting of an html elements text, its only purpose is
|
|
// to return the html encoded version of the text in all cases. (thus the name)
|
|
$.fn.getEncodedText = function() {
|
|
return $( "<div/>" ).text( $(this).text() ).html();
|
|
};
|
|
|
|
// Monkey-patching Sizzle to filter the :jqmData selector
|
|
var oldFind = $.find,
|
|
jqmDataRE = /:jqmData\(([^)]*)\)/g;
|
|
|
|
$.find = function( selector, context, ret, extra ) {
|
|
selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" );
|
|
|
|
return oldFind.call( this, selector, context, ret, extra );
|
|
};
|
|
|
|
$.extend( $.find, oldFind );
|
|
|
|
$.find.matches = function( expr, set ) {
|
|
return $.find( expr, null, null, set );
|
|
};
|
|
|
|
$.find.matchesSelector = function( node, expr ) {
|
|
return $.find( expr, null, null, [ node ] ).length > 0;
|
|
};
|
|
})( jQuery, this );
|
|
|