summaryrefslogtreecommitdiff
path: root/public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-06-26 13:40:55 +0200
committererdgeist <erdgeist@erdgeist.org>2026-06-26 13:40:55 +0200
commit811bb04649365b0faaa00b1e0810bb101a4d19b1 (patch)
tree581d52faa6e1bf21a1cdfd4da7127a0f95786bad /public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js
parenta1ddc25da0d2aa79a4d9216ef7792f26233bd38e (diff)
Stage 5 click-testing fixes
- Fix link_to :method → button_to for all PUT/DELETE actions - Add button_to CSS reset to admin.css for visual consistency - Fix admin layout: replace broken jquery/jquery_ujs pipeline refs with admin_bundle via sprockets; add sprockets-rails, jquery-ui-rails gems - Add app/assets/javascripts/admin_bundle.js pipeline manifest - Fix event_information helper: use safe_join to avoid double-escaping - Fix nodes_helper: to_s(:db) → to_fs(:db) for event times - Fix revisions view: eliminate nested forms; diff button uses vanilla JS to collect radio button values before POST - Fix config/environments/development.rb and test.rb: cache_classes → enable_reloading - Add routing_filter_rails71_patch.rb version guard - Move LockedByAnotherUser to own file for Zeitwerk autoloading - Fix Globalize fallbacks via config.i18n.fallbacks in application.rb
Diffstat (limited to 'public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js')
-rw-r--r--public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js862
1 files changed, 862 insertions, 0 deletions
diff --git a/public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js b/public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js
new file mode 100644
index 00000000..ef283f27
--- /dev/null
+++ b/public/assets/actiontext-338257afa53cc53f94018abf7a897120d1eb3ee71f39e4641b2058442c9c4dc6.js
@@ -0,0 +1,862 @@
1(function(factory) {
2 typeof define === "function" && define.amd ? define(factory) : factory();
3})((function() {
4 "use strict";
5 var sparkMd5 = {
6 exports: {}
7 };
8 (function(module, exports) {
9 (function(factory) {
10 {
11 module.exports = factory();
12 }
13 })((function(undefined$1) {
14 var hex_chr = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ];
15 function md5cycle(x, k) {
16 var a = x[0], b = x[1], c = x[2], d = x[3];
17 a += (b & c | ~b & d) + k[0] - 680876936 | 0;
18 a = (a << 7 | a >>> 25) + b | 0;
19 d += (a & b | ~a & c) + k[1] - 389564586 | 0;
20 d = (d << 12 | d >>> 20) + a | 0;
21 c += (d & a | ~d & b) + k[2] + 606105819 | 0;
22 c = (c << 17 | c >>> 15) + d | 0;
23 b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
24 b = (b << 22 | b >>> 10) + c | 0;
25 a += (b & c | ~b & d) + k[4] - 176418897 | 0;
26 a = (a << 7 | a >>> 25) + b | 0;
27 d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
28 d = (d << 12 | d >>> 20) + a | 0;
29 c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
30 c = (c << 17 | c >>> 15) + d | 0;
31 b += (c & d | ~c & a) + k[7] - 45705983 | 0;
32 b = (b << 22 | b >>> 10) + c | 0;
33 a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
34 a = (a << 7 | a >>> 25) + b | 0;
35 d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
36 d = (d << 12 | d >>> 20) + a | 0;
37 c += (d & a | ~d & b) + k[10] - 42063 | 0;
38 c = (c << 17 | c >>> 15) + d | 0;
39 b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
40 b = (b << 22 | b >>> 10) + c | 0;
41 a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
42 a = (a << 7 | a >>> 25) + b | 0;
43 d += (a & b | ~a & c) + k[13] - 40341101 | 0;
44 d = (d << 12 | d >>> 20) + a | 0;
45 c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
46 c = (c << 17 | c >>> 15) + d | 0;
47 b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
48 b = (b << 22 | b >>> 10) + c | 0;
49 a += (b & d | c & ~d) + k[1] - 165796510 | 0;
50 a = (a << 5 | a >>> 27) + b | 0;
51 d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
52 d = (d << 9 | d >>> 23) + a | 0;
53 c += (d & b | a & ~b) + k[11] + 643717713 | 0;
54 c = (c << 14 | c >>> 18) + d | 0;
55 b += (c & a | d & ~a) + k[0] - 373897302 | 0;
56 b = (b << 20 | b >>> 12) + c | 0;
57 a += (b & d | c & ~d) + k[5] - 701558691 | 0;
58 a = (a << 5 | a >>> 27) + b | 0;
59 d += (a & c | b & ~c) + k[10] + 38016083 | 0;
60 d = (d << 9 | d >>> 23) + a | 0;
61 c += (d & b | a & ~b) + k[15] - 660478335 | 0;
62 c = (c << 14 | c >>> 18) + d | 0;
63 b += (c & a | d & ~a) + k[4] - 405537848 | 0;
64 b = (b << 20 | b >>> 12) + c | 0;
65 a += (b & d | c & ~d) + k[9] + 568446438 | 0;
66 a = (a << 5 | a >>> 27) + b | 0;
67 d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
68 d = (d << 9 | d >>> 23) + a | 0;
69 c += (d & b | a & ~b) + k[3] - 187363961 | 0;
70 c = (c << 14 | c >>> 18) + d | 0;
71 b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
72 b = (b << 20 | b >>> 12) + c | 0;
73 a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
74 a = (a << 5 | a >>> 27) + b | 0;
75 d += (a & c | b & ~c) + k[2] - 51403784 | 0;
76 d = (d << 9 | d >>> 23) + a | 0;
77 c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
78 c = (c << 14 | c >>> 18) + d | 0;
79 b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
80 b = (b << 20 | b >>> 12) + c | 0;
81 a += (b ^ c ^ d) + k[5] - 378558 | 0;
82 a = (a << 4 | a >>> 28) + b | 0;
83 d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
84 d = (d << 11 | d >>> 21) + a | 0;
85 c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
86 c = (c << 16 | c >>> 16) + d | 0;
87 b += (c ^ d ^ a) + k[14] - 35309556 | 0;
88 b = (b << 23 | b >>> 9) + c | 0;
89 a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
90 a = (a << 4 | a >>> 28) + b | 0;
91 d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
92 d = (d << 11 | d >>> 21) + a | 0;
93 c += (d ^ a ^ b) + k[7] - 155497632 | 0;
94 c = (c << 16 | c >>> 16) + d | 0;
95 b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
96 b = (b << 23 | b >>> 9) + c | 0;
97 a += (b ^ c ^ d) + k[13] + 681279174 | 0;
98 a = (a << 4 | a >>> 28) + b | 0;
99 d += (a ^ b ^ c) + k[0] - 358537222 | 0;
100 d = (d << 11 | d >>> 21) + a | 0;
101 c += (d ^ a ^ b) + k[3] - 722521979 | 0;
102 c = (c << 16 | c >>> 16) + d | 0;
103 b += (c ^ d ^ a) + k[6] + 76029189 | 0;
104 b = (b << 23 | b >>> 9) + c | 0;
105 a += (b ^ c ^ d) + k[9] - 640364487 | 0;
106 a = (a << 4 | a >>> 28) + b | 0;
107 d += (a ^ b ^ c) + k[12] - 421815835 | 0;
108 d = (d << 11 | d >>> 21) + a | 0;
109 c += (d ^ a ^ b) + k[15] + 530742520 | 0;
110 c = (c << 16 | c >>> 16) + d | 0;
111 b += (c ^ d ^ a) + k[2] - 995338651 | 0;
112 b = (b << 23 | b >>> 9) + c | 0;
113 a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
114 a = (a << 6 | a >>> 26) + b | 0;
115 d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
116 d = (d << 10 | d >>> 22) + a | 0;
117 c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
118 c = (c << 15 | c >>> 17) + d | 0;
119 b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
120 b = (b << 21 | b >>> 11) + c | 0;
121 a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
122 a = (a << 6 | a >>> 26) + b | 0;
123 d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
124 d = (d << 10 | d >>> 22) + a | 0;
125 c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
126 c = (c << 15 | c >>> 17) + d | 0;
127 b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
128 b = (b << 21 | b >>> 11) + c | 0;
129 a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
130 a = (a << 6 | a >>> 26) + b | 0;
131 d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
132 d = (d << 10 | d >>> 22) + a | 0;
133 c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
134 c = (c << 15 | c >>> 17) + d | 0;
135 b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
136 b = (b << 21 | b >>> 11) + c | 0;
137 a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
138 a = (a << 6 | a >>> 26) + b | 0;
139 d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
140 d = (d << 10 | d >>> 22) + a | 0;
141 c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
142 c = (c << 15 | c >>> 17) + d | 0;
143 b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
144 b = (b << 21 | b >>> 11) + c | 0;
145 x[0] = a + x[0] | 0;
146 x[1] = b + x[1] | 0;
147 x[2] = c + x[2] | 0;
148 x[3] = d + x[3] | 0;
149 }
150 function md5blk(s) {
151 var md5blks = [], i;
152 for (i = 0; i < 64; i += 4) {
153 md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
154 }
155 return md5blks;
156 }
157 function md5blk_array(a) {
158 var md5blks = [], i;
159 for (i = 0; i < 64; i += 4) {
160 md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
161 }
162 return md5blks;
163 }
164 function md51(s) {
165 var n = s.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi;
166 for (i = 64; i <= n; i += 64) {
167 md5cycle(state, md5blk(s.substring(i - 64, i)));
168 }
169 s = s.substring(i - 64);
170 length = s.length;
171 tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
172 for (i = 0; i < length; i += 1) {
173 tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
174 }
175 tail[i >> 2] |= 128 << (i % 4 << 3);
176 if (i > 55) {
177 md5cycle(state, tail);
178 for (i = 0; i < 16; i += 1) {
179 tail[i] = 0;
180 }
181 }
182 tmp = n * 8;
183 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
184 lo = parseInt(tmp[2], 16);
185 hi = parseInt(tmp[1], 16) || 0;
186 tail[14] = lo;
187 tail[15] = hi;
188 md5cycle(state, tail);
189 return state;
190 }
191 function md51_array(a) {
192 var n = a.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi;
193 for (i = 64; i <= n; i += 64) {
194 md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
195 }
196 a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);
197 length = a.length;
198 tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
199 for (i = 0; i < length; i += 1) {
200 tail[i >> 2] |= a[i] << (i % 4 << 3);
201 }
202 tail[i >> 2] |= 128 << (i % 4 << 3);
203 if (i > 55) {
204 md5cycle(state, tail);
205 for (i = 0; i < 16; i += 1) {
206 tail[i] = 0;
207 }
208 }
209 tmp = n * 8;
210 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
211 lo = parseInt(tmp[2], 16);
212 hi = parseInt(tmp[1], 16) || 0;
213 tail[14] = lo;
214 tail[15] = hi;
215 md5cycle(state, tail);
216 return state;
217 }
218 function rhex(n) {
219 var s = "", j;
220 for (j = 0; j < 4; j += 1) {
221 s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
222 }
223 return s;
224 }
225 function hex(x) {
226 var i;
227 for (i = 0; i < x.length; i += 1) {
228 x[i] = rhex(x[i]);
229 }
230 return x.join("");
231 }
232 if (hex(md51("hello")) !== "5d41402abc4b2a76b9719d911017c592") ;
233 if (typeof ArrayBuffer !== "undefined" && !ArrayBuffer.prototype.slice) {
234 (function() {
235 function clamp(val, length) {
236 val = val | 0 || 0;
237 if (val < 0) {
238 return Math.max(val + length, 0);
239 }
240 return Math.min(val, length);
241 }
242 ArrayBuffer.prototype.slice = function(from, to) {
243 var length = this.byteLength, begin = clamp(from, length), end = length, num, target, targetArray, sourceArray;
244 if (to !== undefined$1) {
245 end = clamp(to, length);
246 }
247 if (begin > end) {
248 return new ArrayBuffer(0);
249 }
250 num = end - begin;
251 target = new ArrayBuffer(num);
252 targetArray = new Uint8Array(target);
253 sourceArray = new Uint8Array(this, begin, num);
254 targetArray.set(sourceArray);
255 return target;
256 };
257 })();
258 }
259 function toUtf8(str) {
260 if (/[\u0080-\uFFFF]/.test(str)) {
261 str = unescape(encodeURIComponent(str));
262 }
263 return str;
264 }
265 function utf8Str2ArrayBuffer(str, returnUInt8Array) {
266 var length = str.length, buff = new ArrayBuffer(length), arr = new Uint8Array(buff), i;
267 for (i = 0; i < length; i += 1) {
268 arr[i] = str.charCodeAt(i);
269 }
270 return returnUInt8Array ? arr : buff;
271 }
272 function arrayBuffer2Utf8Str(buff) {
273 return String.fromCharCode.apply(null, new Uint8Array(buff));
274 }
275 function concatenateArrayBuffers(first, second, returnUInt8Array) {
276 var result = new Uint8Array(first.byteLength + second.byteLength);
277 result.set(new Uint8Array(first));
278 result.set(new Uint8Array(second), first.byteLength);
279 return returnUInt8Array ? result : result.buffer;
280 }
281 function hexToBinaryString(hex) {
282 var bytes = [], length = hex.length, x;
283 for (x = 0; x < length - 1; x += 2) {
284 bytes.push(parseInt(hex.substr(x, 2), 16));
285 }
286 return String.fromCharCode.apply(String, bytes);
287 }
288 function SparkMD5() {
289 this.reset();
290 }
291 SparkMD5.prototype.append = function(str) {
292 this.appendBinary(toUtf8(str));
293 return this;
294 };
295 SparkMD5.prototype.appendBinary = function(contents) {
296 this._buff += contents;
297 this._length += contents.length;
298 var length = this._buff.length, i;
299 for (i = 64; i <= length; i += 64) {
300 md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
301 }
302 this._buff = this._buff.substring(i - 64);
303 return this;
304 };
305 SparkMD5.prototype.end = function(raw) {
306 var buff = this._buff, length = buff.length, i, tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], ret;
307 for (i = 0; i < length; i += 1) {
308 tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3);
309 }
310 this._finish(tail, length);
311 ret = hex(this._hash);
312 if (raw) {
313 ret = hexToBinaryString(ret);
314 }
315 this.reset();
316 return ret;
317 };
318 SparkMD5.prototype.reset = function() {
319 this._buff = "";
320 this._length = 0;
321 this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ];
322 return this;
323 };
324 SparkMD5.prototype.getState = function() {
325 return {
326 buff: this._buff,
327 length: this._length,
328 hash: this._hash.slice()
329 };
330 };
331 SparkMD5.prototype.setState = function(state) {
332 this._buff = state.buff;
333 this._length = state.length;
334 this._hash = state.hash;
335 return this;
336 };
337 SparkMD5.prototype.destroy = function() {
338 delete this._hash;
339 delete this._buff;
340 delete this._length;
341 };
342 SparkMD5.prototype._finish = function(tail, length) {
343 var i = length, tmp, lo, hi;
344 tail[i >> 2] |= 128 << (i % 4 << 3);
345 if (i > 55) {
346 md5cycle(this._hash, tail);
347 for (i = 0; i < 16; i += 1) {
348 tail[i] = 0;
349 }
350 }
351 tmp = this._length * 8;
352 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
353 lo = parseInt(tmp[2], 16);
354 hi = parseInt(tmp[1], 16) || 0;
355 tail[14] = lo;
356 tail[15] = hi;
357 md5cycle(this._hash, tail);
358 };
359 SparkMD5.hash = function(str, raw) {
360 return SparkMD5.hashBinary(toUtf8(str), raw);
361 };
362 SparkMD5.hashBinary = function(content, raw) {
363 var hash = md51(content), ret = hex(hash);
364 return raw ? hexToBinaryString(ret) : ret;
365 };
366 SparkMD5.ArrayBuffer = function() {
367 this.reset();
368 };
369 SparkMD5.ArrayBuffer.prototype.append = function(arr) {
370 var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), length = buff.length, i;
371 this._length += arr.byteLength;
372 for (i = 64; i <= length; i += 64) {
373 md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
374 }
375 this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
376 return this;
377 };
378 SparkMD5.ArrayBuffer.prototype.end = function(raw) {
379 var buff = this._buff, length = buff.length, tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], i, ret;
380 for (i = 0; i < length; i += 1) {
381 tail[i >> 2] |= buff[i] << (i % 4 << 3);
382 }
383 this._finish(tail, length);
384 ret = hex(this._hash);
385 if (raw) {
386 ret = hexToBinaryString(ret);
387 }
388 this.reset();
389 return ret;
390 };
391 SparkMD5.ArrayBuffer.prototype.reset = function() {
392 this._buff = new Uint8Array(0);
393 this._length = 0;
394 this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ];
395 return this;
396 };
397 SparkMD5.ArrayBuffer.prototype.getState = function() {
398 var state = SparkMD5.prototype.getState.call(this);
399 state.buff = arrayBuffer2Utf8Str(state.buff);
400 return state;
401 };
402 SparkMD5.ArrayBuffer.prototype.setState = function(state) {
403 state.buff = utf8Str2ArrayBuffer(state.buff, true);
404 return SparkMD5.prototype.setState.call(this, state);
405 };
406 SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
407 SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
408 SparkMD5.ArrayBuffer.hash = function(arr, raw) {
409 var hash = md51_array(new Uint8Array(arr)), ret = hex(hash);
410 return raw ? hexToBinaryString(ret) : ret;
411 };
412 return SparkMD5;
413 }));
414 })(sparkMd5);
415 var SparkMD5 = sparkMd5.exports;
416 const fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
417 class FileChecksum {
418 static create(file, callback) {
419 const instance = new FileChecksum(file);
420 instance.create(callback);
421 }
422 constructor(file) {
423 this.file = file;
424 this.chunkSize = 2097152;
425 this.chunkCount = Math.ceil(this.file.size / this.chunkSize);
426 this.chunkIndex = 0;
427 }
428 create(callback) {
429 this.callback = callback;
430 this.md5Buffer = new SparkMD5.ArrayBuffer;
431 this.fileReader = new FileReader;
432 this.fileReader.addEventListener("load", (event => this.fileReaderDidLoad(event)));
433 this.fileReader.addEventListener("error", (event => this.fileReaderDidError(event)));
434 this.readNextChunk();
435 }
436 fileReaderDidLoad(event) {
437 this.md5Buffer.append(event.target.result);
438 if (!this.readNextChunk()) {
439 const binaryDigest = this.md5Buffer.end(true);
440 const base64digest = btoa(binaryDigest);
441 this.callback(null, base64digest);
442 }
443 }
444 fileReaderDidError(event) {
445 this.callback(`Error reading ${this.file.name}`);
446 }
447 readNextChunk() {
448 if (this.chunkIndex < this.chunkCount || this.chunkIndex == 0 && this.chunkCount == 0) {
449 const start = this.chunkIndex * this.chunkSize;
450 const end = Math.min(start + this.chunkSize, this.file.size);
451 const bytes = fileSlice.call(this.file, start, end);
452 this.fileReader.readAsArrayBuffer(bytes);
453 this.chunkIndex++;
454 return true;
455 } else {
456 return false;
457 }
458 }
459 }
460 function getMetaValue(name) {
461 const element = findElement(document.head, `meta[name="${name}"]`);
462 if (element) {
463 return element.getAttribute("content");
464 }
465 }
466 function findElements(root, selector) {
467 if (typeof root == "string") {
468 selector = root;
469 root = document;
470 }
471 const elements = root.querySelectorAll(selector);
472 return toArray(elements);
473 }
474 function findElement(root, selector) {
475 if (typeof root == "string") {
476 selector = root;
477 root = document;
478 }
479 return root.querySelector(selector);
480 }
481 function dispatchEvent(element, type, eventInit = {}) {
482 const {disabled: disabled} = element;
483 const {bubbles: bubbles, cancelable: cancelable, detail: detail} = eventInit;
484 const event = document.createEvent("Event");
485 event.initEvent(type, bubbles || true, cancelable || true);
486 event.detail = detail || {};
487 try {
488 element.disabled = false;
489 element.dispatchEvent(event);
490 } finally {
491 element.disabled = disabled;
492 }
493 return event;
494 }
495 function toArray(value) {
496 if (Array.isArray(value)) {
497 return value;
498 } else if (Array.from) {
499 return Array.from(value);
500 } else {
501 return [].slice.call(value);
502 }
503 }
504 class BlobRecord {
505 constructor(file, checksum, url, customHeaders = {}) {
506 this.file = file;
507 this.attributes = {
508 filename: file.name,
509 content_type: file.type || "application/octet-stream",
510 byte_size: file.size,
511 checksum: checksum
512 };
513 this.xhr = new XMLHttpRequest;
514 this.xhr.open("POST", url, true);
515 this.xhr.responseType = "json";
516 this.xhr.setRequestHeader("Content-Type", "application/json");
517 this.xhr.setRequestHeader("Accept", "application/json");
518 this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
519 Object.keys(customHeaders).forEach((headerKey => {
520 this.xhr.setRequestHeader(headerKey, customHeaders[headerKey]);
521 }));
522 const csrfToken = getMetaValue("csrf-token");
523 if (csrfToken != undefined) {
524 this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
525 }
526 this.xhr.addEventListener("load", (event => this.requestDidLoad(event)));
527 this.xhr.addEventListener("error", (event => this.requestDidError(event)));
528 }
529 get status() {
530 return this.xhr.status;
531 }
532 get response() {
533 const {responseType: responseType, response: response} = this.xhr;
534 if (responseType == "json") {
535 return response;
536 } else {
537 return JSON.parse(response);
538 }
539 }
540 create(callback) {
541 this.callback = callback;
542 this.xhr.send(JSON.stringify({
543 blob: this.attributes
544 }));
545 }
546 requestDidLoad(event) {
547 if (this.status >= 200 && this.status < 300) {
548 const {response: response} = this;
549 const {direct_upload: direct_upload} = response;
550 delete response.direct_upload;
551 this.attributes = response;
552 this.directUploadData = direct_upload;
553 this.callback(null, this.toJSON());
554 } else {
555 this.requestDidError(event);
556 }
557 }
558 requestDidError(event) {
559 this.callback(`Error creating Blob for "${this.file.name}". Status: ${this.status}`);
560 }
561 toJSON() {
562 const result = {};
563 for (const key in this.attributes) {
564 result[key] = this.attributes[key];
565 }
566 return result;
567 }
568 }
569 class BlobUpload {
570 constructor(blob) {
571 this.blob = blob;
572 this.file = blob.file;
573 const {url: url, headers: headers} = blob.directUploadData;
574 this.xhr = new XMLHttpRequest;
575 this.xhr.open("PUT", url, true);
576 this.xhr.responseType = "text";
577 for (const key in headers) {
578 this.xhr.setRequestHeader(key, headers[key]);
579 }
580 this.xhr.addEventListener("load", (event => this.requestDidLoad(event)));
581 this.xhr.addEventListener("error", (event => this.requestDidError(event)));
582 }
583 create(callback) {
584 this.callback = callback;
585 this.xhr.send(this.file.slice());
586 }
587 requestDidLoad(event) {
588 const {status: status, response: response} = this.xhr;
589 if (status >= 200 && status < 300) {
590 this.callback(null, response);
591 } else {
592 this.requestDidError(event);
593 }
594 }
595 requestDidError(event) {
596 this.callback(`Error storing "${this.file.name}". Status: ${this.xhr.status}`);
597 }
598 }
599 let id = 0;
600 class DirectUpload {
601 constructor(file, url, delegate, customHeaders = {}) {
602 this.id = ++id;
603 this.file = file;
604 this.url = url;
605 this.delegate = delegate;
606 this.customHeaders = customHeaders;
607 }
608 create(callback) {
609 FileChecksum.create(this.file, ((error, checksum) => {
610 if (error) {
611 callback(error);
612 return;
613 }
614 const blob = new BlobRecord(this.file, checksum, this.url, this.customHeaders);
615 notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
616 blob.create((error => {
617 if (error) {
618 callback(error);
619 } else {
620 const upload = new BlobUpload(blob);
621 notify(this.delegate, "directUploadWillStoreFileWithXHR", upload.xhr);
622 upload.create((error => {
623 if (error) {
624 callback(error);
625 } else {
626 callback(null, blob.toJSON());
627 }
628 }));
629 }
630 }));
631 }));
632 }
633 }
634 function notify(object, methodName, ...messages) {
635 if (object && typeof object[methodName] == "function") {
636 return object[methodName](...messages);
637 }
638 }
639 class DirectUploadController {
640 constructor(input, file) {
641 this.input = input;
642 this.file = file;
643 this.directUpload = new DirectUpload(this.file, this.url, this);
644 this.dispatch("initialize");
645 }
646 start(callback) {
647 const hiddenInput = document.createElement("input");
648 hiddenInput.type = "hidden";
649 hiddenInput.name = this.input.name;
650 this.input.insertAdjacentElement("beforebegin", hiddenInput);
651 this.dispatch("start");
652 this.directUpload.create(((error, attributes) => {
653 if (error) {
654 hiddenInput.parentNode.removeChild(hiddenInput);
655 this.dispatchError(error);
656 } else {
657 hiddenInput.value = attributes.signed_id;
658 }
659 this.dispatch("end");
660 callback(error);
661 }));
662 }
663 uploadRequestDidProgress(event) {
664 const progress = event.loaded / event.total * 100;
665 if (progress) {
666 this.dispatch("progress", {
667 progress: progress
668 });
669 }
670 }
671 get url() {
672 return this.input.getAttribute("data-direct-upload-url");
673 }
674 dispatch(name, detail = {}) {
675 detail.file = this.file;
676 detail.id = this.directUpload.id;
677 return dispatchEvent(this.input, `direct-upload:${name}`, {
678 detail: detail
679 });
680 }
681 dispatchError(error) {
682 const event = this.dispatch("error", {
683 error: error
684 });
685 if (!event.defaultPrevented) {
686 alert(error);
687 }
688 }
689 directUploadWillCreateBlobWithXHR(xhr) {
690 this.dispatch("before-blob-request", {
691 xhr: xhr
692 });
693 }
694 directUploadWillStoreFileWithXHR(xhr) {
695 this.dispatch("before-storage-request", {
696 xhr: xhr
697 });
698 xhr.upload.addEventListener("progress", (event => this.uploadRequestDidProgress(event)));
699 }
700 }
701 const inputSelector = "input[type=file][data-direct-upload-url]:not([disabled])";
702 class DirectUploadsController {
703 constructor(form) {
704 this.form = form;
705 this.inputs = findElements(form, inputSelector).filter((input => input.files.length));
706 }
707 start(callback) {
708 const controllers = this.createDirectUploadControllers();
709 const startNextController = () => {
710 const controller = controllers.shift();
711 if (controller) {
712 controller.start((error => {
713 if (error) {
714 callback(error);
715 this.dispatch("end");
716 } else {
717 startNextController();
718 }
719 }));
720 } else {
721 callback();
722 this.dispatch("end");
723 }
724 };
725 this.dispatch("start");
726 startNextController();
727 }
728 createDirectUploadControllers() {
729 const controllers = [];
730 this.inputs.forEach((input => {
731 toArray(input.files).forEach((file => {
732 const controller = new DirectUploadController(input, file);
733 controllers.push(controller);
734 }));
735 }));
736 return controllers;
737 }
738 dispatch(name, detail = {}) {
739 return dispatchEvent(this.form, `direct-uploads:${name}`, {
740 detail: detail
741 });
742 }
743 }
744 const processingAttribute = "data-direct-uploads-processing";
745 const submitButtonsByForm = new WeakMap;
746 let started = false;
747 function start() {
748 if (!started) {
749 started = true;
750 document.addEventListener("click", didClick, true);
751 document.addEventListener("submit", didSubmitForm, true);
752 document.addEventListener("ajax:before", didSubmitRemoteElement);
753 }
754 }
755 function didClick(event) {
756 const button = event.target.closest("button, input");
757 if (button && button.type === "submit" && button.form) {
758 submitButtonsByForm.set(button.form, button);
759 }
760 }
761 function didSubmitForm(event) {
762 handleFormSubmissionEvent(event);
763 }
764 function didSubmitRemoteElement(event) {
765 if (event.target.tagName == "FORM") {
766 handleFormSubmissionEvent(event);
767 }
768 }
769 function handleFormSubmissionEvent(event) {
770 const form = event.target;
771 if (form.hasAttribute(processingAttribute)) {
772 event.preventDefault();
773 return;
774 }
775 const controller = new DirectUploadsController(form);
776 const {inputs: inputs} = controller;
777 if (inputs.length) {
778 event.preventDefault();
779 form.setAttribute(processingAttribute, "");
780 inputs.forEach(disable);
781 controller.start((error => {
782 form.removeAttribute(processingAttribute);
783 if (error) {
784 inputs.forEach(enable);
785 } else {
786 submitForm(form);
787 }
788 }));
789 }
790 }
791 function submitForm(form) {
792 let button = submitButtonsByForm.get(form) || findElement(form, "input[type=submit], button[type=submit]");
793 if (button) {
794 const {disabled: disabled} = button;
795 button.disabled = false;
796 button.focus();
797 button.click();
798 button.disabled = disabled;
799 } else {
800 button = document.createElement("input");
801 button.type = "submit";
802 button.style.display = "none";
803 form.appendChild(button);
804 button.click();
805 form.removeChild(button);
806 }
807 submitButtonsByForm.delete(form);
808 }
809 function disable(input) {
810 input.disabled = true;
811 }
812 function enable(input) {
813 input.disabled = false;
814 }
815 function autostart() {
816 if (window.ActiveStorage) {
817 start();
818 }
819 }
820 setTimeout(autostart, 1);
821 class AttachmentUpload {
822 constructor(attachment, element) {
823 this.attachment = attachment;
824 this.element = element;
825 this.directUpload = new DirectUpload(attachment.file, this.directUploadUrl, this);
826 }
827 start() {
828 this.directUpload.create(this.directUploadDidComplete.bind(this));
829 }
830 directUploadWillStoreFileWithXHR(xhr) {
831 xhr.upload.addEventListener("progress", (event => {
832 const progress = event.loaded / event.total * 100;
833 this.attachment.setUploadProgress(progress);
834 }));
835 }
836 directUploadDidComplete(error, attributes) {
837 if (error) {
838 throw new Error(`Direct upload failed: ${error}`);
839 }
840 this.attachment.setAttributes({
841 sgid: attributes.attachable_sgid,
842 url: this.createBlobUrl(attributes.signed_id, attributes.filename)
843 });
844 }
845 createBlobUrl(signedId, filename) {
846 return this.blobUrlTemplate.replace(":signed_id", signedId).replace(":filename", encodeURIComponent(filename));
847 }
848 get directUploadUrl() {
849 return this.element.dataset.directUploadUrl;
850 }
851 get blobUrlTemplate() {
852 return this.element.dataset.blobUrlTemplate;
853 }
854 }
855 addEventListener("trix-attachment-add", (event => {
856 const {attachment: attachment, target: target} = event;
857 if (attachment.file) {
858 const upload = new AttachmentUpload(attachment, target);
859 upload.start();
860 }
861 }));
862}));