diff --git a/qt/aqt/browser/browser.py b/qt/aqt/browser/browser.py
index f3acadde8..d607c301a 100644
--- a/qt/aqt/browser/browser.py
+++ b/qt/aqt/browser/browser.py
@@ -387,12 +387,12 @@ class Browser(QMainWindow):
editor._links["preview"] = lambda _editor: self.onTogglePreview()
editor.web.eval(
f"""
-$editorToolbar.addButton(editorToolbar.labelButton({{
+$editorToolbar.then(({{ addButton }}) => addButton(editorToolbar.labelButton({{
label: `{tr.actions_preview()}`,
tooltip: `{tr.browsing_preview_selected_card(val=shortcut(preview_shortcut))}`,
onClick: () => bridgeCommand("preview"),
disables: false,
-}}), "notetype", -1);
+}}), "notetype", -1));
"""
)
diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py
index 1db017bb1..6b2b3b2ac 100644
--- a/qt/aqt/editor.py
+++ b/qt/aqt/editor.py
@@ -82,7 +82,7 @@ _html = """
}
-
+
@@ -155,7 +155,7 @@ class Editor:
gui_hooks.editor_did_init_left_buttons(lefttopbtns, self)
lefttopbtns_defs = [
- f"$editorToolbar.addButton(editorToolbar.rawButton({{ html: `{button}` }}), 'notetype', -1);"
+ f"$editorToolbar.then(({{ addButton }}) => addButton(editorToolbar.rawButton({{ html: `{button}` }}), 'notetype', -1));"
for button in lefttopbtns
]
lefttopbtns_js = "\n".join(lefttopbtns_defs)
@@ -173,10 +173,10 @@ class Editor:
)
righttopbtns_js = (
f"""
-$editorToolbar.addButton(editorToolbar.buttonGroup({{
+$editorToolbar.then(({{ addButton }}) => addButton(editorToolbar.buttonGroup({{
id: "addons",
items: [ {righttopbtns_defs} ]
-}}), -1);
+}}), -1));
"""
if righttopbtns_defs
else ""
@@ -1277,9 +1277,9 @@ gui_hooks.editor_will_munge_html.append(reverse_url_quoting)
def set_cloze_button(editor: Editor) -> None:
if editor.note.model()["type"] == MODEL_CLOZE:
- editor.web.eval('$editorToolbar.showButton("template", "cloze"); ')
+ editor.web.eval('$editorToolbar.then(({ showButton }) => showButton("template", "cloze")); ')
else:
- editor.web.eval('$editorToolbar.hideButton("template", "cloze"); ')
+ editor.web.eval('$editorToolbar.then(({ hideButton }) => hideButton("template", "cloze")); ')
gui_hooks.editor_did_load_note.append(set_cloze_button)
diff --git a/ts/editor-toolbar/editorToolbar.d.ts b/ts/editor-toolbar/editorToolbar.d.ts
deleted file mode 100644
index 4fd9afb11..000000000
--- a/ts/editor-toolbar/editorToolbar.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import type { EditorToolbar } from ".";
-
-declare namespace globalThis {
- const $editorToolbar: EditorToolbar;
-}
diff --git a/ts/editor-toolbar/index.ts b/ts/editor-toolbar/index.ts
index 0ff494251..ff6e645c7 100644
--- a/ts/editor-toolbar/index.ts
+++ b/ts/editor-toolbar/index.ts
@@ -3,7 +3,7 @@
import type { ToolbarItem, IterableToolbarItem } from "./types";
import type { Identifier } from "./identifiable";
-import { Writable, writable } from "svelte/store";
+import { writable } from "svelte/store";
import EditorToolbarSvelte from "./EditorToolbar.svelte";
@@ -12,78 +12,73 @@ import "./bootstrap.css";
import { add, insert, updateRecursive } from "./identifiable";
import { showComponent, hideComponent, toggleComponent } from "./hideable";
-let buttonsResolve: (value: Writable) => void;
-let menusResolve: (value: Writable) => void;
-
-export class EditorToolbar extends HTMLElement {
- private buttonsPromise: Promise> = new Promise(
- (resolve) => {
- buttonsResolve = resolve;
- }
- );
- private menusPromise: Promise> = new Promise(
- (resolve): void => {
- menusResolve = resolve;
- }
- );
-
- connectedCallback(): void {
- globalThis.$editorToolbar = this;
-
- const buttons = writable([]);
- const menus = writable([]);
-
- new EditorToolbarSvelte({
- target: this,
- props: {
- buttons,
- menus,
- nightMode: document.documentElement.classList.contains("night-mode"),
- },
- });
-
- buttonsResolve(buttons);
- menusResolve(menus);
- }
-
+export interface EditorToolbarAPI {
+ // Button API
updateButton(
update: (component: ToolbarItem) => ToolbarItem,
...identifiers: Identifier[]
- ): void {
- this.buttonsPromise.then(
- (
- buttons: Writable
- ): Writable => {
- buttons.update(
- (items: IterableToolbarItem[]): IterableToolbarItem[] =>
- updateRecursive(
- update,
- ({ items } as unknown) as ToolbarItem,
- ...identifiers
- ).items as IterableToolbarItem[]
- );
+ ): void;
+ showButton(...identifiers: Identifier[]): void;
+ hideButton(...identifiers: Identifier[]): void;
+ toggleButton(...identifiers: Identifier[]): void;
+ insertButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void;
+ addButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void;
- return buttons;
- }
+ // Menu API
+ updateMenu(
+ update: (component: ToolbarItem) => ToolbarItem,
+ ...identifiers: Identifier[]
+ ): void;
+ addMenu(newMenu: ToolbarItem, ...identifiers: Identifier[]): void;
+}
+
+export function editorToolbar(
+ target: HTMLElement,
+ initialButtons: IterableToolbarItem[] = [],
+ initialMenus: ToolbarItem[] = []
+): EditorToolbarAPI {
+ const buttons = writable(initialButtons);
+ const menus = writable(initialMenus);
+
+ new EditorToolbarSvelte({
+ target,
+ props: {
+ buttons,
+ menus,
+ nightMode: document.documentElement.classList.contains("night-mode"),
+ },
+ });
+
+ function updateButton(
+ update: (component: ToolbarItem) => ToolbarItem,
+ ...identifiers: Identifier[]
+ ): void {
+ buttons.update(
+ (items: IterableToolbarItem[]): IterableToolbarItem[] =>
+ updateRecursive(
+ update,
+ ({ items } as unknown) as ToolbarItem,
+ ...identifiers
+ ).items as IterableToolbarItem[]
);
}
- showButton(...identifiers: Identifier[]): void {
- this.updateButton(showComponent, ...identifiers);
+ function showButton(...identifiers: Identifier[]): void {
+ updateButton(showComponent, ...identifiers);
}
- hideButton(...identifiers: Identifier[]): void {
- this.updateButton(hideComponent, ...identifiers);
+ function hideButton(...identifiers: Identifier[]): void {
+ updateButton(hideComponent, ...identifiers);
}
- toggleButton(...identifiers: Identifier[]): void {
- this.updateButton(toggleComponent, ...identifiers);
+ function toggleButton(...identifiers: Identifier[]): void {
+ updateButton(toggleComponent, ...identifiers);
}
- insertButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void {
+ function insertButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void {
const initIdentifiers = identifiers.slice(0, -1);
const lastIdentifier = identifiers[identifiers.length - 1];
- this.updateButton(
+ updateButton(
(component: ToolbarItem) =>
insert(component as IterableToolbarItem, newButton, lastIdentifier),
@@ -91,48 +86,51 @@ export class EditorToolbar extends HTMLElement {
);
}
- addButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void {
+ function addButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void {
const initIdentifiers = identifiers.slice(0, -1);
const lastIdentifier = identifiers[identifiers.length - 1];
- this.updateButton(
+ updateButton(
(component: ToolbarItem) =>
add(component as IterableToolbarItem, newButton, lastIdentifier),
...initIdentifiers
);
}
- updateMenu(
+ function updateMenu(
update: (component: ToolbarItem) => ToolbarItem,
...identifiers: Identifier[]
): void {
- this.menusPromise.then(
- (menus: Writable): Writable => {
- menus.update(
- (items: ToolbarItem[]): ToolbarItem[] =>
- updateRecursive(
- update,
- ({ items } as unknown) as ToolbarItem,
- ...identifiers
- ).items as ToolbarItem[]
- );
-
- return menus;
- }
+ menus.update(
+ (items: ToolbarItem[]): ToolbarItem[] =>
+ updateRecursive(
+ update,
+ ({ items } as unknown) as ToolbarItem,
+ ...identifiers
+ ).items as ToolbarItem[]
);
}
- addMenu(newMenu: ToolbarItem, ...identifiers: Identifier[]): void {
+ function addMenu(newMenu: ToolbarItem, ...identifiers: Identifier[]): void {
const initIdentifiers = identifiers.slice(0, -1);
const lastIdentifier = identifiers[identifiers.length - 1];
- this.updateMenu(
+ updateMenu(
(component: ToolbarItem) =>
add(component as IterableToolbarItem, newMenu, lastIdentifier),
...initIdentifiers
);
}
-}
-customElements.define("anki-editor-toolbar", EditorToolbar);
+ return {
+ updateButton,
+ showButton,
+ hideButton,
+ toggleButton,
+ insertButton,
+ addButton,
+ updateMenu,
+ addMenu,
+ };
+}
/* Exports for editor */
// @ts-expect-error insufficient typing of svelte modules
diff --git a/ts/editor/index.ts b/ts/editor/index.ts
index 826d7942f..8cac7ee94 100644
--- a/ts/editor/index.ts
+++ b/ts/editor/index.ts
@@ -31,7 +31,6 @@ declare global {
}
}
-import "editor-toolbar";
customElements.define("anki-editable", Editable);
customElements.define("anki-editing-area", EditingArea, { extends: "div" });
customElements.define("anki-label-container", LabelContainer, { extends: "div" });
@@ -170,4 +169,4 @@ export function setFormat(cmd: string, arg?: any, nosave: boolean = false): void
const i18n = setupI18n({ modules: [ModuleName.EDITING] });
-initToolbar(i18n);
+export const $editorToolbar = initToolbar(i18n);
diff --git a/ts/editor/toolbar.ts b/ts/editor/toolbar.ts
index f0af19df7..b74de5ccf 100644
--- a/ts/editor/toolbar.ts
+++ b/ts/editor/toolbar.ts
@@ -1,14 +1,23 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
+import { editorToolbar, EditorToolbarAPI } from "editor-toolbar";
+
import { getNotetypeGroup } from "./notetype";
import { getFormatInlineGroup } from "./formatInline";
import { getFormatBlockGroup, getFormatBlockMenus } from "./formatBlock";
import { getColorGroup } from "./color";
import { getTemplateGroup, getTemplateMenus } from "./template";
-export function initToolbar(i18n: Promise): void {
+export function initToolbar(i18n: Promise): Promise {
+ let toolbarResolve: (value: EditorToolbarAPI) => void;
+ const toolbarPromise = new Promise((resolve) => {
+ toolbarResolve = resolve;
+ });
+
document.addEventListener("DOMContentLoaded", () => {
i18n.then(() => {
+ const target = document.getElementById("editorToolbar")!;
+
const buttons = [
getNotetypeGroup(),
getFormatInlineGroup(),
@@ -19,8 +28,9 @@ export function initToolbar(i18n: Promise): void {
const menus = [...getFormatBlockMenus(), ...getTemplateMenus()];
- globalThis.$editorToolbar.updateButton(() => ({ items: buttons }));
- globalThis.$editorToolbar.updateMenu(() => ({ items: menus }));
+ toolbarResolve(editorToolbar(target, buttons, menus));
});
});
+
+ return toolbarPromise;
}