BookStack/resources/js/editor/menu/index.js

158 lines
5 KiB
JavaScript
Raw Normal View History

import {
2022-01-12 17:10:16 +01:00
MenuItem, Dropdown, DropdownSubmenu, renderGrouped, joinUpItem, liftItem, selectParentNodeItem,
undoItem, redoItem, wrapItem, blockTypeItem, setAttrItem,
} from "./menu"
2022-01-12 17:10:16 +01:00
import {icons} from "./icons";
import ColorPickerGrid from "./ColorPickerGrid";
import {toggleMark} from "prosemirror-commands";
import {menuBar} from "./menubar"
import schema from "../schema";
function cmdItem(cmd, options) {
const passedOptions = {
label: options.title,
run: cmd
};
for (const prop in options) {
passedOptions[prop] = options[prop];
}
if ((!options.enable || options.enable === true) && !options.select) {
passedOptions[options.enable ? "enable" : "select"] = function (state) {
return cmd(state);
};
}
return new MenuItem(passedOptions)
}
function markActive(state, type) {
const ref = state.selection;
const from = ref.from;
const $from = ref.$from;
const to = ref.to;
const empty = ref.empty;
if (empty) {
return type.isInSet(state.storedMarks || $from.marks())
} else {
return state.doc.rangeHasMark(from, to, type)
}
}
function markItem(markType, options) {
const passedOptions = {
active: function active(state) {
return markActive(state, markType)
},
enable: true
};
for (const prop in options) {
passedOptions[prop] = options[prop];
}
2022-01-12 12:02:28 +01:00
return cmdItem(toggleMark(markType, passedOptions.attrs), passedOptions)
}
const inlineStyles = [
markItem(schema.marks.strong, {title: "Bold", icon: icons.strong}),
markItem(schema.marks.em, {title: "Italic", icon: icons.em}),
2022-01-12 17:10:16 +01:00
markItem(schema.marks.underline, {title: "Underline", icon: icons.underline}),
markItem(schema.marks.strike, {title: "Strikethrough", icon: icons.strike}),
markItem(schema.marks.superscript, {title: "Superscript", icon: icons.superscript}),
markItem(schema.marks.subscript, {title: "Subscript", icon: icons.subscript}),
];
const formats = [
blockTypeItem(schema.nodes.heading, {
label: "Header Large",
attrs: {level: 2}
}),
blockTypeItem(schema.nodes.heading, {
label: "Header Medium",
attrs: {level: 3}
}),
blockTypeItem(schema.nodes.heading, {
label: "Header Small",
attrs: {level: 4}
}),
blockTypeItem(schema.nodes.heading, {
label: "Header Tiny",
attrs: {level: 5}
}),
blockTypeItem(schema.nodes.paragraph, {
label: "Paragraph",
attrs: {}
}),
new DropdownSubmenu([
blockTypeItem(schema.nodes.callout, {
label: "Info Callout",
attrs: {type: 'info'}
}),
blockTypeItem(schema.nodes.callout, {
label: "Danger Callout",
attrs: {type: 'danger'}
}),
blockTypeItem(schema.nodes.callout, {
label: "Success Callout",
attrs: {type: 'success'}
}),
blockTypeItem(schema.nodes.callout, {
label: "Warning Callout",
attrs: {type: 'warning'}
})
], { label: 'Callouts' }),
];
const alignments = [
setAttrItem('align', 'left', {
2022-01-12 17:10:16 +01:00
icon: icons.align_left
}),
setAttrItem('align', 'right', {
2022-01-12 17:10:16 +01:00
icon: icons.align_right
}),
setAttrItem('align', 'center', {
2022-01-12 17:10:16 +01:00
icon: icons.align_center
}),
setAttrItem('align', 'justify', {
2022-01-12 17:10:16 +01:00
icon: icons.align_justify
}),
];
const colorOptions = ["#000000","#993300","#333300","#003300","#003366","#000080","#333399","#333333","#800000","#FF6600","#808000","#008000","#008080","#0000FF","#666699","#808080","#FF0000","#FF9900","#99CC00","#339966","#33CCCC","#3366FF","#800080","#999999","#FF00FF","#FFCC00","#FFFF00","#00FF00","#00FFFF","#00CCFF","#993366","#FFFFFF","#FF99CC","#FFCC99","#FFFF99","#CCFFCC","#CCFFFF","#99CCFF","#CC99FF"];
2022-01-12 12:02:28 +01:00
const colors = [
new DropdownSubmenu([
new ColorPickerGrid(schema.marks.text_color, 'color', colorOptions),
2022-01-12 17:10:16 +01:00
], {icon: icons.text_color}),
new DropdownSubmenu([
new ColorPickerGrid(schema.marks.background_color, 'color', colorOptions),
2022-01-12 17:10:16 +01:00
], {icon: icons.background_color}),
2022-01-12 12:02:28 +01:00
];
const menu = menuBar({
floating: false,
content: [
[undoItem, redoItem],
[new DropdownSubmenu(formats, { label: 'Formats' })],
inlineStyles,
colors,
alignments,
],
});
export default menu;
// !! This module defines a number of building blocks for ProseMirror
// menus, along with a [menu bar](#menu.menuBar) implementation.
// MenuElement:: interface
// The types defined in this module aren't the only thing you can
// display in your menu. Anything that conforms to this interface can
// be put into a menu structure.
//
// render:: (pm: EditorView) → {dom: dom.Node, update: (EditorState) → bool}
// Render the element for display in the menu. Must return a DOM
// element and a function that can be used to update the element to
// a new state. The `update` function will return false if the
// update hid the entire element.