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..5065abb29 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,13 @@ 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.svelte b/ts/editor-toolbar/EditorToolbar.svelte index c11f6ee7f..5626973dc 100644 --- a/ts/editor-toolbar/EditorToolbar.svelte +++ b/ts/editor-toolbar/EditorToolbar.svelte @@ -18,19 +18,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
- {#each _menus as menu} + {#each menus as menu} {/each}
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..0e64430cb 100644 --- a/ts/editor-toolbar/index.ts +++ b/ts/editor-toolbar/index.ts @@ -1,139 +1,27 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import type { ToolbarItem, IterableToolbarItem } from "./types"; -import type { Identifier } from "./identifiable"; -import { Writable, writable } from "svelte/store"; - -import EditorToolbarSvelte from "./EditorToolbar.svelte"; +import EditorToolbar from "./EditorToolbar.svelte"; +export { default as EditorToolbar } from "./EditorToolbar.svelte"; 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); - } - - 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[] - ); - - return buttons; - } - ); - } - - showButton(...identifiers: Identifier[]): void { - this.updateButton(showComponent, ...identifiers); - } - - hideButton(...identifiers: Identifier[]): void { - this.updateButton(hideComponent, ...identifiers); - } - - toggleButton(...identifiers: Identifier[]): void { - this.updateButton(toggleComponent, ...identifiers); - } - - insertButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void { - const initIdentifiers = identifiers.slice(0, -1); - const lastIdentifier = identifiers[identifiers.length - 1]; - this.updateButton( - (component: ToolbarItem) => - insert(component as IterableToolbarItem, newButton, lastIdentifier), - - ...initIdentifiers - ); - } - - addButton(newButton: ToolbarItem, ...identifiers: Identifier[]): void { - const initIdentifiers = identifiers.slice(0, -1); - const lastIdentifier = identifiers[identifiers.length - 1]; - this.updateButton( - (component: ToolbarItem) => - add(component as IterableToolbarItem, newButton, lastIdentifier), - ...initIdentifiers - ); - } - - 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; - } - ); - } - - addMenu(newMenu: ToolbarItem, ...identifiers: Identifier[]): void { - const initIdentifiers = identifiers.slice(0, -1); - const lastIdentifier = identifiers[identifiers.length - 1]; - this.updateMenu( - (component: ToolbarItem) => - add(component as IterableToolbarItem, newMenu, lastIdentifier), - ...initIdentifiers - ); - } +export function editorToolbar( + target: HTMLElement, + buttons: IterableToolbarItem[] = [], + menus: ToolbarItem[] = [] +): EditorToolbar { + return new EditorToolbar({ + target, + props: { + buttons, + menus, + nightMode: document.documentElement.classList.contains("night-mode"), + }, + }); } -customElements.define("anki-editor-toolbar", EditorToolbar); - /* Exports for editor */ // @ts-expect-error insufficient typing of svelte modules export { updateActiveButtons, clearActiveButtons } from "./CommandIconButton.svelte"; 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..930c3ee41 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, EditorToolbar } 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) { + let toolbarResolve: (value: EditorToolbar) => 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; }