Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@lexical/selection

Package Overview
Dependencies
Maintainers
6
Versions
193
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lexical/selection - npm Package Compare versions

Comparing version 0.5.0 to 0.5.1-next.0

constants.d.ts

38

index.d.ts

@@ -9,33 +9,7 @@ /** @module @lexical/selection */

*/
import { ElementNode, GridSelection, LexicalEditor, LexicalNode, NodeKey, NodeSelection, Point, RangeSelection, TextNode } from 'lexical';
export declare function $cloneWithProperties<T extends LexicalNode>(node: T): T;
export declare function $cloneContents(selection: RangeSelection | NodeSelection | GridSelection): {
nodeMap: Array<[NodeKey, LexicalNode]>;
range: Array<NodeKey>;
};
export declare function getStyleObjectFromCSS(css: string): Record<string, string>;
export declare function $addNodeStyle(node: TextNode): void;
export declare function $patchStyleText(selection: RangeSelection | GridSelection, patch: Record<string, string>): void;
export declare function $getSelectionStyleValueForProperty(selection: RangeSelection, styleProperty: string, defaultValue?: string): string;
export declare function $moveCaretSelection(selection: RangeSelection, isHoldingShift: boolean, isBackward: boolean, granularity: 'character' | 'word' | 'lineboundary'): void;
export declare function $isParentElementRTL(selection: RangeSelection): boolean;
export declare function $moveCharacter(selection: RangeSelection, isHoldingShift: boolean, isBackward: boolean): void;
export declare function $selectAll(selection: RangeSelection): void;
/**
* Attempts to wrap all nodes in the Selection in ElementNodes returned from createElement.
* If wrappingElement is provided, all of the wrapped leaves are appended to the wrappingElement.
* It attempts to append the resulting sub-tree to the nearest safe insertion target.
*
* @param selection
* @param createElement
* @param wrappingElement
* @returns
*/
export declare function $wrapNodes(selection: RangeSelection, createElement: () => ElementNode, wrappingElement?: null | ElementNode): void;
export declare function $wrapNodesImpl(selection: RangeSelection, nodes: LexicalNode[], nodesLength: number, createElement: () => ElementNode, wrappingElement?: null | ElementNode): void;
export declare function $isAtNodeEnd(point: Point): boolean;
export declare function $shouldOverrideDefaultCharacterSelection(selection: RangeSelection, isBackward: boolean): boolean;
export declare function createDOMRange(editor: LexicalEditor, anchorNode: LexicalNode, _anchorOffset: number, focusNode: LexicalNode, _focusOffset: number): Range | null;
export declare function createRectsFromDOMRange(editor: LexicalEditor, range: Range): Array<ClientRect>;
export declare function trimTextContentFromAnchor(editor: LexicalEditor, anchor: Point, delCount: number): void;
export declare function $sliceSelectedTextNodeContent(selection: RangeSelection | GridSelection | NodeSelection, textNode: TextNode): LexicalNode;
import { $addNodeStyle, $cloneContents, $cloneWithProperties, $isAtNodeEnd, $patchStyleText, $sliceSelectedTextNodeContent, trimTextContentFromAnchor } from './lexical-node';
import { $getSelectionStyleValueForProperty, $isParentElementRTL, $moveCaretSelection, $moveCharacter, $selectAll, $shouldOverrideDefaultCharacterSelection, $wrapNodes, $wrapNodesImpl } from './range-selection';
import { createDOMRange, createRectsFromDOMRange, getStyleObjectFromCSS } from './utils';
export { $addNodeStyle, $cloneContents, $cloneWithProperties, $isAtNodeEnd, $patchStyleText, $sliceSelectedTextNodeContent, trimTextContentFromAnchor, };
export { $getSelectionStyleValueForProperty, $isParentElementRTL, $moveCaretSelection, $moveCharacter, $selectAll, $shouldOverrideDefaultCharacterSelection, $wrapNodes, $wrapNodesImpl, };
export { createDOMRange, createRectsFromDOMRange, getStyleObjectFromCSS };

@@ -11,223 +11,160 @@ /**

/** @module @lexical/selection */
const cssToStyles = new Map();
function $cloneWithProperties(node) {
const latest = node.getLatest();
const constructor = latest.constructor; // @ts-expect-error
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
const CSS_TO_STYLES = new Map();
const clone = constructor.clone(latest);
clone.__parent = latest.__parent;
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
function $cloneGridSelectionContent(selection) {
const nodeMap = selection.getNodes().map(node => {
const nodeKey = node.getKey();
const clone = $cloneWithProperties(node);
return [nodeKey, clone];
});
return {
nodeMap,
range: [selection.gridKey]
};
}
if (lexical.$isElementNode(latest) && lexical.$isElementNode(clone)) {
clone.__children = Array.from(latest.__children);
clone.__format = latest.__format;
clone.__indent = latest.__indent;
clone.__dir = latest.__dir;
} else if (lexical.$isTextNode(latest) && lexical.$isTextNode(clone)) {
clone.__format = latest.__format;
clone.__style = latest.__style;
clone.__mode = latest.__mode;
clone.__detail = latest.__detail;
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
function $cloneNodeSelectionContent(selection) {
{
throw Error(`TODO`);
}
return clone;
}
function $getIndexFromPossibleClone(node, parent, nodeMap) {
const parentClone = nodeMap.get(parent.getKey());
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
if (lexical.$isElementNode(parentClone)) {
return parentClone.__children.indexOf(node.getKey());
function getDOMTextNode(element) {
let node = element;
while (node != null) {
if (node.nodeType === Node.TEXT_NODE) {
return node;
}
node = node.firstChild;
}
return node.getIndexWithinParent();
return null;
}
function $getParentAvoidingExcludedElements(node) {
let parent = node.getParent();
function getDOMIndexWithinParent(node) {
const parent = node.parentNode;
while (parent !== null && parent.excludeFromCopy('clone')) {
parent = parent.getParent();
if (parent == null) {
throw new Error('Should never happen');
}
return parent;
return [parent, Array.from(parent.childNodes).indexOf(node)];
}
function $copyLeafNodeBranchToRoot(leaf, startingOffset, endingOffset, isLeftSide, range, nodeMap) {
let node = leaf;
let offset = startingOffset;
function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffset) {
const anchorKey = anchorNode.getKey();
const focusKey = focusNode.getKey();
const range = document.createRange();
let anchorDOM = editor.getElementByKey(anchorKey);
let focusDOM = editor.getElementByKey(focusKey);
let anchorOffset = _anchorOffset;
let focusOffset = _focusOffset;
while (node !== null) {
const parent = $getParentAvoidingExcludedElements(node);
if (lexical.$isTextNode(anchorNode)) {
anchorDOM = getDOMTextNode(anchorDOM);
}
if (parent === null) {
break;
}
if (lexical.$isTextNode(focusNode)) {
focusDOM = getDOMTextNode(focusDOM);
}
if (!lexical.$isElementNode(node) || !node.excludeFromCopy('clone')) {
const key = node.getKey();
let clone = nodeMap.get(key);
const needsClone = clone === undefined;
if (anchorNode === undefined || focusNode === undefined || anchorDOM === null || focusDOM === null) {
return null;
}
if (needsClone) {
clone = $cloneWithProperties(node);
nodeMap.set(key, clone);
}
if (anchorDOM.nodeName === 'BR') {
[anchorDOM, anchorOffset] = getDOMIndexWithinParent(anchorDOM);
}
if (lexical.$isTextNode(clone) && !clone.isSegmented() && !clone.isToken()) {
clone.__text = clone.__text.slice(isLeftSide ? offset : 0, isLeftSide ? endingOffset : offset);
} else if (lexical.$isElementNode(clone)) {
clone.__children = clone.__children.slice(isLeftSide ? offset : 0, isLeftSide ? undefined : (offset || 0) + 1);
}
if (focusDOM.nodeName === 'BR') {
[focusDOM, focusOffset] = getDOMIndexWithinParent(focusDOM);
}
if (lexical.$isRootNode(parent)) {
if (needsClone) {
// We only want to collect a range of top level nodes.
// So if the parent is the root, we know this is a top level.
range.push(key);
}
const firstChild = anchorDOM.firstChild;
break;
}
}
offset = $getIndexFromPossibleClone(node, parent, nodeMap);
node = parent;
if (anchorDOM === focusDOM && firstChild != null && firstChild.nodeName === 'BR' && anchorOffset === 0 && focusOffset === 0) {
focusOffset = 1;
}
}
function errGetLatestOnClone() {
{
throw Error(`getLatest() on clone node`);
try {
range.setStart(anchorDOM, anchorOffset);
range.setEnd(focusDOM, focusOffset);
} catch (e) {
return null;
}
}
function $cloneContents(selection) {
const clone = $cloneContentsImpl(selection);
{
const nodeMap = clone.nodeMap;
for (let i = 0; i < nodeMap.length; i++) {
const node = nodeMap[i][1];
if (node.getLatest === errGetLatestOnClone) {
continue;
}
Object.setPrototypeOf(node, Object.create(Object.getPrototypeOf(node), {
getLatest: {
configurable: true,
enumerable: true,
value: errGetLatestOnClone,
writable: true
}
}));
}
if (range.collapsed && (anchorOffset !== focusOffset || anchorKey !== focusKey)) {
// Range is backwards, we need to reverse it
range.setStart(focusDOM, focusOffset);
range.setEnd(anchorDOM, anchorOffset);
}
return clone;
return range;
}
function createRectsFromDOMRange(editor, range) {
const rootElement = editor.getRootElement();
function $cloneContentsImpl(selection) {
if (lexical.$isRangeSelection(selection)) {
const anchor = selection.anchor;
const focus = selection.focus;
const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
const nodes = selection.getNodes();
if (rootElement === null) {
return [];
}
if (nodes.length === 0) {
return {
nodeMap: [],
range: []
};
} // Check if we can use the parent of the nodes, if the
// parent can't be empty, then it's important that we
// also copy that element node along with its children.
const rootRect = rootElement.getBoundingClientRect();
const computedStyle = getComputedStyle(rootElement);
const rootPadding = parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
const selectionRects = Array.from(range.getClientRects());
let selectionRectsLength = selectionRects.length;
let prevRect;
for (let i = 0; i < selectionRectsLength; i++) {
const selectionRect = selectionRects[i]; // Exclude a rect that is the exact same as the last rect. getClientRects() can return
// the same rect twice for some elements. A more sophisticated thing to do here is to
// merge all the rects together into a set of rects that don't overlap, so we don't
// generate backgrounds that are too dark.
let nodesLength = nodes.length;
const firstNode = nodes[0];
const firstNodeParent = firstNode.getParent();
const isDuplicateRect = prevRect && prevRect.top === selectionRect.top && prevRect.left === selectionRect.left && prevRect.width === selectionRect.width && prevRect.height === selectionRect.height; // Exclude selections that span the entire element
if (firstNodeParent !== null && (!firstNodeParent.canBeEmpty() || lexical.$isRootNode(firstNodeParent))) {
const parentChildren = firstNodeParent.__children;
const parentChildrenLength = parentChildren.length;
const selectionSpansElement = selectionRect.width + rootPadding === rootRect.width;
if (parentChildrenLength === nodesLength) {
let areTheSame = true;
for (let i = 0; i < parentChildren.length; i++) {
if (parentChildren[i] !== nodes[i].__key) {
areTheSame = false;
break;
}
}
if (areTheSame) {
nodesLength++;
nodes.push(firstNodeParent);
}
}
if (isDuplicateRect || selectionSpansElement) {
selectionRects.splice(i--, 1);
selectionRectsLength--;
continue;
}
const lastNode = nodes[nodesLength - 1];
const isBefore = anchor.isBefore(focus);
const nodeMap = new Map();
const range = [];
const isOnlyText = lexical.$isTextNode(firstNode) && nodesLength === 1; // Do first node to root
$copyLeafNodeBranchToRoot(firstNode, isBefore ? anchorOffset : focusOffset, isOnlyText ? isBefore ? focusOffset : anchorOffset : undefined, true, range, nodeMap); // Copy all nodes between
for (let i = 0; i < nodesLength; i++) {
const node = nodes[i];
const key = node.getKey();
if (!nodeMap.has(key) && (!lexical.$isElementNode(node) || !node.excludeFromCopy('clone'))) {
const clone = $cloneWithProperties(node);
if (lexical.$isRootNode(node.getParent())) {
range.push(node.getKey());
}
if (key !== 'root') {
nodeMap.set(key, clone);
}
}
} // Do last node to root
$copyLeafNodeBranchToRoot(lastNode, isOnlyText ? undefined : isBefore ? focusOffset : anchorOffset, undefined, false, range, nodeMap);
return {
nodeMap: Array.from(nodeMap.entries()),
range
};
} else if (lexical.DEPRECATED_$isGridSelection(selection)) {
const nodeMap = selection.getNodes().map(node => {
const nodeKey = node.getKey();
const clone = $cloneWithProperties(node);
return [nodeKey, clone];
});
return {
nodeMap,
range: [selection.gridKey]
};
prevRect = selectionRect;
}
{
throw Error(`TODO`);
}
return selectionRects;
}
function getStyleObjectFromCSS(css) {
let value = cssToStyles.get(css);
if (value === undefined) {
value = getStyleObjectFromRawCSS(css);
cssToStyles.set(css, value);
}
return value;
}
function getStyleObjectFromRawCSS(css) {

@@ -247,3 +184,12 @@ const styleObject = {};

}
function getStyleObjectFromCSS(css) {
let value = CSS_TO_STYLES.get(css);
if (value === undefined) {
value = getStyleObjectFromRawCSS(css);
CSS_TO_STYLES.set(css, value);
}
return value;
}
function getCSSFromStyleObject(styles) {

@@ -261,201 +207,10 @@ let css = '';

function $addNodeStyle(node) {
const CSSText = node.getStyle();
const styles = getStyleObjectFromRawCSS(CSSText);
cssToStyles.set(CSSText, styles);
}
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
function $patchNodeStyle(node, patch) {
const prevStyles = getStyleObjectFromCSS(node.getStyle());
const newStyles = prevStyles ? { ...prevStyles,
...patch
} : patch;
const newCSSText = getCSSFromStyleObject(newStyles);
node.setStyle(newCSSText);
cssToStyles.set(newCSSText, newStyles);
}
function $patchStyleText(selection, patch) {
const selectedNodes = selection.getNodes();
const selectedNodesLength = selectedNodes.length;
const lastIndex = selectedNodesLength - 1;
let firstNode = selectedNodes[0];
let lastNode = selectedNodes[lastIndex];
if (selection.isCollapsed()) {
return;
}
const anchor = selection.anchor;
const focus = selection.focus;
const firstNodeText = firstNode.getTextContent();
const firstNodeTextLength = firstNodeText.length;
const focusOffset = focus.offset;
let anchorOffset = anchor.offset;
let startOffset;
let endOffset;
const isBefore = anchor.isBefore(focus);
startOffset = isBefore ? anchorOffset : focusOffset;
endOffset = isBefore ? focusOffset : anchorOffset; // This is the case where the user only selected the very end of the
// first node so we don't want to include it in the formatting change.
if (startOffset === firstNode.getTextContentSize()) {
const nextSibling = firstNode.getNextSibling();
if (lexical.$isTextNode(nextSibling)) {
// we basically make the second node the firstNode, changing offsets accordingly
anchorOffset = 0;
startOffset = 0;
firstNode = nextSibling;
}
} // This is the case where we only selected a single node
if (firstNode.is(lastNode)) {
if (lexical.$isTextNode(firstNode)) {
startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset; // No actual text is selected, so do nothing.
if (startOffset === endOffset) {
return;
} // The entire node is selected, so just format it
if (startOffset === 0 && endOffset === firstNodeTextLength) {
$patchNodeStyle(firstNode, patch);
firstNode.select(startOffset, endOffset);
} else {
// The node is partially selected, so split it into two nodes
// and style the selected one.
const splitNodes = firstNode.splitText(startOffset, endOffset);
const replacement = startOffset === 0 ? splitNodes[0] : splitNodes[1];
$patchNodeStyle(replacement, patch);
replacement.select(0, endOffset - startOffset);
}
} // multiple nodes selected.
} else {
if (lexical.$isTextNode(firstNode)) {
if (startOffset !== 0) {
// the entire first node isn't selected, so split it
firstNode = firstNode.splitText(startOffset)[1];
startOffset = 0;
}
$patchNodeStyle(firstNode, patch);
}
if (lexical.$isTextNode(lastNode)) {
const lastNodeText = lastNode.getTextContent();
const lastNodeTextLength = lastNodeText.length; // if the entire last node isn't selected, split it
if (endOffset !== lastNodeTextLength) {
[lastNode] = lastNode.splitText(endOffset);
}
if (endOffset !== 0) {
$patchNodeStyle(lastNode, patch);
}
} // style all the text nodes in between
for (let i = 1; i < lastIndex; i++) {
const selectedNode = selectedNodes[i];
const selectedNodeKey = selectedNode.getKey();
if (lexical.$isTextNode(selectedNode) && selectedNodeKey !== firstNode.getKey() && selectedNodeKey !== lastNode.getKey() && !selectedNode.isToken()) {
$patchNodeStyle(selectedNode, patch);
}
}
}
}
function $getSelectionStyleValueForProperty(selection, styleProperty, defaultValue = '') {
let styleValue = null;
const nodes = selection.getNodes();
const anchor = selection.anchor;
const focus = selection.focus;
const isBackward = selection.isBackward();
const endOffset = isBackward ? focus.offset : anchor.offset;
const endNode = isBackward ? focus.getNode() : anchor.getNode();
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]; // if no actual characters in the end node are selected, we don't
// include it in the selection for purposes of determining style
// value
if (i !== 0 && endOffset === 0 && node.is(endNode)) {
continue;
}
if (lexical.$isTextNode(node)) {
const nodeStyleValue = $getNodeStyleValueForProperty(node, styleProperty, defaultValue);
if (styleValue === null) {
styleValue = nodeStyleValue;
} else if (styleValue !== nodeStyleValue) {
// multiple text nodes are in the selection and they don't all
// have the same font size.
styleValue = '';
break;
}
}
}
return styleValue === null ? defaultValue : styleValue;
}
function $getNodeStyleValueForProperty(node, styleProperty, defaultValue) {
const css = node.getStyle();
const styleObject = getStyleObjectFromCSS(css);
if (styleObject !== null) {
return styleObject[styleProperty] || defaultValue;
}
return defaultValue;
}
function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity) {
selection.modify(isHoldingShift ? 'extend' : 'move', isBackward, granularity);
}
function $isParentElementRTL(selection) {
const anchorNode = selection.anchor.getNode();
const parent = lexical.$isRootNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
return parent.getDirection() === 'rtl';
}
function $moveCharacter(selection, isHoldingShift, isBackward) {
const isRTL = $isParentElementRTL(selection);
$moveCaretSelection(selection, isHoldingShift, isBackward ? !isRTL : isRTL, 'character');
}
function $selectAll(selection) {
const anchor = selection.anchor;
const focus = selection.focus;
const anchorNode = anchor.getNode();
const topParent = anchorNode.getTopLevelElementOrThrow();
const root = topParent.getParentOrThrow();
let firstNode = root.getFirstDescendant();
let lastNode = root.getLastDescendant();
let firstType = 'element';
let lastType = 'element';
let lastOffset = 0;
if (lexical.$isTextNode(firstNode)) {
firstType = 'text';
} else if (!lexical.$isElementNode(firstNode) && firstNode !== null) {
firstNode = firstNode.getParentOrThrow();
}
if (lexical.$isTextNode(lastNode)) {
lastType = 'text';
lastOffset = lastNode.getTextContentSize();
} else if (!lexical.$isElementNode(lastNode) && lastNode !== null) {
lastNode = lastNode.getParentOrThrow();
}
if (firstNode && lastNode) {
anchor.set(firstNode.getKey(), 0, firstType);
focus.set(lastNode.getKey(), lastOffset, lastType);
}
}
function $removeParentEmptyElements(startingNode) {

@@ -475,2 +230,6 @@ let node = startingNode;

}
function isPointAttached(point) {
return point.getNode().isAttached();
}
/**

@@ -681,127 +440,315 @@ * Attempts to wrap all nodes in the Selection in ElementNodes returned from createElement.

}
function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
const possibleNode = lexical.$getDecoratorNode(selection.focus, isBackward);
return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
}
function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity) {
selection.modify(isHoldingShift ? 'extend' : 'move', isBackward, granularity);
}
function $isParentElementRTL(selection) {
const anchorNode = selection.anchor.getNode();
const parent = lexical.$isRootNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
return parent.getDirection() === 'rtl';
}
function $moveCharacter(selection, isHoldingShift, isBackward) {
const isRTL = $isParentElementRTL(selection);
$moveCaretSelection(selection, isHoldingShift, isBackward ? !isRTL : isRTL, 'character');
}
function $selectAll(selection) {
const anchor = selection.anchor;
const focus = selection.focus;
const anchorNode = anchor.getNode();
const topParent = anchorNode.getTopLevelElementOrThrow();
const root = topParent.getParentOrThrow();
let firstNode = root.getFirstDescendant();
let lastNode = root.getLastDescendant();
let firstType = 'element';
let lastType = 'element';
let lastOffset = 0;
function isPointAttached(point) {
return point.getNode().isAttached();
if (lexical.$isTextNode(firstNode)) {
firstType = 'text';
} else if (!lexical.$isElementNode(firstNode) && firstNode !== null) {
firstNode = firstNode.getParentOrThrow();
}
if (lexical.$isTextNode(lastNode)) {
lastType = 'text';
lastOffset = lastNode.getTextContentSize();
} else if (!lexical.$isElementNode(lastNode) && lastNode !== null) {
lastNode = lastNode.getParentOrThrow();
}
if (firstNode && lastNode) {
anchor.set(firstNode.getKey(), 0, firstType);
focus.set(lastNode.getKey(), lastOffset, lastType);
}
}
function $isAtNodeEnd(point) {
if (point.type === 'text') {
return point.offset === point.getNode().getTextContentSize();
function $getIndexFromPossibleClone(node, parent, nodeMap) {
const parentClone = nodeMap.get(parent.getKey());
if (lexical.$isElementNode(parentClone)) {
return parentClone.__children.indexOf(node.getKey());
}
return point.offset === point.getNode().getChildrenSize();
return node.getIndexWithinParent();
}
function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
const possibleNode = lexical.$getDecoratorNode(selection.focus, isBackward);
return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
function $getParentAvoidingExcludedElements(node) {
let parent = node.getParent();
while (parent !== null && parent.excludeFromCopy('clone')) {
parent = parent.getParent();
}
return parent;
}
function getDOMTextNode(element) {
let node = element;
function $copyLeafNodeBranchToRoot(leaf, startingOffset, endingOffset, isLeftSide, range, nodeMap) {
let node = leaf;
let offset = startingOffset;
while (node != null) {
if (node.nodeType === Node.TEXT_NODE) {
return node;
while (node !== null) {
const parent = $getParentAvoidingExcludedElements(node);
if (parent === null) {
break;
}
node = node.firstChild;
if (!lexical.$isElementNode(node) || !node.excludeFromCopy('clone')) {
const key = node.getKey();
let clone = nodeMap.get(key);
const needsClone = clone === undefined;
if (needsClone) {
clone = $cloneWithProperties(node);
nodeMap.set(key, clone);
}
if (lexical.$isTextNode(clone) && !clone.isSegmented() && !clone.isToken()) {
clone.__text = clone.__text.slice(isLeftSide ? offset : 0, isLeftSide ? endingOffset : offset);
} else if (lexical.$isElementNode(clone)) {
clone.__children = clone.__children.slice(isLeftSide ? offset : 0, isLeftSide ? undefined : (offset || 0) + 1);
}
if (lexical.$isRootNode(parent)) {
if (needsClone) {
// We only want to collect a range of top level nodes.
// So if the parent is the root, we know this is a top level.
range.push(key);
}
break;
}
}
offset = $getIndexFromPossibleClone(node, parent, nodeMap);
node = parent;
}
return null;
}
function getDOMIndexWithinParent(node) {
const parent = node.parentNode;
function $cloneRangeSelectionContent(selection) {
const anchor = selection.anchor;
const focus = selection.focus;
const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
const nodes = selection.getNodes();
if (parent == null) {
throw new Error('Should never happen');
if (nodes.length === 0) {
return {
nodeMap: [],
range: []
};
} // Check if we can use the parent of the nodes, if the
// parent can't be empty, then it's important that we
// also copy that element node along with its children.
let nodesLength = nodes.length;
const firstNode = nodes[0];
const firstNodeParent = firstNode.getParent();
if (firstNodeParent !== null && (!firstNodeParent.canBeEmpty() || lexical.$isRootNode(firstNodeParent))) {
const parentChildren = firstNodeParent.__children;
const parentChildrenLength = parentChildren.length;
if (parentChildrenLength === nodesLength) {
let areTheSame = true;
for (let i = 0; i < parentChildren.length; i++) {
if (parentChildren[i] !== nodes[i].__key) {
areTheSame = false;
break;
}
}
if (areTheSame) {
nodesLength++;
nodes.push(firstNodeParent);
}
}
}
return [parent, Array.from(parent.childNodes).indexOf(node)];
const lastNode = nodes[nodesLength - 1];
const isBefore = anchor.isBefore(focus);
const nodeMap = new Map();
const range = [];
const isOnlyText = lexical.$isTextNode(firstNode) && nodesLength === 1; // Do first node to root
$copyLeafNodeBranchToRoot(firstNode, isBefore ? anchorOffset : focusOffset, isOnlyText ? isBefore ? focusOffset : anchorOffset : undefined, true, range, nodeMap); // Copy all nodes between
for (let i = 0; i < nodesLength; i++) {
const node = nodes[i];
const key = node.getKey();
if (!nodeMap.has(key) && (!lexical.$isElementNode(node) || !node.excludeFromCopy('clone'))) {
const clone = $cloneWithProperties(node);
if (lexical.$isRootNode(node.getParent())) {
range.push(node.getKey());
}
if (key !== 'root') {
nodeMap.set(key, clone);
}
}
} // Do last node to root
$copyLeafNodeBranchToRoot(lastNode, isOnlyText ? undefined : isBefore ? focusOffset : anchorOffset, undefined, false, range, nodeMap);
return {
nodeMap: Array.from(nodeMap.entries()),
range
};
}
function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffset) {
const anchorKey = anchorNode.getKey();
const focusKey = focusNode.getKey();
const range = document.createRange();
let anchorDOM = editor.getElementByKey(anchorKey);
let focusDOM = editor.getElementByKey(focusKey);
let anchorOffset = _anchorOffset;
let focusOffset = _focusOffset;
function $getNodeStyleValueForProperty(node, styleProperty, defaultValue) {
const css = node.getStyle();
const styleObject = getStyleObjectFromCSS(css);
if (lexical.$isTextNode(anchorNode)) {
anchorDOM = getDOMTextNode(anchorDOM);
if (styleObject !== null) {
return styleObject[styleProperty] || defaultValue;
}
if (lexical.$isTextNode(focusNode)) {
focusDOM = getDOMTextNode(focusDOM);
}
return defaultValue;
}
if (anchorNode === undefined || focusNode === undefined || anchorDOM === null || focusDOM === null) {
return null;
}
function $getSelectionStyleValueForProperty(selection, styleProperty, defaultValue = '') {
let styleValue = null;
const nodes = selection.getNodes();
const anchor = selection.anchor;
const focus = selection.focus;
const isBackward = selection.isBackward();
const endOffset = isBackward ? focus.offset : anchor.offset;
const endNode = isBackward ? focus.getNode() : anchor.getNode();
if (anchorDOM.nodeName === 'BR') {
[anchorDOM, anchorOffset] = getDOMIndexWithinParent(anchorDOM);
}
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]; // if no actual characters in the end node are selected, we don't
// include it in the selection for purposes of determining style
// value
if (focusDOM.nodeName === 'BR') {
[focusDOM, focusOffset] = getDOMIndexWithinParent(focusDOM);
}
if (i !== 0 && endOffset === 0 && node.is(endNode)) {
continue;
}
const firstChild = anchorDOM.firstChild;
if (lexical.$isTextNode(node)) {
const nodeStyleValue = $getNodeStyleValueForProperty(node, styleProperty, defaultValue);
if (anchorDOM === focusDOM && firstChild != null && firstChild.nodeName === 'BR' && anchorOffset === 0 && focusOffset === 0) {
focusOffset = 1;
if (styleValue === null) {
styleValue = nodeStyleValue;
} else if (styleValue !== nodeStyleValue) {
// multiple text nodes are in the selection and they don't all
// have the same font size.
styleValue = '';
break;
}
}
}
try {
range.setStart(anchorDOM, anchorOffset);
range.setEnd(focusDOM, focusOffset);
} catch (e) {
return null;
}
return styleValue === null ? defaultValue : styleValue;
}
if (range.collapsed && (anchorOffset !== focusOffset || anchorKey !== focusKey)) {
// Range is backwards, we need to reverse it
range.setStart(focusDOM, focusOffset);
range.setEnd(anchorDOM, anchorOffset);
}
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
return range;
function $updateElementNodeProperties(target, source) {
target.__children = Array.from(source.__children);
target.__format = source.__format;
target.__indent = source.__indent;
target.__dir = source.__dir;
return target;
}
function createRectsFromDOMRange(editor, range) {
const rootElement = editor.getRootElement();
if (rootElement === null) {
return [];
function $updateTextNodeProperties(target, source) {
target.__format = source.__format;
target.__style = source.__style;
target.__mode = source.__mode;
target.__detail = source.__detail;
return target;
}
function $cloneWithProperties(node) {
const latest = node.getLatest();
const constructor = latest.constructor; // @ts-expect-error
const clone = constructor.clone(latest);
clone.__parent = latest.__parent;
if (lexical.$isElementNode(latest) && lexical.$isElementNode(clone)) {
return $updateElementNodeProperties(clone, latest);
}
const rootRect = rootElement.getBoundingClientRect();
const computedStyle = getComputedStyle(rootElement);
const rootPadding = parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
const selectionRects = Array.from(range.getClientRects());
let selectionRectsLength = selectionRects.length;
let prevRect;
if (lexical.$isTextNode(latest) && lexical.$isTextNode(clone)) {
return $updateTextNodeProperties(clone, latest);
}
for (let i = 0; i < selectionRectsLength; i++) {
const selectionRect = selectionRects[i]; // Exclude a rect that is the exact same as the last rect. getClientRects() can return
// the same rect twice for some elements. A more sophisticated thing to do here is to
// merge all the rects together into a set of rects that don't overlap, so we don't
// generate backgrounds that are too dark.
return clone;
}
function $sliceSelectedTextNodeContent(selection, textNode) {
if (textNode.isSelected() && !textNode.isSegmented() && !textNode.isToken() && (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection))) {
const anchorNode = selection.anchor.getNode();
const focusNode = selection.focus.getNode();
const isAnchor = textNode.is(anchorNode);
const isFocus = textNode.is(focusNode);
const isDuplicateRect = prevRect && prevRect.top === selectionRect.top && prevRect.left === selectionRect.left && prevRect.width === selectionRect.width && prevRect.height === selectionRect.height; // Exclude selections that span the entire element
if (isAnchor || isFocus) {
const isBackward = selection.isBackward();
const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
const isSame = anchorNode.is(focusNode);
const isFirst = textNode.is(isBackward ? focusNode : anchorNode);
const isLast = textNode.is(isBackward ? anchorNode : focusNode);
let startOffset = 0;
let endOffset = undefined;
const selectionSpansElement = selectionRect.width + rootPadding === rootRect.width;
if (isSame) {
startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset;
} else if (isFirst) {
const offset = isBackward ? focusOffset : anchorOffset;
startOffset = offset;
endOffset = undefined;
} else if (isLast) {
const offset = isBackward ? anchorOffset : focusOffset;
startOffset = 0;
endOffset = offset;
}
if (isDuplicateRect || selectionSpansElement) {
selectionRects.splice(i--, 1);
selectionRectsLength--;
continue;
textNode.__text = textNode.__text.slice(startOffset, endOffset);
return textNode;
}
}
prevRect = selectionRect;
return textNode;
}
function $isAtNodeEnd(point) {
if (point.type === 'text') {
return point.offset === point.getNode().getTextContentSize();
}
return selectionRects;
return point.offset === point.getNode().getChildrenSize();
}

@@ -931,39 +878,157 @@ function trimTextContentFromAnchor(editor, anchor, delCount) {

}
function $sliceSelectedTextNodeContent(selection, textNode) {
if (textNode.isSelected() && !textNode.isSegmented() && !textNode.isToken() && (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection))) {
const anchorNode = selection.anchor.getNode();
const focusNode = selection.focus.getNode();
const isAnchor = textNode.is(anchorNode);
const isFocus = textNode.is(focusNode);
if (isAnchor || isFocus) {
const isBackward = selection.isBackward();
const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
const isSame = anchorNode.is(focusNode);
const isFirst = textNode.is(isBackward ? focusNode : anchorNode);
const isLast = textNode.is(isBackward ? anchorNode : focusNode);
let startOffset = 0;
let endOffset = undefined;
function errGetLatestOnClone() {
{
throw Error(`getLatest() on clone node`);
}
}
if (isSame) {
startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset;
} else if (isFirst) {
const offset = isBackward ? focusOffset : anchorOffset;
startOffset = offset;
endOffset = undefined;
} else if (isLast) {
const offset = isBackward ? anchorOffset : focusOffset;
startOffset = 0;
endOffset = offset;
function $cloneContents(selection) {
let clone = {
nodeMap: [],
range: []
};
if (lexical.$isRangeSelection(selection)) {
clone = $cloneRangeSelectionContent(selection);
} else if (lexical.DEPRECATED_$isGridSelection(selection)) {
clone = $cloneGridSelectionContent(selection);
} else if (lexical.$isNodeSelection(selection)) {
clone = $cloneNodeSelectionContent();
}
{
const nodeMap = clone.nodeMap;
for (let i = 0; i < nodeMap.length; i++) {
const node = nodeMap[i][1];
if (node.getLatest === errGetLatestOnClone) {
continue;
}
textNode.__text = textNode.__text.slice(startOffset, endOffset);
return textNode;
Object.setPrototypeOf(node, Object.create(Object.getPrototypeOf(node), {
getLatest: {
configurable: true,
enumerable: true,
value: errGetLatestOnClone,
writable: true
}
}));
}
}
return textNode;
return clone;
}
function $addNodeStyle(node) {
const CSSText = node.getStyle();
const styles = getStyleObjectFromRawCSS(CSSText);
CSS_TO_STYLES.set(CSSText, styles);
}
function $patchNodeStyle(node, patch) {
const prevStyles = getStyleObjectFromCSS(node.getStyle());
const newStyles = prevStyles ? { ...prevStyles,
...patch
} : patch;
const newCSSText = getCSSFromStyleObject(newStyles);
node.setStyle(newCSSText);
CSS_TO_STYLES.set(newCSSText, newStyles);
}
function $patchStyleText(selection, patch) {
const selectedNodes = selection.getNodes();
const selectedNodesLength = selectedNodes.length;
const lastIndex = selectedNodesLength - 1;
let firstNode = selectedNodes[0];
let lastNode = selectedNodes[lastIndex];
if (selection.isCollapsed()) {
return;
}
const anchor = selection.anchor;
const focus = selection.focus;
const firstNodeText = firstNode.getTextContent();
const firstNodeTextLength = firstNodeText.length;
const focusOffset = focus.offset;
let anchorOffset = anchor.offset;
let startOffset;
let endOffset;
const isBefore = anchor.isBefore(focus);
startOffset = isBefore ? anchorOffset : focusOffset;
endOffset = isBefore ? focusOffset : anchorOffset; // This is the case where the user only selected the very end of the
// first node so we don't want to include it in the formatting change.
if (startOffset === firstNode.getTextContentSize()) {
const nextSibling = firstNode.getNextSibling();
if (lexical.$isTextNode(nextSibling)) {
// we basically make the second node the firstNode, changing offsets accordingly
anchorOffset = 0;
startOffset = 0;
firstNode = nextSibling;
}
} // This is the case where we only selected a single node
if (firstNode.is(lastNode)) {
if (lexical.$isTextNode(firstNode)) {
startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset; // No actual text is selected, so do nothing.
if (startOffset === endOffset) {
return;
} // The entire node is selected, so just format it
if (startOffset === 0 && endOffset === firstNodeTextLength) {
$patchNodeStyle(firstNode, patch);
firstNode.select(startOffset, endOffset);
} else {
// The node is partially selected, so split it into two nodes
// and style the selected one.
const splitNodes = firstNode.splitText(startOffset, endOffset);
const replacement = startOffset === 0 ? splitNodes[0] : splitNodes[1];
$patchNodeStyle(replacement, patch);
replacement.select(0, endOffset - startOffset);
}
} // multiple nodes selected.
} else {
if (lexical.$isTextNode(firstNode)) {
if (startOffset !== 0) {
// the entire first node isn't selected, so split it
firstNode = firstNode.splitText(startOffset)[1];
startOffset = 0;
}
$patchNodeStyle(firstNode, patch);
}
if (lexical.$isTextNode(lastNode)) {
const lastNodeText = lastNode.getTextContent();
const lastNodeTextLength = lastNodeText.length; // if the entire last node isn't selected, split it
if (endOffset !== lastNodeTextLength) {
[lastNode] = lastNode.splitText(endOffset);
}
if (endOffset !== 0) {
$patchNodeStyle(lastNode, patch);
}
} // style all the text nodes in between
for (let i = 1; i < lastIndex; i++) {
const selectedNode = selectedNodes[i];
const selectedNodeKey = selectedNode.getKey();
if (lexical.$isTextNode(selectedNode) && selectedNodeKey !== firstNode.getKey() && selectedNodeKey !== lastNode.getKey() && !selectedNode.isToken()) {
$patchNodeStyle(selectedNode, patch);
}
}
}
}
exports.$addNodeStyle = $addNodeStyle;

@@ -970,0 +1035,0 @@ exports.$cloneContents = $cloneContents;

@@ -7,26 +7,26 @@ /**

*/
'use strict';var l=require("lexical");let r=new Map;function u(a){a=a.getLatest();let b=a.constructor.clone(a);b.__parent=a.__parent;l.$isElementNode(a)&&l.$isElementNode(b)?(b.__children=Array.from(a.__children),b.__format=a.__format,b.__indent=a.__indent,b.__dir=a.__dir):l.$isTextNode(a)&&l.$isTextNode(b)&&(b.__format=a.__format,b.__style=a.__style,b.__mode=a.__mode,b.__detail=a.__detail);return b}
function v(a,b,c,g,d,f){for(var h=b;null!==a;){for(b=a.getParent();null!==b&&b.excludeFromCopy("clone");)b=b.getParent();if(null===b)break;if(!l.$isElementNode(a)||!a.excludeFromCopy("clone")){let e=a.getKey(),k=f.get(e),m=void 0===k;m&&(k=u(a),f.set(e,k));!l.$isTextNode(k)||k.isSegmented()||k.isToken()?l.$isElementNode(k)&&(k.__children=k.__children.slice(g?h:0,g?void 0:(h||0)+1)):k.__text=k.__text.slice(g?h:0,g?c:h);if(l.$isRootNode(b)){m&&d.push(e);break}}h=f.get(b.getKey());h=l.$isElementNode(h)?
h.__children.indexOf(a.getKey()):a.getIndexWithinParent();a=b}}
function x(a){if(l.$isRangeSelection(a)){var b=a.anchor,c=a.focus;let [k,m]=a.getCharacterOffsets();a=a.getNodes();if(0===a.length)return{nodeMap:[],range:[]};let p=a.length;var g=a[0],d=g.getParent();if(null!==d&&(!d.canBeEmpty()||l.$isRootNode(d))){var f=d.__children;if(f.length===p){var h=!0;for(var e=0;e<f.length;e++)if(f[e]!==a[e].__key){h=!1;break}h&&(p++,a.push(d))}}d=a[p-1];b=b.isBefore(c);c=new Map;f=[];h=l.$isTextNode(g)&&1===p;v(g,b?k:m,h?b?m:k:void 0,!0,f,c);for(g=0;g<p;g++){e=a[g];let n=
e.getKey();if(!(c.has(n)||l.$isElementNode(e)&&e.excludeFromCopy("clone"))){let w=u(e);l.$isRootNode(e.getParent())&&f.push(e.getKey());"root"!==n&&c.set(n,w)}}v(d,h?void 0:b?m:k,void 0,!1,f,c);return{nodeMap:Array.from(c.entries()),range:f}}if(l.DEPRECATED_$isGridSelection(a))return{nodeMap:a.getNodes().map(k=>{const m=k.getKey();k=u(k);return[m,k]}),range:[a.gridKey]};throw Error("Minified Lexical error #1; visit https://lexical.dev/docs/error?code=1 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");
}function y(a){let b=r.get(a);void 0===b&&(b=z(a),r.set(a,b));return b}function z(a){let b={};a=a.split(";");for(let c of a)if(""!==c){let [g,d]=c.split(/:([^]+)/);b[g.trim()]=d.trim()}return b}function A(a,b){var c=y(a.getStyle());b=c?{...c,...b}:b;c="";for(g in b)g&&(c+=`${g}: ${b[g]};`);var g=c;a.setStyle(g);r.set(g,b)}function B(a,b,c,g){a.modify(b?"extend":"move",c,g)}function C(a){a=a.anchor.getNode();return"rtl"===(l.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}
function E(a){for(;null!==a&&!l.$isRootOrShadowRoot(a);){let b=a.getLatest(),c=a.getParent();0===b.__children.length&&a.remove(!0);a=c}}
function F(a,b,c,g,d=null){if(0!==b.length){var f=b[0],h=new Map,e=[];f=l.$isElementNode(f)?f:f.getParentOrThrow();f.isInline()&&(f=f.getParentOrThrow());for(var k=!1;null!==f;){var m=f.getPreviousSibling();if(null!==m){f=m;k=!0;break}f=f.getParentOrThrow();if(l.$isRootOrShadowRoot(f))break}m=new Set;for(var p=0;p<c;p++){var n=b[p];l.$isElementNode(n)&&0===n.getChildrenSize()&&m.add(n.getKey())}var w=new Set;for(p=0;p<c;p++){n=b[p];var q=n.getParent();null!==q&&q.isInline()&&(q=q.getParent());if(null!==
q&&l.$isLeafNode(n)&&!w.has(n.getKey())){if(n=q.getKey(),void 0===h.get(n)){let t=g();t.setFormat(q.getFormatType());t.setIndent(q.getIndent());e.push(t);h.set(n,t);q.getChildren().forEach(D=>{t.append(D);w.add(D.getKey())});E(q)}}else m.has(n.getKey())&&(q=g(),q.setFormat(n.getFormatType()),q.setIndent(n.getIndent()),e.push(q),n.remove(!0))}if(null!==d)for(b=0;b<e.length;b++)d.append(e[b]);if(l.$isRootOrShadowRoot(f))if(k)if(null!==d)f.insertAfter(d);else for(d=e.length-1;0<=d;d--)f.insertAfter(e[d]);
else if(b=f.getFirstChild(),l.$isElementNode(b)&&(f=b),null===b)if(d)f.append(d);else for(d=0;d<e.length;d++)f.append(e[d]);else if(null!==d)b.insertBefore(d);else for(f=0;f<e.length;f++)b.insertBefore(e[f]);else if(d)f.insertAfter(d);else for(d=e.length-1;0<=d;d--)f.insertAfter(e[d]);e=l.$getPreviousSelection();l.$isRangeSelection(e)&&e.anchor.getNode().isAttached()&&e.focus.getNode().isAttached()?l.$setSelection(e.clone()):a.dirty=!0}}
function G(a){for(;null!=a;){if(a.nodeType===Node.TEXT_NODE)return a;a=a.firstChild}return null}function H(a){let b=a.parentNode;if(null==b)throw Error("Should never happen");return[b,Array.from(b.childNodes).indexOf(a)]}exports.$addNodeStyle=function(a){a=a.getStyle();let b=z(a);r.set(a,b)};exports.$cloneContents=function(a){return x(a)};exports.$cloneWithProperties=u;
exports.$getSelectionStyleValueForProperty=function(a,b,c=""){let g=null,d=a.getNodes();var f=a.anchor,h=a.focus,e=a.isBackward();a=e?h.offset:f.offset;f=e?h.getNode():f.getNode();for(h=0;h<d.length;h++){var k=d[h];if((0===h||0!==a||!k.is(f))&&l.$isTextNode(k)){e=b;var m=c;k=k.getStyle();k=y(k);e=null!==k?k[e]||m:m;if(null===g)g=e;else if(g!==e){g="";break}}}return null===g?c:g};exports.$isAtNodeEnd=function(a){return"text"===a.type?a.offset===a.getNode().getTextContentSize():a.offset===a.getNode().getChildrenSize()};
exports.$isParentElementRTL=C;exports.$moveCaretSelection=B;exports.$moveCharacter=function(a,b,c){let g=C(a);B(a,b,c?!g:g,"character")};
exports.$patchStyleText=function(a,b){var c=a.getNodes();let g=c.length-1,d=c[0],f=c[g];if(!a.isCollapsed()){var h=a.anchor,e=a.focus;a=d.getTextContent().length;var k=e.offset,m=h.offset;h=(e=h.isBefore(e))?m:k;e=e?k:m;if(h===d.getTextContentSize()){let p=d.getNextSibling();l.$isTextNode(p)&&(h=m=0,d=p)}if(d.is(f))l.$isTextNode(d)&&(h=m>k?k:m,e=m>k?m:k,h!==e&&(0===h&&e===a?(A(d,b),d.select(h,e)):(c=d.splitText(h,e),c=0===h?c[0]:c[1],A(c,b),c.select(0,e-h))));else for(l.$isTextNode(d)&&(0!==h&&(d=
d.splitText(h)[1]),A(d,b)),l.$isTextNode(f)&&(a=f.getTextContent().length,e!==a&&([f]=f.splitText(e)),0!==e&&A(f,b)),a=1;a<g;a++)k=c[a],m=k.getKey(),l.$isTextNode(k)&&m!==d.getKey()&&m!==f.getKey()&&!k.isToken()&&A(k,b)}};
exports.$selectAll=function(a){let b=a.anchor;a=a.focus;var c=b.getNode().getTopLevelElementOrThrow().getParentOrThrow();let g=c.getFirstDescendant();c=c.getLastDescendant();let d="element",f="element",h=0;l.$isTextNode(g)?d="text":l.$isElementNode(g)||null===g||(g=g.getParentOrThrow());l.$isTextNode(c)?(f="text",h=c.getTextContentSize()):l.$isElementNode(c)||null===c||(c=c.getParentOrThrow());g&&c&&(b.set(g.getKey(),0,d),a.set(c.getKey(),h,f))};
'use strict';var l=require("lexical");let t=new Map;function u(a){return{nodeMap:a.getNodes().map(b=>{const c=b.getKey();b=v(b);return[c,b]}),range:[a.gridKey]}}function w(a){for(;null!=a;){if(a.nodeType===Node.TEXT_NODE)return a;a=a.firstChild}return null}function y(a){let b=a.parentNode;if(null==b)throw Error("Should never happen");return[b,Array.from(b.childNodes).indexOf(a)]}
function z(a){let b={};a=a.split(";");for(let c of a)if(""!==c){let [g,d]=c.split(/:([^]+)/);b[g.trim()]=d.trim()}return b}function A(a){let b=t.get(a);void 0===b&&(b=z(a),t.set(a,b));return b}function B(a){for(;null!==a&&!l.$isRootOrShadowRoot(a);){let b=a.getLatest(),c=a.getParent();0===b.__children.length&&a.remove(!0);a=c}}
function D(a,b,c,g,d=null){if(0!==b.length){var e=b[0],h=new Map,f=[];e=l.$isElementNode(e)?e:e.getParentOrThrow();e.isInline()&&(e=e.getParentOrThrow());for(var k=!1;null!==e;){var m=e.getPreviousSibling();if(null!==m){e=m;k=!0;break}e=e.getParentOrThrow();if(l.$isRootOrShadowRoot(e))break}m=new Set;for(var p=0;p<c;p++){var n=b[p];l.$isElementNode(n)&&0===n.getChildrenSize()&&m.add(n.getKey())}var x=new Set;for(p=0;p<c;p++){n=b[p];var q=n.getParent();null!==q&&q.isInline()&&(q=q.getParent());if(null!==
q&&l.$isLeafNode(n)&&!x.has(n.getKey())){if(n=q.getKey(),void 0===h.get(n)){let r=g();r.setFormat(q.getFormatType());r.setIndent(q.getIndent());f.push(r);h.set(n,r);q.getChildren().forEach(C=>{r.append(C);x.add(C.getKey())});B(q)}}else m.has(n.getKey())&&(q=g(),q.setFormat(n.getFormatType()),q.setIndent(n.getIndent()),f.push(q),n.remove(!0))}if(null!==d)for(b=0;b<f.length;b++)d.append(f[b]);if(l.$isRootOrShadowRoot(e))if(k)if(null!==d)e.insertAfter(d);else for(d=f.length-1;0<=d;d--)e.insertAfter(f[d]);
else if(b=e.getFirstChild(),l.$isElementNode(b)&&(e=b),null===b)if(d)e.append(d);else for(d=0;d<f.length;d++)e.append(f[d]);else if(null!==d)b.insertBefore(d);else for(e=0;e<f.length;e++)b.insertBefore(f[e]);else if(d)e.insertAfter(d);else for(d=f.length-1;0<=d;d--)e.insertAfter(f[d]);f=l.$getPreviousSelection();l.$isRangeSelection(f)&&f.anchor.getNode().isAttached()&&f.focus.getNode().isAttached()?l.$setSelection(f.clone()):a.dirty=!0}}function E(a,b,c,g){a.modify(b?"extend":"move",c,g)}
function F(a){a=a.anchor.getNode();return"rtl"===(l.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}
function G(a,b,c,g,d,e){for(var h=b;null!==a;){for(b=a.getParent();null!==b&&b.excludeFromCopy("clone");)b=b.getParent();if(null===b)break;if(!l.$isElementNode(a)||!a.excludeFromCopy("clone")){let f=a.getKey(),k=e.get(f),m=void 0===k;m&&(k=v(a),e.set(f,k));!l.$isTextNode(k)||k.isSegmented()||k.isToken()?l.$isElementNode(k)&&(k.__children=k.__children.slice(g?h:0,g?void 0:(h||0)+1)):k.__text=k.__text.slice(g?h:0,g?c:h);if(l.$isRootNode(b)){m&&d.push(f);break}}h=e.get(b.getKey());h=l.$isElementNode(h)?
h.__children.indexOf(a.getKey()):a.getIndexWithinParent();a=b}}function v(a){a=a.getLatest();let b=a.constructor.clone(a);b.__parent=a.__parent;if(l.$isElementNode(a)&&l.$isElementNode(b))return b.__children=Array.from(a.__children),b.__format=a.__format,b.__indent=a.__indent,b.__dir=a.__dir,b;l.$isTextNode(a)&&l.$isTextNode(b)&&(b.__format=a.__format,b.__style=a.__style,b.__mode=a.__mode,b.__detail=a.__detail);return b}
function H(a,b){var c=A(a.getStyle());b=c?{...c,...b}:b;c="";for(g in b)g&&(c+=`${g}: ${b[g]};`);var g=c;a.setStyle(g);t.set(g,b)}exports.$addNodeStyle=function(a){a=a.getStyle();let b=z(a);t.set(a,b)};
exports.$cloneContents=function(a){var b={nodeMap:[],range:[]};if(l.$isRangeSelection(a)){{var c=a.anchor,g=a.focus;let [m,p]=a.getCharacterOffsets();b=a.getNodes();if(0===b.length)b={nodeMap:[],range:[]};else{a=b.length;var d=b[0],e=d.getParent();if(null!==e&&(!e.canBeEmpty()||l.$isRootNode(e))){var h=e.__children;if(h.length===a){var f=!0;for(var k=0;k<h.length;k++)if(h[k]!==b[k].__key){f=!1;break}f&&(a++,b.push(e))}}e=b[a-1];c=c.isBefore(g);g=new Map;h=[];f=l.$isTextNode(d)&&1===a;G(d,c?m:p,f?
c?p:m:void 0,!0,h,g);for(d=0;d<a;d++){k=b[d];let n=k.getKey();if(!(g.has(n)||l.$isElementNode(k)&&k.excludeFromCopy("clone"))){let x=v(k);l.$isRootNode(k.getParent())&&h.push(k.getKey());"root"!==n&&g.set(n,x)}}G(e,f?void 0:c?p:m,void 0,!1,h,g);b={nodeMap:Array.from(g.entries()),range:h}}}}else if(l.DEPRECATED_$isGridSelection(a))b=u(a);else if(l.$isNodeSelection(a))throw Error("Minified Lexical error #1; visit https://lexical.dev/docs/error?code=1 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");
return b};exports.$cloneWithProperties=v;exports.$getSelectionStyleValueForProperty=function(a,b,c=""){let g=null,d=a.getNodes();var e=a.anchor,h=a.focus,f=a.isBackward();a=f?h.offset:e.offset;e=f?h.getNode():e.getNode();for(h=0;h<d.length;h++){var k=d[h];if((0===h||0!==a||!k.is(e))&&l.$isTextNode(k)){f=b;var m=c;k=k.getStyle();k=A(k);f=null!==k?k[f]||m:m;if(null===g)g=f;else if(g!==f){g="";break}}}return null===g?c:g};
exports.$isAtNodeEnd=function(a){return"text"===a.type?a.offset===a.getNode().getTextContentSize():a.offset===a.getNode().getChildrenSize()};exports.$isParentElementRTL=F;exports.$moveCaretSelection=E;exports.$moveCharacter=function(a,b,c){let g=F(a);E(a,b,c?!g:g,"character")};
exports.$patchStyleText=function(a,b){var c=a.getNodes();let g=c.length-1,d=c[0],e=c[g];if(!a.isCollapsed()){var h=a.anchor,f=a.focus;a=d.getTextContent().length;var k=f.offset,m=h.offset;h=(f=h.isBefore(f))?m:k;f=f?k:m;if(h===d.getTextContentSize()){let p=d.getNextSibling();l.$isTextNode(p)&&(h=m=0,d=p)}if(d.is(e))l.$isTextNode(d)&&(h=m>k?k:m,f=m>k?m:k,h!==f&&(0===h&&f===a?(H(d,b),d.select(h,f)):(c=d.splitText(h,f),c=0===h?c[0]:c[1],H(c,b),c.select(0,f-h))));else for(l.$isTextNode(d)&&(0!==h&&(d=
d.splitText(h)[1]),H(d,b)),l.$isTextNode(e)&&(a=e.getTextContent().length,f!==a&&([e]=e.splitText(f)),0!==f&&H(e,b)),a=1;a<g;a++)k=c[a],m=k.getKey(),l.$isTextNode(k)&&m!==d.getKey()&&m!==e.getKey()&&!k.isToken()&&H(k,b)}};
exports.$selectAll=function(a){let b=a.anchor;a=a.focus;var c=b.getNode().getTopLevelElementOrThrow().getParentOrThrow();let g=c.getFirstDescendant();c=c.getLastDescendant();let d="element",e="element",h=0;l.$isTextNode(g)?d="text":l.$isElementNode(g)||null===g||(g=g.getParentOrThrow());l.$isTextNode(c)?(e="text",h=c.getTextContentSize()):l.$isElementNode(c)||null===c||(c=c.getParentOrThrow());g&&c&&(b.set(g.getKey(),0,d),a.set(c.getKey(),h,e))};
exports.$shouldOverrideDefaultCharacterSelection=function(a,b){a=l.$getDecoratorNode(a.focus,b);return l.$isDecoratorNode(a)&&!a.isIsolated()};
exports.$sliceSelectedTextNodeContent=function(a,b){if(b.isSelected()&&!b.isSegmented()&&!b.isToken()&&(l.$isRangeSelection(a)||l.DEPRECATED_$isGridSelection(a))){var c=a.anchor.getNode(),g=a.focus.getNode(),d=b.is(c),f=b.is(g);if(d||f){d=a.isBackward();let [h,e]=a.getCharacterOffsets();a=c.is(g);f=b.is(d?g:c);g=b.is(d?c:g);c=0;let k=void 0;a?(c=h>e?e:h,k=h>e?h:e):f?(c=d?e:h,k=void 0):g&&(d=d?h:e,c=0,k=d);b.__text=b.__text.slice(c,k)}}return b};
exports.$wrapNodes=function(a,b,c=null){var g=a.getNodes();let d=g.length;var f=a.anchor;if(0===d||1===d&&"element"===f.type&&0===f.getNode().getChildrenSize()){a="text"===f.type?f.getNode().getParentOrThrow():f.getNode();g=a.getChildren();let e=b();e.setFormat(a.getFormatType());e.setIndent(a.getIndent());g.forEach(k=>e.append(k));c&&(e=c.append(e));a.replace(e)}else{f=null;var h=[];for(let e=0;e<d;e++){let k=g[e];l.$isRootOrShadowRoot(k)?(F(a,h,h.length,b,c),h=[],f=k):null===f||null!==f&&l.$hasAncestor(k,
f)?h.push(k):(F(a,h,h.length,b,c),h=[k])}F(a,h,h.length,b,c)}};exports.$wrapNodesImpl=F;
exports.createDOMRange=function(a,b,c,g,d){let f=b.getKey(),h=g.getKey(),e=document.createRange(),k=a.getElementByKey(f);a=a.getElementByKey(h);l.$isTextNode(b)&&(k=G(k));l.$isTextNode(g)&&(a=G(a));if(void 0===b||void 0===g||null===k||null===a)return null;"BR"===k.nodeName&&([k,c]=H(k));"BR"===a.nodeName&&([a,d]=H(a));b=k.firstChild;k===a&&null!=b&&"BR"===b.nodeName&&0===c&&0===d&&(d=1);try{e.setStart(k,c),e.setEnd(a,d)}catch(m){return null}!e.collapsed||c===d&&f===h||(e.setStart(a,d),e.setEnd(k,
c));return e};exports.createRectsFromDOMRange=function(a,b){var c=a.getRootElement();if(null===c)return[];a=c.getBoundingClientRect();c=getComputedStyle(c);c=parseFloat(c.paddingLeft)+parseFloat(c.paddingRight);b=Array.from(b.getClientRects());let g=b.length,d;for(let f=0;f<g;f++){let h=b[f],e=h.width+c===a.width;d&&d.top===h.top&&d.left===h.left&&d.width===h.width&&d.height===h.height||e?(b.splice(f--,1),g--):d=h}return b};exports.getStyleObjectFromCSS=y;
exports.trimTextContentFromAnchor=function(a,b,c){let g=b.getNode();if(l.$isElementNode(g)){var d=g.getDescendantByIndex(b.offset);null!==d&&(g=d)}for(;0<c&&null!==g;){var f=g.getPreviousSibling(),h=0;if(null===f){d=g.getParentOrThrow();for(var e=d.getPreviousSibling();null===e;){d=d.getParent();if(null===d){f=null;break}e=d.getPreviousSibling()}null!==d&&(h=d.isInline()?0:2,f=l.$isElementNode(e)?e.getLastDescendant():e)}let k=g.getTextContent();""===k&&l.$isElementNode(g)&&!g.isInline()&&(k="\n\n");
d=k.length;e=d-c;let m=k.slice(0,e);if(!l.$isTextNode(g)||c>=d)e=g.getParent(),g.remove(),null!=e&&0===e.getChildrenSize()&&e.remove(),c-=d+h,g=f;else{let p=g.getKey();f=a.getEditorState().read(()=>{const n=l.$getNodeByKey(p);return l.$isTextNode(n)&&n.isSimpleText()?n.getTextContent():null});null!==f&&f!==k?(c=l.$getPreviousSelection(),d=g,g.isSimpleText()?g.setTextContent(f):(d=l.$createTextNode(f),g.replace(d)),l.$isRangeSelection(c)&&c.isCollapsed()&&(c=c.anchor.offset,d.select(c,c))):g.isSimpleText()?
(f=b.key===p,h=b.offset,h<c&&(h=d),c=f?h-c:0,d=f?h:e,f&&0===c?([c]=g.splitText(c,d),c.remove()):([,c]=g.splitText(c,d),c.remove())):(c=l.$createTextNode(m),g.replace(c));c=0}}}
exports.$sliceSelectedTextNodeContent=function(a,b){if(b.isSelected()&&!b.isSegmented()&&!b.isToken()&&(l.$isRangeSelection(a)||l.DEPRECATED_$isGridSelection(a))){var c=a.anchor.getNode(),g=a.focus.getNode(),d=b.is(c),e=b.is(g);if(d||e){d=a.isBackward();let [h,f]=a.getCharacterOffsets();a=c.is(g);e=b.is(d?g:c);g=b.is(d?c:g);c=0;let k=void 0;a?(c=h>f?f:h,k=h>f?h:f):e?(c=d?f:h,k=void 0):g&&(d=d?h:f,c=0,k=d);b.__text=b.__text.slice(c,k)}}return b};
exports.$wrapNodes=function(a,b,c=null){var g=a.getNodes();let d=g.length;var e=a.anchor;if(0===d||1===d&&"element"===e.type&&0===e.getNode().getChildrenSize()){a="text"===e.type?e.getNode().getParentOrThrow():e.getNode();g=a.getChildren();let f=b();f.setFormat(a.getFormatType());f.setIndent(a.getIndent());g.forEach(k=>f.append(k));c&&(f=c.append(f));a.replace(f)}else{e=null;var h=[];for(let f=0;f<d;f++){let k=g[f];l.$isRootOrShadowRoot(k)?(D(a,h,h.length,b,c),h=[],e=k):null===e||null!==e&&l.$hasAncestor(k,
e)?h.push(k):(D(a,h,h.length,b,c),h=[k])}D(a,h,h.length,b,c)}};exports.$wrapNodesImpl=D;
exports.createDOMRange=function(a,b,c,g,d){let e=b.getKey(),h=g.getKey(),f=document.createRange(),k=a.getElementByKey(e);a=a.getElementByKey(h);l.$isTextNode(b)&&(k=w(k));l.$isTextNode(g)&&(a=w(a));if(void 0===b||void 0===g||null===k||null===a)return null;"BR"===k.nodeName&&([k,c]=y(k));"BR"===a.nodeName&&([a,d]=y(a));b=k.firstChild;k===a&&null!=b&&"BR"===b.nodeName&&0===c&&0===d&&(d=1);try{f.setStart(k,c),f.setEnd(a,d)}catch(m){return null}!f.collapsed||c===d&&e===h||(f.setStart(a,d),f.setEnd(k,
c));return f};exports.createRectsFromDOMRange=function(a,b){var c=a.getRootElement();if(null===c)return[];a=c.getBoundingClientRect();c=getComputedStyle(c);c=parseFloat(c.paddingLeft)+parseFloat(c.paddingRight);b=Array.from(b.getClientRects());let g=b.length,d;for(let e=0;e<g;e++){let h=b[e],f=h.width+c===a.width;d&&d.top===h.top&&d.left===h.left&&d.width===h.width&&d.height===h.height||f?(b.splice(e--,1),g--):d=h}return b};exports.getStyleObjectFromCSS=A;
exports.trimTextContentFromAnchor=function(a,b,c){let g=b.getNode();if(l.$isElementNode(g)){var d=g.getDescendantByIndex(b.offset);null!==d&&(g=d)}for(;0<c&&null!==g;){var e=g.getPreviousSibling(),h=0;if(null===e){d=g.getParentOrThrow();for(var f=d.getPreviousSibling();null===f;){d=d.getParent();if(null===d){e=null;break}f=d.getPreviousSibling()}null!==d&&(h=d.isInline()?0:2,e=l.$isElementNode(f)?f.getLastDescendant():f)}let k=g.getTextContent();""===k&&l.$isElementNode(g)&&!g.isInline()&&(k="\n\n");
d=k.length;f=d-c;let m=k.slice(0,f);if(!l.$isTextNode(g)||c>=d)f=g.getParent(),g.remove(),null!=f&&0===f.getChildrenSize()&&f.remove(),c-=d+h,g=e;else{let p=g.getKey();e=a.getEditorState().read(()=>{const n=l.$getNodeByKey(p);return l.$isTextNode(n)&&n.isSimpleText()?n.getTextContent():null});null!==e&&e!==k?(c=l.$getPreviousSelection(),d=g,g.isSimpleText()?g.setTextContent(e):(d=l.$createTextNode(e),g.replace(d)),l.$isRangeSelection(c)&&c.isCollapsed()&&(c=c.anchor.offset,d.select(c,c))):g.isSimpleText()?
(e=b.key===p,h=b.offset,h<c&&(h=d),c=e?h-c:0,d=e?h:f,e&&0===c?([c]=g.splitText(c,d),c.remove()):([,c]=g.splitText(c,d),c.remove())):(c=l.$createTextNode(m),g.replace(c));c=0}}}

@@ -12,6 +12,6 @@ {

"license": "MIT",
"version": "0.5.0",
"version": "0.5.1-next.0",
"main": "LexicalSelection.js",
"peerDependencies": {
"lexical": "0.5.0"
"lexical": "0.5.1-next.0"
},

@@ -18,0 +18,0 @@ "repository": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc