mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
fix(editor): should preserve indentation when pasting code with spaces into code block (#11587)
Close [BS-3087](https://linear.app/affine-design/issue/BS-3087/粘贴内容到-code-block-缩进会丢)
This commit is contained in:
@@ -71,6 +71,7 @@ export const paragraphBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher =
|
|||||||
'children'
|
'children'
|
||||||
)
|
)
|
||||||
.closeNode();
|
.closeNode();
|
||||||
|
walkerContext.skipAllChildren();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'heading': {
|
case 'heading': {
|
||||||
|
|||||||
@@ -34,12 +34,6 @@ const NotionClipboardConfig = ClipboardAdapterConfigExtension({
|
|||||||
priority: 95,
|
priority: 95,
|
||||||
});
|
});
|
||||||
|
|
||||||
const HtmlClipboardConfig = ClipboardAdapterConfigExtension({
|
|
||||||
mimeType: 'text/html',
|
|
||||||
adapter: HtmlAdapter,
|
|
||||||
priority: 90,
|
|
||||||
});
|
|
||||||
|
|
||||||
const imageClipboardConfigs = [
|
const imageClipboardConfigs = [
|
||||||
'image/apng',
|
'image/apng',
|
||||||
'image/avif',
|
'image/avif',
|
||||||
@@ -52,14 +46,20 @@ const imageClipboardConfigs = [
|
|||||||
return ClipboardAdapterConfigExtension({
|
return ClipboardAdapterConfigExtension({
|
||||||
mimeType,
|
mimeType,
|
||||||
adapter: ImageAdapter,
|
adapter: ImageAdapter,
|
||||||
priority: 80,
|
priority: 85,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const PlainTextClipboardConfig = ClipboardAdapterConfigExtension({
|
const PlainTextClipboardConfig = ClipboardAdapterConfigExtension({
|
||||||
mimeType: 'text/plain',
|
mimeType: 'text/plain',
|
||||||
adapter: MixTextAdapter,
|
adapter: MixTextAdapter,
|
||||||
priority: 70,
|
priority: 80,
|
||||||
|
});
|
||||||
|
|
||||||
|
const HtmlClipboardConfig = ClipboardAdapterConfigExtension({
|
||||||
|
mimeType: 'text/html',
|
||||||
|
adapter: HtmlAdapter,
|
||||||
|
priority: 75,
|
||||||
});
|
});
|
||||||
|
|
||||||
const AttachmentClipboardConfig = ClipboardAdapterConfigExtension({
|
const AttachmentClipboardConfig = ClipboardAdapterConfigExtension({
|
||||||
|
|||||||
@@ -79,6 +79,17 @@ export const markdownListToDeltaMatcher = MarkdownASTToDeltaExtension({
|
|||||||
toDelta: () => [],
|
toDelta: () => [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const markdownHtmlToDeltaMatcher = MarkdownASTToDeltaExtension({
|
||||||
|
name: 'html',
|
||||||
|
match: ast => ast.type === 'html',
|
||||||
|
toDelta: ast => {
|
||||||
|
if (!('value' in ast)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [{ insert: ast.value }];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const MarkdownInlineToDeltaAdapterExtensions = [
|
export const MarkdownInlineToDeltaAdapterExtensions = [
|
||||||
markdownTextToDeltaMatcher,
|
markdownTextToDeltaMatcher,
|
||||||
markdownInlineCodeToDeltaMatcher,
|
markdownInlineCodeToDeltaMatcher,
|
||||||
@@ -89,4 +100,5 @@ export const MarkdownInlineToDeltaAdapterExtensions = [
|
|||||||
markdownInlineMathToDeltaMatcher,
|
markdownInlineMathToDeltaMatcher,
|
||||||
markdownListToDeltaMatcher,
|
markdownListToDeltaMatcher,
|
||||||
markdownFootnoteReferenceToDeltaMatcher,
|
markdownFootnoteReferenceToDeltaMatcher,
|
||||||
|
markdownHtmlToDeltaMatcher,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -323,4 +323,54 @@ test.describe('paste to code block', () => {
|
|||||||
|
|
||||||
await verifyCodeBlockContent(page, 0, 'hello test\ntest\ntest hello');
|
await verifyCodeBlockContent(page, 0, 'hello test\ntest\ntest hello');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should preserve indentation when pasting code with spaces into code block', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await pressEnter(page);
|
||||||
|
await addCodeBlock(page);
|
||||||
|
|
||||||
|
// Sample code with proper indentation for text/plain
|
||||||
|
const plainTextCode = [
|
||||||
|
'const fibonacci = (n: number): number => {',
|
||||||
|
' if (n <= 1) return n;',
|
||||||
|
' return fibonacci(n - 1) + fibonacci(n - 2);',
|
||||||
|
'}',
|
||||||
|
'function generateSequence(length: number) {',
|
||||||
|
' const sequence = [];',
|
||||||
|
' for (let i = 0; i < length; i++) {',
|
||||||
|
' sequence.push(fibonacci(i));',
|
||||||
|
' }',
|
||||||
|
' return sequence;',
|
||||||
|
'}',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const htmlCode =
|
||||||
|
'<div><span>const</span><span> </span><span>fibonacci</span><span> </span><span>=</span><span> (n</span><span>:</span><span> </span><span>number</span><span>)</span><span>:</span><span> </span><span>number</span><span> </span><span>=></span><span> {</span></div><div><span> </span><span>if</span><span> (n </span><span><=</span><span> </span><span>1</span><span>) </span><span>return</span><span> n;</span></div><div><span> </span><span>return</span><span> </span><span>fibonacci</span><span>(n </span><span>-</span><span> </span><span>1</span><span>) </span><span>+</span><span> </span><span>fibonacci</span><span>(n </span><span>-</span><span> </span><span>2</span><span>);</span></div><div><span>}</span></div><div><span>function</span><span> </span><span>generateSequence</span><span>(length</span><span>:</span><span> </span><span>number</span><span>) {</span></div><div><span> </span><span>const</span><span> </span><span>sequence</span><span> </span><span>=</span><span> [];</span></div><div><span> </span><span>for</span><span> (</span><span>let</span><span> i </span><span>=</span><span> </span><span>0</span><span>; i </span><span><</span><span> length; i</span><span>++</span><span>) {</span></div><div><span> sequence.</span><span>push</span><span>(</span><span>fibonacci</span><span>(i));</span></div><div><span> }</span></div><div><span> </span><span>return</span><span> sequence;</span></div><div><span>}</span></div></div>';
|
||||||
|
|
||||||
|
await pasteContent(page, {
|
||||||
|
'text/plain': plainTextCode,
|
||||||
|
'text/html': htmlCode,
|
||||||
|
});
|
||||||
|
await page.waitForTimeout(100);
|
||||||
|
|
||||||
|
// Verify the pasted code maintains indentation
|
||||||
|
await verifyCodeBlockContent(page, 0, plainTextCode);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('html tag should be treated as plain text when pasting', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await pressEnter(page);
|
||||||
|
await addCodeBlock(page);
|
||||||
|
|
||||||
|
const textWithHtmlTags =
|
||||||
|
'<div><span>const</span><span> </span><span>fibonacci</span><span> </span><span>=</span><span> (n</span><span>:</span><span> </span><span>number</span><span>)</span><span>:</span><span> </span><span>number</span><span> </span><span>=></span><span> {</span></div><div><span> </span><span>if</span><span> (n </span><span><=</span><span> </span><span>1</span><span>) </span><span>return</span><span> n;</span></div><div><span> </span><span>return</span><span> </span><span>fibonacci</span><span>(n </span><span>-</span><span> </span><span>1</span><span>) </span><span>+</span><span> </span><span>fibonacci</span><span>(n </span><span>-</span><span> </span><span>2</span><span>);</span></div><div><span>}</span></div><div><span>function</span><span> </span><span>generateSequence</span><span>(length</span><span>:</span><span> </span><span>number</span><span>) {</span></div><div><span> </span><span>const</span><span> </span><span>sequence</span><span> </span><span>=</span><span> [];</span></div><div><span> </span><span>for</span><span> (</span><span>let</span><span> i </span><span>=</span><span> </span><span>0</span><span>; i </span><span><</span><span> length; i</span><span>++</span><span>) {</span></div><div><span> sequence.</span><span>push</span><span>(</span><span>fibonacci</span><span>(i));</span></div><div><span> }</span></div><div><span> </span><span>return</span><span> sequence;</span></div><div><span>}</span></div></div>';
|
||||||
|
|
||||||
|
await pasteContent(page, { 'text/plain': textWithHtmlTags });
|
||||||
|
await page.waitForTimeout(100);
|
||||||
|
|
||||||
|
// Verify the pasted code maintains indentation
|
||||||
|
await verifyCodeBlockContent(page, 0, textWithHtmlTags);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user