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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -91
- data/MIT-LICENSE +1 -1
- data/README.md +4 -0
- data/app/assets/javascripts/actiontext.js +880 -0
- data/app/assets/javascripts/trix.js +5278 -0
- data/app/assets/stylesheets/trix.css +375 -0
- data/app/helpers/action_text/content_helper.rb +17 -3
- data/app/helpers/action_text/tag_helper.rb +5 -7
- data/app/models/action_text/encrypted_rich_text.rb +9 -0
- data/app/models/action_text/record.rb +1 -1
- data/app/models/action_text/rich_text.rb +4 -0
- data/app/views/action_text/contents/_content.html.erb +1 -0
- data/app/views/layouts/action_text/contents/_content.html.erb +3 -0
- data/db/migrate/20180528164100_create_action_text_tables.rb +14 -2
- data/lib/action_text/attachable.rb +4 -0
- data/lib/action_text/attachment.rb +4 -4
- data/lib/action_text/attachment_gallery.rb +14 -9
- data/lib/action_text/attachments/caching.rb +1 -1
- data/lib/action_text/attachments/minification.rb +1 -1
- data/lib/action_text/attribute.rb +18 -2
- data/lib/action_text/content.rb +7 -3
- data/lib/action_text/encryption.rb +38 -0
- data/lib/action_text/engine.rb +14 -0
- data/lib/action_text/fixture_set.rb +49 -0
- data/lib/action_text/gem_version.rb +4 -4
- data/lib/action_text/rendering.rb +1 -1
- data/lib/action_text/trix_attachment.rb +3 -3
- data/lib/action_text.rb +1 -0
- data/lib/generators/action_text/install/install_generator.rb +28 -35
- data/lib/generators/action_text/install/templates/actiontext.css +35 -0
- data/package.json +13 -3
- metadata +28 -22
- data/app/views/action_text/content/_layout.html.erb +0 -3
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f0735e66acca9916e461de2094203f923aab79749a70eb10de2d060d70f7784
|
4
|
+
data.tar.gz: e22fa48ba71858e0bd786690fe7521a99a8edde6194db6955cf1a477a3d7a0eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b5ec0e335aa42817f62436ab55e5b5eba6616ccf7ba562f48dac68faf48af82536f843a3f4b5c6c1a85416aea937a455685bc65125b2c0ea0434a71506e0fc0
|
7
|
+
data.tar.gz: d15c8203e48105087852dd8f7dfdba4198cb6e62c9e50b053672ece3d0aafc9c45b127092d2c5c674181b50c8ab687640009d6683f3d4ae30c0bdc2bbc5c8af0
|
data/CHANGELOG.md
CHANGED
@@ -1,106 +1,34 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Make the Action Text + Trix JavaScript and CSS available through the asset pipeline.
|
4
4
|
|
5
|
+
*DHH*
|
5
6
|
|
6
|
-
|
7
|
+
* OpenSSL constants are now used for Digest computations.
|
7
8
|
|
8
|
-
*
|
9
|
+
*Dirkjan Bussink*
|
9
10
|
|
10
|
-
|
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
|
-
*
|
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
|
-
|
79
|
-
message = Message.create!(body: "<h1>Funny times!</h1>")
|
80
|
-
message.body? #=> true
|
81
|
-
```
|
19
|
+
*Mark VanLandingham*
|
82
20
|
|
83
|
-
|
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
|
-
*
|
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
|
-
|
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
|
-
*
|
31
|
+
*Matt Swanson*, *DHH*
|
104
32
|
|
105
33
|
|
106
|
-
Please check [6-
|
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
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
|
+
});
|