TeaWeb/shared/js/text/bbcode/url.tsx

116 lines
4.7 KiB
TypeScript
Raw Normal View History

2020-07-19 16:34:08 +02:00
import * as contextmenu from "tc-shared/ui/elements/ContextMenu";
import {copy_to_clipboard} from "tc-shared/utils/helpers";
import * as loader from "tc-loader";
import {ElementRenderer} from "vendor/xbbcode/renderer/base";
import {TagElement} from "vendor/xbbcode/elements";
import * as React from "react";
2020-12-21 19:13:25 +01:00
import ReactRenderer from "vendor/xbbcode/renderer/react";
import {rendererReact, rendererText, BBCodeHandlerContext} from "tc-shared/text/bbcode/renderer";
import {ClientTag} from "tc-shared/ui/tree/EntryTags";
2020-12-21 21:07:19 +01:00
import {isYoutubeLink, YoutubeRenderer} from "tc-shared/text/bbcode/youtube";
2020-07-19 16:34:08 +02:00
function spawnUrlContextMenu(pageX: number, pageY: number, target: string) {
contextmenu.spawn_context_menu(pageX, pageY, {
callback: () => {
const win = window.open(target, '_blank');
win.focus();
},
name: tr("Open URL"),
type: contextmenu.MenuEntryType.ENTRY,
icon_class: "client-browse-addon-online"
}, {
callback: () => {
//TODO
},
name: tr("Open URL in Browser"),
type: contextmenu.MenuEntryType.ENTRY,
visible: __build.target === "client" && false // Currently not possible
}, contextmenu.Entry.HR(), {
callback: () => copy_to_clipboard(target),
name: tr("Copy URL to clipboard"),
type: contextmenu.MenuEntryType.ENTRY,
icon_class: "client-copy"
});
}
const ClientUrlRegex = /client:\/\/([0-9]+)\/([-A-Za-z0-9+/=]+)~/g;
2020-07-19 16:34:08 +02:00
loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, {
name: "XBBCode code tag init",
function: async () => {
let reactId = 0;
const regexUrl = /^(?:[a-zA-Z]{1,16}):(?:\/{1,3}|\\)[-a-zA-Z0-9:;,@#%&()~_?+=\/\\.]*$/g;
rendererReact.registerCustomRenderer(new class extends ElementRenderer<TagElement, React.ReactNode> {
render(element: TagElement, renderer: ReactRenderer): React.ReactNode {
let target: string;
if (!element.options) {
2020-07-19 16:34:08 +02:00
target = rendererText.render(element);
} else {
2020-07-19 16:34:08 +02:00
target = element.options;
}
2020-07-19 16:34:08 +02:00
regexUrl.lastIndex = 0;
if (!regexUrl.test(target)) {
2020-07-19 16:34:08 +02:00
target = '#';
}
2020-12-21 18:10:16 +01:00
return (
<BBCodeHandlerContext.Consumer key={"er-" + ++reactId}>
{handlerId => {
if(handlerId) {
/* TS3-Protocol for a client */
if(target.match(ClientUrlRegex)) {
const clientData = target.match(ClientUrlRegex);
const clientDatabaseId = parseInt(clientData[1]);
const clientUniqueId = clientDatabaseId[2];
2020-12-21 18:10:16 +01:00
return <ClientTag
key={"er-" + ++reactId}
clientName={rendererText.renderContent(element).join("")}
clientUniqueId={clientUniqueId}
clientDatabaseId={clientDatabaseId > 0 ? clientDatabaseId : undefined}
handlerId={handlerId}
/>;
}
}
2020-12-21 21:07:19 +01:00
const body = (
2020-12-21 18:10:16 +01:00
<a key={"er-" + ++reactId} className={"xbbcode xbbcode-tag-url"} href={target} target={"_blank"} onContextMenu={event => {
event.preventDefault();
spawnUrlContextMenu(event.pageX, event.pageY, target);
}}>
{renderer.renderContent(element)}
</a>
);
2020-12-21 21:07:19 +01:00
if(isYoutubeLink(target)) {
return (
<YoutubeRenderer url={target}>{body}</YoutubeRenderer>
);
} else {
return body;
}
2020-12-21 18:10:16 +01:00
}}
</BBCodeHandlerContext.Consumer>
);
2020-07-19 16:34:08 +02:00
}
tags(): string | string[] {
return "url";
}
});
},
priority: 10
});
export function fixupJQueryUrlTags(container: JQuery) {
container.find("a").on('contextmenu', event => {
if(event.isDefaultPrevented())
return;
event.preventDefault();
spawnUrlContextMenu(event.pageX, event.pageY, $(event.target).attr("href"));
});
}