Skip to content

Commit fbb18b4

Browse files
committed
separate files
1 parent 21d633c commit fbb18b4

File tree

5 files changed

+223
-211
lines changed

5 files changed

+223
-211
lines changed

modules/RestoreScroll.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react'
2+
import { findDOMNode } from 'react-dom'
3+
4+
const RestoreScroll = React.createClass({
5+
6+
contextTypes: {
7+
router: React.PropTypes.object.isRequired
8+
},
9+
10+
propTypes: {
11+
scrollKey: React.PropTypes.string.isRequired
12+
},
13+
14+
componentDidMount() {
15+
const { registerScroller } = this.context.router.restoreScroll
16+
const { scrollKey } = this.props
17+
registerScroller(scrollKey, findDOMNode(this))
18+
this.restoreScrollPosition()
19+
},
20+
21+
componentWillUnmount() {
22+
const { unregisterScroller } = this.context.router.restoreScroll
23+
const { scrollKey } = this.props
24+
unregisterScroller(scrollKey)
25+
},
26+
27+
restoreScrollPosition() {
28+
const { restoreScrollPosition } = this.context.router.restoreScroll
29+
restoreScrollPosition(this.props.scrollKey)
30+
},
31+
32+
render() {
33+
return React.Children.only(this.props.children)
34+
}
35+
36+
})
37+
38+
export default RestoreScroll
39+

modules/RestoreWindowScroll.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react'
2+
3+
const RestoreWindowScroll = React.createClass({
4+
5+
propTypes: {
6+
restoreScrollPosition: React.PropTypes.func.isRequired,
7+
location: React.PropTypes.object.isRequired
8+
},
9+
10+
componentDidUpdate(prevProps) {
11+
const { location } = this.props
12+
if (prevProps.location !== this.props.location) {
13+
this.props.restoreScrollPosition('window', location)
14+
}
15+
},
16+
17+
render() {
18+
return this.props.children
19+
}
20+
})
21+
22+
export default RestoreWindowScroll
23+

modules/index.js

Lines changed: 3 additions & 211 deletions
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,4 @@
1-
import React from 'react'
2-
import { findDOMNode } from 'react-dom'
3-
import parsePath from 'history/lib/parsePath'
4-
5-
const setManualScroll = () => {
6-
if (typeof window !== 'undefined' && 'scrollRestoration' in window.history) {
7-
history.scrollRestoration = 'manual'
8-
}
9-
}
10-
11-
const createKey = () => (
12-
Math.random().toString(36).substr(2, 6)
13-
)
14-
15-
const addScrollKey = (locationOrString) => {
16-
const location = typeof locationOrString === 'string' ?
17-
parsePath(locationOrString) : locationOrString
18-
if (!location.state)
19-
location.state = {}
20-
location.state.__scrollKey = createKey()
21-
return location
22-
}
23-
24-
const RestoreWindowScroll = React.createClass({
25-
26-
propTypes: {
27-
restoreScrollPosition: React.PropTypes.func.isRequired,
28-
location: React.PropTypes.object.isRequired
29-
},
30-
31-
componentDidUpdate(prevProps) {
32-
const { location } = this.props
33-
if (prevProps.location !== this.props.location) {
34-
this.props.restoreScrollPosition('window', location)
35-
}
36-
},
37-
38-
render() {
39-
return this.props.children
40-
}
41-
})
42-
43-
const RestoreScroll = React.createClass({
44-
45-
contextTypes: {
46-
router: React.PropTypes.object.isRequired
47-
},
48-
49-
propTypes: {
50-
scrollKey: React.PropTypes.string.isRequired
51-
},
52-
53-
componentDidMount() {
54-
const { registerScroller } = this.context.router.restoreScroll
55-
const { scrollKey } = this.props
56-
registerScroller(scrollKey, findDOMNode(this))
57-
this.restoreScrollPosition()
58-
},
59-
60-
componentWillUnmount() {
61-
const { unregisterScroller } = this.context.router.restoreScroll
62-
const { scrollKey } = this.props
63-
unregisterScroller(scrollKey)
64-
},
65-
66-
restoreScrollPosition() {
67-
const { restoreScrollPosition } = this.context.router.restoreScroll
68-
restoreScrollPosition(this.props.scrollKey)
69-
},
70-
71-
render() {
72-
return React.Children.only(this.props.children)
73-
}
74-
75-
})
76-
77-
const useHistoryRestoreScroll = (createHistory) => (
78-
(options={}) => {
79-
setManualScroll()
80-
81-
const initialScrollKey = createKey()
82-
let currentScrollKey = null
83-
84-
const history = createHistory(options)
85-
86-
////
87-
// `positionsByLocation` looks like this
88-
//
89-
// ```
90-
// {
91-
// [location.key]: {
92-
// window: { scrollX, scrollY },
93-
// [scrollKey]: { scrollTop, scrollLeft }
94-
// },
95-
// [location.key]: etc...
96-
// }
97-
// ```
98-
const positionsByLocation = {}
99-
const scrollers = {}
100-
101-
const push = (locationWithoutKey) => {
102-
const location = addScrollKey(locationWithoutKey)
103-
history.push(location)
104-
}
105-
106-
const replace = (locationWithoutKey) => {
107-
const location = addScrollKey(locationWithoutKey)
108-
history.replace(location)
109-
}
110-
111-
const registerScroller = (scrollKey, node) => {
112-
scrollers[scrollKey] = node
113-
}
114-
115-
const unregisterScroller = (scrollKey) => {
116-
delete scrollers[scrollKey]
117-
}
118-
119-
const getScrollerPosition = (componentScrollKey) => {
120-
const locationPositions = positionsByLocation[currentScrollKey]
121-
return locationPositions ? locationPositions[componentScrollKey] || null : null
122-
}
123-
124-
const saveScrollerPositions = () => {
125-
if (!positionsByLocation[currentScrollKey])
126-
positionsByLocation[currentScrollKey] = {}
127-
const { scrollY, scrollX } = window
128-
savePosition('window', { scrollX, scrollY })
129-
for (const scrollKey in scrollers) {
130-
const scrollerNode = scrollers[scrollKey]
131-
const { scrollTop, scrollLeft } = scrollerNode
132-
savePosition(scrollKey, { scrollTop, scrollLeft })
133-
}
134-
}
135-
136-
const savePosition = (scrollKey, position) => {
137-
positionsByLocation[currentScrollKey][scrollKey] = position
138-
}
139-
140-
const unlisten = history.listen((location) => {
141-
saveScrollerPositions()
142-
currentScrollKey = (
143-
location.state && location.state.__scrollKey
144-
) || initialScrollKey
145-
})
146-
147-
const listen = (...args) => {
148-
const internalUnlisten = history.listen(...args)
149-
return () => unlisten() && internalUnlisten()
150-
}
151-
152-
const restoreWindow = (location) => {
153-
if (location.action === 'PUSH' || location.action === 'REPLACE') {
154-
window.scrollTo(0, 0)
155-
} else {
156-
const position = getScrollerPosition('window')
157-
if (position) {
158-
const { scrollX, scrollY } = position
159-
window.scrollTo(scrollX, scrollY)
160-
}
161-
}
162-
}
163-
164-
const restoreNode = (scrollKey) => {
165-
const position = getScrollerPosition(scrollKey)
166-
if (position) {
167-
const node = scrollers[scrollKey]
168-
const { scrollTop, scrollLeft } = position
169-
node.scrollTop = scrollTop
170-
node.scrollLeft = scrollLeft
171-
}
172-
}
173-
174-
const restoreScrollPosition = (key, location) => {
175-
if (key === 'window') {
176-
restoreWindow(location)
177-
} else {
178-
restoreNode(key)
179-
}
180-
}
181-
182-
return {
183-
...history,
184-
listen,
185-
push,
186-
replace,
187-
restoreScroll: {
188-
registerScroller,
189-
unregisterScroller,
190-
getScrollerPosition,
191-
restoreScrollPosition
192-
}
193-
}
194-
}
195-
)
196-
197-
const useRouterRestoreScroll = () => ({
198-
renderRouterContext: (child, props) => (
199-
<RestoreWindowScroll
200-
restoreScrollPosition={props.router.restoreScroll.restoreScrollPosition}
201-
location={props.location}
202-
children={child}
203-
/>
204-
)
205-
})
206-
207-
export {
208-
useHistoryRestoreScroll,
209-
useRouterRestoreScroll,
210-
RestoreScroll
211-
}
1+
export RestoreScroll from './RestoreScroll'
2+
export useHistoryRestoreScroll from './useHistoryRestoreScroll'
3+
export useRouterRestoreScroll from './useRouterRestoreScroll'
2124

0 commit comments

Comments
 (0)