@@ -206,6 +206,8 @@ function startRecorder() {
206
206
document . addEventListener ( 'input' , handleInput , true ) ;
207
207
document . addEventListener ( 'change' , handleSelectChange , true ) ;
208
208
document . addEventListener ( 'keydown' , handleKeydown , true ) ;
209
+ document . addEventListener ( 'mouseover' , handleMouseOver , true ) ;
210
+ document . addEventListener ( 'mouseout' , handleMouseOut , true ) ;
209
211
console . log ( 'Permanently attached custom event listeners.' ) ;
210
212
}
211
213
@@ -221,6 +223,8 @@ function stopRecorder() {
221
223
document . removeEventListener ( 'input' , handleInput , true ) ;
222
224
document . removeEventListener ( 'change' , handleSelectChange , true ) ; // Remove change listener
223
225
document . removeEventListener ( 'keydown' , handleKeydown , true ) ; // Remove keydown listener
226
+ document . removeEventListener ( 'mouseover' , handleMouseOver , true ) ;
227
+ document . removeEventListener ( 'mouseout' , handleMouseOut , true ) ;
224
228
} else {
225
229
console . log ( 'Recorder not running, cannot stop.' ) ;
226
230
}
@@ -391,6 +395,66 @@ function handleKeydown(event: KeyboardEvent) {
391
395
}
392
396
// --- End Custom Keydown Handler ---
393
397
398
+ // Store the current overlay to manage its lifecycle
399
+ let currentOverlay : HTMLDivElement | null = null ;
400
+
401
+ // Handle mouseover to create overlay
402
+ function handleMouseOver ( event : MouseEvent ) {
403
+ if ( ! isRecordingActive ) return ;
404
+ const targetElement = event . target as HTMLElement ;
405
+ if ( ! targetElement ) return ;
406
+
407
+ // Remove any existing overlay to avoid duplicates
408
+ if ( currentOverlay ) {
409
+ // console.log('Removing existing overlay');
410
+ currentOverlay . remove ( ) ;
411
+ currentOverlay = null ;
412
+ }
413
+
414
+ try {
415
+ const xpath = getXPath ( targetElement ) ;
416
+ // console.log('XPath of target element:', xpath);
417
+ const elementToHighlight = document . evaluate (
418
+ xpath ,
419
+ document ,
420
+ null ,
421
+ XPathResult . FIRST_ORDERED_NODE_TYPE ,
422
+ null
423
+ ) . singleNodeValue as HTMLElement ;
424
+ if ( elementToHighlight ) {
425
+ const rect = elementToHighlight . getBoundingClientRect ( ) ;
426
+ const highlightOverlay = document . createElement ( 'div' ) ;
427
+ highlightOverlay . className = 'highlight-overlay' ;
428
+ Object . assign ( highlightOverlay . style , {
429
+ position : 'absolute' ,
430
+ top : `${ rect . top + window . scrollY } px` ,
431
+ left : `${ rect . left + window . scrollX } px` ,
432
+ width : `${ rect . width } px` ,
433
+ height : `${ rect . height } px` ,
434
+ border : '2px solid lightgreen' ,
435
+ backgroundColor : 'rgba(144, 238, 144, 0.2)' , // lightgreen tint
436
+ pointerEvents : 'none' ,
437
+ zIndex : '2147483000' ,
438
+ } ) ;
439
+ document . body . appendChild ( highlightOverlay ) ;
440
+ currentOverlay = highlightOverlay ;
441
+ } else {
442
+ console . warn ( 'No element found to highlight for xpath:' , xpath ) ;
443
+ }
444
+ } catch ( error ) {
445
+ console . error ( 'Error creating highlight overlay:' , error ) ;
446
+ }
447
+ }
448
+
449
+ // Handle mouseout to remove overlay
450
+ function handleMouseOut ( event : MouseEvent ) {
451
+ if ( ! isRecordingActive ) return ;
452
+ if ( currentOverlay ) {
453
+ currentOverlay . remove ( ) ;
454
+ currentOverlay = null ;
455
+ }
456
+ }
457
+
394
458
export default defineContentScript ( {
395
459
matches : [ '<all_urls>' ] ,
396
460
main ( ctx ) {
@@ -443,6 +507,8 @@ export default defineContentScript({
443
507
document . removeEventListener ( 'input' , handleInput , true ) ;
444
508
document . removeEventListener ( 'change' , handleSelectChange , true ) ;
445
509
document . removeEventListener ( 'keydown' , handleKeydown , true ) ;
510
+ document . removeEventListener ( 'mouseover' , handleMouseOver , true ) ;
511
+ document . removeEventListener ( 'mouseout' , handleMouseOut , true ) ;
446
512
stopRecorder ( ) ; // Ensure rrweb is stopped
447
513
} ) ;
448
514
0 commit comments