unpoly-rails 0.37.0 → 0.50.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +127 -25
- data/LICENSE +1 -1
- data/README_RAILS.md +4 -2
- data/Rakefile +6 -1
- data/dist/unpoly.js +3192 -2198
- data/dist/unpoly.min.js +4 -3
- data/lib/assets/javascripts/unpoly/browser.coffee +51 -63
- data/lib/assets/javascripts/unpoly/bus.coffee +58 -33
- data/lib/assets/javascripts/unpoly/classes/cache.coffee +117 -0
- data/lib/assets/javascripts/unpoly/{dom → classes}/extract_cascade.coffee +3 -3
- data/lib/assets/javascripts/unpoly/{dom → classes}/extract_plan.coffee +1 -1
- data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +57 -0
- data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +52 -0
- data/lib/assets/javascripts/unpoly/classes/motion_tracker.coffee +95 -0
- data/lib/assets/javascripts/unpoly/classes/record.coffee +16 -0
- data/lib/assets/javascripts/unpoly/classes/request.coffee +228 -0
- data/lib/assets/javascripts/unpoly/classes/response.coffee +138 -0
- data/lib/assets/javascripts/unpoly/dom.coffee +151 -142
- data/lib/assets/javascripts/unpoly/feedback.coffee +67 -38
- data/lib/assets/javascripts/unpoly/form.coffee +156 -139
- data/lib/assets/javascripts/unpoly/history.coffee +22 -19
- data/lib/assets/javascripts/unpoly/layout.coffee +108 -90
- data/lib/assets/javascripts/unpoly/link.coffee +159 -158
- data/lib/assets/javascripts/unpoly/log.coffee +5 -5
- data/lib/assets/javascripts/unpoly/modal.coffee +93 -81
- data/lib/assets/javascripts/unpoly/motion.coffee +291 -250
- data/lib/assets/javascripts/unpoly/popup.coffee +67 -53
- data/lib/assets/javascripts/unpoly/protocol.coffee +67 -16
- data/lib/assets/javascripts/unpoly/proxy.coffee +282 -211
- data/lib/assets/javascripts/unpoly/rails.coffee +3 -14
- data/lib/assets/javascripts/unpoly/syntax.coffee +54 -49
- data/lib/assets/javascripts/unpoly/tooltip.coffee +18 -25
- data/lib/assets/javascripts/unpoly/util.coffee +236 -477
- data/lib/assets/javascripts/unpoly.coffee +1 -1
- data/lib/unpoly/rails/inspector.rb +67 -22
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile.lock +13 -13
- data/spec_app/app/assets/javascripts/integration_test.coffee +1 -0
- data/spec_app/app/assets/javascripts/jasmine_specs.coffee +1 -1
- data/spec_app/app/assets/stylesheets/jasmine_specs.sass +10 -0
- data/spec_app/app/controllers/binding_test_controller.rb +19 -2
- data/spec_app/app/controllers/method_test_controller.rb +16 -0
- data/spec_app/app/views/layouts/jasmine_rails/spec_runner.html.erb +20 -0
- data/spec_app/app/views/method_test/form_target.erb +17 -0
- data/spec_app/app/views/method_test/page1.erb +11 -0
- data/spec_app/app/views/method_test/page2.erb +6 -0
- data/spec_app/app/views/pages/start.erb +33 -19
- data/spec_app/config/initializers/assets.rb +5 -0
- data/spec_app/config/routes.rb +3 -0
- data/spec_app/spec/controllers/binding_test_controller_spec.rb +82 -27
- data/spec_app/spec/javascripts/helpers/agent_detector.coffee +17 -0
- data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +102 -0
- data/spec_app/spec/javascripts/helpers/last_request.js.coffee +1 -1
- data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +5 -2
- data/spec_app/spec/javascripts/helpers/promise_state.js +18 -0
- data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +9 -0
- data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +22 -0
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +11 -3
- data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +10 -0
- data/spec_app/spec/javascripts/helpers/to_be_error.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_match_url.coffee +13 -0
- data/spec_app/spec/javascripts/helpers/trigger.js.coffee +13 -6
- data/spec_app/spec/javascripts/up/browser_spec.js.coffee +92 -33
- data/spec_app/spec/javascripts/up/bus_spec.js.coffee +64 -15
- data/spec_app/spec/javascripts/up/classes/.keep +0 -0
- data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +1 -0
- data/spec_app/spec/javascripts/up/dom_spec.js.coffee +759 -551
- data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +155 -82
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +490 -349
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +226 -179
- data/spec_app/spec/javascripts/up/layout_spec.js.coffee +253 -185
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +416 -270
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +459 -330
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +198 -153
- data/spec_app/spec/javascripts/up/namespace_spec.js.coffee +9 -0
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +240 -175
- data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +38 -0
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +777 -303
- data/spec_app/spec/javascripts/up/rails_spec.js.coffee +24 -8
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +40 -23
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +80 -66
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +227 -201
- data/spec_app/vendor/asset-libs/es6-promise-4.1.6/es6-promise.auto.js +1159 -0
- metadata +30 -7
- data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +0 -7
- data/spec_app/spec/javascripts/helpers/to_equal_url.coffee +0 -11
@@ -1,6 +1,9 @@
|
|
1
1
|
describe 'up.history', ->
|
2
2
|
|
3
3
|
u = up.util
|
4
|
+
|
5
|
+
beforeEach ->
|
6
|
+
up.history.config.enabled = true
|
4
7
|
|
5
8
|
describe 'JavaScript functions', ->
|
6
9
|
|
@@ -10,37 +13,41 @@ describe 'up.history', ->
|
|
10
13
|
|
11
14
|
describe 'up.history.url', ->
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
describeCapability 'canPushState', ->
|
17
|
+
|
18
|
+
it 'does not strip a trailing slash from the current URL', ->
|
19
|
+
history.replaceState?({}, 'title', '/host/path/')
|
20
|
+
expect(up.history.url()).toMatchUrl('/host/path/')
|
16
21
|
|
17
22
|
describe 'up.history.isUrl', ->
|
18
23
|
|
19
|
-
|
20
|
-
history.replaceState?({}, 'title', '/host/path/')
|
21
|
-
expect(up.history.isUrl('/host/path/')).toBe(true)
|
24
|
+
describeCapability 'canPushState', ->
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
it 'returns true if the given path is the current URL', ->
|
27
|
+
history.replaceState?({}, 'title', '/host/path/')
|
28
|
+
expect(up.history.isUrl('/host/path/')).toBe(true)
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
it 'returns false if the given path is not the current URL', ->
|
31
|
+
history.replaceState?({}, 'title', '/host/path/')
|
32
|
+
expect(up.history.isUrl('/host/other-path/')).toBe(false)
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
it 'returns true if the given full URL is the current URL', ->
|
35
|
+
history.replaceState?({}, 'title', '/host/path/')
|
36
|
+
expect(up.history.isUrl("http://#{location.host}/host/path/")).toBe(true)
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
it 'returns true if the given path is the current URL, but without a trailing slash', ->
|
39
|
+
history.replaceState?({}, 'title', '/host/path/')
|
40
|
+
expect(up.history.isUrl('/host/path')).toBe(true)
|
41
|
+
|
42
|
+
it 'returns true if the given path is the current URL, but with a trailing slash', ->
|
43
|
+
history.replaceState?({}, 'title', '/host/path')
|
44
|
+
expect(up.history.isUrl('/host/path/')).toBe(true)
|
38
45
|
|
39
46
|
describe 'unobtrusive behavior', ->
|
40
47
|
|
41
48
|
describe 'back button', ->
|
42
49
|
|
43
|
-
it 'calls destructor functions when destroying compiled elements (bugfix)', (
|
50
|
+
it 'calls destructor functions when destroying compiled elements (bugfix)', asyncSpec (next) ->
|
44
51
|
waitForBrowser = 70
|
45
52
|
|
46
53
|
# By default, up.history will replace the <body> tag when
|
@@ -65,227 +72,267 @@ describe 'up.history', ->
|
|
65
72
|
expect(constructorSpy).toHaveBeenCalled()
|
66
73
|
|
67
74
|
history.back()
|
68
|
-
u.setTimer waitForBrowser, =>
|
69
|
-
expect(location.pathname).toEqual('/one')
|
70
75
|
|
76
|
+
next.after waitForBrowser, =>
|
77
|
+
expect(location.pathname).toEqual('/one')
|
71
78
|
@respondWith "<div class='container'>restored container text</div>"
|
72
79
|
|
73
|
-
|
74
|
-
|
75
|
-
done()
|
80
|
+
next =>
|
81
|
+
expect(destructorSpy).toHaveBeenCalled()
|
76
82
|
|
77
83
|
|
78
84
|
describe '[up-back]', ->
|
79
85
|
|
80
|
-
|
81
|
-
|
82
|
-
up
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
describeCapability 'canPushState', ->
|
87
|
+
|
88
|
+
it 'sets an [up-href] attribute to the previous URL and sets the up-restore-scroll attribute to "true"', ->
|
89
|
+
up.history.push('/path1')
|
90
|
+
up.history.push('/path2')
|
91
|
+
$element = up.hello(affix('a[href="/path3"][up-back]').text('text'))
|
92
|
+
expect($element.attr('href')).toMatchUrl('/path3')
|
93
|
+
expect($element.attr('up-href')).toMatchUrl('/path1')
|
94
|
+
expect($element.attr('up-restore-scroll')).toBe('')
|
95
|
+
expect($element.attr('up-follow')).toBe('')
|
88
96
|
|
89
97
|
it 'does not overwrite an existing up-href or up-restore-scroll attribute'
|
90
98
|
|
91
99
|
it 'does not set an up-href attribute if there is no previous URL'
|
92
100
|
|
101
|
+
describeFallback 'canPushState', ->
|
102
|
+
|
103
|
+
it 'does not change the element', ->
|
104
|
+
$element = up.hello(affix('a[href="/three"][up-back]').text('text'))
|
105
|
+
expect($element.attr('up-href')).toBeUndefined()
|
106
|
+
|
93
107
|
describe 'scroll restoration', ->
|
94
108
|
|
95
|
-
|
96
|
-
$('.viewport').remove()
|
109
|
+
describeCapability 'canPushState', ->
|
97
110
|
|
98
|
-
|
111
|
+
afterEach ->
|
112
|
+
$('.viewport').remove()
|
99
113
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
114
|
+
it 'restores the scroll position of viewports when the user hits the back button', asyncSpec (next) ->
|
115
|
+
|
116
|
+
longContentHtml = """
|
117
|
+
<div class="viewport" style="width: 100px; height: 100px; overflow-y: scroll">
|
118
|
+
<div class="content" style="height: 1000px"></div>
|
119
|
+
</div>
|
120
|
+
"""
|
105
121
|
|
106
|
-
|
122
|
+
respond = => @respondWith(longContentHtml)
|
107
123
|
|
108
|
-
|
124
|
+
$viewport = $(longContentHtml).appendTo(document.body)
|
109
125
|
|
110
|
-
|
111
|
-
|
126
|
+
up.layout.config.viewports = ['.viewport']
|
127
|
+
up.history.config.popTargets = ['.viewport']
|
112
128
|
|
113
|
-
|
114
|
-
respond()
|
129
|
+
up.replace('.content', '/one')
|
115
130
|
|
116
|
-
|
131
|
+
next =>
|
132
|
+
respond()
|
117
133
|
|
118
|
-
|
119
|
-
|
134
|
+
next =>
|
135
|
+
$viewport.scrollTop(50)
|
136
|
+
up.replace('.content', '/two')
|
120
137
|
|
121
|
-
|
138
|
+
next =>
|
139
|
+
respond()
|
122
140
|
|
123
|
-
|
124
|
-
|
125
|
-
|
141
|
+
next =>
|
142
|
+
$('.viewport').scrollTop(150)
|
143
|
+
up.replace('.content', '/three')
|
126
144
|
|
127
|
-
|
128
|
-
|
129
|
-
respond() # we need to respond since we've never requested /two with the popTarget
|
130
|
-
expect($('.viewport').scrollTop()).toBe(150)
|
145
|
+
next =>
|
146
|
+
respond()
|
131
147
|
|
132
|
-
|
133
|
-
|
148
|
+
next =>
|
149
|
+
$('.viewport').scrollTop(250)
|
150
|
+
history.back()
|
151
|
+
|
152
|
+
next.after 50, =>
|
153
|
+
respond() # we need to respond since we've never requested /two with the popTarget
|
154
|
+
|
155
|
+
next =>
|
156
|
+
expect($('.viewport').scrollTop()).toBe(150)
|
157
|
+
history.back()
|
158
|
+
|
159
|
+
next.after 50, =>
|
134
160
|
respond() # we need to respond since we've never requested /one with the popTarget
|
161
|
+
|
162
|
+
next =>
|
135
163
|
expect($('.viewport').scrollTop()).toBe(50)
|
164
|
+
history.forward()
|
136
165
|
|
166
|
+
next.after 50, =>
|
167
|
+
# No need to respond since we requested /two with the popTarget
|
168
|
+
# when we went backwards
|
169
|
+
expect($('.viewport').scrollTop()).toBe(150)
|
137
170
|
history.forward()
|
138
|
-
u.setTimer 50, ->
|
139
|
-
# No need to respond since we requested /two with the popTarget
|
140
|
-
# when we went backwards
|
141
|
-
expect($('.viewport').scrollTop()).toBe(150)
|
142
|
-
|
143
|
-
history.forward()
|
144
|
-
u.setTimer 50, ->
|
145
|
-
respond() # we need to respond since we've never requested /three with the popTarget
|
146
|
-
expect($('.viewport').scrollTop()).toBe(250)
|
147
|
-
done()
|
148
|
-
|
149
|
-
it 'restores the scroll position of two viewports marked with [up-viewport], but not configured in up.layout.config (bugfix)', (done) ->
|
150
|
-
up.history.config.popTargets = ['.container']
|
151
171
|
|
152
|
-
|
153
|
-
|
154
|
-
<div class="viewport1" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
|
155
|
-
<div class="content1" style="height: 5000px">content1</div>
|
156
|
-
</div>
|
157
|
-
<div class="viewport2" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
|
158
|
-
<div class="content2" style="height: 5000px">content2</div>
|
159
|
-
</div>
|
160
|
-
</div>
|
161
|
-
"""
|
172
|
+
next.after 50, =>
|
173
|
+
respond() # we need to respond since we've never requested /three with the popTarget
|
162
174
|
|
163
|
-
|
175
|
+
next =>
|
176
|
+
expect($('.viewport').scrollTop()).toBe(250)
|
164
177
|
|
165
|
-
|
166
|
-
|
178
|
+
it 'restores the scroll position of two viewports marked with [up-viewport], but not configured in up.layout.config (bugfix)', asyncSpec (next) ->
|
179
|
+
up.history.config.popTargets = ['.container']
|
167
180
|
|
168
|
-
|
169
|
-
|
181
|
+
html = """
|
182
|
+
<div class="container">
|
183
|
+
<div class="viewport1" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
|
184
|
+
<div class="content1" style="height: 5000px">content1</div>
|
185
|
+
</div>
|
186
|
+
<div class="viewport2" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
|
187
|
+
<div class="content2" style="height: 5000px">content2</div>
|
188
|
+
</div>
|
189
|
+
</div>
|
190
|
+
"""
|
191
|
+
|
192
|
+
respond = => @respondWith(html)
|
170
193
|
|
171
|
-
|
172
|
-
|
194
|
+
$screen = affix('.screen')
|
195
|
+
$screen.html(html)
|
173
196
|
|
174
|
-
|
175
|
-
expect('.viewport2').toBeScrolledTo(3050)
|
197
|
+
up.replace('.content1, .content2', '/one', reveal: false)
|
176
198
|
|
177
|
-
|
178
|
-
|
199
|
+
next =>
|
200
|
+
respond()
|
179
201
|
|
180
|
-
|
202
|
+
next =>
|
203
|
+
$('.viewport1').scrollTop(3000)
|
204
|
+
$('.viewport2').scrollTop(3050)
|
205
|
+
expect('.viewport1').toBeScrolledTo(3000)
|
206
|
+
expect('.viewport2').toBeScrolledTo(3050)
|
181
207
|
|
182
|
-
|
208
|
+
up.replace('.content1, .content2', '/two', reveal: false)
|
183
209
|
|
184
|
-
|
210
|
+
next =>
|
211
|
+
respond()
|
185
212
|
|
186
|
-
|
213
|
+
next.after 50, =>
|
214
|
+
expect(location.href).toMatchUrl('/two')
|
215
|
+
history.back()
|
216
|
+
|
217
|
+
next.after 50, =>
|
187
218
|
# we need to respond since we've never requested the original URL with the popTarget
|
188
219
|
respond()
|
189
220
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
done()
|
221
|
+
next =>
|
222
|
+
expect('.viewport1').toBeScrolledTo(3000)
|
223
|
+
expect('.viewport2').toBeScrolledTo(3050)
|
194
224
|
|
195
225
|
|
196
226
|
describe 'events', ->
|
197
227
|
|
198
|
-
|
199
|
-
up.proxy.config.cacheSize = 0
|
200
|
-
up.history.config.popTargets = ['.viewport']
|
228
|
+
describeCapability 'canPushState', ->
|
201
229
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
"""
|
230
|
+
it 'emits up:history:* events as the user goes forwards and backwards through history', asyncSpec (next) ->
|
231
|
+
up.proxy.config.cacheSize = 0
|
232
|
+
up.history.config.popTargets = ['.viewport']
|
233
|
+
|
234
|
+
affix('.viewport .content')
|
235
|
+
respond = =>
|
236
|
+
@respondWith """
|
237
|
+
<div class="viewport">
|
238
|
+
<div class="content">content</div>
|
239
|
+
</div>
|
240
|
+
"""
|
209
241
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
242
|
+
events = []
|
243
|
+
u.each ['up:history:pushed', 'up:history:restored'], (eventName) ->
|
244
|
+
up.on eventName, (event) ->
|
245
|
+
events.push [eventName, event.url]
|
214
246
|
|
215
|
-
|
247
|
+
normalize = up.history.normalizeUrl
|
216
248
|
|
217
|
-
|
218
|
-
respond()
|
249
|
+
up.replace('.content', '/foo')
|
219
250
|
|
220
|
-
|
221
|
-
|
222
|
-
|
251
|
+
next =>
|
252
|
+
respond()
|
253
|
+
|
254
|
+
next =>
|
255
|
+
expect(events).toEqual [
|
256
|
+
['up:history:pushed', normalize('/foo')]
|
257
|
+
]
|
223
258
|
|
224
|
-
|
225
|
-
respond()
|
259
|
+
up.replace('.content', '/bar')
|
226
260
|
|
227
|
-
|
228
|
-
|
229
|
-
['up:history:pushed', normalize('/two')]
|
230
|
-
]
|
261
|
+
next =>
|
262
|
+
respond()
|
231
263
|
|
232
|
-
|
233
|
-
|
264
|
+
next =>
|
265
|
+
expect(events).toEqual [
|
266
|
+
['up:history:pushed', normalize('/foo')]
|
267
|
+
['up:history:pushed', normalize('/bar')]
|
268
|
+
]
|
234
269
|
|
235
|
-
|
236
|
-
['up:history:pushed', normalize('/one')]
|
237
|
-
['up:history:pushed', normalize('/two')]
|
238
|
-
['up:history:pushed', normalize('/three')]
|
239
|
-
]
|
270
|
+
up.replace('.content', '/baz')
|
240
271
|
|
241
|
-
|
242
|
-
u.setTimer 50, ->
|
243
|
-
respond()
|
244
|
-
|
245
|
-
expect(events).toEqual [
|
246
|
-
['up:history:pushed', normalize('/one')]
|
247
|
-
['up:history:pushed', normalize('/two')]
|
248
|
-
['up:history:pushed', normalize('/three')]
|
249
|
-
['up:history:restored', normalize('/two')]
|
250
|
-
]
|
251
|
-
|
252
|
-
history.back()
|
253
|
-
u.setTimer 50, ->
|
272
|
+
next =>
|
254
273
|
respond()
|
255
274
|
|
275
|
+
next =>
|
256
276
|
expect(events).toEqual [
|
257
|
-
['up:history:pushed', normalize('/
|
258
|
-
['up:history:pushed', normalize('/
|
259
|
-
['up:history:pushed', normalize('/
|
260
|
-
|
261
|
-
|
277
|
+
['up:history:pushed', normalize('/foo')]
|
278
|
+
['up:history:pushed', normalize('/bar')]
|
279
|
+
['up:history:pushed', normalize('/baz')]
|
280
|
+
]
|
281
|
+
|
282
|
+
history.back()
|
283
|
+
|
284
|
+
next.after 50, =>
|
285
|
+
respond()
|
286
|
+
|
287
|
+
next =>
|
288
|
+
expect(events).toEqual [
|
289
|
+
['up:history:pushed', normalize('/foo')]
|
290
|
+
['up:history:pushed', normalize('/bar')]
|
291
|
+
['up:history:pushed', normalize('/baz')]
|
292
|
+
['up:history:restored', normalize('/bar')]
|
293
|
+
]
|
294
|
+
|
295
|
+
history.back()
|
296
|
+
|
297
|
+
next.after 50, =>
|
298
|
+
respond()
|
299
|
+
|
300
|
+
next =>
|
301
|
+
expect(events).toEqual [
|
302
|
+
['up:history:pushed', normalize('/foo')]
|
303
|
+
['up:history:pushed', normalize('/bar')]
|
304
|
+
['up:history:pushed', normalize('/baz')]
|
305
|
+
['up:history:restored', normalize('/bar')]
|
306
|
+
['up:history:restored', normalize('/foo')]
|
262
307
|
]
|
263
308
|
|
264
309
|
history.forward()
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
]
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
310
|
+
|
311
|
+
next.after 50, =>
|
312
|
+
respond()
|
313
|
+
|
314
|
+
next =>
|
315
|
+
expect(events).toEqual [
|
316
|
+
['up:history:pushed', normalize('/foo')]
|
317
|
+
['up:history:pushed', normalize('/bar')]
|
318
|
+
['up:history:pushed', normalize('/baz')]
|
319
|
+
['up:history:restored', normalize('/bar')]
|
320
|
+
['up:history:restored', normalize('/foo')]
|
321
|
+
['up:history:restored', normalize('/bar')]
|
322
|
+
]
|
323
|
+
|
324
|
+
history.forward()
|
325
|
+
|
326
|
+
next.after 50, =>
|
327
|
+
respond() # we need to respond since we've never requested /baz with the popTarget
|
328
|
+
|
329
|
+
next =>
|
330
|
+
expect(events).toEqual [
|
331
|
+
['up:history:pushed', normalize('/foo')]
|
332
|
+
['up:history:pushed', normalize('/bar')]
|
333
|
+
['up:history:pushed', normalize('/baz')]
|
334
|
+
['up:history:restored', normalize('/bar')]
|
335
|
+
['up:history:restored', normalize('/foo')]
|
336
|
+
['up:history:restored', normalize('/bar')]
|
337
|
+
['up:history:restored', normalize('/baz')]
|
338
|
+
]
|