Newsgroup: it.comp.lang.javascript
Titolo: selezione di testo / modifica DOM

Ho questo problema.
L'utente esegue tramite browser (Mozilla) una selezione del testo.
Quindi data la selezione, recupero il relativo DOM range (sto lavorando su
Mozilla).
var Selection = window._content.getSelection();
var range =  window._content.getSelection().getRangeAt(0);
Della parte di testo selezionata, tramite un JS modifico il DOM togliendo
tutti i link.
Tutto funziona fino a qua.
Il problema nasce quando cerco di riottenere il range che rappresenta la
selezione iniziale.
Riutilizzando:
var Selection = window._content.getSelection();
var range =  window._content.getSelection().getRangeAt(0);
e tutto OK quando la seleziona NON interseca uno dei link rimossi.
Quando però questa interseca uno di tali link, la selezione (probabilmente a
seguito della modifica del DOM) viene azzerata e non riesco a recuperarla.
Come possa fare? Sapete aiutarmi?
Qualche idea per recuperare la selezione, ma sulla base del nuovo DOM?
Ciao.
--Gabriele

 Qualche idea per recuperare la selezione, ma sulla base del nuovo DOM?
Uhm, non e' chiarissimo cio' che dici, ma a naso temo che ci possano essere
problemi nel cercare di fare cio' che "credo di aver capito" tu voglia
fare.. La cosa piu' semplice e' che metti a disposizione il codice da
qualche parte cosi' ci smanetto/smanettiamo un po' su e vediamo cosa ne
caviamo.
-- 
C'ya,
  ZER0 :: coder.gfxer.webDesigner();
"When you have eliminated the impossible, whatever remains,
however improbable, must be the truth." (S.H.)

 caviamo.
Perfetto.
Il codice js sostanzialmente è questo.
////////////////////////
//define resolver function (xPath)
var resolver = function (aPrefix) {
  var retval = "";
   return retval;
  };
var pcontent = getBrowser().contentDocument;
 pcontent.body.normalize();
//prendo la selezione
 var Selection = window._content.getSelection();
 var range =  window._content.getSelection().getRangeAt(0);
 alert("prima: " + range);
 var ancestor = range.commonAncestorContainer;
 var xpathanc = './/a[@href]';
 try {var resultanc = pcontent.evaluate(xpathanc, ancestor, resolver, 4,
null);
 } catch (e) {
    return false;
 };
 var nodeanc = [];
 var curr = null;
 while (curr = resultanc.iterateNext()) {
  nodeanc.push(curr);
 };
 for (var i = 0; i<nodeanc.length;i++) {
  while (nodeanc[i].hasChildNodes()) {
   var rem = nodeanc[i].removeChild(nodeanc[i].firstChild);
   nodeanc[i].parentNode.insertBefore(rem,nodeanc[i]);
   dump("spostato figlio\n");
  };
  nodeanc[i].parentNode.removeChild(nodeanc[i]);
  dump("rimosso nodo\n");
 };
 ancestor.normalize();
 alert("dopo: " + range);
///////////////////
La funzione viene richiamata da un'overlay di mozilla. (ad esempio aggiunti
un item sul menu Window di mozilla).
Se devo mandarti anche l'overlay, il modo per installarlo e via dicendo
fammi sapere.
Grazie cmq per l'interessamento.
Ciao,
--Gabriele

 Grazie cmq per l'interessamento.
De nada. 


 Firebird 0.6 se non ricordo male, devo aggiornarlo).
Vorrei provare il tuo codice esattamente cosi, se me lo posti...qua o via
e-mail, ti ringrazio.
Lo provo con Mozilla 1.5 e vedo se dipende dalla pagina HTML / XUL oppure
dal browser.
Non è una novità che nsRange.js abbia dei bug...!
Ciao.
--Gabriele

 e-mail, ti ringrazio.
Nessun problema, premetto che cmq non ho dato un occhiata al tuo codice per
vedere se vi erano errori, ottimizzazioni da fare o altro, non l'ho proprio
"toccato" da quel punto di vista, l'ho solo messo in condizioni di "girare"
su Firebird come pagina HTML:
<html>
<head>
	<title>Untitled</title>
	<script type="text/javascript">
	var resolver = function (aPrefix) {
		var retval = "";
		return retval;
	};
	function myf(){
		var pcontent = document;
		pcontent.body.normalize();
 
		//prendo la selezione
		var Selection = window.getSelection();
		var range =  window.getSelection().getRangeAt(0);
		alert("prima: " + range);
 
		var ancestor = range.commonAncestorContainer;
 
		var xpathanc = './/a[@href]';
		try {
			var resultanc = pcontent.evaluate(xpathanc, ancestor, resolver, 4,null);
		} catch (e) {
		 	alert(e);
		    return false;
		};
 
 
		var nodeanc = [];
		var curr = null;
 
		while (curr = resultanc.iterateNext()) {
			nodeanc.push(curr);
		};
 
		for (var i = 0; i<nodeanc.length;i++) {
 
			while (nodeanc[i].hasChildNodes()) {
				var rem = nodeanc[i].removeChild(nodeanc[i].firstChild);
 
				nodeanc[i].parentNode.insertBefore(rem,nodeanc[i]);
				dump("spostato figlio\n");
	  		};
 
			nodeanc[i].parentNode.removeChild(nodeanc[i]);
			dump("rimosso nodo\n");
		};
 
		ancestor.normalize();
		alert("dopo: " + range);
	}
</script>
</head>
<body>
	<button onclick="myf()">aaa</button>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	<a href="#">a test</a><br>	
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	<a href="#" onclick="myf();return false;">click me</a>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
	BU!<br>BU!<br>BU!<br>BU!<br>BU!<br>
</body>
</html>


Ok, testandomeglio il mio e il tuo codice il comportamento è il medesimo.
Il primo alert ritorna esattamente la selezione.
Il secondo alert ritorna la selezione allargata al contenuto dell'elemento
<A> quando questo è all'estremo DX della selezione.
Ritorna stringa vuota (e non capisto perché)  o la parte della selezione che
non è sovrapposta al link quando <A> è all'estremo SX della selezione.
Provo ad enunciare il problema specifico. Magari la strada che sto
percorrento è quella sbagliata.
Ho l'utente che fa una selezione del testo.
Quando la selezione sovrappone un link devo modificare il DOM per togliere
quel link.
Quindi devo andare a riselezionare il testo precedentemente selezionato,
che ora ha cambiato posto (a seguito della variazione del DOM) (per
spiegarmi meglio, il range che descrive la selezione a seguito della
variazione del DOM è cambiato: devo ricrearlo in modo che mi descriva la
selezione precedente ma sulla base del nuovo DOM).
Che intreccio..... :-(
Ciao,
--Gabriele