Skip to content

Commit

Permalink
Utils: Improve range rect detection for br-separated content
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed May 2, 2018
1 parent f20baf0 commit 573269e
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,22 @@ export function getRectangleFromRange( range ) {
return range.getBoundingClientRect();
}

// If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` will return undefined. To fix this we can get the
// bounding rectangle of the element node to create a DOMRect based on that.
if ( range.startContainer.nodeType === ELEMENT_NODE ) {
const { x, y, height } = range.startContainer.getBoundingClientRect();
let rect = range.getClientRects()[ 0 ];

// Create a new DOMRect with zero width.
return new DOMRect( x, y, 0, height );
// If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` will be empty. To account for this, append a temporary
// node with zero-width character to use as source for dimensions.
if ( ! rect ) {
const span = document.createElement( 'span' );
span.appendChild( document.createTextNode( '\u200b' ) );
range.insertNode( span );
rect = span.getClientRects()[ 0 ];
const spanParent = span.parentNode;
spanParent.removeChild( span );
spanParent.normalize();
}

// 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 573269e

Please sign in to comment.