diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts')
-rw-r--r-- | src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index a75efd77b..eabc6455f 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -1,12 +1,12 @@ import { chainCommands, deleteSelection, exitCode, joinBackward, joinDown, joinUp, lift, newlineInCode, selectNodeBackward, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn } from 'prosemirror-commands'; import { redo, undo } from 'prosemirror-history'; -import { MarkType, Node, ResolvedPos, Schema } from 'prosemirror-model'; +import { MarkType, Node, Schema } from 'prosemirror-model'; import { liftListItem, sinkListItem, splitListItem, wrapInList } from 'prosemirror-schema-list'; 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'; @@ -19,12 +19,12 @@ const mac = typeof navigator !== 'undefined' ? /Mac/.test(navigator.platform) : 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: 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 unknown as { path: (number | Node)[] }; // bcz: can't access path .. need to FIX - let depth = Array.from(path).reduce((p: number, c: number | Node) => p + ((c as Node).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++; @@ -33,7 +33,7 @@ export const updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle } }); return tx2; -}; +} export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: FormattedTextBox): KeyMap { const keys: { [key: string]: Command } = {}; @@ -43,8 +43,9 @@ export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: Formatte } 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 - return tbox?._props.onKey?.(event, tbox); + // 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 event && tbox?._props.onKey?.(event as unknown as KeyboardEvent, tbox); } const canEdit = (state: EditorState) => { @@ -53,8 +54,9 @@ export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: Formatte switch (permissions) { case AclAugment: { - const prevNode = (state.selection as any).$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; } @@ -208,12 +210,14 @@ export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: Formatte return true; }); bind('Cmd-]', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { - const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible - const { tr } = state; - if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); + 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 || [])]); @@ -223,12 +227,14 @@ export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: Formatte return true; }); bind('Cmd-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { - const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible - const { tr } = state; - if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); + 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 || [])]); @@ -238,12 +244,14 @@ export function buildKeymap<S extends Schema<string>>(schema: S, tbox?: Formatte return true; }); bind('Cmd-[', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { - const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible - const { tr } = state; - if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); + 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 || [])]); |