From 46b455a0d3e96099e78975f53a25365a2ca9dcb4 Mon Sep 17 00:00:00 2001 From: polo Date: Fri, 5 Sep 2025 11:27:37 +0200 Subject: =?UTF-8?q?classe=20Editor=20et=20encapsulation,=20placement=20art?= =?UTF-8?q?icle=20premier=20ou=20dernier,=20variable=20window.Config.page,?= =?UTF-8?q?=20s=C3=A9paration=20openEditor=20et=20initEditor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/main.js | 17 +- public/js/menu.js | 87 ------- public/js/modif_page.js | 9 +- public/js/new_page.js | 5 +- public/js/tinymce.js | 647 ++++++++++++++++++++++++++---------------------- 5 files changed, 367 insertions(+), 398 deletions(-) (limited to 'public/js') diff --git a/public/js/main.js b/public/js/main.js index 4be7843..8f2b214 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,10 +1,10 @@ -function newPassword(page, id = ''){ +function newPassword(id = ''){ if(id != ''){ id = '&id=' + id; } alert('Le mot de passe a été modifié.'); window.setTimeout(function(){ - location.href = "index.php?page=" + page + "&message=nouveau_mdp" + id; + location.href = "index.php?page=" + window.Config.page + "&message=nouveau_mdp" + id; }, 0); } @@ -71,14 +71,16 @@ document.addEventListener('DOMContentLoaded', () => { // pour pouvoir attraper l nav_zone.style.height = entry.contentRect.height + 'px'; } }); - resize_observer.observe(nav); + if(nav){ + resize_observer.observe(nav); + } }); // complète les fonctions dans tinymce.js function switchPositions(article_id, direction) { - const current_article = findParent(document.getElementById(article_id), 'article'); // l'id n'est pas sur la bonne balise + const current_article = findParentByTagName(document.getElementById(article_id), 'article'); // l'id n'est pas sur la bonne balise var other_article; if(direction == 'down'){ @@ -232,10 +234,9 @@ function updateDate(id_date, date_input){ return date_input; } -function findParent(element, tag_name){ - while (element !== null) { - if (element.tagName === tag_name.toUpperCase()) // tagName est en majuscules - { +function findParentByTagName(element, tag_name){ + while(element !== null){ + if(element.tagName === tag_name.toUpperCase()){ // tagName est en majuscules return element; } element = element.parentElement; diff --git a/public/js/menu.js b/public/js/menu.js index ac6d35e..7f48ac9 100644 --- a/public/js/menu.js +++ b/public/js/menu.js @@ -63,93 +63,6 @@ function moveOneLevelDown(page_id) .catch(error => { console.error('Erreur:', error); }); - - /*const element = document.getElementById(page_id); // div parente du bouton cliqué - let previous_element = element.previousElementSibling; - - if(previous_element != null) - { - // si l'element précédent n'a pas de chemin relatif, donc est une URL, on vérifie le précédent également - if(previous_element.querySelector(".path") == null){ - let test_previous = previous_element; - while(test_previous.querySelector(".url") != null){ - console.log(test_previous); - //if() - test_previous = test_previous.previousElementSibling; - if(test_previous == null){ - console.log("pas d'élément précédent"); - return; - } - console.log(test_previous); - } - previous_element = test_previous; - } - - fetch('index.php?menu_edit=move_one_level_down', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ id: element.id }) - }) - .then(response => response.json()) - .then(data => { - if(data.success) - { - // - - // menu régénéré - nav_zone.innerHTML = ''; - nav_zone.insertAdjacentHTML('afterbegin', data.nav); - } - else { - - console.error('Échec de l\'inversion'); - } - }) - .catch(error => { - console.error('Erreur:', error); - }); - - // nouveau parent - let level_div = previous_element.querySelector(".level"); - if(level_div == null){ - // créer une
- level_div = document.createElement("div"); - level_div.classList.add("level"); - previous_element.appendChild(level_div); - } - - // déplacement - level_div.appendChild(element); - - // marges - let margin_left = parseInt(element.style.marginLeft); - margin_left += 29; - element.style.marginLeft = String(margin_left) + "px"; - - // MAJ des chemins affichés si c'est un chemin relatif (les liens URL ne peuvent avoir d'enfants) - const element_path = element.querySelector(".path"); - if(element_path != null){ - const previous_element_path = previous_element.querySelector(".path"); - element_path.innerHTML = previous_element_path.innerHTML + "/" + element_path.innerHTML.split("/").slice(-1); - - // même chose pour tous les enfants sauf les URL vers l'extérieur - if(element.querySelector(".level") != null){ - element.querySelector(".level").querySelectorAll(".path").forEach( (one_elem) => { - const parent_elem_path = one_elem.parentNode.parentNode.parentNode.querySelector(".path"); // => div de l'élém => div class level => div du parent - const end_of_path = one_elem.innerHTML.split("/").slice(-1); - one_elem.innerHTML = parent_elem_path.innerHTML + "/" + end_of_path[0]; - }); - } - } - - // dernier problème à corriger: le parent est une URL vers l'extérieur - } - else{ - // ne rien faire - console.log("pas d'élément précédent"); - }*/ } function switchMenuPositions(page_id, direction) diff --git a/public/js/modif_page.js b/public/js/modif_page.js index 615f34a..dd7271e 100644 --- a/public/js/modif_page.js +++ b/public/js/modif_page.js @@ -2,10 +2,7 @@ // même fonction que dans new_page.js function makePageNamePath(){ - const page_name = document.getElementById("page_name"); - const page_name_path = document.getElementById("page_name_path"); - - page_name_path.value = page_name.value + document.getElementById("page_name_path").value = document.getElementById("page_name").value .normalize("NFD") // décompose lettres + accents: é devient "e + accent aigu" .replace(/[\u0300-\u036f]/g, "") // supprime les accents .replace(/[^a-zA-Z0-9]+/g, " ") // supprime tout ce qu'il n'est pas alphanuméric @@ -130,7 +127,7 @@ function renamePageBloc(bloc_id){ }); } -function switchBlocsPositions(bloc_id, direction, current_page) { +function switchBlocsPositions(bloc_id, direction) { const current_bloc = document.getElementById(bloc_id); const current_bloc_edit_zone = document.getElementById("bloc_edit_" + bloc_id); var other_bloc; @@ -149,7 +146,7 @@ function switchBlocsPositions(bloc_id, direction, current_page) { } const other_bloc_edit_zone = document.getElementById("bloc_edit_" + other_bloc.id); - fetch('index.php?page=' + current_page + '&bloc_edit=switch_blocs_positions', { + fetch('index.php?page=' + window.Config.page + '&bloc_edit=switch_blocs_positions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id1: bloc_id, id2: parseInt(other_bloc.id) }) diff --git a/public/js/new_page.js b/public/js/new_page.js index 5b1c5c5..4b49060 100644 --- a/public/js/new_page.js +++ b/public/js/new_page.js @@ -2,10 +2,7 @@ // même fonction que dans modif_page.js function makePageNamePath(){ - const page_name = document.getElementById("page_name"); - const page_name_path = document.getElementById("page_name_path"); - - page_name_path.value = page_name.value + document.getElementById("page_name_path").value = document.getElementById("page_name").value .normalize("NFD") // décompose lettres + accents: é devient "e + accent aigu" .replace(/[\u0300-\u036f]/g, "") // supprime les accents .replace(/[^a-zA-Z0-9]+/g, " ") // supprime tout ce qu'il n'est pas alphanuméric diff --git a/public/js/tinymce.js b/public/js/tinymce.js index f153246..071c61b 100644 --- a/public/js/tinymce.js +++ b/public/js/tinymce.js @@ -1,178 +1,40 @@ -let editors = {}; +// code à réorganiser +// seule certaines fonctions ont leur place dans Editor, d'autres servent à manipuler les articles d'une autre manière (déplacer, supprimer...) +// => encapsuler Editor dans une classe Article (comme la balise) qui existe même quand l'éditeur est fermé -function openEditor(id, page = '') { - var creation_mode; - var real_id; - var article; - // création ou modification d'un article? - if(id[0] === 'n'){ - creation_mode = true; - article = document.getElementById(id); +/* -- utilisé par les évènements -- */ +let editors = {}; +function openEditor(id){ + if(!editors[id]){ + editors[id] = new Editor(id); // appel de init à l'intérieur } - else{ - creation_mode = false; - // Récupérer et sauvegarder le contenu d'origine de l'article - real_id = 'i' + id.slice(1); - article = document.getElementById(id); - document.getElementById(id).setAttribute('data-original-content', article.innerHTML); + //else{editors[id].reopen();} +} +// placement d'un nouvel article dans un bloc "Articles libres" +function setArticlePlacement(id){ + if(editors[id]){ + editors[id].setArticlePlacement(id); } - - tinymce.init({ - selector: `#${id}`, - language: 'fr_FR', // téléchargement ici: https://www.tiny.cloud/get-tiny/language-packages/ - language_url: 'js/tinymce-langs/fr_FR.js', // ou installer tweeb/tinymce-i18n avec composer - license_key: 'gpl', - branding: false, - plugins: 'lists link autolink table image media autoresize help', - toolbar: 'undo redo newdocument print selectall styles bold italic underline strikethrough fontsizeinput forecolor backcolor fontfamily align numlist bullist outdent indent table link image media help', - menubar: false, - toolbar_mode: 'wrap', - statusbar: false, - setup: function (editor) { - editor.on('init', function (){ - editors[id] = editor; - - // boutons "Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Soumettre" - document.querySelector(`#cancel-${id}`).classList.remove('hidden'); - document.querySelector(`#submit-${id}`).classList.remove('hidden'); - if(creation_mode === false){ - document.querySelector(`#edit-${id}`).classList.add('hidden'); - if(page != 'article'){ - document.querySelector(`#position_up-${id}`).classList.add('hidden'); - document.querySelector(`#position_down-${id}`).classList.add('hidden'); - document.querySelector(`#delete-${real_id}`).classList.add('hidden'); - } - } - else{ - document.querySelector(`#new-${id}`).classList.add('hidden'); // id = new-new-id_node - } - }); - let skipPastePreProcess = false; - editor.on('Paste', function (e){ // déclenchement AVANT PastePreProcess et quelque que soit le contenu collé - const clipboardData = (e.clipboardData || e.originalEvent.clipboardData); - if(!clipboardData){ - return; - } - const items = clipboardData.items; - let foundImage = false; - - for(let i = 0; i < items.length; i++){ - let item = items[i]; - - if(item.type.indexOf('image') !== -1){ // test type MIME contenant image - foundImage = true; - - const file = item.getAsFile(); // presse-papier => fichier lisible - const reader = new FileReader(); - - reader.onload = function (event){ // fonction exécutée lorsque reader.readAsDataURL(file) est terminée - const base64Data = event.target.result; // données de l'image - - fetch('index.php?action=upload_image_base64', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ image_base64: base64Data }) - }) - .then(response => response.json()) - .then(data => { - if(data.location){ - editor.insertContent(''); - } - }) - .catch(error => { - console.error('Erreur lors de l’upload de l’image base64 :', error); - }); - }; - reader.readAsDataURL(file); // lecture asynchrone du fichier - } - } - - if(foundImage){ - e.preventDefault(); // supprime le collage automatiue - skipPastePreProcess = true; // désactiver le PastePreProcess pour ce collage - } - }); - editor.on('PastePreProcess', function (e){ // déclenchement au collage AVANT insertion dans l'éditeur - const parser = new DOMParser(); - const doc = parser.parseFromString(e.content, 'text/html'); - const images = doc.querySelectorAll('img'); - - let downloads_in_progress = []; - - images.forEach(img => { - if(img.src.startsWith('file://')){ // détection d'images non insérables - console.warn('Image locale non insérable dans tinymce :', img.src); - img.outerHTML = `
- "Image locale non insérée (vient-elle d'un document LibreOffice ?). Effacez ce message rouge et copiez-collez l'image seule.
`; - } - else if(img.src.startsWith('http')){ // détection d'images web - const promise = fetch('index.php?action=upload_image_url', { // promesse d'un fichier téléchargeable sur le serveur - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ image_url: img.src }) - }) - .then(response => response.json()) - .then(data => { - if(data.location){ - img.src = data.location; // remplacer l'image par celle du serveur - } - }) - .catch(error => { - console.error('Erreur lors de l’upload de l’image distante:', error); - }); - - downloads_in_progress.push(promise); - } - }); - - // une image web ou plus: différer l'insertion dans l'éditeur le temps que le serveur télécharge les images - if(downloads_in_progress.length > 0){ - e.preventDefault(); - - Promise.all(downloads_in_progress).then(() => { - e.content = doc.body.innerHTML; // remplacement du HTML dans l'éditeur par la copie modifiée (doc) - editor.insertContent(e.content); - }); - } - else{ - e.content = doc.body.innerHTML; // remplacement du HTML dans l'éditeur par la copie modifiée (doc) - } - }); // fin editor.on('PastePreProcess'... - }, - // upload d'image natif de tinymce avec le bouton "Insérer une image" - images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => { - const formData = new FormData(); - formData.append("file", blobInfo.blob()); - - fetch("index.php?action=upload_image_tinymce", { - method: "POST", - body: formData - }) - .then(response => response.json()) - .then(data => { - if(data.location) { - resolve(data.location); - } - else { - reject("Erreur: Chemin d'image invalide"); - } - }) - .catch(error => { - reject("Erreur lors de l'upload"); - }); - }), - image_caption: true - }); - - // Remplacer le contenu de l'article par l'éditeur - if(creation_mode === false){ - document.getElementById(id).innerHTML = article.innerHTML; +} +function closeEditor(id, restore_old){ + if(editors[id]){ + editors[id].close(restore_old); } } - -function deleteArticle(id, page = '') { - if (confirm('Voulez-vous vraiment supprimer cet article ?')) +function submitArticle(id, clone = null) +{ + if(editors[id]){ + editors[id].submit(clone); + } + else if(window.Config.page === "article" && id[0] === 'n'){ // bouton Tout enregistrer (pas d'éditeur) + editors[id] = new Editor(id); + editors[id].submit(); + } +} +// standalone contraîrement aux autres fonctions ici +function deleteArticle(id){ + if(confirm('Voulez-vous vraiment supprimer cet article ?')) { // Envoyer une requête au serveur pour supprimer l'article fetch('index.php?action=delete_article', { @@ -199,146 +61,337 @@ function deleteArticle(id, page = '') { } } -function closeEditor(id, page = '', restore_old = true) + + +class Editor { - var creation_mode; - var real_id; - var article; - var parent; - - // création ou modification d'un article? - if(id[0] === 'n'){ - creation_mode = true; - } - else{ - creation_mode = false; - } + constructor(id){ + this.id = id; + this.article = document.getElementById(this.id); + this.creation_mode = this.id[0] === 'n' ? true : false; + //this.isOpen = false; + this.tiny_instance = null; - // Fermer l'éditeur - tinymce.remove(`#${id}`); - delete editors[id]; - - if(creation_mode){ - article = document.getElementById(id); - parent = findParent(article, 'section'); - } - else{ - real_id = 'i' + id.slice(1); + // moche, on ne devrait sortir l'envoi des données avec fetch de Editor.submit + if(!this.creation_mode || window.Config.page !== 'article'){ + if(this.creation_mode && window.Config.page !== 'article'){ + this.setArticlePlacement(this.id); + } + else{ + // insérer le contenu de l'article dans l'éditeur + this.article.setAttribute('data-original-content', this.article.innerHTML); + } + this.init(); + } + //else // bouton Tout enregistrer, pas d'éditeur } - // Restaurer le contenu d'origine de l'article - if(restore_old){ - const originalContent = document.getElementById(id).getAttribute('data-original-content'); - document.getElementById(id).innerHTML = originalContent; + setArticlePlacement(id_block){ + const checked_button = document.querySelector('input[name="article_placement-' + id_block + '"]:checked'); + if(checked_button){ // vrai clic + this.placement = checked_button.value; + } + else{ + document.getElementById('radio_last-' + id_block).checked = true; // faux clic + this.placement = 'last'; + } } + + init(){ + tinymce.init({ + selector: `#${this.id}`, // avec un # comme dans querySelector + language: 'fr_FR', // téléchargement ici: https://www.tiny.cloud/get-tiny/language-packages/ + language_url: 'js/tinymce-langs/fr_FR.js', // ou installer tweeb/tinymce-i18n avec composer + license_key: 'gpl', + branding: false, + plugins: 'lists link autolink table image media autoresize help', + toolbar: 'undo redo newdocument print selectall styles bold italic underline strikethrough fontsizeinput forecolor backcolor fontfamily align numlist bullist outdent indent table link image media help', + menubar: false, + toolbar_mode: 'wrap', + statusbar: false, + // les fonctions fléchées permettent de garder le contexte (= this) + setup: (editor) => { + editor.on('init', () => { + this.tiny_instance = editor; + + // boutons "Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Soumettre" + document.getElementById(`cancel-${this.id}`).classList.remove('hidden'); + document.getElementById(`submit-${this.id}`).classList.remove('hidden'); + const radio = document.getElementById(`radio-${this.id}`); + if(radio){ + radio.classList.remove('hidden'); + } + if(this.creation_mode){ + document.getElementById(`new-${this.id}`).classList.add('hidden'); // id = new-new-id_node + } + else{ + document.getElementById(`edit-${this.id}`).classList.add('hidden'); + if(window.Config.page !== 'article'){ + document.getElementById(`position_up-${this.id}`).classList.add('hidden'); + document.getElementById(`position_down-${this.id}`).classList.add('hidden'); + document.getElementById(`delete-${('i' + this.id.slice(1))}`).classList.add('hidden'); + } + } + }); + let skipPastePreProcess = false; + editor.on('Paste', function (e){ // déclenchement AVANT PastePreProcess et quelque que soit le contenu collé + const clipboardData = (e.clipboardData || e.originalEvent.clipboardData); + if(!clipboardData){ + return; + } + const items = clipboardData.items; + let foundImage = false; + + for(let i = 0; i < items.length; i++){ + let item = items[i]; + + if(item.type.indexOf('image') !== -1){ // test type MIME contenant image + foundImage = true; - // boutons: "Nouvel article", Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Valider" - document.querySelector(`#cancel-${id}`).classList.add('hidden'); - document.querySelector(`#submit-${id}`).classList.add('hidden'); - if(creation_mode){ - document.querySelector(`#new-${id}`).classList.remove('hidden'); // id = new-new-id_node + const file = item.getAsFile(); // presse-papier => fichier lisible + const reader = new FileReader(); + + reader.onload = function (event){ // fonction exécutée lorsque reader.readAsDataURL(file) est terminée + const base64Data = event.target.result; // données de l'image + + fetch('index.php?action=upload_image_base64', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ image_base64: base64Data }) + }) + .then(response => response.json()) + .then(data => { + if(data.location){ + editor.insertContent(''); + } + }) + .catch(error => { + console.error('Erreur lors de l’upload de l’image base64 :', error); + }); + }; + reader.readAsDataURL(file); // lecture asynchrone du fichier + } + } + + if(foundImage){ + e.preventDefault(); // supprime le collage automatiue + skipPastePreProcess = true; // désactiver le PastePreProcess pour ce collage + } + }); + editor.on('PastePreProcess', function (e){ // déclenchement au collage AVANT insertion dans l'éditeur + const parser = new DOMParser(); + const doc = parser.parseFromString(e.content, 'text/html'); + const images = doc.querySelectorAll('img'); + + let downloads_in_progress = []; + + images.forEach(img => { + if(img.src.startsWith('file://')){ // détection d'images non insérables + console.warn('Image locale non insérable dans tinymce :', img.src); + img.outerHTML = `
+ "Image locale non insérée (vient-elle d'un document LibreOffice ?). Effacez ce message rouge et copiez-collez l'image seule.
`; + } + else if(img.src.startsWith('http')){ // détection d'images web + const promise = fetch('index.php?action=upload_image_url', { // promesse d'un fichier téléchargeable sur le serveur + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ image_url: img.src }) + }) + .then(response => response.json()) + .then(data => { + if(data.location){ + img.src = data.location; // remplacer l'image par celle du serveur + } + }) + .catch(error => { + console.error('Erreur lors de l’upload de l’image distante:', error); + }); + + downloads_in_progress.push(promise); + } + }); + + // une image web ou plus: différer l'insertion dans l'éditeur le temps que le serveur télécharge les images + if(downloads_in_progress.length > 0){ + e.preventDefault(); + + Promise.all(downloads_in_progress).then(() => { + e.content = doc.body.innerHTML; // remplacement du HTML dans l'éditeur par la copie modifiée (doc) + editor.insertContent(e.content); + }); + } + else{ + e.content = doc.body.innerHTML; // remplacement du HTML dans l'éditeur par la copie modifiée (doc) + } + }); // fin editor.on('PastePreProcess'... + }, + // upload d'image natif de tinymce avec le bouton "Insérer une image" + images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => { + const formData = new FormData(); + formData.append("file", blobInfo.blob()); + + fetch("index.php?action=upload_image_tinymce", { + method: "POST", + body: formData + }) + .then(response => response.json()) + .then(data => { + if(data.location) { + resolve(data.location); + } + else { + reject("Erreur: Chemin d'image invalide"); + } + }) + .catch(error => { + reject("Erreur lors de l'upload"); + }); + }), + image_caption: true + }); } - else{ - document.querySelector(`#edit-${id}`).classList.remove('hidden'); - if(page != 'article'){ - document.querySelector(`#position_up-${id}`).classList.remove('hidden'); - document.querySelector(`#position_down-${id}`).classList.remove('hidden'); - document.querySelector(`#delete-${id}`).classList.remove('hidden'); + + close(restore_old = true){ + tinymce.remove(`#${this.id}`); // avec un # comme dans querySelector + delete editors[this.id]; + + // Restaurer le contenu d'origine de l'article + if(restore_old){ + const original_content = document.getElementById(this.id).getAttribute('data-original-content'); + document.getElementById(this.id).innerHTML = original_content; } - } -} -function submitArticle(id, page = '', clone = null) -{ - var editor; - var content; - const params = new URL(document.location).searchParams; // "search" = ? et paramètres, searchParams = objet avec des getters - - // clic sur "Tout enregistrer" - if(id[0] === 'n' && page === 'article'){ - const prefixes = ['t', 'p', 'i', 'd']; - const allElemsWithId = document.querySelectorAll('.data'); - content = {}; - var id_from_builder; - - allElemsWithId.forEach(element => { - const first_letter = element.id.charAt(0).toLowerCase(); - if(prefixes.includes(first_letter)){ - content[first_letter] = element.innerHTML; - if(first_letter === 'i'){ - id_from_builder = element.id; - } + // boutons: "Nouvel article", Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Valider" + document.getElementById(`cancel-${this.id}`).classList.add('hidden'); + document.getElementById(`submit-${this.id}`).classList.add('hidden'); + + const radio = document.getElementById(`radio-${this.id}`); + if(radio){ + document.querySelector('input[name="article_placement-' + this.id + '"]:checked').checked = false; // décoche l'option "en mémoire" + radio.classList.add('hidden'); + } + + if(this.creation_mode){ + document.getElementById(`new-${this.id}`).classList.remove('hidden'); // id = new-new-id_node + } + else{ + document.getElementById(`edit-${this.id}`).classList.remove('hidden'); + if(window.Config.page !== 'article'){ + document.getElementById(`position_up-${this.id}`).classList.remove('hidden'); + document.getElementById(`position_down-${this.id}`).classList.remove('hidden'); + document.getElementById(`delete-${this.id}`).classList.remove('hidden'); } - }) - content['d'] = dateToISO(content['d']); - } - // champs à remplir des nouvelles "news" - else if(page === 'article' && params != null && params.get("id")[0] === 'n'){ - closeEditor(id, page, false); - //makeNewArticleButtons(id, id, clone); - return; - } - // dans les autres cas, on doit pouvoir récupérer l'éditeur - else{ - // l'éditeur correspond à l'article OU page "article" à un élément: titre, aperçu, article - editor = editors[id]; - if(!editor) { - console.error('Éditeur non trouvé pour l\'article:', id); - return; } - content = editor.getContent(); } - - // Envoi AJAX au serveur - fetch('index.php?action=editor_submit', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({id: id, content: content}) - }) - .then(response => response.json()) - .then(data => { - if(data.success) { - //console.log(data.article_id); - if(id[0] === 'n' && page === 'article'){ - console.log('données envoyées au serveur avec succès.'); - - // redirection page de l'article - window.setTimeout(function(){ - const url_params = new URLSearchParams(window.location.search); // le "$_GET" de javascript - location.href = "index.php?page=article&id=" + data.article_id + "&from=" + url_params.get('from'); - }, 0); - } - else{ - // Fermer l'éditeur et mettre à jour le contenu de l'article - closeEditor(id, page, false); - if(id[0] === 'n'){ - makeNewArticleButtons(id, data.article_id, clone); + + submit(clone = null){ + //var editor; + var content; + const params = new URL(document.location).searchParams; // "search" = ? et paramètres, searchParams = objet avec des getters + // à comparer avec: new URLSearchParams(window.location.search); + // c'est pareil ou pas? + + // clic sur "Tout enregistrer" (ne devrait pas se situer dans Editor) + if(this.creation_mode && window.Config.page === 'article'){ + const prefixes = ['t', 'p', 'i', 'd']; + const allElemsWithId = document.querySelectorAll('.data'); + content = {}; + var id_from_builder; + + allElemsWithId.forEach(element => { + const first_letter = element.id.charAt(0).toLowerCase(); + if(prefixes.includes(first_letter)){ + content[first_letter] = element.innerHTML; + if(first_letter === 'i'){ + id_from_builder = element.id; + } } - } + }) + content['d'] = dateToISO(content['d']); } + // champs à remplir des nouvelles "news" + else if(window.Config.page === 'article' && params != null && params.get("id")[0] === 'n'){ + this.close(false); + return; + } + // dans les autres cas, on doit pouvoir récupérer l'éditeur else{ - alert('Erreur lors de la sauvegarde de l\'article.'); + // l'éditeur correspond à l'article OU si page = "article" à un élément: titre, aperçu, article + //editor = editors[id]; + if(!this.tiny_instance){ + console.error("Éditeur non trouvé pour l'article:", this.id); + return; + } + content = this.tiny_instance.getContent(); } - }) - .catch(error => { - console.error('Erreur:', error); - }); + + let fetch_params = {id: this.id, content: content}; + if(this.placement){ + fetch_params['placement'] = this.placement; + } + + // Envoi AJAX au serveur + fetch('index.php?action=editor_submit', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(fetch_params) + }) + .then(response => response.json()) + .then(data => { + if(data.success) + { + if(this.creation_mode && window.Config.page === 'article'){ + console.log('données envoyées au serveur avec succès.'); + + // redirection page de l'article + window.setTimeout(function(){ + const url_params = new URLSearchParams(window.location.search); // le "$_GET" de javascript + location.href = "index.php?page=article&id=" + data.article_id + "&from=" + url_params.get('from'); + }, 0); + } + else{ + // Fermer l'éditeur et mettre à jour le contenu de l'article + this.close(false); + if(this.creation_mode){ + makeNewArticleButtons(this.id, data.article_id, clone, this.placement); + } + } + } + else{ + alert('Erreur lors de la sauvegarde de l\'article.'); + } + }) + .catch(error => { + console.error('Erreur:', error); + }); + } + + //reopen(){} + + /*destroy(){ + this.close(); + delete editors[this.id]; + console.log(`Editor ${this.id} détruit.`); + }*/ } -function makeNewArticleButtons(id, article_id, clone) + + + + +// restera ici jusqu'à ce que la gestion des balises soient faite ailleurs +function makeNewArticleButtons(id, article_id, clone, placement = 'last') { var share_btn = document.querySelector(`.share.hidden`); // combinaison de deux classes - var new_btn = document.querySelector(`#new-${id}`); - var edit_btn = document.querySelector(`#edit-${id}`); - var pos_up_btn = document.querySelector(`#position_up-${id}`); - var pos_down_btn = document.querySelector(`#position_down-${id}`); - var delete_btn = document.querySelector(`#delete-${id}`); - var cancel_btn = document.querySelector(`#cancel-${id}`); - var submit_btn = document.querySelector(`#submit-${id}`); - - share_btn.classList.remove('hidden') + var new_btn = document.getElementById(`new-${id}`); + var edit_btn = document.getElementById(`edit-${id}`); + var pos_up_btn = document.getElementById(`position_up-${id}`); + var pos_down_btn = document.getElementById(`position_down-${id}`); + var delete_btn = document.getElementById(`delete-${id}`); + var cancel_btn = document.getElementById(`cancel-${id}`); + var submit_btn = document.getElementById(`submit-${id}`); + + share_btn.classList.remove('hidden'); new_btn.classList.add('hidden'); edit_btn.classList.remove('hidden'); pos_up_btn.classList.remove('hidden'); @@ -348,7 +401,7 @@ function makeNewArticleButtons(id, article_id, clone) //submit_btn.classList.add('hidden'); var article = document.getElementById(id); - var parent = findParent(article, 'article'); + var article_elem_parent = findParentByTagName(article, 'article'); share_btn.setAttribute('onclick', "copyInClipBoard('" + window.location.href + article_id + "')"); // # de l'ancre ajouté au clic sur le lien ouvrant l'éditeur article.id = article_id; @@ -364,8 +417,16 @@ function makeNewArticleButtons(id, article_id, clone) cancel_btn.querySelector('button').setAttribute('onclick', "closeEditor('" + article_id + "')"); submit_btn.id = 'submit-' + article_id; submit_btn.querySelector('button').setAttribute('onclick', "submitArticle('" + article_id + "')"); + + var section_child = article_elem_parent.parentNode.querySelector('.section_child'); // renommer section_child + + // parentNode vise la balise section + article_elem_parent.parentNode.replaceChild(clone.cloneNode(true), article_elem_parent); // clone du squelette pour le garder intact - var next_div = parent.nextElementSibling.nextElementSibling; - parent.parentNode.replaceChild(clone.cloneNode(true), parent); // clone du squelette pour le garder intact - next_div.appendChild(parent); + if(placement === 'first'){ + section_child.insertBefore(article_elem_parent, section_child.firstChild); + } + else{ // = 'last' + section_child.appendChild(article_elem_parent); + } } \ No newline at end of file -- cgit v1.2.3