diff --git a/static/skin/viewer.js b/static/skin/viewer.js
index 8beec989..4da7a895 100644
--- a/static/skin/viewer.js
+++ b/static/skin/viewer.js
@@ -310,6 +310,12 @@ function blockLink(url) {
: url;
}
+function urlMustBeHandledByAnExternalApp(url) {
+ const WHITELISTED_URL_SCHEMATA = ['http:', 'https:', 'about:', 'javascript:'];
+
+ return WHITELISTED_URL_SCHEMATA.indexOf(url.protocol) == -1;
+}
+
function isExternalUrl(url) {
if ( url.startsWith(window.location.origin) )
return false;
@@ -334,7 +340,13 @@ function onClickEvent(e) {
const target = matchingAncestorElement(e.target, iframeDocument, "a");
if (target !== null && "href" in target) {
const target_href = getRealHref(target);
- if (isExternalUrl(target_href)) {
+ const target_url = new URL(target_href, iframeDocument.location);
+ const isExternalAppUrl = urlMustBeHandledByAnExternalApp(target_url);
+ if ( isExternalAppUrl && !viewerSettings.linkBlockingEnabled ) {
+ target.setAttribute("target", "_blank");
+ }
+
+ if (isExternalAppUrl || isExternalUrl(target_href)) {
const possiblyBlockedLink = blockLink(target_href);
if ( e.ctrlKey || e.shiftKey ) {
// The link will be loaded in a new tab/window - update the link
@@ -343,6 +355,7 @@ function onClickEvent(e) {
} else {
// Load the external URL in the viewer window (rather than iframe)
contentIframe.contentWindow.parent.location = possiblyBlockedLink;
+ e.preventDefault();
}
}
}
diff --git a/test/server.cpp b/test/server.cpp
index e7b5714f..555ba3c1 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -75,7 +75,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=80d56607" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
- { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=5fc4badf" },
+ { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=215635fd" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
@@ -324,7 +324,7 @@ R"EXPECTEDRESULT(
-
+
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";