1 /* ce code s'inspire du travail de http://www.spip-contrib.net/_courcy_
2 * il a été en grande partie ré-écrit pour :
3 * - générer une syntaxe de tableau SPIP et non HTML (l'éditeur de couleur de cellules disparaît donc aussi)
4 * - pour permettre non seulement de créer un tableau mais aussi de modifier un tableau existant
5 * - pour intégrer les éléments HTML titre et résumé de tableau
7 /******************************************
8 * FONCTIONNEMENT Général
9 *********************BUT****************************************
10 * Le but de ce script est de permettre à l'utilisateur de créer son propre
11 * tableau sans s'encombrer de la syntaxe SPIP. Si un tableau à syntaxe SPIP est
12 * sélectionné avant l'appel de l'assistant, les données sont récupérées par l'assistant.
13 * Si rien n'est sélectionné l'appel de l'assistant, un nouveau tableau est créé au point
15 ************Structure de donnees ***********************************
17 * Classe ihm qui gère l'interface homme-machine de l'assistant et sa construction
18 * On trouve en autres les méthodes permettant d'insérer et de supprimer lignes et colonnes
20 * Classe Cellule qui contient les informations relatives à une cellule
21 * Ses attributs sont des informations relatives a une cellule (contenu)
22 * chaque objet cellule est contenu dans le tableau lc qui est un tableau bidimensionnel de cellules
23 * ce tableau a autant d'éléments que de ligne * colonne dans le tableau
26 *******************ALGORITHME*************************************
27 * Le tableau est sauvé en mémoire dans la variable lc
28 * La fonction construit_tableau( ) de la classe ihm construit l'interface pour manipuler les données du tableau
29 * qui (re)initialisera la valeur innerHTML de <div id=tableau></div>
30 * toute modification des valeurs dans l'assistant modifie lc
31 * toute modification de l'interface (ajout/suppression de ligne/colonne) modifie lc puis appelle la fonction construit_tableau
32 * simple mais efficace+
34 * La validation des modifications déclenche construit_code_tableau qui construit le code SPIP du tableau
38 /********INITIALISATION**************/
39 //classe ihm : classe générique de gestion de tableau
44 this.construit_tableau
= construit_tableau
;
45 this.bouton_insere_ligne
= bouton_insere_ligne
;
46 this.bouton_supprime_ligne
= bouton_supprime_ligne
;
47 this.bouton_insere_colonne
= bouton_insere_colonne
;
48 this.bouton_supprime_colonne
= bouton_supprime_colonne
;
49 this.insere_commande_ligne
= insere_commande_ligne
;
50 this.insere_commande_colonne
= insere_commande_colonne
;
51 this.insere_ligne
= insere_ligne
;
52 this.supprime_ligne
= supprime_ligne
;
53 this.insere_colonne
= insere_colonne
;
54 this.supprime_colonne
= supprime_colonne
;
56 /*******CONStrUIT tableAU**********/
57 function construit_tableau(){
59 texte
+="<table id='ihm' cellspacing='"+cellspacing
+"'>\n";
60 for (i
=0;i
<nl
+2;i
++){//on rajoute deux lignes en plus pour l'interface
62 for (j
=0;j
<nc
+2;j
++){//on rajoute deux lignes en plus pour l'interface
64 if (i
==0 && j
==0) position
= "coin"; //on est dans le coin on met le menu
65 if (i
==0 && j
>0) position
= "1st_l"; //on est sur la premiere ligne on insere des colonnes
66 if (i
>0 && j
==0) position
= "1st_c"; //on est sur la premiere colonne on insere des lignes
67 if (i
==nl
+1 && j
>0) position
= "last_l"; //on est dans la zone non éditée de la derniere ligne
68 if (i
>0 && j
==nc
+1) position
= "last_c"; //on est dans la zone non éditée la derniere colonne
70 case "coin" : texte
+="<td></td>\n"; break;
71 case "1st_l" : texte
+="<td class='first_l'>"+this.insere_commande_colonne(j
-1)+"</td>\n"; break;
72 case "1st_c" : texte
+="<td class='first_c'>"+this.insere_commande_ligne(i
-1)+"</td>\n"; break;
73 case "last_l" : texte
+="<td class='last_l'></td>\n"; break;
74 case "last_c" : texte
+="<td class='last_c'></td>\n"; break;
75 default: //on est dans la partie éditable du tableau
76 texte
+="<td>"+ lc
[i
-1][j
-1].insere() +"</td>\n";
82 //win=window.open('');
83 //win.document.write("<textarea cols='100' rows='50'>"+texte+"</textarea>");
84 table
.innerHTML
=texte
;//on modifie le texte de ce noeud
87 *cette fonction crée un bouton pour l'insertion d'une ligne
89 function bouton_insere_ligne(ligne
){
90 var texte
= "<a href='javascript:ihm_tableau.insere_ligne("+ligne
+")'><img ";
91 texte
+= " title='إدراج سطر فوق' ";
92 texte
+= " alt='إدراج سطر فوق' ";
93 texte
+= "src='"+tableau_edit_images_path
+"inserer_ligne.gif' value=''></a>\n";
98 *cette fonction crée un bouton pour la supression d'une ligne
100 function bouton_supprime_ligne(ligne
){
101 if (nl
== 1) return "";
102 var texte
="<a href='javascript:ihm_tableau.supprime_ligne("+ligne
+")'><img ";
103 texte
+= " title='حذف هذا السطر' ";
104 texte
+= " alt='حذف هذا السطر' ";
105 texte
+= "src='"+tableau_edit_images_path
+"supprimer_ligne.png' value='ligne' /></a>\n";
110 *cette fonction crée un bouton pour l'insertion d'une colonne
112 function bouton_insere_colonne(colonne
){
113 var texte
="<a href='javascript:ihm_tableau.insere_colonne("+colonne
+")'> <img ";
114 texte
+=" title='إدراج عمود قبل' ";
115 texte
+=" alt='إدراج عمود قبل' ";
116 texte
+="src='"+tableau_edit_images_path
+"inserer_colonne.gif' value='colonne'></a>\n";
120 *cette fonction crée un bouton pour la supression d'une colonne
122 function bouton_supprime_colonne(colonne
){
123 if (nc
== 1) return "";
124 var texte
="<a href='javascript:ihm_tableau.supprime_colonne("+colonne
+")'><img";
125 texte
+=" title='حذف هذا العمود'";
126 texte
+=" alt='حذف هذا العمود'";
127 texte
+=" src='"+tableau_edit_images_path
+"supprimer_ligne.png' value='colonne' /></a>\n";
131 *cette fonction met en forme les commandes pour une ligne
133 function insere_commande_ligne(ligne
){
136 texte
= this.bouton_insere_ligne(ligne
);
138 texte
+= this.bouton_supprime_ligne(ligne
);
144 *cette fonction met en forme les commandes pour une colonne
146 function insere_commande_colonne(colonne
){
149 texte
+= this.bouton_insere_colonne(colonne
);
151 texte
+= this.bouton_supprime_colonne(colonne
);
156 /*********LES CALLBACKS depuis les boutons de l'IHM ****************************************/
157 function insere_ligne(num_ligne
){
158 //création d'un tableau temporaire bidimensionnel de cellules
159 var lctemp
= new tableau_cellules(nl
+1, nc
);
161 lctemp
.insL(num_ligne
); //insertion d'une ligne dans le tableau lc
162 lc
=lctemp
.getT(); //on a une ligne en plus
165 this.construit_tableau();
168 function supprime_ligne(num_ligne
){
169 //création d'un tableau temporaire bidimensionnel de cellule
170 var lctemp
= new tableau_cellules(nl
-1, nc
);
172 lctemp
.supL(num_ligne
); //supression d'une ligne dans le tableau lc
173 lc
=lctemp
.getT(); //on a une ligne en moins
176 this.construit_tableau();
178 function insere_colonne(num_colonne
){
179 //création d'un tableau temporaire bidimensionnel de cellule
180 var lctemp
= new tableau_cellules(nl
, nc
+1);
182 lctemp
.insC(num_colonne
); //insertion d'une colonne dans le tableau lc
185 nc
++; //on a une ligne en plus
186 this.construit_tableau();
188 function supprime_colonne(num_colonne
){
189 //création d'un tableau temporaire bidimensionnel de cellules
190 var lctemp
= new tableau_cellules(nl
, nc
-1);
192 lctemp
.supC(num_colonne
); //supression d'une colonne dans le tableau lc
193 lc
=lctemp
.getT(); //on remplace le tableau lc par le tableau temp
195 nc
--; //on a une colonne en moins
196 this.construit_tableau();
201 function cellule(i
,j
){
206 /* les méthodes getters et setters */
207 this.setC = function(c
){this.c
= c
}
208 this.getC = function(){return this.c
}
209 this.setL = function(l
){this.l
= l
}
210 this.getL = function(){return this.l
}
212 /* les méthodes de la classe cellule */
213 this.insere
= insere
;
215 /* cette fonction insere une zone de texte dans la cellule */
218 var texte
="<textarea cols='10' rows='2'";
219 // on sauve le contenu
220 texte
+=" onchange='lc[" + this.l
+ "][" + this.c
+ "].content=this.value;'>";
222 texte
+="</textarea> \n";
225 } //fin de la classe "cellule"
227 function tableau_cellules(nb_l
,nb_c
){
228 this.t
= new Array();
229 for (var i
=0; i
<nb_l
; i
++){
230 this.t
[i
]=new Array();
231 for (var j
=0; j
<nb_c
; j
++){
232 this.t
[i
][j
]=new cellule(i
,j
);
236 this.getT = function(){return this.t
}
238 this.insL = function(num_ligne
) {
239 //insertion d'une ligne dans le tableau lc
240 for (var i
=0;i
<nl
+1;i
++){
241 for (var j
=0;j
<nc
;j
++){
244 this.t
[i
][j
]=lc
[i
][j
];
248 this.t
[i
][j
]=lc
[i
-1][j
];
249 this.t
[i
][j
].setL(i
);
255 this.supL = function(num_ligne
){
256 for (i
=0;i
<nl
-1;i
++){
260 this.t
[i
][j
]=lc
[i
][j
];
262 this.t
[i
][j
]=lc
[i
+1][j
];
263 this.t
[i
][j
].setL(i
);
270 this.insC = function(num_colonne
){
272 for (j
=0;j
<nc
+1;j
++){
275 this.t
[i
][j
]=lc
[i
][j
];
279 this.t
[i
][j
]=lc
[i
][j
-1];
280 this.t
[i
][j
].setC(j
);
286 this.supC = function(num_colonne
){
288 for (j
=0;j
<nc
-1;j
++){
291 this.t
[i
][j
]=lc
[i
][j
];
293 this.t
[i
][j
]=lc
[i
][j
+1];
294 this.t
[i
][j
].setC(j
);
302 function selection(zone
){
306 this.t_SPIP
= new Array(); // les lignes du tableau SPIP
307 this.t
= new Array(); // le tableau des valeurs à modifier
308 this.premiere_ligne
= "";
310 this.avec_entete
= avec_entete
;
311 this.recup_caption
= recup_caption
;
312 this.recup_summary
= recup_summary
;
313 this.compte_lignes
= compte_lignes
;
314 this.recup_ligne
= recup_ligne
;
315 this.recup_cellule
= recup_cellule
;
316 this.contenu
= contenu
;
317 this.existe
= existe
;
319 var lignes
= new Array(); // les lignes brutes de la zone d'édition SPIP
320 var ligne_cour
= ""; // la ligne brute en cours de traitement lors de la reconstitution du tableau SPIP
322 var init_i
; // début du contenu du tableau de données (1 si tableau avec entête, 0 sinon)
324 if ((clientVer
>= 4) && is_ie
&& is_win
)
326 var theSelection
= false;
328 theSelection
= top
.opener
.document
.selection
.createRange().text
; // Get text selection
330 this.s2
= theSelection
;
332 this.s1
= top
.opener
.document
.getElementById("text_area").value
;
336 var selLength
= zone
.textLength
;
337 var selStart
= zone
.selectionStart
;
338 var selEnd
= zone
.selectionEnd
;
340 if (selEnd
== 1 || selEnd
== 2) selEnd
= selLength
;
342 // Raccourcir la selection par double-clic si dernier caractere est espace
343 if (selEnd
- selStart
> 0 && (zone
.value
).substring(selEnd
-1,selEnd
) == ' ') selEnd
= selEnd
-1;
344 this.s1
= (zone
.value
).substring(0,selStart
);
345 this.s2
= (zone
.value
).substring(selStart
, selEnd
)
346 this.s3
= (zone
.value
).substring(selEnd
, selLength
);
349 lignes
= this.s2
.split("\n");
351 if (this.avec_entete()) init_i
= 1;
352 for (i
=init_i
;i
<lignes
.length
;i
++) {
353 ligne_cour
+= lignes
[i
] + "\n";
354 if (lignes
[i
].match(/\|.?$/)) {
355 ligne_cour
= ligne_cour
.replace(/\|(left|right|center)/g, "££$1"); //pour distinguer les barres verticales des codes d'inclusion d'image et de document
356 this.t_SPIP
[j
++] = ligne_cour
;
360 this.premiere_ligne
= this.t_SPIP
[0];
365 function avec_entete(){
366 return (lignes
[0].search(/^\|\|/) != -1); // si double pipe en tête de la première ligne(resumé)
368 function recup_caption(){
369 return lignes
[0].match(/^\|\|([^\|]*)/)[1];
371 function recup_summary(){
372 return lignes
[0].match(/^\|\|([^\|])*\|([^\|]*)/)[2];
374 function compte_lignes(){
375 return (this.t_SPIP
.length
);
377 function recup_ligne(num_ligne
){
378 var ligne_encodee
= this.t_SPIP
[num_ligne
].split("|");
379 var ligne_decodee
= new Array();
381 for (var i
=0; i
<ligne_encodee
.length
; i
++){
382 ligne_decodee
[i
] = ligne_encodee
[i
].replace(/££/g,"|");
384 return (ligne_decodee
);
387 for (var i
=0; i
<this.t_SPIP
.length
; i
++){
388 this.t
[i
] = this.recup_ligne(i
); //t est un tableau bidimensionnel avec les valeurs à modifier
391 function recup_cellule(i
,j
){
392 return (this.t
[i
][j
+1] ? this.t
[i
][j
+1] : "");
394 function existe() {return (this.s2
!="")} //indique si un tableau SPIP a été sélectionné
398 //nombre de lignes et nombre de colonnes
402 //création d'un tableau bidimensionnel de cellules
407 //noeud ou l'on va ecrire le tableau
411 var ihm_tableau
= new ihm();
414 ancien_tableau
= new selection(top
.opener
.zone_selection
);
416 if (ancien_tableau
.existe() & ancien_tableau
.avec_entete()) {
417 document
.getElementById("titre_t").value
= ancien_tableau
.recup_caption() ; //récupération du titre du tableau
418 document
.getElementById("resume_t").value
= ancien_tableau
.recup_summary() ;//récupération du résumé du tableau
421 nl
= (ancien_tableau
.existe()) ? ancien_tableau
.compte_lignes() : 3;
422 nc
= (ancien_tableau
.existe()) ? ancien_tableau
.t
[0].length
- 2 : 3;
425 lc
[i
]=new Array(); //2 lignes au depart
427 lc
[i
][j
]=new cellule(i
,j
);
428 if (ancien_tableau
.existe()) lc
[i
][j
].content
= ancien_tableau
.recup_cellule(i
,j
);
432 table
=document
.getElementById("table");
433 debug
=document
.getElementById("debug");
435 /*********CONStrUCTION DE L'INTERFACE UTILISATEUR**********************/
436 ihm_tableau
.construit_tableau();
438 function d(s
){debug
.innerHTML
+=s
;}
440 /****génération du code SPIP du tableau ******/
442 function construit_code_tableau(){
443 var le_titre
= document
.getElementById("titre_t").value
;
444 var le_resume
= document
.getElementById("resume_t").value
;
448 texte
+= "||" + le_titre
+ "|" + le_resume
+ "||\n";
449 for (var j
=0;j
<nc
;j
++){
450 //on supprime les accolades éventuelles avant de placer les accolades d'entete de tableau
451 var cont_cell
= lc
[0][j
].content
.replace(/(\{)*([^\}]*)(\})*/,"$2");
452 la_ligne
+= "|{{" + (cont_cell
=="" ? " " : cont_cell
) + "}}";
454 texte
+= la_ligne
+ "|\n";
457 for (j
=0;j
<nc
;j
++) {texte
+= "|" + lc
[i
][j
].content
;}
463 /**********LES FONCTIONS DE CREATION DE L'INTERFACE**********/
465 function enregistre(){
466 if (ancien_tableau
.existe()) {
467 if ((clientVer
>= 4) && is_ie
&& is_win
) {
468 top
.opener
.document
.selection
.createRange().text
= construit_code_tableau();
470 top
.opener
.zone_selection
.value
= ancien_tableau
.s1
+ construit_code_tableau() + ancien_tableau
.s3
;
472 } else { //insertion d'un nouveau tableau
473 if (top
.opener
.zone_selection
.createTextRange
&& top
.opener
.zone_selection
.caretPos
) { //IE
474 var caretPos
= top
.opener
.zone_selection
.caretPos
;
475 caretPos
.text
= caretPos
.text
+ construit_code_tableau();
476 top
.opener
.zone_selection
.focus();
478 top
.opener
.zone_selection
.value
= ancien_tableau
.s1
+ construit_code_tableau() + ancien_tableau
.s3
;