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.
*/