Skip to content

Commit 4c4b0ef

Browse files
authored
Fix language being discarded when copy and pasting code block in new editor (#1391)
1 parent c300a68 commit 4c4b0ef

File tree

4 files changed

+70
-8
lines changed

4 files changed

+70
-8
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@keystatic/core': patch
3+
---
4+
5+
Fix language being discarded when copy and pasting code block in new editor

packages/keystatic/src/form/fields/markdoc/editor/schema.tsx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ const dividerDOM: DOMOutputSpec = [
7070
}),
7171
},
7272
];
73-
const codeDOM: DOMOutputSpec = [
74-
'pre',
75-
{ spellcheck: 'false' },
76-
['code', {}, 0],
77-
];
7873
const hardBreakDOM: DOMOutputSpec = ['br'];
7974

8075
const olDOM: DOMOutputSpec = ['ol', {}, 0];
@@ -191,9 +186,22 @@ const nodeSpecs = {
191186
},
192187
marks: '',
193188
code: true,
194-
parseDOM: [{ tag: 'pre', preserveWhitespace: 'full' }],
195-
toDOM() {
196-
return codeDOM;
189+
parseDOM: [
190+
{
191+
tag: 'pre',
192+
preserveWhitespace: 'full',
193+
getAttrs(node) {
194+
if (typeof node === 'string') return {};
195+
return { language: node.getAttribute('data-language') ?? '' };
196+
},
197+
},
198+
],
199+
toDOM(node) {
200+
return [
201+
'pre',
202+
{ spellcheck: 'false', 'data-language': node.attrs.language },
203+
['code', {}, 0],
204+
];
197205
},
198206
},
199207
list_item: {

packages/keystatic/src/form/fields/markdoc/editor/tests/pasting/pasting-within-editor.test.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,42 @@ test('blockquote pasting', async () => {
122122
</doc>
123123
`);
124124
});
125+
126+
test('codeblock pasting with language', async () => {
127+
let dataTransfer;
128+
const codeBlock = (
129+
<code_block language="javascript">
130+
<text>console.log(1);</text>
131+
</code_block>
132+
);
133+
{
134+
const { user } = renderEditor(
135+
<doc>
136+
<paragraph>
137+
<anchor />
138+
</paragraph>
139+
{codeBlock}
140+
<paragraph>
141+
<head />
142+
</paragraph>
143+
</doc>
144+
);
145+
146+
dataTransfer = await user.copy();
147+
}
148+
const { state, user } = renderEditor(
149+
<doc>
150+
<paragraph />
151+
</doc>
152+
);
153+
await user.paste(dataTransfer);
154+
expect(state()).toEqual(
155+
<doc>
156+
<paragraph />
157+
{codeBlock}
158+
<paragraph>
159+
<cursor />
160+
</paragraph>
161+
</doc>
162+
);
163+
});

packages/keystatic/src/form/fields/markdoc/editor/tests/utils.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ export function renderEditor(editorState: EditorStateDescription): {
516516
rendered: ReturnType<typeof render>;
517517
user: ReturnType<(typeof userEvent)['setup']>;
518518
state: () => EditorStateDescription;
519+
contentElement: HTMLElement;
519520
} {
520521
const viewRef = createRef<{ view: EditorView | null }>();
521522
const user = userEvent.setup();
@@ -537,10 +538,19 @@ export function renderEditor(editorState: EditorStateDescription): {
537538

538539
viewRef.current!.view!.focus();
539540

541+
const contentElement = rendered.baseElement.querySelector(
542+
'[contenteditable="true"]'
543+
)!;
544+
545+
if (!(contentElement instanceof HTMLElement)) {
546+
throw new Error('content element not found/not HTMLElement');
547+
}
548+
540549
return {
541550
state: () => editorState,
542551
user,
543552
rendered,
553+
contentElement,
544554
};
545555
}
546556

0 commit comments

Comments
 (0)