aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng/location.js
diff options
context:
space:
mode:
authorMisko Hevery2012-05-22 16:45:56 -0700
committerMisko Hevery2012-06-02 15:44:58 -0700
commit92a2e1807657c69e1372106b0727675a30f4cbd7 (patch)
treef236f146b44c4a03cfc04e48e6dba878c74c6153 /src/ng/location.js
parent8aa18f0ad036fd4f2dc26f54d80754c70232b4f7 (diff)
downloadangular.js-92a2e1807657c69e1372106b0727675a30f4cbd7.tar.bz2
feat($location): add $locatonChange[begin|completed] event
This allows location change cancelation
Diffstat (limited to 'src/ng/location.js')
-rw-r--r--src/ng/location.js110
1 files changed, 67 insertions, 43 deletions
diff --git a/src/ng/location.js b/src/ng/location.js
index c7b41605..64a234ad 100644
--- a/src/ng/location.js
+++ b/src/ng/location.js
@@ -408,7 +408,10 @@ function locationGetterSetter(property, preprocess) {
* @requires $rootElement
*
* @description
- * The $location service parses the URL in the browser address bar (based on the {@link https://developer.mozilla.org/en/window.location window.location}) and makes the URL available to your application. Changes to the URL in the address bar are reflected into $location service and changes to $location are reflected into the browser address bar.
+ * The $location service parses the URL in the browser address bar (based on the
+ * {@link https://developer.mozilla.org/en/window.location window.location}) and makes the URL
+ * available to your application. Changes to the URL in the address bar are reflected into
+ * $location service and changes to $location are reflected into the browser address bar.
*
* **The $location service:**
*
@@ -421,7 +424,8 @@ function locationGetterSetter(property, preprocess) {
* - Clicks on a link.
* - Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
*
- * For more information see {@link guide/dev_guide.services.$location Developer Guide: Angular Services: Using $location}
+ * For more information see {@link guide/dev_guide.services.$location Developer Guide: Angular
+ * Services: Using $location}
*/
/**
@@ -470,65 +474,73 @@ function $LocationProvider(){
this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement',
function( $rootScope, $browser, $sniffer, $rootElement) {
- var currentUrl,
+ var $location,
basePath = $browser.baseHref() || '/',
pathPrefix = pathPrefixFromBase(basePath),
- initUrl = $browser.url();
+ initUrl = $browser.url(),
+ absUrlPrefix;
if (html5Mode) {
if ($sniffer.history) {
- currentUrl = new LocationUrl(convertToHtml5Url(initUrl, basePath, hashPrefix), pathPrefix);
+ $location = new LocationUrl(
+ convertToHtml5Url(initUrl, basePath, hashPrefix),
+ pathPrefix);
} else {
- currentUrl = new LocationHashbangUrl(convertToHashbangUrl(initUrl, basePath, hashPrefix),
- hashPrefix);
+ $location = new LocationHashbangUrl(
+ convertToHashbangUrl(initUrl, basePath, hashPrefix),
+ hashPrefix);
}
+ } else {
+ $location = new LocationHashbangUrl(initUrl, hashPrefix);
+ }
- // link rewriting
- var u = currentUrl,
- absUrlPrefix = composeProtocolHostPort(u.protocol(), u.host(), u.port()) + pathPrefix;
+ // link rewriting
+ absUrlPrefix = composeProtocolHostPort(
+ $location.protocol(), $location.host(), $location.port()) + pathPrefix;
- $rootElement.bind('click', function(event) {
- // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
- // currently we open nice url link and redirect then
+ $rootElement.bind('click', function(event) {
+ // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
+ // currently we open nice url link and redirect then
- if (event.ctrlKey || event.metaKey || event.which == 2) return;
+ if (event.ctrlKey || event.metaKey || event.which == 2) return;
- var elm = jqLite(event.target);
+ var elm = jqLite(event.target);
- // traverse the DOM up to find first A tag
- while (elm.length && lowercase(elm[0].nodeName) !== 'a') {
- elm = elm.parent();
- }
+ // traverse the DOM up to find first A tag
+ while (elm.length && lowercase(elm[0].nodeName) !== 'a') {
+ elm = elm.parent();
+ }
- var absHref = elm.prop('href');
+ var absHref = elm.prop('href');
- if (!absHref ||
- elm.attr('target') ||
- absHref.indexOf(absUrlPrefix) !== 0) { // link to different domain or base path
- return;
- }
+ if (!absHref ||
+ elm.attr('target') ||
+ absHref.indexOf(absUrlPrefix) !== 0) { // link to different domain or base path
+ return;
+ }
+
+ // update location with href without the prefix
+ $location.url(absHref.substr(absUrlPrefix.length));
+ $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
- currentUrl.url(absHref.substr(absUrlPrefix.length));
- $rootScope.$apply();
- event.preventDefault();
- // hack to work around FF6 bug 684208 when scenario runner clicks on links
- window.angular['ff-684208-preventDefault'] = true;
- });
- } else {
- currentUrl = new LocationHashbangUrl(initUrl, hashPrefix);
- }
// rewrite hashbang url <> html5 url
- if (currentUrl.absUrl() != initUrl) {
- $browser.url(currentUrl.absUrl(), true);
+ if ($location.absUrl() != initUrl) {
+ $browser.url($location.absUrl(), true);
}
// update $location when $browser url changes
$browser.onUrlChange(function(newUrl) {
- if (currentUrl.absUrl() != newUrl) {
+ if ($location.absUrl() != newUrl) {
$rootScope.$evalAsync(function() {
- currentUrl.$$parse(newUrl);
+ var oldUrl = $location.absUrl();
+
+ $location.$$parse(newUrl);
+ afterLocationChange(oldUrl);
});
if (!$rootScope.$$phase) $rootScope.$digest();
}
@@ -537,17 +549,29 @@ function $LocationProvider(){
// update browser
var changeCounter = 0;
$rootScope.$watch(function $locationWatch() {
- if ($browser.url() != currentUrl.absUrl()) {
+ var oldUrl = $browser.url();
+
+ if (!changeCounter || oldUrl != $location.absUrl()) {
changeCounter++;
$rootScope.$evalAsync(function() {
- $browser.url(currentUrl.absUrl(), currentUrl.$$replace);
- currentUrl.$$replace = false;
+ if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
+ defaultPrevented) {
+ $location.$$parse(oldUrl);
+ } else {
+ $browser.url($location.absUrl(), $location.$$replace);
+ $location.$$replace = false;
+ afterLocationChange(oldUrl);
+ }
});
}
return changeCounter;
});
- return currentUrl;
+ return $location;
+
+ function afterLocationChange(oldUrl) {
+ $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl);
+ }
}];
}