Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into lexical-eslint-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
etrepum committed May 3, 2024
2 parents f309cc3 + 0fb96a6 commit f814234
Show file tree
Hide file tree
Showing 59 changed files with 1,755 additions and 589 deletions.
30 changes: 30 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!--
Title format should be:
[Affected Packages] PR Type: title
Example:
[lexical-playground][lexical-link] Feature: Add more emojis
Choose from the following PR Types:
Breaking change / Refactor / Feature / Bug Fix / Documentation Update / Chore
-->

## Description
<!--
- What is the current behavior that you are modifying?
- What are the behavior or changes that are being added by this PR?
-->
*Describe the changes in this pull request*

**Closes:** #<!-- issue number -->

## Test plan

### Before

*Insert relevant screenshots/recordings/automated-tests*


### After

*Insert relevant screenshots/recordings/automated-tests*
31 changes: 1 addition & 30 deletions packages/lexical-code/src/CodeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,7 @@ export class CodeNode extends ElementNode {
const td = node as HTMLTableCellElement;
const table: HTMLTableElement | null = td.closest('table');

if (isGitHubCodeCell(td)) {
return {
conversion: convertTableCellElement,
priority: 3,
};
}
if (table && isGitHubCodeTable(table)) {
if (isGitHubCodeCell(td) || (table && isGitHubCodeTable(table))) {
// Return a no-op if it's a table cell in a code table, but not a code line.
// Otherwise it'll fall back to the T
return {
Expand Down Expand Up @@ -348,13 +342,6 @@ function convertDivElement(domNode: Node): DOMConversionOutput {
};
}
return {
after: (childLexicalNodes) => {
const domParent = domNode.parentNode;
if (domParent != null && domNode !== domParent.lastChild) {
childLexicalNodes.push($createLineBreakNode());
}
return childLexicalNodes;
},
node: isCode ? $createCodeNode() : null,
};
}
Expand All @@ -367,22 +354,6 @@ function convertCodeNoop(): DOMConversionOutput {
return {node: null};
}

function convertTableCellElement(domNode: Node): DOMConversionOutput {
// domNode is a <td> since we matched it by nodeName
const cell = domNode as HTMLTableCellElement;

return {
after: (childLexicalNodes) => {
if (cell.parentNode && cell.parentNode.nextSibling) {
// Append newline between code lines
childLexicalNodes.push($createLineBreakNode());
}
return childLexicalNodes;
},
node: null,
};
}

function isCodeElement(div: HTMLElement): boolean {
return div.style.fontFamily.match('monospace') !== null;
}
Expand Down
54 changes: 27 additions & 27 deletions packages/lexical-code/src/__tests__/unit/LexicalCodeNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertText('function');
$getSelection()!.insertText('function');
});
await editor.dispatchCommand(KEY_TAB_COMMAND, tabKeyboardEvent());
expect(testEnv.innerHTML).toBe(
Expand All @@ -187,12 +187,12 @@ describe('LexicalCodeNode tests', () => {

// CodeNode should only render diffs, make sure that the TabNode is not cloned when
// appending more text
let tabKey;
let tabKey: string;
await editor.update(() => {
tabKey = $dfs()
.find(({node}) => $isTabNode(node))
.find(({node}) => $isTabNode(node))!
.node.getKey();
$getSelection().insertText('foo');
$getSelection()!.insertText('foo');
});
expect(
editor.getEditorState().read(() => {
Expand All @@ -214,7 +214,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertText('function');
$getSelection()!.insertText('function');
});
// TODO consolidate editor.update - there's some bad logic in updateAndRetainSelection
await editor.update(() => {
Expand All @@ -238,7 +238,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertText('function');
$getSelection()!.insertText('function');
});
// TODO consolidate editor.update - there's some bad logic in updateAndRetainSelection
await editor.update(() => {
Expand All @@ -253,8 +253,8 @@ describe('LexicalCodeNode tests', () => {

await editor.update(() => {
const root = $getRoot();
const codeTab = root.getFirstDescendant();
const codeText = root.getLastDescendant();
const codeTab = root.getFirstDescendant()!;
const codeText = root.getLastDescendant()!;
const selection = $createRangeSelection();
selection.anchor.set(codeTab.getKey(), 0, 'text');
selection.focus.set(codeText.getKey(), 'function'.length, 'text');
Expand All @@ -275,7 +275,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertText('function');
$getSelection()!.insertText('function');
});
// TODO consolidate editor.update - there's some bad logic in updateAndRetainSelection
await editor.update(() => {
Expand All @@ -290,8 +290,8 @@ describe('LexicalCodeNode tests', () => {

await editor.update(() => {
const root = $getRoot();
const codeTab = root.getFirstDescendant();
const codeText = root.getLastDescendant();
const codeTab = root.getFirstDescendant()!;
const codeText = root.getLastDescendant()!;
const selection = $createRangeSelection();
selection.anchor.set(codeTab.getKey(), 0, 'text');
selection.focus.set(codeText.getKey(), 0, 'text');
Expand All @@ -313,12 +313,12 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertRawText('hello\tworld\nhello\tworld');
$getSelection()!.insertRawText('hello\tworld\nhello\tworld');
});
// TODO consolidate editor.update - there's some bad logic in updateAndRetainSelection
await editor.update(() => {
const firstCodeText = $getRoot().getFirstDescendant();
const lastCodeText = $getRoot().getLastDescendant();
const firstCodeText = $getRoot().getFirstDescendant()!;
const lastCodeText = $getRoot().getLastDescendant()!;
const selection = $createRangeSelection();
selection.anchor.set(firstCodeText.getKey(), 1, 'text');
selection.focus.set(lastCodeText.getKey(), 1, 'text');
Expand Down Expand Up @@ -347,7 +347,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertRawText('hello\n');
$getSelection()!.insertRawText('hello\n');
});
await editor.dispatchCommand(KEY_TAB_COMMAND, tabKeyboardEvent());
expect(testEnv.innerHTML)
Expand All @@ -365,7 +365,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertRawText('\thello');
$getSelection()!.insertRawText('\thello');
});
// TODO consolidate editor.update - there's some bad logic in updateAndRetainSelection
await editor.update(() => {
Expand All @@ -389,7 +389,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertRawText('abc\tdef\nghi\tjkl');
$getSelection()!.insertRawText('abc\tdef\nghi\tjkl');
});
const keyEvent = new KeyboardEventMock();
keyEvent.altKey = true;
Expand All @@ -409,16 +409,16 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
$getSelection().insertRawText('abc\tdef\nghi\tjkl\nmno\tpqr');
$getSelection()!.insertRawText('abc\tdef\nghi\tjkl\nmno\tpqr');
});
// TODO consolidate editor.update - there's some bad logic in updateAndRetainSelection
await editor.update(() => {
const firstCodeText = $getRoot().getFirstDescendant();
const firstCodeText = $getRoot().getFirstDescendant()!;
const secondCodeText = firstCodeText
.getNextSibling() // tab
.getNextSibling() // def
.getNextSibling() // linebreak
.getNextSibling(); // ghi;
.getNextSibling()! // tab
.getNextSibling()! // def
.getNextSibling()! // linebreak
.getNextSibling()!; // ghi;
const selection = $createRangeSelection();
selection.anchor.set(firstCodeText.getKey(), 1, 'text');
selection.focus.set(secondCodeText.getKey(), 1, 'text');
Expand Down Expand Up @@ -455,7 +455,7 @@ describe('LexicalCodeNode tests', () => {
const code = $createCodeNode();
root.append(code);
code.selectStart();
const selection = $getSelection();
const selection = $getSelection()!;
if (tabOrSpaces === 'tab') {
selection.insertRawText('\t\tfunction foo\n\t\tfunction bar');
} else {
Expand Down Expand Up @@ -570,7 +570,7 @@ describe('LexicalCodeNode tests', () => {
const firstChild = code.getFirstChild();
invariant($isTextNode(firstChild));
if (tabOrSpaces === 'tab') {
firstChild.getNextSibling().selectNext(0, 0);
firstChild.getNextSibling()!.selectNext(0, 0);
} else {
firstChild.select(4, 4);
}
Expand Down Expand Up @@ -605,7 +605,7 @@ describe('LexicalCodeNode tests', () => {
$isLineBreakNode(dfsNode.node),
)[0].node;
if (tabOrSpaces === 'tab') {
const firstTab = linebreak.getNextSibling();
const firstTab = linebreak.getNextSibling()!;
firstTab.selectNext();
} else {
linebreak.selectNext(4, 4);
Expand Down Expand Up @@ -687,7 +687,7 @@ describe('LexicalCodeNode tests', () => {
$isLineBreakNode(dfsNode.node),
)[0].node;
if (tabOrSpaces === 'tab') {
const firstTab = linebreak.getNextSibling();
const firstTab = linebreak.getNextSibling()!;
firstTab.selectNext(0, 0);
} else {
linebreak.selectNext(2, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
*
* @flow strict
*/

/**
* LexicalDevtoolsCore
*/
22 changes: 16 additions & 6 deletions packages/lexical-devtools-core/src/generateContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export function generateContent(
editor: LexicalEditor,
commandsLog: ReadonlyArray<LexicalCommand<unknown> & {payload: unknown}>,
exportDOM: boolean,
obfuscateText: boolean = false,
): string {
const editorState = editor.getEditorState();
const editorConfig = editor._config;
Expand Down Expand Up @@ -118,7 +119,10 @@ export function generateContent(

res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(
' ',
)} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node)}\n`;
)} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(
node,
obfuscateText,
)}\n`;

res += printSelectedCharsLine({
indent,
Expand Down Expand Up @@ -230,26 +234,32 @@ function visitTree(
});
}

function normalize(text: string) {
return Object.entries(NON_SINGLE_WIDTH_CHARS_REPLACEMENT).reduce(
function normalize(text: string, obfuscateText: boolean = false) {
const textToPrint = Object.entries(NON_SINGLE_WIDTH_CHARS_REPLACEMENT).reduce(
(acc, [key, value]) => acc.replace(new RegExp(key, 'g'), String(value)),
text,
);
if (obfuscateText) {
return textToPrint.replace(/[^\s]/g, '*');
}
return textToPrint;
}

// TODO Pass via props to allow customizability
function printNode(node: LexicalNode) {
function printNode(node: LexicalNode, obfuscateText: boolean = false) {
if ($isTextNode(node)) {
const text = node.getTextContent();
const title = text.length === 0 ? '(empty)' : `"${normalize(text)}"`;
const title =
text.length === 0 ? '(empty)' : `"${normalize(text, obfuscateText)}"`;
const properties = printAllTextNodeProperties(node);
return [title, properties.length !== 0 ? `{ ${properties} }` : null]
.filter(Boolean)
.join(' ')
.trim();
} else if ($isLinkNode(node)) {
const link = node.getURL();
const title = link.length === 0 ? '(empty)' : `"${normalize(link)}"`;
const title =
link.length === 0 ? '(empty)' : `"${normalize(link, obfuscateText)}"`;
const properties = printAllLinkNodeProperties(node);
return [title, properties.length !== 0 ? `{ ${properties} }` : null]
.filter(Boolean)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
*/

import type {RangeSelection} from 'lexical';
import type {EditorState, LexicalEditor, RangeSelection} from 'lexical';

import {$generateHtmlFromNodes} from '@lexical/html';
import {JSDOM} from 'jsdom';
Expand All @@ -33,14 +33,17 @@ import {
import {createHeadlessEditor} from '../..';

describe('LexicalHeadlessEditor', () => {
let editor;
let editor: LexicalEditor;

async function update(updateFn) {
async function update(updateFn: () => void) {
editor.update(updateFn);
await Promise.resolve();
}

function assertEditorState(editorState, nodes) {
function assertEditorState(
editorState: EditorState,
nodes: Record<string, unknown>[],
) {
const nodesFromState = Array.from(editorState._nodeMap.values());
expect(nodesFromState).toEqual(
nodes.map((node) => expect.objectContaining(node)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ import {
} from 'lexical/src';
import {createTestEditor, TestComposer} from 'lexical/src/__tests__/utils';
import React from 'react';
import {createRoot} from 'react-dom/client';
import {createRoot, Root} from 'react-dom/client';
import * as ReactTestUtils from 'react-dom/test-utils';

describe('LexicalHistory tests', () => {
let container: HTMLDivElement | null = null;
let reactRoot;
let reactRoot: Root;

beforeEach(() => {
container = document.createElement('div');
Expand Down
Loading

0 comments on commit f814234

Please sign in to comment.