Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

Commit ecd5be5

Browse files
author
Gabriel Schulhof
committed
Navigation: Do not assume "//" is always part of an absolute URL
(cherry picked from commit 9e082b0) Closes gh-6597 Fixes gh-6574 Fixes gh-6599
1 parent dca0976 commit ecd5be5

File tree

4 files changed

+35
-14
lines changed

4 files changed

+35
-14
lines changed

js/jquery.mobile.init.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ define([
5757
var path = $.mobile.path,
5858
$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
5959
hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
60+
theLocation = $.mobile.path.parseLocation(),
6061
hashPage = document.getElementById( hash );
6162

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

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

js/navigation/base.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ define([
4646
page.find( base.linkSelector ).each(function( i, link ) {
4747
var thisAttr = $( link ).is( "[href]" ) ? "href" :
4848
$( link ).is( "[src]" ) ? "src" : "action",
49+
theLocation = $.mobile.path.parseLocation(),
4950
thisUrl = $( link ).attr( thisAttr );
5051

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

5758
if ( !/^(\w+:|#|\/)/.test( thisUrl ) ) {
5859
$( link ).attr( thisAttr, newPath + thisUrl );

js/navigation/path.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,34 @@ define([
4141
urlParseRE: /^\s*(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
4242

4343
// Abstraction to address xss (Issue #4787) by removing the authority in
44-
// browsers that auto decode it. All references to location.href should be
44+
// browsers that auto-decode it. All references to location.href should be
4545
// replaced with a call to this method so that it can be dealt with properly here
4646
getLocation: function( url ) {
47-
var uri = url ? this.parseUrl( url ) : location,
48-
hash = this.parseUrl( url || location.href ).hash;
47+
var parsedUrl = this.parseUrl( url || location.href ),
48+
uri = url ? parsedUrl : location,
49+
50+
// Make sure to parse the url or the location object for the hash because using
51+
// location.hash is autodecoded in firefox, the rest of the url should be from
52+
// the object (location unless we're testing) to avoid the inclusion of the
53+
// authority
54+
hash = parsedUrl.hash;
4955

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

53-
// Make sure to parse the url or the location object for the hash because using location.hash
54-
// is autodecoded in firefox, the rest of the url should be from the object (location unless
55-
// we're testing) to avoid the inclusion of the authority
56-
return uri.protocol + "//" + uri.host + uri.pathname + uri.search + hash;
59+
return uri.protocol +
60+
parsedUrl.doubleSlash +
61+
uri.host +
62+
63+
// The pathname must start with a slash if there's a protocol, because you
64+
// can't have a protocol followed by a relative path. Also, it's impossible to
65+
// calculate absolute URLs from relative ones if the absolute one doesn't have
66+
// a leading "/".
67+
( ( uri.protocol !== "" && uri.pathname.substring( 0, 1 ) !== "/" ) ?
68+
"/" : "" ) +
69+
uri.pathname +
70+
uri.search +
71+
hash;
5772
},
5873

5974
//return the original document url
@@ -323,7 +338,8 @@ define([
323338

324339
// reconstruct each of the pieces with the new search string and hash
325340
href = path.parseUrl( href );
326-
href = href.protocol + "//" + href.host + href.pathname + search + preservedHash;
341+
href = href.protocol + href.doubleSlash + href.host + href.pathname + search +
342+
preservedHash;
327343
} else {
328344
href += href.indexOf( "#" ) > -1 ? uiState : "#" + uiState;
329345
}

tests/unit/path/path_core.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,11 @@
239239

240240
test( "path.getLocation works properly", function() {
241241
equal( $.mobile.path.getLocation("http://example.com/"), "http://example.com/" );
242-
equal( $.mobile.path.getLocation("http://foo@example.com"), "http://example.com" );
243-
equal( $.mobile.path.getLocation("http://foo:bar@example.com"), "http://example.com" );
244-
equal( $.mobile.path.getLocation("http://<foo<:bar@example.com"), "http://example.com" );
242+
equal( $.mobile.path.getLocation("http://foo@example.com/"), "http://example.com/" );
243+
equal( $.mobile.path.getLocation("http://foo:bar@example.com/"), "http://example.com/" );
244+
equal( $.mobile.path.getLocation("http://<foo<:bar@example.com/"), "http://example.com/" );
245+
equal( $.mobile.path.getLocation("x-wmapp0:www/index.html" ), "x-wmapp0:/www/index.html" );
246+
equal( $.mobile.path.getLocation("qrc:/index.html" ), "qrc:/index.html" );
245247

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

0 commit comments

Comments
 (0)