mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-05-04 18:08:46 +03:00
WYSIWYG: Added inline code support to minimal editor
Used for comments and descriptions. Also updated shortcut handling that we're not registering shortcuts for edits which can't use the related formatting types. For #6003
This commit is contained in:
@@ -27,6 +27,7 @@ class HtmlDescriptionFilter
|
||||
'span' => [],
|
||||
'em' => [],
|
||||
'br' => [],
|
||||
'code' => [],
|
||||
];
|
||||
|
||||
public static function filterFromString(string $html): string
|
||||
|
||||
@@ -59,7 +59,7 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
|
||||
mergeRegister(
|
||||
registerRichText(editor),
|
||||
registerHistory(editor, createEmptyHistoryState(), 300),
|
||||
registerShortcuts(context),
|
||||
registerShortcuts(context, true),
|
||||
registerKeyboardHandling(context),
|
||||
registerMouseHandling(context),
|
||||
registerSelectionHandling(context),
|
||||
@@ -123,7 +123,7 @@ export function createBasicEditorInstance(container: HTMLElement, htmlContent: s
|
||||
const editorTeardown = mergeRegister(
|
||||
registerRichText(editor),
|
||||
registerHistory(editor, createEmptyHistoryState(), 300),
|
||||
registerShortcuts(context),
|
||||
registerShortcuts(context, false),
|
||||
registerAutoLinks(editor),
|
||||
);
|
||||
|
||||
@@ -157,7 +157,7 @@ export function createCommentEditorInstance(container: HTMLElement, htmlContent:
|
||||
const editorTeardown = mergeRegister(
|
||||
registerRichText(editor),
|
||||
registerHistory(editor, createEmptyHistoryState(), 300),
|
||||
registerShortcuts(context),
|
||||
registerShortcuts(context, false),
|
||||
registerAutoLinks(editor),
|
||||
registerMentions(context),
|
||||
);
|
||||
|
||||
@@ -38,29 +38,9 @@ type ShortcutAction = (editor: LexicalEditor, context: EditorUiContext) => boole
|
||||
* List of action functions by their shortcut combo.
|
||||
* We use "meta" as an abstraction for ctrl/cmd depending on platform.
|
||||
*/
|
||||
const actionsByKeys: Record<string, ShortcutAction> = {
|
||||
'meta+s': () => {
|
||||
window.$events.emit('editor-save-draft');
|
||||
return true;
|
||||
},
|
||||
'meta+enter': () => {
|
||||
window.$events.emit('editor-save-page');
|
||||
return true;
|
||||
},
|
||||
'meta+1': (editor, context) => headerHandler(context, 'h2'),
|
||||
'meta+2': (editor, context) => headerHandler(context, 'h3'),
|
||||
'meta+3': (editor, context) => headerHandler(context, 'h4'),
|
||||
'meta+4': (editor, context) => headerHandler(context, 'h5'),
|
||||
'meta+5': wrapFormatAction(toggleSelectionAsParagraph),
|
||||
'meta+d': wrapFormatAction(toggleSelectionAsParagraph),
|
||||
'meta+6': wrapFormatAction(toggleSelectionAsBlockquote),
|
||||
'meta+q': wrapFormatAction(toggleSelectionAsBlockquote),
|
||||
'meta+7': wrapFormatAction(formatCodeBlock),
|
||||
'meta+e': wrapFormatAction(formatCodeBlock),
|
||||
const baseActionsByKeys: Record<string, ShortcutAction> = {
|
||||
'meta+8': toggleInlineCode,
|
||||
'meta+shift+e': toggleInlineCode,
|
||||
'meta+9': wrapFormatAction(cycleSelectionCalloutFormats),
|
||||
|
||||
'meta+o': wrapFormatAction((e) => toggleSelectionAsList(e, 'number')),
|
||||
'meta+p': wrapFormatAction((e) => toggleSelectionAsList(e, 'bullet')),
|
||||
'meta+k': (editor, context) => {
|
||||
@@ -87,12 +67,39 @@ const actionsByKeys: Record<string, ShortcutAction> = {
|
||||
},
|
||||
};
|
||||
|
||||
function createKeyDownListener(context: EditorUiContext): (e: KeyboardEvent) => void {
|
||||
/**
|
||||
* An extended set of the above, used for fuller-featured editors with heavier block-level formatting.
|
||||
*/
|
||||
const extendedActionsByKeys: Record<string, ShortcutAction> = {
|
||||
...baseActionsByKeys,
|
||||
'meta+s': () => {
|
||||
window.$events.emit('editor-save-draft');
|
||||
return true;
|
||||
},
|
||||
'meta+enter': () => {
|
||||
window.$events.emit('editor-save-page');
|
||||
return true;
|
||||
},
|
||||
'meta+1': (editor, context) => headerHandler(context, 'h2'),
|
||||
'meta+2': (editor, context) => headerHandler(context, 'h3'),
|
||||
'meta+3': (editor, context) => headerHandler(context, 'h4'),
|
||||
'meta+4': (editor, context) => headerHandler(context, 'h5'),
|
||||
'meta+5': wrapFormatAction(toggleSelectionAsParagraph),
|
||||
'meta+d': wrapFormatAction(toggleSelectionAsParagraph),
|
||||
'meta+6': wrapFormatAction(toggleSelectionAsBlockquote),
|
||||
'meta+7': wrapFormatAction(formatCodeBlock),
|
||||
'meta+e': wrapFormatAction(formatCodeBlock),
|
||||
'meta+q': wrapFormatAction(toggleSelectionAsBlockquote),
|
||||
'meta+9': wrapFormatAction(cycleSelectionCalloutFormats),
|
||||
};
|
||||
|
||||
function createKeyDownListener(context: EditorUiContext, useExtended: boolean): (e: KeyboardEvent) => void {
|
||||
const keySetToUse = useExtended ? extendedActionsByKeys : baseActionsByKeys;
|
||||
return (event: KeyboardEvent) => {
|
||||
const combo = keyboardEventToKeyComboString(event);
|
||||
// console.log(`pressed: ${combo}`);
|
||||
if (actionsByKeys[combo]) {
|
||||
const handled = actionsByKeys[combo](context.editor, context);
|
||||
if (keySetToUse[combo]) {
|
||||
const handled = keySetToUse[combo](context.editor, context);
|
||||
if (handled) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
@@ -127,8 +134,8 @@ function overrideDefaultCommands(editor: LexicalEditor) {
|
||||
}, COMMAND_PRIORITY_HIGH);
|
||||
}
|
||||
|
||||
export function registerShortcuts(context: EditorUiContext) {
|
||||
const listener = createKeyDownListener(context);
|
||||
export function registerShortcuts(context: EditorUiContext, useExtended: boolean) {
|
||||
const listener = createKeyDownListener(context, useExtended);
|
||||
overrideDefaultCommands(context.editor);
|
||||
|
||||
return context.editor.registerRootListener((rootElement: null | HTMLElement, prevRootElement: null | HTMLElement) => {
|
||||
|
||||
@@ -227,6 +227,7 @@ export function getBasicEditorToolbar(context: EditorUiContext): EditorContainer
|
||||
new EditorButton(bold),
|
||||
new EditorButton(italic),
|
||||
new EditorButton(link),
|
||||
new EditorButton(code),
|
||||
new EditorButton(bulletList),
|
||||
new EditorButton(numberList),
|
||||
])
|
||||
|
||||
@@ -256,8 +256,8 @@ class BookTest extends TestCase
|
||||
{
|
||||
$book = $this->entities->book();
|
||||
|
||||
$input = '<h1>Test</h1><p id="abc" href="beans">Content<a href="#cat" target="_blank" data-a="b">a</a><section>Hello</section></p>';
|
||||
$expected = '<p>Content<a href="#cat" target="_blank">a</a></p>';
|
||||
$input = '<h1>Test</h1><p id="abc" href="beans">Content<a href="#cat" target="_blank" data-a="b">a</a><section>Hello</section><code id="abc">code</code></p>';
|
||||
$expected = '<p>Content<a href="#cat" target="_blank">a</a><code>code</code></p>';
|
||||
|
||||
$this->asEditor()->put($book->getUrl(), [
|
||||
'name' => $book->name,
|
||||
|
||||
Reference in New Issue
Block a user