jquery-rails 3.0.4 → 3.1.4

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 jquery-rails might be problematic. Click here for more details.

@@ -4,7 +4,7 @@
4
4
  * Unobtrusive scripting adapter for jQuery
5
5
  * https://github.com/rails/jquery-ujs
6
6
  *
7
- * Requires jQuery 1.7.0 or later.
7
+ * Requires jQuery 1.8.0 or later.
8
8
  *
9
9
  * Released under the MIT license
10
10
  *
@@ -22,10 +22,10 @@
22
22
 
23
23
  $.rails = rails = {
24
24
  // Link elements bound by jquery-ujs
25
- linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]',
25
+ linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with], a[data-disable]',
26
26
 
27
- // Button elements boud jquery-ujs
28
- buttonClickSelector: 'button[data-remote]',
27
+ // Button elements bound by jquery-ujs
28
+ buttonClickSelector: 'button[data-remote]:not(form button), button[data-confirm]:not(form button)',
29
29
 
30
30
  // Select elements bound by jquery-ujs
31
31
  inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
@@ -34,13 +34,13 @@
34
34
  formSubmitSelector: 'form',
35
35
 
36
36
  // Form input elements bound by jquery-ujs
37
- formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])',
37
+ formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
38
38
 
39
39
  // Form input elements disabled during form submission
40
- disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]',
40
+ disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
41
41
 
42
42
  // Form input elements re-enabled after form submission
43
- enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled',
43
+ enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
44
44
 
45
45
  // Form required input elements
46
46
  requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])',
@@ -49,7 +49,10 @@
49
49
  fileInputSelector: 'input[type=file]',
50
50
 
51
51
  // Link onClick disable selector with possible reenable after remote submission
52
- linkDisableSelector: 'a[data-disable-with]',
52
+ linkDisableSelector: 'a[data-disable-with], a[data-disable]',
53
+
54
+ // Button onClick disable selector with possible reenable after remote submission
55
+ buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',
53
56
 
54
57
  // Make sure that every Ajax request sends the CSRF token
55
58
  CSRFProtection: function(xhr) {
@@ -57,6 +60,13 @@
57
60
  if (token) xhr.setRequestHeader('X-CSRF-Token', token);
58
61
  },
59
62
 
63
+ // making sure that all forms have actual up-to-date token(cached forms contain old one)
64
+ refreshCSRFTokens: function(){
65
+ var csrfToken = $('meta[name=csrf-token]').attr('content');
66
+ var csrfParam = $('meta[name=csrf-param]').attr('content');
67
+ $('form input[name="' + csrfParam + '"]').val(csrfToken);
68
+ },
69
+
60
70
  // Triggers an event on an element and returns false if the event result is false
61
71
  fire: function(obj, name, data) {
62
72
  var event = $.Event(name);
@@ -76,16 +86,14 @@
76
86
 
77
87
  // Default way to get an element's href. May be overridden at $.rails.href.
78
88
  href: function(element) {
79
- return element.attr('href');
89
+ return element[0].href;
80
90
  },
81
91
 
82
92
  // Submits "remote" forms and links with ajax
83
93
  handleRemote: function(element) {
84
- var method, url, data, elCrossDomain, crossDomain, withCredentials, dataType, options;
94
+ var method, url, data, withCredentials, dataType, options;
85
95
 
86
96
  if (rails.fire(element, 'ajax:before')) {
87
- elCrossDomain = element.data('cross-domain');
88
- crossDomain = elCrossDomain === undefined ? null : elCrossDomain;
89
97
  withCredentials = element.data('with-credentials') || null;
90
98
  dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
91
99
 
@@ -122,7 +130,11 @@
122
130
  if (settings.dataType === undefined) {
123
131
  xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
124
132
  }
125
- return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
133
+ if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
134
+ element.trigger('ajax:send', xhr);
135
+ } else {
136
+ return false;
137
+ }
126
138
  },
127
139
  success: function(data, status, xhr) {
128
140
  element.trigger('ajax:success', [data, status, xhr]);
@@ -133,7 +145,7 @@
133
145
  error: function(xhr, status, error) {
134
146
  element.trigger('ajax:error', [xhr, status, error]);
135
147
  },
136
- crossDomain: crossDomain
148
+ crossDomain: rails.isCrossDomain(url)
137
149
  };
138
150
 
139
151
  // There is no withCredentials for IE6-8 when
@@ -147,61 +159,106 @@
147
159
  // Only pass url to `ajax` options if not blank
148
160
  if (url) { options.url = url; }
149
161
 
150
- var jqxhr = rails.ajax(options);
151
- element.trigger('ajax:send', jqxhr);
152
- return jqxhr;
162
+ return rails.ajax(options);
153
163
  } else {
154
164
  return false;
155
165
  }
156
166
  },
157
167
 
168
+ // Determines if the request is a cross domain request.
169
+ isCrossDomain: function(url) {
170
+ var originAnchor = document.createElement("a");
171
+ originAnchor.href = location.href;
172
+ var urlAnchor = document.createElement("a");
173
+
174
+ try {
175
+ urlAnchor.href = url;
176
+ // This is a workaround to a IE bug.
177
+ urlAnchor.href = urlAnchor.href;
178
+
179
+ // If URL protocol is false or is a string containing a single colon
180
+ // *and* host are false, assume it is not a cross-domain request
181
+ // (should only be the case for IE7 and IE compatibility mode).
182
+ // Otherwise, evaluate protocol and host of the URL against the origin
183
+ // protocol and host
184
+ return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) ||
185
+ (originAnchor.protocol + "//" + originAnchor.host ===
186
+ urlAnchor.protocol + "//" + urlAnchor.host)); //
187
+ } catch (e) {
188
+ // If there is an error parsing the URL, assume it is crossDomain.
189
+ return true;
190
+ }
191
+ },
192
+
158
193
  // Handles "data-method" on links such as:
159
194
  // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
160
195
  handleMethod: function(link) {
161
196
  var href = rails.href(link),
162
197
  method = link.data('method'),
163
198
  target = link.attr('target'),
164
- csrf_token = $('meta[name=csrf-token]').attr('content'),
165
- csrf_param = $('meta[name=csrf-param]').attr('content'),
199
+ csrfToken = $('meta[name=csrf-token]').attr('content'),
200
+ csrfParam = $('meta[name=csrf-param]').attr('content'),
166
201
  form = $('<form method="post" action="' + href + '"></form>'),
167
- metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
202
+ metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
168
203
 
169
- if (csrf_param !== undefined && csrf_token !== undefined) {
170
- metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
204
+ if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {
205
+ metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
171
206
  }
172
207
 
173
208
  if (target) { form.attr('target', target); }
174
209
 
175
- form.hide().append(metadata_input).appendTo('body');
210
+ form.hide().append(metadataInput).appendTo('body');
176
211
  form.submit();
177
212
  },
178
213
 
214
+ // Helper function that returns form elements that match the specified CSS selector
215
+ // If form is actually a "form" element this will return associated elements outside the from that have
216
+ // the html form attribute set
217
+ formElements: function(form, selector) {
218
+ return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector);
219
+ },
220
+
179
221
  /* Disables form elements:
180
222
  - Caches element value in 'ujs:enable-with' data store
181
223
  - Replaces element text with value of 'data-disable-with' attribute
182
224
  - Sets disabled property to true
183
225
  */
184
226
  disableFormElements: function(form) {
185
- form.find(rails.disableSelector).each(function() {
186
- var element = $(this), method = element.is('button') ? 'html' : 'val';
187
- element.data('ujs:enable-with', element[method]());
188
- element[method](element.data('disable-with'));
189
- element.prop('disabled', true);
227
+ rails.formElements(form, rails.disableSelector).each(function() {
228
+ rails.disableFormElement($(this));
190
229
  });
191
230
  },
192
231
 
232
+ disableFormElement: function(element) {
233
+ var method, replacement;
234
+
235
+ method = element.is('button') ? 'html' : 'val';
236
+ replacement = element.data('disable-with');
237
+
238
+ element.data('ujs:enable-with', element[method]());
239
+ if (replacement !== undefined) {
240
+ element[method](replacement);
241
+ }
242
+
243
+ element.prop('disabled', true);
244
+ },
245
+
193
246
  /* Re-enables disabled form elements:
194
247
  - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
195
248
  - Sets disabled property to false
196
249
  */
197
250
  enableFormElements: function(form) {
198
- form.find(rails.enableSelector).each(function() {
199
- var element = $(this), method = element.is('button') ? 'html' : 'val';
200
- if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
201
- element.prop('disabled', false);
251
+ rails.formElements(form, rails.enableSelector).each(function() {
252
+ rails.enableFormElement($(this));
202
253
  });
203
254
  },
204
255
 
256
+ enableFormElement: function(element) {
257
+ var method = element.is('button') ? 'html' : 'val';
258
+ if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
259
+ element.prop('disabled', false);
260
+ },
261
+
205
262
  /* For 'data-confirm' attribute:
206
263
  - Fires `confirm` event
207
264
  - Shows the confirmation dialog
@@ -262,8 +319,13 @@
262
319
  // replace element's html with the 'data-disable-with' after storing original html
263
320
  // and prevent clicking on it
264
321
  disableElement: function(element) {
322
+ var replacement = element.data('disable-with');
323
+
265
324
  element.data('ujs:enable-with', element.html()); // store enabled state
266
- element.html(element.data('disable-with')); // set to disabled state
325
+ if (replacement !== undefined) {
326
+ element.html(replacement);
327
+ }
328
+
267
329
  element.bind('click.railsDisable', function(e) { // prevent further clicking
268
330
  return rails.stopEverything(e);
269
331
  });
@@ -277,7 +339,6 @@
277
339
  }
278
340
  element.unbind('click.railsDisable'); // enable element
279
341
  }
280
-
281
342
  };
282
343
 
283
344
  if (rails.fire($document, 'rails:attachBindings')) {
@@ -288,14 +349,18 @@
288
349
  rails.enableElement($(this));
289
350
  });
290
351
 
352
+ $document.delegate(rails.buttonDisableSelector, 'ajax:complete', function() {
353
+ rails.enableFormElement($(this));
354
+ });
355
+
291
356
  $document.delegate(rails.linkClickSelector, 'click.rails', function(e) {
292
- var link = $(this), method = link.data('method'), data = link.data('params');
357
+ var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
293
358
  if (!rails.allowAction(link)) return rails.stopEverything(e);
294
359
 
295
- if (link.is(rails.linkDisableSelector)) rails.disableElement(link);
360
+ if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);
296
361
 
297
362
  if (link.data('remote') !== undefined) {
298
- if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; }
363
+ if (metaClick && (!method || method === 'GET') && !data) { return true; }
299
364
 
300
365
  var handleRemote = rails.handleRemote(link);
301
366
  // response from rails.handleRemote() will either be false or a deferred object promise.
@@ -314,9 +379,18 @@
314
379
 
315
380
  $document.delegate(rails.buttonClickSelector, 'click.rails', function(e) {
316
381
  var button = $(this);
382
+
317
383
  if (!rails.allowAction(button)) return rails.stopEverything(e);
318
384
 
319
- rails.handleRemote(button);
385
+ if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button);
386
+
387
+ var handleRemote = rails.handleRemote(button);
388
+ // response from rails.handleRemote() will either be false or a deferred object promise.
389
+ if (handleRemote === false) {
390
+ rails.enableFormElement(button);
391
+ } else {
392
+ handleRemote.error( function() { rails.enableFormElement(button); } );
393
+ }
320
394
  return false;
321
395
  });
322
396
 
@@ -331,17 +405,21 @@
331
405
  $document.delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
332
406
  var form = $(this),
333
407
  remote = form.data('remote') !== undefined,
334
- blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
335
- nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
408
+ blankRequiredInputs,
409
+ nonBlankFileInputs;
336
410
 
337
411
  if (!rails.allowAction(form)) return rails.stopEverything(e);
338
412
 
339
413
  // skip other logic when required values are missing or file upload is present
340
- if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
341
- return rails.stopEverything(e);
414
+ if (form.attr('novalidate') == undefined) {
415
+ blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector);
416
+ if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
417
+ return rails.stopEverything(e);
418
+ }
342
419
  }
343
420
 
344
421
  if (remote) {
422
+ nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
345
423
  if (nonBlankFileInputs) {
346
424
  // slight timeout so that the submit button gets properly serialized
347
425
  // (make it easy for event handler to serialize form without disabled values)
@@ -375,7 +453,7 @@
375
453
  button.closest('form').data('ujs:submit-button', data);
376
454
  });
377
455
 
378
- $document.delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) {
456
+ $document.delegate(rails.formSubmitSelector, 'ajax:send.rails', function(event) {
379
457
  if (this == event.target) rails.disableFormElements($(this));
380
458
  });
381
459
 
@@ -384,10 +462,7 @@
384
462
  });
385
463
 
386
464
  $(function(){
387
- // making sure that all forms have actual up-to-date token(cached forms contain old one)
388
- var csrf_token = $('meta[name=csrf-token]').attr('content');
389
- var csrf_param = $('meta[name=csrf-param]').attr('content');
390
- $('form input[name="' + csrf_param + '"]').val(csrf_token);
465
+ rails.refreshCSRFTokens();
391
466
  });
392
467
  }
393
468
 
metadata CHANGED
@@ -1,52 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jquery-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.4
5
- prerelease:
4
+ version: 3.1.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - André Arko
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-11 00:00:00.000000000Z
11
+ date: 2015-09-01 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: railties
16
- requirement: &70284820442980 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '3.0'
22
- - - <
20
+ - - "<"
23
21
  - !ruby/object:Gem::Version
24
22
  version: '5.0'
25
23
  type: :runtime
26
24
  prerelease: false
27
- version_requirements: *70284820442980
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
28
33
  - !ruby/object:Gem::Dependency
29
34
  name: thor
30
- requirement: &70284820449140 !ruby/object:Gem::Requirement
31
- none: false
35
+ requirement: !ruby/object:Gem::Requirement
32
36
  requirements:
33
- - - ! '>='
37
+ - - ">="
34
38
  - !ruby/object:Gem::Version
35
39
  version: '0.14'
36
- - - <
40
+ - - "<"
37
41
  - !ruby/object:Gem::Version
38
42
  version: '2.0'
39
43
  type: :runtime
40
44
  prerelease: false
41
- version_requirements: *70284820449140
42
- description: This gem provides jQuery and the jQuery-ujs driver for your Rails 3 application.
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0.14'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.0'
53
+ description: This gem provides jQuery and the jQuery-ujs driver for your Rails 3+
54
+ application.
43
55
  email:
44
56
  - andre@arko.net
45
57
  executables: []
46
58
  extensions: []
47
59
  extra_rdoc_files: []
48
60
  files:
49
- - .gitignore
61
+ - ".gitignore"
50
62
  - CHANGELOG.md
51
63
  - CONTRIBUTING.md
52
64
  - Gemfile
@@ -69,29 +81,26 @@ files:
69
81
  homepage: http://rubygems.org/gems/jquery-rails
70
82
  licenses:
71
83
  - MIT
84
+ metadata: {}
72
85
  post_install_message:
73
86
  rdoc_options: []
74
87
  require_paths:
75
88
  - lib
76
89
  required_ruby_version: !ruby/object:Gem::Requirement
77
- none: false
78
90
  requirements:
79
- - - ! '>='
91
+ - - ">="
80
92
  - !ruby/object:Gem::Version
81
93
  version: '0'
82
- segments:
83
- - 0
84
- hash: 20524014126529113
85
94
  required_rubygems_version: !ruby/object:Gem::Requirement
86
- none: false
87
95
  requirements:
88
- - - ! '>='
96
+ - - ">="
89
97
  - !ruby/object:Gem::Version
90
98
  version: 1.3.6
91
99
  requirements: []
92
100
  rubyforge_project: jquery-rails
93
- rubygems_version: 1.8.15
101
+ rubygems_version: 2.4.7
94
102
  signing_key:
95
- specification_version: 3
96
- summary: Use jQuery with Rails 3
103
+ specification_version: 4
104
+ summary: Use jQuery with Rails 3+
97
105
  test_files: []
106
+ has_rdoc: