UNPKG

@paperbits/prosemirror

Version:
136 lines (114 loc) 4.62 kB
import { wrapIn, setBlockType, chainCommands, toggleMark, exitCode, joinUp, joinDown, lift, selectParentNode } from "prosemirror-commands"; import { wrapInList, splitListItem, liftListItem, sinkListItem } from "prosemirror-schema-list"; import { undo, redo } from "prosemirror-history"; import { undoInputRule } from "prosemirror-inputrules"; const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; // :: (Schema, ?Object) → Object // inspect the given schema looking for marks and nodes from the // basic schema, and if found, add key bindings related to them. // this will add: // // * **Mod-b** for toggling [strong](#schema-basic.StrongMark) // * **Mod-i** for toggling [emphasis](#schema-basic.EmMark) // * **Mod-`** for toggling [code font](#schema-basic.CodeMark) // * **Ctrl-Shift-0** for making the current textblock a paragraph // * **Ctrl-Shift-1** to **Ctrl-Shift-Digit6** for making the current // textblock a heading of the corresponding level // * **Ctrl-Shift-Backslash** to make the current textblock a code block // * **Ctrl-Shift-8** to wrap the selection in an ordered list // * **Ctrl-Shift-9** to wrap the selection in a bullet list // * **Ctrl->** to wrap the selection in a block quote // * **Enter** to split a non-empty textblock in a list item while at // the same time splitting the list item // * **Mod-Enter** to insert a hard break // * **Mod-_** to insert a horizontal rule // * **Backspace** to undo an input rule // * **Alt-ArrowUp** to `joinUp` // * **Alt-ArrowDown** to `joinDown` // * **Mod-BracketLeft** to `lift` // * **Escape** to `selectParentNode` // // you can suppress or map these bindings by passing a `mapKeys` // argument, which maps key names (say `"Mod-B"` to either `false`, to // remove the binding, or a new key name string. export function buildKeymap(schema, mapKeys) { let keys = {}, type; function bind(key, cmd) { if (mapKeys) { const mapped = mapKeys[key]; if (mapped === false) { return; } if (mapped) { key = mapped; } } keys[key] = cmd; } bind("Mod-z", undo); bind("Shift-Mod-z", redo); bind("Backspace", undoInputRule); if (!mac) { bind("Mod-y", redo); } bind("Alt-ArrowUp", joinUp); bind("Alt-ArrowDown", joinDown); bind("Mod-BracketLeft", lift); bind("Escape", selectParentNode); if (type = schema.marks.bold) { bind("Mod-b", toggleMark(type)); } if (type = schema.marks.italic) { bind("Mod-i", toggleMark(type)); } if (type = schema.marks.code) { bind("Mod-`", toggleMark(type)); } if (type = schema.nodes.bullet_list) { bind("Shift-Ctrl-8", wrapInList(type)); } if (type = schema.nodes.ordered_list) { bind("Shift-Ctrl-9", wrapInList(type)); } if (type = schema.nodes.blockquote) { bind("Ctrl->", wrapIn(type)); } if (type = schema.nodes.break) { const br = type, cmd = chainCommands(exitCode, (state, dispatch) => { const $anchor = state.selection.$anchor; if (!$anchor) { return; } if ($anchor.nodeBefore && $anchor.nodeBefore.type.name === "break") { dispatch(state.tr.delete($anchor.pos - 1, $anchor.pos) .replaceSelectionWith(schema.nodes.paragraph.create()).scrollIntoView()); } else { dispatch(state.tr.replaceSelectionWith(br.create()).scrollIntoView()); } return true; }); bind("Mod-Enter", cmd); bind("Shift-Enter", cmd); bind("Ctrl-Enter", cmd); } if (type = schema.nodes.list_item) { bind("Enter", splitListItem(type)); bind("Mod-[", liftListItem(type)); bind("Mod-]", sinkListItem(type)); } if (type = schema.nodes.paragraph) { bind("Shift-Ctrl-0", setBlockType(type)); } if (type = schema.nodes.code_block) { bind("Shift-Ctrl-\\", setBlockType(type)); } if (type = schema.nodes.heading) { for (let i = 1; i <= 6; i++) { bind("Shift-Ctrl-" + i, setBlockType(type, { level: i })); } } if (type = schema.nodes.horizontal_rule) { const hr = type; bind("Mod-_", (state, dispatch) => { dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); return true; }); } return keys; }