From b55b6af0071cdaa0554bc11f25e5d8cda940e584 Mon Sep 17 00:00:00 2001
From: Kevin R
Date: Sat, 11 Nov 2023 17:49:00 +0100
Subject: [PATCH] Migration to MV3
---
clearurls.js | 6 ++++
core_js/badgedHandler.js | 4 +--
core_js/context_menu.js | 53 ++++++++++++++-------------------
core_js/historyListener.js | 40 +++++++++++++++----------
core_js/settings.js | 5 +---
core_js/storage.js | 24 +++++++--------
core_js/tools.js | 10 +++----
core_js/watchdog.js | 17 ++++++-----
external_js/clipboard-helper.js | 16 ----------
html/settings.html | 7 -----
manifest.json | 19 +++++++-----
11 files changed, 96 insertions(+), 105 deletions(-)
delete mode 100644 external_js/clipboard-helper.js
diff --git a/clearurls.js b/clearurls.js
index 66a4aee..f2d820f 100644
--- a/clearurls.js
+++ b/clearurls.js
@@ -727,3 +727,9 @@ function start() {
["blocking"]
);
}
+
+// TODO: Must be asked after install
+browser.permissions.request({
+ permissions: ["webRequest", "webRequestBlocking", "tabs", "scripting", "webNavigation"],
+ origins: [""],
+});
diff --git a/core_js/badgedHandler.js b/core_js/badgedHandler.js
index 61d0ad4..a5723f5 100644
--- a/core_js/badgedHandler.js
+++ b/core_js/badgedHandler.js
@@ -48,9 +48,9 @@ function increaseBadged(quiet = false, request) {
checkOSAndroid().then((res) => {
if (!res) {
if (storage.badgedStatus && !quiet) {
- browser.browserAction.setBadgeText({text: (badges[tabId]).counter.toString(), tabId: tabId}).catch(handleError);
+ browser.action.setBadgeText({text: (badges[tabId]).counter.toString(), tabId: tabId}).catch(handleError);
} else {
- browser.browserAction.setBadgeText({text: "", tabId: tabId}).catch(handleError);
+ browser.action.setBadgeText({text: "", tabId: tabId}).catch(handleError);
}
}
});
diff --git a/core_js/context_menu.js b/core_js/context_menu.js
index 7626303..517b92c 100644
--- a/core_js/context_menu.js
+++ b/core_js/context_menu.js
@@ -22,36 +22,29 @@
* and based on: https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
*/
-function contextMenuStart() {
- if(storage.contextMenuEnabled) {
- browser.contextMenus.create({
- id: "copy-link-to-clipboard",
- title: translate("clipboard_copy_link"),
- contexts: ["link"]
- });
+browser.runtime.onInstalled.addListener(contextMenuStart);
- browser.contextMenus.onClicked.addListener((info, tab) => {
- if (info.menuItemId === "copy-link-to-clipboard") {
- const url = pureCleaning(info.linkUrl);
- const code = "copyToClipboard(" +
- JSON.stringify(url)+");";
+function contextMenuStart(details) {
+ browser.contextMenus.create({
+ id: "copy-link-to-clipboard",
+ title: translate("clipboard_copy_link"),
+ contexts: ["link"]
+ });
- browser.tabs.executeScript({
- code: "typeof copyToClipboard === 'function';",
- }).then((results) => {
- if (!results || results[0] !== true) {
- return browser.tabs.executeScript(tab.id, {
- file: "/external_js/clipboard-helper.js",
- }).catch(handleError);
- }
- }).then(() => {
- return browser.tabs.executeScript(tab.id, {
- code,
- });
- }).catch((error) => {
- console.error("Failed to copy text: " + error);
- });
- }
- });
- }
+ browser.contextMenus.onClicked.addListener((info, tab) => {
+ if (info.menuItemId === "copy-link-to-clipboard") {
+ const url = pureCleaning(info.linkUrl);
+
+ browser.scripting.executeScript({
+ target: {
+ tabId: tab.id,
+ allFrames: true
+ },
+ func: (text) => navigator.clipboard.writeText(text),
+ args: [
+ url
+ ]
+ });
+ }
+ });
}
diff --git a/core_js/historyListener.js b/core_js/historyListener.js
index 5248d1a..d576ff4 100644
--- a/core_js/historyListener.js
+++ b/core_js/historyListener.js
@@ -17,35 +17,45 @@
*/
/*jshint esversion: 6 */
+
/*
* This script is responsible for listen on history changes.
* This technique is often used to inject tracking code into the location bar,
* because all feature events will use the updated URL.
*/
+browser.webNavigation.onHistoryStateUpdated.addListener(historyCleaner);
+
function historyListenerStart() {
- if(storage.historyListenerEnabled) {
- browser.webNavigation.onHistoryStateUpdated.addListener(historyCleaner);
- }
+
}
/**
-* Function that is triggered on history changes. Injects script into page
-* to clean links that were pushed to the history stack with the
-* history.replaceState method.
-* @param {state object} details The state object is a JavaScript object
-* which is associated with the new history entry created by replaceState()
-*/
+ * Function that is triggered on history changes. Injects script into page
+ * to clean links that were pushed to the history stack with the
+ * history.replaceState method.
+ * @param {state object} details The state object is a JavaScript object
+ * which is associated with the new history entry created by replaceState()
+ */
function historyCleaner(details) {
- if(storage.globalStatus) {
+ if (storage.globalStatus && storage.historyListenerEnabled) {
const urlBefore = details.url;
const urlAfter = pureCleaning(details.url);
- if(urlBefore !== urlAfter) {
- browser.tabs.executeScript(details.tabId, {
- frameId: details.frameId,
- code: 'history.replaceState({state: null},"",'+JSON.stringify(urlAfter)+');'
- }).then(() => {}, onError);
+ if (urlBefore !== urlAfter) {
+ browser.scripting.executeScript({
+ target: {
+ tabId: details.tabId,
+ frameIds: [
+ details.frameId
+ ]
+ },
+ func: (url) => history.replaceState({state: null}, "", url),
+ args: [
+ urlAfter
+ ]
+ }).then(() => {
+ }, onError);
}
}
}
diff --git a/core_js/settings.js b/core_js/settings.js
index 3e6162d..eee7507 100644
--- a/core_js/settings.js
+++ b/core_js/settings.js
@@ -132,8 +132,7 @@ function getData() {
}
}).catch(handleError);
- loadData("contextMenuEnabled")
- .then(() => loadData("historyListenerEnabled"))
+ loadData("historyListenerEnabled")
.then(() => loadData("localHostsSkipping"))
.then(() => loadData("referralMarketing"))
.then(() => loadData("domainBlocking"))
@@ -142,7 +141,6 @@ function getData() {
.then(() => {
changeSwitchButton("localHostsSkipping", "localHostsSkipping");
changeSwitchButton("historyListenerEnabled", "historyListenerEnabled");
- changeSwitchButton("contextMenuEnabled", "contextMenuEnabled");
changeSwitchButton("referralMarketing", "referralMarketing");
changeSwitchButton("domainBlocking", "domainBlocking");
changeSwitchButton("pingBlocking", "pingBlocking");
@@ -219,7 +217,6 @@ function setText() {
document.getElementById('types_label').innerHTML = translate('setting_types_label');
document.getElementById('save_settings_btn').textContent = translate('settings_html_save_button');
document.getElementById('save_settings_btn').setAttribute('title', translate('settings_html_save_button_title'));
- injectText("context_menu_enabled", "context_menu_enabled");
document.getElementById('history_listener_enabled').innerHTML = translate('history_listener_enabled');
injectText("local_hosts_skipping", "local_hosts_skipping");
document.getElementById('export_settings_btn_text').textContent = translate('setting_html_export_button');
diff --git a/core_js/storage.js b/core_js/storage.js
index ccfb980..a2f0698 100644
--- a/core_js/storage.js
+++ b/core_js/storage.js
@@ -86,7 +86,7 @@ function saveOnDisk(keys) {
}
/**
- * Schedule to save a key to disk in 30 seconds.
+ * Schedule to save a key to disk in 60 seconds.
* @param {String} key
*/
function deferSaveOnDisk(key) {
@@ -95,13 +95,20 @@ function deferSaveOnDisk(key) {
return;
}
- setTimeout(function () {
+ browser.alarms.create("deferSaveOnDisk", {
+ delayInMinutes: 1
+ });
+
+ hasPendingSaves = true;
+}
+
+browser.alarms.onAlarm.addListener(function (alarmInfo) {
+ if (alarmInfo.name === "deferSaveOnDisk") {
saveOnDisk(Array.from(pendingSaves));
pendingSaves.clear();
hasPendingSaves = false;
- }, 30000);
- hasPendingSaves = true;
-}
+ }
+});
/**
* Start sequence for ClearURLs.
@@ -115,12 +122,6 @@ function genesis() {
//Set correct icon on startup
changeIcon();
-
- // Start the context_menu
- contextMenuStart();
-
- // Start history listener
- historyListenerStart();
}, handleError);
}
@@ -216,7 +217,6 @@ function initSettings() {
storage.badged_color = "#ffa500";
storage.hashURL = "https://rules2.clearurls.xyz/rules.minify.hash";
storage.ruleURL = "https://rules2.clearurls.xyz/data.minify.json";
- storage.contextMenuEnabled = true;
storage.historyListenerEnabled = true;
storage.localHostsSkipping = true;
storage.referralMarketing = false;
diff --git a/core_js/tools.js b/core_js/tools.js
index 9e087b6..f8abd5b 100644
--- a/core_js/tools.js
+++ b/core_js/tools.js
@@ -181,9 +181,9 @@ function changeIcon() {
checkOSAndroid().then((res) => {
if (!res) {
if (storage.globalStatus) {
- browser.browserAction.setIcon({path: "img/clearurls_128x128.png"}).catch(handleError);
+ browser.action.setIcon({path: "img/clearurls_128x128.png"}).catch(handleError);
} else {
- browser.browserAction.setIcon({path: "img/clearurls_gray_128x128.png"}).catch(handleError);
+ browser.action.setIcon({path: "img/clearurls_gray_128x128.png"}).catch(handleError);
}
}
});
@@ -200,13 +200,13 @@ function setBadgedStatus() {
let color = storage.badged_color;
if (storage.badged_color.charAt(0) !== '#')
color = '#' + storage.badged_color;
- browser.browserAction.setBadgeBackgroundColor({
+ browser.action.setBadgeBackgroundColor({
'color': color
}).catch(handleError);
- // Works only in Firefox: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/setBadgeTextColor#Browser_compatibility
+ // Works only in Firefox: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action/setBadgeTextColor#Browser_compatibility
if (getBrowser() === "Firefox") {
- browser.browserAction.setBadgeTextColor({
+ browser.action.setBadgeTextColor({
color: "#FFFFFF"
}).catch(handleError);
}
diff --git a/core_js/watchdog.js b/core_js/watchdog.js
index c966308..e9b66f5 100644
--- a/core_js/watchdog.js
+++ b/core_js/watchdog.js
@@ -24,20 +24,23 @@
*
* This watchdog restarts the whole Add-on, when the check fails.
*/
-const CHECK_INTERVAL = 60000;
const __dirtyURL = "https://clearurls.roebert.eu?utm_source=addon";
const __cleanURL = new URL("https://clearurls.roebert.eu").toString();
-setInterval(function() {
- if(isStorageAvailable() && storage.globalStatus) {
- if(new URL(pureCleaning(__dirtyURL, true)).toString() !== __cleanURL) {
+browser.alarms.create("watchdog", {
+ periodInMinutes: 1,
+});
+
+browser.alarms.onAlarm.addListener(function (alarmInfo) {
+ if (alarmInfo.name === "watchdog" && isStorageAvailable() && storage.globalStatus) {
+ if (new URL(pureCleaning(__dirtyURL, true)).toString() !== __cleanURL) {
storage.watchDogErrorCount += 1;
console.log(translate('watchdog', storage.watchDogErrorCount));
saveOnExit();
- if(storage.watchDogErrorCount < 3) reload();
- } else if(storage.watchDogErrorCount > 0){
+ if (storage.watchDogErrorCount < 3) reload();
+ } else if (storage.watchDogErrorCount > 0) {
storage.watchDogErrorCount = 0;
saveOnExit();
}
}
-}, CHECK_INTERVAL);
+});
diff --git a/external_js/clipboard-helper.js b/external_js/clipboard-helper.js
deleted file mode 100644
index 49aa673..0000000
--- a/external_js/clipboard-helper.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Source: https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
- */
-function copyToClipboard(text) {
- function oncopy(event) {
- document.removeEventListener("copy", oncopy, true);
-
- event.stopImmediatePropagation();
-
- event.preventDefault();
- event.clipboardData.setData("text/plain", text);
- }
- document.addEventListener("copy", oncopy, true);
-
- document.execCommand("copy");
-}
diff --git a/html/settings.html b/html/settings.html
index f28ded9..2ea2641 100644
--- a/html/settings.html
+++ b/html/settings.html
@@ -136,13 +136,6 @@ along with this program. If not, see .
-
-
-
-