diff --git a/ChangeLog.md b/ChangeLog.md index 3d1b42cc..53d01a9d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -5,6 +5,7 @@ - Added proper BBCode support for lazy close tags - Improved the URL detecting and replace support (Reduced false positives and proper protocol checking) - Adding support for list bb codes and background color + - Fixed a bug where `code` and `noparse` areas got parsed by the bbcode url parser - Fixed some minor BBCode parser bugs - Fixed BBCode inline code style - URL tags can not contain any other tags diff --git a/pkg/index.js b/pkg/index.js new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/text/chat.ts b/shared/js/text/chat.ts index e043094d..2b115f11 100644 --- a/shared/js/text/chat.ts +++ b/shared/js/text/chat.ts @@ -2,6 +2,8 @@ import UrlKnife from 'url-knife'; import {Settings, settings} from "../settings"; import {renderMarkdownAsBBCode} from "../text/markdown"; import {escapeBBCode} from "../text/bbcode"; +import {parse as parseBBCode} from "vendor/xbbcode/parser"; +import {TagElement} from "vendor/xbbcode/elements"; interface UrlKnifeUrl { value: { @@ -14,7 +16,7 @@ interface UrlKnifeUrl { } } -function bbcodeLinkUrls(message: string) : string { +function bbcodeLinkUrls(message: string, ignore: { start: number, end: number }[]) : string { const urls: UrlKnifeUrl[] = UrlKnife.TextArea.extractAllUrls(message, { 'ip_v4' : true, 'ip_v6' : false, @@ -25,6 +27,10 @@ function bbcodeLinkUrls(message: string) : string { /* 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) { + if(ignore.findIndex(range => range.start <= url.index.start && range.end >= url.index.end) !== -1) { + continue; + } + 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); @@ -44,31 +50,48 @@ function bbcodeLinkUrls(message: string) : string { } export function preprocessChatMessageForSend(message: string) : string { - const processUrls = settings.static_global(Settings.KEY_CHAT_TAG_URLS); const parseMarkdown = settings.static_global(Settings.KEY_CHAT_ENABLE_MARKDOWN); const escapeBBCodes = !settings.static_global(Settings.KEY_CHAT_ENABLE_BBCODE); if(parseMarkdown) { - return renderMarkdownAsBBCode(message, text => { - if(escapeBBCodes) { - text = escapeBBCode(text); - } - - if(processUrls) { - text = bbcodeLinkUrls(text); - } - - return text; - }); - } else { - if(escapeBBCodes) { - message = escapeBBCode(message); - } - - if(processUrls) { - message = bbcodeLinkUrls(message); - } - - return message; + 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; + } + + if(!(element instanceof TagElement)) { + continue; + } + + 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; + + default: + bbcodeElements.push(...element.content); + break; + } + } + + message = bbcodeLinkUrls(message, noParseRanges); + } + + return message; } \ No newline at end of file diff --git a/shared/js/text/markdown.ts b/shared/js/text/markdown.ts index 4a7b1643..4660c957 100644 --- a/shared/js/text/markdown.ts +++ b/shared/js/text/markdown.ts @@ -88,8 +88,9 @@ export class MD2BBCodeRenderer { "ins_open": () => "[u]", "ins_close": () => "[/u]", - "code": (renderer: MD2BBCodeRenderer, token: CodeToken) => "[i-code]" + escapeBBCode(token.content) + "[/i-code]", - "fence": (renderer: MD2BBCodeRenderer, token: FenceToken) => "[code" + (token.params ? ("=" + token.params) : "") + "]" + escapeBBCode(token.content) + "[/code]", + //[code]teaspeak.de[/code] + "code": (renderer: MD2BBCodeRenderer, token: CodeToken) => "[i-code]" + token.content + "[/i-code]", + "fence": (renderer: MD2BBCodeRenderer, token: FenceToken) => "[code" + (token.params ? ("=" + token.params) : "") + "]" + token.content + "[/code]", "heading_open": (renderer: MD2BBCodeRenderer, token: HeadingOpenToken) => "[size=" + (9 - Math.min(4, token.hLevel)) + "]", "heading_close": () => "[/size][hr]",