Parcourir la source

Fixed: Range#getVisible throws when used for document#body.

Aleksander Nowodzinski il y a 8 ans
Parent
commit
e1088036e1

+ 20 - 15
packages/ckeditor5-utils/src/dom/rect.js

@@ -206,27 +206,32 @@ export default class Rect {
 	getVisible() {
 		const obj = this._obj;
 		let visibleRect = this.clone();
-		let parent = obj.parentNode || obj.commonAncestorContainer;
 
-		while ( parent && parent != global.document.body ) {
-			const parentOverflow = global.window.getComputedStyle( parent ).overflow;
+		// There's no ancestor to crop <body> with the overflow.
+		if ( obj != global.document.body ) {
+			let parent = obj.parentNode || obj.commonAncestorContainer;
 
-			if ( parentOverflow != 'visible' ) {
-				const parentRect = new Rect( parent );
-				const intersectionRect = visibleRect.getIntersection( parentRect );
+			// Check the ancestors all the way up to the <body>.
+			while ( parent && parent != global.document.body ) {
+				const parentOverflow = global.window.getComputedStyle( parent ).overflow;
 
-				if ( intersectionRect ) {
-					if ( intersectionRect.getArea() < visibleRect.getArea() ) {
-						// Reduce the visible rect to the intersection.
-						visibleRect = intersectionRect;
+				if ( parentOverflow != 'visible' ) {
+					const parentRect = new Rect( parent );
+					const intersectionRect = visibleRect.getIntersection( parentRect );
+
+					if ( intersectionRect ) {
+						if ( intersectionRect.getArea() < visibleRect.getArea() ) {
+							// Reduce the visible rect to the intersection.
+							visibleRect = intersectionRect;
+						}
+					} else {
+						// There's no intersection, the rect is completely invisible.
+						return null;
 					}
-				} else {
-					// There's no intersection, the rect is completely invisible.
-					return null;
 				}
-			}
 
-			parent = parent.parentNode;
+				parent = parent.parentNode;
+			}
 		}
 
 		return visibleRect;

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

@@ -361,6 +361,26 @@ describe( 'Rect', () => {
 			expect( visible ).to.not.equal( rect );
 		} );
 
+		it( 'should not fail when the rect is for document#body', () => {
+			testUtils.sinon.stub( document.body, 'getBoundingClientRect' ).returns( {
+				top: 0,
+				right: 100,
+				bottom: 100,
+				left: 0,
+				width: 100,
+				height: 100
+			} );
+
+			assertRect( new Rect( document.body ).getVisible(), {
+				top: 0,
+				right: 100,
+				bottom: 100,
+				left: 0,
+				width: 100,
+				height: 100
+			} );
+		} );
+
 		it( 'should return the visible rect (HTMLElement), partially cropped', () => {
 			ancestorA.style.overflow = 'scroll';