expose sourceString on result of parsing message body

and also do some cleanup
This commit is contained in:
Bruno Windels 2021-05-17 11:26:30 +02:00
parent 4f1149c1a7
commit 01b8b397b6
2 changed files with 105 additions and 96 deletions

View 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);
}
};
}

View file

@ -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);
}
};
}