window.domain = 'hedgedoc.fransgenre.fr' window.urlpath = '' window.debug = false window.version = '1.10.5-7185a44448b41080ccda16339f973c76874c62d2' window.enableUploads = 'all' window.allowedUploadMimeTypes = ["image/jpeg","image/png","image/gif","image/svg+xml"] window.linkifyHeaderStyle = 'keep-case' window.DROPBOX_APP_KEY = '' window.cookiePolicy = 'lax' window.userToken = '' // fg-copy-button.js // Script qui ajoute des boutons de copie aux blocs de code HedgeDoc. // Fonction pour détecter quand un élément
 est connecté au DOM.
// Nécessaire parce que HedgeDoc effectue le rendu côté client.
function onPreConnected(connectedCallback) {
  const observer = new MutationObserver((mutationList) => {
    for (const mutation of mutationList) {
      if (mutation.type != "childList") {
        // Ça ne devrait pas arriver mais au cas où.
        continue;
      }

      for (const addedNode of mutation.addedNodes) {
        // Est-ce que le nouveau nœud est bien un élément HTML ?
        if (!(addedNode instanceof HTMLElement)) {
          continue;
        }
        // Est-ce que le nouvel élément est un bloc de code ?
        if (addedNode instanceof HTMLPreElement) {
          connectedCallback(addedNode);
          continue;
        }
        // Des blocs de code peuvent être contenus dans le nouvel élément.
        addedNode.querySelectorAll("pre").forEach(connectedCallback);
      }
    }
  });

  // Connexion des blocs de code préexistants.
  document.querySelectorAll("pre").forEach(connectedCallback);

  // Observation des nouveaux blocs de code.
  observer.observe(document, {
    childList: true,
    subtree: true,
  });
}

// Ajout d’un bouton de copie à chaque bloc de code.
onPreConnected((pre) => {
  // On ne s’occupe que des blocs de code du rendu Markdown.
  if (!pre.closest("#doc.markdown-body")) {
    return;
  }

  // Création du bouton.
  const button = document.createElement("button");
  button.classList.add("btn", "btn-primary");
  button.innerText = "Copier";
  button.dataset.fgCopyButton = "true";
  button.fgCopyButtonTarget = pre;

  // Positionnement du bouton.
  const wrapper = document.createElement("div");
  Object.assign(wrapper.style, {
    display: "flex",
    justifyContent: "end",
    paddingBottom: "0.5rem",
  });
  wrapper.style.display = "flex";
  wrapper.appendChild(button);

  // Ajout du bouton au-dessus du bloc de code.
  pre.insertAdjacentElement("beforebegin", wrapper);
});

// Un seul écouteur pour tous les boutons de copie.
// Ainsi pas besoin de détecter la déconnexion des boutons pour nettoyer.
document.addEventListener("click", async (event) => {
  const button = event.target;

  // Est-ce bien un bouton de copie ?
  if (!("fgCopyButton" in button.dataset)) {
    return;
  }

  // Récupération du bloc de code du bouton.
  const pre = event.target.fgCopyButtonTarget;
  if (!pre) {
    return;
  }

  // Suppression des numéros de ligne si besoin.
  const clonedPre = pre.cloneNode(true);
  const gutter = clonedPre.querySelector(".gutter.linenumber");
  if (gutter) {
    gutter.remove();
  }

  // Copie du contenu textuel.
  await navigator.clipboard.writeText(clonedPre.textContent);

  // Indication que la copie a été effectuée.
  button.classList.remove("btn-primary");
  button.classList.add("btn-success");
  button.innerText = "Copié !";

  // Nettoyage du timeout existant si besoin.
  if (button.fgCopyButtonTimeout !== undefined) {
    clearTimeout(button.fgCopyButtonTimeout);
  }

  // Remise à zéro du bouton au bout d’un moment.
  button.fgCopyButtonTimeout = setTimeout(() => {
    button.classList.remove("btn-success");
    button.classList.add("btn-primary");
    button.innerText = "Copier";
    button.fgCopyButtonTimeout = undefined;
  }, 750);
});