ProjetDevWeb2/Projet/src/main/webapp/js/bloc.js

265 lines
7.4 KiB
JavaScript

import { autoResize, creerBlocDOM } from './utils.js';
import { activerCollagePropre } from './collagePropre.js';
import { renderBlocStyle,
handleSlashCommand,
handleMarkdownSyntax} from './functionsBloc.js'
export function initBlocs() {
document.querySelectorAll('.editor').forEach(bloc => {
addBlocEvent(bloc);
renderBlocStyle(bloc);
autoResize(bloc);
activerCollagePropre(bloc);
});
document.querySelectorAll('.editor a').forEach(link => {
link.addEventListener('click', event => {
event.preventDefault();
window.location.href = link.href;
});
});
document.querySelectorAll('.delete-bloc-btn').forEach(t => {
addDeleteBloc(t);
});
formatEditorContent();
document.querySelectorAll('#md [contenteditable="true"]').forEach(bloc => {
autoResize(bloc);
});
}
function formatEditorContent() {
document.querySelectorAll('.editor').forEach(function(element) {
let content = element.innerHTML;
content = content.replace(/\n/g, '<br />');
content = content.replace(/`(.*?)`/g, '<code>$1</code>&nbsp;');
content = content.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>&nbsp;');
content = content.replace(/\*(.*?)\*/g, '<i>$1</i>&nbsp;');
element.innerHTML = content;
// Appliquer le rendu MathJax après modification du contenu
MathJax.typeset();
autoResize(element);
});
}
export function addBlocEvent(bloc) {
bloc.addEventListener('input', event => {
const blocId = event.target.getAttribute('data-id');
const content = event.target.innerHTML;
const type = event.target.getAttribute('data-type');
const metadata = event.target.getAttribute('data-metadata');
const modif = {
action: "update",
blocId,
content,
metadata,
type
};
if (window.socketBloc && window.socketBloc.readyState === WebSocket.OPEN) {
window.socketBloc.send(JSON.stringify(modif));
}
});
bloc.addEventListener('keydown', async event => {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
const texte = bloc.innerText.trim();
if (texte.startsWith("/")) {
// Gérer les instructions commençant par /
await handleSlashCommand(bloc, texte);
} else {
// Gérer les titres et citations markdown
await handleMarkdownSyntax(bloc, texte);
}
sauvegarderBloc(bloc);
ajouterBlocVideSiBesoin();
formatEditorContent();
focusDernierBloc();
const blocId = bloc.getAttribute('data-id');
const content = bloc.innerHTML;
const type = bloc.getAttribute('data-type');
const classBloc = bloc.getAttribute('class');
const metadata = bloc.getAttribute('data-metadata');
const modif = {
action: "actualiserMiseEnPageBloc",
blocId,
content,
metadata,
classBloc,
type
};
socketBloc.send(JSON.stringify(modif));
}
// Si on est dans une liste, on crée un nouveau li
if (event.key === 'Enter' && event.shiftKey) {
const isListe = bloc.dataset.type === "LISTE";
if (isListe) {
event.preventDefault();
// Trouver le <li> courant
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const li = (range.startContainer.nodeType === Node.ELEMENT_NODE
? range.startContainer
: range.startContainer.parentNode
).closest('li');
if (li) {
// Créer un nouvel <li> vide
const newLi = document.createElement('li');
newLi.innerHTML = '<br>'; // pour que le li soit focusable
li.parentNode.insertBefore(newLi, li.nextSibling);
// Placer le curseur dans le nouveau li
const newRange = document.createRange();
newRange.setStart(newLi, 0);
newRange.collapse(true);
selection.removeAllRanges();
selection.addRange(newRange);
autoResize(bloc); // redimensionne si nécessaire
}
}
}
});
bloc.addEventListener('input', () => autoResize(bloc));
}
export function sauvegarderBloc(bloc) {
const blocId = bloc.getAttribute('data-id');
const type = bloc.getAttribute('data-type');
const metadata = bloc.getAttribute('data-metadata');
const params = new URLSearchParams();
let contenuTexte = bloc.innerHTML
.replace(/<br\s*\/?>/gi, '\n')
.replace(/<b>/gi, '**')
.replace(/<\/b>/gi, '**')
.replace(/<i>/gi, '*')
.replace(/<\/i>/gi, '*')
.replace(/<code>/gi, '`')
.replace(/<\/code>/gi, '`')
.replace(/<\/li>/gi, '\n')
.replace(/<\/?[^>]+(>|$)/g, ""); // Supprime les balises restantes
params.append("contenu", contenuTexte);
params.append("blocId", blocId);
params.append("metadata", metadata);
params.append("type", type);
fetch("/Projet/ModifBloc", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: params
}).catch(() => console.error("Erreur lors de la mise à jour du bloc."));
}
export function addDeleteBloc(button) {
button.addEventListener('click', function() {
const blocId = button.dataset.id;
const blocContainer = button.closest('.bloc-container');
const bloc = blocContainer.querySelector('[contenteditable="true"]');
if (bloc.dataset.type != "SEPARATEUR" && bloc.innerText === "") {
return;
}
if (confirm("Voulez-vous vraiment supprimer ce bloc ?")) {
const params = new URLSearchParams();
params.append("blocId", blocId);
fetch("/Projet/SupprimerBloc", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: params
}).then(response => {
if (response.ok) {
blocContainer.remove();
ajouterBlocVideSiBesoin();
window.socketBloc.send(JSON.stringify({
action: "deleteBloc",
blocId,
}));
} else {
console.error("Erreur lors de la suppression du bloc.");
}
});
}
});
}
export function ajouterBlocVideSiBesoin() {
const allBlocs = document.querySelectorAll('#md [contenteditable="true"]');
const pageId = new URLSearchParams(window.location.search).get("id");
if (pageId === null) return;
const message = document.querySelector('.column.is-half p');
if (message && message.textContent.trim() === "Pas encore de page choisie.") {
return;
}
if (allBlocs.length === 0 || allBlocs[allBlocs.length - 1].innerText.trim() !== "") {
const params = new URLSearchParams();
params.append("contenu", ""); // Bloc vide
params.append("type", "TEXTE"); // Type par défaut : TEXTE
params.append("metadata", "{}");
params.append("ordre", allBlocs.length);
params.append("pageId", new URLSearchParams(window.location.search).get("id"));
fetch("/Projet/NouveauBloc", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: params.toString()
}).then(response => response.json())
.then(data => {
if (data && data.idGenere) {
const idGenere = data.idGenere;
const newBloc = creerBlocDOM({
blocId: idGenere,
content: "",
type: "TEXTE",
metadata: "{}",
ordre: allBlocs.length
});
newBloc.focus();
// Envoi d'une notification d'un nouveau bloc créé via websocket
window.socketBloc.send(JSON.stringify({
action: "newBloc",
blocId: idGenere,
content: "",
type: "TEXTE",
metadata: "{}",
ordre: allBlocs.length
}));
}
});
}
}
export function focusDernierBloc() {
const blocs = document.querySelectorAll('.editor'); // Remplace `.bloc` par ta classe de bloc
const dernierBloc = blocs[blocs.length - 1];
if (dernierBloc) {
dernierBloc.focus();
}
}