From babbbdf3966f70daf78b58752ae3aae4df21b595 Mon Sep 17 00:00:00 2001 From: Buchheit Date: Thu, 12 Apr 2018 11:42:18 -0400 Subject: [PATCH] feat: Add specific padding to boundaries (#518) --- packages/popper/src/utils/getBoundaries.js | 10 +- packages/popper/tests/unit/getBoundaries.js | 99 +++++++++++++++++++ .../tests/unit/getBoundaries.padding.js | 74 ++++++++++++++ packages/test/karma.conf.js | 12 ++- 4 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 packages/popper/tests/unit/getBoundaries.js create mode 100644 packages/popper/tests/unit/getBoundaries.padding.js diff --git a/packages/popper/src/utils/getBoundaries.js b/packages/popper/src/utils/getBoundaries.js index ae6583a042..6c7d3a7685 100644 --- a/packages/popper/src/utils/getBoundaries.js +++ b/packages/popper/src/utils/getBoundaries.js @@ -69,10 +69,12 @@ export default function getBoundaries( } // Add paddings - boundaries.left += padding; - boundaries.top += padding; - boundaries.right -= padding; - boundaries.bottom -= padding; + padding = padding || 0; + const isPaddingNumber = typeof padding === 'number'; + boundaries.left += isPaddingNumber ? padding : padding.left || 0; + boundaries.top += isPaddingNumber ? padding : padding.top || 0; + boundaries.right -= isPaddingNumber ? padding : padding.right || 0; + boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; return boundaries; } diff --git a/packages/popper/tests/unit/getBoundaries.js b/packages/popper/tests/unit/getBoundaries.js new file mode 100644 index 0000000000..e12d9844de --- /dev/null +++ b/packages/popper/tests/unit/getBoundaries.js @@ -0,0 +1,99 @@ +import getBoundaries from '../../src/utils/getBoundaries'; +import getFixedPositionOffsetParent from '../../src/utils/getFixedPositionOffsetParent'; + +describe('utils/getBoundaries', () => { + let node; + let spacing; + let scrolling; + let scrollingChild; + let popper; + let scrollingPopper; + + function setCss(element, css) { + for (const key in css) { + if (css.hasOwnProperty(key)) { + element.style[key] = css[key]; + } + } + } + function expectBoundary(result, expected) { + const tolerance = 3; + console.log(result, expected); + expect(Math.abs(result.top - expected.top) <= tolerance).toBeTruthy(); + expect(Math.abs(result.right - expected.right) <= tolerance).toBeTruthy(); + expect(Math.abs(result.bottom - expected.bottom) <= tolerance).toBeTruthy(); + expect(Math.abs(result.left - expected.left) <= tolerance).toBeTruthy(); + } + + beforeEach(() => { + node = document.createElement('div'); + spacing = document.createElement('div'); + popper = document.createElement('div'); + scrollingPopper = document.createElement('div'); + + scrolling = document.createElement('div'); + setCss(scrolling, { + top: '150px', + left: '160px', + right: '300px', + bottom: '400px', + height: '150px', + width: '125px', + }); + + scrollingChild = document.createElement('div'); + setCss(scrollingChild, { + overflow: 'scroll', + top: '50px', + left: '60px', + right: '-100px', + bottom: '-200px', + height: '350px', + width: '625px', + position: 'absolute', + transform: 'translate3d(100px, 100px, 0)', + willChange: 'transform', + }); + + document.body.appendChild(node); + node.appendChild(spacing); + node.appendChild(scrolling); + node.appendChild(popper); + scrolling.appendChild(scrollingChild); + scrollingChild.appendChild(scrollingPopper); + }); + + afterEach(() => { + document.body.removeChild(node); + }); + + it('returns a boundary defined by the document element.', () => { + const result = getBoundaries(popper, node, 0, 'window', true); + expectBoundary(result, { + top: 0, + right: 1009, + bottom: 768, + left: 0, + }); + }); + + it('returns a boundary defined by the document element by way of a child reference.', () => { + const result = getBoundaries(popper, spacing, 0, 'scrollParent', true); + expectBoundary(result, { + top: 0, + right: 1009, + bottom: 768, + left: 0, + }); + }); + + it('returns a boundary with a null padding offset.', () => { + const result = getBoundaries(scrollingPopper, scrollingChild, 0, 'scrollParent', true); + expectBoundary(result, { + top: -150, + right: 849, + bottom: 618, + left: -160, + }); + }); +}); \ No newline at end of file diff --git a/packages/popper/tests/unit/getBoundaries.padding.js b/packages/popper/tests/unit/getBoundaries.padding.js new file mode 100644 index 0000000000..3b2f13cb2a --- /dev/null +++ b/packages/popper/tests/unit/getBoundaries.padding.js @@ -0,0 +1,74 @@ +import getBoundaries from '../../src/utils/getBoundaries'; +import getFixedPositionOffsetParent from '../../src/utils/getFixedPositionOffsetParent'; + +describe('utils/getBoundaries-padding-offset', () => { + let node; + + beforeEach(() => { + node = document.createElement('div'); + document.body.appendChild(node); + }); + + afterEach(() => { + document.body.removeChild(node); + }); + + function expectBoundary(result, expected) { + const tolerance = 3; + console.log(result, expected); + expect(Math.abs(result.top - expected.top) <= tolerance).toBeTruthy(); + expect(Math.abs(result.right - expected.right) <= tolerance).toBeTruthy(); + expect(Math.abs(result.bottom - expected.bottom) <= tolerance).toBeTruthy(); + expect(Math.abs(result.left - expected.left) <= tolerance).toBeTruthy(); + } + + it('returns a boundary with a single value padding offset.', () => { + const padding = 50; + const result = getBoundaries(null, null, padding, 'viewport', true); + expectBoundary(result, { + top: 50, + right: 960, + bottom: 720, + left: 50, + }); + }); + + it('returns a boundary with a top and left componentized padding offset.', () => { + const padding = { + top: 50, + left: 100, + }; + const result = getBoundaries(null, null, padding, 'viewport', true); + expectBoundary(result, { + top: 50, + right: 1009, + bottom: 768, + left: 100, + }); + }); + + it('returns a boundary with a bottom and right componentized padding offset.', () => { + const padding = { + bottom: 50, + right: 85, + }; + const result = getBoundaries(null, null, padding, 'viewport', true); + expectBoundary(result, { + top: 0, + right: 924, + bottom: 718, + left: 0, + }); + }); + + it('returns a boundary with a null padding offset.', () => { + const padding = null; + const result = getBoundaries(null, null, padding, 'viewport', true); + expectBoundary(result, { + top: 0, + right: 1009, + bottom: 768, + left: 0, + }); + }); +}); \ No newline at end of file diff --git a/packages/test/karma.conf.js b/packages/test/karma.conf.js index d2b6a4c65b..0afaed5fea 100644 --- a/packages/test/karma.conf.js +++ b/packages/test/karma.conf.js @@ -59,8 +59,9 @@ module.exports = function(config) { '--headless', '--disable-gpu', // Without a remote debugging port, Google Chrome exits immediately. - ' --remote-debugging-port=9222', - ], + ' --remote-debugging-port=9222', + ' --window-size=1024,768', + ] }, ChromeDebug: { base: 'Chrome', @@ -70,32 +71,38 @@ module.exports = function(config) { base: 'SauceLabs', browserName: 'chrome', platform: 'macOS 10.12', + args: ['window-size=1024,768'] }, SLFirefox: { base: 'SauceLabs', browserName: 'firefox', platform: 'macOS 10.12', + args: ['window-size=1024,768'] }, SLEdge: { base: 'SauceLabs', browserName: 'microsoftedge', + args: ['window-size=1024,768'] }, SLSafari: { base: 'SauceLabs', browserName: 'safari', platform: 'macOS 10.12', + args: ['window-size=1024,768'] }, SLInternetExplorer10: { base: 'SauceLabs', browserName: 'internet explorer', version: '10', platform: 'Windows 8', + args: ['window-size=1024,768'] }, SLInternetExplorer11: { base: 'SauceLabs', browserName: 'internet explorer', version: '11', platform: 'Windows 10', + args: ['window-size=1024,768'] }, // Currently not used because the iOS emulator isn't reliable and // most of the times it times out @@ -143,6 +150,7 @@ module.exports = function(config) { startConnect: false, recordVideo: true, tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER, + screenResolution: "1024,768" }, reporters: ['mocha', 'saucelabs'], plugins: [