Skip to content

Commit

Permalink
Utils: Use temporary text node for rect fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed May 3, 2018
1 parent 1d2e112 commit 6dd05fc
Showing 1 changed file with 9 additions and 25 deletions.
34 changes: 9 additions & 25 deletions utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,35 +129,19 @@ export function getRectangleFromRange( range ) {
return range.getBoundingClientRect();
}

const { startContainer, startOffset } = range;
let rect = range.getClientRects()[ 0 ];

// If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` will return undefined. To fix this we can get the
// selected child node and calculate a rectangle for that.
if ( startContainer.nodeType === ELEMENT_NODE ) {
const { childNodes } = startContainer;
const selectedNode = childNodes[
// Make sure there can be no errors.
Math.min( startOffset, childNodes.length - 1 )
];

if ( selectedNode.nodeType === ELEMENT_NODE ) {
return selectedNode.getBoundingClientRect();
}

// Text nodes have no `getBoundingClientRect` method, so create a range.
range = document.createRange();
range.setStart( selectedNode, 0 );
range.setEnd( selectedNode, 0 );

return range.getBoundingClientRect();
// `getClientRects` can be empty in some browsers. This can be resolved
// by adding a temporary text node to the range.
if ( ! rect ) {
const padNode = document.createTextNode( '\u200b' );
range.insertNode( padNode );
rect = range.getClientRects()[ 0 ];
padNode.parentNode.removeChild( padNode );
}

// For normal collapsed ranges (exception above), the bounding rectangle of
// the range may be inaccurate in some browsers. There will only be one
// rectangle since it is a collapsed range, so it is safe to pass this as
// the union of them. This works consistently in all browsers.
return first( range.getClientRects() );
return rect;
}

/**
Expand Down

0 comments on commit 6dd05fc

Please sign in to comment.