ruffle/web/packages/extension/src/utils.ts

147 lines
4.1 KiB
TypeScript
Raw Normal View History

import { Options } from "./common";
2021-09-25 10:02:01 +00:00
import { LogLevel } from "ruffle-core";
const DEFAULT_OPTIONS: Options = {
2021-03-09 19:50:47 +00:00
ruffleEnable: true,
ignoreOptout: false,
warnOnUnsupportedContent: true,
2021-09-25 10:02:01 +00:00
logLevel: LogLevel.Error,
showSwfDownload: false,
2021-03-09 19:50:47 +00:00
};
export let i18n: {
getMessage: (name: string) => string;
};
interface StorageArea {
get: (keys?: string[]) => Promise<Record<string, unknown>>;
remove: (keys: string[]) => Promise<void>;
set: (items: Record<string, unknown>) => Promise<void>;
}
export let storage: {
local: StorageArea;
sync: StorageArea;
onChanged: {
addListener: (
listener: (
changes:
| Record<string, chrome.storage.StorageChange>
| Record<string, browser.storage.StorageChange>,
areaName: string
) => void
) => void;
};
};
export let tabs: {
reload: (tabId: number) => Promise<void>;
query: (
query: chrome.tabs.QueryInfo & browser.tabs._QueryQueryInfo
) => Promise<chrome.tabs.Tab[] | browser.tabs.Tab[]>;
sendMessage: (
tabId: number,
message: unknown,
options?: chrome.tabs.MessageSendOptions &
browser.tabs._SendMessageOptions
) => Promise<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
};
export let runtime: {
onMessage: {
addListener: (
listener: (
message: unknown,
sender:
| chrome.runtime.MessageSender
| browser.runtime.MessageSender,
sendResponse: (response?: unknown) => void
) => void
) => void;
};
getURL: (path: string) => string;
};
export let openOptionsPage: () => Promise<void>;
2021-03-09 19:50:47 +00:00
function promisify<T>(
func: (callback: (result?: T) => void) => void
): Promise<T> {
2021-03-09 19:50:47 +00:00
return new Promise((resolve, reject) => {
func((result) => {
const error = chrome.runtime.lastError;
if (error) {
reject(error);
} else {
resolve(result!);
2021-03-09 19:50:47 +00:00
}
});
});
}
function promisifyStorageArea(
storage: chrome.storage.StorageArea
): StorageArea {
return {
get: (keys?: string[]) =>
promisify((cb) => storage.get(keys || null, cb)),
remove: (keys: string[]) => promisify((cb) => storage.remove(keys, cb)),
set: (items: Record<string, unknown>) =>
promisify((cb) => storage.set(items, cb)),
2021-03-09 19:50:47 +00:00
};
}
if (typeof chrome !== "undefined") {
i18n = chrome.i18n;
2021-03-09 19:50:47 +00:00
storage = {
local: promisifyStorageArea(chrome.storage.local),
sync: promisifyStorageArea(chrome.storage.sync),
2021-03-09 19:50:47 +00:00
onChanged: {
addListener: (
listener: (
changes: Record<string, chrome.storage.StorageChange>,
areaName: string
) => void
) => chrome.storage.onChanged.addListener(listener),
2021-03-09 19:50:47 +00:00
},
};
tabs = {
reload: (tabId: number) =>
promisify((cb) => chrome.tabs.reload(tabId, undefined, cb)),
query: (query: chrome.tabs.QueryInfo) =>
promisify((cb) => chrome.tabs.query(query, cb)),
sendMessage: (
tabId: number,
message: unknown,
options?: chrome.tabs.MessageSendOptions
) =>
promisify((cb) =>
chrome.tabs.sendMessage(tabId, message, options || {}, cb)
),
2021-03-09 19:50:47 +00:00
};
runtime = chrome.runtime;
2021-03-09 19:50:47 +00:00
openOptionsPage = () =>
promisify((cb: () => void) =>
chrome.tabs.create({ url: "/options.html" }, cb)
);
2021-03-09 19:50:47 +00:00
} else if (typeof browser !== "undefined") {
i18n = browser.i18n;
storage = browser.storage;
tabs = browser.tabs;
runtime = browser.runtime;
2021-03-09 19:50:47 +00:00
openOptionsPage = () => browser.runtime.openOptionsPage();
} else {
throw new Error("Extension API not found.");
}
export async function getOptions(): Promise<Options> {
const options = await storage.sync.get();
2021-03-09 19:50:47 +00:00
// Copy over default options if they don't exist yet.
return { ...DEFAULT_OPTIONS, ...options };
}