Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
1/*
2 * Copyright (C) 2023-2025 Yomitan Authors
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18import type {TextSourceGenerator} from '../../ext/js/dom/text-source-generator';
19import type {API} from '../../ext/js/comm/api';
20import type * as Dictionary from './dictionary';
21import type * as Display from './display';
22import type * as Input from './input';
23import type * as Settings from './settings';
24import type * as TextSource from './text-source';
25import type {EventNames, EventArgument as BaseEventArgument} from './core';
26import {PageType} from 'frontend';
27
28export type SearchResultDetail = {
29 documentTitle: string;
30};
31
32export type Options = {
33 inputs?: InputOptionsOuter[];
34 deepContentScan?: boolean;
35 normalizeCssZoom?: boolean;
36 selectText?: boolean;
37 delay?: number;
38 scanLength?: number;
39 layoutAwareScan?: boolean;
40 preventMiddleMouseOnPage?: boolean;
41 preventMiddleMouseOnTextHover?: boolean;
42 preventBackForwardOnPage?: boolean;
43 preventBackForwardOnTextHover?: boolean;
44 matchTypePrefix?: boolean;
45 sentenceParsingOptions?: SentenceParsingOptions;
46 scanWithoutMousemove?: boolean;
47 scanResolution?: string;
48 pageType?: PageType;
49};
50
51export type InputOptionsOuter = {
52 include: string;
53 exclude: string;
54 types: {
55 mouse: boolean;
56 touch: boolean;
57 pen: boolean;
58 };
59 options: InputOptions;
60};
61
62export type InputOptions = {
63 searchTerms: boolean;
64 searchKanji: boolean;
65 scanOnTouchMove: boolean;
66 scanOnTouchPress: boolean;
67 scanOnTouchRelease: boolean;
68 scanOnTouchTap: boolean;
69 scanOnPenMove: boolean;
70 scanOnPenHover: boolean;
71 scanOnPenReleaseHover: boolean;
72 scanOnPenPress: boolean;
73 scanOnPenRelease: boolean;
74 preventTouchScrolling: boolean;
75 preventPenScrolling: boolean;
76 minimumTouchTime: number;
77};
78
79export type SentenceParsingOptions = {
80 scanExtent: number;
81 terminationCharacterMode: Settings.SentenceTerminationCharacterMode;
82 terminationCharacters: Settings.SentenceParsingTerminationCharacterOption[];
83};
84
85export type InputConfig = {
86 include: string[];
87 exclude: string[];
88 types: Set<Input.PointerType>;
89 searchTerms: boolean;
90 searchKanji: boolean;
91 scanOnTouchMove: boolean;
92 scanOnTouchPress: boolean;
93 scanOnTouchRelease: boolean;
94 scanOnTouchTap: boolean;
95 scanOnPenMove: boolean;
96 scanOnPenHover: boolean;
97 scanOnPenReleaseHover: boolean;
98 scanOnPenPress: boolean;
99 scanOnPenRelease: boolean;
100 preventTouchScrolling: boolean;
101 preventPenScrolling: boolean;
102 minimumTouchTime: number;
103};
104
105export type InputInfo = {
106 input: InputConfig | null;
107 pointerType: Input.PointerType;
108 eventType: Input.PointerEventType;
109 passive: boolean;
110 modifiers: Input.Modifier[];
111 modifierKeys: Input.ModifierKey[];
112 detail: InputInfoDetail | undefined | null;
113};
114
115export type InputInfoDetail = {
116 focus: boolean;
117 restoreSelection: boolean;
118};
119
120export type Events = {
121 clear: {
122 reason: ClearReason;
123 };
124 searchSuccess: {
125 type: 'terms' | 'kanji';
126 dictionaryEntries: Dictionary.DictionaryEntry[];
127 sentence: Display.HistoryStateSentence;
128 inputInfo: InputInfo;
129 textSource: TextSource.TextSource;
130 optionsContext: Settings.OptionsContext;
131 detail: SearchResultDetail;
132 pageTheme: 'dark' | 'light';
133 };
134 searchEmpty: {
135 inputInfo: InputInfo;
136 };
137 searchError: {
138 error: Error;
139 textSource: TextSource.TextSource;
140 inputInfo: InputInfo;
141 };
142};
143
144export type ClearReason = 'mousedown';
145
146export type EventArgument<TName extends EventNames<Events>> = BaseEventArgument<Events, TName>;
147
148export type GetSearchContextCallback = GetSearchContextCallbackSync | GetSearchContextCallbackAsync;
149
150export type GetSearchContextCallbackSync = () => SearchContext;
151
152export type GetSearchContextCallbackAsync = () => Promise<SearchContext>;
153
154export type ConstructorDetails = {
155 api: API;
156 node: HTMLElement | Window;
157 getSearchContext: GetSearchContextCallback;
158 ignoreElements?: (() => Element[]) | null;
159 ignorePoint?: ((x: number, y: number) => Promise<boolean>) | null;
160 searchTerms?: boolean;
161 searchKanji?: boolean;
162 searchOnClick?: boolean;
163 searchOnClickOnly?: boolean;
164 textSourceGenerator: TextSourceGenerator;
165};
166
167export type SearchContext = {
168 optionsContext: Settings.OptionsContext;
169 detail: SearchResultDetail;
170};
171
172export type SelectionRestoreInfo = {
173 ranges: Range[];
174};
175
176export type TermSearchResults = {
177 type: 'terms';
178 dictionaryEntries: Dictionary.TermDictionaryEntry[];
179 sentence: Sentence;
180};
181
182export type KanjiSearchResults = {
183 type: 'kanji';
184 dictionaryEntries: Dictionary.KanjiDictionaryEntry[];
185 sentence: Sentence;
186};
187
188export type SearchResults = TermSearchResults | KanjiSearchResults;
189
190export type Sentence = {
191 text: string;
192 offset: number;
193};
194
195export type SentenceTerminatorMap = Map<string, [includeCharacterAtStart: boolean, includeCharacterAtEnd: boolean]>;
196
197export type SentenceForwardQuoteMap = Map<string, [character: string, includeCharacterAtStart: boolean]>;
198
199export type SentenceBackwardQuoteMap = Map<string, [character: string, includeCharacterAtEnd: boolean]>;