Aller au contenu

MediaWiki:Common.js

De Loic Wiki
Version datée du 19 mars 2026 à 23:10 par Maintenance script (discussion | contributions) (Correction du rendu D2 via Kroki)
(diff) ← Version précédente | Version actuelle (diff) | Version suivante → (diff)

Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
  • Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
  •  Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
(function () {
  function loadScript(src) {
    return new Promise(function (resolve, reject) {
      if ([].some.call(document.scripts, function (s) { return s.src === src; })) return resolve();
      var script = document.createElement('script');
      script.src = src;
      script.async = true;
      script.onload = resolve;
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }

  function escapeHtml(str) {
    return str.replace(/[&<>"']/g, function (m) {
      return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[m];
    });
  }

  function renderMermaid() {
    var blocks = document.querySelectorAll('pre.oc-mermaid');
    if (!blocks.length || !window.mermaid) return Promise.resolve();
    mermaid.initialize({ startOnLoad: false, securityLevel: 'loose', theme: 'default' });
    return Promise.all(Array.from(blocks).map(function (block, idx) {
      if (block.dataset.ocRendered) return Promise.resolve();
      block.dataset.ocRendered = '1';
      var wrapper = document.createElement('div');
      wrapper.className = 'oc-diagram oc-mermaid-rendered';
      var source = block.textContent.trim();
      block.style.display = 'none';
      block.parentNode.insertBefore(wrapper, block);
      return mermaid.render('oc-mermaid-' + idx + '-' + Date.now(), source).then(function (result) {
        wrapper.innerHTML = result.svg;
      }).catch(function (err) {
        wrapper.innerHTML = '<div class="oc-diagram-error">Mermaid error: ' + escapeHtml(String(err)) + '</div>';
      });
    }));
  }

  function renderPlantUML() {
    var blocks = document.querySelectorAll('pre.oc-plantuml');
    if (!blocks.length || !window.plantumlEncoder) return;
    blocks.forEach(function (block) {
      if (block.dataset.ocRendered) return;
      block.dataset.ocRendered = '1';
      var src = block.textContent.trim();
      var encoded = plantumlEncoder.encode(src);
      var img = document.createElement('img');
      img.className = 'oc-diagram oc-plantuml-rendered';
      img.alt = 'PlantUML diagram';
      img.src = 'https://kroki.io/plantuml/svg/' + encoded;
      var wrap = document.createElement('div');
      wrap.className = 'oc-diagram-wrap';
      wrap.appendChild(img);
      block.style.display = 'none';
      block.parentNode.insertBefore(wrap, block);
    });
  }

  function renderBPMN() {
    var blocks = document.querySelectorAll('.oc-bpmn-container');
    if (!blocks.length || !window.BpmnJS) return;
    blocks.forEach(function (container) {
      if (container.dataset.ocRendered) return;
      var source = container.querySelector('pre.oc-bpmn-xml');
      var mount = container.querySelector('.oc-bpmn-viewer');
      if (!source || !mount) return;
      container.dataset.ocRendered = '1';
      var xml = source.textContent.trim();
      source.style.display = 'none';
      var viewer = new BpmnJS({ container: mount, keyboard: { bindTo: document } });
      viewer.importXML(xml).then(function () {
        var canvas = viewer.get('canvas');
        canvas.zoom('fit-viewport', 'auto');
      }).catch(function (err) {
        mount.innerHTML = '<div class="oc-diagram-error">BPMN error: ' + escapeHtml(String(err)) + '</div>';
      });
    });
  }

  function renderD2() {
    var blocks = document.querySelectorAll('pre.oc-d2');
    if (!blocks.length) return Promise.resolve();
    return Promise.all(Array.from(blocks).map(function (block) {
      if (block.dataset.ocRendered) return Promise.resolve();
      block.dataset.ocRendered = '1';
      var source = block.textContent.trim();
      var wrapper = document.createElement('div');
      wrapper.className = 'oc-diagram oc-d2-rendered';
      block.style.display = 'none';
      block.parentNode.insertBefore(wrapper, block);
      return fetch('https://kroki.io/d2/svg', {
        method: 'POST',
        headers: {
          'Content-Type': 'text/plain',
          'Accept': 'image/svg+xml'
        },
        body: source
      }).then(function (res) {
        if (!res.ok) throw new Error('HTTP ' + res.status);
        return res.text();
      }).then(function (svg) {
        wrapper.innerHTML = svg;
      }).catch(function (err) {
        wrapper.innerHTML = '<div class="oc-diagram-error">D2 error: ' + escapeHtml(String(err)) + '</div>';
      });
    }));
  }

  function boot() {
    Promise.all([
      loadScript('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js'),
      loadScript('https://cdn.jsdelivr.net/npm/plantuml-encoder/dist/plantuml-encoder.min.js'),
      loadScript('https://cdn.jsdelivr.net/npm/bpmn-js@18/dist/bpmn-navigated-viewer.production.min.js')
    ]).then(function () {
      return renderMermaid();
    }).then(function () {
      renderPlantUML();
      renderBPMN();
      return renderD2();
    }).catch(function (err) {
      console.error('Diagram integration failed', err);
    });
  }

  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
  else boot();
})();