Lexical: Fixed code in lists, removed extra old alignment code

Code in lists could throw error on parse due to inner <code> tag being
parsed but not actually used within a <pre>, so this updates the
importDOM to disregard childdren for code blocks.

This also improves the invariant implementation to not be so
dev/debugger based, and to include vars in the output.
This commit is contained in:
Dan Brown 2025-02-16 15:09:33 +00:00
parent 7e03a973d8
commit 2b746425c9
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
10 changed files with 25 additions and 68 deletions

View File

@ -8,7 +8,6 @@
import type {
BaseSelection,
ElementFormatType,
LexicalCommand,
LexicalNode,
TextFormatType,
@ -91,8 +90,6 @@ export const OUTDENT_CONTENT_COMMAND: LexicalCommand<void> = createCommand(
);
export const DROP_COMMAND: LexicalCommand<DragEvent> =
createCommand('DROP_COMMAND');
export const FORMAT_ELEMENT_COMMAND: LexicalCommand<ElementFormatType> =
createCommand('FORMAT_ELEMENT_COMMAND');
export const DRAGSTART_COMMAND: LexicalCommand<DragEvent> =
createCommand('DRAGSTART_COMMAND');
export const DRAGOVER_COMMAND: LexicalCommand<DragEvent> =

View File

@ -6,7 +6,6 @@
*
*/
import type {ElementFormatType} from './nodes/LexicalElementNode';
import type {
TextDetailType,
TextFormatType,
@ -111,27 +110,6 @@ export const DETAIL_TYPE_TO_DETAIL: Record<TextDetailType | string, number> = {
unmergeable: IS_UNMERGEABLE,
};
export const ELEMENT_TYPE_TO_FORMAT: Record<
Exclude<ElementFormatType, ''>,
number
> = {
center: IS_ALIGN_CENTER,
end: IS_ALIGN_END,
justify: IS_ALIGN_JUSTIFY,
left: IS_ALIGN_LEFT,
right: IS_ALIGN_RIGHT,
start: IS_ALIGN_START,
};
export const ELEMENT_FORMAT_TO_TYPE: Record<number, ElementFormatType> = {
[IS_ALIGN_CENTER]: 'center',
[IS_ALIGN_END]: 'end',
[IS_ALIGN_JUSTIFY]: 'justify',
[IS_ALIGN_LEFT]: 'left',
[IS_ALIGN_RIGHT]: 'right',
[IS_ALIGN_START]: 'start',
};
export const TEXT_MODE_TO_TYPE: Record<TextModeType, 0 | 1 | 2> = {
normal: IS_NORMAL,
segmented: IS_SEGMENTED,

View File

@ -146,6 +146,12 @@ type NodeName = string;
* Output for a DOM conversion.
* Node can be set to 'ignore' to ignore the conversion and handling of the DOMNode
* including all its children.
*
* You can specify a function to run for each converted child (forChild) or on all
* the child nodes after the conversion is complete (after).
* The key difference here is that forChild runs for every deeply nested child node
* of the current node, whereas after will run only once after the
* transformation of the node and all its children is complete.
*/
export type DOMConversionOutput = {
after?: (childLexicalNodes: Array<LexicalNode>) => Array<LexicalNode>;

View File

@ -49,15 +49,12 @@ export type {
} from './LexicalNode';
export type {
BaseSelection,
ElementPointType as ElementPoint,
NodeSelection,
Point,
PointType,
RangeSelection,
TextPointType as TextPoint,
} from './LexicalSelection';
export type {
ElementFormatType,
SerializedElementNode,
} from './nodes/LexicalElementNode';
export type {SerializedRootNode} from './nodes/LexicalRootNode';
@ -87,7 +84,6 @@ export {
DRAGSTART_COMMAND,
DROP_COMMAND,
FOCUS_COMMAND,
FORMAT_ELEMENT_COMMAND,
FORMAT_TEXT_COMMAND,
INDENT_CONTENT_COMMAND,
INSERT_LINE_BREAK_COMMAND,

View File

@ -46,15 +46,6 @@ export type SerializedElementNode<
SerializedLexicalNode
>;
export type ElementFormatType =
| 'left'
| 'start'
| 'center'
| 'right'
| 'end'
| 'justify'
| '';
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
export interface ElementNode {
getTopLevelElement(): ElementNode | null;

View File

@ -1314,6 +1314,11 @@ const nodeNameToTextFormat: Record<string, TextFormatType> = {
function convertTextFormatElement(domNode: HTMLElement): DOMConversionOutput {
const format = nodeNameToTextFormat[domNode.nodeName.toLowerCase()];
if (format === 'code' && domNode.closest('pre')) {
return {node: null};
}
if (format === undefined) {
return {node: null};
}

View File

@ -18,9 +18,9 @@ export default function invariant(
return;
}
throw new Error(
'Internal Lexical error: invariant() is meant to be replaced at compile ' +
'time. There is no runtime version. Error: ' +
message,
);
for (const arg of args) {
message = (message || '').replace('%s', arg);
}
throw new Error(message);
}

View File

@ -11,7 +11,6 @@ import type {
DOMChildConversion,
DOMConversion,
DOMConversionFn,
ElementFormatType,
LexicalEditor,
LexicalNode,
} from 'lexical';
@ -58,6 +57,7 @@ export function $generateNodesFromDOM(
}
}
}
$unwrapArtificalNodes(allArtificialNodes);
return lexicalNodes;
@ -324,8 +324,6 @@ function wrapContinuousInlines(
nodes: Array<LexicalNode>,
createWrapperFn: () => ElementNode,
): Array<LexicalNode> {
const textAlign = (domNode as HTMLElement).style
.textAlign as ElementFormatType;
const out: Array<LexicalNode> = [];
let continuousInlines: Array<LexicalNode> = [];
// wrap contiguous inline child nodes in para

View File

@ -145,7 +145,14 @@ export class CodeBlockNode extends DecoratorNode<EditorDecoratorAdapter> {
node.setId(element.id);
}
return { node };
return {
node,
after(childNodes): LexicalNode[] {
// Remove any child nodes that may get parsed since we're manually
// controlling the code contents.
return [];
},
};
},
priority: 3,
};

View File

@ -8,7 +8,6 @@
import type {
CommandPayloadType,
ElementFormatType,
LexicalCommand,
LexicalEditor,
PasteCommandType,
@ -44,7 +43,6 @@ import {
DRAGSTART_COMMAND,
DROP_COMMAND,
ElementNode,
FORMAT_ELEMENT_COMMAND,
FORMAT_TEXT_COMMAND,
INSERT_LINE_BREAK_COMMAND,
INSERT_PARAGRAPH_COMMAND,
@ -285,25 +283,6 @@ export function registerRichText(editor: LexicalEditor): () => void {
},
COMMAND_PRIORITY_EDITOR,
),
editor.registerCommand<ElementFormatType>(
FORMAT_ELEMENT_COMMAND,
(format) => {
const selection = $getSelection();
if (!$isRangeSelection(selection) && !$isNodeSelection(selection)) {
return false;
}
const nodes = selection.getNodes();
for (const node of nodes) {
const element = $findMatchingParent(
node,
(parentNode): parentNode is ElementNode =>
$isElementNode(parentNode) && !parentNode.isInline(),
);
}
return true;
},
COMMAND_PRIORITY_EDITOR,
),
editor.registerCommand<boolean>(
INSERT_LINE_BREAK_COMMAND,
(selectStart) => {