mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-05-18 11:31:06 +00:00
Merge remote branch 'origin/master'
This commit is contained in:
commit
821f0d88d5
21 changed files with 599 additions and 342 deletions
2
Makefile
2
Makefile
|
|
@ -14,9 +14,9 @@ FILES = js/jquery.ui.widget.js \
|
|||
js/jquery.mobile.support.js \
|
||||
js/jquery.mobile.event.js \
|
||||
js/jquery.mobile.hashchange.js \
|
||||
js/jquery.mobile.page.js \
|
||||
js/jquery.mobile.core.js \
|
||||
js/jquery.mobile.navigation.js \
|
||||
js/jquery.mobile.page.js \
|
||||
js/jquery.ui.position.js \
|
||||
js/jquery.mobile.fixHeaderFooter.js \
|
||||
js/jquery.mobile.forms.checkboxradio.js \
|
||||
|
|
|
|||
10
build.xml
10
build.xml
|
|
@ -27,9 +27,9 @@
|
|||
jquery.mobile.support.js,
|
||||
jquery.mobile.event.js,
|
||||
jquery.mobile.hashchange.js,
|
||||
jquery.mobile.page.js,
|
||||
jquery.mobile.core.js,
|
||||
jquery.mobile.navigation.js,
|
||||
jquery.mobile.page.js,
|
||||
jquery.mobile.buttonMarkup.js,
|
||||
jquery.mobile.collapsible.js,
|
||||
jquery.mobile.controlGroup.js,
|
||||
|
|
@ -52,15 +52,15 @@
|
|||
<antcall target="merge_js" />
|
||||
</target>
|
||||
|
||||
<target name="merge_css">
|
||||
<target name="merge_css">
|
||||
<concat destfile="combine/jquery.mobile.css">
|
||||
<filelist dir="${cssdir}" files="${css-sources}"/>
|
||||
</concat>
|
||||
</target>
|
||||
|
||||
<target name="merge_js">
|
||||
|
||||
<target name="merge_js">
|
||||
<concat destfile="combine/jquery.mobile.js">
|
||||
<filelist dir="${jsdir}" files="${js-sources}"/>
|
||||
</concat>
|
||||
</target>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -80,11 +80,14 @@ $(document).bind("mobileinit", function(){
|
|||
|
||||
<dt>activeBtnClass (<em>string</em>, default: "ui-page-active"):</dt>
|
||||
<dd>The class used for "active" button state, from CSS framework.</dd>
|
||||
|
||||
<dt>ajaxEnabled (<em>boolean</em>, default: true):</dt>
|
||||
<dd>jQuery Mobile will automatically handle link clicks and form submissions through Ajax, when possible. If false, url hash listening will be disabled as well, and urls will load as regular http requests.</dd>
|
||||
|
||||
<dt>ajaxLinksEnabled (<em>boolean</em>, default: true):</dt>
|
||||
<dt>ajaxLinksEnabled (<strong>deprecated</strong> <em>boolean</em>, default: true):</dt>
|
||||
<dd>jQuery Mobile will automatically handle link clicks through Ajax, when possible.</dd>
|
||||
|
||||
<dt>ajaxFormsEnabled (<em>boolean</em>, default: true):</dt>
|
||||
<dt>ajaxFormsEnabled (<strong>deprecated</strong> <em>boolean</em>, default: true):</dt>
|
||||
<dd>jQuery Mobile will automatically handle form submissions through Ajax, when possible.</dd>
|
||||
|
||||
<dt>defaultTransition (<em>string</em>, default: 'slide'):</dt>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
</dd>
|
||||
|
||||
<dd><code>transition</code> (<em>string</em>, examples: "pop", "slide"," "none")</dd>
|
||||
<dd><code>back</code> (<em>boolean</em>, default: false). True will cause a reverse-direction transition.</dd>
|
||||
<dd><code>reverse</code> (<em>boolean</em>, default: false). True will cause a reverse-direction transition.</dd>
|
||||
<dd><code>changeHash</code> (<em>boolean</em>, default: true). Update the hash to the to page's URL when page change is complete.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
|
@ -89,6 +89,14 @@ $.mobile.pageLoading( true );
|
|||
</dd>
|
||||
|
||||
|
||||
<dt><code>$.mobile.path</code> (<em>methods, properties</em>)</dt>
|
||||
<dd>Utilities for getting, setting, and manipulating url paths. TODO: document as public API is finalized.</dd>
|
||||
|
||||
<dt><code>$.mobile.base</code> (<em>methods, properties</em>)</dt>
|
||||
<dd>Utilities for working with generated base element. TODO: document as public API is finalized.</dd>
|
||||
|
||||
|
||||
|
||||
<dt><code>$.mobile.silentScroll</code> (<em>method</em>)</dt>
|
||||
<dd>Scroll to a particular Y position without triggering scroll event listeners.</dd>
|
||||
<dd>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
<a href="transition-success.html" data-role="button" data-rel="dialog" data-transition="flip">flip</a>
|
||||
</p>
|
||||
|
||||
<p>In addition, you can also force a "backwards" transition by specifying <code>data-back="true"</code> on your link.</p>
|
||||
<p>In addition, you can also force a "backwards" transition by specifying <code>data-direction="reverse"</code> on your link. Note: (this was formerly <code>data-back="true"</code>, which will remain supported until 1.0)</p>
|
||||
|
||||
<div class="ui-body ui-body-e">
|
||||
<p><strong>Transitions from <a href="http://www.jqtouch.com/">jQtouch</a></strong> (<em>with small modifications</em>): Built by David Kaneda and maintained by Jonathan Stark.</p>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<p>That was an animated page transition effect that we added with a <code>data-transition</code> attribute on the link.</p>
|
||||
<p>Since it uses CSS transforms, this should be hardware accelerated on many mobile devices.</p>
|
||||
<p>What do you think?</p>
|
||||
<a href="docs-transitions.html" data-role="button" data-theme="b">I like it</a>
|
||||
<a href="docs-transitions.html" data-role="button" data-theme="b" data-direction="reverse">I like it</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ $elements = array(
|
|||
'jquery.mobile.support.js',
|
||||
'jquery.mobile.event.js',
|
||||
'jquery.mobile.hashchange.js',
|
||||
'jquery.mobile.page.js',
|
||||
'jquery.mobile.core.js',
|
||||
'jquery.mobile.navigation.js',
|
||||
'jquery.mobile.page.js',
|
||||
'jquery.ui.position.js',
|
||||
'jquery.mobile.fixHeaderFooter.js',
|
||||
'jquery.mobile.forms.checkboxradio.js',
|
||||
|
|
|
|||
|
|
@ -27,11 +27,16 @@
|
|||
//class used for "active" button state, from CSS framework
|
||||
activeBtnClass: 'ui-btn-active',
|
||||
|
||||
//automatically handle link clicks through Ajax, when possible
|
||||
ajaxLinksEnabled: true,
|
||||
//automatically handle clicks and form submissions through Ajax, when same-domain
|
||||
ajaxEnabled: true,
|
||||
|
||||
// TODO: deprecated - remove at 1.0
|
||||
//automatically handle link clicks through Ajax, when possible
|
||||
ajaxLinksEnabled: true,
|
||||
|
||||
//automatically handle form submissions through Ajax, when possible
|
||||
ajaxFormsEnabled: true,
|
||||
// TODO: deprecated - remove at 1.0
|
||||
//automatically handle form submissions through Ajax, when possible
|
||||
ajaxFormsEnabled: true,
|
||||
|
||||
//set default transition - 'none' for no transitions
|
||||
defaultTransition: 'slide',
|
||||
|
|
|
|||
|
|
@ -10,19 +10,27 @@ $.widget( "mobile.dialog", $.mobile.widget, {
|
|||
_create: function(){
|
||||
var self = this,
|
||||
$el = self.element,
|
||||
$prevPage = $.mobile.activePage,
|
||||
$closeBtn = $('<a href="#" data-icon="delete" data-iconpos="notext">Close</a>'),
|
||||
|
||||
dialogClickHandler = function(e){
|
||||
var $target = $(e.target);
|
||||
var $target = $(e.target),
|
||||
href = $.mobile.path.stripHash( $target.closest("a").attr("href") ),
|
||||
isRelative = $.mobile.path.isRelative( href ),
|
||||
absUrl = isRelative ? $.mobile.path.makeAbsolute( href ) : href;
|
||||
|
||||
// fixes issues with target links in dialogs breaking
|
||||
// page transitions by reseting the active page below
|
||||
if( $.mobile.isExternalLink($target) ) {
|
||||
if( $.mobile.path.isExternal( href ) ||
|
||||
$target.closest("a[target]").length ||
|
||||
$target.is( "[rel='external']" ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( e.type == "click" && ( $(e.target).closest('[data-back]')[0] || this==$closeBtn[0] ) ){
|
||||
|
||||
|
||||
//if it's a close button click
|
||||
//or the href is the same as the page we're on, close the dialog
|
||||
if( e.type == "click" &&
|
||||
( this==$closeBtn[0] || absUrl == $.mobile.path.stripHash( location.hash ) ) ){
|
||||
self.close();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -38,8 +46,15 @@ $.widget( "mobile.dialog", $.mobile.widget, {
|
|||
|
||||
this.element
|
||||
.bind("pageshow",function(){
|
||||
self.thisPage = $.mobile.urlHistory.getActive();
|
||||
self.prevPage = $.mobile.urlHistory.getPrev();
|
||||
return false;
|
||||
})
|
||||
.bind("pagehide", function(){
|
||||
$.mobile.urlHistory.stack = $.mobile.urlHistory.stack.slice(0,$.mobile.urlHistory.stack.length-2);
|
||||
$.mobile.urlHistory.activeIndex = $.mobile.urlHistory.stack.length -1;
|
||||
})
|
||||
|
||||
//add ARIA role
|
||||
.attr("role","dialog")
|
||||
.addClass('ui-page ui-dialog ui-body-a')
|
||||
|
|
@ -54,11 +69,15 @@ $.widget( "mobile.dialog", $.mobile.widget, {
|
|||
.last()
|
||||
.addClass('ui-corner-bottom ui-overlay-shadow');
|
||||
|
||||
|
||||
|
||||
$(window).bind('hashchange',function(){
|
||||
$.mobile.urlHistory.listeningEnabled = true;
|
||||
if( $el.is('.ui-page-active') ){
|
||||
self.close();
|
||||
$el.bind('pagehide',function(){
|
||||
$.mobile.updateHash( $prevPage.attr('data-url'), true);
|
||||
$.mobile.urlHistory.listeningEnabled = false;
|
||||
$.mobile.updateHash( self.prevPage.url );
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -66,7 +85,7 @@ $.widget( "mobile.dialog", $.mobile.widget, {
|
|||
},
|
||||
|
||||
close: function(){
|
||||
$.mobile.changePage([this.element, $.mobile.activePage], undefined, true, true );
|
||||
$.mobile.changePage([this.element, $.mobile.activePage], this.thisPage.transition, true, true, true );
|
||||
}
|
||||
});
|
||||
})( jQuery );
|
||||
|
|
@ -63,21 +63,37 @@ $.event.special.tap = {
|
|||
$this = $( thisObject );
|
||||
|
||||
$this
|
||||
.bind( touchStartEvent, function( event ) {
|
||||
if ( event.which && event.which !== 1 ) {
|
||||
return;
|
||||
.bind( "mousedown touchstart", function( event ) {
|
||||
if ( event.which && event.which !== 1 ||
|
||||
//check if event fired once already by a device that fires both mousedown and touchstart (while supporting both events)
|
||||
$this.data( "prevEvent") && $this.data( "prevEvent") !== event.type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//save event type so only this type is let through for a temp duration,
|
||||
//allowing quick repetitive taps but not duplicative events
|
||||
$this.data( "prevEvent", event.type );
|
||||
setTimeout(function(){
|
||||
$this.removeData( "prevEvent" );
|
||||
}, 800);
|
||||
|
||||
var moved = false,
|
||||
touching = true,
|
||||
origTarget = event.target,
|
||||
origPos = [ event.pageX, event.pageY ],
|
||||
origEvent = event.originalEvent,
|
||||
origPos = event.type == "touchstart" ? [origEvent.touches[0].pageX, origEvent.touches[0].pageY] : [ event.pageX, event.pageY ],
|
||||
originalType,
|
||||
timer;
|
||||
|
||||
|
||||
function moveHandler() {
|
||||
if ((Math.abs(origPos[0] - event.pageX) > 10) ||
|
||||
(Math.abs(origPos[1] - event.pageY) > 10)) {
|
||||
function moveHandler( event ) {
|
||||
if( event.type == "scroll" ){
|
||||
moved = true;
|
||||
return;
|
||||
}
|
||||
var newPageXY = event.type == "touchmove" ? event.originalEvent.touches[0] : event;
|
||||
if ((Math.abs(origPos[0] - newPageXY.pageX) > 10) ||
|
||||
(Math.abs(origPos[1] - newPageXY.pageY) > 10)) {
|
||||
moved = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -91,17 +107,21 @@ $.event.special.tap = {
|
|||
}
|
||||
}, 750 );
|
||||
|
||||
//scroll now cancels tap
|
||||
$(window).one("scroll", moveHandler);
|
||||
|
||||
$this
|
||||
.one( touchMoveEvent, moveHandler)
|
||||
.one( touchStopEvent, function( event ) {
|
||||
$this.unbind( touchMoveEvent, moveHandler );
|
||||
.bind( "mousemove touchmove", moveHandler )
|
||||
.one( "mouseup touchend", function( event ) {
|
||||
$this.unbind( "mousemove touchmove", moveHandler );
|
||||
$(window).unbind("scroll", moveHandler);
|
||||
clearTimeout( timer );
|
||||
touching = false;
|
||||
|
||||
/* ONLY trigger a 'tap' event if the start target is
|
||||
* the same as the stop target.
|
||||
*/
|
||||
if ( !moved && (origTarget == event.target)) {
|
||||
if ( !moved && ( origTarget == event.target ) ) {
|
||||
originalType = event.type;
|
||||
event.type = "tap";
|
||||
$.event.handle.call( thisObject, event );
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
if( newPath == undefined ){
|
||||
newPath = location.hash;
|
||||
}
|
||||
return newPath.replace(/#/,'').replace(/[^\/]*\.[^\/*]+$/, '');
|
||||
return path.stripHash( newPath ).replace(/[^\/]*\.[^\/*]+$/, '');
|
||||
},
|
||||
|
||||
//return the substring of a filepath before the sub-page key, for making a server request
|
||||
|
|
@ -27,9 +27,9 @@
|
|||
var splitkey = '&' + $.mobile.subPageUrlKey;
|
||||
return path && path.indexOf( splitkey ) > -1 ? path.split( splitkey )[0] : path;
|
||||
},
|
||||
|
||||
set: function( path, disableListening){
|
||||
if(disableListening) { hashListener = false; }
|
||||
|
||||
//set location hash to path
|
||||
set: function( path ){
|
||||
location.hash = path;
|
||||
},
|
||||
|
||||
|
|
@ -38,29 +38,91 @@
|
|||
|
||||
setOrigin: function(){
|
||||
path.origin = path.get( location.protocol + '//' + location.host + location.pathname );
|
||||
},
|
||||
|
||||
//prefix a relative url with the current path
|
||||
makeAbsolute: function( url ){
|
||||
return path.get() + url;
|
||||
},
|
||||
|
||||
//return a url path with the window's location protocol/hostname removed
|
||||
clean: function( url ){
|
||||
return url.replace( location.protocol + "//" + location.host, "");
|
||||
},
|
||||
|
||||
//just return the url without an initial #
|
||||
stripHash: function( url ){
|
||||
return url.replace( /^#/, "" );
|
||||
},
|
||||
|
||||
//check whether a url is referencing the same domain, or an external domain or different protocol
|
||||
//could be mailto, etc
|
||||
isExternal: function( url ){
|
||||
return path.hasProtocol( path.clean( url ) );
|
||||
},
|
||||
|
||||
hasProtocol: function( url ){
|
||||
return /^(:?\w+:)/.test( url );
|
||||
},
|
||||
|
||||
//check if the url is relative
|
||||
isRelative: function( url ){
|
||||
return /^[^\/|#]/.test( url ) && !path.hasProtocol( url );
|
||||
}
|
||||
},
|
||||
|
||||
//will be defined when a link is clicked and given an active class
|
||||
$activeClickedLink = null,
|
||||
|
||||
//array of pages that are visited during a single page load
|
||||
//length will grow as pages are visited, and shrink as "back" link/button is clicked
|
||||
//each item has a url (string matches ID), and transition (saved for reuse when "back" link/button is clicked)
|
||||
urlStack = [ {
|
||||
url: location.hash.replace( /^#/, "" ),
|
||||
transition: undefined
|
||||
} ],
|
||||
|
||||
//urlHistory is purely here to make guesses at whether the back or forward button was clicked
|
||||
//and provide an appropriate transition
|
||||
urlHistory = {
|
||||
//array of pages that are visited during a single page load. each has a url and optional transition
|
||||
stack: [],
|
||||
|
||||
//maintain an index number for the active page in the stack
|
||||
activeIndex: 0,
|
||||
|
||||
//get active
|
||||
getActive: function(){
|
||||
return urlHistory.stack[ urlHistory.activeIndex ];
|
||||
},
|
||||
|
||||
getPrev: function(){
|
||||
return urlHistory.stack[ urlHistory.activeIndex - 1 ];
|
||||
},
|
||||
|
||||
getNext: function(){
|
||||
return urlHistory.stack[ urlHistory.activeIndex + 1 ];
|
||||
},
|
||||
|
||||
// addNew is used whenever a new page is added
|
||||
addNew: function( url, transition ){
|
||||
//if there's forward history, wipe it
|
||||
if( urlHistory.getNext() ){
|
||||
urlHistory.clearForward();
|
||||
}
|
||||
|
||||
urlHistory.stack.push( {url : url, transition: transition } );
|
||||
|
||||
urlHistory.activeIndex = urlHistory.stack.length - 1;
|
||||
},
|
||||
|
||||
//wipe urls ahead of active index
|
||||
clearForward: function(){
|
||||
urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 );
|
||||
},
|
||||
|
||||
//enable/disable hashchange event listener
|
||||
//toggled internally when location.hash is updated to match the url of a successful page load
|
||||
listeningEnabled: true
|
||||
},
|
||||
|
||||
//define first selector to receive focus when a page is shown
|
||||
focusable = "[tabindex],a,button:visible,select:visible,input",
|
||||
|
||||
//contains role for next page, if defined on clicked link via data-rel
|
||||
nextPageRole = null,
|
||||
|
||||
//enable/disable hashchange event listener
|
||||
//toggled internally when location.hash is updated to match the url of a successful page load
|
||||
hashListener = true;
|
||||
nextPageRole = null;
|
||||
|
||||
//existing base tag?
|
||||
var $base = $head.children("base"),
|
||||
|
|
@ -83,7 +145,7 @@
|
|||
//the href is a document relative url
|
||||
docBase = docLocation + href;
|
||||
//XXX: we need some code here to calculate the final path
|
||||
// just in case the docBase contains up-level (../) references.
|
||||
// just in case the docBase contains up-level (../) references.
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -142,7 +204,6 @@
|
|||
$activeClickedLink = null;
|
||||
};
|
||||
|
||||
|
||||
//animation complete callback
|
||||
$.fn.animationComplete = function( callback ){
|
||||
if($.support.cssTransitions){
|
||||
|
|
@ -158,41 +219,77 @@
|
|||
/* exposed $.mobile methods */
|
||||
|
||||
//update location.hash, with or without triggering hashchange event
|
||||
//TODO - deprecate this one at 1.0
|
||||
$.mobile.updateHash = path.set;
|
||||
|
||||
//expose path object on $.mobile
|
||||
$.mobile.path = path;
|
||||
|
||||
//expose base object on $.mobile
|
||||
$.mobile.base = base;
|
||||
|
||||
//url stack, useful when plugins need to be aware of previous pages viewed
|
||||
$.mobile.urlStack = urlStack;
|
||||
|
||||
//check for an external resource
|
||||
$.mobile.isExternalLink = function(anchor){
|
||||
var $anchor = $(anchor),
|
||||
hasProtocol = /^(:?\w+:)/.test( $anchor.attr('href') ),
|
||||
hasRelExternal = $anchor.is( "[rel=external]" ),
|
||||
hasTarget = $anchor.is( "[target]" );
|
||||
|
||||
return hasProtocol || hasRelExternal || hasTarget;
|
||||
},
|
||||
//TODO: deprecate this one at 1.0
|
||||
$.mobile.urlstack = urlHistory.stack;
|
||||
|
||||
//history stack
|
||||
$.mobile.urlHistory = urlHistory;
|
||||
|
||||
// changepage function
|
||||
$.mobile.changePage = function( to, transition, back, changeHash){
|
||||
// TODO : consider moving args to an object hash
|
||||
$.mobile.changePage = function( to, transition, reverse, changeHash, fromHashChange ){
|
||||
|
||||
//from is always the currently viewed page
|
||||
var toIsArray = $.type(to) === "array",
|
||||
toIsObject = $.type(to) === "object",
|
||||
from = toIsArray ? to[0] : $.mobile.activePage,
|
||||
to = toIsArray ? to[1] : to,
|
||||
url = fileUrl = $.type(to) === "string" ? to.replace( /^#/, "" ) : null,
|
||||
url = fileUrl = $.type(to) === "string" ? path.stripHash( to ) : "",
|
||||
data = undefined,
|
||||
type = 'get',
|
||||
isFormRequest = false,
|
||||
duplicateCachedPage = null,
|
||||
back = (back !== undefined) ? back : ( urlStack.length > 1 && urlStack[ urlStack.length - 2 ].url === url );
|
||||
|
||||
//If we are trying to transition to the same page that we are currently on ignore the request.
|
||||
if(urlStack.length > 1 && url === urlStack[urlStack.length -1].url && !toIsArray ) {
|
||||
currPage = urlHistory.getActive(),
|
||||
back = false,
|
||||
forward = false;
|
||||
|
||||
// If we are trying to transition to the same page that we are currently on ignore the request.
|
||||
// an illegal same page request is defined by the current page being the same as the url, as long as there's history
|
||||
// and to is not an array or object (those are allowed to be "same")
|
||||
if( currPage && urlHistory.stack.length > 1 && currPage.url === url && !toIsArray && !toIsObject ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the changePage was sent from a hashChange event
|
||||
// guess if it came from the history menu
|
||||
if( fromHashChange ){
|
||||
|
||||
// check if url is in history and if it's ahead or behind current page
|
||||
$.each( urlHistory.stack, function( i ){
|
||||
//if the url is in the stack, it's a forward or a back
|
||||
if( this.url == url ){
|
||||
urlIndex = i;
|
||||
//define back and forward by whether url is older or newer than current page
|
||||
back = i < urlHistory.activeIndex;
|
||||
//forward set to opposite of back
|
||||
forward = !back;
|
||||
//reset activeIndex to this one
|
||||
urlHistory.activeIndex = i;
|
||||
}
|
||||
});
|
||||
|
||||
//if it's a back, use reverse animation
|
||||
if( back ){
|
||||
reverse = true;
|
||||
transition = transition || currPage.transition;
|
||||
}
|
||||
else if ( forward ){
|
||||
transition = transition || urlHistory.getActive().transition;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( $.type(to) === "object" && to.url ){
|
||||
if( toIsObject && to.url ){
|
||||
url = to.url,
|
||||
data = to.data,
|
||||
type = to.type,
|
||||
|
|
@ -216,25 +313,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// if the new href is the same as the previous one
|
||||
if ( back ) {
|
||||
var pop = urlStack.pop();
|
||||
|
||||
// prefer the explicitly set transition
|
||||
if( pop && !transition ){
|
||||
transition = pop.transition;
|
||||
}
|
||||
|
||||
// ensure a transition has been set where pop is undefined
|
||||
defaultTransition();
|
||||
} else {
|
||||
// If no transition has been passed
|
||||
defaultTransition();
|
||||
|
||||
// push the url and transition onto the stack
|
||||
urlStack.push({ url: url, transition: transition });
|
||||
}
|
||||
|
||||
//function for transitioning between two existing pages
|
||||
function transitionPages() {
|
||||
|
||||
|
|
@ -256,8 +334,18 @@
|
|||
reFocus( to );
|
||||
|
||||
if( changeHash !== false && url ){
|
||||
path.set(url, (back !== true));
|
||||
if( !back ){
|
||||
urlHistory.listeningEnabled = false;
|
||||
}
|
||||
path.set( url );
|
||||
urlHistory.listeningEnabled = true;
|
||||
}
|
||||
|
||||
//add page to history stack if it's not back or forward, or a dialog
|
||||
if( !back && !forward ){
|
||||
urlHistory.addNew( url, transition );
|
||||
}
|
||||
|
||||
removeActiveLinkClass();
|
||||
|
||||
//jump to top or prev scroll, if set
|
||||
|
|
@ -296,9 +384,9 @@
|
|||
addContainerClass('ui-mobile-viewport-transitioning');
|
||||
|
||||
// animate in / out
|
||||
from.addClass( transition + " out " + ( back ? "reverse" : "" ) );
|
||||
from.addClass( transition + " out " + ( reverse ? "reverse" : "" ) );
|
||||
to.addClass( $.mobile.activePageClass + " " + transition +
|
||||
" in " + ( back ? "reverse" : "" ) );
|
||||
" in " + ( reverse ? "reverse" : "" ) );
|
||||
|
||||
// callback - remove classes, etc
|
||||
to.animationComplete(function() {
|
||||
|
|
@ -344,6 +432,9 @@
|
|||
fileUrl = toIDfileurl;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure a transition has been set where pop is undefined
|
||||
defaultTransition();
|
||||
|
||||
// find the "to" page, either locally existing in the dom or by creating it through ajax
|
||||
if ( to.length && !isFormRequest ) {
|
||||
|
|
@ -417,20 +508,22 @@
|
|||
/* Event Bindings - hashchange, submit, and click */
|
||||
|
||||
//bind to form submit events, handle with Ajax
|
||||
$("form[data-ajax!='false']").live('submit', function(event){
|
||||
if( !$.mobile.ajaxFormsEnabled ){ return; }
|
||||
$( "form[data-ajax!='false']" ).live('submit', function(event){
|
||||
if( !$.mobile.ajaxEnabled ||
|
||||
//TODO: deprecated - remove at 1.0
|
||||
!$.mobile.ajaxFormsEnabled ){ return; }
|
||||
|
||||
var type = $(this).attr("method"),
|
||||
url = $(this).attr( "action" ).replace( location.protocol + "//" + location.host, "");
|
||||
url = path.clean( $(this).attr( "action" ) );
|
||||
|
||||
//external submits use regular HTTP
|
||||
if( /^(:?\w+:)/.test( url ) ){
|
||||
if( path.isExternal( url ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
//if it's a relative href, prefix href with base url
|
||||
if( url.indexOf('/') && url.indexOf('#') !== 0 ){
|
||||
url = path.get() + url;
|
||||
if( path.isRelative( url ) ){
|
||||
url = path.makeAbsolute( url );
|
||||
}
|
||||
|
||||
$.mobile.changePage({
|
||||
|
|
@ -448,51 +541,57 @@
|
|||
|
||||
//click routing - direct to HTTP or Ajax, accordingly
|
||||
$( "a" ).live( "click", function(event) {
|
||||
|
||||
if( !$.mobile.ajaxLinksEnabled ){ return; }
|
||||
|
||||
var $this = $(this),
|
||||
//get href, remove same-domain protocol and host
|
||||
href = $this.attr( "href" ).replace( location.protocol + "//" + location.host, ""),
|
||||
//if target attr is specified, it's external, and we mimic _blank... for now
|
||||
target = $this.is( "[target]" ),
|
||||
url = path.clean( $this.attr( "href" ) ),
|
||||
|
||||
//check if it's external
|
||||
isExternal = path.isExternal( url ) || $this.is( "[rel='external']" ),
|
||||
|
||||
//if target attr is specified we mimic _blank... for now
|
||||
hasTarget = $this.is( "[target]" );
|
||||
|
||||
|
||||
//if it still starts with a protocol, it's external, or could be :mailto, etc
|
||||
external = $.mobile.isExternalLink(this);
|
||||
|
||||
if( href === '#' ){
|
||||
if( url === "#" ){
|
||||
//for links created purely for interaction - ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
$activeClickedLink = $this.closest( ".ui-btn" ).addClass( $.mobile.activeBtnClass );
|
||||
|
||||
if( external || !$.mobile.ajaxLinksEnabled ){
|
||||
//remove active link class if external
|
||||
if( isExternal || hasTarget || !$.mobile.ajaxEnabled ||
|
||||
// TODO: deprecated - remove at 1.0
|
||||
!$.mobile.ajaxLinksEnabled ){
|
||||
//remove active link class if external (then it won't be there if you come back)
|
||||
removeActiveLinkClass(true);
|
||||
|
||||
//deliberately redirect, in case click was triggered
|
||||
if( target ){
|
||||
window.open(href);
|
||||
if( hasTarget ){
|
||||
window.open( url );
|
||||
}
|
||||
else{
|
||||
location.href = href;
|
||||
location.href = url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//use ajax
|
||||
var transition = $this.data( "transition" ),
|
||||
back = $this.data( "back" );
|
||||
direction = $this.data("direction"),
|
||||
reverse = direction && direction == "reverse" ||
|
||||
// deprecated - remove by 1.0
|
||||
$this.data( "back" );
|
||||
|
||||
nextPageRole = $this.attr( "data-rel" );
|
||||
|
||||
//if it's a relative href, prefix href with base url
|
||||
if( href.indexOf('/') && href.indexOf('#') !== 0 ){
|
||||
href = path.get() + href;
|
||||
if( path.isRelative( url ) ){
|
||||
url = path.makeAbsolute( url );
|
||||
}
|
||||
|
||||
href.replace(/^#/,'');
|
||||
url = path.stripHash( url );
|
||||
|
||||
$.mobile.changePage(href, transition, back);
|
||||
$.mobile.changePage( url, transition, reverse);
|
||||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
|
|
@ -501,8 +600,10 @@
|
|||
|
||||
//hashchange event handler
|
||||
$window.bind( "hashchange", function(e, triggered) {
|
||||
if( !hashListener ){
|
||||
hashListener = true;
|
||||
if( !urlHistory.listeningEnabled || !$.mobile.ajaxEnabled ||
|
||||
// TODO: deprecated - remove at 1.0
|
||||
// only links need to be checked here, as forms don't trigger a hashchange event (they just silently update the hash)
|
||||
( !$.mobile.ajaxLinksEnabled ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -510,20 +611,21 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var to = location.hash,
|
||||
var to = path.stripHash( location.hash ),
|
||||
transition = triggered ? false : undefined;
|
||||
|
||||
//if to is defined, use it
|
||||
if ( to ){
|
||||
$.mobile.changePage( to, transition, undefined, false);
|
||||
$.mobile.changePage( to, transition, undefined, false, true );
|
||||
}
|
||||
//there's no hash, the active page is not the start page, and it's not manually triggered hashchange
|
||||
//we probably backed out to the first page visited
|
||||
else if( $.mobile.activePage.length && $.mobile.startPage[0] !== $.mobile.activePage[0] && !triggered ) {
|
||||
$.mobile.changePage( $.mobile.startPage, transition, true, false );
|
||||
$.mobile.changePage( $.mobile.startPage, transition, true, false, true );
|
||||
}
|
||||
//probably the first page - show it
|
||||
else{
|
||||
urlHistory.addNew( "" );
|
||||
$.mobile.startPage.trigger("pagebeforeshow", {prevPage: $('')});
|
||||
$.mobile.startPage.addClass( $.mobile.activePageClass );
|
||||
$.mobile.pageLoading( true );
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ $.widget( "mobile.page", $.mobile.widget, {
|
|||
|
||||
// auto-add back btn on pages beyond first view
|
||||
if ( o.addBackBtn && role === "header" &&
|
||||
($.mobile.urlStack.length > 1 || $(".ui-page").length > 1) &&
|
||||
($.mobile.urlHistory.getPrev() || $(".ui-page").length > 1) &&
|
||||
!leftbtn && $this.data( "backbtn" ) !== false ) {
|
||||
|
||||
$( "<a href='#' class='ui-btn-left' data-icon='arrow-l'>"+ o.backBtnText +"</a>" )
|
||||
|
|
|
|||
47
tests/functional/addrbar.html
Executable file
47
tests/functional/addrbar.html
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>jQuery Mobile: Event Logger</title>
|
||||
<link rel="stylesheet" href="../../themes/default/" />
|
||||
<link rel="stylesheet" href="../../docs/_assets/css/jqm-docs.css" />
|
||||
<script type="text/javascript" src="../../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../../js/"></script>
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
$( "a" ).bind("tap",function( e ){
|
||||
$("#log")
|
||||
.prepend("<li>"+ e.type +" event; target: "+ e.target.nodeName +"</li>")
|
||||
.listview("refresh");
|
||||
return false;
|
||||
})
|
||||
.bind("click", false);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#jqm-home {
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div data-role="page" data-theme="b" id="jqm-home">
|
||||
<div data-role="header">
|
||||
<h1>Event Logger</h1>
|
||||
</div>
|
||||
|
||||
<div data-role="content">
|
||||
<p>Touch events on this page will log out below, prepending to the top as they arrive.</p>
|
||||
|
||||
<a href="foo.html" data-role="button">Click me</a>
|
||||
|
||||
<ul data-role="listview" id="log">
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
37
tests/functional/eventlogger.html
Executable file
37
tests/functional/eventlogger.html
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>jQuery Mobile: Event Logger</title>
|
||||
<link rel="stylesheet" href="../../themes/default/" />
|
||||
<link rel="stylesheet" href="../../docs/_assets/css/jqm-docs.css" />
|
||||
<script type="text/javascript" src="../../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../../js/"></script>
|
||||
|
||||
<script>
|
||||
$( document )
|
||||
.bind("tap taphold swipe swipeleft swiperight scrollstart scrollstop orientationchange",function( e ){
|
||||
$("#log")
|
||||
.prepend("<li>"+ e.type +" event; target: "+ e.target.nodeName +"</li>")
|
||||
.listview("refresh");
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div data-role="page" data-theme="b" id="jqm-home">
|
||||
<div data-role="header">
|
||||
<h1>Event Logger</h1>
|
||||
</div>
|
||||
|
||||
<div data-role="content">
|
||||
<p>Touch events on this page will log out below, prepending to the top as they arrive.</p>
|
||||
|
||||
<ul data-role="listview" id="log">
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2,148 +2,148 @@
|
|||
* mobile core unit tests
|
||||
*/
|
||||
|
||||
var libName = "jquery.mobile.core.js",
|
||||
setGradeA = function(value) { $.support.mediaquery = value; },
|
||||
extendFn = $.extend;
|
||||
(function($){
|
||||
var libName = "jquery.mobile.core.js",
|
||||
setGradeA = function(value) { $.support.mediaquery = value; },
|
||||
extendFn = $.extend;
|
||||
|
||||
module(libName, {
|
||||
setup: function(){
|
||||
// NOTE reset for gradeA tests
|
||||
$('html').removeClass('ui-mobile');
|
||||
module(libName, {
|
||||
setup: function(){
|
||||
// NOTE reset for gradeA tests
|
||||
$('html').removeClass('ui-mobile');
|
||||
|
||||
// NOTE reset for pageLoading tests
|
||||
$('.ui-loader').remove();
|
||||
},
|
||||
teardown: function(){
|
||||
$.extend = extendFn;
|
||||
}
|
||||
});
|
||||
|
||||
$.testHelper.excludeFileProtocol(function(){
|
||||
test( "grade A browser support media queries", function(){
|
||||
setGradeA(false);
|
||||
$.testHelper.reloadLib(libName);
|
||||
ok(!$.mobile.gradeA());
|
||||
|
||||
setGradeA(true);
|
||||
$.testHelper.reloadLib(libName);
|
||||
ok($.mobile.gradeA());
|
||||
// NOTE reset for pageLoading tests
|
||||
$('.ui-loader').remove();
|
||||
},
|
||||
teardown: function(){
|
||||
$.extend = extendFn;
|
||||
}
|
||||
});
|
||||
|
||||
test( "loading the core library triggers mobilinit on the document", function(){
|
||||
expect( 1 );
|
||||
$.testHelper.excludeFileProtocol(function(){
|
||||
test( "grade A browser support media queries", function(){
|
||||
setGradeA(false);
|
||||
$.testHelper.reloadLib(libName);
|
||||
ok(!$.mobile.gradeA());
|
||||
|
||||
$(window.document).bind('mobileinit', function(event){
|
||||
ok(true);
|
||||
setGradeA(true);
|
||||
$.testHelper.reloadLib(libName);
|
||||
ok($.mobile.gradeA());
|
||||
});
|
||||
|
||||
$.testHelper.reloadLib(libName);
|
||||
});
|
||||
test( "loading the core library triggers mobilinit on the document", function(){
|
||||
expect( 1 );
|
||||
|
||||
test( "enhancments are skipped when the browser is not grade A", function(){
|
||||
setGradeA(false);
|
||||
$.testHelper.reloadLib(libName);
|
||||
$(window.document).bind('mobileinit', function(event){
|
||||
ok(true);
|
||||
});
|
||||
|
||||
//NOTE easiest way to check for enhancements, not the most obvious
|
||||
ok(!$("html").hasClass("ui-mobile"));
|
||||
});
|
||||
|
||||
test( "enhancments are added when the browser is grade A", function(){
|
||||
setGradeA(true);
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
ok($("html").hasClass("ui-mobile"));
|
||||
});
|
||||
|
||||
|
||||
//TODO lots of duplication
|
||||
test( "pageLoading doesn't add the dialog to the page when loading message is false", function(){
|
||||
$.testHelper.alterExtend({loadingMessage: false});
|
||||
$.testHelper.reloadLib(libName);
|
||||
$.mobile.pageLoading(false);
|
||||
ok(!$(".ui-loader").length);
|
||||
});
|
||||
|
||||
test( "pageLoading doesn't add the dialog to the page when done is passed as true", function(){
|
||||
$.testHelper.alterExtend({loadingMessage: true});
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
// TODO add post reload callback
|
||||
$('.ui-loader').remove();
|
||||
|
||||
$.mobile.pageLoading(true);
|
||||
ok(!$(".ui-loader").length);
|
||||
});
|
||||
|
||||
test( "pageLoading adds the dialog to the page when done is true", function(){
|
||||
$.testHelper.alterExtend({loadingMessage: true});
|
||||
$.testHelper.reloadLib(libName);
|
||||
$.mobile.pageLoading(false);
|
||||
ok($(".ui-loader").length);
|
||||
});
|
||||
|
||||
var metaViewportSelector = "head meta[name=viewport]",
|
||||
setViewPortContent = function(value){
|
||||
$(metaViewportSelector).remove();
|
||||
$.testHelper.alterExtend({metaViewportContent: value});
|
||||
$.testHelper.reloadLib(libName);
|
||||
};
|
||||
|
||||
test( "meta view port element is added to head when defined on mobile", function(){
|
||||
setViewPortContent("width=device-width");
|
||||
same($(metaViewportSelector).length, 1);
|
||||
});
|
||||
|
||||
test( "meta view port element not added to head when not defined on mobile", function(){
|
||||
setViewPortContent(false);
|
||||
same($(metaViewportSelector).length, 0);
|
||||
});
|
||||
|
||||
var findFirstPage = function() {
|
||||
return $("[data-role='page']").first();
|
||||
};
|
||||
|
||||
test( "active page and start page should be set to the fist page in the selected set", function(){
|
||||
var firstPage = findFirstPage();
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
same($.mobile.startPage, firstPage);
|
||||
same($.mobile.activePage, firstPage);
|
||||
});
|
||||
|
||||
test( "mobile viewport class is defined on the first page's parent", function(){
|
||||
var firstPage = findFirstPage();
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
ok(firstPage.parent().hasClass('ui-mobile-viewport'));
|
||||
});
|
||||
|
||||
test( "mobile page container is the first page's parent", function(){
|
||||
var firstPage = findFirstPage();
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
same($.mobile.pageContainer, firstPage.parent());
|
||||
});
|
||||
|
||||
test( "page loading is called on document ready", function(){
|
||||
expect( 2 );
|
||||
|
||||
$.testHelper.alterExtend({ pageLoading: function(){
|
||||
ok("called");
|
||||
}});
|
||||
|
||||
$.testHelper.reloadLib(libName);
|
||||
});
|
||||
|
||||
test( "hashchange triggered on document ready with single argument: true", function(){
|
||||
expect( 2 );
|
||||
|
||||
$(window).bind("hashchange", function(ev, arg){
|
||||
same(arg, true);
|
||||
$.testHelper.reloadLib(libName);
|
||||
});
|
||||
|
||||
$.testHelper.reloadLib(libName);
|
||||
});
|
||||
test( "enhancments are skipped when the browser is not grade A", function(){
|
||||
setGradeA(false);
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
//TODO test that silentScroll is called on window load
|
||||
});
|
||||
//NOTE easiest way to check for enhancements, not the most obvious
|
||||
ok(!$("html").hasClass("ui-mobile"));
|
||||
});
|
||||
|
||||
test( "enhancments are added when the browser is grade A", function(){
|
||||
setGradeA(true);
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
ok($("html").hasClass("ui-mobile"));
|
||||
});
|
||||
|
||||
|
||||
//TODO lots of duplication
|
||||
test( "pageLoading doesn't add the dialog to the page when loading message is false", function(){
|
||||
$.testHelper.alterExtend({loadingMessage: false});
|
||||
$.testHelper.reloadLib(libName);
|
||||
$.mobile.pageLoading(false);
|
||||
ok(!$(".ui-loader").length);
|
||||
});
|
||||
|
||||
test( "pageLoading doesn't add the dialog to the page when done is passed as true", function(){
|
||||
$.testHelper.alterExtend({loadingMessage: true});
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
// TODO add post reload callback
|
||||
$('.ui-loader').remove();
|
||||
|
||||
$.mobile.pageLoading(true);
|
||||
ok(!$(".ui-loader").length);
|
||||
});
|
||||
|
||||
test( "pageLoading adds the dialog to the page when done is true", function(){
|
||||
$.testHelper.alterExtend({loadingMessage: true});
|
||||
$.testHelper.reloadLib(libName);
|
||||
$.mobile.pageLoading(false);
|
||||
ok($(".ui-loader").length);
|
||||
});
|
||||
|
||||
var metaViewportSelector = "head meta[name=viewport]",
|
||||
setViewPortContent = function(value){
|
||||
$(metaViewportSelector).remove();
|
||||
$.testHelper.alterExtend({metaViewportContent: value});
|
||||
$.testHelper.reloadLib(libName);
|
||||
};
|
||||
|
||||
test( "meta view port element is added to head when defined on mobile", function(){
|
||||
setViewPortContent("width=device-width");
|
||||
same($(metaViewportSelector).length, 1);
|
||||
});
|
||||
|
||||
test( "meta view port element not added to head when not defined on mobile", function(){
|
||||
setViewPortContent(false);
|
||||
same($(metaViewportSelector).length, 0);
|
||||
});
|
||||
|
||||
var findFirstPage = function() {
|
||||
return $("[data-role='page']").first();
|
||||
};
|
||||
|
||||
test( "active page and start page should be set to the fist page in the selected set", function(){
|
||||
var firstPage = findFirstPage();
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
same($.mobile.startPage, firstPage);
|
||||
same($.mobile.activePage, firstPage);
|
||||
});
|
||||
|
||||
test( "mobile viewport class is defined on the first page's parent", function(){
|
||||
var firstPage = findFirstPage();
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
ok(firstPage.parent().hasClass('ui-mobile-viewport'));
|
||||
});
|
||||
|
||||
test( "mobile page container is the first page's parent", function(){
|
||||
var firstPage = findFirstPage();
|
||||
$.testHelper.reloadLib(libName);
|
||||
|
||||
same($.mobile.pageContainer, firstPage.parent());
|
||||
});
|
||||
|
||||
test( "page loading is called on document ready", function(){
|
||||
$.testHelper.alterExtend({ pageLoading: function(){
|
||||
start();
|
||||
ok("called");
|
||||
}});
|
||||
|
||||
stop();
|
||||
$.testHelper.reloadLib(libName);
|
||||
});
|
||||
|
||||
test( "hashchange triggered on document ready with single argument: true", function(){
|
||||
$(window).bind("hashchange", function(ev, arg){
|
||||
same(arg, true);
|
||||
start();
|
||||
});
|
||||
|
||||
stop();
|
||||
$.testHelper.reloadLib(libName);
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
18
tests/unit/core/core_mobileinit.js
Normal file
18
tests/unit/core/core_mobileinit.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* mobile core unit tests
|
||||
*/
|
||||
|
||||
(function($){
|
||||
var mobilePage = undefined;
|
||||
module('jquery.mobile.core.js');
|
||||
|
||||
// NOTE important to use $.fn.one here to make sure library reloads don't fire
|
||||
// the event before the test check below
|
||||
$(document).one("mobileinit", function(){
|
||||
mobilePage = $.mobile.page;
|
||||
});
|
||||
|
||||
test( "mobile.page is available when mobile init is fired", function(){
|
||||
ok(mobilePage !== undefined, "$.mobile.page is defined");
|
||||
});
|
||||
})(jQuery);
|
||||
|
|
@ -2,71 +2,75 @@
|
|||
* mobile core unit tests
|
||||
*/
|
||||
|
||||
var libName = "jquery.mobile.core.js",
|
||||
scrollTimeout = 20, // TODO expose timing as an attribute
|
||||
scrollStartEnabledTimeout = 150;
|
||||
(function($){
|
||||
var libName = "jquery.mobile.core.js",
|
||||
scrollTimeout = 20, // TODO expose timing as an attribute
|
||||
scrollStartEnabledTimeout = 150;
|
||||
|
||||
module(libName, {
|
||||
setup: function(){
|
||||
$("<div id='scroll-testing' style='height: 1000px'></div>").appendTo("body");
|
||||
},
|
||||
module(libName, {
|
||||
setup: function(){
|
||||
$("<div id='scroll-testing' style='height: 1000px'></div>").appendTo("body");
|
||||
},
|
||||
|
||||
teardown: function(){
|
||||
$("#scroll-testing").remove();
|
||||
}
|
||||
});
|
||||
teardown: function(){
|
||||
$("#scroll-testing").remove();
|
||||
}
|
||||
});
|
||||
|
||||
var scrollUp = function( pos ){
|
||||
$(window).scrollTop(1000);
|
||||
ok($(window).scrollTop() > 0);
|
||||
var scrollUp = function( pos ){
|
||||
$(window).scrollTop(1000);
|
||||
ok($(window).scrollTop() > 0);
|
||||
|
||||
if(pos) {
|
||||
$.mobile.silentScroll(pos);
|
||||
} else {
|
||||
$.mobile.silentScroll();
|
||||
}
|
||||
};
|
||||
if(pos) {
|
||||
$.mobile.silentScroll(pos);
|
||||
} else {
|
||||
$.mobile.silentScroll();
|
||||
}
|
||||
};
|
||||
|
||||
test( "silent scroll scrolls the page to the top by default", function(){
|
||||
scrollUp();
|
||||
test( "silent scroll scrolls the page to the top by default", function(){
|
||||
scrollUp();
|
||||
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
same($(window).scrollTop(), 0);
|
||||
start();
|
||||
}, scrollTimeout);
|
||||
});
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
same($(window).scrollTop(), 0);
|
||||
start();
|
||||
}, scrollTimeout);
|
||||
});
|
||||
|
||||
test( "silent scroll scrolls the page to the passed y position", function(){
|
||||
var pos = 10;
|
||||
scrollUp(pos);
|
||||
test( "silent scroll scrolls the page to the passed y position", function(){
|
||||
var pos = 10;
|
||||
scrollUp(pos);
|
||||
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
same($(window).scrollTop(), pos);
|
||||
start();
|
||||
}, scrollTimeout);
|
||||
});
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
same($(window).scrollTop(), pos);
|
||||
start();
|
||||
}, scrollTimeout);
|
||||
});
|
||||
|
||||
// NOTE may be brittle depending on timing
|
||||
test( "silent scroll takes at least 20 ms to scroll to the top", function(){
|
||||
scrollUp();
|
||||
// NOTE may be brittle depending on timing
|
||||
test( "silent scroll takes at least 20 ms to scroll to the top", function(){
|
||||
scrollUp();
|
||||
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
ok($(window).scrollTop() != 0);
|
||||
start();
|
||||
}, scrollTimeout - 1);
|
||||
});
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
ok($(window).scrollTop() != 0);
|
||||
start();
|
||||
}, scrollTimeout - 1);
|
||||
});
|
||||
|
||||
test( "scrolling marks scrollstart as disabled for 150 ms", function(){
|
||||
$.event.special.scrollstart.enabled = true;
|
||||
scrollUp();
|
||||
ok(!$.event.special.scrollstart.enabled);
|
||||
test( "scrolling marks scrollstart as disabled for 150 ms", function(){
|
||||
$.event.special.scrollstart.enabled = true;
|
||||
scrollUp();
|
||||
ok(!$.event.special.scrollstart.enabled);
|
||||
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
ok($.event.special.scrollstart.enabled);
|
||||
start();
|
||||
}, scrollStartEnabledTimeout);
|
||||
});
|
||||
stop();
|
||||
setTimeout(function(){
|
||||
ok($.event.special.scrollstart.enabled);
|
||||
start();
|
||||
}, scrollStartEnabledTimeout);
|
||||
});
|
||||
|
||||
//TODO test that silentScroll is called on window load
|
||||
})(jQuery);
|
||||
|
|
|
|||
|
|
@ -5,27 +5,13 @@
|
|||
<title>jQuery Mobile Core Test Suite</title>
|
||||
|
||||
<script type="text/javascript" src="../../../js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../../../tests/jquery.testHelper.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.ui.widget.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.widget.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.media.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.support.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.event.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.core.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.page.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.ui.position.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.fixHeaderFooter.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.forms.checkboxradio.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.forms.textinput.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.forms.select.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.buttonMarkup.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.forms.button.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.forms.slider.js"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.controlGroup.js"></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../../../external/qunit.css" type="text/css"/>
|
||||
<script type="text/javascript" src="../../../external/qunit.js"></script>
|
||||
<script type="text/javascript" src="core_mobileinit.js"></script>
|
||||
<script type="text/javascript" src="../../../js/"></script>
|
||||
<script type="text/javascript" src="../../../js/jquery.mobile.core.js"></script>
|
||||
<script type="text/javascript" src="../../jquery.testHelper.js"></script>
|
||||
<link rel="stylesheet" href="../../../themes/default" />
|
||||
<link rel="stylesheet" href="../../../external/qunit.css" type="text/css"/>
|
||||
|
||||
<script type="text/javascript" src="core.js"></script>
|
||||
<script type="text/javascript" src="core_scroll.js"></script>
|
||||
|
|
|
|||
|
|
@ -37,16 +37,24 @@
|
|||
|
||||
same(called, 2, "change page should be called twice");
|
||||
});
|
||||
|
||||
test( "check for external link succeeds", function(){
|
||||
same($.mobile.isExternalLink("<a href='mailto:'></a>"), true, "mailto");
|
||||
same($.mobile.isExternalLink("<a href='http://foo.com'></a>"), true, "http protocol");
|
||||
same($.mobile.isExternalLink("<a href='foo' rel='external'></a>"), true, "rel=external");
|
||||
same($.mobile.isExternalLink("<a href='foo' target='foo'></a>"), true, "target");
|
||||
|
||||
test( "path.get method is working properly", function(){
|
||||
same($.mobile.path.get(), window.location.hash, "get method returns location.hash");
|
||||
same($.mobile.path.get( "#foo/bar/baz.html" ), "foo/bar/", "get method with hash arg returns path with no filename or hash prefix");
|
||||
same($.mobile.path.get( "#foo/bar/baz.html/" ), "foo/bar/baz.html/", "last segment of hash is retained if followed by a trailing slash");
|
||||
});
|
||||
|
||||
test( "check for external link fails", function(){
|
||||
same($.mobile.isExternalLink("<a href='foo.html'></a>"), false, "mailto");
|
||||
same($.mobile.isExternalLink("<a href='#foo'></a>"), false, "mailto");
|
||||
test( "path.isExternal method is working properly", function(){
|
||||
same($.mobile.path.isExternal("mailto:"), true, "mailto protocol");
|
||||
same($.mobile.path.isExternal("http://foo.com"), true, "http protocol");
|
||||
same($.mobile.path.isExternal("http://www.foo.com"), true, "http protocol with www");
|
||||
same($.mobile.path.isExternal("tel:16178675309"), true, "tel protocol");
|
||||
same($.mobile.path.isExternal("foo.html"), false, "filename");
|
||||
same($.mobile.path.isExternal("foo/foo/foo.html"), false, "file path");
|
||||
same($.mobile.path.isExternal("../../index.html"), false, "relative parent path");
|
||||
same($.mobile.path.isExternal("/foo"), false, "root-relative path");
|
||||
same($.mobile.path.isExternal("foo"), false, "simple string");
|
||||
same($.mobile.path.isExternal("#foo"), false, "local id reference");
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
Loading…
Reference in a new issue