11import { Extension } from '@core/Extension.js' ;
22import { search , SearchQuery , setSearchState , getMatchHighlights } from 'prosemirror-search' ;
3- import { TextSelection } from 'prosemirror-state' ;
4-
3+ import { Plugin , PluginKey , TextSelection } from 'prosemirror-state' ;
4+ import { Decoration , DecorationSet } from 'prosemirror-view' ;
5+ import { v4 as uuidv4 } from 'uuid' ;
56
67export const Search = Extension . create ( {
8+ addStorage ( ) {
9+ return {
10+ searchResults : [ ] ,
11+ } ;
12+ } ,
13+
714 addPmPlugins ( ) {
8- return [ search ( ) ] ;
15+ const editor = this . editor ;
16+ const storage = this . storage ;
17+
18+ const searchHighlightWithIdPlugin = new Plugin ( {
19+ key : new PluginKey ( 'customSearchHighlights' ) ,
20+ props : {
21+ decorations ( state ) {
22+ if ( ! editor ) return null ;
23+
24+ const matches = storage ?. searchResults ;
25+ if ( ! matches ?. length ) return null ;
26+
27+ const decorations = matches . map ( ( match , index ) =>
28+ Decoration . inline ( match . from , match . to , {
29+ id : `search-match-${ match . id } ` ,
30+ } )
31+ ) ;
32+
33+ return DecorationSet . create ( state . doc , decorations ) ;
34+ }
35+ }
36+ } ) ;
37+
38+ return [ search ( ) , searchHighlightWithIdPlugin ] ;
939 } ,
1040
1141 addCommands ( ) {
@@ -19,7 +49,7 @@ export const Search = Extension.create({
1949 editor . view . domAtPos ( firstSearchItemPosition ) ?. node ?. scrollIntoView ( true ) ;
2050 } ,
2151
22- search : ( patternInput ) => ( { state, dispatch } ) => {
52+ search : ( patternInput ) => ( { state, editor , dispatch } ) => {
2353 let pattern ;
2454 let caseSensitive = false ;
2555 let regexp = false ;
@@ -47,14 +77,21 @@ export const Search = Extension.create({
4777 const tr = setSearchState ( state . tr , query ) ;
4878 dispatch ( tr ) ;
4979
50- const newState = state . apply ( tr ) ;
51- const decoSet = getMatchHighlights ( newState ) ;
52- const matches = decoSet ? decoSet . find ( ) : [ ] ;
53- return matches . map ( d => ( {
80+ const newState = state . apply ( tr ) ;
81+
82+ const decoSet = getMatchHighlights ( newState ) ;
83+ const matches = decoSet ? decoSet . find ( ) : [ ] ;
84+
85+ const resultMatches = matches . map ( d => ( {
5486 from : d . from ,
55- to : d . to ,
56- text : newState . doc . textBetween ( d . from , d . to )
87+ to : d . to ,
88+ text : newState . doc . textBetween ( d . from , d . to ) ,
89+ id : uuidv4 ( ) ,
5790 } ) ) ;
91+
92+ this . storage . searchResults = resultMatches ;
93+
94+ return resultMatches ;
5895 } ,
5996
6097 goToSearchResult : ( match ) => ( { state, dispatch, editor } ) => {
@@ -71,9 +108,13 @@ export const Search = Extension.create({
71108 node . scrollIntoView ( { block : 'center' , inline : 'nearest' } )
72109 }
73110
74- return true
111+ return true ;
75112 } ,
76113
77114 }
78115 }
79116} ) ;
117+
118+
119+
120+
0 commit comments