11import { isBrowser } from '@vue-devtools/shared-utils'
22import { BackendContext } from '@vue-devtools/app-backend-api'
3+ import { ComponentBounds } from '@vue/devtools-api'
34import { JobQueue } from './util/queue'
45
56let overlay : HTMLDivElement
67let overlayContent : HTMLDivElement
8+ let currentInstance
79
810function createOverlay ( ) {
911 if ( overlay || ! isBrowser ) return
@@ -64,31 +66,46 @@ export async function highlight (instance, ctx: BackendContext) {
6466 size . appendChild ( multiply )
6567 size . appendChild ( document . createTextNode ( ( Math . round ( bounds . height * 100 ) / 100 ) . toString ( ) ) )
6668
69+ currentInstance = instance
70+
6771 await showOverlay ( bounds , [ pre , text , post , size ] )
6872 }
73+
74+ startUpdateTimer ( ctx )
6975 } )
7076}
7177
7278export async function unHighlight ( ) {
7379 await jobQueue . queue ( async ( ) => {
7480 overlay ?. parentNode ?. removeChild ( overlay )
7581 overlayContent ?. parentNode ?. removeChild ( overlayContent )
82+ currentInstance = null
83+
84+ stopUpdateTimer ( )
7685 } )
7786}
7887
79- function showOverlay ( { width = 0 , height = 0 , top = 0 , left = 0 } , children : Node [ ] = [ ] ) {
88+ function showOverlay ( bounds : ComponentBounds , children : Node [ ] = null ) {
8089 if ( ! isBrowser || ! children . length ) return
8190
82- overlay . style . width = Math . round ( width ) + 'px'
83- overlay . style . height = Math . round ( height ) + 'px'
84- overlay . style . left = Math . round ( left ) + 'px'
85- overlay . style . top = Math . round ( top ) + 'px'
91+ positionOverlay ( bounds )
8692 document . body . appendChild ( overlay )
8793
8894 overlayContent . innerHTML = ''
8995 children . forEach ( child => overlayContent . appendChild ( child ) )
9096 document . body . appendChild ( overlayContent )
9197
98+ positionOverlayContent ( bounds )
99+ }
100+
101+ function positionOverlay ( { width = 0 , height = 0 , top = 0 , left = 0 } ) {
102+ overlay . style . width = Math . round ( width ) + 'px'
103+ overlay . style . height = Math . round ( height ) + 'px'
104+ overlay . style . left = Math . round ( left ) + 'px'
105+ overlay . style . top = Math . round ( top ) + 'px'
106+ }
107+
108+ function positionOverlayContent ( { wifth = 0 , height = 0 , top = 0 , left = 0 } ) {
92109 // Content position (prevents overflow)
93110 const contentWidth = overlayContent . offsetWidth
94111 const contentHeight = overlayContent . offsetHeight
@@ -110,3 +127,35 @@ function showOverlay ({ width = 0, height = 0, top = 0, left = 0 }, children: No
110127 overlayContent . style . left = ~ ~ contentLeft + 'px'
111128 overlayContent . style . top = ~ ~ contentTop + 'px'
112129}
130+
131+ async function updateOverlay ( ctx : BackendContext ) {
132+ if ( currentInstance ) {
133+ const bounds = await ctx . api . getComponentBounds ( currentInstance )
134+ if ( bounds ) {
135+ const sizeEl = overlayContent . children . item ( 3 )
136+ console . log ( sizeEl )
137+ const widthEl = sizeEl . childNodes [ 0 ] as unknown as Text
138+ widthEl . textContent = ( Math . round ( bounds . width * 100 ) / 100 ) . toString ( )
139+ const heightEl = sizeEl . childNodes [ 2 ] as unknown as Text
140+ heightEl . textContent = ( Math . round ( bounds . height * 100 ) / 100 ) . toString ( )
141+
142+ positionOverlay ( bounds )
143+ positionOverlayContent ( bounds )
144+ }
145+ }
146+ }
147+
148+ let updateTimer
149+
150+ function startUpdateTimer ( ctx : BackendContext ) {
151+ stopUpdateTimer ( )
152+ updateTimer = setInterval ( ( ) => {
153+ jobQueue . queue ( async ( ) => {
154+ await updateOverlay ( ctx )
155+ } )
156+ } , 1000 / 30 ) // 30fps
157+ }
158+
159+ function stopUpdateTimer ( ) {
160+ clearInterval ( updateTimer )
161+ }
0 commit comments