actionview 7.0.8.7 → 7.1.5.1

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +309 -321
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/app/assets/javascripts/rails-ujs.esm.js +686 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +34 -14
  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 +4 -4
  14. data/lib/action_view/helpers/active_model_helper.rb +1 -1
  15. data/lib/action_view/helpers/asset_tag_helper.rb +136 -52
  16. data/lib/action_view/helpers/asset_url_helper.rb +6 -5
  17. data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
  18. data/lib/action_view/helpers/cache_helper.rb +7 -13
  19. data/lib/action_view/helpers/capture_helper.rb +30 -10
  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 +2 -2
  24. data/lib/action_view/helpers/date_helper.rb +17 -19
  25. data/lib/action_view/helpers/debug_helper.rb +3 -3
  26. data/lib/action_view/helpers/form_helper.rb +54 -25
  27. data/lib/action_view/helpers/form_options_helper.rb +2 -1
  28. data/lib/action_view/helpers/form_tag_helper.rb +49 -15
  29. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  30. data/lib/action_view/helpers/number_helper.rb +37 -330
  31. data/lib/action_view/helpers/output_safety_helper.rb +2 -2
  32. data/lib/action_view/helpers/rendering_helper.rb +1 -1
  33. data/lib/action_view/helpers/sanitize_helper.rb +51 -21
  34. data/lib/action_view/helpers/tag_helper.rb +5 -27
  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 +3 -0
  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 +156 -84
  53. data/lib/action_view/helpers/translation_helper.rb +3 -3
  54. data/lib/action_view/helpers/url_helper.rb +46 -17
  55. data/lib/action_view/helpers.rb +2 -0
  56. data/lib/action_view/layouts.rb +8 -6
  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 +15 -8
  63. data/lib/action_view/renderer/abstract_renderer.rb +1 -1
  64. data/lib/action_view/renderer/collection_renderer.rb +10 -2
  65. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +2 -1
  66. data/lib/action_view/renderer/partial_renderer.rb +2 -1
  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 +22 -4
  71. data/lib/action_view/ripper_ast_parser.rb +5 -5
  72. data/lib/action_view/template/error.rb +14 -1
  73. data/lib/action_view/template/handlers/builder.rb +4 -4
  74. data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
  75. data/lib/action_view/template/handlers/erb.rb +73 -1
  76. data/lib/action_view/template/handlers.rb +1 -1
  77. data/lib/action_view/template/html.rb +1 -1
  78. data/lib/action_view/template/raw_file.rb +1 -1
  79. data/lib/action_view/template/renderable.rb +1 -1
  80. data/lib/action_view/template/resolver.rb +10 -2
  81. data/lib/action_view/template/text.rb +1 -1
  82. data/lib/action_view/template/types.rb +25 -34
  83. data/lib/action_view/template.rb +249 -54
  84. data/lib/action_view/template_path.rb +2 -0
  85. data/lib/action_view/test_case.rb +176 -21
  86. data/lib/action_view/unbound_template.rb +17 -7
  87. data/lib/action_view/version.rb +1 -1
  88. data/lib/action_view/view_paths.rb +15 -24
  89. data/lib/action_view.rb +4 -1
  90. metadata +22 -23
  91. data/lib/assets/compiled/rails-ujs.js +0 -777
@@ -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
+ }));