|
1 | 1 | import { clipboard } from 'mauss/web'; |
2 | 2 |
|
3 | | -export function listen(node: HTMLElement) { |
4 | | - for (const block of node.querySelectorAll('.mrq[data-mrq="block"]')) { |
5 | | - const actions = block.querySelectorAll('.mrq[data-mrq-toolbar]'); |
6 | | - const source = block.querySelector('.mrq[data-mrq="pre"]'); |
7 | | - if (!actions.length || !source) continue; |
| 3 | +export function hydrate(signal?: any) { |
| 4 | + signal; // listen to signal changes and re-run the function if needed |
| 5 | + return (node: HTMLElement) => { |
| 6 | + const active: Array<() => void> = []; |
| 7 | + for (const block of node.querySelectorAll('[data-aubade="block"]')) { |
| 8 | + const actions = block.querySelectorAll('[data-aubade-toolbar]'); |
| 9 | + const source = block.querySelector('[data-aubade="pre"]'); |
| 10 | + if (!actions.length || !source) continue; |
8 | 11 |
|
9 | | - for (const item of actions) { |
10 | | - const action = item.getAttribute('data-mrq-toolbar'); |
11 | | - if (action === 'clipboard') { |
12 | | - item.addEventListener('click', () => { |
13 | | - const tooltip = item.querySelector('.mrq[data-mrq="tooltip"]'); |
14 | | - if (!tooltip) return; |
15 | | - const text = tooltip.textContent; |
16 | | - clipboard.copy(source.textContent || '', { |
17 | | - accept() { |
18 | | - tooltip.textContent = 'Copied to clipboard!'; |
19 | | - }, |
20 | | - reject() { |
21 | | - tooltip.textContent = `Failed to copy code`; |
22 | | - }, |
23 | | - }); |
| 12 | + for (const item of actions) { |
| 13 | + const action = item.getAttribute('data-aubade-toolbar'); |
| 14 | + if (action === 'clipboard') { |
| 15 | + const tooltip = item.querySelector('[data-aubade="tooltip"]'); |
| 16 | + if (!tooltip) continue; |
| 17 | + const original = tooltip.textContent; |
24 | 18 |
|
25 | | - setTimeout(() => { |
26 | | - tooltip.textContent = text; |
27 | | - }, 5000); |
28 | | - }); |
29 | | - } else if (action === 'list') { |
30 | | - item.addEventListener('click', () => { |
31 | | - source.classList.toggle('numbered'); |
32 | | - }); |
| 19 | + const handler = () => { |
| 20 | + clipboard.copy(source.textContent || '', { |
| 21 | + accept() { |
| 22 | + tooltip.textContent = 'Copied to clipboard!'; |
| 23 | + }, |
| 24 | + reject() { |
| 25 | + tooltip.textContent = `Failed to copy code`; |
| 26 | + }, |
| 27 | + }); |
| 28 | + |
| 29 | + setTimeout(() => { |
| 30 | + tooltip.textContent = original; |
| 31 | + }, 5000); |
| 32 | + }; |
| 33 | + |
| 34 | + item.addEventListener('click', handler); |
| 35 | + active.push(() => item.removeEventListener('click', handler)); |
| 36 | + } else if (action === 'list') { |
| 37 | + const handler = () => source.classList.toggle('numbered'); |
| 38 | + item.addEventListener('click', handler); |
| 39 | + active.push(() => item.removeEventListener('click', handler)); |
| 40 | + } |
33 | 41 | } |
34 | 42 | } |
35 | | - } |
36 | | -} |
37 | | - |
38 | | -export function hydrate(node: HTMLElement, _: any) { |
39 | | - listen(node); |
40 | | - return { |
41 | | - update: () => listen(node), |
| 43 | + return () => { |
| 44 | + active.forEach((fn) => fn()); |
| 45 | + active.length = 0; |
| 46 | + }; |
42 | 47 | }; |
43 | 48 | } |
0 commit comments