Merge pull request #3552 from maunium/fix-html-parsing-for-edit
Fix some things in the edit HTML parser
This commit is contained in:
commit
b237ecab29
2 changed files with 32 additions and 14 deletions
|
@ -58,7 +58,16 @@ function parseLink(a, partCreator) {
|
||||||
|
|
||||||
function parseCodeBlock(n, partCreator) {
|
function parseCodeBlock(n, partCreator) {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
const preLines = ("```\n" + n.textContent + "```").split("\n");
|
let language = "";
|
||||||
|
if (n.firstChild && n.firstChild.nodeName === "CODE") {
|
||||||
|
for (const className of n.firstChild.classList) {
|
||||||
|
if (className.startsWith("language-")) {
|
||||||
|
language = className.substr("language-".length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const preLines = ("```" + language + "\n" + n.textContent + "```").split("\n");
|
||||||
preLines.forEach((l, i) => {
|
preLines.forEach((l, i) => {
|
||||||
parts.push(partCreator.plain(l));
|
parts.push(partCreator.plain(l));
|
||||||
if (i < preLines.length - 1) {
|
if (i < preLines.length - 1) {
|
||||||
|
@ -99,7 +108,10 @@ function parseElement(n, partCreator, lastNode, state) {
|
||||||
case "LI": {
|
case "LI": {
|
||||||
const indent = " ".repeat(state.listDepth - 1);
|
const indent = " ".repeat(state.listDepth - 1);
|
||||||
if (n.parentElement.nodeName === "OL") {
|
if (n.parentElement.nodeName === "OL") {
|
||||||
return partCreator.plain(`${indent}1. `);
|
// The markdown parser doesn't do nested indexed lists at all, but this supports it anyway.
|
||||||
|
let index = state.listIndex[state.listIndex.length - 1];
|
||||||
|
state.listIndex[state.listIndex.length - 1] += 1;
|
||||||
|
return partCreator.plain(`${indent}${index}. `);
|
||||||
} else {
|
} else {
|
||||||
return partCreator.plain(`${indent}- `);
|
return partCreator.plain(`${indent}- `);
|
||||||
}
|
}
|
||||||
|
@ -111,23 +123,25 @@ function parseElement(n, partCreator, lastNode, state) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "OL":
|
case "OL":
|
||||||
|
state.listIndex.push(n.start || 1);
|
||||||
|
// fallthrough
|
||||||
case "UL":
|
case "UL":
|
||||||
state.listDepth = (state.listDepth || 0) + 1;
|
state.listDepth = (state.listDepth || 0) + 1;
|
||||||
// es-lint-disable-next-line no-fallthrough
|
// fallthrough
|
||||||
default:
|
default:
|
||||||
// don't textify block nodes we'll decend into
|
// don't textify block nodes we'll descend into
|
||||||
if (!checkDecendInto(n)) {
|
if (!checkDescendInto(n)) {
|
||||||
return partCreator.plain(n.textContent);
|
return partCreator.plain(n.textContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDecendInto(node) {
|
function checkDescendInto(node) {
|
||||||
switch (node.nodeName) {
|
switch (node.nodeName) {
|
||||||
case "PRE":
|
case "PRE":
|
||||||
// a code block is textified in parseCodeBlock
|
// a code block is textified in parseCodeBlock
|
||||||
// as we don't want to preserve markup in it,
|
// as we don't want to preserve markup in it,
|
||||||
// so no need to decend into it
|
// so no need to descend into it
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return checkBlockNode(node);
|
return checkBlockNode(node);
|
||||||
|
@ -168,7 +182,9 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
let lastNode;
|
let lastNode;
|
||||||
let inQuote = isQuotedMessage;
|
let inQuote = isQuotedMessage;
|
||||||
const state = {};
|
const state = {
|
||||||
|
listIndex: [],
|
||||||
|
};
|
||||||
|
|
||||||
function onNodeEnter(n) {
|
function onNodeEnter(n) {
|
||||||
if (checkIgnored(n)) {
|
if (checkIgnored(n)) {
|
||||||
|
@ -203,11 +219,11 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) {
|
||||||
|
|
||||||
parts.push(...newParts);
|
parts.push(...newParts);
|
||||||
|
|
||||||
const decend = checkDecendInto(n);
|
const descend = checkDescendInto(n);
|
||||||
// when not decending (like for PRE), onNodeLeave won't be called to set lastNode
|
// when not descending (like for PRE), onNodeLeave won't be called to set lastNode
|
||||||
// so do that here.
|
// so do that here.
|
||||||
lastNode = decend ? null : n;
|
lastNode = descend ? null : n;
|
||||||
return decend;
|
return descend;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNodeLeave(n) {
|
function onNodeLeave(n) {
|
||||||
|
@ -219,6 +235,8 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) {
|
||||||
inQuote = false;
|
inQuote = false;
|
||||||
break;
|
break;
|
||||||
case "OL":
|
case "OL":
|
||||||
|
state.listIndex.pop();
|
||||||
|
// fallthrough
|
||||||
case "UL":
|
case "UL":
|
||||||
state.listDepth -= 1;
|
state.listDepth -= 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -21,8 +21,8 @@ import DocumentOffset from "./offset";
|
||||||
export function walkDOMDepthFirst(rootNode, enterNodeCallback, leaveNodeCallback) {
|
export function walkDOMDepthFirst(rootNode, enterNodeCallback, leaveNodeCallback) {
|
||||||
let node = rootNode.firstChild;
|
let node = rootNode.firstChild;
|
||||||
while (node && node !== rootNode) {
|
while (node && node !== rootNode) {
|
||||||
const shouldDecend = enterNodeCallback(node);
|
const shouldDescend = enterNodeCallback(node);
|
||||||
if (shouldDecend && node.firstChild) {
|
if (shouldDescend && node.firstChild) {
|
||||||
node = node.firstChild;
|
node = node.firstChild;
|
||||||
} else if (node.nextSibling) {
|
} else if (node.nextSibling) {
|
||||||
node = node.nextSibling;
|
node = node.nextSibling;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue