Release Firefox and Chromium extensions / Package and attach browser extensions (release) Successful in 54s
174 lines
5.0 KiB
JavaScript
174 lines
5.0 KiB
JavaScript
(function (root) {
|
|
"use strict";
|
|
|
|
const FONT_STYLE_KEY = "glagolifyFontStyle";
|
|
const TAB_STATES_KEY = "glagolifyTabStates";
|
|
const FONT_STYLES = new Set(["round", "angular-sans", "angular", "missal-angular"]);
|
|
const DEFAULT_FONT_STYLE = "round";
|
|
|
|
function createBackgroundController(api) {
|
|
const tabStates = new Map();
|
|
let fontStyle = DEFAULT_FONT_STYLE;
|
|
const fontStyleReady = Promise.resolve(api.storage.local.get(FONT_STYLE_KEY))
|
|
.then((stored) => {
|
|
if (stored && FONT_STYLES.has(stored[FONT_STYLE_KEY])) {
|
|
fontStyle = stored[FONT_STYLE_KEY];
|
|
}
|
|
})
|
|
.catch(() => undefined);
|
|
const tabStatesReady = Promise.resolve(api.storage.session.get(TAB_STATES_KEY))
|
|
.then((stored) => {
|
|
const states = stored && stored[TAB_STATES_KEY];
|
|
if (!states || typeof states !== "object" || Array.isArray(states)) {
|
|
return;
|
|
}
|
|
|
|
for (const [storedTabId, enabled] of Object.entries(states)) {
|
|
const tabId = Number(storedTabId);
|
|
if (validTabId(tabId) && typeof enabled === "boolean") {
|
|
tabStates.set(tabId, enabled);
|
|
}
|
|
}
|
|
})
|
|
.catch(() => undefined);
|
|
const controllerReady = Promise.all([fontStyleReady, tabStatesReady]);
|
|
|
|
function validTabId(tabId) {
|
|
return Number.isInteger(tabId) && tabId >= 0;
|
|
}
|
|
|
|
async function persistTabStates() {
|
|
await api.storage.session.set({
|
|
[TAB_STATES_KEY]: Object.fromEntries(tabStates)
|
|
});
|
|
}
|
|
|
|
async function broadcast(tabId, enabled) {
|
|
await fontStyleReady;
|
|
try {
|
|
await api.tabs.sendMessage(tabId, {
|
|
type: "glagolify:set-enabled",
|
|
enabled,
|
|
fontStyle
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function handleMessage(message, sender) {
|
|
if (!message || typeof message.type !== "string") {
|
|
return undefined;
|
|
}
|
|
|
|
if (message.type === "glagolify:document-ready") {
|
|
const tabId = sender && sender.tab && sender.tab.id;
|
|
return controllerReady.then(() => ({
|
|
enabled: validTabId(tabId) && tabStates.get(tabId) === true,
|
|
fontStyle
|
|
}));
|
|
}
|
|
|
|
if (message.type === "glagolify:get-tab-state") {
|
|
const tabId = message.tabId;
|
|
return controllerReady.then(async () => {
|
|
if (!validTabId(tabId)) {
|
|
return { enabled: false, available: false, fontStyle };
|
|
}
|
|
|
|
const enabled = tabStates.get(tabId) === true;
|
|
const available = await broadcast(tabId, enabled);
|
|
return { enabled, available, fontStyle };
|
|
});
|
|
}
|
|
|
|
if (message.type === "glagolify:set-tab-enabled") {
|
|
const tabId = message.tabId;
|
|
if (!validTabId(tabId) || typeof message.enabled !== "boolean") {
|
|
return controllerReady.then(() => ({
|
|
enabled: false,
|
|
available: false,
|
|
fontStyle
|
|
}));
|
|
}
|
|
|
|
return controllerReady.then(async () => {
|
|
tabStates.set(tabId, message.enabled);
|
|
await persistTabStates();
|
|
const available = await broadcast(tabId, message.enabled);
|
|
return {
|
|
enabled: message.enabled,
|
|
available,
|
|
fontStyle
|
|
};
|
|
});
|
|
}
|
|
|
|
if (message.type === "glagolify:set-font-style") {
|
|
if (!FONT_STYLES.has(message.fontStyle)) {
|
|
return controllerReady.then(() => ({ fontStyle, accepted: false }));
|
|
}
|
|
|
|
return controllerReady.then(async () => {
|
|
await api.storage.local.set({ [FONT_STYLE_KEY]: message.fontStyle });
|
|
fontStyle = message.fontStyle;
|
|
await Promise.all(
|
|
[...tabStates]
|
|
.filter(([, tabEnabled]) => tabEnabled)
|
|
.map(([tabId]) => broadcast(tabId, true))
|
|
);
|
|
return { fontStyle, accepted: true };
|
|
});
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
api.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
const response = handleMessage(message, sender);
|
|
if (response === undefined) {
|
|
return false;
|
|
}
|
|
|
|
Promise.resolve(response).then(
|
|
(value) => sendResponse(value),
|
|
() => sendResponse(undefined)
|
|
);
|
|
return true;
|
|
});
|
|
|
|
api.tabs.onRemoved.addListener(async (tabId) => {
|
|
await tabStatesReady;
|
|
if (tabStates.delete(tabId)) {
|
|
await persistTabStates();
|
|
}
|
|
});
|
|
|
|
return {
|
|
tabStates,
|
|
broadcast,
|
|
controllerReady,
|
|
getFontStyle: () => fontStyle
|
|
};
|
|
}
|
|
|
|
const exported = Object.freeze({ createBackgroundController });
|
|
|
|
const extensionApi =
|
|
typeof browser === "object"
|
|
? browser
|
|
: typeof chrome === "object"
|
|
? chrome
|
|
: null;
|
|
if (extensionApi && extensionApi.runtime && extensionApi.tabs) {
|
|
createBackgroundController(extensionApi);
|
|
}
|
|
|
|
if (typeof module === "object" && module.exports) {
|
|
module.exports = exported;
|
|
}
|
|
|
|
root.GlagolifyBackground = exported;
|
|
})(typeof globalThis === "object" ? globalThis : this);
|