actiontext 7.0.0.alpha2 → 7.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actiontext might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/app/assets/javascripts/actiontext.js +27 -7
- data/app/helpers/action_text/tag_helper.rb +14 -2
- data/app/javascript/actiontext/attachment_upload.js +8 -1
- data/lib/action_text/fixture_set.rb +18 -12
- data/lib/action_text/gem_version.rb +1 -1
- data/lib/action_text/plain_text_conversion.rb +31 -2
- data/lib/action_text/serialization.rb +2 -0
- data/lib/generators/action_text/install/install_generator.rb +12 -0
- data/package.json +1 -1
- metadata +29 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39c49e2382be3b158f503ab091dfd137d7b70d8169f0a5d3bf0a15f563abedfd
|
4
|
+
data.tar.gz: 14a99fd63b659a235cc62f8359948ede8a71223bedfff6fc3a41f5871d9bc9b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf2e8b05f1232635c2754ae18606137abb012b3d00ec15f03eab1e8f416040aae2fedd5a5aa93f5b8ce20cccb56da9e269c7d2b10989cbe7873235fd265d626d
|
7
|
+
data.tar.gz: ffd63158c7e3b41aa602e767325a489b08f76580a4940b324296205f9fb938eb00511907e77e033c4eea19dcc90722f11b4d8d858d65f176a2deb9e821240f62
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
* Fix an issue with how nested lists were displayed when converting to plain text
|
2
|
+
|
3
|
+
*Matt Swanson*
|
4
|
+
|
5
|
+
* Allow passing in a custom `direct_upload_url` or `blob_url_template` to `rich_text_area_tag`.
|
6
|
+
|
7
|
+
*Lucas Mansur*
|
8
|
+
|
9
|
+
|
1
10
|
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
2
11
|
|
3
12
|
* No changes.
|
@@ -506,14 +506,16 @@ var activestorage = {exports: {}};
|
|
506
506
|
}
|
507
507
|
}
|
508
508
|
class BlobRecord {
|
509
|
-
constructor(file, checksum, url) {
|
509
|
+
constructor(file, checksum, url, directUploadToken, attachmentName) {
|
510
510
|
this.file = file;
|
511
511
|
this.attributes = {
|
512
512
|
filename: file.name,
|
513
513
|
content_type: file.type || "application/octet-stream",
|
514
514
|
byte_size: file.size,
|
515
|
-
checksum: checksum
|
515
|
+
checksum: checksum,
|
516
516
|
};
|
517
|
+
this.directUploadToken = directUploadToken;
|
518
|
+
this.attachmentName = attachmentName;
|
517
519
|
this.xhr = new XMLHttpRequest;
|
518
520
|
this.xhr.open("POST", url, true);
|
519
521
|
this.xhr.responseType = "json";
|
@@ -541,7 +543,9 @@ var activestorage = {exports: {}};
|
|
541
543
|
create(callback) {
|
542
544
|
this.callback = callback;
|
543
545
|
this.xhr.send(JSON.stringify({
|
544
|
-
blob: this.attributes
|
546
|
+
blob: this.attributes,
|
547
|
+
direct_upload_token: this.directUploadToken,
|
548
|
+
attachment_name: this.attachmentName
|
545
549
|
}));
|
546
550
|
}
|
547
551
|
requestDidLoad(event) {
|
@@ -599,10 +603,12 @@ var activestorage = {exports: {}};
|
|
599
603
|
}
|
600
604
|
let id = 0;
|
601
605
|
class DirectUpload {
|
602
|
-
constructor(file, url, delegate) {
|
606
|
+
constructor(file, url, directUploadToken, attachmentName, delegate) {
|
603
607
|
this.id = ++id;
|
604
608
|
this.file = file;
|
605
609
|
this.url = url;
|
610
|
+
this.directUploadToken = directUploadToken;
|
611
|
+
this.attachmentName = attachmentName;
|
606
612
|
this.delegate = delegate;
|
607
613
|
}
|
608
614
|
create(callback) {
|
@@ -611,7 +617,7 @@ var activestorage = {exports: {}};
|
|
611
617
|
callback(error);
|
612
618
|
return;
|
613
619
|
}
|
614
|
-
const blob = new BlobRecord(this.file, checksum, this.url);
|
620
|
+
const blob = new BlobRecord(this.file, checksum, this.url, this.directUploadToken, this.attachmentName);
|
615
621
|
notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
|
616
622
|
blob.create((error => {
|
617
623
|
if (error) {
|
@@ -640,7 +646,7 @@ var activestorage = {exports: {}};
|
|
640
646
|
constructor(input, file) {
|
641
647
|
this.input = input;
|
642
648
|
this.file = file;
|
643
|
-
this.directUpload = new DirectUpload(this.file, this.url, this);
|
649
|
+
this.directUpload = new DirectUpload(this.file, this.url, this.directUploadToken, this.attachmentName, this);
|
644
650
|
this.dispatch("initialize");
|
645
651
|
}
|
646
652
|
start(callback) {
|
@@ -671,6 +677,12 @@ var activestorage = {exports: {}};
|
|
671
677
|
get url() {
|
672
678
|
return this.input.getAttribute("data-direct-upload-url");
|
673
679
|
}
|
680
|
+
get directUploadToken() {
|
681
|
+
return this.input.getAttribute("data-direct-upload-token");
|
682
|
+
}
|
683
|
+
get attachmentName() {
|
684
|
+
return this.input.getAttribute("data-direct-upload-attachment-name");
|
685
|
+
}
|
674
686
|
dispatch(name, detail = {}) {
|
675
687
|
detail.file = this.file;
|
676
688
|
detail.id = this.directUpload.id;
|
@@ -830,7 +842,7 @@ class AttachmentUpload {
|
|
830
842
|
constructor(attachment, element) {
|
831
843
|
this.attachment = attachment;
|
832
844
|
this.element = element;
|
833
|
-
this.directUpload = new activestorage.exports.DirectUpload(attachment.file, this.directUploadUrl, this);
|
845
|
+
this.directUpload = new activestorage.exports.DirectUpload(attachment.file, this.directUploadUrl, this.directUploadToken, this.directUploadAttachmentName, this);
|
834
846
|
}
|
835
847
|
|
836
848
|
start() {
|
@@ -865,6 +877,14 @@ class AttachmentUpload {
|
|
865
877
|
return this.element.dataset.directUploadUrl
|
866
878
|
}
|
867
879
|
|
880
|
+
get directUploadToken() {
|
881
|
+
return this.element.dataset.directUploadToken
|
882
|
+
}
|
883
|
+
|
884
|
+
get directUploadAttachmentName() {
|
885
|
+
return this.element.dataset.directUploadAttachmentName
|
886
|
+
}
|
887
|
+
|
868
888
|
get blobUrlTemplate() {
|
869
889
|
return this.element.dataset.blobUrlTemplate
|
870
890
|
}
|
@@ -13,6 +13,8 @@ module ActionText
|
|
13
13
|
# ==== Options
|
14
14
|
# * <tt>:class</tt> - Defaults to "trix-content" so that default styles will be applied.
|
15
15
|
# Setting this to a different value will prevent default styles from being applied.
|
16
|
+
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
17
|
+
# * <tt>[:data][:blob_url_template]</tt> - Defaults to <tt>rails_service_blob_url(":signed_id", ":filename")</tt>.
|
16
18
|
#
|
17
19
|
# ==== Example
|
18
20
|
#
|
@@ -27,8 +29,16 @@ module ActionText
|
|
27
29
|
options[:class] ||= "trix-content"
|
28
30
|
|
29
31
|
options[:data] ||= {}
|
30
|
-
options[:data][:direct_upload_url]
|
31
|
-
options[:data][:blob_url_template]
|
32
|
+
options[:data][:direct_upload_url] ||= main_app.rails_direct_uploads_url
|
33
|
+
options[:data][:blob_url_template] ||= main_app.rails_service_blob_url(":signed_id", ":filename")
|
34
|
+
|
35
|
+
class_with_attachment = "ActionText::RichText#embeds"
|
36
|
+
options[:data][:direct_upload_attachment_name] ||= class_with_attachment
|
37
|
+
options[:data][:direct_upload_token] = ActiveStorage::DirectUploadToken.generate_direct_upload_token(
|
38
|
+
class_with_attachment,
|
39
|
+
ActiveStorage::Blob.service.name,
|
40
|
+
session
|
41
|
+
)
|
32
42
|
|
33
43
|
editor_tag = content_tag("trix-editor", "", options)
|
34
44
|
input_tag = hidden_field_tag(name, value.try(:to_trix_html) || value, id: options[:input], form: form)
|
@@ -59,6 +69,8 @@ module ActionView::Helpers
|
|
59
69
|
# ==== Options
|
60
70
|
# * <tt>:class</tt> - Defaults to "trix-content" which ensures default styling is applied.
|
61
71
|
# * <tt>:value</tt> - Adds a default value to the HTML input tag.
|
72
|
+
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
73
|
+
# * <tt>[:data][:blob_url_template]</tt> - Defaults to +rails_service_blob_url(":signed_id", ":filename")+.
|
62
74
|
#
|
63
75
|
# ==== Example
|
64
76
|
# form_with(model: @message) do |form|
|
@@ -4,7 +4,7 @@ export class AttachmentUpload {
|
|
4
4
|
constructor(attachment, element) {
|
5
5
|
this.attachment = attachment
|
6
6
|
this.element = element
|
7
|
-
this.directUpload = new DirectUpload(attachment.file, this.directUploadUrl, this)
|
7
|
+
this.directUpload = new DirectUpload(attachment.file, this.directUploadUrl, this.directUploadToken, this.attachmentName, this)
|
8
8
|
}
|
9
9
|
|
10
10
|
start() {
|
@@ -42,4 +42,11 @@ export class AttachmentUpload {
|
|
42
42
|
get blobUrlTemplate() {
|
43
43
|
return this.element.dataset.blobUrlTemplate
|
44
44
|
}
|
45
|
+
|
46
|
+
get directUploadToken() {
|
47
|
+
return this.element.getAttribute("data-direct-upload-token");
|
48
|
+
}
|
49
|
+
get attachmentName() {
|
50
|
+
return this.element.getAttribute("data-direct-upload-attachment-name");
|
51
|
+
}
|
45
52
|
}
|
@@ -10,23 +10,26 @@ module ActionText
|
|
10
10
|
# === YAML
|
11
11
|
#
|
12
12
|
# Like other Active Record-backed models, ActionText::RichText records inherit
|
13
|
-
# from ActiveRecord::Base instances and therefore
|
13
|
+
# from ActiveRecord::Base instances and can therefore be populated by
|
14
14
|
# fixtures.
|
15
15
|
#
|
16
|
-
# Consider
|
17
|
-
# data, as well as fixture data for related ActionText::RichText records:
|
16
|
+
# Consider an <tt>Article</tt> class:
|
18
17
|
#
|
19
|
-
# # app/models/article.rb
|
20
18
|
# class Article < ApplicationRecord
|
21
19
|
# has_rich_text :content
|
22
20
|
# end
|
23
21
|
#
|
24
|
-
#
|
22
|
+
# To declare fixture data for the related <tt>content</tt>, first declare fixture
|
23
|
+
# data for <tt>Article</tt> instances in <tt>test/fixtures/articles.yml</tt>:
|
24
|
+
#
|
25
25
|
# first:
|
26
26
|
# title: An Article
|
27
27
|
#
|
28
|
-
#
|
29
|
-
#
|
28
|
+
# Then declare the <tt>ActionText::RichText</tt> fixture data in
|
29
|
+
# <tt>test/fixtures/action_text/rich_texts.yml</tt>, making sure to declare
|
30
|
+
# each entry's <tt>record:</tt> key as a polymorphic relationship:
|
31
|
+
#
|
32
|
+
# first:
|
30
33
|
# record: first (Article)
|
31
34
|
# name: content
|
32
35
|
# body: <div>Hello, world.</div>
|
@@ -39,18 +42,21 @@ module ActionText
|
|
39
42
|
#
|
40
43
|
# === Examples
|
41
44
|
#
|
42
|
-
# For example, consider a second <tt>Article</tt>
|
43
|
-
#
|
45
|
+
# For example, consider a second <tt>Article</tt> fixture declared in
|
46
|
+
# <tt>test/fixtures/articles.yml</tt>:
|
44
47
|
#
|
45
|
-
# # tests/fixtures/articles.yml
|
46
48
|
# second:
|
47
49
|
# title: Another Article
|
48
50
|
#
|
49
|
-
#
|
50
|
-
#
|
51
|
+
# You can attach a mention of <tt>articles(:first)</tt> to <tt>second</tt>'s
|
52
|
+
# <tt>content</tt> by embedding a call to <tt>ActionText::FixtureSet.attachment</tt>
|
53
|
+
# in the <tt>body:</tt> value in <tt>test/fixtures/action_text/rich_texts.yml</tt>:
|
54
|
+
#
|
55
|
+
# second:
|
51
56
|
# record: second (Article)
|
52
57
|
# name: content
|
53
58
|
# body: <div>Hello, <%= ActionText::FixtureSet.attachment("articles", :first) %></div>
|
59
|
+
#
|
54
60
|
def self.attachment(fixture_set_name, label, column_type: :integer)
|
55
61
|
signed_global_id = ActiveRecord::FixtureSet.signed_global_id fixture_set_name, label,
|
56
62
|
column_type: column_type, for: ActionText::Attachable::LOCATOR_NAME
|
@@ -33,10 +33,18 @@ module ActionText
|
|
33
33
|
"#{remove_trailing_newlines(plain_text_for_node_children(node))}\n\n"
|
34
34
|
end
|
35
35
|
|
36
|
-
%i[ h1 p
|
36
|
+
%i[ h1 p ].each do |element|
|
37
37
|
alias_method :"plain_text_for_#{element}_node", :plain_text_for_block
|
38
38
|
end
|
39
39
|
|
40
|
+
def plain_text_for_list(node, index)
|
41
|
+
"#{break_if_nested_list(node, plain_text_for_block(node))}"
|
42
|
+
end
|
43
|
+
|
44
|
+
%i[ ul ol ].each do |element|
|
45
|
+
alias_method :"plain_text_for_#{element}_node", :plain_text_for_list
|
46
|
+
end
|
47
|
+
|
40
48
|
def plain_text_for_br_node(node, index)
|
41
49
|
"\n"
|
42
50
|
end
|
@@ -61,7 +69,9 @@ module ActionText
|
|
61
69
|
def plain_text_for_li_node(node, index)
|
62
70
|
bullet = bullet_for_li_node(node, index)
|
63
71
|
text = remove_trailing_newlines(plain_text_for_node_children(node))
|
64
|
-
|
72
|
+
indentation = indentation_for_li_node(node)
|
73
|
+
|
74
|
+
"#{indentation}#{bullet} #{text}\n"
|
65
75
|
end
|
66
76
|
|
67
77
|
def remove_trailing_newlines(text)
|
@@ -79,5 +89,24 @@ module ActionText
|
|
79
89
|
def list_node_name_for_li_node(node)
|
80
90
|
node.ancestors.lazy.map(&:name).grep(/^[uo]l$/).first
|
81
91
|
end
|
92
|
+
|
93
|
+
def indentation_for_li_node(node)
|
94
|
+
depth = list_node_depth_for_node(node)
|
95
|
+
if depth > 1
|
96
|
+
" " * (depth - 1)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def list_node_depth_for_node(node)
|
101
|
+
node.ancestors.map(&:name).grep(/^[uo]l$/).count
|
102
|
+
end
|
103
|
+
|
104
|
+
def break_if_nested_list(node, text)
|
105
|
+
if list_node_depth_for_node(node) > 0
|
106
|
+
"\n#{text}"
|
107
|
+
else
|
108
|
+
text
|
109
|
+
end
|
110
|
+
end
|
82
111
|
end
|
83
112
|
end
|
@@ -32,8 +32,20 @@ module ActionText
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def create_actiontext_files
|
35
|
+
destination = Pathname(destination_root)
|
36
|
+
|
35
37
|
template "actiontext.css", "app/assets/stylesheets/actiontext.css"
|
36
38
|
|
39
|
+
unless destination.join("app/assets/application.css").exist?
|
40
|
+
if (stylesheets = Dir.glob "#{destination_root}/app/assets/stylesheets/application.*.{scss,css}").length > 0
|
41
|
+
insert_into_file stylesheets.first.to_s, %(@import 'actiontext.css';)
|
42
|
+
else
|
43
|
+
say <<~INSTRUCTIONS, :green
|
44
|
+
To use the Trix editor, you must require 'app/assets/stylesheets/actiontext.css' in your base stylesheet.
|
45
|
+
INSTRUCTIONS
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
37
49
|
gem_root = "#{__dir__}/../../../.."
|
38
50
|
|
39
51
|
copy_file "#{gem_root}/app/views/active_storage/blobs/_blob.html.erb",
|
data/package.json
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actiontext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0.0.
|
4
|
+
version: 7.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javan Makhmali
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-12-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -18,56 +18,56 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 7.0.0.
|
21
|
+
version: 7.0.0.rc1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 7.0.0.
|
28
|
+
version: 7.0.0.rc1
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: activerecord
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - '='
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 7.0.0.
|
35
|
+
version: 7.0.0.rc1
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - '='
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 7.0.0.
|
42
|
+
version: 7.0.0.rc1
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: activestorage
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - '='
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 7.0.0.
|
49
|
+
version: 7.0.0.rc1
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - '='
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: 7.0.0.
|
56
|
+
version: 7.0.0.rc1
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: actionpack
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - '='
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 7.0.0.
|
63
|
+
version: 7.0.0.rc1
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
68
|
- - '='
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 7.0.0.
|
70
|
+
version: 7.0.0.rc1
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: nokogiri
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,6 +82,20 @@ dependencies:
|
|
82
82
|
- - ">="
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: 1.8.5
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: globalid
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 0.6.0
|
92
|
+
type: :runtime
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.6.0
|
85
99
|
description: Edit and display rich text in Rails applications.
|
86
100
|
email:
|
87
101
|
- javan@javan.us
|
@@ -146,10 +160,11 @@ licenses:
|
|
146
160
|
- MIT
|
147
161
|
metadata:
|
148
162
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
149
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.0.0.
|
150
|
-
documentation_uri: https://api.rubyonrails.org/v7.0.0.
|
163
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.0.rc1/actiontext/CHANGELOG.md
|
164
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.0.rc1/
|
151
165
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
152
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.0.0.
|
166
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.0.rc1/actiontext
|
167
|
+
rubygems_mfa_required: 'true'
|
153
168
|
post_install_message:
|
154
169
|
rdoc_options: []
|
155
170
|
require_paths:
|
@@ -165,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
180
|
- !ruby/object:Gem::Version
|
166
181
|
version: 1.3.1
|
167
182
|
requirements: []
|
168
|
-
rubygems_version: 3.
|
183
|
+
rubygems_version: 3.2.22
|
169
184
|
signing_key:
|
170
185
|
specification_version: 4
|
171
186
|
summary: Rich text framework.
|