TeaWeb/shared/js/text/chat.ts

97 lines
3 KiB
TypeScript
Raw Normal View History

2020-12-07 15:07:47 +01:00
import UrlKnife from 'url-knife';
import {Settings, settings} from "../settings";
import {renderMarkdownAsBBCode} from "../text/markdown";
import {escapeBBCode} from "../text/bbcode";
2020-12-07 15:22:39 +01:00
import {parse as parseBBCode} from "vendor/xbbcode/parser";
import {TagElement} from "vendor/xbbcode/elements";
2020-07-19 16:34:08 +02:00
2020-12-07 15:07:47 +01:00
interface UrlKnifeUrl {
value: {
url: string,
},
area: string,
index: {
start: number,
end: number
}
}
2020-07-19 16:34:08 +02:00
2020-12-07 15:22:39 +01:00
function bbcodeLinkUrls(message: string, ignore: { start: number, end: number }[]) : string {
2020-12-07 15:07:47 +01:00
const urls: UrlKnifeUrl[] = UrlKnife.TextArea.extractAllUrls(message, {
'ip_v4' : true,
'ip_v6' : false,
'localhost' : false,
'intranet' : true
});
2020-07-19 16:34:08 +02:00
2020-12-07 15:07:47 +01:00
/* we want to go through the urls from the back to the front */
urls.sort((a, b) => b.index.start - a.index.start);
for(const url of urls) {
2020-12-07 15:22:39 +01:00
if(ignore.findIndex(range => range.start <= url.index.start && range.end >= url.index.end) !== -1) {
continue;
}
2020-12-07 15:07:47 +01:00
const prefix = message.substr(0, url.index.start);
const suffix = message.substr(url.index.end);
const urlPath = message.substring(url.index.start, url.index.end);
let bbcodeUrl;
let colonIndex = urlPath.indexOf(":");
if(colonIndex === -1 || colonIndex + 2 < urlPath.length || urlPath[colonIndex + 1] !== "/" || urlPath[colonIndex + 2] !== "/") {
bbcodeUrl = "[url=https://" + urlPath + "]" + urlPath + "[/url]";
} else {
bbcodeUrl = "[url]" + urlPath + "[/url]";
2020-07-19 16:34:08 +02:00
}
2020-12-07 15:07:47 +01:00
message = prefix + bbcodeUrl + suffix;
2020-07-19 16:34:08 +02:00
}
2020-12-07 15:07:47 +01:00
return message;
2020-07-19 16:34:08 +02:00
}
export function preprocessChatMessageForSend(message: string) : string {
2020-12-07 15:07:47 +01:00
const parseMarkdown = settings.static_global(Settings.KEY_CHAT_ENABLE_MARKDOWN);
const escapeBBCodes = !settings.static_global(Settings.KEY_CHAT_ENABLE_BBCODE);
2020-07-19 16:34:08 +02:00
2020-12-07 15:07:47 +01:00
if(parseMarkdown) {
2020-12-07 15:22:39 +01:00
message = renderMarkdownAsBBCode(message, text => escapeBBCodes ? escapeBBCode(text) : text);
} else if(escapeBBCodes) {
message = escapeBBCode(message);
}
if(settings.static_global(Settings.KEY_CHAT_TAG_URLS)) {
const bbcodeElements = parseBBCode(message, {});
const noParseRanges: { start: number, end: number }[] = [];
while(true) {
const element = bbcodeElements.pop();
if(!element) {
break;
2020-12-07 15:07:47 +01:00
}
2020-07-19 16:34:08 +02:00
2020-12-07 15:22:39 +01:00
if(!(element instanceof TagElement)) {
continue;
2020-12-07 15:07:47 +01:00
}
2020-07-19 16:34:08 +02:00
2020-12-07 15:22:39 +01:00
switch(element.tagType?.tag) {
case "code":
case "i-code":
case "url":
case "img":
case "no-parse":
case "youtube":
case "quote":
noParseRanges.push(element.textPosition);
break;
2020-07-19 16:34:08 +02:00
2020-12-07 15:22:39 +01:00
default:
bbcodeElements.push(...element.content);
break;
}
2020-12-07 15:07:47 +01:00
}
2020-07-19 16:34:08 +02:00
2020-12-07 15:22:39 +01:00
message = bbcodeLinkUrls(message, noParseRanges);
2020-12-07 15:07:47 +01:00
}
2020-12-07 15:22:39 +01:00
return message;
2020-07-19 16:34:08 +02:00
}