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:
| M | editeur.css | | | 16 | ++++++++-------- |
| M | editeur.js | | | 185 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
| M | todo | | | 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