actiontext 7.1.3.2 → 7.2.0.beta1
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 +21 -88
- data/app/assets/javascripts/actiontext.esm.js +3 -3
- data/app/assets/javascripts/actiontext.js +3 -3
- data/app/assets/javascripts/trix.js +92 -30
- data/app/assets/stylesheets/trix.css +3 -1
- data/app/helpers/action_text/content_helper.rb +2 -0
- data/app/helpers/action_text/tag_helper.rb +38 -28
- data/app/models/action_text/encrypted_rich_text.rb +2 -2
- data/app/models/action_text/record.rb +2 -0
- data/app/models/action_text/rich_text.rb +58 -26
- data/db/migrate/20180528164100_create_action_text_tables.rb +1 -1
- data/lib/action_text/attachable.rb +35 -33
- data/lib/action_text/attachables/content_attachment.rb +2 -0
- data/lib/action_text/attachables/missing_attachable.rb +2 -0
- data/lib/action_text/attachables/remote_image.rb +2 -0
- data/lib/action_text/attachment.rb +27 -25
- data/lib/action_text/attachment_gallery.rb +2 -0
- data/lib/action_text/attachments/caching.rb +2 -0
- data/lib/action_text/attachments/minification.rb +2 -0
- data/lib/action_text/attachments/trix_conversion.rb +2 -0
- data/lib/action_text/attribute.rb +36 -22
- data/lib/action_text/content.rb +46 -26
- data/lib/action_text/deprecator.rb +2 -0
- data/lib/action_text/encryption.rb +2 -0
- data/lib/action_text/engine.rb +2 -0
- data/lib/action_text/fixture_set.rb +34 -34
- data/lib/action_text/fragment.rb +4 -0
- data/lib/action_text/gem_version.rb +6 -4
- data/lib/action_text/html_conversion.rb +2 -0
- data/lib/action_text/plain_text_conversion.rb +2 -0
- data/lib/action_text/rendering.rb +2 -0
- data/lib/action_text/serialization.rb +2 -0
- data/lib/action_text/system_test_helper.rb +20 -17
- data/lib/action_text/trix_attachment.rb +2 -0
- data/lib/action_text/version.rb +3 -1
- data/lib/action_text.rb +1 -1
- data/lib/generators/action_text/install/install_generator.rb +10 -3
- data/lib/rails/generators/test_unit/install_generator.rb +2 -0
- data/package.json +1 -1
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d497d50205633b66005bfcfe850ee8d5404c0b3b9f953a14356bb912c8b3b4d5
|
4
|
+
data.tar.gz: '099e3d4dca02f13983f06b8ffcf6c49a1bb2f3cb66ae94e8534c0764f8b56700'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9acfe56af6ec22cf0448fc42c7dc3cba769bbbce316efa926869ac083db8491a547366ae5beede3da8a02b75c1cbb6f7a8e252c0519fbd7c282af841835a644
|
7
|
+
data.tar.gz: 9beaaede36bf8158e2fee2e6d5f2fb02dbaabeb86a279ee7ca0e9ef87b5cc710d3ea454ae3e8723235eb8b2d2bc2586e540f89623c2609fd3620207e2785c042
|
data/CHANGELOG.md
CHANGED
@@ -1,21 +1,32 @@
|
|
1
|
-
## Rails 7.
|
1
|
+
## Rails 7.2.0.beta1 (May 29, 2024) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Use `includes` instead of `eager_load` for `with_all_rich_text`.
|
4
4
|
|
5
|
+
*Petrik de Heus*
|
5
6
|
|
6
|
-
|
7
|
+
* Delegate `ActionText::Content#deconstruct` to `Nokogiri::XML::DocumentFragment#elements`.
|
7
8
|
|
8
|
-
|
9
|
+
```ruby
|
10
|
+
content = ActionText::Content.new <<~HTML
|
11
|
+
<h1>Hello, world</h1>
|
9
12
|
|
13
|
+
<div>The body</div>
|
14
|
+
HTML
|
10
15
|
|
11
|
-
|
16
|
+
content => [h1, div]
|
12
17
|
|
13
|
-
|
18
|
+
assert_pattern { h1 => { content: "Hello, world" } }
|
19
|
+
assert_pattern { div => { content: "The body" } }
|
20
|
+
```
|
14
21
|
|
22
|
+
*Sean Doyle*
|
23
|
+
|
24
|
+
* Fix all Action Text database related models to respect
|
25
|
+
`ActiveRecord::Base.table_name_prefix` configuration.
|
15
26
|
|
16
|
-
|
27
|
+
*Chedli Bourguiba*
|
17
28
|
|
18
|
-
* Compile ESM package that can be used directly in the browser as
|
29
|
+
* Compile ESM package that can be used directly in the browser as actiontext.esm.js
|
19
30
|
|
20
31
|
*Matias Grunberg*
|
21
32
|
|
@@ -23,7 +34,7 @@
|
|
23
34
|
|
24
35
|
*Matias Grunberg*
|
25
36
|
|
26
|
-
* Upgrade Trix to 2.0.7
|
37
|
+
* Upgrade Trix to 2.0.7
|
27
38
|
|
28
39
|
*Hartley McGuire*
|
29
40
|
|
@@ -31,82 +42,4 @@
|
|
31
42
|
|
32
43
|
*Hartley McGuire*
|
33
44
|
|
34
|
-
|
35
|
-
## Rails 7.1.1 (October 11, 2023) ##
|
36
|
-
|
37
|
-
* No changes.
|
38
|
-
|
39
|
-
|
40
|
-
## Rails 7.1.0 (October 05, 2023) ##
|
41
|
-
|
42
|
-
* No changes.
|
43
|
-
|
44
|
-
|
45
|
-
## Rails 7.1.0.rc2 (October 01, 2023) ##
|
46
|
-
|
47
|
-
* No changes.
|
48
|
-
|
49
|
-
|
50
|
-
## Rails 7.1.0.rc1 (September 27, 2023) ##
|
51
|
-
|
52
|
-
* No changes.
|
53
|
-
|
54
|
-
|
55
|
-
## Rails 7.1.0.beta1 (September 13, 2023) ##
|
56
|
-
|
57
|
-
* Use `Rails::HTML5::SafeListSanitizer` by default in the Rails 7.1 configuration if it is
|
58
|
-
supported.
|
59
|
-
|
60
|
-
Action Text's sanitizer can be configured by setting
|
61
|
-
`config.action_text.sanitizer_vendor`. Supported values are `Rails::HTML4::Sanitizer` or
|
62
|
-
`Rails::HTML5::Sanitizer`.
|
63
|
-
|
64
|
-
The Rails 7.1 configuration will set this to `Rails::HTML5::Sanitizer` when it is supported, and
|
65
|
-
fall back to `Rails::HTML4::Sanitizer`. Previous configurations default to
|
66
|
-
`Rails::HTML4::Sanitizer`.
|
67
|
-
|
68
|
-
As a result of this change, the defaults for `ActionText::ContentHelper.allowed_tags` and
|
69
|
-
`.allowed_attributes` are applied at runtime, so the value of these attributes is now 'nil'
|
70
|
-
unless set by the application. You may call `sanitizer_allowed_tags` or
|
71
|
-
`sanitizer_allowed_attributes` to inspect the tags and attributes being allowed by the
|
72
|
-
sanitizer.
|
73
|
-
|
74
|
-
*Mike Dalessio*
|
75
|
-
|
76
|
-
* Attachables now can override default attachment missing template.
|
77
|
-
|
78
|
-
When rendering Action Text attachments where the underlying attachable model has
|
79
|
-
been removed, a fallback template is used. You now can override this template on
|
80
|
-
a per-model basis. For example, you could render a placeholder image for a file
|
81
|
-
attachment or the text "Deleted User" for a User attachment.
|
82
|
-
|
83
|
-
*Matt Swanson*, *Joel Drapper*
|
84
|
-
|
85
|
-
* Update bundled Trix version from `1.3.1` to `2.0.4`.
|
86
|
-
|
87
|
-
*Sarah Ridge*, *Sean Doyle*
|
88
|
-
|
89
|
-
* Apply `field_error_proc` to `rich_text_area` form fields.
|
90
|
-
|
91
|
-
*Kaíque Kandy Koga*
|
92
|
-
|
93
|
-
* Action Text attachment URLs rendered in a background job (a la Turbo
|
94
|
-
Streams) now use `Rails.application.default_url_options` and
|
95
|
-
`Rails.application.config.force_ssl` instead of `http://example.org`.
|
96
|
-
|
97
|
-
*Jonathan Hefner*
|
98
|
-
|
99
|
-
* Support `strict_loading:` option for `has_rich_text` declaration
|
100
|
-
|
101
|
-
*Sean Doyle*
|
102
|
-
|
103
|
-
* Update ContentAttachment so that it can encapsulate arbitrary HTML content in a document.
|
104
|
-
|
105
|
-
*Jamis Buck*
|
106
|
-
|
107
|
-
* Fix an issue that caused the content layout to render multiple times when a
|
108
|
-
rich_text field was updated.
|
109
|
-
|
110
|
-
*Jacob Herrington*
|
111
|
-
|
112
|
-
Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/actiontext/CHANGELOG.md) for previous changes.
|
45
|
+
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/actiontext/CHANGELOG.md) for previous changes.
|
@@ -771,9 +771,9 @@ function start() {
|
|
771
771
|
}
|
772
772
|
|
773
773
|
function didClick(event) {
|
774
|
-
const
|
775
|
-
if (
|
776
|
-
submitButtonsByForm.set(
|
774
|
+
const {target: target} = event;
|
775
|
+
if ((target.tagName == "INPUT" || target.tagName == "BUTTON") && target.type == "submit" && target.form) {
|
776
|
+
submitButtonsByForm.set(target.form, target);
|
777
777
|
}
|
778
778
|
}
|
779
779
|
|
@@ -753,9 +753,9 @@
|
|
753
753
|
}
|
754
754
|
}
|
755
755
|
function didClick(event) {
|
756
|
-
const
|
757
|
-
if (
|
758
|
-
submitButtonsByForm.set(
|
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
759
|
}
|
760
760
|
}
|
761
761
|
function didSubmitForm(event) {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
|
-
Trix 2.
|
3
|
-
Copyright ©
|
2
|
+
Trix 2.1.1
|
3
|
+
Copyright © 2024 37signals, LLC
|
4
4
|
*/
|
5
5
|
(function (global, factory) {
|
6
6
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
@@ -9,7 +9,7 @@ Copyright © 2023 37signals, LLC
|
|
9
9
|
})(this, (function () { 'use strict';
|
10
10
|
|
11
11
|
var name = "trix";
|
12
|
-
var version = "2.
|
12
|
+
var version = "2.1.1";
|
13
13
|
var description = "A rich text editor for everyday writing";
|
14
14
|
var main = "dist/trix.umd.min.js";
|
15
15
|
var module = "dist/trix.esm.min.js";
|
@@ -17,6 +17,7 @@ Copyright © 2023 37signals, LLC
|
|
17
17
|
var files = [
|
18
18
|
"dist/*.css",
|
19
19
|
"dist/*.js",
|
20
|
+
"dist/*.map",
|
20
21
|
"src/{inspector,trix}/*.js"
|
21
22
|
];
|
22
23
|
var repository = {
|
@@ -130,6 +131,7 @@ Copyright © 2023 37signals, LLC
|
|
130
131
|
code: {
|
131
132
|
tagName: "pre",
|
132
133
|
terminal: true,
|
134
|
+
htmlAttributes: ["language"],
|
133
135
|
text: {
|
134
136
|
plaintext: true
|
135
137
|
}
|
@@ -1215,7 +1217,7 @@ $\
|
|
1215
1217
|
no-useless-escape,
|
1216
1218
|
*/
|
1217
1219
|
const normalizeSpaces = string => string.replace(new RegExp("".concat(ZERO_WIDTH_SPACE), "g"), "").replace(new RegExp("".concat(NON_BREAKING_SPACE), "g"), " ");
|
1218
|
-
const normalizeNewlines = string => string.replace(/\r\n
|
1220
|
+
const normalizeNewlines = string => string.replace(/\r\n?/g, "\n");
|
1219
1221
|
const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]"));
|
1220
1222
|
const squishBreakableWhitespace = string => string
|
1221
1223
|
// Replace all breakable whitespace characters with a space
|
@@ -2144,20 +2146,28 @@ $\
|
|
2144
2146
|
}
|
2145
2147
|
}
|
2146
2148
|
createContainerElement(depth) {
|
2147
|
-
|
2149
|
+
const attributes = {};
|
2150
|
+
let className;
|
2148
2151
|
const attributeName = this.attributes[depth];
|
2149
2152
|
const {
|
2150
|
-
tagName
|
2153
|
+
tagName,
|
2154
|
+
htmlAttributes = []
|
2151
2155
|
} = getBlockConfig(attributeName);
|
2152
2156
|
if (depth === 0 && this.block.isRTL()) {
|
2153
|
-
attributes
|
2157
|
+
Object.assign(attributes, {
|
2154
2158
|
dir: "rtl"
|
2155
|
-
};
|
2159
|
+
});
|
2156
2160
|
}
|
2157
2161
|
if (attributeName === "attachmentGallery") {
|
2158
2162
|
const size = this.block.getBlockBreakPosition();
|
2159
2163
|
className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size);
|
2160
2164
|
}
|
2165
|
+
Object.entries(this.block.htmlAttributes).forEach(_ref => {
|
2166
|
+
let [name, value] = _ref;
|
2167
|
+
if (htmlAttributes.includes(name)) {
|
2168
|
+
attributes[name] = value;
|
2169
|
+
}
|
2170
|
+
});
|
2161
2171
|
return makeElement({
|
2162
2172
|
tagName,
|
2163
2173
|
className,
|
@@ -5828,28 +5838,29 @@ $\
|
|
5828
5838
|
class Block extends TrixObject {
|
5829
5839
|
static fromJSON(blockJSON) {
|
5830
5840
|
const text = Text.fromJSON(blockJSON.text);
|
5831
|
-
return new this(text, blockJSON.attributes);
|
5841
|
+
return new this(text, blockJSON.attributes, blockJSON.htmlAttributes);
|
5832
5842
|
}
|
5833
|
-
constructor(text, attributes) {
|
5843
|
+
constructor(text, attributes, htmlAttributes) {
|
5834
5844
|
super(...arguments);
|
5835
5845
|
this.text = applyBlockBreakToText(text || new Text());
|
5836
5846
|
this.attributes = attributes || [];
|
5847
|
+
this.htmlAttributes = htmlAttributes || {};
|
5837
5848
|
}
|
5838
5849
|
isEmpty() {
|
5839
5850
|
return this.text.isBlockBreak();
|
5840
5851
|
}
|
5841
5852
|
isEqualTo(block) {
|
5842
5853
|
if (super.isEqualTo(block)) return true;
|
5843
|
-
return this.text.isEqualTo(block === null || block === void 0 ? void 0 : block.text) && arraysAreEqual(this.attributes, block === null || block === void 0 ? void 0 : block.attributes);
|
5854
|
+
return this.text.isEqualTo(block === null || block === void 0 ? void 0 : block.text) && arraysAreEqual(this.attributes, block === null || block === void 0 ? void 0 : block.attributes) && objectsAreEqual(this.htmlAttributes, block === null || block === void 0 ? void 0 : block.htmlAttributes);
|
5844
5855
|
}
|
5845
5856
|
copyWithText(text) {
|
5846
|
-
return new Block(text, this.attributes);
|
5857
|
+
return new Block(text, this.attributes, this.htmlAttributes);
|
5847
5858
|
}
|
5848
5859
|
copyWithoutText() {
|
5849
5860
|
return this.copyWithText(null);
|
5850
5861
|
}
|
5851
5862
|
copyWithAttributes(attributes) {
|
5852
|
-
return new Block(this.text, attributes);
|
5863
|
+
return new Block(this.text, attributes, this.htmlAttributes);
|
5853
5864
|
}
|
5854
5865
|
copyWithoutAttributes() {
|
5855
5866
|
return this.copyWithAttributes(null);
|
@@ -5866,6 +5877,12 @@ $\
|
|
5866
5877
|
const attributes = this.attributes.concat(expandAttribute(attribute));
|
5867
5878
|
return this.copyWithAttributes(attributes);
|
5868
5879
|
}
|
5880
|
+
addHTMLAttribute(attribute, value) {
|
5881
|
+
const htmlAttributes = Object.assign({}, this.htmlAttributes, {
|
5882
|
+
[attribute]: value
|
5883
|
+
});
|
5884
|
+
return new Block(this.text, this.attributes, htmlAttributes);
|
5885
|
+
}
|
5869
5886
|
removeAttribute(attribute) {
|
5870
5887
|
const {
|
5871
5888
|
listAttribute
|
@@ -5962,7 +5979,8 @@ $\
|
|
5962
5979
|
toJSON() {
|
5963
5980
|
return {
|
5964
5981
|
text: this.text,
|
5965
|
-
attributes: this.attributes
|
5982
|
+
attributes: this.attributes,
|
5983
|
+
htmlAttributes: this.htmlAttributes
|
5966
5984
|
};
|
5967
5985
|
}
|
5968
5986
|
|
@@ -6325,6 +6343,11 @@ $\
|
|
6325
6343
|
const range = this.getRangeOfAttachment(attachment);
|
6326
6344
|
return this.removeAttributeAtRange(attribute, range);
|
6327
6345
|
}
|
6346
|
+
setHTMLAttributeAtPosition(position, name, value) {
|
6347
|
+
const block = this.getBlockAtPosition(position);
|
6348
|
+
const updatedBlock = block.addHTMLAttribute(name, value);
|
6349
|
+
return this.replaceBlock(block, updatedBlock);
|
6350
|
+
}
|
6328
6351
|
insertBlockBreakAtRange(range) {
|
6329
6352
|
let blocks;
|
6330
6353
|
range = normalizeRange(range);
|
@@ -6793,9 +6816,9 @@ $\
|
|
6793
6816
|
return attributes;
|
6794
6817
|
};
|
6795
6818
|
|
6796
|
-
const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height class".split(" ");
|
6819
|
+
const DEFAULT_ALLOWED_ATTRIBUTES = "style href src width height language class".split(" ");
|
6797
6820
|
const DEFAULT_FORBIDDEN_PROTOCOLS = "javascript:".split(" ");
|
6798
|
-
const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form".split(" ");
|
6821
|
+
const DEFAULT_FORBIDDEN_ELEMENTS = "script iframe form noscript".split(" ");
|
6799
6822
|
class HTMLSanitizer extends BasicObject {
|
6800
6823
|
static sanitize(html, options) {
|
6801
6824
|
const sanitizer = new this(html, options);
|
@@ -6923,15 +6946,21 @@ $\
|
|
6923
6946
|
};
|
6924
6947
|
const blockForAttributes = function () {
|
6925
6948
|
let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
6949
|
+
let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
6926
6950
|
const text = [];
|
6927
6951
|
return {
|
6928
6952
|
text,
|
6929
|
-
attributes
|
6953
|
+
attributes,
|
6954
|
+
htmlAttributes
|
6930
6955
|
};
|
6931
6956
|
};
|
6932
6957
|
const parseTrixDataAttribute = (element, name) => {
|
6933
6958
|
try {
|
6934
|
-
|
6959
|
+
const data = JSON.parse(element.getAttribute("data-trix-".concat(name)));
|
6960
|
+
if (data.contentType === "text/html" && data.content) {
|
6961
|
+
data.content = HTMLSanitizer.sanitize(data.content).getHTML();
|
6962
|
+
}
|
6963
|
+
return data;
|
6935
6964
|
} catch (error) {
|
6936
6965
|
return {};
|
6937
6966
|
}
|
@@ -7027,8 +7056,9 @@ $\
|
|
7027
7056
|
} else if (element === this.containerElement || this.isBlockElement(element)) {
|
7028
7057
|
var _this$currentBlock;
|
7029
7058
|
const attributes = this.getBlockAttributes(element);
|
7059
|
+
const htmlAttributes = this.getBlockHTMLAttributes(element);
|
7030
7060
|
if (!arraysAreEqual(attributes, (_this$currentBlock = this.currentBlock) === null || _this$currentBlock === void 0 ? void 0 : _this$currentBlock.attributes)) {
|
7031
|
-
this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element);
|
7061
|
+
this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
|
7032
7062
|
this.currentBlockElement = element;
|
7033
7063
|
}
|
7034
7064
|
}
|
@@ -7039,9 +7069,10 @@ $\
|
|
7039
7069
|
if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) {
|
7040
7070
|
if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) {
|
7041
7071
|
const attributes = this.getBlockAttributes(element);
|
7072
|
+
const htmlAttributes = this.getBlockHTMLAttributes(element);
|
7042
7073
|
if (element.firstChild) {
|
7043
7074
|
if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) {
|
7044
|
-
this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element);
|
7075
|
+
this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
|
7045
7076
|
this.currentBlockElement = element;
|
7046
7077
|
} else {
|
7047
7078
|
return this.appendStringWithAttributes("\n");
|
@@ -7129,8 +7160,9 @@ $\
|
|
7129
7160
|
// Document construction
|
7130
7161
|
|
7131
7162
|
appendBlockForAttributesWithElement(attributes, element) {
|
7163
|
+
let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
7132
7164
|
this.blockElements.push(element);
|
7133
|
-
const block = blockForAttributes(attributes);
|
7165
|
+
const block = blockForAttributes(attributes, htmlAttributes);
|
7134
7166
|
this.blocks.push(block);
|
7135
7167
|
return block;
|
7136
7168
|
}
|
@@ -7235,6 +7267,17 @@ $\
|
|
7235
7267
|
}
|
7236
7268
|
return attributes$1.reverse();
|
7237
7269
|
}
|
7270
|
+
getBlockHTMLAttributes(element) {
|
7271
|
+
const attributes$1 = {};
|
7272
|
+
const blockConfig = Object.values(attributes).find(settings => settings.tagName === tagName(element));
|
7273
|
+
const allowedAttributes = (blockConfig === null || blockConfig === void 0 ? void 0 : blockConfig.htmlAttributes) || [];
|
7274
|
+
allowedAttributes.forEach(attribute => {
|
7275
|
+
if (element.hasAttribute(attribute)) {
|
7276
|
+
attributes$1[attribute] = element.getAttribute(attribute);
|
7277
|
+
}
|
7278
|
+
});
|
7279
|
+
return attributes$1;
|
7280
|
+
}
|
7238
7281
|
findBlockElementAncestors(element) {
|
7239
7282
|
const ancestors = [];
|
7240
7283
|
while (element && element !== this.containerElement) {
|
@@ -7830,6 +7873,15 @@ $\
|
|
7830
7873
|
return this.notifyDelegateOfCurrentAttributesChange();
|
7831
7874
|
}
|
7832
7875
|
}
|
7876
|
+
setHTMLAtributeAtPosition(position, attributeName, value) {
|
7877
|
+
var _getBlockConfig;
|
7878
|
+
const block = this.document.getBlockAtPosition(position);
|
7879
|
+
const allowedHTMLAttributes = (_getBlockConfig = getBlockConfig(block.getLastAttribute())) === null || _getBlockConfig === void 0 ? void 0 : _getBlockConfig.htmlAttributes;
|
7880
|
+
if (block && allowedHTMLAttributes !== null && allowedHTMLAttributes !== void 0 && allowedHTMLAttributes.includes(attributeName)) {
|
7881
|
+
const newDocument = this.document.setHTMLAttributeAtPosition(position, attributeName, value);
|
7882
|
+
this.setDocument(newDocument);
|
7883
|
+
}
|
7884
|
+
}
|
7833
7885
|
setTextAttribute(attributeName, value) {
|
7834
7886
|
const selectedRange = this.getSelectedRange();
|
7835
7887
|
if (!selectedRange) return;
|
@@ -7877,10 +7929,10 @@ $\
|
|
7877
7929
|
return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0;
|
7878
7930
|
}
|
7879
7931
|
canIncreaseNestingLevel() {
|
7880
|
-
var
|
7932
|
+
var _getBlockConfig2;
|
7881
7933
|
const block = this.getBlock();
|
7882
7934
|
if (!block) return;
|
7883
|
-
if ((
|
7935
|
+
if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) {
|
7884
7936
|
const previousBlock = this.getPreviousBlock();
|
7885
7937
|
if (previousBlock) {
|
7886
7938
|
return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes());
|
@@ -8521,6 +8573,11 @@ $\
|
|
8521
8573
|
return this.composition.removeCurrentAttribute(name);
|
8522
8574
|
}
|
8523
8575
|
|
8576
|
+
// HTML attributes
|
8577
|
+
setHTMLAtributeAtPosition(position, name, value) {
|
8578
|
+
this.composition.setHTMLAtributeAtPosition(position, name, value);
|
8579
|
+
}
|
8580
|
+
|
8524
8581
|
// Nesting level
|
8525
8582
|
|
8526
8583
|
canDecreaseNestingLevel() {
|
@@ -10941,8 +10998,12 @@ $\
|
|
10941
10998
|
});
|
10942
10999
|
},
|
10943
11000
|
insertReplacementText() {
|
10944
|
-
|
10945
|
-
|
11001
|
+
const replacement = this.event.dataTransfer.getData("text/plain");
|
11002
|
+
const domRange = this.event.getTargetRanges()[0];
|
11003
|
+
this.withTargetDOMRange(domRange, () => {
|
11004
|
+
this.insertString(replacement, {
|
11005
|
+
updatePosition: false
|
11006
|
+
});
|
10946
11007
|
});
|
10947
11008
|
},
|
10948
11009
|
insertText() {
|
@@ -11064,7 +11125,7 @@ $\
|
|
11064
11125
|
return this.toggleDialog(actionName);
|
11065
11126
|
} else {
|
11066
11127
|
var _this$delegate2;
|
11067
|
-
return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName);
|
11128
|
+
return (_this$delegate2 = this.delegate) === null || _this$delegate2 === void 0 ? void 0 : _this$delegate2.toolbarDidInvokeAction(actionName, element);
|
11068
11129
|
}
|
11069
11130
|
}
|
11070
11131
|
didClickAttributeButton(event, element) {
|
@@ -11509,8 +11570,8 @@ $\
|
|
11509
11570
|
});
|
11510
11571
|
}
|
11511
11572
|
}
|
11512
|
-
toolbarDidInvokeAction(actionName) {
|
11513
|
-
return this.invokeAction(actionName);
|
11573
|
+
toolbarDidInvokeAction(actionName, invokingElement) {
|
11574
|
+
return this.invokeAction(actionName, invokingElement);
|
11514
11575
|
}
|
11515
11576
|
toolbarDidToggleAttribute(attributeName) {
|
11516
11577
|
this.recordFormattingUndoEntry(attributeName);
|
@@ -11579,10 +11640,11 @@ $\
|
|
11579
11640
|
return !!((_this$actions$actionN = this.actions[actionName]) !== null && _this$actions$actionN !== void 0 && (_this$actions$actionN = _this$actions$actionN.test) !== null && _this$actions$actionN !== void 0 && _this$actions$actionN.call(this));
|
11580
11641
|
}
|
11581
11642
|
}
|
11582
|
-
invokeAction(actionName) {
|
11643
|
+
invokeAction(actionName, invokingElement) {
|
11583
11644
|
if (this.actionIsExternal(actionName)) {
|
11584
11645
|
return this.notifyEditorElement("action-invoke", {
|
11585
|
-
actionName
|
11646
|
+
actionName,
|
11647
|
+
invokingElement
|
11586
11648
|
});
|
11587
11649
|
} else {
|
11588
11650
|
var _this$actions$actionN2;
|
@@ -334,7 +334,9 @@ trix-editor .attachment__metadata {
|
|
334
334
|
white-space: nowrap; }
|
335
335
|
|
336
336
|
.trix-content {
|
337
|
-
line-height: 1.5;
|
337
|
+
line-height: 1.5;
|
338
|
+
overflow-wrap: break-word;
|
339
|
+
word-break: break-word; }
|
338
340
|
.trix-content * {
|
339
341
|
box-sizing: border-box;
|
340
342
|
margin: 0;
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/object/try"
|
4
6
|
require "action_view/helpers/tags/placeholderable"
|
5
7
|
|
@@ -7,20 +9,24 @@ module ActionText
|
|
7
9
|
module TagHelper
|
8
10
|
cattr_accessor(:id, instance_accessor: false) { 0 }
|
9
11
|
|
10
|
-
# Returns a
|
11
|
-
# that Trix will write to on changes, so the content will
|
12
|
+
# Returns a `trix-editor` tag that instantiates the Trix JavaScript editor as
|
13
|
+
# well as a hidden field that Trix will write to on changes, so the content will
|
14
|
+
# be sent on form submissions.
|
15
|
+
#
|
16
|
+
# #### Options
|
17
|
+
# * `:class` - Defaults to "trix-content" so that default styles will be
|
18
|
+
# applied. Setting this to a different value will prevent default styles
|
19
|
+
# from being applied.
|
20
|
+
# * `[:data][:direct_upload_url]` - Defaults to `rails_direct_uploads_url`.
|
21
|
+
# * `[:data][:blob_url_template]` - Defaults to
|
22
|
+
# `rails_service_blob_url(":signed_id", ":filename")`.
|
12
23
|
#
|
13
|
-
# ==== Options
|
14
|
-
# * <tt>:class</tt> - Defaults to "trix-content" so that default styles will be applied.
|
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>.
|
18
24
|
#
|
19
|
-
#
|
25
|
+
# #### Example
|
20
26
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
27
|
+
# rich_text_area_tag "content", message.content
|
28
|
+
# # <input type="hidden" name="content" id="trix_input_post_1">
|
29
|
+
# # <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>
|
24
30
|
def rich_text_area_tag(name, value = nil, options = {})
|
25
31
|
options = options.symbolize_keys
|
26
32
|
form = options.delete(:form)
|
@@ -56,23 +62,27 @@ module ActionView::Helpers
|
|
56
62
|
end
|
57
63
|
|
58
64
|
module FormHelper
|
59
|
-
# Returns a
|
60
|
-
# that Trix will write to on changes, so the content will
|
65
|
+
# Returns a `trix-editor` tag that instantiates the Trix JavaScript editor as
|
66
|
+
# well as a hidden field that Trix will write to on changes, so the content will
|
67
|
+
# be sent on form submissions.
|
68
|
+
#
|
69
|
+
# #### Options
|
70
|
+
# * `:class` - Defaults to "trix-content" which ensures default styling is
|
71
|
+
# applied.
|
72
|
+
# * `:value` - Adds a default value to the HTML input tag.
|
73
|
+
# * `[:data][:direct_upload_url]` - Defaults to `rails_direct_uploads_url`.
|
74
|
+
# * `[:data][:blob_url_template]` - Defaults to
|
75
|
+
# `rails_service_blob_url(":signed_id", ":filename")`.
|
61
76
|
#
|
62
|
-
# ==== Options
|
63
|
-
# * <tt>:class</tt> - Defaults to "trix-content" which ensures default styling is applied.
|
64
|
-
# * <tt>:value</tt> - Adds a default value to the HTML input tag.
|
65
|
-
# * <tt>[:data][:direct_upload_url]</tt> - Defaults to +rails_direct_uploads_url+.
|
66
|
-
# * <tt>[:data][:blob_url_template]</tt> - Defaults to <tt>rails_service_blob_url(":signed_id", ":filename")</tt>.
|
67
77
|
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
78
|
+
# #### Example
|
79
|
+
# rich_text_area :message, :content
|
80
|
+
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
|
81
|
+
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
72
82
|
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
83
|
+
# rich_text_area :message, :content, value: "<h1>Default message</h1>"
|
84
|
+
# # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
|
85
|
+
# # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
|
76
86
|
def rich_text_area(object_name, method, options = {})
|
77
87
|
Tags::ActionText.new(object_name, method, self, options).render
|
78
88
|
end
|
@@ -81,9 +91,9 @@ module ActionView::Helpers
|
|
81
91
|
class FormBuilder
|
82
92
|
# Wraps ActionView::Helpers::FormHelper#rich_text_area for form builders:
|
83
93
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
94
|
+
# <%= form_with model: @message do |f| %>
|
95
|
+
# <%= f.rich_text_area :content %>
|
96
|
+
# <% end %>
|
87
97
|
#
|
88
98
|
# Please refer to the documentation of the base helper for details.
|
89
99
|
def rich_text_area(method, options = {})
|