upjs-rails 0.14.1 → 0.15.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.
@@ -1,10 +1,68 @@
1
1
  describe 'up.form', ->
2
-
2
+
3
+ u = up.util
4
+
3
5
  describe 'Javascript functions', ->
4
6
 
5
7
  describe 'up.observe', ->
6
8
 
7
- it 'should have tests'
9
+ changeEvents = if up.browser.canInputEvent()
10
+ # Actually we only need `input`, but we want to notice
11
+ # if another script manually triggers `change` on the element.
12
+ ['input', 'change']
13
+ else
14
+ # Actually we won't ever get `input` from the user in this browser,
15
+ # but we want to notice if another script manually triggers `input`
16
+ # on the element.
17
+ ['input', 'change', 'keypress', 'paste', 'cut', 'click', 'propertychange']
18
+
19
+ u.each changeEvents, (eventName) ->
20
+
21
+ describe 'when the first argument is a form field', ->
22
+
23
+ it "runs the callback when the input receives a '#{eventName}' event and the value changed", (done) ->
24
+ $input = affix('input[value="old-value"]')
25
+ callback = jasmine.createSpy('change callback')
26
+ up.observe($input, callback)
27
+ $input.val('new-value')
28
+ u.times 2, -> $input.trigger(eventName)
29
+ u.nextFrame ->
30
+ expect(callback).toHaveBeenCalledWith('new-value', $input)
31
+ expect(callback.calls.count()).toEqual(1)
32
+ done()
33
+
34
+ it "does not run the callback when the input receives a '#{eventName}' event, but the value didn't change", (done) ->
35
+ $input = affix('input[value="old-value"]')
36
+ callback = jasmine.createSpy('change callback')
37
+ up.observe($input, callback)
38
+ $input.trigger(eventName)
39
+ u.nextFrame ->
40
+ expect(callback).not.toHaveBeenCalled()
41
+ done()
42
+
43
+ describe 'when the first argument is a form', ->
44
+
45
+ it "runs the callback when any of the form's inputs receives a '#{eventName}' event and the value changed", (done) ->
46
+ $form = affix('form')
47
+ $input = $form.affix('input[value="old-value"]')
48
+ callback = jasmine.createSpy('change callback')
49
+ up.observe($form, callback)
50
+ $input.val('new-value')
51
+ u.times 2, -> $input.trigger(eventName)
52
+ u.nextFrame ->
53
+ expect(callback).toHaveBeenCalledWith('new-value', $input)
54
+ expect(callback.calls.count()).toEqual(1)
55
+ done()
56
+
57
+ it "does not run the callback when any of the form's inputs receives a '#{eventName}' event, but the value didn't change", (done) ->
58
+ $form = affix('form')
59
+ $input = $form.affix('input[value="old-value"]')
60
+ callback = jasmine.createSpy('change callback')
61
+ up.observe($form, callback)
62
+ $input.trigger(eventName)
63
+ u.nextFrame ->
64
+ expect(callback).not.toHaveBeenCalled()
65
+ done()
8
66
 
9
67
  describe 'up.submit', ->
10
68
 
@@ -99,7 +157,33 @@ describe 'up.form', ->
99
157
 
100
158
  it 'rigs the form to use up.submit instead of a standard submit'
101
159
 
102
- describe 'input[up-observe]', ->
160
+ describe 'input[up-autosubmit]', ->
161
+
162
+ it 'submits the form when a change is observed in the given form field', (done) ->
163
+ $form = affix('form')
164
+ $field = $form.affix('input[up-autosubmit][val="old-value"]')
165
+ up.hello($field)
166
+ submitSpy = up.form.knife.mock('submit').and.returnValue(u.unresolvablePromise())
167
+ $field.val('new-value')
168
+ $field.trigger('change')
169
+ u.nextFrame ->
170
+ expect(submitSpy).toHaveBeenCalled()
171
+ done()
172
+
173
+ describe 'form[up-autosubmit]', ->
174
+
175
+ it 'submits the form when a change is observed in any of its fields', (done) ->
176
+ $form = affix('form[up-autosubmit]')
177
+ $field = $form.affix('input[val="old-value"]')
178
+ up.hello($form)
179
+ submitSpy = up.form.knife.mock('submit').and.returnValue(u.unresolvablePromise())
180
+ $field.val('new-value')
181
+ $field.trigger('change')
182
+ u.nextFrame ->
183
+ expect(submitSpy).toHaveBeenCalled()
184
+ done()
185
+
186
+ describe '[up-observe]', ->
103
187
 
104
188
  it 'should have tests'
105
189
 
@@ -100,13 +100,39 @@ describe 'up.modal', ->
100
100
  expect(followSpy).toHaveBeenCalledWith($link)
101
101
 
102
102
  describe '[up-close]', ->
103
+
104
+ describe 'when clicked inside a modal', ->
103
105
 
104
- it 'closes the modal when clicked', ->
105
- closeSpy = up.modal.knife.mock('close')
106
- $link = affix('a[up-close]')
107
- up.hello($link)
108
- $link.click()
109
- expect(closeSpy).toHaveBeenCalled()
106
+ it 'closes the open modal and prevents the default action', ->
107
+ $modal = affix('.up-modal')
108
+ $link = $modal.affix('a[up-close]') # link is within the modal
109
+ up.hello($link)
110
+ wasDefaultPrevented = false
111
+ wasClosed = false
112
+ up.on 'click', 'a[up-close]', (event) ->
113
+ wasDefaultPrevented = event.isDefaultPrevented()
114
+ true # the line above might return false and cancel propagation / prevent default
115
+ up.on 'up:modal:close', ->
116
+ wasClosed = true
117
+ $link.click()
118
+ expect(wasClosed).toBe(true)
119
+ expect(wasDefaultPrevented).toBe(true)
120
+
121
+ describe 'when no modal is open', ->
122
+
123
+ it 'does neither close the modal nor prevent the default action', ->
124
+ $link = affix('a[up-close]') # link is outside the modal
125
+ up.hello($link)
126
+ wasDefaultPrevented = false
127
+ wasClosed = false
128
+ up.on 'click', 'a[up-close]', (event) ->
129
+ wasDefaultPrevented = event.isDefaultPrevented()
130
+ true # the line above might return false and cancel propagation / prevent default
131
+ up.on 'up:modal:close', ->
132
+ wasClosed = true
133
+ $link.click()
134
+ expect(wasClosed).toBe(false)
135
+ expect(wasDefaultPrevented).toBe(false)
110
136
 
111
137
  describe 'when following links inside a modal', ->
112
138
 
@@ -4,7 +4,7 @@ describe 'up.motion', ->
4
4
 
5
5
  describe 'up.animate', ->
6
6
 
7
- if up.browser.canCssAnimation()
7
+ if up.browser.canCssTransition()
8
8
 
9
9
  it 'animates the given element', (done) ->
10
10
  $element = affix('.element').text('content')
@@ -35,7 +35,7 @@ describe 'up.motion', ->
35
35
 
36
36
  describe 'up.morph', ->
37
37
 
38
- if up.browser.canCssAnimation()
38
+ if up.browser.canCssTransition()
39
39
 
40
40
  it 'transitions between two element by animating two copies while keeping the originals in the background', (done) ->
41
41
 
@@ -32,9 +32,52 @@ describe 'up.popup', ->
32
32
 
33
33
  describe 'a[up-popup]', ->
34
34
 
35
- it 'should have tests'
35
+ it "loads this link's destination in a popup when clicked", ->
36
+ $link = affix('a[href="/path/to"][up-popup=".middle"]').text('link')
37
+ $link.click()
38
+ expect(@lastRequest().url).toMatch /\/path\/to$/
39
+ @respondWith """
40
+ <div class="before">new-before</div>
41
+ <div class="middle">new-middle</div>
42
+ <div class="after">new-after</div>
43
+ """
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()
36
48
 
37
49
  describe '[up-close]', ->
38
50
 
39
- it 'should have tests'
51
+ describe 'when clicked inside a popup', ->
52
+
53
+ it 'closes the open popup and prevents the default action', ->
54
+ $popup = affix('.up-popup')
55
+ $link = $popup.affix('a[up-close]') # link is within the popup
56
+ up.hello($link)
57
+ wasDefaultPrevented = false
58
+ wasClosed = false
59
+ up.on 'click', 'a[up-close]', (event) ->
60
+ wasDefaultPrevented = event.isDefaultPrevented()
61
+ true # the line above might return false and cancel propagation / prevent default
62
+ up.on 'up:popup:close', ->
63
+ wasClosed = true
64
+ $link.click()
65
+ expect(wasClosed).toBe(true)
66
+ expect(wasDefaultPrevented).toBe(true)
67
+
68
+ describe 'when no popup is open', ->
69
+
70
+ it 'does neither close the popup nor prevent the default action', ->
71
+ $link = affix('a[up-close]') # link is outside the popup
72
+ up.hello($link)
73
+ wasDefaultPrevented = false
74
+ wasClosed = false
75
+ up.on 'click', 'a[up-close]', (event) ->
76
+ wasDefaultPrevented = event.isDefaultPrevented()
77
+ true # the line above might return false and cancel propagation / prevent default
78
+ up.on 'up:popup:close', ->
79
+ wasClosed = true
80
+ $link.click()
81
+ expect(wasClosed).toBe(false)
82
+ expect(wasDefaultPrevented).toBe(false)
40
83
 
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.14.1
4
+ version: 0.15.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-04 00:00:00.000000000 Z
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -81,7 +81,6 @@ files:
81
81
  - design/ghost-debugging.txt
82
82
  - design/homepage.txt
83
83
  - design/rename.txt
84
- - design/up-validate.js.coffee
85
84
  - dist/up-bootstrap.css
86
85
  - dist/up-bootstrap.js
87
86
  - dist/up-bootstrap.min.css
@@ -1,284 +0,0 @@
1
- findSelector = (selector, $origin) ->
2
-
3
- $match = undefined
4
-
5
- if u.isPresent($origin)
6
- $match ||= filterFirstReal($origin.find(selector))
7
- $match ||= filterFirstReal($origin.closest(selector))
8
- $match ||= filterFirstReal($origin.closest('form').find(selector))
9
-
10
- $match ||= filterFirstReal($(".up-popup #{selector}"))
11
- $match ||= filterFirstReal($(".up-modal #{selector}"))
12
- $match ||= filterFirstReal($(selector))
13
-
14
- $match
15
-
16
-
17
-
18
-
19
- [1] Präferiert $origin selbst
20
- [2] Präferiert ein direkter Nachfahr von $origin
21
- [3] ein direkter Vorfahr von $origin
22
- [4] Präferiert im gleichen <form> von $origin
23
- [5] Präferiert in .up-modal
24
- [6] Präferiert in .up-popup
25
- [7] Sonst irgendwo im Dokument
26
-
27
-
28
-
29
- first(".up-popup #{selector}") ||
30
- first(".up-modal #{selector}") ||
31
- first(selector) ||
32
- fragmentNotFound(selector)
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
- Vielleicht Mittelding aus Variante 3 + hinterlegte
48
-
49
- Wie gehe ich damit um, dass .form-group nicht unique ist?
50
-
51
- form.submit(origin: '[name=email]')
52
-
53
- Oder in den CSS-Selektor mit Custom Selector? input[name=email]^^.form-group
54
-
55
- Oder kann ich bei elementFromSelector schlauer sein?
56
-
57
- Oder das hier passiert nicht mit replace?
58
-
59
-
60
-
61
- Variante 3: up-validate definiert Control-Gruppe
62
- ================================================
63
-
64
- HTML
65
- ----
66
-
67
- <form>
68
-
69
- <div class="form-group">
70
- <label>E-mail</label>
71
- <input type="text" name="email" up-validate=".form-group:has(&)" />
72
- </div>
73
-
74
- <div class="form-group">
75
- <label>Password</label>
76
- <input type="text" name="password" up-validate="& < .form-group" />
77
- </div>
78
-
79
- </form>
80
-
81
- Con:
82
- ----
83
- So kann ich up-validate nicht mehr für change/input verwenden, oder vielleicht mal die URL zu benennen
84
- Das könnten dann aber auch andere Attribute sein.
85
-
86
- Pro:
87
- ----
88
- Das wäre vielleicht auch eine Lösung für das Selects-Visibility-For Problem:
89
-
90
- <form>
91
-
92
- <div class="form-group">
93
- <label>Public card</label>
94
- <input type="checkbox" name="is_public" up-validate=".form-group, .confidential" />
95
- </div>
96
-
97
- <% if @form.object.is_public? %>
98
- <div class="form-group confidential">
99
- <label>Confidentiality</label>
100
- <input type="text" name="confidential" up-validate=".form-group" />
101
- </div>
102
- <% end %>
103
-
104
- </form>
105
-
106
-
107
-
108
- Implementierung
109
- ---------------
110
-
111
- selectorForElement = ($element) ->
112
- id = $element.attr("id")
113
- upId = $element.attr("up-id")
114
- name = $element.attr("name")
115
- if present(upId)
116
- selector = "[up-id='#{upId}']"
117
- else if present(id)
118
- selector = "##{id}" + id if present(id)
119
- else if present(name)
120
- tagName = $element.prop("tagName").toLowerCase()
121
- selector = "#{tagName}[name='#{name}']"
122
- else
123
- error('...')
124
- selector
125
-
126
- isGoodSelector = (selector) ->
127
- u.contains(selector, '#') || u.contains(selector, '[name=]')
128
-
129
- enhanceSelector = (selector, $origin) ->
130
- unless isGoodSelector(selector)
131
- $form = $origin.closest('form')
132
- selector = "#{u.selectorFromElement($form)}:has(#{selector})"
133
- selector
134
-
135
- validate = (elementOrSelector, options) ->
136
- $input = $(elementOrSelector)
137
- closestGroupSelector = u.option(u.presence($input.attr('up-validate')), config.groups, 'form')
138
- $group = $start.closest(closestGroupSelector)
139
- $form = $group.closest('form')
140
- $validateFlag = $('<input type="hidden" name="up-validate" value="1" >')
141
- $validateFlag.appendTo($form)
142
-
143
- groupSelector = u.selectorForElement($group)
144
- groupSelector = enhanceSelector(groupSelector)
145
-
146
- up.submit($form, target: groupSelector, failTarget: groupSelector)
147
-
148
- up.on 'change', '[up-validate!="input"]', (event) -> validate(event.target)
149
- up.on 'input', '[up-validate="input"]', (event) -> validate(event.target)
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
- Alternatives HTML
158
- ------------------
159
-
160
- <form>
161
-
162
- <div class="form-group">
163
- <label>E-mail</label>
164
- <input type="text" name="email" up-changes=".form-group" />
165
- </div>
166
-
167
- <div class="form-group">
168
- <label>Password</label>
169
- <input type="text" name="password" up-changes=".form-group" />
170
- </div>
171
-
172
- </form>
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
- Variante 2: up-validate an der Control-Gruppe
181
- ==============================================
182
-
183
- HTML
184
- ----
185
-
186
- <form>
187
-
188
- <div class="form-group" up-validate>
189
- <label>E-mail</label>
190
- <input type="text" name="email" />
191
- </div>
192
-
193
- <div class="form-group" up-validate>
194
- <label>Password</label>
195
- <input type="text" name="password" />
196
- </div>
197
-
198
- </form>
199
-
200
-
201
- Implementierung
202
- ---------------
203
-
204
- validate = (elementOrSelector, options) ->
205
- $start = $(elementOrSelector) # $start is either a control or a form group
206
- $group = $start.closest('[up-validate], form')
207
- $form = $formGroup.closest('form')
208
- $validateFlag = $('<input type="hidden" name="up-validate" value="1" >')
209
- $validateFlag.appendTo($form)
210
- groupSelector = u.selectorForElement($group)
211
- up.submit($form, target: groupSelector, failTarget: groupSelector, origin: )
212
-
213
- up.on 'change', '[up-validate!="input"]', (event) -> validate(event.target)
214
- up.on 'input', '[up-validate="input"]', (event) -> validate(event.target)
215
-
216
-
217
-
218
-
219
- Variante 2: up-validate am Input, Up.js weiß wie Control-Gruppen gefunden werden
220
- ================================================================================
221
-
222
- HTML
223
- ----
224
-
225
- <form>
226
-
227
- <div class="form-group">
228
- <label>E-mail</label>
229
- <input type="text" name="email" up-validate />
230
- </div>
231
-
232
- <div class="form-group">
233
- <label>Password</label>
234
- <input type="text" name="password" up-validate />
235
- </div>
236
-
237
- </form>
238
-
239
-
240
- Implementierung
241
- ---------------
242
-
243
- config.groups = ['.form-group']
244
-
245
- validate = (elementOrSelector, options) ->
246
- $control = $(elementOrSelector)
247
- $formGroup = u.multiSelector(config.groups).seekUp($control) || $control.closest('form')
248
- $form = $formGroup.closest('form')
249
- $validateFlag = $('<input type="hidden" name="up-validate" value="1" >')
250
- $validateFlag.appendTo($form)
251
- groupSelector = u.selectorForElement($formGroup)
252
- up.submit($form, target: groupSelector, failTarget: groupSelector)
253
-
254
- up.on 'change', '[up-validate!="input"]', (event) -> validate(this)
255
- up.on 'input', '[up-validate="input"]', (event) -> validate(this)
256
-
257
-
258
- Alle Varianten: In Rails Controller
259
- ===================================
260
-
261
-
262
- class UsersController < ApplicationController
263
-
264
- def create
265
- build_user
266
-
267
- if up?
268
-
269
- if up.validate?
270
-
271
-
272
- if request.up.validate? # same as `params['up-validate'].present?`
273
- @user.valid? # run validations
274
- render 'new'
275
- elsif @user.save?
276
- sign_in @user
277
- redirect_to root_path
278
- else
279
- render 'new', status: :bad_request
280
- end
281
- end
282
-
283
- end
284
-