2016-11-11 18:36:11 -02:00

93 lines
3.4 KiB
JavaScript

const { wrapIn, setBlockType, chainCommands, newlineInCode, toggleMark } = require('prosemirror-commands');
const { selectNextCell, selectPreviousCell } = require('prosemirror-schema-table');
const { wrapInList, splitListItem, liftListItem, sinkListItem } = require('prosemirror-schema-list');
const { undo, redo } = require('prosemirror-history');
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
//
// 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.
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('Mod-y', redo);
if (type = schema.marks.strong)
bind('Mod-b', toggleMark(type));
if (type = schema.marks.em)
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.hard_break) {
let br = type, cmd = chainCommands(newlineInCode, (state, onAction) => {
onAction(state.tr.replaceSelection(br.create()).scrollAction());
return true;
});
bind('Mod-Enter', cmd);
bind('Shift-Enter', cmd);
if (mac) 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, onAction) => {
onAction(state.tr.replaceSelection(hr.create()).scrollAction());
return true;
});
}
if (schema.nodes.table_row) {
bind('Tab', selectNextCell);
bind('Shift-Tab', selectPreviousCell);
}
return keys;
}
exports.buildKeymap = buildKeymap;