From f5fba15435788b56b0ef2738a3ec6ec1e690a500 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 25 Apr 2021 18:25:03 +0200 Subject: [PATCH] Initialize editor toolbar via function, not web component --- qt/aqt/browser/browser.py | 4 +- qt/aqt/editor.py | 12 +-- ts/editor-toolbar/editorToolbar.d.ts | 5 - ts/editor-toolbar/index.ts | 154 +++++++++++++-------------- ts/editor/index.ts | 3 +- ts/editor/toolbar.ts | 16 ++- 6 files changed, 98 insertions(+), 96 deletions(-) delete mode 100644 ts/editor-toolbar/editorToolbar.d.ts 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; }