11548 sujets

JavaScript, DOM et API Web HTML5

Cela fait longtemp que je cherche des solutions d'editeur WYSIWYG js sympa, j'en ai essayé pas mal, mais la pluspart je les trouve soit trop lourds, soit buggés. Ça ne m'a pas empeché de les utiliser.

J'ai donc essayé d'en faire un, pour limiter les dégats, j'ai décidé d'utiliser uniquement la méthode execCommand compatibles sur les differents navigateurs.

Je me suis en effet rendu compte que les éditeurs DOM en plus d'être super lourd pour pouvoir s'adapter à toutes les variations entre les navigateurs, sont aussi moins fiables. Il suffit de s'essayer à l'exercice pour vite s'apercevoir que c'est un problème sans fin.

L'idée sur laquelle j'aimerais bien votre avis et la suivante :
Le problème principal (et le seul en fait Smiley biggrin ) de execCommand, c'est qu'il génere du code différent celon les navigateurs. Pour corriger cela j'hésite entre deux methodes, soit :

- faire une fonction htmlToXhtml javascript qui convertirais le document au moment de l'affichage du code et de l'envoie des donnés.

- ou plus simple, tout envoyer tel quel et corriger avec php les plus grosse abérations de execCommand, le seul problème étant que si pendant l'édition on travail avec ie et que l'on bascule sur le code source c'est pas super.

Dans tout les cas mon idée est aussi d'accompagner l' éditeur d'un troisieme onglet aide qui permettrais de bien comprendre le fonctionnement, de donner quelques notion d'html, et de conseiller un navigateur adapté.

Voilà l'exemple en ligne, n'hesitez pas à vous amuser avec, merci d'avance à tout ceux qui me signale des bugs.

matmat WYSIWYG

Vous verrez j'ai fait une petite amélioration sympa de la fonction lien, on peut maintenant les remplacer Smiley lol .
Modifié par matmat (25 Oct 2007 - 08:26)
Salut matmat Smiley smile ,

matmat a écrit :
Cela fait longtemp que je cherche des solutions d'editeur WYSIWYG js sympa, j'en ai essayé pas mal, mais la pluspart je les trouve soit trop lourds, soit buggés. Ça ne m'a pas empeché de les utiliser.

J'ai donc essayé d'en faire un, pour limiter les dégats, j'ai décidé d'utiliser uniquement la méthode execCommand compatibles sur les differents navigateurs.


Heu, ben, j'ai regardé et essayé en vitesse, jusque maintenant, c'est pas trop mal selon moi, maintenant, faudra m'expliquer en quoi cet outil permet de créer/modifier du .js de façon WYSIWYG parce que jusque maintenant, en WYSIWYG, on peut juste agir sur l'html et le css des span. Smiley rolleyes

Ou alors, c'est que je suis hors contexte là, parce que y a un stûût comme on dit en Belgique.^^

Sinon, j'ai seulement testé sur FF(version 2.0.0.8), tout à l'air de rouler à part le petit encart déroulant des couleurs qui a l'air de disparaître difficilement dès qu'on en a plus besoin.

Sinon, ben, c'est bien de vouloir faire cet outil, mais faudrait aussi m'expliquer en quoi il est réellement utile car on a pas la possibilité de mettre du css dans un fichier externe, ce qui nous oblige à utiliser uniquement les span, dommage.

Enfin, bonne initiative de ta part qui, je l'espère portera ses fruits tôt ou tard. Smiley smile

EDIT : Ou alors, peut-être parlais-tu du comportement des éléments formant ton interface faisant appel au .js quand tu parlais d'éditeur js. Si c'est ça, alors, c'est clair que j'étais vraiment à côté de la plaque. Smiley langue
Modifié par touvert (25 Oct 2007 - 11:17)
a écrit :
Sinon, j'ai seulement testé sur FF(version 2.0.0.8), tout à l'air de rouler à part le petit encart déroulant des couleurs qui a l'air de disparaître difficilement dès qu'on en a plus besoin.

à oui c'est vrai en fait il disparait que quand tu t'en sert, il faut que je trouve une idée...

a écrit :
Sinon, ben, c'est bien de vouloir faire cet outil, mais faudrait aussi m'expliquer en quoi il est réellement utile car on a pas la possibilité de mettre du css dans un fichier externe, ce qui nous oblige à utiliser uniquement les span, dommage.


Ça c'est justement tout l'interêt de la commande formatblock qui permet de changer le type de block, donc de prédefinir des styles (par le développeur) pour les titres les sous titres et les paragraphes.

effectivement ça ne sert pas à éditer les javascript, c'est juste une façon de le nommer parcequ'il est développer en js
Modifié par matmat (25 Oct 2007 - 16:22)
J'avoue que j'aime bien !
Depuis le temps que je cherche un éditeur WYSYWIG simple léger et modifiable...

On peut récupérer le source pour le modifier ?
oui, il le js est la:wysiwyg.js, 3k...
Tu peux copier le html avec voir source est il faut aussi copier le fichier testpage.html qui est l'iframe de l'éditeur voilà c'est tout Smiley biggrin .

Je viens de mettre un style prédéfini pour title (balise h3) et subtitle (balise h4) pour comprendre tout l'interet de formatblock.

Edit : Il faudrait aussi voir pour la command useCss qui à l'air pas mal, si quelqu'un connait....
Modifié par matmat (25 Oct 2007 - 17:27)
Slt matmat,

Il est nickel ton WYSYWIG, léger efficace et compréhensible!!
Depuis le temps que je me demandais comment TinyMCE et autres marchaient!

Il est possible que je m'en inspire très fortement!!


Merci bp!
+++
Il est prévu que je fasse une interface rédaction pour les novice en HTML pour qu'il puisse modifier du contenu simple, et je dois avoué qu'il est très sympa.

Il est idéal pour une interface simple pour rédiger du texte et pas lourd du tout

Par contre faudrait jouer sur le style des petit bouton, pour donner la sensation d'avoir cliquer dessus
Modifié par micky_sywater (25 Oct 2007 - 18:49)
je continue à me poser la question de la validitée du code produit par cet éditeur, surtout par Internet Explorer, en m'inspirant de different exemple j'ai commencé cette fonction :


function get_xhtml(node) {

var text = '';
var children = node.childNodes;
var child_length = children.length;
var tag_name;

   for (I=0;I<child_length;I++) {
      var child = children[I];

      switch (child.nodeType) {
         case 1: { 

            var tag_name = String(child.tagName).toLowerCase();
            text += '\n<'+tag_name;

            var attr = child.attributes;
            var attr_length = attr.length;
            var attr_value;

            var is_alt_attr = false;

            for (j=0;j<attr_length;j++) {

               var attr_name = attr[j].nodeName.toLowerCase();

               if (!attr[j].specified && (attr_name != 'style' || child.style.cssText == '')) continue;

               if (attr_name == '_moz_dirty' || 
               attr_name == '_moz_resizing' ||
               tag_name == 'br' && attr_name == 'type' &&
               child.getAttribute('type') == '_moz') continue;

               var valid_attr = true;

               if (attr_name == "style") attr_value = child.style.cssText;
               if (attr_name == "class") attr_value = child.style.cssText;
               if (attr_name == 'alt') is_alt_attr = true;
               if (attr_name == "face"){
                  var font = child.getAttribute(attr_name, 2);
                  attr_name = 'style';
                  attr_value = 'font-family:'+font;
               }

               text += ' '+attr_name+'="'+fix_attribute(attr_value)+'"';

               if (attr_name == 'alt') is_alt_attr = true;
          }

         if (tag_name == 'img' && !is_alt_attr)text += ' alt=""';
					          
         if (child.canHaveChildren || child.hasChildNodes()){
            text += '>';
            text += get_xhtml(child, lang, encoding, true, inside_pre||tag_name=='pre'?true:false);
            text += '</'+tag_name+'>\n';
	}else{
            text += ' />';
        }

	break;
        }
        case 3: { //TEXT_NODE
           text += child.nodeValue;
           break;
       }
	default:
        break;
     }
   }
   return text;
}


function fix_attribute(text) {
	return String(text).replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;");
}


qui est un début pour pouvoir convertir le html en xhtml, pensez vous que c'est une bonne idée en chassant que pour prévoir tout les cas (safari, opera...) elle serat à la fin 2 fois plus grande...

Elle est buggé pour l'instant mais c'est possible de faire quelque chose qui prévoit au moins les cas du code generé par execCommand qui est toujours le même celon les navigateurs.

Cette fonction serait placée au moment du basculement entre l'éditeur et le html et au moment de l'enregistrement.

Ou alors vaut il mieux convertir coté serveur avec tidy par exemple. Ou alors ne rien faire du tout et tant pis pour la validité...
Modifié par matmat (26 Oct 2007 - 01:57)
Bon comme je vois que je n'ai pas trop de réponses je vais poser la question plus directement :

la balise géneré par Explorer 6 ou 7 est pour la taille et la font:
<FONT face=verdana size=2 > sans guillemet et en majuscule, quel que soit le doctype.

Il est possible d'"émuler" execCommand pour faire quelque chose de plus sympa met le problème c'est qu'on se retrouve avec les même problèmes que les éditeurs connus, c'est à dire qu'au lieu imbrication sans fin de balises à chaques modifications, balise non-fermés, ou code super lourd.

Ce qui nous oblige sans rien faire à laisser notre document en doctype html

Avec un traitement posterieur on peut obtenir du xhtml transitional en mettant en minuscule et en rajoutant les guillemets (avec un code comme celui plus haut, enfin un peu different). Défault de cette solution étant que l'on traite également le code produit par l'utilisateur et c'est difficle de prévoir tout les cas.

Il casi impossible (hors de ma porté en tout cas )d'obtenir du xhtml strict à moins de se tourner vers des solutions tel que tinyMC
Modifié par matmat (26 Oct 2007 - 18:52)
Rien à voir avec ton problème, mais une petite amélioration Smiley smile
Mettre le code du onClick dans le href, de cette façon javascript:MaFonction();
Ca enlève le lien # qui a chaque fois remet en haut de page.

Sinon il manque le > de fermeture pour la balise link en entête.

Petit edit: si on veut ajouter une fonction pour sauver tout ça dans une base de donnée avec Firefox, il faut procéder de la façon suivante
function SauveModele(id_modele)
{
	var recap=document.getElementById('validation');
	//On montre et on cache la partie HTML pour que texte.value prenne bien la bonne valeur
	showHtml();
	var texte=document.getElementById('html_code');
	var requete='action=sauve_modele&id_modele='+id_modele+'&texte='+escape(texte.value);
	
	//On envoie le tout dans la base de données.
	xmlhttp.open('POST','admin_ajax.php',true);
	xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	xmlhttp.send(requete);
	xmlhttp.onreadystatechange = function()	{
		recap.innerHTML = '<img src="images/loading_16x16.gif" width="16" height="16" />Sauvegarde en cours - Merci de patienter...';
		if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
			recap.innerHTML=xmlhttp.responseText;
			showEditor();
		}
	}
}


Il faut faire apparaître le textarea contenant le code source, créer la variable qui va prendre le texte après avoir fait apparaître le textarea.
Pour plus de rapidité, il est possible de repasser en mode éditeur juste après la création de la variable.
Modifié par BruceFeuillette (30 Oct 2007 - 15:14)
C'est vrai que c'est mieux de mettre le javascript dans le href vu que de toute façon, un editeur de ce type necessite forcement javascript activé.

C'est pas mal de sauver avec ajax, peut-être que ça peut être bien d'utiliser une fonction callback pour pouvoir reutiliser le code ajax pour d'autre fonctions ou formulaires...

Sinon pour mon probléme, aprés avoir testé plusieurs editeur (la boite Hotmail, Blogger, FckEditor...) Je pense de plus en plus qu'il ne faut pas intervenir sur execCommand. En effet les essais que j'ai fait, au bout de 2 3 passages entre l'éditeur et le code html c'est n'importe quoi. Bref il vaut mieux laisser tranquille le code produit par le navigateur même si c'est du html (valide cela dit en passant) et au moment de l'enregistrement le traiter avec une fonction php qui le transformerais en xhtml transitional. (pas strict).

C'est à dire que la fonction ce contenterais de transformer <FONT SIZE=2>
en <font size="2" > . Le plus gros probléme étant Safari qui produit un code complétement stupide avec plein de class="apple-Mac"
Modifié par matmat (30 Oct 2007 - 15:55)
j'ai exactement le même prob que toi et j'ai tout modifier coté serveur...

mais il y a moyen de limiter les dégats car ff commet moins de faute.
il ne supprime que les balise auto-fermantes
un autre truc au niveau de l'execcommand... je n'arrive pas à rajouter les balises que je veux du genre <code> ...

pour moi un bon wisiwig doit etre xhtml et de ce fait...

juste les balises courrante et attribution de class.
qui elle doivent etre defini avant.

pas de font..ou taille possible ou alors pour la création d'une bouvelle classe....
execCommand ne rajoute pas n'importequelle balise, il ne rajoute que des balises prédéfinies, il faut que tu regardes du coté des fonctions "range".

Pour avoir un wyiwyg xhtml strict sans "font", tu devrais te tourner vers d'autre solutions, parcequ'avec execCommand ça vat être dur...

Je préfere execCommand parceque mème s'il ne produit pas de code valide xhtml il produit un code propre c'est a dire si tu surlignes un texte et que tu lui mets 3 de font et que tu modifies à 5 il ne vat pas recréer une balise il vat modifier la même contrairement à la plupart des machine à gaz à partir de DOM et range().

C'est vrai que Explorer produit du code html, pour ceux qui édite avec lui tant pis, si ils veulent éditer du xhtml qu'ils changent de navigateur...

Par contre ça n'empeche pas de pouvoir avoir des pages valides xhtml transitional (font et valide xhtml transitional comme les attributs size et color) et de pouvoir profiter des avantages de ce doctype, il faut pour cela corriger coté serveur par exemple avec cette classe php ça marche trés bien.
Modifié par matmat (02 Nov 2007 - 16:55)
J'ai mis à jour l'éditeur avec des nouvelles fonctions comme les images et les tableaux, avec même la possibilité de colorier les tableaux.

J'ai mit également un boutton appelé "Txt" qui permet d'inserer du texte sans copier la mise en forme depuis Word par exemple. C'est la meilleur solution que j'ai trouvé, parceque le copier/coller depuis word ça fait parfois un code asser surprenant.

Pour les images, elles seront uploader via un autre formulaire puis inseré comme l'ai actuellement l'exemple (le colibri).

Pour le nettoyage du code j'ai définitivement opter pour un solution coté serveur, parceque les solutions javascript m'ont poser trop de problémes et la classe php que j'utilise est une petite merveille. Peut-être que pour plus de flexibilité je ferrais appel a celle ci via ajax ce qui permettras également de faire des sauvegardes temporaires pendant la rédaction.

Vos commentaires sont les bienvenus Smiley biggrin
Bonjour,

Déjà, bravo pour l'initiative, le sujet n'est pas évident.

Hélas, le résultat m'a l'air assez pauvre. Autant il y a des bonnes idées et des choses très bien faites, autant ça m'a semblé plus casse-gueule encore que les éditeurs à la TinyMCE et FCKeditor au niveau du code produit.

Le gros problème c'est comme toujours avec l'édition WYSIWYG les problèmes de reliquats lors d'éditions successives. Je fais une modification, ça ne me convient pas, je «supprime» ma modification en faisant la modification inverse (sur une sélection de texte un peu différente, voir sur tout le paragraphe, forcément...), etc. Au final, j'ai un résultat complètement imbitable.

Le problème tient en partie à des restrictions techniques, et en partie à un problème structurel: certains éléments importants sur lesquels ont devrait pouvoir agir sont considérés comme du «non-contenu», donc pas sélectionnable au contraire du texte et des images.

Ici, si j'insère une image, j'insère une div (bordure noire) qui contient une image et un bout de texte en légende. Si je veux supprimer le tout, il faut d'abord supprimer le contenu, puis placer le curseur dans le cadre vide qui en résulte, et faire SUPPR ou BACKSPACE. Ben, mine de rien, c'est pas évident. Un utilisateur lambda s'attendra à pouvoir sélectionner le cadre entier en cliquant dessus, et à le supprimer d'un coup.

Même chose si je met un texte en gras: je peux supprimer du texte, tenter de lui donner une mise en forme différente (pas toujours évident), mais je ne peux pas sélectionner mon élément «mise en forme en gras» et supprimer cette mise en forme directement.
Il nous manque une petite innovation d'interface pour faire mieux que les éditeurs équivalents, sur ce plan-là.

Mais tout cela n'est pas spécifique à cet éditeur, et je suppose qu'il y a des contraintes techniques derrière.

Une petite chose tout de même avec cet éditeur: comment crée-t-on un paragraphe quand au départ on a du texte brut (une option dans la liste déroulante "style" serait un plus)? Et plus clairement: comment évite-t-on en toute circonstance d'avoir des paragraphes vides, et du texte hors de tout élément de type bloc (paragraphe, titre, ul li, etc.)?


Bravo encore pour ce travail. Pour l'instant, concernant les moyens d'édition de contenu en ligne, je reste sur ma faim.
Salut Florent,

Merci beaucoup pour ton commentaire, c'est un peu ce que j'attend depuis le début avec ce post, dans l'objectif d'essayer de produire un éditeur WYSIWYG qui produise un code propre et respectueux des standards xhtml.

a écrit :
Hélas, le résultat m'a l'air assez pauvre. Autant il y a des bonnes idées et des choses très bien faites, autant ça m'a semblé plus casse-gueule encore que les éditeurs à la TinyMCE et FCKeditor au niveau du code produit.


Il y a deux options pour insérer du code par le biais d'un éditeur : soit utiliser les fonctions range() qui permettent d'intervenir sur une selection, soit utiliser execCommand() qui automatise certaines actions.

Mais le probléme c'est qu'il y a beaucoup de différence entre entre les navigateurs pour les fonctions range(), donc si on choisie cette option le code devient vite trés lourd et il faut faire des manipulations dom qui peuvent devenir périlleuses.

Au contraire execCommand() est beaucoup plus efficace, même si il produit un code "a l'ancienne", j'ai donc choisi cette option pour plus de légéreté. Ce qui explique que le code produit n'est pas toujours super.
C'est pour cela que je met derriére un "nettoyeur" qui transforme a l'enregistrement le code en xhtml transitional, je ferais un mise à jour pour que vous compreniez comment ça marche.

a écrit :
Le gros problème c'est comme toujours avec l'édition WYSIWYG les problèmes de reliquats lors d'éditions successives. Je fais une modification, ça ne me convient pas, je «supprime» ma modification en faisant la modification inverse (sur une sélection de texte un peu différente, voir sur tout le paragraphe, forcément...), etc. Au final, j'ai un résultat complètement imbitable.

C'est malheureusement un probléme que l'on a même sur Word... c'est à dire qu'a part en touchant au code, le script ne peut pas savoir ce que veut faire l'utilisateur, surtout si il y a plusieurs styles dans une même balise. Ceci dit je trouve qu' avec execCommand, c'est pas mal, par exemple si tu mets un texte en gras et que tu l'enléves, il enléve les balises, de plus quand tu mets un texte en couleur et que tu changes de couleur il ne rajoute pas la balise mais modifie l'existante (ce que ne fait pas toujours TinyMCE).

a écrit :
Ici, si j'insère une image, j'insère une div (bordure noire) qui contient une image et un bout de texte en légende. Si je veux supprimer le tout, il faut d'abord supprimer le contenu, puis placer le curseur dans le cadre vide qui en résulte, et faire SUPPR ou BACKSPACE. Ben, mine de rien, c'est pas évident. Un utilisateur lambda s'attendra à pouvoir sélectionner le cadre entier en cliquant dessus, et à le supprimer d'un coup.

c'est vrai que ça c'est un probléme... de Firefox, en effet c'est beaucoup plus simple sur ie. Je ne crois pas que le probléme soit solvable parceque comme il n'y a pas moyen de selectionner la div, on ne peut pas agir dessus.

a écrit :
Une petite chose tout de même avec cet éditeur: comment crée-t-on un paragraphe quand au départ on a du texte brut (une option dans la liste déroulante "style" serait un plus)? Et plus clairement: comment évite-t-on en toute circonstance d'avoir des paragraphes vides, et du texte hors de tout élément de type bloc (paragraphe, titre, ul li, etc.)?


Tu as raison je vais remettre le paragraphe, je l'ai enlevé pour d'obscures raisons. Par contre pour éviter les paragraphes vides, ça vat être dur, je crois que le seul moyen c'est de leur mettre des marges relativement importantes ainsi quand l'utilsateur efface le texte, il est obligé de les effacer.

a écrit :
Bravo encore pour ce travail. Pour l'instant, concernant les moyens d'édition de contenu en ligne, je reste sur ma faim.

Moi aussi je reste un peu sur ma faim, parcequ'en fait c'est vraiment trés difficile d'obtenir un résultat ne serait-ce que "correct" (donc perfectionistes s'abstenir). En fin de compte ce n'est qu'une serie de compromis.
Le pire je crois ce sont les copier/coller depuis word sur Explorer, là c'est carrement déprimant, et ça donne envie de revenir au bbcode ou une sintaxe dans le style.

Je suis en train de l'essayer en production sur ce site. Pour l'instant ça l'air de pas trop mal ce passer (regardes les tableaux il y en a pas mal dans le site, le résultat est correct). Ce qui est sûr c'est qu'il faut quand même informer un minimum les auteurs pour éviter les gros problémes.
Modifié par matmat (26 Nov 2007 - 22:01)