Skip to content

Commit

Permalink
Navigation: Do not assume "//" is always part of an absolute URL
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Schulhof authored and agcolom committed Nov 26, 2014
1 parent dca6002 commit b7b6795
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
4 changes: 3 additions & 1 deletion js/init.js
Expand Up @@ -57,6 +57,7 @@ define([
var path = $.mobile.path,
$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
theLocation = $.mobile.path.parseLocation(),
hashPage = document.getElementById( hash );

// if no pages are found, create one with body's inner html
Expand All @@ -70,7 +71,8 @@ define([

// unless the data url is already set set it to the pathname
if ( !$this[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) ) {
$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname + location.search );
$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) ||
theLocation.pathname + theLocation.search );
}
});

Expand Down
5 changes: 3 additions & 2 deletions js/navigation/base.js
Expand Up @@ -46,13 +46,14 @@ define([
page.find( base.linkSelector ).each(function( i, link ) {
var thisAttr = $( link ).is( "[href]" ) ? "href" :
$( link ).is( "[src]" ) ? "src" : "action",
theLocation = $.mobile.path.parseLocation(),
thisUrl = $( link ).attr( thisAttr );

// XXX_jblas: We need to fix this so that it removes the document
// base URL, and then prepends with the new page URL.
// if full path exists and is same, chop it - helps IE out
thisUrl = thisUrl.replace( location.protocol + "//" +
location.host + location.pathname, "" );
thisUrl = thisUrl.replace( theLocation.protocol + theLocation.doubleSlash +
theLocation.host + theLocation.pathname, "" );

if ( !/^(\w+:|#|\/)/.test( thisUrl ) ) {
$( link ).attr( thisAttr, newPath + thisUrl );
Expand Down
32 changes: 24 additions & 8 deletions js/navigation/path.js
Expand Up @@ -41,19 +41,34 @@ define([
urlParseRE: /^\s*(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,

// Abstraction to address xss (Issue #4787) by removing the authority in
// browsers that auto decode it. All references to location.href should be
// browsers that auto-decode it. All references to location.href should be
// replaced with a call to this method so that it can be dealt with properly here
getLocation: function( url ) {
var uri = url ? this.parseUrl( url ) : location,
hash = this.parseUrl( url || location.href ).hash;
var parsedUrl = this.parseUrl( url || location.href ),
uri = url ? parsedUrl : location,

// Make sure to parse the url or the location object for the hash because using
// location.hash is autodecoded in firefox, the rest of the url should be from
// the object (location unless we're testing) to avoid the inclusion of the
// authority
hash = parsedUrl.hash;

// mimic the browser with an empty string when the hash is empty
hash = hash === "#" ? "" : hash;

// Make sure to parse the url or the location object for the hash because using location.hash
// is autodecoded in firefox, the rest of the url should be from the object (location unless
// we're testing) to avoid the inclusion of the authority
return uri.protocol + "//" + uri.host + uri.pathname + uri.search + hash;
return uri.protocol +
parsedUrl.doubleSlash +
uri.host +

// The pathname must start with a slash if there's a protocol, because you
// can't have a protocol followed by a relative path. Also, it's impossible to
// calculate absolute URLs from relative ones if the absolute one doesn't have
// a leading "/".
( ( uri.protocol !== "" && uri.pathname.substring( 0, 1 ) !== "/" ) ?
"/" : "" ) +
uri.pathname +
uri.search +
hash;
},

//return the original document url
Expand Down Expand Up @@ -323,7 +338,8 @@ define([

// reconstruct each of the pieces with the new search string and hash
href = path.parseUrl( href );
href = href.protocol + "//" + href.host + href.pathname + search + preservedHash;
href = href.protocol + href.doubleSlash + href.host + href.pathname + search +
preservedHash;
} else {
href += href.indexOf( "#" ) > -1 ? uiState : "#" + uiState;
}
Expand Down
8 changes: 5 additions & 3 deletions tests/unit/path/path_core.js
Expand Up @@ -239,9 +239,11 @@

test( "path.getLocation works properly", function() {
equal( $.mobile.path.getLocation("http://example.com/"), "http://example.com/" );
equal( $.mobile.path.getLocation("http://foo@example.com"), "http://example.com" );
equal( $.mobile.path.getLocation("http://foo:bar@example.com"), "http://example.com" );
equal( $.mobile.path.getLocation("http://<foo<:bar@example.com"), "http://example.com" );
equal( $.mobile.path.getLocation("http://foo@example.com/"), "http://example.com/" );
equal( $.mobile.path.getLocation("http://foo:bar@example.com/"), "http://example.com/" );
equal( $.mobile.path.getLocation("http://<foo<:bar@example.com/"), "http://example.com/" );
equal( $.mobile.path.getLocation("x-wmapp0:www/index.html" ), "x-wmapp0:/www/index.html" );
equal( $.mobile.path.getLocation("qrc:/index.html" ), "qrc:/index.html" );

var allUriParts = "http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content";

Expand Down

0 comments on commit b7b6795

Please sign in to comment.