Newsgroup: it.comp.lang.javascript
Titolo: Selezione, range ed execCommand?

Salve a tutti.
In questi ultimi tempi sto veramente sbattendo la testa su un problema
che non riesco a risolvere ovvero la corretta gestione dei range
derivati da selezioni e l'applicazioni dei comuni tag di formattazione.
Come sapete nei comuni editor WYSIWYG in javascript, l'applicazioni di
effetti come BOLD, ITALIC ecc... viene fatta con l'ausilio del comando
execCommand.
Tale comando è molto potente perché riscrive automaticamente i tag
secondo quanto richiesto. Es:
Testo originale:
<b>Pippo è simpatico</b> e goffo;
Poniamo di selezionare "tico e goffo" e di applicarci un ITALIC.
Il risultato finale della execCommand sarà qualcosa come:
<b>Pippo è simpa<i>tico</i></b><i> e goffo</i>;
In pratica lui gestisce automaticamente anche le intersezioni tra i
tag.
La cosa è molto bella se non fosse che tale comando ha due
comportamenti distinti sui Gecko e su IE.
Nel primo caso vengono utilizzati degli SPAN con gli opportuni
attributi in Style.
Nel secondo vengono usati le varianti STRONG, EM ecc...
Ora. Nel famoso editor tinyMCE tale inconveniente non succede in quanto
anche in Firefox/Mozilla, l'applicazione di execCommand restituisce
STRONG, EM ecc..
Ho postato sul loro forum per tentare di farmi spiegare come facessero
e mi sono spulciato il codice sorgente ma non ho ricevuto/trovato la
soluzione.
Come posso quindi ottenere un tale risultato anche, eventualmente,
senza l'abblicazione di execCommand ma manipolando manualmente il
range?
Per gli interessati, ricordo che per creare un range in Firefox occorre
usare la seguente funzione:
[CODE]
var selection = getSel (rte);
var newRange = selection.getRangeAt(0);
[/CODE]
dove getSel è la seguente funzione:
[code]
function getSel()
{
	var txt = '';
	if (window.getSelection)
		txt = window.getSelection();
	else if (document.getSelection)
		txt = document.getSelection();
	else if (document.selection)
		txt = document.selection.createRange().text;
	else return;
   return txt;
}
[/code]
Il secondo problema è conoscere anche la struttura dei tag della
selezione. In pratica riuscire non solo a carpire il testo, ma anche il
codice sorgente inerente il testo selezionato.
Spero possiate aiutarmi.
Ho trovato a questo indirizzo, un comodo (anche se in inglese) elenco
di funzioni e methodi applicabili ai range:
[url]
http://www.dotvoid.com/view.php?id=11[/url]
Grazie e alla prossima...

 STRONG, EM ecc..
Se proprio ci tieni, imposta in MIDAS (il set di API che in Gecko ti
permette di fare content editing) "useCSS" a false. In questo modo ti
imposterŕ i tag <b> e <i>, etc:
execCommand("useCSS", false, false);  
Se poi desideri avere i tag "<strong>" e "<em>" invece di "<b>" e "<i>",
devi fare tu un replace a posteriori (fanno sicuramente cosě anche quelli
che hanno sviluppato tinyMCE: prova a scrivere un tag <b> in
visualizzazione HTML, e vedrai che ti verrŕ trasformato in <strong>...
quindi l'execCommand non c'entra).
Selezioni e range non c'entrano, alla fin della fiera.
-- 
~ "Nell'anno 1969 č bastata la potenza di calcolo di due Commodore 64 per
mandare con successo una navicella sulla Luna. Nell'anno 2003 č
necessario un Pentium 4 a 2000 Mhz per far funzionare Windows XP.
Qualcosa deve essere andato storto."

Ti ringrazio per la risposta.
Il comando funziona anche se va messo con execCommand("useCSS", false,
true);
Tra  l'altro si ottengono B, I ed U che era il mio scopo originale. Gli
STRONG, EM ecc... erano solo più facili da parsare e sostituire.
Rimane la seconda domanda. E' possibile conoscere il codiche che sta
dietro ad una selezione?
Grazie e alla prossima...

 dietro ad una selezione?
Fatta al volo, ma dovrebbe andare:
function getSelectedHTML(){
	var rng=null,html="";
 
	if (document.selection && document.selection.createRange){
		rng=document.selection.createRange();
		html=rng.htmlText||"";
	}else if (window.getSelection){
		rng=window.getSelection();
 
		if (rng.rangeCount > 0 && window.XMLSerializer){
			rng=rng.getRangeAt(0);
			html=new XMLSerializer().serializeToString(rng.cloneContents());
		}
	}
	return html;
}
-- 
~ "Nell'anno 1969 è bastata la potenza di calcolo di due Commodore 64 per
mandare con successo una navicella sulla Luna. Nell'anno 2003 è


Cosě hai "preso" l'html. Ora per manipolarlo?
Anch'io avevo il problema di "Amadei" e alla fine ho scritto una serie 
di regExp che "mettessero le cose a posto" visto che l'HTML generato 
andava in pasto a Flash che ha una interpretazione tutta sua...
Alex.

 di regExp che "mettessero le cose a posto" 
Il che va bene. Del resto tali editor servono per avere una
rappresentazione visuale; poi il codice puň essere sistemato prima di
inviarlo al server (o a Flash). Non ha molto senso creare regioni per
fixare ogni singola cosa "durante" l'editing da parte dell'utente.
-- 
~ "Nell'anno 1969 č bastata la potenza di calcolo di due Commodore 64 per
mandare con successo una navicella sulla Luna. Nell'anno 2003 č


A me serviva conoscere l'HTML per capire se nella selezione venivano
"coinvolti" dei tag specifici. Devo ancora sviluppare questa parte.
Spero che si possa manipolarlo o convertirlo in stringa, magari col
metodo toString().
Mi è sorte però un altro problema mentre continuavo a sviluppare il
mio editor.
Posto la domanda qui perché interessa i range.
Ho notato, ma potrei sbagliarmi, che i range hanno metodi differenti
per i due browser.
In Firefox utilizzo il metodo:
commonAncestorContainer
per avere il totale contenuto di un nodo anche se ne seleziono solo una
parte.
<div>Pippo è goffo</div>
Se io seleziono "è gof", con il comando sopra citato, posso ottenere
il nodo #text (figlio del div) che contiente "Pippo è goffo". Posso
infatti ricavarmi il testo completo con un semplice nodeValue. Da qui
poi posso partire con i vari parentNode ecc... per ricavarmi anche
quello che c'è attorno.
Esiste un equivalente in Internet Explorer?
Ho notato che con parentElement, ottenge l'equivalmente di parentNode
di cui sopra. Però non risco a ottenere il nodo #text a cui la
sottoselezione appartiene.
Spulciando sulla rete dato che il mio manuale cartaceo non parla delle
selezioni approfonditamente, ho trovato alcuni metodi per IE che però
non sembrano idonei. Tra questi c'era il metodo expand che citava
"Expands the range so that partial units are completely contained."
Ho provato ad utilizzare expand con l'unica opzione, delle 4, che
poteva funzionare ovvero "textedit" ma il risultato è quello di
prendermi TUTTO il contenuto dell'area, ovvero tutta la struttura di
tutto il testo contenuto nell'area di editing.
Faccio ancora appello alla vostra pazienza. Come posse ricavare il nodo
#text che contiene la selezione (anche nel caso la selezione coprisse
effettivamente tutto il value del nodo) in Internet Explorer?
Grazie e alla prossima...