mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
refactor(editor): remove inline editor keyboard utils and add markdown property in rich-text (#10375)
This commit is contained in:
@@ -1,376 +0,0 @@
|
||||
import {
|
||||
type InlineEditor,
|
||||
type InlineRange,
|
||||
KEYBOARD_ALLOW_DEFAULT,
|
||||
KEYBOARD_PREVENT_DEFAULT,
|
||||
} from '@blocksuite/inline';
|
||||
import type * as Y from 'yjs';
|
||||
|
||||
interface MarkdownMatch {
|
||||
name: string;
|
||||
pattern: RegExp;
|
||||
action: (props: {
|
||||
inlineEditor: InlineEditor;
|
||||
prefixText: string;
|
||||
inlineRange: InlineRange;
|
||||
pattern: RegExp;
|
||||
undoManager: Y.UndoManager;
|
||||
}) => boolean;
|
||||
}
|
||||
|
||||
export const markdownMatches: MarkdownMatch[] = [
|
||||
{
|
||||
name: 'bolditalic',
|
||||
pattern: /(?:\*){3}([^* \n](.+?[^* \n])?)(?:\*){3}$/g,
|
||||
action: ({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern,
|
||||
undoManager,
|
||||
}) => {
|
||||
const match = pattern.exec(prefixText);
|
||||
if (!match) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
|
||||
const annotatedText = match[0];
|
||||
const startIndex = inlineRange.index - annotatedText.length;
|
||||
|
||||
inlineEditor.insertText(
|
||||
{
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 0,
|
||||
},
|
||||
' '
|
||||
);
|
||||
|
||||
undoManager.stopCapturing();
|
||||
|
||||
inlineEditor.formatText(
|
||||
{
|
||||
index: startIndex,
|
||||
length: annotatedText.length,
|
||||
},
|
||||
{
|
||||
bold: true,
|
||||
italic: true,
|
||||
}
|
||||
);
|
||||
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length - 3,
|
||||
length: 3,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex,
|
||||
length: 3,
|
||||
});
|
||||
|
||||
inlineEditor.setInlineRange({
|
||||
index: startIndex + annotatedText.length - 6,
|
||||
length: 0,
|
||||
});
|
||||
|
||||
return KEYBOARD_PREVENT_DEFAULT;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'bold',
|
||||
pattern: /(?:\*){2}([^* \n](.+?[^* \n])?)(?:\*){2}$/g,
|
||||
action: ({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern,
|
||||
undoManager,
|
||||
}) => {
|
||||
const match = pattern.exec(prefixText);
|
||||
if (!match) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
const annotatedText = match[0];
|
||||
const startIndex = inlineRange.index - annotatedText.length;
|
||||
|
||||
inlineEditor.insertText(
|
||||
{
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 0,
|
||||
},
|
||||
' '
|
||||
);
|
||||
|
||||
undoManager.stopCapturing();
|
||||
|
||||
inlineEditor.formatText(
|
||||
{
|
||||
index: startIndex,
|
||||
length: annotatedText.length,
|
||||
},
|
||||
{
|
||||
bold: true,
|
||||
}
|
||||
);
|
||||
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length - 2,
|
||||
length: 2,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex,
|
||||
length: 2,
|
||||
});
|
||||
|
||||
inlineEditor.setInlineRange({
|
||||
index: startIndex + annotatedText.length - 4,
|
||||
length: 0,
|
||||
});
|
||||
|
||||
return KEYBOARD_PREVENT_DEFAULT;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'italic',
|
||||
pattern: /(?:\*){1}([^* \n](.+?[^* \n])?)(?:\*){1}$/g,
|
||||
action: ({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern,
|
||||
undoManager,
|
||||
}) => {
|
||||
const match = pattern.exec(prefixText);
|
||||
if (!match) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
const annotatedText = match[0];
|
||||
const startIndex = inlineRange.index - annotatedText.length;
|
||||
|
||||
inlineEditor.insertText(
|
||||
{
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 0,
|
||||
},
|
||||
' '
|
||||
);
|
||||
|
||||
undoManager.stopCapturing();
|
||||
|
||||
inlineEditor.formatText(
|
||||
{
|
||||
index: startIndex,
|
||||
length: annotatedText.length,
|
||||
},
|
||||
{
|
||||
italic: true,
|
||||
}
|
||||
);
|
||||
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length - 1,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex,
|
||||
length: 1,
|
||||
});
|
||||
|
||||
inlineEditor.setInlineRange({
|
||||
index: startIndex + annotatedText.length - 2,
|
||||
length: 0,
|
||||
});
|
||||
|
||||
return KEYBOARD_PREVENT_DEFAULT;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'strikethrough',
|
||||
pattern: /(?:~~)([^~ \n](.+?[^~ \n])?)(?:~~)$/g,
|
||||
action: ({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern,
|
||||
undoManager,
|
||||
}) => {
|
||||
const match = pattern.exec(prefixText);
|
||||
if (!match) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
const annotatedText = match[0];
|
||||
const startIndex = inlineRange.index - annotatedText.length;
|
||||
|
||||
inlineEditor.insertText(
|
||||
{
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 0,
|
||||
},
|
||||
' '
|
||||
);
|
||||
|
||||
undoManager.stopCapturing();
|
||||
|
||||
inlineEditor.formatText(
|
||||
{
|
||||
index: startIndex,
|
||||
length: annotatedText.length,
|
||||
},
|
||||
{
|
||||
strike: true,
|
||||
}
|
||||
);
|
||||
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length - 2,
|
||||
length: 2,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex,
|
||||
length: 2,
|
||||
});
|
||||
|
||||
inlineEditor.setInlineRange({
|
||||
index: startIndex + annotatedText.length - 4,
|
||||
length: 0,
|
||||
});
|
||||
|
||||
return KEYBOARD_PREVENT_DEFAULT;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'underthrough',
|
||||
pattern: /(?:~)([^~ \n](.+?[^~ \n])?)(?:~)$/g,
|
||||
action: ({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern,
|
||||
undoManager,
|
||||
}) => {
|
||||
const match = pattern.exec(prefixText);
|
||||
if (!match) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
const annotatedText = match[0];
|
||||
const startIndex = inlineRange.index - annotatedText.length;
|
||||
|
||||
inlineEditor.insertText(
|
||||
{
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 0,
|
||||
},
|
||||
' '
|
||||
);
|
||||
|
||||
undoManager.stopCapturing();
|
||||
|
||||
inlineEditor.formatText(
|
||||
{
|
||||
index: startIndex,
|
||||
length: annotatedText.length,
|
||||
},
|
||||
{
|
||||
underline: true,
|
||||
}
|
||||
);
|
||||
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: inlineRange.index - 1,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex,
|
||||
length: 1,
|
||||
});
|
||||
|
||||
inlineEditor.setInlineRange({
|
||||
index: startIndex + annotatedText.length - 2,
|
||||
length: 0,
|
||||
});
|
||||
|
||||
return KEYBOARD_PREVENT_DEFAULT;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'code',
|
||||
pattern: /(?:`)(`{2,}?|[^`]+)(?:`)$/g,
|
||||
action: ({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern,
|
||||
undoManager,
|
||||
}) => {
|
||||
const match = pattern.exec(prefixText);
|
||||
if (!match) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
const annotatedText = match[0];
|
||||
const startIndex = inlineRange.index - annotatedText.length;
|
||||
|
||||
if (prefixText.match(/^([* \n]+)$/g)) {
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
}
|
||||
|
||||
inlineEditor.insertText(
|
||||
{
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 0,
|
||||
},
|
||||
' '
|
||||
);
|
||||
|
||||
undoManager.stopCapturing();
|
||||
|
||||
inlineEditor.formatText(
|
||||
{
|
||||
index: startIndex,
|
||||
length: annotatedText.length,
|
||||
},
|
||||
{
|
||||
code: true,
|
||||
}
|
||||
);
|
||||
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex + annotatedText.length - 1,
|
||||
length: 1,
|
||||
});
|
||||
inlineEditor.deleteText({
|
||||
index: startIndex,
|
||||
length: 1,
|
||||
});
|
||||
|
||||
inlineEditor.setInlineRange({
|
||||
index: startIndex + annotatedText.length - 2,
|
||||
length: 0,
|
||||
});
|
||||
|
||||
return KEYBOARD_PREVENT_DEFAULT;
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -5,9 +5,7 @@ import {
|
||||
type AttributeRenderer,
|
||||
type BaseTextAttributes,
|
||||
baseTextAttributes,
|
||||
createInlineKeyDownHandler,
|
||||
InlineEditor,
|
||||
KEYBOARD_ALLOW_DEFAULT,
|
||||
ZERO_WIDTH_NON_JOINER,
|
||||
} from '@blocksuite/inline';
|
||||
import { effects } from '@blocksuite/inline/effects';
|
||||
@@ -18,8 +16,6 @@ import { styleMap } from 'lit/directives/style-map.js';
|
||||
import * as Y from 'yjs';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { markdownMatches } from './markdown.js';
|
||||
|
||||
effects();
|
||||
|
||||
function inlineTextStyles(
|
||||
@@ -132,30 +128,6 @@ export class TestRichText extends ShadowlessElement {
|
||||
this.style.outline = 'none';
|
||||
this.inlineEditor.mount(this._container, this);
|
||||
|
||||
const keydownHandler = createInlineKeyDownHandler(this.inlineEditor, {
|
||||
inputRule: {
|
||||
key: ' ',
|
||||
handler: context => {
|
||||
const { inlineEditor, prefixText, inlineRange } = context;
|
||||
for (const match of markdownMatches) {
|
||||
const matchedText = prefixText.match(match.pattern);
|
||||
if (matchedText) {
|
||||
return match.action({
|
||||
inlineEditor,
|
||||
prefixText,
|
||||
inlineRange,
|
||||
pattern: match.pattern,
|
||||
undoManager: this.undoManager,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return KEYBOARD_ALLOW_DEFAULT;
|
||||
},
|
||||
},
|
||||
});
|
||||
this.addEventListener('keydown', keydownHandler);
|
||||
|
||||
this.inlineEditor.slots.textChange.on(() => {
|
||||
const el = this.querySelector('.y-text');
|
||||
if (el) {
|
||||
|
||||
Reference in New Issue
Block a user