From 6bbc2ebc8875c7411384a498cc94f3a805d9c85d Mon Sep 17 00:00:00 2001 From: Greg Weber Date: Fri, 7 Dec 2012 19:46:48 -0800 Subject: [PATCH] $location support for pushState --- src/ng/browser.js | 14 +++++++++----- src/ng/location.js | 46 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/ng/browser.js b/src/ng/browser.js index 3925348317ce..de71170d1906 100644 --- a/src/ng/browser.js +++ b/src/ng/browser.js @@ -145,16 +145,20 @@ function Browser(window, document, $log, $sniffer) { * * @param {string} url New url (when used as setter) * @param {boolean=} replace Should new url replace current history record ? + * @param {object=} state object to use with pushState/replaceState + * @param {string=} title to use with pushState/replaceState */ - self.url = function(url, replace) { + self.url = function(url, replace, state, title) { // setter if (url) { if (lastBrowserUrl == url) return; lastBrowserUrl = url; if ($sniffer.history) { - if (replace) history.replaceState(null, '', url); + var title = title || '' + if(isUndefined(state)) state = null + if (replace) history.replaceState(state, title, url); else { - history.pushState(null, '', url); + history.pushState(state, title, url); // Crazy Opera Bug: http://my.opera.com/community/forums/topic.dml?id=1185462 baseElement.attr('href', baseElement.attr('href')); } @@ -173,12 +177,12 @@ function Browser(window, document, $log, $sniffer) { var urlChangeListeners = [], urlChangeInit = false; - function fireUrlChange() { + function fireUrlChange(ev) { if (lastBrowserUrl == self.url()) return; lastBrowserUrl = self.url(); forEach(urlChangeListeners, function(listener) { - listener(self.url()); + listener(self.url(), ev); }); } diff --git a/src/ng/location.js b/src/ng/location.js index 73ef7f7b1db7..e2c9cc0dd9ea 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -265,6 +265,40 @@ LocationUrl.prototype = { return this; }, + /* + * @ngdoc method + * @name ng.$location#pushState + * @methodOf ng.$location + * + * @description + * @param {object=} state object for pushState + * @param {string=} title for pushState + * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`) + * @return {object} $location + */ + pushState: function(state, title, url, replace) { + this.$$state = state; + this.$$title = title; + this.url(url, replace) + return this; + }, + + /* + * @ngdoc method + * @name ng.$location#replaceState + * @methodOf ng.$location + * + * @description + * @param {object=} state object for replaceState + * @param {string=} title for pushState + * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`) + * @return {object} $location + */ + replaceState: function(state, title, url) { + this.pushState(state, title, url, true) + return this; + }, + /** * @ngdoc method * @name ng.$location#protocol @@ -574,13 +608,13 @@ function $LocationProvider(){ } // update $location when $browser url changes - $browser.onUrlChange(function(newUrl) { + $browser.onUrlChange(function(newUrl, ev) { if ($location.absUrl() != newUrl) { $rootScope.$evalAsync(function() { var oldUrl = $location.absUrl(); $location.$$parse(newUrl); - afterLocationChange(oldUrl); + afterLocationChange(oldUrl, ev); }); if (!$rootScope.$$phase) $rootScope.$digest(); } @@ -599,20 +633,22 @@ function $LocationProvider(){ defaultPrevented) { $location.$$parse(oldUrl); } else { - $browser.url($location.absUrl(), currentReplace); + $browser.url($location.absUrl(), $location.$$replace, $location.$$state, $location.$$title); afterLocationChange(oldUrl); } }); } $location.$$replace = false; + $location.$$state = null; + $location.$$title = null; return changeCounter; }); return $location; - function afterLocationChange(oldUrl) { - $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl); + function afterLocationChange(oldUrl, ev) { + $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl, ev); } }]; }