diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts')
-rw-r--r-- | src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts | 209 |
1 files changed, 114 insertions, 95 deletions
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 3c84e5a10..7ae1fc202 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -1,29 +1,30 @@ import { chainCommands, deleteSelection, exitCode, joinBackward, joinDown, joinUp, lift, newlineInCode, selectNodeBackward, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn } from 'prosemirror-commands'; import { redo, undo } from 'prosemirror-history'; -import { Schema } from 'prosemirror-model'; +import { MarkType, Node, Schema } from 'prosemirror-model'; import { liftListItem, sinkListItem, splitListItem, wrapInList } from 'prosemirror-schema-list'; -import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state'; +import { Command, EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state'; import { liftTarget } from 'prosemirror-transform'; import { EditorView } from 'prosemirror-view'; import { ClientUtils } from '../../../../ClientUtils'; -import { Utils } from '../../../../Utils'; +import { numberRange, Utils } from '../../../../Utils'; import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../../fields/DocSymbols'; import { GetEffectiveAcl } from '../../../../fields/util'; import { Docs } from '../../../documents/Documents'; import { RTFMarkup } from '../../../util/RTFMarkup'; import { DocumentView } from '../DocumentView'; import { OpenWhere } from '../OpenWhere'; +import { FormattedTextBox } from './FormattedTextBox'; const mac = typeof navigator !== 'undefined' ? /Mac/.test(navigator.platform) : false; -export type KeyMap = { [key: string]: any }; +export type KeyMap = { [key: string]: Command }; -export const updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle?: string, from?: number, to?: number) => { +export function updateBullets(tx2: Transaction, schema: Schema, assignedMapStyle?: string, from?: number, to?: number) { let mapStyle = assignedMapStyle; - tx2.doc.descendants((node: any, offset: any /* , index: any */) => { + tx2.doc.descendants((node: Node, offset: number /* , index: any */) => { if ((from === undefined || to === undefined || (from <= offset + node.nodeSize && to >= offset)) && (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item)) { - const { path } = tx2.doc.resolve(offset) as any; - let depth = Array.from(path).reduce((p: number, c: any) => p + (c.type === schema.nodes.ordered_list ? 1 : 0), 0); + const resolved = tx2.doc.resolve(offset); + let depth = [0, ...numberRange(resolved.depth)].reduce((p, c, idx) => p + (resolved.node(idx).type === schema.nodes.ordered_list ? 1 : 0), 0); if (node.type === schema.nodes.ordered_list) { if (depth === 0 && !assignedMapStyle) mapStyle = node.attrs.mapStyle; depth++; @@ -32,28 +33,29 @@ export const updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle } }); return tx2; -}; +} -export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMap { - const keys: { [key: string]: any } = {}; +export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: FormattedTextBox): KeyMap { + const keys: { [key: string]: Command } = {}; - function bind(key: string, cmd: any) { + function bind(key: string, cmd: Command) { keys[key] = cmd; } function onKey(): boolean | undefined { - // bcz: this is pretty hacky -- prosemirror doesn't send us the keyboard event, but the 'event' variable is in scope.. so we access it anyway + // bcz: hack -- prosemirror doesn't send us the keyboard event, but the 'event' variable is in scope.. so we access it anyway // eslint-disable-next-line no-restricted-globals - return props.onKey?.(event, props); + return event && tbox?._props.onKey?.(event as unknown as KeyboardEvent, tbox); } - const canEdit = (state: any) => { - const permissions = GetEffectiveAcl(props.TemplateDataDocument ?? props.Document[DocData]); - switch (permissions) { + const canEdit = (state: EditorState) => { + if (!tbox) return true; + switch (GetEffectiveAcl(tbox.dataDoc)) { case AclAugment: { - const prevNode = state.selection.$cursor.nodeBefore; - const prevUser = !prevNode ? ClientUtils.CurrentUserEmail() : prevNode.marks.lastElement()?.attrs.userid; + // previously used hack: (state.selection as any).$cursor.nodeBefore; + const prevNode = state.selection?.$anchor.nodeBefore; + const prevUser = !prevNode ? ClientUtils.CurrentUserEmail() : Array.from(prevNode.marks).lastElement()?.attrs.userid; if (prevUser !== ClientUtils.CurrentUserEmail()) { return false; } @@ -64,7 +66,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa return true; }; - const toggleEditableMark = (mark: any) => (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && toggleMark(mark)(state, dispatch); + const toggleEditableMark = (mark: MarkType) => (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && toggleMark(mark)(state, dispatch); // History commands bind('Mod-z', undo); @@ -84,13 +86,13 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa bind('Mod-U', toggleEditableMark(schema.marks.underline)); // Commands for lists - bind('Ctrl-i', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any)); + bind('Ctrl-i', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state, dispatch)); bind('Ctrl-Tab', () => onKey() || true); bind('Alt-Tab', () => onKey() || true); bind('Meta-Tab', () => onKey() || true); bind('Meta-Enter', () => onKey() || true); - bind('Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Tab', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (onKey()) return true; if (!canEdit(state)) return true; const ref = state.selection; @@ -101,13 +103,13 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); }) ) { // couldn't sink into an existing list, so wrap in a new one const newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end))); if ( - !wrapInList(schema.nodes.ordered_list)(newstate.state as any, (tx2: Transaction) => { + !wrapInList(schema.nodes.ordered_list)(newstate.state, (tx2: Transaction) => { const tx25 = updateBullets(tx2, schema); const olNode = tx25.doc.nodeAt(range!.start)!; const tx3 = tx25.setNodeMarkup(range!.start, olNode.type, olNode.attrs, marks); @@ -115,16 +117,16 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); const tx4 = tx3.setSelection(TextSelection.near(tx3.doc.resolve(state.selection.to + 2))); - dispatch(tx4); + dispatch?.(tx4); }) ) { console.log('bullet promote fail'); } } - return undefined; + return false; }); - bind('Shift-Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Shift-Tab', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (onKey()) return true; if (!canEdit(state)) return true; const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); @@ -134,119 +136,136 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); }) ) { console.log('bullet demote fail'); } - return undefined; + return false; }); // Command to create a new Tab with a PDF of all the command shortcuts - bind('Mod-/', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + bind('Mod-/', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { const newDoc = Docs.Create.PdfDocument(ClientUtils.prepend('/assets/cheat-sheet.pdf'), { _width: 300, _height: 300 }); - props.addDocTab(newDoc, OpenWhere.addRight); + tbox?._props.addDocTab(newDoc, OpenWhere.addRight); + return false; }); // Commands to modify BlockType - bind('Ctrl->', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state && wrapIn(schema.nodes.blockquote)(state as any, dispatch as any))); - bind('Alt-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state as any, dispatch as any)); - bind('Shift-Ctrl-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.code_block)(state as any, dispatch as any)); + bind('Ctrl->', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && wrapIn(schema.nodes.blockquote)(state, dispatch)); + bind('Alt-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state, dispatch)); + bind('Shift-Ctrl-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.code_block)(state, dispatch)); - bind('Ctrl-m', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Ctrl-m', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (canEdit(state)) { const tr = state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: 'math' + Utils.GenerateGuid() })); - dispatch(tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)))); + dispatch?.(tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)))); + return true; } + return false; }); for (let i = 1; i <= 6; i++) { - bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state as any, dispatch as any)); + bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state, dispatch)); } // Command to create a horizontal break line const hr = schema.nodes.horizontal_rule; - bind('Mod-_', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView())); + bind('Mod-_', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + if (canEdit(state)) { + dispatch?.(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); + return true; + } + return false; + }); // Command to unselect all - bind('Escape', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); - (document.activeElement as any).blur?.(); + bind('Escape', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); + (document.activeElement as HTMLElement)?.blur?.(); DocumentView.DeselectAll(); + return true; }); bind('Alt-Enter', () => onKey() || true); bind('Ctrl-Enter', () => onKey() || true); - bind('Cmd-a', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); + bind('Cmd-a', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); return true; }); bind('Cmd-?', () => { RTFMarkup.Instance.setOpen(true); return true; }); - bind('Cmd-e', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Cmd-e', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (!state.selection.empty) { const mark = state.schema.marks.summarizeInclusive.create(); const tr = state.tr.addMark(state.selection.$from.pos, state.selection.$to.pos, mark); const content = tr.selection.content(); - tr.selection.replaceWith(tr, schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() })); - dispatch(tr); + tr.selection.replaceWith(tr, schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() }, undefined, state.selection.$anchor.marks() ?? [])); + dispatch?.(tr); } return true; }); - bind('Cmd-]', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; - const { tr } = state; - if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); + bind('Cmd-]', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const { + tr, + selection: { $from }, + } = state; + if ($from?.parent.type.name === 'paragraph') { + tr.setNodeMarkup(state.selection.from - state.selection.$from.parentOffset - 1, schema.nodes.paragraph, { ...$from.parent.attrs, align: 'right' }, $from.parent.marks); } else { - const node = resolved.nodeAfter; + const node = $from.nodeAfter; const sm = state.storedMarks || undefined; if (node) { tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; - const { tr } = state; - if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); + bind('Cmd-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const { + tr, + selection: { $from }, + } = state; + if ($from?.parent.type.name === 'paragraph') { + tr.setNodeMarkup(state.selection.from - state.selection.$from.parentOffset - 1, schema.nodes.paragraph, { ...$from.parent.attrs, align: 'center' }, $from.parent.marks); } else { - const node = resolved.nodeAfter; + const node = $from.nodeAfter; const sm = state.storedMarks || undefined; if (node) { tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-[', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; - const { tr } = state; - if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); + bind('Cmd-[', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const { + tr, + selection: { $from }, + } = state; + if ($from?.parent.type.name === 'paragraph') { + tr.setNodeMarkup(state.selection.from - state.selection.$from.parentOffset - 1, schema.nodes.paragraph, { ...$from.parent.attrs, align: 'left' }, $from.parent.marks); } else { - const node = resolved.nodeAfter; + const node = $from.nodeAfter; const sm = state.storedMarks || undefined; if (node) { tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-f', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Cmd-f', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { const content = state.tr.selection.empty ? undefined : state.tr.selection.content().content.textBetween(0, state.tr.selection.content().size + 1); const newNode = schema.nodes.footnote.create({}, content ? state.schema.text(content) : undefined); const { tr } = state; tr.replaceSelectionWith(newNode); // replace insertion with a footnote. - dispatch( + dispatch?.( tr.setSelection( new NodeSelection( // select the footnote node to open its display tr.doc.resolve( @@ -259,25 +278,25 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa return true; }); - bind('Ctrl-a', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); + bind('Ctrl-a', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); return true; }); // backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward); - const backspace = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView) => { + const backspace = (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined, view?: EditorView) => { if (onKey()) return true; if (!canEdit(state)) return true; if ( !deleteSelection(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); + dispatch?.(updateBullets(tx, schema)); }) ) { if ( !joinBackward(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); - if (view.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) { + dispatch?.(updateBullets(tx, schema)); + if (view?.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) { // gets rid of an extra paragraph when joining two list items together. joinBackward(view.state, (tx2: Transaction) => view.dispatch(tx2)); } @@ -285,7 +304,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa ) { if ( !selectNodeBackward(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); + dispatch?.(updateBullets(tx, schema)); }) ) { return false; @@ -299,7 +318,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa // newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock // command to break line - const enter = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView, once = true) => { + const enter = (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined, view?: EditorView, once = true) => { if (onKey()) return true; if (!canEdit(state)) return true; @@ -311,31 +330,31 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa !state.selection.$from.node().content.size && trange ) { - dispatch(state.tr.lift(trange, depth) as any); + dispatch?.(state.tr.lift(trange, depth)); return true; } const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); - if (!newlineInCode(state, dispatch as any)) { - const olNode = view.state.selection.$anchor.node(-2); - const liNode = view.state.selection.$anchor.node(-1); + if (!newlineInCode(state, dispatch)) { + const olNode = view?.state.selection.$anchor.node(-2); + const liNode = view?.state.selection.$anchor.node(-1); // prettier-ignore if (liNode?.type === schema.nodes.list_item && !liNode.textContent && - olNode?.type === schema.nodes.ordered_list && once && view.state.selection.$from.depth === 3) + olNode?.type === schema.nodes.ordered_list && once && view?.state.selection.$from.depth === 3) { // handles case of hitting enter at then end of a top-level empty list item - the result is to create a paragraph - for (let i = 0; i < 10 && view.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++); + for (let i = 0; i < 10 && view?.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++); } else if ( - !splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => { + !splitListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); // removes an extra paragraph created when selecting text across two list items or splitting an empty list item - !once && view.dispatch(view.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2)); + !once && view?.dispatch(view?.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2)); }) ) { - if (once && view.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') { + if (once && view?.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view?.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') { // handles case of hitting enter on an empty list item which needs to create a second empty paragraph, then split it by calling enter() again view.dispatch(view.state.tr.insert(view.state.selection.from, schema.nodes.paragraph.create({}))); enter(view.state, view.dispatch, view, false); @@ -346,12 +365,12 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa const tonode = tx3.selection.$to.node(); if (tx3.selection.to && tx3.doc.nodeAt(tx3.selection.to - 1)) { const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks).setStoredMarks(marks || []); - dispatch(tx4); + dispatch?.(tx4); } - if (view.state.selection.$anchor.depth > 0 && - view.state.selection.$anchor.node(view.state.selection.$anchor.depth-1).type === schema.nodes.list_item && - view.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) { + if ((view?.state.selection.$anchor.depth ??0) > 0 && + view?.state.selection.$anchor.node(view.state.selection.$anchor.depth-1).type === schema.nodes.list_item && + view?.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) { // if text is selected across list items, then we need to forcibly insert a new line since the splitBlock code joins the two list items. enter(view.state, dispatch, view, false); } @@ -368,14 +387,14 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any): KeyMa // Command to create a blank space bind('Space', () => { - const editDoc = props.TemplateDataDocument ?? props.Document[DocData]; + const editDoc = tbox?._props.TemplateDataDocument ?? tbox?.Document[DocData]; if (editDoc && ![AclAdmin, AclAugment, AclEdit].includes(GetEffectiveAcl(editDoc))) return true; return false; }); - bind('Alt-ArrowUp', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && joinUp(state, dispatch as any)); - bind('Alt-ArrowDown', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && joinDown(state, dispatch as any)); - bind('Mod-BracketLeft', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && lift(state, dispatch as any)); + bind('Alt-ArrowUp', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && joinUp(state, dispatch)); + bind('Alt-ArrowDown', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && joinDown(state, dispatch)); + bind('Mod-BracketLeft', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && lift(state, dispatch)); const cmd = chainCommands(exitCode, (state, dispatch) => { if (dispatch) { |