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

[0.5] $wrapLeafNodesInElements -> $wrapNodes #3020

Merged
merged 2 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {ContentEditable} from '@lexical/react/src/LexicalContentEditable';
import {HistoryPlugin} from '@lexical/react/src/LexicalHistoryPlugin';
import {RichTextPlugin} from '@lexical/react/src/LexicalRichTextPlugin';
import {$createQuoteNode} from '@lexical/rich-text/src';
import {$wrapLeafNodesInElements} from '@lexical/selection/src';
import {$wrapNodes} from '@lexical/selection/src';
import {
$createRangeSelection,
LexicalEditor,
Expand Down Expand Up @@ -103,7 +103,7 @@ describe('LexicalHistory tests', () => {
selection.focus.set(firstTextNode.getKey(), 3, 'text');

$setSelection(selection);
$wrapLeafNodesInElements(selection, () => $createQuoteNode());
$wrapNodes(selection, () => $createQuoteNode());
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
useBasicTypeaheadTriggerMatch,
} from '@lexical/react/LexicalTypeaheadMenuPlugin';
import {$createHeadingNode, $createQuoteNode} from '@lexical/rich-text';
import {$wrapLeafNodesInElements} from '@lexical/selection';
import {$wrapNodes} from '@lexical/selection';
import {
$createParagraphNode,
$getSelection,
Expand Down Expand Up @@ -175,7 +175,7 @@ export default function ComponentPickerMenuPlugin(): JSX.Element {
editor.update(() => {
const selection = $getSelection();
if ($isRangeSelection(selection)) {
$wrapLeafNodesInElements(selection, () => $createParagraphNode());
$wrapNodes(selection, () => $createParagraphNode());
}
}),
}),
Expand All @@ -188,7 +188,7 @@ export default function ComponentPickerMenuPlugin(): JSX.Element {
editor.update(() => {
const selection = $getSelection();
if ($isRangeSelection(selection)) {
$wrapLeafNodesInElements(selection, () =>
$wrapNodes(selection, () =>
// @ts-ignore Correct types, but since they're dynamic TS doesn't like it.
$createHeadingNode(`h${n}`),
);
Expand Down Expand Up @@ -229,7 +229,7 @@ export default function ComponentPickerMenuPlugin(): JSX.Element {
editor.update(() => {
const selection = $getSelection();
if ($isRangeSelection(selection)) {
$wrapLeafNodesInElements(selection, () => $createQuoteNode());
$wrapNodes(selection, () => $createQuoteNode());
}
}),
}),
Expand All @@ -242,7 +242,7 @@ export default function ComponentPickerMenuPlugin(): JSX.Element {

if ($isRangeSelection(selection)) {
if (selection.isCollapsed()) {
$wrapLeafNodesInElements(selection, () => $createCodeNode());
$wrapNodes(selection, () => $createCodeNode());
} else {
// Will this ever happen?
const textContent = selection.getTextContent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
$isParentElementRTL,
$patchStyleText,
$selectAll,
$wrapLeafNodesInElements,
$wrapNodes,
} from '@lexical/selection';
import {INSERT_TABLE_COMMAND} from '@lexical/table';
import {
Expand Down Expand Up @@ -417,7 +417,7 @@ function BlockFormatDropDown({
const selection = $getSelection();

if ($isRangeSelection(selection)) {
$wrapLeafNodesInElements(selection, () => $createParagraphNode());
$wrapNodes(selection, () => $createParagraphNode());
}
});
}
Expand All @@ -429,9 +429,7 @@ function BlockFormatDropDown({
const selection = $getSelection();

if ($isRangeSelection(selection)) {
$wrapLeafNodesInElements(selection, () =>
$createHeadingNode(headingSize),
);
$wrapNodes(selection, () => $createHeadingNode(headingSize));
}
});
}
Expand Down Expand Up @@ -467,7 +465,7 @@ function BlockFormatDropDown({
const selection = $getSelection();

if ($isRangeSelection(selection)) {
$wrapLeafNodesInElements(selection, () => $createQuoteNode());
$wrapNodes(selection, () => $createQuoteNode());
}
});
}
Expand All @@ -480,7 +478,7 @@ function BlockFormatDropDown({

if ($isRangeSelection(selection)) {
if (selection.isCollapsed()) {
$wrapLeafNodesInElements(selection, () => $createCodeNode());
$wrapNodes(selection, () => $createCodeNode());
} else {
const textContent = selection.getTextContent();
const codeNode = $createCodeNode();
Expand Down
6 changes: 3 additions & 3 deletions packages/lexical-selection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ Expands the current Selection to cover all of the content in the editor.
export function $selectAll(selection: RangeSelection): void;
```

#### `$wrapLeafNodesInElements`
#### `$wrapNodes`

Attempts to wrap all leaf 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.
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.

```ts
export function $wrapLeafNodesInElements(
export function $wrapNodes(
selection: RangeSelection,
createElement: () => ElementNode,
wrappingElement?: ElementNode,
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical-selection/flow/LexicalSelection.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ declare export function $moveCharacter(
isBackward: boolean,
): void;
declare export function $selectAll(selection: RangeSelection): void;
declare export function $wrapLeafNodesInElements(
declare export function $wrapNodes(
selection: RangeSelection,
createElement: () => ElementNode,
wrappingElement?: ElementNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {$createHeadingNode} from '@lexical/rich-text';
import {
$addNodeStyle,
$getSelectionStyleValueForProperty,
$wrapLeafNodesInElements,
$wrapNodes,
} from '@lexical/selection';
import {$createTableNodeWithDimensions} from '@lexical/table';
import {
Expand Down Expand Up @@ -2255,7 +2255,7 @@ describe('LexicalSelection tests', () => {
});
});

describe('$wrapLeafNodesInElements', () => {
describe('$wrapNodes', () => {
test('Collapsed selection in text', async () => {
const testEditor = createTestEditor();
const element = document.createElement('div');
Expand Down Expand Up @@ -2284,7 +2284,7 @@ describe('LexicalSelection tests', () => {
type: 'text',
});

$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2319,7 +2319,7 @@ describe('LexicalSelection tests', () => {
type: 'element',
});

$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2358,7 +2358,7 @@ describe('LexicalSelection tests', () => {
type: 'text',
});

$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2393,7 +2393,7 @@ describe('LexicalSelection tests', () => {
type: 'element',
});

$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2432,7 +2432,7 @@ describe('LexicalSelection tests', () => {
type: 'text',
});

$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2471,7 +2471,7 @@ describe('LexicalSelection tests', () => {

const columnChildrenPrev = column.getChildren();
expect(columnChildrenPrev[0].__type).toBe('paragraph');
$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2513,7 +2513,7 @@ describe('LexicalSelection tests', () => {

const columnChildrenPrev = column.getChildren();
expect(columnChildrenPrev[0].__type).toBe('paragraph');
$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down Expand Up @@ -2576,7 +2576,7 @@ describe('LexicalSelection tests', () => {
// @ts-ignore
const selection = $getSelection() as RangeSelection;

$wrapLeafNodesInElements(selection, () => {
$wrapNodes(selection, () => {
return $createHeadingNode('h1');
});

Expand Down
21 changes: 15 additions & 6 deletions packages/lexical-selection/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,17 @@ function $removeParentEmptyElements(startingNode: ElementNode): void {
}
}

// TODO 0.6 Rename to $wrapDescendantNodesInElements
export function $wrapLeafNodesInElements(
/**
* 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 function $wrapNodes(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not even sure this should take a selection. Does it wrap every node in the Selection into the wrapper? The semantics seem off.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's quite a magical function, it takes a selection because based on the selection it can wrap on one way or another (unlike $wrapNodeInElement). I personally find it more explicit this way (especially after a chat with @fantactuka).

Passing a list of nodes in would require some change of behavior, in which case you probably want to use the use function instead.

Let's connect offline if you have strong feeling about this one

selection: RangeSelection,
createElement: () => ElementNode,
wrappingElement: null | ElementNode = null,
Expand Down Expand Up @@ -630,7 +639,7 @@ export function $wrapLeafNodesInElements(
// their own branch. I.e. you don't want to wrap a whole table, but rather the contents of each
// of each of the cell nodes.
if ($isRootOrShadowRoot(node)) {
$wrapLeafNodesInElementsImpl(
$wrapNodesImpl(
selection,
descendants,
descendants.length,
Expand All @@ -645,7 +654,7 @@ export function $wrapLeafNodesInElements(
) {
descendants.push(node);
} else {
$wrapLeafNodesInElementsImpl(
$wrapNodesImpl(
selection,
descendants,
descendants.length,
Expand All @@ -655,7 +664,7 @@ export function $wrapLeafNodesInElements(
descendants = [node];
}
}
$wrapLeafNodesInElementsImpl(
$wrapNodesImpl(
selection,
descendants,
descendants.length,
Expand All @@ -664,7 +673,7 @@ export function $wrapLeafNodesInElements(
);
}

export function $wrapLeafNodesInElementsImpl(
export function $wrapNodesImpl(
selection: RangeSelection,
nodes: LexicalNode[],
nodesLength: number,
Expand Down