Something went wrong. Try again.
Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515/* * Copyright (C) 2023-2025 Yomitan Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */
import type * as Anki from './anki';import type * as AnkiNoteBuilder from './anki-note-builder';import type * as Audio from './audio';import type * as AudioDownloader from './audio-downloader';import type * as Backend from './backend';import type * as Core from './core';import type * as Dictionary from './dictionary';import type * as DictionaryDatabase from './dictionary-database';import type * as DictionaryImporter from './dictionary-importer';import type * as Environment from './environment';import type * as Extension from './extension';import type * as Language from './language';import type * as Log from './log';import type * as Settings from './settings';import type * as SettingsModifications from './settings-modifications';import type * as Translation from './translation';import type * as Translator from './translator';import type {ApiMessageNoFrameIdAny as ApplicationApiMessageNoFrameIdAny} from './application';import type { ApiMap as BaseApiMap, ApiMapInit as BaseApiMapInit, ApiHandler as BaseApiHandler, ApiParams as BaseApiParams, ApiReturn as BaseApiReturn, ApiNames as BaseApiNames, ApiParam as BaseApiParam, ApiParamNames as BaseApiParamNames, ApiParamsAny as BaseApiParamsAny,} from './api-map';
export type FindTermsDetails = { matchType?: Translation.FindTermsMatchType; deinflect?: boolean; primaryReading?: string;};
export type ParseTextResultItem = { id: string; source: 'scanning-parser' | 'mecab'; dictionary: null | string; index: number; content: ParseTextLine[];};
export type ParseTextSegment = { text: string; reading: string; headwords?: { term: string; reading: string; sources: Dictionary.TermSource[]; }[][];};
export type ParseTextLine = ParseTextSegment[];
export type InjectAnkiNoteMediaTermDefinitionDetails = { type: 'term'; term: string; reading: string;};
export type InjectAnkiNoteMediaKanjiDefinitionDetails = { type: 'kanji'; character: string;};
export type InjectAnkiNoteMediaDefinitionDetails = InjectAnkiNoteMediaTermDefinitionDetails | InjectAnkiNoteMediaKanjiDefinitionDetails;
export type InjectAnkiNoteMediaAudioDetails = AnkiNoteBuilder.AudioMediaOptions;
export type InjectAnkiNoteMediaScreenshotDetails = { tabId: number; frameId: number; format: Settings.AnkiScreenshotFormat; quality: number;};
export type InjectAnkiNoteMediaClipboardDetails = { image: boolean; text: boolean;};
export type InjectAnkiNoteMediaDictionaryMediaDetails = { dictionary: string; path: string;};
export type InjectAnkiNoteDictionaryMediaResult = { dictionary: string; path: string; fileName: string | null;};
export type GetMediaDetailsTarget = { path: string; dictionary: string;};
export type GetTermFrequenciesDetailsTermReadingListItem = { term: string; reading: string | null;};
type ApiSurface = { applicationReady: { params: void; return: void; }; optionsGet: { params: { optionsContext: Settings.OptionsContext; }; return: Settings.ProfileOptions; }; optionsGetFull: { params: void; return: Settings.Options; }; termsFind: { params: { text: string; details: FindTermsDetails; optionsContext: Settings.OptionsContext; }; return: { dictionaryEntries: Dictionary.TermDictionaryEntry[]; originalTextLength: number; }; }; parseText: { params: { text: string | string[]; optionsContext: Settings.OptionsContext; scanLength: number; useInternalParser: boolean; useMecabParser: boolean; }; return: ParseTextResultItem[]; }; kanjiFind: { params: { text: string; optionsContext: Settings.OptionsContext; }; return: Dictionary.KanjiDictionaryEntry[]; }; isAnkiConnected: { params: void; return: boolean; }; getAnkiConnectVersion: { params: void; return: number | null; }; addAnkiNote: { params: { note: Anki.Note; }; return: Anki.NoteId | null; }; updateAnkiNote: { params: { noteWithId: Anki.NoteWithId; }; return: null; }; getAnkiNoteInfo: { params: { notes: Anki.Note[]; fetchAdditionalInfo: boolean; }; return: Anki.NoteInfoWrapper[]; }; injectAnkiNoteMedia: { params: { timestamp: number; definitionDetails: InjectAnkiNoteMediaDefinitionDetails; audioDetails: InjectAnkiNoteMediaAudioDetails | null; screenshotDetails: InjectAnkiNoteMediaScreenshotDetails | null; clipboardDetails: InjectAnkiNoteMediaClipboardDetails | null; dictionaryMediaDetails: InjectAnkiNoteMediaDictionaryMediaDetails[]; }; return: { screenshotFileName: string | null; clipboardImageFileName: string | null; clipboardText: string | null; audioFileName: string | null; dictionaryMedia: InjectAnkiNoteDictionaryMediaResult[]; errors: Core.SerializedError[]; }; }; viewNotes: { params: { noteIds: Anki.NoteId[]; mode: Settings.AnkiNoteGuiMode; allowFallback: boolean; }; return: Settings.AnkiNoteGuiMode; }; suspendAnkiCardsForNote: { params: { noteId: Anki.NoteId; }; return: number; }; getTermAudioInfoList: { params: { source: Audio.AudioSourceInfo; term: string; reading: string; languageSummary: Language.LanguageSummary; }; return: AudioDownloader.Info[]; }; commandExec: { params: { command: string; params?: Core.SerializableObject; }; return: boolean; }; sendMessageToFrame: { params: { frameId: number; message: ApplicationApiMessageNoFrameIdAny; }; return: boolean; }; broadcastTab: { params: { message: ApplicationApiMessageNoFrameIdAny; }; return: boolean; }; frameInformationGet: { params: void; return: Extension.ContentOrigin; }; injectStylesheet: { params: { type: 'file' | 'code'; value: string; }; return: void; }; getStylesheetContent: { params: { url: string; }; return: string; }; getEnvironmentInfo: { params: void; return: Environment.Info; }; clipboardGet: { params: void; return: string; }; getZoom: { params: void; return: { zoomFactor: number; }; }; getDefaultAnkiFieldTemplates: { params: void; return: string; }; getDictionaryInfo: { params: void; return: DictionaryImporter.Summary[]; }; purgeDatabase: { params: void; return: void; }; getMedia: { params: { targets: GetMediaDetailsTarget[]; }; return: DictionaryDatabase.MediaDataStringContent[]; }; logGenericErrorBackend: { params: { error: Core.SerializedError; level: Log.LogLevel; context: Log.LogContext | undefined; }; return: void; }; logIndicatorClear: { params: void; return: void; }; modifySettings: { params: { targets: SettingsModifications.ScopedModification[]; source: string; }; return: Core.Response<SettingsModifications.ModificationResult>[]; }; getSettings: { params: { targets: SettingsModifications.ScopedRead[]; }; return: Core.Response<SettingsModifications.ModificationResult>[]; }; setAllSettings: { params: { value: Settings.Options; source: string; }; return: void; }; getOrCreateSearchPopup: { params: { focus?: boolean | 'ifCreated'; text?: string; }; return: { tabId: number | null; windowId: number; }; }; isTabSearchPopup: { params: { tabId: number; }; return: boolean; }; triggerDatabaseUpdated: { params: { type: Backend.DatabaseUpdateType; cause: Backend.DatabaseUpdateCause; }; return: void; }; testMecab: { params: void; return: true; }; testYomitanApi: { params: { url: string; }; return: true; }; isTextLookupWorthy: { params: { text: string; language: string; }; return: boolean; }; getTermFrequencies: { params: { termReadingList: GetTermFrequenciesDetailsTermReadingListItem[]; dictionaries: string[]; }; return: Translator.TermFrequencySimple[]; }; findAnkiNotes: { params: { query: string; }; return: Anki.NoteId[]; }; openCrossFramePort: { params: { targetTabId: number; targetFrameId: number; }; return: { targetTabId: number; targetFrameId: number; }; }; requestBackendReadySignal: { params: void; return: boolean; }; getLanguageSummaries: { params: void; return: Language.LanguageSummary[]; }; heartbeat: { params: void; return: void; }; forceSync: { params: void; return: void; };};
type ApiExtraArgs = [sender: chrome.runtime.MessageSender];
export type ApiNames = BaseApiNames<ApiSurface>;
export type ApiMap = BaseApiMap<ApiSurface, ApiExtraArgs>;
export type ApiMapInit = BaseApiMapInit<ApiSurface, ApiExtraArgs>;
export type ApiHandler<TName extends ApiNames> = BaseApiHandler<ApiSurface[TName], ApiExtraArgs>;
export type ApiHandlerNoExtraArgs<TName extends ApiNames> = BaseApiHandler<ApiSurface[TName], []>;
export type ApiParams<TName extends ApiNames> = BaseApiParams<ApiSurface[TName]>;
export type ApiParam<TName extends ApiNames, TParamName extends BaseApiParamNames<ApiSurface[TName]>> = BaseApiParam<ApiSurface[TName], TParamName>;
export type ApiReturn<TName extends ApiNames> = BaseApiReturn<ApiSurface[TName]>;
export type ApiParamsAny = BaseApiParamsAny<ApiSurface>;
export type ApiMessageAny = {[name in ApiNames]: ApiMessage<name>}[ApiNames];
type ApiMessage<TName extends ApiNames> = { action: TName; params: ApiParams<TName>;};
// postMessage API (i.e., API endpoints called via postMessage, either through ServiceWorker on Chrome or a MessageChannel port on Firefox)
type PmApiSurface = { drawMedia: { params: { requests: DrawMediaRequest[]; }; return: void; }; connectToDatabaseWorker: { params: void; return: void; }; drawBufferToCanvases: { params: { buffer: ArrayBuffer; width: number; height: number; canvasIndexes: number[]; generation: number; }; return: void; }; drawDecodedImageToCanvases: { params: { decodedImage: VideoFrame | ImageBitmap; canvasIndexes: number[]; generation: number; }; return: void; }; registerOffscreenPort: { params: void; return: void; }; registerDatabasePort: { params: void; return: void; };};
type DrawMediaRequest = { path: string; dictionary: string; canvas: OffscreenCanvas;};
type PmApiExtraArgs = [ports: readonly MessagePort[] | null];
export type PmApiNames = BaseApiNames<PmApiSurface>;
export type PmApiMap = BaseApiMap<PmApiSurface, PmApiExtraArgs>;
export type PmApiMapInit = BaseApiMapInit<PmApiSurface, PmApiExtraArgs>;
export type PmApiHandler<TName extends PmApiNames> = BaseApiHandler<PmApiSurface[TName], PmApiExtraArgs>;
export type PmApiHandlerNoExtraArgs<TName extends PmApiNames> = BaseApiHandler<PmApiSurface[TName], []>;
export type PmApiParams<TName extends PmApiNames> = BaseApiParams<PmApiSurface[TName]>;
export type PmApiParam<TName extends PmApiNames, TParamName extends BaseApiParamNames<PmApiSurface[TName]>> = BaseApiParam<PmApiSurface[TName], TParamName>;
export type PmApiReturn<TName extends PmApiNames> = BaseApiReturn<PmApiSurface[TName]>;
export type PmApiParamsAny = BaseApiParamsAny<PmApiSurface>;
export type PmApiMessageAny = {[name in PmApiNames]: PmApiMessage<name>}[PmApiNames];
type PmApiMessage<TName extends PmApiNames> = { action: TName; params: PmApiParams<TName>;};