fix(editor): support more divider markdown shortcut (#10139)
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
import { CodeBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
import { CodeBlockModel, ParagraphBlockModel } from '@blocksuite/affine-model';
|
||||||
import { isMarkdownPrefix, matchModels } from '@blocksuite/affine-shared/utils';
|
import {
|
||||||
|
isHorizontalRuleMarkdown,
|
||||||
|
isMarkdownPrefix,
|
||||||
|
matchModels,
|
||||||
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import { type BlockStdScope, TextSelection } from '@blocksuite/block-std';
|
import { type BlockStdScope, TextSelection } from '@blocksuite/block-std';
|
||||||
|
|
||||||
import { getInlineEditorByModel } from '../dom.js';
|
import { getInlineEditorByModel } from '../dom.js';
|
||||||
@@ -47,6 +51,10 @@ export function markdownInput(
|
|||||||
return toCode(std, model, prefixText, codeMatch[0].slice(3));
|
return toCode(std, model, prefixText, codeMatch[0].slice(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isHorizontalRuleMarkdown(prefixText.trim())) {
|
||||||
|
return toDivider(std, model, prefixText);
|
||||||
|
}
|
||||||
|
|
||||||
switch (prefixText.trim()) {
|
switch (prefixText.trim()) {
|
||||||
case '[]':
|
case '[]':
|
||||||
case '[ ]':
|
case '[ ]':
|
||||||
@@ -60,9 +68,6 @@ export function markdownInput(
|
|||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case '*':
|
||||||
return toList(std, model, 'bulleted', prefixText);
|
return toList(std, model, 'bulleted', prefixText);
|
||||||
case '***':
|
|
||||||
case '---':
|
|
||||||
return toDivider(std, model, prefixText);
|
|
||||||
case '#':
|
case '#':
|
||||||
return toParagraph(std, model, 'h1', prefixText);
|
return toParagraph(std, model, 'h1', prefixText);
|
||||||
case '##':
|
case '##':
|
||||||
|
|||||||
@@ -76,10 +76,32 @@ export function substringMatchScore(name: string, query: string) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the prefix is a markdown prefix.
|
* Checks if the prefix is a markdown prefix.
|
||||||
* Ex. 1. 2. 3. - * [] [ ] [x] # ## ### #### ##### ###### --- *** > ```
|
* Ex. 1. 2. 3. - * [] [ ] [x] # ## ### #### ##### ###### --- *** ___ > ```
|
||||||
*/
|
*/
|
||||||
export function isMarkdownPrefix(prefix: string) {
|
export function isMarkdownPrefix(prefix: string) {
|
||||||
return !!prefix.match(
|
return (
|
||||||
/^(\d+\.|-|\*|\[ ?\]|\[x\]|(#){1,6}|(-){3}|(\*){3}|>|```([a-zA-Z0-9]*))$/
|
!!prefix.match(
|
||||||
|
/^(\d+\.|-|\*|\[ ?\]|\[x\]|(#){1,6}|>|```([a-zA-Z0-9]*))$/
|
||||||
|
) || isHorizontalRuleMarkdown(prefix)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the prefix is a valid markdown horizontal rule - https://www.markdownguide.org/basic-syntax/#horizontal-rules
|
||||||
|
* @param prefix - The string to check for horizontal rule syntax
|
||||||
|
* @returns boolean - True if the string represents a valid horizontal rule
|
||||||
|
*
|
||||||
|
* Valid horizontal rules:
|
||||||
|
* - Three or more consecutive hyphens (e.g., "---", "----")
|
||||||
|
* - Three or more consecutive asterisks (e.g., "***", "****")
|
||||||
|
* - Three or more consecutive underscores (e.g., "___", "____")
|
||||||
|
*
|
||||||
|
* Invalid examples:
|
||||||
|
* - Mixed characters (e.g., "--*", "-*-")
|
||||||
|
* - Less than three characters (e.g., "--", "**")
|
||||||
|
*/
|
||||||
|
export function isHorizontalRuleMarkdown(prefix: string) {
|
||||||
|
const horizontalRulePattern = /^(-{3,}|\*{3,}|_{3,})$/;
|
||||||
|
|
||||||
|
return !!prefix.match(horizontalRulePattern);
|
||||||
|
}
|
||||||
|
|||||||
@@ -175,18 +175,48 @@ test('markdown shortcut', async ({ page }) => {
|
|||||||
await undoByClick(page);
|
await undoByClick(page);
|
||||||
await assertRichTexts(page, ['']);
|
await assertRichTexts(page, ['']);
|
||||||
|
|
||||||
|
// testing various horizontal dividers
|
||||||
await waitNextFrame(page);
|
await waitNextFrame(page);
|
||||||
await type(page, '--- ');
|
await type(page, '--- ');
|
||||||
await undoByClick(page);
|
await undoByClick(page);
|
||||||
await assertRichTexts(page, ['--- ']);
|
await assertRichTexts(page, ['--- ']);
|
||||||
await undoByClick(page);
|
await undoByClick(page);
|
||||||
await assertRichTexts(page, ['']);
|
await assertRichTexts(page, ['']);
|
||||||
|
|
||||||
await waitNextFrame(page);
|
await waitNextFrame(page);
|
||||||
await type(page, '*** ');
|
await type(page, '*** ');
|
||||||
await undoByClick(page);
|
await undoByClick(page);
|
||||||
await assertRichTexts(page, ['*** ']);
|
await assertRichTexts(page, ['*** ']);
|
||||||
await undoByClick(page);
|
await undoByClick(page);
|
||||||
await assertRichTexts(page, ['']);
|
await assertRichTexts(page, ['']);
|
||||||
|
|
||||||
|
await waitNextFrame(page);
|
||||||
|
await type(page, '___ ');
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['___ ']);
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['']);
|
||||||
|
|
||||||
|
await waitNextFrame(page);
|
||||||
|
await type(page, '------ ');
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['------ ']);
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['']);
|
||||||
|
|
||||||
|
await waitNextFrame(page);
|
||||||
|
await type(page, '****** ');
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['****** ']);
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['']);
|
||||||
|
|
||||||
|
await waitNextFrame(page);
|
||||||
|
await type(page, '______ ');
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['______ ']);
|
||||||
|
await undoByClick(page);
|
||||||
|
await assertRichTexts(page, ['']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('markdown inline-text', () => {
|
test.describe('markdown inline-text', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user