actiontext 7.2.0 → 8.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d77dbdf62d70a0ee5468ec4b03146cec33d5326dbdd73f3dca7008e516ca751
4
- data.tar.gz: 40ef3f337c58d72213a1655f978793e195d03ad9fecf283115b24af2d4ee359a
3
+ metadata.gz: 47681928e4eb5de7fb4d7958ec7071174c8671e9750049693f8bc6a4742d90be
4
+ data.tar.gz: 162c998b362b84e68c0a404014c227a04925c3554de18ad66563dd3b00759040
5
5
  SHA512:
6
- metadata.gz: ca3c5b6008ad562a0c98cf0534fbfaadfd5e79fa97a18c7f3f5ba94e78cd782492ccc380a6a798d2e34b820f26667a01276cd4059460da157e5103d8f67ffd14
7
- data.tar.gz: 9b1190da576e6742190168cdadede33cfa915572e25ef661fcd2b29794122b91860164bc1dd4095e7d18bfa136cd05f77ecf2db36a5bb54264bb0bc172de7d91
6
+ metadata.gz: 13900860666132a1931d50ce22c8cb65f5a39f09a65f7fcc893aece5c55b292d7c7c63735450da6181d3736944e1ce4610cb2407a24e6740991ddf0c30f2a3fe
7
+ data.tar.gz: 02ed293526d7691e072e5f8711e8fd69dabcf6c7aaa3dcaf01d07c29d09d43629acf60f6aa65d22a67727a1f5622ef4c3cfbc8bc69108cd8240fcbb1c960d9d8
data/CHANGELOG.md CHANGED
@@ -1,54 +1,44 @@
1
- ## Rails 7.2.0 (August 09, 2024) ##
1
+ ## Rails 8.0.0.beta1 (September 26, 2024) ##
2
2
 
3
- * Only sanitize `content` attribute when present in attachments.
4
-
5
- *Petrik de Heus*
3
+ * Dispatch direct-upload events on attachment uploads
6
4
 
7
- * Sanitize ActionText HTML ContentAttachment in Trix edit view
8
- [CVE-2024-32464]
5
+ When using Action Text's rich textarea, it's possible to attach files to the
6
+ editor. Previously, that action didn't dispatch any events, which made it hard
7
+ to react to the file uploads. For instance, if an upload failed, there was no
8
+ way to notify the user about it, or remove the attachment from the editor.
9
9
 
10
- *Aaron Patterson*, *Zack Deveau*
10
+ This commits adds new events - `direct-upload:start`, `direct-upload:progress`,
11
+ and `direct-upload:end` - similar to how Active Storage's direct uploads work.
11
12
 
12
- * Use `includes` instead of `eager_load` for `with_all_rich_text`.
13
+ *Matheus Richard*, *Brad Rees*
13
14
 
14
- *Petrik de Heus*
15
+ * Add `store_if_blank` option to `has_rich_text`
15
16
 
16
- * Delegate `ActionText::Content#deconstruct` to `Nokogiri::XML::DocumentFragment#elements`.
17
+ Pass `store_if_blank: false` to not create `ActionText::RichText` records when saving with a blank attribute, such as from an optional form parameter.
17
18
 
18
19
  ```ruby
19
- content = ActionText::Content.new <<~HTML
20
- <h1>Hello, world</h1>
20
+ class Message
21
+ has_rich_text :content, store_if_blank: false
22
+ end
21
23
 
22
- <div>The body</div>
23
- HTML
24
-
25
- content => [h1, div]
26
-
27
- assert_pattern { h1 => { content: "Hello, world" } }
28
- assert_pattern { div => { content: "The body" } }
24
+ Message.create(content: "hi") # creates an ActionText::RichText
25
+ Message.create(content: "") # does not create an ActionText::RichText
29
26
  ```
30
27
 
31
- *Sean Doyle*
28
+ *Alex Ghiculescu*
32
29
 
33
- * Fix all Action Text database related models to respect
34
- `ActiveRecord::Base.table_name_prefix` configuration.
30
+ * Strip `content` attribute if the key is present but the value is empty
35
31
 
36
- *Chedli Bourguiba*
32
+ *Jeremy Green*
37
33
 
38
- * Compile ESM package that can be used directly in the browser as actiontext.esm.js
34
+ * Rename `rich_text_area` methods into `rich_textarea`
39
35
 
40
- *Matias Grunberg*
36
+ Old names are still available as aliases.
41
37
 
42
- * Fix using actiontext.js with Sprockets.
43
-
44
- *Matias Grunberg*
45
-
46
- * Upgrade Trix to 2.0.7
47
-
48
- *Hartley McGuire*
38
+ *Sean Doyle*
49
39
 
50
- * Fix using Trix with Sprockets.
40
+ * Only sanitize `content` attribute when present in attachments.
51
41
 
52
- *Hartley McGuire*
42
+ *Petrik de Heus*
53
43
 
54
- Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/actiontext/CHANGELOG.md) for previous changes.
44
+ Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/actiontext/CHANGELOG.md) for previous changes.
@@ -853,25 +853,47 @@ class AttachmentUpload {
853
853
  }
854
854
  start() {
855
855
  this.directUpload.create(this.directUploadDidComplete.bind(this));
856
+ this.dispatch("start");
856
857
  }
857
858
  directUploadWillStoreFileWithXHR(xhr) {
858
859
  xhr.upload.addEventListener("progress", (event => {
859
860
  const progress = event.loaded / event.total * 100;
860
861
  this.attachment.setUploadProgress(progress);
862
+ if (progress) {
863
+ this.dispatch("progress", {
864
+ progress: progress
865
+ });
866
+ }
861
867
  }));
862
868
  }
863
869
  directUploadDidComplete(error, attributes) {
864
870
  if (error) {
865
- throw new Error(`Direct upload failed: ${error}`);
871
+ this.dispatchError(error);
872
+ } else {
873
+ this.attachment.setAttributes({
874
+ sgid: attributes.attachable_sgid,
875
+ url: this.createBlobUrl(attributes.signed_id, attributes.filename)
876
+ });
877
+ this.dispatch("end");
866
878
  }
867
- this.attachment.setAttributes({
868
- sgid: attributes.attachable_sgid,
869
- url: this.createBlobUrl(attributes.signed_id, attributes.filename)
870
- });
871
879
  }
872
880
  createBlobUrl(signedId, filename) {
873
881
  return this.blobUrlTemplate.replace(":signed_id", signedId).replace(":filename", encodeURIComponent(filename));
874
882
  }
883
+ dispatch(name, detail = {}) {
884
+ detail.attachment = this.attachment;
885
+ return dispatchEvent(this.element, `direct-upload:${name}`, {
886
+ detail: detail
887
+ });
888
+ }
889
+ dispatchError(error) {
890
+ const event = this.dispatch("error", {
891
+ error: error
892
+ });
893
+ if (!event.defaultPrevented) {
894
+ alert(error);
895
+ }
896
+ }
875
897
  get directUploadUrl() {
876
898
  return this.element.dataset.directUploadUrl;
877
899
  }
@@ -826,25 +826,47 @@
826
826
  }
827
827
  start() {
828
828
  this.directUpload.create(this.directUploadDidComplete.bind(this));
829
+ this.dispatch("start");
829
830
  }
830
831
  directUploadWillStoreFileWithXHR(xhr) {
831
832
  xhr.upload.addEventListener("progress", (event => {
832
833
  const progress = event.loaded / event.total * 100;
833
834
  this.attachment.setUploadProgress(progress);
835
+ if (progress) {
836
+ this.dispatch("progress", {
837
+ progress: progress
838
+ });
839
+ }
834
840
  }));
835
841
  }
836
842
  directUploadDidComplete(error, attributes) {
837
843
  if (error) {
838
- throw new Error(`Direct upload failed: ${error}`);
844
+ this.dispatchError(error);
845
+ } else {
846
+ this.attachment.setAttributes({
847
+ sgid: attributes.attachable_sgid,
848
+ url: this.createBlobUrl(attributes.signed_id, attributes.filename)
849
+ });
850
+ this.dispatch("end");
839
851
  }
840
- this.attachment.setAttributes({
841
- sgid: attributes.attachable_sgid,
842
- url: this.createBlobUrl(attributes.signed_id, attributes.filename)
843
- });
844
852
  }
845
853
  createBlobUrl(signedId, filename) {
846
854
  return this.blobUrlTemplate.replace(":signed_id", signedId).replace(":filename", encodeURIComponent(filename));
847
855
  }
856
+ dispatch(name, detail = {}) {
857
+ detail.attachment = this.attachment;
858
+ return dispatchEvent(this.element, `direct-upload:${name}`, {
859
+ detail: detail
860
+ });
861
+ }
862
+ dispatchError(error) {
863
+ const event = this.dispatch("error", {
864
+ error: error
865
+ });
866
+ if (!event.defaultPrevented) {
867
+ alert(error);
868
+ }
869
+ }
848
870
  get directUploadUrl() {
849
871
  return this.element.dataset.directUploadUrl;
850
872
  }
@@ -24,10 +24,10 @@ module ActionText
24
24
  #
25
25
  # #### Example
26
26
  #
27
- # rich_text_area_tag "content", message.content
27
+ # rich_textarea_tag "content", message.content
28
28
  # # <input type="hidden" name="content" id="trix_input_post_1">
29
29
  # # <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>
30
- def rich_text_area_tag(name, value = nil, options = {})
30
+ def rich_textarea_tag(name, value = nil, options = {})
31
31
  options = options.symbolize_keys
32
32
  form = options.delete(:form)
33
33
 
@@ -43,6 +43,7 @@ module ActionText
43
43
 
44
44
  input_tag + editor_tag
45
45
  end
46
+ alias_method :rich_text_area_tag, :rich_textarea_tag
46
47
  end
47
48
  end
48
49
 
@@ -56,7 +57,7 @@ module ActionView::Helpers
56
57
  options = @options.stringify_keys
57
58
  add_default_name_and_id(options)
58
59
  options["input"] ||= dom_id(object, [options["id"], :trix_input].compact.join("_")) if object
59
- html_tag = @template_object.rich_text_area_tag(options.delete("name"), options.fetch("value") { value }, options.except("value"))
60
+ html_tag = @template_object.rich_textarea_tag(options.delete("name"), options.fetch("value") { value }, options.except("value"))
60
61
  error_wrapping(html_tag)
61
62
  end
62
63
  end
@@ -76,28 +77,30 @@ module ActionView::Helpers
76
77
  #
77
78
  #
78
79
  # #### Example
79
- # rich_text_area :message, :content
80
+ # rich_textarea :message, :content
80
81
  # # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
81
82
  # # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
82
83
  #
83
- # rich_text_area :message, :content, value: "<h1>Default message</h1>"
84
+ # rich_textarea :message, :content, value: "<h1>Default message</h1>"
84
85
  # # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
85
86
  # # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
86
- def rich_text_area(object_name, method, options = {})
87
+ def rich_textarea(object_name, method, options = {})
87
88
  Tags::ActionText.new(object_name, method, self, options).render
88
89
  end
90
+ alias_method :rich_text_area, :rich_textarea
89
91
  end
90
92
 
91
93
  class FormBuilder
92
- # Wraps ActionView::Helpers::FormHelper#rich_text_area for form builders:
94
+ # Wraps ActionView::Helpers::FormHelper#rich_textarea for form builders:
93
95
  #
94
96
  # <%= form_with model: @message do |f| %>
95
- # <%= f.rich_text_area :content %>
97
+ # <%= f.rich_textarea :content %>
96
98
  # <% end %>
97
99
  #
98
100
  # Please refer to the documentation of the base helper for details.
99
- def rich_text_area(method, options = {})
100
- @template.rich_text_area(@object_name, method, objectify_options(options))
101
+ def rich_textarea(method, options = {})
102
+ @template.rich_textarea(@object_name, method, objectify_options(options))
101
103
  end
104
+ alias_method :rich_text_area, :rich_textarea
102
105
  end
103
106
  end
@@ -1,4 +1,4 @@
1
- import { DirectUpload } from "@rails/activestorage"
1
+ import { DirectUpload, dispatchEvent } from "@rails/activestorage"
2
2
 
3
3
  export class AttachmentUpload {
4
4
  constructor(attachment, element) {
@@ -9,24 +9,29 @@ export class AttachmentUpload {
9
9
 
10
10
  start() {
11
11
  this.directUpload.create(this.directUploadDidComplete.bind(this))
12
+ this.dispatch("start")
12
13
  }
13
14
 
14
15
  directUploadWillStoreFileWithXHR(xhr) {
15
16
  xhr.upload.addEventListener("progress", event => {
16
17
  const progress = event.loaded / event.total * 100
17
18
  this.attachment.setUploadProgress(progress)
19
+ if (progress) {
20
+ this.dispatch("progress", { progress: progress })
21
+ }
18
22
  })
19
23
  }
20
24
 
21
25
  directUploadDidComplete(error, attributes) {
22
26
  if (error) {
23
- throw new Error(`Direct upload failed: ${error}`)
27
+ this.dispatchError(error)
28
+ } else {
29
+ this.attachment.setAttributes({
30
+ sgid: attributes.attachable_sgid,
31
+ url: this.createBlobUrl(attributes.signed_id, attributes.filename)
32
+ })
33
+ this.dispatch("end")
24
34
  }
25
-
26
- this.attachment.setAttributes({
27
- sgid: attributes.attachable_sgid,
28
- url: this.createBlobUrl(attributes.signed_id, attributes.filename)
29
- })
30
35
  }
31
36
 
32
37
  createBlobUrl(signedId, filename) {
@@ -35,6 +40,18 @@ export class AttachmentUpload {
35
40
  .replace(":filename", encodeURIComponent(filename))
36
41
  }
37
42
 
43
+ dispatch(name, detail = {}) {
44
+ detail.attachment = this.attachment
45
+ return dispatchEvent(this.element, `direct-upload:${name}`, { detail })
46
+ }
47
+
48
+ dispatchError(error) {
49
+ const event = this.dispatch("error", { error })
50
+ if (!event.defaultPrevented) {
51
+ alert(error);
52
+ }
53
+ }
54
+
38
55
  get directUploadUrl() {
39
56
  return this.element.dataset.directUploadUrl
40
57
  }
@@ -41,13 +41,16 @@ module ActionText
41
41
  # `strict_loading:` will be set to the value of the
42
42
  # `strict_loading_by_default` class attribute (false by default).
43
43
  #
44
+ # * `:store_if_blank` - Pass false to not create RichText records with empty values,
45
+ # if a blank value is provided. Default: true.
46
+ #
44
47
  #
45
48
  # Note: Action Text relies on polymorphic associations, which in turn store
46
49
  # class names in the database. When renaming classes that use `has_rich_text`,
47
50
  # make sure to also update the class names in the
48
51
  # `action_text_rich_texts.record_type` polymorphic type column of the
49
52
  # corresponding rows.
50
- def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default)
53
+ def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default, store_if_blank: true)
51
54
  class_eval <<-CODE, __FILE__, __LINE__ + 1
52
55
  def #{name}
53
56
  rich_text_#{name} || build_rich_text_#{name}
@@ -56,12 +59,29 @@ module ActionText
56
59
  def #{name}?
57
60
  rich_text_#{name}.present?
58
61
  end
59
-
60
- def #{name}=(body)
61
- self.#{name}.body = body
62
- end
63
62
  CODE
64
63
 
64
+ if store_if_blank
65
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
66
+ def #{name}=(body)
67
+ self.#{name}.body = body
68
+ end
69
+ CODE
70
+ else
71
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
72
+ def #{name}=(body)
73
+ if body.present?
74
+ self.#{name}.body = body
75
+ else
76
+ if #{name}?
77
+ self.#{name}.body = body
78
+ self.#{name}.mark_for_destruction
79
+ end
80
+ end
81
+ end
82
+ CODE
83
+ end
84
+
65
85
  rich_text_class_name = encrypted ? "ActionText::EncryptedRichText" : "ActionText::RichText"
66
86
  has_one :"rich_text_#{name}", -> { where(name: name) },
67
87
  class_name: rich_text_class_name, as: :record, inverse_of: :record, autosave: true, dependent: :destroy,
@@ -97,8 +97,9 @@ module ActionText
97
97
 
98
98
  def render_attachments(**options, &block)
99
99
  content = fragment.replace(ActionText::Attachment.tag_name) do |node|
100
- if node.key? "content"
101
- node["content"] = sanitize_content_attachment(node["content"])
100
+ if node.key?("content")
101
+ sanitized_content = sanitize_content_attachment(node.remove_attribute("content").to_s)
102
+ node["content"] = sanitized_content if sanitized_content.present?
102
103
  end
103
104
  block.call(attachment_for_node(node, **options))
104
105
  end
@@ -9,10 +9,10 @@ module ActionText
9
9
  end
10
10
 
11
11
  module VERSION
12
- MAJOR = 7
13
- MINOR = 2
12
+ MAJOR = 8
13
+ MINOR = 0
14
14
  TINY = 0
15
- PRE = nil
15
+ PRE = "beta1"
16
16
 
17
17
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
18
18
  end
@@ -17,42 +17,45 @@ module ActionText
17
17
  # Examples:
18
18
  #
19
19
  # # <trix-editor id="message_content" ...></trix-editor>
20
- # fill_in_rich_text_area "message_content", with: "Hello <em>world!</em>"
20
+ # fill_in_rich_textarea "message_content", with: "Hello <em>world!</em>"
21
21
  #
22
22
  # # <trix-editor placeholder="Your message here" ...></trix-editor>
23
- # fill_in_rich_text_area "Your message here", with: "Hello <em>world!</em>"
23
+ # fill_in_rich_textarea "Your message here", with: "Hello <em>world!</em>"
24
24
  #
25
25
  # # <label for="message_content">Message content</label>
26
26
  # # <trix-editor id="message_content" ...></trix-editor>
27
- # fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
27
+ # fill_in_rich_textarea "Message content", with: "Hello <em>world!</em>"
28
28
  #
29
29
  # # <trix-editor aria-label="Message content" ...></trix-editor>
30
- # fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
30
+ # fill_in_rich_textarea "Message content", with: "Hello <em>world!</em>"
31
31
  #
32
32
  # # <input id="trix_input_1" name="message[content]" type="hidden">
33
33
  # # <trix-editor input="trix_input_1"></trix-editor>
34
- # fill_in_rich_text_area "message[content]", with: "Hello <em>world!</em>"
35
- def fill_in_rich_text_area(locator = nil, with:)
36
- find(:rich_text_area, locator).execute_script("this.editor.loadHTML(arguments[0])", with.to_s)
34
+ # fill_in_rich_textarea "message[content]", with: "Hello <em>world!</em>"
35
+ def fill_in_rich_textarea(locator = nil, with:)
36
+ find(:rich_textarea, locator).execute_script("this.editor.loadHTML(arguments[0])", with.to_s)
37
37
  end
38
+ alias_method :fill_in_rich_text_area, :fill_in_rich_textarea
38
39
  end
39
40
  end
40
41
 
41
- Capybara.add_selector :rich_text_area do
42
- label "rich-text area"
43
- xpath do |locator|
44
- if locator.nil?
45
- XPath.descendant(:"trix-editor")
46
- else
47
- input_located_by_name = XPath.anywhere(:input).where(XPath.attr(:name) == locator).attr(:id)
48
- input_located_by_label = XPath.anywhere(:label).where(XPath.string.n.is(locator)).attr(:for)
42
+ %i[rich_textarea rich_text_area].each do |rich_textarea|
43
+ Capybara.add_selector rich_textarea do
44
+ label "rich-text area"
45
+ xpath do |locator|
46
+ if locator.nil?
47
+ XPath.descendant(:"trix-editor")
48
+ else
49
+ input_located_by_name = XPath.anywhere(:input).where(XPath.attr(:name) == locator).attr(:id)
50
+ input_located_by_label = XPath.anywhere(:label).where(XPath.string.n.is(locator)).attr(:for)
49
51
 
50
- XPath.descendant(:"trix-editor").where \
51
- XPath.attr(:id).equals(locator) |
52
- XPath.attr(:placeholder).equals(locator) |
53
- XPath.attr(:"aria-label").equals(locator) |
54
- XPath.attr(:input).equals(input_located_by_name) |
55
- XPath.attr(:id).equals(input_located_by_label)
52
+ XPath.descendant(:"trix-editor").where \
53
+ XPath.attr(:id).equals(locator) |
54
+ XPath.attr(:placeholder).equals(locator) |
55
+ XPath.attr(:"aria-label").equals(locator) |
56
+ XPath.attr(:input).equals(input_located_by_name) |
57
+ XPath.attr(:id).equals(input_located_by_label)
58
+ end
56
59
  end
57
60
  end
58
61
  end
@@ -36,20 +36,8 @@ module ActionText
36
36
  end
37
37
 
38
38
  def create_actiontext_files
39
- destination = Pathname(destination_root)
40
-
41
39
  template "actiontext.css", "app/assets/stylesheets/actiontext.css"
42
40
 
43
- unless destination.join("app/assets/application.css").exist?
44
- if (stylesheets = Dir.glob "#{destination_root}/app/assets/stylesheets/application.*.{scss,css}").length > 0
45
- insert_into_file stylesheets.first.to_s, %(@import 'actiontext.css';)
46
- else
47
- say <<~INSTRUCTIONS, :green
48
- To use the Trix editor, you must require 'app/assets/stylesheets/actiontext.css' in your base stylesheet.
49
- INSTRUCTIONS
50
- end
51
- end
52
-
53
41
  gem_root = "#{__dir__}/../../../.."
54
42
 
55
43
  copy_file "#{gem_root}/app/views/active_storage/blobs/_blob.html.erb",
@@ -1,11 +1,420 @@
1
1
  /*
2
- * Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
3
- * the trix-editor content (whether displayed or under editing). Feel free to incorporate this
4
- * inclusion directly in any other asset bundle and remove this file.
5
- *
6
- *= require trix
2
+ * Default Trix editor styles. See Action Text overwrites below.
7
3
  */
8
4
 
5
+ trix-editor {
6
+ border: 1px solid #bbb;
7
+ border-radius: 3px;
8
+ margin: 0;
9
+ padding: 0.4em 0.6em;
10
+ min-height: 5em;
11
+ outline: none; }
12
+
13
+ trix-toolbar * {
14
+ box-sizing: border-box; }
15
+
16
+ trix-toolbar .trix-button-row {
17
+ display: flex;
18
+ flex-wrap: nowrap;
19
+ justify-content: space-between;
20
+ overflow-x: auto; }
21
+
22
+ trix-toolbar .trix-button-group {
23
+ display: flex;
24
+ margin-bottom: 10px;
25
+ border: 1px solid #bbb;
26
+ border-top-color: #ccc;
27
+ border-bottom-color: #888;
28
+ border-radius: 3px; }
29
+ trix-toolbar .trix-button-group:not(:first-child) {
30
+ margin-left: 1.5vw; }
31
+ @media (max-width: 768px) {
32
+ trix-toolbar .trix-button-group:not(:first-child) {
33
+ margin-left: 0; } }
34
+
35
+ trix-toolbar .trix-button-group-spacer {
36
+ flex-grow: 1; }
37
+ @media (max-width: 768px) {
38
+ trix-toolbar .trix-button-group-spacer {
39
+ display: none; } }
40
+
41
+ trix-toolbar .trix-button {
42
+ position: relative;
43
+ float: left;
44
+ color: rgba(0, 0, 0, 0.6);
45
+ font-size: 0.75em;
46
+ font-weight: 600;
47
+ white-space: nowrap;
48
+ padding: 0 0.5em;
49
+ margin: 0;
50
+ outline: none;
51
+ border: none;
52
+ border-bottom: 1px solid #ddd;
53
+ border-radius: 0;
54
+ background: transparent; }
55
+ trix-toolbar .trix-button:not(:first-child) {
56
+ border-left: 1px solid #ccc; }
57
+ trix-toolbar .trix-button.trix-active {
58
+ background: #cbeefa;
59
+ color: black; }
60
+ trix-toolbar .trix-button:not(:disabled) {
61
+ cursor: pointer; }
62
+ trix-toolbar .trix-button:disabled {
63
+ color: rgba(0, 0, 0, 0.125); }
64
+ @media (max-width: 768px) {
65
+ trix-toolbar .trix-button {
66
+ letter-spacing: -0.01em;
67
+ padding: 0 0.3em; } }
68
+
69
+ trix-toolbar .trix-button--icon {
70
+ font-size: inherit;
71
+ width: 2.6em;
72
+ height: 1.6em;
73
+ max-width: calc(0.8em + 4vw);
74
+ text-indent: -9999px; }
75
+ @media (max-width: 768px) {
76
+ trix-toolbar .trix-button--icon {
77
+ height: 2em;
78
+ max-width: calc(0.8em + 3.5vw); } }
79
+ trix-toolbar .trix-button--icon::before {
80
+ display: inline-block;
81
+ position: absolute;
82
+ top: 0;
83
+ right: 0;
84
+ bottom: 0;
85
+ left: 0;
86
+ opacity: 0.6;
87
+ content: "";
88
+ background-position: center;
89
+ background-repeat: no-repeat;
90
+ background-size: contain; }
91
+ @media (max-width: 768px) {
92
+ trix-toolbar .trix-button--icon::before {
93
+ right: 6%;
94
+ left: 6%; } }
95
+ trix-toolbar .trix-button--icon.trix-active::before {
96
+ opacity: 1; }
97
+ trix-toolbar .trix-button--icon:disabled::before {
98
+ opacity: 0.125; }
99
+
100
+ trix-toolbar .trix-button--icon-attach::before {
101
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M10.5%2018V7.5c0-2.25%203-2.25%203%200V18c0%204.125-6%204.125-6%200V7.5c0-6.375%209-6.375%209%200V18%22%20stroke%3D%22%23000%22%20stroke-width%3D%222%22%20stroke-miterlimit%3D%2210%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E");
102
+ top: 8%;
103
+ bottom: 4%; }
104
+
105
+ trix-toolbar .trix-button--icon-bold::before {
106
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M6.522%2019.242a.5.5%200%200%201-.5-.5V5.35a.5.5%200%200%201%20.5-.5h5.783c1.347%200%202.46.345%203.24.982.783.64%201.216%201.562%201.216%202.683%200%201.13-.587%202.129-1.476%202.71a.35.35%200%200%200%20.049.613c1.259.56%202.101%201.742%202.101%203.22%200%201.282-.483%202.334-1.363%203.063-.876.726-2.132%201.12-3.66%201.12h-5.89ZM9.27%207.347v3.362h1.97c.766%200%201.347-.17%201.733-.464.38-.291.587-.716.587-1.27%200-.53-.183-.928-.513-1.198-.334-.273-.838-.43-1.505-.43H9.27Zm0%205.606v3.791h2.389c.832%200%201.448-.177%201.853-.497.399-.315.614-.786.614-1.423%200-.62-.22-1.077-.63-1.385-.418-.313-1.053-.486-1.905-.486H9.27Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
107
+
108
+ trix-toolbar .trix-button--icon-italic::before {
109
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M9%205h6.5v2h-2.23l-2.31%2010H13v2H6v-2h2.461l2.306-10H9V5Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
110
+
111
+ trix-toolbar .trix-button--icon-link::before {
112
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M18.948%205.258a4.337%204.337%200%200%200-6.108%200L11.217%206.87a.993.993%200%200%200%200%201.41c.392.39%201.027.39%201.418%200l1.623-1.613a2.323%202.323%200%200%201%203.271%200%202.29%202.29%200%200%201%200%203.251l-2.393%202.38a3.021%203.021%200%200%201-4.255%200l-.05-.049a1.007%201.007%200%200%200-1.418%200%20.993.993%200%200%200%200%201.41l.05.049a5.036%205.036%200%200%200%207.091%200l2.394-2.38a4.275%204.275%200%200%200%200-6.072Zm-13.683%2013.6a4.337%204.337%200%200%200%206.108%200l1.262-1.255a.993.993%200%200%200%200-1.41%201.007%201.007%200%200%200-1.418%200L9.954%2017.45a2.323%202.323%200%200%201-3.27%200%202.29%202.29%200%200%201%200-3.251l2.344-2.331a2.579%202.579%200%200%201%203.631%200c.392.39%201.027.39%201.419%200a.993.993%200%200%200%200-1.41%204.593%204.593%200%200%200-6.468%200l-2.345%202.33a4.275%204.275%200%200%200%200%206.072Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
113
+
114
+ trix-toolbar .trix-button--icon-strike::before {
115
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M6%2014.986c.088%202.647%202.246%204.258%205.635%204.258%203.496%200%205.713-1.728%205.713-4.463%200-.275-.02-.536-.062-.781h-3.461c.398.293.573.654.573%201.123%200%201.035-1.074%201.787-2.646%201.787-1.563%200-2.773-.762-2.91-1.924H6ZM6.432%2010h3.763c-.632-.314-.914-.715-.914-1.273%200-1.045.977-1.739%202.432-1.739%201.475%200%202.52.723%202.617%201.914h2.764c-.05-2.548-2.11-4.238-5.39-4.238-3.145%200-5.392%201.719-5.392%204.316%200%20.363.04.703.12%201.02ZM4%2011a1%201%200%201%200%200%202h15a1%201%200%201%200%200-2H4Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
116
+
117
+ trix-toolbar .trix-button--icon-quote::before {
118
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M4.581%208.471c.44-.5%201.056-.834%201.758-.995C8.074%207.17%209.201%207.822%2010%208.752c1.354%201.578%201.33%203.555.394%205.277-.941%201.731-2.788%203.163-4.988%203.56a.622.622%200%200%201-.653-.317c-.113-.205-.121-.49.16-.764.294-.286.567-.566.791-.835.222-.266.413-.54.524-.815.113-.28.156-.597.026-.908-.128-.303-.39-.524-.72-.69a3.02%203.02%200%200%201-1.674-2.7c0-.905.283-1.59.72-2.088Zm9.419%200c.44-.5%201.055-.834%201.758-.995%201.734-.306%202.862.346%203.66%201.276%201.355%201.578%201.33%203.555.395%205.277-.941%201.731-2.789%203.163-4.988%203.56a.622.622%200%200%201-.653-.317c-.113-.205-.122-.49.16-.764.294-.286.567-.566.791-.835.222-.266.412-.54.523-.815.114-.28.157-.597.026-.908-.127-.303-.39-.524-.72-.69a3.02%203.02%200%200%201-1.672-2.701c0-.905.283-1.59.72-2.088Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
119
+
120
+ trix-toolbar .trix-button--icon-heading-1::before {
121
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M21.5%207.5v-3h-12v3H14v13h3v-13h4.5ZM9%2013.5h3.5v-3h-10v3H6v7h3v-7Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
122
+
123
+ trix-toolbar .trix-button--icon-code::before {
124
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M3.293%2011.293a1%201%200%200%200%200%201.414l4%204a1%201%200%201%200%201.414-1.414L5.414%2012l3.293-3.293a1%201%200%200%200-1.414-1.414l-4%204Zm13.414%205.414%204-4a1%201%200%200%200%200-1.414l-4-4a1%201%200%201%200-1.414%201.414L18.586%2012l-3.293%203.293a1%201%200%200%200%201.414%201.414Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
125
+
126
+ trix-toolbar .trix-button--icon-bullet-list::before {
127
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M5%207.5a1.5%201.5%200%201%200%200-3%201.5%201.5%200%200%200%200%203ZM8%206a1%201%200%200%201%201-1h11a1%201%200%201%201%200%202H9a1%201%200%200%201-1-1Zm1%205a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm0%206a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm-2.5-5a1.5%201.5%200%201%201-3%200%201.5%201.5%200%200%201%203%200ZM5%2019.5a1.5%201.5%200%201%200%200-3%201.5%201.5%200%200%200%200%203Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
128
+
129
+ trix-toolbar .trix-button--icon-number-list::before {
130
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M3%204h2v4H4V5H3V4Zm5%202a1%201%200%200%201%201-1h11a1%201%200%201%201%200%202H9a1%201%200%200%201-1-1Zm1%205a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm0%206a1%201%200%201%200%200%202h11a1%201%200%201%200%200-2H9Zm-3.5-7H6v1l-1.5%202H6v1H3v-1l1.667-2H3v-1h2.5ZM3%2017v-1h3v4H3v-1h2v-.5H4v-1h1V17H3Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
131
+
132
+ trix-toolbar .trix-button--icon-undo::before {
133
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M3%2014a1%201%200%200%200%201%201h6a1%201%200%201%200%200-2H6.257c2.247-2.764%205.151-3.668%207.579-3.264%202.589.432%204.739%202.356%205.174%205.405a1%201%200%200%200%201.98-.283c-.564-3.95-3.415-6.526-6.825-7.095C11.084%207.25%207.63%208.377%205%2011.39V8a1%201%200%200%200-2%200v6Zm2-1Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
134
+
135
+ trix-toolbar .trix-button--icon-redo::before {
136
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M21%2014a1%201%200%200%201-1%201h-6a1%201%200%201%201%200-2h3.743c-2.247-2.764-5.151-3.668-7.579-3.264-2.589.432-4.739%202.356-5.174%205.405a1%201%200%200%201-1.98-.283c.564-3.95%203.415-6.526%206.826-7.095%203.08-.513%206.534.614%209.164%203.626V8a1%201%200%201%201%202%200v6Zm-2-1Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
137
+
138
+ trix-toolbar .trix-button--icon-decrease-nesting-level::before {
139
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M5%206a1%201%200%200%201%201-1h12a1%201%200%201%201%200%202H6a1%201%200%200%201-1-1Zm4%205a1%201%200%201%200%200%202h9a1%201%200%201%200%200-2H9Zm-3%206a1%201%200%201%200%200%202h12a1%201%200%201%200%200-2H6Zm-3.707-5.707a1%201%200%200%200%200%201.414l2%202a1%201%200%201%200%201.414-1.414L4.414%2012l1.293-1.293a1%201%200%200%200-1.414-1.414l-2%202Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
140
+
141
+ trix-toolbar .trix-button--icon-increase-nesting-level::before {
142
+ background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M5%206a1%201%200%200%201%201-1h12a1%201%200%201%201%200%202H6a1%201%200%200%201-1-1Zm4%205a1%201%200%201%200%200%202h9a1%201%200%201%200%200-2H9Zm-3%206a1%201%200%201%200%200%202h12a1%201%200%201%200%200-2H6Zm-2.293-2.293%202-2a1%201%200%200%200%200-1.414l-2-2a1%201%200%201%200-1.414%201.414L3.586%2012l-1.293%201.293a1%201%200%201%200%201.414%201.414Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); }
143
+
144
+ trix-toolbar .trix-dialogs {
145
+ position: relative; }
146
+
147
+ trix-toolbar .trix-dialog {
148
+ position: absolute;
149
+ top: 0;
150
+ left: 0;
151
+ right: 0;
152
+ font-size: 0.75em;
153
+ padding: 15px 10px;
154
+ background: #fff;
155
+ box-shadow: 0 0.3em 1em #ccc;
156
+ border-top: 2px solid #888;
157
+ border-radius: 5px;
158
+ z-index: 5; }
159
+
160
+ trix-toolbar .trix-input--dialog {
161
+ font-size: inherit;
162
+ font-weight: normal;
163
+ padding: 0.5em 0.8em;
164
+ margin: 0 10px 0 0;
165
+ border-radius: 3px;
166
+ border: 1px solid #bbb;
167
+ background-color: #fff;
168
+ box-shadow: none;
169
+ outline: none;
170
+ -webkit-appearance: none;
171
+ -moz-appearance: none; }
172
+ trix-toolbar .trix-input--dialog.validate:invalid {
173
+ box-shadow: #F00 0px 0px 1.5px 1px; }
174
+
175
+ trix-toolbar .trix-button--dialog {
176
+ font-size: inherit;
177
+ padding: 0.5em;
178
+ border-bottom: none; }
179
+
180
+ trix-toolbar .trix-dialog--link {
181
+ max-width: 600px; }
182
+
183
+ trix-toolbar .trix-dialog__link-fields {
184
+ display: flex;
185
+ align-items: baseline; }
186
+ trix-toolbar .trix-dialog__link-fields .trix-input {
187
+ flex: 1; }
188
+ trix-toolbar .trix-dialog__link-fields .trix-button-group {
189
+ flex: 0 0 content;
190
+ margin: 0; }
191
+
192
+ trix-editor [data-trix-mutable]:not(.attachment__caption-editor) {
193
+ -webkit-user-select: none;
194
+ -moz-user-select: none;
195
+ -ms-user-select: none;
196
+ user-select: none; }
197
+
198
+ trix-editor [data-trix-mutable]::-moz-selection,
199
+ trix-editor [data-trix-cursor-target]::-moz-selection, trix-editor [data-trix-mutable] ::-moz-selection {
200
+ background: none; }
201
+
202
+ trix-editor [data-trix-mutable]::selection,
203
+ trix-editor [data-trix-cursor-target]::selection, trix-editor [data-trix-mutable] ::selection {
204
+ background: none; }
205
+
206
+ trix-editor .attachment__caption-editor:focus[data-trix-mutable]::-moz-selection {
207
+ background: highlight; }
208
+
209
+ trix-editor .attachment__caption-editor:focus[data-trix-mutable]::selection {
210
+ background: highlight; }
211
+
212
+ trix-editor [data-trix-mutable].attachment.attachment--file {
213
+ box-shadow: 0 0 0 2px highlight;
214
+ border-color: transparent; }
215
+
216
+ trix-editor [data-trix-mutable].attachment img {
217
+ box-shadow: 0 0 0 2px highlight; }
218
+
219
+ trix-editor .attachment {
220
+ position: relative; }
221
+ trix-editor .attachment:hover {
222
+ cursor: default; }
223
+
224
+ trix-editor .attachment--preview .attachment__caption:hover {
225
+ cursor: text; }
226
+
227
+ trix-editor .attachment__progress {
228
+ position: absolute;
229
+ z-index: 1;
230
+ height: 20px;
231
+ top: calc(50% - 10px);
232
+ left: 5%;
233
+ width: 90%;
234
+ opacity: 0.9;
235
+ transition: opacity 200ms ease-in; }
236
+ trix-editor .attachment__progress[value="100"] {
237
+ opacity: 0; }
238
+
239
+ trix-editor .attachment__caption-editor {
240
+ display: inline-block;
241
+ width: 100%;
242
+ margin: 0;
243
+ padding: 0;
244
+ font-size: inherit;
245
+ font-family: inherit;
246
+ line-height: inherit;
247
+ color: inherit;
248
+ text-align: center;
249
+ vertical-align: top;
250
+ border: none;
251
+ outline: none;
252
+ -webkit-appearance: none;
253
+ -moz-appearance: none; }
254
+
255
+ trix-editor .attachment__toolbar {
256
+ position: absolute;
257
+ z-index: 1;
258
+ top: -0.9em;
259
+ left: 0;
260
+ width: 100%;
261
+ text-align: center; }
262
+
263
+ trix-editor .trix-button-group {
264
+ display: inline-flex; }
265
+
266
+ trix-editor .trix-button {
267
+ position: relative;
268
+ float: left;
269
+ color: #666;
270
+ white-space: nowrap;
271
+ font-size: 80%;
272
+ padding: 0 0.8em;
273
+ margin: 0;
274
+ outline: none;
275
+ border: none;
276
+ border-radius: 0;
277
+ background: transparent; }
278
+ trix-editor .trix-button:not(:first-child) {
279
+ border-left: 1px solid #ccc; }
280
+ trix-editor .trix-button.trix-active {
281
+ background: #cbeefa; }
282
+ trix-editor .trix-button:not(:disabled) {
283
+ cursor: pointer; }
284
+
285
+ trix-editor .trix-button--remove {
286
+ text-indent: -9999px;
287
+ display: inline-block;
288
+ padding: 0;
289
+ outline: none;
290
+ width: 1.8em;
291
+ height: 1.8em;
292
+ line-height: 1.8em;
293
+ border-radius: 50%;
294
+ background-color: #fff;
295
+ border: 2px solid highlight;
296
+ box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.25); }
297
+ trix-editor .trix-button--remove::before {
298
+ display: inline-block;
299
+ position: absolute;
300
+ top: 0;
301
+ right: 0;
302
+ bottom: 0;
303
+ left: 0;
304
+ opacity: 0.7;
305
+ content: "";
306
+ background-image: url("data:image/svg+xml,%3Csvg%20height%3D%2224%22%20width%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M19%206.41%2017.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22%2F%3E%3Cpath%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%3C%2Fsvg%3E");
307
+ background-position: center;
308
+ background-repeat: no-repeat;
309
+ background-size: 90%; }
310
+ trix-editor .trix-button--remove:hover {
311
+ border-color: #333; }
312
+ trix-editor .trix-button--remove:hover::before {
313
+ opacity: 1; }
314
+
315
+ trix-editor .attachment__metadata-container {
316
+ position: relative; }
317
+
318
+ trix-editor .attachment__metadata {
319
+ position: absolute;
320
+ left: 50%;
321
+ top: 2em;
322
+ transform: translate(-50%, 0);
323
+ max-width: 90%;
324
+ padding: 0.1em 0.6em;
325
+ font-size: 0.8em;
326
+ color: #fff;
327
+ background-color: rgba(0, 0, 0, 0.7);
328
+ border-radius: 3px; }
329
+ trix-editor .attachment__metadata .attachment__name {
330
+ display: inline-block;
331
+ max-width: 100%;
332
+ vertical-align: bottom;
333
+ overflow: hidden;
334
+ text-overflow: ellipsis;
335
+ white-space: nowrap; }
336
+ trix-editor .attachment__metadata .attachment__size {
337
+ margin-left: 0.2em;
338
+ white-space: nowrap; }
339
+
340
+ .trix-content {
341
+ line-height: 1.5;
342
+ overflow-wrap: break-word;
343
+ word-break: break-word; }
344
+ .trix-content * {
345
+ box-sizing: border-box;
346
+ margin: 0;
347
+ padding: 0; }
348
+ .trix-content h1 {
349
+ font-size: 1.2em;
350
+ line-height: 1.2; }
351
+ .trix-content blockquote {
352
+ border: 0 solid #ccc;
353
+ border-left-width: 0.3em;
354
+ margin-left: 0.3em;
355
+ padding-left: 0.6em; }
356
+ .trix-content [dir=rtl] blockquote,
357
+ .trix-content blockquote[dir=rtl] {
358
+ border-width: 0;
359
+ border-right-width: 0.3em;
360
+ margin-right: 0.3em;
361
+ padding-right: 0.6em; }
362
+ .trix-content li {
363
+ margin-left: 1em; }
364
+ .trix-content [dir=rtl] li {
365
+ margin-right: 1em; }
366
+ .trix-content pre {
367
+ display: inline-block;
368
+ width: 100%;
369
+ vertical-align: top;
370
+ font-family: monospace;
371
+ font-size: 0.9em;
372
+ padding: 0.5em;
373
+ white-space: pre;
374
+ background-color: #eee;
375
+ overflow-x: auto; }
376
+ .trix-content img {
377
+ max-width: 100%;
378
+ height: auto; }
379
+ .trix-content .attachment {
380
+ display: inline-block;
381
+ position: relative;
382
+ max-width: 100%; }
383
+ .trix-content .attachment a {
384
+ color: inherit;
385
+ text-decoration: none; }
386
+ .trix-content .attachment a:hover, .trix-content .attachment a:visited:hover {
387
+ color: inherit; }
388
+ .trix-content .attachment__caption {
389
+ text-align: center; }
390
+ .trix-content .attachment__caption .attachment__name + .attachment__size::before {
391
+ content: ' \2022 '; }
392
+ .trix-content .attachment--preview {
393
+ width: 100%;
394
+ text-align: center; }
395
+ .trix-content .attachment--preview .attachment__caption {
396
+ color: #666;
397
+ font-size: 0.9em;
398
+ line-height: 1.2; }
399
+ .trix-content .attachment--file {
400
+ color: #333;
401
+ line-height: 1;
402
+ margin: 0 2px 2px 2px;
403
+ padding: 0.4em 1em;
404
+ border: 1px solid #bbb;
405
+ border-radius: 5px; }
406
+ .trix-content .attachment-gallery {
407
+ display: flex;
408
+ flex-wrap: wrap;
409
+ position: relative; }
410
+ .trix-content .attachment-gallery .attachment {
411
+ flex: 1 0 33%;
412
+ padding: 0 0.5em;
413
+ max-width: 33%; }
414
+ .trix-content .attachment-gallery.attachment-gallery--2 .attachment, .trix-content .attachment-gallery.attachment-gallery--4 .attachment {
415
+ flex-basis: 50%;
416
+ max-width: 50%; }
417
+
9
418
  /*
10
419
  * We need to override trix.css’s image gallery styles to accommodate the
11
420
  * <action-text-attachment> element we wrap around attachments. Otherwise,
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rails/actiontext",
3
- "version": "7.2.0",
3
+ "version": "8.0.0-beta1",
4
4
  "description": "Edit and display rich text in Rails applications",
5
5
  "module": "app/assets/javascripts/actiontext.esm.js",
6
6
  "main": "app/assets/javascripts/actiontext.js",
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@rails/activestorage": ">= 7.2.0-alpha"
25
+ "@rails/activestorage": ">= 8.0.0-alpha"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "trix": "^2.0.0"
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actiontext
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0
4
+ version: 8.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javan Makhmali
8
8
  - Sam Stephenson
9
9
  - David Heinemeier Hansson
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-08-09 00:00:00.000000000 Z
13
+ date: 2024-09-26 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.2.0
21
+ version: 8.0.0.beta1
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.2.0
28
+ version: 8.0.0.beta1
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.2.0
35
+ version: 8.0.0.beta1
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.2.0
42
+ version: 8.0.0.beta1
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.2.0
49
+ version: 8.0.0.beta1
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.2.0
56
+ version: 8.0.0.beta1
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.2.0
63
+ version: 8.0.0.beta1
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.2.0
70
+ version: 8.0.0.beta1
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: nokogiri
73
73
  requirement: !ruby/object:Gem::Requirement
@@ -163,12 +163,12 @@ licenses:
163
163
  - MIT
164
164
  metadata:
165
165
  bug_tracker_uri: https://github.com/rails/rails/issues
166
- changelog_uri: https://github.com/rails/rails/blob/v7.2.0/actiontext/CHANGELOG.md
167
- documentation_uri: https://api.rubyonrails.org/v7.2.0/
166
+ changelog_uri: https://github.com/rails/rails/blob/v8.0.0.beta1/actiontext/CHANGELOG.md
167
+ documentation_uri: https://api.rubyonrails.org/v8.0.0.beta1/
168
168
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
169
- source_code_uri: https://github.com/rails/rails/tree/v7.2.0/actiontext
169
+ source_code_uri: https://github.com/rails/rails/tree/v8.0.0.beta1/actiontext
170
170
  rubygems_mfa_required: 'true'
171
- post_install_message:
171
+ post_install_message:
172
172
  rdoc_options: []
173
173
  require_paths:
174
174
  - lib
@@ -176,15 +176,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
176
176
  requirements:
177
177
  - - ">="
178
178
  - !ruby/object:Gem::Version
179
- version: 3.1.0
179
+ version: 3.2.0
180
180
  required_rubygems_version: !ruby/object:Gem::Requirement
181
181
  requirements:
182
182
  - - ">="
183
183
  - !ruby/object:Gem::Version
184
184
  version: '0'
185
185
  requirements: []
186
- rubygems_version: 3.5.11
187
- signing_key:
186
+ rubygems_version: 3.5.16
187
+ signing_key:
188
188
  specification_version: 4
189
189
  summary: Rich text framework.
190
190
  test_files: []