import { autoResize, placeCursorAtEnd } from './utils.js' import { createNewPage } from './page.js'; function applyBlocType(bloc, type, extra = {}) { bloc.dataset.type = type; let metadata = {}; switch (type) { case "TEXTE": metadata = {}; break; case "TITRE": metadata = { level: extra.level || 1 }; break; case "LISTE": metadata = { style: extra.style || "bullet" }; break; case "CODE": metadata = { language: extra.language || "plaintext", theme: "light" }; break; case "PAGE": metadata = { pageId: extra.pageId || "nouvelle-page-id", title: extra.title || "Nouvelle page" }; break; case "SEPARATEUR": metadata = {}; break; case "CITATION": metadata = { type: extra.type || "normal" }; break; default: console.warn("Type de bloc inconnu :", type); } setBlocMetadata(bloc, metadata); renderBlocStyle(bloc); } export function renderBlocStyle(bloc) { if (!bloc || !bloc.dataset) return; clearBlocStyles(bloc); const type = bloc.dataset.type || 'TEXTE'; switch (type) { case 'TEXTE': bloc.classList.add('is-text'); break; case 'TITRE': const metadata = getBlocDataMetadata(bloc); const level = metadata.level || '1'; bloc.classList.add('is-title', `is-title-${level}`); break; case 'LISTE': renderListe(bloc); bloc.classList.add('is-list'); break; case 'CODE': bloc.classList.add('is-code-block'); bloc.style.whiteSpace = "pre"; bloc.dataset.language || 'plaintext'; break; case 'PAGE': bloc.classList.add('is-page-link'); break; case 'SEPARATEUR': bloc.classList.add('is-separator'); bloc.contentEditable = "false"; break; case "CITATION": const metadataCitation = getBlocDataMetadata(bloc); const citationType = metadataCitation.type || 'normal'; bloc.classList.add('is-quote', `is-quote-${citationType}`); break; default: bloc.classList.add('is-text'); break; } autoResize(bloc); } export function clearBlocStyles(bloc) { bloc.classList.remove( 'is-title', 'is-title-1', 'is-title-2', 'is-title-3', 'is-quote', 'is-quote-info', 'is-quote-warning', 'is-quote-normal', 'is-code-block', 'is-list', 'is-page-link', 'is-separator', 'is-text' ); bloc.style.whiteSpace = "normal"; } export function renderListe(bloc) { const metadata = getBlocDataMetadata(bloc); const style = metadata.style || 'bullet'; const tag = style === 'number' ? 'ol' : 'ul'; const lignes = bloc.textContent.split('\n').filter(line => line.trim() !== ''); const items = lignes.map(line => `
  • ${line.trim()}
  • `).join(''); bloc.innerHTML = `<${tag}>${items}`; } export function handleSlashCommand(bloc, texte) { return new Promise((resolve) => { const parts = texte.trim().substring(1).split(" "); const command = parts[0].toLowerCase(); const param = parts.slice(1).join(" "); switch (command) { case "page": const pageId = new URLSearchParams(window.location.search).get("id"); createNewPage(param || "Nouvelle page", pageId).then(data => { if (data && data.id) { const lien = `/Projet/AfficherPage?id=${data.id}`; bloc.innerHTML = `${param || "Nouvelle page"}`; applyBlocType(bloc, "PAGE", { pageId: data.id, title: param, from: pageId }); autoResize(bloc); resolve(); } else { console.error("Erreur de création de page"); resolve(); } }).catch(error => { console.error("Erreur lors de la création de la page :", error); resolve(); }); break; case "h1": case "h2": case "h3": applyBlocType(bloc, "TITRE", { level: parseInt(command[1] || "1") }); bloc.textContent = param; autoResize(bloc); resolve(); break; case "ul": applyBlocType(bloc, "LISTE", { style: "bullet" }); bloc.textContent = ''; autoResize(bloc); resolve(); break; case "ol": applyBlocType(bloc, "LISTE", { style: "numbered" }); bloc.textContent = ''; autoResize(bloc); resolve(); break; case "code": applyBlocType(bloc, "CODE", { language: param || "plaintext" }); bloc.textContent = ''; autoResize(bloc); resolve(); break; case "hr": applyBlocType(bloc, "SEPARATEUR", {}); // ou un type adapté selon ta logique bloc.innerText = ' '; autoResize(bloc); resolve(true); break; default: console.log(`Commande non reconnue: ${command}`); resolve(); break; } bloc.focus(); placeCursorAtEnd(bloc); }); } export async function handleMarkdownSyntax(bloc, texte) { // Vérifier si c'est un titre if (texte.startsWith('#')) { const level = texte.split(' ')[0].length; // Compter le nombre de # pour le niveau du titre if (level >= 1 && level <= 6) { applyBlocType(bloc, "TITRE", { level: level }); bloc.textContent = texte.replace(/^#+\s*/, ''); autoResize(bloc); } } // Vérifier si c'est une citation else if (texte.startsWith('>')) { const citation = detectCitation(texte); applyBlocType(bloc, "CITATION", { type: citation.type }); bloc.textContent = citation.content; autoResize(bloc); } // Vérifier si c'est un bloc de code else if (texte.startsWith('```')) { applyBlocType(bloc, "CODE", {}); bloc.textContent = texte.replace(/^```(.*)$/, ''); autoResize(bloc); } // Vérifier si c'est un séparateur horizontal (Markdown) else if (texte.match(/^(\*{3,}|\-{3,}|_{3,})$/)) { applyBlocType(bloc, "SEPARATEUR", {}); bloc.textContent = ''; autoResize(bloc); } // Vérifier si c'est une liste else if (texte.match(/^(\s*([-*+])\s+.+|\s*\d+\.\s+.+)(\n|$)/m)) { const lignes = texte.split('\n').filter(line => line.trim() !== ''); let style = 'bullet'; if (lignes.every(line => line.trim().match(/^\d+\.\s+/))) { style = 'number'; } else if (lignes.every(line => line.trim().match(/^[-*+]\s+/))) { style = 'bullet'; } else { return; // Pas une vraie liste structurée } const contenu = lignes.map(line => line.replace(/^(\d+\.\s+|[-*+]\s+)/, '')).join('\n'); applyBlocType(bloc, "LISTE", { style: style }); bloc.textContent = contenu; renderListe(bloc); autoResize(bloc); } } export function getBlocDataMetadata(bloc) { try { return JSON.parse(bloc.getAttribute('data-metadata') || "{}"); } catch (e) { return {}; } } export function setBlocMetadata(bloc, metadata) { const metadataStr = JSON.stringify(metadata); bloc.dataset.metadata = metadataStr; bloc.setAttribute('data-metadata', metadataStr); } const citationTypes = { '>!': 'danger', '>i': 'info', /* '>w': 'warning', '>s': 'success',*/ '>': 'normal' // doit rester en dernier }; function detectCitation(texte) { for (const prefix in citationTypes) { if (texte.startsWith(prefix)) { return { type: citationTypes[prefix], content: texte.replace(new RegExp(`^${prefix}\\s*`), '') }; } } return null; }