@37signals/lexxy 0.9.9-beta.preview2 → 0.9.9-beta.preview3.domselection1
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 +41 -16
- package/package.json +1 -1
package/dist/lexxy.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { isActiveAndVisible, createElement, extractPlainTextFromHtml, createAtta
|
|
|
2
2
|
export { highlightCode } from './lexxy_helpers.esm.js';
|
|
3
3
|
import DOMPurify from 'dompurify';
|
|
4
4
|
import { getStyleObjectFromCSS, getCSSFromStyleObject, $isAtNodeEnd, $getSelectionStyleValueForProperty, $patchStyleText, $ensureForwardRangeSelection, $setBlocksType, $forEachSelectedTextNode } from '@lexical/selection';
|
|
5
|
-
import { SKIP_DOM_SELECTION_TAG, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, CAN_REDO_COMMAND, $getSelection, $isRangeSelection, DecoratorNode, $createParagraphNode, $getNodeByKey, $isTextNode, $createRangeSelection, $setSelection, $createTextNode, $isElementNode, $isRootOrShadowRoot, $isRootNode, $createNodeSelection, $isDecoratorNode, $isLineBreakNode, TextNode, createCommand, createState, defineExtension, COMMAND_PRIORITY_NORMAL, $getState, $setState, $hasUpdateTag, PASTE_TAG, FORMAT_TEXT_COMMAND, UNDO_COMMAND, REDO_COMMAND, PASTE_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, COMMAND_PRIORITY_EDITOR, $getEditor, HISTORY_MERGE_TAG, SKIP_SCROLL_INTO_VIEW_TAG, $cloneWithProperties, $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, $addUpdateTag, ElementNode, $splitNode, $getChildCaretAtIndex, $createLineBreakNode, $isParagraphNode, ParagraphNode, RootNode, COMMAND_PRIORITY_HIGH, DRAGSTART_COMMAND, DROP_COMMAND, INSERT_PARAGRAPH_COMMAND, mergeRegister as mergeRegister$1, $findMatchingParent, CLEAR_HISTORY_COMMAND, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_SPACE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND } from 'lexical';
|
|
5
|
+
import { SKIP_DOM_SELECTION_TAG, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, CAN_REDO_COMMAND, $getSelection, $isRangeSelection, DecoratorNode, $createParagraphNode, $getNodeByKey, $isTextNode, $createRangeSelection, $setSelection, $createTextNode, $isElementNode, $isRootOrShadowRoot, $isRootNode, $createNodeSelection, $isDecoratorNode, $isLineBreakNode, TextNode, createCommand, createState, defineExtension, COMMAND_PRIORITY_NORMAL, $getState, $setState, $hasUpdateTag, PASTE_TAG, FORMAT_TEXT_COMMAND, UNDO_COMMAND, REDO_COMMAND, PASTE_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, COMMAND_PRIORITY_EDITOR, $getEditor, HISTORY_MERGE_TAG, SKIP_SCROLL_INTO_VIEW_TAG, $cloneWithProperties, $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, $addUpdateTag, ElementNode, $splitNode, $getChildCaretAtIndex, $createLineBreakNode, $isParagraphNode, ParagraphNode, RootNode, COMMAND_PRIORITY_HIGH, DRAGSTART_COMMAND, DROP_COMMAND, INSERT_PARAGRAPH_COMMAND, mergeRegister as mergeRegister$1, $findMatchingParent, CLEAR_HISTORY_COMMAND, $onUpdate, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_SPACE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND } from 'lexical';
|
|
6
6
|
import { buildEditorFromExtensions } from '@lexical/extension';
|
|
7
7
|
import { ListNode, ListItemNode, $getListDepth, INSERT_UNORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $isListItemNode, $isListNode, registerList } from '@lexical/list';
|
|
8
8
|
import { LinkNode, $createAutoLinkNode, $toggleLink, $createLinkNode, $isLinkNode, AutoLinkNode } from '@lexical/link';
|
|
@@ -2655,6 +2655,13 @@ class RewritableHistoryExtension extends LexxyExtension {
|
|
|
2655
2655
|
}
|
|
2656
2656
|
|
|
2657
2657
|
#rewriteHistory(rewrites) {
|
|
2658
|
+
this.#applyRewritesImmediatelyToCurrentState(rewrites);
|
|
2659
|
+
this.#applyRewritesToHistory(rewrites);
|
|
2660
|
+
|
|
2661
|
+
return true
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
#applyRewritesImmediatelyToCurrentState(rewrites) {
|
|
2658
2665
|
$getEditor().update(() => {
|
|
2659
2666
|
for (const [ nodeKey, { patch, replace } ] of Object.entries(rewrites)) {
|
|
2660
2667
|
const node = $getNodeByKey(nodeKey);
|
|
@@ -2664,27 +2671,27 @@ class RewritableHistoryExtension extends LexxyExtension {
|
|
|
2664
2671
|
if (replace) node.replace(replace);
|
|
2665
2672
|
}
|
|
2666
2673
|
}, { discrete: true, tag: this.#getBackgroundUpdateTags() });
|
|
2674
|
+
}
|
|
2667
2675
|
|
|
2676
|
+
#applyRewritesToHistory(rewrites) {
|
|
2668
2677
|
const nodeKeys = Object.keys(rewrites);
|
|
2669
2678
|
|
|
2670
2679
|
for (const entry of this.#allHistoryEntries) {
|
|
2671
2680
|
if (!this.#entryHasSomeKeys(entry, nodeKeys)) continue
|
|
2672
2681
|
|
|
2682
|
+
const editorState = entry.editorState = safeCloneEditorState(entry.editorState);
|
|
2683
|
+
|
|
2673
2684
|
for (const [ nodeKey, { patch, replace } ] of Object.entries(rewrites)) {
|
|
2674
|
-
const node =
|
|
2685
|
+
const node = editorState._nodeMap.get(nodeKey);
|
|
2675
2686
|
if (!node) continue
|
|
2676
2687
|
|
|
2677
|
-
entry.editorState = safeCloneEditorState(entry.editorState);
|
|
2678
|
-
|
|
2679
2688
|
if (patch) {
|
|
2680
|
-
|
|
2689
|
+
this.#patchNodeInEditorState(editorState, node, patch);
|
|
2681
2690
|
} else if (replace) {
|
|
2682
|
-
|
|
2691
|
+
this.#replaceNodeInEditorState(editorState, node, replace);
|
|
2683
2692
|
}
|
|
2684
2693
|
}
|
|
2685
2694
|
}
|
|
2686
|
-
|
|
2687
|
-
return true
|
|
2688
2695
|
}
|
|
2689
2696
|
|
|
2690
2697
|
#entryHasSomeKeys(entry, nodeKeys) {
|
|
@@ -2696,6 +2703,14 @@ class RewritableHistoryExtension extends LexxyExtension {
|
|
|
2696
2703
|
if (!isEditorFocused(this.editorElement.editor)) { tags.push(SKIP_DOM_SELECTION_TAG); }
|
|
2697
2704
|
return tags
|
|
2698
2705
|
}
|
|
2706
|
+
|
|
2707
|
+
#patchNodeInEditorState(editorState, node, patch) {
|
|
2708
|
+
editorState._nodeMap.set(node.__key, $cloneNodeWithPatch(node, patch));
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
#replaceNodeInEditorState(editorState, node, replaceWith) {
|
|
2712
|
+
editorState._nodeMap.set(node.__key, $cloneNodeAdoptingKeys(replaceWith, node));
|
|
2713
|
+
}
|
|
2699
2714
|
}
|
|
2700
2715
|
|
|
2701
2716
|
function $cloneNodeWithPatch(node, patch) {
|
|
@@ -2704,12 +2719,12 @@ function $cloneNodeWithPatch(node, patch) {
|
|
|
2704
2719
|
return clone
|
|
2705
2720
|
}
|
|
2706
2721
|
|
|
2707
|
-
function $
|
|
2708
|
-
const clone = $cloneWithProperties(
|
|
2709
|
-
clone.__key =
|
|
2710
|
-
clone.__parent =
|
|
2711
|
-
clone.__prev =
|
|
2712
|
-
clone.__next =
|
|
2722
|
+
function $cloneNodeAdoptingKeys(node, previousNode) {
|
|
2723
|
+
const clone = $cloneWithProperties(node);
|
|
2724
|
+
clone.__key = previousNode.__key;
|
|
2725
|
+
clone.__parent = previousNode.__parent;
|
|
2726
|
+
clone.__prev = previousNode.__prev;
|
|
2727
|
+
clone.__next = previousNode.__next;
|
|
2713
2728
|
return clone
|
|
2714
2729
|
}
|
|
2715
2730
|
|
|
@@ -6932,7 +6947,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6932
6947
|
}
|
|
6933
6948
|
|
|
6934
6949
|
get #isContentFocused() {
|
|
6935
|
-
return !!this.
|
|
6950
|
+
return !!this.editor && isEditorFocused(this.editor)
|
|
6936
6951
|
}
|
|
6937
6952
|
|
|
6938
6953
|
get value() {
|
|
@@ -6946,14 +6961,24 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
6946
6961
|
}
|
|
6947
6962
|
|
|
6948
6963
|
set value(html) {
|
|
6964
|
+
const editorHasFocus = this.#isContentFocused;
|
|
6965
|
+
|
|
6949
6966
|
this.editor.update(() => {
|
|
6967
|
+
if (editorHasFocus) {
|
|
6968
|
+
// Address Safari inconsistently placing the cursor in the contenteditable by forcing focus back onto the editor
|
|
6969
|
+
// Use direct `editor.focus` to bypass the pre-existing focus optimization and skip the callback
|
|
6970
|
+
$onUpdate(() => this.editor.focus());
|
|
6971
|
+
} else {
|
|
6972
|
+
$addUpdateTag(SKIP_DOM_SELECTION_TAG);
|
|
6973
|
+
}
|
|
6974
|
+
|
|
6950
6975
|
$getRoot()
|
|
6951
6976
|
.clear()
|
|
6952
6977
|
.selectEnd()
|
|
6953
6978
|
.insertNodes(this.#parseHtmlIntoLexicalNodes(html));
|
|
6954
6979
|
|
|
6955
6980
|
this.#toggleEmptyStatus();
|
|
6956
|
-
}, { discrete: true
|
|
6981
|
+
}, { discrete: true });
|
|
6957
6982
|
}
|
|
6958
6983
|
|
|
6959
6984
|
get canUndo() {
|