Skip to content

Commit

Permalink
fix(ui5-dialog): correctly restore body scrolling on ESC (#3696)
Browse files Browse the repository at this point in the history
Body scrolling is now blocked only on first call of blockBodyScrolling and restored on the last call of unblockBodyScrolling.

Fixes #3690
  • Loading branch information
dimovpetar authored and ilhan007 committed Sep 10, 2021
1 parent e61f46f commit 983af6a
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 24 deletions.
21 changes: 16 additions & 5 deletions packages/main/src/Popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { isTabPrevious } from "@ui5/webcomponents-base/dist/Keys.js";
import { getNextZIndex, getFocusedElement, isFocusedElementWithinNode } from "@ui5/webcomponents-base/dist/util/PopupUtils.js";
import PopupTemplate from "./generated/templates/PopupTemplate.lit.js";
import PopupBlockLayer from "./generated/templates/PopupBlockLayerTemplate.lit.js";
import { getOpenedPopups, addOpenedPopup, removeOpenedPopup } from "./popup-utils/OpenedPopupsRegistry.js";
import { addOpenedPopup, removeOpenedPopup } from "./popup-utils/OpenedPopupsRegistry.js";

// Styles
import styles from "./generated/themes/Popup.css.js";
Expand Down Expand Up @@ -150,6 +150,8 @@ const createBlockingStyle = () => {

createBlockingStyle();

let bodyScrollingBlockers = 0;

/**
* @class
* <h3 class="comment-api-title">Overview</h3>
Expand Down Expand Up @@ -237,6 +239,12 @@ class Popup extends UI5Element {
* @protected
*/
static blockBodyScrolling() {
bodyScrollingBlockers++;

if (bodyScrollingBlockers !== 1) {
return;
}

if (window.pageYOffset > 0) {
document.body.style.top = `-${window.pageYOffset}px`;
}
Expand All @@ -248,6 +256,12 @@ class Popup extends UI5Element {
* @protected
*/
static unblockBodyScrolling() {
bodyScrollingBlockers--;

if (bodyScrollingBlockers !== 0) {
return;
}

document.body.classList.remove("ui5-popup-scroll-blocker");
window.scrollTo(0, -parseFloat(document.body.style.top));
document.body.style.top = "";
Expand Down Expand Up @@ -422,12 +436,9 @@ class Popup extends UI5Element {
return;
}

const openedPopups = getOpenedPopups();
if (this.isModal) {
this._blockLayerHidden = true;
if (openedPopups.length === 1) {
Popup.unblockBodyScrolling();
}
Popup.unblockBodyScrolling();
}

this.hide();
Expand Down
2 changes: 1 addition & 1 deletion packages/main/src/popup-utils/OpenedPopupsRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const _keydownListener = event => {
}

if (isEscape(event)) {
openedRegistry.pop().instance.close(true);
openedRegistry[openedRegistry.length - 1].instance.close(true);
}
};

Expand Down
9 changes: 8 additions & 1 deletion packages/main/test/pages/Dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

<body>
<ui5-checkbox text="Compact size" id="cbCompact"></ui5-checkbox>
<ui5-checkbox text="Scrollable page" id="cbScrollable"></ui5-checkbox>
<br>
<ui5-button id="btnOpenDialog">Open Streched Dialog</ui5-button>
<br>
Expand Down Expand Up @@ -309,7 +310,7 @@
<br>
<br>

<ui5-button id='popbtn'>Open Popover</ui5-button>
<ui5-button id="dangerDialogBtn">Open Dialog</ui5-button>



Expand Down Expand Up @@ -356,11 +357,17 @@

<ui5-dialog id="empty-dialog">Empty</ui5-dialog>

<span id="scrollHelper" style="display: none; margin-top: 1000px;">SCroll Helper</span>

<script>
cbCompact.addEventListener("change", function () {
document.body.classList.toggle("ui5-content-density-compact", cbCompact.checked);
});

cbScrollable.addEventListener("change", function () {
scrollHelper.style.display = cbScrollable.checked ? "block" : "none";
});

let preventClosing = true;

btnOpenDialog.addEventListener("click", function () {
Expand Down
58 changes: 41 additions & 17 deletions packages/main/test/specs/Dialog.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,29 +167,53 @@ describe("Acc", () => {
});
});

describe("Multiple dialogs page scroll", () => {
before(() => {
browser.url(`http://localhost:${PORT}/test-resources/pages/Dialog.html`);
});
describe("Page scrolling", () => {
before(() => {
browser.url(`http://localhost:${PORT}/test-resources/pages/Dialog.html`);
});

it("tests multiple dialogs page scrolling", () => {
const preventButtonBefore = browser.$("#prevent");
it("tests that page scrolling is blocked and restored", () => {
browser.$("#cbScrollable").click();
const offsetHeightBefore = browser.$("body").getProperty("offsetHeight");

browser.setWindowSize(400, 400);
preventButtonBefore.scrollIntoView();
browser.$("#btnOpenDialog").click();

const offsetBefore = preventButtonBefore.getLocation('y');
assert.ok(browser.$("body").getProperty("offsetHeight") < offsetHeightBefore, "Body scrolling is blocked");

preventButtonBefore.click();
browser.$("#btnCloseDialog").click();

browser.keys("Escape");
const confirmButton = browser.$("#yes");
confirmButton.click();
assert.strictEqual(browser.$("body").getProperty("offsetHeight"), offsetHeightBefore, "Body scrolling is restored");
browser.$("#cbScrollable").click();
});

browser.setTimeout({ script: 5000 });
const offsetAfter = preventButtonBefore.getLocation('y');
it("test page scrolling is restored after close with ESC", () => {
browser.$("#cbScrollable").click();
const offsetHeightBefore = browser.$("body").getProperty("offsetHeight");

assert.strictEqual(offsetBefore, offsetAfter, "No vertical page scrolling when multiple dialogs are closed");
});
browser.$("#btnOpenDialog").click();
browser.keys("Escape");
assert.strictEqual(browser.$("body").getProperty("offsetHeight"), offsetHeightBefore, "Body scrolling is restored");

browser.$("#cbScrollable").click();
});

it("tests multiple dialogs page scrolling", () => {
const preventButtonBefore = browser.$("#prevent");

browser.setWindowSize(400, 400);
preventButtonBefore.scrollIntoView();

const offsetBefore = preventButtonBefore.getLocation('y');

preventButtonBefore.click();

browser.keys("Escape");
const confirmButton = browser.$("#yes");
confirmButton.click();

browser.setTimeout({ script: 5000 });
const offsetAfter = preventButtonBefore.getLocation('y');

assert.strictEqual(offsetBefore, offsetAfter, "No vertical page scrolling when multiple dialogs are closed");
});
});

0 comments on commit 983af6a

Please sign in to comment.