Fix: cannot select names in hovercards in the reply dialog Change-Id: I8756ea57f7db68d98e9ffbfb9b49474670a78b9f
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts index 7ad7223..48de78e 100644 --- a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts +++ b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard-behavior.ts
@@ -35,6 +35,26 @@ const HIDE_CLASS = 'hide'; /** + * ID for the container element. + */ +const containerId = 'gr-hovercard-container'; + +export function getHovercardContainer( + options: {createIfNotExists: boolean} = {createIfNotExists: false} +): HTMLElement | null { + let container = getRootElement().querySelector<HTMLElement>( + `#${containerId}` + ); + if (!container && options.createIfNotExists) { + // If it does not exist, create and initialize the hovercard container. + container = document.createElement('div'); + container.setAttribute('id', containerId); + getRootElement().appendChild(container); + } + return container; +} + +/** * How long should we wait before showing the hovercard when the user hovers * over the element? */ @@ -99,12 +119,6 @@ @property({type: Object}) container: HTMLElement | null = null; - /** - * ID for the container element. - */ - @property({type: String}) - containerId = 'gr-hovercard-container'; - private hideTask?: DelayedTask; private showTask?: DelayedTask; @@ -147,16 +161,7 @@ ready() { super.ready(); // First, check to see if the container has already been created. - this.container = getRootElement().querySelector('#' + this.containerId); - - if (this.container) { - return; - } - - // If it does not exist, create and initialize the hovercard container. - this.container = document.createElement('div'); - this.container.setAttribute('id', this.containerId); - getRootElement().appendChild(this.container); + this.container = getHovercardContainer({createIfNotExists: true}); } removeListeners() {
diff --git a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.ts b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.ts index 100d5cc..2c48ec0f 100644 --- a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.ts +++ b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.ts
@@ -22,6 +22,7 @@ import {IronOverlayBehavior} from '@polymer/iron-overlay-behavior/iron-overlay-behavior'; import {findActiveElement} from '../../../utils/dom-util'; import {fireEvent} from '../../../utils/event-util'; +import {getHovercardContainer} from '../gr-hovercard/gr-hovercard-behavior'; const AWAIT_MAX_ITERS = 10; const AWAIT_STEP = 5; @@ -118,6 +119,20 @@ } } + _onCaptureFocus(e: Event) { + const hovercardContainer = getHovercardContainer(); + if (hovercardContainer) { + // Hovercard container is not a child of an overlay. + // When an overlay is opened and a user clicks inside hovercard, + // the IronOverlayBehavior doesn't allow to set focus inside a hovercard. + // As a result, user can't select a text (username) in the hovercard + // in a dialog. We should skip default _onCaptureFocus for hovercards. + const path = e.composedPath(); + if (path.indexOf(hovercardContainer) >= 0) return; + } + super._onCaptureFocus(e); + } + /** * Override the focus stops that iron-overlay-behavior tries to find. */