1
+ var supportsHistory = require ( '../utils/supportsHistory' ) ;
2
+ var HistoryLocation = require ( '../locations/HistoryLocation' ) ;
3
+ var RefreshLocation = require ( '../locations/RefreshLocation' ) ;
1
4
var LocationDispatcher = require ( '../dispatchers/LocationDispatcher' ) ;
5
+ var ActionTypes = require ( '../constants/ActionTypes' ) ;
6
+ var warning = require ( 'react/lib/warning' ) ;
2
7
var isAbsoluteURL = require ( '../utils/isAbsoluteURL' ) ;
3
8
var makePath = require ( '../utils/makePath' ) ;
4
9
5
10
function loadURL ( url ) {
6
11
window . location = url ;
7
12
}
8
13
14
+ var _location = null ;
15
+ var _isDispatching = false ;
16
+ var _previousPath = null ;
17
+
18
+ function dispatchAction ( actionType , operation ) {
19
+ if ( _isDispatching )
20
+ throw new Error ( 'Cannot handle ' + actionType + ' in the middle of another action.' ) ;
21
+
22
+ _isDispatching = true ;
23
+
24
+ var scrollPosition = {
25
+ x : window . scrollX ,
26
+ y : window . scrollY
27
+ } ;
28
+
29
+ if ( typeof operation === 'function' )
30
+ operation ( _location ) ;
31
+
32
+ var path = _location . getCurrentPath ( ) ;
33
+ LocationDispatcher . handleViewAction ( {
34
+ type : actionType ,
35
+ path : path ,
36
+ scrollPosition : scrollPosition
37
+ } ) ;
38
+
39
+ _isDispatching = false ;
40
+ _previousPath = path ;
41
+ }
42
+
43
+ function handleChange ( ) {
44
+ var path = _location . getCurrentPath ( ) ;
45
+
46
+ // Ignore changes inside or caused by dispatchAction
47
+ if ( ! _isDispatching && path !== _previousPath ) {
48
+ dispatchAction ( ActionTypes . POP ) ;
49
+ }
50
+ }
51
+
9
52
/**
10
53
* Actions that modify the URL.
11
54
*/
12
55
var LocationActions = {
13
56
14
- PUSH : 'push' ,
15
- REPLACE : 'replace' ,
16
- POP : 'pop' ,
17
- UPDATE_SCROLL : 'update-scroll' ,
57
+ getLocation : function ( ) {
58
+ return _location ;
59
+ } ,
60
+
61
+ setup : function ( location ) {
62
+ // When using HistoryLocation, automatically fallback
63
+ // to RefreshLocation in browsers that do not support
64
+ // the HTML5 history API.
65
+ if ( location === HistoryLocation && ! supportsHistory ( ) )
66
+ location = RefreshLocation ;
67
+
68
+ if ( _location !== null ) {
69
+ warning (
70
+ _location === location ,
71
+ 'Cannot use location %s, already using %s' , location , _location
72
+ ) ;
73
+ return ;
74
+ }
75
+
76
+ _location = location ;
77
+
78
+ if ( _location !== null ) {
79
+ dispatchAction ( ActionTypes . SETUP , function ( location ) {
80
+ if ( typeof location . setup === 'function' )
81
+ location . setup ( handleChange ) ;
82
+ } ) ;
83
+ }
84
+ } ,
85
+
86
+ teardown : function ( ) {
87
+ if ( _location !== null ) {
88
+ if ( typeof _location . teardown === 'function' )
89
+ _location . teardown ( ) ;
90
+
91
+ _location = null ;
92
+ }
93
+ } ,
18
94
19
95
/**
20
96
* Transitions to the URL specified in the arguments by pushing
@@ -24,9 +100,9 @@ var LocationActions = {
24
100
if ( isAbsoluteURL ( to ) ) {
25
101
loadURL ( to ) ;
26
102
} else {
27
- LocationDispatcher . handleViewAction ( {
28
- type : LocationActions . PUSH ,
29
- path : makePath ( to , params , query )
103
+ dispatchAction ( ActionTypes . PUSH , function ( location ) {
104
+ var path = makePath ( to , params , query ) ;
105
+ location . push ( path ) ;
30
106
} ) ;
31
107
}
32
108
} ,
@@ -39,9 +115,9 @@ var LocationActions = {
39
115
if ( isAbsoluteURL ( to ) ) {
40
116
loadURL ( to ) ;
41
117
} else {
42
- LocationDispatcher . handleViewAction ( {
43
- type : LocationActions . REPLACE ,
44
- path : makePath ( to , params , query )
118
+ dispatchAction ( ActionTypes . REPLACE , function ( location ) {
119
+ var path = makePath ( to , params , query ) ;
120
+ location . replace ( path ) ;
45
121
} ) ;
46
122
}
47
123
} ,
@@ -50,18 +126,8 @@ var LocationActions = {
50
126
* Transitions to the previous URL.
51
127
*/
52
128
goBack : function ( ) {
53
- LocationDispatcher . handleViewAction ( {
54
- type : LocationActions . POP
55
- } ) ;
56
- } ,
57
-
58
- /**
59
- * Updates the window's scroll position to the last known position
60
- * for the current URL path.
61
- */
62
- updateScroll : function ( ) {
63
- LocationDispatcher . handleViewAction ( {
64
- type : LocationActions . UPDATE_SCROLL
129
+ dispatchAction ( ActionTypes . POP , function ( location ) {
130
+ location . pop ( ) ;
65
131
} ) ;
66
132
}
67
133
0 commit comments