aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts')
-rw-r--r--src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts213
1 files changed, 114 insertions, 99 deletions
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index c66cb502e..31552cf1b 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -1,17 +1,17 @@
-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 { splitListItem, wrapInList } from "prosemirror-schema-list";
-import { EditorState, TextSelection, Transaction } from "prosemirror-state";
-import { liftTarget } from "prosemirror-transform";
-import { AclAugment, AclSelfEdit, Doc } from "../../../../fields/Doc";
-import { GetEffectiveAcl } from "../../../../fields/util";
-import { Utils } from "../../../../Utils";
-import { Docs } from "../../../documents/Documents";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { liftListItem, sinkListItem } from "./prosemirrorPatches.js";
-
-const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
+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 { splitListItem, wrapInList } from 'prosemirror-schema-list';
+import { EditorState, TextSelection, Transaction } from 'prosemirror-state';
+import { liftTarget } from 'prosemirror-transform';
+import { AclAugment, AclSelfEdit, Doc } from '../../../../fields/Doc';
+import { GetEffectiveAcl } from '../../../../fields/util';
+import { Utils } from '../../../../Utils';
+import { Docs } from '../../../documents/Documents';
+import { SelectionManager } from '../../../util/SelectionManager';
+import { liftListItem, sinkListItem } from './prosemirrorPatches.js';
+
+const mac = typeof navigator !== 'undefined' ? /Mac/.test(navigator.platform) : false;
export type KeyMap = { [key: string]: any };
@@ -20,12 +20,12 @@ export let updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle?:
tx2.doc.descendants((node: any, offset: any, 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).path;
- let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && c.type === schema.nodes.ordered_list ? 1 : 0), 0);
+ let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty('type') && c.type === schema.nodes.ordered_list ? 1 : 0), 0);
if (node.type === schema.nodes.ordered_list) {
if (depth === 0 && !assignedMapStyle) mapStyle = node.attrs.mapStyle;
depth++;
}
- tx2.setNodeMarkup(offset, node.type, { ...node.attrs, mapStyle, bulletStyle: depth, }, node.marks);
+ tx2.setNodeMarkup(offset, node.type, { ...node.attrs, mapStyle, bulletStyle: depth }, node.marks);
}
});
return tx2;
@@ -45,7 +45,8 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
const canEdit = (state: any) => {
switch (GetEffectiveAcl(props.DataDoc)) {
- case AclAugment: return false;
+ case AclAugment:
+ return false;
case AclSelfEdit:
for (var i = state.selection.from; i < state.selection.to; i++) {
const marks = state.doc.resolve(i)?.marks?.();
@@ -58,95 +59,102 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
return true;
};
- const toggleEditableMark = (mark: any) => (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && toggleMark(mark)(state, dispatch);
+ const toggleEditableMark = (mark: any) => (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && toggleMark(mark)(state, dispatch);
//History commands
- bind("Mod-z", undo);
- bind("Shift-Mod-z", redo);
- !mac && bind("Mod-y", redo);
+ bind('Mod-z', undo);
+ bind('Shift-Mod-z', redo);
+ !mac && bind('Mod-y', redo);
//Commands to modify Mark
- bind("Mod-b", toggleEditableMark(schema.marks.strong));
- bind("Mod-B", toggleEditableMark(schema.marks.strong));
+ bind('Mod-b', toggleEditableMark(schema.marks.strong));
+ bind('Mod-B', toggleEditableMark(schema.marks.strong));
- bind("Mod-e", toggleEditableMark(schema.marks.em));
- bind("Mod-E", toggleEditableMark(schema.marks.em));
+ bind('Mod-e', toggleEditableMark(schema.marks.em));
+ bind('Mod-E', toggleEditableMark(schema.marks.em));
- bind("Mod-*", toggleEditableMark(schema.marks.code));
+ bind('Mod-*', toggleEditableMark(schema.marks.code));
- bind("Mod-u", toggleEditableMark(schema.marks.underline));
- bind("Mod-U", toggleEditableMark(schema.marks.underline));
+ bind('Mod-u', toggleEditableMark(schema.marks.underline));
+ bind('Mod-U', toggleEditableMark(schema.marks.underline));
//Commands for lists
- bind("Ctrl-i", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any));
+ bind('Ctrl-i', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any));
- bind("Ctrl-Tab", () => props.onKey?.(event, props) ? true : true);
- bind("Alt-Tab", () => props.onKey?.(event, props) ? true : true);
- bind("Meta-Tab", () => props.onKey?.(event, props) ? true : true);
- bind("Meta-Enter", () => props.onKey?.(event, props) ? true : true);
- bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
+ bind('Ctrl-Tab', () => (props.onKey?.(event, props) ? true : true));
+ bind('Alt-Tab', () => (props.onKey?.(event, props) ? true : true));
+ bind('Meta-Tab', () => (props.onKey?.(event, props) ? true : true));
+ bind('Meta-Enter', () => (props.onKey?.(event, props) ? true : true));
+ bind('Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => {
if (props.onKey?.(event, props)) return true;
if (!canEdit(state)) return true;
const ref = state.selection;
const range = ref.$from.blockRange(ref.$to);
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
- const tx3 = updateBullets(tx2, schema);
- marks && tx3.ensureMarks([...marks]);
- marks && tx3.setStoredMarks([...marks]);
- 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) => {
+ if (
+ !sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
const tx3 = updateBullets(tx2, schema);
- // when promoting to a list, assume list will format things so don't copy the stored marks.
marks && tx3.ensureMarks([...marks]);
marks && tx3.setStoredMarks([...marks]);
dispatch(tx3);
- })) {
- console.log("bullet promote fail");
+ })
+ ) {
+ // 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) => {
+ const tx3 = updateBullets(tx2, schema);
+ // when promoting to a list, assume list will format things so don't copy the stored marks.
+ marks && tx3.ensureMarks([...marks]);
+ marks && tx3.setStoredMarks([...marks]);
+ dispatch(tx3);
+ })
+ ) {
+ console.log('bullet promote fail');
}
}
});
- bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
+ bind('Shift-Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => {
if (props.onKey?.(event, props)) return true;
if (!canEdit(state)) return true;
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- if (!liftListItem(schema.nodes.list_item)(state.tr, (tx2: Transaction) => {
- const tx3 = updateBullets(tx2, schema);
- marks && tx3.ensureMarks([...marks]);
- marks && tx3.setStoredMarks([...marks]);
- dispatch(tx3);
- })) {
- console.log("bullet demote fail");
+ if (
+ !liftListItem(schema.nodes.list_item)(state.tr, (tx2: Transaction) => {
+ const tx3 = updateBullets(tx2, schema);
+ marks && tx3.ensureMarks([...marks]);
+ marks && tx3.setStoredMarks([...marks]);
+ dispatch(tx3);
+ })
+ ) {
+ console.log('bullet demote fail');
}
});
//Command to create a new Tab with a PDF of all the command shortcuts
- bind("Mod-/", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
- const newDoc = Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 });
- props.addDocTab(newDoc, "add:right");
+ bind('Mod-/', (state: EditorState, dispatch: (tx: Transaction) => void) => {
+ const newDoc = Docs.Create.PdfDocument(Utils.prepend('/assets/cheat-sheet.pdf'), { _width: 300, _height: 300 });
+ props.addDocTab(newDoc, 'add:right');
});
//Commands to modify BlockType
- bind("Ctrl->", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit((state) && wrapIn(schema.nodes.blockquote)(state as any, dispatch as any)));
- bind("Alt-\\", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state as any, dispatch as any));
- bind("Shift-Ctrl-\\", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && setBlockType(schema.nodes.code_block)(state as any, dispatch as any));
+ 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-m", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: "math" + Utils.GenerateGuid() }))));
+ bind('Ctrl-m', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: 'math' + Utils.GenerateGuid() }))));
for (let i = 1; i <= 6; i++) {
- bind("Shift-Ctrl-" + i, (state: EditorState<S>, dispatch: (tx: Transaction<S>) => 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) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state as any, dispatch as any));
}
//Command to create a horizontal break line
const hr = schema.nodes.horizontal_rule;
- bind("Mod-_", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()));
+ bind('Mod-_', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()));
//Command to unselect all
- bind("Escape", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
+ 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?.();
SelectionManager.DeselectAll();
@@ -158,24 +166,29 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
return tx;
};
-
- bind("Alt-Enter", () => props.onKey?.(event, props) ? true : true);
- bind("Ctrl-Enter", () => props.onKey?.(event, props) ? true : true);
+ bind('Alt-Enter', () => (props.onKey?.(event, props) ? true : true));
+ bind('Ctrl-Enter', () => (props.onKey?.(event, props) ? true : true));
// backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
- bind("Backspace", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
+ bind('Backspace', (state: EditorState, dispatch: (tx: Transaction) => void) => {
if (props.onKey?.(event, props)) return true;
if (!canEdit(state)) return true;
- if (!deleteSelection(state, (tx: Transaction<S>) => {
- dispatch(updateBullets(tx, schema));
- })) {
- if (!joinBackward(state, (tx: Transaction<S>) => {
+ if (
+ !deleteSelection(state, (tx: Transaction) => {
dispatch(updateBullets(tx, schema));
- })) {
- if (!selectNodeBackward(state, (tx: Transaction<S>) => {
+ })
+ ) {
+ if (
+ !joinBackward(state, (tx: Transaction) => {
dispatch(updateBullets(tx, schema));
- })) {
+ })
+ ) {
+ if (
+ !selectNodeBackward(state, (tx: Transaction) => {
+ dispatch(updateBullets(tx, schema));
+ })
+ ) {
return false;
}
}
@@ -185,8 +198,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
//newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock
//command to break line
- bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
-
+ bind('Enter', (state: EditorState, dispatch: (tx: Transaction) => void) => {
if (props.onKey?.(event, props)) return true;
if (!canEdit(state)) return true;
@@ -200,25 +212,29 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
}
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- const cr = state.selection.$from.node().textContent.endsWith("\n");
+ const cr = state.selection.$from.node().textContent.endsWith('\n');
if (cr || !newlineInCode(state, dispatch as any)) {
- if (!splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => {
- const tx3 = updateBullets(tx2, schema);
- marks && tx3.ensureMarks([...marks]);
- marks && tx3.setStoredMarks([...marks]);
- dispatch(tx3);
- })) {
+ if (
+ !splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => {
+ const tx3 = updateBullets(tx2, schema);
+ marks && tx3.ensureMarks([...marks]);
+ marks && tx3.setStoredMarks([...marks]);
+ dispatch(tx3);
+ })
+ ) {
const fromattrs = state.selection.$from.node().attrs;
- if (!splitBlockKeepMarks(state, (tx3: Transaction) => {
- 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);
- splitMetadata(marks, tx4);
- if (!liftListItem(schema.nodes.list_item)(tx4, dispatch as ((tx: Transaction<Schema<any, any>>) => void))) {
- dispatch(tx4);
- }
- } else dispatch(tx3.insertText("\r\n"));
- })) {
+ if (
+ !splitBlockKeepMarks(state, (tx3: Transaction) => {
+ 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);
+ splitMetadata(marks, tx4);
+ if (!liftListItem(schema.nodes.list_item)(tx4, dispatch as (tx: Transaction) => void)) {
+ dispatch(tx4);
+ }
+ } else dispatch(tx3.insertText('\r\n'));
+ })
+ ) {
return false;
}
}
@@ -227,16 +243,16 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
});
//Command to create a blank space
- bind("Space", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
+ bind('Space', (state: EditorState, dispatch: (tx: Transaction) => void) => {
if (!canEdit(state)) return true;
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
dispatch(splitMetadata(marks, state.tr));
return false;
});
- bind("Alt-ArrowUp", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && joinUp(state, dispatch as any));
- bind("Alt-ArrowDown", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && joinDown(state, dispatch as any));
- bind("Mod-BracketLeft", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && lift(state, dispatch as any));
+ 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));
const cmd = chainCommands(exitCode, (state, dispatch) => {
if (dispatch) {
@@ -246,8 +262,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
return false;
});
- bind("Shift-Enter", cmd);
+ bind('Shift-Enter', cmd);
return keys;
}
-