diff --git a/qt/aqt/browser/browser.py b/qt/aqt/browser/browser.py index 4b66b2ef9..51bd999a1 100644 --- a/qt/aqt/browser/browser.py +++ b/qt/aqt/browser/browser.py @@ -408,7 +408,7 @@ class Browser(QMainWindow): def add_preview_button(editor: Editor) -> None: editor._links["preview"] = lambda _editor: self.onTogglePreview() editor.web.eval( - "$editorToolbar.then(({ notetypeButtons }) => notetypeButtons.appendButton({ component: editorToolbar.PreviewButton, id: 'preview' }));" + "noteEditorPromise.then(noteEditor => noteEditor.toolbar.then(toolbar => toolbar.notetypeButtons.appendButton({ component: editorToolbar.PreviewButton, id: 'preview' })));", ) gui_hooks.editor_did_init.append(add_preview_button) diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 9d11e127b..bea54332e 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -137,7 +137,7 @@ class Editor: gui_hooks.editor_did_init_left_buttons(lefttopbtns, self) lefttopbtns_defs = [ - f"$editorToolbar.then(({{ notetypeButtons }}) => notetypeButtons.appendButton({{ component: editorToolbar.Raw, props: {{ html: {json.dumps(button)} }} }}, -1));" + f"noteEditorPromise.then((noteEditor) => noteEditor.toolbar.then((toolbar) => toolbar.notetypeButtons.appendButton({{ component: editorToolbar.Raw, props: {{ html: {json.dumps(button)} }} }}, -1)));" for button in lefttopbtns ] lefttopbtns_js = "\n".join(lefttopbtns_defs) @@ -150,7 +150,7 @@ class Editor: righttopbtns_defs = ", ".join([json.dumps(button) for button in righttopbtns]) righttopbtns_js = ( f""" -$editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ +noteEditorPromise.then(noteEditor => noteEditor.toolbar.then((toolbar) => toolbar.toolbar.appendGroup({{ component: editorToolbar.AddonButtons, id: "addons", props: {{ buttons: [ {righttopbtns_defs} ] }}, @@ -1323,11 +1323,11 @@ gui_hooks.editor_will_munge_html.append(reverse_url_quoting) def set_cloze_button(editor: Editor) -> None: if editor.note.note_type()["type"] == MODEL_CLOZE: editor.web.eval( - '$editorToolbar.then(({ templateButtons }) => templateButtons.showButton("cloze")); ' + 'noteEditorPromise.then((noteEditor) => noteEditor.toolbar.then((toolbar) => toolbar.templateButtons.showButton("cloze"))); ' ) else: editor.web.eval( - '$editorToolbar.then(({ templateButtons }) => templateButtons.hideButton("cloze")); ' + 'noteEditorPromise.then((noteEditor) => noteEditor.toolbar.then(({ templateButtons }) => templateButtons.hideButton("cloze"))); ' ) diff --git a/ts/editor/EditorToolbar.svelte b/ts/editor/EditorToolbar.svelte index f9f95024a..238a4b214 100644 --- a/ts/editor/EditorToolbar.svelte +++ b/ts/editor/EditorToolbar.svelte @@ -14,6 +14,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html resetAllState(false); } + export interface EditorToolbarAPI { + toolbar: any; + notetypeButtons: any; + formatInlineButtons: any; + formatBlockButtons: any; + colorButtons: any; + templateButtons: any; + } + /* Our dynamic components */ import AddonButtons from "./AddonButtons.svelte"; import PreviewButton from "./PreviewButton.svelte"; @@ -41,12 +50,21 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html export let textColor: string; export let highlightColor: string; - export const toolbar = {}; - export const notetypeButtons = {}; - export const formatInlineButtons = {}; - export const formatBlockButtons = {}; - export const colorButtons = {}; - export const templateButtons = {}; + const toolbar = {}; + const notetypeButtons = {}; + const formatInlineButtons = {}; + const formatBlockButtons = {}; + const colorButtons = {}; + const templateButtons = {}; + + export const api = { + toolbar, + notetypeButtons, + formatInlineButtons, + formatBlockButtons, + colorButtons, + templateButtons, + }; diff --git a/ts/editor/OldEditorAdapter.svelte b/ts/editor/OldEditorAdapter.svelte index 23943c46d..b7e1be554 100644 --- a/ts/editor/OldEditorAdapter.svelte +++ b/ts/editor/OldEditorAdapter.svelte @@ -6,6 +6,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import type { EditorFieldAPI } from "./EditorField.svelte"; import type { RichTextInputAPI } from "./RichTextInput.svelte"; import type { PlainTextInputAPI } from "./PlainTextInput.svelte"; + import type { EditorToolbarAPI } from "./EditorToolbar.svelte"; + import contextProperty from "../sveltelib/context-property"; export interface NoteEditorAPI { @@ -13,6 +15,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html currentField: Writable; activeInput: Writable; focusInRichText: Writable; + toolbar: EditorToolbarAPI; } const key = Symbol("noteEditor"); @@ -49,6 +52,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { writable, get } from "svelte/store"; import { bridgeCommand } from "../lib/bridgecommand"; import { isApplePlatform } from "../lib/platform"; + import { promiseWithResolver } from "../lib/promise"; import { ChangeTimer } from "./change-timer"; import { alertIcon } from "./icons"; @@ -221,12 +225,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html const activeInput = writable(null); const focusInRichText = writable(false); + const [toolbarPromise, toolbarResolve] = promiseWithResolver(); + let toolbar: EditorToolbarAPI; + $: if (toolbar) { + toolbarResolve(toolbar); + } + export const api = set( Object.create( { currentField, activeInput, focusInRichText, + toolbar: toolbarPromise, }, { fields: { get: () => fieldApis }, @@ -244,7 +255,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html - + {#if hint} diff --git a/ts/editor/index.ts b/ts/editor/index.ts index b4da15b43..e662abdf6 100644 --- a/ts/editor/index.ts +++ b/ts/editor/index.ts @@ -7,10 +7,8 @@ */ import { filterHTML } from "../html-filter"; +import { execCommand } from "./helpers"; import { updateAllState } from "../components/WithState.svelte"; -import { noop } from "../lib/functional"; - -export const $editorToolbar = new Promise(noop); export function pasteHTML( html: string, @@ -25,10 +23,12 @@ export function pasteHTML( } export function setFormat(cmd: string, arg?: string, _nosave = false): void { - document.execCommand(cmd, false, arg); + execCommand(cmd, false, arg); updateAllState(new Event(cmd)); } +export { editorToolbar } from "./EditorToolbar.svelte"; + import "../sveltelib/export-runtime"; import "../lib/register-package"; @@ -60,18 +60,14 @@ export const i18n = setupI18n({ }); import OldEditorAdapter from "./OldEditorAdapter.svelte"; +import type { NoteEditorAPI } from "./OldEditorAdapter.svelte"; import { nightModeKey } from "../components/context-keys"; import "./editor-base.css"; import "./bootstrap.css"; import "./legacy.css"; -function setupNoteEditor(i18n: Promise): Promise { - let editorResolve: (value: OldEditorAdapter) => void; - const editorPromise = new Promise((resolve) => { - editorResolve = resolve; - }); - +async function setupNoteEditor(): Promise { const context = new Map(); context.set( @@ -79,34 +75,29 @@ function setupNoteEditor(i18n: Promise): Promise { document.documentElement.classList.contains("night-mode"), ); - i18n.then(() => { - const noteEditor = new OldEditorAdapter({ - target: document.body, - props: { - class: "h-100", - }, - context, - } as any); + await i18n; - Object.assign(globalThis, { - setFields: noteEditor.setFields, - setFonts: noteEditor.setFonts, - focusField: noteEditor.focusField, - setColorButtons: noteEditor.setColorButtons, - setTags: noteEditor.setTags, - setSticky: noteEditor.setSticky, - setBackgrounds: noteEditor.setBackgrounds, - setClozeHint: noteEditor.setClozeHint, - saveNow: noteEditor.saveFieldNow, - activateStickyShortcuts: noteEditor.activateStickyShortcuts, - focusIfField: noteEditor.focusIfField, - setNoteId: noteEditor.setNoteId, - }); - - editorResolve(noteEditor); + const noteEditor = new OldEditorAdapter({ + target: document.body, + context, }); - return editorPromise; + Object.assign(globalThis, { + setFields: noteEditor.setFields, + setFonts: noteEditor.setFonts, + focusField: noteEditor.focusField, + setColorButtons: noteEditor.setColorButtons, + setTags: noteEditor.setTags, + setSticky: noteEditor.setSticky, + setBackgrounds: noteEditor.setBackgrounds, + setClozeHint: noteEditor.setClozeHint, + saveNow: noteEditor.saveFieldNow, + activateStickyShortcuts: noteEditor.activateStickyShortcuts, + focusIfField: noteEditor.focusIfField, + setNoteId: noteEditor.setNoteId, + }); + + return noteEditor.api; } -export const noteEditorPromise = setupNoteEditor(i18n); +export const noteEditorPromise = setupNoteEditor();