Skip to content

Commit 3ba388e

Browse files
committed
- Moved the global link hijacking callback back to "click".
- Refactored out the href/url calculation code from our hijacking callback into a utility function getAjaxUrlForLink(). - Added a touchend handler so we can catch link clicks and call preventDefault() to stop the iOS location bar from dropping down. - Removed the $.mobile.useFastClick option.
1 parent e0042cf commit 3ba388e

File tree

2 files changed

+84
-68
lines changed

2 files changed

+84
-68
lines changed

js/jquery.mobile.core.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@
3333
//automatically handle clicks and form submissions through Ajax, when same-domain
3434
ajaxEnabled: true,
3535

36-
//When enabled, clicks and taps that result in Ajax page changes will happen slightly sooner on touch devices.
37-
//Also, it will prevent the address bar from appearing on platforms like iOS during page transitions.
38-
//This option has no effect on non-touch devices, but enabling it may interfere with jQuery plugins that bind to click events
39-
useFastClick: true,
40-
4136
//automatically load and show pages based on location.hash
4237
hashListeningEnabled: true,
4338

@@ -144,6 +139,7 @@
144139
return this.removeData( $.mobile.nsNormalize(prop) );
145140
};
146141

142+
147143
$.jqmRemoveData = function( elem, prop ){
148144
return $.removeData( elem, $.mobile.nsNormalize(prop) );
149145
};

js/jquery.mobile.navigation.js

Lines changed: 83 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,13 @@
371371
}
372372

373373
//remove active classes after page transition or error
374-
function removeActiveLinkClass( forceRemoval ) {
375-
if( !!$activeClickedLink && ( !$activeClickedLink.closest( '.ui-page-active' ).length || forceRemoval ) ) {
374+
function removeActiveLinkClass( forceRemoval, delay ) {
375+
if ( delay ) {
376+
setTimeout( function() { removeActiveLinkClass( forceRemoval ); }, delay );
377+
return;
378+
}
379+
380+
if( !!$activeClickedLink && ( forceRemoval || !$activeClickedLink.closest( '.ui-page-active' ).length ) ) {
376381
$activeClickedLink.removeClass( $.mobile.activeBtnClass );
377382
}
378383
$activeClickedLink = null;
@@ -582,6 +587,9 @@
582587
// within the same domain as the document base, it is the site relative
583588
// path. For cross-domain pages (Phone Gap only) the entire absolute Url
584589
// used to load the page.
590+
591+
592+
585593
dataUrl = path.convertUrlToDataUrl( absUrl );
586594

587595
// Make sure we have a pageContainer to work with.
@@ -988,94 +996,106 @@
988996
event.preventDefault();
989997
});
990998

999+
function getAjaxUrlForLink( $link ) {
1000+
var url = undefined;
1001+
if ( $.mobile.ajaxEnabled ) {
1002+
var baseUrl = getClosestBaseUrl( $link ),
1003+
1004+
//get href, if defined, otherwise default to empty hash
1005+
url = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl );
1006+
1007+
// XXX_jblas: Ideally links to application pages should be specified as
1008+
// an url to the application document with a hash that is either
1009+
// the site relative path or id to the page. But some of the
1010+
// internal code that dynamically generates sub-pages for nested
1011+
// lists and select dialogs, just write a hash in the link they
1012+
// create. This means the actual URL path is based on whatever
1013+
// the current value of the base tag is at the time this code
1014+
// is called. For now we are just assuming that any url with a
1015+
// hash in it is an application page reference.
1016+
if ( url.search( "#" ) != -1 ) {
1017+
url = url.replace( /[^#]*#/, "" );
1018+
if ( url ) {
1019+
if ( path.isPath( url ) ) {
1020+
//we have apath so make it the href we want to load.
1021+
url = path.makeUrlAbsolute( href, baseUrl );
1022+
} else {
1023+
//we have a simple id so use the documentUrl as its base.
1024+
href = path.makeUrlAbsolute( "#" + url, documentUrl.hrefNoHash );
1025+
}
1026+
}
1027+
}
1028+
1029+
var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ),
1030+
1031+
// Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR
1032+
// requests if the document doing the request was loaded via the file:// protocol.
1033+
// This is usually to allow the application to "phone home" and fetch app specific
1034+
// data. We normally let the browser handle external/cross-domain urls, but if the
1035+
// allowCrossDomainPages option is true, we will allow cross-domain http/https
1036+
// requests to go through our page loading logic.
1037+
isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && url.search( /^https?:/ ) != -1 ),
1038+
1039+
//check for protocol or rel and its not an embedded page
1040+
//TODO overlap in logic from isExternal, rel=external check should be
1041+
// moved into more comprehensive isExternalLink
1042+
isExternal = useDefaultUrlHandling || ( !isCrossDomainPageLoad) && path.isExternal( url );
1043+
1044+
if ( isExternal ) {
1045+
url = undefined;
1046+
}
1047+
}
1048+
return url;
1049+
}
1050+
1051+
$( document ).bind( "touchend", function( event ) {
1052+
var link = findClosestLink( event.target );
1053+
if ( link ) {
1054+
var url = getAjaxUrlForLink( $( link ) );
1055+
if ( url && url.replace( /[^#]*#/, "" ) ) {
1056+
event.preventDefault();
1057+
}
1058+
}
1059+
});
1060+
9911061
//add active state on vclick
9921062
$( document ).bind( "vclick", function( event ) {
9931063
var link = findClosestLink( event.target );
9941064
if ( link ) {
9951065
if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) {
996-
$( link ).closest( ".ui-btn" ).not( ".ui-disabled" ).addClass( $.mobile.activeBtnClass );
1066+
$activeClickedLink = $( link ).closest( ".ui-btn" ).not( ".ui-disabled" ).addClass( $.mobile.activeBtnClass );
9971067
$( "." + $.mobile.activePageClass + " .ui-btn" ).not( link ).blur();
9981068
}
9991069
}
10001070
});
10011071

10021072
// click routing - direct to HTTP or Ajax, accordingly
1003-
$( document ).bind( $.mobile.useFastClick ? "vclick" : "click", function( event ) {
1073+
$( document ).bind( "click", function( event ) {
10041074
var link = findClosestLink( event.target );
10051075
if ( !link ) {
10061076
return;
10071077
}
10081078

1009-
var $link = $( link ),
1010-
//remove active link class if external (then it won't be there if you come back)
1011-
httpCleanup = function(){
1012-
window.setTimeout( function() { removeActiveLinkClass( true ); }, 200 );
1013-
};
1079+
var $link = $( link );
10141080

10151081
//if there's a data-rel=back attr, go back in history
10161082
if( $link.is( ":jqmData(rel='back')" ) ) {
1083+
removeActiveLinkClass( true, 200 );
10171084
window.history.back();
10181085
return false;
10191086
}
1020-
1021-
//if ajax is disabled, exit early
1022-
if( !$.mobile.ajaxEnabled ){
1023-
httpCleanup();
1024-
//use default click handling
1025-
return;
1026-
}
1027-
1028-
var baseUrl = getClosestBaseUrl( $link ),
10291087

1030-
//get href, if defined, otherwise default to empty hash
1031-
href = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl );
1032-
1033-
// XXX_jblas: Ideally links to application pages should be specified as
1034-
// an url to the application document with a hash that is either
1035-
// the site relative path or id to the page. But some of the
1036-
// internal code that dynamically generates sub-pages for nested
1037-
// lists and select dialogs, just write a hash in the link they
1038-
// create. This means the actual URL path is based on whatever
1039-
// the current value of the base tag is at the time this code
1040-
// is called. For now we are just assuming that any url with a
1041-
// hash in it is an application page reference.
1042-
if ( href.search( "#" ) != -1 ) {
1043-
href = href.replace( /[^#]*#/, "" );
1044-
if ( !href ) {
1088+
var href = getAjaxUrlForLink( $link ),
1089+
hashOrUrl = href && href.replace( /[^#]*#/, "" );
1090+
1091+
if ( !href || !hashOrUrl ) {
1092+
//use default click handling
1093+
if (! hashOrUrl ) {
10451094
//link was an empty hash meant purely
10461095
//for interaction, so we ignore it.
10471096
event.preventDefault();
1048-
return;
1049-
} else if ( path.isPath( href ) ) {
1050-
//we have apath so make it the href we want to load.
1051-
href = path.makeUrlAbsolute( href, baseUrl );
1052-
} else {
1053-
//we have a simple id so use the documentUrl as its base.
1054-
href = path.makeUrlAbsolute( "#" + href, documentUrl.hrefNoHash );
10551097
}
1056-
}
1057-
1058-
// Should we handle this link, or let the browser deal with it?
1059-
var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ),
1060-
1061-
// Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR
1062-
// requests if the document doing the request was loaded via the file:// protocol.
1063-
// This is usually to allow the application to "phone home" and fetch app specific
1064-
// data. We normally let the browser handle external/cross-domain urls, but if the
1065-
// allowCrossDomainPages option is true, we will allow cross-domain http/https
1066-
// requests to go through our page loading logic.
1067-
isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && href.search( /^https?:/ ) != -1 ),
1068-
1069-
//check for protocol or rel and its not an embedded page
1070-
//TODO overlap in logic from isExternal, rel=external check should be
1071-
// moved into more comprehensive isExternalLink
1072-
isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !isCrossDomainPageLoad );
1073-
1074-
$activeClickedLink = $link.closest( ".ui-btn" );
1075-
1076-
if( isExternal ) {
1077-
httpCleanup();
1078-
//use default click handling
1098+
removeActiveLinkClass( true, 200 );
10791099
return;
10801100
}
10811101

0 commit comments

Comments
 (0)