1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/*
* SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
*
* SPDX-License-Identifier: EPL-2.0
*/
import {
closeSearchPanel,
findNext,
findPrevious,
getSearchQuery,
openSearchPanel,
replaceAll,
replaceNext,
SearchQuery,
setSearchQuery,
} from '@codemirror/search';
import { action, computed, makeObservable, observable, override } from 'mobx';
import type EditorStore from './EditorStore';
import PanelStore from './PanelStore';
export default class SearchPanelStore extends PanelStore {
searchField: HTMLInputElement | undefined;
constructor(store: EditorStore) {
// Use a custom class name to avoid specificity issues with
// CodeMirror `.cm-search.cm-panel` CSS styles.
super('refinery-cm-search', openSearchPanel, closeSearchPanel, store);
makeObservable<SearchPanelStore, 'selectSearchField'>(this, {
searchField: observable.ref,
query: computed,
invalidRegexp: computed,
open: override,
setSearchField: action,
updateQuery: action,
findNext: action,
findPrevious: action,
replaceNext: action,
replaceAll: action,
selectSearchField: false,
});
}
setSearchField(newSearchField: HTMLInputElement | undefined): void {
this.searchField = newSearchField;
if (this.state) {
this.selectSearchField();
}
}
get query(): SearchQuery {
return getSearchQuery(this.store.state);
}
get invalidRegexp(): boolean {
const { search, valid } = this.query;
return !valid && search !== '';
}
updateQuery(newQueryOptions: {
search?: string;
caseSensitive?: boolean;
literal?: boolean;
regexp?: boolean;
replace?: string;
}): void {
const { search, caseSensitive, literal, regexp, replace } = this.query;
const newQuery = new SearchQuery({
search,
caseSensitive,
literal,
regexp,
replace,
...newQueryOptions,
...(newQueryOptions.regexp === true && { literal: false }),
...(newQueryOptions.literal === true && { regexp: false }),
});
this.store.dispatch({
effects: [setSearchQuery.of(newQuery)],
});
}
findNext(): void {
this.store.doCommand(findNext);
}
findPrevious(): void {
this.store.doCommand(findPrevious);
}
replaceNext(): void {
this.store.doCommand(replaceNext);
}
replaceAll(): void {
this.store.doCommand(replaceAll);
}
override open(): boolean {
return super.open() || this.selectSearchField();
}
private selectSearchField(): boolean {
if (this.searchField === undefined) {
return false;
}
this.searchField.select();
return true;
}
}
|