浏览代码

Merge pull request #213 from ckeditor/t/ckeditor5-ui/317

Fix: `Rect.getDomRangeRects()` should not throw if the provided DOM range starts in a text node. Closes ckeditor/ckeditor5-ui#317.
Aleksander Nowodzinski 8 年之前
父节点
当前提交
36d02ba155
共有 2 个文件被更改,包括 34 次插入4 次删除
  1. 13 4
      packages/ckeditor5-utils/src/dom/rect.js
  2. 21 0
      packages/ckeditor5-utils/tests/dom/rect.js

+ 13 - 4
packages/ckeditor5-utils/src/dom/rect.js

@@ -7,6 +7,8 @@
  * @module utils/dom/rect
  */
 
+/* global Node */
+
 import isRange from './isrange';
 import isWindow from './iswindow';
 import isElement from '../lib/lodash/isElement';
@@ -361,12 +363,19 @@ export default class Rect {
 		// If there's no client rects for the Range, use parent container's bounding rect
 		// instead and adjust rect's width to simulate the actual geometry of such range.
 		// https://github.com/ckeditor/ckeditor5-utils/issues/153
+		// https://github.com/ckeditor/ckeditor5-ui/issues/317
 		else {
-			const startContainerRect = new Rect( range.startContainer.getBoundingClientRect() );
-			startContainerRect.right = startContainerRect.left;
-			startContainerRect.width = 0;
+			let startContainer = range.startContainer;
+
+			if ( startContainer.nodeType === Node.TEXT_NODE ) {
+				startContainer = startContainer.parentNode;
+			}
+
+			const rect = new Rect( startContainer.getBoundingClientRect() );
+			rect.right = rect.left;
+			rect.width = 0;
 
-			rects.push( startContainerRect );
+			rects.push( rect );
 		}
 
 		return rects;

+ 21 - 0
packages/ckeditor5-utils/tests/dom/rect.js

@@ -965,6 +965,27 @@ describe( 'Rect', () => {
 			expect( rects ).to.have.length( 1 );
 			assertRect( rects[ 0 ], expectedGeometry );
 		} );
+
+		// https://github.com/ckeditor/ckeditor5-ui/issues/317
+		it( 'should return rects for a text node\'s parent (collapsed, no Range rects available)', () => {
+			const range = document.createRange();
+			const element = document.createElement( 'div' );
+			const textNode = document.createTextNode( 'abc' );
+			element.appendChild( textNode );
+
+			range.setStart( textNode, 3 );
+			range.collapse();
+			testUtils.sinon.stub( range, 'getClientRects' ).returns( [] );
+			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+
+			const expectedGeometry = Object.assign( {}, geometry );
+			expectedGeometry.right = expectedGeometry.left;
+			expectedGeometry.width = 0;
+
+			const rects = Rect.getDomRangeRects( range );
+			expect( rects ).to.have.length( 1 );
+			assertRect( rects[ 0 ], expectedGeometry );
+		} );
 	} );
 } );