upjs-rails 0.12.5 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rdoc_options +23 -0
  3. data/CHANGELOG.md +20 -0
  4. data/design/up-validate.js.coffee +284 -0
  5. data/dist/up-bootstrap.js +4 -0
  6. data/dist/up-bootstrap.min.js +1 -1
  7. data/dist/up.js +547 -102
  8. data/dist/up.min.js +2 -2
  9. data/lib/assets/javascripts/up/browser.js.coffee +3 -2
  10. data/lib/assets/javascripts/up/flow.js.coffee +95 -17
  11. data/lib/assets/javascripts/up/form.js.coffee +327 -34
  12. data/lib/assets/javascripts/up/history.js.coffee +1 -1
  13. data/lib/assets/javascripts/up/layout.js.coffee +4 -4
  14. data/lib/assets/javascripts/up/link.js.coffee +5 -2
  15. data/lib/assets/javascripts/up/modal.js.coffee +1 -0
  16. data/lib/assets/javascripts/up/proxy.js.coffee +27 -12
  17. data/lib/assets/javascripts/up/syntax.js.coffee +39 -20
  18. data/lib/assets/javascripts/up/util.js.coffee +29 -12
  19. data/lib/assets/javascripts/up-bootstrap/form-ext.js.coffee +1 -0
  20. data/lib/upjs/rails/engine.rb +1 -1
  21. data/lib/upjs/rails/inspector.rb +63 -0
  22. data/lib/upjs/rails/inspector_accessor.rb +28 -0
  23. data/lib/upjs/rails/request_echo_headers.rb +7 -0
  24. data/lib/upjs/rails/request_method_cookie.rb +12 -4
  25. data/lib/upjs/rails/version.rb +5 -1
  26. data/lib/upjs-rails.rb +7 -5
  27. data/spec_app/.rspec +2 -0
  28. data/spec_app/Gemfile +0 -3
  29. data/spec_app/Gemfile.lock +43 -44
  30. data/spec_app/app/assets/stylesheets/application.css +1 -1
  31. data/spec_app/app/controllers/test_controller.rb +23 -0
  32. data/spec_app/config/routes.rb +2 -0
  33. data/spec_app/spec/controllers/test_controller_spec.rb +67 -0
  34. data/spec_app/spec/javascripts/helpers/append_fixture.js.coffee +8 -0
  35. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +18 -0
  36. data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +1 -0
  37. data/spec_app/spec/javascripts/up/flow_spec.js.coffee +93 -43
  38. data/spec_app/spec/javascripts/up/form_spec.js.coffee +80 -18
  39. data/spec_app/spec/javascripts/up/history_spec.js.coffee +1 -5
  40. data/spec_app/spec/javascripts/up/link_spec.js.coffee +18 -17
  41. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +32 -37
  42. data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +7 -26
  43. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +1 -7
  44. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +26 -25
  45. data/spec_app/spec/javascripts/up/util_spec.js.coffee +23 -0
  46. data/spec_app/spec/spec_helper.rb +62 -0
  47. metadata +12 -3
  48. data/lib/upjs/rails/request_ext.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f13c82c612066844882580ed4073b0f025cda22
4
- data.tar.gz: a0cef27d64bfdd0ea2ae249d668b679b23321841
3
+ metadata.gz: 22234d5edc76355380cc9a8c1c4996a59bf53afe
4
+ data.tar.gz: ee6e5cd9ec9a5932389cf08de790f855c2f8b558
5
5
  SHA512:
6
- metadata.gz: 008081bdca8fe235b86454baf676c3e5e19e7f89f3d76a6b58ee47502852f448411b26f5a0d0b0234b1a344a1c23276948efae1eefb1f04cbbd238b53981fa04
7
- data.tar.gz: 1775166c4643ffdcd0d2801669ea94557b6fa75adf38b5176b9b159f319aeae1dce2e8ffd8e4b17f43597bb9d1bf765d2f9b17aaf75df83b49925f185913eb1c
6
+ metadata.gz: 3ec849ae6db3272550ba10cfc26d906389a403751f2c1a7c2e71a7b66a59572595729077eb5d3c282097e8e1f1fdad579da12da60cc40cea21b6e4fbe8b667bf
7
+ data.tar.gz: d7c90fd8186375cb8584e0ba4413fa296182208e804a361bdf9ffea63f5c29f5a3ceb50d8c7219b87b86ddbbd781b8c00cac6a6ba7d307a4cf3d354745b1ff95
data/.rdoc_options ADDED
@@ -0,0 +1,23 @@
1
+ --- !ruby/object:RDoc::Options
2
+ encoding: UTF-8
3
+ static_path: []
4
+ rdoc_include:
5
+ - "./README.md"
6
+ - "./lib"
7
+ charset: UTF-8
8
+ exclude:
9
+ hyperlink_all: false
10
+ line_numbers: false
11
+ locale:
12
+ locale_dir: locale
13
+ locale_name:
14
+ main_page: README.md
15
+ markup: markdown
16
+ output_decoration: true
17
+ page_dir:
18
+ show_hash: false
19
+ tab_width: 2
20
+ template_stylesheets: []
21
+ title: upjs-rails - Rails bindings for Up.js
22
+ visibility: :protected
23
+ webcvs:
data/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
5
5
  This project mostly adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
7
 
8
+ 0.13.0
9
+ ------
10
+
11
+ ### Compatible changes
12
+
13
+ - Support for server-side live validation of forms
14
+ using the [`[up-validate]`](/up-validate) selector.
15
+ - Support for [non-standard CSS selectors from jQuery](https://api.jquery.com/category/selectors/),
16
+ such as [`:has`](http://api.jquery.com/has-selector/) or [`:visible`](http://api.jquery.com/visible-selector/).
17
+ - Allow to refer to the current element as `&` in target selectors. This is useful
18
+ to reference containers that contain the triggering element, e.g.
19
+ `<a href="/path" up-target=".container:has(&)">`
20
+ - Improve automatic generation of selectors for elements when no
21
+ explicit selector is given.
22
+ - Forms with `file` inputs will now cause forms to fall back to a standard submission without AJAX.
23
+ In a future release we will be able to submit file inputs via AJAX.
24
+ - The [request cache](/up.proxy) now reuses responses for `body` and `html` when asked for other selectors.
25
+ - Server responses can now change the document title by including an `X-Up-Title` header.
26
+
27
+
8
28
  0.12.5
9
29
  ------
10
30
 
@@ -0,0 +1,284 @@
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
+ createSelectorFromElement = ($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.createSelectorFromElement($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.createSelectorFromElement($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.createSelectorFromElement($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
+
data/dist/up-bootstrap.js CHANGED
@@ -1,3 +1,7 @@
1
+ (function() {
2
+ up.form.config.validateTargets.unshift('.form-group:has(&)');
3
+
4
+ }).call(this);
1
5
  (function() {
2
6
  up.layout.config.fixedTop.push('.navbar-fixed-top');
3
7
 
@@ -1 +1 @@
1
- (function(){up.layout.config.fixedTop.push(".navbar-fixed-top"),up.layout.config.fixedBottom.push(".navbar-fixed-bottom"),up.layout.config.anchoredRight.push(".navbar-fixed-top"),up.layout.config.anchoredRight.push(".navbar-fixed-bottom"),up.layout.config.anchoredRight.push(".footer")}).call(this),function(){up.modal.config.template='<div class="up-modal">\n <div class="up-modal-dialog modal-dialog">\n <div class="up-modal-content modal-content"></div>\n </div>\n</div>'}.call(this),function(){up.navigation.config.currentClasses.push("active")}.call(this),function(){}.call(this);
1
+ (function(){up.form.config.validateTargets.unshift(".form-group:has(&)")}).call(this),function(){up.layout.config.fixedTop.push(".navbar-fixed-top"),up.layout.config.fixedBottom.push(".navbar-fixed-bottom"),up.layout.config.anchoredRight.push(".navbar-fixed-top"),up.layout.config.anchoredRight.push(".navbar-fixed-bottom"),up.layout.config.anchoredRight.push(".footer")}.call(this),function(){up.modal.config.template='<div class="up-modal">\n <div class="up-modal-dialog modal-dialog">\n <div class="up-modal-content modal-content"></div>\n </div>\n</div>'}.call(this),function(){up.navigation.config.currentClasses.push("active")}.call(this),function(){}.call(this);