fix: only re-import dom modules in menu, don't use until post-re-import

This commit is contained in:
dragonwocky 2023-08-04 16:13:23 +10:00
parent 4f07420c4a
commit 19e6d5451c
Signed by: dragonwocky
GPG Key ID: 7998D08F7D7BD7A8
3 changed files with 41 additions and 26 deletions

View File

@ -171,8 +171,9 @@ window.addEventListener("message", (event) => {
});
useState(["hotkey"], ([hotkey]) => {
const { addKeyListener } = globalThis.__enhancerApi ?? {},
[hotkeyRegistered] = useState(["hotkeyRegistered"]);
if (!hotkey || !addKeyListener || hotkeyRegistered) return;
[hotkeyRegistered] = useState(["hotkeyRegistered"]),
[renderStarted] = useState(["renderStarted"]);
if (!hotkey || !addKeyListener || hotkeyRegistered || !renderStarted) return;
setState({ hotkeyRegistered: true });
addKeyListener(hotkey, (event) => {
event.preventDefault();
@ -195,16 +196,7 @@ useState(["theme"], ([theme]) => {
useState(["rerender"], async () => {
const [theme, icon] = useState(["theme", "icon"]);
if (!theme || !icon) return;
// chrome extensions run in an isolated execution context
// but extension:// pages can access chrome apis
// => notion-enhancer api is imported directly
if (typeof globalThis.__enhancerApi === "undefined") {
if (typeof globalThis.__enhancerApi === "undefined")
await import("../../shared/system.js");
// in electron this isn't necessary, as a) scripts are
// not running in an isolated execution context and b)
// the notion:// protocol csp bypass allows scripts to
// set iframe globals via $iframe.contentWindow
}
// load stylesheets and api globals
(await import("../../load.mjs")).default.then(render);
});

View File

@ -8,30 +8,53 @@
export default (async () => {
// prettier-ignore
const { enhancerUrl } = globalThis.__enhancerApi,
isMenu = location.href.startsWith(enhancerUrl("core/menu/index.html")),
const { enhancerUrl, platform } = globalThis.__enhancerApi,
signedIn = localStorage["LRU:KeyValueStore2:current-user-id"],
pageLoaded = /(^\/$)|((-|\/)[0-9a-f]{32}((\?.+)|$))/.test(location.pathname),
signedIn = localStorage["LRU:KeyValueStore2:current-user-id"];
if (!isMenu && (!signedIn || !pageLoaded)) return;
if (!isMenu) console.log("notion-enhancer: loading...");
IS_MENU = location.href.startsWith(enhancerUrl("core/menu/index.html")),
IS_ELECTRON = ['linux', 'win32', 'darwin'].includes(platform);
if (!IS_MENU) {
if (!signedIn || !pageLoaded) return;
console.log("notion-enhancer: loading...");
}
// in electron, iframes cannot access node
// => relevant functionality can be provided
// by setting contentWindow.__enhancerApi from
// the preload.js parent script thanks to the
// notion:// protocol csp bypass
// in browser, extensions run in an isolated
// execution context => __enhancerApi modules
// can't be passed from the parent script and
// must be re-imported. this is fine, since
// extension:// pages can access chrome apis
// in both situations, modules that attach to
// the dom must be re-imported, and should not
// be used until import is complete, otherwise
// their local states will be cleared (e.g.,
// references to registered hotkeys)
await Promise.all([
import(enhancerUrl("assets/icons.svg.js")),
// i.e. if (not_menu) or (is_menu && not_electron), then import
!(!IS_MENU || !IS_ELECTRON) || import(enhancerUrl("assets/icons.svg.js")),
import(enhancerUrl("vendor/twind.min.js")),
import(enhancerUrl("vendor/lucide.min.js")),
import(enhancerUrl("vendor/htm.min.js")),
]);
await Promise.all([
!(!IS_MENU || !IS_ELECTRON) || import(enhancerUrl("shared/registry.js")),
import(enhancerUrl("shared/events.js")),
import(enhancerUrl("shared/registry.js")),
import(enhancerUrl("shared/markup.js")),
]);
const { getMods, isEnabled, modDatabase } = globalThis.__enhancerApi;
const { getMods, isEnabled, modDatabase } = globalThis.__enhancerApi;
for (const mod of await getMods()) {
if (!(await isEnabled(mod.id))) continue;
const isTheme = mod._src.startsWith("themes/");
if (isMenu && !(mod._src === "core" || isTheme)) continue;
if (IS_MENU && !(mod._src === "core" || isTheme)) continue;
// clientStyles
for (let stylesheet of mod.clientStyles ?? []) {
@ -42,7 +65,7 @@ export default (async () => {
}
// clientScripts
if (isMenu) continue;
if (IS_MENU) continue;
const db = await modDatabase(mod.id);
for (let script of mod.clientScripts ?? []) {
script = await import(enhancerUrl(`${mod._src}/${script}`));
@ -50,5 +73,5 @@ export default (async () => {
}
}
if (isMenu) console.log("notion-enhancer: ready");
if (IS_MENU) console.log("notion-enhancer: ready");
})();

View File

@ -6,7 +6,7 @@
"use strict";
const { twind, htm } = globalThis,
const { twind, htm, lucide } = globalThis,
{ readFile, iconColour, iconMonochrome } = globalThis.__enhancerApi;
const kebabToPascalCase = (string) =>
@ -45,8 +45,8 @@ const encodeSvg = (svg) =>
svg = mode === "mask" ? iconMonochrome : iconColour;
} else {
icon = kebabToPascalCase(icon);
if (!globalThis.lucide[icon]) return;
const [type, props, children] = globalThis.lucide[icon];
if (!lucide[icon]) return;
const [type, props, children] = lucide[icon];
svg = hToString(type, props, ...children);
}
// https://antfu.me/posts/icons-in-pure-css