From c45b6b63ddd19c01d03183ba8a336da952f07538 Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Tue, 9 Jul 2019 22:09:00 +1000 Subject: [PATCH] fix: reference object popper positioning (closes #800) --- .../src/utils/findCommonOffsetParent.js | 19 +++++--- packages/popper/tests/functional/core.js | 43 +++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/packages/popper/src/utils/findCommonOffsetParent.js b/packages/popper/src/utils/findCommonOffsetParent.js index ca905fab24..eac1da064e 100644 --- a/packages/popper/src/utils/findCommonOffsetParent.js +++ b/packages/popper/src/utils/findCommonOffsetParent.js @@ -1,19 +1,26 @@ import isOffsetContainer from './isOffsetContainer'; import getRoot from './getRoot'; import getOffsetParent from './getOffsetParent'; +import getParentNode from './getParentNode'; /** - * Finds the offset parent common to the two provided nodes + * Finds the offset parent common to the two provided nodes/references * @method * @memberof Popper.Utils - * @argument {Element} element1 - * @argument {Element} element2 + * @argument {Element|Object} element1 + * @argument {Element|Object} element2 * @returns {Element} common offset parent */ export default function findCommonOffsetParent(element1, element2) { - // This check is needed to avoid errors in case one of the elements isn't defined for any reason - if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { - return document.documentElement; + // This is needed in case one of the elements isn't defined or if one of the "elements" is a reference object. + if (!element2 || !element2.nodeType) { + if (element1 && element1.nodeType) { + element2 = getParentNode(element1); + } else { + return document.documentElement; + } + } else if (!element1 || !element1.nodeType) { + element1 = getParentNode(element2); } // Here we make sure to give as "start" the element that comes first in the DOM diff --git a/packages/popper/tests/functional/core.js b/packages/popper/tests/functional/core.js index cb9b96bf47..a9311285ae 100644 --- a/packages/popper/tests/functional/core.js +++ b/packages/popper/tests/functional/core.js @@ -1428,6 +1428,49 @@ const arrowSize = 5; }); }); + it('uses an object instead of the reference element to position its popper in a container', done => { + // As above + if (isIE10) { + pending(); + } + + jasmineWrapper.innerHTML = ` +
+
popper
+
+ `; + + const popper = document.getElementById('popper'); + + const reference = { + getBoundingClientRect() { + return { + top: 10, + left: 100, + right: 150, + bottom: 90, + width: 50, + height: 80, + }; + }, + clientWidth: 50, + clientHeight: 80, + }; + + new Popper(reference, popper, { + placement: 'bottom-start', + onCreate() { + expect(getRect(popper).top).toBe( + reference.getBoundingClientRect().bottom + ); + expect(getRect(popper).left).toBe( + reference.getBoundingClientRect().left + ); + done(); + }, + }); + }); + it('checks cases where the reference element is fixed', done => { jasmineWrapper.innerHTML = `
reference