Start working on images.

This commit is contained in:
Danila Fedorin 2021-07-07 23:40:16 -07:00
parent 1a14719483
commit c582b723bd
4 changed files with 39 additions and 5 deletions

View file

@ -80,6 +80,15 @@ export class FormatPart {
get type() { return "format"; }
}
export class ImagePart {
constructor(src, properties) {
this.src = src;
this.properties = properties;
}
get type() { return "image"; }
};
export class LinkPart {
constructor(url, inlines) {
this.url = url;

View file

@ -1,4 +1,4 @@
import { MessageBody, HeaderBlock, ListBlock, CodeBlock, FormatPart, NewLinePart, RulePart, TextPart, LinkPart } from "./MessageBody.js"
import { MessageBody, HeaderBlock, ListBlock, CodeBlock, FormatPart, NewLinePart, RulePart, TextPart, LinkPart, ImagePart } from "./MessageBody.js"
/* At the time of writing (Jul 1 2021), Matrix Spec recommends
@ -71,8 +71,27 @@ function parseCodeBlock(result, node) {
return new CodeBlock(language, codeNode.textContent);
}
// TODO: duplicated from MediaRepository. Extract somewhere.
function parseMxcUrl(url) {
const prefix = "mxc://";
if (url.startsWith(prefix)) {
return url.substr(prefix.length).split("/", 2);
} else {
return null;
}
}
function parseImage(result, node) {
return null;
const src = result.getAttributeValue(node, "src") || "";
// We just ignore non-mxc `src` attributes.
if (!parseMxcUrl(src)) {
return null;
}
const width = result.getAttributeValue(node, "width");
const height = result.getAttributeValue(node, "height");
const alt = result.getAttributeValue(node, "alt");
const title = result.getAttributeValue(node, "title");
return new ImagePart(src, { width, height, alt, title });
}
function buildNodeMap() {
@ -135,7 +154,7 @@ function parseNodes(result, nodes) {
return parsed;
}
export function parseHTMLBody(platform, html) {
export function parseHTMLBody({ mediaRepository, platform }, html) {
const parseResult = platform.parseHTML(html);
const parts = parseNodes(parseResult, parseResult.rootNodes);
return new MessageBody(html, parts);
@ -187,7 +206,7 @@ const platform = {
export function tests() {
function test(assert, input, output) {
assert.deepEqual(parseHTMLBody(platform, input), new MessageBody(input, output));
assert.deepEqual(parseHTMLBody({ mediaRepository: null, platform }, input), new MessageBody(input, output));
}
return {

View file

@ -46,7 +46,7 @@ export class TextTile extends BaseTextTile {
_parseBody(body) {
const string = body.string;
if (body.format === "html") {
return parseHTMLBody(this.platform, string);
return parseHTMLBody({ mediaRepository: this._mediaRepository, platform: this.platform }, string);
} else {
return parsePlainBody(string);
}

View file

@ -41,6 +41,11 @@ function renderList(listBlock) {
return tag.ul({}, items);
}
}
function renderImage(imagePart) {
return text(imagePart.src);
}
/**
* Map from part to function that outputs DOM for the part
*/
@ -53,6 +58,7 @@ const formatFunction = {
link: linkPart => tag.a({ href: linkPart.url, target: "_blank", rel: "noopener" }, renderParts(linkPart.inlines)),
format: formatPart => tag[formatPart.format]({}, renderParts(formatPart.children)),
list: renderList,
image: renderImage,
newline: () => tag.br()
};