Skip to content

Commit 37c44a1

Browse files
committed
fix: overlapping issue between the info box and the more options box
1 parent cd95ddf commit 37c44a1

File tree

1 file changed

+89
-12
lines changed

1 file changed

+89
-12
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,22 @@ function RemoteFunctions(config) {
323323
delete element._originalDragOpacity;
324324
}
325325

326+
function checkOverlap(elemWidth, id, classes) {
327+
if(elemWidth > 280) {
328+
return false;
329+
}
330+
if(classes.length >= 3 && elemWidth <= 280) {
331+
return true;
332+
}
333+
if((id || classes.length <= 2) && elemWidth <= 250) {
334+
return true;
335+
}
336+
if(elemWidth <= 180) {
337+
return true;
338+
}
339+
return false;
340+
}
341+
326342
/**
327343
* This is for the advanced DOM options that appears when a DOM element is clicked
328344
* advanced options like: 'select parent', 'duplicate', 'delete'
@@ -380,10 +396,34 @@ function RemoteFunctions(config) {
380396
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
381397
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
382398

383-
const leftPos = elemBounds.right - boxWidth + scrollLeft;
384-
const topPos = (elemBounds.top - 30 < 0
385-
? elemBounds.top + elemBounds.height + 5
386-
: elemBounds.top - 30) + scrollTop;
399+
// get the ID and classes for the element
400+
// we need this to check for overlap issue between the info box and this box
401+
// because when we have classes and ids then the info box tends to stretch in width
402+
const id = this.element.id;
403+
const classes = this.element.className ? this.element.className.split(/\s+/).filter(Boolean) : [];
404+
405+
const isOverlap = checkOverlap(elemBounds.width, id, classes);
406+
407+
// default position (right aligned with element)
408+
let leftPos = elemBounds.right - boxWidth + scrollLeft;
409+
410+
// this will be calculated based on whether we have overlap issue or not
411+
let topPos;
412+
413+
if (isOverlap) {
414+
if (elemBounds.top > 40) { // check if there's enough space at the top
415+
// place at the top
416+
topPos = elemBounds.top - 30 + scrollTop;
417+
} else {
418+
// at the bottom
419+
topPos = elemBounds.top + elemBounds.height + 5 + scrollTop;
420+
}
421+
} else {
422+
// no overlap, so it comes just above the element
423+
topPos = (elemBounds.top - 30 < 0
424+
? elemBounds.top + elemBounds.height + 5
425+
: elemBounds.top - 30) + scrollTop;
426+
}
387427

388428
// the icons that is displayed in the box
389429
const ICONS = {
@@ -492,8 +532,9 @@ function RemoteFunctions(config) {
492532
};
493533

494534
// Node info box to display DOM node ID and classes on hover
495-
function NodeInfoBox(element) {
535+
function NodeInfoBox(element, isFromClick) {
496536
this.element = element;
537+
this.isFromClick = isFromClick || false;
497538
this.remove = this.remove.bind(this);
498539
this.create();
499540
}
@@ -545,12 +586,45 @@ function RemoteFunctions(config) {
545586
pushBoxUp += 16;
546587
}
547588

548-
// Now calculate topPos using the final pushBoxUp value
549-
const leftPos = elemBounds.left + scrollLeft;
550-
const topPos = (elemBounds.top - pushBoxUp < 0
589+
let leftPos = elemBounds.left + scrollLeft;
590+
let topPos = (elemBounds.top - pushBoxUp < 0
551591
? elemBounds.top + elemBounds.height + 5
552592
: elemBounds.top - pushBoxUp) + scrollTop;
553593

594+
// we need to check for overlap if this is from a click
595+
if (this.isFromClick) {
596+
const isOverlap = checkOverlap(elemBounds.width, id, classes);
597+
598+
if (isOverlap) {
599+
const windowWidth = window.innerWidth;
600+
const boxWidth = 300; // max-width of the box
601+
602+
// Estimate the height of the info box based on its content
603+
// base height for tag name + padding
604+
let estimatedHeight = 20;
605+
606+
// height adjustment if ID is present
607+
if (id) {
608+
estimatedHeight += 15;
609+
}
610+
611+
// height adjustment if classes are present
612+
if (classes.length > 0) {
613+
estimatedHeight += 15;
614+
}
615+
616+
// align with the bottom of the info box
617+
topPos = (elemBounds.top + elemBounds.height - estimatedHeight) + scrollTop;
618+
619+
// decide whether position at left or right
620+
if (elemBounds.left > boxWidth + 10) {
621+
leftPos = elemBounds.left - boxWidth - 10 + scrollLeft;
622+
} else if (windowWidth - elemBounds.right > boxWidth + 10) {
623+
leftPos = elemBounds.right + 10 + scrollLeft;
624+
}
625+
}
626+
}
627+
554628
const styles = `
555629
.box {
556630
background-color: #4285F4;
@@ -1007,7 +1081,10 @@ function RemoteFunctions(config) {
10071081
if (_nodeInfoBox) {
10081082
_nodeInfoBox.remove();
10091083
}
1010-
_nodeInfoBox = new NodeInfoBox(event.target);
1084+
// check if this element is already clicked (has more options box)
1085+
// this is needed so that we can check for overlapping issue among the boxes
1086+
const isAlreadyClicked = previouslyClickedElement === event.target && _nodeMoreOptionsBox !== null;
1087+
_nodeInfoBox = new NodeInfoBox(event.target, isAlreadyClicked);
10111088
}
10121089
}
10131090
}
@@ -1069,11 +1146,11 @@ function RemoteFunctions(config) {
10691146
if (_nodeInfoBox) {
10701147
_nodeInfoBox.remove();
10711148
}
1072-
_nodeInfoBox = new NodeInfoBox(event.target);
1149+
_nodeInfoBox = new NodeInfoBox(event.target, true); // true means that the element was clicked
10731150

10741151
event.target._originalOutline = event.target.style.outline;
10751152
event.target.style.outline = "1px solid #4285F4";
1076-
previouslyClickedElement = event.target; // add the current element to the previouslyClickedElement
1153+
previouslyClickedElement = event.target;
10771154
}
10781155
}
10791156

@@ -1175,7 +1252,7 @@ function RemoteFunctions(config) {
11751252

11761253
if (_nodeInfoBox) {
11771254
_nodeInfoBox.remove();
1178-
_nodeInfoBox = new NodeInfoBox(element);
1255+
_nodeInfoBox = new NodeInfoBox(element, true); // true means it came from a click
11791256
}
11801257
}
11811258
}

0 commit comments

Comments
 (0)