From 93197f8175e8543f0e3f57e53183562dc2b1a616 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Tue, 16 May 2023 18:17:25 +0400 Subject: [PATCH] Mostly fixed external links in the viewer iframe Before this fix clicking an external link in the viewer iframe had no effect (other than an error being reported in the browser dev tools console) because the attempt to navigate the top browser context was suppressed due to sandboxing - the click handling code changed the target of the link but navigating to that target was blocked. Now the click handler works as follows: 1. Changes the target of the link to the catch page only if the link is going to be opened in a new tab or window (in this case sandboxing restrictions do not apply). 2. Otherwise directly navigates the viewer window to external URL or the catch page. An unhandled scenario is opening an external link in a new tab/window via a middle click or context menu - such events cannot be intercepted and therefore there is no way of blocking external links accessed in the said way. --- static/skin/viewer.js | 18 ++++++++++++------ test/server.cpp | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/static/skin/viewer.js b/static/skin/viewer.js index a850b6693..0ad55ffbc 100644 --- a/static/skin/viewer.js +++ b/static/skin/viewer.js @@ -259,9 +259,10 @@ function matchingAncestorElement(el, context, selector) { const block_path = `${root}/catch/external`; -function blockLink(target) { - const encodedHref = encodeURIComponent(target.href); - target.setAttribute("href", block_path + "?source=" + encodedHref); +function blockLink(url) { + return viewerSettings.linkBlockingEnabled + ? block_path + "?source=" + encodeURIComponent(url) + : url; } function isExternalUrl(url) { @@ -278,9 +279,14 @@ function onClickEvent(e) { const target = matchingAncestorElement(e.target, iframeDocument, "a"); if (target !== null && "href" in target) { if ( isExternalUrl(target.href) ) { - target.setAttribute("target", "_top"); - if ( viewerSettings.linkBlockingEnabled ) { - return blockLink(target); + const possiblyBlockedLink = blockLink(target.href); + if ( e.ctrlKey || e.shiftKey ) { + // The link will be loaded in a new tab/window - update the link + // and let the browser handle the rest. + target.setAttribute("href", possiblyBlockedLink); + } else { + // Load the external URL in the viewer window (rather than iframe) + contentIframe.contentWindow.parent.location = possiblyBlockedLink; } } } diff --git a/test/server.cpp b/test/server.cpp index b48b488e2..f4f2ecb56 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -73,7 +73,7 @@ const ResourceCollection resources200Compressible{ { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" }, { STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=bbdaf425" }, { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" }, - { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=725c95a2" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=0c02871d" }, { 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" }, @@ -312,7 +312,7 @@ R"EXPECTEDRESULT( - + const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";