avm99963 | 2485a3e | 2021-09-08 22:18:38 +0200 | [diff] [blame] | 1 | import {MDCTooltip} from '@material/tooltip'; |
| 2 | |
| 3 | const probCleanOrphanTooltips = 0.07; |
| 4 | |
| 5 | const currentTooltips = new Set(); |
| 6 | |
| 7 | // For each tooltip, if the element which is being described by it no longer |
| 8 | // exists, delete it. |
| 9 | function cleanOrphanTooltips() { |
| 10 | return new Promise((res, rej) => { |
| 11 | for (const tooltip of currentTooltips) { |
| 12 | if (document.querySelector('[aria-describedby="' + tooltip.id + '"]') === |
| 13 | null) { |
| 14 | currentTooltips.delete(tooltip); |
| 15 | tooltip.remove(); |
| 16 | } |
| 17 | } |
| 18 | res(); |
| 19 | }); |
| 20 | } |
| 21 | |
| 22 | export function createPlainTooltip(srcElement, label, initTooltip = true) { |
| 23 | if (srcElement.hasAttribute('aria-describedby')) { |
| 24 | let tooltip = |
| 25 | document.getElementById(srcElement.getAttribute('aria-describedby')); |
| 26 | if (tooltip !== null) tooltip.remove(); |
| 27 | } |
| 28 | |
| 29 | let tooltip = document.createElement('div'); |
| 30 | let tooltipId; |
| 31 | do { |
| 32 | // Idea from: https://stackoverflow.com/a/44078785 |
| 33 | let randomId = |
| 34 | Date.now().toString(36) + Math.random().toString(36).substring(2); |
| 35 | tooltipId = 'TWPT_tooltip_' + randomId; |
| 36 | } while (document.getElementById(tooltipId) !== null); |
| 37 | tooltip.id = tooltipId; |
| 38 | tooltip.classList.add('mdc-tooltip'); |
| 39 | tooltip.setAttribute('role', 'tooltip'); |
| 40 | tooltip.setAttribute('aria-hidden', 'true'); |
| 41 | |
| 42 | let surface = document.createElement('div'); |
| 43 | surface.classList.add( |
| 44 | 'mdc-tooltip__surface', 'mdc-tooltip__surface-animation'); |
| 45 | surface.textContent = label; |
| 46 | |
| 47 | tooltip.append(surface); |
| 48 | |
| 49 | // In the Community Console we inject the tooltip into |
| 50 | // #default-acx-overlay-container, and in TW directly into the body. |
| 51 | var tooltipParent = |
| 52 | document.getElementById('default-acx-overlay-container') ?? document.body; |
| 53 | tooltipParent.append(tooltip); |
| 54 | currentTooltips.add(tooltip); |
| 55 | |
| 56 | srcElement.setAttribute('aria-describedby', tooltipId); |
| 57 | |
| 58 | if (Math.random() < probCleanOrphanTooltips) cleanOrphanTooltips(); |
| 59 | |
| 60 | if (initTooltip) return new MDCTooltip(tooltip); |
| 61 | return tooltip; |
| 62 | } |