From 555d39c8486ddd5f50c9ddbb2a39cde5dacddf2e Mon Sep 17 00:00:00 2001
From: Max Nikulin
Date: Wed, 23 Oct 2024 12:52:41 +0700
Subject: [PATCH] Make the webNavigation permission optional
Capture quality may be silently degraded if the permission
is not granted. No attempt to get active subframe is performed.
---
README.org | 5 +++--
background/lr_settings.js | 17 +++++++++++++++++
background/lr_tabframe.js | 29 ++++++++++++++++++++++++-----
manifest-chrome.json | 4 ++--
manifest-common.yaml | 2 +-
manifest-firefox.json | 2 +-
pages/lrp_help.html | 11 +++++++----
7 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/README.org b/README.org
index de81a9c..998a6e3 100644
--- a/README.org
+++ b/README.org
@@ -426,8 +426,9 @@ Chrome: "Read your browsing history".
It is necessary to reliably restore tree of nested frames.
Consider the case when some element is focused in a subframe
and capture is invoked using keyboard shortcut.
-Maybe I will add a less reliable fallback in future
-to make this permission optional.
+Another case is context menu invoked in a deeply nested frame.
+
+You may grant this permission on the extension options page.[fn:3]
*** Access browser tabs (=tabs=)
:PROPERTIES:
diff --git a/background/lr_settings.js b/background/lr_settings.js
index 02de16a..699793e 100644
--- a/background/lr_settings.js
+++ b/background/lr_settings.js
@@ -276,6 +276,23 @@ var lr_settings = lr_util.namespace(lr_settings, function lr_settings() {
host: true,
parent: "misc",
});
+ this.registerOption({
+ name: "permissions.webNavigation",
+ title: 'Access browser activity during navigation ("webNavigation")',
+ version: "0.4",
+ description: [
+ "Relevant to frames and embedded objects.",
+ "Without this permission the extension may be unable",
+ "to find active frame when invoked using",
+ "the toolbar button or the shortcut.",
+ "",
+ "Context menu is affected in less degree,",
+ "but capture info may still be incomplete",
+ "in the case of multiple level of nested frames."
+ ],
+ type: "permission",
+ parent: "misc",
+ });
};
this.load = async function() {
diff --git a/background/lr_tabframe.js b/background/lr_tabframe.js
index d79f640..3ad1ddc 100644
--- a/background/lr_tabframe.js
+++ b/background/lr_tabframe.js
@@ -40,6 +40,25 @@ var lr_tabframe = lr_util.namespace(lr_tabframe, function lr_tabframe() {
};
}
+ lr_tabframe._hasWebNavigationPermission = async function _hasWebNavigationPermission() {
+ if (chrome.webNavigation?.getAllFrames === undefined) {
+ return false;
+ }
+ // Chromium-130 throws synchronously after `permissions.remove`
+ // chrome.webNavigation.getAllFrames({tabId: -1})
+ // Error: 'webNavigation.getAllFrames' is not available in this context.
+ //
+ // If the permission is not available
+ //
+ // TypeError: Error in invocation of webNavigation.getAllFrames(object details, function callback): Error at parameter 'details': Error at property 'tabId': Value must be at least 0.
+ try {
+ return await bapi.permissions.contains({ permissions: [ "webNavigation" ] });
+ } catch (ex) {
+ Promise.reject(ex);
+ }
+ return false;
+ }
+
Object.assign(this, {
FORMAT, VERSION,
makeCapture,
@@ -147,7 +166,7 @@ function focusedFrameChain(frameMap) {
async function lrGetAllFrames(tab) {
// Likely redundant protection, tab should be valid here
const tabId = tab != null ? tab.id : -1;
- if (!(tabId >= 0)) {
+ if (!(tabId >= 0) || ! await lr_tabframe._hasWebNavigationPermission()) {
// May happen in Chromium-87 when context menu is invoked for a PDF file
// but should be handled by caller since
@@ -727,7 +730,7 @@
-
Created: 2024-10-26 Sat 08:07
+
Created: 2024-10-26 Sat 08:08