diff --git a/baseStore.ts b/baseStore.ts new file mode 100644 index 0000000..05c341e --- /dev/null +++ b/baseStore.ts @@ -0,0 +1,12 @@ +export type BaseStoreListenerInit = { store: BaseStore; event: string }; +export type BaseStoreListener = (init: BaseStoreListenerInit) => void; +export declare class BaseStore { + constructor(); + + public addChangeListener(listener: BaseStoreListener): void; + public removeChangeListener(listener: BaseStoreListener): void; + public emitChange(event: string): void; + public get listenersCount(): number; + + private _onChangeListeners: BaseStoreListener[]; +} diff --git a/deps/events.ts b/deps/events.ts new file mode 100644 index 0000000..94f12cc --- /dev/null +++ b/deps/events.ts @@ -0,0 +1 @@ +export type { EventEmitter } from "https://deno.land/std@0.131.0/node/events.ts"; diff --git a/deps/react.ts b/deps/react.ts new file mode 100644 index 0000000..06095b7 --- /dev/null +++ b/deps/react.ts @@ -0,0 +1 @@ +export type { default as React } from "https://esm.sh/react@17.0.2"; diff --git a/layout.ts b/layout.ts new file mode 100644 index 0000000..8bc71ac --- /dev/null +++ b/layout.ts @@ -0,0 +1,31 @@ +export type PartialLayout = + | "launch" + | "error-page" + | "billings-new" + | "billings-info" + | "login-by-email-page" + | "login-by-email-confirm-page" + | "login-by-easy-trial-page" + | "list" + | "stream" + | "welcome-page" + | "new-project-page" + | "invitation-page" + | "no-project-page" + | "setup-profile" + | "settings-profile-page" + | "settings-extensions-page" + | "settings-file-capacity-page" + | "settings-delete-account-page" + | "project-settings-basic-page" + | "project-settings-pro-page" + | "project-settings-theme-page" + | "project-settings-notifications-page" + | "project-settings-backup-page" + | "project-settings-audit-page" + | "project-settings-members-page" + | "project-settings-page-data-page" + | "project-settings-upload-page" + | "project-settings-billing-page"; + +export type Layout = "page" | PartialLayout; diff --git a/pageMenu.ts b/pageMenu.ts new file mode 100644 index 0000000..aa68c67 --- /dev/null +++ b/pageMenu.ts @@ -0,0 +1,44 @@ +import type { React } from "./deps/react.ts"; +import { BaseStore } from "./baseStore.ts"; + +export type AddMenuInit = { + title?: string; + image: string; + onClick?: (event: React.MouseEvent) => void; +}; +export type Menu = { + image: string; + items: ((Item & { separator: false }) | { separator: true })[]; + onClick?: (event: React.MouseEvent) => void; +}; +export type Item = { + /** the title of a menu item */ + title: string | (() => string); + /** the URL of an image which views on the left of the title */ + image?: string; + /** the event listener which is executed when the menu item is clicked */ + onClick: (event: React.MouseEvent) => void; +}; + +export declare class PageMenu extends BaseStore { + constructor(); + public initialize(): void; + public reset(): void; + public pageMenu(menuName?: string): PageMenu; + public addMenu(init: AddMenuInit): void; + /** Add a menu item to a particular Page Menu button + * + * @param item information used for a menu item + */ + public addItem(item: Item): void; + /** Add a separator to a particular Page Menu button */ + public addSeparator(): void; + public removeAllItems(): void; + + public menuName: string; + public menus: Map; + + private _addToMenu( + item: (Item & { separator: false }) | { separator: true }, + ): void; +} diff --git a/userscript.ts b/userscript.ts index 434dadc..2519832 100644 --- a/userscript.ts +++ b/userscript.ts @@ -1,92 +1,56 @@ import { ParsedLine } from "./userscript/blocks.ts"; import { StringLc } from "./base.ts"; +import type { Layout, PartialLayout } from "./layout.ts"; +import type { AddMenuInit, Item, PageMenu } from "./pageMenu.ts"; +import type { EventEmitter } from "./deps/events.ts"; +export type { EventEmitter, Layout, ParsedLine, PartialLayout, StringLc }; +export * from "./pageMenu.ts"; -export type Layout = - | "list" - | "page" - | "stream" - | "project-settings-billing-page" - | "project-settings-basic-page" - | "project-settings-members-page" - | "settings-profile-page" - | "settings-extensions-page" - | "settings-delete-account-page"; export type Scrapbox = + & EventEmitter & { - Project: { - name: string; - pages: PageBrief[]; + PageMenu: { + (menuName?: string): PageMenu; + addMenu: (init: AddMenuInit) => void; + /** Add a menu item to a particular Page Menu button + * + * @param item information used for a menu item + */ + addItem: (item: Item) => void; + /** Add a separator to a particular Page Menu button */ + addSeparater: () => void; + removeAllItems: () => void; }; - TimeStamp: TimeStamp; PopupMenu: { - addButton: ( - props: { - title: string | ((selectedText: string) => string); - onClick: (selectedText: string) => string | undefined; - }, - ) => void; + addButton: (button: { + title: string | ((text: string) => (string | undefined)); + onClick: (text: string) => (string | undefined); + }) => void; }; - PageMenu: ((name: string) => PageMenu) & { - addMenu: ( - props: { title: string; image: string; onClick?: () => void }, - ) => void; - addItem: (props: AddItemProps) => void; - addSeparator: () => void; - removeAllItems: () => void; + TimeStamp: TimeStamp; + Project: { + get name(): string; + get pages(): PageBrief[]; }; } - & UserScriptEventTarget - & ({ - Layout: - | "list" - | "stream" - | "project-settings-billing-page" - | "project-settings-basic-page" - | "project-settings-members-page" - | "settings-profile-page" - | "settings-extensions-page" - | "settings-delete-account-page"; - Page: { - title: null; - lines: null; - id: null; - }; - } | { - Layout: "page"; - Page: { - title: string; - lines: ParsedLine[]; - id: string; - }; - }); + & ( + { + Layout: "page"; + Page: { + get lines(): ParsedLine[]; + get title(): string; + get id(): string; + }; + } | { + Layout: PartialLayout; + Page: { + get lines(): null; + get title(): null; + get id(): null; + }; + } + ); -export interface UserScriptEventTarget { - /** Register an event listener to Scrapbox - * - * @param type the event type the event listener registers to - * @param the event listener - */ - addListener: (type: string, listener: () => void) => void; - /** Register an event listener to Scrapbox - * - * @param type the event type the event listener registers to - * @param the event listener - */ - on: (type: string, listener: () => void) => void; - removeListener: (type: string, listener: () => void) => void; - off: (type: string, listener: () => void) => void; - removeAllListeners: (type?: string) => void; - once: (type: string, listener: () => void) => void; - prependListener: (type: string, listener: () => void) => void; - prependOnceListener: (type: string, listener: () => void) => void; - listeners: (type: string) => (() => void)[]; - rawListeners: (type: string) => (() => void)[]; - listenerCount: (type: string) => number; - emit: (type: string) => void; - eventNames: () => string[]; - getMexListeners: () => number; - setMexListeners: (length: number) => void; -} export interface PageBrief { /** true when the page has contents */ exists: boolean; /** whether the page contains any image */ hasIcon?: boolean; @@ -109,37 +73,6 @@ export interface TimeStamp { removeAllFormat: () => void; } -export interface AddItemProps { - /** the title of a menu item */ title: string | (() => string); - /** the URL of an image which views on the left of the title */ - image?: string; - /** the event listener which is executed when the menu item is clicked */ - onClick: () => void; -} -export interface PageMenu { - /** Add a menu item to a particular Page Menu button - * - * @param props information used for a menu item - */ - addItem: ( - props: AddItemProps, - ) => void; - /** Add a separator to a particular Page Menu button */ - addSeparator: () => void; - removeAllItems: () => void; - menuName: string; - reset: () => void; - emitChange: () => void; - menus: Map< - string, - { - image: string | null; - onClick?: () => void; - items: (AddItemProps & { separator: boolean })[]; - } - >; -} - /** built-in UserScript events */ export type eventName = | "lines:changed"