www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 9f13e4ca99a6bea1c12db6a61d57f26509602250
parent d858073b78588425b63bfa0a42ff510ce9844181
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date:   Fri,  3 Sep 2010 01:22:59 +0200

Début de la vue aperçu (~30%).

Diffstat:
Mediteur.css | 16++++++++--------
Mediteur.js | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mtodo | 11+++++++----
3 files changed, 140 insertions(+), 72 deletions(-)

diff --git a/editeur.css b/editeur.css @@ -14,7 +14,7 @@ margin: 0.5em; } -.conteneur-esem .element { +.conteneur-esem .noeud { margin-bottom: 0.1em; } @@ -25,41 +25,41 @@ } -.conteneur-esem .element.document { +.conteneur-esem .noeud.document { display: block; } -.conteneur-esem .element.titre { +.conteneur-esem .noeud.titre { font-weight: bold; font-size: large; border: thick solid #ddd; display: block; } -.conteneur-esem .element.titre:before { +.conteneur-esem .noeud.titre:before { content: "Titre"; font-weight: bold; padding: 0 0.3em; background-color: #ddd; } -.conteneur-esem .element.paragraphe { +.conteneur-esem .noeud.paragraphe { border: thick solid #ddd; display: block; } -.conteneur-esem .element.paragraphe:before { +.conteneur-esem .noeud.paragraphe:before { content: "Paragraphe"; font-size: smaller; background-color: #ddd; display:block; } -.conteneur-esem .element.important { +.conteneur-esem .noeud.important { background-color: mistyrose; } -.conteneur-esem .element.important:before { +.conteneur-esem .noeud.important:before { content: "Important"; padding: 0 0.3em; font-size: smaller; diff --git a/editeur.js b/editeur.js @@ -1,22 +1,61 @@ var MULTI_LIGNE = 0; var MONO_LIGNE = 1; var EN_LIGNE = 2; + +function appendVuesEnfants(html, typeVue) { + for (var i = 0; i < this.contenu.length; i++) { + html.append(this.contenu[i].créerVue(typeVue)); + } +} var typesNoeud = { - document: { catégorie: MULTI_LIGNE, enfants: ['titre', 'paragraphe'] }, - titre: { catégorie: MONO_LIGNE, enfants: ['important', 'texte'] }, - paragraphe: { catégorie: MULTI_LIGNE, enfants: ['important', 'texte'] }, - important: { catégorie: EN_LIGNE, enfants: ['texte'] }, - lien: { catégorie: EN_LIGNE, enfants: ['texte'], 'propriétés': ['cible'] }, - texte: { catégorie: EN_LIGNE, enfants: [] }, - + document: { + catégorie: MULTI_LIGNE, + enfants: ['titre', 'paragraphe'], + vue: function() { + var ret = $('<div class="conteneur-esem"/>'); + appendVuesEnfants.call(this, ret, 'aperçu'); + return ret; + } + }, + titre: { + catégorie: MONO_LIGNE, + enfants: ['important', 'texte'], + vue: function() { + var ret = $('<div class="noeud titre mono-ligne"/>'); + appendVuesEnfants.call(this, ret, 'aperçu'); + return ret; + } + }, + paragraphe: { + catégorie: MULTI_LIGNE, + enfants: ['important', 'texte'], + vue: function() { + var ret = $('<div class="noeud paragraphe multi-ligne"/>'); + appendVuesEnfants.call(this, ret, 'aperçu'); + return ret; + } + }, + important: { + catégorie: EN_LIGNE, + enfants: ['texte'], + vue: function() { + var ret = $('<span class="noeud important en-ligne"/>'); + appendVuesEnfants.call(this, ret, 'aperçu'); + return ret; + } + }, lien: { - aperçu: function(n) { - return aperçu_noeud(n) - .children(".étiquette") - .append('<img src="..." alt="">'); - }, - édition: function(n) { - return édition_noeud(n).prepend('<input type="text" value="propriété <cible>"/>') + catégorie: EN_LIGNE, + enfants: ['texte'], + vue: { + aperçu: function(typeVue) { + return aperçu_noeud(this) + .children(".étiquette") + .append('<img src="..." alt="">'); + }, + édition: function(n) { + return édition_noeud(n).prepend('<input type="text" value="propriété <cible>"/>') + }, }, propriétés: { 'interne': false, @@ -24,11 +63,18 @@ var typesNoeud = { } }, texte: { - aperçu: function(n) { - return $("<span/>").bind_text(n.texte); - }, - édition: function(n) { - return $("<textarea/>").bind_val(n.texte); + catégorie: EN_LIGNE, + enfants: [], + vue: { + aperçu: function(typeVue) { + return $('<span class="noeud texte en-ligne"/>') + /* .append($('<span class="étiquette">texte</span>')) */ + .append($('<span class="contenu"/>').text(this.texte)); + // .bind_text(this.texte); + }, + édition: function(n) { + return $("<textarea/>").bind_val(n.texte); + }, }, propriétés: { texte: new valeur("") @@ -36,35 +82,55 @@ var typesNoeud = { } }; +$(function() { + $(".éditeur-semantique").each(function(i,e) { + éditeurSémantique(e); + }); +}); + function éditeurSémantique(textareaOrigine) { + // XML -> modèle var textareaOrigine = $(textareaOrigine); var xml = $("<document/>").append(textareaOrigine.val()); // Est-ce portable ?. - var modèle = xmlVersModèle(xml.get(0)); - console.log(modèle); + + // Vue + var vue = modèle.créerVue(null); + textareaOrigine.replaceWith(vue); + + // Debug m = modèle; + v = vue; } function xmlVersModèle(xml) { - function recursion(xml, parent) { + function recursion(xml, parent, document) { var tag = xml.tagName.toLowerCase(); // TODO : si tagName n'est pas toujours un "vrai" string, .toString() . var ret = { type: tag, texte: (tag == "texte") ? $(xml).text() : '', - parent: parent, - document: null, // TODO + contenu: $(xml).children().map(function (i,e) { + return recursion(e, {p:ret}, document); + }).get(), + + // Navigation + parent: function() { return parent.p; }, + document: function() { return document.d; }, + + // Modèle : fonctions principales. positionDansParent: function() { - return this.parent.contenu.indexOf(this); // Mouais... + return this.parent().contenu.indexOf(this); // Mouais... }, insérer: function(noeud, position) { this.contenu.splice(position, 0, noeud); - this.contenu[position].parent = this; + this.contenu[position].parent() = this; // TODO : modifier la vue }, supprimerEnfant: function(position) { return this.contenu.splice(position, 1); }, modifierType: function(nouveauType) { + // TODO : lien -> (texte ou important ou ...) doit préserver le texte du lien. // TODO : vérifier si le parent peut bien contenir ce type this.type = nouveauType; // TODO : modifier la vue @@ -75,16 +141,16 @@ function xmlVersModèle(xml) { // TODO : modifier la vue }, - // Fonctions secondaires : + // Modèle : Fonctions secondaires : supprimer: function() { - return this.parent.supprimerEnfant(this.positionDansParent()); + return this.parent().supprimerEnfant(this.positionDansParent()); }, - insérerAvant: function(noeud) { // insère noeud avant this (à l'extérieur) - this.parent.insérer(noeud, this.positionDansParent()); + insérerAvant: function(noeud) { // insère noeud avant this (à l'extérieur). + this.parent().insérer(noeud, this.positionDansParent()); }, insérerAprès: function(noeud) { // insère noeud après this (à l'extérieur) - this.parent.insérer(noeud, this.positionDansParent() + 1); + this.parent().insérer(noeud, this.positionDansParent() + 1); }, insérerDébut: function(noeud) { // insère noeud au début de this (à l'intérieur) this.insérer(noeud, 0); @@ -94,14 +160,14 @@ function xmlVersModèle(xml) { }, emballer: function(noeud) { // insère noeud à la place de this, et met this dedans var pos = this.positionDansParent(); - var parent = this.parent; + var parent = this.parent(); var n = parent.supprimerEnfant(pos); parent.insérer(noeud, pos); noeud.insérer(n, 0); // TODO ? noeud.setContenu(this); }, remplacer: function () { var pos = this.positionDansParent(); - var parent = this.parent; + var parent = this.parent(); parent.supprimerEnfant(pos); for (var i = 0; i < arguments.length; i++) { parent.insérer(arguments[i], pos++); @@ -113,16 +179,34 @@ function xmlVersModèle(xml) { c[i] = this.supprimerEnfant(i); // TODO : l'insertion devrait elle-même supprimer le noeud s'il est déjà inséré quelque part. } this.remplacer.apply(this, c); + }, + + // Vue + créerVue: function(typeVue) { + surcharge = typesNoeud[tag].vue; + if (typeof surcharge == "function") { + return surcharge.call(this, typeVue); + } else if (typeof surcharge == "object" && typeof surcharge[typeVue] == "function") { + return surcharge[typeVue].call(this); + } else { + var ret = $('<div/>').text("" + typeVue); + for (var i = 0; i < this.contenu.length; i++) { + ret.append(this.contenu[i].créerVue('aperçu')); + } + return ret; + } } }; - ret.contenu = $(xml).children().map(function (i,e) { - return recursion(e, ret); - }).get(); return ret; } - var ret = recursion(xml, null); - /* ret.parent = ret; // Rhôôô le hack ! */ - return ret; + + var _doc = {d: 42}; + var _par = {p: 42}; + doc = recursion(xml, _par, _doc); + _doc.d = doc; + _par.p = doc; + + return doc; } /* Modèle : @@ -133,11 +217,12 @@ function xmlVersModèle(xml) { vue.supprimerVue(); vue.supprimerEnfant(position); -noeud.créerVue(noeud, typeVue); +noeud.créerVue(typeVue); vue.insérerEnfant(noeud_enfant, position) { insérer_dans_vue_courante_à_position(créerVue(noeud_enfant), position); } vue.setPropriété(propriété, valeur); vue.setActif(bool); document.noeudActif(noeud); // ? +document.créerVue($(html_element)); ================= @@ -152,20 +237,6 @@ n.détacher(); // ? // Contrôleur : noeud.document.nouveauNoeud() -noeud.insérerAvant(n2) -noeud.insérerAprès(n2) -noeud.insérerDébut(n2) -noeud.insérerFin(n2) -noeud.insérerAutour(n2) - -noeud.supprimer() -noeud.remplacer(n2, n3, ...) // remplacer n par n2, ... n(n+1) -noeud.supprimer_en_gardant_le_contenu() // TODO : trouver un nom meilleur. jquery : unwrap - -m - noeud.modifierType(nouveaType); // TODO ! lien -> texte ou important ou ... doit préserver le texte du lien ! - -m - noeud.setPropriété(propriété, valeur); - */ function valeur(v) { // TODO : voir si ça peut marcher aussi pour des éléments complets (pas que du texte). @@ -225,12 +296,6 @@ function édition_noeud_texte(n) { -$(function() { - $(".éditeur-semantique").each(function(i,e) { - éditeurSémantique(e); - }); -}); - function éditeurSémantique_(textareaÉditeur) { var conteneur = $('<div class="conteneur-esem"/>'); var éditeur = $(textareaÉditeur).removeClass("éditeur-semantique").addClass("éditeur"); diff --git a/todo b/todo @@ -1,13 +1,16 @@ Ne pas créer de noeud <texte> vide (sauf explicitement). Petit refactor pour pouvoir spécifier un nombre arbitraire de types de noeud. -Différence noeuds Multiligne (paragraphe), monoligne (titre) en-ligne (important, emphase). +ok Différence noeuds Multiligne (paragraphe), monoligne (titre) en-ligne (important, emphase). Toutes les opérations sur l'arbre : - Nouveau noeud (avant, après, dans, autour) par rapport à sélection ou à un noeud (transformer la sélection en noeud texte, puis utiliser la même fonction que pour un noeud "normal"); - Supprimer un noeud et son contenu, supprimer et garder le contenu; - Modifier le type d'un noeud (important -> emphase par ex.); - Couper / Copier / Coller un noeud ou une sélection. Le collage utilise la même fonction que l'insertion, couper utilise "copier" et "supprimer". - - Pour ces opérations, utiliser un "langage" de réécriture contextuelle ? Pouvoir spécifier des restrictions sur la structure (tel noeud peut/doit contenir tel noeud, etc.) Propriétés d'un noeud (cible pour les liens, source pour les images), pouvoir spécifier quel dialogue permet l'édition des propriétés, plus l'apparence du noeud (icône lien -> quand on clique, ouvre le dialogue ?). + pouvoir manipuler le contenu (texte) du noeud directement depuis le "dialogue". En fait, le "dialogue" ne devrait être qu'une variation du textarea "éditeur". Afficher "texte" pour les noeuds texte ? -Faire du M(VC) !!! Modèle -> objet javascript (DOM + focus), vue/contrôleur -> arbre, aperçu, paneau d'édition -\ No newline at end of file +Faire du M(VC) !!! Modèle -> objet javascript (DOM + focus), vue/contrôleur -> arbre, aperçu, paneau d'édition + +Court-terme : +corriger et compléter typesNoeud; +nettoyer typesNoeud (toujours avoir une fonction vue() au lieu d'un tableau, fonctions pour créer les vues d'aperçu courantes, appendVuesEnfants -> $.appendVuesEnfants(), ...). +\ No newline at end of file