actiontext 6.1.4.1 → 7.0.0.alpha1

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

Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -91
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +4 -0
  5. data/app/assets/javascripts/actiontext.js +880 -0
  6. data/app/assets/javascripts/trix.js +5278 -0
  7. data/app/assets/stylesheets/trix.css +375 -0
  8. data/app/helpers/action_text/content_helper.rb +17 -3
  9. data/app/helpers/action_text/tag_helper.rb +5 -7
  10. data/app/models/action_text/encrypted_rich_text.rb +9 -0
  11. data/app/models/action_text/record.rb +1 -1
  12. data/app/models/action_text/rich_text.rb +4 -0
  13. data/app/views/action_text/contents/_content.html.erb +1 -0
  14. data/app/views/layouts/action_text/contents/_content.html.erb +3 -0
  15. data/db/migrate/20180528164100_create_action_text_tables.rb +14 -2
  16. data/lib/action_text/attachable.rb +4 -0
  17. data/lib/action_text/attachment.rb +4 -4
  18. data/lib/action_text/attachment_gallery.rb +14 -9
  19. data/lib/action_text/attachments/caching.rb +1 -1
  20. data/lib/action_text/attachments/minification.rb +1 -1
  21. data/lib/action_text/attribute.rb +18 -2
  22. data/lib/action_text/content.rb +7 -3
  23. data/lib/action_text/encryption.rb +38 -0
  24. data/lib/action_text/engine.rb +14 -0
  25. data/lib/action_text/fixture_set.rb +49 -0
  26. data/lib/action_text/gem_version.rb +4 -4
  27. data/lib/action_text/rendering.rb +1 -1
  28. data/lib/action_text/trix_attachment.rb +3 -3
  29. data/lib/action_text.rb +1 -0
  30. data/lib/generators/action_text/install/install_generator.rb +28 -35
  31. data/lib/generators/action_text/install/templates/actiontext.css +35 -0
  32. data/package.json +13 -3
  33. metadata +28 -22
  34. data/app/views/action_text/content/_layout.html.erb +0 -3
  35. data/lib/generators/action_text/install/templates/actiontext.scss +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5a7fb2811d060b4183dbac7e78b0999227e42c63271b32088c5212769191149
4
- data.tar.gz: 90be4c6c08a2af75f9dba432e9039b283b4fb4ee44ac3e2d26d9005a9c19a15d
3
+ metadata.gz: 2f0735e66acca9916e461de2094203f923aab79749a70eb10de2d060d70f7784
4
+ data.tar.gz: e22fa48ba71858e0bd786690fe7521a99a8edde6194db6955cf1a477a3d7a0eb
5
5
  SHA512:
6
- metadata.gz: e531afe3c6ad50674d091e9a086c724ff0676db35e84c65ec4a5f25f7a59f85509374318f0d421a3a8ad27d5fc5f6f6aeafbbc9c20fd7dcc98105dfd35e276a7
7
- data.tar.gz: 8c011da2ae1784bb8b3b67ea8a210dcc0068de5aaf8516a1d1e5c990efc99646afb1e0368930a82139f5c484ee76f634eab3f09fae82188b5600ec1007f10b50
6
+ metadata.gz: 6b5ec0e335aa42817f62436ab55e5b5eba6616ccf7ba562f48dac68faf48af82536f843a3f4b5c6c1a85416aea937a455685bc65125b2c0ea0434a71506e0fc0
7
+ data.tar.gz: d15c8203e48105087852dd8f7dfdba4198cb6e62c9e50b053672ece3d0aafc9c45b127092d2c5c674181b50c8ab687640009d6683f3d4ae30c0bdc2bbc5c8af0
data/CHANGELOG.md CHANGED
@@ -1,106 +1,34 @@
1
- ## Rails 6.1.4.1 (August 19, 2021) ##
1
+ ## Rails 7.0.0.alpha1 (September 15, 2021) ##
2
2
 
3
- * No changes.
3
+ * Make the Action Text + Trix JavaScript and CSS available through the asset pipeline.
4
4
 
5
+ *DHH*
5
6
 
6
- ## Rails 6.1.4 (June 24, 2021) ##
7
+ * OpenSSL constants are now used for Digest computations.
7
8
 
8
- * Always render attachment partials as HTML with `:html` format inside trix editor.
9
+ *Dirkjan Bussink*
9
10
 
10
- *James Brooks*
11
-
12
-
13
- ## Rails 6.1.3.2 (May 05, 2021) ##
14
-
15
- * No changes.
16
-
17
-
18
- ## Rails 6.1.3.1 (March 26, 2021) ##
19
-
20
- * No changes.
21
-
22
-
23
- ## Rails 6.1.3 (February 17, 2021) ##
24
-
25
- * No changes.
26
-
27
-
28
- ## Rails 6.1.2.1 (February 10, 2021) ##
29
-
30
- * No changes.
31
-
32
-
33
- ## Rails 6.1.2 (February 09, 2021) ##
34
-
35
- * No changes.
36
-
37
-
38
- ## Rails 6.1.1 (January 07, 2021) ##
39
-
40
- * No changes.
41
-
42
-
43
- ## Rails 6.1.0 (December 09, 2020) ##
44
-
45
- * Declare `ActionText::FixtureSet.attachment` to generate an
46
- `<action-text-attachment sgid="..."></action-text-attachment>` element with
47
- a valid `sgid` attribute.
48
-
49
- ```ruby
50
- hello_world_review_content:
51
- record: hello_world (Review)
52
- name: content
53
- body: <p><%= ActionText::FixtureSet.attachment("messages", :hello_world) %> is great!</p>
54
- ```
55
-
56
- *Sean Doyle*
57
-
58
- * Locate `fill_in_rich_text_area` by `<label>` text
59
-
60
- In addition to searching for `<trix-editor>` elements with the appropriate
61
- `aria-label` attribute, also support locating elements that match the
62
- corresponding `<label>` element's text.
11
+ * Add support for passing `form:` option to `rich_text_area_tag` and
12
+ `rich_text_area` helpers to specify the `<input type="hidden" form="...">`
13
+ value.
63
14
 
64
15
  *Sean Doyle*
65
16
 
66
- * Be able to add a default value to `rich_text_area`.
67
-
68
- ```ruby
69
- form.rich_text_area :content, value: "<h1>Hello world</h1>"
70
- #=> <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Hello world</h1>">
71
- ```
72
-
73
- *Paulo Ancheta*
74
-
75
- * Add method to confirm rich text content existence by adding `?` after rich
76
- text attribute.
17
+ * Add `config.action_text.attachment_tag_name`, to specify the HTML tag that contains attachments.
77
18
 
78
- ```ruby
79
- message = Message.create!(body: "<h1>Funny times!</h1>")
80
- message.body? #=> true
81
- ```
19
+ *Mark VanLandingham*
82
20
 
83
- *Kyohei Toyoda*
21
+ * Expose how we render the HTML _surrounding_ rich text content as an
22
+ extensible `layouts/action_view/contents/_content.html.erb` template to
23
+ encourage user-land customizations, while retaining private API control over how
24
+ the rich text itself is rendered by `action_text/contents/_content.html.erb`
25
+ partial.
84
26
 
85
- * The `fill_in_rich_text_area` system test helper locates a Trix editor
86
- and fills it in with the given HTML.
87
-
88
- ```ruby
89
- # <trix-editor id="message_content" ...></trix-editor>
90
- fill_in_rich_text_area "message_content", with: "Hello <em>world!</em>"
91
-
92
- # <trix-editor placeholder="Your message here" ...></trix-editor>
93
- fill_in_rich_text_area "Your message here", with: "Hello <em>world!</em>"
94
-
95
- # <trix-editor aria-label="Message content" ...></trix-editor>
96
- fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
27
+ *Sean Doyle*
97
28
 
98
- # <input id="trix_input_1" name="message[content]" type="hidden">
99
- # <trix-editor input="trix_input_1"></trix-editor>
100
- fill_in_rich_text_area "message[content]", with: "Hello <em>world!</em>"
101
- ```
29
+ * Add `with_all_rich_text` method to eager load all rich text associations on a model at once.
102
30
 
103
- *George Claghorn*
31
+ *Matt Swanson*, *DHH*
104
32
 
105
33
 
106
- Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actiontext/CHANGELOG.md) for previous changes.
34
+ Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/actiontext/CHANGELOG.md) for previous changes.
data/MIT-LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Basecamp, LLC
3
+ Copyright (c) 2020-2021 Basecamp, LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -4,6 +4,10 @@ Action Text brings rich text content and editing to Rails. It includes the [Trix
4
4
 
5
5
  You can read more about Action Text in the [Action Text Overview](https://edgeguides.rubyonrails.org/action_text_overview.html) guide.
6
6
 
7
+ ## Development
8
+
9
+ The JavaScript for Action Text is distributed both as a npm module under @rails/actiontext and via the asset pipeline as actiontext.js (and we mirror Trix as trix.js). To ensure that the latter remains in sync, you must run `yarn build` and checkin the artifacts whenever the JavaScript source or the Trix dependency is bumped. CSS changes must be brought over manually to app/assets/stylesheets/trix.css
10
+
7
11
  ## License
8
12
 
9
13
  Action Text is released under the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,880 @@
1
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2
+
3
+ var activestorage = {exports: {}};
4
+
5
+ (function (module, exports) {
6
+ (function(global, factory) {
7
+ factory(exports) ;
8
+ })(commonjsGlobal, (function(exports) {
9
+ var sparkMd5 = {
10
+ exports: {}
11
+ };
12
+ (function(module, exports) {
13
+ (function(factory) {
14
+ {
15
+ module.exports = factory();
16
+ }
17
+ })((function(undefined$1) {
18
+ var hex_chr = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ];
19
+ function md5cycle(x, k) {
20
+ var a = x[0], b = x[1], c = x[2], d = x[3];
21
+ a += (b & c | ~b & d) + k[0] - 680876936 | 0;
22
+ a = (a << 7 | a >>> 25) + b | 0;
23
+ d += (a & b | ~a & c) + k[1] - 389564586 | 0;
24
+ d = (d << 12 | d >>> 20) + a | 0;
25
+ c += (d & a | ~d & b) + k[2] + 606105819 | 0;
26
+ c = (c << 17 | c >>> 15) + d | 0;
27
+ b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
28
+ b = (b << 22 | b >>> 10) + c | 0;
29
+ a += (b & c | ~b & d) + k[4] - 176418897 | 0;
30
+ a = (a << 7 | a >>> 25) + b | 0;
31
+ d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
32
+ d = (d << 12 | d >>> 20) + a | 0;
33
+ c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
34
+ c = (c << 17 | c >>> 15) + d | 0;
35
+ b += (c & d | ~c & a) + k[7] - 45705983 | 0;
36
+ b = (b << 22 | b >>> 10) + c | 0;
37
+ a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
38
+ a = (a << 7 | a >>> 25) + b | 0;
39
+ d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
40
+ d = (d << 12 | d >>> 20) + a | 0;
41
+ c += (d & a | ~d & b) + k[10] - 42063 | 0;
42
+ c = (c << 17 | c >>> 15) + d | 0;
43
+ b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
44
+ b = (b << 22 | b >>> 10) + c | 0;
45
+ a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
46
+ a = (a << 7 | a >>> 25) + b | 0;
47
+ d += (a & b | ~a & c) + k[13] - 40341101 | 0;
48
+ d = (d << 12 | d >>> 20) + a | 0;
49
+ c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
50
+ c = (c << 17 | c >>> 15) + d | 0;
51
+ b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
52
+ b = (b << 22 | b >>> 10) + c | 0;
53
+ a += (b & d | c & ~d) + k[1] - 165796510 | 0;
54
+ a = (a << 5 | a >>> 27) + b | 0;
55
+ d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
56
+ d = (d << 9 | d >>> 23) + a | 0;
57
+ c += (d & b | a & ~b) + k[11] + 643717713 | 0;
58
+ c = (c << 14 | c >>> 18) + d | 0;
59
+ b += (c & a | d & ~a) + k[0] - 373897302 | 0;
60
+ b = (b << 20 | b >>> 12) + c | 0;
61
+ a += (b & d | c & ~d) + k[5] - 701558691 | 0;
62
+ a = (a << 5 | a >>> 27) + b | 0;
63
+ d += (a & c | b & ~c) + k[10] + 38016083 | 0;
64
+ d = (d << 9 | d >>> 23) + a | 0;
65
+ c += (d & b | a & ~b) + k[15] - 660478335 | 0;
66
+ c = (c << 14 | c >>> 18) + d | 0;
67
+ b += (c & a | d & ~a) + k[4] - 405537848 | 0;
68
+ b = (b << 20 | b >>> 12) + c | 0;
69
+ a += (b & d | c & ~d) + k[9] + 568446438 | 0;
70
+ a = (a << 5 | a >>> 27) + b | 0;
71
+ d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
72
+ d = (d << 9 | d >>> 23) + a | 0;
73
+ c += (d & b | a & ~b) + k[3] - 187363961 | 0;
74
+ c = (c << 14 | c >>> 18) + d | 0;
75
+ b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
76
+ b = (b << 20 | b >>> 12) + c | 0;
77
+ a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
78
+ a = (a << 5 | a >>> 27) + b | 0;
79
+ d += (a & c | b & ~c) + k[2] - 51403784 | 0;
80
+ d = (d << 9 | d >>> 23) + a | 0;
81
+ c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
82
+ c = (c << 14 | c >>> 18) + d | 0;
83
+ b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
84
+ b = (b << 20 | b >>> 12) + c | 0;
85
+ a += (b ^ c ^ d) + k[5] - 378558 | 0;
86
+ a = (a << 4 | a >>> 28) + b | 0;
87
+ d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
88
+ d = (d << 11 | d >>> 21) + a | 0;
89
+ c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
90
+ c = (c << 16 | c >>> 16) + d | 0;
91
+ b += (c ^ d ^ a) + k[14] - 35309556 | 0;
92
+ b = (b << 23 | b >>> 9) + c | 0;
93
+ a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
94
+ a = (a << 4 | a >>> 28) + b | 0;
95
+ d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
96
+ d = (d << 11 | d >>> 21) + a | 0;
97
+ c += (d ^ a ^ b) + k[7] - 155497632 | 0;
98
+ c = (c << 16 | c >>> 16) + d | 0;
99
+ b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
100
+ b = (b << 23 | b >>> 9) + c | 0;
101
+ a += (b ^ c ^ d) + k[13] + 681279174 | 0;
102
+ a = (a << 4 | a >>> 28) + b | 0;
103
+ d += (a ^ b ^ c) + k[0] - 358537222 | 0;
104
+ d = (d << 11 | d >>> 21) + a | 0;
105
+ c += (d ^ a ^ b) + k[3] - 722521979 | 0;
106
+ c = (c << 16 | c >>> 16) + d | 0;
107
+ b += (c ^ d ^ a) + k[6] + 76029189 | 0;
108
+ b = (b << 23 | b >>> 9) + c | 0;
109
+ a += (b ^ c ^ d) + k[9] - 640364487 | 0;
110
+ a = (a << 4 | a >>> 28) + b | 0;
111
+ d += (a ^ b ^ c) + k[12] - 421815835 | 0;
112
+ d = (d << 11 | d >>> 21) + a | 0;
113
+ c += (d ^ a ^ b) + k[15] + 530742520 | 0;
114
+ c = (c << 16 | c >>> 16) + d | 0;
115
+ b += (c ^ d ^ a) + k[2] - 995338651 | 0;
116
+ b = (b << 23 | b >>> 9) + c | 0;
117
+ a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
118
+ a = (a << 6 | a >>> 26) + b | 0;
119
+ d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
120
+ d = (d << 10 | d >>> 22) + a | 0;
121
+ c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
122
+ c = (c << 15 | c >>> 17) + d | 0;
123
+ b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
124
+ b = (b << 21 | b >>> 11) + c | 0;
125
+ a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
126
+ a = (a << 6 | a >>> 26) + b | 0;
127
+ d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
128
+ d = (d << 10 | d >>> 22) + a | 0;
129
+ c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
130
+ c = (c << 15 | c >>> 17) + d | 0;
131
+ b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
132
+ b = (b << 21 | b >>> 11) + c | 0;
133
+ a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
134
+ a = (a << 6 | a >>> 26) + b | 0;
135
+ d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
136
+ d = (d << 10 | d >>> 22) + a | 0;
137
+ c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
138
+ c = (c << 15 | c >>> 17) + d | 0;
139
+ b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
140
+ b = (b << 21 | b >>> 11) + c | 0;
141
+ a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
142
+ a = (a << 6 | a >>> 26) + b | 0;
143
+ d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
144
+ d = (d << 10 | d >>> 22) + a | 0;
145
+ c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
146
+ c = (c << 15 | c >>> 17) + d | 0;
147
+ b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
148
+ b = (b << 21 | b >>> 11) + c | 0;
149
+ x[0] = a + x[0] | 0;
150
+ x[1] = b + x[1] | 0;
151
+ x[2] = c + x[2] | 0;
152
+ x[3] = d + x[3] | 0;
153
+ }
154
+ function md5blk(s) {
155
+ var md5blks = [], i;
156
+ for (i = 0; i < 64; i += 4) {
157
+ md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
158
+ }
159
+ return md5blks;
160
+ }
161
+ function md5blk_array(a) {
162
+ var md5blks = [], i;
163
+ for (i = 0; i < 64; i += 4) {
164
+ md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
165
+ }
166
+ return md5blks;
167
+ }
168
+ function md51(s) {
169
+ var n = s.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi;
170
+ for (i = 64; i <= n; i += 64) {
171
+ md5cycle(state, md5blk(s.substring(i - 64, i)));
172
+ }
173
+ s = s.substring(i - 64);
174
+ length = s.length;
175
+ tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
176
+ for (i = 0; i < length; i += 1) {
177
+ tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
178
+ }
179
+ tail[i >> 2] |= 128 << (i % 4 << 3);
180
+ if (i > 55) {
181
+ md5cycle(state, tail);
182
+ for (i = 0; i < 16; i += 1) {
183
+ tail[i] = 0;
184
+ }
185
+ }
186
+ tmp = n * 8;
187
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
188
+ lo = parseInt(tmp[2], 16);
189
+ hi = parseInt(tmp[1], 16) || 0;
190
+ tail[14] = lo;
191
+ tail[15] = hi;
192
+ md5cycle(state, tail);
193
+ return state;
194
+ }
195
+ function md51_array(a) {
196
+ var n = a.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi;
197
+ for (i = 64; i <= n; i += 64) {
198
+ md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
199
+ }
200
+ a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);
201
+ length = a.length;
202
+ tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
203
+ for (i = 0; i < length; i += 1) {
204
+ tail[i >> 2] |= a[i] << (i % 4 << 3);
205
+ }
206
+ tail[i >> 2] |= 128 << (i % 4 << 3);
207
+ if (i > 55) {
208
+ md5cycle(state, tail);
209
+ for (i = 0; i < 16; i += 1) {
210
+ tail[i] = 0;
211
+ }
212
+ }
213
+ tmp = n * 8;
214
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
215
+ lo = parseInt(tmp[2], 16);
216
+ hi = parseInt(tmp[1], 16) || 0;
217
+ tail[14] = lo;
218
+ tail[15] = hi;
219
+ md5cycle(state, tail);
220
+ return state;
221
+ }
222
+ function rhex(n) {
223
+ var s = "", j;
224
+ for (j = 0; j < 4; j += 1) {
225
+ s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
226
+ }
227
+ return s;
228
+ }
229
+ function hex(x) {
230
+ var i;
231
+ for (i = 0; i < x.length; i += 1) {
232
+ x[i] = rhex(x[i]);
233
+ }
234
+ return x.join("");
235
+ }
236
+ if (hex(md51("hello")) !== "5d41402abc4b2a76b9719d911017c592") ;
237
+ if (typeof ArrayBuffer !== "undefined" && !ArrayBuffer.prototype.slice) {
238
+ (function() {
239
+ function clamp(val, length) {
240
+ val = val | 0 || 0;
241
+ if (val < 0) {
242
+ return Math.max(val + length, 0);
243
+ }
244
+ return Math.min(val, length);
245
+ }
246
+ ArrayBuffer.prototype.slice = function(from, to) {
247
+ var length = this.byteLength, begin = clamp(from, length), end = length, num, target, targetArray, sourceArray;
248
+ if (to !== undefined$1) {
249
+ end = clamp(to, length);
250
+ }
251
+ if (begin > end) {
252
+ return new ArrayBuffer(0);
253
+ }
254
+ num = end - begin;
255
+ target = new ArrayBuffer(num);
256
+ targetArray = new Uint8Array(target);
257
+ sourceArray = new Uint8Array(this, begin, num);
258
+ targetArray.set(sourceArray);
259
+ return target;
260
+ };
261
+ })();
262
+ }
263
+ function toUtf8(str) {
264
+ if (/[\u0080-\uFFFF]/.test(str)) {
265
+ str = unescape(encodeURIComponent(str));
266
+ }
267
+ return str;
268
+ }
269
+ function utf8Str2ArrayBuffer(str, returnUInt8Array) {
270
+ var length = str.length, buff = new ArrayBuffer(length), arr = new Uint8Array(buff), i;
271
+ for (i = 0; i < length; i += 1) {
272
+ arr[i] = str.charCodeAt(i);
273
+ }
274
+ return returnUInt8Array ? arr : buff;
275
+ }
276
+ function arrayBuffer2Utf8Str(buff) {
277
+ return String.fromCharCode.apply(null, new Uint8Array(buff));
278
+ }
279
+ function concatenateArrayBuffers(first, second, returnUInt8Array) {
280
+ var result = new Uint8Array(first.byteLength + second.byteLength);
281
+ result.set(new Uint8Array(first));
282
+ result.set(new Uint8Array(second), first.byteLength);
283
+ return returnUInt8Array ? result : result.buffer;
284
+ }
285
+ function hexToBinaryString(hex) {
286
+ var bytes = [], length = hex.length, x;
287
+ for (x = 0; x < length - 1; x += 2) {
288
+ bytes.push(parseInt(hex.substr(x, 2), 16));
289
+ }
290
+ return String.fromCharCode.apply(String, bytes);
291
+ }
292
+ function SparkMD5() {
293
+ this.reset();
294
+ }
295
+ SparkMD5.prototype.append = function(str) {
296
+ this.appendBinary(toUtf8(str));
297
+ return this;
298
+ };
299
+ SparkMD5.prototype.appendBinary = function(contents) {
300
+ this._buff += contents;
301
+ this._length += contents.length;
302
+ var length = this._buff.length, i;
303
+ for (i = 64; i <= length; i += 64) {
304
+ md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
305
+ }
306
+ this._buff = this._buff.substring(i - 64);
307
+ return this;
308
+ };
309
+ SparkMD5.prototype.end = function(raw) {
310
+ 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;
311
+ for (i = 0; i < length; i += 1) {
312
+ tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3);
313
+ }
314
+ this._finish(tail, length);
315
+ ret = hex(this._hash);
316
+ if (raw) {
317
+ ret = hexToBinaryString(ret);
318
+ }
319
+ this.reset();
320
+ return ret;
321
+ };
322
+ SparkMD5.prototype.reset = function() {
323
+ this._buff = "";
324
+ this._length = 0;
325
+ this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ];
326
+ return this;
327
+ };
328
+ SparkMD5.prototype.getState = function() {
329
+ return {
330
+ buff: this._buff,
331
+ length: this._length,
332
+ hash: this._hash.slice()
333
+ };
334
+ };
335
+ SparkMD5.prototype.setState = function(state) {
336
+ this._buff = state.buff;
337
+ this._length = state.length;
338
+ this._hash = state.hash;
339
+ return this;
340
+ };
341
+ SparkMD5.prototype.destroy = function() {
342
+ delete this._hash;
343
+ delete this._buff;
344
+ delete this._length;
345
+ };
346
+ SparkMD5.prototype._finish = function(tail, length) {
347
+ var i = length, tmp, lo, hi;
348
+ tail[i >> 2] |= 128 << (i % 4 << 3);
349
+ if (i > 55) {
350
+ md5cycle(this._hash, tail);
351
+ for (i = 0; i < 16; i += 1) {
352
+ tail[i] = 0;
353
+ }
354
+ }
355
+ tmp = this._length * 8;
356
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
357
+ lo = parseInt(tmp[2], 16);
358
+ hi = parseInt(tmp[1], 16) || 0;
359
+ tail[14] = lo;
360
+ tail[15] = hi;
361
+ md5cycle(this._hash, tail);
362
+ };
363
+ SparkMD5.hash = function(str, raw) {
364
+ return SparkMD5.hashBinary(toUtf8(str), raw);
365
+ };
366
+ SparkMD5.hashBinary = function(content, raw) {
367
+ var hash = md51(content), ret = hex(hash);
368
+ return raw ? hexToBinaryString(ret) : ret;
369
+ };
370
+ SparkMD5.ArrayBuffer = function() {
371
+ this.reset();
372
+ };
373
+ SparkMD5.ArrayBuffer.prototype.append = function(arr) {
374
+ var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), length = buff.length, i;
375
+ this._length += arr.byteLength;
376
+ for (i = 64; i <= length; i += 64) {
377
+ md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
378
+ }
379
+ this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
380
+ return this;
381
+ };
382
+ SparkMD5.ArrayBuffer.prototype.end = function(raw) {
383
+ 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;
384
+ for (i = 0; i < length; i += 1) {
385
+ tail[i >> 2] |= buff[i] << (i % 4 << 3);
386
+ }
387
+ this._finish(tail, length);
388
+ ret = hex(this._hash);
389
+ if (raw) {
390
+ ret = hexToBinaryString(ret);
391
+ }
392
+ this.reset();
393
+ return ret;
394
+ };
395
+ SparkMD5.ArrayBuffer.prototype.reset = function() {
396
+ this._buff = new Uint8Array(0);
397
+ this._length = 0;
398
+ this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ];
399
+ return this;
400
+ };
401
+ SparkMD5.ArrayBuffer.prototype.getState = function() {
402
+ var state = SparkMD5.prototype.getState.call(this);
403
+ state.buff = arrayBuffer2Utf8Str(state.buff);
404
+ return state;
405
+ };
406
+ SparkMD5.ArrayBuffer.prototype.setState = function(state) {
407
+ state.buff = utf8Str2ArrayBuffer(state.buff, true);
408
+ return SparkMD5.prototype.setState.call(this, state);
409
+ };
410
+ SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
411
+ SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
412
+ SparkMD5.ArrayBuffer.hash = function(arr, raw) {
413
+ var hash = md51_array(new Uint8Array(arr)), ret = hex(hash);
414
+ return raw ? hexToBinaryString(ret) : ret;
415
+ };
416
+ return SparkMD5;
417
+ }));
418
+ })(sparkMd5);
419
+ var SparkMD5 = sparkMd5.exports;
420
+ const fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
421
+ class FileChecksum {
422
+ static create(file, callback) {
423
+ const instance = new FileChecksum(file);
424
+ instance.create(callback);
425
+ }
426
+ constructor(file) {
427
+ this.file = file;
428
+ this.chunkSize = 2097152;
429
+ this.chunkCount = Math.ceil(this.file.size / this.chunkSize);
430
+ this.chunkIndex = 0;
431
+ }
432
+ create(callback) {
433
+ this.callback = callback;
434
+ this.md5Buffer = new SparkMD5.ArrayBuffer;
435
+ this.fileReader = new FileReader;
436
+ this.fileReader.addEventListener("load", (event => this.fileReaderDidLoad(event)));
437
+ this.fileReader.addEventListener("error", (event => this.fileReaderDidError(event)));
438
+ this.readNextChunk();
439
+ }
440
+ fileReaderDidLoad(event) {
441
+ this.md5Buffer.append(event.target.result);
442
+ if (!this.readNextChunk()) {
443
+ const binaryDigest = this.md5Buffer.end(true);
444
+ const base64digest = btoa(binaryDigest);
445
+ this.callback(null, base64digest);
446
+ }
447
+ }
448
+ fileReaderDidError(event) {
449
+ this.callback(`Error reading ${this.file.name}`);
450
+ }
451
+ readNextChunk() {
452
+ if (this.chunkIndex < this.chunkCount || this.chunkIndex == 0 && this.chunkCount == 0) {
453
+ const start = this.chunkIndex * this.chunkSize;
454
+ const end = Math.min(start + this.chunkSize, this.file.size);
455
+ const bytes = fileSlice.call(this.file, start, end);
456
+ this.fileReader.readAsArrayBuffer(bytes);
457
+ this.chunkIndex++;
458
+ return true;
459
+ } else {
460
+ return false;
461
+ }
462
+ }
463
+ }
464
+ function getMetaValue(name) {
465
+ const element = findElement(document.head, `meta[name="${name}"]`);
466
+ if (element) {
467
+ return element.getAttribute("content");
468
+ }
469
+ }
470
+ function findElements(root, selector) {
471
+ if (typeof root == "string") {
472
+ selector = root;
473
+ root = document;
474
+ }
475
+ const elements = root.querySelectorAll(selector);
476
+ return toArray(elements);
477
+ }
478
+ function findElement(root, selector) {
479
+ if (typeof root == "string") {
480
+ selector = root;
481
+ root = document;
482
+ }
483
+ return root.querySelector(selector);
484
+ }
485
+ function dispatchEvent(element, type, eventInit = {}) {
486
+ const {disabled: disabled} = element;
487
+ const {bubbles: bubbles, cancelable: cancelable, detail: detail} = eventInit;
488
+ const event = document.createEvent("Event");
489
+ event.initEvent(type, bubbles || true, cancelable || true);
490
+ event.detail = detail || {};
491
+ try {
492
+ element.disabled = false;
493
+ element.dispatchEvent(event);
494
+ } finally {
495
+ element.disabled = disabled;
496
+ }
497
+ return event;
498
+ }
499
+ function toArray(value) {
500
+ if (Array.isArray(value)) {
501
+ return value;
502
+ } else if (Array.from) {
503
+ return Array.from(value);
504
+ } else {
505
+ return [].slice.call(value);
506
+ }
507
+ }
508
+ class BlobRecord {
509
+ constructor(file, checksum, url) {
510
+ this.file = file;
511
+ this.attributes = {
512
+ filename: file.name,
513
+ content_type: file.type || "application/octet-stream",
514
+ byte_size: file.size,
515
+ checksum: checksum
516
+ };
517
+ this.xhr = new XMLHttpRequest;
518
+ this.xhr.open("POST", url, true);
519
+ this.xhr.responseType = "json";
520
+ this.xhr.setRequestHeader("Content-Type", "application/json");
521
+ this.xhr.setRequestHeader("Accept", "application/json");
522
+ this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
523
+ const csrfToken = getMetaValue("csrf-token");
524
+ if (csrfToken != undefined) {
525
+ this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
526
+ }
527
+ this.xhr.addEventListener("load", (event => this.requestDidLoad(event)));
528
+ this.xhr.addEventListener("error", (event => this.requestDidError(event)));
529
+ }
530
+ get status() {
531
+ return this.xhr.status;
532
+ }
533
+ get response() {
534
+ const {responseType: responseType, response: response} = this.xhr;
535
+ if (responseType == "json") {
536
+ return response;
537
+ } else {
538
+ return JSON.parse(response);
539
+ }
540
+ }
541
+ create(callback) {
542
+ this.callback = callback;
543
+ this.xhr.send(JSON.stringify({
544
+ blob: this.attributes
545
+ }));
546
+ }
547
+ requestDidLoad(event) {
548
+ if (this.status >= 200 && this.status < 300) {
549
+ const {response: response} = this;
550
+ const {direct_upload: direct_upload} = response;
551
+ delete response.direct_upload;
552
+ this.attributes = response;
553
+ this.directUploadData = direct_upload;
554
+ this.callback(null, this.toJSON());
555
+ } else {
556
+ this.requestDidError(event);
557
+ }
558
+ }
559
+ requestDidError(event) {
560
+ this.callback(`Error creating Blob for "${this.file.name}". Status: ${this.status}`);
561
+ }
562
+ toJSON() {
563
+ const result = {};
564
+ for (const key in this.attributes) {
565
+ result[key] = this.attributes[key];
566
+ }
567
+ return result;
568
+ }
569
+ }
570
+ class BlobUpload {
571
+ constructor(blob) {
572
+ this.blob = blob;
573
+ this.file = blob.file;
574
+ const {url: url, headers: headers} = blob.directUploadData;
575
+ this.xhr = new XMLHttpRequest;
576
+ this.xhr.open("PUT", url, true);
577
+ this.xhr.responseType = "text";
578
+ for (const key in headers) {
579
+ this.xhr.setRequestHeader(key, headers[key]);
580
+ }
581
+ this.xhr.addEventListener("load", (event => this.requestDidLoad(event)));
582
+ this.xhr.addEventListener("error", (event => this.requestDidError(event)));
583
+ }
584
+ create(callback) {
585
+ this.callback = callback;
586
+ this.xhr.send(this.file.slice());
587
+ }
588
+ requestDidLoad(event) {
589
+ const {status: status, response: response} = this.xhr;
590
+ if (status >= 200 && status < 300) {
591
+ this.callback(null, response);
592
+ } else {
593
+ this.requestDidError(event);
594
+ }
595
+ }
596
+ requestDidError(event) {
597
+ this.callback(`Error storing "${this.file.name}". Status: ${this.xhr.status}`);
598
+ }
599
+ }
600
+ let id = 0;
601
+ class DirectUpload {
602
+ constructor(file, url, delegate) {
603
+ this.id = ++id;
604
+ this.file = file;
605
+ this.url = url;
606
+ this.delegate = delegate;
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);
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 {target: target} = event;
757
+ if ((target.tagName == "INPUT" || target.tagName == "BUTTON") && target.type == "submit" && target.form) {
758
+ submitButtonsByForm.set(target.form, target);
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
+ exports.DirectUpload = DirectUpload;
822
+ exports.start = start;
823
+ Object.defineProperty(exports, "__esModule", {
824
+ value: true
825
+ });
826
+ }));
827
+ }(activestorage, activestorage.exports));
828
+
829
+ class AttachmentUpload {
830
+ constructor(attachment, element) {
831
+ this.attachment = attachment;
832
+ this.element = element;
833
+ this.directUpload = new activestorage.exports.DirectUpload(attachment.file, this.directUploadUrl, this);
834
+ }
835
+
836
+ start() {
837
+ this.directUpload.create(this.directUploadDidComplete.bind(this));
838
+ }
839
+
840
+ directUploadWillStoreFileWithXHR(xhr) {
841
+ xhr.upload.addEventListener("progress", event => {
842
+ const progress = event.loaded / event.total * 100;
843
+ this.attachment.setUploadProgress(progress);
844
+ });
845
+ }
846
+
847
+ directUploadDidComplete(error, attributes) {
848
+ if (error) {
849
+ throw new Error(`Direct upload failed: ${error}`)
850
+ }
851
+
852
+ this.attachment.setAttributes({
853
+ sgid: attributes.attachable_sgid,
854
+ url: this.createBlobUrl(attributes.signed_id, attributes.filename)
855
+ });
856
+ }
857
+
858
+ createBlobUrl(signedId, filename) {
859
+ return this.blobUrlTemplate
860
+ .replace(":signed_id", signedId)
861
+ .replace(":filename", encodeURIComponent(filename))
862
+ }
863
+
864
+ get directUploadUrl() {
865
+ return this.element.dataset.directUploadUrl
866
+ }
867
+
868
+ get blobUrlTemplate() {
869
+ return this.element.dataset.blobUrlTemplate
870
+ }
871
+ }
872
+
873
+ addEventListener("trix-attachment-add", event => {
874
+ const { attachment, target } = event;
875
+
876
+ if (attachment.file) {
877
+ const upload = new AttachmentUpload(attachment, target);
878
+ upload.start();
879
+ }
880
+ });