diff --git a/src/dom/position.js b/src/dom/position.js
index f9ee7aa..d4a2fad 100644
--- a/src/dom/position.js
+++ b/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 ] =
diff --git a/tests/dom/position.js b/tests/dom/position.js
index 21a9852..35af41e 100644
--- a/tests/dom/position.js
+++ b/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', () => {
diff --git a/tests/manual/tickets/148/1.html b/tests/manual/tickets/148/1.html
new file mode 100644
index 0000000..0d97e60
--- /dev/null
+++ b/tests/manual/tickets/148/1.html
@@ -0,0 +1,38 @@
+
+
+
+
diff --git a/tests/manual/tickets/148/1.js b/tests/manual/tickets/148/1.js
new file mode 100644
index 0000000..9d66fcf
--- /dev/null
+++ b/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 );
diff --git a/tests/manual/tickets/148/1.md b/tests/manual/tickets/148/1.md
new file mode 100644
index 0000000..652e4ba
--- /dev/null
+++ b/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.