diff --git a/modules/__tests__/Router-test.js b/modules/__tests__/Router-test.js
index 3b3003a976..59996ef931 100644
--- a/modules/__tests__/Router-test.js
+++ b/modules/__tests__/Router-test.js
@@ -87,11 +87,11 @@ describe('Router', function () {
location.pop();
expect(div.innerHTML).toMatch(/Bar/);
}, Async.delay / 2);
+ });
- setTimeout(function () {
- expect(div.innerHTML).toMatch(/Bar/);
- done();
- }, Async.delay + 10);
+ steps.push(function () {
+ expect(div.innerHTML).toMatch(/Bar/);
+ done();
});
router = Router.create({
@@ -314,11 +314,11 @@ describe('Router', function () {
location.pop();
expect(div.innerHTML).toMatch(/Bar/);
}, RedirectToFooAsync.delay / 2);
+ });
- setTimeout(function () {
- expect(div.innerHTML).toMatch(/Bar/);
- done();
- }, RedirectToFooAsync.delay + 10);
+ steps.push(function () {
+ expect(div.innerHTML).toMatch(/Bar/);
+ done();
});
router = Router.create({
@@ -421,9 +421,14 @@ describe('Router', function () {
var div = document.createElement('div');
+ var runCount = 0;
Router.run(routes, location, function (Handler) {
+ runCount += 1;
React.render(, div, function () {
- location.push('/abort');
+ if (runCount === 1){
+ location.push('/abort');
+ return;
+ }
expect(div.innerHTML).toMatch(/Foo/);
expect(location.getCurrentPath()).toEqual('/foo');
done();
@@ -482,11 +487,11 @@ describe('Router', function () {
location.pop();
expect(div.innerHTML).toMatch(/Bar/);
}, Async.delay / 2);
+ });
- setTimeout(function () {
- expect(div.innerHTML).toMatch(/Bar/);
- done();
- }, Async.delay + 10);
+ steps.push(function () {
+ expect(div.innerHTML).toMatch(/Bar/);
+ done();
});
router = Router.create({
@@ -741,7 +746,8 @@ describe('Router', function () {
Router.run(routes, location, function (Handler, state) {
React.render(, div, function () {
- location.push('/baz');
+ if (state.path !== '/baz')
+ location.push('/baz');
});
});
});
diff --git a/modules/actions/LocationActions.js b/modules/actions/LocationActions.js
index 68e512f769..3628151cb2 100644
--- a/modules/actions/LocationActions.js
+++ b/modules/actions/LocationActions.js
@@ -16,7 +16,12 @@ var LocationActions = {
/**
* Indicates the most recent entry should be removed from the history stack.
*/
- POP: 'pop'
+ POP: 'pop',
+
+ /**
+ * Indicates the current location should be refreshed.
+ */
+ REFRESH: 'refresh'
};
diff --git a/modules/createRouter.js b/modules/createRouter.js
index 833f5d2984..4e42012339 100644
--- a/modules/createRouter.js
+++ b/modules/createRouter.js
@@ -327,10 +327,6 @@ function createRouter(options) {
Router.cancelPendingTransition();
var prevPath = state.path;
- var isRefreshing = action == null;
-
- if (prevPath === path && !isRefreshing)
- return; // Nothing to do!
// Record the scroll position as early as possible to
// get it before browsers try update it automatically.
@@ -433,7 +429,7 @@ function createRouter(options) {
},
refresh: function () {
- Router.dispatch(location.getCurrentPath(), null);
+ Router.dispatch(location.getCurrentPath(), LocationActions.REFRESH);
},
stop: function () {
diff --git a/modules/locations/HashLocation.js b/modules/locations/HashLocation.js
index a3ac0da6aa..610b08ab74 100644
--- a/modules/locations/HashLocation.js
+++ b/modules/locations/HashLocation.js
@@ -42,6 +42,11 @@ function onHashChange() {
}
}
+function refresh() {
+ _actionType = LocationActions.REFRESH;
+ onHashChange();
+}
+
/**
* A Location that uses `window.location.hash`.
*/
@@ -81,15 +86,25 @@ var HashLocation = {
},
push(path) {
- _actionType = LocationActions.PUSH;
- window.location.hash = path;
+ // ensure change event if path has not changed
+ if (path !== HashLocation.getCurrentPath()) {
+ _actionType = LocationActions.PUSH;
+ window.location.hash = path;
+ } else {
+ refresh();
+ }
},
replace(path) {
- _actionType = LocationActions.REPLACE;
- window.location.replace(
- window.location.pathname + window.location.search + '#' + path
- );
+ // ensure change event if path has not changed
+ if (path !== HashLocation.getCurrentPath()) {
+ _actionType = LocationActions.REPLACE;
+ window.location.replace(
+ window.location.pathname + window.location.search + '#' + path
+ );
+ } else {
+ refresh();
+ }
},
pop() {
diff --git a/modules/locations/HistoryLocation.js b/modules/locations/HistoryLocation.js
index d08dfa34ed..5380e1252b 100644
--- a/modules/locations/HistoryLocation.js
+++ b/modules/locations/HistoryLocation.js
@@ -58,14 +58,24 @@ var HistoryLocation = {
},
push(path) {
- window.history.pushState({ path: path }, '', path);
- History.length += 1;
- notifyChange(LocationActions.PUSH);
+ // don't push state if path has not changed
+ if (path !== HistoryLocation.getCurrentPath()) {
+ window.history.pushState({ path: path }, '', path);
+ History.length += 1;
+ notifyChange(LocationActions.PUSH);
+ } else {
+ notifyChange(LocationActions.REFRESH);
+ }
},
replace(path) {
- window.history.replaceState({ path: path }, '', path);
- notifyChange(LocationActions.REPLACE);
+ // don't replace state if path has not changed
+ if (path !== HistoryLocation.getCurrentPath()) {
+ window.history.replaceState({ path: path }, '', path);
+ notifyChange(LocationActions.REPLACE);
+ } else {
+ notifyChange(LocationActions.REFRESH);
+ }
},
pop: History.back,
diff --git a/modules/locations/TestLocation.js b/modules/locations/TestLocation.js
index 76cab8ad65..143877f70d 100644
--- a/modules/locations/TestLocation.js
+++ b/modules/locations/TestLocation.js
@@ -42,9 +42,13 @@ class TestLocation {
}
push(path) {
- this.history.push(path);
- this._updateHistoryLength();
- this._notifyChange(LocationActions.PUSH);
+ if (!this.history.length || path !== this.getCurrentPath()) {
+ this.history.push(path);
+ this._updateHistoryLength();
+ this._notifyChange(LocationActions.PUSH);
+ } else {
+ this._notifyChange(LocationActions.REFRESH);
+ }
}
replace(path) {
@@ -53,9 +57,13 @@ class TestLocation {
'You cannot replace the current path with no history'
);
- this.history[this.history.length - 1] = path;
+ if (path !== this.getCurrentPath()) {
+ this.history[this.history.length - 1] = path;
+ this._notifyChange(LocationActions.REPLACE);
+ } else {
+ this._notifyChange(LocationActions.REFRESH);
+ }
- this._notifyChange(LocationActions.REPLACE);
}
pop() {