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 .

-

-
- -