mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 10:15:43 +03:00
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) {
|
||||
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) => {
|
||||
parts.push(partCreator.plain(l));
|
||||
if (i < preLines.length - 1) {
|
||||
|
@ -99,7 +108,10 @@ function parseElement(n, partCreator, lastNode, state) {
|
|||
case "LI": {
|
||||
const indent = " ".repeat(state.listDepth - 1);
|
||||
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 {
|
||||
return partCreator.plain(`${indent}- `);
|
||||
}
|
||||
|
@ -111,23 +123,25 @@ function parseElement(n, partCreator, lastNode, state) {
|
|||
break;
|
||||
}
|
||||
case "OL":
|
||||
state.listIndex.push(n.start || 1);
|
||||
// fallthrough
|
||||
case "UL":
|
||||
state.listDepth = (state.listDepth || 0) + 1;
|
||||
// es-lint-disable-next-line no-fallthrough
|
||||
// fallthrough
|
||||
default:
|
||||
// don't textify block nodes we'll decend into
|
||||
if (!checkDecendInto(n)) {
|
||||
// don't textify block nodes we'll descend into
|
||||
if (!checkDescendInto(n)) {
|
||||
return partCreator.plain(n.textContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkDecendInto(node) {
|
||||
function checkDescendInto(node) {
|
||||
switch (node.nodeName) {
|
||||
case "PRE":
|
||||
// a code block is textified in parseCodeBlock
|
||||
// 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;
|
||||
default:
|
||||
return checkBlockNode(node);
|
||||
|
@ -168,7 +182,9 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) {
|
|||
const parts = [];
|
||||
let lastNode;
|
||||
let inQuote = isQuotedMessage;
|
||||
const state = {};
|
||||
const state = {
|
||||
listIndex: [],
|
||||
};
|
||||
|
||||
function onNodeEnter(n) {
|
||||
if (checkIgnored(n)) {
|
||||
|
@ -203,11 +219,11 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) {
|
|||
|
||||
parts.push(...newParts);
|
||||
|
||||
const decend = checkDecendInto(n);
|
||||
// when not decending (like for PRE), onNodeLeave won't be called to set lastNode
|
||||
const descend = checkDescendInto(n);
|
||||
// when not descending (like for PRE), onNodeLeave won't be called to set lastNode
|
||||
// so do that here.
|
||||
lastNode = decend ? null : n;
|
||||
return decend;
|
||||
lastNode = descend ? null : n;
|
||||
return descend;
|
||||
}
|
||||
|
||||
function onNodeLeave(n) {
|
||||
|
@ -219,6 +235,8 @@ function parseHtmlMessage(html, partCreator, isQuotedMessage) {
|
|||
inQuote = false;
|
||||
break;
|
||||
case "OL":
|
||||
state.listIndex.pop();
|
||||
// fallthrough
|
||||
case "UL":
|
||||
state.listDepth -= 1;
|
||||
break;
|
||||
|
|
|
@ -21,8 +21,8 @@ import DocumentOffset from "./offset";
|
|||
export function walkDOMDepthFirst(rootNode, enterNodeCallback, leaveNodeCallback) {
|
||||
let node = rootNode.firstChild;
|
||||
while (node && node !== rootNode) {
|
||||
const shouldDecend = enterNodeCallback(node);
|
||||
if (shouldDecend && node.firstChild) {
|
||||
const shouldDescend = enterNodeCallback(node);
|
||||
if (shouldDescend && node.firstChild) {
|
||||
node = node.firstChild;
|
||||
} else if (node.nextSibling) {
|
||||
node = node.nextSibling;
|
||||
|
|
Loading…
Reference in a new issue