forked from mystiq/hydrogen-web
expose sourceString on result of parsing message body
and also do some cleanup
This commit is contained in:
parent
4f1149c1a7
commit
01b8b397b6
2 changed files with 105 additions and 96 deletions
105
src/domain/session/room/timeline/MessageBody.js
Normal file
105
src/domain/session/room/timeline/MessageBody.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
import { linkify } from "./linkify/linkify.js";
|
||||
|
||||
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, text));
|
||||
} else {
|
||||
parts.push(new TextPart(text));
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < lines.length; i += 1) {
|
||||
const line = lines[i];
|
||||
if (line.length) {
|
||||
linkify(lines[i], 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)]);
|
||||
}
|
||||
|
||||
class NewLinePart {
|
||||
get type() { return "newline"; }
|
||||
}
|
||||
|
||||
class LinkPart {
|
||||
constructor(url, text) {
|
||||
this.url = url;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
get type() { return "link"; }
|
||||
}
|
||||
|
||||
class TextPart {
|
||||
constructor(text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
get type() { return "text"; }
|
||||
}
|
||||
|
||||
class MessageBody {
|
||||
constructor(sourceString, parts) {
|
||||
this._sourceString = sourceString;
|
||||
this._parts = parts;
|
||||
}
|
||||
|
||||
get sourceString() {
|
||||
return this._sourceString;
|
||||
}
|
||||
|
||||
get parts() {
|
||||
return this._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);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
import { linkify } from "./linkify/linkify.js";
|
||||
|
||||
export class MessageBodyBuilder {
|
||||
|
||||
constructor(message = []) {
|
||||
this._root = message;
|
||||
}
|
||||
|
||||
fromText(text) {
|
||||
const components = text.split("\n");
|
||||
components.flatMap(e => ["\n", e]).slice(1).forEach(e => {
|
||||
if (e === "\n") {
|
||||
this.insertNewline();
|
||||
}
|
||||
else {
|
||||
linkify(e, this.insert.bind(this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
insert(text, isLink) {
|
||||
if (!text.length) {
|
||||
return;
|
||||
}
|
||||
if (isLink) {
|
||||
this.insertLink(text, text);
|
||||
}
|
||||
else {
|
||||
this.insertText(text);
|
||||
}
|
||||
}
|
||||
|
||||
insertText(text) {
|
||||
if (text.length) {
|
||||
this._root.push({ type: "text", text: text });
|
||||
}
|
||||
}
|
||||
|
||||
insertLink(link, displayText) {
|
||||
this._root.push({ type: "link", url: link, text: displayText });
|
||||
}
|
||||
|
||||
insertNewline() {
|
||||
this._root.push({ type: "newline" });
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this._root.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function tests() {
|
||||
|
||||
function linkify(text) {
|
||||
const obj = new MessageBodyBuilder();
|
||||
obj.fromText(text);
|
||||
return obj;
|
||||
}
|
||||
|
||||
function test(assert, input, output) {
|
||||
output = new MessageBodyBuilder(output);
|
||||
input = linkify(input);
|
||||
assert.deepEqual(input, output);
|
||||
}
|
||||
|
||||
return {
|
||||
// Tests for text
|
||||
"Text only": assert => {
|
||||
const input = "This is a sentence";
|
||||
const output = [{ type: "text", text: input }];
|
||||
test(assert, input, output);
|
||||
},
|
||||
|
||||
"Text with newline": assert => {
|
||||
const input = "This is a sentence.\nThis is another sentence.";
|
||||
const output = [
|
||||
{ type: "text", text: "This is a sentence." },
|
||||
{ type: "newline" },
|
||||
{ type: "text", text: "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 = [
|
||||
{ type: "text", text: "This is a sentence." },
|
||||
{ type: "newline" },
|
||||
{ type: "text", text: "This is another sentence." },
|
||||
{ type: "newline" }
|
||||
];
|
||||
test(assert, input, output);
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue