unpoly-rails 0.52.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -2
- data/dist/unpoly.js +204 -55
- data/dist/unpoly.min.js +4 -4
- data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +20 -2
- data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +3 -9
- data/lib/assets/javascripts/unpoly/dom.coffee +14 -5
- data/lib/assets/javascripts/unpoly/form.coffee +23 -5
- data/lib/assets/javascripts/unpoly/layout.coffee +8 -2
- data/lib/assets/javascripts/unpoly/link.coffee +19 -5
- data/lib/assets/javascripts/unpoly/protocol.coffee +12 -6
- data/lib/assets/javascripts/unpoly/radio.coffee +63 -0
- data/lib/assets/javascripts/unpoly/util.coffee +15 -4
- data/lib/assets/javascripts/unpoly.coffee +1 -0
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/controllers/hash_test_controller.rb +5 -0
- data/spec_app/app/views/hash_test/vanilla.erb +13 -0
- data/spec_app/app/views/pages/start.erb +1 -0
- data/spec_app/config/routes.rb +1 -0
- data/spec_app/spec/javascripts/up/dom_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +111 -1
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +122 -4
- data/spec_app/spec/javascripts/up/radio_spec.js.coffee +75 -0
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +30 -5
- metadata +6 -2
@@ -336,11 +336,129 @@ describe 'up.link', ->
|
|
336
336
|
next =>
|
337
337
|
expect($viewport.scrollTop()).toEqual(65)
|
338
338
|
|
339
|
-
describe "when the browser is already on the link's destination", ->
|
340
339
|
|
341
|
-
|
340
|
+
describe 'revealing', ->
|
342
341
|
|
343
|
-
it
|
342
|
+
it 'reaveals the target fragment', asyncSpec (next) ->
|
343
|
+
$link = affix('a[href="/action"][up-target=".target"]')
|
344
|
+
$target = affix('.target')
|
345
|
+
|
346
|
+
revealStub = up.layout.knife.mock('reveal')
|
347
|
+
|
348
|
+
up.follow($link)
|
349
|
+
|
350
|
+
next =>
|
351
|
+
@respondWith('<div class="target">new text</div>')
|
352
|
+
|
353
|
+
next =>
|
354
|
+
expect(revealStub).toHaveBeenCalled()
|
355
|
+
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.target')
|
356
|
+
|
357
|
+
it 'reveals the { failTarget } if the server responds with an error', asyncSpec (next) ->
|
358
|
+
$link = affix('a[href="/action"][up-target=".target"][up-fail-target=".fail-target"]')
|
359
|
+
$target = affix('.target')
|
360
|
+
$failTarget = affix('.fail-target')
|
361
|
+
|
362
|
+
revealStub = up.layout.knife.mock('reveal')
|
363
|
+
|
364
|
+
up.follow($link)
|
365
|
+
|
366
|
+
next =>
|
367
|
+
@respondWith
|
368
|
+
status: 500,
|
369
|
+
responseText: """
|
370
|
+
<div class="fail-target">
|
371
|
+
Errors here
|
372
|
+
</div>
|
373
|
+
"""
|
374
|
+
|
375
|
+
next =>
|
376
|
+
expect(revealStub).toHaveBeenCalled()
|
377
|
+
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.fail-target')
|
378
|
+
|
379
|
+
|
380
|
+
describe 'with { reveal } option', ->
|
381
|
+
|
382
|
+
it 'allows to reveal a different selector', asyncSpec (next) ->
|
383
|
+
$link = affix('a[href="/action"][up-target=".target"]')
|
384
|
+
$target = affix('.target')
|
385
|
+
$other = affix('.other')
|
386
|
+
|
387
|
+
revealStub = up.layout.knife.mock('reveal')
|
388
|
+
|
389
|
+
up.follow($link, reveal: '.other')
|
390
|
+
|
391
|
+
next =>
|
392
|
+
@respondWith """
|
393
|
+
<div class="target">
|
394
|
+
new text
|
395
|
+
</div>
|
396
|
+
<div class="other">
|
397
|
+
new other
|
398
|
+
</div>
|
399
|
+
"""
|
400
|
+
|
401
|
+
next =>
|
402
|
+
expect(revealStub).toHaveBeenCalled()
|
403
|
+
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.other')
|
404
|
+
|
405
|
+
it 'still reveals the { failTarget } for a failed submission', asyncSpec (next) ->
|
406
|
+
$link = affix('a[href="/action"][up-target=".target"][up-fail-target=".fail-target"]')
|
407
|
+
$target = affix('.target')
|
408
|
+
$failTarget = affix('.fail-target')
|
409
|
+
$other = affix('.other')
|
410
|
+
|
411
|
+
revealStub = up.layout.knife.mock('reveal')
|
412
|
+
|
413
|
+
up.submit($link, reveal: '.other', failTarget: '.fail-target')
|
414
|
+
|
415
|
+
next =>
|
416
|
+
@respondWith
|
417
|
+
status: 500,
|
418
|
+
responseText: """
|
419
|
+
<div class="fail-target">
|
420
|
+
Errors here
|
421
|
+
</div>
|
422
|
+
"""
|
423
|
+
|
424
|
+
next =>
|
425
|
+
expect(revealStub).toHaveBeenCalled()
|
426
|
+
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.fail-target')
|
427
|
+
|
428
|
+
describe 'with { failReveal } option', ->
|
429
|
+
|
430
|
+
it 'reveals the given selector when the server responds with an error', asyncSpec (next) ->
|
431
|
+
$link = affix('a[href="/action"][up-target=".target"][up-fail-target=".fail-target"]')
|
432
|
+
$target = affix('.target')
|
433
|
+
$failTarget = affix('.fail-target')
|
434
|
+
$other = affix('.other')
|
435
|
+
$failOther = affix('.fail-other')
|
436
|
+
|
437
|
+
revealStub = up.layout.knife.mock('reveal')
|
438
|
+
|
439
|
+
up.follow($link, reveal: '.other', failReveal: '.fail-other')
|
440
|
+
|
441
|
+
next =>
|
442
|
+
@respondWith
|
443
|
+
status: 500,
|
444
|
+
responseText: """
|
445
|
+
<div class="fail-target">
|
446
|
+
Errors here
|
447
|
+
</div>
|
448
|
+
<div class="fail-other">
|
449
|
+
Fail other here
|
450
|
+
</div>
|
451
|
+
"""
|
452
|
+
|
453
|
+
next =>
|
454
|
+
expect(revealStub).toHaveBeenCalled()
|
455
|
+
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.fail-other')
|
456
|
+
|
457
|
+
describe "when the browser is already on the link's destination", ->
|
458
|
+
|
459
|
+
it "doesn't make a request and reveals the target container"
|
460
|
+
|
461
|
+
it "doesn't make a request and reveals the target of a #hash in the URL"
|
344
462
|
|
345
463
|
describe 'with { confirm } option', ->
|
346
464
|
|
@@ -609,7 +727,7 @@ describe 'up.link', ->
|
|
609
727
|
expect($('.document .target')).toHaveText('new text from modal link')
|
610
728
|
expect($('.up-modal .target')).toHaveText('old modal text')
|
611
729
|
|
612
|
-
it 'ignores [up-layer] if the server responds with
|
730
|
+
it 'ignores [up-layer] if the server responds with an error', asyncSpec (next) ->
|
613
731
|
affix('.document').affix('.target').text('old document text')
|
614
732
|
up.modal.extract('.target', "<div class='target'>old modal text</div>", sticky: true)
|
615
733
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
describe 'up.radio', ->
|
2
|
+
|
3
|
+
describe 'JavaScript functions', ->
|
4
|
+
|
5
|
+
describe 'unobtrusive behavior', ->
|
6
|
+
|
7
|
+
describe '[up-hungry]', ->
|
8
|
+
|
9
|
+
it "replaces the element when it is found in a response, even when the element wasn't targeted", asyncSpec (next) ->
|
10
|
+
affix('.hungry[up-hungry]').text('old hungry')
|
11
|
+
affix('.target').text('old target')
|
12
|
+
|
13
|
+
up.replace('.target', '/path')
|
14
|
+
|
15
|
+
next =>
|
16
|
+
@respondWith """
|
17
|
+
<div class="target">
|
18
|
+
new target
|
19
|
+
</div>
|
20
|
+
<div class="between">
|
21
|
+
new between
|
22
|
+
</div>
|
23
|
+
<div class="hungry">
|
24
|
+
new hungry
|
25
|
+
</div>
|
26
|
+
"""
|
27
|
+
|
28
|
+
next =>
|
29
|
+
expect('.target').toHaveText('new target')
|
30
|
+
expect('.hungry').toHaveText('new hungry')
|
31
|
+
|
32
|
+
it "does not impede replacements when the element is not part of a response", asyncSpec (next) ->
|
33
|
+
affix('.hungry[up-hungry]').text('old hungry')
|
34
|
+
affix('.target').text('old target')
|
35
|
+
|
36
|
+
promise = up.replace('.target', '/path')
|
37
|
+
|
38
|
+
next =>
|
39
|
+
@respondWith """
|
40
|
+
<div class="target">
|
41
|
+
new target
|
42
|
+
</div>
|
43
|
+
"""
|
44
|
+
|
45
|
+
next =>
|
46
|
+
expect('.target').toHaveText('new target')
|
47
|
+
expect('.hungry').toHaveText('old hungry')
|
48
|
+
|
49
|
+
promiseState(promise).then (result) ->
|
50
|
+
expect(result.state).toEqual('fulfilled')
|
51
|
+
|
52
|
+
it 'does not replace the element when the server responds with an error', asyncSpec (next) ->
|
53
|
+
affix('.hungry[up-hungry]').text('old hungry')
|
54
|
+
affix('.target').text('old target')
|
55
|
+
|
56
|
+
up.replace('.target', '/path', failTarget: '.target')
|
57
|
+
|
58
|
+
next =>
|
59
|
+
@respondWith
|
60
|
+
status: 500
|
61
|
+
responseText: """
|
62
|
+
<div class="target">
|
63
|
+
new target
|
64
|
+
</div>
|
65
|
+
<div class="between">
|
66
|
+
new between
|
67
|
+
</div>
|
68
|
+
<div class="hungry">
|
69
|
+
new hungry
|
70
|
+
</div>
|
71
|
+
"""
|
72
|
+
|
73
|
+
next =>
|
74
|
+
expect('.target').toHaveText('new target')
|
75
|
+
expect('.hungry').toHaveText('old hungry')
|
@@ -278,24 +278,49 @@ describe 'up.util', ->
|
|
278
278
|
|
279
279
|
it "prefers using the element's 'up-id' attribute to using the element's ID", ->
|
280
280
|
$element = affix('div[up-id=up-id-value]#id-value')
|
281
|
-
expect(up.util.selectorForElement($element)).toBe(
|
281
|
+
expect(up.util.selectorForElement($element)).toBe('[up-id="up-id-value"]')
|
282
282
|
|
283
283
|
it "prefers using the element's ID to using the element's name", ->
|
284
284
|
$element = affix('div#id-value[name=name-value]')
|
285
285
|
expect(up.util.selectorForElement($element)).toBe("#id-value")
|
286
286
|
|
287
|
-
it "
|
288
|
-
$element = affix('div
|
289
|
-
expect(up.util.selectorForElement($element)).toBe(
|
287
|
+
it "selects the ID with an attribute selector if the ID contains a slash", ->
|
288
|
+
$element = affix('div').attr(id: 'foo/bar')
|
289
|
+
expect(up.util.selectorForElement($element)).toBe('[id="foo/bar"]')
|
290
290
|
|
291
|
-
it "
|
291
|
+
it "selects the ID with an attribute selector if the ID contains a space", ->
|
292
|
+
$element = affix('div').attr(id: 'foo bar')
|
293
|
+
expect(up.util.selectorForElement($element)).toBe('[id="foo bar"]')
|
294
|
+
|
295
|
+
it "selects the ID with an attribute selector if the ID contains a dot", ->
|
296
|
+
$element = affix('div').attr(id: 'foo.bar')
|
297
|
+
expect(up.util.selectorForElement($element)).toBe('[id="foo.bar"]')
|
298
|
+
|
299
|
+
it "selects the ID with an attribute selector if the ID contains a quote", ->
|
300
|
+
$element = affix('div').attr(id: 'foo"bar')
|
301
|
+
expect(up.util.selectorForElement($element)).toBe('[id="foo\\"bar"]')
|
302
|
+
|
303
|
+
it "prefers using the element's tagName + [name] to using the element's classes", ->
|
304
|
+
$element = affix('input[name=name-value].class1.class2')
|
305
|
+
expect(up.util.selectorForElement($element)).toBe('input[name="name-value"]')
|
306
|
+
|
307
|
+
it "prefers using the element's classes to using the element's ARIA label", ->
|
292
308
|
$element = affix('div.class1.class2')
|
293
309
|
expect(up.util.selectorForElement($element)).toBe(".class1.class2")
|
294
310
|
|
311
|
+
it "prefers using the element's ARIA label to using the element's tag name", ->
|
312
|
+
$element = affix('div[aria-label="ARIA label value"]')
|
313
|
+
expect(up.util.selectorForElement($element)).toBe('[aria-label="ARIA label value"]')
|
314
|
+
|
295
315
|
it "uses the element's tag name if no better description is available", ->
|
296
316
|
$element = affix('div')
|
297
317
|
expect(up.util.selectorForElement($element)).toBe("div")
|
298
318
|
|
319
|
+
it 'escapes quotes in attribute selector values', ->
|
320
|
+
$element = affix('div')
|
321
|
+
$element.attr('aria-label', 'foo"bar')
|
322
|
+
expect(up.util.selectorForElement($element)).toBe('[aria-label="foo\\"bar"]')
|
323
|
+
|
299
324
|
|
300
325
|
describe 'up.util.castedAttr', ->
|
301
326
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unpoly-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.53.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henning Koch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- lib/assets/javascripts/unpoly/popup.coffee
|
119
119
|
- lib/assets/javascripts/unpoly/protocol.coffee
|
120
120
|
- lib/assets/javascripts/unpoly/proxy.coffee
|
121
|
+
- lib/assets/javascripts/unpoly/radio.coffee
|
121
122
|
- lib/assets/javascripts/unpoly/rails.coffee
|
122
123
|
- lib/assets/javascripts/unpoly/syntax.coffee
|
123
124
|
- lib/assets/javascripts/unpoly/toast.coffee
|
@@ -164,6 +165,7 @@ files:
|
|
164
165
|
- spec_app/app/controllers/form_test/basics_controller.rb
|
165
166
|
- spec_app/app/controllers/form_test/redirects_controller.rb
|
166
167
|
- spec_app/app/controllers/form_test/uploads_controller.rb
|
168
|
+
- spec_app/app/controllers/hash_test_controller.rb
|
167
169
|
- spec_app/app/controllers/method_test_controller.rb
|
168
170
|
- spec_app/app/controllers/pages_controller.rb
|
169
171
|
- spec_app/app/controllers/replace_test_controller.rb
|
@@ -183,6 +185,7 @@ files:
|
|
183
185
|
- spec_app/app/views/form_test/redirects/target.erb
|
184
186
|
- spec_app/app/views/form_test/submission_result.erb
|
185
187
|
- spec_app/app/views/form_test/uploads/new.erb
|
188
|
+
- spec_app/app/views/hash_test/vanilla.erb
|
186
189
|
- spec_app/app/views/layouts/integration_test.erb
|
187
190
|
- spec_app/app/views/layouts/jasmine_rails/spec_runner.html.erb
|
188
191
|
- spec_app/app/views/method_test/form_target.erb
|
@@ -282,6 +285,7 @@ files:
|
|
282
285
|
- spec_app/spec/javascripts/up/popup_spec.js.coffee
|
283
286
|
- spec_app/spec/javascripts/up/protocol_spec.js.coffee
|
284
287
|
- spec_app/spec/javascripts/up/proxy_spec.js.coffee
|
288
|
+
- spec_app/spec/javascripts/up/radio_spec.js.coffee
|
285
289
|
- spec_app/spec/javascripts/up/rails_spec.js.coffee
|
286
290
|
- spec_app/spec/javascripts/up/syntax_spec.js.coffee
|
287
291
|
- spec_app/spec/javascripts/up/tooltip_spec.js.coffee
|