diff --git a/modules/mixins/Scrolling.js b/modules/mixins/Scrolling.js index 01e2d9c372..d6729c38c2 100644 --- a/modules/mixins/Scrolling.js +++ b/modules/mixins/Scrolling.js @@ -1,22 +1,18 @@ var invariant = require('react/lib/invariant'); var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; var getWindowScrollPosition = require('../utils/getWindowScrollPosition'); -var Path = require('../utils/Path'); function shouldUpdateScroll(state, prevState) { - if (!prevState) { + if (!prevState) return true; - } - var path = state.path; + // Don't update scroll position when only the query has changed. + if (state.pathname === prevState.pathname) + return false; + var routes = state.routes; - var prevPath = prevState.path; var prevRoutes = prevState.routes; - if (Path.withoutQuery(path) === Path.withoutQuery(prevPath)) { - return false; - } - var sharedAncestorRoutes = routes.filter(function (route) { return prevRoutes.indexOf(route) !== -1; }); diff --git a/modules/mixins/State.js b/modules/mixins/State.js index 5499043c16..a2d98d2aaf 100644 --- a/modules/mixins/State.js +++ b/modules/mixins/State.js @@ -23,6 +23,7 @@ var State = { contextTypes: { getCurrentPath: React.PropTypes.func.isRequired, getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentPathname: React.PropTypes.func.isRequired, getCurrentParams: React.PropTypes.func.isRequired, getCurrentQuery: React.PropTypes.func.isRequired, isActive: React.PropTypes.func.isRequired @@ -42,6 +43,13 @@ var State = { return this.context.getCurrentRoutes(); }, + /** + * Returns the current URL path without the query string. + */ + getPathname: function () { + return this.context.getCurrentPathname(); + }, + /** * Returns an object of the URL params that are currently active. */ diff --git a/modules/mixins/StateContext.js b/modules/mixins/StateContext.js index 5d49fb25a2..315bd7597e 100644 --- a/modules/mixins/StateContext.js +++ b/modules/mixins/StateContext.js @@ -43,6 +43,13 @@ var StateContext = { return this.state.routes.slice(0); }, + /** + * Returns the current URL path without the query string. + */ + getCurrentPathname: function () { + return this.state.pathname; + }, + /** * Returns a read-only object of the currently active URL parameters. */ @@ -72,6 +79,7 @@ var StateContext = { childContextTypes: { getCurrentPath: React.PropTypes.func.isRequired, getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentPathname: React.PropTypes.func.isRequired, getCurrentParams: React.PropTypes.func.isRequired, getCurrentQuery: React.PropTypes.func.isRequired, isActive: React.PropTypes.func.isRequired @@ -81,6 +89,7 @@ var StateContext = { return { getCurrentPath: this.getCurrentPath, getCurrentRoutes: this.getCurrentRoutes, + getCurrentPathname: this.getCurrentPathname, getCurrentParams: this.getCurrentParams, getCurrentQuery: this.getCurrentQuery, isActive: this.isActive diff --git a/modules/utils/createRouter.js b/modules/utils/createRouter.js index 923a195d25..037e30ead7 100644 --- a/modules/utils/createRouter.js +++ b/modules/utils/createRouter.js @@ -255,8 +255,8 @@ function createRouter(options) { * Performs a match of the given pathname against this router and returns an object * with the { routes, params } that match. Returns null if no match can be made. */ - match: function (path) { - return findMatch(Path.withoutQuery(path), routes, this.defaultRoute, this.notFoundRoute) || null; + match: function (pathname) { + return findMatch(pathname, routes, this.defaultRoute, this.notFoundRoute) || null; }, /** @@ -289,7 +289,8 @@ function createRouter(options) { this.recordScrollPosition(prevPath); } - var match = this.match(path); + var pathname = Path.withoutQuery(path); + var match = this.match(pathname); warning( match != null, @@ -334,6 +335,7 @@ function createRouter(options) { nextState.path = path; nextState.action = action; + nextState.pathname = pathname; nextState.routes = nextRoutes; nextState.params = nextParams; nextState.query = nextQuery;