Skip to content

Commit

Permalink
Fix overlays position on scroll (#237)
Browse files Browse the repository at this point in the history
* Fix overlays position on scroll, add tests

* Simplify and update the test

* Skip scrolling tests on iOS

* Use arbitary props for page offsets

* Remove iphone simulator 9

* Update wct config
  • Loading branch information
yuriy-fix committed May 15, 2019
1 parent d67b28b commit d8e23bc
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 6 deletions.
42 changes: 42 additions & 0 deletions src/vaadin-context-menu.html
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,19 @@
this._boundOnGlobalContextMenu = this._onGlobalContextMenu.bind(this);
}

connectedCallback() {
super.connectedCallback();

this.__boundOnScroll = this.__onScroll.bind(this);
window.addEventListener('scroll', this.__boundOnScroll, true);
}

disconnectedCallback() {
super.disconnectedCallback();

window.removeEventListener('scroll', this.__boundOnScroll, true);
}

ready() {
super.ready();
this._observer = new Polymer.FlattenedNodesObserver(this, info => {
Expand Down Expand Up @@ -536,13 +549,42 @@

// Used in alignment which is delayed until overlay is rendered
this.__x = this._getEventCoordinate(e, 'x');
this.__pageXOffset = window.pageXOffset;

this.__y = this._getEventCoordinate(e, 'y');
this.__pageYOffset = window.pageYOffset;

this.$.overlay.style.opacity = '0';
this._setOpened(true);
}
}
}

__onScroll() {
if (!this.opened) {
return;
}

const yDiff = window.pageYOffset - this.__pageYOffset;
const xDiff = window.pageXOffset - this.__pageXOffset;

this.__adjustPosition('left', -xDiff);
this.__adjustPosition('right', xDiff);

this.__adjustPosition('top', -yDiff);
this.__adjustPosition('bottom', yDiff);

this.__pageYOffset += yDiff;
this.__pageXOffset += xDiff;
}

__adjustPosition(coord, diff) {
const overlay = this.$.overlay;
const style = overlay.style;

style[coord] = (parseInt(style[coord]) || 0) + diff + 'px';
}

__alignOverlayPosition() {
const overlay = this.$.overlay;
const style = overlay.style;
Expand Down
68 changes: 68 additions & 0 deletions test/items.html
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,74 @@
expect(menuComponents()[0].hasAttribute('expanded')).to.be.false;
expect(menuComponents()[0].getAttribute('aria-expanded')).to.equal('false');
});

if (!MOBILE) {
describe('scrolling', () => {
let rootOverlay, subOverlay1, subOverlay2, scrollElm;

beforeEach(done => {
const testStyle = document.createElement('style');
testStyle.innerHTML = `
html {
overflow:scroll;
}
body {
width: 2000px;
height: 2000px;
}
`;
window.document.body.appendChild(testStyle);

scrollElm = window.document.scrollingElement || window.document.querySelector('html');

rootOverlay = rootMenu.$.overlay;
subOverlay1 = subMenu.$.overlay;

flush(async() => {
open(menuComponents(subMenu)[2]);
const subMenu2 = getSubMenu(subMenu);
await nextRender(subMenu2);
subOverlay2 = subMenu2.$.overlay;
flush(done);
});
});

it('Should properly move overlays on scrolling distance within y axis', done => {
const scrollDistance = 150;

// Default indentation is 16
const rootBRCTop = rootOverlay.getBoundingClientRect().top;
const subBRCTop1 = subOverlay1.getBoundingClientRect().top;
const subBRCTop2 = subOverlay2.getBoundingClientRect().top;

scrollElm.scrollTop = scrollDistance;
Polymer.RenderStatus.afterNextRender(rootMenu, () => {
expect(rootOverlay.getBoundingClientRect().top).to.be.closeTo(rootBRCTop - scrollDistance, 1);
expect(subOverlay1.getBoundingClientRect().top).to.be.closeTo(subBRCTop1 - scrollDistance, 1);
expect(subOverlay2.getBoundingClientRect().top).to.be.closeTo(subBRCTop2 - scrollDistance, 1);
done();
});
});

it('Should properly move overlays on scrolling distance within x axis', done => {
const scrollDistance = 150;

// Default indentation is 16
const rootBRCLeft = rootOverlay.getBoundingClientRect().left;
const subBRCLeft1 = subOverlay1.getBoundingClientRect().left;
const subBRCLeft2 = subOverlay2.getBoundingClientRect().left;

scrollElm.scrollLeft = scrollDistance;
Polymer.RenderStatus.afterNextRender(rootMenu, () => {
expect(rootOverlay.getBoundingClientRect().left).to.be.closeTo(rootBRCLeft - scrollDistance, 1);
expect(subOverlay1.getBoundingClientRect().left).to.be.closeTo(subBRCLeft1 - scrollDistance, 1);
expect(subOverlay2.getBoundingClientRect().left).to.be.closeTo(subBRCLeft2 - scrollDistance, 1);
done();
});
});
});
}
});
});
</script>
Expand Down
12 changes: 6 additions & 6 deletions wct.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ module.exports = {

registerHooks: function(context) {
const saucelabsPlatformsMobile = [
'iOS Simulator/iphone@11.3',
'iOS Simulator/iphone@9.3'
'iOS Simulator/iphone@12.2',
'iOS Simulator/iphone@10.3'
];

const saucelabsPlatformsMicrosoft = [
'Windows 10/microsoftedge@17',
'Windows 10/microsoftedge@18',
'Windows 10/internet explorer@11'
];

const saucelabsPlatformsDesktop = [
'macOS 10.13/safari@11.1'
'macOS 10.13/safari@latest'
];

const saucelabsPlatforms = [
Expand All @@ -56,10 +56,10 @@ module.exports = {
{
deviceName: 'Android GoogleAPI Emulator',
platformName: 'Android',
platformVersion: '7.1',
platformVersion: '8.1',
browserName: 'chrome'
},
'iOS Simulator/ipad@11.3',
'iOS Simulator/ipad@12.2',
'iOS Simulator/iphone@10.3',
'Windows 10/chrome@latest',
'Windows 10/firefox@latest'
Expand Down

0 comments on commit d8e23bc

Please sign in to comment.