Rapid Diffs: Restore "Viewed by me" tooltip on viewed checkbox
## Summary The Rapid Diffs "Viewed" checkbox is missing the "Viewed by me" tooltip that exists in the legacy Vue implementation. The tooltip was implemented during !222771 but was removed due to a Chrome-specific bug where the tooltip persists after scrolling and causes panel overflow. This is a feature parity gap with the legacy diffs implementation. ## Legacy behavior In `app/assets/javascripts/diffs/components/diff_file_header.vue` (line 430), the legacy Viewed checkbox uses `v-gl-tooltip.hover.focus.left.html` with the text "Viewed by me" and an optional keyboard shortcut hint (`<kbd>v</kbd>`). The tooltip is defined via the `MR_TOGGLE_REVIEW` keybinding in `app/assets/javascripts/behaviors/shortcuts/keybindings.js`. The legacy implementation does not exhibit the persistence/overflow bug in Chrome. ## Root cause analysis The `has-tooltip` CSS class (used for server-rendered HAML elements) and `v-gl-tooltip` (used in Vue components) take different initialization paths to the same underlying `GlTooltip` -> `BTooltip` -> `BVTooltip` stack: - **`v-gl-tooltip`**: Binds `mouseenter`/`mouseleave` and `focusin`/`focusout` directly on the element at directive bind time. - **`has-tooltip`**: Uses document-level event delegation (`app/assets/javascripts/tooltips/index.js`). On `mouseenter` or `focus`, it lazily creates a `GlTooltip` component instance targeting the element. When the tooltip is open and the user scrolls, BVTooltip relies on a 100ms `setInterval` visibility poll (`bv-tooltip.js`, `visibleCheck`). This poll checks `isVisible(target)`, which tests whether the element has layout dimensions - NOT whether it's in the viewport. An element scrolled out of view but still in the DOM passes this check, so the tooltip remains visible. In Chrome specifically (not Firefox), when `has-tooltip` elements are inside Rapid Diffs `<diff-file>` web components, the tooltip persists after scrolling. This is observable when keyboard focus opens the tooltip: the tooltip remains visible as the user scrolls away from the checkbox and persists until the focus changes (via additional keyboard input or a click). Hover-triggered tooltips exhibit the same persistence in Chrome, but are more easily dismissed since mouse movement naturally triggers `mouseleave`. ### Additional finding: `trigger`/`triggers` key mismatch In `app/assets/javascripts/main.js` (line 111), `initTooltips` is called with `trigger: 'hover'` (singular key). However, `initTooltips` in `tooltips/index.js` (line 63) reads `config.triggers` (plural). The singular `trigger` key is silently ignored, and the system falls back to `DEFAULT_TRIGGER = 'hover focus'`. This means `has-tooltip` always responds to both hover AND focus events, regardless of the configured intent. ## References - !222771 - MR where the tooltip was implemented and then removed - !222771#note_3096439340 - Review thread documenting the overflow behavior (video attached) - `app/assets/javascripts/tooltips/index.js` - `has-tooltip` event delegation system - `app/assets/javascripts/main.js:109-114` - Global tooltip initialization with mismatched key - `app/assets/javascripts/diffs/components/diff_file_header.vue:428-437` - Legacy tooltip implementation ## Proposal 1. Investigate why Chrome handles the tooltip persistence differently from Firefox in the Rapid Diffs web component context 2. Fix the `trigger`/`triggers` key mismatch in `main.js` / `tooltips/index.js` 3. Restore the "Viewed by me" tooltip with `placement: 'left'` on the Rapid Diffs checkbox
issue