@embedpdf/plugin-search 1.5.0 → 2.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +324 -199
- package/dist/index.js.map +1 -1
- package/dist/lib/actions.d.ts +58 -22
- package/dist/lib/index.d.ts +2 -2
- package/dist/lib/reducer.d.ts +2 -1
- package/dist/lib/search-plugin.d.ts +8 -8
- package/dist/lib/types.d.ts +76 -63
- package/dist/preact/adapter.d.ts +1 -1
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +49 -18
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +49 -18
- package/dist/react/index.js.map +1 -1
- package/dist/shared/components/search-layer.d.ts +3 -2
- package/dist/shared/hooks/use-search.d.ts +4 -4
- package/dist/shared-preact/components/search-layer.d.ts +3 -2
- package/dist/shared-preact/hooks/use-search.d.ts +4 -4
- package/dist/shared-react/components/search-layer.d.ts +3 -2
- package/dist/shared-react/hooks/use-search.d.ts +4 -4
- package/dist/svelte/components/SearchLayer.svelte.d.ts +4 -3
- package/dist/svelte/hooks/use-search.svelte.d.ts +11 -5
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +69 -35
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/components/search-layer.vue.d.ts +4 -2
- package/dist/vue/hooks/use-search.d.ts +9 -64
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +77 -32
- package/dist/vue/index.js.map +1 -1
- package/package.json +4 -6
package/dist/index.js
CHANGED
|
@@ -1,39 +1,149 @@
|
|
|
1
1
|
import { BasePlugin, createBehaviorEmitter } from "@embedpdf/core";
|
|
2
|
-
import { PdfTaskHelper } from "@embedpdf/models";
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
import { PdfErrorCode, PdfTaskHelper } from "@embedpdf/models";
|
|
3
|
+
const INIT_SEARCH_STATE = "SEARCH/INIT_STATE";
|
|
4
|
+
const CLEANUP_SEARCH_STATE = "SEARCH/CLEANUP_STATE";
|
|
5
|
+
const START_SEARCH_SESSION = "SEARCH/START_SEARCH_SESSION";
|
|
6
|
+
const STOP_SEARCH_SESSION = "SEARCH/STOP_SEARCH_SESSION";
|
|
7
|
+
const SET_SEARCH_FLAGS = "SEARCH/SET_SEARCH_FLAGS";
|
|
8
|
+
const SET_SHOW_ALL_RESULTS = "SEARCH/SET_SHOW_ALL_RESULTS";
|
|
9
|
+
const START_SEARCH = "SEARCH/START_SEARCH";
|
|
10
|
+
const SET_SEARCH_RESULTS = "SEARCH/SET_SEARCH_RESULTS";
|
|
11
|
+
const APPEND_SEARCH_RESULTS = "SEARCH/APPEND_SEARCH_RESULTS";
|
|
12
|
+
const SET_ACTIVE_RESULT_INDEX = "SEARCH/SET_ACTIVE_RESULT_INDEX";
|
|
13
|
+
function initSearchState(documentId, state) {
|
|
14
|
+
return { type: INIT_SEARCH_STATE, payload: { documentId, state } };
|
|
13
15
|
}
|
|
14
|
-
function
|
|
15
|
-
return { type:
|
|
16
|
+
function cleanupSearchState(documentId) {
|
|
17
|
+
return { type: CLEANUP_SEARCH_STATE, payload: documentId };
|
|
16
18
|
}
|
|
17
|
-
function
|
|
18
|
-
return { type:
|
|
19
|
+
function startSearchSession(documentId) {
|
|
20
|
+
return { type: START_SEARCH_SESSION, payload: { documentId } };
|
|
19
21
|
}
|
|
20
|
-
function
|
|
21
|
-
return { type:
|
|
22
|
+
function stopSearchSession(documentId) {
|
|
23
|
+
return { type: STOP_SEARCH_SESSION, payload: { documentId } };
|
|
22
24
|
}
|
|
23
|
-
function
|
|
24
|
-
return { type:
|
|
25
|
+
function setSearchFlags(documentId, flags) {
|
|
26
|
+
return { type: SET_SEARCH_FLAGS, payload: { documentId, flags } };
|
|
25
27
|
}
|
|
26
|
-
function
|
|
27
|
-
return { type:
|
|
28
|
+
function setShowAllResults(documentId, showAll) {
|
|
29
|
+
return { type: SET_SHOW_ALL_RESULTS, payload: { documentId, showAll } };
|
|
28
30
|
}
|
|
29
|
-
function
|
|
30
|
-
return { type:
|
|
31
|
+
function startSearch(documentId, query) {
|
|
32
|
+
return { type: START_SEARCH, payload: { documentId, query } };
|
|
31
33
|
}
|
|
32
|
-
function
|
|
33
|
-
return { type:
|
|
34
|
+
function setSearchResults(documentId, results, total, activeResultIndex) {
|
|
35
|
+
return { type: SET_SEARCH_RESULTS, payload: { documentId, results, total, activeResultIndex } };
|
|
34
36
|
}
|
|
37
|
+
function appendSearchResults(documentId, results) {
|
|
38
|
+
return { type: APPEND_SEARCH_RESULTS, payload: { documentId, results } };
|
|
39
|
+
}
|
|
40
|
+
function setActiveResultIndex(documentId, index) {
|
|
41
|
+
return { type: SET_ACTIVE_RESULT_INDEX, payload: { documentId, index } };
|
|
42
|
+
}
|
|
43
|
+
const initialSearchDocumentState = {
|
|
44
|
+
flags: [],
|
|
45
|
+
results: [],
|
|
46
|
+
total: 0,
|
|
47
|
+
activeResultIndex: -1,
|
|
48
|
+
showAllResults: true,
|
|
49
|
+
query: "",
|
|
50
|
+
loading: false,
|
|
51
|
+
active: false
|
|
52
|
+
};
|
|
53
|
+
const initialState = {
|
|
54
|
+
documents: {}
|
|
55
|
+
};
|
|
56
|
+
const updateDocState = (state, documentId, newDocState) => {
|
|
57
|
+
const oldDocState = state.documents[documentId] || initialSearchDocumentState;
|
|
58
|
+
return {
|
|
59
|
+
...state,
|
|
60
|
+
documents: {
|
|
61
|
+
...state.documents,
|
|
62
|
+
[documentId]: {
|
|
63
|
+
...oldDocState,
|
|
64
|
+
...newDocState
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
const searchReducer = (state = initialState, action) => {
|
|
70
|
+
switch (action.type) {
|
|
71
|
+
case INIT_SEARCH_STATE:
|
|
72
|
+
return {
|
|
73
|
+
...state,
|
|
74
|
+
documents: {
|
|
75
|
+
...state.documents,
|
|
76
|
+
[action.payload.documentId]: action.payload.state
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
case CLEANUP_SEARCH_STATE: {
|
|
80
|
+
const documentId = action.payload;
|
|
81
|
+
const { [documentId]: removed, ...remaining } = state.documents;
|
|
82
|
+
return {
|
|
83
|
+
...state,
|
|
84
|
+
documents: remaining
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
case START_SEARCH_SESSION:
|
|
88
|
+
return updateDocState(state, action.payload.documentId, { active: true });
|
|
89
|
+
case STOP_SEARCH_SESSION:
|
|
90
|
+
return updateDocState(state, action.payload.documentId, {
|
|
91
|
+
results: [],
|
|
92
|
+
total: 0,
|
|
93
|
+
activeResultIndex: -1,
|
|
94
|
+
query: "",
|
|
95
|
+
loading: false,
|
|
96
|
+
active: false
|
|
97
|
+
});
|
|
98
|
+
case SET_SEARCH_FLAGS:
|
|
99
|
+
return updateDocState(state, action.payload.documentId, { flags: action.payload.flags });
|
|
100
|
+
case SET_SHOW_ALL_RESULTS:
|
|
101
|
+
return updateDocState(state, action.payload.documentId, {
|
|
102
|
+
showAllResults: action.payload.showAll
|
|
103
|
+
});
|
|
104
|
+
case START_SEARCH:
|
|
105
|
+
return updateDocState(state, action.payload.documentId, {
|
|
106
|
+
loading: true,
|
|
107
|
+
query: action.payload.query,
|
|
108
|
+
// clear old results on new search start
|
|
109
|
+
results: [],
|
|
110
|
+
total: 0,
|
|
111
|
+
activeResultIndex: -1
|
|
112
|
+
});
|
|
113
|
+
case APPEND_SEARCH_RESULTS: {
|
|
114
|
+
const { documentId, results } = action.payload;
|
|
115
|
+
const docState = state.documents[documentId];
|
|
116
|
+
if (!docState) return state;
|
|
117
|
+
const newResults = [...docState.results, ...results];
|
|
118
|
+
const firstHitIndex = docState.activeResultIndex === -1 && newResults.length > 0 ? 0 : docState.activeResultIndex;
|
|
119
|
+
return updateDocState(state, documentId, {
|
|
120
|
+
results: newResults,
|
|
121
|
+
total: newResults.length,
|
|
122
|
+
// total-so-far
|
|
123
|
+
activeResultIndex: firstHitIndex,
|
|
124
|
+
// keep loading true until final SET_SEARCH_RESULTS
|
|
125
|
+
loading: true
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
case SET_SEARCH_RESULTS: {
|
|
129
|
+
const { documentId, results, total, activeResultIndex } = action.payload;
|
|
130
|
+
return updateDocState(state, documentId, {
|
|
131
|
+
results,
|
|
132
|
+
total,
|
|
133
|
+
activeResultIndex,
|
|
134
|
+
loading: false
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
case SET_ACTIVE_RESULT_INDEX:
|
|
138
|
+
return updateDocState(state, action.payload.documentId, {
|
|
139
|
+
activeResultIndex: action.payload.index
|
|
140
|
+
});
|
|
141
|
+
default:
|
|
142
|
+
return state;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
35
145
|
const _SearchPlugin = class _SearchPlugin extends BasePlugin {
|
|
36
|
-
constructor(id, registry) {
|
|
146
|
+
constructor(id, registry, config) {
|
|
37
147
|
super(id, registry);
|
|
38
148
|
this.searchStop$ = createBehaviorEmitter();
|
|
39
149
|
this.searchStart$ = createBehaviorEmitter();
|
|
@@ -41,172 +151,250 @@ const _SearchPlugin = class _SearchPlugin extends BasePlugin {
|
|
|
41
151
|
this.searchActiveResultChange$ = createBehaviorEmitter();
|
|
42
152
|
this.searchResultState$ = createBehaviorEmitter();
|
|
43
153
|
this.searchState$ = createBehaviorEmitter();
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
this.loader.onLoaderEvent(this.handleLoaderEvent.bind(this));
|
|
154
|
+
this.currentTask = /* @__PURE__ */ new Map();
|
|
155
|
+
this.pluginConfig = config;
|
|
47
156
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.
|
|
52
|
-
|
|
157
|
+
onDocumentLoadingStarted(documentId) {
|
|
158
|
+
const initialState2 = {
|
|
159
|
+
...initialSearchDocumentState,
|
|
160
|
+
flags: this.pluginConfig.flags || [],
|
|
161
|
+
showAllResults: this.pluginConfig.showAllResults ?? true
|
|
162
|
+
};
|
|
163
|
+
this.dispatch(initSearchState(documentId, initialState2));
|
|
53
164
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
this.currentDocument = void 0;
|
|
60
|
-
}
|
|
165
|
+
onDocumentClosed(documentId) {
|
|
166
|
+
this.stopSearchSession(documentId);
|
|
167
|
+
this.dispatch(cleanupSearchState(documentId));
|
|
168
|
+
this.currentTask.delete(documentId);
|
|
61
169
|
}
|
|
62
|
-
async initialize(
|
|
63
|
-
this.dispatch(setSearchFlags(config.flags || []));
|
|
64
|
-
this.dispatch(
|
|
65
|
-
setShowAllResults(config.showAllResults !== void 0 ? config.showAllResults : true)
|
|
66
|
-
);
|
|
170
|
+
async initialize() {
|
|
67
171
|
}
|
|
68
|
-
onStoreUpdated(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
172
|
+
onStoreUpdated(prevState, newState) {
|
|
173
|
+
for (const documentId in newState.documents) {
|
|
174
|
+
const prevDocState = prevState.documents[documentId];
|
|
175
|
+
const newDocState = newState.documents[documentId];
|
|
176
|
+
if (prevDocState !== newDocState) {
|
|
177
|
+
this.searchState$.emit({ documentId, state: newDocState });
|
|
178
|
+
if (!prevDocState || prevDocState.results !== newDocState.results || prevDocState.activeResultIndex !== newDocState.activeResultIndex || prevDocState.showAllResults !== newDocState.showAllResults || prevDocState.active !== newDocState.active) {
|
|
179
|
+
this.searchResultState$.emit({
|
|
180
|
+
documentId,
|
|
181
|
+
state: {
|
|
182
|
+
results: newDocState.results,
|
|
183
|
+
activeResultIndex: newDocState.activeResultIndex,
|
|
184
|
+
showAllResults: newDocState.showAllResults,
|
|
185
|
+
active: newDocState.active
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
76
191
|
}
|
|
77
192
|
buildCapability() {
|
|
193
|
+
const getDocId = (documentId) => documentId ?? this.getActiveDocumentId();
|
|
194
|
+
const getDocState = (docId) => {
|
|
195
|
+
const id = getDocId(docId);
|
|
196
|
+
const state = this.state.documents[id];
|
|
197
|
+
if (!state) throw new Error(`Search state not found for document ${id}`);
|
|
198
|
+
return state;
|
|
199
|
+
};
|
|
78
200
|
return {
|
|
79
|
-
startSearch: this.startSearchSession
|
|
80
|
-
stopSearch: this.stopSearchSession
|
|
81
|
-
searchAllPages: this.searchAllPages
|
|
82
|
-
nextResult: this.nextResult
|
|
83
|
-
previousResult: this.previousResult
|
|
84
|
-
goToResult: this.goToResult
|
|
85
|
-
setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),
|
|
86
|
-
getShowAllResults: () =>
|
|
201
|
+
startSearch: (docId) => this.startSearchSession(getDocId(docId)),
|
|
202
|
+
stopSearch: (docId) => this.stopSearchSession(getDocId(docId)),
|
|
203
|
+
searchAllPages: (keyword, docId) => this.searchAllPages(keyword, getDocId(docId)),
|
|
204
|
+
nextResult: (docId) => this.nextResult(getDocId(docId)),
|
|
205
|
+
previousResult: (docId) => this.previousResult(getDocId(docId)),
|
|
206
|
+
goToResult: (index, docId) => this.goToResult(index, getDocId(docId)),
|
|
207
|
+
setShowAllResults: (showAll, docId) => this.dispatch(setShowAllResults(getDocId(docId), showAll)),
|
|
208
|
+
getShowAllResults: (docId) => getDocState(docId).showAllResults,
|
|
209
|
+
getFlags: (docId) => getDocState(docId).flags,
|
|
210
|
+
setFlags: (flags, docId) => this.setFlags(flags, getDocId(docId)),
|
|
211
|
+
getState: (docId) => getDocState(docId),
|
|
212
|
+
forDocument: this.createSearchScope.bind(this),
|
|
87
213
|
onSearchResult: this.searchResult$.on,
|
|
88
214
|
onSearchStart: this.searchStart$.on,
|
|
89
215
|
onSearchStop: this.searchStop$.on,
|
|
90
216
|
onActiveResultChange: this.searchActiveResultChange$.on,
|
|
91
217
|
onSearchResultStateChange: this.searchResultState$.on,
|
|
92
|
-
onStateChange: this.searchState$.on
|
|
93
|
-
getFlags: () => this.state.flags,
|
|
94
|
-
setFlags: (flags) => this.setFlags(flags),
|
|
95
|
-
getState: () => this.state
|
|
218
|
+
onStateChange: this.searchState$.on
|
|
96
219
|
};
|
|
97
220
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
221
|
+
createSearchScope(documentId) {
|
|
222
|
+
const getDocState = () => {
|
|
223
|
+
const state = this.state.documents[documentId];
|
|
224
|
+
if (!state) throw new Error(`Search state not found for document ${documentId}`);
|
|
225
|
+
return state;
|
|
226
|
+
};
|
|
227
|
+
return {
|
|
228
|
+
startSearch: () => this.startSearchSession(documentId),
|
|
229
|
+
stopSearch: () => this.stopSearchSession(documentId),
|
|
230
|
+
searchAllPages: (keyword) => this.searchAllPages(keyword, documentId),
|
|
231
|
+
nextResult: () => this.nextResult(documentId),
|
|
232
|
+
previousResult: () => this.previousResult(documentId),
|
|
233
|
+
goToResult: (index) => this.goToResult(index, documentId),
|
|
234
|
+
setShowAllResults: (showAll) => this.dispatch(setShowAllResults(documentId, showAll)),
|
|
235
|
+
getShowAllResults: () => getDocState().showAllResults,
|
|
236
|
+
getFlags: () => getDocState().flags,
|
|
237
|
+
setFlags: (flags) => this.setFlags(flags, documentId),
|
|
238
|
+
getState: getDocState,
|
|
239
|
+
onSearchResult: (listener) => this.searchResult$.on((event) => {
|
|
240
|
+
if (event.documentId === documentId) listener(event.results);
|
|
241
|
+
}),
|
|
242
|
+
onSearchStart: (listener) => this.searchStart$.on((event) => {
|
|
243
|
+
if (event.documentId === documentId) listener();
|
|
244
|
+
}),
|
|
245
|
+
onSearchStop: (listener) => this.searchStop$.on((event) => {
|
|
246
|
+
if (event.documentId === documentId) listener();
|
|
247
|
+
}),
|
|
248
|
+
onActiveResultChange: (listener) => this.searchActiveResultChange$.on((event) => {
|
|
249
|
+
if (event.documentId === documentId) listener(event.index);
|
|
250
|
+
}),
|
|
251
|
+
onSearchResultStateChange: (listener) => this.searchResultState$.on((event) => {
|
|
252
|
+
if (event.documentId === documentId) listener(event.state);
|
|
253
|
+
}),
|
|
254
|
+
onStateChange: (listener) => this.searchState$.on((event) => {
|
|
255
|
+
if (event.documentId === documentId) listener(event.state);
|
|
256
|
+
})
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
setFlags(flags, documentId) {
|
|
260
|
+
this.dispatch(setSearchFlags(documentId, flags));
|
|
261
|
+
const docState = this.state.documents[documentId];
|
|
262
|
+
if (docState == null ? void 0 : docState.active) {
|
|
263
|
+
this.searchAllPages(docState.query, documentId, true);
|
|
102
264
|
}
|
|
103
265
|
}
|
|
104
|
-
notifySearchStart() {
|
|
105
|
-
this.searchStart$.emit();
|
|
266
|
+
notifySearchStart(documentId) {
|
|
267
|
+
this.searchStart$.emit({ documentId });
|
|
106
268
|
}
|
|
107
|
-
notifySearchStop() {
|
|
108
|
-
this.searchStop$.emit();
|
|
269
|
+
notifySearchStop(documentId) {
|
|
270
|
+
this.searchStop$.emit({ documentId });
|
|
109
271
|
}
|
|
110
|
-
notifyActiveResultChange(index) {
|
|
111
|
-
this.searchActiveResultChange$.emit(index);
|
|
272
|
+
notifyActiveResultChange(documentId, index) {
|
|
273
|
+
this.searchActiveResultChange$.emit({ documentId, index });
|
|
112
274
|
}
|
|
113
|
-
startSearchSession() {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.
|
|
275
|
+
startSearchSession(documentId) {
|
|
276
|
+
const coreDoc = this.getCoreDocument(documentId);
|
|
277
|
+
if (!coreDoc) return;
|
|
278
|
+
this.dispatch(startSearchSession(documentId));
|
|
279
|
+
this.notifySearchStart(documentId);
|
|
117
280
|
}
|
|
118
|
-
stopSearchSession() {
|
|
119
|
-
var _a
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
281
|
+
stopSearchSession(documentId) {
|
|
282
|
+
var _a;
|
|
283
|
+
const docState = this.state.documents[documentId];
|
|
284
|
+
if (!(docState == null ? void 0 : docState.active)) return;
|
|
285
|
+
const task = this.currentTask.get(documentId);
|
|
286
|
+
if (task) {
|
|
287
|
+
try {
|
|
288
|
+
(_a = task.abort) == null ? void 0 : _a.call(task, { code: PdfErrorCode.Cancelled, message: "search stopped" });
|
|
289
|
+
} catch {
|
|
290
|
+
}
|
|
291
|
+
this.currentTask.delete(documentId);
|
|
124
292
|
}
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
127
|
-
this.notifySearchStop();
|
|
293
|
+
this.dispatch(stopSearchSession(documentId));
|
|
294
|
+
this.notifySearchStop(documentId);
|
|
128
295
|
}
|
|
129
|
-
searchAllPages(keyword, force = false) {
|
|
130
|
-
var _a
|
|
296
|
+
searchAllPages(keyword, documentId, force = false) {
|
|
297
|
+
var _a;
|
|
298
|
+
const docState = this.state.documents[documentId];
|
|
299
|
+
if (!docState) {
|
|
300
|
+
return PdfTaskHelper.reject({
|
|
301
|
+
code: PdfErrorCode.NotFound,
|
|
302
|
+
message: "Search state not initialized"
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
const coreDoc = this.getCoreDocument(documentId);
|
|
306
|
+
if (!(coreDoc == null ? void 0 : coreDoc.document)) {
|
|
307
|
+
return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: "Document not loaded" });
|
|
308
|
+
}
|
|
131
309
|
const trimmedKeyword = keyword.trim();
|
|
132
|
-
if (
|
|
310
|
+
if (docState.query === trimmedKeyword && !force) {
|
|
133
311
|
return PdfTaskHelper.resolve({
|
|
134
|
-
results:
|
|
135
|
-
total:
|
|
312
|
+
results: docState.results,
|
|
313
|
+
total: docState.total
|
|
136
314
|
});
|
|
137
315
|
}
|
|
138
|
-
|
|
316
|
+
const oldTask = this.currentTask.get(documentId);
|
|
317
|
+
if (oldTask) {
|
|
139
318
|
try {
|
|
140
|
-
(
|
|
319
|
+
(_a = oldTask.abort) == null ? void 0 : _a.call(oldTask, { code: PdfErrorCode.Cancelled, message: "new search" });
|
|
141
320
|
} catch {
|
|
142
321
|
}
|
|
143
|
-
this.currentTask
|
|
322
|
+
this.currentTask.delete(documentId);
|
|
144
323
|
}
|
|
145
|
-
this.dispatch(startSearch(trimmedKeyword));
|
|
146
|
-
if (!trimmedKeyword
|
|
147
|
-
this.dispatch(setSearchResults([], 0, -1));
|
|
324
|
+
this.dispatch(startSearch(documentId, trimmedKeyword));
|
|
325
|
+
if (!trimmedKeyword) {
|
|
326
|
+
this.dispatch(setSearchResults(documentId, [], 0, -1));
|
|
148
327
|
return PdfTaskHelper.resolve({
|
|
149
328
|
results: [],
|
|
150
329
|
total: 0
|
|
151
330
|
});
|
|
152
331
|
}
|
|
153
|
-
if (!
|
|
154
|
-
this.startSearchSession();
|
|
332
|
+
if (!docState.active) {
|
|
333
|
+
this.startSearchSession(documentId);
|
|
155
334
|
}
|
|
156
|
-
const task = this.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
);
|
|
335
|
+
const task = this.engine.searchAllPages(coreDoc.document, trimmedKeyword, {
|
|
336
|
+
flags: docState.flags
|
|
337
|
+
});
|
|
338
|
+
this.currentTask.set(documentId, task);
|
|
161
339
|
task.onProgress((p) => {
|
|
162
340
|
var _a2;
|
|
163
341
|
if ((_a2 = p == null ? void 0 : p.results) == null ? void 0 : _a2.length) {
|
|
164
|
-
this.
|
|
165
|
-
|
|
166
|
-
this.
|
|
167
|
-
|
|
342
|
+
if (this.currentTask.get(documentId) === task) {
|
|
343
|
+
this.dispatch(appendSearchResults(documentId, p.results));
|
|
344
|
+
if (this.state.documents[documentId].activeResultIndex === -1) {
|
|
345
|
+
this.dispatch(setActiveResultIndex(documentId, 0));
|
|
346
|
+
this.notifyActiveResultChange(documentId, 0);
|
|
347
|
+
}
|
|
168
348
|
}
|
|
169
349
|
}
|
|
170
350
|
});
|
|
171
351
|
task.wait(
|
|
172
352
|
(results) => {
|
|
173
|
-
this.currentTask
|
|
353
|
+
this.currentTask.delete(documentId);
|
|
174
354
|
const activeResultIndex = results.total > 0 ? 0 : -1;
|
|
175
|
-
this.dispatch(
|
|
176
|
-
|
|
355
|
+
this.dispatch(
|
|
356
|
+
setSearchResults(documentId, results.results, results.total, activeResultIndex)
|
|
357
|
+
);
|
|
358
|
+
this.searchResult$.emit({ documentId, results });
|
|
177
359
|
if (results.total > 0) {
|
|
178
|
-
this.notifyActiveResultChange(0);
|
|
360
|
+
this.notifyActiveResultChange(documentId, 0);
|
|
179
361
|
}
|
|
180
362
|
},
|
|
181
363
|
(error) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
364
|
+
var _a2;
|
|
365
|
+
if (((_a2 = error == null ? void 0 : error.reason) == null ? void 0 : _a2.code) !== PdfErrorCode.Cancelled) {
|
|
366
|
+
console.error("Error during search:", error);
|
|
367
|
+
this.dispatch(setSearchResults(documentId, [], 0, -1));
|
|
368
|
+
}
|
|
369
|
+
this.currentTask.delete(documentId);
|
|
185
370
|
}
|
|
186
371
|
);
|
|
187
372
|
return task;
|
|
188
373
|
}
|
|
189
|
-
nextResult() {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
374
|
+
nextResult(documentId) {
|
|
375
|
+
const docState = this.state.documents[documentId];
|
|
376
|
+
if (!docState || docState.results.length === 0) return -1;
|
|
377
|
+
const nextIndex = docState.activeResultIndex >= docState.results.length - 1 ? 0 : docState.activeResultIndex + 1;
|
|
378
|
+
return this.goToResult(nextIndex, documentId);
|
|
193
379
|
}
|
|
194
|
-
previousResult() {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
380
|
+
previousResult(documentId) {
|
|
381
|
+
const docState = this.state.documents[documentId];
|
|
382
|
+
if (!docState || docState.results.length === 0) return -1;
|
|
383
|
+
const prevIndex = docState.activeResultIndex <= 0 ? docState.results.length - 1 : docState.activeResultIndex - 1;
|
|
384
|
+
return this.goToResult(prevIndex, documentId);
|
|
198
385
|
}
|
|
199
|
-
goToResult(index) {
|
|
200
|
-
|
|
386
|
+
goToResult(index, documentId) {
|
|
387
|
+
const docState = this.state.documents[documentId];
|
|
388
|
+
if (!docState || docState.results.length === 0 || index < 0 || index >= docState.results.length) {
|
|
201
389
|
return -1;
|
|
202
390
|
}
|
|
203
|
-
this.dispatch(setActiveResultIndex(index));
|
|
204
|
-
this.notifyActiveResultChange(index);
|
|
391
|
+
this.dispatch(setActiveResultIndex(documentId, index));
|
|
392
|
+
this.notifyActiveResultChange(documentId, index);
|
|
205
393
|
return index;
|
|
206
394
|
}
|
|
207
395
|
async destroy() {
|
|
208
|
-
|
|
209
|
-
this.stopSearchSession();
|
|
396
|
+
for (const documentId of Object.keys(this.state.documents)) {
|
|
397
|
+
this.stopSearchSession(documentId);
|
|
210
398
|
}
|
|
211
399
|
this.searchResult$.clear();
|
|
212
400
|
this.searchStart$.clear();
|
|
@@ -214,6 +402,7 @@ const _SearchPlugin = class _SearchPlugin extends BasePlugin {
|
|
|
214
402
|
this.searchActiveResultChange$.clear();
|
|
215
403
|
this.searchResultState$.clear();
|
|
216
404
|
this.searchState$.clear();
|
|
405
|
+
super.destroy();
|
|
217
406
|
}
|
|
218
407
|
};
|
|
219
408
|
_SearchPlugin.id = "search";
|
|
@@ -224,81 +413,16 @@ const manifest = {
|
|
|
224
413
|
name: "Search Plugin",
|
|
225
414
|
version: "1.0.0",
|
|
226
415
|
provides: ["search"],
|
|
227
|
-
requires: [
|
|
416
|
+
requires: [],
|
|
228
417
|
optional: [],
|
|
229
418
|
defaultConfig: {
|
|
230
419
|
enabled: true,
|
|
231
420
|
flags: []
|
|
232
421
|
}
|
|
233
422
|
};
|
|
234
|
-
const initialState = {
|
|
235
|
-
flags: [],
|
|
236
|
-
results: [],
|
|
237
|
-
total: 0,
|
|
238
|
-
activeResultIndex: -1,
|
|
239
|
-
showAllResults: true,
|
|
240
|
-
query: "",
|
|
241
|
-
loading: false,
|
|
242
|
-
active: false
|
|
243
|
-
};
|
|
244
|
-
const searchReducer = (state = initialState, action) => {
|
|
245
|
-
switch (action.type) {
|
|
246
|
-
case START_SEARCH_SESSION:
|
|
247
|
-
return { ...state, active: true };
|
|
248
|
-
case STOP_SEARCH_SESSION:
|
|
249
|
-
return {
|
|
250
|
-
...state,
|
|
251
|
-
results: [],
|
|
252
|
-
total: 0,
|
|
253
|
-
activeResultIndex: -1,
|
|
254
|
-
query: "",
|
|
255
|
-
loading: false,
|
|
256
|
-
active: false
|
|
257
|
-
};
|
|
258
|
-
case SET_SEARCH_FLAGS:
|
|
259
|
-
return { ...state, flags: action.payload };
|
|
260
|
-
case SET_SHOW_ALL_RESULTS:
|
|
261
|
-
return { ...state, showAllResults: action.payload };
|
|
262
|
-
case START_SEARCH:
|
|
263
|
-
return {
|
|
264
|
-
...state,
|
|
265
|
-
loading: true,
|
|
266
|
-
query: action.payload,
|
|
267
|
-
// clear old results on new search start
|
|
268
|
-
results: [],
|
|
269
|
-
total: 0,
|
|
270
|
-
activeResultIndex: -1
|
|
271
|
-
};
|
|
272
|
-
case APPEND_SEARCH_RESULTS: {
|
|
273
|
-
const newResults = [...state.results, ...action.payload.results];
|
|
274
|
-
const firstHitIndex = state.activeResultIndex === -1 && newResults.length > 0 ? 0 : state.activeResultIndex;
|
|
275
|
-
return {
|
|
276
|
-
...state,
|
|
277
|
-
results: newResults,
|
|
278
|
-
total: newResults.length,
|
|
279
|
-
// total-so-far
|
|
280
|
-
activeResultIndex: firstHitIndex,
|
|
281
|
-
// keep loading true until final SET_SEARCH_RESULTS
|
|
282
|
-
loading: true
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
case SET_SEARCH_RESULTS:
|
|
286
|
-
return {
|
|
287
|
-
...state,
|
|
288
|
-
results: action.payload.results,
|
|
289
|
-
total: action.payload.total,
|
|
290
|
-
activeResultIndex: action.payload.activeResultIndex,
|
|
291
|
-
loading: false
|
|
292
|
-
};
|
|
293
|
-
case SET_ACTIVE_RESULT_INDEX:
|
|
294
|
-
return { ...state, activeResultIndex: action.payload };
|
|
295
|
-
default:
|
|
296
|
-
return state;
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
423
|
const SearchPluginPackage = {
|
|
300
424
|
manifest,
|
|
301
|
-
create: (registry) => new SearchPlugin(SEARCH_PLUGIN_ID, registry),
|
|
425
|
+
create: (registry, config) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, config),
|
|
302
426
|
reducer: searchReducer,
|
|
303
427
|
initialState
|
|
304
428
|
};
|
|
@@ -306,6 +430,7 @@ export {
|
|
|
306
430
|
SEARCH_PLUGIN_ID,
|
|
307
431
|
SearchPlugin,
|
|
308
432
|
SearchPluginPackage,
|
|
433
|
+
initialSearchDocumentState,
|
|
309
434
|
initialState,
|
|
310
435
|
manifest
|
|
311
436
|
};
|