mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-06-26 05:41:03 +03:00
Got alignment buttons barely working for paragraphs
This commit is contained in:
38
resources/js/editor/commands.js
Normal file
38
resources/js/editor/commands.js
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -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,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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",
|
||||||
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user