2025-06-23 17:36:39 +00:00
|
|
|
import { type IBlock, type IShortcutPattern, type ISlashMenuItem } from './wysiwyg.types.js';
|
|
|
|
|
|
|
|
export class WysiwygShortcuts {
|
|
|
|
static readonly HEADING_PATTERNS: IShortcutPattern[] = [
|
|
|
|
{ pattern: /^#[\s\u00A0]$/, type: 'heading-1' },
|
|
|
|
{ pattern: /^##[\s\u00A0]$/, type: 'heading-2' },
|
|
|
|
{ pattern: /^###[\s\u00A0]$/, type: 'heading-3' }
|
|
|
|
];
|
|
|
|
|
|
|
|
static readonly LIST_PATTERNS: IShortcutPattern[] = [
|
|
|
|
{ pattern: /^[*-][\s\u00A0]$/, type: 'bullet' },
|
|
|
|
{ pattern: /^(\d+)\.[\s\u00A0]$/, type: 'ordered' },
|
|
|
|
{ pattern: /^(\d+)\)[\s\u00A0]$/, type: 'ordered' }
|
|
|
|
];
|
|
|
|
|
|
|
|
static readonly QUOTE_PATTERN = /^>[\s\u00A0]$/;
|
|
|
|
static readonly CODE_PATTERN = /^```$/;
|
|
|
|
static readonly DIVIDER_PATTERNS = ['---', '***', '___'];
|
|
|
|
|
|
|
|
static checkHeadingShortcut(content: string): { type: IBlock['type'] } | null {
|
|
|
|
for (const { pattern, type } of this.HEADING_PATTERNS) {
|
|
|
|
if (pattern.test(content)) {
|
|
|
|
return { type: type as IBlock['type'] };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
static checkListShortcut(content: string): { type: 'list', listType: 'bullet' | 'ordered' } | null {
|
|
|
|
for (const { pattern, type } of this.LIST_PATTERNS) {
|
|
|
|
if (pattern.test(content)) {
|
|
|
|
return { type: 'list', listType: type as 'bullet' | 'ordered' };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
static checkQuoteShortcut(content: string): boolean {
|
|
|
|
return this.QUOTE_PATTERN.test(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
static checkCodeShortcut(content: string): boolean {
|
|
|
|
return this.CODE_PATTERN.test(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
static checkDividerShortcut(content: string): boolean {
|
|
|
|
return this.DIVIDER_PATTERNS.includes(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
static getSlashMenuItems(): ISlashMenuItem[] {
|
|
|
|
return [
|
|
|
|
{ type: 'paragraph', label: 'Paragraph', icon: '¶' },
|
|
|
|
{ type: 'heading-1', label: 'Heading 1', icon: 'H₁' },
|
|
|
|
{ type: 'heading-2', label: 'Heading 2', icon: 'H₂' },
|
|
|
|
{ type: 'heading-3', label: 'Heading 3', icon: 'H₃' },
|
|
|
|
{ type: 'quote', label: 'Quote', icon: '"' },
|
|
|
|
{ type: 'code', label: 'Code', icon: '<>' },
|
|
|
|
{ type: 'list', label: 'List', icon: '•' },
|
2025-06-24 17:16:13 +00:00
|
|
|
{ type: 'image', label: 'Image', icon: '🖼' },
|
2025-06-23 17:36:39 +00:00
|
|
|
{ type: 'divider', label: 'Divider', icon: '—' },
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
static generateBlockId(): string {
|
|
|
|
return `block-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-export the type that is used in this module
|
|
|
|
export type { ISlashMenuItem } from './wysiwyg.types.js';
|