@@ -7,8 +7,12 @@ import Utils from "../misc/utils";
77export default class TestHighlighter extends EventDispatcher {
88 constructor ( editor ) {
99 super ( ) ;
10+
1011 this . editor = editor ;
1112 this . activeMarks = [ ] ;
13+ this . widgets = [ ] ;
14+
15+ this . textHeight = editor . defaultTextHeight ( ) ;
1216 }
1317
1418 draw ( tokens ) {
@@ -20,13 +24,6 @@ export default class TestHighlighter extends EventDispatcher {
2024 const marks = this . activeMarks ;
2125
2226 for ( const token of tokens ) {
23- const className = "match" ;
24- const location = Editor . calcRangePos (
25- this . editor ,
26- token . location . start ,
27- token . location . end - token . location . start
28- ) ;
29-
3027 const match = Utils . htmlSafe ( token . value ) ;
3128 let tooltip = `<div class="text-start font-monospace">
3229 <div><span class="fw-bolder">match:</span> ${ match } </div>
@@ -38,29 +35,113 @@ export default class TestHighlighter extends EventDispatcher {
3835 for ( const [ i , capture ] of token . captures . entries ( ) ) {
3936 const value = Utils . htmlSafe ( capture . value || "" ) ;
4037 tooltip += `<div class="text-start font-monospace">
41- <div><span class="fw-bolder">group #${ i + 1 } :</span> ${ value } </div>
38+ <div><span class="fw-bolder">group #${ i + 1 } :</span> ${
39+ value === "" ? "empty string" : value
40+ } </div>
4241 </div>` ;
4342 }
4443 }
45- marks . push (
46- doc . markText ( location . startPos , location . endPos , {
47- className : className ,
48- attributes : {
49- "data-tippy-content" : tooltip ,
50- } ,
51- } )
52- ) ;
44+
45+ if ( token . location . start < token . location . end ) {
46+ const location = Editor . calcRangePos (
47+ editor ,
48+ token . location . start ,
49+ token . location . end - token . location . start
50+ ) ;
51+ marks . push (
52+ doc . markText ( location . startPos , location . endPos , {
53+ className : "match-char" ,
54+ attributes : {
55+ "data-tippy-content" : tooltip ,
56+ } ,
57+ } )
58+ ) ;
59+ } else {
60+ const location = Editor . calcRangePos ( editor , token . location . start , 1 ) ;
61+
62+ if (
63+ location . startPos . line === location . endPos . line &&
64+ location . startPos . ch === location . endPos . ch
65+ ) {
66+ this . addLeftAnchor ( location , { "data-tippy-content" : tooltip } ) ;
67+ }
68+ if ( location . startPos . line === location . endPos . line ) {
69+ if ( location . startPos . ch < location . endPos . ch ) {
70+ marks . push (
71+ doc . markText ( location . startPos , location . endPos , {
72+ className : "match-left" ,
73+ attributes : {
74+ "data-tippy-content" : tooltip ,
75+ } ,
76+ } )
77+ ) ;
78+ } else {
79+ // this.addRightAnchor(location, { "data-tippy-content": tooltip });
80+ }
81+ } else {
82+ if ( location . startPos . ch === 0 && location . endPos . ch === 0 ) {
83+ this . addLeftAnchor ( location , { "data-tippy-content" : tooltip } ) ;
84+ } else {
85+ this . addRightAnchor ( location , { "data-tippy-content" : tooltip } ) ;
86+ }
87+ }
88+ }
5389 }
5490 } ) ;
5591 }
5692
93+ addLeftAnchor ( location , attributes = { } ) {
94+ const widget = document . createElement ( "span" ) ;
95+ widget . className = "match-left" ;
96+ widget . style . height = `${ this . textHeight * 1.5 } px` ;
97+ widget . style . width = "1px" ;
98+ widget . style . zIndex = "10" ;
99+
100+ for ( const [ key , value ] of Object . entries ( attributes ) ) {
101+ widget . setAttribute ( key , value ) ;
102+ }
103+
104+ this . editor . addWidget ( location . startPos , widget ) ;
105+
106+ const coords = this . editor . charCoords ( location . startPos , "local" ) ;
107+ widget . style . left = `${ coords . left } px` ;
108+ widget . style . top = `${ coords . top + 2 } px` ;
109+
110+ this . widgets . push ( widget ) ;
111+ }
112+
113+ addRightAnchor ( location , attributes = { } ) {
114+ const widget = document . createElement ( "span" ) ;
115+ widget . className = "match-right" ;
116+ widget . style . height = `${ this . textHeight * 1.5 } px` ;
117+ widget . style . width = "1px" ;
118+ widget . style . zIndex = "10" ;
119+
120+ for ( const [ key , value ] of Object . entries ( attributes ) ) {
121+ widget . setAttribute ( key , value ) ;
122+ }
123+
124+ this . editor . addWidget ( location . endPos , widget ) ;
125+
126+ const coords = this . editor . charCoords ( location . startPos , "local" ) ;
127+ widget . style . left = `${ coords . left } px` ;
128+ widget . style . top = `${ coords . top + 2 } px` ;
129+
130+ this . widgets . push ( widget ) ;
131+ }
132+
57133 clear ( ) {
58134 this . editor . operation ( ( ) => {
59135 let marks = this . activeMarks ;
60136 for ( var i = 0 , l = marks . length ; i < l ; i ++ ) {
61137 marks [ i ] . clear ( ) ;
62138 }
63139 marks . length = 0 ;
140+
141+ for ( const widget of this . widgets ) {
142+ widget . parentNode . removeChild ( widget ) ;
143+ }
144+ this . widgets . length = 0 ;
64145 } ) ;
65146 }
66147}
0 commit comments