Преглед изворни кода

Performance: Speed up Rect#getVisible nearly twice by avoiding window#getComputedStyles.

Aleksander Nowodzinski пре 8 година
родитељ
комит
64cc2f7775
2 измењених фајлова са 24 додато и 26 уклоњено
  1. 10 14
      packages/ckeditor5-utils/src/dom/rect.js
  2. 14 12
      packages/ckeditor5-utils/tests/dom/rect.js

+ 10 - 14
packages/ckeditor5-utils/src/dom/rect.js

@@ -198,7 +198,7 @@ export default class Rect {
 	 * e.g. an original rect cropped by parent element rects which have `overflow` set in CSS
 	 * other than `"visible"`.
 	 *
-	 * If there's no such visible rect, which is when the rect is obscured by one or many of
+	 * If there's no such visible rect, which is when the rect is limited by one or many of
 	 * the ancestors, `null` is returned.
 	 *
 	 * @returns {module:utils/dom/rect~Rect|null} A visible rect instance or `null`, if there's none.
@@ -213,21 +213,17 @@ export default class Rect {
 
 			// Check the ancestors all the way up to the <body>.
 			while ( parent && parent != global.document.body ) {
-				const parentOverflow = global.window.getComputedStyle( parent ).overflow;
+				const parentRect = new Rect( parent );
+				const intersectionRect = visibleRect.getIntersection( parentRect );
 
-				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;
+				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;
 				}
 
 				parent = parent.parentNode;

+ 14 - 12
packages/ckeditor5-utils/tests/dom/rect.js

@@ -345,8 +345,7 @@ describe( 'Rect', () => {
 			ancestorB = document.createElement( 'div' );
 
 			ancestorA.append( element );
-			ancestorB.append( ancestorA );
-			document.body.appendChild( ancestorB );
+			document.body.appendChild( ancestorA );
 		} );
 
 		afterEach( () => {
@@ -382,8 +381,6 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return the visible rect (HTMLElement), partially cropped', () => {
-			ancestorA.style.overflow = 'scroll';
-
 			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
@@ -413,8 +410,6 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return the visible rect (HTMLElement), fully visible', () => {
-			ancestorA.style.overflow = 'scroll';
-
 			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
@@ -444,7 +439,8 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return the visible rect (HTMLElement), partially cropped, deep ancestor overflow', () => {
-			ancestorB.style.overflow = 'scroll';
+			ancestorB.append( ancestorA );
+			document.body.appendChild( ancestorB );
 
 			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
@@ -455,10 +451,19 @@ describe( 'Rect', () => {
 				height: 100
 			} );
 
-			testUtils.sinon.stub( ancestorB, 'getBoundingClientRect' ).returns( {
+			testUtils.sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
 				top: 50,
+				right: 100,
+				bottom: 100,
+				left: 0,
+				width: 50,
+				height: 50
+			} );
+
+			testUtils.sinon.stub( ancestorB, 'getBoundingClientRect' ).returns( {
+				top: 0,
 				right: 150,
-				bottom: 150,
+				bottom: 100,
 				left: 50,
 				width: 100,
 				height: 100
@@ -476,7 +481,6 @@ describe( 'Rect', () => {
 
 		it( 'should return the visible rect (Range), partially cropped', () => {
 			range.setStart( ancestorA, 0 );
-			ancestorA.style.overflow = 'scroll';
 
 			testUtils.sinon.stub( range, 'getBoundingClientRect' ).returns( {
 				top: 0,
@@ -507,8 +511,6 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return null if there\'s no visible rect', () => {
-			ancestorA.style.overflow = 'scroll';
-
 			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,