312 lines
11 KiB
JavaScript
312 lines
11 KiB
JavaScript
|
importScripts("./util.js");
|
||
|
const nonWebstoreExtensionsDownloading = new Set();
|
||
|
const manualInstallExtensionsDownloading = new Set();
|
||
|
const tabsAwaitingInstall = new Set();
|
||
|
const extensionsTabId = {};
|
||
|
function handleContextClick(info, tab) {
|
||
|
if (info.menuItemId == "updateAll")
|
||
|
checkForUpdates(function (
|
||
|
updateCheck,
|
||
|
installed_versions,
|
||
|
appid,
|
||
|
updatever,
|
||
|
is_webstore,
|
||
|
) {
|
||
|
let crx_url = updateCheck["@codebase"];
|
||
|
promptInstall(crx_url, is_webstore, WEBSTORE.chrome, msgHandler);
|
||
|
});
|
||
|
else if (info.menuItemId == "installExt") {
|
||
|
let store = WEBSTORE.chrome;
|
||
|
[...WEBSTORE_MAP.keys()].some((k) => {
|
||
|
if (k.test(tab.url)) {
|
||
|
store = WEBSTORE_MAP.get(k);
|
||
|
return true;
|
||
|
}
|
||
|
});
|
||
|
promptInstall(buildExtensionUrl(tab.url), true, store, msgHandler);
|
||
|
} else if (info.menuItemId == "cws")
|
||
|
chrome.tabs.create({
|
||
|
url: "https://chrome.google.com/webstore/",
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function updateBadge(modified_ext_id = null) {
|
||
|
checkForUpdates();
|
||
|
}
|
||
|
|
||
|
function startupTasks() {
|
||
|
chrome.storage.sync.get(DEFAULT_MANAGEMENT_OPTIONS, function (settings) {
|
||
|
chrome.storage.local.get(
|
||
|
{
|
||
|
badge_display: "",
|
||
|
last_scheduled_update: 0,
|
||
|
},
|
||
|
(localstore) => {
|
||
|
chrome.action.setBadgeText({
|
||
|
text: localstore.badge_display,
|
||
|
});
|
||
|
chrome.alarms.create("cws_check_extension_updates", {
|
||
|
delayInMinutes: Math.max(
|
||
|
1,
|
||
|
settings.update_period_in_minutes -
|
||
|
Math.floor(
|
||
|
(Date.now() -
|
||
|
localstore.last_scheduled_update) /
|
||
|
1000 /
|
||
|
60,
|
||
|
),
|
||
|
),
|
||
|
periodInMinutes: settings.update_period_in_minutes,
|
||
|
});
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
}
|
||
|
chrome.action.setBadgeBackgroundColor({
|
||
|
color: "#FE0000",
|
||
|
});
|
||
|
chrome.management.onInstalled.addListener(function (ext) {
|
||
|
updateBadge(ext.id);
|
||
|
for (let tabid of tabsAwaitingInstall) {
|
||
|
chrome.tabs.sendMessage(
|
||
|
tabid,
|
||
|
{
|
||
|
action: "extInstalled",
|
||
|
extId: ext.id,
|
||
|
},
|
||
|
() => {
|
||
|
if (chrome.runtime.lastError) tabsAwaitingInstall.delete(tabid);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
});
|
||
|
chrome.management.onUninstalled.addListener(function (ext) {
|
||
|
updateBadge(ext.id);
|
||
|
});
|
||
|
chrome.runtime.onStartup.addListener(function () {
|
||
|
startupTasks();
|
||
|
});
|
||
|
chrome.alarms.onAlarm.addListener(function (alarm) {
|
||
|
if (alarm.name == "cws_check_extension_updates")
|
||
|
chrome.storage.sync.get(
|
||
|
DEFAULT_MANAGEMENT_OPTIONS,
|
||
|
function (settings) {
|
||
|
if (settings.auto_update) {
|
||
|
updateBadge();
|
||
|
chrome.storage.local.set({
|
||
|
last_scheduled_update: Date.now(),
|
||
|
});
|
||
|
chrome.alarms.create("cws_check_extension_updates", {
|
||
|
delayInMinutes: settings.update_period_in_minutes,
|
||
|
periodInMinutes: settings.update_period_in_minutes,
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
chrome.runtime.onInstalled.addListener(function () {
|
||
|
startupTasks();
|
||
|
chrome.contextMenus.create({
|
||
|
title: chrome.i18n.getMessage("contextMenu_updateAll"),
|
||
|
id: "updateAll",
|
||
|
contexts: ["action"],
|
||
|
});
|
||
|
chrome.contextMenus.create({
|
||
|
title: "🔗 Chrome Web Store",
|
||
|
id: "cws",
|
||
|
contexts: ["action"],
|
||
|
});
|
||
|
chrome.contextMenus.create({
|
||
|
title: chrome.i18n.getMessage("webstore_addButton"),
|
||
|
id: "installExt",
|
||
|
documentUrlPatterns: [
|
||
|
"https://chrome.google.com/webstore/detail/*",
|
||
|
"https://chromewebstore.google.com/detail/*",
|
||
|
"https://addons.opera.com/*/extensions/details/*",
|
||
|
"https://microsoftedge.microsoft.com/addons/detail/*",
|
||
|
],
|
||
|
});
|
||
|
});
|
||
|
const msgHandler = function (request, sender, sendResponse) {
|
||
|
if (request.nonWebstoreDownloadUrl) {
|
||
|
chrome.downloads.download(
|
||
|
{
|
||
|
url: request.nonWebstoreDownloadUrl,
|
||
|
},
|
||
|
(dlid) => {
|
||
|
nonWebstoreExtensionsDownloading.add(dlid);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
if (request.manualInstallDownloadUrl) {
|
||
|
chrome.downloads.download(
|
||
|
{
|
||
|
url: request.manualInstallDownloadUrl,
|
||
|
saveAs: true, // required to suppress warning: "Apps, extensions and user scripts cannot be added from this website"
|
||
|
},
|
||
|
(dlid) => {
|
||
|
manualInstallExtensionsDownloading.add(dlid);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
if (request.newTabUrl) {
|
||
|
chrome.tabs.create({ active: false, url: request.newTabUrl });
|
||
|
}
|
||
|
if (request.checkExtInstalledId) {
|
||
|
chrome.management.get(request.checkExtInstalledId, (extinfo) => {
|
||
|
sendResponse({
|
||
|
installed: !(chrome.runtime.lastError && !extinfo),
|
||
|
});
|
||
|
});
|
||
|
return true;
|
||
|
}
|
||
|
if (request.uninstallExt) {
|
||
|
chrome.management.uninstall(request.uninstallExt, () => {
|
||
|
sendResponse({ uninstalled: !chrome.runtime.lastError });
|
||
|
});
|
||
|
return true;
|
||
|
}
|
||
|
if (request.installExt) {
|
||
|
tabsAwaitingInstall.add(sender.tab.id);
|
||
|
}
|
||
|
};
|
||
|
chrome.runtime.onMessage.addListener(msgHandler);
|
||
|
chrome.downloads.onChanged.addListener((d) => {
|
||
|
// open chrome://extensions if user has "Always download CRX files" checked, for easy drag-and-drop installation
|
||
|
if (d.endTime && manualInstallExtensionsDownloading.has(d.id)) {
|
||
|
manualInstallExtensionsDownloading.delete(d.id);
|
||
|
chrome.tabs.get(extensionsTabId?.id ?? 0, (tab) => {
|
||
|
if (!chrome.runtime.lastError)
|
||
|
chrome.tabs.highlight({
|
||
|
tabs: tab.index,
|
||
|
windowId: tab.windowId,
|
||
|
});
|
||
|
else
|
||
|
chrome.tabs.create(
|
||
|
{
|
||
|
url: "chrome://extensions/",
|
||
|
},
|
||
|
(tab) => {
|
||
|
extensionsTabId.id = tab.id;
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
// chrome.notifications.create("manually_install", {
|
||
|
// type: "basic",
|
||
|
// iconUrl: "assets/icon/icon_128.png",
|
||
|
// title: chrome.i18n.getMessage("notify_manuallyInstall_title"),
|
||
|
// message: chrome.i18n.getMessage("notify_manuallyInstall_message"),
|
||
|
// });
|
||
|
}
|
||
|
});
|
||
|
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;
|
||
|
}
|
||
|
});
|