Skip to content

Commit

Permalink
fix: force reflow on resize in Safari
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored and DiegoCardoso committed Sep 17, 2020
1 parent 27ac039 commit 338ec45
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/vaadin-dialog-resizable-mixin.html
Expand Up @@ -145,6 +145,7 @@

if (e.button === 0 || e.touches) {
e.preventDefault();

this._originalBounds = this._getOverlayBounds();
const event = this.__getMouseOrFirstTouchEvent(e);
this._originalMouseCoords = {top: event.pageY, left: event.pageX};
Expand Down Expand Up @@ -196,6 +197,7 @@
}
}
});

this.$.overlay.notifyResize();
}
}
Expand All @@ -209,11 +211,13 @@
}

_getResizeDimensions() {
const scrollPosition = this.$.overlay.$.resizerContainer.scrollTop;
const {width, height} = getComputedStyle(this.$.overlay.$.overlay);
const content = this.$.overlay.$.content;
content.setAttribute('style', 'position: absolute; top: 0; right: 0; bottom: 0; left: 0; box-sizing: content-box; height: auto;');
const {width: contentWidth, height: contentHeight} = getComputedStyle(content);
content.removeAttribute('style');
this.$.overlay.$.resizerContainer.scrollTop = scrollPosition;
return {width, height, contentWidth, contentHeight};
}
};
Expand Down
15 changes: 15 additions & 0 deletions src/vaadin-dialog.html
Expand Up @@ -408,6 +408,21 @@
__getMouseOrFirstTouchEvent(e) {
return e.touches ? e.touches[0] : e;
}

/**
* Safari 13 renders overflowing elements incorrectly.
* This forces it to recalculate height.
* @private
*/
__forceSafariReflow() {
const scrollPosition = this.$.overlay.$.resizerContainer.scrollTop;
const overlay = this.$.overlay.$.overlay;
overlay.style.display = 'block';
window.requestAnimationFrame(() => {
overlay.style.display = '';
this.$.overlay.$.resizerContainer.scrollTop = scrollPosition;
});
}
}

customElements.define(DialogElement.is, DialogElement);
Expand Down
73 changes: 57 additions & 16 deletions test/vaadin-dialog_draggable-resizable-test.html
Expand Up @@ -7,6 +7,7 @@
<link rel="import" href="../../test-fixture/test-fixture.html">
<link rel="import" href="../../iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="../src/vaadin-dialog.html">
<link rel="import" href="../../vaadin-text-field/vaadin-text-area.html">
<link rel="import" href="../../polymer/polymer-element.html">
<link rel="import" href="../../polymer/lib/utils/html-tag.html">
</head>
Expand Down Expand Up @@ -84,7 +85,7 @@

<test-fixture id="overflow">
<template>
<vaadin-dialog draggable opened modeless>
<vaadin-dialog resizable opened modeless>
<template>
</template>
</vaadin-dialog>
Expand Down Expand Up @@ -345,7 +346,7 @@

const contentBounds = dialog.$.overlay.firstElementChild.getBoundingClientRect();
const overlayBounds = overlayPart.getBoundingClientRect();
expect(contentBounds.height).to.equal(overlayBounds.height);
expect(Math.floor(contentBounds.height)).to.equal(Math.floor(overlayBounds.height));
});

it('should not resize dialog if not left mouse button', () => {
Expand Down Expand Up @@ -615,14 +616,17 @@
expect(dialog._setBounds).to.be.calledOnce;
});

it('should not reset scroll position on dragstart', () => {
it('should not reset scroll position on dragstart', (done) => {
dialog.modeless = true;
button.style.marginBottom = '200px';
dialog._setBounds({height: '100px'});
container.scrollTop = 100;
expect(container.scrollTop).to.equal(100);
drag(container);
expect(container.scrollTop).to.equal(100);
requestAnimationFrame(() => {
container.scrollTop = 100;
expect(container.scrollTop).to.equal(100);
drag(container);
expect(container.scrollTop).to.equal(100);
done();
});
});
});

Expand Down Expand Up @@ -810,23 +814,60 @@
});

describe('dialog with overflowing content', () => {
let dialog;
let dialog, overlay, overlayPart, container;

beforeEach(() => {
dialog = fixture('overflow');
overlay = dialog.$.overlay;
overlayPart = overlay.$.overlay;
container = overlay.$.resizerContainer;
});

it('should not overflow when style attribute is set on the overlay part', () => {
const container = document.createElement('div');
container.style.maxWidth = '300px';
container.style.overflow = 'auto';
container.textContent = Array(100).join('Lorem ipsum dolor sit amet');
const overlay = dialog.$.overlay;
overlay.content.appendChild(container);
const div = document.createElement('div');
div.style.maxWidth = '300px';
div.style.overflow = 'auto';
div.textContent = Array(100).join('Lorem ipsum dolor sit amet');
overlay.content.appendChild(div);
window.ShadyDOM && window.ShadyDOM.flush();
// emulate removing "pointer-events: none"
overlay.$.overlay.setAttribute('style', '');
expect(overlay.$.overlay.offsetHeight).to.equal(overlay.$.resizerContainer.offsetHeight);
overlayPart.setAttribute('style', '');
expect(overlayPart.offsetHeight).to.equal(container.offsetHeight);
});

const ios = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
const isIOS10 = ios && String(ios).indexOf('OS 10') > -1;
if (!isIOS10) {
it('should not overflow when using vaadin-textarea in the content', (done) => {
const textarea = document.createElement('vaadin-text-area');
textarea.value = Array(20).join('Lorem ipsum dolor sit amet');
overlay.content.appendChild(textarea);
window.ShadyDOM && window.ShadyDOM.flush();
overlay.$.content.style.padding = '20px';
resize(overlayPart.querySelector('.s'), 0, -50);
window.requestAnimationFrame(() => {
expect(getComputedStyle(overlayPart).height).to.equal(getComputedStyle(container).height);
done();
});
});

it('should not reset scroll position on resize', (done) => {
const div = document.createElement('div');
div.textContent = Array(100).join('Lorem ipsum dolor sit amet');
overlay.content.appendChild(div);
window.ShadyDOM && window.ShadyDOM.flush();
dialog._setBounds({height: 200});
window.requestAnimationFrame(() => {
overlay.$.content.style.padding = '20px';
container.scrollTop = 100;
resize(overlayPart.querySelector('.s'), 0, -50);
window.requestAnimationFrame(() => {
expect(container.scrollTop).to.equal(100);
done();
});
});
});
}
});
</script>
</body>

0 comments on commit 338ec45

Please sign in to comment.