aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng/location.js
diff options
context:
space:
mode:
authorMisko Hevery2012-06-13 15:37:52 -0700
committerIgor Minar2012-06-14 10:48:56 -0700
commit6593a3e0823f3c08079f05010f9628fc4503cd43 (patch)
tree9d8cd01b9c469e18d2b1d694cbc09eb80b1b7b22 /src/ng/location.js
parent0f44964e5e0f7e37d7fa3216bb10fd61fbf52ae2 (diff)
downloadangular.js-6593a3e0823f3c08079f05010f9628fc4503cd43.tar.bz2
fix($location): fix URL interception in hash-bang mode
Closes #1051
Diffstat (limited to 'src/ng/location.js')
-rw-r--r--src/ng/location.js96
1 files changed, 65 insertions, 31 deletions
diff --git a/src/ng/location.js b/src/ng/location.js
index b5f10293..727a0c2b 100644
--- a/src/ng/location.js
+++ b/src/ng/location.js
@@ -23,6 +23,10 @@ function encodePath(path) {
return segments.join('/');
}
+function stripHash(url) {
+ return url.split('#')[0];
+}
+
function matchUrl(url, obj) {
var match = URL_MATCH.exec(url);
@@ -102,19 +106,19 @@ function convertToHashbangUrl(url, basePath, hashPrefix) {
* @param {string} url HTML5 url
* @param {string} pathPrefix
*/
-function LocationUrl(url, pathPrefix) {
+function LocationUrl(url, pathPrefix, appBaseUrl) {
pathPrefix = pathPrefix || '';
/**
* Parse given html5 (regular) url string into properties
- * @param {string} url HTML5 url
+ * @param {string} newAbsoluteUrl HTML5 url
* @private
*/
- this.$$parse = function(url) {
- var match = matchUrl(url, this);
+ this.$$parse = function(newAbsoluteUrl) {
+ var match = matchUrl(newAbsoluteUrl, this);
if (match.path.indexOf(pathPrefix) !== 0) {
- throw Error('Invalid url "' + url + '", missing path prefix "' + pathPrefix + '" !');
+ throw Error('Invalid url "' + newAbsoluteUrl + '", missing path prefix "' + pathPrefix + '" !');
}
this.$$path = decodeURIComponent(match.path.substr(pathPrefix.length));
@@ -137,6 +141,14 @@ function LocationUrl(url, pathPrefix) {
pathPrefix + this.$$url;
};
+
+ this.$$rewriteAppUrl = function(absoluteLinkUrl) {
+ if(absoluteLinkUrl.indexOf(appBaseUrl) == 0) {
+ return absoluteLinkUrl;
+ }
+ }
+
+
this.$$parse(url);
}
@@ -149,7 +161,7 @@ function LocationUrl(url, pathPrefix) {
* @param {string} url Legacy url
* @param {string} hashPrefix Prefix for hash part (containing path and search)
*/
-function LocationHashbangUrl(url, hashPrefix) {
+function LocationHashbangUrl(url, hashPrefix, appBaseUrl) {
var basePath;
/**
@@ -192,6 +204,13 @@ function LocationHashbangUrl(url, hashPrefix) {
basePath + (this.$$url ? '#' + hashPrefix + this.$$url : '');
};
+ this.$$rewriteAppUrl = function(absoluteLinkUrl) {
+ if(absoluteLinkUrl.indexOf(appBaseUrl) == 0) {
+ return absoluteLinkUrl;
+ }
+ }
+
+
this.$$parse(url);
}
@@ -380,6 +399,19 @@ LocationUrl.prototype = {
LocationHashbangUrl.prototype = inherit(LocationUrl.prototype);
+function LocationHashbangInHtml5Url(url, hashPrefix, appBaseUrl, baseExtra) {
+ LocationHashbangUrl.apply(this, arguments);
+
+
+ this.$$rewriteAppUrl = function(absoluteLinkUrl) {
+ if (absoluteLinkUrl.indexOf(appBaseUrl) == 0) {
+ return appBaseUrl + baseExtra + '#' + hashPrefix + absoluteLinkUrl.substr(appBaseUrl.length);
+ }
+ }
+}
+
+LocationHashbangInHtml5Url.prototype = inherit(LocationHashbangUrl.prototype);
+
function locationGetter(property) {
return function() {
return this[property];
@@ -479,26 +511,33 @@ function $LocationProvider(){
basePath,
pathPrefix,
initUrl = $browser.url(),
- absUrlPrefix;
+ initUrlParts = matchUrl(initUrl),
+ appBaseUrl;
if (html5Mode) {
basePath = $browser.baseHref() || '/';
pathPrefix = pathPrefixFromBase(basePath);
+ appBaseUrl =
+ composeProtocolHostPort(initUrlParts.protocol, initUrlParts.host, initUrlParts.port) +
+ pathPrefix + '/';
+
if ($sniffer.history) {
$location = new LocationUrl(
convertToHtml5Url(initUrl, basePath, hashPrefix),
- pathPrefix);
+ pathPrefix, appBaseUrl);
} else {
- $location = new LocationHashbangUrl(
+ $location = new LocationHashbangInHtml5Url(
convertToHashbangUrl(initUrl, basePath, hashPrefix),
- hashPrefix);
+ hashPrefix, appBaseUrl, basePath.substr(pathPrefix.length + 1));
}
- // link rewriting
- absUrlPrefix = composeProtocolHostPort(
- $location.protocol(), $location.host(), $location.port()) + pathPrefix;
} else {
- $location = new LocationHashbangUrl(initUrl, hashPrefix);
- absUrlPrefix = $location.absUrl().split('#')[0];
+ appBaseUrl =
+ composeProtocolHostPort(initUrlParts.protocol, initUrlParts.host, initUrlParts.port) +
+ (initUrlParts.path || '') +
+ (initUrlParts.search ? ('?' + initUrlParts.search) : '') +
+ '#' + hashPrefix + '/';
+
+ $location = new LocationHashbangUrl(initUrl, hashPrefix, appBaseUrl);
}
$rootElement.bind('click', function(event) {
@@ -510,27 +549,22 @@ function $LocationProvider(){
var elm = jqLite(event.target);
// traverse the DOM up to find first A tag
- while (elm.length && lowercase(elm[0].nodeName) !== 'a') {
+ while (lowercase(elm[0].nodeName) !== 'a') {
+ if (elm[0] === $rootElement[0]) return;
elm = elm.parent();
}
var absHref = elm.prop('href'),
- href;
-
- if (!absHref ||
- elm.attr('target') ||
- absHref.indexOf(absUrlPrefix) !== 0) { // link to different domain or base path
- return;
+ rewrittenUrl = $location.$$rewriteAppUrl(absHref);
+
+ if (absHref && !elm.attr('target') && rewrittenUrl) {
+ // update location manually
+ $location.$$parse(rewrittenUrl);
+ $rootScope.$apply();
+ event.preventDefault();
+ // hack to work around FF6 bug 684208 when scenario runner clicks on links
+ window.angular['ff-684208-preventDefault'] = true;
}
-
- // update location with href without the prefix
- href = absHref.substr(absUrlPrefix.length);
- if (href.indexOf('#' + hashPrefix) == 0) href = href.substr(hashPrefix.length + 1);
- $location.url(href);
- $rootScope.$apply();
- event.preventDefault();
- // hack to work around FF6 bug 684208 when scenario runner clicks on links
- window.angular['ff-684208-preventDefault'] = true;
});