Move pill parsing into deserialize and avoid intermediate objects.

This commit is contained in:
Danila Fedorin 2021-07-16 13:01:33 -07:00
parent eacc033929
commit cdf85edad9
2 changed files with 18 additions and 18 deletions

View file

@ -1,6 +1,5 @@
import { MessageBody, HeaderBlock, TableBlock, ListBlock, CodeBlock, PillPart, FormatPart, NewLinePart, RulePart, TextPart, LinkPart, ImagePart } from "./MessageBody.js" import { MessageBody, HeaderBlock, TableBlock, ListBlock, CodeBlock, PillPart, FormatPart, NewLinePart, RulePart, TextPart, LinkPart, ImagePart } from "./MessageBody.js"
import { linkify } from "./linkify/linkify.js"; import { linkify } from "./linkify/linkify.js";
import { parsePillLink } from "./pills.js"
/* At the time of writing (Jul 1 2021), Matrix Spec recommends /* At the time of writing (Jul 1 2021), Matrix Spec recommends
* allowing the following HTML tags: * allowing the following HTML tags:
@ -15,6 +14,8 @@ import { parsePillLink } from "./pills.js"
const basicInline = ["EM", "STRONG", "CODE", "DEL", "SPAN" ]; const basicInline = ["EM", "STRONG", "CODE", "DEL", "SPAN" ];
const basicBlock = ["DIV", "BLOCKQUOTE"]; const basicBlock = ["DIV", "BLOCKQUOTE"];
const safeSchemas = ["https", "http", "ftp", "mailto", "magnet"].map(name => `${name}://`); const safeSchemas = ["https", "http", "ftp", "mailto", "magnet"].map(name => `${name}://`);
const baseUrl = 'https://matrix.to';
const linkPrefix = `${baseUrl}/#/`;
class Deserializer { class Deserializer {
constructor(result, mediaRepository) { constructor(result, mediaRepository) {
@ -22,6 +23,17 @@ class Deserializer {
this.mediaRepository = mediaRepository; this.mediaRepository = mediaRepository;
} }
parsePillLink(link) {
if (!link.startsWith(linkPrefix)) {
return null;
}
const contents = link.substring(linkPrefix.length);
if (contents[0] === '@') {
return contents;
}
return null;
}
parseLink(node, children) { parseLink(node, children) {
const href = this.result.getAttributeValue(node, "href"); const href = this.result.getAttributeValue(node, "href");
const lcUrl = href?.toLowerCase(); const lcUrl = href?.toLowerCase();
@ -29,9 +41,9 @@ class Deserializer {
if (!lcUrl || !safeSchemas.some(schema => lcUrl.startsWith(schema))) { if (!lcUrl || !safeSchemas.some(schema => lcUrl.startsWith(schema))) {
return new FormatPart("span", children); return new FormatPart("span", children);
} }
const pillData = parsePillLink(href); const pillId = this.parsePillLink(href);
if (pillData && pillData.userId) { if (pillId) {
return new PillPart(pillData.userId, href, children); return new PillPart(pillId, href, children);
} }
return new LinkPart(href, children); return new LinkPart(href, children);
} }
@ -43,13 +55,13 @@ class Deserializer {
// Will return 1 for, say, '1A', which may not be intended? // Will return 1 for, say, '1A', which may not be intended?
start = parseInt(result.getAttributeValue(node, "start")) || 1; start = parseInt(result.getAttributeValue(node, "start")) || 1;
} }
const nodes = []; const items = [];
for (const child of result.getChildNodes(node)) { for (const child of result.getChildNodes(node)) {
if (result.getNodeElementName(child) !== "LI") { if (result.getNodeElementName(child) !== "LI") {
continue; continue;
} }
const item = this.parseAnyNodes(result.getChildNodes(child)); const item = this.parseAnyNodes(result.getChildNodes(child));
nodes.push(item); items.push(item);
} }
return new ListBlock(start, nodes); return new ListBlock(start, nodes);
} }

View file

@ -1,12 +0,0 @@
const baseUrl = 'https://matrix.to';
const linkPrefix = `${baseUrl}/#/`;
export function parsePillLink(link) {
if (!link.startsWith(linkPrefix)) {
return null;
}
const contents = link.substring(linkPrefix.length);
if (contents[0] === '@') {
return { userId: contents }
}
}