Start working on images.
This commit is contained in:
parent
1a14719483
commit
c582b723bd
4 changed files with 39 additions and 5 deletions
|
@ -80,6 +80,15 @@ export class FormatPart {
|
||||||
get type() { return "format"; }
|
get type() { return "format"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ImagePart {
|
||||||
|
constructor(src, properties) {
|
||||||
|
this.src = src;
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() { return "image"; }
|
||||||
|
};
|
||||||
|
|
||||||
export class LinkPart {
|
export class LinkPart {
|
||||||
constructor(url, inlines) {
|
constructor(url, inlines) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
|
|
|
@ -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
|
/* 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);
|
return new CodeBlock(language, codeNode.textContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseImage(result, node) {
|
// 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;
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseImage(result, node) {
|
||||||
|
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() {
|
function buildNodeMap() {
|
||||||
|
@ -135,7 +154,7 @@ function parseNodes(result, nodes) {
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseHTMLBody(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 parts = parseNodes(parseResult, parseResult.rootNodes);
|
||||||
return new MessageBody(html, parts);
|
return new MessageBody(html, parts);
|
||||||
|
@ -187,7 +206,7 @@ const platform = {
|
||||||
|
|
||||||
export function tests() {
|
export function tests() {
|
||||||
function test(assert, input, output) {
|
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 {
|
return {
|
||||||
|
|
|
@ -46,7 +46,7 @@ export class TextTile extends BaseTextTile {
|
||||||
_parseBody(body) {
|
_parseBody(body) {
|
||||||
const string = body.string;
|
const string = body.string;
|
||||||
if (body.format === "html") {
|
if (body.format === "html") {
|
||||||
return parseHTMLBody(this.platform, string);
|
return parseHTMLBody({ mediaRepository: this._mediaRepository, platform: this.platform }, string);
|
||||||
} else {
|
} else {
|
||||||
return parsePlainBody(string);
|
return parsePlainBody(string);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,11 @@ function renderList(listBlock) {
|
||||||
return tag.ul({}, items);
|
return tag.ul({}, items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderImage(imagePart) {
|
||||||
|
return text(imagePart.src);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from part to function that outputs DOM for the part
|
* 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)),
|
link: linkPart => tag.a({ href: linkPart.url, target: "_blank", rel: "noopener" }, renderParts(linkPart.inlines)),
|
||||||
format: formatPart => tag[formatPart.format]({}, renderParts(formatPart.children)),
|
format: formatPart => tag[formatPart.format]({}, renderParts(formatPart.children)),
|
||||||
list: renderList,
|
list: renderList,
|
||||||
|
image: renderImage,
|
||||||
newline: () => tag.br()
|
newline: () => tag.br()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Reference in a new issue