@@ -2,6 +2,7 @@ import { inDoc, getComponentName, getComponentDisplayName } from '@utils/util'
2
2
import SharedData from '@utils/shared-data'
3
3
import { isBrowser , target } from '@utils/env'
4
4
import { getInstanceName } from './index'
5
+ import { isFragment } from './components'
5
6
6
7
let overlay
7
8
let overlayContent
@@ -79,7 +80,8 @@ export function unHighlight () {
79
80
*/
80
81
81
82
export function getInstanceOrVnodeRect ( instance ) {
82
- const el = instance . $el || instance . elm
83
+ const el = instance . subTree ? instance . subTree . el : instance . $el || instance . elm
84
+
83
85
if ( ! isBrowser ) {
84
86
// TODO: Find position from instance or a vnode (for functional components).
85
87
@@ -88,13 +90,67 @@ export function getInstanceOrVnodeRect (instance) {
88
90
if ( ! inDoc ( el ) ) {
89
91
return
90
92
}
91
- if ( instance . _isFragment ) {
92
- return getFragmentRect ( instance )
93
+
94
+ if ( isFragment ( instance ) ) {
95
+ return getFragmentRect ( instance . subTree )
96
+ } else if ( instance . _isFragment ) {
97
+ return getLegacyFragmentRect ( instance )
93
98
} else if ( el . nodeType === 1 ) {
94
99
return el . getBoundingClientRect ( )
95
100
}
96
101
}
97
102
103
+ function createRect ( ) {
104
+ const rect = {
105
+ top : 0 ,
106
+ bottom : 0 ,
107
+ left : 0 ,
108
+ right : 0 ,
109
+ get width ( ) { return rect . right - rect . left } ,
110
+ get height ( ) { return rect . bottom - rect . top }
111
+ }
112
+ return rect
113
+ }
114
+
115
+ function mergeRects ( a , b ) {
116
+ if ( ! a . top || b . top < a . top ) {
117
+ a . top = b . top
118
+ }
119
+ if ( ! a . bottom || b . bottom > a . bottom ) {
120
+ a . bottom = b . bottom
121
+ }
122
+ if ( ! a . left || b . left < a . left ) {
123
+ a . left = b . left
124
+ }
125
+ if ( ! a . right || b . right > a . right ) {
126
+ a . right = b . right
127
+ }
128
+ }
129
+
130
+ function getFragmentRect ( vnode ) {
131
+ const rect = createRect ( )
132
+
133
+ for ( let i = 0 , l = vnode . children . length ; i < l ; i ++ ) {
134
+ const child = vnode . children [ i ]
135
+ let childRect
136
+ if ( isFragment ( child ) ) {
137
+ childRect = getFragmentRect ( child )
138
+ } else if ( child . el ) {
139
+ const el = child . el
140
+ if ( el . nodeType === 1 || el . getBoundingClientRect ) {
141
+ childRect = el . getBoundingClientRect ( )
142
+ } else if ( el . nodeType === 3 && el . data . trim ( ) ) {
143
+ childRect = getTextRect ( el )
144
+ }
145
+ }
146
+ if ( childRect ) {
147
+ mergeRects ( rect , childRect )
148
+ }
149
+ }
150
+
151
+ return rect
152
+ }
153
+
98
154
/**
99
155
* Highlight a fragment instance.
100
156
* Loop over its node range and determine its bounding box.
@@ -103,36 +159,20 @@ export function getInstanceOrVnodeRect (instance) {
103
159
* @return {Object }
104
160
*/
105
161
106
- function getFragmentRect ( { _fragmentStart, _fragmentEnd } ) {
107
- let top , bottom , left , right
162
+ function getLegacyFragmentRect ( { _fragmentStart, _fragmentEnd } ) {
163
+ const rect = createRect ( )
108
164
util ( ) . mapNodeRange ( _fragmentStart , _fragmentEnd , function ( node ) {
109
- let rect
165
+ let childRect
110
166
if ( node . nodeType === 1 || node . getBoundingClientRect ) {
111
- rect = node . getBoundingClientRect ( )
167
+ childRect = node . getBoundingClientRect ( )
112
168
} else if ( node . nodeType === 3 && node . data . trim ( ) ) {
113
- rect = getTextRect ( node )
169
+ childRect = getTextRect ( node )
114
170
}
115
- if ( rect ) {
116
- if ( ! top || rect . top < top ) {
117
- top = rect . top
118
- }
119
- if ( ! bottom || rect . bottom > bottom ) {
120
- bottom = rect . bottom
121
- }
122
- if ( ! left || rect . left < left ) {
123
- left = rect . left
124
- }
125
- if ( ! right || rect . right > right ) {
126
- right = rect . right
127
- }
171
+ if ( childRect ) {
172
+ mergeRects ( rect , childRect )
128
173
}
129
174
} )
130
- return {
131
- top,
132
- left,
133
- width : right - left ,
134
- height : bottom - top
135
- }
175
+ return rect
136
176
}
137
177
138
178
let range
0 commit comments