@37signals/lexxy 0.9.0-beta → 0.9.2-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.
- package/dist/lexxy.esm.js +229 -131
- package/dist/stylesheets/lexxy-editor.css +23 -11
- package/package.json +1 -1
package/dist/lexxy.esm.js
CHANGED
|
@@ -10,7 +10,7 @@ import 'prismjs/components/prism-json';
|
|
|
10
10
|
import 'prismjs/components/prism-diff';
|
|
11
11
|
import DOMPurify from 'dompurify';
|
|
12
12
|
import { getStyleObjectFromCSS, getCSSFromStyleObject, $isAtNodeEnd, $getSelectionStyleValueForProperty, $patchStyleText, $setBlocksType } from '@lexical/selection';
|
|
13
|
-
import { SKIP_DOM_SELECTION_TAG, $getSelection, $isRangeSelection, $getNodeByKey, $isTextNode, $createRangeSelection, $setSelection, DecoratorNode, $createTextNode, $createNodeSelection, $isDecoratorNode, $isLineBreakNode, $isElementNode, HISTORY_MERGE_TAG, SKIP_SCROLL_INTO_VIEW_TAG, $createParagraphNode, TextNode, createCommand, createState, defineExtension, COMMAND_PRIORITY_NORMAL, $getState, $setState, $hasUpdateTag, PASTE_TAG, FORMAT_TEXT_COMMAND, UNDO_COMMAND, REDO_COMMAND, PASTE_COMMAND, COMMAND_PRIORITY_LOW, KEY_ARROW_RIGHT_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, $getEditor, $getNearestRootOrShadowRoot, $isNodeSelection, $getRoot, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_DOWN_COMMAND, DELETE_CHARACTER_COMMAND, SELECTION_CHANGE_COMMAND, CLICK_COMMAND, isDOMNode, $getNearestNodeFromDOMNode, $isRootOrShadowRoot, ElementNode, $splitNode, $isParagraphNode, $createLineBreakNode, $isRootNode, ParagraphNode, RootNode, COMMAND_PRIORITY_HIGH, DRAGSTART_COMMAND, DROP_COMMAND, INSERT_PARAGRAPH_COMMAND, CLEAR_HISTORY_COMMAND, $addUpdateTag, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_SPACE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND } from 'lexical';
|
|
13
|
+
import { SKIP_DOM_SELECTION_TAG, $getSelection, $isRangeSelection, $getNodeByKey, $isTextNode, $createRangeSelection, $setSelection, DecoratorNode, $createTextNode, $createNodeSelection, $isDecoratorNode, $isLineBreakNode, $isElementNode, HISTORY_MERGE_TAG, SKIP_SCROLL_INTO_VIEW_TAG, $createParagraphNode, TextNode, createCommand, createState, defineExtension, COMMAND_PRIORITY_NORMAL, $getState, $setState, $hasUpdateTag, PASTE_TAG, FORMAT_TEXT_COMMAND, UNDO_COMMAND, REDO_COMMAND, PASTE_COMMAND, COMMAND_PRIORITY_LOW, KEY_ARROW_RIGHT_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, $getEditor, $getNearestRootOrShadowRoot, $isNodeSelection, $getRoot, mergeRegister as mergeRegister$1, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_DOWN_COMMAND, DELETE_CHARACTER_COMMAND, SELECTION_CHANGE_COMMAND, CLICK_COMMAND, isDOMNode, $getNearestNodeFromDOMNode, $isRootOrShadowRoot, ElementNode, $splitNode, $isParagraphNode, $createLineBreakNode, $isRootNode, ParagraphNode, RootNode, COMMAND_PRIORITY_HIGH, DRAGSTART_COMMAND, DROP_COMMAND, INSERT_PARAGRAPH_COMMAND, CLEAR_HISTORY_COMMAND, $addUpdateTag, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_SPACE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND } from 'lexical';
|
|
14
14
|
import { buildEditorFromExtensions } from '@lexical/extension';
|
|
15
15
|
import { ListNode, INSERT_UNORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, ListItemNode, $getListDepth, $isListItemNode, $isListNode, registerList } from '@lexical/list';
|
|
16
16
|
import { $createAutoLinkNode, $toggleLink, LinkNode, $createLinkNode, AutoLinkNode, $isLinkNode } from '@lexical/link';
|
|
@@ -22,7 +22,7 @@ import { registerMarkdownShortcuts, TRANSFORMERS } from '@lexical/markdown';
|
|
|
22
22
|
import { createEmptyHistoryState, registerHistory } from '@lexical/history';
|
|
23
23
|
import { createElement, extractPlainTextFromHtml, createAttachmentFigure, isPreviewableImage, dispatch, parseHtml, addBlockSpacing, generateDomId } from './lexxy_helpers.esm.js';
|
|
24
24
|
export { highlightCode as highlightAll, highlightCode } from './lexxy_helpers.esm.js';
|
|
25
|
-
import { INSERT_TABLE_COMMAND, $getTableCellNodeFromLexicalNode, TableCellNode, TableNode, TableRowNode, registerTablePlugin, registerTableSelectionObserver,
|
|
25
|
+
import { INSERT_TABLE_COMMAND, $getTableCellNodeFromLexicalNode, TableCellNode, TableNode, TableRowNode, setScrollableTablesActive, registerTablePlugin, registerTableSelectionObserver, TableCellHeaderStates, $insertTableRowAtSelection, $insertTableColumnAtSelection, $deleteTableRowAtSelection, $deleteTableColumnAtSelection, $findTableNode, $getTableRowIndexFromTableCellNode, $getTableColumnIndexFromTableCellNode, $findCellNode, $getElementForTableNode } from '@lexical/table';
|
|
26
26
|
import { $getNearestNodeOfType, $wrapNodeInElement, $lastToFirstIterator, mergeRegister, $insertFirst, $unwrapAndFilterDescendants, $firstToLastIterator, $descendantsMatching } from '@lexical/utils';
|
|
27
27
|
import { marked } from 'marked';
|
|
28
28
|
import { $insertDataTransferForRichText } from '@lexical/clipboard';
|
|
@@ -382,9 +382,22 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
382
382
|
}
|
|
383
383
|
|
|
384
384
|
disconnectedCallback() {
|
|
385
|
+
this.dispose();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
dispose() {
|
|
385
389
|
this.#uninstallResizeObserver();
|
|
390
|
+
this.#unbindButtons();
|
|
386
391
|
this.#unbindHotkeys();
|
|
387
392
|
this.#unbindFocusListeners();
|
|
393
|
+
this.unregisterSelectionListener?.();
|
|
394
|
+
this.unregisterHistoryListener?.();
|
|
395
|
+
|
|
396
|
+
this.editorElement = null;
|
|
397
|
+
this.editor = null;
|
|
398
|
+
this.selection = null;
|
|
399
|
+
|
|
400
|
+
this.#createEditorPromise();
|
|
388
401
|
}
|
|
389
402
|
|
|
390
403
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -428,10 +441,12 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
428
441
|
this.connectedCallback();
|
|
429
442
|
}
|
|
430
443
|
|
|
431
|
-
#createEditorPromise() {
|
|
444
|
+
async #createEditorPromise() {
|
|
432
445
|
this.editorPromise = new Promise((resolve) => {
|
|
433
446
|
this.resolveEditorPromise = resolve;
|
|
434
447
|
});
|
|
448
|
+
|
|
449
|
+
this.editorElement = await this.editorPromise;
|
|
435
450
|
}
|
|
436
451
|
|
|
437
452
|
#installResizeObserver() {
|
|
@@ -447,10 +462,14 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
447
462
|
}
|
|
448
463
|
|
|
449
464
|
#bindButtons() {
|
|
450
|
-
this.addEventListener("click", this.#handleButtonClicked
|
|
465
|
+
this.addEventListener("click", this.#handleButtonClicked);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
#unbindButtons() {
|
|
469
|
+
this.removeEventListener("click", this.#handleButtonClicked);
|
|
451
470
|
}
|
|
452
471
|
|
|
453
|
-
#handleButtonClicked(event) {
|
|
472
|
+
#handleButtonClicked = (event) => {
|
|
454
473
|
this.#handleTargetClicked(event, "[data-command]", this.#dispatchButtonCommand.bind(this));
|
|
455
474
|
}
|
|
456
475
|
|
|
@@ -510,8 +529,8 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
510
529
|
}
|
|
511
530
|
|
|
512
531
|
#unbindFocusListeners() {
|
|
513
|
-
this.editorElement
|
|
514
|
-
this.editorElement
|
|
532
|
+
this.editorElement?.removeEventListener("lexxy:focus", this.#handleEditorFocus);
|
|
533
|
+
this.editorElement?.removeEventListener("lexxy:blur", this.#handleEditorBlur);
|
|
515
534
|
this.removeEventListener("keydown", this.#handleKeydown);
|
|
516
535
|
}
|
|
517
536
|
|
|
@@ -535,7 +554,7 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
535
554
|
}
|
|
536
555
|
|
|
537
556
|
#monitorSelectionChanges() {
|
|
538
|
-
this.editor.registerUpdateListener(() => {
|
|
557
|
+
this.unregisterSelectionListener = this.editor.registerUpdateListener(() => {
|
|
539
558
|
this.editor.getEditorState().read(() => {
|
|
540
559
|
this.#updateButtonStates();
|
|
541
560
|
this.#closeDropdowns();
|
|
@@ -544,7 +563,7 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
544
563
|
}
|
|
545
564
|
|
|
546
565
|
#monitorHistoryChanges() {
|
|
547
|
-
this.editor.registerUpdateListener(() => {
|
|
566
|
+
this.unregisterHistoryListener = this.editor.registerUpdateListener(() => {
|
|
548
567
|
this.#updateUndoRedoButtonStates();
|
|
549
568
|
});
|
|
550
569
|
}
|
|
@@ -696,13 +715,13 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
696
715
|
|
|
697
716
|
static get defaultTemplate() {
|
|
698
717
|
return `
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
718
|
+
<button class="lexxy-editor__toolbar-button" type="button" name="image" data-command="uploadImage" data-prevent-overflow="true" title="Add images and video">
|
|
719
|
+
${ToolbarIcons.image}
|
|
720
|
+
</button>
|
|
702
721
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
722
|
+
<button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="file" data-command="uploadFile" title="Upload files">
|
|
723
|
+
${ToolbarIcons.attachment}
|
|
724
|
+
</button>
|
|
706
725
|
|
|
707
726
|
<button class="lexxy-editor__toolbar-button" type="button" name="bold" data-command="bold" title="Bold">
|
|
708
727
|
${ToolbarIcons.bold}
|
|
@@ -726,10 +745,10 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
726
745
|
<button type="button" name="heading-medium" data-command="setFormatHeadingMedium" title="Medium heading">
|
|
727
746
|
${ToolbarIcons.h3} <span>Medium Heading</span>
|
|
728
747
|
</button>
|
|
729
|
-
<button type="button" name="heading-small" data-command="setFormatHeadingSmall" title="Small heading">
|
|
748
|
+
<button class="lexxy-editor__toolbar-group-end" type="button" name="heading-small" data-command="setFormatHeadingSmall" title="Small heading">
|
|
730
749
|
${ToolbarIcons.h4} <span>Small Heading</span>
|
|
731
750
|
</button>
|
|
732
|
-
<div class="separator" role="separator"></div>
|
|
751
|
+
<div class="lexxy-editor__toolbar-separator" role="separator"></div>
|
|
733
752
|
<button type="button" name="strikethrough" data-command="strikethrough" title="Strikethrough">
|
|
734
753
|
${ToolbarIcons.strikethrough} <span>Strikethrough</span>
|
|
735
754
|
</button>
|
|
@@ -739,21 +758,6 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
739
758
|
</div>
|
|
740
759
|
</details>
|
|
741
760
|
|
|
742
|
-
|
|
743
|
-
<details class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-dropdown--chevron" name="lexxy-dropdown">
|
|
744
|
-
<summary class="lexxy-editor__toolbar-button" name="lists" title="Lists">
|
|
745
|
-
${ToolbarIcons.ul}
|
|
746
|
-
</summary>
|
|
747
|
-
<div class="lexxy-editor__toolbar-dropdown-list">
|
|
748
|
-
<button type="button" name="unordered-list" data-command="insertUnorderedList" title="Bullet list">
|
|
749
|
-
${ToolbarIcons.ul} <span>Bullets</span>
|
|
750
|
-
</button>
|
|
751
|
-
<button type="button" name="ordered-list" data-command="insertOrderedList" title="Numbered list">
|
|
752
|
-
${ToolbarIcons.ol} <span>Numbers</span>
|
|
753
|
-
</button>
|
|
754
|
-
</div>
|
|
755
|
-
</details>
|
|
756
|
-
|
|
757
761
|
<details class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-dropdown--chevron" name="lexxy-dropdown">
|
|
758
762
|
<summary class="lexxy-editor__toolbar-button" name="highlight" title="Color highlight">
|
|
759
763
|
${ToolbarIcons.highlight}
|
|
@@ -765,7 +769,7 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
765
769
|
</details>
|
|
766
770
|
|
|
767
771
|
<details class="lexxy-editor__toolbar-dropdown" name="lexxy-dropdown">
|
|
768
|
-
<summary class="lexxy-editor__toolbar-button" name="link" title="Link" data-hotkey="cmd+k ctrl+k">
|
|
772
|
+
<summary class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" name="link" title="Link" data-hotkey="cmd+k ctrl+k">
|
|
769
773
|
${ToolbarIcons.link}
|
|
770
774
|
</summary>
|
|
771
775
|
<lexxy-link-dropdown class="lexxy-editor__toolbar-dropdown-content">
|
|
@@ -783,10 +787,17 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
783
787
|
${ToolbarIcons.quote}
|
|
784
788
|
</button>
|
|
785
789
|
|
|
786
|
-
<button class="lexxy-editor__toolbar-button
|
|
790
|
+
<button class="lexxy-editor__toolbar-button" type="button" name="code" data-command="insertCodeBlock" title="Code">
|
|
787
791
|
${ToolbarIcons.code}
|
|
788
792
|
</button>
|
|
789
793
|
|
|
794
|
+
<button class="lexxy-editor__toolbar-button" type="button" name="unordered-list" data-command="insertUnorderedList" title="Bullet list">
|
|
795
|
+
${ToolbarIcons.ul}
|
|
796
|
+
</button>
|
|
797
|
+
<button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="ordered-list" data-command="insertOrderedList" title="Numbered list">
|
|
798
|
+
${ToolbarIcons.ol}
|
|
799
|
+
</button>
|
|
800
|
+
|
|
790
801
|
<button class="lexxy-editor__toolbar-button" type="button" name="table" data-command="insertTable" title="Insert a table">
|
|
791
802
|
${ToolbarIcons.table}
|
|
792
803
|
</button>
|
|
@@ -1961,7 +1972,8 @@ const COMMANDS = [
|
|
|
1961
1972
|
"insertQuoteBlock",
|
|
1962
1973
|
"insertCodeBlock",
|
|
1963
1974
|
"insertHorizontalDivider",
|
|
1964
|
-
"
|
|
1975
|
+
"uploadImage",
|
|
1976
|
+
"uploadFile",
|
|
1965
1977
|
|
|
1966
1978
|
"insertTable",
|
|
1967
1979
|
|
|
@@ -1971,9 +1983,10 @@ const COMMANDS = [
|
|
|
1971
1983
|
|
|
1972
1984
|
class CommandDispatcher {
|
|
1973
1985
|
#selectionBeforeDrag = null
|
|
1986
|
+
#unregister = []
|
|
1974
1987
|
|
|
1975
1988
|
static configureFor(editorElement) {
|
|
1976
|
-
new CommandDispatcher(editorElement)
|
|
1989
|
+
return new CommandDispatcher(editorElement)
|
|
1977
1990
|
}
|
|
1978
1991
|
|
|
1979
1992
|
constructor(editorElement) {
|
|
@@ -2145,15 +2158,27 @@ class CommandDispatcher {
|
|
|
2145
2158
|
this.contents.applyParagraphFormat();
|
|
2146
2159
|
}
|
|
2147
2160
|
|
|
2148
|
-
|
|
2149
|
-
|
|
2161
|
+
dispatchUploadImage() {
|
|
2162
|
+
this.#dispatchUploadAttachment("image/*,video/*");
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
dispatchUploadFile() {
|
|
2166
|
+
this.#dispatchUploadAttachment();
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
#dispatchUploadAttachment(accept = null) {
|
|
2170
|
+
const attributes = {
|
|
2150
2171
|
type: "file",
|
|
2151
2172
|
multiple: true,
|
|
2152
2173
|
style: "display: none;",
|
|
2153
2174
|
onchange: ({ target: { files } }) => {
|
|
2154
2175
|
this.contents.uploadFiles(files, { selectLast: true });
|
|
2155
2176
|
}
|
|
2156
|
-
}
|
|
2177
|
+
};
|
|
2178
|
+
|
|
2179
|
+
if (accept) attributes.accept = accept;
|
|
2180
|
+
|
|
2181
|
+
const input = createElement("input", attributes);
|
|
2157
2182
|
|
|
2158
2183
|
// Append and remove to make testable
|
|
2159
2184
|
this.editorElement.appendChild(input);
|
|
@@ -2173,6 +2198,13 @@ class CommandDispatcher {
|
|
|
2173
2198
|
this.editor.dispatchCommand(REDO_COMMAND, undefined);
|
|
2174
2199
|
}
|
|
2175
2200
|
|
|
2201
|
+
dispose() {
|
|
2202
|
+
while (this.#unregister.length) {
|
|
2203
|
+
const unregister = this.#unregister.pop();
|
|
2204
|
+
unregister();
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2176
2208
|
#registerCommands() {
|
|
2177
2209
|
for (const command of COMMANDS) {
|
|
2178
2210
|
const methodName = `dispatch${capitalize(command)}`;
|
|
@@ -2183,12 +2215,12 @@ class CommandDispatcher {
|
|
|
2183
2215
|
}
|
|
2184
2216
|
|
|
2185
2217
|
#registerCommandHandler(command, priority, handler) {
|
|
2186
|
-
this.editor.registerCommand(command, handler, priority);
|
|
2218
|
+
this.#unregister.push(this.editor.registerCommand(command, handler, priority));
|
|
2187
2219
|
}
|
|
2188
2220
|
|
|
2189
2221
|
#registerKeyboardCommands() {
|
|
2190
|
-
this
|
|
2191
|
-
this
|
|
2222
|
+
this.#registerCommandHandler(KEY_ARROW_RIGHT_COMMAND, COMMAND_PRIORITY_NORMAL, this.#handleArrowRightKey.bind(this));
|
|
2223
|
+
this.#registerCommandHandler(KEY_TAB_COMMAND, COMMAND_PRIORITY_NORMAL, this.#handleTabKey.bind(this));
|
|
2192
2224
|
}
|
|
2193
2225
|
|
|
2194
2226
|
#handleArrowRightKey(event) {
|
|
@@ -2674,6 +2706,8 @@ function $isActionTextAttachmentNode(node) {
|
|
|
2674
2706
|
}
|
|
2675
2707
|
|
|
2676
2708
|
class Selection {
|
|
2709
|
+
#unregister = []
|
|
2710
|
+
|
|
2677
2711
|
constructor(editorElement) {
|
|
2678
2712
|
this.editorElement = editorElement;
|
|
2679
2713
|
this.editorContentElement = editorElement.editorContentElement;
|
|
@@ -2930,6 +2964,18 @@ class Selection {
|
|
|
2930
2964
|
return this.#findPreviousSiblingUp(anchorNode)
|
|
2931
2965
|
}
|
|
2932
2966
|
|
|
2967
|
+
dispose() {
|
|
2968
|
+
this.editorElement = null;
|
|
2969
|
+
this.editorContentElement = null;
|
|
2970
|
+
this.editor = null;
|
|
2971
|
+
this.previouslySelectedKeys = null;
|
|
2972
|
+
|
|
2973
|
+
while (this.#unregister.length) {
|
|
2974
|
+
const unregister = this.#unregister.pop();
|
|
2975
|
+
unregister();
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2933
2979
|
// When all inline code text is deleted, Lexical's selection retains the stale
|
|
2934
2980
|
// code format flag. Verify the flag is backed by actual code-formatted content:
|
|
2935
2981
|
// a code block ancestor or a text node that carries the code format.
|
|
@@ -2945,7 +2991,7 @@ class Selection {
|
|
|
2945
2991
|
// detects that stale state and clears it so newly typed text won't be
|
|
2946
2992
|
// code-formatted.
|
|
2947
2993
|
#clearStaleInlineCodeFormat() {
|
|
2948
|
-
this.editor.registerUpdateListener(({ editorState, tags }) => {
|
|
2994
|
+
this.#unregister.push(this.editor.registerUpdateListener(({ editorState, tags }) => {
|
|
2949
2995
|
if (tags.has("history-merge") || tags.has("skip-dom-selection")) return
|
|
2950
2996
|
|
|
2951
2997
|
let isStale = false;
|
|
@@ -2974,7 +3020,7 @@ class Selection {
|
|
|
2974
3020
|
});
|
|
2975
3021
|
}, 0);
|
|
2976
3022
|
}
|
|
2977
|
-
});
|
|
3023
|
+
}));
|
|
2978
3024
|
}
|
|
2979
3025
|
|
|
2980
3026
|
get #currentlySelectedKeys() {
|
|
@@ -2993,29 +3039,32 @@ class Selection {
|
|
|
2993
3039
|
}
|
|
2994
3040
|
|
|
2995
3041
|
#processSelectionChangeCommands() {
|
|
2996
|
-
this
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3042
|
+
this.#unregister.push(mergeRegister$1(
|
|
3043
|
+
this.editor.registerCommand(KEY_ARROW_LEFT_COMMAND, this.#selectPreviousNode.bind(this), COMMAND_PRIORITY_LOW),
|
|
3044
|
+
this.editor.registerCommand(KEY_ARROW_RIGHT_COMMAND, this.#selectNextNode.bind(this), COMMAND_PRIORITY_LOW),
|
|
3045
|
+
this.editor.registerCommand(KEY_ARROW_UP_COMMAND, this.#selectPreviousTopLevelNode.bind(this), COMMAND_PRIORITY_LOW),
|
|
3046
|
+
this.editor.registerCommand(KEY_ARROW_DOWN_COMMAND, this.#selectNextTopLevelNode.bind(this), COMMAND_PRIORITY_LOW),
|
|
3000
3047
|
|
|
3001
|
-
|
|
3048
|
+
this.editor.registerCommand(DELETE_CHARACTER_COMMAND, this.#selectDecoratorNodeBeforeDeletion.bind(this), COMMAND_PRIORITY_LOW),
|
|
3002
3049
|
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3050
|
+
this.editor.registerCommand(SELECTION_CHANGE_COMMAND, () => {
|
|
3051
|
+
this.current = $getSelection();
|
|
3052
|
+
}, COMMAND_PRIORITY_LOW)
|
|
3053
|
+
));
|
|
3006
3054
|
}
|
|
3007
3055
|
|
|
3008
3056
|
#listenForNodeSelections() {
|
|
3009
|
-
this.editor.registerCommand(CLICK_COMMAND, ({ target }) => {
|
|
3057
|
+
this.#unregister.push(this.editor.registerCommand(CLICK_COMMAND, ({ target }) => {
|
|
3010
3058
|
if (!isDOMNode(target)) return false
|
|
3011
3059
|
|
|
3012
3060
|
const targetNode = $getNearestNodeFromDOMNode(target);
|
|
3013
3061
|
return $isDecoratorNode(targetNode) && this.#selectInLexical(targetNode)
|
|
3014
|
-
}, COMMAND_PRIORITY_LOW);
|
|
3062
|
+
}, COMMAND_PRIORITY_LOW));
|
|
3015
3063
|
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3064
|
+
const moveNextLineHandler = () => this.#selectOrAppendNextLine();
|
|
3065
|
+
const rootElement = this.editor.getRootElement();
|
|
3066
|
+
rootElement.addEventListener("lexxy:internal:move-to-next-line", moveNextLineHandler);
|
|
3067
|
+
this.#unregister.push(() => rootElement.removeEventListener("lexxy:internal:move-to-next-line", moveNextLineHandler));
|
|
3019
3068
|
}
|
|
3020
3069
|
|
|
3021
3070
|
#containEditorFocus() {
|
|
@@ -4150,7 +4199,11 @@ class Contents {
|
|
|
4150
4199
|
constructor(editorElement) {
|
|
4151
4200
|
this.editorElement = editorElement;
|
|
4152
4201
|
this.editor = editorElement.editor;
|
|
4202
|
+
}
|
|
4153
4203
|
|
|
4204
|
+
dispose() {
|
|
4205
|
+
this.editorElement = null;
|
|
4206
|
+
this.editor = null;
|
|
4154
4207
|
}
|
|
4155
4208
|
|
|
4156
4209
|
insertHtml(html, { tag } = {}) {
|
|
@@ -5181,11 +5234,12 @@ class TablesExtension extends LexxyExtension {
|
|
|
5181
5234
|
TableRowNode
|
|
5182
5235
|
],
|
|
5183
5236
|
register(editor) {
|
|
5237
|
+
setScrollableTablesActive(editor, true);
|
|
5238
|
+
|
|
5184
5239
|
return mergeRegister(
|
|
5185
5240
|
// Register Lexical table plugins
|
|
5186
5241
|
registerTablePlugin(editor),
|
|
5187
5242
|
registerTableSelectionObserver(editor, true),
|
|
5188
|
-
setScrollableTablesActive(editor, true),
|
|
5189
5243
|
|
|
5190
5244
|
// Bug fix: Prevent hardcoded background color (Lexical #8089)
|
|
5191
5245
|
editor.registerNodeTransform(TableCellNode, (node) => {
|
|
@@ -5912,6 +5966,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
5912
5966
|
|
|
5913
5967
|
#initialValue = ""
|
|
5914
5968
|
#validationTextArea = document.createElement("textarea")
|
|
5969
|
+
#disposables = []
|
|
5915
5970
|
|
|
5916
5971
|
constructor() {
|
|
5917
5972
|
super();
|
|
@@ -5925,12 +5980,19 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
5925
5980
|
this.extensions = new Extensions(this);
|
|
5926
5981
|
|
|
5927
5982
|
this.editor = this.#createEditor();
|
|
5983
|
+
this.#disposables.push(this.editor);
|
|
5928
5984
|
|
|
5929
5985
|
this.contents = new Contents(this);
|
|
5986
|
+
this.#disposables.push(this.contents);
|
|
5987
|
+
|
|
5930
5988
|
this.selection = new Selection(this);
|
|
5989
|
+
this.#disposables.push(this.selection);
|
|
5990
|
+
|
|
5931
5991
|
this.clipboard = new Clipboard(this);
|
|
5932
5992
|
|
|
5933
|
-
CommandDispatcher.configureFor(this);
|
|
5993
|
+
const commandDispatcher = CommandDispatcher.configureFor(this);
|
|
5994
|
+
this.#disposables.push(commandDispatcher);
|
|
5995
|
+
|
|
5934
5996
|
this.#initialize();
|
|
5935
5997
|
|
|
5936
5998
|
requestAnimationFrame(() => dispatch(this, "lexxy:initialize"));
|
|
@@ -5983,7 +6045,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
5983
6045
|
get toolbarElement() {
|
|
5984
6046
|
if (!this.#hasToolbar) return null
|
|
5985
6047
|
|
|
5986
|
-
this.toolbar
|
|
6048
|
+
this.toolbar ??= this.#findOrCreateDefaultToolbar();
|
|
5987
6049
|
return this.toolbar
|
|
5988
6050
|
}
|
|
5989
6051
|
|
|
@@ -6119,6 +6181,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6119
6181
|
|
|
6120
6182
|
#createEditor() {
|
|
6121
6183
|
this.editorContentElement ||= this.#createEditorContentElement();
|
|
6184
|
+
this.appendChild(this.editorContentElement);
|
|
6122
6185
|
|
|
6123
6186
|
const editor = buildEditorFromExtensions({
|
|
6124
6187
|
name: "lexxy/core",
|
|
@@ -6168,7 +6231,6 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6168
6231
|
});
|
|
6169
6232
|
editorContentElement.id = `${this.id}-content`;
|
|
6170
6233
|
this.#ariaAttributes.forEach(attribute => editorContentElement.setAttribute(attribute.name, attribute.value));
|
|
6171
|
-
this.appendChild(editorContentElement);
|
|
6172
6234
|
|
|
6173
6235
|
if (this.getAttribute("tabindex")) {
|
|
6174
6236
|
editorContentElement.setAttribute("tabindex", this.getAttribute("tabindex"));
|
|
@@ -6244,36 +6306,48 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6244
6306
|
}
|
|
6245
6307
|
|
|
6246
6308
|
#registerComponents() {
|
|
6309
|
+
const registered = [];
|
|
6310
|
+
|
|
6247
6311
|
if (this.supportsRichText) {
|
|
6248
|
-
|
|
6249
|
-
|
|
6312
|
+
registered.push(
|
|
6313
|
+
registerRichText(this.editor),
|
|
6314
|
+
registerList(this.editor)
|
|
6315
|
+
);
|
|
6250
6316
|
this.#registerTableComponents();
|
|
6251
6317
|
this.#registerCodeHiglightingComponents();
|
|
6252
6318
|
if (this.supportsMarkdown) {
|
|
6253
|
-
|
|
6254
|
-
|
|
6319
|
+
registered.push(
|
|
6320
|
+
registerMarkdownShortcuts(this.editor, TRANSFORMERS),
|
|
6321
|
+
registerMarkdownLeadingTagHandler(this.editor, TRANSFORMERS)
|
|
6322
|
+
);
|
|
6255
6323
|
}
|
|
6256
6324
|
} else {
|
|
6257
|
-
registerPlainText(this.editor);
|
|
6325
|
+
registered.push(registerPlainText(this.editor));
|
|
6258
6326
|
}
|
|
6259
6327
|
this.historyState = createEmptyHistoryState();
|
|
6260
|
-
registerHistory(this.editor, this.historyState, 20);
|
|
6328
|
+
registered.push(registerHistory(this.editor, this.historyState, 20));
|
|
6329
|
+
|
|
6330
|
+
this.#addUnregisterHandler(mergeRegister$1(...registered));
|
|
6261
6331
|
}
|
|
6262
6332
|
|
|
6263
6333
|
#registerTableComponents() {
|
|
6264
|
-
|
|
6265
|
-
|
|
6334
|
+
let tableTools = this.querySelector("lexxy-table-tools");
|
|
6335
|
+
tableTools ??= createElement("lexxy-table-tools");
|
|
6336
|
+
this.append(tableTools);
|
|
6337
|
+
this.#disposables.push(tableTools);
|
|
6266
6338
|
}
|
|
6267
6339
|
|
|
6268
6340
|
#registerCodeHiglightingComponents() {
|
|
6269
6341
|
registerCodeHighlighting(this.editor);
|
|
6270
|
-
|
|
6271
|
-
|
|
6342
|
+
let codeLanguagePicker = this.querySelector("lexxy-code-language-picker");
|
|
6343
|
+
codeLanguagePicker ??= createElement("lexxy-code-language-picker");
|
|
6344
|
+
this.append(codeLanguagePicker);
|
|
6345
|
+
this.#disposables.push(codeLanguagePicker);
|
|
6272
6346
|
}
|
|
6273
6347
|
|
|
6274
6348
|
#handleEnter() {
|
|
6275
6349
|
// We can't prevent these externally using regular keydown because Lexical handles it first.
|
|
6276
|
-
this.editor.registerCommand(
|
|
6350
|
+
this.#addUnregisterHandler(this.editor.registerCommand(
|
|
6277
6351
|
KEY_ENTER_COMMAND,
|
|
6278
6352
|
(event) => {
|
|
6279
6353
|
// Prevent CTRL+ENTER
|
|
@@ -6291,12 +6365,17 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6291
6365
|
return false
|
|
6292
6366
|
},
|
|
6293
6367
|
COMMAND_PRIORITY_NORMAL
|
|
6294
|
-
);
|
|
6368
|
+
));
|
|
6295
6369
|
}
|
|
6296
6370
|
|
|
6297
6371
|
#registerFocusEvents() {
|
|
6298
6372
|
this.addEventListener("focusin", this.#handleFocusIn);
|
|
6299
6373
|
this.addEventListener("focusout", this.#handleFocusOut);
|
|
6374
|
+
|
|
6375
|
+
this.#addUnregisterHandler(() => {
|
|
6376
|
+
this.removeEventListener("focusin", this.#handleFocusIn);
|
|
6377
|
+
this.removeEventListener("focusout", this.#handleFocusOut);
|
|
6378
|
+
});
|
|
6300
6379
|
}
|
|
6301
6380
|
|
|
6302
6381
|
#handleFocusIn(event) {
|
|
@@ -6339,6 +6418,10 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6339
6418
|
#attachToolbar() {
|
|
6340
6419
|
if (this.#hasToolbar) {
|
|
6341
6420
|
this.toolbarElement.setEditor(this);
|
|
6421
|
+
if (typeof this.toolbarElement.dispose === "function") {
|
|
6422
|
+
this.#disposables.push(this.toolbarElement);
|
|
6423
|
+
}
|
|
6424
|
+
|
|
6342
6425
|
this.extensions.initializeToolbars();
|
|
6343
6426
|
}
|
|
6344
6427
|
}
|
|
@@ -6348,7 +6431,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6348
6431
|
if (typeof toolbarConfig === "string") {
|
|
6349
6432
|
return document.getElementById(toolbarConfig)
|
|
6350
6433
|
} else {
|
|
6351
|
-
return this.#createDefaultToolbar()
|
|
6434
|
+
return this.querySelector("lexxy-toolbar") ?? this.#createDefaultToolbar()
|
|
6352
6435
|
}
|
|
6353
6436
|
}
|
|
6354
6437
|
|
|
@@ -6378,34 +6461,22 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6378
6461
|
}
|
|
6379
6462
|
|
|
6380
6463
|
#reset() {
|
|
6381
|
-
this.#
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
this.editorContentElement.remove();
|
|
6385
|
-
this.editorContentElement = null;
|
|
6386
|
-
}
|
|
6387
|
-
|
|
6388
|
-
this.contents = null;
|
|
6389
|
-
this.editor = null;
|
|
6464
|
+
this.#dispose();
|
|
6465
|
+
this.editorContentElement?.remove();
|
|
6466
|
+
this.editorContentElement = null;
|
|
6390
6467
|
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6468
|
+
// Prevents issues with turbo morphing receiving an empty <lexxy-editor> which wipes
|
|
6469
|
+
// out the DOM for the tools, and the old toolbar reference will cause issues
|
|
6470
|
+
this.toolbar = null;
|
|
6471
|
+
}
|
|
6395
6472
|
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
}
|
|
6473
|
+
#dispose() {
|
|
6474
|
+
this.#unregisterHandlers();
|
|
6475
|
+
document.removeEventListener("turbo:before-cache", this.#handleTurboBeforeCache);
|
|
6400
6476
|
|
|
6401
|
-
|
|
6402
|
-
this.
|
|
6403
|
-
this.tableHandler = null;
|
|
6477
|
+
while (this.#disposables.length) {
|
|
6478
|
+
this.#disposables.pop().dispose();
|
|
6404
6479
|
}
|
|
6405
|
-
|
|
6406
|
-
this.selection = null;
|
|
6407
|
-
|
|
6408
|
-
document.removeEventListener("turbo:before-cache", this.#handleTurboBeforeCache);
|
|
6409
6480
|
}
|
|
6410
6481
|
|
|
6411
6482
|
#reconnect() {
|
|
@@ -6446,14 +6517,15 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
6446
6517
|
connectedCallback() {
|
|
6447
6518
|
this.container = this.closest("details");
|
|
6448
6519
|
|
|
6449
|
-
this.container.addEventListener("toggle", this.#handleToggle
|
|
6450
|
-
this.container.addEventListener("keydown", this.#handleKeyDown
|
|
6520
|
+
this.container.addEventListener("toggle", this.#handleToggle);
|
|
6521
|
+
this.container.addEventListener("keydown", this.#handleKeyDown);
|
|
6451
6522
|
|
|
6452
6523
|
this.#onToolbarEditor(this.initialize.bind(this));
|
|
6453
6524
|
}
|
|
6454
6525
|
|
|
6455
6526
|
disconnectedCallback() {
|
|
6456
|
-
this.container
|
|
6527
|
+
this.container?.removeEventListener("toggle", this.#handleToggle);
|
|
6528
|
+
this.container?.removeEventListener("keydown", this.#handleKeyDown);
|
|
6457
6529
|
}
|
|
6458
6530
|
|
|
6459
6531
|
get toolbar() {
|
|
@@ -6478,11 +6550,11 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
6478
6550
|
}
|
|
6479
6551
|
|
|
6480
6552
|
async #onToolbarEditor(callback) {
|
|
6481
|
-
await this.toolbar.
|
|
6553
|
+
await this.toolbar.editorElement;
|
|
6482
6554
|
callback();
|
|
6483
6555
|
}
|
|
6484
6556
|
|
|
6485
|
-
#handleToggle() {
|
|
6557
|
+
#handleToggle = () => {
|
|
6486
6558
|
if (this.container.open) {
|
|
6487
6559
|
this.#handleOpen();
|
|
6488
6560
|
}
|
|
@@ -6493,7 +6565,7 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
6493
6565
|
this.#resetTabIndexValues();
|
|
6494
6566
|
}
|
|
6495
6567
|
|
|
6496
|
-
#handleKeyDown(event) {
|
|
6568
|
+
#handleKeyDown = (event) => {
|
|
6497
6569
|
if (event.key === "Escape") {
|
|
6498
6570
|
event.stopPropagation();
|
|
6499
6571
|
this.close();
|
|
@@ -6521,27 +6593,30 @@ class LinkDropdown extends ToolbarDropdown {
|
|
|
6521
6593
|
super.connectedCallback();
|
|
6522
6594
|
this.input = this.querySelector("input");
|
|
6523
6595
|
|
|
6524
|
-
this.#
|
|
6596
|
+
this.container.addEventListener("toggle", this.#handleToggle);
|
|
6597
|
+
this.addEventListener("submit", this.#handleSubmit);
|
|
6598
|
+
this.querySelector("[value='unlink']").addEventListener("click", this.#handleUnlink);
|
|
6525
6599
|
}
|
|
6526
6600
|
|
|
6527
|
-
|
|
6528
|
-
this.container
|
|
6529
|
-
this.
|
|
6530
|
-
this.querySelector("[value='unlink']")
|
|
6601
|
+
disconnectedCallback() {
|
|
6602
|
+
this.container?.removeEventListener("toggle", this.#handleToggle);
|
|
6603
|
+
this.removeEventListener("submit", this.#handleSubmit);
|
|
6604
|
+
this.querySelector("[value='unlink']")?.removeEventListener("click", this.#handleUnlink);
|
|
6605
|
+
super.disconnectedCallback();
|
|
6531
6606
|
}
|
|
6532
6607
|
|
|
6533
|
-
#handleToggle({ newState }) {
|
|
6608
|
+
#handleToggle = ({ newState }) => {
|
|
6534
6609
|
this.input.value = this.#selectedLinkUrl;
|
|
6535
6610
|
this.input.required = newState === "open";
|
|
6536
6611
|
}
|
|
6537
6612
|
|
|
6538
|
-
#handleSubmit(event) {
|
|
6613
|
+
#handleSubmit = (event) => {
|
|
6539
6614
|
const command = event.submitter?.value;
|
|
6540
6615
|
this.editor.dispatchCommand(command, this.input.value);
|
|
6541
6616
|
this.close();
|
|
6542
6617
|
}
|
|
6543
6618
|
|
|
6544
|
-
#handleUnlink() {
|
|
6619
|
+
#handleUnlink = () => {
|
|
6545
6620
|
this.editor.dispatchCommand("unlink");
|
|
6546
6621
|
this.close();
|
|
6547
6622
|
}
|
|
@@ -6576,26 +6651,35 @@ const REMOVE_HIGHLIGHT_SELECTOR = "[data-command='removeHighlight']";
|
|
|
6576
6651
|
const NO_STYLE = Symbol("no_style");
|
|
6577
6652
|
|
|
6578
6653
|
class HighlightDropdown extends ToolbarDropdown {
|
|
6579
|
-
connectedCallback() {
|
|
6580
|
-
super.connectedCallback();
|
|
6581
|
-
this.#registerToggleHandler();
|
|
6582
|
-
}
|
|
6583
|
-
|
|
6584
6654
|
initialize() {
|
|
6585
6655
|
this.#setUpButtons();
|
|
6586
6656
|
this.#registerButtonHandlers();
|
|
6587
6657
|
}
|
|
6588
6658
|
|
|
6589
|
-
|
|
6590
|
-
|
|
6659
|
+
connectedCallback() {
|
|
6660
|
+
super.connectedCallback();
|
|
6661
|
+
this.container.addEventListener("toggle", this.#handleToggle);
|
|
6662
|
+
}
|
|
6663
|
+
|
|
6664
|
+
disconnectedCallback() {
|
|
6665
|
+
this.container?.removeEventListener("toggle", this.#handleToggle);
|
|
6666
|
+
this.#removeButtonHandlers();
|
|
6667
|
+
super.disconnectedCallback();
|
|
6591
6668
|
}
|
|
6592
6669
|
|
|
6593
6670
|
#registerButtonHandlers() {
|
|
6594
|
-
this.#colorButtons.forEach(button => button.addEventListener("click", this.#handleColorButtonClick
|
|
6595
|
-
this.querySelector(REMOVE_HIGHLIGHT_SELECTOR).addEventListener("click", this.#handleRemoveHighlightClick
|
|
6671
|
+
this.#colorButtons.forEach(button => button.addEventListener("click", this.#handleColorButtonClick));
|
|
6672
|
+
this.querySelector(REMOVE_HIGHLIGHT_SELECTOR).addEventListener("click", this.#handleRemoveHighlightClick);
|
|
6673
|
+
}
|
|
6674
|
+
|
|
6675
|
+
#removeButtonHandlers() {
|
|
6676
|
+
this.#colorButtons.forEach(button => button.removeEventListener("click", this.#handleColorButtonClick));
|
|
6677
|
+
this.querySelector(REMOVE_HIGHLIGHT_SELECTOR)?.removeEventListener("click", this.#handleRemoveHighlightClick);
|
|
6596
6678
|
}
|
|
6597
6679
|
|
|
6598
6680
|
#setUpButtons() {
|
|
6681
|
+
this.#buttonContainer.innerHTML = "";
|
|
6682
|
+
|
|
6599
6683
|
const colorGroups = this.editorElement.config.get("highlight.buttons");
|
|
6600
6684
|
|
|
6601
6685
|
this.#populateButtonGroup("color", colorGroups.color);
|
|
@@ -6621,7 +6705,7 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
6621
6705
|
return button
|
|
6622
6706
|
}
|
|
6623
6707
|
|
|
6624
|
-
#handleToggle({ newState }) {
|
|
6708
|
+
#handleToggle = ({ newState }) => {
|
|
6625
6709
|
if (newState === "open") {
|
|
6626
6710
|
this.editor.getEditorState().read(() => {
|
|
6627
6711
|
this.#updateColorButtonStates($getSelection());
|
|
@@ -6629,7 +6713,7 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
6629
6713
|
}
|
|
6630
6714
|
}
|
|
6631
6715
|
|
|
6632
|
-
#handleColorButtonClick(event) {
|
|
6716
|
+
#handleColorButtonClick = (event) => {
|
|
6633
6717
|
event.preventDefault();
|
|
6634
6718
|
|
|
6635
6719
|
const button = event.target.closest(APPLY_HIGHLIGHT_SELECTOR);
|
|
@@ -6642,7 +6726,7 @@ class HighlightDropdown extends ToolbarDropdown {
|
|
|
6642
6726
|
this.close();
|
|
6643
6727
|
}
|
|
6644
6728
|
|
|
6645
|
-
#handleRemoveHighlightClick(event) {
|
|
6729
|
+
#handleRemoveHighlightClick = (event) => {
|
|
6646
6730
|
event.preventDefault();
|
|
6647
6731
|
|
|
6648
6732
|
this.editor.dispatchCommand("removeHighlight");
|
|
@@ -7304,19 +7388,21 @@ class CodeLanguagePicker extends HTMLElement {
|
|
|
7304
7388
|
}
|
|
7305
7389
|
|
|
7306
7390
|
disconnectedCallback() {
|
|
7391
|
+
this.dispose();
|
|
7392
|
+
}
|
|
7393
|
+
|
|
7394
|
+
dispose() {
|
|
7307
7395
|
this.unregisterUpdateListener?.();
|
|
7308
7396
|
this.unregisterUpdateListener = null;
|
|
7309
7397
|
}
|
|
7310
7398
|
|
|
7311
7399
|
#attachLanguagePicker() {
|
|
7312
|
-
this.languagePickerElement = this.#createLanguagePicker();
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
this.#updateCodeBlockLanguage(this.languagePickerElement.value);
|
|
7316
|
-
});
|
|
7400
|
+
this.languagePickerElement = this.#findLanguagePicker() ?? this.#createLanguagePicker();
|
|
7401
|
+
this.append(this.languagePickerElement);
|
|
7402
|
+
}
|
|
7317
7403
|
|
|
7318
|
-
|
|
7319
|
-
this.
|
|
7404
|
+
#findLanguagePicker() {
|
|
7405
|
+
return this.querySelector("select")
|
|
7320
7406
|
}
|
|
7321
7407
|
|
|
7322
7408
|
#createLanguagePicker() {
|
|
@@ -7329,6 +7415,12 @@ class CodeLanguagePicker extends HTMLElement {
|
|
|
7329
7415
|
selectElement.appendChild(option);
|
|
7330
7416
|
}
|
|
7331
7417
|
|
|
7418
|
+
selectElement.addEventListener("change", () => {
|
|
7419
|
+
this.#updateCodeBlockLanguage(this.languagePickerElement.value);
|
|
7420
|
+
});
|
|
7421
|
+
|
|
7422
|
+
selectElement.setAttribute("nonce", getNonce());
|
|
7423
|
+
|
|
7332
7424
|
return selectElement
|
|
7333
7425
|
}
|
|
7334
7426
|
|
|
@@ -7889,6 +7981,10 @@ class TableTools extends HTMLElement {
|
|
|
7889
7981
|
}
|
|
7890
7982
|
|
|
7891
7983
|
disconnectedCallback() {
|
|
7984
|
+
this.dispose();
|
|
7985
|
+
}
|
|
7986
|
+
|
|
7987
|
+
dispose() {
|
|
7892
7988
|
this.#unregisterKeyboardShortcuts();
|
|
7893
7989
|
|
|
7894
7990
|
this.unregisterUpdateListener?.();
|
|
@@ -7913,6 +8009,8 @@ class TableTools extends HTMLElement {
|
|
|
7913
8009
|
}
|
|
7914
8010
|
|
|
7915
8011
|
#setUpButtons() {
|
|
8012
|
+
this.innerHTML = "";
|
|
8013
|
+
|
|
7916
8014
|
this.appendChild(this.#createRowButtonsContainer());
|
|
7917
8015
|
this.appendChild(this.#createColumnButtonsContainer());
|
|
7918
8016
|
|
|
@@ -488,14 +488,15 @@
|
|
|
488
488
|
|
|
489
489
|
&:after {
|
|
490
490
|
background-color: var(--lexxy-color-ink-lighter);
|
|
491
|
+
block-size: var(--lexxy-toolbar-icon-size);
|
|
491
492
|
content: "";
|
|
492
493
|
display: block;
|
|
493
|
-
|
|
494
|
-
height: 60%;
|
|
494
|
+
inline-size: 1px;
|
|
495
495
|
inset-inline-end: calc(-1 * var(--lexxy-toolbar-spacing));
|
|
496
|
-
inset-block
|
|
497
|
-
|
|
496
|
+
inset-block: 0;
|
|
497
|
+
margin: auto;
|
|
498
498
|
pointer-events: none;
|
|
499
|
+
position: absolute;
|
|
499
500
|
}
|
|
500
501
|
}
|
|
501
502
|
}
|
|
@@ -556,11 +557,6 @@
|
|
|
556
557
|
}
|
|
557
558
|
}
|
|
558
559
|
|
|
559
|
-
[overflowing] &:not(.lexxy-editor__toolbar-overflow) summary ~ * {
|
|
560
|
-
inset-inline-end: var(--lexxy-toolbar-spacing);
|
|
561
|
-
inset-inline-start: var(--lexxy-toolbar-spacing);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
560
|
button {
|
|
565
561
|
color: var(--lexxy-color-text);
|
|
566
562
|
|
|
@@ -572,7 +568,6 @@
|
|
|
572
568
|
.lexxy-editor__toolbar-dropdown-list {
|
|
573
569
|
border-start-start-radius: 0;
|
|
574
570
|
flex-direction: column;
|
|
575
|
-
gap: 0.1ch;
|
|
576
571
|
padding: 0.1ch;
|
|
577
572
|
|
|
578
573
|
button {
|
|
@@ -581,6 +576,7 @@
|
|
|
581
576
|
flex-direction: row;
|
|
582
577
|
gap: 1ch;
|
|
583
578
|
padding: 1ch;
|
|
579
|
+
position: relative;
|
|
584
580
|
|
|
585
581
|
&[aria-pressed="true"] {
|
|
586
582
|
background-color: var(--lexxy-color-selected);
|
|
@@ -600,11 +596,22 @@
|
|
|
600
596
|
}
|
|
601
597
|
}
|
|
602
598
|
|
|
603
|
-
.separator {
|
|
599
|
+
.lexxy-editor__toolbar-separator {
|
|
604
600
|
background: var(--lexxy-color-ink-lighter);
|
|
605
601
|
block-size: 1px;
|
|
606
602
|
inline-size: 100%;
|
|
607
603
|
}
|
|
604
|
+
|
|
605
|
+
[overflowing] & {
|
|
606
|
+
display: grid;
|
|
607
|
+
grid-template-columns: repeat(4, 1fr);
|
|
608
|
+
|
|
609
|
+
button span { display: none; }
|
|
610
|
+
|
|
611
|
+
.lexxy-editor__toolbar-separator {
|
|
612
|
+
grid-column: 1 / -1;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
608
615
|
}
|
|
609
616
|
|
|
610
617
|
|
|
@@ -706,6 +713,11 @@
|
|
|
706
713
|
inset-inline-start: 0;
|
|
707
714
|
max-inline-size: var(--max-inline-size);
|
|
708
715
|
|
|
716
|
+
[overflowing] & {
|
|
717
|
+
inset-inline-end: var(--lexxy-toolbar-spacing);
|
|
718
|
+
inset-inline-start: var(--lexxy-toolbar-spacing);
|
|
719
|
+
}
|
|
720
|
+
|
|
709
721
|
button {
|
|
710
722
|
position: relative;
|
|
711
723
|
}
|