@37signals/lexxy 0.9.24 → 0.9.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lexxy.esm.js +66 -9
- package/package.json +1 -1
package/dist/lexxy.esm.js
CHANGED
|
@@ -1061,9 +1061,9 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
1061
1061
|
const HEADING_BUTTON_SELECTOR = "button.lexxy-heading-button";
|
|
1062
1062
|
|
|
1063
1063
|
const HEADING_PRESETS = [
|
|
1064
|
-
{ label: "Large Heading", name: "heading-large" },
|
|
1065
|
-
{ label: "Medium Heading", name: "heading-medium" },
|
|
1066
|
-
{ label: "Small Heading", name: "heading-small" }
|
|
1064
|
+
{ label: "Large Heading", name: "heading-large", command: "setFormatHeadingLarge" },
|
|
1065
|
+
{ label: "Medium Heading", name: "heading-medium", command: "setFormatHeadingMedium" },
|
|
1066
|
+
{ label: "Small Heading", name: "heading-small", command: "setFormatHeadingSmall" }
|
|
1067
1067
|
];
|
|
1068
1068
|
|
|
1069
1069
|
class HeadingDropdown extends HTMLElement {
|
|
@@ -1093,6 +1093,14 @@ class HeadingDropdown extends HTMLElement {
|
|
|
1093
1093
|
}
|
|
1094
1094
|
}
|
|
1095
1095
|
|
|
1096
|
+
static commandFor(index) {
|
|
1097
|
+
if (index < HEADING_PRESETS.length) {
|
|
1098
|
+
return HEADING_PRESETS[index].command
|
|
1099
|
+
} else {
|
|
1100
|
+
return "applyHeadingFormat"
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1096
1104
|
#listeners = new ListenerBin()
|
|
1097
1105
|
|
|
1098
1106
|
connectedCallback() {
|
|
@@ -1155,6 +1163,7 @@ class HeadingDropdown extends HTMLElement {
|
|
|
1155
1163
|
const button = document.createElement("button");
|
|
1156
1164
|
button.type = "button";
|
|
1157
1165
|
button.dataset.heading = tag;
|
|
1166
|
+
button.dataset.command = HeadingDropdown.commandFor(index);
|
|
1158
1167
|
button.classList.add("lexxy-heading-button");
|
|
1159
1168
|
button.name = name;
|
|
1160
1169
|
button.title = label;
|
|
@@ -1169,7 +1178,7 @@ class HeadingDropdown extends HTMLElement {
|
|
|
1169
1178
|
if (!this.#editor) return
|
|
1170
1179
|
|
|
1171
1180
|
event.preventDefault();
|
|
1172
|
-
this.#editor.dispatchCommand(
|
|
1181
|
+
this.#editor.dispatchCommand(button.dataset.command, button.dataset.heading);
|
|
1173
1182
|
this.#editor.focus();
|
|
1174
1183
|
}));
|
|
1175
1184
|
});
|
|
@@ -1938,14 +1947,29 @@ function $shrinkSelectionPastBlockEdges(selection) {
|
|
|
1938
1947
|
if (!anchorBlock || !focusBlock || anchorBlock.is(focusBlock)) return
|
|
1939
1948
|
|
|
1940
1949
|
if ($isAtBlockEnd(selection.anchor, anchorBlock)) {
|
|
1941
|
-
const nextBlock = anchorBlock
|
|
1950
|
+
const nextBlock = $nearestElementSibling(anchorBlock, "next");
|
|
1942
1951
|
if (nextBlock) selection.anchor.set(nextBlock.getKey(), 0, "element");
|
|
1943
1952
|
}
|
|
1944
1953
|
|
|
1945
1954
|
if ($isAtBlockStart(selection.focus, focusBlock)) {
|
|
1946
|
-
const previousBlock = focusBlock
|
|
1955
|
+
const previousBlock = $nearestElementSibling(focusBlock, "previous");
|
|
1947
1956
|
if (previousBlock) selection.focus.set(previousBlock.getKey(), previousBlock.getChildrenSize(), "element");
|
|
1948
1957
|
}
|
|
1958
|
+
|
|
1959
|
+
// Shrinking moves the endpoints toward each other, so they can cross when
|
|
1960
|
+
// both were flush against block edges; callers assume a forward selection.
|
|
1961
|
+
$ensureForwardRangeSelection(selection);
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
// Top-level decorator blocks (attachments, horizontal dividers) can't hold a
|
|
1965
|
+
// selection point, so walk past them to the nearest element sibling. Returns
|
|
1966
|
+
// null when no element sibling exists in that direction.
|
|
1967
|
+
function $nearestElementSibling(block, direction) {
|
|
1968
|
+
let sibling = block;
|
|
1969
|
+
do {
|
|
1970
|
+
sibling = direction === "next" ? sibling.getNextSibling() : sibling.getPreviousSibling();
|
|
1971
|
+
} while (sibling && !$isElementNode(sibling))
|
|
1972
|
+
return sibling
|
|
1949
1973
|
}
|
|
1950
1974
|
|
|
1951
1975
|
function $isAtBlockEnd(point, block) {
|
|
@@ -3747,6 +3771,9 @@ const COMMANDS = [
|
|
|
3747
3771
|
"unlink",
|
|
3748
3772
|
"toggleHighlight",
|
|
3749
3773
|
"removeHighlight",
|
|
3774
|
+
"setFormatHeadingLarge",
|
|
3775
|
+
"setFormatHeadingMedium",
|
|
3776
|
+
"setFormatHeadingSmall",
|
|
3750
3777
|
"setFormatParagraph",
|
|
3751
3778
|
"applyHeadingFormat",
|
|
3752
3779
|
"clearFormatting",
|
|
@@ -3940,6 +3967,18 @@ class CommandDispatcher {
|
|
|
3940
3967
|
$insertNodeToNearestRoot(new HorizontalDividerNode);
|
|
3941
3968
|
}
|
|
3942
3969
|
|
|
3970
|
+
dispatchSetFormatHeadingLarge() {
|
|
3971
|
+
this.#applyConfiguredHeadingFormat(0);
|
|
3972
|
+
}
|
|
3973
|
+
|
|
3974
|
+
dispatchSetFormatHeadingMedium() {
|
|
3975
|
+
this.#applyConfiguredHeadingFormat(1);
|
|
3976
|
+
}
|
|
3977
|
+
|
|
3978
|
+
dispatchSetFormatHeadingSmall() {
|
|
3979
|
+
this.#applyConfiguredHeadingFormat(2);
|
|
3980
|
+
}
|
|
3981
|
+
|
|
3943
3982
|
dispatchSetFormatParagraph() {
|
|
3944
3983
|
this.contents.applyParagraphFormat();
|
|
3945
3984
|
}
|
|
@@ -3996,6 +4035,11 @@ class CommandDispatcher {
|
|
|
3996
4035
|
this.#listeners.dispose();
|
|
3997
4036
|
}
|
|
3998
4037
|
|
|
4038
|
+
#applyConfiguredHeadingFormat(index) {
|
|
4039
|
+
const tag = this.editorElement.config.get("headings")[index];
|
|
4040
|
+
if (tag) this.contents.applyHeadingFormat(tag);
|
|
4041
|
+
}
|
|
4042
|
+
|
|
3999
4043
|
#registerCommands() {
|
|
4000
4044
|
for (const command of COMMANDS) {
|
|
4001
4045
|
const methodName = `dispatch${capitalize(command)}`;
|
|
@@ -5566,11 +5610,11 @@ class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode {
|
|
|
5566
5610
|
}
|
|
5567
5611
|
|
|
5568
5612
|
#forgetUploadRequest() {
|
|
5569
|
-
this.#editorElement
|
|
5613
|
+
this.#editorElement?.uploadRequests.forget(this.getKey());
|
|
5570
5614
|
}
|
|
5571
5615
|
|
|
5572
5616
|
#rememberUploadRequest(request) {
|
|
5573
|
-
this.#editorElement
|
|
5617
|
+
this.#editorElement?.uploadRequests.track(this.getKey(), request);
|
|
5574
5618
|
}
|
|
5575
5619
|
|
|
5576
5620
|
get #editorElement() {
|
|
@@ -5876,6 +5920,7 @@ class PastedContentFormatter {
|
|
|
5876
5920
|
}
|
|
5877
5921
|
|
|
5878
5922
|
format() {
|
|
5923
|
+
this.#stripStyleElements();
|
|
5879
5924
|
this.#unwrapPlaceholderAnchors();
|
|
5880
5925
|
this.#stripTableCellColorStyles();
|
|
5881
5926
|
this.#nestStrayListChildren();
|
|
@@ -5883,6 +5928,18 @@ class PastedContentFormatter {
|
|
|
5883
5928
|
return this.doc
|
|
5884
5929
|
}
|
|
5885
5930
|
|
|
5931
|
+
// Spreadsheets (e.g. Excel) copy a <style> block whose rules (td { color:
|
|
5932
|
+
// black }, .xlNN { ... }) cascade onto the imported text. That color rides
|
|
5933
|
+
// in through the cascade rather than an inline style, so it slips past both
|
|
5934
|
+
// the cell-level stripping below and the paste style canonicalizer, leaving
|
|
5935
|
+
// pasted tables with foreign text colors that don't adapt to the theme. Drop
|
|
5936
|
+
// foreign style sheets so nothing cascades into imported content.
|
|
5937
|
+
#stripStyleElements() {
|
|
5938
|
+
for (const style of this.doc.querySelectorAll("style")) {
|
|
5939
|
+
style.remove();
|
|
5940
|
+
}
|
|
5941
|
+
}
|
|
5942
|
+
|
|
5886
5943
|
// Anchors with non-meaningful hrefs (e.g. "#", "") appear in content copied
|
|
5887
5944
|
// from rendered views where mentions and interactive elements are wrapped in
|
|
5888
5945
|
// <a href="#"> tags. Unwrap them so their text content pastes as plain text
|
|
@@ -9412,7 +9469,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
9412
9469
|
{ label: "Normal", command: "setFormatParagraph", tag: null },
|
|
9413
9470
|
...headings.map((tag, index) => ({
|
|
9414
9471
|
label: HeadingDropdown.labelFor(tag, index),
|
|
9415
|
-
command:
|
|
9472
|
+
command: HeadingDropdown.commandFor(index),
|
|
9416
9473
|
tag
|
|
9417
9474
|
}))
|
|
9418
9475
|
]
|