diff --git a/internal/assets/static/js/main.js b/internal/assets/static/js/main.js index ff26caa..106886d 100644 --- a/internal/assets/static/js/main.js +++ b/internal/assets/static/js/main.js @@ -1,6 +1,6 @@ import { setupPopovers } from './popover.js'; import { setupMasonries } from './masonry.js'; -import { throttledDebounce, isElementVisible } from './utils.js'; +import { throttledDebounce, isElementVisible, openURLInNewTab } from './utils.js'; async function fetchPageContent(pageData) { // TODO: handle non 200 status codes/time outs @@ -255,8 +255,23 @@ function setupGroups() { for (let t = 0; t < titles.length; t++) { const title = titles[t]; + + if (title.dataset.titleUrl !== undefined) { + title.addEventListener("auxclick", (event) => { + if (event.button != 1) { + return; + } + + openURLInNewTab(title.dataset.titleUrl); + }); + } + title.addEventListener("click", () => { if (t == current) { + if (title.dataset.titleUrl !== undefined) { + openURLInNewTab(title.dataset.titleUrl); + } + return; } diff --git a/internal/assets/static/js/utils.js b/internal/assets/static/js/utils.js index ddf7e4f..ae2f6e0 100644 --- a/internal/assets/static/js/utils.js +++ b/internal/assets/static/js/utils.js @@ -27,3 +27,7 @@ export function isElementVisible(element) { export function clamp(value, min, max) { return Math.min(Math.max(value, min), max); } + +export function openURLInNewTab(url) { + window.open(url, '_blank', 'noopener,noreferrer')?.focus(); +} diff --git a/internal/assets/templates/group.html b/internal/assets/templates/group.html index fe296fe..646df2f 100644 --- a/internal/assets/templates/group.html +++ b/internal/assets/templates/group.html @@ -6,7 +6,7 @@
{{ range $i, $widget := .Widgets }} - + {{ end }}