lexxy 0.7.2.beta → 0.7.3.beta
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.
- checksums.yaml +4 -4
- data/app/assets/javascript/lexxy.js +827 -552
- data/app/assets/javascript/lexxy.js.br +0 -0
- data/app/assets/javascript/lexxy.js.gz +0 -0
- data/app/assets/javascript/lexxy.js.map +1 -1
- data/app/assets/javascript/lexxy.min.js +2 -2
- data/app/assets/javascript/lexxy.min.js.br +0 -0
- data/app/assets/javascript/lexxy.min.js.gz +0 -0
- data/app/assets/stylesheets/lexxy-content.css +18 -2
- data/app/assets/stylesheets/lexxy-editor.css +318 -212
- data/app/assets/stylesheets/lexxy-variables.css +9 -3
- data/lib/lexxy/version.rb +1 -1
- metadata +1 -1
|
@@ -4716,6 +4716,7 @@ function buildConfig() {
|
|
|
4716
4716
|
return {
|
|
4717
4717
|
ALLOWED_TAGS: ALLOWED_HTML_TAGS.concat(Lexxy.global.get("attachmentTagName")),
|
|
4718
4718
|
ALLOWED_ATTR: ALLOWED_HTML_ATTRIBUTES,
|
|
4719
|
+
ADD_URI_SAFE_ATTR: [ "caption", "filename" ],
|
|
4719
4720
|
SAFE_FOR_XML: false // So that it does not strip attributes that contains serialized HTML (like content)
|
|
4720
4721
|
}
|
|
4721
4722
|
}
|
|
@@ -6622,6 +6623,8 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6622
6623
|
super();
|
|
6623
6624
|
this.internals = this.attachInternals();
|
|
6624
6625
|
this.internals.role = "toolbar";
|
|
6626
|
+
|
|
6627
|
+
this.#createEditorPromise();
|
|
6625
6628
|
}
|
|
6626
6629
|
|
|
6627
6630
|
connectedCallback() {
|
|
@@ -6654,14 +6657,26 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6654
6657
|
this.#refreshToolbarOverflow();
|
|
6655
6658
|
this.#bindFocusListeners();
|
|
6656
6659
|
|
|
6660
|
+
this.resolveEditorPromise(editorElement);
|
|
6661
|
+
|
|
6657
6662
|
this.toggleAttribute("connected", true);
|
|
6658
6663
|
}
|
|
6659
6664
|
|
|
6665
|
+
async getEditorElement() {
|
|
6666
|
+
return this.editorElement || await this.editorPromise
|
|
6667
|
+
}
|
|
6668
|
+
|
|
6660
6669
|
#reconnect() {
|
|
6661
6670
|
this.disconnectedCallback();
|
|
6662
6671
|
this.connectedCallback();
|
|
6663
6672
|
}
|
|
6664
6673
|
|
|
6674
|
+
#createEditorPromise() {
|
|
6675
|
+
this.editorPromise = new Promise((resolve) => {
|
|
6676
|
+
this.resolveEditorPromise = resolve;
|
|
6677
|
+
});
|
|
6678
|
+
}
|
|
6679
|
+
|
|
6665
6680
|
#installResizeObserver() {
|
|
6666
6681
|
this.resizeObserver = new ResizeObserver(() => this.#refreshToolbarOverflow());
|
|
6667
6682
|
this.resizeObserver.observe(this);
|
|
@@ -6730,28 +6745,24 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6730
6745
|
}
|
|
6731
6746
|
|
|
6732
6747
|
#bindFocusListeners() {
|
|
6733
|
-
this.editorElement.addEventListener("lexxy:focus", this.#
|
|
6734
|
-
this.editorElement.addEventListener("lexxy:blur", this.#
|
|
6735
|
-
this.addEventListener("focusout", this.#handleFocusOut);
|
|
6748
|
+
this.editorElement.addEventListener("lexxy:focus", this.#handleEditorFocus);
|
|
6749
|
+
this.editorElement.addEventListener("lexxy:blur", this.#handleEditorBlur);
|
|
6736
6750
|
this.addEventListener("keydown", this.#handleKeydown);
|
|
6737
6751
|
}
|
|
6738
6752
|
|
|
6739
6753
|
#unbindFocusListeners() {
|
|
6740
|
-
this.editorElement.removeEventListener("lexxy:focus", this.#
|
|
6741
|
-
this.editorElement.removeEventListener("lexxy:blur", this.#
|
|
6742
|
-
this.removeEventListener("focusout", this.#handleFocusOut);
|
|
6754
|
+
this.editorElement.removeEventListener("lexxy:focus", this.#handleEditorFocus);
|
|
6755
|
+
this.editorElement.removeEventListener("lexxy:blur", this.#handleEditorBlur);
|
|
6743
6756
|
this.removeEventListener("keydown", this.#handleKeydown);
|
|
6744
6757
|
}
|
|
6745
6758
|
|
|
6746
|
-
#
|
|
6747
|
-
this.#resetTabIndexValues();
|
|
6759
|
+
#handleEditorFocus = () => {
|
|
6748
6760
|
this.#focusableItems[0].tabIndex = 0;
|
|
6749
6761
|
}
|
|
6750
6762
|
|
|
6751
|
-
#
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
}
|
|
6763
|
+
#handleEditorBlur = () => {
|
|
6764
|
+
this.#resetTabIndexValues();
|
|
6765
|
+
this.#closeDropdowns();
|
|
6755
6766
|
}
|
|
6756
6767
|
|
|
6757
6768
|
#handleKeydown = (event) => {
|
|
@@ -6765,11 +6776,13 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6765
6776
|
}
|
|
6766
6777
|
|
|
6767
6778
|
#monitorSelectionChanges() {
|
|
6768
|
-
this.editor.
|
|
6769
|
-
|
|
6779
|
+
this.editor.registerCommand(
|
|
6780
|
+
ie$1,
|
|
6781
|
+
() => {
|
|
6782
|
+
this.#closeDropdowns();
|
|
6770
6783
|
this.#updateButtonStates();
|
|
6771
|
-
|
|
6772
|
-
|
|
6784
|
+
return false
|
|
6785
|
+
}, Bi);
|
|
6773
6786
|
}
|
|
6774
6787
|
|
|
6775
6788
|
#monitorHistoryChanges() {
|
|
@@ -6858,11 +6871,13 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6858
6871
|
}
|
|
6859
6872
|
|
|
6860
6873
|
#toolbarIsOverflowing() {
|
|
6861
|
-
|
|
6874
|
+
// Safari can report inconsistent clientWidth values on more than 100% window zoom level,
|
|
6875
|
+
// that was affecting the toolbar overflow calculation. We're adding +1 to get around this issue.
|
|
6876
|
+
return (this.scrollWidth - this.#overflow.clientWidth) > this.clientWidth + 1
|
|
6862
6877
|
}
|
|
6863
6878
|
|
|
6864
6879
|
#refreshToolbarOverflow = () => {
|
|
6865
|
-
this.#
|
|
6880
|
+
this.#resetToolbarOverflow();
|
|
6866
6881
|
this.#compactMenu();
|
|
6867
6882
|
|
|
6868
6883
|
this.#overflow.style.display = this.#overflowMenu.children.length ? "block" : "none";
|
|
@@ -6888,7 +6903,7 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6888
6903
|
}
|
|
6889
6904
|
}
|
|
6890
6905
|
|
|
6891
|
-
#
|
|
6906
|
+
#resetToolbarOverflow() {
|
|
6892
6907
|
const items = Array.from(this.#overflowMenu.children);
|
|
6893
6908
|
items.sort((a, b) => this.#itemPosition(b) - this.#itemPosition(a));
|
|
6894
6909
|
|
|
@@ -6910,6 +6925,16 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6910
6925
|
});
|
|
6911
6926
|
}
|
|
6912
6927
|
|
|
6928
|
+
#closeDropdowns() {
|
|
6929
|
+
this.#dropdowns.forEach((details) => {
|
|
6930
|
+
details.open = false;
|
|
6931
|
+
});
|
|
6932
|
+
}
|
|
6933
|
+
|
|
6934
|
+
get #dropdowns() {
|
|
6935
|
+
return this.querySelectorAll("details")
|
|
6936
|
+
}
|
|
6937
|
+
|
|
6913
6938
|
get #overflow() {
|
|
6914
6939
|
return this.querySelector(".lexxy-editor__toolbar-overflow")
|
|
6915
6940
|
}
|
|
@@ -6951,9 +6976,8 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6951
6976
|
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.65422 0.711575C7.1856 0.242951 6.42579 0.242951 5.95717 0.711575C5.48853 1.18021 5.48853 1.94 5.95717 2.40864L8.70864 5.16011L2.85422 11.0145C1.44834 12.4204 1.44833 14.6998 2.85422 16.1057L7.86011 21.1115C9.26599 22.5174 11.5454 22.5174 12.9513 21.1115L19.6542 14.4087C20.1228 13.94 20.1228 13.1802 19.6542 12.7115L11.8544 4.91171L11.2542 4.31158L7.65422 0.711575ZM4.55127 12.7115L10.4057 6.85716L17.1087 13.56H4.19981C4.19981 13.253 4.31696 12.9459 4.55127 12.7115ZM23.6057 20.76C23.6057 22.0856 22.5311 23.16 21.2057 23.16C19.8802 23.16 18.8057 22.0856 18.8057 20.76C18.8057 19.5408 19.8212 18.5339 20.918 17.4462C21.0135 17.3516 21.1096 17.2563 21.2057 17.16C21.3018 17.2563 21.398 17.3516 21.4935 17.4462C22.5903 18.5339 23.6057 19.5408 23.6057 20.76Z"/></svg>
|
|
6952
6977
|
</summary>
|
|
6953
6978
|
<lexxy-highlight-dropdown class="lexxy-editor__toolbar-dropdown-content">
|
|
6954
|
-
<div
|
|
6955
|
-
<
|
|
6956
|
-
<button data-command="removeHighlight" class="lexxy-editor__toolbar-dropdown-reset">Remove all coloring</button>
|
|
6979
|
+
<div class="lexxy-highlight-colors"></div>
|
|
6980
|
+
<button data-command="removeHighlight" class="lexxy-editor__toolbar-button lexxy-editor__toolbar-dropdown-reset">Remove all coloring</button>
|
|
6957
6981
|
</lexxy-highlight-dropdown>
|
|
6958
6982
|
</details>
|
|
6959
6983
|
|
|
@@ -6965,8 +6989,8 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6965
6989
|
<form method="dialog">
|
|
6966
6990
|
<input type="url" placeholder="Enter a URL…" class="input">
|
|
6967
6991
|
<div class="lexxy-editor__toolbar-dropdown-actions">
|
|
6968
|
-
<button type="submit" class="
|
|
6969
|
-
<button type="button" class="
|
|
6992
|
+
<button type="submit" class="lexxy-editor__toolbar-button" value="link">Link</button>
|
|
6993
|
+
<button type="button" class="lexxy-editor__toolbar-button" value="unlink">Unlink</button>
|
|
6970
6994
|
</div>
|
|
6971
6995
|
</form>
|
|
6972
6996
|
</lexxy-link-dropdown>
|
|
@@ -7014,9 +7038,9 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
7014
7038
|
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M18.2599 8.26531C15.9672 6.56386 13.1237 5.77629 10.2823 6.05535C7.4408 6.33452 4.80455 7.66079 2.88681 9.77605C1.32245 11.5016 0.326407 13.6516 0.0127834 15.9352C-0.105117 16.7939 0.608975 17.4997 1.47567 17.4997C2.34228 17.4997 3.02969 16.7915 3.19149 15.9401C3.47682 14.4379 4.17156 13.0321 5.212 11.8844C6.60637 10.3464 8.52287 9.38139 10.589 9.17839C12.655 8.97546 14.7227 9.54856 16.3897 10.7858C17.5237 11.6275 18.4165 12.7361 18.9991 13.9997H15.4063C14.578 13.9997 13.9066 14.6714 13.9063 15.4997C13.9063 16.3281 14.5779 16.9997 15.4063 16.9997H22.4063C23.2348 16.9997 23.9063 16.3281 23.9063 15.4997V8.49968C23.9061 7.67144 23.2346 6.99968 22.4063 6.99968C21.578 6.99968 20.9066 7.67144 20.9063 8.49968V11.0212C20.1897 9.9704 19.2984 9.03613 18.2599 8.26531Z"/></svg>
|
|
7015
7039
|
</button>
|
|
7016
7040
|
|
|
7017
|
-
<details class="lexxy-editor__toolbar-overflow">
|
|
7041
|
+
<details class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-overflow" name="lexxy-dropdown">
|
|
7018
7042
|
<summary class="lexxy-editor__toolbar-button" aria-label="Show more toolbar buttons">•••</summary>
|
|
7019
|
-
<div class="lexxy-editor__toolbar-overflow-menu" aria-label="More toolbar buttons"></div>
|
|
7043
|
+
<div class="lexxy-editor__toolbar-dropdown-content lexxy-editor__toolbar-overflow-menu" aria-label="More toolbar buttons"></div>
|
|
7020
7044
|
</details>
|
|
7021
7045
|
`
|
|
7022
7046
|
}
|
|
@@ -7066,6 +7090,8 @@ var theme = {
|
|
|
7066
7090
|
tableCellSelected: "lexxy-content__table-cell--selected",
|
|
7067
7091
|
tableSelection: "lexxy-content__table--selection",
|
|
7068
7092
|
tableScrollableWrapper: "lexxy-content__table-wrapper",
|
|
7093
|
+
tableCellHighlight: "lexxy-content__table-cell--highlight",
|
|
7094
|
+
tableCellFocus: "lexxy-content__table-cell--focus",
|
|
7069
7095
|
list: {
|
|
7070
7096
|
nested: {
|
|
7071
7097
|
listitem: "lexxy-nested-listitem",
|
|
@@ -7647,30 +7673,6 @@ class HorizontalDividerNode extends ki {
|
|
|
7647
7673
|
}
|
|
7648
7674
|
}
|
|
7649
7675
|
|
|
7650
|
-
class WrappedTableNode extends hn {
|
|
7651
|
-
static clone(node) {
|
|
7652
|
-
return new WrappedTableNode(node.__key)
|
|
7653
|
-
}
|
|
7654
|
-
|
|
7655
|
-
exportDOM(editor) {
|
|
7656
|
-
const superExport = super.exportDOM(editor);
|
|
7657
|
-
|
|
7658
|
-
return {
|
|
7659
|
-
...superExport,
|
|
7660
|
-
after: (tableElement) => {
|
|
7661
|
-
if (superExport.after) {
|
|
7662
|
-
tableElement = superExport.after(tableElement);
|
|
7663
|
-
const clonedTable = tableElement.cloneNode(true);
|
|
7664
|
-
const wrappedTable = createElement("figure", { className: "lexxy-content__table-wrapper" }, clonedTable.outerHTML);
|
|
7665
|
-
return wrappedTable
|
|
7666
|
-
}
|
|
7667
|
-
|
|
7668
|
-
return tableElement
|
|
7669
|
-
}
|
|
7670
|
-
}
|
|
7671
|
-
}
|
|
7672
|
-
}
|
|
7673
|
-
|
|
7674
7676
|
const COMMANDS = [
|
|
7675
7677
|
"bold",
|
|
7676
7678
|
"italic",
|
|
@@ -7688,13 +7690,6 @@ const COMMANDS = [
|
|
|
7688
7690
|
"uploadAttachments",
|
|
7689
7691
|
|
|
7690
7692
|
"insertTable",
|
|
7691
|
-
"insertTableRowAbove",
|
|
7692
|
-
"insertTableRowBelow",
|
|
7693
|
-
"insertTableColumnAfter",
|
|
7694
|
-
"insertTableColumnBefore",
|
|
7695
|
-
"deleteTableRow",
|
|
7696
|
-
"deleteTableColumn",
|
|
7697
|
-
"deleteTable",
|
|
7698
7693
|
|
|
7699
7694
|
"undo",
|
|
7700
7695
|
"redo"
|
|
@@ -7803,9 +7798,7 @@ class CommandDispatcher {
|
|
|
7803
7798
|
}
|
|
7804
7799
|
|
|
7805
7800
|
dispatchInsertHorizontalDivider() {
|
|
7806
|
-
this.
|
|
7807
|
-
this.contents.insertAtCursorEnsuringLineBelow(new HorizontalDividerNode());
|
|
7808
|
-
});
|
|
7801
|
+
this.contents.insertAtCursorEnsuringLineBelow(new HorizontalDividerNode());
|
|
7809
7802
|
|
|
7810
7803
|
this.editor.focus();
|
|
7811
7804
|
}
|
|
@@ -7867,41 +7860,6 @@ class CommandDispatcher {
|
|
|
7867
7860
|
this.editor.dispatchCommand(Ae$1, { "rows": 3, "columns": 3, "includeHeaders": true });
|
|
7868
7861
|
}
|
|
7869
7862
|
|
|
7870
|
-
dispatchInsertTableRowBelow() {
|
|
7871
|
-
je$1(true);
|
|
7872
|
-
}
|
|
7873
|
-
|
|
7874
|
-
dispatchInsertTableRowAbove() {
|
|
7875
|
-
je$1(false);
|
|
7876
|
-
}
|
|
7877
|
-
|
|
7878
|
-
dispatchInsertTableColumnAfter() {
|
|
7879
|
-
Ze$1(true);
|
|
7880
|
-
}
|
|
7881
|
-
|
|
7882
|
-
dispatchInsertTableColumnBefore() {
|
|
7883
|
-
Ze$1(false);
|
|
7884
|
-
}
|
|
7885
|
-
|
|
7886
|
-
dispatchDeleteTableRow() {
|
|
7887
|
-
ot$1();
|
|
7888
|
-
}
|
|
7889
|
-
|
|
7890
|
-
dispatchDeleteTableColumn() {
|
|
7891
|
-
lt$1();
|
|
7892
|
-
}
|
|
7893
|
-
|
|
7894
|
-
dispatchDeleteTable() {
|
|
7895
|
-
this.editor.update(() => {
|
|
7896
|
-
const selection = Lr();
|
|
7897
|
-
if (!yr(selection)) return
|
|
7898
|
-
|
|
7899
|
-
const anchorNode = selection.anchor.getNode();
|
|
7900
|
-
const tableNode = Qt(anchorNode);
|
|
7901
|
-
tableNode.remove();
|
|
7902
|
-
});
|
|
7903
|
-
}
|
|
7904
|
-
|
|
7905
7863
|
dispatchUndo() {
|
|
7906
7864
|
this.editor.dispatchCommand(pe$1, undefined);
|
|
7907
7865
|
}
|
|
@@ -8195,6 +8153,14 @@ class Selection {
|
|
|
8195
8153
|
return wt$5(anchorNode, q$2) !== null
|
|
8196
8154
|
}
|
|
8197
8155
|
|
|
8156
|
+
get isTableCellSelected() {
|
|
8157
|
+
const selection = Lr();
|
|
8158
|
+
if (!yr(selection)) return false
|
|
8159
|
+
|
|
8160
|
+
const anchorNode = selection.anchor.getNode();
|
|
8161
|
+
return wt$5(anchorNode, xe) !== null
|
|
8162
|
+
}
|
|
8163
|
+
|
|
8198
8164
|
get nodeAfterCursor() {
|
|
8199
8165
|
const { anchorNode, offset } = this.#getCollapsedSelectionData();
|
|
8200
8166
|
if (!anchorNode) return null
|
|
@@ -8707,17 +8673,6 @@ function sanitize(html) {
|
|
|
8707
8673
|
return purify.sanitize(html, buildConfig())
|
|
8708
8674
|
}
|
|
8709
8675
|
|
|
8710
|
-
// Prevent the hardcoded background color
|
|
8711
|
-
// A background color value is set by Lexical if background is null:
|
|
8712
|
-
// https://github.com/facebook/lexical/blob/5bbbe849bd229e1db0e7b536e6a919520ada7bb2/packages/lexical-table/src/LexicalTableCellNode.ts#L187
|
|
8713
|
-
function registerHeaderBackgroundTransform(editor) {
|
|
8714
|
-
return editor.registerNodeTransform(xe, (node) => {
|
|
8715
|
-
if (node.getBackgroundColor() === null) {
|
|
8716
|
-
node.setBackgroundColor("");
|
|
8717
|
-
}
|
|
8718
|
-
})
|
|
8719
|
-
}
|
|
8720
|
-
|
|
8721
8676
|
function dasherize(value) {
|
|
8722
8677
|
return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`)
|
|
8723
8678
|
}
|
|
@@ -8741,6 +8696,10 @@ function filterMatches(text, potentialMatch) {
|
|
|
8741
8696
|
return normalizeFilteredText(text).includes(normalizeFilteredText(potentialMatch))
|
|
8742
8697
|
}
|
|
8743
8698
|
|
|
8699
|
+
function upcaseFirst(string) {
|
|
8700
|
+
return string.charAt(0).toUpperCase() + string.slice(1)
|
|
8701
|
+
}
|
|
8702
|
+
|
|
8744
8703
|
class EditorConfiguration {
|
|
8745
8704
|
#editorElement
|
|
8746
8705
|
#config
|
|
@@ -9182,15 +9141,14 @@ class Contents {
|
|
|
9182
9141
|
new FormatEscaper(editorElement).monitor();
|
|
9183
9142
|
}
|
|
9184
9143
|
|
|
9185
|
-
insertHtml(html) {
|
|
9144
|
+
insertHtml(html, { tag } = {}) {
|
|
9186
9145
|
this.editor.update(() => {
|
|
9187
9146
|
const selection = Lr();
|
|
9188
|
-
|
|
9189
9147
|
if (!yr(selection)) return
|
|
9190
9148
|
|
|
9191
9149
|
const nodes = m$1(this.editor, parseHtml(html));
|
|
9192
9150
|
selection.insertNodes(nodes);
|
|
9193
|
-
});
|
|
9151
|
+
}, { tag });
|
|
9194
9152
|
}
|
|
9195
9153
|
|
|
9196
9154
|
insertAtCursor(node) {
|
|
@@ -10065,14 +10023,14 @@ class Clipboard {
|
|
|
10065
10023
|
|
|
10066
10024
|
#pasteMarkdown(text) {
|
|
10067
10025
|
const html = k(text);
|
|
10068
|
-
this.contents.insertHtml(html);
|
|
10026
|
+
this.contents.insertHtml(html, { tag: [ Fn ] });
|
|
10069
10027
|
}
|
|
10070
10028
|
|
|
10071
10029
|
#pasteRichText(clipboardData) {
|
|
10072
10030
|
this.editor.update(() => {
|
|
10073
10031
|
const selection = Lr();
|
|
10074
10032
|
R$3(clipboardData, selection, this.editor);
|
|
10075
|
-
});
|
|
10033
|
+
}, { tag: Fn });
|
|
10076
10034
|
}
|
|
10077
10035
|
|
|
10078
10036
|
#handlePastedFiles(clipboardData) {
|
|
@@ -10306,6 +10264,124 @@ function $applyLanguage(conversionOutput, element) {
|
|
|
10306
10264
|
conversionOutput.node.setLanguage(language);
|
|
10307
10265
|
}
|
|
10308
10266
|
|
|
10267
|
+
class WrappedTableNode extends hn {
|
|
10268
|
+
static clone(node) {
|
|
10269
|
+
return new WrappedTableNode(node.__key)
|
|
10270
|
+
}
|
|
10271
|
+
|
|
10272
|
+
exportDOM(editor) {
|
|
10273
|
+
const superExport = super.exportDOM(editor);
|
|
10274
|
+
|
|
10275
|
+
return {
|
|
10276
|
+
...superExport,
|
|
10277
|
+
after: (tableElement) => {
|
|
10278
|
+
if (superExport.after) {
|
|
10279
|
+
tableElement = superExport.after(tableElement);
|
|
10280
|
+
const clonedTable = tableElement.cloneNode(true);
|
|
10281
|
+
const wrappedTable = createElement("figure", { className: "lexxy-content__table-wrapper" }, clonedTable.outerHTML);
|
|
10282
|
+
return wrappedTable
|
|
10283
|
+
}
|
|
10284
|
+
|
|
10285
|
+
return tableElement
|
|
10286
|
+
}
|
|
10287
|
+
}
|
|
10288
|
+
}
|
|
10289
|
+
}
|
|
10290
|
+
|
|
10291
|
+
const TablesLexicalExtension = Kl({
|
|
10292
|
+
name: "lexxy/tables",
|
|
10293
|
+
nodes: [
|
|
10294
|
+
WrappedTableNode,
|
|
10295
|
+
{
|
|
10296
|
+
replace: hn,
|
|
10297
|
+
with: () => new WrappedTableNode()
|
|
10298
|
+
},
|
|
10299
|
+
xe,
|
|
10300
|
+
Ee$1
|
|
10301
|
+
],
|
|
10302
|
+
register(editor) {
|
|
10303
|
+
// Register Lexical table plugins
|
|
10304
|
+
Nn(editor);
|
|
10305
|
+
yn(editor, true);
|
|
10306
|
+
un(editor);
|
|
10307
|
+
|
|
10308
|
+
// Bug fix: Prevent hardcoded background color (Lexical #8089)
|
|
10309
|
+
editor.registerNodeTransform(xe, (node) => {
|
|
10310
|
+
if (node.getBackgroundColor() === null) {
|
|
10311
|
+
node.setBackgroundColor("");
|
|
10312
|
+
}
|
|
10313
|
+
});
|
|
10314
|
+
|
|
10315
|
+
// Bug fix: Fix column header states (Lexical #8090)
|
|
10316
|
+
editor.registerNodeTransform(xe, (node) => {
|
|
10317
|
+
const headerState = node.getHeaderStyles();
|
|
10318
|
+
|
|
10319
|
+
if (headerState !== ve$1.ROW) return
|
|
10320
|
+
|
|
10321
|
+
const rowParent = node.getParent();
|
|
10322
|
+
const tableNode = rowParent?.getParent();
|
|
10323
|
+
if (!tableNode) return
|
|
10324
|
+
|
|
10325
|
+
const rows = tableNode.getChildren();
|
|
10326
|
+
const cellIndex = rowParent.getChildren().indexOf(node);
|
|
10327
|
+
|
|
10328
|
+
const cellsInRow = rowParent.getChildren();
|
|
10329
|
+
const isHeaderRow = cellsInRow.every(cell =>
|
|
10330
|
+
cell.getHeaderStyles() !== ve$1.NO_STATUS
|
|
10331
|
+
);
|
|
10332
|
+
|
|
10333
|
+
const isHeaderColumn = rows.every(row => {
|
|
10334
|
+
const cell = row.getChildren()[cellIndex];
|
|
10335
|
+
return cell && cell.getHeaderStyles() !== ve$1.NO_STATUS
|
|
10336
|
+
});
|
|
10337
|
+
|
|
10338
|
+
let newHeaderState = ve$1.NO_STATUS;
|
|
10339
|
+
|
|
10340
|
+
if (isHeaderRow) {
|
|
10341
|
+
newHeaderState |= ve$1.ROW;
|
|
10342
|
+
}
|
|
10343
|
+
|
|
10344
|
+
if (isHeaderColumn) {
|
|
10345
|
+
newHeaderState |= ve$1.COLUMN;
|
|
10346
|
+
}
|
|
10347
|
+
|
|
10348
|
+
if (newHeaderState !== headerState) {
|
|
10349
|
+
node.setHeaderStyles(newHeaderState, ve$1.BOTH);
|
|
10350
|
+
}
|
|
10351
|
+
});
|
|
10352
|
+
|
|
10353
|
+
editor.registerCommand("insertTableRowAfter", () => {
|
|
10354
|
+
je$1(true);
|
|
10355
|
+
}, Ri);
|
|
10356
|
+
|
|
10357
|
+
editor.registerCommand("insertTableRowBefore", () => {
|
|
10358
|
+
je$1(false);
|
|
10359
|
+
}, Ri);
|
|
10360
|
+
|
|
10361
|
+
editor.registerCommand("insertTableColumnAfter", () => {
|
|
10362
|
+
Ze$1(true);
|
|
10363
|
+
}, Ri);
|
|
10364
|
+
|
|
10365
|
+
editor.registerCommand("insertTableColumnBefore", () => {
|
|
10366
|
+
Ze$1(false);
|
|
10367
|
+
}, Ri);
|
|
10368
|
+
|
|
10369
|
+
editor.registerCommand("deleteTableRow", () => {
|
|
10370
|
+
ot$1();
|
|
10371
|
+
}, Ri);
|
|
10372
|
+
|
|
10373
|
+
editor.registerCommand("deleteTableColumn", () => {
|
|
10374
|
+
lt$1();
|
|
10375
|
+
}, Ri);
|
|
10376
|
+
|
|
10377
|
+
editor.registerCommand("deleteTable", () => {
|
|
10378
|
+
const selection = Lr();
|
|
10379
|
+
if (!yr(selection)) return false
|
|
10380
|
+
Qt(selection.anchor.getNode())?.remove();
|
|
10381
|
+
}, Ri);
|
|
10382
|
+
}
|
|
10383
|
+
});
|
|
10384
|
+
|
|
10309
10385
|
class LexicalEditorElement extends HTMLElement {
|
|
10310
10386
|
static formAssociated = true
|
|
10311
10387
|
static debug = false
|
|
@@ -10497,8 +10573,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
10497
10573
|
this.#registerComponents();
|
|
10498
10574
|
this.#listenForInvalidatedNodes();
|
|
10499
10575
|
this.#handleEnter();
|
|
10500
|
-
this.#
|
|
10501
|
-
this.#handleTables();
|
|
10576
|
+
this.#registerFocusEvents();
|
|
10502
10577
|
this.#attachDebugHooks();
|
|
10503
10578
|
this.#attachToolbar();
|
|
10504
10579
|
this.#loadInitialValue();
|
|
@@ -10526,7 +10601,8 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
10526
10601
|
const extensions = [ ];
|
|
10527
10602
|
const richTextExtensions = [
|
|
10528
10603
|
this.highlighter.lexicalExtension,
|
|
10529
|
-
TrixContentExtension
|
|
10604
|
+
TrixContentExtension,
|
|
10605
|
+
TablesLexicalExtension
|
|
10530
10606
|
];
|
|
10531
10607
|
|
|
10532
10608
|
if (this.supportsRichText) {
|
|
@@ -10551,14 +10627,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
10551
10627
|
et$1,
|
|
10552
10628
|
y$1,
|
|
10553
10629
|
A,
|
|
10554
|
-
HorizontalDividerNode
|
|
10555
|
-
WrappedTableNode,
|
|
10556
|
-
{
|
|
10557
|
-
replace: hn,
|
|
10558
|
-
with: () => { return new WrappedTableNode() }
|
|
10559
|
-
},
|
|
10560
|
-
xe,
|
|
10561
|
-
Ee$1,
|
|
10630
|
+
HorizontalDividerNode
|
|
10562
10631
|
);
|
|
10563
10632
|
}
|
|
10564
10633
|
|
|
@@ -10672,11 +10741,8 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
10672
10741
|
}
|
|
10673
10742
|
|
|
10674
10743
|
#registerTableComponents() {
|
|
10675
|
-
|
|
10676
|
-
this.
|
|
10677
|
-
this.append(this.tableHandler);
|
|
10678
|
-
|
|
10679
|
-
this.#addUnregisterHandler(registerHeaderBackgroundTransform(this.editor));
|
|
10744
|
+
this.tableTools = createElement("lexxy-table-tools");
|
|
10745
|
+
this.append(this.tableTools);
|
|
10680
10746
|
}
|
|
10681
10747
|
|
|
10682
10748
|
#registerCodeHiglightingComponents() {
|
|
@@ -10723,12 +10789,27 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
10723
10789
|
);
|
|
10724
10790
|
}
|
|
10725
10791
|
|
|
10726
|
-
#
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10792
|
+
#registerFocusEvents() {
|
|
10793
|
+
this.addEventListener("focusin", this.#handleFocusIn);
|
|
10794
|
+
this.addEventListener("focusout", this.#handleFocusOut);
|
|
10795
|
+
}
|
|
10796
|
+
|
|
10797
|
+
#handleFocusIn(event) {
|
|
10798
|
+
if (this.#elementInEditorOrToolbar(event.target) && !this.currentlyFocused) {
|
|
10799
|
+
dispatch(this, "lexxy:focus");
|
|
10800
|
+
this.currentlyFocused = true;
|
|
10801
|
+
}
|
|
10802
|
+
}
|
|
10803
|
+
|
|
10804
|
+
#handleFocusOut(event) {
|
|
10805
|
+
if (!this.#elementInEditorOrToolbar(event.relatedTarget)) {
|
|
10806
|
+
dispatch(this, "lexxy:blur");
|
|
10807
|
+
this.currentlyFocused = false;
|
|
10808
|
+
}
|
|
10809
|
+
}
|
|
10810
|
+
|
|
10811
|
+
#elementInEditorOrToolbar(element) {
|
|
10812
|
+
return this.contains(element) || this.toolbarElement?.contains(element)
|
|
10732
10813
|
}
|
|
10733
10814
|
|
|
10734
10815
|
#onFocus() {
|
|
@@ -10745,12 +10826,6 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
10745
10826
|
}
|
|
10746
10827
|
}
|
|
10747
10828
|
|
|
10748
|
-
#handleTables() {
|
|
10749
|
-
if (this.supportsRichText) {
|
|
10750
|
-
this.removeTableSelectionObserver = yn(this.editor, true);
|
|
10751
|
-
un(this.editor);
|
|
10752
|
-
}
|
|
10753
|
-
}
|
|
10754
10829
|
|
|
10755
10830
|
#attachDebugHooks() {
|
|
10756
10831
|
if (!LexicalEditorElement.debug) return
|
|
@@ -10848,10 +10923,11 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
10848
10923
|
|
|
10849
10924
|
this.container.addEventListener("toggle", this.#handleToggle.bind(this));
|
|
10850
10925
|
this.container.addEventListener("keydown", this.#handleKeyDown.bind(this));
|
|
10926
|
+
|
|
10927
|
+
this.#onToolbarEditor(this.initialize.bind(this));
|
|
10851
10928
|
}
|
|
10852
10929
|
|
|
10853
10930
|
disconnectedCallback() {
|
|
10854
|
-
this.#removeClickOutsideHandler();
|
|
10855
10931
|
this.container.removeEventListener("keydown", this.#handleKeyDown.bind(this));
|
|
10856
10932
|
}
|
|
10857
10933
|
|
|
@@ -10867,46 +10943,29 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
10867
10943
|
return this.toolbar.editor
|
|
10868
10944
|
}
|
|
10869
10945
|
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
}
|
|
10873
|
-
|
|
10874
|
-
#handleToggle(event) {
|
|
10875
|
-
if (this.container.open) {
|
|
10876
|
-
this.#handleOpen(event.target);
|
|
10877
|
-
} else {
|
|
10878
|
-
this.#handleClose();
|
|
10879
|
-
}
|
|
10880
|
-
}
|
|
10881
|
-
|
|
10882
|
-
#handleOpen() {
|
|
10883
|
-
this.#interactiveElements[0].focus();
|
|
10884
|
-
this.#setupClickOutsideHandler();
|
|
10885
|
-
|
|
10886
|
-
this.#resetTabIndexValues();
|
|
10946
|
+
initialize() {
|
|
10947
|
+
// Any post-editor initialization
|
|
10887
10948
|
}
|
|
10888
10949
|
|
|
10889
|
-
|
|
10890
|
-
this.#removeClickOutsideHandler();
|
|
10950
|
+
close() {
|
|
10891
10951
|
this.editor.focus();
|
|
10952
|
+
this.container.open = false;
|
|
10892
10953
|
}
|
|
10893
10954
|
|
|
10894
|
-
#
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
this.clickOutsideHandler = this.#handleClickOutside.bind(this);
|
|
10898
|
-
document.addEventListener("click", this.clickOutsideHandler, true);
|
|
10955
|
+
async #onToolbarEditor(callback) {
|
|
10956
|
+
await this.toolbar.editorConnected;
|
|
10957
|
+
callback();
|
|
10899
10958
|
}
|
|
10900
10959
|
|
|
10901
|
-
#
|
|
10902
|
-
if (
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
this.clickOutsideHandler = null;
|
|
10960
|
+
#handleToggle() {
|
|
10961
|
+
if (this.container.open) {
|
|
10962
|
+
this.#handleOpen();
|
|
10963
|
+
}
|
|
10906
10964
|
}
|
|
10907
10965
|
|
|
10908
|
-
#
|
|
10909
|
-
|
|
10966
|
+
async #handleOpen() {
|
|
10967
|
+
this.#interactiveElements[0].focus();
|
|
10968
|
+
this.#resetTabIndexValues();
|
|
10910
10969
|
}
|
|
10911
10970
|
|
|
10912
10971
|
#handleKeyDown(event) {
|
|
@@ -10994,19 +11053,14 @@ const REMOVE_HIGHLIGHT_SELECTOR = "[data-command='removeHighlight']";
|
|
|
10994
11053
|
const NO_STYLE = Symbol("no_style");
|
|
10995
11054
|
|
|
10996
11055
|
class HighlightDropdown extends ToolbarDropdown {
|
|
10997
|
-
#initialized = false
|
|
10998
|
-
|
|
10999
11056
|
connectedCallback() {
|
|
11000
11057
|
super.connectedCallback();
|
|
11001
11058
|
this.#registerToggleHandler();
|
|
11002
11059
|
}
|
|
11003
11060
|
|
|
11004
|
-
|
|
11005
|
-
if (this.#initialized) return
|
|
11006
|
-
|
|
11061
|
+
initialize() {
|
|
11007
11062
|
this.#setUpButtons();
|
|
11008
11063
|
this.#registerButtonHandlers();
|
|
11009
|
-
this.#initialized = true;
|
|
11010
11064
|
}
|
|
11011
11065
|
|
|
11012
11066
|
#registerToggleHandler() {
|
|
@@ -11019,16 +11073,18 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
11019
11073
|
}
|
|
11020
11074
|
|
|
11021
11075
|
#setUpButtons() {
|
|
11022
|
-
this
|
|
11023
|
-
|
|
11024
|
-
|
|
11076
|
+
const colorGroups = this.editorElement.config.get("highlight.buttons");
|
|
11077
|
+
|
|
11078
|
+
this.#populateButtonGroup("color", colorGroups.color);
|
|
11079
|
+
this.#populateButtonGroup("background-color", colorGroups["background-color"]);
|
|
11080
|
+
|
|
11081
|
+
const maxNumberOfColors = Math.max(colorGroups.color.length, colorGroups["background-color"].length);
|
|
11082
|
+
this.style.setProperty("--max-colors", maxNumberOfColors);
|
|
11025
11083
|
}
|
|
11026
11084
|
|
|
11027
|
-
#populateButtonGroup(
|
|
11028
|
-
const attribute = buttonGroup.dataset.buttonGroup;
|
|
11029
|
-
const values = this.editorElement.config.get(`highlight.buttons.${attribute}`) || [];
|
|
11085
|
+
#populateButtonGroup(attribute, values) {
|
|
11030
11086
|
values.forEach((value, index) => {
|
|
11031
|
-
|
|
11087
|
+
this.#buttonContainer.appendChild(this.#createButton(attribute, value, index));
|
|
11032
11088
|
});
|
|
11033
11089
|
}
|
|
11034
11090
|
|
|
@@ -11037,15 +11093,13 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
11037
11093
|
button.dataset.style = attribute;
|
|
11038
11094
|
button.style.setProperty(attribute, value);
|
|
11039
11095
|
button.dataset.value = value;
|
|
11040
|
-
button.classList.add("lexxy-highlight-button");
|
|
11096
|
+
button.classList.add("lexxy-editor__toolbar-button", "lexxy-highlight-button");
|
|
11041
11097
|
button.name = attribute + "-" + index;
|
|
11042
11098
|
return button
|
|
11043
11099
|
}
|
|
11044
11100
|
|
|
11045
11101
|
#handleToggle({ newState }) {
|
|
11046
11102
|
if (newState === "open") {
|
|
11047
|
-
this.#ensureInitialized();
|
|
11048
|
-
|
|
11049
11103
|
this.editor.getEditorState().read(() => {
|
|
11050
11104
|
this.#updateColorButtonStates(Lr());
|
|
11051
11105
|
});
|
|
@@ -11088,8 +11142,8 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
11088
11142
|
this.querySelector(REMOVE_HIGHLIGHT_SELECTOR).disabled = !hasHighlight;
|
|
11089
11143
|
}
|
|
11090
11144
|
|
|
11091
|
-
get #
|
|
11092
|
-
return this.
|
|
11145
|
+
get #buttonContainer() {
|
|
11146
|
+
return this.querySelector(".lexxy-highlight-colors")
|
|
11093
11147
|
}
|
|
11094
11148
|
|
|
11095
11149
|
get #colorButtons() {
|
|
@@ -11099,501 +11153,714 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
11099
11153
|
|
|
11100
11154
|
customElements.define("lexxy-highlight-dropdown", HighlightDropdown);
|
|
11101
11155
|
|
|
11102
|
-
class
|
|
11103
|
-
|
|
11104
|
-
this
|
|
11105
|
-
this
|
|
11106
|
-
this
|
|
11156
|
+
class TableController {
|
|
11157
|
+
constructor(editorElement) {
|
|
11158
|
+
this.editor = editorElement.editor;
|
|
11159
|
+
this.contents = editorElement.contents;
|
|
11160
|
+
this.selection = editorElement.selection;
|
|
11161
|
+
|
|
11162
|
+
this.currentTableNodeKey = null;
|
|
11163
|
+
this.currentCellKey = null;
|
|
11164
|
+
|
|
11165
|
+
this.#registerKeyHandlers();
|
|
11107
11166
|
}
|
|
11108
11167
|
|
|
11109
|
-
|
|
11110
|
-
this
|
|
11168
|
+
destroy() {
|
|
11169
|
+
this.currentTableNodeKey = null;
|
|
11170
|
+
this.currentCellKey = null;
|
|
11171
|
+
|
|
11172
|
+
this.#unregisterKeyHandlers();
|
|
11111
11173
|
}
|
|
11112
11174
|
|
|
11113
|
-
get
|
|
11114
|
-
|
|
11175
|
+
get currentCell() {
|
|
11176
|
+
if (!this.currentCellKey) return null
|
|
11177
|
+
|
|
11178
|
+
return this.editor.getEditorState().read(() => {
|
|
11179
|
+
const cell = xo(this.currentCellKey);
|
|
11180
|
+
return (cell instanceof xe) ? cell : null
|
|
11181
|
+
})
|
|
11115
11182
|
}
|
|
11116
11183
|
|
|
11117
|
-
get
|
|
11118
|
-
|
|
11184
|
+
get currentTableNode() {
|
|
11185
|
+
if (!this.currentTableNodeKey) return null
|
|
11186
|
+
|
|
11187
|
+
return this.editor.getEditorState().read(() => {
|
|
11188
|
+
const tableNode = xo(this.currentTableNodeKey);
|
|
11189
|
+
return (tableNode instanceof hn) ? tableNode : null
|
|
11190
|
+
})
|
|
11119
11191
|
}
|
|
11120
11192
|
|
|
11121
|
-
get
|
|
11122
|
-
const
|
|
11123
|
-
if (!yr(selection)) return null
|
|
11193
|
+
get currentRowCells() {
|
|
11194
|
+
const currentRowIndex = this.currentRowIndex;
|
|
11124
11195
|
|
|
11125
|
-
const
|
|
11126
|
-
|
|
11196
|
+
const rows = this.tableRows;
|
|
11197
|
+
if (!rows) return null
|
|
11198
|
+
|
|
11199
|
+
return this.editor.getEditorState().read(() => {
|
|
11200
|
+
return rows[currentRowIndex]?.getChildren() ?? null
|
|
11201
|
+
}) ?? null
|
|
11127
11202
|
}
|
|
11128
11203
|
|
|
11129
|
-
get
|
|
11130
|
-
const currentCell = this
|
|
11204
|
+
get currentRowIndex() {
|
|
11205
|
+
const currentCell = this.currentCell;
|
|
11131
11206
|
if (!currentCell) return 0
|
|
11132
|
-
|
|
11207
|
+
|
|
11208
|
+
return this.editor.getEditorState().read(() => {
|
|
11209
|
+
return Ie$1(currentCell)
|
|
11210
|
+
}) ?? 0
|
|
11133
11211
|
}
|
|
11134
11212
|
|
|
11135
|
-
get
|
|
11136
|
-
const
|
|
11137
|
-
|
|
11138
|
-
|
|
11213
|
+
get currentColumnCells() {
|
|
11214
|
+
const columnIndex = this.currentColumnIndex;
|
|
11215
|
+
|
|
11216
|
+
const rows = this.tableRows;
|
|
11217
|
+
if (!rows) return null
|
|
11218
|
+
|
|
11219
|
+
return this.editor.getEditorState().read(() => {
|
|
11220
|
+
return rows.map(row => row.getChildAtIndex(columnIndex))
|
|
11221
|
+
}) ?? null
|
|
11139
11222
|
}
|
|
11140
11223
|
|
|
11141
|
-
get
|
|
11142
|
-
|
|
11224
|
+
get currentColumnIndex() {
|
|
11225
|
+
const currentCell = this.currentCell;
|
|
11226
|
+
if (!currentCell) return 0
|
|
11227
|
+
|
|
11228
|
+
return this.editor.getEditorState().read(() => {
|
|
11229
|
+
return Ue$1(currentCell)
|
|
11230
|
+
}) ?? 0
|
|
11143
11231
|
}
|
|
11144
11232
|
|
|
11145
|
-
|
|
11146
|
-
this.
|
|
11233
|
+
get tableRows() {
|
|
11234
|
+
return this.editor.getEditorState().read(() => {
|
|
11235
|
+
return this.currentTableNode?.getChildren()
|
|
11236
|
+
}) ?? null
|
|
11147
11237
|
}
|
|
11148
11238
|
|
|
11149
|
-
|
|
11150
|
-
|
|
11239
|
+
updateSelectedTable() {
|
|
11240
|
+
let cellNode = null;
|
|
11241
|
+
let tableNode = null;
|
|
11242
|
+
|
|
11243
|
+
this.editor.getEditorState().read(() => {
|
|
11244
|
+
const selection = Lr();
|
|
11245
|
+
if (!selection || !this.selection.isTableCellSelected) return
|
|
11246
|
+
|
|
11247
|
+
const node = selection.getNodes()[0];
|
|
11248
|
+
|
|
11249
|
+
cellNode = Gt(node);
|
|
11250
|
+
tableNode = Qt(node);
|
|
11251
|
+
});
|
|
11252
|
+
|
|
11253
|
+
this.currentCellKey = cellNode?.getKey() ?? null;
|
|
11254
|
+
this.currentTableNodeKey = tableNode?.getKey() ?? null;
|
|
11151
11255
|
}
|
|
11152
11256
|
|
|
11153
|
-
|
|
11154
|
-
if (
|
|
11155
|
-
|
|
11156
|
-
|
|
11157
|
-
|
|
11158
|
-
} else if (event.key === "Escape") {
|
|
11159
|
-
this.#editor.getEditorState().read(() => {
|
|
11160
|
-
const cell = this.#currentCell;
|
|
11161
|
-
if (!cell) return
|
|
11257
|
+
executeTableCommand(command, customIndex = null) {
|
|
11258
|
+
if (command.action === "delete" && command.childType === "table") {
|
|
11259
|
+
this.#deleteTable();
|
|
11260
|
+
return
|
|
11261
|
+
}
|
|
11162
11262
|
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
|
|
11166
|
-
});
|
|
11167
|
-
this.#closeMoreMenu();
|
|
11263
|
+
if (command.action === "toggle") {
|
|
11264
|
+
this.#executeToggleStyle(command);
|
|
11265
|
+
return
|
|
11168
11266
|
}
|
|
11267
|
+
|
|
11268
|
+
this.#executeCommand(command, customIndex);
|
|
11169
11269
|
}
|
|
11170
11270
|
|
|
11171
|
-
#
|
|
11172
|
-
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
handleRollingTabIndex(this.#tableHandlerButtons, event);
|
|
11176
|
-
}
|
|
11271
|
+
#executeCommand(command, customIndex = null) {
|
|
11272
|
+
this.#selectCellAtSelection();
|
|
11273
|
+
this.editor.dispatchCommand(this.#commandName(command));
|
|
11274
|
+
this.#selectNextBestCell(command, customIndex);
|
|
11177
11275
|
}
|
|
11178
11276
|
|
|
11179
|
-
#
|
|
11180
|
-
|
|
11181
|
-
this.appendChild(this.#createColumnButtonsContainer());
|
|
11277
|
+
#executeToggleStyle(command) {
|
|
11278
|
+
const childType = command.childType;
|
|
11182
11279
|
|
|
11183
|
-
|
|
11184
|
-
|
|
11185
|
-
this.addEventListener("keydown", this.#handleTableHandlerKeydown);
|
|
11186
|
-
}
|
|
11280
|
+
let cells = null;
|
|
11281
|
+
let headerState = null;
|
|
11187
11282
|
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11283
|
+
if (childType === "row") {
|
|
11284
|
+
cells = this.currentRowCells;
|
|
11285
|
+
headerState = ve$1.ROW;
|
|
11286
|
+
} else if (childType === "column") {
|
|
11287
|
+
cells = this.currentColumnCells;
|
|
11288
|
+
headerState = ve$1.COLUMN;
|
|
11289
|
+
}
|
|
11191
11290
|
|
|
11192
|
-
|
|
11193
|
-
|
|
11291
|
+
if (!cells || cells.length === 0) return
|
|
11292
|
+
|
|
11293
|
+
this.editor.update(() => {
|
|
11294
|
+
const firstCell = Be$1(cells[0]);
|
|
11295
|
+
if (!firstCell) return
|
|
11296
|
+
|
|
11297
|
+
const currentStyle = firstCell.getHeaderStyles();
|
|
11298
|
+
const newStyle = currentStyle ^ headerState;
|
|
11299
|
+
|
|
11300
|
+
cells.forEach(cell => {
|
|
11301
|
+
this.#setHeaderStyle(cell, newStyle, headerState);
|
|
11302
|
+
});
|
|
11303
|
+
});
|
|
11194
11304
|
}
|
|
11195
11305
|
|
|
11196
|
-
#
|
|
11197
|
-
this
|
|
11198
|
-
this
|
|
11306
|
+
#deleteTable() {
|
|
11307
|
+
this.#selectCellAtSelection();
|
|
11308
|
+
this.editor.dispatchCommand("deleteTable");
|
|
11309
|
+
}
|
|
11310
|
+
|
|
11311
|
+
#selectCellAtSelection() {
|
|
11312
|
+
this.editor.update(() => {
|
|
11313
|
+
const selection = Lr();
|
|
11314
|
+
if (!selection) return
|
|
11199
11315
|
|
|
11200
|
-
|
|
11201
|
-
|
|
11316
|
+
const node = selection.getNodes()[0];
|
|
11317
|
+
|
|
11318
|
+
Gt(node)?.selectEnd();
|
|
11319
|
+
});
|
|
11202
11320
|
}
|
|
11203
11321
|
|
|
11204
|
-
#
|
|
11205
|
-
const
|
|
11206
|
-
if (!tableElement) return
|
|
11322
|
+
#commandName(command) {
|
|
11323
|
+
const { action, childType, direction } = command;
|
|
11207
11324
|
|
|
11208
|
-
const
|
|
11209
|
-
const
|
|
11325
|
+
const childTypeSuffix = upcaseFirst(childType);
|
|
11326
|
+
const directionSuffix = action == "insert" ? upcaseFirst(direction) : "";
|
|
11327
|
+
return `${action}Table${childTypeSuffix}${directionSuffix}`
|
|
11328
|
+
}
|
|
11210
11329
|
|
|
11211
|
-
|
|
11212
|
-
const
|
|
11213
|
-
|
|
11214
|
-
this.style.left = `${relativeCenter}px`;
|
|
11330
|
+
#setHeaderStyle(cell, newStyle, headerState) {
|
|
11331
|
+
const tableCellNode = Be$1(cell);
|
|
11332
|
+
tableCellNode?.setHeaderStyles(newStyle, headerState);
|
|
11215
11333
|
}
|
|
11216
11334
|
|
|
11217
|
-
#
|
|
11218
|
-
|
|
11335
|
+
async #selectCellAtIndex(rowIndex, columnIndex) {
|
|
11336
|
+
// We wait for next frame, otherwise table operations might not have completed yet.
|
|
11337
|
+
await nextFrame();
|
|
11219
11338
|
|
|
11220
|
-
|
|
11221
|
-
if (!tableElement) return
|
|
11339
|
+
if (!this.currentTableNode) return
|
|
11222
11340
|
|
|
11223
|
-
const
|
|
11224
|
-
|
|
11341
|
+
const rows = this.tableRows;
|
|
11342
|
+
if (!rows) return
|
|
11225
11343
|
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
}
|
|
11344
|
+
const row = rows[rowIndex];
|
|
11345
|
+
if (!row) return
|
|
11229
11346
|
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
"aria-label": label,
|
|
11234
|
-
type: "button"
|
|
11347
|
+
this.editor.update(() => {
|
|
11348
|
+
const cell = Be$1(row.getChildAtIndex(columnIndex));
|
|
11349
|
+
cell?.selectEnd();
|
|
11235
11350
|
});
|
|
11236
|
-
button.tabIndex = -1;
|
|
11237
|
-
button.innerHTML = `${icon} <span>${label}</span>`;
|
|
11238
|
-
button.addEventListener("click", onClick.bind(this));
|
|
11239
|
-
|
|
11240
|
-
return button
|
|
11241
11351
|
}
|
|
11242
11352
|
|
|
11243
|
-
#
|
|
11244
|
-
const
|
|
11353
|
+
#selectNextBestCell(command, customIndex = null) {
|
|
11354
|
+
const { childType, direction } = command;
|
|
11245
11355
|
|
|
11246
|
-
|
|
11247
|
-
|
|
11356
|
+
let rowIndex = this.currentRowIndex;
|
|
11357
|
+
let columnIndex = customIndex !== null ? customIndex : this.currentColumnIndex;
|
|
11248
11358
|
|
|
11249
|
-
|
|
11250
|
-
|
|
11359
|
+
const deleteOffset = command.action === "delete" ? -1 : 0;
|
|
11360
|
+
const offset = direction === "after" ? 1 : deleteOffset;
|
|
11251
11361
|
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
|
|
11362
|
+
if (childType === "row") {
|
|
11363
|
+
rowIndex += offset;
|
|
11364
|
+
} else if (childType === "column") {
|
|
11365
|
+
columnIndex += offset;
|
|
11366
|
+
}
|
|
11255
11367
|
|
|
11256
|
-
|
|
11368
|
+
this.#selectCellAtIndex(rowIndex, columnIndex);
|
|
11257
11369
|
}
|
|
11258
11370
|
|
|
11259
|
-
#
|
|
11260
|
-
const
|
|
11371
|
+
#selectNextRow() {
|
|
11372
|
+
const rows = this.tableRows;
|
|
11373
|
+
if (!rows) return
|
|
11261
11374
|
|
|
11262
|
-
const
|
|
11263
|
-
|
|
11375
|
+
const nextRow = rows.at(this.currentRowIndex + 1);
|
|
11376
|
+
if (!nextRow) return
|
|
11264
11377
|
|
|
11265
|
-
this.
|
|
11266
|
-
|
|
11378
|
+
this.editor.update(() => {
|
|
11379
|
+
nextRow.getChildAtIndex(this.currentColumnIndex)?.selectEnd();
|
|
11380
|
+
});
|
|
11381
|
+
}
|
|
11267
11382
|
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11383
|
+
#selectPreviousCell() {
|
|
11384
|
+
const cell = this.currentCell;
|
|
11385
|
+
if (!cell) return
|
|
11271
11386
|
|
|
11272
|
-
|
|
11387
|
+
this.editor.update(() => {
|
|
11388
|
+
cell.selectPrevious();
|
|
11389
|
+
});
|
|
11273
11390
|
}
|
|
11274
11391
|
|
|
11275
|
-
#
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
});
|
|
11279
|
-
container.setAttribute("name", "lexxy-dropdown");
|
|
11392
|
+
#insertRowAndSelectFirstCell() {
|
|
11393
|
+
this.executeTableCommand({ action: "insert", childType: "row", direction: "after" }, 0);
|
|
11394
|
+
}
|
|
11280
11395
|
|
|
11281
|
-
|
|
11396
|
+
#deleteRowAndSelectLastCell() {
|
|
11397
|
+
this.executeTableCommand({ action: "delete", childType: "row" }, -1);
|
|
11398
|
+
}
|
|
11282
11399
|
|
|
11283
|
-
|
|
11284
|
-
|
|
11400
|
+
#deleteRowAndSelectNextNode() {
|
|
11401
|
+
const tableNode = this.currentTableNode;
|
|
11402
|
+
this.executeTableCommand({ action: "delete", childType: "row" });
|
|
11285
11403
|
|
|
11286
|
-
|
|
11287
|
-
|
|
11404
|
+
this.editor.update(() => {
|
|
11405
|
+
const next = tableNode?.getNextSibling();
|
|
11406
|
+
if (Ii(next)) {
|
|
11407
|
+
next.selectStart();
|
|
11408
|
+
} else {
|
|
11409
|
+
const newParagraph = Li();
|
|
11410
|
+
this.currentTableNode.insertAfter(newParagraph);
|
|
11411
|
+
newParagraph.selectStart();
|
|
11412
|
+
}
|
|
11413
|
+
});
|
|
11414
|
+
}
|
|
11288
11415
|
|
|
11289
|
-
|
|
11290
|
-
|
|
11291
|
-
details.appendChild(this.#createDeleteTableSection());
|
|
11416
|
+
#isCurrentCellEmpty() {
|
|
11417
|
+
if (!this.currentTableNode) return false
|
|
11292
11418
|
|
|
11293
|
-
|
|
11419
|
+
const cell = this.currentCell;
|
|
11420
|
+
if (!cell) return false
|
|
11294
11421
|
|
|
11295
|
-
return
|
|
11422
|
+
return cell.getTextContent().trim() === ""
|
|
11296
11423
|
}
|
|
11297
11424
|
|
|
11298
|
-
#
|
|
11299
|
-
|
|
11425
|
+
#isCurrentRowLast() {
|
|
11426
|
+
if (!this.currentTableNode) return false
|
|
11300
11427
|
|
|
11301
|
-
const
|
|
11302
|
-
|
|
11303
|
-
{ icon: this.#icon("add-column-after"), label: "Add column after", onClick: () => this.#insertTableColumn("right") },
|
|
11304
|
-
{ icon: this.#icon("remove-column"), label: "Remove column", onClick: this.#deleteTableColumn },
|
|
11305
|
-
{ icon: this.#icon("toggle-column-style"), label: "Toggle column style", onClick: this.#toggleColumnHeaderStyle },
|
|
11306
|
-
];
|
|
11428
|
+
const rows = this.tableRows;
|
|
11429
|
+
if (!rows) return false
|
|
11307
11430
|
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11431
|
+
return rows.length === this.currentRowIndex + 1
|
|
11432
|
+
}
|
|
11433
|
+
|
|
11434
|
+
#isCurrentRowEmpty() {
|
|
11435
|
+
if (!this.currentTableNode) return false
|
|
11312
11436
|
|
|
11313
|
-
|
|
11437
|
+
const cells = this.currentRowCells;
|
|
11438
|
+
if (!cells) return false
|
|
11439
|
+
|
|
11440
|
+
return cells.every(cell => cell.getTextContent().trim() === "")
|
|
11314
11441
|
}
|
|
11315
11442
|
|
|
11316
|
-
#
|
|
11317
|
-
|
|
11443
|
+
#isFirstCellInRow() {
|
|
11444
|
+
if (!this.currentTableNode) return false
|
|
11318
11445
|
|
|
11319
|
-
const
|
|
11320
|
-
|
|
11321
|
-
{ icon: this.#icon("add-row-below"), label: "Add row below", onClick: () => this.#insertTableRow("below") },
|
|
11322
|
-
{ icon: this.#icon("remove-row"), label: "Remove row", onClick: this.#deleteTableRow },
|
|
11323
|
-
{ icon: this.#icon("toggle-row-style"), label: "Toggle row style", onClick: this.#toggleRowHeaderStyle }
|
|
11324
|
-
];
|
|
11446
|
+
const cells = this.currentRowCells;
|
|
11447
|
+
if (!cells) return false
|
|
11325
11448
|
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11449
|
+
return cells.indexOf(this.currentCell) === 0
|
|
11450
|
+
}
|
|
11451
|
+
|
|
11452
|
+
#registerKeyHandlers() {
|
|
11453
|
+
// We can't prevent these externally using regular keydown because Lexical handles it first.
|
|
11454
|
+
this.unregisterBackspaceKeyHandler = this.editor.registerCommand(we$1, (event) => this.#handleBackspaceKey(event), Bi);
|
|
11455
|
+
this.unregisterEnterKeyHandler = this.editor.registerCommand(Ne$2, (event) => this.#handleEnterKey(event), Bi);
|
|
11456
|
+
}
|
|
11457
|
+
|
|
11458
|
+
#unregisterKeyHandlers() {
|
|
11459
|
+
this.unregisterBackspaceKeyHandler?.();
|
|
11460
|
+
this.unregisterEnterKeyHandler?.();
|
|
11330
11461
|
|
|
11331
|
-
|
|
11462
|
+
this.unregisterBackspaceKeyHandler = null;
|
|
11463
|
+
this.unregisterEnterKeyHandler = null;
|
|
11332
11464
|
}
|
|
11333
11465
|
|
|
11334
|
-
#
|
|
11335
|
-
|
|
11466
|
+
#handleBackspaceKey(event) {
|
|
11467
|
+
if (!this.currentTableNode) return false
|
|
11336
11468
|
|
|
11337
|
-
|
|
11469
|
+
if (this.#isCurrentRowEmpty() && this.#isFirstCellInRow()) {
|
|
11470
|
+
event.preventDefault();
|
|
11471
|
+
this.#deleteRowAndSelectLastCell();
|
|
11472
|
+
return true
|
|
11473
|
+
}
|
|
11338
11474
|
|
|
11339
|
-
|
|
11340
|
-
|
|
11475
|
+
if (this.#isCurrentCellEmpty() && !this.#isFirstCellInRow()) {
|
|
11476
|
+
event.preventDefault();
|
|
11477
|
+
this.#selectPreviousCell();
|
|
11478
|
+
return true
|
|
11479
|
+
}
|
|
11341
11480
|
|
|
11342
|
-
return
|
|
11481
|
+
return false
|
|
11343
11482
|
}
|
|
11344
11483
|
|
|
11345
|
-
#
|
|
11346
|
-
if (
|
|
11347
|
-
|
|
11484
|
+
#handleEnterKey(event) {
|
|
11485
|
+
if ((event.ctrlKey || event.metaKey) || event.shiftKey || !this.currentTableNode) return false
|
|
11486
|
+
|
|
11487
|
+
if (this.selection.isInsideList || this.selection.isInsideCodeBlock) return false
|
|
11488
|
+
|
|
11489
|
+
event.preventDefault();
|
|
11490
|
+
|
|
11491
|
+
if (this.#isCurrentRowLast() && this.#isCurrentRowEmpty()) {
|
|
11492
|
+
this.#deleteRowAndSelectNextNode();
|
|
11493
|
+
} else if (this.#isCurrentRowLast()) {
|
|
11494
|
+
this.#insertRowAndSelectFirstCell();
|
|
11348
11495
|
} else {
|
|
11349
|
-
this.#
|
|
11496
|
+
this.#selectNextRow();
|
|
11350
11497
|
}
|
|
11498
|
+
|
|
11499
|
+
return true
|
|
11351
11500
|
}
|
|
11501
|
+
}
|
|
11352
11502
|
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11503
|
+
var TableIcons = {
|
|
11504
|
+
"insert-row-before":
|
|
11505
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11506
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.86804e-07 15C8.29055e-07 15.8284 0.671574 16.5 1.5 16.5H15L15.1533 16.4922C15.8593 16.4205 16.4205 15.8593 16.4922 15.1533L16.5 15V4.5L16.4922 4.34668C16.4154 3.59028 15.7767 3 15 3H13.5L13.5 4.5H15V9H1.5L1.5 4.5L3 4.5V3H1.5C0.671574 3 1.20956e-06 3.67157 1.24577e-06 4.5L7.86804e-07 15ZM15 10.5V15H1.5L1.5 10.5H15Z"/>
|
|
11507
|
+
<path d="M4.5 4.5H7.5V7.5H9V4.5H12L12 3L9 3V6.55671e-08L7.5 0V3L4.5 3V4.5Z"/>
|
|
11508
|
+
</svg>`,
|
|
11509
|
+
|
|
11510
|
+
"insert-row-after":
|
|
11511
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11512
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.86804e-07 13.5C7.50592e-07 14.3284 0.671574 15 1.5 15H3V13.5H1.5L1.5 9L15 9V13.5H13.5V15H15C15.7767 15 16.4154 14.4097 16.4922 13.6533L16.5 13.5V3L16.4922 2.84668C16.4205 2.14069 15.8593 1.57949 15.1533 1.50781L15 1.5L1.5 1.5C0.671574 1.5 1.28803e-06 2.17157 1.24577e-06 3L7.86804e-07 13.5ZM15 3V7.5L1.5 7.5L1.5 3L15 3Z"/>
|
|
11513
|
+
<path d="M7.5 15V18H9V15H12V13.5H9V10.5H7.5V13.5H4.5V15H7.5Z"/>
|
|
11514
|
+
</svg>`,
|
|
11515
|
+
|
|
11516
|
+
"delete-row":
|
|
11517
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11518
|
+
<path d="M16.4922 12.1533C16.4154 12.9097 15.7767 13.5 15 13.5L12 13.5V12H15V6L1.5 6L1.5 12H4.5V13.5H1.5C0.723337 13.5 0.0846104 12.9097 0.00781328 12.1533L7.86804e-07 12L1.04907e-06 6C1.17362e-06 5.22334 0.590278 4.58461 1.34668 4.50781L1.5 4.5L15 4.5C15.8284 4.5 16.5 5.17157 16.5 6V12L16.4922 12.1533Z"/>
|
|
11519
|
+
<path d="M10.3711 15.9316L8.25 13.8096L6.12793 15.9316L5.06738 14.8711L7.18945 12.75L5.06738 10.6289L6.12793 9.56836L8.25 11.6895L10.3711 9.56836L11.4316 10.6289L9.31055 12.75L11.4316 14.8711L10.3711 15.9316Z"/>
|
|
11520
|
+
</svg>`,
|
|
11521
|
+
|
|
11522
|
+
"toggle-row":
|
|
11523
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11524
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.00781328 13.6533C0.0846108 14.4097 0.723337 15 1.5 15L15 15L15.1533 14.9922C15.8593 14.9205 16.4205 14.3593 16.4922 13.6533L16.5 13.5V4.5L16.4922 4.34668C16.4205 3.64069 15.8593 3.07949 15.1533 3.00781L15 3L1.5 3C0.671574 3 1.24863e-06 3.67157 1.18021e-06 4.5L7.86804e-07 13.5L0.00781328 13.6533ZM15 9V13.5L1.5 13.5L1.5 9L15 9Z"/>
|
|
11525
|
+
</svg>`,
|
|
11526
|
+
|
|
11527
|
+
"insert-column-before":
|
|
11528
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11529
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 0C3.67157 0 3 0.671573 3 1.5V3H4.5V1.5H9V15H4.5V13.5H3V15C3 15.7767 3.59028 16.4154 4.34668 16.4922L4.5 16.5H15L15.1533 16.4922C15.8593 16.4205 16.4205 15.8593 16.4922 15.1533L16.5 15V1.5C16.5 0.671573 15.8284 6.03989e-09 15 0H4.5ZM15 15H10.5V1.5H15V15Z"/>
|
|
11530
|
+
<path d="M3 7.5H0V9H3V12H4.5V9H7.5V7.5H4.5V4.5H3V7.5Z"/>
|
|
11531
|
+
</svg>`,
|
|
11532
|
+
|
|
11533
|
+
"insert-column-after":
|
|
11534
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11535
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 0C14.3284 0 15 0.671573 15 1.5V3H13.5V1.5H9V15H13.5V13.5H15V15C15 15.7767 14.4097 16.4154 13.6533 16.4922L13.5 16.5H3L2.84668 16.4922C2.14069 16.4205 1.57949 15.8593 1.50781 15.1533L1.5 15V1.5C1.5 0.671573 2.17157 6.03989e-09 3 0H13.5ZM3 15H7.5V1.5H3V15Z"/>
|
|
11536
|
+
<path d="M15 7.5H18V9H15V12H13.5V9H10.5V7.5H13.5V4.5H15V7.5Z"/>
|
|
11537
|
+
</svg>`,
|
|
11538
|
+
|
|
11539
|
+
"delete-column":
|
|
11540
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11541
|
+
<path d="M12.1533 0.0078125C12.9097 0.0846097 13.5 0.723336 13.5 1.5V4.5H12V1.5H6V15H12V12H13.5V15C13.5 15.7767 12.9097 16.4154 12.1533 16.4922L12 16.5H6C5.22334 16.5 4.58461 15.9097 4.50781 15.1533L4.5 15V1.5C4.5 0.671573 5.17157 2.41596e-08 6 0H12L12.1533 0.0078125Z"/>
|
|
11542
|
+
<path d="M15.9316 6.12891L13.8105 8.24902L15.9326 10.3711L14.8711 11.4316L12.75 9.31055L10.6289 11.4316L9.56738 10.3711L11.6885 8.24902L9.56836 6.12891L10.6289 5.06836L12.75 7.18848L14.8711 5.06836L15.9316 6.12891Z"/>
|
|
11543
|
+
</svg>`,
|
|
11544
|
+
|
|
11545
|
+
"toggle-column":
|
|
11546
|
+
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11547
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6533 17.9922C14.4097 17.9154 15 17.2767 15 16.5L15 3L14.9922 2.84668C14.9205 2.14069 14.3593 1.57949 13.6533 1.50781L13.5 1.5L4.5 1.5L4.34668 1.50781C3.59028 1.58461 3 2.22334 3 3L3 16.5C3 17.2767 3.59028 17.9154 4.34668 17.9922L4.5 18L13.5 18L13.6533 17.9922ZM9 3L13.5 3L13.5 16.5L9 16.5L9 3Z" />
|
|
11548
|
+
</svg>`,
|
|
11549
|
+
|
|
11550
|
+
"delete-table":
|
|
11551
|
+
`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
11552
|
+
<path d="M18.2129 19.2305C18.0925 20.7933 16.7892 22 15.2217 22H7.77832C6.21084 22 4.90753 20.7933 4.78711 19.2305L4 9H19L18.2129 19.2305Z"/><path d="M13 2C14.1046 2 15 2.89543 15 4H19C19.5523 4 20 4.44772 20 5V6C20 6.55228 19.5523 7 19 7H4C3.44772 7 3 6.55228 3 6V5C3 4.44772 3.44772 4 4 4H8C8 2.89543 8.89543 2 10 2H13Z"/>
|
|
11553
|
+
</svg>`
|
|
11554
|
+
};
|
|
11555
|
+
|
|
11556
|
+
class TableTools extends HTMLElement {
|
|
11557
|
+
connectedCallback() {
|
|
11558
|
+
this.tableController = new TableController(this.#editorElement);
|
|
11559
|
+
|
|
11560
|
+
this.#setUpButtons();
|
|
11561
|
+
this.#monitorForTableSelection();
|
|
11562
|
+
this.#registerKeyboardShortcuts();
|
|
11356
11563
|
}
|
|
11357
11564
|
|
|
11358
|
-
|
|
11359
|
-
this.#
|
|
11360
|
-
this.#editor.getEditorState().read(() => {
|
|
11361
|
-
const selection = Lr();
|
|
11362
|
-
if (!yr(selection)) return
|
|
11565
|
+
disconnectedCallback() {
|
|
11566
|
+
this.#unregisterKeyboardShortcuts();
|
|
11363
11567
|
|
|
11364
|
-
|
|
11365
|
-
|
|
11568
|
+
this.unregisterUpdateListener?.();
|
|
11569
|
+
this.unregisterUpdateListener = null;
|
|
11366
11570
|
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
}
|
|
11372
|
-
});
|
|
11373
|
-
});
|
|
11571
|
+
this.removeEventListener("keydown", this.#handleToolsKeydown);
|
|
11572
|
+
|
|
11573
|
+
this.tableController?.destroy();
|
|
11574
|
+
this.tableController = null;
|
|
11374
11575
|
}
|
|
11375
11576
|
|
|
11376
|
-
#
|
|
11377
|
-
this.#editorElement.
|
|
11577
|
+
get #editor() {
|
|
11578
|
+
return this.#editorElement.editor
|
|
11579
|
+
}
|
|
11378
11580
|
|
|
11379
|
-
|
|
11380
|
-
|
|
11381
|
-
if (!tableParent) return
|
|
11382
|
-
tableParent.classList.add("node--selected");
|
|
11383
|
-
}
|
|
11581
|
+
get #editorElement() {
|
|
11582
|
+
return this.closest("lexxy-editor")
|
|
11384
11583
|
}
|
|
11385
11584
|
|
|
11386
|
-
#
|
|
11387
|
-
this.
|
|
11388
|
-
this.#updateButtonsPosition(tableNode);
|
|
11389
|
-
this.#showTableHandlerButtons();
|
|
11585
|
+
get #tableToolsButtons() {
|
|
11586
|
+
return Array.from(this.querySelectorAll("button, details > summary"))
|
|
11390
11587
|
}
|
|
11391
11588
|
|
|
11392
|
-
#
|
|
11393
|
-
this
|
|
11394
|
-
|
|
11395
|
-
if (!currentCell) return
|
|
11589
|
+
#setUpButtons() {
|
|
11590
|
+
this.appendChild(this.#createRowButtonsContainer());
|
|
11591
|
+
this.appendChild(this.#createColumnButtonsContainer());
|
|
11396
11592
|
|
|
11397
|
-
|
|
11398
|
-
|
|
11593
|
+
this.appendChild(this.#createDeleteTableButton());
|
|
11594
|
+
this.addEventListener("keydown", this.#handleToolsKeydown);
|
|
11595
|
+
}
|
|
11399
11596
|
|
|
11400
|
-
|
|
11401
|
-
});
|
|
11597
|
+
#createButtonsContainer(childType, setCountProperty, moreMenu) {
|
|
11598
|
+
const container = createElement("div", { className: `lexxy-table-control lexxy-table-control--${childType}` });
|
|
11599
|
+
|
|
11600
|
+
const plusButton = this.#createButton(`Add ${childType}`, { action: "insert", childType, direction: "after" }, "+");
|
|
11601
|
+
const minusButton = this.#createButton(`Remove ${childType}`, { action: "delete", childType }, "−");
|
|
11602
|
+
|
|
11603
|
+
const dropdown = createElement("details", { className: "lexxy-table-control__more-menu" });
|
|
11604
|
+
dropdown.setAttribute("name", "lexxy-dropdown");
|
|
11605
|
+
dropdown.tabIndex = -1;
|
|
11606
|
+
|
|
11607
|
+
const count = createElement("summary", {}, `_ ${childType}s`);
|
|
11608
|
+
setCountProperty(count);
|
|
11609
|
+
dropdown.appendChild(count);
|
|
11610
|
+
|
|
11611
|
+
dropdown.appendChild(moreMenu);
|
|
11612
|
+
|
|
11613
|
+
container.appendChild(minusButton);
|
|
11614
|
+
container.appendChild(dropdown);
|
|
11615
|
+
container.appendChild(plusButton);
|
|
11616
|
+
|
|
11617
|
+
return container
|
|
11402
11618
|
}
|
|
11403
11619
|
|
|
11404
|
-
#
|
|
11405
|
-
this.#
|
|
11620
|
+
#createRowButtonsContainer() {
|
|
11621
|
+
return this.#createButtonsContainer(
|
|
11622
|
+
"row",
|
|
11623
|
+
(count) => { this.rowCount = count; },
|
|
11624
|
+
this.#createMoreMenuSection("row")
|
|
11625
|
+
)
|
|
11406
11626
|
}
|
|
11407
11627
|
|
|
11408
|
-
#
|
|
11409
|
-
|
|
11628
|
+
#createColumnButtonsContainer() {
|
|
11629
|
+
return this.#createButtonsContainer(
|
|
11630
|
+
"column",
|
|
11631
|
+
(count) => { this.columnCount = count; },
|
|
11632
|
+
this.#createMoreMenuSection("column")
|
|
11633
|
+
)
|
|
11634
|
+
}
|
|
11410
11635
|
|
|
11411
|
-
|
|
11412
|
-
|
|
11636
|
+
#createMoreMenuSection(childType) {
|
|
11637
|
+
const section = createElement("div", { className: "lexxy-table-control__more-menu-details" });
|
|
11638
|
+
const addBeforeButton = this.#createButton(`Add ${childType} before`, { action: "insert", childType, direction: "before" });
|
|
11639
|
+
const addAfterButton = this.#createButton(`Add ${childType} after`, { action: "insert", childType, direction: "after" });
|
|
11640
|
+
const toggleStyleButton = this.#createButton(`Toggle ${childType} style`, { action: "toggle", childType });
|
|
11641
|
+
const deleteButton = this.#createButton(`Remove ${childType}`, { action: "delete", childType });
|
|
11413
11642
|
|
|
11414
|
-
|
|
11643
|
+
section.appendChild(addBeforeButton);
|
|
11644
|
+
section.appendChild(addAfterButton);
|
|
11645
|
+
section.appendChild(toggleStyleButton);
|
|
11646
|
+
section.appendChild(deleteButton);
|
|
11647
|
+
|
|
11648
|
+
return section
|
|
11415
11649
|
}
|
|
11416
11650
|
|
|
11417
|
-
#
|
|
11418
|
-
|
|
11651
|
+
#createDeleteTableButton() {
|
|
11652
|
+
const container = createElement("div", { className: "lexxy-table-control" });
|
|
11419
11653
|
|
|
11420
|
-
this.#
|
|
11421
|
-
|
|
11422
|
-
|
|
11654
|
+
const deleteTableButton = this.#createButton("Delete this table?", { action: "delete", childType: "table" });
|
|
11655
|
+
deleteTableButton.classList.add("lexxy-table-control__button--delete-table");
|
|
11656
|
+
|
|
11657
|
+
container.appendChild(deleteTableButton);
|
|
11658
|
+
|
|
11659
|
+
this.deleteContainer = container;
|
|
11423
11660
|
|
|
11424
|
-
|
|
11425
|
-
this.#executeTableCommand("insert", "row", direction);
|
|
11661
|
+
return container
|
|
11426
11662
|
}
|
|
11427
11663
|
|
|
11428
|
-
#
|
|
11429
|
-
|
|
11664
|
+
#createButton(label, command = {}, icon = this.#icon(command)) {
|
|
11665
|
+
const button = createElement("button", {
|
|
11666
|
+
className: "lexxy-table-control__button",
|
|
11667
|
+
"aria-label": label,
|
|
11668
|
+
type: "button"
|
|
11669
|
+
});
|
|
11670
|
+
button.tabIndex = -1;
|
|
11671
|
+
button.innerHTML = `${icon} <span>${label}</span>`;
|
|
11672
|
+
|
|
11673
|
+
button.dataset.action = command.action;
|
|
11674
|
+
button.dataset.childType = command.childType;
|
|
11675
|
+
button.dataset.direction = command.direction;
|
|
11676
|
+
|
|
11677
|
+
button.addEventListener("click", () => this.#executeTableCommand(command));
|
|
11678
|
+
|
|
11679
|
+
button.addEventListener("mouseover", () => this.#handleCommandButtonHover());
|
|
11680
|
+
button.addEventListener("focus", () => this.#handleCommandButtonHover());
|
|
11681
|
+
button.addEventListener("mouseout", () => this.#handleCommandButtonHover());
|
|
11682
|
+
|
|
11683
|
+
return button
|
|
11430
11684
|
}
|
|
11431
11685
|
|
|
11432
|
-
#
|
|
11433
|
-
this.#
|
|
11686
|
+
#registerKeyboardShortcuts() {
|
|
11687
|
+
this.unregisterKeyboardShortcuts = this.#editor.registerCommand(me$1, this.#handleAccessibilityShortcutKey, Bi);
|
|
11434
11688
|
}
|
|
11435
11689
|
|
|
11436
|
-
#
|
|
11437
|
-
this
|
|
11690
|
+
#unregisterKeyboardShortcuts() {
|
|
11691
|
+
this.unregisterKeyboardShortcuts?.();
|
|
11692
|
+
this.unregisterKeyboardShortcuts = null;
|
|
11438
11693
|
}
|
|
11439
11694
|
|
|
11440
|
-
#
|
|
11441
|
-
|
|
11442
|
-
const
|
|
11443
|
-
|
|
11695
|
+
#handleAccessibilityShortcutKey = (event) => {
|
|
11696
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "F10") {
|
|
11697
|
+
const firstButton = this.querySelector("button, [tabindex]:not([tabindex='-1'])");
|
|
11698
|
+
firstButton?.focus();
|
|
11699
|
+
}
|
|
11700
|
+
}
|
|
11444
11701
|
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11702
|
+
#handleToolsKeydown = (event) => {
|
|
11703
|
+
if (event.key === "Escape") {
|
|
11704
|
+
this.#handleEscapeKey();
|
|
11705
|
+
} else {
|
|
11706
|
+
handleRollingTabIndex(this.#tableToolsButtons, event);
|
|
11707
|
+
}
|
|
11708
|
+
}
|
|
11448
11709
|
|
|
11449
|
-
|
|
11710
|
+
#handleEscapeKey() {
|
|
11711
|
+
const cell = this.tableController.currentCell;
|
|
11712
|
+
if (!cell) return
|
|
11450
11713
|
|
|
11451
|
-
|
|
11452
|
-
|
|
11453
|
-
|
|
11714
|
+
this.#editor.update(() => {
|
|
11715
|
+
cell.select();
|
|
11716
|
+
this.#editor.focus();
|
|
11454
11717
|
});
|
|
11455
11718
|
|
|
11456
|
-
this.#
|
|
11457
|
-
this.#updateRowColumnCount();
|
|
11719
|
+
this.#update();
|
|
11458
11720
|
}
|
|
11459
11721
|
|
|
11460
|
-
#
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11722
|
+
async #handleCommandButtonHover() {
|
|
11723
|
+
await nextFrame();
|
|
11724
|
+
|
|
11725
|
+
this.#clearCellStyles();
|
|
11726
|
+
|
|
11727
|
+
const activeElement = this.querySelector("button:hover, button:focus");
|
|
11728
|
+
if (!activeElement) return
|
|
11729
|
+
|
|
11730
|
+
const command = {
|
|
11731
|
+
action: activeElement.dataset.action,
|
|
11732
|
+
childType: activeElement.dataset.childType,
|
|
11733
|
+
direction: activeElement.dataset.direction
|
|
11734
|
+
};
|
|
11735
|
+
|
|
11736
|
+
let cellsToHighlight = null;
|
|
11737
|
+
|
|
11738
|
+
switch (command.childType) {
|
|
11739
|
+
case "row":
|
|
11740
|
+
cellsToHighlight = this.tableController.currentRowCells;
|
|
11479
11741
|
break
|
|
11480
|
-
case "
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
case "column":
|
|
11486
|
-
this.#editor.dispatchCommand("deleteTableColumn");
|
|
11487
|
-
break
|
|
11488
|
-
}
|
|
11742
|
+
case "column":
|
|
11743
|
+
cellsToHighlight = this.tableController.currentColumnCells;
|
|
11744
|
+
break
|
|
11745
|
+
case "table":
|
|
11746
|
+
cellsToHighlight = this.tableController.tableRows;
|
|
11489
11747
|
break
|
|
11490
11748
|
}
|
|
11491
|
-
}
|
|
11492
11749
|
|
|
11493
|
-
|
|
11494
|
-
this.#editor.update(() => {
|
|
11495
|
-
const rows = this.currentTableNode.getChildren();
|
|
11750
|
+
if (!cellsToHighlight) return
|
|
11496
11751
|
|
|
11497
|
-
|
|
11498
|
-
|
|
11752
|
+
cellsToHighlight.forEach(cell => {
|
|
11753
|
+
const cellElement = this.#editor.getElementByKey(cell.getKey());
|
|
11754
|
+
if (!cellElement) return
|
|
11499
11755
|
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
|
|
11756
|
+
cellElement.classList.toggle(theme.tableCellHighlight, true);
|
|
11757
|
+
Object.assign(cellElement.dataset, command);
|
|
11758
|
+
});
|
|
11759
|
+
}
|
|
11503
11760
|
|
|
11504
|
-
|
|
11505
|
-
|
|
11761
|
+
#monitorForTableSelection() {
|
|
11762
|
+
this.unregisterUpdateListener = this.#editor.registerUpdateListener(() => {
|
|
11763
|
+
this.tableController.updateSelectedTable();
|
|
11506
11764
|
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11765
|
+
const tableNode = this.tableController.currentTableNode;
|
|
11766
|
+
if (tableNode) {
|
|
11767
|
+
this.#show();
|
|
11768
|
+
} else {
|
|
11769
|
+
this.#hide();
|
|
11770
|
+
}
|
|
11510
11771
|
});
|
|
11511
11772
|
}
|
|
11512
11773
|
|
|
11513
|
-
#
|
|
11514
|
-
this
|
|
11515
|
-
|
|
11774
|
+
#executeTableCommand(command) {
|
|
11775
|
+
this.tableController.executeTableCommand(command);
|
|
11776
|
+
this.#update();
|
|
11777
|
+
}
|
|
11516
11778
|
|
|
11517
|
-
|
|
11518
|
-
|
|
11779
|
+
#show() {
|
|
11780
|
+
this.style.display = "flex";
|
|
11781
|
+
this.#update();
|
|
11782
|
+
}
|
|
11519
11783
|
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11784
|
+
#hide() {
|
|
11785
|
+
this.style.display = "none";
|
|
11786
|
+
this.#clearCellStyles();
|
|
11787
|
+
}
|
|
11523
11788
|
|
|
11524
|
-
|
|
11525
|
-
|
|
11789
|
+
#update() {
|
|
11790
|
+
this.#updateButtonsPosition();
|
|
11791
|
+
this.#updateRowColumnCount();
|
|
11792
|
+
this.#closeMoreMenu();
|
|
11793
|
+
this.#handleCommandButtonHover();
|
|
11794
|
+
}
|
|
11526
11795
|
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
if (!cell) return
|
|
11530
|
-
this.#setHeaderStyle(cell, newStyle, ve$1.COLUMN);
|
|
11531
|
-
});
|
|
11532
|
-
});
|
|
11796
|
+
#closeMoreMenu() {
|
|
11797
|
+
this.querySelector("details[open]")?.removeAttribute("open");
|
|
11533
11798
|
}
|
|
11534
11799
|
|
|
11535
|
-
#
|
|
11536
|
-
const
|
|
11800
|
+
#updateButtonsPosition() {
|
|
11801
|
+
const tableNode = this.tableController.currentTableNode;
|
|
11802
|
+
if (!tableNode) return
|
|
11537
11803
|
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
const
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
</svg>`,
|
|
11560
|
-
|
|
11561
|
-
"toggle-row-style":
|
|
11562
|
-
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11563
|
-
<path d="M1 2C1 1.44772 1.44772 1 2 1H7C7.55228 1 8 1.44772 8 2V7C8 7.55228 7.55228 8 7 8H2C1.44772 8 1 7.55228 1 7V2Z"/><path d="M2.5 15.5H6.5V11.5H2.5V15.5ZM8 16C8 16.5177 7.60667 16.9438 7.10254 16.9951L7 17H2L1.89746 16.9951C1.42703 16.9472 1.05278 16.573 1.00488 16.1025L1 16V11C1 10.4477 1.44772 10 2 10H7C7.55228 10 8 10.4477 8 11V16Z"/><path d="M10 2C10 1.44772 10.4477 1 11 1H16C16.5523 1 17 1.44772 17 2V7C17 7.55228 16.5523 8 16 8H11C10.4477 8 10 7.55228 10 7V2Z"/><path d="M11.5 15.5H15.5V11.5H11.5V15.5ZM17 16C17 16.5177 16.6067 16.9438 16.1025 16.9951L16 17H11L10.8975 16.9951C10.427 16.9472 10.0528 16.573 10.0049 16.1025L10 16V11C10 10.4477 10.4477 10 11 10H16C16.5523 10 17 10.4477 17 11V16Z"/>
|
|
11564
|
-
</svg>`,
|
|
11565
|
-
|
|
11566
|
-
"add-column-before":
|
|
11567
|
-
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11568
|
-
<path d="M7 4L10 2.62268e-07L4 0L7 4ZM7.5 6.5L7.5 16.5H6.5L6.5 6.5H7.5ZM8 18C8.55228 18 9 17.5523 9 17V6C9 5.44772 8.55229 5 8 5H6C5.44772 5 5 5.44772 5 6L5 17C5 17.5523 5.44772 18 6 18H8Z"/><path d="M2 2C1.44772 2 1 2.44772 1 3L1 15C1 15.5523 1.44772 16 2 16C2.55228 16 3 15.5523 3 15L3 3C3 2.44772 2.55229 2 2 2Z"/><path d="M12 2C11.4477 2 11 2.44772 11 3L11 15C11 15.5523 11.4477 16 12 16C12.5523 16 13 15.5523 13 15L13 3C13 2.44772 12.5523 2 12 2Z"/><path d="M16 2C15.4477 2 15 2.44772 15 3L15 15C15 15.5523 15.4477 16 16 16C16.5523 16 17 15.5523 17 15V3C17 2.44772 16.5523 2 16 2Z"/>
|
|
11569
|
-
</svg>`,
|
|
11570
|
-
|
|
11571
|
-
"add-column-after":
|
|
11572
|
-
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11573
|
-
<path d="M11 4L8 2.62268e-07L14 0L11 4ZM10.5 6.5V16.5H11.5V6.5H10.5ZM10 18C9.44772 18 9 17.5523 9 17V6C9 5.44772 9.44772 5 10 5H12C12.5523 5 13 5.44772 13 6V17C13 17.5523 12.5523 18 12 18H10Z"/><path d="M16 2C16.5523 2 17 2.44772 17 3L17 15C17 15.5523 16.5523 16 16 16C15.4477 16 15 15.5523 15 15V3C15 2.44772 15.4477 2 16 2Z"/><path d="M6 2C6.55228 2 7 2.44772 7 3L7 15C7 15.5523 6.55228 16 6 16C5.44772 16 5 15.5523 5 15L5 3C5 2.44772 5.44771 2 6 2Z"/><path d="M2 2C2.55228 2 3 2.44772 3 3L3 15C3 15.5523 2.55228 16 2 16C1.44772 16 1 15.5523 1 15V3C1 2.44772 1.44771 2 2 2Z"/>
|
|
11574
|
-
</svg>`,
|
|
11575
|
-
|
|
11576
|
-
"remove-column":
|
|
11577
|
-
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11578
|
-
<path d="M10.1025 0.00488281C10.6067 0.0562145 11 0.482323 11 1V5.50781L9.5 4.00781V1.5H5.5V16.5H9.5V13.9941L11 12.4941V17L10.9951 17.1025C10.9472 17.573 10.573 17.9472 10.1025 17.9951L10 18H5C4.48232 18 4.05621 17.6067 4.00488 17.1025L4 17V1C4 0.447715 4.44772 1.61064e-08 5 0H10L10.1025 0.00488281Z"/><path d="M12.7169 8.99999L15.015 11.2981L13.9543 12.3588L11.6562 10.0607L9.35815 12.3588L8.29749 11.2981L10.5956 8.99999L8.29749 6.7019L9.35815 5.64124L11.6562 7.93933L13.9543 5.64124L15.015 6.7019L12.7169 8.99999Z"/>
|
|
11579
|
-
</svg>`,
|
|
11580
|
-
|
|
11581
|
-
"toggle-column-style":
|
|
11582
|
-
`<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
|
|
11583
|
-
<path d="M1 2C1 1.44772 1.44772 1 2 1H7C7.55228 1 8 1.44772 8 2V7C8 7.55228 7.55228 8 7 8H2C1.44772 8 1 7.55228 1 7V2Z"/><path d="M1 11C1 10.4477 1.44772 10 2 10H7C7.55228 10 8 10.4477 8 11V16C8 16.5523 7.55228 17 7 17H2C1.44772 17 1 16.5523 1 16V11Z"/><path d="M11.5 6.5H15.5V2.5H11.5V6.5ZM17 7C17 7.51768 16.6067 7.94379 16.1025 7.99512L16 8H11L10.8975 7.99512C10.427 7.94722 10.0528 7.57297 10.0049 7.10254L10 7V2C10 1.44772 10.4477 1 11 1H16C16.5523 1 17 1.44772 17 2V7Z"/><path d="M11.5 15.5H15.5V11.5H11.5V15.5ZM17 16C17 16.5177 16.6067 16.9438 16.1025 16.9951L16 17H11L10.8975 16.9951C10.427 16.9472 10.0528 16.573 10.0049 16.1025L10 16V11C10 10.4477 10.4477 10 11 10H16C16.5523 10 17 10.4477 17 11V16Z"/>
|
|
11584
|
-
</svg>`,
|
|
11585
|
-
|
|
11586
|
-
"delete-table":
|
|
11587
|
-
`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
11588
|
-
<path d="M18.2129 19.2305C18.0925 20.7933 16.7892 22 15.2217 22H7.77832C6.21084 22 4.90753 20.7933 4.78711 19.2305L4 9H19L18.2129 19.2305Z"/><path d="M13 2C14.1046 2 15 2.89543 15 4H19C19.5523 4 20 4.44772 20 5V6C20 6.55228 19.5523 7 19 7H4C3.44772 7 3 6.55228 3 6V5C3 4.44772 3.44772 4 4 4H8C8 2.89543 8.89543 2 10 2H13Z"/>
|
|
11589
|
-
</svg>`
|
|
11590
|
-
};
|
|
11804
|
+
const tableElement = this.#editor.getElementByKey(tableNode.getKey());
|
|
11805
|
+
if (!tableElement) return
|
|
11806
|
+
|
|
11807
|
+
const tableRect = tableElement.getBoundingClientRect();
|
|
11808
|
+
const editorRect = this.#editorElement.getBoundingClientRect();
|
|
11809
|
+
|
|
11810
|
+
const relativeTop = tableRect.top - editorRect.top;
|
|
11811
|
+
const relativeCenter = (tableRect.left + tableRect.right) / 2 - editorRect.left;
|
|
11812
|
+
this.style.top = `${relativeTop}px`;
|
|
11813
|
+
this.style.left = `${relativeCenter}px`;
|
|
11814
|
+
}
|
|
11815
|
+
|
|
11816
|
+
#updateRowColumnCount() {
|
|
11817
|
+
const tableNode = this.tableController.currentTableNode;
|
|
11818
|
+
if (!tableNode) return
|
|
11819
|
+
|
|
11820
|
+
const tableElement = dn(this.#editor, tableNode);
|
|
11821
|
+
if (!tableElement) return
|
|
11822
|
+
|
|
11823
|
+
const rowCount = tableElement.rows;
|
|
11824
|
+
const columnCount = tableElement.columns;
|
|
11591
11825
|
|
|
11592
|
-
|
|
11826
|
+
this.rowCount.textContent = `${rowCount} row${rowCount === 1 ? "" : "s"}`;
|
|
11827
|
+
this.columnCount.textContent = `${columnCount} column${columnCount === 1 ? "" : "s"}`;
|
|
11828
|
+
}
|
|
11829
|
+
|
|
11830
|
+
#setTableCellFocus() {
|
|
11831
|
+
const cell = this.tableController.currentCell;
|
|
11832
|
+
if (!cell) return
|
|
11833
|
+
|
|
11834
|
+
const cellElement = this.#editor.getElementByKey(cell.getKey());
|
|
11835
|
+
if (!cellElement) return
|
|
11836
|
+
|
|
11837
|
+
cellElement.classList.add(theme.tableCellFocus);
|
|
11838
|
+
}
|
|
11839
|
+
|
|
11840
|
+
#clearCellStyles() {
|
|
11841
|
+
this.#editorElement.querySelectorAll(`.${theme.tableCellFocus}`)?.forEach(cell => {
|
|
11842
|
+
cell.classList.remove(theme.tableCellFocus);
|
|
11843
|
+
});
|
|
11844
|
+
|
|
11845
|
+
this.#editorElement.querySelectorAll(`.${theme.tableCellHighlight}`)?.forEach(cell => {
|
|
11846
|
+
cell.classList.remove(theme.tableCellHighlight);
|
|
11847
|
+
cell.removeAttribute("data-action");
|
|
11848
|
+
cell.removeAttribute("data-child-type");
|
|
11849
|
+
cell.removeAttribute("data-direction");
|
|
11850
|
+
});
|
|
11851
|
+
|
|
11852
|
+
this.#setTableCellFocus();
|
|
11853
|
+
}
|
|
11854
|
+
|
|
11855
|
+
#icon(command) {
|
|
11856
|
+
const { action, childType } = command;
|
|
11857
|
+
const direction = (action == "insert" ? command.direction : null);
|
|
11858
|
+
const iconId = [ action, childType, direction ].filter(Boolean).join("-");
|
|
11859
|
+
return TableIcons[iconId]
|
|
11593
11860
|
}
|
|
11594
11861
|
}
|
|
11595
11862
|
|
|
11596
|
-
customElements.define("lexxy-table-
|
|
11863
|
+
customElements.define("lexxy-table-tools", TableTools);
|
|
11597
11864
|
|
|
11598
11865
|
class BaseSource {
|
|
11599
11866
|
// Template method to override
|
|
@@ -11797,25 +12064,30 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
11797
12064
|
}
|
|
11798
12065
|
|
|
11799
12066
|
#addTriggerListener() {
|
|
11800
|
-
const unregister = this.#editor.registerUpdateListener(() => {
|
|
11801
|
-
|
|
12067
|
+
const unregister = this.#editor.registerUpdateListener(({ editorState }) => {
|
|
12068
|
+
editorState.read(() => {
|
|
11802
12069
|
const { node, offset } = this.#selection.selectedNodeWithOffset();
|
|
11803
12070
|
if (!node) return
|
|
11804
12071
|
|
|
11805
|
-
if (lr(node)
|
|
12072
|
+
if (lr(node)) {
|
|
11806
12073
|
const fullText = node.getTextContent();
|
|
11807
|
-
const
|
|
12074
|
+
const triggerLength = this.trigger.length;
|
|
12075
|
+
|
|
12076
|
+
// Check if we have enough characters for the trigger
|
|
12077
|
+
if (offset >= triggerLength) {
|
|
12078
|
+
const textBeforeCursor = fullText.slice(offset - triggerLength, offset);
|
|
11808
12079
|
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
12080
|
+
// Check if trigger is at the start of the text node (new line case) or preceded by space or newline
|
|
12081
|
+
if (textBeforeCursor === this.trigger) {
|
|
12082
|
+
const isAtStart = offset === triggerLength;
|
|
11812
12083
|
|
|
11813
|
-
|
|
11814
|
-
|
|
12084
|
+
const charBeforeTrigger = offset > triggerLength ? fullText[offset - triggerLength - 1] : null;
|
|
12085
|
+
const isPrecededBySpaceOrNewline = charBeforeTrigger === " " || charBeforeTrigger === "\n";
|
|
11815
12086
|
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
12087
|
+
if (isAtStart || isPrecededBySpaceOrNewline) {
|
|
12088
|
+
unregister();
|
|
12089
|
+
this.#showPopover();
|
|
12090
|
+
}
|
|
11819
12091
|
}
|
|
11820
12092
|
}
|
|
11821
12093
|
}
|
|
@@ -11835,9 +12107,10 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
11835
12107
|
const fullText = node.getTextContent();
|
|
11836
12108
|
const textBeforeCursor = fullText.slice(0, offset);
|
|
11837
12109
|
const lastTriggerIndex = textBeforeCursor.lastIndexOf(this.trigger);
|
|
12110
|
+
const triggerEndIndex = lastTriggerIndex + this.trigger.length - 1;
|
|
11838
12111
|
|
|
11839
|
-
// If trigger is not found, or cursor is at or before the trigger position, hide popover
|
|
11840
|
-
if (lastTriggerIndex === -1 || offset <=
|
|
12112
|
+
// If trigger is not found, or cursor is at or before the trigger end position, hide popover
|
|
12113
|
+
if (lastTriggerIndex === -1 || offset <= triggerEndIndex) {
|
|
11841
12114
|
this.#hidePopover();
|
|
11842
12115
|
}
|
|
11843
12116
|
} else {
|
|
@@ -12281,8 +12554,10 @@ class CodeLanguagePicker extends HTMLElement {
|
|
|
12281
12554
|
const codeRect = codeElement.getBoundingClientRect();
|
|
12282
12555
|
const editorRect = this.editorElement.getBoundingClientRect();
|
|
12283
12556
|
const relativeTop = codeRect.top - editorRect.top;
|
|
12557
|
+
const relativeRight = editorRect.right - codeRect.right;
|
|
12284
12558
|
|
|
12285
12559
|
this.style.top = `${relativeTop}px`;
|
|
12560
|
+
this.style.right = `${relativeRight}px`;
|
|
12286
12561
|
}
|
|
12287
12562
|
|
|
12288
12563
|
#showLanguagePicker() {
|