From 58a03e9dfb97eaeb6b41ef4ddd281fafec637c1a Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Thu, 20 Mar 2014 17:00:25 +0200 Subject: [PATCH 1/6] Navigation: Expect a trailing slash when testing path.getLocation() --- tests/unit/path/path_core.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/path/path_core.js b/tests/unit/path/path_core.js index 357d6b644ef..636a5d9ddb6 100644 --- a/tests/unit/path/path_core.js +++ b/tests/unit/path/path_core.js @@ -239,9 +239,9 @@ 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:// Date: Wed, 19 Mar 2014 17:59:05 +0200 Subject: [PATCH 2/6] Navigation: Do not assume "//" is always part of an absolute URL Note: this does indeed represent a fix for gh-6574, but only once a version of Cordova sporting https://github.com/apache/cordova-wp8/pull/30 is released. Closes gh-6597 Fixes gh-6574 Fixes gh-6599 --- js/init.js | 4 +++- js/navigation/base.js | 5 +++-- js/navigation/path.js | 22 +++++++++++++++++----- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/js/init.js b/js/init.js index 9ba79bb9366..a1f2e2e71db 100644 --- a/js/init.js +++ b/js/init.js @@ -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 @@ -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 ); } }); diff --git a/js/navigation/base.js b/js/navigation/base.js index 26ab6f755a6..7432ce9c726 100644 --- a/js/navigation/base.js +++ b/js/navigation/base.js @@ -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 ); diff --git a/js/navigation/path.js b/js/navigation/path.js index 40d52bf0f3b..bff85c35a45 100644 --- a/js/navigation/path.js +++ b/js/navigation/path.js @@ -41,19 +41,31 @@ 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; + + // Always use our own URL parser, even though location potentially provides all the + // fields we may need later on. This way, URL parsing is consistent, and we only + // grab location.href from the browser. + var uri = this.parseUrl( url || location.href ), + hash = uri.hash; // mimic the browser with an empty string when the hash is empty hash = hash === "#" ? "" : hash; + // 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 "/". + if ( uri.protocol !== "" && uri.pathname.substring( 0, 1 ) !== "/" ) { + uri.pathname = "/" + uri.pathname; + uri.directory = "/" + uri.directory; + } + // 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 + uri.doubleSlash + uri.host + uri.pathname + uri.search + hash; }, //return the original document url @@ -323,7 +335,7 @@ 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; } From a61435f653518ea15730d1709ce25a1cfdffc105 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Thu, 20 Mar 2014 22:14:27 +0200 Subject: [PATCH 3/6] Navigation: Test authority-less protocols with path.getLocation() --- tests/unit/path/path_core.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/path/path_core.js b/tests/unit/path/path_core.js index 636a5d9ddb6..4c2724b63ca 100644 --- a/tests/unit/path/path_core.js +++ b/tests/unit/path/path_core.js @@ -242,6 +242,8 @@ 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:// Date: Fri, 25 Apr 2014 09:36:48 +0300 Subject: [PATCH 4/6] Navigation: Remove getLocation() comment --- js/navigation/path.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/js/navigation/path.js b/js/navigation/path.js index bff85c35a45..4441c850be7 100644 --- a/js/navigation/path.js +++ b/js/navigation/path.js @@ -44,10 +44,6 @@ define([ // 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 ) { - - // Always use our own URL parser, even though location potentially provides all the - // fields we may need later on. This way, URL parsing is consistent, and we only - // grab location.href from the browser. var uri = this.parseUrl( url || location.href ), hash = uri.hash; From abbd4626bbc0a94b602af52dd4eadbf213c9b233 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Sat, 26 Apr 2014 00:41:07 +0300 Subject: [PATCH 5/6] Navigation: Revert to using location as much as possible --- js/navigation/path.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/js/navigation/path.js b/js/navigation/path.js index 4441c850be7..5e43d90f330 100644 --- a/js/navigation/path.js +++ b/js/navigation/path.js @@ -44,24 +44,28 @@ define([ // 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 = this.parseUrl( url || location.href ), - hash = uri.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; - // 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 "/". - if ( uri.protocol !== "" && uri.pathname.substring( 0, 1 ) !== "/" ) { - uri.pathname = "/" + uri.pathname; - uri.directory = "/" + uri.directory; - } - - // 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.doubleSlash + 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 From 0cb8fc646c04eb97b45ce98c4b34c7db59479f16 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Wed, 21 May 2014 15:27:32 +0300 Subject: [PATCH 6/6] Navigation: Shortening lines in path.js below 100 chars --- js/navigation/path.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/js/navigation/path.js b/js/navigation/path.js index 5e43d90f330..f2b28dc52c2 100644 --- a/js/navigation/path.js +++ b/js/navigation/path.js @@ -47,9 +47,10 @@ define([ 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 + // 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 @@ -59,10 +60,12 @@ define([ 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 ) !== "/" ) ? "/" : "" ) + + // 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; @@ -335,7 +338,8 @@ define([ // reconstruct each of the pieces with the new search string and hash href = path.parseUrl( href ); - href = href.protocol + href.doubleSlash + href.host + href.pathname + search + preservedHash; + href = href.protocol + href.doubleSlash + href.host + href.pathname + search + + preservedHash; } else { href += href.indexOf( "#" ) > -1 ? uiState : "#" + uiState; }