1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-06-27 16:41:53 +03:00

Got alignment buttons barely working for paragraphs

This commit is contained in:
Dan Brown
2022-01-11 18:58:24 +00:00
parent 4e5153d372
commit 6744ab2ff9
5 changed files with 120 additions and 6 deletions

View File

@ -0,0 +1,38 @@
export function setBlockAttr(attrName, attrValue) {
return function (state, dispatch) {
const ref = state.selection;
const from = ref.from;
const to = ref.to;
let applicable = false;
state.doc.nodesBetween(from, to, function (node, pos) {
if (applicable) {
return false
}
if (!node.isTextblock || node.attrs[attrName] === attrValue) {
return
}
applicable = node.attrs[attrName] !== undefined;
});
if (!applicable) {
return false
}
if (dispatch) {
const tr = state.tr;
tr.doc.nodesBetween(from, to, function (node, pos) {
const nodeAttrs = Object.assign({}, node.attrs);
if (node.attrs[attrName] !== undefined) {
nodeAttrs[attrName] = attrValue;
tr.setBlockType(pos, pos+1, node.type, nodeAttrs)
}
});
dispatch(tr);
}
return true
}
}

View File

@ -1,6 +1,6 @@
import { import {
MenuItem, Dropdown, DropdownSubmenu, renderGrouped, icons, joinUpItem, liftItem, selectParentNodeItem, MenuItem, Dropdown, DropdownSubmenu, renderGrouped, icons, joinUpItem, liftItem, selectParentNodeItem,
undoItem, redoItem, wrapItem, blockTypeItem undoItem, redoItem, wrapItem, blockTypeItem, setAttrItem,
} from "./menu" } from "./menu"
import {toggleMark} from "prosemirror-commands"; import {toggleMark} from "prosemirror-commands";
@ -102,12 +102,28 @@ const formats = [
], { label: 'Callouts' }), ], { label: 'Callouts' }),
]; ];
const alignments = [
setAttrItem('align', 'left', {
label: 'Align Left'
}),
setAttrItem('align', 'right', {
label: 'Align Right'
}),
setAttrItem('align', 'center', {
label: 'Align Center'
}),
setAttrItem('align', 'justify', {
label: 'Align Justify'
}),
];
const menu = menuBar({ const menu = menuBar({
floating: false, floating: false,
content: [ content: [
[undoItem, redoItem], [undoItem, redoItem],
[new DropdownSubmenu(formats, { label: 'Formats' })], [new DropdownSubmenu(formats, { label: 'Formats' })],
inlineStyles, inlineStyles,
alignments,
], ],
}); });

View File

@ -8,6 +8,7 @@
import crel from "crelt" import crel from "crelt"
import {lift, joinUp, selectParentNode, wrapIn, setBlockType} from "prosemirror-commands" import {lift, joinUp, selectParentNode, wrapIn, setBlockType} from "prosemirror-commands"
import {undo, redo} from "prosemirror-history" import {undo, redo} from "prosemirror-history"
import {setBlockAttr} from "../commands";
import {getIcon} from "./icons" import {getIcon} from "./icons"
@ -457,6 +458,21 @@ export function blockTypeItem(nodeType, options) {
return new MenuItem(passedOptions) return new MenuItem(passedOptions)
} }
export function setAttrItem(attrName, attrValue, options) {
const command = setBlockAttr(attrName, attrValue);
const passedOptions = {
run: command,
enable(state) { return command(state) },
active(state) {
const {$from, to, node} = state.selection
if (node) return node.attrs[attrValue] === attrValue;
return to <= $from.end() && $from.parent.attrs[attrValue] === attrValue;
}
}
for (const prop in options) passedOptions[prop] = options[prop]
return new MenuItem(passedOptions)
}
// Work around classList.toggle being broken in IE11 // Work around classList.toggle being broken in IE11
function setClass(dom, cls, on) { function setClass(dom, cls, on) {
if (on) dom.classList.add(cls) if (on) dom.classList.add(cls)

View File

@ -1,5 +1,21 @@
import {orderedList, bulletList, listItem} from "prosemirror-schema-list"; import {orderedList, bulletList, listItem} from "prosemirror-schema-list";
const alignAttrFromDomNode = node => {
if (node.classList.contains('align-right')) {
return 'right';
}
if (node.classList.contains('align-left')) {
return 'left';
}
if (node.classList.contains('align-center')) {
return 'center';
}
if (node.classList.contains('align-justify')) {
return 'justify';
}
return null;
};
const doc = { const doc = {
content: "block+", content: "block+",
}; };
@ -7,9 +23,30 @@ const doc = {
const paragraph = { const paragraph = {
content: "inline*", content: "inline*",
group: "block", group: "block",
parseDOM: [{tag: "p"}], parseDOM: [
toDOM() { {
return ["p", 0]; tag: "p",
getAttrs(node) {
return {
align: alignAttrFromDomNode(node),
};
}
}
],
attrs: {
align: {
default: null,
}
},
toDOM(node) {
const attrs = {};
if (node.attrs.align === 'right') {
attrs['class'] = 'align-right';
}
if (node.attrs.align === 'left') {
attrs['class'] = 'align-left';
}
return ["p", attrs, 0];
} }
}; };
@ -18,6 +55,9 @@ const blockquote = {
group: "block", group: "block",
defining: true, defining: true,
parseDOM: [{tag: "blockquote"}], parseDOM: [{tag: "blockquote"}],
align: {
default: null,
},
toDOM() { toDOM() {
return ["blockquote", 0]; return ["blockquote", 0];
} }
@ -32,7 +72,7 @@ const horizontal_rule = {
}; };
const heading = { const heading = {
attrs: {level: {default: 1}}, attrs: {level: {default: 1}, align: {default: null}},
content: "inline*", content: "inline*",
group: "block", group: "block",
defining: true, defining: true,
@ -103,6 +143,7 @@ const hard_break = {
const callout = { const callout = {
attrs: { attrs: {
type: {default: 'info'}, type: {default: 'info'},
align: {default: null},
}, },
content: "inline*", content: "inline*",
group: "block", group: "block",

View File

@ -7,7 +7,7 @@
<input id="markdown-toggle" type="checkbox"> <input id="markdown-toggle" type="checkbox">
</div> </div>
<div id="editor" class="bs-editor" style="margin-bottom: 23px"></div> <div id="editor" class="bs-editor page-content" style="margin-bottom: 23px"></div>
<div id="content" style="display: none;"> <div id="content" style="display: none;">
<h2>This is an editable block</h2> <h2>This is an editable block</h2>
@ -22,7 +22,10 @@
<li>Item B</li> <li>Item B</li>
<li>Item C</li> <li>Item C</li>
</ul> </ul>
<p>Lorem ipsum dolor sit amet.</p> <p>Lorem ipsum dolor sit amet.</p>
<p class="align-right">Lorem ipsum dolor sit amet.</p>
<p class="callout info"> <p class="callout info">
This is an info callout test! This is an info callout test!
</p> </p>