Skip to content

Commit a47a226

Browse files
committed
Add mouseover and mouseout event listeners to highlight elements during recording
1 parent 8475a06 commit a47a226

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

extension/src/entrypoints/content.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ function startRecorder() {
206206
document.addEventListener('input', handleInput, true);
207207
document.addEventListener('change', handleSelectChange, true);
208208
document.addEventListener('keydown', handleKeydown, true);
209+
document.addEventListener('mouseover', handleMouseOver, true);
210+
document.addEventListener('mouseout', handleMouseOut, true);
209211
console.log('Permanently attached custom event listeners.');
210212
}
211213

@@ -221,6 +223,8 @@ function stopRecorder() {
221223
document.removeEventListener('input', handleInput, true);
222224
document.removeEventListener('change', handleSelectChange, true); // Remove change listener
223225
document.removeEventListener('keydown', handleKeydown, true); // Remove keydown listener
226+
document.removeEventListener('mouseover', handleMouseOver, true);
227+
document.removeEventListener('mouseout', handleMouseOut, true);
224228
} else {
225229
console.log('Recorder not running, cannot stop.');
226230
}
@@ -391,6 +395,66 @@ function handleKeydown(event: KeyboardEvent) {
391395
}
392396
// --- End Custom Keydown Handler ---
393397

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+
394458
export default defineContentScript({
395459
matches: ['<all_urls>'],
396460
main(ctx) {
@@ -443,6 +507,8 @@ export default defineContentScript({
443507
document.removeEventListener('input', handleInput, true);
444508
document.removeEventListener('change', handleSelectChange, true);
445509
document.removeEventListener('keydown', handleKeydown, true);
510+
document.removeEventListener('mouseover', handleMouseOver, true);
511+
document.removeEventListener('mouseout', handleMouseOut, true);
446512
stopRecorder(); // Ensure rrweb is stopped
447513
});
448514

0 commit comments

Comments
 (0)