upjs-rails 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -304,13 +304,15 @@ up.syntax = (($) ->
304
304
 
305
305
  @function up.hello
306
306
  @param {String|Element|jQuery} selectorOrElement
307
+ @param {String|Element|jQuery} [options.origin]
307
308
  @return {jQuery}
308
309
  The compiled element
309
310
  @stable
310
311
  ###
311
- hello = (selectorOrElement) ->
312
+ hello = (selectorOrElement, options) ->
312
313
  $element = $(selectorOrElement)
313
- up.emit('up:fragment:inserted', $element: $element)
314
+ eventAttrs = u.options(options, $element: $element)
315
+ up.emit('up:fragment:inserted', eventAttrs)
314
316
  $element
315
317
 
316
318
  ###*
@@ -149,7 +149,7 @@ up.tooltip = (($) ->
149
149
  ###*
150
150
  Displays a tooltip with HTML content when hovering the mouse over this element:
151
151
 
152
- <a href="/decks" up-tooltip="Show &lt;b&gt;all&lt;/b&gt; decks">Decks</a>
152
+ <a href="/decks" up-tooltip-html="Show &lt;b&gt;all&lt;/b&gt; decks">Decks</a>
153
153
 
154
154
  @selector [up-tooltip-html]
155
155
  @stable
@@ -913,37 +913,33 @@ up.util = (($) ->
913
913
  ###
914
914
  cssAnimate = (elementOrSelector, lastFrame, opts) ->
915
915
  $element = $(elementOrSelector)
916
- if up.browser.canCssTransition()
917
- opts = options(opts,
918
- duration: 300,
919
- delay: 0,
920
- easing: 'ease'
921
- )
922
- # We don't finish an existing animation here, since
923
- # the public API `up.motion.animate` already does this.
924
- deferred = $.Deferred()
925
- transition =
926
- 'transition-property': Object.keys(lastFrame).join(', ')
927
- 'transition-duration': "#{opts.duration}ms"
928
- 'transition-delay': "#{opts.delay}ms"
929
- 'transition-timing-function': opts.easing
930
- withoutCompositing = forceCompositing($element)
931
- withoutTransition = temporaryCss($element, transition)
932
- $element.css(lastFrame)
933
- deferred.then(withoutCompositing)
934
- deferred.then(withoutTransition)
935
- $element.data(ANIMATION_PROMISE_KEY, deferred)
936
- deferred.then(-> $element.removeData(ANIMATION_PROMISE_KEY))
937
- endTimeout = setTimeout((-> deferred.resolve()), opts.duration + opts.delay)
938
- deferred.then(-> clearTimeout(endTimeout)) # clean up in case we're canceled
939
- # Return the whole deferred and not just return a thenable.
940
- # Other code will need the possibility to cancel the animation
941
- # by resolving the deferred.
942
- deferred
943
- else
944
- $element.css(lastFrame)
945
- resolvedDeferred()
946
-
916
+ opts = options(opts,
917
+ duration: 300,
918
+ delay: 0,
919
+ easing: 'ease'
920
+ )
921
+ # We don't finish an existing animation here, since
922
+ # the public API `up.motion.animate` already does this.
923
+ deferred = $.Deferred()
924
+ transition =
925
+ 'transition-property': Object.keys(lastFrame).join(', ')
926
+ 'transition-duration': "#{opts.duration}ms"
927
+ 'transition-delay': "#{opts.delay}ms"
928
+ 'transition-timing-function': opts.easing
929
+ withoutCompositing = forceCompositing($element)
930
+ withoutTransition = temporaryCss($element, transition)
931
+ $element.css(lastFrame)
932
+ deferred.then(withoutCompositing)
933
+ deferred.then(withoutTransition)
934
+ $element.data(ANIMATION_PROMISE_KEY, deferred)
935
+ deferred.then(-> $element.removeData(ANIMATION_PROMISE_KEY))
936
+ endTimeout = setTimeout((-> deferred.resolve()), opts.duration + opts.delay)
937
+ deferred.then(-> clearTimeout(endTimeout)) # clean up in case we're canceled
938
+ # Return the whole deferred and not just return a thenable.
939
+ # Other code will need the possibility to cancel the animation
940
+ # by resolving the deferred.
941
+ deferred
942
+
947
943
  ANIMATION_PROMISE_KEY = 'up-animation-promise'
948
944
 
949
945
  ###*
@@ -4,6 +4,6 @@ module Upjs
4
4
  # The current version of the upjs-rails gem.
5
5
  # This version number is also used for releases of the Up.js
6
6
  # frontend code.
7
- VERSION = '0.15.1'
7
+ VERSION = '0.16.0'
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- upjs-rails (0.14.1)
4
+ upjs-rails (0.15.1)
5
5
  rails (>= 3)
6
6
 
7
7
  GEM
@@ -210,3 +210,6 @@ DEPENDENCIES
210
210
  uglifier (>= 1.3.0)
211
211
  upjs-rails!
212
212
  web-console (~> 2.0)
213
+
214
+ BUNDLED WITH
215
+ 1.10.6
@@ -1,4 +1,6 @@
1
1
  describe 'up.modal', ->
2
+
3
+ u = up.util
2
4
 
3
5
  describe 'Javascript functions', ->
4
6
 
@@ -64,6 +66,12 @@ describe 'up.modal', ->
64
66
  expect(parseInt($anchoredElement.css('right'))).toBeAround(30 , 10)
65
67
  done()
66
68
 
69
+ it 'does not explode if the modal was closed before the response was received', ->
70
+ up.modal.visit('/foo', target: '.container')
71
+ up.modal.close()
72
+ respond = => @respondWith('<div class="container">text</div>')
73
+ expect(respond).not.toThrowError()
74
+ expect($('.up-error')).not.toExist()
67
75
 
68
76
  describe 'up.modal.coveredUrl', ->
69
77
 
@@ -134,16 +142,64 @@ describe 'up.modal', ->
134
142
  expect(wasClosed).toBe(false)
135
143
  expect(wasDefaultPrevented).toBe(false)
136
144
 
137
- describe 'when following links inside a modal', ->
145
+ describe 'when replacing content', ->
146
+
147
+ beforeEach ->
148
+ up.motion.config.enabled = false
138
149
 
139
150
  it 'prefers to replace a selector within the modal', ->
140
151
  $outside = affix('.foo').text('old outside')
141
152
  up.modal.visit('/path', target: '.foo')
142
153
  @respondWith("<div class='foo'>old inside</div>")
143
154
  up.flow.implant('.foo', "<div class='foo'>new text</div>")
155
+ expect($outside).toBeInDOM()
144
156
  expect($outside).toHaveText('old outside')
145
157
  expect($('.up-modal-content')).toHaveText('new text')
146
158
 
159
+ it 'auto-closes the modal when a replacement from inside the modal affects a selector behind the modal', ->
160
+ affix('.outside').text('old outside')
161
+ up.modal.visit('/path', target: '.inside')
162
+ @respondWith("<div class='inside'>old inside</div>")
163
+ up.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
164
+ expect($('.outside')).toHaveText('new outside')
165
+ expect($('.up-modal')).not.toExist()
166
+
167
+ it 'does not auto-close the modal when a replacement from inside the modal affects a selector inside the modal', ->
168
+ affix('.outside').text('old outside')
169
+ up.modal.visit('/path', target: '.inside')
170
+ @respondWith("<div class='inside'>old inside</div>")
171
+ up.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.inside'))
172
+ expect($('.inside')).toHaveText('new inside')
173
+ expect($('.up-modal')).toExist()
174
+
175
+ it 'does not auto-close the modal when a replacement from outside the modal affects a selector outside the modal', ->
176
+ affix('.outside').text('old outside')
177
+ up.modal.visit('/path', target: '.inside')
178
+ @respondWith("<div class='inside'>old inside</div>")
179
+ up.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
180
+ expect($('.outside')).toHaveText('new outside')
181
+ expect($('.up-modal')).toExist()
182
+
183
+ it 'does not auto-close the modal when a replacement from outside the modal affects a selector inside the modal', ->
184
+ affix('.outside').text('old outside')
185
+ up.modal.visit('/path', target: '.inside')
186
+ @respondWith("<div class='inside'>old inside</div>")
187
+ up.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
188
+ expect($('.inside')).toHaveText('new inside')
189
+ expect($('.up-modal')).toExist()
190
+
191
+ it 'does not auto-close the modal when the new fragment is within a popup', ->
192
+ up.modal.visit('/modal', target: '.modal-content')
193
+ @respondWith("<div class='modal-content'></div>")
194
+ up.popup.attach('.modal-content', url: '/popup', target: '.popup-content')
195
+ @respondWith("<div class='popup-content'></div>")
196
+ expect($('.up-modal')).toExist()
197
+ expect($('.up-popup')).toExist()
198
+
199
+ describe 'when following links inside a modal', ->
200
+
201
+ it 'prefers to replace a selector within the modal', ->
202
+
147
203
  it 'auto-closes the modal if a selector behind the modal gets replaced'
148
204
 
149
205
  it "doesn't auto-close the modal if a selector behind the modal if the modal is sticky"
@@ -25,6 +25,16 @@ describe 'up.motion', ->
25
25
  up.animate($element, { 'fade-in' }, duration: 100, easing: 'linear')
26
26
  expect($element.css('font-size')).toEqual('40px')
27
27
 
28
+ describe 'with animations disabled globally', ->
29
+
30
+ beforeEach ->
31
+ up.motion.config.enabled = false
32
+
33
+ it "doesn't animate and directly sets the last frame instead", ->
34
+ $element = affix('.element').text('content')
35
+ up.animate($element, { 'font-size': '40px' }, duration: 10000, easing: 'linear')
36
+ expect($element.css('font-size')).toEqual('40px')
37
+
28
38
  else
29
39
 
30
40
  it "doesn't animate and directly sets the last frame instead", ->
@@ -185,6 +195,20 @@ describe 'up.motion', ->
185
195
  # was at the scroll position before we revealed $new.
186
196
  expect($oldGhost.offset().top).toEqual(-300)
187
197
 
198
+
199
+ describe 'with animations disabled globally', ->
200
+
201
+ beforeEach ->
202
+ up.motion.config.enabled = false
203
+
204
+ it "doesn't animate and hides the old element instead", ->
205
+ $old = affix('.old').text('old content')
206
+ $new = affix('.new').text('new content')
207
+ up.morph($old, $new, 'cross-fade', duration: 1000)
208
+ expect($old).toBeHidden()
209
+ expect($new).toBeVisible()
210
+ expect($new.css('opacity')).toEqual('1')
211
+
188
212
  else
189
213
 
190
214
  it "doesn't animate and hides the old element instead", ->
@@ -193,6 +217,7 @@ describe 'up.motion', ->
193
217
  up.morph($old, $new, 'cross-fade', duration: 1000)
194
218
  expect($old).toBeHidden()
195
219
  expect($new).toBeVisible()
220
+ expect($new.css('opacity')).toEqual('1')
196
221
 
197
222
  describe 'up.transition', ->
198
223
 
@@ -1,10 +1,18 @@
1
1
  describe 'up.popup', ->
2
2
 
3
+ u = up.util
4
+
3
5
  describe 'Javascript functions', ->
4
6
 
5
7
  describe 'up.popup.attach', ->
6
8
 
7
- it 'should have tests'
9
+ it 'does not explode if the popup was closed before the response was received', ->
10
+ $span = affix('span')
11
+ up.popup.attach($span, url: '/foo', target: '.container')
12
+ up.popup.close()
13
+ respond = => @respondWith('<div class="container">text</div>')
14
+ expect(respond).not.toThrowError()
15
+ expect($('.up-error')).not.toExist()
8
16
 
9
17
  describe 'up.popup.coveredUrl', ->
10
18
 
@@ -34,6 +42,10 @@ describe 'up.popup', ->
34
42
 
35
43
  it "loads this link's destination in a popup when clicked", ->
36
44
  $link = affix('a[href="/path/to"][up-popup=".middle"]').text('link')
45
+ $link.css
46
+ position: 'fixed'
47
+ left: '100px'
48
+ top: '50px'
37
49
  $link.click()
38
50
  expect(@lastRequest().url).toMatch /\/path\/to$/
39
51
  @respondWith """
@@ -41,10 +53,19 @@ describe 'up.popup', ->
41
53
  <div class="middle">new-middle</div>
42
54
  <div class="after">new-after</div>
43
55
  """
44
- expect($('.up-popup')).toExist()
45
- expect($('.up-popup .middle')).toHaveText('new-middle')
46
- expect($('.up-popup .before')).not.toExist()
47
- expect($('.up-popup .after')).not.toExist()
56
+
57
+ $popup = $('.up-popup')
58
+
59
+ expect($popup).toExist()
60
+ expect($popup.find('.middle')).toHaveText('new-middle')
61
+ expect($popup.find('.before')).not.toExist()
62
+ expect($popup.find('.after')).not.toExist()
63
+
64
+ popupDims = u.measure($popup, full: true)
65
+ linkDims = u.measure($link, full: true)
66
+
67
+ expect(popupDims.right).toBeAround(linkDims.right, 1)
68
+ expect(popupDims.top).toBeAround(linkDims.top + linkDims.height, 1)
48
69
 
49
70
  describe '[up-close]', ->
50
71
 
@@ -80,4 +101,54 @@ describe 'up.popup', ->
80
101
  $link.click()
81
102
  expect(wasClosed).toBe(false)
82
103
  expect(wasDefaultPrevented).toBe(false)
83
-
104
+
105
+ describe 'when replacing content', ->
106
+
107
+ beforeEach ->
108
+ up.motion.config.enabled = false
109
+
110
+ it 'prefers to replace a selector within the popup', ->
111
+ $outside = affix('.foo').text('old outside')
112
+ $link = affix('.link')
113
+ up.popup.attach($link, href: '/path', target: '.foo')
114
+ @respondWith("<div class='foo'>old inside</div>")
115
+ up.flow.implant('.foo', "<div class='foo'>new text</div>")
116
+ expect($outside).toBeInDOM()
117
+ expect($outside).toHaveText('old outside')
118
+ expect($('.up-popup')).toHaveText('new text')
119
+
120
+ it 'auto-closes the popup when a replacement from inside the popup affects a selector behind the popup', ->
121
+ affix('.outside').text('old outside')
122
+ $link = affix('.link')
123
+ up.popup.attach($link, href: '/path', target: '.inside')
124
+ @respondWith("<div class='inside'>old inside</div>")
125
+ up.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
126
+ expect($('.outside')).toHaveText('new outside')
127
+ expect($('.up-popup')).not.toExist()
128
+
129
+ it 'does not auto-close the popup when a replacement from inside the popup affects a selector inside the popup', ->
130
+ affix('.outside').text('old outside')
131
+ $link = affix('.link')
132
+ up.popup.attach($link, href: '/path', target: '.inside')
133
+ @respondWith("<div class='inside'>old inside</div>")
134
+ up.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.inside'))
135
+ expect($('.inside')).toHaveText('new inside')
136
+ expect($('.up-popup')).toExist()
137
+
138
+ it 'does not auto-close the popup when a replacement from outside the popup affects a selector outside the popup', ->
139
+ affix('.outside').text('old outside')
140
+ $link = affix('.link')
141
+ up.popup.attach($link, href: '/path', target: '.inside')
142
+ @respondWith("<div class='inside'>old inside</div>")
143
+ up.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
144
+ expect($('.outside')).toHaveText('new outside')
145
+ expect($('.up-popup')).toExist()
146
+
147
+ it 'does not auto-close the popup when a replacement from outside the popup affects a selector inside the popup', ->
148
+ affix('.outside').text('old outside')
149
+ $link = affix('.link')
150
+ up.popup.attach($link, href: '/path', target: '.inside')
151
+ @respondWith("<div class='inside'>old inside</div>")
152
+ up.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
153
+ expect($('.inside')).toHaveText('new inside')
154
+ expect($('.up-popup')).toExist()
@@ -88,7 +88,7 @@ describe 'up.proxy', ->
88
88
  u.times 2, -> up.proxy.ajax(url: '/foo', method: method, cache: true)
89
89
  expect(jasmine.Ajax.requests.count()).toEqual(1)
90
90
 
91
- it 'does not responses with a non-200 status code', ->
91
+ it 'does not cache responses with a non-200 status code', ->
92
92
  # Send the same request for the same path, 3 minutes apart
93
93
  up.proxy.ajax(url: '/foo')
94
94
 
@@ -101,6 +101,26 @@ describe 'up.proxy', ->
101
101
 
102
102
  expect(jasmine.Ajax.requests.count()).toEqual(2)
103
103
 
104
+ describe 'with config.maxRequests set', ->
105
+
106
+ beforeEach ->
107
+ up.proxy.config.maxRequests = 1
108
+
109
+ it 'limits the number of concurrent requests', ->
110
+ responses = []
111
+ up.proxy.ajax(url: '/foo').then (html) -> responses.push(html)
112
+ up.proxy.ajax(url: '/bar').then (html) -> responses.push(html)
113
+ expect(jasmine.Ajax.requests.count()).toEqual(1) # only one request was made
114
+ @respondWith('first response', request: jasmine.Ajax.requests.at(0))
115
+ expect(responses).toEqual ['first response']
116
+ expect(jasmine.Ajax.requests.count()).toEqual(2) # a second request was made
117
+ @respondWith('second response', request: jasmine.Ajax.requests.at(1))
118
+ expect(responses).toEqual ['first response', 'second response']
119
+
120
+ # it 'considers preloading links for the request limit', ->
121
+ # up.proxy.ajax(url: '/foo', preload: true)
122
+ # up.proxy.ajax(url: '/bar')
123
+ # expect(jasmine.Ajax.requests.count()).toEqual(1)
104
124
 
105
125
  describe 'events', ->
106
126
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.16.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: 2016-01-07 00:00:00.000000000 Z
11
+ date: 2016-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails