diff --git a/assets/css/app.css b/assets/css/app.css index 8b998608..f13f64c8 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -923,8 +923,7 @@ * pure CSS anchor positioning (the "⋮" trigger carries anchor-name, this popover * carries position-anchor). `position-area` drops it just below the trigger, * right-aligned, and `position-try-fallbacks` flips it above when there is no - * room below. The SubfieldMenu hook only toggles it — no coordinate math. This - * mirrors the payment-badge popover approach (§548) for a consistent look/feel. + * room below. The SubfieldMenu hook only toggles it — no coordinate math. */ .popover-menu { margin: 0; diff --git a/assets/js/app.js b/assets/js/app.js index 85ea1875..745d580f 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -352,6 +352,20 @@ Hooks.SortableList = { } } +// Guarded native Popover API toggles: showPopover()/hidePopover() throw on a +// detached element or a redundant open/close, so the popover hooks below share +// these wrappers instead of repeating the try/catch + :popover-open check. +function openPopover(el) { + try { + if (el && !el.matches(":popover-open")) el.showPopover() + } catch (_e) {} +} +function closePopover(el) { + try { + if (el && el.matches(":popover-open")) el.hidePopover() + } catch (_e) {} +} + // PopoverTooltip hook: shows a hint (referenced by data-tooltip-id) in the // browser TOP LAYER via the native Popover API, so it escapes the members // table's overflow clipping (overflow-x:auto forces overflow-y:auto, which clips @@ -386,19 +400,15 @@ Hooks.PopoverTooltip = { } this.show = () => { + openPopover(this.tip) + // Popover is measurable once open; positioning in the same tick avoids a + // visible flash (JS runs before the browser paints). try { - if (!this.tip.matches(":popover-open")) this.tip.showPopover() - // showPopover() makes it measurable; positioning in the same tick avoids - // a visible flash (JS runs before the browser paints). this.position() } catch (_e) {} } - this.hide = () => { - try { - if (this.tip.matches(":popover-open")) this.tip.hidePopover() - } catch (_e) {} - } + this.hide = () => closePopover(this.tip) this.onKey = (e) => { if (e.key === "Escape") this.hide() } @@ -431,8 +441,9 @@ Hooks.PopoverTooltip = { // sort sub-field. Attached to the "⋮" trigger; data-menu-id names the