unpoly-rails 0.55.1 → 0.56.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.

Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -2
  3. data/dist/unpoly-bootstrap3.js +6 -4
  4. data/dist/unpoly-bootstrap3.min.js +1 -1
  5. data/dist/unpoly.js +1323 -805
  6. data/dist/unpoly.min.js +4 -3
  7. data/lib/assets/javascripts/unpoly-bootstrap3/{navigation-ext.coffee → feedback-ext.coffee} +2 -0
  8. data/lib/assets/javascripts/unpoly/browser.coffee.erb +7 -7
  9. data/lib/assets/javascripts/unpoly/bus.coffee.erb +5 -6
  10. data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +127 -0
  11. data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +1 -1
  12. data/lib/assets/javascripts/unpoly/classes/motion_tracker.coffee +62 -32
  13. data/lib/assets/javascripts/unpoly/classes/url_set.coffee +27 -0
  14. data/lib/assets/javascripts/unpoly/dom.coffee.erb +78 -99
  15. data/lib/assets/javascripts/unpoly/feedback.coffee +147 -96
  16. data/lib/assets/javascripts/unpoly/form.coffee.erb +26 -2
  17. data/lib/assets/javascripts/unpoly/history.coffee +2 -1
  18. data/lib/assets/javascripts/unpoly/layout.coffee.erb +68 -12
  19. data/lib/assets/javascripts/unpoly/link.coffee.erb +10 -4
  20. data/lib/assets/javascripts/unpoly/modal.coffee.erb +11 -9
  21. data/lib/assets/javascripts/unpoly/{motion.coffee → motion.coffee.erb} +184 -322
  22. data/lib/assets/javascripts/unpoly/popup.coffee.erb +13 -12
  23. data/lib/assets/javascripts/unpoly/radio.coffee +1 -1
  24. data/lib/assets/javascripts/unpoly/syntax.coffee +8 -17
  25. data/lib/assets/javascripts/unpoly/tooltip.coffee +11 -11
  26. data/lib/assets/javascripts/unpoly/util.coffee +332 -145
  27. data/lib/unpoly/rails/version.rb +1 -1
  28. data/package.json +1 -1
  29. data/spec_app/Gemfile.lock +1 -1
  30. data/spec_app/app/assets/javascripts/integration_test.coffee +1 -0
  31. data/spec_app/app/assets/stylesheets/integration_test.sass +1 -0
  32. data/spec_app/app/assets/stylesheets/jasmine_specs.sass +4 -0
  33. data/spec_app/app/views/motion_test/transitions.erb +13 -0
  34. data/spec_app/app/views/pages/start.erb +1 -0
  35. data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +5 -0
  36. data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +5 -0
  37. data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +1 -1
  38. data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +11 -0
  39. data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +5 -0
  40. data/spec_app/spec/javascripts/up/dom_spec.js.coffee +217 -102
  41. data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +162 -44
  42. data/spec_app/spec/javascripts/up/layout_spec.js.coffee +97 -10
  43. data/spec_app/spec/javascripts/up/link_spec.js.coffee +3 -3
  44. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +22 -20
  45. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +344 -228
  46. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +1 -1
  47. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +1 -1
  48. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +1 -1
  49. data/spec_app/spec/javascripts/up/util_spec.js.coffee +194 -0
  50. metadata +11 -4
@@ -16,7 +16,7 @@ describe 'up.popup', ->
16
16
  Math.abs(popupDims.right - linkDims.right) < 1.0 && Math.abs(popupDims.top - linkDims.bottom) < 1.0
17
17
 
18
18
  beforeEach ->
19
- @restoreBodyHeight = u.temporaryCss('body', 'min-height': '3000px')
19
+ @restoreBodyHeight = u.writeTemporaryStyle('body', minHeight: '3000px')
20
20
 
21
21
  afterEach ->
22
22
  @restoreBodyHeight()
@@ -13,7 +13,7 @@ describe 'up.syntax', ->
13
13
  up.hello(affix('.container .child'))
14
14
 
15
15
  expect(observeClass).not.toHaveBeenCalledWith('container')
16
- expect(observeClass).toHaveBeenCalledWith('child')
16
+ expect(observeClass).toHaveBeenCalledWith('child')
17
17
 
18
18
  describe 'destructors', ->
19
19
 
@@ -40,7 +40,7 @@ describe 'up.tooltip', ->
40
40
  )
41
41
 
42
42
  beforeEach ->
43
- @restoreBodyHeight = u.temporaryCss('body', 'min-height': '3000px')
43
+ @restoreBodyHeight = u.writeTemporaryStyle('body', minHeight: '3000px')
44
44
 
45
45
  afterEach ->
46
46
  @restoreBodyHeight()
@@ -135,6 +135,82 @@ describe 'up.util', ->
135
135
  expect(callback).toHaveBeenCalledWith('return value')
136
136
  done()
137
137
 
138
+ describe 'up.util.kebabCase', ->
139
+
140
+ it 'converts a string of multiple words from camel-case to kebap-case', ->
141
+ result = up.util.kebabCase('fooBarBaz')
142
+ expect(result).toEqual('foo-bar-baz')
143
+
144
+ it 'does not change a single word', ->
145
+ result = up.util.kebabCase('foo')
146
+ expect(result).toEqual('foo')
147
+
148
+ it 'downcases the first word when it starts with a capital letter', ->
149
+ result = up.util.kebabCase('FooBar')
150
+ expect(result).toEqual('foo-bar')
151
+
152
+ it 'does not change a string that is already in kebab-case', ->
153
+ result = up.util.kebabCase('foo-bar-baz')
154
+ expect(result).toEqual('foo-bar-baz')
155
+
156
+ describe 'up.util.camelCase', ->
157
+
158
+ it 'converts a string of multiple words from kebap-case to camel-case', ->
159
+ result = up.util.camelCase('foo-bar-baz')
160
+ expect(result).toEqual('fooBarBaz')
161
+
162
+ it 'does not change a single word', ->
163
+ result = up.util.camelCase('foo')
164
+ expect(result).toEqual('foo')
165
+
166
+ it 'downcases the first word when it starts with a capital letter', ->
167
+ result = up.util.camelCase('Foo-Bar')
168
+ expect(result).toEqual('fooBar')
169
+
170
+ it 'does not change a string that is already in camel-case', ->
171
+ result = up.util.camelCase('fooBarBaz')
172
+ expect(result).toEqual('fooBarBaz')
173
+
174
+ describe 'up.util.kebabCaseKeys', ->
175
+
176
+ it "converts the given object's keys from camel-case to kebab-case", ->
177
+ input =
178
+ fooBar: 'one'
179
+ barBaz: 'two'
180
+ result = up.util.kebabCaseKeys(input)
181
+ expect(result).toEqual
182
+ 'foo-bar': 'one'
183
+ 'bar-baz': 'two'
184
+
185
+ it "does not change an object whose keys are already kebab-case", ->
186
+ input =
187
+ 'foo-bar': 'one'
188
+ 'bar-baz': 'two'
189
+ result = up.util.kebabCaseKeys(input)
190
+ expect(result).toEqual
191
+ 'foo-bar': 'one'
192
+ 'bar-baz': 'two'
193
+
194
+ describe 'up.util.camelCaseKeys', ->
195
+
196
+ it "converts the given object's keys from kebab-case to camel-case", ->
197
+ input =
198
+ 'foo-bar': 'one'
199
+ 'bar-baz': 'two'
200
+ result = up.util.camelCaseKeys(input)
201
+ expect(result).toEqual
202
+ fooBar: 'one'
203
+ barBaz: 'two'
204
+
205
+ it "does not change an object whose keys are already camel-case", ->
206
+ input =
207
+ fooBar: 'one'
208
+ barBaz: 'two'
209
+ result = up.util.camelCaseKeys(input)
210
+ expect(result).toEqual
211
+ fooBar: 'one'
212
+ barBaz: 'two'
213
+
138
214
  describe 'up.util.DivertibleChain', ->
139
215
 
140
216
  it "instantiates a task queue whose (2..n)th tasks can be changed by calling '.asap'", (done) ->
@@ -351,6 +427,98 @@ describe 'up.util', ->
351
427
  baz: 'baz-value'
352
428
  bam: 'bam-value'
353
429
 
430
+ it 'does not add empty keys to the returned object if the given object does not have that key', ->
431
+ original =
432
+ foo: 'foo-value'
433
+ whitelisted = up.util.only(original, 'foo', 'bar')
434
+ expect(whitelisted).toHaveOwnProperty('foo')
435
+ expect(whitelisted).not.toHaveOwnProperty('bar')
436
+
437
+ describe 'up.util.readInlineStyle', ->
438
+
439
+ describe 'with a string as second argument', ->
440
+
441
+ it 'returns a CSS value string from an inline [style] attribute', ->
442
+ $div = affix('div').attr('style', 'background-color: #ff0000')
443
+ style = up.util.readInlineStyle($div, 'backgroundColor')
444
+ # Browsers convert colors to rgb() values, even IE11
445
+ expect(style).toEqual('rgb(255, 0, 0)')
446
+
447
+ it 'returns a blank value if the element does not have the given property in the [style] attribute', ->
448
+ $div = affix('div').attr('style', 'background-color: red')
449
+ style = up.util.readInlineStyle($div, 'color')
450
+ expect(style).toBeBlank()
451
+
452
+ it 'returns a blank value the given property is a computed property, but not in the [style] attribute', ->
453
+ $div = affix('div[class="red-background"]')
454
+ inlineStyle = up.util.readInlineStyle($div, 'backgroundColor')
455
+ computedStyle = up.util.readComputedStyle($div, 'backgroundColor')
456
+ expect(computedStyle).toEqual('rgb(255, 0, 0)')
457
+ expect(inlineStyle).toBeBlank()
458
+
459
+ describe 'with an array as second argument', ->
460
+
461
+ it 'returns an object with the given inline [style] properties', ->
462
+ $div = affix('div').attr('style', 'background-color: #ff0000; color: #0000ff')
463
+ style = up.util.readInlineStyle($div, ['backgroundColor', 'color'])
464
+ expect(style).toEqual
465
+ backgroundColor: 'rgb(255, 0, 0)'
466
+ color: 'rgb(0, 0, 255)'
467
+
468
+ it 'returns blank keys if the element does not have the given property in the [style] attribute', ->
469
+ $div = affix('div').attr('style', 'background-color: #ff0000')
470
+ style = up.util.readInlineStyle($div, ['backgroundColor', 'color'])
471
+ expect(style).toHaveOwnProperty('color')
472
+ expect(style.color).toBeBlank()
473
+
474
+ it 'returns a blank value the given property is a computed property, but not in the [style] attribute', ->
475
+ $div = affix('div[class="red-background"]')
476
+ inlineStyleHash = up.util.readInlineStyle($div, ['backgroundColor'])
477
+ computedBackground = up.util.readComputedStyle($div, 'backgroundColor')
478
+ expect(computedBackground).toEqual('rgb(255, 0, 0)')
479
+ expect(inlineStyleHash).toHaveOwnProperty('backgroundColor')
480
+ expect(inlineStyleHash.backgroundColor).toBeBlank()
481
+
482
+ describe 'up.util.writeInlineStyle', ->
483
+
484
+ it "sets the given style properties as the given element's [style] attribute", ->
485
+ $div = affix('div')
486
+ up.util.writeInlineStyle($div, { color: 'red', backgroundColor: 'blue' })
487
+ style = $div.attr('style')
488
+ expect(style).toContain('color: red')
489
+ expect(style).toContain('background-color: blue')
490
+
491
+ it "merges the given style properties into the given element's existing [style] value", ->
492
+ $div = affix('div[style="color: red"]')
493
+ up.util.writeInlineStyle($div, { backgroundColor: 'blue' })
494
+ style = $div.attr('style')
495
+ expect(style).toContain('color: red')
496
+ expect(style).toContain('background-color: blue')
497
+
498
+ it "converts the values of known length properties to px values automatically", ->
499
+ $div = affix('div')
500
+ up.util.writeInlineStyle($div, { paddingTop: 100 })
501
+ style = $div.attr('style')
502
+ expect(style).toContain('padding-top: 100px')
503
+
504
+ describe 'up.util.writeTemporaryStyle', ->
505
+
506
+ it "sets the given inline styles and returns a function that will restore the previous inline styles", ->
507
+ $div = affix('div[style="color: red"]')
508
+ restore = up.util.writeTemporaryStyle($div, { color: 'blue' })
509
+ expect($div.attr('style')).toContain('color: blue')
510
+ expect($div.attr('style')).not.toContain('color: red')
511
+ restore()
512
+ expect($div.attr('style')).not.toContain('color: blue')
513
+ expect($div.attr('style')).toContain('color: red')
514
+
515
+ it "does not restore inherited styles", ->
516
+ $div = affix('div[class="red-background"]')
517
+ restore = up.util.writeTemporaryStyle($div, { backgroundColor: 'blue' })
518
+ expect($div.attr('style')).toContain('background-color: blue')
519
+ restore()
520
+ expect($div.attr('style')).not.toContain('background-color')
521
+
354
522
  describe 'up.util.except', ->
355
523
 
356
524
  it 'returns a copy of the given object but omits the given blacklisted properties', ->
@@ -418,6 +586,29 @@ describe 'up.util', ->
418
586
  expect(up.util.selectorForElement($element)).toBe('[aria-label="foo\\"bar"]')
419
587
 
420
588
 
589
+ describe 'up.util.addTemporaryClass', ->
590
+
591
+ it 'adds the given class to the given element', ->
592
+ $element = affix('.foo.bar')
593
+ element = $element.get(0)
594
+
595
+ expect(element.className).toEqual('foo bar')
596
+
597
+ up.util.addTemporaryClass(element, 'baz')
598
+
599
+ expect(element.className).toEqual('foo bar baz')
600
+
601
+ it 'returns a function that restores the original class', ->
602
+ $element = affix('.foo.bar')
603
+ element = $element.get(0)
604
+
605
+ restoreClass = up.util.addTemporaryClass(element, 'baz')
606
+ expect(element.className).toEqual('foo bar baz')
607
+
608
+ restoreClass()
609
+ expect(element.className).toEqual('foo bar')
610
+
611
+
421
612
  describe 'up.util.castedAttr', ->
422
613
 
423
614
  it 'returns true if the attribute value is the string "true"', ->
@@ -578,6 +769,9 @@ describe 'up.util', ->
578
769
  it 'returns true for an empty object', ->
579
770
  expect(up.util.isBlank({})).toBe(true)
580
771
 
772
+ it 'returns false for a function', ->
773
+ expect(up.util.isBlank((->))).toBe(false)
774
+
581
775
  it 'returns true for an object with at least one key', ->
582
776
  expect(up.util.isBlank({key: 'value'})).toBe(false)
583
777
 
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.55.1
4
+ version: 0.56.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-04-13 00:00:00.000000000 Z
11
+ date: 2018-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -89,14 +89,15 @@ files:
89
89
  - dist/unpoly.min.css
90
90
  - dist/unpoly.min.js
91
91
  - lib/assets/javascripts/unpoly-bootstrap3.coffee
92
+ - lib/assets/javascripts/unpoly-bootstrap3/feedback-ext.coffee
92
93
  - lib/assets/javascripts/unpoly-bootstrap3/form-ext.coffee
93
94
  - lib/assets/javascripts/unpoly-bootstrap3/layout-ext.coffee
94
95
  - lib/assets/javascripts/unpoly-bootstrap3/modal-ext.coffee
95
- - lib/assets/javascripts/unpoly-bootstrap3/navigation-ext.coffee
96
96
  - lib/assets/javascripts/unpoly.coffee
97
97
  - lib/assets/javascripts/unpoly/browser.coffee.erb
98
98
  - lib/assets/javascripts/unpoly/bus.coffee.erb
99
99
  - lib/assets/javascripts/unpoly/classes/cache.coffee
100
+ - lib/assets/javascripts/unpoly/classes/css_transition.coffee
100
101
  - lib/assets/javascripts/unpoly/classes/extract_cascade.coffee
101
102
  - lib/assets/javascripts/unpoly/classes/extract_plan.coffee
102
103
  - lib/assets/javascripts/unpoly/classes/extract_step.coffee
@@ -106,6 +107,7 @@ files:
106
107
  - lib/assets/javascripts/unpoly/classes/record.coffee
107
108
  - lib/assets/javascripts/unpoly/classes/request.coffee
108
109
  - lib/assets/javascripts/unpoly/classes/response.coffee
110
+ - lib/assets/javascripts/unpoly/classes/url_set.coffee
109
111
  - lib/assets/javascripts/unpoly/dom.coffee.erb
110
112
  - lib/assets/javascripts/unpoly/feedback.coffee
111
113
  - lib/assets/javascripts/unpoly/form.coffee.erb
@@ -114,7 +116,7 @@ files:
114
116
  - lib/assets/javascripts/unpoly/link.coffee.erb
115
117
  - lib/assets/javascripts/unpoly/log.coffee
116
118
  - lib/assets/javascripts/unpoly/modal.coffee.erb
117
- - lib/assets/javascripts/unpoly/motion.coffee
119
+ - lib/assets/javascripts/unpoly/motion.coffee.erb
118
120
  - lib/assets/javascripts/unpoly/namespace.coffee.erb
119
121
  - lib/assets/javascripts/unpoly/popup.coffee.erb
120
122
  - lib/assets/javascripts/unpoly/protocol.coffee
@@ -196,6 +198,7 @@ files:
196
198
  - spec_app/app/views/method_test/page1.erb
197
199
  - spec_app/app/views/method_test/page2.erb
198
200
  - spec_app/app/views/motion_test/animations.erb
201
+ - spec_app/app/views/motion_test/transitions.erb
199
202
  - spec_app/app/views/pages/start.erb
200
203
  - spec_app/app/views/replace_test/_nav.erb
201
204
  - spec_app/app/views/replace_test/page1.erb
@@ -260,7 +263,9 @@ files:
260
263
  - spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee
261
264
  - spec_app/spec/javascripts/helpers/show_lib_versions.coffee
262
265
  - spec_app/spec/javascripts/helpers/to_be_around.js.coffee
266
+ - spec_app/spec/javascripts/helpers/to_be_attached.coffee
263
267
  - spec_app/spec/javascripts/helpers/to_be_blank.js.coffee
268
+ - spec_app/spec/javascripts/helpers/to_be_detached.coffee
264
269
  - spec_app/spec/javascripts/helpers/to_be_error.coffee
265
270
  - spec_app/spec/javascripts/helpers/to_be_given.js.coffee
266
271
  - spec_app/spec/javascripts/helpers/to_be_jquery.js.coffee
@@ -270,6 +275,8 @@ files:
270
275
  - spec_app/spec/javascripts/helpers/to_contain.js.coffee
271
276
  - spec_app/spec/javascripts/helpers/to_end_with.js.coffee
272
277
  - spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee
278
+ - spec_app/spec/javascripts/helpers/to_have_opacity.coffee
279
+ - spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee
273
280
  - spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee
274
281
  - spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee
275
282
  - spec_app/spec/javascripts/helpers/to_match_text.js.coffee