@@ -64,10 +64,9 @@ function RemoteFunctions(config) {
6464 if ( window . navigator . platform . substr ( 0 , 3 ) === "Mac" ) {
6565 // Mac
6666 return event . metaKey ;
67- } else {
68- // Windows
69- return event . ctrlKey ;
7067 }
68+ // Windows
69+ return event . ctrlKey ;
7170 }
7271
7372
@@ -567,6 +566,20 @@ function RemoteFunctions(config) {
567566 } ) ;
568567 } ,
569568
569+ // note: this box width is the width of the more options box
570+ // we need this as the value is not consistent, it depends on the number of options we show in the box
571+ _getBoxPosition : function ( boxWidth ) {
572+ const elemBounds = this . element . getBoundingClientRect ( ) ;
573+
574+ const scrollLeft = window . pageXOffset || document . documentElement . scrollLeft ;
575+ const scrollTop = window . pageYOffset || document . documentElement . scrollTop ;
576+
577+ let topPos = elemBounds . top - 30 + scrollTop ;
578+ let leftPos = elemBounds . right - boxWidth + scrollLeft ;
579+
580+ return { topPos : topPos , leftPos : leftPos } ;
581+ } ,
582+
570583 _style : function ( ) {
571584 this . body = window . document . createElement ( "div" ) ;
572585
@@ -575,9 +588,6 @@ function RemoteFunctions(config) {
575588 // {mode: "closed"} means that users will not be able to access the shadow DOM
576589 const shadow = this . body . attachShadow ( { mode : "closed" } ) ;
577590
578- // the element that was clicked
579- let elemBounds = this . element . getBoundingClientRect ( ) ;
580-
581591 // check which options should be shown to determine box width
582592 const showEditTextOption = _shouldShowEditTextOption ( this . element ) ;
583593 const showSelectParentOption = _shouldShowSelectParentOption ( this . element ) ;
@@ -601,43 +611,6 @@ function RemoteFunctions(config) {
601611 } else {
602612 boxWidth = 106 ;
603613 }
604- const scrollLeft = window . pageXOffset || document . documentElement . scrollLeft ;
605- const scrollTop = window . pageYOffset || document . documentElement . scrollTop ;
606-
607- // get the ID and classes for the element
608- // we need this to check for overlap issue between the info box and this box
609- // because when we have classes and ids then the info box tends to stretch in width
610- const id = this . element . id ;
611- const classes = this . element . className ? this . element . className . split ( / \s + / ) . filter ( Boolean ) : [ ] ;
612- const tagName = this . element . tagName . toLowerCase ( ) ;
613-
614- const isOverlap = checkOverlap ( elemBounds . width , tagName , id , classes ) ;
615-
616- const viewportWidth = window . innerWidth ;
617- const idealLeftPos = elemBounds . right - boxWidth + scrollLeft ;
618- const maxLeftPos = viewportWidth - boxWidth - 10 + scrollLeft ;
619- // 10px is just the padding, because we want some space
620- const minLeftPos = 10 + scrollLeft ;
621-
622- // we'll use the position that keeps the box within viewport bounds
623- let leftPos = Math . min ( idealLeftPos , maxLeftPos ) ;
624- leftPos = Math . max ( leftPos , minLeftPos ) ;
625- let topPos ;
626-
627- if ( isOverlap ) {
628- if ( elemBounds . top > 40 ) { // check if there's enough space at the top
629- // place at the top
630- topPos = elemBounds . top - 30 + scrollTop ;
631- } else {
632- // at the bottom
633- topPos = elemBounds . top + elemBounds . height + 5 + scrollTop ;
634- }
635- } else {
636- // no overlap, so it comes just above the element
637- topPos = ( elemBounds . top - 30 < 0
638- ? elemBounds . top + elemBounds . height + 5
639- : elemBounds . top - 30 ) + scrollTop ;
640- }
641614
642615 // the icons that is displayed in the box
643616 const ICONS = {
@@ -693,6 +666,8 @@ function RemoteFunctions(config) {
693666 </span>
694667 </div>` ;
695668
669+ const boxPos = this . _getBoxPosition ( boxWidth ) ;
670+
696671 const styles = `
697672 .box {
698673 background-color: #4285F4;
@@ -704,8 +679,8 @@ function RemoteFunctions(config) {
704679 font-family: Arial, sans-serif;
705680 z-index: 2147483647;
706681 position: absolute;
707- left: ${ leftPos } px;
708- top: ${ topPos } px;
682+ left: ${ boxPos . leftPos } px;
683+ top: ${ boxPos . topPos } px;
709684 width: ${ boxWidth } px;
710685 box-sizing: border-box;
711686 }
@@ -774,6 +749,32 @@ function RemoteFunctions(config) {
774749 }
775750
776751 NodeInfoBox . prototype = {
752+ _calcHeight : function ( ) {
753+ const element = this . element ;
754+
755+ let baseHeight = 26.75 ;
756+ if ( element . id ) {
757+ baseHeight += 17.25 ;
758+ }
759+ if ( element . className . length !== 0 ) {
760+ baseHeight += 17.25 ;
761+ }
762+
763+ return baseHeight ;
764+ } ,
765+
766+ _getBoxPosition : function ( ) {
767+ const elemBounds = this . element . getBoundingClientRect ( ) ;
768+
769+ const scrollLeft = window . pageXOffset || document . documentElement . scrollLeft ;
770+ const scrollTop = window . pageYOffset || document . documentElement . scrollTop ;
771+
772+ let topPos = elemBounds . top - this . _calcHeight ( ) + scrollTop ;
773+ let leftPos = elemBounds . left + scrollLeft ;
774+
775+ return { topPos : topPos , leftPos : leftPos } ;
776+ } ,
777+
777778 _style : function ( ) {
778779 this . body = window . document . createElement ( "div" ) ;
779780
@@ -782,18 +783,6 @@ function RemoteFunctions(config) {
782783 // {mode: "closed"} means that users will not be able to access the shadow DOM
783784 const shadow = this . body . attachShadow ( { mode : "closed" } ) ;
784785
785- // the element that was clicked
786- let elemBounds = this . element . getBoundingClientRect ( ) ;
787-
788- // the positions where it should be placed
789- const scrollLeft = window . pageXOffset || document . documentElement . scrollLeft ;
790- const scrollTop = window . pageYOffset || document . documentElement . scrollTop ;
791-
792- // this value decides where we need to show the box in the UI
793- // we are creating this here, because if the element has IDs and Classes then we need to increase the value
794- // so that the box doesn't obscure the element
795- let pushBoxUp = 32 ; // px value
796-
797786 // get the ID and classes for that element, as we need to display it in the box
798787 const id = this . element . id ;
799788 const classes = this . element . className ? this . element . className . split ( / \s + / ) . filter ( Boolean ) : [ ] ;
@@ -804,7 +793,6 @@ function RemoteFunctions(config) {
804793 // Add ID if present
805794 if ( id ) {
806795 content += "<div class='id-name'>#" + id + "</div>" ;
807- pushBoxUp += 20 ;
808796 }
809797
810798 // Add classes (limit to 3 with dropdown indicator)
@@ -817,89 +805,9 @@ function RemoteFunctions(config) {
817805 content += "<span class='exceeded-classes'>+" + ( classes . length - 3 ) + " more</span>" ;
818806 }
819807 content += "</div>" ;
820- pushBoxUp += 20 ;
821808 }
822809
823- let leftPos = elemBounds . left + scrollLeft ;
824- let topPos = ( elemBounds . top - pushBoxUp < 0
825- ? elemBounds . top + elemBounds . height + 5
826- : elemBounds . top - pushBoxUp ) + scrollTop ;
827-
828- let avgCharWidth = 6 ;
829- const basePadding = 16 ;
830-
831- // Get the tag name
832- const tagName = this . element . tagName . toLowerCase ( ) ;
833-
834- // Count characters in tag name, id, and classes
835- let charCount = _calculateInfoBoxCharCount ( tagName , id , classes ) ;
836- if ( charCount <= 10 ) {
837- avgCharWidth = 7.5 ;
838- }
839-
840- // Calculate estimated width based on character count
841- // Formula: base padding + (character count * average character width)
842- const boxWidth = basePadding + ( charCount * avgCharWidth ) ;
843-
844- // we need to check for overlap if this is from a click
845- if ( this . isFromClick ) {
846- const isOverlap = checkOverlap ( elemBounds . width , tagName , id , classes ) ;
847-
848- if ( isOverlap ) {
849- const windowWidth = window . innerWidth ;
850- const viewportHeight = window . innerHeight ;
851-
852- // Estimate the height of the info box based on its content
853- // base height for tag name + padding
854- let estimatedHeight = 32 ;
855-
856- // height adjustment if ID is present
857- if ( id ) {
858- estimatedHeight += 20 ;
859- }
860-
861- // height adjustment if classes are present
862- if ( classes . length > 0 ) {
863- estimatedHeight += 20 ;
864- }
865-
866- // check if element is near bottom of viewport
867- const elementBottomFromViewportTop = elemBounds . bottom ;
868- const availableSpaceBelow = viewportHeight - elementBottomFromViewportTop ;
869-
870- // align with the bottom of the info box (original behavior)
871- topPos = ( elemBounds . top + elemBounds . height - estimatedHeight ) + scrollTop ;
872-
873- // If element is near bottom and there's not enough space below,
874- // push the info box up a bit to prevent scrollbar
875- if ( availableSpaceBelow < estimatedHeight + 10 ) {
876- // Push it up by the amount it would overflow
877- const pushUpAmount = estimatedHeight - availableSpaceBelow ;
878- topPos -= pushUpAmount ;
879- }
880-
881- // decide whether position at left or right based on available space
882- // check if there's enough space on the left side
883- if ( elemBounds . left > boxWidth + 10 ) {
884- leftPos = elemBounds . left - boxWidth - 10 + scrollLeft ;
885- } else if ( windowWidth - elemBounds . right > boxWidth + 10 ) {
886- // position on the right
887- leftPos = elemBounds . right + 10 + scrollLeft ;
888- }
889- }
890- }
891-
892- // to make sure that the info box stays under the viewport width
893- const viewportWidth = window . innerWidth ;
894- const margin = 10 ;
895-
896- // horizontal boundary checking
897- if ( leftPos + boxWidth + margin > viewportWidth + scrollLeft ) {
898- leftPos = viewportWidth + scrollLeft - boxWidth - margin ;
899- }
900- if ( leftPos < scrollLeft + margin ) {
901- leftPos = scrollLeft + margin ;
902- }
810+ const boxPos = this . _getBoxPosition ( ) ;
903811
904812 const styles = `
905813 .box {
@@ -912,8 +820,8 @@ function RemoteFunctions(config) {
912820 font-family: Arial, sans-serif;
913821 z-index: 2147483647;
914822 position: absolute;
915- left: ${ leftPos } px;
916- top: ${ topPos } px;
823+ left: ${ boxPos . leftPos } px;
824+ top: ${ boxPos . topPos } px;
917825 max-width: fit-content;
918826 box-sizing: border-box;
919827 pointer-events: none;
0 commit comments