unpoly-rails 0.52.0 → 0.53.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.

@@ -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
- it "doesn't make a request and reveals the target container"
340
+ describe 'revealing', ->
342
341
 
343
- it "doesn't make a request and reveals the target of a #hash in the URL"
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 a non-200 status code', asyncSpec (next) ->
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("[up-id='up-id-value']")
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 "prefers using the element's name to using the element's classes", ->
288
- $element = affix('div[name=name-value].class1.class2')
289
- expect(up.util.selectorForElement($element)).toBe("[name='name-value']")
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 "prefers using the element's classes to using the element's tag name", ->
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.52.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-08 00:00:00.000000000 Z
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