unpoly-rails 0.53.4 → 0.54.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 +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
|