This repository has been archived on 2022-08-19. You can view files and clone it, but cannot push or open issues or pull requests.
hydrogen-web/src/domain/session/room/timeline/MessageBody.js

152 lines
3.5 KiB
JavaScript
Raw Normal View History

import { linkify } from "./linkify/linkify.js";
/**
* Parse text into parts such as newline, links and text.
* @param {string} body A string to parse into parts
* @returns {MessageBody} Parsed result
*/
export function parsePlainBody(body) {
const parts = [];
const lines = body.split("\n");
// create callback outside of loop
const linkifyCallback = (text, isLink) => {
if (isLink) {
parts.push(new LinkPart(text, [new TextPart(text)]));
} else {
parts.push(new TextPart(text));
}
};
for (let i = 0; i < lines.length; i += 1) {
const line = lines[i];
if (line.length) {
linkify(line, linkifyCallback);
}
const isLastLine = i >= (lines.length - 1);
if (!isLastLine) {
parts.push(new NewLinePart());
}
}
return new MessageBody(body, parts);
}
export function stringAsBody(body) {
return new MessageBody(body, [new TextPart(body)]);
}
export class HeaderBlock {
2021-07-01 12:49:01 +05:30
constructor(level, inlines) {
this.level = level;
this.inlines = inlines;
}
get type() { return "header"; }
}
export class CodeBlock {
constructor(language, text) {
this.language = language;
2021-07-01 12:49:01 +05:30
this.text = text;
}
get type() { return "codeblock"; }
}
export class ListBlock {
constructor(startOffset, items) {
this.items = items;
this.startOffset = startOffset;
}
get type() { return "list"; }
2021-07-01 12:49:01 +05:30
}
export class RulePart {
get type( ) { return "rule"; }
}
2021-07-01 12:49:01 +05:30
export class NewLinePart {
get type() { return "newline"; }
2021-07-01 12:49:01 +05:30
}
export class FormatPart {
constructor(format, children) {
this.format = format.toLowerCase();
this.children = children;
2021-07-01 12:49:01 +05:30
}
get type() { return "format"; }
}
2021-07-08 12:10:16 +05:30
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;
this.inlines = inlines;
}
get type() { return "link"; }
}
export class TextPart {
constructor(text) {
this.text = text;
}
get type() { return "text"; }
}
export class MessageBody {
constructor(sourceString, parts) {
2021-05-17 16:15:55 +05:30
this.sourceString = sourceString;
this.parts = parts;
}
}
export function tests() {
function test(assert, input, output) {
assert.deepEqual(parsePlainBody(input), new MessageBody(input, output));
}
return {
// Tests for text
"Text only": assert => {
const input = "This is a sentence";
const output = [new TextPart(input)];
test(assert, input, output);
},
"Text with newline": assert => {
const input = "This is a sentence.\nThis is another sentence.";
const output = [
new TextPart("This is a sentence."),
new NewLinePart(),
new TextPart("This is another sentence.")
];
test(assert, input, output);
},
"Text with newline & trailing newline": assert => {
const input = "This is a sentence.\nThis is another sentence.\n";
const output = [
new TextPart("This is a sentence."),
new NewLinePart(),
new TextPart("This is another sentence."),
new NewLinePart()
];
test(assert, input, output);
}
};
}