make MarkDown into a class and fixed emojis

This commit is contained in:
MathMan05 2024-07-20 19:05:23 -05:00
parent 36fc3fecc2
commit ec5b86b276
12 changed files with 957 additions and 848 deletions

View file

@ -3,7 +3,6 @@ import { Message } from "./message.js";
import { Voice } from "./audio.js"; import { Voice } from "./audio.js";
import { Contextmenu } from "./contextmenu.js"; import { Contextmenu } from "./contextmenu.js";
import { Fullscreen } from "./fullscreen.js"; import { Fullscreen } from "./fullscreen.js";
import { markdown } from "./markdown.js";
import { Permissions } from "./permissions.js"; import { Permissions } from "./permissions.js";
import { Settings, RoleList } from "./settings.js"; import { Settings, RoleList } from "./settings.js";
import { InfiniteScroller } from "./infiniteScroller.js"; import { InfiniteScroller } from "./infiniteScroller.js";
@ -745,10 +744,10 @@ class Channel {
if (!("Notification" in window)) { if (!("Notification" in window)) {
} }
else if (Notification.permission === "granted") { else if (Notification.permission === "granted") {
let noticontent = markdown(message.content).textContent; let noticontent = message.content.textContent;
if (message.embeds[0]) { if (message.embeds[0]) {
noticontent ||= message.embeds[0].json.title; noticontent ||= message.embeds[0].json.title;
noticontent ||= markdown(message.embeds[0].json.description).textContent; noticontent ||= message.content.textContent;
} }
noticontent ||= "Blank Message"; noticontent ||= "Blank Message";
let imgurl = null; let imgurl = null;

View file

@ -1,5 +1,5 @@
import { Fullscreen } from "./fullscreen.js"; import { Fullscreen } from "./fullscreen.js";
import { markdown } from "./markdown.js"; import { MarkDown } from "./markdown.js";
class Embed { class Embed {
type; type;
owner; owner;
@ -27,6 +27,18 @@ class Embed {
return document.createElement("div"); //prevent errors by giving blank div return document.createElement("div"); //prevent errors by giving blank div
} }
} }
get message() {
return this.owner;
}
get channel() {
return this.message.channel;
}
get guild() {
return this.channel.guild;
}
get localuser() {
return this.guild.localuser;
}
generateRich() { generateRich() {
console.log(this.json); console.log(this.json);
const div = document.createElement("div"); const div = document.createElement("div");
@ -55,7 +67,7 @@ class Embed {
embed.append(authorline); embed.append(authorline);
} }
const title = document.createElement("a"); const title = document.createElement("a");
title.append(markdown(this.json.title)); title.append(new MarkDown(this.json.title, this.localuser).makeHTML());
if (this.json.url) { if (this.json.url) {
title.href = this.json.url; title.href = this.json.url;
} }
@ -63,7 +75,7 @@ class Embed {
embed.append(title); embed.append(title);
if (this.json.description) { if (this.json.description) {
const p = document.createElement("p"); const p = document.createElement("p");
p.append(markdown(this.json.description)); p.append(new MarkDown(this.json.description, this.channel).makeHTML());
embed.append(p); embed.append(p);
} }
embed.append(document.createElement("br")); embed.append(document.createElement("br"));
@ -74,7 +86,7 @@ class Embed {
b.textContent = thing.name; b.textContent = thing.name;
div.append(b); div.append(b);
const p = document.createElement("p"); const p = document.createElement("p");
p.append(markdown(thing.value)); p.append(new MarkDown(thing.value, this.channel).makeHTML());
p.classList.add("embedp"); p.classList.add("embedp");
div.append(p); div.append(p);
if (thing.inline) { if (thing.inline) {

View file

@ -1,446 +1,476 @@
export { markdown }; export { MarkDown };
function markdown(text, { keep = false, stdsize = false } = {}) { class MarkDown {
let txt; txt;
if ((typeof text) === (typeof "")) { keep;
txt = text.split(""); stdsize;
} owner;
else { info;
txt = text; constructor(text, owner, { keep = false, stdsize = false } = {}) {
} if ((typeof text) === (typeof "")) {
if (txt === undefined) { this.txt = text.split("");
txt = [];
}
const span = document.createElement("span");
let current = document.createElement("span");
function appendcurrent() {
if (current.innerHTML !== "") {
span.append(current);
current = document.createElement("span");
} }
else {
this.txt = text;
}
if (this.txt === undefined) {
this.txt = [];
}
this.info = owner.info;
this.keep = keep;
this.owner = owner;
this.stdsize = stdsize;
} }
for (let i = 0; i < txt.length; i++) { get rawString() {
if (txt[i] === "\n" || i === 0) { return this.txt.concat("");
const first = i === 0; }
if (first) { get textContent() {
i--; return this.makeHTML().textContent;
}
makeHTML({ keep = this.keep, stdsize = this.stdsize } = {}) {
return this.markdown(this.txt, { keep: keep, stdsize: stdsize });
}
markdown(text, { keep = false, stdsize = false } = {}) {
let txt;
if ((typeof text) === (typeof "")) {
txt = text.split("");
}
else {
txt = text;
}
if (txt === undefined) {
txt = [];
}
const span = document.createElement("span");
let current = document.createElement("span");
function appendcurrent() {
if (current.innerHTML !== "") {
span.append(current);
current = document.createElement("span");
} }
let element = null; }
let keepys = ""; for (let i = 0; i < txt.length; i++) {
if (txt[i + 1] === "#") { if (txt[i] === "\n" || i === 0) {
console.log("test"); const first = i === 0;
if (txt[i + 2] === "#") { if (first) {
if (txt[i + 3] === "#" && txt[i + 4] === " ") { i--;
element = document.createElement("h3"); }
keepys = "### "; let element = null;
i += 5; let keepys = "";
if (txt[i + 1] === "#") {
console.log("test");
if (txt[i + 2] === "#") {
if (txt[i + 3] === "#" && txt[i + 4] === " ") {
element = document.createElement("h3");
keepys = "### ";
i += 5;
}
else if (txt[i + 3] === " ") {
element = document.createElement("h2");
element.classList.add("h2md");
keepys = "## ";
i += 4;
}
} }
else if (txt[i + 3] === " ") { else if (txt[i + 2] === " ") {
element = document.createElement("h2"); element = document.createElement("h1");
element.classList.add("h2md"); keepys = "# ";
keepys = "## "; i += 3;
i += 4;
} }
} }
else if (txt[i + 2] === " ") { else if (txt[i + 1] === ">" && txt[i + 2] === " ") {
element = document.createElement("h1"); element = document.createElement("div");
keepys = "# "; const line = document.createElement("div");
line.classList.add("quoteline");
element.append(line);
element.classList.add("quote");
keepys = "> ";
i += 3; i += 3;
} }
} if (keepys) {
else if (txt[i + 1] === ">" && txt[i + 2] === " ") { appendcurrent();
element = document.createElement("div"); if (!first && !stdsize) {
const line = document.createElement("div"); span.appendChild(document.createElement("br"));
line.classList.add("quoteline"); }
element.append(line); const build = [];
element.classList.add("quote"); for (; txt[i] !== "\n" && txt[i] !== undefined; i++) {
keepys = "> "; build.push(txt[i]);
i += 3; }
} if (stdsize) {
if (keepys) { element = document.createElement("span");
appendcurrent(); }
if (!first && !stdsize) { if (keep) {
span.appendChild(document.createElement("br")); element.append(keepys);
}
element.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
span.append(element);
i--;
continue;
} }
const build = []; if (first) {
for (; txt[i] !== "\n" && txt[i] !== undefined; i++) { i++;
build.push(txt[i]); }
}
if (txt[i] === "\n") {
if (!stdsize) {
appendcurrent();
span.append(document.createElement("br"));
}
continue;
}
if (txt[i] === "`") {
let count = 1;
if (txt[i + 1] === "`") {
count++;
if (txt[i + 2] === "`") {
count++;
}
}
let build = "";
if (keep) {
build += "`".repeat(count);
}
let find = 0;
let j = i + count;
let init = true;
for (; txt[j] !== undefined && (txt[j] !== "\n" || count === 3) && find !== count; j++) {
if (txt[j] === "`") {
find++;
}
else {
if (find !== 0) {
build += "`".repeat(find);
find = 0;
}
if (init && count === 3) {
if (txt[j] === " " || txt[j] === "\n") {
init = false;
}
if (keep) {
build += txt[j];
}
continue;
}
build += txt[j];
}
} }
if (stdsize) { if (stdsize) {
element = document.createElement("span"); console.log(build);
build = build.replaceAll("\n", "");
console.log(build, JSON.stringify(build));
} }
if (keep) { if (find === count) {
element.append(keepys);
}
element.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
span.append(element);
i--;
continue;
}
if (first) {
i++;
}
}
if (txt[i] === "\n") {
if (!stdsize) {
appendcurrent();
span.append(document.createElement("br"));
}
continue;
}
if (txt[i] === "`") {
let count = 1;
if (txt[i + 1] === "`") {
count++;
if (txt[i + 2] === "`") {
count++;
}
}
let build = "";
if (keep) {
build += "`".repeat(count);
}
let find = 0;
let j = i + count;
let init = true;
for (; txt[j] !== undefined && (txt[j] !== "\n" || count === 3) && find !== count; j++) {
if (txt[j] === "`") {
find++;
}
else {
if (find !== 0) {
build += "`".repeat(find);
find = 0;
}
if (init && count === 3) {
if (txt[j] === " " || txt[j] === "\n") {
init = false;
}
if (keep) {
build += txt[j];
}
continue;
}
build += txt[j];
}
}
if (stdsize) {
console.log(build);
build = build.replaceAll("\n", "");
console.log(build, JSON.stringify(build));
}
if (find === count) {
appendcurrent();
i = j;
if (keep) {
build += "`".repeat(find);
}
if (count !== 3 && !stdsize) {
const samp = document.createElement("samp");
samp.textContent = build;
span.appendChild(samp);
}
else {
const pre = document.createElement("pre");
if (build[build.length - 1] === "\n") {
build = build.substring(0, build.length - 1);
}
if (txt[i] === "\n") {
i++;
}
pre.textContent = build;
span.appendChild(pre);
}
i--;
continue;
}
}
if (txt[i] === "*") {
let count = 1;
if (txt[i + 1] === "*") {
count++;
if (txt[i + 2] === "*") {
count++;
}
}
let build = [];
let find = 0;
let j = i + count;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "*") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("*"));
find = 0;
}
}
}
if (find === count && (count != 1 || txt[i + 1] !== " ")) {
appendcurrent();
i = j;
const stars = "*".repeat(count);
if (count === 1) {
const i = document.createElement("i");
if (keep) {
i.append(stars);
}
i.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
i.append(stars);
}
span.appendChild(i);
}
else if (count === 2) {
const b = document.createElement("b");
if (keep) {
b.append(stars);
}
b.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
b.append(stars);
}
span.appendChild(b);
}
else {
const b = document.createElement("b");
const i = document.createElement("i");
if (keep) {
b.append(stars);
}
b.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
b.append(stars);
}
i.appendChild(b);
span.appendChild(i);
}
i--;
continue;
}
}
if (txt[i] === "_") {
let count = 1;
if (txt[i + 1] === "_") {
count++;
if (txt[i + 2] === "_") {
count++;
}
}
let build = [];
let find = 0;
let j = i + count;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "_") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("_"));
find = 0;
}
}
}
if (find === count && (count != 1 || (txt[j + 1] === " " || txt[j + 1] === "\n" || txt[j + 1] === undefined))) {
appendcurrent();
i = j;
const underscores = "_".repeat(count);
if (count === 1) {
const i = document.createElement("i");
if (keep) {
i.append(underscores);
}
i.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
i.append(underscores);
}
span.appendChild(i);
}
else if (count === 2) {
const u = document.createElement("u");
if (keep) {
u.append(underscores);
}
u.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
u.append(underscores);
}
span.appendChild(u);
}
else {
const u = document.createElement("u");
const i = document.createElement("i");
if (keep) {
i.append(underscores);
}
i.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
i.append(underscores);
}
u.appendChild(i);
span.appendChild(u);
}
i--;
continue;
}
}
if (txt[i] === "~" && txt[i + 1] === "~") {
let count = 2;
let build = [];
let find = 0;
let j = i + 2;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "~") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("~"));
find = 0;
}
}
}
if (find === count) {
appendcurrent();
i = j;
const tildes = "~~";
if (count === 2) {
const s = document.createElement("s");
if (keep) {
s.append(tildes);
}
s.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
s.append(tildes);
}
span.appendChild(s);
}
continue;
}
}
if (txt[i] === "|" && txt[i + 1] === "|") {
let count = 2;
let build = [];
let find = 0;
let j = i + 2;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "|") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("~"));
find = 0;
}
}
}
if (find === count) {
appendcurrent();
i = j;
const pipes = "||";
if (count === 2) {
const j = document.createElement("j");
if (keep) {
j.append(pipes);
}
j.appendChild(markdown(build, { keep: keep, stdsize: stdsize }));
j.classList.add("spoiler");
j.onclick = markdown.unspoil;
if (keep) {
j.append(pipes);
}
span.appendChild(j);
}
continue;
}
}
if (txt[i] === "<" && txt[i + 1] === "t" && txt[i + 2] === ":") {
let found = false;
const build = ["<", "t", ":"];
let j = i + 3;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j] === ">") {
found = true;
break;
}
}
if (found) {
appendcurrent();
i = j;
const parts = build.join("").match(/^<t:([0-9]{1,16})(:([tTdDfFR]))?>$/);
const dateInput = new Date(Number.parseInt(parts[1]) * 1000);
let time = "";
if (Number.isNaN(dateInput.getTime()))
time = build.join("");
else {
if (parts[3] === "d")
time = dateInput.toLocaleString(void 0, { day: "2-digit", month: "2-digit", year: "numeric" });
else if (parts[3] === "D")
time = dateInput.toLocaleString(void 0, { day: "numeric", month: "long", year: "numeric" });
else if (!parts[3] || parts[3] === "f")
time = dateInput.toLocaleString(void 0, { day: "numeric", month: "long", year: "numeric" }) + " " +
dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit" });
else if (parts[3] === "F")
time = dateInput.toLocaleString(void 0, { day: "numeric", month: "long", year: "numeric", weekday: "long" }) + " " +
dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit" });
else if (parts[3] === "t")
time = dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit" });
else if (parts[3] === "T")
time = dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit", second: "2-digit" });
else if (parts[3] === "R")
time = Math.round((Date.now() - (Number.parseInt(parts[1]) * 1000)) / 1000 / 60) + " minutes ago";
}
const timeElem = document.createElement("span");
timeElem.classList.add("markdown-timestamp");
timeElem.textContent = time;
span.appendChild(timeElem);
continue;
}
}
if (txt[i] === "<" && (txt[i + 1] === ":" || (txt[i + 1] === "a" && txt[i + 2] === ":"))) {
let found = false;
const build = txt[i + 1] === "a" ? ["<", "a", ":"] : ["<", ":"];
let j = i + build.length;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j] === ">") {
found = true;
break;
}
}
if (found) {
const parts = build.join("").match(/^<(a)?:\w+:(\d{10,30})>$/);
if (parts && parts[2]) {
appendcurrent(); appendcurrent();
i = j; i = j;
console.log(typeof txt, txt); if (keep) {
const isEmojiOnly = txt.join("").trim() === build.join("").trim(); build += "`".repeat(find);
const emojiElem = document.createElement("img"); }
emojiElem.classList.add("md-emoji"); if (count !== 3 && !stdsize) {
emojiElem.width = isEmojiOnly ? 48 : 22; const samp = document.createElement("samp");
emojiElem.height = isEmojiOnly ? 48 : 22; samp.textContent = build;
emojiElem.crossOrigin = "anonymous"; span.appendChild(samp);
//emojiElem.src=this.info.cdn.toString() + "/emojis/" + parts[2] + "." + (parts[1] ? "gif" : "png") + "?size=32"; }
//must uncomment later else {
emojiElem.alt = ""; const pre = document.createElement("pre");
emojiElem.loading = "lazy"; if (build[build.length - 1] === "\n") {
span.appendChild(emojiElem); build = build.substring(0, build.length - 1);
}
if (txt[i] === "\n") {
i++;
}
pre.textContent = build;
span.appendChild(pre);
}
i--;
continue; continue;
} }
} }
if (txt[i] === "*") {
let count = 1;
if (txt[i + 1] === "*") {
count++;
if (txt[i + 2] === "*") {
count++;
}
}
let build = [];
let find = 0;
let j = i + count;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "*") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("*"));
find = 0;
}
}
}
if (find === count && (count != 1 || txt[i + 1] !== " ")) {
appendcurrent();
i = j;
const stars = "*".repeat(count);
if (count === 1) {
const i = document.createElement("i");
if (keep) {
i.append(stars);
}
i.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
i.append(stars);
}
span.appendChild(i);
}
else if (count === 2) {
const b = document.createElement("b");
if (keep) {
b.append(stars);
}
b.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
b.append(stars);
}
span.appendChild(b);
}
else {
const b = document.createElement("b");
const i = document.createElement("i");
if (keep) {
b.append(stars);
}
b.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
b.append(stars);
}
i.appendChild(b);
span.appendChild(i);
}
i--;
continue;
}
}
if (txt[i] === "_") {
let count = 1;
if (txt[i + 1] === "_") {
count++;
if (txt[i + 2] === "_") {
count++;
}
}
let build = [];
let find = 0;
let j = i + count;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "_") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("_"));
find = 0;
}
}
}
if (find === count && (count != 1 || (txt[j + 1] === " " || txt[j + 1] === "\n" || txt[j + 1] === undefined))) {
appendcurrent();
i = j;
const underscores = "_".repeat(count);
if (count === 1) {
const i = document.createElement("i");
if (keep) {
i.append(underscores);
}
i.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
i.append(underscores);
}
span.appendChild(i);
}
else if (count === 2) {
const u = document.createElement("u");
if (keep) {
u.append(underscores);
}
u.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
u.append(underscores);
}
span.appendChild(u);
}
else {
const u = document.createElement("u");
const i = document.createElement("i");
if (keep) {
i.append(underscores);
}
i.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
i.append(underscores);
}
u.appendChild(i);
span.appendChild(u);
}
i--;
continue;
}
}
if (txt[i] === "~" && txt[i + 1] === "~") {
let count = 2;
let build = [];
let find = 0;
let j = i + 2;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "~") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("~"));
find = 0;
}
}
}
if (find === count) {
appendcurrent();
i = j;
const tildes = "~~";
if (count === 2) {
const s = document.createElement("s");
if (keep) {
s.append(tildes);
}
s.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
if (keep) {
s.append(tildes);
}
span.appendChild(s);
}
continue;
}
}
if (txt[i] === "|" && txt[i + 1] === "|") {
let count = 2;
let build = [];
let find = 0;
let j = i + 2;
for (; txt[j] !== undefined && find !== count; j++) {
if (txt[j] === "|") {
find++;
}
else {
build.push(txt[j]);
if (find !== 0) {
build = build.concat(new Array(find).fill("~"));
find = 0;
}
}
}
if (find === count) {
appendcurrent();
i = j;
const pipes = "||";
if (count === 2) {
const j = document.createElement("j");
if (keep) {
j.append(pipes);
}
j.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
j.classList.add("spoiler");
j.onclick = MarkDown.unspoil;
if (keep) {
j.append(pipes);
}
span.appendChild(j);
}
continue;
}
}
if (txt[i] === "<" && txt[i + 1] === "t" && txt[i + 2] === ":") {
let found = false;
const build = ["<", "t", ":"];
let j = i + 3;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j] === ">") {
found = true;
break;
}
}
if (found) {
appendcurrent();
i = j;
const parts = build.join("").match(/^<t:([0-9]{1,16})(:([tTdDfFR]))?>$/);
const dateInput = new Date(Number.parseInt(parts[1]) * 1000);
let time = "";
if (Number.isNaN(dateInput.getTime()))
time = build.join("");
else {
if (parts[3] === "d")
time = dateInput.toLocaleString(void 0, { day: "2-digit", month: "2-digit", year: "numeric" });
else if (parts[3] === "D")
time = dateInput.toLocaleString(void 0, { day: "numeric", month: "long", year: "numeric" });
else if (!parts[3] || parts[3] === "f")
time = dateInput.toLocaleString(void 0, { day: "numeric", month: "long", year: "numeric" }) + " " +
dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit" });
else if (parts[3] === "F")
time = dateInput.toLocaleString(void 0, { day: "numeric", month: "long", year: "numeric", weekday: "long" }) + " " +
dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit" });
else if (parts[3] === "t")
time = dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit" });
else if (parts[3] === "T")
time = dateInput.toLocaleString(void 0, { hour: "2-digit", minute: "2-digit", second: "2-digit" });
else if (parts[3] === "R")
time = Math.round((Date.now() - (Number.parseInt(parts[1]) * 1000)) / 1000 / 60) + " minutes ago";
}
const timeElem = document.createElement("span");
timeElem.classList.add("markdown-timestamp");
timeElem.textContent = time;
span.appendChild(timeElem);
continue;
}
}
if (txt[i] === "<" && (txt[i + 1] === ":" || (txt[i + 1] === "a" && txt[i + 2] === ":"))) {
let found = false;
const build = txt[i + 1] === "a" ? ["<", "a", ":"] : ["<", ":"];
let j = i + build.length;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j] === ">") {
found = true;
break;
}
}
if (found) {
const buildjoin = build.join("");
const parts = buildjoin.match(/^<(a)?:\w+:(\d{10,30})>$/);
if (parts && parts[2]) {
appendcurrent();
i = j;
console.log(typeof txt, txt);
const isEmojiOnly = txt.join("").trim() === buildjoin.trim();
console.log(isEmojiOnly, ":3");
const emojiElem = document.createElement("img");
emojiElem.classList.add("md-emoji");
emojiElem.classList.add(isEmojiOnly ? "bigemoji" : "smallemoji");
emojiElem.crossOrigin = "anonymous";
emojiElem.src = this.info.cdn.toString() + "emojis/" + parts[2] + "." + (parts[1] ? "gif" : "png") + "?size=32";
emojiElem.alt = buildjoin;
emojiElem.loading = "lazy";
span.appendChild(emojiElem);
continue;
}
}
}
current.textContent += txt[i];
} }
current.textContent += txt[i]; appendcurrent();
return span;
}
static unspoil(e) {
e.target.classList.remove("spoiler");
e.target.classList.add("unspoiled");
} }
appendcurrent();
return span;
} }
markdown.unspoil = function (e) {
//console.log("undone")
e.target.classList.remove("spoiler");
e.target.classList.add("unspoiled");
};

View file

@ -1,7 +1,7 @@
import { Contextmenu } from "./contextmenu.js"; import { Contextmenu } from "./contextmenu.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { Member } from "./member.js"; import { Member } from "./member.js";
import { markdown } from "./markdown.js"; import { MarkDown } from "./markdown.js";
import { Embed } from "./embed.js"; import { Embed } from "./embed.js";
import { File } from "./file.js"; import { File } from "./file.js";
class Message { class Message {
@ -33,7 +33,7 @@ class Message {
} }
static setupcmenu() { static setupcmenu() {
Message.contextmenu.addbutton("Copy raw text", function () { Message.contextmenu.addbutton("Copy raw text", function () {
navigator.clipboard.writeText(this.content); navigator.clipboard.writeText(this.content.rawString);
}); });
Message.contextmenu.addbutton("Reply", function (div) { Message.contextmenu.addbutton("Reply", function (div) {
this.channel.setReplying(this); this.channel.setReplying(this);
@ -63,6 +63,10 @@ class Message {
} }
continue; continue;
} }
else if (thing === "content") {
this.content = new MarkDown(messagejson[thing], this.channel);
continue;
}
this[thing] = messagejson[thing]; this[thing] = messagejson[thing];
} }
for (const thing in this.embeds) { for (const thing in this.embeds) {
@ -204,7 +208,7 @@ class Message {
replyline.classList.add("replyflex"); replyline.classList.add("replyflex");
this.channel.getmessage(this.message_reference.message_id).then(message => { this.channel.getmessage(this.message_reference.message_id).then(message => {
const author = message.author; const author = message.author;
reply.appendChild(markdown(message.content, { stdsize: true })); reply.appendChild(message.content.makeHTML({ stdsize: true }));
minipfp.src = author.getpfpsrc(); minipfp.src = author.getpfpsrc();
author.bind(minipfp); author.bind(minipfp);
username.textContent = author.username; username.textContent = author.username;
@ -266,7 +270,7 @@ class Message {
else { else {
div.classList.remove("topMessage"); div.classList.remove("topMessage");
} }
const messaged = markdown(this.content); const messaged = this.content.makeHTML();
div["txt"] = messaged; div["txt"] = messaged;
const messagedwrap = document.createElement("div"); const messagedwrap = document.createElement("div");
messagedwrap.classList.add("flexttb"); messagedwrap.classList.add("flexttb");

View file

@ -1,6 +1,6 @@
//const usercache={}; //const usercache={};
import { Member } from "./member.js"; import { Member } from "./member.js";
import { markdown } from "./markdown.js"; import { MarkDown } from "./markdown.js";
import { Contextmenu } from "./contextmenu.js"; import { Contextmenu } from "./contextmenu.js";
class User { class User {
static userids = {}; static userids = {};
@ -48,6 +48,10 @@ class User {
} }
if (dontclone) { if (dontclone) {
for (const thing of Object.keys(userjson)) { for (const thing of Object.keys(userjson)) {
if (thing === "bio") {
this.bio = new MarkDown(userjson[thing], this.localuser);
continue;
}
this[thing] = userjson[thing]; this[thing] = userjson[thing];
} }
this.hypotheticalpfp = false; this.hypotheticalpfp = false;
@ -146,7 +150,7 @@ class User {
userbody.appendChild(pronounshtml); userbody.appendChild(pronounshtml);
const rule = document.createElement("hr"); const rule = document.createElement("hr");
userbody.appendChild(rule); userbody.appendChild(rule);
const biohtml = markdown(this.bio); const biohtml = this.bio.makeHTML();
userbody.appendChild(biohtml); userbody.appendChild(biohtml);
} }
console.log(div); console.log(div);

View file

@ -3,7 +3,7 @@ import { Message } from "./message.js";
import {Voice} from "./audio.js"; import {Voice} from "./audio.js";
import {Contextmenu} from "./contextmenu.js"; import {Contextmenu} from "./contextmenu.js";
import {Fullscreen} from "./fullscreen.js"; import {Fullscreen} from "./fullscreen.js";
import {markdown} from "./markdown.js"; import {MarkDown} from "./markdown.js";
import {Guild} from "./guild.js"; import {Guild} from "./guild.js";
import { Localuser } from "./localuser.js"; import { Localuser } from "./localuser.js";
import { Permissions } from "./permissions.js"; import { Permissions } from "./permissions.js";
@ -744,10 +744,10 @@ class Channel{
if (!("Notification" in window)) { if (!("Notification" in window)) {
} else if (Notification.permission === "granted") { } else if (Notification.permission === "granted") {
let noticontent=markdown(message.content).textContent; let noticontent=message.content.textContent;
if(message.embeds[0]){ if(message.embeds[0]){
noticontent||=message.embeds[0].json.title; noticontent||=message.embeds[0].json.title;
noticontent||=markdown(message.embeds[0].json.description).textContent; noticontent||=message.content.textContent;
} }
noticontent||="Blank Message"; noticontent||="Blank Message";
let imgurl=null; let imgurl=null;

View file

@ -1,6 +1,6 @@
import {Fullscreen} from "./fullscreen.js"; import {Fullscreen} from "./fullscreen.js";
import {Message} from "./message.js"; import {Message} from "./message.js";
import {markdown} from "./markdown.js"; import {MarkDown} from "./markdown.js";
class Embed{ class Embed{
type:string; type:string;
@ -29,6 +29,18 @@ class Embed{
return document.createElement("div");//prevent errors by giving blank div return document.createElement("div");//prevent errors by giving blank div
} }
} }
get message(){
return this.owner;
}
get channel(){
return this.message.channel;
}
get guild(){
return this.channel.guild;
}
get localuser(){
return this.guild.localuser;
}
generateRich(){ generateRich(){
console.log(this.json) console.log(this.json)
const div=document.createElement("div"); const div=document.createElement("div");
@ -59,7 +71,7 @@ class Embed{
embed.append(authorline); embed.append(authorline);
} }
const title=document.createElement("a"); const title=document.createElement("a");
title.append(markdown(this.json.title)); title.append(new MarkDown(this.json.title,this.localuser).makeHTML());
if(this.json.url){ if(this.json.url){
title.href=this.json.url; title.href=this.json.url;
} }
@ -68,7 +80,7 @@ class Embed{
if(this.json.description){ if(this.json.description){
const p=document.createElement("p"); const p=document.createElement("p");
p.append(markdown(this.json.description)); p.append(new MarkDown(this.json.description,this.channel).makeHTML());
embed.append(p); embed.append(p);
} }
@ -80,7 +92,7 @@ class Embed{
b.textContent=thing.name; b.textContent=thing.name;
div.append(b); div.append(b);
const p=document.createElement("p") const p=document.createElement("p")
p.append(markdown(thing.value)); p.append(new MarkDown(thing.value,this.channel).makeHTML());
p.classList.add("embedp"); p.classList.add("embedp");
div.append(p); div.append(p);

View file

@ -4,7 +4,7 @@ import {Direct} from "./direct.js";
import {Voice} from "./audio.js"; import {Voice} from "./audio.js";
import {User} from "./user.js"; import {User} from "./user.js";
import {Member} from "./member.js"; import {Member} from "./member.js";
import {markdown} from "./markdown.js"; import {MarkDown} from "./markdown.js";
import {Fullscreen} from "./fullscreen.js"; import {Fullscreen} from "./fullscreen.js";
import {setTheme, Specialuser} from "./login.js"; import {setTheme, Specialuser} from "./login.js";

View file

@ -1,413 +1,446 @@
export {markdown}; import { Channel } from "./channel";
function markdown(text : string|string[],{keep=false,stdsize=false} = {}){ import { Localuser } from "./localuser";
let txt : string[];
if((typeof text)===(typeof "")){ export {MarkDown};
txt=(text as string).split(""); class MarkDown{
}else{ txt : string[];
txt=(text as string[]); keep:boolean;
} stdsize:boolean;
if(txt===undefined){ owner:Localuser|Channel;
txt=[]; info:Localuser["info"];
} constructor(text : string|string[],owner:MarkDown["owner"],{keep=false,stdsize=false} = {}){
const span=document.createElement("span"); if((typeof text)===(typeof "")){
let current=document.createElement("span"); this.txt=(text as string).split("");
function appendcurrent(){ }else{
if(current.innerHTML!==""){ this.txt=(text as string[]);
span.append(current);
current=document.createElement("span");
} }
if(this.txt===undefined){
this.txt=[];
}
this.info=owner.info;
this.keep=keep;
this.owner=owner;
this.stdsize=stdsize;
} }
for(let i=0;i<txt.length;i++){ get rawString(){
if(txt[i]==="\n"||i===0){ return this.txt.concat("");
const first=i===0; }
if(first){ get textContent(){
i--; return this.makeHTML().textContent;
}
makeHTML({keep=this.keep,stdsize=this.stdsize}={}){
return this.markdown(this.txt,{keep:keep,stdsize:stdsize});
}
markdown(text : string|string[],{keep=false,stdsize=false} = {}){
let txt : string[];
if((typeof text)===(typeof "")){
txt=(text as string).split("");
}else{
txt=(text as string[]);
}
if(txt===undefined){
txt=[];
}
const span=document.createElement("span");
let current=document.createElement("span");
function appendcurrent(){
if(current.innerHTML!==""){
span.append(current);
current=document.createElement("span");
} }
let element=null;
let keepys="";
if(txt[i+1]==="#"){ }
console.log("test"); for(let i=0;i<txt.length;i++){
if(txt[i+2]==="#"){ if(txt[i]==="\n"||i===0){
if(txt[i+3]==="#"&&txt[i+4]===" "){ const first=i===0;
element=document.createElement("h3"); if(first){
keepys="### "; i--;
i+=5; }
}else if(txt[i+3]===" "){ let element=null;
element=document.createElement("h2"); let keepys="";
element.classList.add("h2md");
keepys="## "; if(txt[i+1]==="#"){
i+=4; console.log("test");
if(txt[i+2]==="#"){
if(txt[i+3]==="#"&&txt[i+4]===" "){
element=document.createElement("h3");
keepys="### ";
i+=5;
}else if(txt[i+3]===" "){
element=document.createElement("h2");
element.classList.add("h2md");
keepys="## ";
i+=4;
}
}else if(txt[i+2]===" "){
element=document.createElement("h1");
keepys="# ";
i+=3;
} }
}else if(txt[i+2]===" "){ }else if(txt[i+1]===">"&&txt[i+2]===" "){
element=document.createElement("h1"); element=document.createElement("div");
keepys="# "; const line=document.createElement("div");
line.classList.add("quoteline");
element.append(line);
element.classList.add("quote");
keepys="> ";
i+=3; i+=3;
} }
}else if(txt[i+1]===">"&&txt[i+2]===" "){ if(keepys){
element=document.createElement("div"); appendcurrent();
const line=document.createElement("div"); if(!first&&!stdsize){
line.classList.add("quoteline"); span.appendChild(document.createElement("br"));
element.append(line); }
element.classList.add("quote"); const build=[];
keepys="> "; for(;txt[i]!=="\n"&&txt[i]!==undefined;i++){
i+=3; build.push(txt[i]);
} }
if(keepys){ if(stdsize){
appendcurrent(); element=document.createElement("span");
if(!first&&!stdsize){ }
span.appendChild(document.createElement("br")); if(keep){
element.append(keepys);
}
element.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
span.append(element);
i--;
continue;
} }
const build=[]; if(first){
for(;txt[i]!=="\n"&&txt[i]!==undefined;i++){ i++;
build.push(txt[i]); }
}
if(txt[i]==="\n"){
if(!stdsize){
appendcurrent();
span.append(document.createElement("br"));
}
continue;
}
if(txt[i]==="`"){
let count=1;
if(txt[i+1]==="`"){
count++;
if(txt[i+2]==="`"){
count++;
}
}
let build="";
if(keep){
build+="`".repeat(count);
}
let find=0;
let j=i+count;
let init=true;
for(;txt[j]!==undefined&&(txt[j]!=="\n"||count===3)&&find!==count;j++){
if(txt[j]==="`"){
find++;
}else{
if(find!==0){
build+="`".repeat(find);
find=0;
}
if(init&&count===3){
if(txt[j]===" "||txt[j]==="\n"){
init=false;
}
if(keep){
build+=txt[j];
}
continue;
}
build+=txt[j];
}
} }
if(stdsize){ if(stdsize){
element=document.createElement("span"); console.log(build);
build=build.replaceAll("\n","");
console.log(build,JSON.stringify(build));
} }
if(keep){ if(find===count){
element.append(keepys);
}
element.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
span.append(element);
i--;
continue;
}
if(first){
i++;
}
}
if(txt[i]==="\n"){
if(!stdsize){
appendcurrent();
span.append(document.createElement("br"));
}
continue;
}
if(txt[i]==="`"){
let count=1;
if(txt[i+1]==="`"){
count++;
if(txt[i+2]==="`"){
count++;
}
}
let build="";
if(keep){
build+="`".repeat(count);
}
let find=0;
let j=i+count;
let init=true;
for(;txt[j]!==undefined&&(txt[j]!=="\n"||count===3)&&find!==count;j++){
if(txt[j]==="`"){
find++;
}else{
if(find!==0){
build+="`".repeat(find);
find=0;
}
if(init&&count===3){
if(txt[j]===" "||txt[j]==="\n"){
init=false;
}
if(keep){
build+=txt[j];
}
continue;
}
build+=txt[j];
}
}
if(stdsize){
console.log(build);
build=build.replaceAll("\n","");
console.log(build,JSON.stringify(build));
}
if(find===count){
appendcurrent();
i=j;
if(keep){
build+="`".repeat(find);
}
if(count!==3&&!stdsize){
const samp=document.createElement("samp");
samp.textContent=build;
span.appendChild(samp);
}else{
const pre=document.createElement("pre");
if(build[build.length-1]==="\n"){
build=build.substring(0,build.length-1);
}
if(txt[i]==="\n"){
i++
}
pre.textContent=build;
span.appendChild(pre);
}
i--;
continue;
}
}
if(txt[i]==="*"){
let count=1;
if(txt[i+1]==="*"){
count++;
if(txt[i+2]==="*"){
count++;
}
}
let build=[];
let find=0;
let j=i+count;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="*"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("*"));
find=0;
}
}
}
if(find===count&&(count!=1||txt[i+1]!==" ")){
appendcurrent();
i=j;
const stars="*".repeat(count);
if(count===1){
const i=document.createElement("i");
if(keep){i.append(stars)}
i.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){i.append(stars)}
span.appendChild(i);
}else if(count===2){
const b=document.createElement("b");
if(keep){b.append(stars)}
b.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){b.append(stars)}
span.appendChild(b);
}else{
const b=document.createElement("b");
const i=document.createElement("i");
if(keep){b.append(stars)}
b.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){b.append(stars)}
i.appendChild(b);
span.appendChild(i);
}
i--
continue;
}
}
if(txt[i]==="_"){
let count=1;
if(txt[i+1]==="_"){
count++;
if(txt[i+2]==="_"){
count++;
}
}
let build=[];
let find=0;
let j=i+count;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="_"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("_"));
find=0;
}
}
}
if(find===count&&(count!=1||(txt[j+1]===" "||txt[j+1]==="\n"||txt[j+1]===undefined))){
appendcurrent();
i=j;
const underscores="_".repeat(count);
if(count===1){
const i=document.createElement("i");
if(keep){i.append(underscores)}
i.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){i.append(underscores)}
span.appendChild(i);
}else if(count===2){
const u=document.createElement("u");
if(keep){u.append(underscores)}
u.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){u.append(underscores)}
span.appendChild(u);
}else{
const u=document.createElement("u");
const i=document.createElement("i");
if(keep){i.append(underscores)}
i.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){i.append(underscores)}
u.appendChild(i)
span.appendChild(u);
}
i--;
continue;
}
}
if(txt[i]==="~"&&txt[i+1]==="~"){
let count=2;
let build=[];
let find=0;
let j=i+2;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="~"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("~"));
find=0;
}
}
}
if(find===count){
appendcurrent();
i=j;
const tildes="~~";
if(count===2){
const s=document.createElement("s");
if(keep){s.append(tildes)}
s.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){s.append(tildes)}
span.appendChild(s);
}
continue;
}
}
if(txt[i]==="|"&&txt[i+1]==="|"){
let count=2;
let build=[];
let find=0;
let j=i+2;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="|"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("~"));
find=0;
}
}
}
if(find===count){
appendcurrent();
i=j;
const pipes="||";
if(count===2){
const j=document.createElement("j");
if(keep){j.append(pipes)}
j.appendChild(markdown(build,{keep:keep,stdsize:stdsize}));
j.classList.add("spoiler");
j.onclick=markdown.unspoil;
if(keep){j.append(pipes)}
span.appendChild(j);
}
continue;
}
}
if (txt[i]==="<" && txt[i + 1]==="t" && txt[i + 2]===":") {
let found=false;
const build=["<","t",":"];
let j = i+3;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j]===">") {
found=true;
break;
}
}
if (found) {
appendcurrent();
i=j;
const parts=build.join("").match(/^<t:([0-9]{1,16})(:([tTdDfFR]))?>$/);
const dateInput=new Date(Number.parseInt(parts[1]) * 1000);
let time="";
if (Number.isNaN(dateInput.getTime())) time=build.join("");
else {
if (parts[3]==="d") time=dateInput.toLocaleString(void 0, {day: "2-digit", month: "2-digit", year: "numeric"});
else if (parts[3]==="D") time=dateInput.toLocaleString(void 0, {day: "numeric", month: "long", year: "numeric"});
else if (!parts[3] || parts[3]==="f") time=dateInput.toLocaleString(void 0, {day: "numeric", month: "long", year: "numeric"}) + " " +
dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit"});
else if (parts[3]==="F") time=dateInput.toLocaleString(void 0, {day: "numeric", month: "long", year: "numeric", weekday: "long"}) + " " +
dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit"});
else if (parts[3]==="t") time=dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit"});
else if (parts[3]==="T") time=dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit", second: "2-digit"});
else if (parts[3]==="R") time=Math.round((Date.now() - (Number.parseInt(parts[1]) * 1000))/1000/60) + " minutes ago";
}
const timeElem=document.createElement("span");
timeElem.classList.add("markdown-timestamp");
timeElem.textContent=time;
span.appendChild(timeElem);
continue;
}
}
if (txt[i] === "<" && (txt[i + 1] === ":" || (txt[i + 1] === "a" && txt[i + 2] === ":"))) {
let found=false;
const build = txt[i + 1] === "a" ? ["<","a",":"] : ["<",":"];
let j = i+build.length;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j]===">") {
found=true;
break;
}
}
if (found) {
const parts=build.join("").match(/^<(a)?:\w+:(\d{10,30})>$/);
if (parts && parts[2]) {
appendcurrent(); appendcurrent();
i=j; i=j;
console.log(typeof txt,txt); if(keep){
const isEmojiOnly = txt.join("").trim()===build.join("").trim(); build+="`".repeat(find);
}
const emojiElem=document.createElement("img"); if(count!==3&&!stdsize){
emojiElem.classList.add("md-emoji"); const samp=document.createElement("samp");
emojiElem.width=isEmojiOnly ? 48 : 22; samp.textContent=build;
emojiElem.height=isEmojiOnly ? 48 : 22; span.appendChild(samp);
emojiElem.crossOrigin="anonymous"; }else{
//emojiElem.src=this.info.cdn.toString() + "/emojis/" + parts[2] + "." + (parts[1] ? "gif" : "png") + "?size=32"; const pre=document.createElement("pre");
//must uncomment later if(build[build.length-1]==="\n"){
emojiElem.alt=""; build=build.substring(0,build.length-1);
emojiElem.loading="lazy"; }
span.appendChild(emojiElem); if(txt[i]==="\n"){
i++
}
pre.textContent=build;
span.appendChild(pre);
}
i--;
continue; continue;
} }
} }
if(txt[i]==="*"){
let count=1;
if(txt[i+1]==="*"){
count++;
if(txt[i+2]==="*"){
count++;
}
}
let build=[];
let find=0;
let j=i+count;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="*"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("*"));
find=0;
}
}
}
if(find===count&&(count!=1||txt[i+1]!==" ")){
appendcurrent();
i=j;
const stars="*".repeat(count);
if(count===1){
const i=document.createElement("i");
if(keep){i.append(stars)}
i.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){i.append(stars)}
span.appendChild(i);
}else if(count===2){
const b=document.createElement("b");
if(keep){b.append(stars)}
b.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){b.append(stars)}
span.appendChild(b);
}else{
const b=document.createElement("b");
const i=document.createElement("i");
if(keep){b.append(stars)}
b.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){b.append(stars)}
i.appendChild(b);
span.appendChild(i);
}
i--
continue;
}
}
if(txt[i]==="_"){
let count=1;
if(txt[i+1]==="_"){
count++;
if(txt[i+2]==="_"){
count++;
}
}
let build=[];
let find=0;
let j=i+count;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="_"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("_"));
find=0;
}
}
}
if(find===count&&(count!=1||(txt[j+1]===" "||txt[j+1]==="\n"||txt[j+1]===undefined))){
appendcurrent();
i=j;
const underscores="_".repeat(count);
if(count===1){
const i=document.createElement("i");
if(keep){i.append(underscores)}
i.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){i.append(underscores)}
span.appendChild(i);
}else if(count===2){
const u=document.createElement("u");
if(keep){u.append(underscores)}
u.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){u.append(underscores)}
span.appendChild(u);
}else{
const u=document.createElement("u");
const i=document.createElement("i");
if(keep){i.append(underscores)}
i.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){i.append(underscores)}
u.appendChild(i)
span.appendChild(u);
}
i--;
continue;
}
}
if(txt[i]==="~"&&txt[i+1]==="~"){
let count=2;
let build=[];
let find=0;
let j=i+2;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="~"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("~"));
find=0;
}
}
}
if(find===count){
appendcurrent();
i=j;
const tildes="~~";
if(count===2){
const s=document.createElement("s");
if(keep){s.append(tildes)}
s.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
if(keep){s.append(tildes)}
span.appendChild(s);
}
continue;
}
}
if(txt[i]==="|"&&txt[i+1]==="|"){
let count=2;
let build=[];
let find=0;
let j=i+2;
for(;txt[j]!==undefined&&find!==count;j++){
if(txt[j]==="|"){
find++;
}else{
build.push(txt[j]);
if(find!==0){
build=build.concat(new Array(find).fill("~"));
find=0;
}
}
}
if(find===count){
appendcurrent();
i=j;
const pipes="||";
if(count===2){
const j=document.createElement("j");
if(keep){j.append(pipes)}
j.appendChild(this.markdown(build,{keep:keep,stdsize:stdsize}));
j.classList.add("spoiler");
j.onclick=MarkDown.unspoil;
if(keep){j.append(pipes)}
span.appendChild(j);
}
continue;
}
}
if (txt[i]==="<" && txt[i + 1]==="t" && txt[i + 2]===":") {
let found=false;
const build=["<","t",":"];
let j = i+3;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j]===">") {
found=true;
break;
}
}
if (found) {
appendcurrent();
i=j;
const parts=build.join("").match(/^<t:([0-9]{1,16})(:([tTdDfFR]))?>$/);
const dateInput=new Date(Number.parseInt(parts[1]) * 1000);
let time="";
if (Number.isNaN(dateInput.getTime())) time=build.join("");
else {
if (parts[3]==="d") time=dateInput.toLocaleString(void 0, {day: "2-digit", month: "2-digit", year: "numeric"});
else if (parts[3]==="D") time=dateInput.toLocaleString(void 0, {day: "numeric", month: "long", year: "numeric"});
else if (!parts[3] || parts[3]==="f") time=dateInput.toLocaleString(void 0, {day: "numeric", month: "long", year: "numeric"}) + " " +
dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit"});
else if (parts[3]==="F") time=dateInput.toLocaleString(void 0, {day: "numeric", month: "long", year: "numeric", weekday: "long"}) + " " +
dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit"});
else if (parts[3]==="t") time=dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit"});
else if (parts[3]==="T") time=dateInput.toLocaleString(void 0, {hour: "2-digit", minute: "2-digit", second: "2-digit"});
else if (parts[3]==="R") time=Math.round((Date.now() - (Number.parseInt(parts[1]) * 1000))/1000/60) + " minutes ago";
}
const timeElem=document.createElement("span");
timeElem.classList.add("markdown-timestamp");
timeElem.textContent=time;
span.appendChild(timeElem);
continue;
}
}
if (txt[i] === "<" && (txt[i + 1] === ":" || (txt[i + 1] === "a" && txt[i + 2] === ":"))) {
let found=false;
const build = txt[i + 1] === "a" ? ["<","a",":"] : ["<",":"];
let j = i+build.length;
for (; txt[j] !== void 0; j++) {
build.push(txt[j]);
if (txt[j]===">") {
found=true;
break;
}
}
if (found) {
const buildjoin=build.join("");
const parts=buildjoin.match(/^<(a)?:\w+:(\d{10,30})>$/);
if (parts && parts[2]) {
appendcurrent();
i=j;
console.log(typeof txt,txt);
const isEmojiOnly = txt.join("").trim()===buildjoin.trim();
console.log(isEmojiOnly,":3");
const emojiElem=document.createElement("img");
emojiElem.classList.add("md-emoji");
emojiElem.classList.add(isEmojiOnly ? "bigemoji" : "smallemoji");
emojiElem.crossOrigin="anonymous";
emojiElem.src=this.info.cdn.toString() + "emojis/" + parts[2] + "." + (parts[1] ? "gif" : "png") + "?size=32";
emojiElem.alt=buildjoin;
emojiElem.loading="lazy";
span.appendChild(emojiElem);
continue;
}
}
}
current.textContent+=txt[i];
} }
appendcurrent();
current.textContent+=txt[i]; return span;
}
static unspoil(e:any) : void{
e.target.classList.remove("spoiler")
e.target.classList.add("unspoiled")
} }
appendcurrent();
return span;
}
markdown.unspoil=function(e:any) : void{
//console.log("undone")
e.target.classList.remove("spoiler")
e.target.classList.add("unspoiled")
} }

View file

@ -1,7 +1,7 @@
import {Contextmenu} from "./contextmenu.js"; import {Contextmenu} from "./contextmenu.js";
import {User} from "./user.js"; import {User} from "./user.js";
import {Member} from "./member.js"; import {Member} from "./member.js";
import {markdown} from "./markdown.js"; import {MarkDown} from "./markdown.js";
import {Embed} from "./embed.js"; import {Embed} from "./embed.js";
import { Channel } from "./channel.js"; import { Channel } from "./channel.js";
import {Localuser} from "./localuser.js"; import {Localuser} from "./localuser.js";
@ -21,7 +21,7 @@ class Message{
message_reference; message_reference;
type:number; type:number;
timestamp:number; timestamp:number;
content:string; content:MarkDown;
static del:Promise<void>; static del:Promise<void>;
static resolve:Function; static resolve:Function;
div:HTMLDivElement; div:HTMLDivElement;
@ -37,7 +37,7 @@ class Message{
} }
static setupcmenu(){ static setupcmenu(){
Message.contextmenu.addbutton("Copy raw text",function(){ Message.contextmenu.addbutton("Copy raw text",function(){
navigator.clipboard.writeText(this.content); navigator.clipboard.writeText(this.content.rawString);
}); });
Message.contextmenu.addbutton("Reply",function(this:Message,div:HTMLDivElement){ Message.contextmenu.addbutton("Reply",function(this:Message,div:HTMLDivElement){
this.channel.setReplying(this); this.channel.setReplying(this);
@ -67,6 +67,9 @@ class Message{
this.attachments.push(new File(thing,this)); this.attachments.push(new File(thing,this));
} }
continue; continue;
}else if(thing==="content"){
this.content=new MarkDown(messagejson[thing],this.channel);
continue;
} }
this[thing]=messagejson[thing]; this[thing]=messagejson[thing];
} }
@ -210,7 +213,7 @@ class Message{
replyline.classList.add("replyflex") replyline.classList.add("replyflex")
this.channel.getmessage(this.message_reference.message_id).then(message=>{ this.channel.getmessage(this.message_reference.message_id).then(message=>{
const author=message.author; const author=message.author;
reply.appendChild(markdown(message.content,{stdsize:true})); reply.appendChild(message.content.makeHTML({stdsize:true}));
minipfp.src=author.getpfpsrc() minipfp.src=author.getpfpsrc()
author.bind(minipfp); author.bind(minipfp);
username.textContent=author.username; username.textContent=author.username;
@ -271,7 +274,7 @@ class Message{
}else{ }else{
div.classList.remove("topMessage"); div.classList.remove("topMessage");
} }
const messaged=markdown(this.content); const messaged=this.content.makeHTML();
div["txt"]=messaged; div["txt"]=messaged;
const messagedwrap=document.createElement("div"); const messagedwrap=document.createElement("div");
messagedwrap.classList.add("flexttb") messagedwrap.classList.add("flexttb")

View file

@ -1359,3 +1359,11 @@ span {
.sizeupdown{ .sizeupdown{
height:4in; height:4in;
} }
.bigemoji{
width:48px;
height:48px;
}
.smallemoji{
width:22px;
height:22px;
}

View file

@ -1,6 +1,6 @@
//const usercache={}; //const usercache={};
import {Member} from "./member.js"; import {Member} from "./member.js";
import {markdown} from "./markdown.js"; import {MarkDown} from "./markdown.js";
import {Contextmenu} from "./contextmenu.js"; import {Contextmenu} from "./contextmenu.js";
import {Localuser} from "./localuser.js"; import {Localuser} from "./localuser.js";
import {Guild} from "./guild.js"; import {Guild} from "./guild.js";
@ -12,7 +12,7 @@ class User{
id:string; id:string;
avatar:string; avatar:string;
username:string; username:string;
bio:string; bio:MarkDown;
discriminator:string; discriminator:string;
pronouns:string; pronouns:string;
bot:boolean; bot:boolean;
@ -49,6 +49,10 @@ class User{
if(!owner){console.error("missing localuser")} if(!owner){console.error("missing localuser")}
if(dontclone){ if(dontclone){
for(const thing of Object.keys(userjson)){ for(const thing of Object.keys(userjson)){
if(thing==="bio"){
this.bio=new MarkDown(userjson[thing],this.localuser);
continue;
}
this[thing]=userjson[thing]; this[thing]=userjson[thing];
} }
this.hypotheticalpfp=false; this.hypotheticalpfp=false;
@ -152,7 +156,7 @@ class User{
const rule=document.createElement("hr"); const rule=document.createElement("hr");
userbody.appendChild(rule); userbody.appendChild(rule);
const biohtml=markdown(this.bio); const biohtml=this.bio.makeHTML();
userbody.appendChild(biohtml); userbody.appendChild(biohtml);
} }
console.log(div); console.log(div);