Skip to content

Commit 2d0461b

Browse files
authored
Merge pull request #5653 from BookStackApp/v25-05-1-lexical
Lexical Fixes for v25.05.1
2 parents aac5479 + b913ae7 commit 2d0461b

24 files changed

+283
-72
lines changed

resources/js/wysiwyg/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
8484

8585
// @ts-ignore
8686
window.debugEditorState = () => {
87-
console.log(editor.getEditorState().toJSON());
87+
return editor.getEditorState().toJSON();
8888
};
8989

9090
registerCommonNodeMutationListeners(context);

resources/js/wysiwyg/lexical/core/LexicalEvents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ function onSelectionChange(
355355
lastNode instanceof ParagraphNode &&
356356
lastNode.getChildrenSize() === 0
357357
) {
358+
selection.format = lastNode.getTextFormat();
358359
selection.style = lastNode.getTextStyle();
359360
} else {
360361
selection.format = 0;

resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditor.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,7 @@ describe('LexicalEditor tests', () => {
10691069
__prev: null,
10701070
__size: 1,
10711071
__style: '',
1072+
__textFormat: 0,
10721073
__textStyle: '',
10731074
__type: 'paragraph',
10741075
});
@@ -1149,6 +1150,7 @@ describe('LexicalEditor tests', () => {
11491150
__prev: null,
11501151
__size: 1,
11511152
__style: '',
1153+
__textFormat: 0,
11521154
__textStyle: '',
11531155
__type: 'paragraph',
11541156
});

resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditorState.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ describe('LexicalEditorState tests', () => {
7676
__prev: null,
7777
__size: 1,
7878
__style: '',
79+
__textFormat: 0,
7980
__textStyle: '',
8081
__type: 'paragraph',
8182
});
@@ -111,7 +112,7 @@ describe('LexicalEditorState tests', () => {
111112
});
112113

113114
expect(JSON.stringify(editor.getEditorState().toJSON())).toEqual(
114-
`{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Hello world","type":"text","version":1}],"direction":null,"type":"paragraph","version":1,"id":"","alignment":"","inset":0,"textStyle":""}],"direction":null,"type":"root","version":1}}`,
115+
`{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Hello world","type":"text","version":1}],"direction":null,"type":"paragraph","version":1,"id":"","alignment":"","inset":0,"textFormat":0,"textStyle":""}],"direction":null,"type":"root","version":1}}`,
115116
);
116117
});
117118

resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSerialization.test.ts

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

resources/js/wysiwyg/lexical/core/__tests__/utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
3838
import {EditorUiContext} from "../../../../ui/framework/core";
3939
import {EditorUIManager} from "../../../../ui/framework/manager";
4040
import {ImageNode} from "@lexical/rich-text/LexicalImageNode";
41+
import {MediaNode} from "@lexical/rich-text/LexicalMediaNode";
4142

4243
type TestEnv = {
4344
readonly container: HTMLDivElement;
@@ -487,6 +488,7 @@ export function createTestContext(): EditorUiContext {
487488
theme: {},
488489
nodes: [
489490
ImageNode,
491+
MediaNode,
490492
]
491493
});
492494

resources/js/wysiwyg/lexical/core/nodes/LexicalParagraphNode.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
LexicalNode,
2020
NodeKey,
2121
} from '../LexicalNode';
22-
import type {RangeSelection} from 'lexical';
22+
import {RangeSelection, TEXT_TYPE_TO_FORMAT, TextFormatType} from 'lexical';
2323

2424
import {
2525
$applyNodeReplacement,
@@ -36,6 +36,7 @@ import {CommonBlockNode, copyCommonBlockProperties, SerializedCommonBlockNode} f
3636

3737
export type SerializedParagraphNode = Spread<
3838
{
39+
textFormat: number;
3940
textStyle: string;
4041
},
4142
SerializedCommonBlockNode
@@ -45,17 +46,35 @@ export type SerializedParagraphNode = Spread<
4546
export class ParagraphNode extends CommonBlockNode {
4647
['constructor']!: KlassConstructor<typeof ParagraphNode>;
4748
/** @internal */
49+
__textFormat: number;
4850
__textStyle: string;
4951

5052
constructor(key?: NodeKey) {
5153
super(key);
54+
this.__textFormat = 0;
5255
this.__textStyle = '';
5356
}
5457

5558
static getType(): string {
5659
return 'paragraph';
5760
}
5861

62+
getTextFormat(): number {
63+
const self = this.getLatest();
64+
return self.__textFormat;
65+
}
66+
67+
setTextFormat(type: number): this {
68+
const self = this.getWritable();
69+
self.__textFormat = type;
70+
return self;
71+
}
72+
73+
hasTextFormat(type: TextFormatType): boolean {
74+
const formatFlag = TEXT_TYPE_TO_FORMAT[type];
75+
return (this.getTextFormat() & formatFlag) !== 0;
76+
}
77+
5978
getTextStyle(): string {
6079
const self = this.getLatest();
6180
return self.__textStyle;
@@ -73,6 +92,7 @@ export class ParagraphNode extends CommonBlockNode {
7392

7493
afterCloneFrom(prevNode: this) {
7594
super.afterCloneFrom(prevNode);
95+
this.__textFormat = prevNode.__textFormat;
7696
this.__textStyle = prevNode.__textStyle;
7797
copyCommonBlockProperties(prevNode, this);
7898
}
@@ -125,12 +145,14 @@ export class ParagraphNode extends CommonBlockNode {
125145
static importJSON(serializedNode: SerializedParagraphNode): ParagraphNode {
126146
const node = $createParagraphNode();
127147
deserializeCommonBlockNode(serializedNode, node);
148+
node.setTextFormat(serializedNode.textFormat);
128149
return node;
129150
}
130151

131152
exportJSON(): SerializedParagraphNode {
132153
return {
133154
...super.exportJSON(),
155+
textFormat: this.getTextFormat(),
134156
textStyle: this.getTextStyle(),
135157
type: 'paragraph',
136158
version: 1,
@@ -144,6 +166,7 @@ export class ParagraphNode extends CommonBlockNode {
144166
restoreSelection: boolean,
145167
): ParagraphNode {
146168
const newElement = $createParagraphNode();
169+
newElement.setTextFormat(rangeSelection.format);
147170
newElement.setTextStyle(rangeSelection.style);
148171
const direction = this.getDirection();
149172
newElement.setDirection(direction);

resources/js/wysiwyg/lexical/core/nodes/LexicalTextNode.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ export class TextNode extends LexicalNode {
620620
// HTML content and not have the ability to use CSS classes.
621621
exportDOM(editor: LexicalEditor): DOMExportOutput {
622622
let {element} = super.exportDOM(editor);
623+
const originalElementName = (element?.nodeName || '').toLowerCase()
623624
invariant(
624625
element !== null && isHTMLElement(element),
625626
'Expected TextNode createDOM to always return a HTMLElement',
@@ -649,8 +650,8 @@ export class TextNode extends LexicalNode {
649650
// This is the only way to properly add support for most clients,
650651
// even if it's semantically incorrect to have to resort to using
651652
// <b>, <u>, <s>, <i> elements.
652-
if (this.hasFormat('bold')) {
653-
element = wrapElementWith(element, 'b');
653+
if (this.hasFormat('bold') && originalElementName !== 'strong') {
654+
element = wrapElementWith(element, 'strong');
654655
}
655656
if (this.hasFormat('italic')) {
656657
element = wrapElementWith(element, 'em');

resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalParagraphNode.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ describe('LexicalParagraphNode tests', () => {
5353
direction: null,
5454
id: '',
5555
inset: 0,
56+
textFormat: 0,
5657
textStyle: '',
5758
type: 'paragraph',
5859
version: 1,

resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTextNode.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ describe('LexicalTextNode tests', () => {
839839
paragraph.append(textNode);
840840

841841
const html = $generateHtmlFromNodes($getEditor(), null);
842-
expect(html).toBe('<p><u><em><b><code spellcheck="false"><strong>hello</strong></code></b></em></u></p>');
842+
expect(html).toBe('<p><u><em><strong><code spellcheck="false"><strong>hello</strong></code></strong></em></u></p>');
843843
});
844844
});
845845

0 commit comments

Comments
 (0)