@@ -129,35 +129,19 @@ export function getRectangleFromRange( range ) {
129
129
return range . getBoundingClientRect ( ) ;
130
130
}
131
131
132
- const { startContainer , startOffset } = range ;
132
+ let rect = range . getClientRects ( ) [ 0 ] ;
133
133
134
134
// If the collapsed range starts (and therefore ends) at an element node,
135
- // `getClientRects` will return undefined. To fix this we can get the
136
- // selected child node and calculate a rectangle for that.
137
- if ( startContainer . nodeType === ELEMENT_NODE ) {
138
- const { childNodes } = startContainer ;
139
- const selectedNode = childNodes [
140
- // Make sure there can be no errors.
141
- Math . min ( startOffset , childNodes . length - 1 )
142
- ] ;
143
-
144
- if ( selectedNode . nodeType === ELEMENT_NODE ) {
145
- return selectedNode . getBoundingClientRect ( ) ;
146
- }
147
-
148
- // Text nodes have no `getBoundingClientRect` method, so create a range.
149
- range = document . createRange ( ) ;
150
- range . setStart ( selectedNode , 0 ) ;
151
- range . setEnd ( selectedNode , 0 ) ;
152
-
153
- return range . getBoundingClientRect ( ) ;
135
+ // `getClientRects` can be empty in some browsers. This can be resolved
136
+ // by adding a temporary text node to the range.
137
+ if ( ! rect ) {
138
+ const padNode = document . createTextNode ( '\u200b' ) ;
139
+ range . insertNode ( padNode ) ;
140
+ rect = range . getClientRects ( ) [ 0 ] ;
141
+ padNode . parentNode . removeChild ( padNode ) ;
154
142
}
155
143
156
- // For normal collapsed ranges (exception above), the bounding rectangle of
157
- // the range may be inaccurate in some browsers. There will only be one
158
- // rectangle since it is a collapsed range, so it is safe to pass this as
159
- // the union of them. This works consistently in all browsers.
160
- return first ( range . getClientRects ( ) ) ;
144
+ return rect ;
161
145
}
162
146
163
147
/**
0 commit comments