@37signals/lexxy 0.9.9-beta.preview3.domselection1 → 0.9.9-beta.preview4

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.
Files changed (2) hide show
  1. package/dist/lexxy.esm.js +21 -13
  2. 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, $onUpdate, 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, 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';
@@ -6512,6 +6512,15 @@ class EarlyEscapeCodeNode extends CodeNode {
6512
6512
  insertNewAfter(selection, restoreSelection) {
6513
6513
  if (!selection.isCollapsed()) return super.insertNewAfter(selection, restoreSelection)
6514
6514
 
6515
+ // Clamp element-type selection offsets that may have been invalidated
6516
+ // by the code retokenizer. The retokenizer's $updateAndRetainSelection
6517
+ // restores the element offset verbatim after re-tokenizing, but when
6518
+ // highlight splits changed the child count before retokenization, the
6519
+ // restored offset can exceed the current child count. Without clamping,
6520
+ // CodeNode.insertNewAfter passes the stale offset to splice(), which
6521
+ // throws "start + deleteCount > oldSize".
6522
+ this.#clampSelectionOffset(selection);
6523
+
6515
6524
  if (this.#isCursorAtStart(selection)) {
6516
6525
  this.insertBefore($createParagraphNode());
6517
6526
  return null
@@ -6528,6 +6537,15 @@ class EarlyEscapeCodeNode extends CodeNode {
6528
6537
  return super.insertNewAfter(selection, restoreSelection)
6529
6538
  }
6530
6539
 
6540
+ #clampSelectionOffset(selection) {
6541
+ const childrenSize = this.getChildrenSize();
6542
+ for (const point of [ selection.anchor, selection.focus ]) {
6543
+ if (point.type === "element" && point.key === this.__key && point.offset > childrenSize) {
6544
+ point.set(this.__key, childrenSize, "element");
6545
+ }
6546
+ }
6547
+ }
6548
+
6531
6549
  #isCursorAtStart(selection) {
6532
6550
  const { anchor } = selection;
6533
6551
  if (!$isAtNodeStart(anchor)) return false
@@ -6947,7 +6965,7 @@ class LexicalEditorElement extends HTMLElement {
6947
6965
  }
6948
6966
 
6949
6967
  get #isContentFocused() {
6950
- return !!this.editor && isEditorFocused(this.editor)
6968
+ return !!this.editorContentElement && this.editorContentElement.contains(document.activeElement)
6951
6969
  }
6952
6970
 
6953
6971
  get value() {
@@ -6961,24 +6979,14 @@ class LexicalEditorElement extends HTMLElement {
6961
6979
  }
6962
6980
 
6963
6981
  set value(html) {
6964
- const editorHasFocus = this.#isContentFocused;
6965
-
6966
6982
  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
-
6975
6983
  $getRoot()
6976
6984
  .clear()
6977
6985
  .selectEnd()
6978
6986
  .insertNodes(this.#parseHtmlIntoLexicalNodes(html));
6979
6987
 
6980
6988
  this.#toggleEmptyStatus();
6981
- }, { discrete: true });
6989
+ }, { discrete: true, tag: SKIP_DOM_SELECTION_TAG });
6982
6990
  }
6983
6991
 
6984
6992
  get canUndo() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@37signals/lexxy",
3
- "version": "0.9.9-beta.preview3.domselection1",
3
+ "version": "0.9.9-beta.preview4",
4
4
  "description": "Lexxy - A modern rich text editor for Rails.",
5
5
  "module": "dist/lexxy.esm.js",
6
6
  "type": "module",