Display images in messages

This commit is contained in:
Danila Fedorin 2021-07-08 00:16:58 -07:00
parent c582b723bd
commit d38c52d311
2 changed files with 31 additions and 17 deletions

View file

@ -17,24 +17,25 @@ const basicNodes = ["EM", "STRONG", "CODE", "DEL", "P", "DIV", "SPAN" ]
* Return a builder function for a particular tag. * Return a builder function for a particular tag.
*/ */
function basicWrapper(tag) { function basicWrapper(tag) {
return (result, node, children) => new FormatPart(tag, children); return (_, node, children) => new FormatPart(tag, children);
} }
/** /**
* Return a builder function for a particular header level. * Return a builder function for a particular header level.
*/ */
function headerWrapper(level) { function headerWrapper(level) {
return (result, node, children) => new HeaderBlock(level, children); return (_, node, children) => new HeaderBlock(level, children);
} }
function parseLink(result, node, children) { function parseLink(options, node, children) {
// TODO Not equivalent to `node.href`! // TODO Not equivalent to `node.href`!
// Add another HTMLParseResult method? // Add another HTMLParseResult method?
let href = result.getAttributeValue(node, "href"); let href = options.result.getAttributeValue(node, "href");
return new LinkPart(href, children); return new LinkPart(href, children);
} }
function parseList(result, node) { function parseList(options, node) {
const { result } = options;
let start = null; let start = null;
if (result.getNodeElementName(node) === "OL") { if (result.getNodeElementName(node) === "OL") {
// Will return 1 for, say, '1A', which may not be intended? // Will return 1 for, say, '1A', which may not be intended?
@ -45,13 +46,14 @@ function parseList(result, node) {
if (result.getNodeElementName(child) !== "LI") { if (result.getNodeElementName(child) !== "LI") {
continue; continue;
} }
const item = parseNodes(result, result.getChildNodes(child)); const item = parseNodes(options, result.getChildNodes(child));
nodes.push(item); nodes.push(item);
} }
return new ListBlock(start, nodes); return new ListBlock(start, nodes);
} }
function parseCodeBlock(result, node) { function parseCodeBlock(options, node) {
const { result } = options;
let codeNode; let codeNode;
for (const child of result.getChildNodes(node)) { for (const child of result.getChildNodes(node)) {
codeNode = child; codeNode = child;
@ -81,17 +83,19 @@ function parseMxcUrl(url) {
} }
} }
function parseImage(result, node) { function parseImage(options, node) {
const { result, mediaRepository } = options;
const src = result.getAttributeValue(node, "src") || ""; const src = result.getAttributeValue(node, "src") || "";
const url = mediaRepository.mxcUrl(src);
// We just ignore non-mxc `src` attributes. // We just ignore non-mxc `src` attributes.
if (!parseMxcUrl(src)) { if (!url) {
return null; return null;
} }
const width = result.getAttributeValue(node, "width"); const width = result.getAttributeValue(node, "width");
const height = result.getAttributeValue(node, "height"); const height = result.getAttributeValue(node, "height");
const alt = result.getAttributeValue(node, "alt"); const alt = result.getAttributeValue(node, "alt");
const title = result.getAttributeValue(node, "title"); const title = result.getAttributeValue(node, "title");
return new ImagePart(src, { width, height, alt, title }); return new ImagePart(url, { width, height, alt, title });
} }
function buildNodeMap() { function buildNodeMap() {
@ -128,7 +132,8 @@ function buildNodeMap() {
*/ */
const nodes = buildNodeMap(); const nodes = buildNodeMap();
function parseNode(result, node) { function parseNode(options, node) {
const { result } = options;
if (result.isTextNode(node)) { if (result.isTextNode(node)) {
return new TextPart(result.getNodeText(node)); return new TextPart(result.getNodeText(node));
} else if (result.isElementNode(node)) { } else if (result.isElementNode(node)) {
@ -136,16 +141,16 @@ function parseNode(result, node) {
if (!f) { if (!f) {
return null; return null;
} }
const children = f.descend ? parseNodes(result, node.childNodes) : null; const children = f.descend ? parseNodes(options, node.childNodes) : null;
return f.parsefn(result, node, children); return f.parsefn(options, node, children);
} }
return null; return null;
} }
function parseNodes(result, nodes) { function parseNodes(options, nodes) {
const parsed = []; const parsed = [];
for (const htmlNode of nodes) { for (const htmlNode of nodes) {
let node = parseNode(result, htmlNode); let node = parseNode(options, htmlNode);
// Just ignore invalid / unknown tags. // Just ignore invalid / unknown tags.
if (node) { if (node) {
parsed.push(node); parsed.push(node);
@ -156,7 +161,8 @@ function parseNodes(result, nodes) {
export function parseHTMLBody({ mediaRepository, platform }, html) { export function parseHTMLBody({ mediaRepository, platform }, html) {
const parseResult = platform.parseHTML(html); const parseResult = platform.parseHTML(html);
const parts = parseNodes(parseResult, parseResult.rootNodes); const options = { result: parseResult, mediaRepository };
const parts = parseNodes(options, parseResult.rootNodes);
return new MessageBody(html, parts); return new MessageBody(html, parts);
} }

View file

@ -43,7 +43,15 @@ function renderList(listBlock) {
} }
function renderImage(imagePart) { function renderImage(imagePart) {
return text(imagePart.src); const props = imagePart.properties;
const attributes = Object.assign(
{ src: imagePart.src },
props.width && { width: props.width },
props.height && { height: props.height },
props.alt && { alt: props.alt },
props.title && { title: props.title }
);
return tag.img(attributes, []);
} }
/** /**