Skip to content

Commit 5d56371

Browse files
authored
[lexical] Add tests for HTMLConfig (#5507)
1 parent c191687 commit 5d56371

File tree

4 files changed

+105
-5
lines changed

4 files changed

+105
-5
lines changed

packages/lexical/src/LexicalEditor.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
DOMConversion,
1212
DOMConversionMap,
1313
DOMExportOutput,
14+
DOMExportOutputMap,
1415
NodeKey,
1516
} from './LexicalNode';
1617

@@ -170,10 +171,7 @@ export type LexicalNodeReplacement = {
170171
};
171172

172173
export type HTMLConfig = {
173-
export?: Map<
174-
Klass<LexicalNode>,
175-
(editor: LexicalEditor, target: LexicalNode) => DOMExportOutput
176-
>;
174+
export?: DOMExportOutputMap;
177175
import?: DOMConversionMap;
178176
};
179177

packages/lexical/src/LexicalNode.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ export type DOMConversionOutput = {
148148
node: null | LexicalNode | Array<LexicalNode>;
149149
};
150150

151+
export type DOMExportOutputMap = Map<
152+
Klass<LexicalNode>,
153+
(editor: LexicalEditor, target: LexicalNode) => DOMExportOutput
154+
>;
155+
151156
export type DOMExportOutput = {
152157
after?: (
153158
generatedElement: HTMLElement | Text | null | undefined,

packages/lexical/src/__tests__/unit/LexicalEditor.test.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*
77
*/
88

9+
import {$generateHtmlFromNodes, $generateNodesFromDOM} from '@lexical/html';
910
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
1011
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
1112
import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';
@@ -57,6 +58,7 @@ import {
5758
} from 'react';
5859
import {createPortal} from 'react-dom';
5960
import {createRoot, Root} from 'react-dom/client';
61+
import invariant from 'shared/invariant';
6062
import * as ReactTestUtils from 'shared/react-test-utils';
6163

6264
import {
@@ -2777,4 +2779,94 @@ describe('LexicalEditor tests', () => {
27772779
newEditor1.setRootElement(null);
27782780
newEditor2.setRootElement(null);
27792781
});
2782+
2783+
describe('html config', () => {
2784+
it('should override export output function', async () => {
2785+
const onError = jest.fn();
2786+
2787+
const newEditor = createTestEditor({
2788+
html: {
2789+
export: new Map([
2790+
[
2791+
TextNode,
2792+
(_, target) => {
2793+
invariant($isTextNode(target));
2794+
2795+
return {
2796+
element: target.hasFormat('bold')
2797+
? document.createElement('bor')
2798+
: document.createElement('foo'),
2799+
};
2800+
},
2801+
],
2802+
]),
2803+
},
2804+
onError: onError,
2805+
});
2806+
2807+
newEditor.setRootElement(container);
2808+
2809+
newEditor.update(() => {
2810+
const root = $getRoot();
2811+
const paragraph = $createParagraphNode();
2812+
const text = $createTextNode();
2813+
root.append(paragraph);
2814+
paragraph.append(text);
2815+
2816+
const selection = $createNodeSelection();
2817+
selection.add(text.getKey());
2818+
2819+
const htmlFoo = $generateHtmlFromNodes(newEditor, selection);
2820+
expect(htmlFoo).toBe('<foo></foo>');
2821+
2822+
text.toggleFormat('bold');
2823+
2824+
const htmlBold = $generateHtmlFromNodes(newEditor, selection);
2825+
expect(htmlBold).toBe('<bor></bor>');
2826+
});
2827+
2828+
expect(onError).not.toHaveBeenCalled();
2829+
});
2830+
2831+
it('should override import conversion function', async () => {
2832+
const onError = jest.fn();
2833+
2834+
const newEditor = createTestEditor({
2835+
html: {
2836+
import: {
2837+
figure: () => ({
2838+
conversion: () => ({node: $createTextNode('yolo')}),
2839+
priority: 4,
2840+
}),
2841+
},
2842+
},
2843+
onError: onError,
2844+
});
2845+
2846+
newEditor.setRootElement(container);
2847+
2848+
newEditor.update(() => {
2849+
const html = '<figure></figure>';
2850+
2851+
const parser = new DOMParser();
2852+
const dom = parser.parseFromString(html, 'text/html');
2853+
const node = $generateNodesFromDOM(newEditor, dom)[0];
2854+
2855+
expect(node).toEqual({
2856+
__detail: 0,
2857+
__format: 0,
2858+
__key: node.getKey(),
2859+
__mode: 0,
2860+
__next: null,
2861+
__parent: null,
2862+
__prev: null,
2863+
__style: '',
2864+
__text: 'yolo',
2865+
__type: 'text',
2866+
});
2867+
});
2868+
2869+
expect(onError).not.toHaveBeenCalled();
2870+
});
2871+
});
27802872
});

packages/lexical/src/__tests__/utils/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ import {createRef} from 'react';
4646
import {createRoot} from 'react-dom/client';
4747
import * as ReactTestUtils from 'shared/react-test-utils';
4848

49-
import {CreateEditorArgs, LexicalNodeReplacement} from '../../LexicalEditor';
49+
import {
50+
CreateEditorArgs,
51+
HTMLConfig,
52+
LexicalNodeReplacement,
53+
} from '../../LexicalEditor';
5054
import {resetRandomKey} from '../../LexicalUtils';
5155

5256
const prettierConfig = prettier.resolveConfig.sync(
@@ -520,6 +524,7 @@ export function createTestEditor(
520524
onError?: (error: Error) => void;
521525
disableEvents?: boolean;
522526
readOnly?: boolean;
527+
html?: HTMLConfig;
523528
} = {},
524529
): LexicalEditor {
525530
const customNodes = config.nodes || [];

0 commit comments

Comments
 (0)