From 703a907aedae4d5e6a2171b177f8aad690ca1889 Mon Sep 17 00:00:00 2001 From: NeverDecaf Date: Wed, 22 Nov 2023 09:30:54 -0500 Subject: [PATCH] Improve integration with new chrome web store --- Chromium Web Store.crx | Bin 58397 -> 60872 bytes src/_locales/en/messages.json | 8 +++ src/manifest.json | 11 +++- src/options.html | 58 ++++++++++++++---- src/scripts/background.js | 109 ++++++++++++++++++++++++++++++++++ src/scripts/chromeApi.js | 97 ++++++++++++++++++++++++++++++ src/scripts/inject.js | 57 +++++++----------- src/scripts/util.js | 3 +- 8 files changed, 294 insertions(+), 49 deletions(-) create mode 100644 src/scripts/chromeApi.js diff --git a/Chromium Web Store.crx b/Chromium Web Store.crx index 6c7311c5c683f7c93368a6d86f5d6021666370e9..63e317f3b5ff6f93db974b901fa6398ffe58826e 100644 GIT binary patch delta 14080 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 delta 11617 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
-

Update Options

+

+ Update Options +

-

Ignored Extensions

-
+

+ Ignored Extensions +

+

Advanced


+
-

Import / Export

+

+ Import / Export +

- +
diff --git a/src/scripts/background.js b/src/scripts/background.js index c3822ec..9777ba6 100644 --- a/src/scripts/background.js +++ b/src/scripts/background.js @@ -202,3 +202,112 @@ chrome.downloads.onChanged.addListener((d) => { } }); chrome.contextMenus.onClicked.addListener(handleContextClick); + +// below functions are for the new chrome web store: +// port is used for functions with callbacks: +chrome.runtime.onConnectExternal.addListener((port) => { + var port_disconnected = false; + port.onDisconnect.addListener(() => { + port_disconnected = true; + }); + port.onMessage.addListener(function (msg, port) { + // console.log("recieved msg through port:", msg); + switch (msg.func) { + case "onInstalled": + var [callback, ..._] = msg.args; + chrome.management.onInstalled.addListener(function cb() { + if (port_disconnected) { + chrome.management.onInstalled.removeListener(cb); + return; + } + port.postMessage({ + args: arguments, + callbackIndex: callback, + err: chrome.runtime.lastError, + }); + }); + break; + case "onUninstalled": + var [callback, ..._] = msg.args; + chrome.management.onUninstalled.addListener(function cb() { + if (port_disconnected) { + chrome.management.onUninstalled.removeListener(cb); + return; + } + port.postMessage({ + args: arguments, + callbackIndex: callback, + err: chrome.runtime.lastError, + }); + }); + break; + case "uninstall": + var [ext_id, options, callback, ..._] = msg.args; + chrome.management.uninstall(ext_id, options, function () { + port.postMessage({ + args: arguments, + callbackIndex: callback, + err: chrome.runtime.lastError, + }); + }); + break; + case "setEnabled": + var [ext_id, enabled, callback, ..._] = msg.args; + chrome.management.setEnabled(ext_id, enabled, function () { + port.postMessage({ + args: arguments, + callbackIndex: callback, + err: chrome.runtime.lastError, + }); + }); + break; + } + }); +}); +chrome.runtime.onMessageExternal.addListener(function ( + request, + sender, + sendResponse, +) { + // console.log("recieved msg through runtime:", request); + switch (request.func) { + case "getExtensionStatus": + var [id, ext, ..._] = request.args; + chrome.management.getAll((exts) => { + const this_ext = exts.filter((extInfo) => extInfo.id === id); + if (!this_ext.length) { + sendResponse({ args: ["installable"] }); + return; + } + sendResponse({ + args: [this_ext[0].enabled ? "enabled" : "disabled"], + }); + }); + break; + case "getAll": + var [id, ..._] = request.args; + chrome.management.getAll((exts) => { + // instead of exposing entire extension list, filter to only the relevant extension. + sendResponse({ + args: [exts.filter((extInfo) => extInfo.id === id)], + }); + }); + break; + case "beginInstallWithManifest3": + var [extInfo, href, ..._] = request.args; + + promptInstall( + buildExtensionUrl(href), + true, + WEBSTORE.chrome, + msgHandler, + ); + sendResponse({ + // because a "cancel" in the context of chromium-web-store won't be detected, + // we must throw user_cancelled here to ensure the button doesn't get stuck on loading spinner. + // The behaviour of this is similar to sending success ("") so this should be fine. + args: ["user_cancelled"], + }); + break; + } +}); diff --git a/src/scripts/chromeApi.js b/src/scripts/chromeApi.js new file mode 100644 index 0000000..3d834a0 --- /dev/null +++ b/src/scripts/chromeApi.js @@ -0,0 +1,97 @@ +// https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/webstore_private.json +const ncws_re = /.*detail(?:\/[^\/]+)?\/([a-z]{32})/i; // copied from util.js since it's out of context +const THIS_EXT_ID = ncws_re.exec(window.location.href)[1]; +const EXT_ID = "ocaahdebbfolfmndjeplogmgcagdmblk"; // need to hardcode this so it's available immediately. (chrome.runtime.id will be undefined in this context) + +const port = chrome.runtime.connect(EXT_ID, { name: "windowchromeport" }); +const CALLBACKS = []; +port.onMessage.addListener((msg, port) => { + if (msg.callbackIndex !== undefined) { + if (msg.err) { + // "throw" error + chrome.runtime.lastError = msg.err; + } + CALLBACKS[msg.callbackIndex].apply(...Array.from(msg.args)); + } +}); +window.chrome.webstorePrivate = { + getExtensionStatus: function (id, manifest, cb) { + chrome.runtime.sendMessage( + EXT_ID, + { func: "getExtensionStatus", args: [id, manifest] }, + (resp) => { + resp.args && cb(...resp.args); + }, + ); + }, + beginInstallWithManifest3: function (extinfo, cb) { + chrome.runtime.sendMessage( + EXT_ID, + { + func: "beginInstallWithManifest3", + args: [extinfo, window.location.href], + }, + (resp) => { + resp.args && cb(...resp.args); + }, + ); + }, + isInIncognitoMode: (cb) => cb(false), // just return false since it's likely this extension isn't running in incognito + getReferrerChain: (cb) => cb("EgIIAA=="), + completeInstall: function (id, cb) { + // will never be called since we cancel all install attempts with "user_cancelled" + // instead we rely on the onInstalled listener to continue the flow correctly (behaviour might be slightly different, + // for example an extension installed tooltip will not show.) + cb(true); + }, +}; +window.chrome.management = { + setEnabled: function (extId, enabled, callback) { + port.postMessage({ + func: "setEnabled", + args: [extId, enabled, CALLBACKS.length], + }); + CALLBACKS.push(callback); + }, + install: function () { + console.log( + "chrome.management.install not implemented, but called with args:", + arguments, + ); + }, + uninstall: function (extId, options, callback) { + port.postMessage({ + func: "uninstall", + args: [extId, options, CALLBACKS.length], + }); + CALLBACKS.push(callback); + }, + getAll: function (cb) { + chrome.runtime.sendMessage( + EXT_ID, + { func: "getAll", args: [THIS_EXT_ID] }, + (resp) => { + resp.args && cb(...resp.args); + }, + ); + }, + onInstalled: { + addListener: function (callback) { + port.postMessage({ + func: "onInstalled", + args: [CALLBACKS.length], + }); + CALLBACKS.push(callback); + }, + }, + onUninstalled: { + addListener: function (callback) { + port.postMessage({ + func: "onUninstalled", + args: [CALLBACKS.length], + }); + CALLBACKS.push(callback); + }, + }, +}; +// window.chrome.runtime.getManifest = () => true; // this is referenced in the CWS source but omitting it seems to have no effect diff --git a/src/scripts/inject.js b/src/scripts/inject.js index 8c701fc..b4c3796 100644 --- a/src/scripts/inject.js +++ b/src/scripts/inject.js @@ -133,29 +133,6 @@ attachMainObserver = new MutationObserver(function (mutations, observer) { }); observer.disconnect(); }); -var modifyButtonObserverNew = new MutationObserver(function ( - mutations, - observer, -) { - mutations.forEach(function (mutation) { - const btn = mutation.target.querySelector( - "button.UywwFc-LgbsSe-OWXEXe-dgl2Hf", - ); - const header = mutation.target.querySelector(".KgGEHd"); - header && header.setAttribute("target", "_top"); - if (btn && !btn.hasAttribute("isInstallBtn")) { - btn.setAttribute("isInstallBtn", "true"); - chrome.runtime.sendMessage( - { - checkExtInstalledId: getExtensionId(window.location.href), - }, - (resp) => { - modifyNewCWSButton(btn, !resp.installed); - }, - ); - } - }); -}); if (is_ews.test(window.location.href)) { new MutationObserver(function (mutations, observer) { mutations.forEach(function (mutation) { @@ -194,21 +171,14 @@ if (is_cws.test(window.location.href)) { childList: true, }); } -function injectCSS(cssCode) { - var style = document.createElement("style"); - style.textContent = cssCode; - document.head.appendChild(style); -} -if (is_ncws.test(window.location.href)) { - injectCSS(` - div[jscontroller="o2G9me"].gSrP5d#c2[jsaction="rcuQ6b:npT2md;KKVPLd:KrIKWc;JIbuQc:M4KNod"] { - display: none; - } - `); - modifyButtonObserverNew.observe(document.body, { - childList: true, - }); +function injectScript(file_path, tag) { + var node = document.getElementsByTagName(tag)[0]; + var script = document.createElement("script"); + script.setAttribute("type", "text/javascript"); + script.setAttribute("src", file_path); + node.appendChild(script); } + if ( is_ows.test(window.location.href) && document.body.querySelector("#feedback-container") //built-ins don't have a feedback section @@ -241,3 +211,16 @@ window.onload = () => { } }); }; +if (is_ncws.test(window.location.href)) { + chrome.storage.sync.get( + { webstore_integration: true }, + function (stored_values) { + if (stored_values.webstore_integration) { + injectScript( + chrome.runtime.getURL("scripts/chromeApi.js"), + "head", + ); + } + }, + ); +} diff --git a/src/scripts/util.js b/src/scripts/util.js index 23d8517..32ed678 100644 --- a/src/scripts/util.js +++ b/src/scripts/util.js @@ -9,6 +9,7 @@ const DEFAULT_MANAGEMENT_OPTIONS = { update_period_in_minutes: 60, removed_extensions: {}, manually_install: false, + webstore_integration: true, }; var fromXML; // prettier-ignore @@ -39,7 +40,7 @@ const is_ncws = /chromewebstore.google.com\//i; const is_ows = /addons.opera.com\/.*extensions/i; const is_ews = /microsoftedge\.microsoft\.com\/addons\//i; const cws_re = /.*detail\/[^\/]*\/([a-z]{32})/i; -const ncws_re = /.*detail\/[^\/]*\/([a-z]{32})/i; +const ncws_re = /.*detail(?:\/[^\/]+)?\/([a-z]{32})/i; const ows_re = /.*details\/([^\/?#]+)/i; const ews_re = /.*addons\/.+?\/([a-z]{32})/i;