mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-28 17:02:04 +03:00
Rolled out text alignment to other block types
Completed off alignment types and markdown handling in the process.
This commit is contained in:
@ -4,10 +4,12 @@ import {docToHtml} from "./util";
|
|||||||
const nodes = defaultMarkdownSerializer.nodes;
|
const nodes = defaultMarkdownSerializer.nodes;
|
||||||
const marks = defaultMarkdownSerializer.marks;
|
const marks = defaultMarkdownSerializer.marks;
|
||||||
|
|
||||||
|
|
||||||
nodes.callout = function(state, node) {
|
nodes.callout = function(state, node) {
|
||||||
writeNodeAsHtml(state, node);
|
writeNodeAsHtml(state, node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
marks.underline = {
|
marks.underline = {
|
||||||
open: '<span style="text-decoration: underline;">',
|
open: '<span style="text-decoration: underline;">',
|
||||||
close: '</span>',
|
close: '</span>',
|
||||||
@ -28,12 +30,28 @@ marks.subscript = {
|
|||||||
close: '</sub>',
|
close: '</sub>',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function writeNodeAsHtml(state, node) {
|
function writeNodeAsHtml(state, node) {
|
||||||
const html = docToHtml({ content: [node] });
|
const html = docToHtml({ content: [node] });
|
||||||
state.write(html);
|
state.write(html);
|
||||||
|
state.ensureNewLine();
|
||||||
|
state.write('\n');
|
||||||
state.closeBlock();
|
state.closeBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update serializers to just write out as HTML if we have an attribute
|
||||||
|
// or element that cannot be represented in commonmark without losing
|
||||||
|
// formatting or content.
|
||||||
|
for (const [nodeType, serializerFunction] of Object.entries(nodes)) {
|
||||||
|
nodes[nodeType] = function(state, node) {
|
||||||
|
if (node.attrs.align) {
|
||||||
|
writeNodeAsHtml(state, node);
|
||||||
|
} else {
|
||||||
|
serializerFunction(state, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const serializer = new MarkdownSerializer(nodes, marks);
|
const serializer = new MarkdownSerializer(nodes, marks);
|
||||||
|
|
||||||
|
@ -1,20 +1,52 @@
|
|||||||
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')) {
|
* @param {HTMLElement} node
|
||||||
return 'right';
|
* @return {string|null}
|
||||||
}
|
*/
|
||||||
if (node.classList.contains('align-left')) {
|
function getAlignAttrFromDomNode(node) {
|
||||||
return 'left';
|
const classList = node.classList;
|
||||||
}
|
const styles = node.style || {};
|
||||||
if (node.classList.contains('align-center')) {
|
const alignments = ['right', 'left', 'center', 'justify'];
|
||||||
return 'center';
|
for (const alignment of alignments) {
|
||||||
}
|
if (classList.contains('align-' + alignment) || styles.textAlign === alignment) {
|
||||||
if (node.classList.contains('align-justify')) {
|
return alignment;
|
||||||
return 'justify';
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} className
|
||||||
|
* @param {Object} attrs
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
function addClassToAttrs(className, attrs) {
|
||||||
|
return Object.assign({}, attrs, {
|
||||||
|
class: attrs.class ? attrs.class + ' ' + className : className,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param node
|
||||||
|
* @param {Object} attrs
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
function addAlignmentAttr(node, attrs) {
|
||||||
|
const positions = ['right', 'left', 'center', 'justify'];
|
||||||
|
for (const position of positions) {
|
||||||
|
if (node.attrs.align === position) {
|
||||||
|
return addClassToAttrs('align-' + position, attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAttrsParserForAlignment(node) {
|
||||||
|
return {
|
||||||
|
align: getAlignAttrFromDomNode(node),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const doc = {
|
const doc = {
|
||||||
content: "block+",
|
content: "block+",
|
||||||
@ -26,11 +58,7 @@ const paragraph = {
|
|||||||
parseDOM: [
|
parseDOM: [
|
||||||
{
|
{
|
||||||
tag: "p",
|
tag: "p",
|
||||||
getAttrs(node) {
|
getAttrs: getAttrsParserForAlignment,
|
||||||
return {
|
|
||||||
align: alignAttrFromDomNode(node),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
attrs: {
|
attrs: {
|
||||||
@ -39,14 +67,7 @@ const paragraph = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
toDOM(node) {
|
toDOM(node) {
|
||||||
const attrs = {};
|
return ["p", addAlignmentAttr(node, {}), 0];
|
||||||
if (node.attrs.align === 'right') {
|
|
||||||
attrs['class'] = 'align-right';
|
|
||||||
}
|
|
||||||
if (node.attrs.align === 'left') {
|
|
||||||
attrs['class'] = 'align-left';
|
|
||||||
}
|
|
||||||
return ["p", attrs, 0];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,12 +75,14 @@ const blockquote = {
|
|||||||
content: "block+",
|
content: "block+",
|
||||||
group: "block",
|
group: "block",
|
||||||
defining: true,
|
defining: true,
|
||||||
parseDOM: [{tag: "blockquote"}],
|
parseDOM: [{tag: "blockquote", getAttrs: getAttrsParserForAlignment}],
|
||||||
align: {
|
attrs: {
|
||||||
default: null,
|
align: {
|
||||||
|
default: null,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
toDOM() {
|
toDOM(node) {
|
||||||
return ["blockquote", 0];
|
return ["blockquote", addAlignmentAttr(node, {}), 0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,19 +94,27 @@ const horizontal_rule = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const headingParseGetAttrs = (level) => {
|
||||||
|
return function (node) {
|
||||||
|
return {level, align: getAlignAttrFromDomNode(node)};
|
||||||
|
};
|
||||||
|
};
|
||||||
const heading = {
|
const heading = {
|
||||||
attrs: {level: {default: 1}, align: {default: null}},
|
attrs: {level: {default: 1}, align: {default: null}},
|
||||||
content: "inline*",
|
content: "inline*",
|
||||||
group: "block",
|
group: "block",
|
||||||
defining: true,
|
defining: true,
|
||||||
parseDOM: [{tag: "h1", attrs: {level: 1}},
|
parseDOM: [
|
||||||
{tag: "h2", attrs: {level: 2}},
|
{tag: "h1", getAttrs: headingParseGetAttrs(1)},
|
||||||
{tag: "h3", attrs: {level: 3}},
|
{tag: "h2", getAttrs: headingParseGetAttrs(2)},
|
||||||
{tag: "h4", attrs: {level: 4}},
|
{tag: "h3", getAttrs: headingParseGetAttrs(3)},
|
||||||
{tag: "h5", attrs: {level: 5}},
|
{tag: "h4", getAttrs: headingParseGetAttrs(4)},
|
||||||
{tag: "h6", attrs: {level: 6}}],
|
{tag: "h5", getAttrs: headingParseGetAttrs(5)},
|
||||||
|
{tag: "h6", getAttrs: headingParseGetAttrs(6)},
|
||||||
|
],
|
||||||
toDOM(node) {
|
toDOM(node) {
|
||||||
return ["h" + node.attrs.level, 0]
|
return ["h" + node.attrs.level, addAlignmentAttr(node, {}), 0]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -140,6 +171,12 @@ const hard_break = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const calloutParseGetAttrs = (type) => {
|
||||||
|
return function (node) {
|
||||||
|
return {type, align: getAlignAttrFromDomNode(node)};
|
||||||
|
};
|
||||||
|
};
|
||||||
const callout = {
|
const callout = {
|
||||||
attrs: {
|
attrs: {
|
||||||
type: {default: 'info'},
|
type: {default: 'info'},
|
||||||
@ -149,15 +186,15 @@ const callout = {
|
|||||||
group: "block",
|
group: "block",
|
||||||
defining: true,
|
defining: true,
|
||||||
parseDOM: [
|
parseDOM: [
|
||||||
{tag: 'p.callout.info', attrs: {type: 'info'}, priority: 75,},
|
{tag: 'p.callout.info', getAttrs: calloutParseGetAttrs('info'), priority: 75},
|
||||||
{tag: 'p.callout.success', attrs: {type: 'success'}, priority: 75,},
|
{tag: 'p.callout.success', getAttrs: calloutParseGetAttrs('success'), priority: 75},
|
||||||
{tag: 'p.callout.danger', attrs: {type: 'danger'}, priority: 75,},
|
{tag: 'p.callout.danger', getAttrs: calloutParseGetAttrs('danger'), priority: 75},
|
||||||
{tag: 'p.callout.warning', attrs: {type: 'warning'}, priority: 75,},
|
{tag: 'p.callout.warning', getAttrs: calloutParseGetAttrs('warning'), priority: 75},
|
||||||
{tag: 'p.callout', attrs: {type: 'info'}, priority: 75},
|
{tag: 'p.callout', getAttrs: calloutParseGetAttrs('info'), priority: 75},
|
||||||
],
|
],
|
||||||
toDOM(node) {
|
toDOM(node) {
|
||||||
const type = node.attrs.type || 'info';
|
const type = node.attrs.type || 'info';
|
||||||
return ['p', {class: 'callout ' + type}, 0];
|
return ['p', addAlignmentAttr(node, {class: 'callout ' + type}) , 0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,6 +105,9 @@ body.mce-fullscreen, body.markdown-fullscreen {
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
.align-justify {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height:auto;
|
height:auto;
|
||||||
|
Reference in New Issue
Block a user