A rewrite of Poly+, my quality-of-life browser extension for Polytoria. Built entirely fresh using the WXT extension framework, Typescript, and with added better overall code quality.
extension

minor: work in progress debug menu in devtools

Index 761fcac3 f549ab74

Changed files
+89
entrypoints
devtools
+28
entrypoints/devtools/index.html
···
+
<!doctype html>
+
<html lang="en">
+
<head>
+
<meta charset="UTF-8" />
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
<script src="main.ts" type="module"></script>
+
</head>
+
<body>
+
<dialog class="polyplus-modal" style="width: 95%; height: 95%; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;">
+
<div class="row text-muted mb-2" style="font-size: 0.8rem;">
+
<div class="col">
+
<h5 class="mb-0" style="color: #fff;" id="modal-title"></h5>
+
<span id="modal-desc"></span>
+
</div>
+
<div class="col-auto">
+
<button id="modal-close" class="btn btn-info mx-auto">X</button>
+
</div>
+
</div>
+
<div class="modal-body" style="overflow-y: auto; height: calc(100% - 50px); padding-right: 10px; word-wrap: break-word; word-break: break-word;"></div>
+
</dialog>
+
+
<div class="container text-center mt-5">
+
<button id="view-preferences" class="btn btn-primary btn-sm w-100 mb-2">View Preferences</button>
+
<button id="view-cache" class="btn btn-warning btn-sm w-100 mb-2">View Cache</button>
+
<button id="expose-config" class="btn btn-secondary btn-sm w-100 mb-2">Expose Config</button>
+
</div>
+
</body>
+
</html>
+61
entrypoints/devtools/main.ts
···
+
import config from "@/utils/config.json";
+
import { preferences, cache } from "@/utils/storage";
+
browser.devtools.panels.create("Poly+", "icon/128.png", "devtools.html");
+
+
for (const src of [
+
"/css/polytoria.css",
+
"/css/preferences.css"
+
]) {
+
const css = browser.runtime.getURL(src as any);
+
const link = document.createElement('link');
+
link.rel = 'stylesheet';
+
link.href = css;
+
document.head.appendChild(link);
+
};
+
+
const modal: HTMLDialogElement = document.getElementsByTagName('dialog')[0]!;
+
const openModal = (title: string, description: string, body: any, json: boolean) => {
+
if (json) {
+
body = `
+
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
+
${JSON.stringify((body || []), null, 2)
+
.replaceAll('\n','<br>')
+
.replaceAll(' ', '&nbsp;')
+
.replaceAll('\t', '&nbsp;&nbsp;&nbsp;&nbsp;')}
+
</div>
+
`;
+
};
+
+
modal.getElementsByTagName('h5')[0]!.textContent = title;
+
modal.getElementsByTagName('span')[0]!.textContent = description;
+
modal.getElementsByClassName('modal-body')[0]!.innerHTML = body;
+
+
modal.showModal();
+
};
+
+
document.getElementById('view-preferences')!.addEventListener('click', async () => {
+
openModal(
+
"Preferences",
+
"The following values are the user's preferences.",
+
await preferences.getPreferences(),
+
true
+
);
+
});
+
+
document.getElementById('view-cache')!.addEventListener('click', async () => {
+
openModal(
+
"Cache",
+
"The following values are saved for a certain period of time, before being \"replenished\" when next requested.",
+
await cache.getValue(),
+
true
+
);
+
});
+
+
document.getElementById('expose-config')!.addEventListener('click', () => openModal(
+
"Configuration",
+
"The defining values for several features of the extension.",
+
config,
+
true
+
));
+
+
document.getElementById('modal-close')!.addEventListener('click', () => modal.close());