Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: expose forEachSelectedTextNode #6981

Merged
merged 29 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6323262
add __classes, getClasses and mutateClasses
GermanJablo Dec 5, 2024
7bb7820
amend
GermanJablo Dec 5, 2024
bede9a9
fix errors
GermanJablo Dec 5, 2024
264b87b
fix $canSimpleTextNodesBeMerged and exportDOM
GermanJablo Dec 6, 2024
f290e0c
add test
GermanJablo Dec 6, 2024
b9fa298
rename $mutateSelectedTextNodes to $forEachSelectedTextNode
GermanJablo Dec 6, 2024
0ff2383
add docs
GermanJablo Dec 6, 2024
10454ee
add tests for exportJSON
GermanJablo Dec 6, 2024
5c554d2
test name
GermanJablo Dec 6, 2024
b6e7525
spread classes
GermanJablo Dec 9, 2024
38764d4
fix updateDOM
GermanJablo Dec 9, 2024
a367219
comment typo
GermanJablo Dec 9, 2024
df4f570
remove comment
GermanJablo Dec 9, 2024
ae2c32a
replace mutateClasses with setClass
GermanJablo Dec 10, 2024
727d47d
update docs
GermanJablo Dec 10, 2024
00c711e
revert getClasses, allow empty object classes, move clone logic to af…
GermanJablo Dec 10, 2024
3da33aa
fix afterCloneFrom
GermanJablo Dec 10, 2024
110e591
Update packages/lexical/src/LexicalNode.ts
GermanJablo Dec 11, 2024
b96a12e
Update packages/lexical/src/LexicalNode.ts
GermanJablo Dec 11, 2024
a2fb1df
Update packages/lexical/src/LexicalEditorState.ts
GermanJablo Dec 11, 2024
66d0679
revert doc url name changed
GermanJablo Dec 11, 2024
2908b29
node.__classes check is actually needed as long as the property is op…
GermanJablo Dec 11, 2024
b8e09bb
|| {} is actually needed as long as the property is optional
GermanJablo Dec 11, 2024
0372f9e
revert || {} is actually needed as long as the property is optional. …
GermanJablo Dec 11, 2024
ba2f11d
revert unused changes
GermanJablo Dec 19, 2024
f6407b7
includeIfCollapsed
GermanJablo Dec 19, 2024
cd2a199
Merge branch 'main' into forEachSelectedTextNode
GermanJablo Dec 19, 2024
813d61c
Revert "includeIfCollapsed"
GermanJablo Dec 20, 2024
60a66dc
Merge branch 'main' into forEachSelectedTextNode
GermanJablo Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/lexical-selection/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import {
$addNodeStyle,
$forEachSelectedTextNode,
$isAtNodeEnd,
$patchStyleText,
$sliceSelectedTextNodeContent,
Expand Down Expand Up @@ -36,6 +37,7 @@ export {

export {
$addNodeStyle,
$forEachSelectedTextNode,
$isAtNodeEnd,
$patchStyleText,
$sliceSelectedTextNodeContent,
Expand Down
38 changes: 23 additions & 15 deletions packages/lexical-selection/src/lexical-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
$getCharacterOffsets,
$getNodeByKey,
$getPreviousSelection,
$getSelection,
$isElementNode,
$isRangeSelection,
$isRootNode,
Expand Down Expand Up @@ -288,23 +289,30 @@ export function $patchStyleText(
) => string)
>,
): void {
const selectedNodes = selection.getNodes();
const selectedNodesLength = selectedNodes.length;
const anchorAndFocus = selection.getStartEndPoints();
if (anchorAndFocus === null) {
if (selection.isCollapsed() && $isRangeSelection(selection)) {
$patchStyle(selection, patch);
GermanJablo marked this conversation as resolved.
Show resolved Hide resolved
} else {
$forEachSelectedTextNode((textNode) => {
$patchStyle(textNode, patch);
});
}
}

export function $forEachSelectedTextNode(
fn: (textNode: TextNode) => void,
): void {
const selection = $getSelection();
if (!$isRangeSelection(selection)) {
return;
}
const [anchor, focus] = anchorAndFocus;
const selectedNodes = selection.getNodes();
const selectedNodesLength = selectedNodes.length;
const {anchor, focus} = selection;

const lastIndex = selectedNodesLength - 1;
let firstNode = selectedNodes[0];
let lastNode = selectedNodes[lastIndex];

if (selection.isCollapsed() && $isRangeSelection(selection)) {
$patchStyle(selection, patch);
return;
}

const firstNodeText = firstNode.getTextContent();
const firstNodeTextLength = firstNodeText.length;
const focusOffset = focus.offset;
Expand Down Expand Up @@ -355,14 +363,14 @@ export function $patchStyleText(
$isTokenOrSegmented(firstNode) ||
(startOffset === 0 && endOffset === firstNodeTextLength)
) {
$patchStyle(firstNode, patch);
fn(firstNode);
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];
$patchStyle(replacement, patch);
fn(replacement);
replacement.select(0, endOffset - startOffset);
}
} // multiple nodes selected.
Expand All @@ -383,7 +391,7 @@ export function $patchStyleText(
}
}

$patchStyle(firstNode as TextNode, patch);
fn(firstNode as TextNode);
}

if ($isTextNode(lastNode) && lastNode.canHaveFormat()) {
Expand All @@ -404,7 +412,7 @@ export function $patchStyleText(
}

if (endOffset !== 0 || endType === 'element') {
$patchStyle(lastNode as TextNode, patch);
fn(lastNode as TextNode);
}
}

Expand All @@ -420,7 +428,7 @@ export function $patchStyleText(
selectedNodeKey !== lastNode.getKey() &&
!selectedNode.isToken()
) {
$patchStyle(selectedNode, patch);
fn(selectedNode as TextNode);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/lexical/src/LexicalSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,7 @@ export class RangeSelection implements BaseSelection {
}
}

// TO-DO: Migrate this method to the new utility function $forEachSelectedTextNode (share similar logic)
/**
* Applies the provided format to the TextNodes in the Selection, splitting or
* merging nodes as necessary.
Expand Down
Loading