From 70bba7064a52b5cb0b7842b8513b58beb6f33755 Mon Sep 17 00:00:00 2001 From: scottjehl Date: Fri, 22 Oct 2010 12:31:00 -0400 Subject: [PATCH] Added a support test $.support.dynamicBaseTag and workaround for browsers that don't support dynamically updating BASE tag (Firefox is the only one I've seen so far. In those browsers, when a new page is fetched, any elements with href and src attributes will have their attribute prefixed with a proper base url (if they don't already start with an external site http address, "/", "#", or any protocol such as "mailto:, etc). In the process, the BASE element and related functions are only implemented if that support is true, and BASE urls now use a full URL path when set, to avoid issues with browsers that may need that. Fixes #263, Fixes #221 --- js/jquery.mobile.js | 32 ++++++++++++++++++++++++++------ js/jquery.mobile.support.js | 11 +++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/js/jquery.mobile.js b/js/jquery.mobile.js index 6b9ad04c..b877c35a 100644 --- a/js/jquery.mobile.js +++ b/js/jquery.mobile.js @@ -58,7 +58,8 @@ focusable = "[tabindex],a,button:visible,select:visible,input", nextPageRole = null, hashListener = true, - unHashedSelectors = '[data-rel=dialog]'; + unHashedSelectors = '[data-rel=dialog]', + baseUrl = location.protocol + '//' + location.host + location.pathname; // TODO: don't expose (temporary during code reorg) $.mobile.urlStack = urlStack; @@ -94,13 +95,13 @@ return newBaseURL; } - function setBaseURL( nonHashPath ){ + var setBaseURL = !$.support.dynamicBaseTag ? $.noop : function( nonHashPath ){ //set base url for new page assets - $('#ui-base').attr('href', getBaseURL( nonHashPath )); + $('#ui-base').attr('href', baseUrl + getBaseURL( nonHashPath )); } - function resetBaseURL(){ - $('#ui-base').attr('href', location.pathname); + var resetBaseURL = !$.support.dynamicBaseTag ? $.noop : function(){ + $('#ui-base').attr('href', baseUrl); } @@ -306,6 +307,24 @@ all.get(0).innerHTML = html; to = all.find('[data-role="page"]'); + //rewrite src and href attrs to use a base url + if( !$.support.dynamicBaseTag ){ + var baseUrl = getBaseURL(fileUrl); + to.find('[src],[href]').each(function(){ + var thisHref = $(this).attr('href'), + thisSrc = $(this).attr('src'), + thisAttr = thisHref ? 'href' : 'src', + thisUrl = thisHref || thisSrc; + + //if full path exists and is same, chop it - helps IE out + thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' ); + + if( !/^(\w+:|#|\/)/.test(thisUrl) ){ + $(this).attr(thisAttr, baseUrl + thisUrl); + } + }); + } + //preserve ID on a retrieved page if ( to.attr('id') ) { to = wrapNewPage( to ); @@ -381,9 +400,10 @@ $html.addClass('ui-mobile'); //insert mobile meta - these will need to be configurable somehow. + var headPrepends = $head.prepend( '' + - '' + ($.support.dynamicBaseTag ? '' : '') ); //set base href to pathname diff --git a/js/jquery.mobile.support.js b/js/jquery.mobile.support.js index bf1ce4f5..a489be1f 100644 --- a/js/jquery.mobile.support.js +++ b/js/jquery.mobile.support.js @@ -42,6 +42,17 @@ function propExists( prop ){ } }; +//test for dynamic-updating base tag support (allows us to avoid href,src attr rewriting) +function baseTagTest(){ + var fauxBase = location.protocol + '//' + location.host + location.pathname + "ui-dir/", + base = $("", {"href": fauxBase}).appendTo("head"), + link = $( "" ).prependTo( fakeBody ); + $.support.dynamicBaseTag = !!link[0].href.match(fauxBase); + base.remove(); +}; + +baseTagTest(); + $.extend( $.support, { orientation: "orientation" in window, touch: "ontouchend" in document,