import type { AutocompleterSpec } from '../components/content/Autocompleter'; import type { ContextFormSpec } from '../components/content/ContextForm'; import type { ContextToolbarSpec } from '../components/content/ContextToolbar'; import type { ContextMenuApi } from '../components/menu/ContextMenu'; import type { MenuItemSpec } from '../components/menu/MenuItem'; import type { NestedMenuItemSpec } from '../components/menu/NestedMenuItem'; import type { ToggleMenuItemSpec } from '../components/menu/ToggleMenuItem'; import type { SidebarSpec } from '../components/sidebar/Sidebar'; import type { GroupToolbarButtonSpec } from '../components/toolbar/GroupToolbarButton'; import type { ToolbarButtonSpec } from '../components/toolbar/ToolbarButton'; import type { ToolbarMenuButtonSpec } from '../components/toolbar/ToolbarMenuButton'; import type { ToolbarSplitButtonSpec } from '../components/toolbar/ToolbarSplitButton'; import type { ToolbarToggleButtonSpec } from '../components/toolbar/ToolbarToggleButton'; import type { ViewSpec } from '../components/view/View'; // This would be part of the tinymce api under editor.ui.* so editor.ui.addButton('bold', ...) // TODO: This should maybe not be part of this project but rather something built into tinymce core using these public types export interface Registry { addButton: (name: string, spec: ToolbarButtonSpec) => void; addGroupToolbarButton: (name: string, spec: GroupToolbarButtonSpec) => void; addToggleButton: (name: string, spec: ToolbarToggleButtonSpec) => void; addMenuButton: (name: string, spec: ToolbarMenuButtonSpec) => void; addSplitButton: (name: string, spec: ToolbarSplitButtonSpec) => void; addMenuItem: (name: string, spec: MenuItemSpec) => void; addNestedMenuItem: (name: string, spec: NestedMenuItemSpec) => void; addToggleMenuItem: (name: string, spec: ToggleMenuItemSpec) => void; addContextMenu: (name: string, spec: ContextMenuApi) => void; addContextToolbar: (name: string, spec: ContextToolbarSpec) => void; addContextForm: (name: string, spec: ContextFormSpec) => void; addIcon: (name: string, svgData: string) => void; addAutocompleter: (name: string, spec: AutocompleterSpec) => void; addSidebar: (name: string, spec: SidebarSpec) => void; addView: (name: string, spec: ViewSpec) => void; addContext: (name: string, pred: (args: string) => boolean) => void; getAll: () => { buttons: Record; menuItems: Record; popups: Record; contextMenus: Record; contextToolbars: Record; icons: Record; sidebars: Record; views: Record; contexts: Record boolean>; }; } export const create = (): Registry => { const buttons: Record = {}; const menuItems: Record = {}; const popups: Record = {}; const icons: Record = {}; const contextMenus: Record = {}; const contextToolbars: Record = {}; const contexts: Record boolean> = {}; const sidebars: Record = {}; const views: Record = {}; const add = (collection: Record, type: string) => (name: string, spec: S): void => { collection[name.toLowerCase()] = { ...spec, type }; }; const addDefaulted = (collection: Record, type: string) => (name: string, spec: S): void => { collection[name.toLowerCase()] = { type, ...spec }; }; const addIcon = (name: string, svgData: string) => icons[name.toLowerCase()] = svgData; const addContext = (name: string, pred: (args: string) => boolean) => contexts[name.toLowerCase()] = pred; return { addButton: add(buttons, 'button'), addGroupToolbarButton: add(buttons, 'grouptoolbarbutton'), addToggleButton: add(buttons, 'togglebutton'), addMenuButton: add(buttons, 'menubutton'), addSplitButton: add(buttons, 'splitbutton'), addMenuItem: add(menuItems, 'menuitem'), addNestedMenuItem: add(menuItems, 'nestedmenuitem'), addToggleMenuItem: add(menuItems, 'togglemenuitem'), addAutocompleter: add(popups, 'autocompleter'), addContextMenu: add(contextMenus, 'contextmenu'), addContextToolbar: add(contextToolbars, 'contexttoolbar'), addContextForm: addDefaulted(contextToolbars, 'contextform'), addSidebar: add(sidebars, 'sidebar'), addView: add(views, 'views'), addIcon, addContext, getAll: () => ({ buttons, menuItems, icons, // TODO: should popups be combined with context menus? We'd need to make a new add function. // Right now using `add` shares the key namespace, which prevents registering both // a completer and a context menu with the same name popups, contextMenus, contextToolbars, sidebars, views, contexts }) }; };