Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
inet
active_desktop
active_scrptng
asp.components
asp.db
asp.general
comctl32
comp.packaging
components.dev
dbweb
dhtml_editing
docobjects
html_authoring
html_objmodel
iis
iis.ftp
iis.security
iis.smtp_nntp
indexserver
misc
mshtml_hosting
scripting.jscript
scripting.vbscript
sdk_setup
shell_objmodel
urlmonikers
webbrowser_ctl
wininet
  
 
date: Mon, 7 Jul 2008 10:50:11 -0700,    group: microsoft.public.inetsdk.programming.scripting.jscript        back       


Passing XML objects between windows   
Folks,

I have a simple web page that creates an array of XML documentElements.

I spawn a window, passing it an index into that array as a query string 
parameter.

The spawned window calls a function on the first window to retrieve the 
specified item from the array.

The spawned window then calls another function on the first window to store 
the node back into the array.  This function actually stores a cloned node 
using the cloneNode method of the xml node begin stored.

The spawned window then calls yet another function on the first window to 
close the spawned window.

When the spawned window closes, the element of the array no longer contains 
the XML.  It has been trashed, even though what was stored was the result of 
cloneNode.

QUESTION:  Why is this happening.

Thanks in advance for all suggestions.
/Joel Finkel

-------------------------------------------------------------------------------
CODE: TestSpawn.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>

<title>Test Spawn</title>

<script type="text/javascript">

var g_XmlArray = [];

function OnLoad()
{
	// Push two new XML nodes onto the g_XmlArray array

	var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");

	xmlDoc.loadXML("<element id='e1'><e1>foo</e1><e2>bar</e2></element>")
	g_XmlArray.push(xmlDoc.documentElement.cloneNode(true));

	xmlDoc.loadXML("<element id='e2'><e1>foo</e1><e2>bar</e2></element>")
	g_XmlArray.push(xmlDoc.documentElement.cloneNode(true));
}

function SpawnWindow()
{
	// Get the index from the input field
	var index = document.getElementById("num").value;

	OpenSubWindow(index);
}

var g_spawnwin;

function OpenSubWindow(p_index)
{
	url = "TestSpawnSub.html?q=" + p_index;

	g_spawnwin = window.open(url, 'spawn');

	g_spawnwin.focus();
}

// Called by the spawned window
function CloseSubWindow()
{
	g_spawnwin.close();
}

// Called by the spawned window
function GetXml(p_index)
{
	try
	{
		return g_XmlArray[p_index].xml;
	}
	catch(e)
	{
		debugger;
		alert(e.message);
	}
}

// Called by the spawned window
function StoreXml(p_index, p_xml)
{
	try
	{
		g_XmlArray[p_index] = p_xml.cloneNode(true);
	}
	catch(e)
	{
		debugger;
		alert(e.message);
	}
}

</script>
</head>

<body onload="OnLoad()">

Which one? ('0' or '1') <input type="text" size="1" id="num" />
<input type="button" value="Spawn Window" onclick="SpawnWindow();" />

</body>
</html>

---------------------------------------------------------------------------------------

CODE:  TestSpawnSub.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>

<title>Test Spawn</title>

<script type="text/javascript">

/************* CLASS QueryString ***********************/

function QueryString()
{
	this.params = [];

	// Gets the query string with a preceeding '?'   
	var QueryString = location.search;   
  
	// Nothing to do if there is no Query String
	if (!QueryString) return;   

	// Remove the '?'
	QueryString = QueryString.substring(1);

	// Split the string on '&'
	var valuePairs = QueryString.split('&');

	// Load up the params array
	for (var i = 0; i < valuePairs.length; i++)
	{
		pair = valuePairs[i].split('=');
		this.params[pair[0]] = pair[1];
	}
}

QueryString.prototype.GetParam = function(p_paramName)
{
	var result = "";
	
	try
	{
		result = this.params[p_paramName];
	}
	catch(e)
	{
	}

	return result;
}

</script>

<script type="text/javascript">

function DoIt()
{
	debugger;

	// Get the index into the opener array, which his passed as a param ("q")
	var qs = new QueryString();
	var index = qs.GetParam("q");  

	// Create a new XML Doc
	var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");

	// Get the XML from the opener window
	xml = window.opener.GetXml(index);

	// Load the XML from into the xmlDoc
 	xmlDoc.loadXML(xml);

	// Store the XML back into the opener
	window.opener.StoreXml(index, xmlDoc.documentElement);

	// Ask the opener to close this window
	window.opener.CloseSubWindow();
}

</script>
</head>
<body>

<input type="button" value="Save and Close" onclick="DoIt();" />

</body>
</html>
------------------------------------------------------------
date: Mon, 7 Jul 2008 10:50:11 -0700   author:   Joel Finkel

RE: Passing XML objects between windows   
Seems pretty straightforward to me.

Your code does:
    function StoreXml(p_index, p_xml) 
    { 
         try 
         { 
               g_XmlArray[p_index] = p_xml.cloneNode(true); 
         } 

So the cloning is done *BY THE p_xml OBJECT* that was passed into this 
function.

But *THAT* object is created in the popup via
     var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
     ...
     window.opener.StoreXml(index, xmlDoc.documentElement); 

so of course when the xmlDoc object from the popup gets destroyed, anything 
that it contains *OR THAT IT CREATED* will also get destroyed.

I'm not clear why you are going around the long way to do this, but I assume 
that you are reproducing just the important parts of the problem (for which, 
thanks! else we'd likely never figure it out!).  Seems to me like if you can 
do
    xml = window.opener.GetXml(index); 
that then instead of doing
     var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
you could maybe add a method on the opener window that would return an 
object in *ITS* scope, so you'd do
     var xmlDoc = window.opener.getMeAnXmlDomObjectPlease( );
and now it should work.  No?
date: Mon, 7 Jul 2008 16:41:03 -0700   author:   Old Pedant

RE: Passing XML objects between windows   
This is very interesting, and not quite what I expect (although I had a 
feeling that something like this was happening).

As I understand it, cloneNode returns a new object.  I would not expect that 
the destruction of the object that created it would destroy it, as well.  
This is why I clone it in the context of the parent window.

You are quite correct in your assumption that I have stripped out everything 
that is not pertinent to this discussion so as not to complicate the code.

The application creates a list of documents that may be edited.  It keeps 
the XML for each in an array.  It spawns a new window that is used to edit 
the document.  The XML is then returned to the parent window.

Unfotunately, in IE, if I want to add nodes in the edit window, I cannot 
simply add them to the original XML, as it is out of context.  Interestingly, 
FF is perfectly happy to add nodes to the original using an xmlDoc that is 
created in the context of the edit window.

I think the solution you suggest, namely to have the parent window create an 
xmlDoc, will solve the problem.  Thanks much.

/Joel Finkel

"Old Pedant" wrote:

> Seems pretty straightforward to me.
> 
> Your code does:
>     function StoreXml(p_index, p_xml) 
>     { 
>          try 
>          { 
>                g_XmlArray[p_index] = p_xml.cloneNode(true); 
>          } 
> 
> So the cloning is done *BY THE p_xml OBJECT* that was passed into this 
> function.
> 
> But *THAT* object is created in the popup via
>      var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
>      ...
>      window.opener.StoreXml(index, xmlDoc.documentElement); 
> 
> so of course when the xmlDoc object from the popup gets destroyed, anything 
> that it contains *OR THAT IT CREATED* will also get destroyed.
> 
> I'm not clear why you are going around the long way to do this, but I assume 
> that you are reproducing just the important parts of the problem (for which, 
> thanks! else we'd likely never figure it out!).  Seems to me like if you can 
> do
>     xml = window.opener.GetXml(index); 
> that then instead of doing
>      var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
> you could maybe add a method on the opener window that would return an 
> object in *ITS* scope, so you'd do
>      var xmlDoc = window.opener.getMeAnXmlDomObjectPlease( );
> and now it should work.  No?
>
date: Tue, 8 Jul 2008 09:38:01 -0700   author:   Joel Finkel

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us