You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.1 KiB
75 lines
2.1 KiB
"use strict"; |
|
|
|
var invariant = require("react/lib/invariant"); |
|
var canUseDOM = require("react/lib/ExecutionEnvironment").canUseDOM; |
|
var getWindowScrollPosition = require("./getWindowScrollPosition"); |
|
|
|
function shouldUpdateScroll(state, prevState) { |
|
if (!prevState) { |
|
return true; |
|
} // Don't update scroll position when only the query has changed. |
|
if (state.pathname === prevState.pathname) { |
|
return false; |
|
}var routes = state.routes; |
|
var prevRoutes = prevState.routes; |
|
|
|
var sharedAncestorRoutes = routes.filter(function (route) { |
|
return prevRoutes.indexOf(route) !== -1; |
|
}); |
|
|
|
return !sharedAncestorRoutes.some(function (route) { |
|
return route.ignoreScrollBehavior; |
|
}); |
|
} |
|
|
|
/** |
|
* Provides the router with the ability to manage window scroll position |
|
* according to its scroll behavior. |
|
*/ |
|
var ScrollHistory = { |
|
|
|
statics: { |
|
|
|
/** |
|
* Records curent scroll position as the last known position for the given URL path. |
|
*/ |
|
recordScrollPosition: function recordScrollPosition(path) { |
|
if (!this.scrollHistory) this.scrollHistory = {}; |
|
|
|
this.scrollHistory[path] = getWindowScrollPosition(); |
|
}, |
|
|
|
/** |
|
* Returns the last known scroll position for the given URL path. |
|
*/ |
|
getScrollPosition: function getScrollPosition(path) { |
|
if (!this.scrollHistory) this.scrollHistory = {}; |
|
|
|
return this.scrollHistory[path] || null; |
|
} |
|
|
|
}, |
|
|
|
componentWillMount: function componentWillMount() { |
|
invariant(this.constructor.getScrollBehavior() == null || canUseDOM, "Cannot use scroll behavior without a DOM"); |
|
}, |
|
|
|
componentDidMount: function componentDidMount() { |
|
this._updateScroll(); |
|
}, |
|
|
|
componentDidUpdate: function componentDidUpdate(prevProps, prevState) { |
|
this._updateScroll(prevState); |
|
}, |
|
|
|
_updateScroll: function _updateScroll(prevState) { |
|
if (!shouldUpdateScroll(this.state, prevState)) { |
|
return; |
|
}var scrollBehavior = this.constructor.getScrollBehavior(); |
|
|
|
if (scrollBehavior) scrollBehavior.updateScrollPosition(this.constructor.getScrollPosition(this.state.path), this.state.action); |
|
} |
|
|
|
}; |
|
|
|
module.exports = ScrollHistory; |