From 93197f8175e8543f0e3f57e53183562dc2b1a616 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Tue, 16 May 2023 18:17:25 +0400 Subject: [PATCH 1/2] 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"; From 96fb65f56058d91d3e1da1bc5ce172f2fab4ed59 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Sat, 20 May 2023 15:48:45 +0400 Subject: [PATCH 2/2] Guaranteed activation of external link blocking This is a quickfix for the problem observed with external link blocking during certain history navigation actions (when the cached iframe content is loaded/restored before the viewer setup is completed). Since external link blocking doesn't depend on the translations (that are asynchronously loaded during the viewer setup) it can be performed unconditionally. However, the current dependence of `on_content_load()` on viewer setup has to be addressed too. --- static/skin/viewer.js | 2 +- test/server.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/static/skin/viewer.js b/static/skin/viewer.js index 0ad55ffbc..ca49833fa 100644 --- a/static/skin/viewer.js +++ b/static/skin/viewer.js @@ -335,8 +335,8 @@ let viewerSetupComplete = false; function on_content_load() { if ( viewerSetupComplete ) { handle_content_url_change(); - setup_external_link_blocker(); } + setup_external_link_blocker(); } function htmlDecode(input) { diff --git a/test/server.cpp b/test/server.cpp index f4f2ecb56..53ee47df1 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=0c02871d" }, + { STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=cb9b1f75" }, { 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";