Skip to content

Commit 161d98d

Browse files
committed
Merge branch 'rm-trix'
2 parents 705b70a + f3f2773 commit 161d98d

File tree

2 files changed

+95
-31
lines changed

2 files changed

+95
-31
lines changed

actiontext/app/assets/javascripts/trix.js

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
Trix 2.0.7
3-
Copyright © 2023 37signals, LLC
2+
Trix 2.1.1
3+
Copyright © 2024 37signals, LLC
44
*/
55
(function (global, factory) {
66
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -9,14 +9,15 @@ Copyright © 2023 37signals, LLC
99
})(this, (function () { 'use strict';
1010

1111
var name = "trix";
12-
var version = "2.0.7";
12+
var version = "2.1.1";
1313
var description = "A rich text editor for everyday writing";
1414
var main = "dist/trix.umd.min.js";
1515
var module = "dist/trix.esm.min.js";
1616
var style = "dist/trix.css";
1717
var files = [
1818
"dist/*.css",
1919
"dist/*.js",
20+
"dist/*.map",
2021
"src/{inspector,trix}/*.js"
2122
];
2223
var repository = {
@@ -130,6 +131,7 @@ Copyright © 2023 37signals, LLC
130131
code: {
131132
tagName: "pre",
132133
terminal: true,
134+
htmlAttributes: ["language"],
133135
text: {
134136
plaintext: true
135137
}
@@ -1215,7 +1217,7 @@ $\
12151217
no-useless-escape,
12161218
*/
12171219
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/g, "\n");
1220+
const normalizeNewlines = string => string.replace(/\r\n?/g, "\n");
12191221
const breakableWhitespacePattern = new RegExp("[^\\S".concat(NON_BREAKING_SPACE, "]"));
12201222
const squishBreakableWhitespace = string => string
12211223
// Replace all breakable whitespace characters with a space
@@ -2144,20 +2146,28 @@ $\
21442146
}
21452147
}
21462148
createContainerElement(depth) {
2147-
let attributes, className;
2149+
const attributes = {};
2150+
let className;
21482151
const attributeName = this.attributes[depth];
21492152
const {
2150-
tagName
2153+
tagName,
2154+
htmlAttributes = []
21512155
} = getBlockConfig(attributeName);
21522156
if (depth === 0 && this.block.isRTL()) {
2153-
attributes = {
2157+
Object.assign(attributes, {
21542158
dir: "rtl"
2155-
};
2159+
});
21562160
}
21572161
if (attributeName === "attachmentGallery") {
21582162
const size = this.block.getBlockBreakPosition();
21592163
className = "".concat(css$1.attachmentGallery, " ").concat(css$1.attachmentGallery, "--").concat(size);
21602164
}
2165+
Object.entries(this.block.htmlAttributes).forEach(_ref => {
2166+
let [name, value] = _ref;
2167+
if (htmlAttributes.includes(name)) {
2168+
attributes[name] = value;
2169+
}
2170+
});
21612171
return makeElement({
21622172
tagName,
21632173
className,
@@ -5828,28 +5838,29 @@ $\
58285838
class Block extends TrixObject {
58295839
static fromJSON(blockJSON) {
58305840
const text = Text.fromJSON(blockJSON.text);
5831-
return new this(text, blockJSON.attributes);
5841+
return new this(text, blockJSON.attributes, blockJSON.htmlAttributes);
58325842
}
5833-
constructor(text, attributes) {
5843+
constructor(text, attributes, htmlAttributes) {
58345844
super(...arguments);
58355845
this.text = applyBlockBreakToText(text || new Text());
58365846
this.attributes = attributes || [];
5847+
this.htmlAttributes = htmlAttributes || {};
58375848
}
58385849
isEmpty() {
58395850
return this.text.isBlockBreak();
58405851
}
58415852
isEqualTo(block) {
58425853
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);
58445855
}
58455856
copyWithText(text) {
5846-
return new Block(text, this.attributes);
5857+
return new Block(text, this.attributes, this.htmlAttributes);
58475858
}
58485859
copyWithoutText() {
58495860
return this.copyWithText(null);
58505861
}
58515862
copyWithAttributes(attributes) {
5852-
return new Block(this.text, attributes);
5863+
return new Block(this.text, attributes, this.htmlAttributes);
58535864
}
58545865
copyWithoutAttributes() {
58555866
return this.copyWithAttributes(null);
@@ -5866,6 +5877,12 @@ $\
58665877
const attributes = this.attributes.concat(expandAttribute(attribute));
58675878
return this.copyWithAttributes(attributes);
58685879
}
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+
}
58695886
removeAttribute(attribute) {
58705887
const {
58715888
listAttribute
@@ -5962,7 +5979,8 @@ $\
59625979
toJSON() {
59635980
return {
59645981
text: this.text,
5965-
attributes: this.attributes
5982+
attributes: this.attributes,
5983+
htmlAttributes: this.htmlAttributes
59665984
};
59675985
}
59685986

@@ -6325,6 +6343,11 @@ $\
63256343
const range = this.getRangeOfAttachment(attachment);
63266344
return this.removeAttributeAtRange(attribute, range);
63276345
}
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+
}
63286351
insertBlockBreakAtRange(range) {
63296352
let blocks;
63306353
range = normalizeRange(range);
@@ -6793,9 +6816,9 @@ $\
67936816
return attributes;
67946817
};
67956818

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(" ");
67976820
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(" ");
67996822
class HTMLSanitizer extends BasicObject {
68006823
static sanitize(html, options) {
68016824
const sanitizer = new this(html, options);
@@ -6923,15 +6946,21 @@ $\
69236946
};
69246947
const blockForAttributes = function () {
69256948
let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6949+
let htmlAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
69266950
const text = [];
69276951
return {
69286952
text,
6929-
attributes
6953+
attributes,
6954+
htmlAttributes
69306955
};
69316956
};
69326957
const parseTrixDataAttribute = (element, name) => {
69336958
try {
6934-
return JSON.parse(element.getAttribute("data-trix-".concat(name)));
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;
69356964
} catch (error) {
69366965
return {};
69376966
}
@@ -7027,8 +7056,9 @@ $\
70277056
} else if (element === this.containerElement || this.isBlockElement(element)) {
70287057
var _this$currentBlock;
70297058
const attributes = this.getBlockAttributes(element);
7059+
const htmlAttributes = this.getBlockHTMLAttributes(element);
70307060
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);
70327062
this.currentBlockElement = element;
70337063
}
70347064
}
@@ -7039,9 +7069,10 @@ $\
70397069
if (elementIsBlockElement && !this.isBlockElement(element.firstChild)) {
70407070
if (!this.isInsignificantTextNode(element.firstChild) || !this.isBlockElement(element.firstElementChild)) {
70417071
const attributes = this.getBlockAttributes(element);
7072+
const htmlAttributes = this.getBlockHTMLAttributes(element);
70427073
if (element.firstChild) {
70437074
if (!(currentBlockContainsElement && arraysAreEqual(attributes, this.currentBlock.attributes))) {
7044-
this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element);
7075+
this.currentBlock = this.appendBlockForAttributesWithElement(attributes, element, htmlAttributes);
70457076
this.currentBlockElement = element;
70467077
} else {
70477078
return this.appendStringWithAttributes("\n");
@@ -7129,8 +7160,9 @@ $\
71297160
// Document construction
71307161

71317162
appendBlockForAttributesWithElement(attributes, element) {
7163+
let htmlAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
71327164
this.blockElements.push(element);
7133-
const block = blockForAttributes(attributes);
7165+
const block = blockForAttributes(attributes, htmlAttributes);
71347166
this.blocks.push(block);
71357167
return block;
71367168
}
@@ -7235,6 +7267,17 @@ $\
72357267
}
72367268
return attributes$1.reverse();
72377269
}
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+
}
72387281
findBlockElementAncestors(element) {
72397282
const ancestors = [];
72407283
while (element && element !== this.containerElement) {
@@ -7830,6 +7873,15 @@ $\
78307873
return this.notifyDelegateOfCurrentAttributesChange();
78317874
}
78327875
}
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+
}
78337885
setTextAttribute(attributeName, value) {
78347886
const selectedRange = this.getSelectedRange();
78357887
if (!selectedRange) return;
@@ -7877,10 +7929,10 @@ $\
78777929
return ((_this$getBlock = this.getBlock()) === null || _this$getBlock === void 0 ? void 0 : _this$getBlock.getNestingLevel()) > 0;
78787930
}
78797931
canIncreaseNestingLevel() {
7880-
var _getBlockConfig;
7932+
var _getBlockConfig2;
78817933
const block = this.getBlock();
78827934
if (!block) return;
7883-
if ((_getBlockConfig = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig !== void 0 && _getBlockConfig.listAttribute) {
7935+
if ((_getBlockConfig2 = getBlockConfig(block.getLastNestableAttribute())) !== null && _getBlockConfig2 !== void 0 && _getBlockConfig2.listAttribute) {
78847936
const previousBlock = this.getPreviousBlock();
78857937
if (previousBlock) {
78867938
return arrayStartsWith(previousBlock.getListItemAttributes(), block.getListItemAttributes());
@@ -8521,6 +8573,11 @@ $\
85218573
return this.composition.removeCurrentAttribute(name);
85228574
}
85238575

8576+
// HTML attributes
8577+
setHTMLAtributeAtPosition(position, name, value) {
8578+
this.composition.setHTMLAtributeAtPosition(position, name, value);
8579+
}
8580+
85248581
// Nesting level
85258582

85268583
canDecreaseNestingLevel() {
@@ -10941,8 +10998,12 @@ $\
1094110998
});
1094210999
},
1094311000
insertReplacementText() {
10944-
return this.insertString(this.event.dataTransfer.getData("text/plain"), {
10945-
updatePosition: false
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+
});
1094611007
});
1094711008
},
1094811009
insertText() {
@@ -11064,7 +11125,7 @@ $\
1106411125
return this.toggleDialog(actionName);
1106511126
} else {
1106611127
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);
1106811129
}
1106911130
}
1107011131
didClickAttributeButton(event, element) {
@@ -11509,8 +11570,8 @@ $\
1150911570
});
1151011571
}
1151111572
}
11512-
toolbarDidInvokeAction(actionName) {
11513-
return this.invokeAction(actionName);
11573+
toolbarDidInvokeAction(actionName, invokingElement) {
11574+
return this.invokeAction(actionName, invokingElement);
1151411575
}
1151511576
toolbarDidToggleAttribute(attributeName) {
1151611577
this.recordFormattingUndoEntry(attributeName);
@@ -11579,10 +11640,11 @@ $\
1157911640
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));
1158011641
}
1158111642
}
11582-
invokeAction(actionName) {
11643+
invokeAction(actionName, invokingElement) {
1158311644
if (this.actionIsExternal(actionName)) {
1158411645
return this.notifyEditorElement("action-invoke", {
11585-
actionName
11646+
actionName,
11647+
invokingElement
1158611648
});
1158711649
} else {
1158811650
var _this$actions$actionN2;

actiontext/app/assets/stylesheets/trix.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ trix-editor .attachment__metadata {
334334
white-space: nowrap; }
335335

336336
.trix-content {
337-
line-height: 1.5; }
337+
line-height: 1.5;
338+
overflow-wrap: break-word;
339+
word-break: break-word; }
338340
.trix-content * {
339341
box-sizing: border-box;
340342
margin: 0;

0 commit comments

Comments
 (0)