Parcourir la source

Fix: The getOptimalPosition utility should consider limiter ancestors with CSS overflow. Closes #148.

Aleksander Nowodzinski il y a 8 ans
Parent
commit
71bfadcf95

+ 1 - 1
packages/ckeditor5-utils/src/dom/position.js

@@ -87,7 +87,7 @@ export function getOptimalPosition( { element, target, positions, limiter, fitIn
 	if ( !limiter && !fitInViewport ) {
 		[ name, bestPosition ] = getPosition( positions[ 0 ], targetRect, elementRect );
 	} else {
-		const limiterRect = limiter && new Rect( limiter );
+		const limiterRect = limiter && new Rect( limiter ).getVisible();
 		const viewportRect = fitInViewport && Rect.getViewportRect();
 
 		[ name, bestPosition ] =

+ 25 - 0
packages/ckeditor5-utils/tests/dom/position.js

@@ -159,6 +159,31 @@ describe( 'getOptimalPosition()', () => {
 				name: 'left'
 			} );
 		} );
+
+		// https://github.com/ckeditor/ckeditor5-utils/issues/148
+		it( 'should return coordinates (#3)', () => {
+			const overflowedAncestor = getElement( {
+				top: 100,
+				left: 0,
+				bottom: 110,
+				right: 10,
+				width: 10,
+				height: 10
+			}, {
+				overflow: 'scroll'
+			} );
+
+			limiter.parentNode = overflowedAncestor;
+
+			assertPosition( {
+				element, target, limiter,
+				positions: [ attachRight, attachLeft ]
+			}, {
+				top: 100,
+				left: 10,
+				name: 'right'
+			} );
+		} );
 	} );
 
 	describe( 'with fitInViewport on', () => {

+ 38 - 0
packages/ckeditor5-utils/tests/manual/tickets/148/1.html

@@ -0,0 +1,38 @@
+<div class="wrapper">
+	<div class="limiter">
+		<div class="target"></div>
+	</div>
+
+	<div class="source"></div>
+</div>
+
+
+<style>
+	.wrapper {
+		overflow: scroll;
+		outline: 1px solid #000;
+		height: 400px;
+		position: relative;
+		padding: 20px;
+		margin-top: 100px;
+	}
+
+	.limiter {
+		height: 500px;
+		overflow: hidden;
+	}
+
+	.target {
+		height: 150px;
+		background: #ccc;
+		width: 50px;
+		margin: 170px auto 0;
+	}
+
+	.source {
+		height: 50px;
+		width: 50px;
+		background: red;
+		position: absolute;
+	}
+</style>

+ 43 - 0
packages/ckeditor5-utils/tests/manual/tickets/148/1.js

@@ -0,0 +1,43 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* global document */
+
+import { getOptimalPosition } from '@ckeditor/ckeditor5-utils/src/dom/position';
+
+const source = document.querySelector( '.source' );
+const target = document.querySelector( '.target' );
+const limiter = document.querySelector( '.limiter' );
+const positions = {
+	above: ( targetRect, sourceRect ) => ( {
+		top: targetRect.top - sourceRect.height - 50,
+		left: targetRect.left,
+		name: 'above'
+	} ),
+	below: ( targetRect ) => ( {
+		top: targetRect.bottom + 50,
+		left: targetRect.left,
+		name: 'below'
+	} )
+};
+
+function updateSourcePosition() {
+	const position = getOptimalPosition( {
+		element: source,
+		target: target,
+		positions: [
+			positions.above,
+			positions.below,
+		],
+		limiter: limiter
+	} );
+
+	source.style.top = position.top + 'px';
+	source.style.left = position.left + 'px';
+}
+
+updateSourcePosition();
+
+document.addEventListener( 'scroll', updateSourcePosition, true );

+ 9 - 0
packages/ckeditor5-utils/tests/manual/tickets/148/1.md

@@ -0,0 +1,9 @@
+### `getOptimalPosition()` with the `limiter` resticted by overflowed parents [#146](https://github.com/ckeditor/ckeditor5-utils/issues/148)
+
+Vertically scroll the container up and down.
+
+**Expected**:
+
+1. The red square should **always** remain visible regardless of the position of the scroll.
+2. In the initial position, the shapes should represent a small letter "i", with the red dot above.
+3. In the opposite scroll position, the shapes should represent an exclamation mark "!" with the red dot underneath.