File size: 2,103 Bytes
5846c4a
 
 
 
 
fee9c1e
5846c4a
 
 
 
 
 
 
 
 
 
 
 
 
fee9c1e
5846c4a
 
fee9c1e
5846c4a
 
 
 
fee9c1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5846c4a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
---
interface Props { src: string }
const { src } = Astro.props as Props;

// Charge tous les fragments .html sous src/fragments/** en tant que string (dev & build)
const fragments = import.meta.glob('../fragments/**/*.html', { query: '?raw', import: 'default', eager: true }) as Record<string, string>;

function resolveFragment(requested: string): string | null {
  // Autorise "banner.html" ou "fragments/banner.html"
  const needle = requested.replace(/^\/*/, '');
  for (const [key, html] of Object.entries(fragments)) {
    if (key.endsWith('/' + needle) || key.endsWith('/' + needle.replace(/^fragments\//, ''))) {
      return html;
    }
  }
  return null;
}

const html = resolveFragment(src);
const mountId = `frag-${Math.random().toString(36).slice(2)}`;
---
{ html ? (
  <div id={mountId} set:html={html} />
 ) : (
  <div><!-- Fragment introuvable: {src} --></div>
 ) }

<script>
  // Ré-exécuter les <script> présents dans le fragment injecté (innerHTML n'exécute pas les scripts)
  const scriptEl = document.currentScript;
  const mount = scriptEl ? scriptEl.previousElementSibling : null;
  const execute = () => {
    if (!mount) return;
    const scripts = mount.querySelectorAll('script');
    scripts.forEach(old => {
      // ignorer les types non exécutables (ex: application/json)
      if (old.type && old.type !== 'text/javascript' && old.type !== 'module' && old.type !== '') return;
      if (old.dataset.executed === 'true') return;
      old.dataset.executed = 'true';
      if (old.src) {
        const s = document.createElement('script');
        Array.from(old.attributes).forEach(({ name, value }) => s.setAttribute(name, value));
        document.body.appendChild(s);
      } else {
        try {
          // exécuter inline
          (0, eval)(old.text || '');
        } catch (e) {
          console.error('HtmlFragment inline script error:', e);
        }
      }
    });
  };
  // Si Plotly n'est pas encore chargé, attendre l'événement load
  if (window.Plotly) execute();
  else window.addEventListener('load', execute, { once: true });
  </script>