diff --git a/ts/editor-toolbar/BUILD.bazel b/ts/editor-toolbar/BUILD.bazel index b4831e813..92419a273 100644 --- a/ts/editor-toolbar/BUILD.bazel +++ b/ts/editor-toolbar/BUILD.bazel @@ -4,7 +4,6 @@ load("//ts:prettier.bzl", "prettier_test") load("//ts:eslint.bzl", "eslint_test") load("//ts:esbuild.bzl", "esbuild") load("//ts:compile_sass.bzl", "compile_sass") -load("//ts:vendor.bzl", "copy_bootstrap_icons", "copy_mdi_icons") svelte_files = glob(["*.svelte"]) @@ -23,7 +22,6 @@ compile_svelte( compile_sass( srcs = [ "bootstrap.scss", - "color.scss", "legacy.scss", ], group = "local_css", @@ -34,45 +32,6 @@ compile_sass( visibility = ["//visibility:public"], ) -copy_bootstrap_icons( - name = "bootstrap-icons", - icons = [ - # inline formatting - "type-bold.svg", - "type-italic.svg", - "type-underline.svg", - "eraser.svg", - "square-fill.svg", - "paperclip.svg", - "mic.svg", - - # block formatting - "paragraph.svg", - "list-ul.svg", - "list-ol.svg", - "text-paragraph.svg", - "justify.svg", - "text-left.svg", - "text-right.svg", - "text-center.svg", - "text-indent-left.svg", - "text-indent-right.svg", - ], - visibility = ["//visibility:public"], -) - -copy_mdi_icons( - name = "mdi-icons", - icons = [ - "format-superscript.svg", - "format-subscript.svg", - "function-variant.svg", - "code-brackets.svg", - "xml.svg", - ], - visibility = ["//visibility:public"], -) - ts_library( name = "editor-toolbar", module_name = "editor-toolbar", diff --git a/ts/editor-toolbar/editorToolbar.d.ts b/ts/editor-toolbar/editorToolbar.d.ts new file mode 100644 index 000000000..d26bebd5e --- /dev/null +++ b/ts/editor-toolbar/editorToolbar.d.ts @@ -0,0 +1,5 @@ +import type { EditorToolbar } from "."; + +declare global { + var $editorToolbar: EditorToolbar; +} diff --git a/ts/editor-toolbar/index.ts b/ts/editor-toolbar/index.ts index 6fa1b5437..aab58bcca 100644 --- a/ts/editor-toolbar/index.ts +++ b/ts/editor-toolbar/index.ts @@ -11,15 +11,8 @@ import { Writable, writable } from "svelte/store"; import EditorToolbarSvelte from "./EditorToolbar.svelte"; -import { setupI18n, ModuleName } from "anki/i18n"; - import "./bootstrap.css"; -import { getNotetypeGroup } from "./notetype"; -import { getFormatInlineGroup } from "./formatInline"; -import { getFormatBlockGroup, getFormatBlockMenus } from "./formatBlock"; -import { getColorGroup } from "./color"; -import { getTemplateGroup, getTemplateMenus } from "./template"; import { Identifiable, search, add, insert } from "./identifiable"; interface Hideable { @@ -45,7 +38,7 @@ let buttonsResolve: ( ) => void; let menusResolve: (value: Writable) => void; -class EditorToolbar extends HTMLElement { +export class EditorToolbar extends HTMLElement { component?: SvelteComponentDev; buttonsPromise: Promise< @@ -60,30 +53,20 @@ class EditorToolbar extends HTMLElement { connectedCallback(): void { globalThis.$editorToolbar = this; - setupI18n({ modules: [ModuleName.EDITING] }).then(() => { - const buttons = writable([ - getNotetypeGroup(), - getFormatInlineGroup(), - getFormatBlockGroup(), - getColorGroup(), - getTemplateGroup(), - ]); - const menus = writable([...getTemplateMenus(), ...getFormatBlockMenus()]); + const buttons = writable([]); + const menus = writable([]); - this.component = new EditorToolbarSvelte({ - target: this, - props: { - buttons, - menus, - nightMode: document.documentElement.classList.contains( - "night-mode" - ), - }, - }); - - buttonsResolve(buttons); - menusResolve(menus); + this.component = new EditorToolbarSvelte({ + target: this, + props: { + buttons, + menus, + nightMode: document.documentElement.classList.contains("night-mode"), + }, }); + + buttonsResolve(buttons); + menusResolve(menus); } updateButtonGroup( @@ -202,20 +185,8 @@ class EditorToolbar extends HTMLElement { customElements.define("anki-editor-toolbar", EditorToolbar); -/* Exports for editor/ -/* @ts-expect-error */ +/* Exports for editor */ +// @ts-expect-error export { updateActiveButtons, clearActiveButtons } from "./CommandIconButton.svelte"; -/* @ts-expect-error */ +// @ts-expect-error export { enableButtons, disableButtons } from "./EditorToolbar.svelte"; - -/* Exports for add-ons */ -export { default as RawButton } from "./RawButton.svelte"; -export { default as LabelButton } from "./LabelButton.svelte"; -export { default as IconButton } from "./IconButton.svelte"; -export { default as CommandIconButton } from "./CommandIconButton.svelte"; -export { default as SelectButton } from "./SelectButton.svelte"; - -export { default as DropdownMenu } from "./DropdownMenu.svelte"; -export { default as DropdownItem } from "./DropdownItem.svelte"; -export { default as ButtonDropdown } from "./DropdownMenu.svelte"; -export { default as WithDropdownMenu } from "./WithDropdownMenu.svelte"; diff --git a/ts/editor/BUILD.bazel b/ts/editor/BUILD.bazel index d7da845d2..c4edeedd1 100644 --- a/ts/editor/BUILD.bazel +++ b/ts/editor/BUILD.bazel @@ -2,7 +2,7 @@ load("@npm//@bazel/typescript:index.bzl", "ts_library") load("//ts:prettier.bzl", "prettier_test") load("//ts:eslint.bzl", "eslint_test") load("//ts:esbuild.bzl", "esbuild") -load("//ts:vendor.bzl", "copy_bootstrap_icons") +load("//ts:vendor.bzl", "copy_bootstrap_icons", "copy_mdi_icons") load("//ts:compile_sass.bzl", "compile_sass") compile_sass( @@ -19,6 +19,7 @@ compile_sass( compile_sass( srcs = [ "fields.scss", + "color.scss", ], group = "base_css", visibility = ["//visibility:public"], @@ -35,14 +36,53 @@ ts_library( tsconfig = "//ts:tsconfig.json", deps = [ "//ts:image_module_support", + "//ts/lib", + "//ts/sveltelib", "//ts/html-filter", "//ts/editor-toolbar", + "@npm//svelte", ], ) copy_bootstrap_icons( name = "bootstrap-icons", - icons = ["pin-angle.svg"], + icons = [ + "pin-angle.svg", + + # inline formatting + "type-bold.svg", + "type-italic.svg", + "type-underline.svg", + "eraser.svg", + "square-fill.svg", + "paperclip.svg", + "mic.svg", + + # block formatting + "paragraph.svg", + "list-ul.svg", + "list-ol.svg", + "text-paragraph.svg", + "justify.svg", + "text-left.svg", + "text-right.svg", + "text-center.svg", + "text-indent-left.svg", + "text-indent-right.svg", + ], + visibility = ["//visibility:public"], +) + +copy_mdi_icons( + name = "mdi-icons", + icons = [ + "format-superscript.svg", + "format-subscript.svg", + "function-variant.svg", + "code-brackets.svg", + "xml.svg", + ], + visibility = ["//visibility:public"], ) esbuild( @@ -65,10 +105,9 @@ esbuild( deps = [ "base_css", "bootstrap-icons", + "mdi-icons", "editor_ts", "//ts/editor-toolbar:local_css", - "//ts/editor-toolbar:bootstrap-icons", - "//ts/editor-toolbar:mdi-icons", "//ts/editor-toolbar:ButtonDropdown", "//ts/editor-toolbar:ButtonGroup", "//ts/editor-toolbar:IconButton", diff --git a/ts/editor/addons.ts b/ts/editor/addons.ts new file mode 100644 index 000000000..b275e233d --- /dev/null +++ b/ts/editor/addons.ts @@ -0,0 +1,22 @@ +import { default as RawButton } from "editor-toolbar/RawButton.svelte"; +import { default as LabelButton } from "editor-toolbar/LabelButton.svelte"; +import { default as IconButton } from "editor-toolbar/IconButton.svelte"; +import { default as CommandIconButton } from "editor-toolbar/CommandIconButton.svelte"; +import { default as SelectButton } from "editor-toolbar/SelectButton.svelte"; + +import { default as DropdownMenu } from "editor-toolbar/DropdownMenu.svelte"; +import { default as DropdownItem } from "editor-toolbar/DropdownItem.svelte"; +import { default as ButtonDropdown } from "editor-toolbar/DropdownMenu.svelte"; +import { default as WithDropdownMenu } from "editor-toolbar/WithDropdownMenu.svelte"; + +export const editorToolbar = { + RawButton, + LabelButton, + IconButton, + CommandIconButton, + SelectButton, + DropdownMenu, + DropdownItem, + ButtonDropdown, + WithDropdownMenu, +}; diff --git a/ts/editor-toolbar/cloze.ts b/ts/editor/cloze.ts similarity index 91% rename from ts/editor-toolbar/cloze.ts rename to ts/editor/cloze.ts index 55fd8ea60..ffa5f5101 100644 --- a/ts/editor-toolbar/cloze.ts +++ b/ts/editor/cloze.ts @@ -1,7 +1,7 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import IconButton from "./IconButton.svelte"; -import type { IconButtonProps } from "./IconButton"; +import IconButton from "editor-toolbar/IconButton.svelte"; +import type { IconButtonProps } from "editor-toolbar/IconButton"; import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent"; import * as tr from "anki/i18n"; diff --git a/ts/editor-toolbar/color.scss b/ts/editor/color.scss similarity index 100% rename from ts/editor-toolbar/color.scss rename to ts/editor/color.scss diff --git a/ts/editor-toolbar/color.ts b/ts/editor/color.ts similarity index 81% rename from ts/editor-toolbar/color.ts rename to ts/editor/color.ts index 2ed6f932b..04d18e82f 100644 --- a/ts/editor-toolbar/color.ts +++ b/ts/editor/color.ts @@ -1,11 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import IconButton from "./IconButton.svelte"; -import type { IconButtonProps } from "./IconButton"; -import ColorPicker from "./ColorPicker.svelte"; -import type { ColorPickerProps } from "./ColorPicker"; -import ButtonGroup from "./ButtonGroup.svelte"; -import type { ButtonGroupProps } from "./ButtonGroup"; +import IconButton from "editor-toolbar/IconButton.svelte"; +import type { IconButtonProps } from "editor-toolbar/IconButton"; +import ColorPicker from "editor-toolbar/ColorPicker.svelte"; +import type { ColorPickerProps } from "editor-toolbar/ColorPicker"; +import ButtonGroup from "editor-toolbar/ButtonGroup.svelte"; +import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup"; import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent"; import * as tr from "anki/i18n"; diff --git a/ts/editor-toolbar/formatBlock.ts b/ts/editor/formatBlock.ts similarity index 85% rename from ts/editor-toolbar/formatBlock.ts rename to ts/editor/formatBlock.ts index e18b0d74c..0de457c20 100644 --- a/ts/editor-toolbar/formatBlock.ts +++ b/ts/editor/formatBlock.ts @@ -1,16 +1,16 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import ButtonGroup from "./ButtonGroup.svelte"; -import type { ButtonGroupProps } from "./ButtonGroup"; -import ButtonDropdown from "./ButtonDropdown.svelte"; -import type { ButtonDropdownProps } from "./ButtonDropdown"; -import WithDropdownMenu from "./WithDropdownMenu.svelte"; -import type { WithDropdownMenuProps } from "./WithDropdownMenu"; +import ButtonGroup from "editor-toolbar/ButtonGroup.svelte"; +import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup"; +import ButtonDropdown from "editor-toolbar/ButtonDropdown.svelte"; +import type { ButtonDropdownProps } from "editor-toolbar/ButtonDropdown"; +import WithDropdownMenu from "editor-toolbar/WithDropdownMenu.svelte"; +import type { WithDropdownMenuProps } from "editor-toolbar/WithDropdownMenu"; -import CommandIconButton from "./CommandIconButton.svelte"; -import type { CommandIconButtonProps } from "./CommandIconButton"; -import IconButton from "./IconButton.svelte"; -import type { IconButtonProps } from "./IconButton"; +import CommandIconButton from "editor-toolbar/CommandIconButton.svelte"; +import type { CommandIconButtonProps } from "editor-toolbar/CommandIconButton"; +import IconButton from "editor-toolbar/IconButton.svelte"; +import type { IconButtonProps } from "editor-toolbar/IconButton"; import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent"; import * as tr from "anki/i18n"; diff --git a/ts/editor-toolbar/formatInline.ts b/ts/editor/formatInline.ts similarity index 88% rename from ts/editor-toolbar/formatInline.ts rename to ts/editor/formatInline.ts index 2629d00f7..4ae1bddf3 100644 --- a/ts/editor-toolbar/formatInline.ts +++ b/ts/editor/formatInline.ts @@ -1,9 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import CommandIconButton from "./CommandIconButton.svelte"; -import type { CommandIconButtonProps } from "./CommandIconButton"; -import ButtonGroup from "./ButtonGroup.svelte"; -import type { ButtonGroupProps } from "./ButtonGroup"; +import CommandIconButton from "editor-toolbar/CommandIconButton.svelte"; +import type { CommandIconButtonProps } from "editor-toolbar/CommandIconButton"; +import ButtonGroup from "editor-toolbar/ButtonGroup.svelte"; +import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup"; import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent"; import * as tr from "anki/i18n"; diff --git a/ts/editor/index.ts b/ts/editor/index.ts index 0297963e1..b08025a39 100644 --- a/ts/editor/index.ts +++ b/ts/editor/index.ts @@ -3,6 +3,8 @@ import { filterHTML } from "html-filter"; import { updateActiveButtons, disableButtons } from "editor-toolbar"; +import { setupI18n, ModuleName } from "anki/i18n"; + import "./fields.css"; import { caretToEnd } from "./helpers"; @@ -17,6 +19,8 @@ export { setNoteId, getNoteId } from "./noteId"; export { saveNow } from "./changeTimer"; export { wrap, wrapIntoText } from "./wrap"; +export * from "./addons"; + declare global { interface Selection { modify(s: string, t: string, u: string): void; @@ -162,3 +166,33 @@ export function setFormat(cmd: string, arg?: any, nosave: boolean = false): void updateActiveButtons(); } } + +////////// EDITOR TOOLBAR + +import { getNotetypeGroup } from "./notetype"; +import { getFormatInlineGroup } from "./formatInline"; +import { getFormatBlockGroup, getFormatBlockMenus } from "./formatBlock"; +import { getColorGroup } from "./color"; +import { getTemplateGroup, getTemplateMenus } from "./template"; + +const i18n = setupI18n({ modules: [ModuleName.EDITING] }); + +document.addEventListener("DOMContentLoaded", () => { + i18n.then(() => { + $editorToolbar.buttonsPromise.then((buttons) => { + buttons.update(() => [ + getNotetypeGroup(), + getFormatInlineGroup(), + getFormatBlockGroup(), + getColorGroup(), + getTemplateGroup(), + ]); + return buttons; + }); + + $editorToolbar.menusPromise.then((menus) => { + menus.update(() => [...getFormatBlockMenus(), ...getTemplateMenus()]); + return menus; + }); + }); +}); diff --git a/ts/editor-toolbar/notetype.ts b/ts/editor/notetype.ts similarity index 81% rename from ts/editor-toolbar/notetype.ts rename to ts/editor/notetype.ts index 80a14095d..f90152ea2 100644 --- a/ts/editor-toolbar/notetype.ts +++ b/ts/editor/notetype.ts @@ -1,9 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import LabelButton from "./LabelButton.svelte"; -import type { LabelButtonProps } from "./LabelButton"; -import ButtonGroup from "./ButtonGroup.svelte"; -import type { ButtonGroupProps } from "./ButtonGroup"; +import LabelButton from "editor-toolbar/LabelButton.svelte"; +import type { LabelButtonProps } from "editor-toolbar/LabelButton"; +import ButtonGroup from "editor-toolbar/ButtonGroup.svelte"; +import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup"; import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent"; import { bridgeCommand } from "anki/bridgecommand"; diff --git a/ts/editor-toolbar/template.ts b/ts/editor/template.ts similarity index 84% rename from ts/editor-toolbar/template.ts rename to ts/editor/template.ts index 90ca847a2..956dc5e04 100644 --- a/ts/editor-toolbar/template.ts +++ b/ts/editor/template.ts @@ -1,15 +1,15 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import IconButton from "./IconButton.svelte"; -import type { IconButtonProps } from "./IconButton"; -import DropdownMenu from "./DropdownMenu.svelte"; -import type { DropdownMenuProps } from "./DropdownMenu"; -import DropdownItem from "./DropdownItem.svelte"; -import type { DropdownItemProps } from "./DropdownItem"; -import WithDropdownMenu from "./WithDropdownMenu.svelte"; -import type { WithDropdownMenuProps } from "./WithDropdownMenu"; -import ButtonGroup from "./ButtonGroup.svelte"; -import type { ButtonGroupProps } from "./ButtonGroup"; +import IconButton from "editor-toolbar/IconButton.svelte"; +import type { IconButtonProps } from "editor-toolbar/IconButton"; +import DropdownMenu from "editor-toolbar/DropdownMenu.svelte"; +import type { DropdownMenuProps } from "editor-toolbar/DropdownMenu"; +import DropdownItem from "editor-toolbar/DropdownItem.svelte"; +import type { DropdownItemProps } from "editor-toolbar/DropdownItem"; +import WithDropdownMenu from "editor-toolbar/WithDropdownMenu.svelte"; +import type { WithDropdownMenuProps } from "editor-toolbar/WithDropdownMenu"; +import ButtonGroup from "editor-toolbar/ButtonGroup.svelte"; +import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup"; import { bridgeCommand } from "anki/bridgecommand"; import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent";