|
5 | 5 | */ |
6 | 6 |
|
7 | 7 | document.addEventListener('DOMContentLoaded', () => { |
8 | | - document.querySelectorAll('[title]').forEach(el => { |
9 | | - const text = el.getAttribute('title'); |
10 | | - if (text) { |
11 | | - el.setAttribute('data-tooltip', text); |
12 | | - if (!el.hasAttribute('aria-label')) { |
13 | | - el.setAttribute('aria-label', text); |
14 | | - } |
15 | | - el.removeAttribute('title'); |
| 8 | + const _attrib = 'title', _sel = '[title]'; |
| 9 | + const apply = el => { |
| 10 | + const t = el.getAttribute(_attrib); |
| 11 | + if (!t) return; |
| 12 | + el.setAttribute('data-tooltip', t); |
| 13 | + el.hasAttribute('aria-label') || el.setAttribute('aria-label', t); |
| 14 | + |
| 15 | + // Kill the original 'title'. |
| 16 | + el.removeAttribute(_attrib); |
| 17 | + }; |
| 18 | + |
| 19 | + // Apply to all elements on load. |
| 20 | + document.querySelectorAll(_sel).forEach(apply); |
| 21 | + |
| 22 | + // Apply to new elements. |
| 23 | + new MutationObserver(muts => { |
| 24 | + for (const m of muts) { |
| 25 | + apply(m.target); |
| 26 | + |
| 27 | + for (const n of m.addedNodes) |
| 28 | + if (n.nodeType === 1) { |
| 29 | + apply(n); |
| 30 | + n.querySelectorAll(_sel).forEach(apply); |
| 31 | + } |
16 | 32 | } |
| 33 | + }).observe(document.body, { |
| 34 | + childList: true, subtree: true, attributes: true, attributeFilter: [_attrib] |
17 | 35 | }); |
18 | 36 | }); |
0 commit comments