actionview 7.0.1 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +281 -202
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/app/assets/javascripts/rails-ujs.esm.js +693 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +33 -12
  8. data/lib/action_view/buffers.rb +106 -8
  9. data/lib/action_view/cache_expiry.rb +40 -43
  10. data/lib/action_view/context.rb +1 -1
  11. data/lib/action_view/deprecator.rb +7 -0
  12. data/lib/action_view/digestor.rb +1 -1
  13. data/lib/action_view/gem_version.rb +2 -2
  14. data/lib/action_view/helpers/active_model_helper.rb +1 -1
  15. data/lib/action_view/helpers/asset_tag_helper.rb +133 -48
  16. data/lib/action_view/helpers/asset_url_helper.rb +13 -12
  17. data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
  18. data/lib/action_view/helpers/cache_helper.rb +3 -9
  19. data/lib/action_view/helpers/capture_helper.rb +26 -12
  20. data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
  21. data/lib/action_view/helpers/controller_helper.rb +6 -0
  22. data/lib/action_view/helpers/csp_helper.rb +2 -2
  23. data/lib/action_view/helpers/csrf_helper.rb +3 -3
  24. data/lib/action_view/helpers/date_helper.rb +76 -64
  25. data/lib/action_view/helpers/debug_helper.rb +3 -3
  26. data/lib/action_view/helpers/form_helper.rb +62 -31
  27. data/lib/action_view/helpers/form_options_helper.rb +6 -3
  28. data/lib/action_view/helpers/form_tag_helper.rb +88 -44
  29. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  30. data/lib/action_view/helpers/number_helper.rb +15 -13
  31. data/lib/action_view/helpers/output_safety_helper.rb +4 -4
  32. data/lib/action_view/helpers/rendering_helper.rb +5 -6
  33. data/lib/action_view/helpers/sanitize_helper.rb +34 -15
  34. data/lib/action_view/helpers/tag_helper.rb +27 -16
  35. data/lib/action_view/helpers/tags/base.rb +11 -52
  36. data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
  37. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
  38. data/lib/action_view/helpers/tags/collection_select.rb +3 -0
  39. data/lib/action_view/helpers/tags/date_field.rb +1 -1
  40. data/lib/action_view/helpers/tags/date_select.rb +2 -0
  41. data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
  42. data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
  43. data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
  44. data/lib/action_view/helpers/tags/month_field.rb +1 -1
  45. data/lib/action_view/helpers/tags/select.rb +4 -1
  46. data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
  47. data/lib/action_view/helpers/tags/time_field.rb +1 -1
  48. data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
  49. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  50. data/lib/action_view/helpers/tags/weekday_select.rb +3 -0
  51. data/lib/action_view/helpers/tags.rb +2 -0
  52. data/lib/action_view/helpers/text_helper.rb +33 -17
  53. data/lib/action_view/helpers/translation_helper.rb +6 -6
  54. data/lib/action_view/helpers/url_helper.rb +90 -65
  55. data/lib/action_view/helpers.rb +2 -0
  56. data/lib/action_view/layouts.rb +13 -8
  57. data/lib/action_view/log_subscriber.rb +49 -32
  58. data/lib/action_view/lookup_context.rb +29 -13
  59. data/lib/action_view/path_registry.rb +57 -0
  60. data/lib/action_view/path_set.rb +13 -14
  61. data/lib/action_view/railtie.rb +26 -3
  62. data/lib/action_view/record_identifier.rb +16 -9
  63. data/lib/action_view/renderer/abstract_renderer.rb +1 -1
  64. data/lib/action_view/renderer/collection_renderer.rb +9 -1
  65. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +21 -3
  66. data/lib/action_view/renderer/partial_renderer.rb +3 -2
  67. data/lib/action_view/renderer/renderer.rb +2 -0
  68. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -2
  69. data/lib/action_view/renderer/template_renderer.rb +3 -2
  70. data/lib/action_view/rendering.rb +24 -6
  71. data/lib/action_view/ripper_ast_parser.rb +6 -6
  72. data/lib/action_view/routing_url_for.rb +7 -4
  73. data/lib/action_view/template/error.rb +14 -1
  74. data/lib/action_view/template/handlers/builder.rb +4 -4
  75. data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
  76. data/lib/action_view/template/handlers/erb.rb +73 -1
  77. data/lib/action_view/template/handlers.rb +1 -1
  78. data/lib/action_view/template/html.rb +1 -1
  79. data/lib/action_view/template/raw_file.rb +1 -1
  80. data/lib/action_view/template/renderable.rb +1 -1
  81. data/lib/action_view/template/resolver.rb +15 -5
  82. data/lib/action_view/template/text.rb +1 -1
  83. data/lib/action_view/template/types.rb +25 -34
  84. data/lib/action_view/template.rb +227 -53
  85. data/lib/action_view/template_path.rb +2 -0
  86. data/lib/action_view/test_case.rb +174 -21
  87. data/lib/action_view/unbound_template.rb +15 -5
  88. data/lib/action_view/version.rb +1 -1
  89. data/lib/action_view/view_paths.rb +19 -28
  90. data/lib/action_view.rb +4 -1
  91. data/lib/assets/compiled/rails-ujs.js +36 -5
  92. metadata +27 -27
@@ -0,0 +1,630 @@
1
+ /*
2
+ Unobtrusive JavaScript
3
+ https://github.com/rails/rails/blob/main/actionview/app/javascript
4
+ Released under the MIT license
5
+ */
6
+ (function(global, factory) {
7
+ typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
8
+ global.Rails = factory());
9
+ })(this, (function() {
10
+ "use strict";
11
+ const linkClickSelector = "a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]";
12
+ const buttonClickSelector = {
13
+ selector: "button[data-remote]:not([form]), button[data-confirm]:not([form])",
14
+ exclude: "form button"
15
+ };
16
+ const inputChangeSelector = "select[data-remote], input[data-remote], textarea[data-remote]";
17
+ const formSubmitSelector = "form:not([data-turbo=true])";
18
+ const formInputClickSelector = "form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])";
19
+ const formDisableSelector = "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";
20
+ const formEnableSelector = "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";
21
+ const fileInputSelector = "input[name][type=file]:not([disabled])";
22
+ const linkDisableSelector = "a[data-disable-with], a[data-disable]";
23
+ const buttonDisableSelector = "button[data-remote][data-disable-with], button[data-remote][data-disable]";
24
+ let nonce = null;
25
+ const loadCSPNonce = () => {
26
+ const metaTag = document.querySelector("meta[name=csp-nonce]");
27
+ return nonce = metaTag && metaTag.content;
28
+ };
29
+ const cspNonce = () => nonce || loadCSPNonce();
30
+ const m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;
31
+ const matches = function(element, selector) {
32
+ if (selector.exclude) {
33
+ return m.call(element, selector.selector) && !m.call(element, selector.exclude);
34
+ } else {
35
+ return m.call(element, selector);
36
+ }
37
+ };
38
+ const EXPANDO = "_ujsData";
39
+ const getData = (element, key) => element[EXPANDO] ? element[EXPANDO][key] : undefined;
40
+ const setData = function(element, key, value) {
41
+ if (!element[EXPANDO]) {
42
+ element[EXPANDO] = {};
43
+ }
44
+ return element[EXPANDO][key] = value;
45
+ };
46
+ const $ = selector => Array.prototype.slice.call(document.querySelectorAll(selector));
47
+ const isContentEditable = function(element) {
48
+ var isEditable = false;
49
+ do {
50
+ if (element.isContentEditable) {
51
+ isEditable = true;
52
+ break;
53
+ }
54
+ element = element.parentElement;
55
+ } while (element);
56
+ return isEditable;
57
+ };
58
+ const csrfToken = () => {
59
+ const meta = document.querySelector("meta[name=csrf-token]");
60
+ return meta && meta.content;
61
+ };
62
+ const csrfParam = () => {
63
+ const meta = document.querySelector("meta[name=csrf-param]");
64
+ return meta && meta.content;
65
+ };
66
+ const CSRFProtection = xhr => {
67
+ const token = csrfToken();
68
+ if (token) {
69
+ return xhr.setRequestHeader("X-CSRF-Token", token);
70
+ }
71
+ };
72
+ const refreshCSRFTokens = () => {
73
+ const token = csrfToken();
74
+ const param = csrfParam();
75
+ if (token && param) {
76
+ return $('form input[name="' + param + '"]').forEach((input => input.value = token));
77
+ }
78
+ };
79
+ const AcceptHeaders = {
80
+ "*": "*/*",
81
+ text: "text/plain",
82
+ html: "text/html",
83
+ xml: "application/xml, text/xml",
84
+ json: "application/json, text/javascript",
85
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
86
+ };
87
+ const ajax = options => {
88
+ options = prepareOptions(options);
89
+ var xhr = createXHR(options, (function() {
90
+ const response = processResponse(xhr.response != null ? xhr.response : xhr.responseText, xhr.getResponseHeader("Content-Type"));
91
+ if (Math.floor(xhr.status / 100) === 2) {
92
+ if (typeof options.success === "function") {
93
+ options.success(response, xhr.statusText, xhr);
94
+ }
95
+ } else {
96
+ if (typeof options.error === "function") {
97
+ options.error(response, xhr.statusText, xhr);
98
+ }
99
+ }
100
+ return typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : undefined;
101
+ }));
102
+ if (options.beforeSend && !options.beforeSend(xhr, options)) {
103
+ return false;
104
+ }
105
+ if (xhr.readyState === XMLHttpRequest.OPENED) {
106
+ return xhr.send(options.data);
107
+ }
108
+ };
109
+ var prepareOptions = function(options) {
110
+ options.url = options.url || location.href;
111
+ options.type = options.type.toUpperCase();
112
+ if (options.type === "GET" && options.data) {
113
+ if (options.url.indexOf("?") < 0) {
114
+ options.url += "?" + options.data;
115
+ } else {
116
+ options.url += "&" + options.data;
117
+ }
118
+ }
119
+ if (!(options.dataType in AcceptHeaders)) {
120
+ options.dataType = "*";
121
+ }
122
+ options.accept = AcceptHeaders[options.dataType];
123
+ if (options.dataType !== "*") {
124
+ options.accept += ", */*; q=0.01";
125
+ }
126
+ return options;
127
+ };
128
+ var createXHR = function(options, done) {
129
+ const xhr = new XMLHttpRequest;
130
+ xhr.open(options.type, options.url, true);
131
+ xhr.setRequestHeader("Accept", options.accept);
132
+ if (typeof options.data === "string") {
133
+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
134
+ }
135
+ if (!options.crossDomain) {
136
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
137
+ CSRFProtection(xhr);
138
+ }
139
+ xhr.withCredentials = !!options.withCredentials;
140
+ xhr.onreadystatechange = function() {
141
+ if (xhr.readyState === XMLHttpRequest.DONE) {
142
+ return done(xhr);
143
+ }
144
+ };
145
+ return xhr;
146
+ };
147
+ var processResponse = function(response, type) {
148
+ if (typeof response === "string" && typeof type === "string") {
149
+ if (type.match(/\bjson\b/)) {
150
+ try {
151
+ response = JSON.parse(response);
152
+ } catch (error) {}
153
+ } else if (type.match(/\b(?:java|ecma)script\b/)) {
154
+ const script = document.createElement("script");
155
+ script.setAttribute("nonce", cspNonce());
156
+ script.text = response;
157
+ document.head.appendChild(script).parentNode.removeChild(script);
158
+ } else if (type.match(/\b(xml|html|svg)\b/)) {
159
+ const parser = new DOMParser;
160
+ type = type.replace(/;.+/, "");
161
+ try {
162
+ response = parser.parseFromString(response, type);
163
+ } catch (error1) {}
164
+ }
165
+ }
166
+ return response;
167
+ };
168
+ const href = element => element.href;
169
+ const isCrossDomain = function(url) {
170
+ const originAnchor = document.createElement("a");
171
+ originAnchor.href = location.href;
172
+ const urlAnchor = document.createElement("a");
173
+ try {
174
+ urlAnchor.href = url;
175
+ return !((!urlAnchor.protocol || urlAnchor.protocol === ":") && !urlAnchor.host || originAnchor.protocol + "//" + originAnchor.host === urlAnchor.protocol + "//" + urlAnchor.host);
176
+ } catch (e) {
177
+ return true;
178
+ }
179
+ };
180
+ let preventDefault;
181
+ let {CustomEvent: CustomEvent} = window;
182
+ if (typeof CustomEvent !== "function") {
183
+ CustomEvent = function(event, params) {
184
+ const evt = document.createEvent("CustomEvent");
185
+ evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
186
+ return evt;
187
+ };
188
+ CustomEvent.prototype = window.Event.prototype;
189
+ ({preventDefault: preventDefault} = CustomEvent.prototype);
190
+ CustomEvent.prototype.preventDefault = function() {
191
+ const result = preventDefault.call(this);
192
+ if (this.cancelable && !this.defaultPrevented) {
193
+ Object.defineProperty(this, "defaultPrevented", {
194
+ get() {
195
+ return true;
196
+ }
197
+ });
198
+ }
199
+ return result;
200
+ };
201
+ }
202
+ const fire = (obj, name, data) => {
203
+ const event = new CustomEvent(name, {
204
+ bubbles: true,
205
+ cancelable: true,
206
+ detail: data
207
+ });
208
+ obj.dispatchEvent(event);
209
+ return !event.defaultPrevented;
210
+ };
211
+ const stopEverything = e => {
212
+ fire(e.target, "ujs:everythingStopped");
213
+ e.preventDefault();
214
+ e.stopPropagation();
215
+ e.stopImmediatePropagation();
216
+ };
217
+ const delegate = (element, selector, eventType, handler) => element.addEventListener(eventType, (function(e) {
218
+ let {target: target} = e;
219
+ while (!!(target instanceof Element) && !matches(target, selector)) {
220
+ target = target.parentNode;
221
+ }
222
+ if (target instanceof Element && handler.call(target, e) === false) {
223
+ e.preventDefault();
224
+ e.stopPropagation();
225
+ }
226
+ }));
227
+ const toArray = e => Array.prototype.slice.call(e);
228
+ const serializeElement = (element, additionalParam) => {
229
+ let inputs = [ element ];
230
+ if (matches(element, "form")) {
231
+ inputs = toArray(element.elements);
232
+ }
233
+ const params = [];
234
+ inputs.forEach((function(input) {
235
+ if (!input.name || input.disabled) {
236
+ return;
237
+ }
238
+ if (matches(input, "fieldset[disabled] *")) {
239
+ return;
240
+ }
241
+ if (matches(input, "select")) {
242
+ toArray(input.options).forEach((function(option) {
243
+ if (option.selected) {
244
+ params.push({
245
+ name: input.name,
246
+ value: option.value
247
+ });
248
+ }
249
+ }));
250
+ } else if (input.checked || [ "radio", "checkbox", "submit" ].indexOf(input.type) === -1) {
251
+ params.push({
252
+ name: input.name,
253
+ value: input.value
254
+ });
255
+ }
256
+ }));
257
+ if (additionalParam) {
258
+ params.push(additionalParam);
259
+ }
260
+ return params.map((function(param) {
261
+ if (param.name) {
262
+ return `${encodeURIComponent(param.name)}=${encodeURIComponent(param.value)}`;
263
+ } else {
264
+ return param;
265
+ }
266
+ })).join("&");
267
+ };
268
+ const formElements = (form, selector) => {
269
+ if (matches(form, "form")) {
270
+ return toArray(form.elements).filter((el => matches(el, selector)));
271
+ } else {
272
+ return toArray(form.querySelectorAll(selector));
273
+ }
274
+ };
275
+ const handleConfirmWithRails = rails => function(e) {
276
+ if (!allowAction(this, rails)) {
277
+ stopEverything(e);
278
+ }
279
+ };
280
+ const confirm = (message, element) => window.confirm(message);
281
+ var allowAction = function(element, rails) {
282
+ let callback;
283
+ const message = element.getAttribute("data-confirm");
284
+ if (!message) {
285
+ return true;
286
+ }
287
+ let answer = false;
288
+ if (fire(element, "confirm")) {
289
+ try {
290
+ answer = rails.confirm(message, element);
291
+ } catch (error) {}
292
+ callback = fire(element, "confirm:complete", [ answer ]);
293
+ }
294
+ return answer && callback;
295
+ };
296
+ const handleDisabledElement = function(e) {
297
+ const element = this;
298
+ if (element.disabled) {
299
+ stopEverything(e);
300
+ }
301
+ };
302
+ const enableElement = e => {
303
+ let element;
304
+ if (e instanceof Event) {
305
+ if (isXhrRedirect(e)) {
306
+ return;
307
+ }
308
+ element = e.target;
309
+ } else {
310
+ element = e;
311
+ }
312
+ if (isContentEditable(element)) {
313
+ return;
314
+ }
315
+ if (matches(element, linkDisableSelector)) {
316
+ return enableLinkElement(element);
317
+ } else if (matches(element, buttonDisableSelector) || matches(element, formEnableSelector)) {
318
+ return enableFormElement(element);
319
+ } else if (matches(element, formSubmitSelector)) {
320
+ return enableFormElements(element);
321
+ }
322
+ };
323
+ const disableElement = e => {
324
+ const element = e instanceof Event ? e.target : e;
325
+ if (isContentEditable(element)) {
326
+ return;
327
+ }
328
+ if (matches(element, linkDisableSelector)) {
329
+ return disableLinkElement(element);
330
+ } else if (matches(element, buttonDisableSelector) || matches(element, formDisableSelector)) {
331
+ return disableFormElement(element);
332
+ } else if (matches(element, formSubmitSelector)) {
333
+ return disableFormElements(element);
334
+ }
335
+ };
336
+ var disableLinkElement = function(element) {
337
+ if (getData(element, "ujs:disabled")) {
338
+ return;
339
+ }
340
+ const replacement = element.getAttribute("data-disable-with");
341
+ if (replacement != null) {
342
+ setData(element, "ujs:enable-with", element.innerHTML);
343
+ element.innerHTML = replacement;
344
+ }
345
+ element.addEventListener("click", stopEverything);
346
+ return setData(element, "ujs:disabled", true);
347
+ };
348
+ var enableLinkElement = function(element) {
349
+ const originalText = getData(element, "ujs:enable-with");
350
+ if (originalText != null) {
351
+ element.innerHTML = originalText;
352
+ setData(element, "ujs:enable-with", null);
353
+ }
354
+ element.removeEventListener("click", stopEverything);
355
+ return setData(element, "ujs:disabled", null);
356
+ };
357
+ var disableFormElements = form => formElements(form, formDisableSelector).forEach(disableFormElement);
358
+ var disableFormElement = function(element) {
359
+ if (getData(element, "ujs:disabled")) {
360
+ return;
361
+ }
362
+ const replacement = element.getAttribute("data-disable-with");
363
+ if (replacement != null) {
364
+ if (matches(element, "button")) {
365
+ setData(element, "ujs:enable-with", element.innerHTML);
366
+ element.innerHTML = replacement;
367
+ } else {
368
+ setData(element, "ujs:enable-with", element.value);
369
+ element.value = replacement;
370
+ }
371
+ }
372
+ element.disabled = true;
373
+ return setData(element, "ujs:disabled", true);
374
+ };
375
+ var enableFormElements = form => formElements(form, formEnableSelector).forEach((element => enableFormElement(element)));
376
+ var enableFormElement = function(element) {
377
+ const originalText = getData(element, "ujs:enable-with");
378
+ if (originalText != null) {
379
+ if (matches(element, "button")) {
380
+ element.innerHTML = originalText;
381
+ } else {
382
+ element.value = originalText;
383
+ }
384
+ setData(element, "ujs:enable-with", null);
385
+ }
386
+ element.disabled = false;
387
+ return setData(element, "ujs:disabled", null);
388
+ };
389
+ var isXhrRedirect = function(event) {
390
+ const xhr = event.detail ? event.detail[0] : undefined;
391
+ return xhr && xhr.getResponseHeader("X-Xhr-Redirect");
392
+ };
393
+ const handleMethodWithRails = rails => function(e) {
394
+ const link = this;
395
+ const method = link.getAttribute("data-method");
396
+ if (!method) {
397
+ return;
398
+ }
399
+ if (isContentEditable(this)) {
400
+ return;
401
+ }
402
+ const href = rails.href(link);
403
+ const csrfToken$1 = csrfToken();
404
+ const csrfParam$1 = csrfParam();
405
+ const form = document.createElement("form");
406
+ let formContent = `<input name='_method' value='${method}' type='hidden' />`;
407
+ if (csrfParam$1 && csrfToken$1 && !isCrossDomain(href)) {
408
+ formContent += `<input name='${csrfParam$1}' value='${csrfToken$1}' type='hidden' />`;
409
+ }
410
+ formContent += '<input type="submit" />';
411
+ form.method = "post";
412
+ form.action = href;
413
+ form.target = link.target;
414
+ form.innerHTML = formContent;
415
+ form.style.display = "none";
416
+ document.body.appendChild(form);
417
+ form.querySelector('[type="submit"]').click();
418
+ stopEverything(e);
419
+ };
420
+ const isRemote = function(element) {
421
+ const value = element.getAttribute("data-remote");
422
+ return value != null && value !== "false";
423
+ };
424
+ const handleRemoteWithRails = rails => function(e) {
425
+ let data, method, url;
426
+ const element = this;
427
+ if (!isRemote(element)) {
428
+ return true;
429
+ }
430
+ if (!fire(element, "ajax:before")) {
431
+ fire(element, "ajax:stopped");
432
+ return false;
433
+ }
434
+ if (isContentEditable(element)) {
435
+ fire(element, "ajax:stopped");
436
+ return false;
437
+ }
438
+ const withCredentials = element.getAttribute("data-with-credentials");
439
+ const dataType = element.getAttribute("data-type") || "script";
440
+ if (matches(element, formSubmitSelector)) {
441
+ const button = getData(element, "ujs:submit-button");
442
+ method = getData(element, "ujs:submit-button-formmethod") || element.getAttribute("method") || "get";
443
+ url = getData(element, "ujs:submit-button-formaction") || element.getAttribute("action") || location.href;
444
+ if (method.toUpperCase() === "GET") {
445
+ url = url.replace(/\?.*$/, "");
446
+ }
447
+ if (element.enctype === "multipart/form-data") {
448
+ data = new FormData(element);
449
+ if (button != null) {
450
+ data.append(button.name, button.value);
451
+ }
452
+ } else {
453
+ data = serializeElement(element, button);
454
+ }
455
+ setData(element, "ujs:submit-button", null);
456
+ setData(element, "ujs:submit-button-formmethod", null);
457
+ setData(element, "ujs:submit-button-formaction", null);
458
+ } else if (matches(element, buttonClickSelector) || matches(element, inputChangeSelector)) {
459
+ method = element.getAttribute("data-method");
460
+ url = element.getAttribute("data-url");
461
+ data = serializeElement(element, element.getAttribute("data-params"));
462
+ } else {
463
+ method = element.getAttribute("data-method");
464
+ url = rails.href(element);
465
+ data = element.getAttribute("data-params");
466
+ }
467
+ ajax({
468
+ type: method || "GET",
469
+ url: url,
470
+ data: data,
471
+ dataType: dataType,
472
+ beforeSend(xhr, options) {
473
+ if (fire(element, "ajax:beforeSend", [ xhr, options ])) {
474
+ return fire(element, "ajax:send", [ xhr ]);
475
+ } else {
476
+ fire(element, "ajax:stopped");
477
+ return false;
478
+ }
479
+ },
480
+ success(...args) {
481
+ return fire(element, "ajax:success", args);
482
+ },
483
+ error(...args) {
484
+ return fire(element, "ajax:error", args);
485
+ },
486
+ complete(...args) {
487
+ return fire(element, "ajax:complete", args);
488
+ },
489
+ crossDomain: isCrossDomain(url),
490
+ withCredentials: withCredentials != null && withCredentials !== "false"
491
+ });
492
+ stopEverything(e);
493
+ };
494
+ const formSubmitButtonClick = function(e) {
495
+ const button = this;
496
+ const {form: form} = button;
497
+ if (!form) {
498
+ return;
499
+ }
500
+ if (button.name) {
501
+ setData(form, "ujs:submit-button", {
502
+ name: button.name,
503
+ value: button.value
504
+ });
505
+ }
506
+ setData(form, "ujs:formnovalidate-button", button.formNoValidate);
507
+ setData(form, "ujs:submit-button-formaction", button.getAttribute("formaction"));
508
+ return setData(form, "ujs:submit-button-formmethod", button.getAttribute("formmethod"));
509
+ };
510
+ const preventInsignificantClick = function(e) {
511
+ const link = this;
512
+ const method = (link.getAttribute("data-method") || "GET").toUpperCase();
513
+ const data = link.getAttribute("data-params");
514
+ const metaClick = e.metaKey || e.ctrlKey;
515
+ const insignificantMetaClick = metaClick && method === "GET" && !data;
516
+ const nonPrimaryMouseClick = e.button != null && e.button !== 0;
517
+ if (nonPrimaryMouseClick || insignificantMetaClick) {
518
+ e.stopImmediatePropagation();
519
+ }
520
+ };
521
+ const Rails = {
522
+ $: $,
523
+ ajax: ajax,
524
+ buttonClickSelector: buttonClickSelector,
525
+ buttonDisableSelector: buttonDisableSelector,
526
+ confirm: confirm,
527
+ cspNonce: cspNonce,
528
+ csrfToken: csrfToken,
529
+ csrfParam: csrfParam,
530
+ CSRFProtection: CSRFProtection,
531
+ delegate: delegate,
532
+ disableElement: disableElement,
533
+ enableElement: enableElement,
534
+ fileInputSelector: fileInputSelector,
535
+ fire: fire,
536
+ formElements: formElements,
537
+ formEnableSelector: formEnableSelector,
538
+ formDisableSelector: formDisableSelector,
539
+ formInputClickSelector: formInputClickSelector,
540
+ formSubmitButtonClick: formSubmitButtonClick,
541
+ formSubmitSelector: formSubmitSelector,
542
+ getData: getData,
543
+ handleDisabledElement: handleDisabledElement,
544
+ href: href,
545
+ inputChangeSelector: inputChangeSelector,
546
+ isCrossDomain: isCrossDomain,
547
+ linkClickSelector: linkClickSelector,
548
+ linkDisableSelector: linkDisableSelector,
549
+ loadCSPNonce: loadCSPNonce,
550
+ matches: matches,
551
+ preventInsignificantClick: preventInsignificantClick,
552
+ refreshCSRFTokens: refreshCSRFTokens,
553
+ serializeElement: serializeElement,
554
+ setData: setData,
555
+ stopEverything: stopEverything
556
+ };
557
+ const handleConfirm = handleConfirmWithRails(Rails);
558
+ Rails.handleConfirm = handleConfirm;
559
+ const handleMethod = handleMethodWithRails(Rails);
560
+ Rails.handleMethod = handleMethod;
561
+ const handleRemote = handleRemoteWithRails(Rails);
562
+ Rails.handleRemote = handleRemote;
563
+ const start = function() {
564
+ if (window._rails_loaded) {
565
+ throw new Error("rails-ujs has already been loaded!");
566
+ }
567
+ window.addEventListener("pageshow", (function() {
568
+ $(formEnableSelector).forEach((function(el) {
569
+ if (getData(el, "ujs:disabled")) {
570
+ enableElement(el);
571
+ }
572
+ }));
573
+ $(linkDisableSelector).forEach((function(el) {
574
+ if (getData(el, "ujs:disabled")) {
575
+ enableElement(el);
576
+ }
577
+ }));
578
+ }));
579
+ delegate(document, linkDisableSelector, "ajax:complete", enableElement);
580
+ delegate(document, linkDisableSelector, "ajax:stopped", enableElement);
581
+ delegate(document, buttonDisableSelector, "ajax:complete", enableElement);
582
+ delegate(document, buttonDisableSelector, "ajax:stopped", enableElement);
583
+ delegate(document, linkClickSelector, "click", preventInsignificantClick);
584
+ delegate(document, linkClickSelector, "click", handleDisabledElement);
585
+ delegate(document, linkClickSelector, "click", handleConfirm);
586
+ delegate(document, linkClickSelector, "click", disableElement);
587
+ delegate(document, linkClickSelector, "click", handleRemote);
588
+ delegate(document, linkClickSelector, "click", handleMethod);
589
+ delegate(document, buttonClickSelector, "click", preventInsignificantClick);
590
+ delegate(document, buttonClickSelector, "click", handleDisabledElement);
591
+ delegate(document, buttonClickSelector, "click", handleConfirm);
592
+ delegate(document, buttonClickSelector, "click", disableElement);
593
+ delegate(document, buttonClickSelector, "click", handleRemote);
594
+ delegate(document, inputChangeSelector, "change", handleDisabledElement);
595
+ delegate(document, inputChangeSelector, "change", handleConfirm);
596
+ delegate(document, inputChangeSelector, "change", handleRemote);
597
+ delegate(document, formSubmitSelector, "submit", handleDisabledElement);
598
+ delegate(document, formSubmitSelector, "submit", handleConfirm);
599
+ delegate(document, formSubmitSelector, "submit", handleRemote);
600
+ delegate(document, formSubmitSelector, "submit", (e => setTimeout((() => disableElement(e)), 13)));
601
+ delegate(document, formSubmitSelector, "ajax:send", disableElement);
602
+ delegate(document, formSubmitSelector, "ajax:complete", enableElement);
603
+ delegate(document, formInputClickSelector, "click", preventInsignificantClick);
604
+ delegate(document, formInputClickSelector, "click", handleDisabledElement);
605
+ delegate(document, formInputClickSelector, "click", handleConfirm);
606
+ delegate(document, formInputClickSelector, "click", formSubmitButtonClick);
607
+ document.addEventListener("DOMContentLoaded", refreshCSRFTokens);
608
+ document.addEventListener("DOMContentLoaded", loadCSPNonce);
609
+ return window._rails_loaded = true;
610
+ };
611
+ Rails.start = start;
612
+ if (typeof jQuery !== "undefined" && jQuery && jQuery.ajax) {
613
+ if (jQuery.rails) {
614
+ throw new Error("If you load both jquery_ujs and rails-ujs, use rails-ujs only.");
615
+ }
616
+ jQuery.rails = Rails;
617
+ jQuery.ajaxPrefilter((function(options, originalOptions, xhr) {
618
+ if (!options.crossDomain) {
619
+ return CSRFProtection(xhr);
620
+ }
621
+ }));
622
+ }
623
+ if (typeof exports !== "object" && typeof module === "undefined") {
624
+ window.Rails = Rails;
625
+ if (fire(document, "rails:attachBindings")) {
626
+ start();
627
+ }
628
+ }
629
+ return Rails;
630
+ }));