a oui tu a raison avec la méthode de loralina j'ai perdu la possibilité d'enlever le shadow je ne m'en était pas rendu compte
je vais remettre ma version string pour voir et je reviens
Version imprimable
a oui tu a raison avec la méthode de loralina j'ai perdu la possibilité d'enlever le shadow je ne m'en était pas rendu compte
je vais remettre ma version string pour voir et je reviens
et voila j'ai remis va version string dans le wysiwyg
mon resultat est nikel je peut enlever remettre a volonté comme les moules frittes chez nous
Pièce jointe 250263
mais ton idée de SPAN N EST PAS SI MAL EN FAIT CA PERMETTRAIT DE S ATTAQUER DIRECTEMENT ET RIEN QU EUX POUR LA FONCTION SHADOW
ce qui me gène c'est d'avoir des font et span dans le même code c'est pas déontologique non???
J'ai testé vos deux fonctions et finalement (apparemment) les deux marchent chez moi (j'utilise Chrome)...
Sauf dans certains cas, peux-tu vérifier ce cas par exemple :
- tu as trois mots et tu leurs mets un shadow de couleur verte...
- Tu mets ces trois mots en italique ou gras ou souligné...
- Peux-tu alors par exemple juste supprimer le shadow du deuxième mot sans toucher aux deux autres mots ? C'est-à-dire le premier et le deuxième mot reste avec un shadow de couleur verte...
Chez-moi cela ne fonctionne pas, je pense que la raison est que pour l'italique, le gras, souligné... la fonction execCommand n'utilise pas la balise <font> mais <i>,<b>...
Perso je ne vois pas pourquoi il y aurait un problème à utiliser plusieurs balises différentes sauf peut-être pour gagner quelques octets ?
re
oulala!!!!
bonjour a tous
aie!!aie!!
en effet j'ai résolu le soucis de la sélection complète puis le xeme mots comme beguinner le voyait mais du coup je me suis intéressé au parent "P"
et la effectivement ca déraille tout du moins il reste des balises vides je n'avais pas vu ca
démonstration et résultat dans la console
Pièce jointe 250382
Bonjour beguinner
et a tous
voila un model avec les span
et toujours pareille la balise est bien netoyée mais le dom laisse les phantome dans le P parent
j'ai tenté un remplacement innerhtml de p par le innerHTMl de la balise crée au cas ou les deux aurait le même innerText mais ca marche pas
c'est vraiment un truc tordu ce machin
je pete les plombs avec ce truc ce dom a la con!!Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 function shadowcolor(coul, MOD) { if (selectionne_text()) { var selection = selectionne_text(); var selectedText = selection.extractContents(); var BB = document.createElement("SPAN"); BB.appendChild(selectedText); var str = BB.innerHTML; var colhtml = BB.getElementsByTagName("SPAN"); if (colhtml.length > 0) { for (var i = 0; i < colhtml.length; i++) { str = str.replace(colhtml[i].outerHTML, colhtml[i].innerHTML); } } console.log(str); BB.innerHTML = str; if (MOD == true) { BB.style.textShadow = "0px 0px 10px " + coul; } selection.insertNode(BB); console.log(BB.outerHTML); var obj = BB.parentElement; do { if (obj.tagName=="SPAN" && MOD == false) { BB.style.textShadow = "none";} obj = obj.parentElement; } while (obj.tagName == "P"); if (BB.parentElement.tagName == "P" && MOD == false && BB.parentElement.firstChild==BB ) { BB.removeAttribute("style"); } if (BB.parentElement.tagName == "P" && BB.parentElement.innerText==BB.innerText ) { BB.parentElement.innerHTML=BB.outerHTML; } } console.log(document.getElementById("editeur").innerHTML); }
Oui moi aussi j'avais fait une version avec la balise <span> :
C'est plus court mais effectivement cela ne résout pas le problème que tu évoques ni ceux que j'ai évoqués... Mais bon ce n'était pas le but, le but c'était plutôt de faire un truc plus concis et plus simple et peut-être plus polyvalent...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 function shadowcolorBis(coul, MOD) { var selection = selectionne_text(); if (selection) { var selectedText = selection.extractContents(); var baliseShadow = document.createElement("span"); baliseShadow.appendChild(selectedText); var colhtml = baliseShadow.getElementsByTagName("span"); var ob_, ob_2, ob_3; var colhtml = baliseShadow.getElementsByClassName("shado"); var i = colhtml.length; while (--i >= 0) { colhtml[i].outerHTML = colhtml[i].innerHTML; } if (MOD == true) { baliseShadow.className = "shado"; baliseShadow.style.textShadow = "0px 0px 10px " + coul; } selection.insertNode(baliseShadow); if (baliseShadow.parentElement.className == "shado" && MOD == false && baliseShadow.parentElement.tagName != "P") { baliseShadow.className = "shado"; baliseShadow.style.textShadow = "none"; } } }
Maintenant il faut résoudre ces problèmes et d'ailleurs as-tu essayer de faire ce que je t'avais dis :
Cela permettrait de savoir si le problème vient de moi ou non...
re oui j avais testé ca vient pas des autres balises mais du fait que je veux les deux sens
faire/défaire en changeant ou défaire en supprimant
visiblement j'ai 3 versions qui ont le même problème a la fin je ne peut pas avoir les 3 en un
je te fait une démo en rentrant ce soir
oui je sais insert HTML ne marche pas tu pense bien que j'ai visité toutes les commandes de execCommand
Ok donc cela ne vient pas de chez moi...
Sinon oui ce que tu veux faire c'est finalement un "removeFormat" (qui existe déjà avec execCommand) sauf que toi (contrairement à ce que fait execCommand) tu ne veux pas supprimer tout le formatage mais seulement un formatage spécifique, dans ton cas c'est le shadow mais cela pourrait être n'importe quoi d'autres comme le gras, l'italique, la taille, la police...
J'avais commencé à essayer de faire cela plusieurs fois sans avoir été jusqu'au bout, cela m'intéresserait aussi de trouver une solution... D'ailleurs voici le fil : Comment supprimer la mise en forme (formatage) ? dans lequel j'avais aussi posé cette question :
Il y a la réponse de Watilin à étudier, je pense qu'il doit y avoir des astuces à utiliser...Citation:
Peut-être plus difficile : comment supprimer une partie du formatage : genre par exemple je supprime la couleur mais je laisse le gras...
:arrow: Je sais déjà que pour supprimer seulement certains formatages comme le bold ou l'italic ou l'underline... Il suffit de lancer la même commande.
A suivre...
Bonjour,
j'ai qu'en même l'impression, en lisant rapidement cette discussion, que tu tires dans tout les sens sans structurer ton travail, tu « pixelises » les tâches sans en avoir une vue d'ensemble.
Concernant ta balise <font> elle est avantageusement remplaçable par une balise <span> comme te l'a fait remarquer Beginner..
Pourquoi gérer des « class » et des « style inline » et ne pas utiliser QUE des « style inline » que tu peux modifier en fonction de tes besoins ?
si mon travil est structurer seulement contrainte que IE et otut ne fonctionne pas
j'ai un wysywyg qui a toutes les fonctions textes qui fonctionnent sauf pour shadow tout du moins pas entièrement entièrement
mon but car visiblement personne n'a compris
c'est que cette fonction se comporte comme le fait execcommand pour le size,backcolor,face
c'est a dire quelle mettre la propriété et quelle face le ménage
jusque la j'ai 3 model de fonctions plus ou moins conventionnelle qui fonctionnent même tres bien
sauf que!!!!!! préoccupé par ce qui se passe dans la balise créée que ce soit span ou font
je n'avais pas passé le console.log au parent P c'est a dire la ligne complète ou se trouve la sélection puis la balise créé
et je me suis rendu compte que rien qu'en faisant in insertnode les balise étaient doublées mais vides ( va savoir pour quoi) et c'est bien le Dom qui fait ca j'ai essayé sur un fichier simple sans propriété de quoi que ce soit et c'est sur ce point que je cale car j'ai essayé plein de chose qui me paraissent logique
entre autre le element(p).removeChild(balise vide) qui est plus que simple en apparence sauf que ça fait pas le boulot
en effet
je pare au debut avec : je vais mettre des ID pour bien mettre le doigt sur le soucis
je sélectionne le texte "ne me comprend pas" et je met une ombreCode:<font id=1 >Nosmoking</font> <font id=2><strong>ne me</strong></font><font id=3> comprend pas </font>
ma fonction me retourne ma font shadow comme suit après nettoyage interne
waouhh!!! c'est parfait me diras tu oui mais voila le genre de chose que je vois quand on regarde le code html de la ligne complèteCode:<font style="text-shadow:0px 0px 10px #xxxxxx;"> <strong>ne me </strong>comprend pas</font>
alors que je ne fait aucun déplacement je supprime le outerhtml et le remplace par innerhtmlCode:<font id=1 ></font> <font id=2><strong></strong></font><font id=3><font id=1 >nosmoking</font><font style="text-shadow:0px 0px 10px #xxxxxx;"><strong>ne me </strong>comprend pas</font>
ca c'est une enigme pour moi
comment le dom fait pour dire que en faisant insertnode(une balise)je vais doubler les balise et les laisser en amont ou en aval selon le range sélectionne
voila juste la partie qu'il me reste a nettoyer
je ne sais pas si je me suis fait comprendre
ca fait une semaine que je suis dessus
a chaque fois que j'ai quelque chose qui fonctionne c'est ailleurs que ça va plus pourquoi le dom fait ca je lui ai rien demandé moi ;)
d'autant plus que c'est totalement absurde et illogique
qu'il ferme et fasse l'ouverture des balise restantes de droite et de gauche je peut comprendre mais doubler non!!! je comprends pas
voila mon soucis depuis 3 jours
voila la version en span pour la mise en place du shadow-text et nettoyage interne rien a dire c'est parfait le résultat meme si ma méthode vous paraîtrait un peu bûcheronne
c'est la partie netoyageamontaval qui déraille et me retourne des "notfounderror" etc... alors qu’après Control point par point les balises sont bien la
je parle des balises fantôme bien sur pas de la balise avec le shadow ,celle la c'est bon on la touche plus
voilaCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 function shadowcolor(coul, MOD) { if (selectionne_text()) { var selection = selectionne_text(); var selectedText = selection.extractContents(); var BB = document.createElement("SPAN"); BB.appendChild(selectedText); var str = BB.innerHTML; var colhtml = BB.getElementsByTagName("SPAN"); if (colhtml.length > 0) { for (var i = 0; i < colhtml.length; i++) { str = str.replace(colhtml[i].outerHTML, colhtml[i].innerHTML); } } console.log(str); BB.innerHTML = str; if (MOD == true) { BB.style.textShadow = "0px 0px 10px " + coul; } selection.insertNode(BB); // voila c'est bon on a le shadow et propre var obj = BB; //alert(obj.parentElement.tagName); // ici pour la suppression de shadow on le met a ""none"" si elle se trouve dans un fontparent shadow if (obj.parentElement.tagName != "P") { do { obj = obj.parentElement; if (obj.tagName == "SPAN" && MOD == false) { BB.style.textShadow = "none"; } } while (obj.tagName != "P"); } ////////////////////netoyageamontaval////////////////////// if (obj.tagName == "P") { var elements = obj.getElementsByTagName("*"); if (elements.length == 1) { nb = 0; } else { nb = elements.length - 1; } if (elements.length != 0) { for (var i = 0; i < nb; i++) { if (elements[i] != BB && elements[i].tagName != "IMG" && elements[i].innerHTML == "") { console.log(elements[i]); obj.removeChild(elements[i]); } } } } } console.log(document.getElementById("editeur").innerHTML); //on regarde le code entier de l'editeur pour le moment il y qu'un P }
ca me rends chèvre depuis hier ce truc
bon j'ai enfin compris comment et pourquoi le dom faisait ca
en fait en mettant un alert juste apres le balise.appendChild(selectedtext) on se rent compte que la sélection disparaît de la ligne
donc le dom fait le replace(fermeture balise en amont fermeture balise en aval) a ce moment la dans la ligne sur le document mais sans la sélection
alors forcement quand je fait un insertnode(balise new)c'est son outerHTML que j'insert
bon ben voila reste a découvrir pour quoi le replace fantome ne fonctionne pas tout du moins en html et mode console
car ca aussi c'est un truc que je pige pas
lafichier html tout seul fonctionne bien mais doit certainement pas faire le nettoyage mais ne me bloque pas pour l'erreur
par contre quand je suis en mode affichage console (F12) la oui il déclenche l'erreur et bloque
Oui c'est bien ce que j'avais compris, je m'étais penché dessus aussi et je mettais aussi rendu compte que la méthode execCommand fonctionne trés bien pour le formatage de base et même le déformatage pour les balises classiques fonctionne très bien...
Mais comme elle ne fait pas tout j'ai voulu comprendre comment elle fonctionne pour pouvoir en faire une autre à laquelle j'aurais ajouté les fonctionnalités manquantes... J'ai même trouvé un code (celui de Ckeditor) mais trop difficile à comprendre...
Mise à part ça cela fonctionne correctement (coté rendu visuel obtiens-tu ce qu'il faut) ? C'est-à-dire as-tu résolu le problème de la suppression du Shadow dans les cas que nous avons évoqués ? Est-ce que maintenant cela fonctionne si tu fais cela :
Si cela marche cela fera un problème en moins...Citation:
- tu as trois mots et tu leurs mets un shadow de couleur verte...
- Tu mets ces trois mots en italique ou gras ou souligné...
- Peux-tu alors par exemple juste supprimer le shadow du deuxième mot sans toucher aux deux autres mots ? C'est-à-dire le premier et le deuxième mot reste avec un shadow de couleur verte et conservent aussi l'italique, le gras, le souligné...
oui ce soucis est resolu
en fait le soucis était du coté du none ou rien
pour cela il fallait non seulement tester le parent mais boucler jusque au "p"
et tester si il y a shadow car le span pouvait etre un subsubsub enfant
donc je peut mettre/changer ou supprimer au milieu d'une phrase
avec celle la
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 function shadowcolor(coul, MOD) { if (selectionne_text()) { var selection = selectionne_text(); var selectedText = selection.extractContents(); var BB = document.createElement("SPAN"); BB.appendChild(selectedText); var str = BB.innerHTML; var colhtml = BB.getElementsByTagName("SPAN"); if (colhtml.length > 0) { for (var i = 0; i < colhtml.length; i++) { str = str.replace(colhtml[i].outerHTML, colhtml[i].innerHTML); } } console.log(str); BB.innerHTML = str; if (MOD == true) { BB.style.textShadow = "0px 0px 10px " + coul;} selection.insertNode(BB); var obj=BB; alert(obj.parentElement.tagName); if (obj.parentElement.tagName!="P"){ do{ obj=obj.parentElement; if (obj.tagName=="SPAN" && MOD==false){BB.style.textShadow="none";} }while(obj.tagName!="P"); } if(obj.tagName=="P"){ var elements=obj.getElementsByTagName("*"); if(elements.length!=0){ for (var i=0;i<elements.length;i++){ var elements=obj.getElementsByTagName("*"); if (elements[i]!=BB && elements[i].tagName!="IMG" && elements[i].innerText==""){ obj.removeChild(elements[0]); } } } } } console.log(document.getElementById("editeur").innerHTML); }
Ah oui effectivement, j'y pensais justement... Alors en bouclant jusqu'à "p" je crois, mais je n'ai pas testé, que cela limite le shadow à un paragraphe donné, tu ne pourras peut-être pas faire du shadow sur un texte à cheval sur deux paragraphes... Mais bon cela peut être un choix sinon il suffirait je pense de remonter jusqu'à la div de l'éditeur...
Donc ça va tu t'es bien débrouillé finalement...
Tu vois que finalement l'usage de la balise span aide bien, c'est ce qui te permet entres autres de faire ce test : if (obj.tagName == "SPAN" && MOD == false), avec la balise font qui sert à d'autres choses cela aurait été plus compliqué... Sinon on peut aussi utiliser la class (ce serait même nécessaire si il y avait d'autres span utilisésr pour autre chose)...
re
même mieux regarde on est pas loin du résultat même sur plusieurs paragraphe
Pièce jointe 250998
je ne doute pas que dans l'ensemble c'est vrai mais je parlais de cette fonction pour laquelle il ne semble pas que tu ais envisagé ce qui peux se produire et le type de code qui peut être généré.Citation:
si mon travil est structurer ...
Exemple après plusieurs manipulations tu peux obtenir par exemple (simulation)
et il doit y avoir bien pire :calim2:Code:Nos<span style="text-shadow: 0px 0px 10px red;">m<span style="text-shadow: none;">okin</span>g<strong> n<span style="text-shadow: none;">e m</span>e</strong> com</span>prend pas
Il faut bien te rendre compte qu'il te faut faire le ménage,
et cela n'est surement pas exhaustif.
- en partant du noeud, remonter l'arbre et tester le style pour épurer si c'est le même que le parent.
- supprimer les <span> sans aucun attribut ou attribut perso
- supprimer les éléments restant vides
- ...
Watilin a bien décrit les outils que tu as à disposition pour triturer le DOM, voir lien mis par Beginner..
non il n'y a pas pire seule les erreur de none...none se sont avéré a l’intérieur je parle :le soucis pour moi c'est ce qui est a l’extérieur qui me gène
au pire a l’intérieur je rajoute avec le test mod=false le parent=span et shadow none
car pour l'instant je teste juste la presence de parent span donc parent direct ou pas en shadow c'est ca l'erreur des none/none/none
mais je crois avoir trouvé ma solution pour ne pas avoir a faire le ménage a l’extérieur car j'ai compris pour quoi
ma fonction sort le range de la ligne quand je appendChild a la newbalise et donc le dom restructure en fermant et remise de l'ouverture des balises non fermées
c'est bien ca j'ai testé
dans mon future model j'ai réussi a ne pas sortir la sélection il n'y a donc pas de reconstruction de la part du DOM c'est badaze qui m'a mis sur la voix même si son exemple ne me correspond pas
il fallait simplement trouver le moyen de récupérer le code HTML correspondant a la sélection sans faire un apendChild de la selection sur la new balise
et j'ai trouvé comment faire
je potasse encore
Je continue ici car en fait le sujet du fil : voir le code html correspondant à la sélection de texte est résolu...
Peut-être qu'on pourrait procéder en deux étapes séparer pour le moment :
1- Concevoir une fonction qui élargie les fonctionnalités de exeCommand et ce en se basant sur la fonction exeCommand elle-même et l'astuce dont on a parlé...
2- Concevoir une fonction qui supprime un formatage spécifique proprement et de manière optimisée (sans multiplication de balises)...
oui je veux bien mais quand tu vois ci dessous dans le alert que le style shadow des font est toujours la c'est a ce demander si c'est pas fait pour me rendre dingue ce machin
pour être honnête avec toi 3 semaines pour essayer de faire ce que je fait en VB VBA VBS en moins de 15 lignes je pense que c'est suffisant pour admettre l’énormité du carnage que l'on a fait sur sur ce language soit disant pour qu'il puisse communiquer avec d'autre language
je me souvient il y a quelque années m'y etre arrêté et avoir constater des possibilités tout ce que je vois aujourd'hui c'est une grosse M..... dans le quel il faut pédaler
pour faire quelque chose q'un langage comme vb fait les doigts dans le nez
allez le debut de la fonction
j'ai supprimer les "if" je remove carrément l'atrribut "style pour supprimer toute ambiguïté d'interprétation
regarde le alert
}Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 function backcol(coul,MOD){var ranges =window.getSelection(); var mySelectionhtml =ranges.getRangeAt(0).cloneContents(); var parent=ranges.getRangeAt(0).commonAncestorContainer; var newNode = document.createElement("FONT"); newNode.appendChild(mySelectionhtml); var str=newNode.innerHTML; var f=newNode.getElementsByTagName("FONT"); for(var i=0;i<f.length;i++){ f[i].removeAttribute("style"); if( !f[i].hasAttributes()){str=str.replace(f[i].outerHTML,f[i].innerHTML);} } newNode.innerHTML=str; if(MOD==true){newNode.style.textShadow ="0px 0px 10px "+coul;} alert("newNode= " +newNode.innerHTML);
c'est un vrai calver
c'est tellement absurde que je n'ai plus rien en ressource pour voir ou entrevoir une possibilité quelconque
je n'y comprends plus rien
je crois sincèrement que mon wysiwyg va rester en VB
Oui je pense que c'est faisable en JS... D'ailleurs cela a déjà été fait, j'avais vu ce plugin : http://ckeditor.com/addon/removeformat pour ckeditor, il y a le source mais comme je disais cela ne me parait pas évident à comprendre (ils utilisent leur librairie...). Dommage car elle a l'air bien...
Je vais regarder ton code...
oui j'en ai décortiqué quelque un de richtext Editor aucun ne fait ca en pure javascript
perso je suis perdu je me tate d’abandonner la conversion vb/js de mon wysiwyg
ça répond jamais pareil et autre bizarrerie dont je n'est trouvé explication nulle part
j'ai passer beaucoup trop de temps sur cette fonction pour un résultat néant CA vaut pas le coup
et surtout j'ai pas envie d’écrire un roman a chaque fonction
je vais te suivre dans tes expériences car pourquoi pas garder un peu d'espoir mais pour moi le wysiwyg restera VB il fonctionne encore très bien après tout
J’ai envie d’éclaircir un point, je ne sais pas si ça a été abordé dans ce fil : les méthodes range.extractContents et range.cloneContents renvoient des DocumentFragment. Ce ne sont pas exactement des nœuds, disons plutôt des « points d’insertion » auquels on peut ajouter autant de nœuds qu’on veut.
Par exemple, si tu as d’une part un fragment contenant un <font>, un nœud texte, puis un autre <font>, et d’autre part une <div> servant de conteneur, au moment où tu vas ajouter le fragment à la <div>C’est comme si tu faisaisCode:div.appendChild(fragment);
Autrement dit, les enfants du fragment sont ajoutés à la place du fragment.Code:
1
2
3 div.appendChild(font1); div.appendChild(texte); div.appendChild(font2);
Ainsi, on peut voir les fragments comme des conteneurs transparents.
Voilà, j’espère que ça peut aider… ;)
Bonjour,
Je n'ai pas suivi la suite de la conversation, mais par rapport à ceci :
Je suis assez d'accord avec le fait d'avoir un seul attribut.
J'avais développé un éditeur avec "span" et "class" pour la partie texte : pas d'attribut "style" ou autre, pas de "execCommand", tout avec les noeuds.
J'avais une classe pour chaque valeur (si je veux affiner une teinte par la suite, il suffit de changer la valeur dans la classe, tous les enregistrements en base en profiteront).
L'objectif n'était pas forcément de rechercher le code html le plus optimisé possible, mais d'avoir une syntaxe simple pour faire une vérification complète niveau serveur.
Rien n'empêche ultérieurement de faire un traitement d'optimisation du html par la suite (si nécessaire, car en réalité, peu d'utilisateurs vont s'amuser à changer les couleurs ou autre à répétition, donc le code html reste léger).
Comme point de départ, je pense qu'il faut d'abord bien définir la syntaxe à obtenir.
Si on a ceci : <couleur1>texte1 texte2 text3</couleur1>
Si on veut annuler la couleur sur "texte2", que veut-on obtenir ?
ceci : <couleur1>texte1 </couleur1>texte2<couleur1> text3</couleur1>
ou ceci : <couleur1>texte1 <couleurDefaut>texte2</couleurDefaut> text3</couleur1>
Et si on en change la couleur ?
ceci : <couleur1>texte1 </couleur1><couleur2>texte2</couleur2><couleur1> text3</couleur1>
ou ceci : <couleur1>texte1 <couleur2>texte2</couleur2> text3</couleur1>
Dans les deux cas, j'étais partie sur la deuxième possibilité (mais sans me renseigner sur la bonne pratique, j'ai juste pris ce qui me semblait le plus simple à coder).
En tout cas, si on commence à mélanger la manipulation sur les noeuds avec une autre sur les chaînes avec du "execCommand" avec plusieurs types de balises avec plusieurs attributs et tout en recherchant une compatibilité multi-navigateur, cela peut devenir vite très complexe.
bonsoir Watilin
oui extractcontent était la méthode que j'avais adopté au debut
mais le soucis l'ors de l insertionnode dans le ranges ca me pourrissait le code des calques vides de ses mêmes nœuds
j'ai découvert en affichant le code html a chaque action que quand je deletais le range je me retrouvais avec un code hyper propre sans la selection
je me suis dis banco !!!
donc plutôt que extract j'ai opté pour clone qui ne supprime pas la sélection au depart
ce qui m'a permis grace a beguinner de capter ce qu'il restait a gauche et pourvoir ainsi identifier le dernier font contenant éventuellement le reste qui aurais été tronqué après délétion du range
ca c'est parfait
j'ai donc
une variable élément font contenant la sélection dans la quelle j'arrive a virer tout ce que je désire virer et remodeler
ca c'est parfait aussi
comme j'ai identifier la balise a gauche de la sélection et qu'elle se referme toute seul et qu'elle garde ses propriété du départ il ne me reste plus qu'a faire un insertbefore(cette dite balise.nexsibling)
ça ca marche mais déjà on retrouve des spectres de l'ancien code alors que le range a été complètement délété
chose qui pour moi sort de ma compréhension
c'est comme si je jetais quelque choses a la poubelle et que le temps de me retourner cette même chose se retrouvait dans mon plaquard
bon dans le fond rien ne m’empêche de faire un nettoyage
mais le soucis c'est que si la sélection contient une balise entière la partie gauche est "undefined"
je me suis alors dis ok si la sélection ne laisse pas d’orphelins je fait un range insert(newbalise) cette balise contenant le nouveau code )
et oui mais problème j'ai délété le range
je ferais un départ au propre demain en fin d’après midi pour démontrer ce que je dis
jusqu’à samedi beaucoup de boulot
et puis ca me permet d'y voir plus clair de m’éloigner de ce problème j’étais trop dessus et partais dans tout les sens
mais les résultats sont quand même assez déconcertants
bonsoir loralina
qu'importe pour moi le style de balise mon soucis c'est le foutoir dans le code html que cela fait
@watilin
le contenu du div edirable dans mo wysiwyg est destiné au mail qui sera transporté par CDO je me vois mal faire un style pour chaque couleur ,chaque shado,etc.....
et seulement attribuer une class car il faudrait que j'envoie la balises style avec le code du div et d'apres mes constat le mime du code html du mail le restitue très mal
et puis c'est impensable cela ferait une sacré feuille de style
je posterais un code de départ demain la ce soir trop crevé
Le deuxième est plus simple mais l'inconvénient c'est qu'on se retrouve avec une balise en plus et ce à chaque fois qu'on voudra annuler la couleur...
Il me semble que execCommand fait le premier...
Cette fois c'est le deuxième qui est plus économique mais son inconvénient c'est qu'il est plus difficile à gérer, on se retrouve avec des balises imbriquées ce qui implique par exemple que si on veut annuler la couleur du text2 il faudra gérer couleur2 et couleur1...
Sauf si pour l'annulation on utilise la deuxième méthode (utiliser "couleurDefaut") de la première question car dans ce cas il suffirait de remplacer couleur2 par couleurDefaut...
Là aussi il me semble que execCommand fait le premier...
Bonjour,
J'ai testé l'exemple https://developer.mozilla.org/fr/doc...ing_in_Mozilla :
Il n'y a pas réellement de couleur par défaut, mais, pour le changement de couleur, j'obtiens ma version 2, sur Internet Explorer et Firefox :
Ensuite, si je mets une couleur sur "te2 tex" :Code:<font color="red">texte1 <font color="black">texte2</font> texte3</font>
Internet Explorer :
Firefox :Code:<font color="red">texte1 <font color="black">tex</font><font color="blue">te2 tex</font>te3</font>
Si je teste mon éditeur, j'ai le même que cet exemple sur Firefox (mais avec "span" et "class"), donc pas le plus optimisé, l'important pour moi étant d'avoir le même code sur les différents navigateurs.Code:<font color="red">texte1 <font color="black">tex<font color="blue">te2</font></font><font color="blue"> tex</font>te3</font>
Si je sélectionne tout et que je mets en "vert", c'est nettoyé comme ceci : <vert>texte1 texte2 texte3</vert>
Après, il ne doit pas y avoir grand chose à faire pour optimiser un peu plus, je le ferai peut-être à l'occasion. :)
Je m'étais dit qu'annuler la couleur, c'était pareil qu'en changer, j'avais préféré uniformiser pour plus de simplicité.Citation:
Le deuxième est plus simple mais l'inconvénient c'est qu'on se retrouve avec une balise en plus et ce à chaque fois qu'on voudra annuler la couleur...
Il est possible qu'une méthode (ou le rendu html) soit plus simple sur un exemple, mais moins sur un autre.
A considérer aussi ce genre d'exemple :
Pour annuler l'italique sur "texte2", avec l'exemple utilisant "execCommand" :Code:<i><font size="4">texte1 texte2</font> texte3</i>
Internet Explorer :
Firefox :Code:<font size="4"><em>texte1 </em>texte2</font><em> texte3</em>
Comme quoi, plusieurs approches sont possibles, mais si on veut tout vérifier sur le serveur et être compatible avec plusieurs navigateurs, "execCommand" n'est pas forcément le plus simple, surtout si on n'arrive pas à gérer la totalité de l'édition avec.Code:<i><font size="4">texte1 </font></i><font size="4">texte2</font><i> texte3</i>
Bonjour loralina
j'ai tester ton lien effectivement il fonctionne mais il n’apporte rien que le mien n'ai déjà
tout ce qui est color,size,bold,italic,underline,strike,itre(H),liste ordonnées ,liste non ordonnée ,etc... fonctionne parfaitement bien
d’ailleurs pour les liste la mienne est mieux car avec execcomand il faut sélectionner tandis que moi je peut cliquer le bouton pour commencer une liste
non le soucis c'est des que l'on touche au propriétés par le style css visiblement l'auto complétion par le dom déraille
dans le sens ou j'ai des balises inutiles dans le code html par contre le résultat visuel lui est bien
pour reprendre votre exemple avec color
apres le foutoir que foutoir que fait le dom avec insertnode dans in range
comme le delete range me nettoie le code je vois pas pourquoi m'en priver
exemple si j'ai
et que je selectionne "a tous" pour le mettre en vert et delete le rangeCitation:
<font style="text-shadow:0px 0px 10px red>bonjour a tous </font>
j'obtiens
le reste de la balise qui n'a pas été selectionner est automatiquement refermée et garde ses propriétésCitation:
<font style="text-shadow:0px 0px 10px red>bonjour </font>
il ne reste plus qu'a mettre la balise créé dynamique ment a la suite
comme suit
[QUOTE][QUOTE]<font style="text-shadow:0px 0px 10px red>bonjour a tous </font><font style="text-shadow:0px 0px 10px green> a tous </font>
manque de pot le delete range visiblement ne surprime pas les ranges puisque je les retrouve a la fin et vides ou dans la font originale vides aussi
voila mon soucis depuis 3 semaines
je ne suis pas le premier a le constater, j'ai trouvé divers sources qui en ont parlé mais a ce jour personne n'a de solutions
re
demo avec résultat dans message a chaque etape j'ai le mot "texte " en shadow red sur "te" et "xte" en blue" mais "xt" est en italic et le tout en bold je met "exte" en shadow vert
on se rends bien compte que des que dans la sélection il y a au moins 2 font le dom déraille et c'est pareille avec les span j'ai testé
Pièce jointe 252924
Salut,
Je pense que Loralina a donné le lien juste pour pouvoir faire des tests et c'est vrai que c'est pratique... En plus cela nous fait un moyen commun pour que chacun puisse tester ce que l'un de nous aura fait...
Il se trouve que je l'utilise moi-même (encore une fois juste pour faire des tests)...
J'ai commencé à comprendre pourquoi ça déconne et en fait ça ne déconne pas vraiment, c'est juste que cela suit une certaine logique...
Oui c'est le cas pour toutes les balises qui ne sont pas entièrement dans la sélection... Pour la suite je vais raisonner par rapport à l'extrémité gauche de la sélection... Mais c'est le même principe pour l'extrémité droite de la sélection.
Ainsi chaque balise dont seule une partie est dans la sélection sera refermée, ce qui est nécessaire pour garder le formatage à gauche de la sélection... Maintenant ce qu'il faut savoir c'est que chaque balise fermée est ré-ouverte à l'intérieure de la sélection, là aussi c'est nécessaire pour garder le formatage de la partie du texte qui est à l'intérieur de la sélection...
Alors dés que tu fais une insertion tu retrouves ces balises ré-ouvertes et donc on se retrouve avec ces balises multipliés par deux...
Je pense que c'est difficile à comprendre sans exemple alors prenons en un :
before - this is <b><i>some text [to show the</i></b> problem] - after Le rendu visuel est :
"before - this is some text [to show the problem] - after".
Si on sélectionne "[to show the problem]" et qu'on prend avec les ranges le html de la sélection (rangeM) celui à gauche (rangeG) et celui à droite (rangeD) on a :
rangeG :
before - this is <b><i>some text </i></b>
rangeM :
<b><i>[to show the</i></b> problem]
rangeD :
- after
Quand on insert rangeM on obtient rangeG + rangeM + rangeD :
before - this is <b><i>some text </i></b><b><i>[to show the</i></b> problem] - after
On voit bien que les balises fermées dans rangeG sont ré-ouvertes juste après dans rangeM ce qui fait que, après insertion on se retrouve avec ces balises multipliés par deux (2x<b> et 2x<i>).
Si par exemple avant l'insertion on supprime l'italique de la sélection on se retrouve avec :
before - this is <b><i>some text </i></b><b>[to show the</b> problem] - after
Ca marche mais on aurait aimé avoir :
before - this is <b><i>some text </i>[to show the</b> problem] - after
:arrow: Ce serait donc un moyen assez simple de supprimer un formatage spécifique si la multiplication des balises ne gêne pas...
re
bonsoir beguinner
voila la seule fonction que j'ai pu monter avec divers recherches elle fonctionne nikel
cela pourrait t’intéresser (comment on obtiens le start et le end
tu vera aussi que l'elelement créé est différent
reste toujours ce soucis de doubles et fantôme
je n'arrive pas a nettoyer aussi dans le le newNode
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=10"> <style type="text/css"> <!-- .editor { font-family: tahoma } .actionbar { background-color: #c0c0c0; border: 1px solid black } .comment { border: 2px dotted red } --> </style> <script> function replaceSelection(coul) { var sel, range, fragment; sel = window.getSelection(); var mySelectionhtml = sel.getRangeAt(0).cloneContents(); var newNode = document.createElement("FONT"); newNode.appendChild(mySelectionhtml); newNode.style.textShadow = "0px 0px 10px " + coul var f = newNode.getElementsByTagName("FONT"); for (var i = 0; i < f.length; i++) { if (f[i].style.backgroundColor != null) { f[i].removeAttribute("style"); } //if(!f[i].hasAttributes()){newNode.innerHTML=newNode.innerHTML.replace(f[i].outerHTML,f[i].innerHTML);} } // Test that the Selection object contains at least one Range if (sel.getRangeAt && sel.rangeCount) { // Get the first Range (only Firefox supports more than one) range = sel.getRangeAt(0); range.deleteContents(); if (range.createContextualFragment) { fragment = range.createContextualFragment(newNode.outerHTML); } var firstInsertedNode = fragment.firstChild; var lastInsertedNode = fragment.lastChild; range.insertNode(fragment); if (firstInsertedNode) { range.setStartBefore(firstInsertedNode); range.setEndAfter(lastInsertedNode); } sel.removeAllRanges(); sel.addRange(range); } document.getElementById('res').value = document.getElementById('comment').outerHTML; } </script> </head> <body> <div id="comment" class="comment" contenteditable> <p> <font size="5">teste de <font style='text-shadow: 0px 0px 10px red;'><strong>te</strong></font> <font style="text-shadow: 0px 0px 10px blue;"><strong><font color="red"><em>xt</em>e</font></strong></font><strong><font color="red"></font></strong> shadow</font> </p> </div> <input type="button" value="backblue" onclick="replaceSelection('blue')" /> <input type="button" value="backgreen" onclick="replaceSelection('green')" /> <input type="button" value="backRED" onclick="replaceSelection('red')" /> <input type="button" value="backmagenta" onclick="replaceSelection('magenta')" /> <input type="button" id="html" value="coupe" onclick="coupe()" /> <input type="button" id="html" value="HTML" onclick="alert(document.getElementById('comment').innerHTML)" /> </br> <textarea id="res" rows="15" cols="100"> </textarea> </body> </html>
tu oublie que la sélection est sensée être deletée et devrait au final ne contenir que l'emplacement et que ce qui est inséré n'est que le outerhtml de newNodeCitation:
Ainsi chaque balise dont seule une partie est dans la sélection sera refermée, ce qui est nécessaire pour garder le formatage à gauche de la sélection... Maintenant ce qu'il faut savoir c'est que chaque balise fermée est ré-ouverte à l'intérieure de la sélection, là aussi c'est nécessaire pour garder le formatage de la partie du texte qui est à l'intérieur de la sélection...
du moins je crois
a oui !! j'ai fait le teste après délétion un alert sur sélection me redonne le innertext de la sélection
donc le renge .remove ou delete ne shunte que l’élément en mémoire mais pas pas dans le parent innerhtml pourtant quand on affiche le html du reste la sélection a bien disparue
c'est vraiment tordu comme truc
Elle est bel et bien supprimée mais le truc c'est qu’après comme tu dis tu inserts le outerhtml de newNode mais d'où vient le innerHTML de newNode ?
Le innerHTML de newNode est une copie de la sélection il contient donc les balises ré-ouvertes dont on a parlées...
Regarde c'est ce que tu fais là :
Après newNode.appendChild(mySelectionhtml); regarde le innerHTML de newNode avant et après le delete tu devrais voir les balises ré-ouvertes dans les deux cas car le delete supprime seulement la sélection sans toucher à la copie qui est indépendante...Code:
1
2
3
4
5 sel = window.getSelection(); var mySelectionhtml = sel.getRangeAt(0).cloneContents(); var newNode = document.createElement("FONT"); newNode.appendChild(mySelectionhtml);
Que tu fasses "delete + clonage" ou extracontent cela revient au même, le problème n'était pas là...
Ben cela suit une certaine logique comme on a vu...
re
Bonjour beguinner
oulah!!non je ne m’arrête pas au appendchild de newnode je le retravaille et le nettoie
c'est ça visiblement que je n'arrive pas a mettre en place
quand j'ai mis la sélection dans newnode je supprime tout les shadow ca c'est ok
pour se faire
je verifie qu'il n'y a pas d'autre attribut dans le style comme background car ca on le garde
je verifie aussi qu'il n'y a pas d'autre attributs html comme color,zize,
si il n'y a pas d'autre attribut je replace le fragment par son innerhtml autrement dis la font devient un fragment de newnode
donc au final le innerhtml de newnode n'a plus rien a voir avec le html de la sélection du départ et je le travaille en string alors je risque pas d'avoir l'auto complétion du dom
c'est ca qui est ahurissant!!! quand je les retrouves dans le code a la fin ou dedans et vides alors que non seulement il sont deleté mais il n'existe plus en fait dans newnode
c'est comme si je sélectionnais et mettais un autre texte a la place
non il y a un truc que je pige pas qui se passe en arrière plan dans le dom par rapport a la selection
comme si le dom considérait que ce que je remet a la place est simplement un morceau a ce qui a été enlevé que j'aurais ajouté
hier j'ai retesté et 6 fois en plus en remplaçant la sélection par du code html qui n'utilise pas l'attribut style et tout est OK
il y a donc bien une corrélation avec le fait que le dom percoit mal l'attribut style
d’ailleurs fait le teste tu verra
avec mon dernier exemple au lieu d'utiliser la sélection met du code html avec style css dans newnode et teste la même chose mais sans style avec color,size fontname ou même les trois tu verra il n'y a pas de soucis
Oui je sais bien que tu le retravailles mon but était d'expliquer que ce que tu retravailles contient des balises auxquelles tu n'as peut-être pas pensé, à savoir les balises ré-ouvertes...
Je ne peux pas tester sur IE il déconne chez moi alors j'aimerais savoir si pour le background il utilise la même balise que pour les autres formatages, est-ce qu'il utilise la balise <font> ou<span> ou autre chose...?
Tu es sûr qu'il n'existe plus dans le newnode ? Est-ce que avant l'insertion tu as bien le résultat souhaité dans la newnode ? Tu vérifies avec la console ?
Peux-tu me donner un exemple concret pour que je vérifie ça ?
non pour le background l'avantage de travailler avec execcommand comme pour tout les attributs sauf le textshadow bien evidement c'est que jamais le background se place dans dans un font stylé en css donc de ce coté pas de soucis
je viens de le terminer il reste des "</strong><strong>" de temps en temps il faut dire que dans mon exemple j'ai chargé la complexité aussi
mais sinon ca match
voila la version complète
bien dommage que tu ne puisse pas tester avec IE cela dit pour les autres explorateur il ne doit pas trop y avoir de gros changements
il y a plusieur boucle for car on ne peut pas tout faire en même temps il y a un ordre a respecter pour les replace
dans la demo ci dessous tu a 2 textarea un pour le résultat un qui t'affiche comment le newnode est comme ca tu peut voir
a un moment donné je me sert du string du html et non du dom cette opération m'est refusé par le dom visiblement
Pièce jointe 253068Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=10"> <style type="text/css"> <!-- .editor {font-family:tahoma} .actionbar {background-color:#c0c0c0;border:1px solid black} .comment {border:2px dotted red} --> </style> <script> function replaceSelection(coul) { var sel, range, fragment,str; sel = window.getSelection(); var mySelectionhtml =sel.getRangeAt(0).cloneContents(); var newNode = document.createElement("FONT"); newNode.appendChild(mySelectionhtml); newNode.style.textShadow="0px 0px 10px " +coul var f=newNode.getElementsByTagName("FONT"); for(var i=0;i<f.length;i++){ if (f[i].style.backgroundColor!=null){ f[i].removeAttribute("style");} if(!f[i].innerText){f[i].parentElement.removeChild(f[i]);} } str=newNode.innerHTML; var f=newNode.getElementsByTagName("FONT"); for(var i=0;i<f.length;i++){ if(!f[i].hasAttributes()){str=str.replace(f[i].outerHTML,f[i].innerHTML);} } newNode.innerHTML=str; var elements=newNode.getElementsByTagName("*") for(var i=0;i<elements.length;i++){ if (!elements[i].innerText){elements[i].parentElement.removeChild(elements[i]);} } document.getElementById('innernewnode').value=" code de newnode :" +newNode.outerHTML; if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); if (range.createContextualFragment) { fragment = range.createContextualFragment(newNode.outerHTML); } var firstInsertedNode = fragment.firstChild; var lastInsertedNode = fragment.lastChild; range.insertNode(fragment); if (firstInsertedNode) { range.setStartBefore(firstInsertedNode); range.setEndAfter(lastInsertedNode); } sel.removeAllRanges(); sel.addRange(range); } document.getElementById('res').value=document.getElementById('comment').outerHTML; } </script> </head> <body> <div id="comment" class="comment" contenteditable> <p><font size="5">teste de <font style='text-shadow: 0px 0px 10px red;'><strong>te</strong></font><font style="text-shadow: 0px 0px 10px blue;"><strong><font color="red"><em>xt</em>e</font></strong></font><strong><font color="red"></font></strong> shadow</font></p> </div> <input type="button"value="backblue" onclick="replaceSelection('blue')"/> <input type="button" value="backgreen" onclick="replaceSelection('green')"/> <input type="button" value="backRED" onclick="replaceSelection('red')"/> <input type="button" value="backmagenta" onclick="replaceSelection('magenta')"/> <input type="button" id="html" value="coupe" onclick="coupe()"/> <input type="button" id="html" value="HTML" onclick="alert(document.getElementById('comment').innerHTML)"/> </br> <textarea id="res"rows="15" cols="100"> </textarea> <textarea id="innernewnode"rows="15" cols="100"> </textarea> </body> </html>
Difficile de suivre tes discussions décidément :aie:
Néanmoins :
là je suis bien d'accord avec toi, pour tous les styles gérés nativement par execCommand le travail est plutôt très bien fait même si les amoureux de la sémantique pourront tiquer sur le <strong> VS <b> ou autre <em> VS <i>. Je mettrais toutefois un bémol pour <font> qui est une balise « deprecated » depuis pas mal de temps.Citation:
tout ce qui est color,size,bold,italic,underline,strike,itre(H),liste ordonnées ,liste non ordonnée ,etc... fonctionne parfaitement bien
Concernant tes remarques sur le DOM, il serait temps que tu arrêtes de le décrier et que tu essaies de comprendre comment il fonctionne et ce que tu peux faire avec les méthodes mises à disposition, presque tout.
Pour le traitement de la sélection, j"ai l'impression que tu te compliques la vie, sauf si tu veux rivaliser avec les milliers de lignes des éditeurs tel que CKEditor par exemple.
J'attaquerais de la façon suivante
c'est du classique, à partir de là les modifications, l'ajout du <span>, sont visibles dans le document, le DOM à changé.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 // récup. selection var oSelection = window.getSelection(); // pointe sur la selection var oRange = oSelection.getRangeAt(0); // récup des noeuds de l'étendue range var oSelectedText = oRange.extractContents(); // get conteneur commun var oParent = oRange.commonAncestorContainer; // création d'un élément neutre var oSpan = document.createElement('SPAN'); // englobe le contenu dans le <span> oRange.surroundContents(oSpan); // ajout de la sélection en cours oSpan.appendChild(oSelectedText);
C'est maintenant que les choses peuvent devenir complexe, mais à peine.
La première chose à faire est de supprimer les styles correspondant à la modification en cours, dans tous les enfants du <span>.
...maintenant on place le style sur le <span>Code:
1
2
3
4
5 // suppression des text-shadow existants des enfants var children = oSpan.getElementsByTagName('SPAN'); for (var i = 0; i < children.length; i++) { removeInlineStyle(children[i], 'text-shadow'); }
A partir de maintenant tu as quelque chose qui tient la route mais avec possiblement des style en double et des éléments inutiles.Code:
1
2
3 // style suivant le cas var style = ajout ? 'text-shadow: 0px 0px 10px ' + coul : 'text-shadow: none'; setInlineStyle(oSpan, style);
Il reste des choses à faire
• supprimer le style si celui du « parent » est le même
• faire le nettoyage et notamment supprimes les éléments <span> neutre, sans attribut style ou du même style inline que le parentCode:cleanInlineStyleNode(oSpan, oParent);
C'est un fait que c'est du travail sur le DOM mais qui te permettrais d'avoir un code « presque » propre.Code:cleanNeutralElements( oEditor)
Nota : on verra les fonctions plus tard si l'approche te convient et aussi parce que je sature un peu ;)
Ok tant mieux donc il utilise une balise <font> dédié au background... Je demande cela car sur Chrome c'est la balise <span> qui est utilisée...
Là je repense à ce que disait Loralina... Oui le fait que la méthode execCommand se comporte différemment selon le navigateur peut parfois poser problème...
Je vais tester ton code...
Oui effectivement et je saisis l’occasion pour rappeler ce que j'avais écrit ici : #23 au cas où cela intéresserait quelqu'un...
Ah merci j'ai mis un moment à capter, je ne comprenais pas à quel moment la span était insérée dans le DOM, c'est apparemment la méthode oRange.surroundContents(oSpan); (que tu m'as fait découvrir) qui fait cela à elle seule... Oui car d’après ce que j'ai compris on pourrait se passer du appendChild() car surroundContents() serait (presque ?) équivalent à : extractContents() + appendChild() + insertNode().
Trois pour le prix d'un...
Je vais quand même regarder si le fonctionnement est le même... En particulier concernant le point que j'ai évoqué au message #71.
On pourrait aussi vérifier avant : si un des parents ("ancêtres") a déjà le style que l'on veut appliquer alors on n’exécute pas la fonction setInlineStyle(oSpan, style);...
Bon ben j'ai faits quelques tests...
Quand j'utilise juste la fonction surroundContents() (sans extractContents) cela ne fonctionne pas toujours, quand cela ne fonctionne pas, FF me dit ça :
Ce qui ne me dit pas grand chose ! Je veux dire que je ne comprends pas quel est le problème... Par contre Chrome est plus sympa, il me dit :Citation:
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
Et là je comprends mieux : on ne peut pas utiliser cette méthode si la sélection contient des balises qui ne sont pas entièrement comprises dans la sélection (partiellement sélectionnées, dont une partie se trouve à l’extérieur de la sélection).Citation:
Uncaught DOMException: Failed to execute 'surroundContents' on 'Range': The Range has partially selected a non-Text node.
L'usage de la fonction extractContents() (ou autre moyen équivalent) est donc nécessaire... Elle ré-ouvre (à l'extrémité gauche de la sélection) et/ou referme (à l'extrémité droite de la sélection) ces balises de sorte que le range ne contienne aucune balise partielle.
Du coup on en revient au problème évoqué au message #71 :
Avec l'exemple c'est plus clair voir le message #71...Citation:
Ainsi chaque balise dont seule une partie est dans la sélection sera refermée, ce qui est nécessaire pour garder le formatage à gauche de la sélection... Maintenant ce qu'il faut savoir c'est que chaque balise fermée est ré-ouverte à l'intérieure de la sélection, là aussi c'est nécessaire pour garder le formatage de la partie du texte qui est à l'intérieur de la sélection...
Alors dés que tu fais une insertion tu retrouves ces balises ré-ouvertes et donc on se retrouve avec ces balises multipliés par deux...
Mais bon comme je disais on peut quand même avec cela facilement supprimer un formatage spécifique mais il y aura une multiplication des balises partiellement sélectionnées...
Cela rejoint ce que NoSmoking a proposé si on est pas trop exigeant...
Mais c'est vrai qu'à chaque fois on multiplie les balises par deux ce qui peut faire vraiment beaucoup si on utilise plusieurs fois le shadow, ce qui peut très bien être le cas car l'utilisateur n'a pas toujours (c'est même peut-être rarement le cas) le rendu souhaité du premier coup ...