unpoly-rails 0.53.4 → 0.54.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 +49 -0
- data/dist/unpoly.js +52 -30
- data/dist/unpoly.min.js +4 -4
- data/lib/assets/javascripts/unpoly/dom.coffee +12 -6
- data/lib/assets/javascripts/unpoly/form.coffee +17 -6
- data/lib/assets/javascripts/unpoly/layout.coffee +4 -2
- data/lib/assets/javascripts/unpoly/link.coffee +7 -1
- data/lib/assets/javascripts/unpoly/protocol.coffee +1 -1
- data/lib/assets/javascripts/unpoly/util.coffee +0 -1
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +0 -1
- data/spec_app/spec/javascripts/up/dom_spec.js.coffee +91 -3
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +114 -0
- data/spec_app/spec/javascripts/up/radio_spec.js.coffee +34 -2
- metadata +2 -2
@@ -350,12 +350,16 @@ up.link = (($) ->
|
|
350
350
|
@selector a[up-target]
|
351
351
|
@param {string} up-target
|
352
352
|
The CSS selector to replace
|
353
|
+
|
354
|
+
Inside the CSS selector you may refer to this link as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
353
355
|
@param {string} [up-method='get']
|
354
356
|
The HTTP method to use for the request.
|
355
357
|
@param {string} [up-transition='none']
|
356
358
|
The [transition](/up.motion) to use for morphing between the old and new elements.
|
357
359
|
@param [up-fail-target='body']
|
358
|
-
The selector to replace if the server responds with an error.
|
360
|
+
The CSS selector to replace if the server responds with an error.
|
361
|
+
|
362
|
+
Inside the CSS selector you may refer to this link as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
359
363
|
@param {string} [up-fail-transition='none']
|
360
364
|
The [transition](/up.motion) to use for morphing between the old and new elements
|
361
365
|
when the server responds with an error.
|
@@ -371,10 +375,12 @@ up.link = (($) ->
|
|
371
375
|
Whether to reveal the target element after it was replaced.
|
372
376
|
|
373
377
|
You can also pass a CSS selector for the element to reveal.
|
378
|
+
Inside the CSS selector you may refer to this link as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
374
379
|
@param {string} [up-fail-reveal='true']
|
375
380
|
Whether to reveal the target element when the server responds with an error.
|
376
381
|
|
377
382
|
You can also pass a CSS selector for the element to reveal.
|
383
|
+
Inside the CSS selector you may refer to this link as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
378
384
|
@param {string} [up-restore-scroll='false']
|
379
385
|
Whether to restore previously known scroll position of all viewports
|
380
386
|
within the target selector.
|
@@ -231,7 +231,7 @@ up.protocol = (($) ->
|
|
231
231
|
The name of the optional cookie the server can send to
|
232
232
|
[signal the initial request method](/up.protocol#signaling-the-initial-request-method).
|
233
233
|
@param {String} [config.methodParam='_method']
|
234
|
-
The name of the POST parameter when [wrapping HTTP methods](/up.
|
234
|
+
The name of the POST parameter when [wrapping HTTP methods](/up.proxy.config#config.wrapMethods)
|
235
235
|
in a `POST` request.
|
236
236
|
@param {String} [config.csrfHeader='X-CSRF-Token']
|
237
237
|
The name of the HTTP header that will include the
|
@@ -1589,7 +1589,6 @@ up.util = (($) ->
|
|
1589
1589
|
poke: =>
|
1590
1590
|
unless @currentTask # don't start a new task while we're still running one
|
1591
1591
|
if @currentTask = @queue.shift()
|
1592
|
-
# console.debug('[DivertibleChain.poke] currentTask is now %o', @currentTask)
|
1593
1592
|
promise = @currentTask()
|
1594
1593
|
always promise, =>
|
1595
1594
|
@currentTask = undefined
|
data/lib/unpoly/rails/version.rb
CHANGED
data/package.json
CHANGED
data/spec_app/Gemfile.lock
CHANGED
@@ -886,8 +886,7 @@ describe 'up.dom', ->
|
|
886
886
|
# No need to respond because /foo has been cached before
|
887
887
|
next => expect($viewport.scrollTop()).toEqual(65)
|
888
888
|
|
889
|
-
|
890
|
-
describe 'with { reveal: true } option', ->
|
889
|
+
describe 'with { reveal } option', ->
|
891
890
|
|
892
891
|
beforeEach ->
|
893
892
|
@revealedHTML = []
|
@@ -910,6 +909,73 @@ describe 'up.dom', ->
|
|
910
909
|
expect(@revealMock).not.toHaveBeenCalledWith(@oldMiddle)
|
911
910
|
expect(@revealedText).toEqual ['new-middle']
|
912
911
|
|
912
|
+
it 'allows to pass another selector to reveal', asyncSpec (next)->
|
913
|
+
$other = affix('.other').text('other text')
|
914
|
+
|
915
|
+
up.replace('.middle', '/path', reveal: '.other')
|
916
|
+
|
917
|
+
next =>
|
918
|
+
@respond()
|
919
|
+
|
920
|
+
next =>
|
921
|
+
expect(@revealedText).toEqual ['other text']
|
922
|
+
|
923
|
+
it 'allows to refer to the replacement { origin } as "&" in the { reveal } selector', asyncSpec (next) ->
|
924
|
+
$origin = affix('.origin').text('origin text')
|
925
|
+
|
926
|
+
up.replace('.middle', '/path', reveal: '&', origin: '.origin')
|
927
|
+
|
928
|
+
next =>
|
929
|
+
@respond()
|
930
|
+
|
931
|
+
next =>
|
932
|
+
expect(@revealedText).toEqual ['origin text']
|
933
|
+
|
934
|
+
describe 'when the server responds with an error code', ->
|
935
|
+
|
936
|
+
it 'ignores the { reveal } option', asyncSpec (next) ->
|
937
|
+
$failTarget = affix('.fail-target')
|
938
|
+
up.replace('.middle', '/path', failTarget: '.fail-target', reveal: true)
|
939
|
+
|
940
|
+
next =>
|
941
|
+
@respond(status: 500)
|
942
|
+
|
943
|
+
next =>
|
944
|
+
expect(@revealMock).not.toHaveBeenCalled()
|
945
|
+
|
946
|
+
it 'accepts a { failReveal } option for error responses', asyncSpec (next) ->
|
947
|
+
$failTarget = affix('.fail-target').text('old fail target text')
|
948
|
+
up.replace('.middle', '/path', failTarget: '.fail-target', reveal: false, failReveal: true)
|
949
|
+
|
950
|
+
next =>
|
951
|
+
@respondWith
|
952
|
+
status: 500
|
953
|
+
responseText: """
|
954
|
+
<div class="fail-target">
|
955
|
+
new fail target text
|
956
|
+
</div>
|
957
|
+
"""
|
958
|
+
|
959
|
+
next =>
|
960
|
+
expect(@revealedText).toEqual ['new fail target text']
|
961
|
+
|
962
|
+
it 'allows to refer to the replacement { origin } as "&" in the { failTarget } selector', asyncSpec (next) ->
|
963
|
+
$origin = affix('.origin').text('origin text')
|
964
|
+
$failTarget = affix('.fail-target').text('old fail target text')
|
965
|
+
up.replace('.middle', '/path', failTarget: '.fail-target', reveal: false, failReveal: '&', origin: $origin)
|
966
|
+
|
967
|
+
next =>
|
968
|
+
@respondWith
|
969
|
+
status: 500
|
970
|
+
responseText: """
|
971
|
+
<div class="fail-target">
|
972
|
+
new fail target text
|
973
|
+
</div>
|
974
|
+
"""
|
975
|
+
|
976
|
+
next =>
|
977
|
+
expect(@revealedText).toEqual ['origin text']
|
978
|
+
|
913
979
|
describe 'when more than one fragment is replaced', ->
|
914
980
|
|
915
981
|
it 'only reveals the first fragment', asyncSpec (next) ->
|
@@ -1187,7 +1253,7 @@ describe 'up.dom', ->
|
|
1187
1253
|
string
|
1188
1254
|
|
1189
1255
|
beforeEach ->
|
1190
|
-
# Need to refactor this spec file so examples don't all share one example
|
1256
|
+
# Need to refactor this spec file so examples don't all share one example
|
1191
1257
|
$('.before, .middle, .after').remove()
|
1192
1258
|
|
1193
1259
|
it 'keeps an [up-keep] element, but does replace other elements around it', asyncSpec (next) ->
|
@@ -1228,6 +1294,26 @@ describe 'up.dom', ->
|
|
1228
1294
|
next =>
|
1229
1295
|
expect(squish($('.container').text())).toEqual('new-before old-inside new-after')
|
1230
1296
|
|
1297
|
+
it 'updates an [up-keep] element with { keep: false } option', asyncSpec (next) ->
|
1298
|
+
$container = affix('.container')
|
1299
|
+
$container.html """
|
1300
|
+
old-before
|
1301
|
+
<div class='element' up-keep>old-inside</div>
|
1302
|
+
old-after
|
1303
|
+
"""
|
1304
|
+
|
1305
|
+
up.extract '.container', """
|
1306
|
+
<div class='container'>
|
1307
|
+
new-before
|
1308
|
+
<div class='element' up-keep>new-inside</div>
|
1309
|
+
new-after
|
1310
|
+
</div>
|
1311
|
+
""",
|
1312
|
+
keep: false
|
1313
|
+
|
1314
|
+
next =>
|
1315
|
+
expect(squish($('.container').text())).toEqual('new-before new-inside new-after')
|
1316
|
+
|
1231
1317
|
describe 'if an [up-keep] element is itself a direct replacement target', ->
|
1232
1318
|
|
1233
1319
|
it "keeps that element", asyncSpec (next) ->
|
@@ -1559,6 +1645,8 @@ describe 'up.dom', ->
|
|
1559
1645
|
expect(newTextDuringTransition).toEqual('new-foo old-bar')
|
1560
1646
|
done()
|
1561
1647
|
|
1648
|
+
|
1649
|
+
|
1562
1650
|
describe 'up.destroy', ->
|
1563
1651
|
|
1564
1652
|
it 'removes the element with the given selector', (done) ->
|
@@ -480,6 +480,28 @@ describe 'up.form', ->
|
|
480
480
|
expect(revealStub).toHaveBeenCalled()
|
481
481
|
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('#foo-form')
|
482
482
|
|
483
|
+
it 'allows to refer to this form as "&" in the selector', asyncSpec (next) ->
|
484
|
+
$form = affix('form#foo-form[action="/action"][up-target="#foo-form"]')
|
485
|
+
|
486
|
+
revealStub = up.layout.knife.mock('reveal')
|
487
|
+
|
488
|
+
up.submit($form, reveal: '& .form-child')
|
489
|
+
|
490
|
+
next =>
|
491
|
+
@respondWith """
|
492
|
+
<div class="target">
|
493
|
+
new text
|
494
|
+
</div>
|
495
|
+
|
496
|
+
<form id="foo-form">
|
497
|
+
<div class="form-child">other</div>
|
498
|
+
</form>
|
499
|
+
"""
|
500
|
+
|
501
|
+
next =>
|
502
|
+
expect(revealStub).toHaveBeenCalled()
|
503
|
+
expect(revealStub.calls.mostRecent().args[0]).toEqual($('#foo-form .form-child'))
|
504
|
+
|
483
505
|
describe 'with { failReveal } option', ->
|
484
506
|
|
485
507
|
it 'reveals the given selector for a failed submission', asyncSpec (next) ->
|
@@ -504,6 +526,31 @@ describe 'up.form', ->
|
|
504
526
|
expect(revealStub).toHaveBeenCalled()
|
505
527
|
expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.error')
|
506
528
|
|
529
|
+
it 'allows to refer to this form as "&" in the selector', asyncSpec (next) ->
|
530
|
+
$form = affix('form#foo-form[action="/action"][up-target=".target"][up-fail-reveal="#foo-form .form-child"]')
|
531
|
+
$target = affix('.target')
|
532
|
+
|
533
|
+
revealStub = up.layout.knife.mock('reveal')
|
534
|
+
|
535
|
+
up.submit($form, reveal: '& .form-child')
|
536
|
+
|
537
|
+
next =>
|
538
|
+
@respondWith
|
539
|
+
status: 500
|
540
|
+
responseText: """
|
541
|
+
<div class="target">
|
542
|
+
new text
|
543
|
+
</div>
|
544
|
+
|
545
|
+
<form id="foo-form">
|
546
|
+
<div class="form-child">other</div>
|
547
|
+
</form>
|
548
|
+
"""
|
549
|
+
|
550
|
+
next =>
|
551
|
+
expect(revealStub).toHaveBeenCalled()
|
552
|
+
expect(revealStub.calls.mostRecent().args[0]).toEqual($('#foo-form .form-child'))
|
553
|
+
|
507
554
|
describe 'in a form with file inputs', ->
|
508
555
|
|
509
556
|
beforeEach ->
|
@@ -559,6 +606,23 @@ describe 'up.form', ->
|
|
559
606
|
next =>
|
560
607
|
expect('.response').toHaveText('new text')
|
561
608
|
|
609
|
+
it 'allows to refer to this form as "&" in the target selector', asyncSpec (next) ->
|
610
|
+
$form = affix('form.my-form[action="/form-target"][up-target="&"]').text('old form text')
|
611
|
+
$submitButton = $form.affix('input[type="submit"]')
|
612
|
+
up.hello($form)
|
613
|
+
|
614
|
+
Trigger.clickSequence($submitButton)
|
615
|
+
|
616
|
+
next =>
|
617
|
+
@respondWith """
|
618
|
+
<form class="my-form">
|
619
|
+
new form text
|
620
|
+
</form>
|
621
|
+
"""
|
622
|
+
|
623
|
+
next =>
|
624
|
+
expect('.my-form').toHaveText('new form text')
|
625
|
+
|
562
626
|
describe 'when the server responds with an error code', ->
|
563
627
|
|
564
628
|
it 'replaces the form instead of the [up-target] selector', asyncSpec (next) ->
|
@@ -596,6 +660,56 @@ describe 'up.form', ->
|
|
596
660
|
# the event handler, our handler mutes the rejection.
|
597
661
|
expect(window).not.toHaveUnhandledRejections()
|
598
662
|
|
663
|
+
it 'updates a given selector when an [up-fail-target] is given', asyncSpec (next) ->
|
664
|
+
$form = affix('form.my-form[action="/path"][up-target=".target"][up-fail-target=".errors"]').text('old form text')
|
665
|
+
$errors = affix('.target').text('old target text')
|
666
|
+
$errors = affix('.errors').text('old errors text')
|
667
|
+
|
668
|
+
$submitButton = $form.affix('input[type="submit"]')
|
669
|
+
up.hello($form)
|
670
|
+
|
671
|
+
Trigger.clickSequence($submitButton)
|
672
|
+
|
673
|
+
next =>
|
674
|
+
@respondWith
|
675
|
+
status: 500
|
676
|
+
responseText: """
|
677
|
+
<form class="my-form">
|
678
|
+
new form text
|
679
|
+
</form>
|
680
|
+
|
681
|
+
<div class="errors">
|
682
|
+
new errors text
|
683
|
+
</div>
|
684
|
+
"""
|
685
|
+
|
686
|
+
next =>
|
687
|
+
expect('.my-form').toHaveText('old form text')
|
688
|
+
expect('.target').toHaveText('old target text')
|
689
|
+
expect('.errors').toHaveText('new errors text')
|
690
|
+
|
691
|
+
it 'allows to refer to this form as "&" in the [up-fail-target] selector', asyncSpec (next) ->
|
692
|
+
$form = affix('form.my-form[action="/form-target"][up-target=".target"][up-fail-target="&"]').text('old form text')
|
693
|
+
$target = affix('.target').text('old target text')
|
694
|
+
|
695
|
+
$submitButton = $form.affix('input[type="submit"]')
|
696
|
+
up.hello($form)
|
697
|
+
|
698
|
+
Trigger.clickSequence($submitButton)
|
699
|
+
|
700
|
+
next =>
|
701
|
+
@respondWith
|
702
|
+
status: 500,
|
703
|
+
responseText: """
|
704
|
+
<form class="my-form">
|
705
|
+
new form text
|
706
|
+
</form>
|
707
|
+
"""
|
708
|
+
|
709
|
+
next =>
|
710
|
+
expect('.target').toHaveText('old target text')
|
711
|
+
expect('.my-form').toHaveText('new form text')
|
712
|
+
|
599
713
|
describe 'submit buttons', ->
|
600
714
|
|
601
715
|
it 'includes the clicked submit button in the params', asyncSpec (next) ->
|
@@ -51,11 +51,23 @@ describe 'up.radio', ->
|
|
51
51
|
promiseState(promise).then (result) ->
|
52
52
|
expect(result.state).toEqual('fulfilled')
|
53
53
|
|
54
|
-
it 'does not
|
54
|
+
it 'does not change the X-Up-Target header for the request', asyncSpec (next) ->
|
55
55
|
affix('.hungry[up-hungry]').text('old hungry')
|
56
56
|
affix('.target').text('old target')
|
57
|
+
affix('.fail-target').text('old fail target')
|
57
58
|
|
58
|
-
up.replace('.target', '/path', failTarget: '.target')
|
59
|
+
up.replace('.target', '/path', failTarget: '.fail-target')
|
60
|
+
|
61
|
+
next =>
|
62
|
+
expect(@lastRequest().requestHeaders['X-Up-Target']).toEqual('.target')
|
63
|
+
expect(@lastRequest().requestHeaders['X-Up-Fail-Target']).toEqual('.fail-target')
|
64
|
+
|
65
|
+
it 'does replace the element when the server responds with an error (e.g. for error flashes)', asyncSpec (next) ->
|
66
|
+
affix('.hungry[up-hungry]').text('old hungry')
|
67
|
+
affix('.target').text('old target')
|
68
|
+
affix('.fail-target').text('old fail target')
|
69
|
+
|
70
|
+
up.replace('.target', '/path', failTarget: '.fail-target')
|
59
71
|
|
60
72
|
next =>
|
61
73
|
@respondWith
|
@@ -64,6 +76,9 @@ describe 'up.radio', ->
|
|
64
76
|
<div class="target">
|
65
77
|
new target
|
66
78
|
</div>
|
79
|
+
<div class="fail-target">
|
80
|
+
new fail target
|
81
|
+
</div>
|
67
82
|
<div class="between">
|
68
83
|
new between
|
69
84
|
</div>
|
@@ -72,6 +87,23 @@ describe 'up.radio', ->
|
|
72
87
|
</div>
|
73
88
|
"""
|
74
89
|
|
90
|
+
it 'does not update [up-hungry] elements with { hungry: false } option', asyncSpec (next) ->
|
91
|
+
affix('.hungry[up-hungry]').text('old hungry')
|
92
|
+
affix('.target').text('old target')
|
93
|
+
|
94
|
+
up.replace('.target', '/path', hungry: false)
|
95
|
+
|
96
|
+
next =>
|
97
|
+
@respondWith
|
98
|
+
responseText: """
|
99
|
+
<div class="target">
|
100
|
+
new target
|
101
|
+
</div>
|
102
|
+
<div class="hungry">
|
103
|
+
new hungry
|
104
|
+
</div>
|
105
|
+
"""
|
106
|
+
|
75
107
|
next =>
|
76
108
|
expect('.target').toHaveText('new target')
|
77
109
|
expect('.hungry').toHaveText('old hungry')
|
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.54.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-03-
|
11
|
+
date: 2018-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|