Skip to content

Commit 1abd40d

Browse files
authoredAug 3, 2021
fix(ui5-dialog): fix text selection on chrome (#3532)
On Chrome, clicking on slotted elements (light DOM) in the dialog (shadow DOM) causes the focus to travel up the light DOM tree to reach the closes element that is focusable. Which ends to be the body element as document.activeElement. This is not the case for FF & Safari, where the focus travels up the slot, reaching the dialog root which is actually the closest focusable element. This change introduces a workaround to align the focus behaviour in Chrome with the other browsers. Related issue: WICG/webcomponents#773 Fixes #3466
1 parent 196a590 commit 1abd40d

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed
 

‎packages/base/src/Device.js

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ const detectTablet = () => {
7575
const supportsTouch = () => touch;
7676
const isIE = () => ie;
7777
const isSafari = () => safari;
78+
const isChrome = () => chrome;
7879

7980
const isTablet = () => {
8081
detectTablet();
@@ -94,6 +95,7 @@ export {
9495
supportsTouch,
9596
isIE,
9697
isSafari,
98+
isChrome,
9799
isPhone,
98100
isTablet,
99101
isDesktop,

‎packages/main/src/Popup.hbs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
dir="{{effectiveDir}}"
99
@keydown={{_onkeydown}}
1010
@focusout={{_onfocusout}}
11+
@mouseup={{_onmouseup}}
12+
@mousedown={{_onmousedown}}
1113
>
1214

1315
<span class="first-fe" data-ui5-focus-trap tabindex="0" @focusin={{forwardToLast}}></span>

‎packages/main/src/Popup.js

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
22
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
33
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
4+
import { isChrome } from "@ui5/webcomponents-base/dist/Device.js";
45
import { getFirstFocusableElement, getLastFocusableElement } from "@ui5/webcomponents-base/dist/util/FocusableElements.js";
56
import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js";
67
import { isTabPrevious } from "@ui5/webcomponents-base/dist/Keys.js";
@@ -278,10 +279,30 @@ class Popup extends UI5Element {
278279
}
279280

280281
_onfocusout(e) {
281-
// relatedTarget is the element, which will get focus. If no such element exists, focus the root
282+
// relatedTarget is the element, which will get focus. If no such element exists, focus the root.
283+
// This happens after the mouse is released in order to not interrupt text selection.
282284
if (!e.relatedTarget) {
283-
this._root.tabIndex = -1;
284-
this._root.focus();
285+
this._shouldFocusRoot = true;
286+
}
287+
}
288+
289+
_onmousedown(e) {
290+
this._root.removeAttribute("tabindex");
291+
292+
if (this.shadowRoot.contains(e.target)) {
293+
this._shouldFocusRoot = true;
294+
} else {
295+
this._shouldFocusRoot = false;
296+
}
297+
}
298+
299+
_onmouseup() {
300+
this._root.tabIndex = -1;
301+
if (this._shouldFocusRoot) {
302+
if (isChrome()) {
303+
this._root.focus();
304+
}
305+
this._shouldFocusRoot = false;
285306
}
286307
}
287308

0 commit comments

Comments
 (0)
Please sign in to comment.