Bug 78622, DOMParser and XMLHttpRequest failures with xml-stylesheet PIs etc. r=harishd, sr=vidur.

git-svn-id: svn://10.0.0.236/branches/MOZILLA_0_9_4_BRANCH@103460 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
heikki%netscape.com
2001-09-21 18:30:09 +00:00
parent 2c917ae462
commit b2d293d7c0
12 changed files with 340 additions and 150 deletions

View File

@@ -34,6 +34,7 @@ CPPSRCS = \
nsDOMSerializer.cpp \
nsXMLHttpRequest.cpp \
nsDOMParser.cpp \
nsLoadListenerProxy.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a

View File

@@ -30,6 +30,7 @@ CPPSRCS= \
nsDOMSerializer.cpp \
nsXMLHttpRequest.cpp \
nsDOMParser.cpp \
nsLoadListenerProxy.cpp \
$(NULL)
@@ -37,6 +38,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsDOMSerializer.obj \
.\$(OBJDIR)\nsXMLHttpRequest.obj \
.\$(OBJDIR)\nsDOMParser.obj \
.\$(OBJDIR)\nsLoadListenerProxy.obj \
$(NULL)
EXPORTS = \

View File

@@ -41,6 +41,20 @@
#include "nsICodebasePrincipal.h"
#include "nsIDOMClassInfo.h"
#ifdef IMPLEMENT_SYNC_LOAD
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIEventQueueService.h"
#include "nsIInterfaceRequestor.h"
#include "nsIDOMEventReceiver.h"
#include "jsapi.h"
#include "nsLoadListenerProxy.h"
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
#endif
static const char* kLoadAsData = "loadAsData";
static NS_DEFINE_CID(kIDOMDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID);
@@ -252,6 +266,71 @@ NS_IMETHODIMP nsDOMParserChannel::AsyncOpen(nsIStreamListener *listener, nsISupp
//
/////////////////////////////////////////////
#ifdef IMPLEMENT_SYNC_LOAD
// See if we have a modal event loop
static inline PRBool IsModal(nsIWebBrowserChrome *aWindow)
{
if (aWindow) {
PRBool isModal;
if (NS_SUCCEEDED(aWindow->IsWindowModal(&isModal))) {
return isModal;
}
}
return PR_FALSE;
}
// nsIDOMEventListener
nsresult
nsDOMParser::HandleEvent(nsIDOMEvent* aEvent)
{
return NS_OK;
}
// nsIDOMLoadListener
nsresult
nsDOMParser::Load(nsIDOMEvent* aEvent)
{
if (IsModal(mChromeWindow)) {
mChromeWindow->ExitModalEventLoop(NS_OK);
}
mChromeWindow = nsnull;
return NS_OK;
}
nsresult
nsDOMParser::Unload(nsIDOMEvent* aEvent)
{
return NS_OK;
}
nsresult
nsDOMParser::Abort(nsIDOMEvent* aEvent)
{
if (IsModal(mChromeWindow)) {
mChromeWindow->ExitModalEventLoop(NS_OK);
}
mChromeWindow = nsnull;
return NS_OK;
}
nsresult
nsDOMParser::Error(nsIDOMEvent* aEvent)
{
if (IsModal(mChromeWindow)) {
mChromeWindow->ExitModalEventLoop(NS_OK);
}
mChromeWindow = nsnull;
return NS_OK;
}
#endif
nsDOMParser::nsDOMParser()
{
NS_INIT_ISUPPORTS();
@@ -259,13 +338,22 @@ nsDOMParser::nsDOMParser()
nsDOMParser::~nsDOMParser()
{
#ifdef IMPLEMENT_SYNC_LOAD
if (IsModal(mChromeWindow)) {
mChromeWindow->ExitModalEventLoop(NS_OK);
}
#endif
}
// QueryInterface implementation for nsDOMParser
NS_INTERFACE_MAP_BEGIN(nsDOMParser)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser)
NS_INTERFACE_MAP_ENTRY(nsIDOMParser)
#ifdef IMPLEMENT_SYNC_LOAD
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
#endif
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(DOMParser)
NS_INTERFACE_MAP_END
@@ -435,6 +523,22 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
getter_AddRefs(domDocument));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
#ifdef IMPLEMENT_SYNC_LOAD
// Register as a load listener on the document
nsCOMPtr<nsIDOMEventReceiver> target(do_QueryInterface(domDocument));
if (target) {
nsWeakPtr requestWeak(getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIDOMParser*, this))));
nsLoadListenerProxy* proxy = new nsLoadListenerProxy(requestWeak);
if (!proxy) return NS_ERROR_OUT_OF_MEMORY;
// This will addref the proxy
rv = target->AddEventListenerByIID(NS_STATIC_CAST(nsIDOMEventListener*,
proxy),
NS_GET_IID(nsIDOMLoadListener));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
}
#endif
// Create a fake channel
nsDOMParserChannel* parserChannel = new nsDOMParserChannel(baseURI, contentType);
if (!parserChannel) return NS_ERROR_OUT_OF_MEMORY;
@@ -449,14 +553,69 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
// Tell the document to start loading
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
if (!document) return NS_ERROR_FAILURE;
#ifdef IMPLEMENT_SYNC_LOAD
nsCOMPtr<nsIEventQueue> modalEventQueue;
nsCOMPtr<nsIEventQueueService> eventQService;
if (cc) {
JSContext* cx;
rv = cc->GetJSContext(&cx);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
// We can only do this if we're called from a DOM script context
nsIScriptContext* scriptCX = (nsIScriptContext*)JS_GetContextPrivate(cx);
if (!scriptCX) return NS_OK;
// Get the nsIDocShellTreeOwner associated with the window
// containing this script context
// XXX Need to find a better way to do this rather than
// chaining through a bunch of getters and QIs
nsCOMPtr<nsIScriptGlobalObject> global;
scriptCX->GetGlobalObject(getter_AddRefs(global));
if (!global) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocShell> docshell;
rv = global->GetDocShell(getter_AddRefs(docshell));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(docshell);
if (!item) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
rv = item->GetTreeOwner(getter_AddRefs(treeOwner));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIInterfaceRequestor> treeRequestor(do_GetInterface(treeOwner));
if (!treeRequestor) return NS_ERROR_FAILURE;
treeRequestor->GetInterface(NS_GET_IID(nsIWebBrowserChrome), getter_AddRefs(mChromeWindow));
if (!mChromeWindow) return NS_ERROR_FAILURE;
eventQService = do_GetService(kEventQueueServiceCID);
if(!eventQService ||
NS_FAILED(eventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue)))) {
return NS_ERROR_FAILURE;
}
}
#endif
rv = document->StartDocumentLoad(kLoadAsData, channel,
nsnull, nsnull,
getter_AddRefs(listener),
PR_FALSE);
#ifdef IMPLEMENT_SYNC_LOAD
if (NS_FAILED(rv) || !listener) {
if (modalEventQueue) {
eventQService->PopThreadEventQueue(modalEventQueue);
}
return NS_ERROR_FAILURE;
}
#else
if (NS_FAILED(rv) || !listener) return NS_ERROR_FAILURE;
#endif
// Now start pumping data to the listener
nsresult status;
@@ -470,7 +629,29 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
}
rv = listener->OnStopRequest(request, nsnull, status);
#ifdef IMPLEMENT_SYNC_LOAD
if (NS_FAILED(rv)) {
if (modalEventQueue) {
eventQService->PopThreadEventQueue(modalEventQueue);
}
return NS_ERROR_FAILURE;
}
#else
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
#endif
#ifdef IMPLEMENT_SYNC_LOAD
// Spin an event loop here and wait
if (mChromeWindow) {
rv = mChromeWindow->ShowAsModal();
eventQService->PopThreadEventQueue(modalEventQueue);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
} else if (modalEventQueue) {
eventQService->PopThreadEventQueue(modalEventQueue);
}
#endif
*_retval = domDocument;
NS_ADDREF(*_retval);

View File

@@ -29,7 +29,18 @@
#include "nsCOMPtr.h"
#include "nsIURI.h"
#define IMPLEMENT_SYNC_LOAD
#ifdef IMPLEMENT_SYNC_LOAD
#include "nsIWebBrowserChrome.h"
#include "nsIDOMLoadListener.h"
#include "nsWeakReference.h"
#endif
class nsDOMParser : public nsIDOMParser
#ifdef IMPLEMENT_SYNC_LOAD
, public nsIDOMLoadListener
, public nsSupportsWeakReference
#endif
{
public:
nsDOMParser();
@@ -40,8 +51,23 @@ public:
// nsIDOMParser
NS_DECL_NSIDOMPARSER
#ifdef IMPLEMENT_SYNC_LOAD
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
// nsIDOMLoadListener
NS_IMETHOD Load(nsIDOMEvent* aEvent);
NS_IMETHOD Unload(nsIDOMEvent* aEvent);
NS_IMETHOD Abort(nsIDOMEvent* aEvent);
NS_IMETHOD Error(nsIDOMEvent* aEvent);
#endif
private:
nsCOMPtr<nsIURI> mBaseURI;
#ifdef IMPLEMENT_SYNC_LOAD
nsCOMPtr<nsIWebBrowserChrome> mChromeWindow;
#endif
};
#endif

View File

@@ -58,6 +58,8 @@
#endif
#include "nsIDOMClassInfo.h"
#include "nsIDOMElement.h"
#include "nsIParser.h"
#include "nsLoadListenerProxy.h"
static const char* kLoadAsData = "loadAsData";
#define LOADSTR NS_LITERAL_STRING("load")
@@ -104,109 +106,6 @@ GetCurrentContext(nsIScriptContext **aScriptContext)
return;
}
/////////////////////////////////////////////
//
// This class exists to prevent a circular reference between
// the loaded document and the nsXMLHttpRequest instance. The
// request owns the document. While the document is loading,
// the request is a load listener, held onto by the document.
// The proxy class breaks the circularity by filling in as the
// load listener and holding a weak reference to the request
// object.
//
/////////////////////////////////////////////
class nsLoadListenerProxy : public nsIDOMLoadListener {
public:
nsLoadListenerProxy(nsWeakPtr aParent);
virtual ~nsLoadListenerProxy();
NS_DECL_ISUPPORTS
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
// nsIDOMLoadListener
NS_IMETHOD Load(nsIDOMEvent* aEvent);
NS_IMETHOD Unload(nsIDOMEvent* aEvent);
NS_IMETHOD Abort(nsIDOMEvent* aEvent);
NS_IMETHOD Error(nsIDOMEvent* aEvent);
protected:
nsWeakPtr mParent;
};
nsLoadListenerProxy::nsLoadListenerProxy(nsWeakPtr aParent)
{
NS_INIT_ISUPPORTS();
mParent = aParent;
}
nsLoadListenerProxy::~nsLoadListenerProxy()
{
}
NS_IMPL_ISUPPORTS1(nsLoadListenerProxy, nsIDOMLoadListener)
NS_IMETHODIMP
nsLoadListenerProxy::HandleEvent(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMLoadListener> listener(do_QueryReferent(mParent));
if (listener) {
return listener->HandleEvent(aEvent);
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadListenerProxy::Load(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMLoadListener> listener(do_QueryReferent(mParent));
if (listener) {
return listener->Load(aEvent);
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadListenerProxy::Unload(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMLoadListener> listener(do_QueryReferent(mParent));
if (listener) {
return listener->Unload(aEvent);
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadListenerProxy::Abort(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMLoadListener> listener(do_QueryReferent(mParent));
if (listener) {
return listener->Abort(aEvent);
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadListenerProxy::Error(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMLoadListener> listener(do_QueryReferent(mParent));
if (listener) {
return listener->Error(aEvent);
}
return NS_OK;
}
/////////////////////////////////////////////
//
@@ -924,12 +823,23 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
NS_IMETHODIMP
nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status)
{
nsCOMPtr<nsIParser> parser(do_QueryInterface(mXMLParserStreamListener));
NS_ABORT_IF_FALSE(parser, "stream listener was expected to be a parser");
nsresult rv = mXMLParserStreamListener->OnStopRequest(request,ctxt,status);
mXMLParserStreamListener = nsnull;
mReadRequest = nsnull;
mContext = nsnull;
RequestCompleted();
// The parser needs to be enabled for us to safely call RequestCompleted().
// If the parser is not enabled, it means it was blocked, by xml-stylesheet PI
// for example, and is still building the document. RequestCompleted() must be
// called later, when we get the load event from the document.
if (parser && parser->IsParserEnabled()) {
RequestCompleted();
} else {
ChangeState(XML_HTTP_REQUEST_STOPPED,PR_FALSE);
}
return rv;
}
@@ -940,8 +850,10 @@ nsXMLHttpRequest::RequestCompleted()
nsresult rv = NS_OK;
// If we're uninitialized at this point, we encountered an error
// earlier and listeners have already been notified.
if (mStatus == XML_HTTP_REQUEST_UNINITIALIZED) {
// earlier and listeners have already been notified. Also we do
// not want to do this if we already completed.
if ((mStatus == XML_HTTP_REQUEST_UNINITIALIZED) ||
(mStatus == XML_HTTP_REQUEST_COMPLETED)) {
return NS_OK;
}
@@ -1267,10 +1179,17 @@ NS_IMETHODIMP
nsXMLHttpRequest::GetReadyState(PRInt32 *aState)
{
NS_ENSURE_ARG_POINTER(aState);
if (mStatus == XML_HTTP_REQUEST_SENT) {
*aState = XML_HTTP_REQUEST_OPENED;
} else {
*aState = mStatus;
// Translate some of our internal states for external consumers
switch (mStatus) {
case XML_HTTP_REQUEST_SENT:
*aState = XML_HTTP_REQUEST_OPENED;
break;
case XML_HTTP_REQUEST_STOPPED:
*aState = XML_HTTP_REQUEST_INTERACTIVE;
break;
default:
*aState = mStatus;
break;
}
return NS_OK;
}
@@ -1293,6 +1212,16 @@ nsXMLHttpRequest::Load(nsIDOMEvent* aEvent)
// sending the load event until OnStopRequest(). In normal case
// there is no harm done, we will get OnStopRequest() immediately
// after the load event.
//
// However, if the data we were loading caused the parser to stop,
// for example when loading external stylesheets, we can receive
// the OnStopRequest() call before the parser has finished building
// the document. In that case, we obviously should not fire the event
// in OnStopRequest(). For those documents, we must wait for the load
// event from the document to fire our RequestCompleted().
if (mStatus == XML_HTTP_REQUEST_STOPPED) {
RequestCompleted();
}
return NS_OK;
}

View File

@@ -51,7 +51,8 @@ enum nsXMLHttpRequestState {
XML_HTTP_REQUEST_LOADED,
XML_HTTP_REQUEST_INTERACTIVE,
XML_HTTP_REQUEST_COMPLETED,
XML_HTTP_REQUEST_SENT // This is Mozilla-internal only, LOADING in IE and external view
XML_HTTP_REQUEST_SENT, // This is Mozilla-internal only, LOADING in IE and external view
XML_HTTP_REQUEST_STOPPED // This is Mozilla-internal only, INTERACTIVE in IE and external view
};
class nsXMLHttpRequest : public nsIXMLHttpRequest,

View File

@@ -26,7 +26,15 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
REQUIRES = xpcom string xmlextras necko dom layout widget
REQUIRES = xpcom \
string \
xmlextras \
necko \
dom \
layout \
content \
widget \
$(NULL)
CPPSRCS = \
TestXMLExtras.cpp \

View File

@@ -18,17 +18,26 @@ pre {
<script type="text/javascript">
var p = new XMLHttpRequest();
function myfunc()
function myfunc(e)
{
var s = new XMLSerializer();
var d = p.responseXML;
var str = s.serializeToString(d);
document.getElementById("id1").firstChild.nodeValue = p.responseText;
document.getElementById("id2").firstChild.nodeValue = str;
if (p.responseXML) {
var s = new XMLSerializer();
var d = p.responseXML;
var str = s.serializeToString(d);
document.getElementById("id2").firstChild.nodeValue = str;
}
document.getElementById("id3").firstChild.nodeValue = p.getAllResponseHeaders();
document.getElementById("id4").firstChild.nodeValue = p.status;
document.getElementById("id5").firstChild.nodeValue = p.statusText;
document.getElementById("id6").firstChild.nodeValue = p.readyState;
var eventProperties = "";
for (prop in e) {
eventProperties += prop + " : '" + e[prop] + "'\n";
}
document.getElementById("id7").firstChild.nodeValue =
"Event object: " + e + "\n" +
"Event properties:\n" + eventProperties;
}
p.onload = myfunc;
@@ -58,6 +67,9 @@ p.send(null);
<div class="box"><span class="boxheader">readyState</span>
<pre id="id6">@@No result@@</pre>
</div>
<div class="box"><span class="boxheader">Event information</span>
<pre id="id7">@@No result@@</pre>
</div>
</body>
</html>

View File

@@ -23,6 +23,16 @@
DEPTH = ..\..\..
REQUIRES = xpcom \
string \
xmlextras \
necko \
dom \
content \
layout \
widget \
$(NULL)
include <$(DEPTH)/config/config.mak>
MAKE_OBJ_TYPE = EXE
@@ -33,12 +43,6 @@ PROGRAMS = $(PROG1) \
LCFLAGS = -DUSE_NSREG -GX
REQUIRES = libreg
LINCS = \
-Iservices \
-I$(PUBLIC)\xpcom
LLIBS = \
$(DIST)\lib\xpcom.lib \
$(LIBNSPR)

View File

@@ -30,22 +30,26 @@ if (!sendPlainTextData) {
var p = new XMLHttpRequest();
function myfunc()
function myfunc(e)
{
var s = new XMLSerializer();
var str;
if (!sendPlainTextData) {
var d = p.responseXML;
str = s.serializeToString(d);
} else {
str = p.responseText;
}
document.getElementById("id1").firstChild.nodeValue = p.responseText;
document.getElementById("id2").firstChild.nodeValue = str;
if (p.responseXML) {
var s = new XMLSerializer();
var d = p.responseXML;
var str = s.serializeToString(d);
document.getElementById("id2").firstChild.nodeValue = str;
}
document.getElementById("id3").firstChild.nodeValue = p.getAllResponseHeaders();
document.getElementById("id4").firstChild.nodeValue = p.status;
document.getElementById("id5").firstChild.nodeValue = p.statusText;
document.getElementById("id6").firstChild.nodeValue = p.readyState;
var eventProperties = "";
for (prop in e) {
eventProperties += prop + " : '" + e[prop] + "'\n";
}
document.getElementById("id7").firstChild.nodeValue =
"Event object: " + e + "\n" +
"Event properties:\n" + eventProperties;
}
p.onload = myfunc;
@@ -82,6 +86,9 @@ if (!sendPlainTextData) {
<div class="box"><span class="boxheader">readyState</span>
<pre id="id6">@@No result@@</pre>
</div>
<div class="box"><span class="boxheader">Event information</span>
<pre id="id7">@@No result@@</pre>
</div>
</body>
</html>

View File

@@ -28,11 +28,13 @@ function execute()
p.open("POST", "http://green/cgi-bin/echo_xml.cgi", false);
p.send(x);
var d = p.responseXML;
var s = new XMLSerializer()
str = s.serializeToString(d);
document.getElementById("id1").firstChild.nodeValue = p.responseText;
document.getElementById("id2").firstChild.nodeValue = str;
if (p.responseXML) {
var s = new XMLSerializer();
var d = p.responseXML;
var str = s.serializeToString(d);
document.getElementById("id2").firstChild.nodeValue = str;
}
document.getElementById("id3").firstChild.nodeValue = p.getAllResponseHeaders();
document.getElementById("id4").firstChild.nodeValue = p.status;
document.getElementById("id5").firstChild.nodeValue = p.statusText;

View File

@@ -25,21 +25,37 @@ try {
// In Mozilla, you can only create the text string if you can bybass security, like in chrome
var sendPlainTextData = false;
var docsize = 400; // the document has docsize*2+1 elements
var x;
if (!sendPlainTextData) {
try {
x = document.implementation.createDocument("", "test", null);
x.documentElement.appendChild(document.createElement("Foo"));
x.documentElement.appendChild(document.createElement("Bar"));
x.documentElement.firstChild.appendChild(document.createTextNode("My Stuff\nYeah"));
var i;
for (i = 0; i < docsize; i++) {
var fooElement = document.createElement("Foo");
fooElement.appendChild(document.createTextNode("My Stuff\nYeah"));
x.documentElement.appendChild(fooElement);
x.documentElement.appendChild(document.createElement("Bar"));
}
} catch (e) {
x = new ActiveXObject("Msxml2.DOMDocument");
x.loadXML("<?xml version='1.0'?>\n<test><foo>My Stuff\nYeah</foo><bar/></test>");
var str = "<?xml version='1.0'?>\n<test>";
var i;
for (i = 0; i < docsize; i++) {
str += "<Foo>My Stuff\nYeah</Foo><Bar/>";
}
str += "</test>";
x.loadXML(str);
}
}
var interactiveCount = 0;
function myfunc()
{
if (p.readyState == 3) {
interactiveCount++;
}
//alert("myfunc readyState=" + p.readyState);
//if (p.readyState == 2) {
// alert(p.getAllResponseHeaders());
@@ -48,9 +64,9 @@ function myfunc()
if (p.readyState != 4)
return;
var str;
if (!sendPlainTextData) {
document.getElementById("id1").firstChild.nodeValue = p.responseText;
if (p.responseXML) {
var str;
try {
var s = new XMLSerializer();
var d = p.responseXML;
@@ -58,15 +74,13 @@ function myfunc()
} catch (e) {
str = "@@TODO@@";
}
} else {
str = p.responseText;
document.getElementById("id2").firstChild.nodeValue = str;
}
document.getElementById("id1").firstChild.nodeValue = p.responseText;
document.getElementById("id2").firstChild.nodeValue = str;
document.getElementById("id3").firstChild.nodeValue = p.getAllResponseHeaders();
document.getElementById("id4").firstChild.nodeValue = p.status;
document.getElementById("id5").firstChild.nodeValue = p.statusText;
document.getElementById("id6").firstChild.nodeValue = p.readyState;
document.getElementById("id7").firstChild.nodeValue = interactiveCount;
}
// p.onload would also work in Mozilla
@@ -122,6 +136,9 @@ if (!sendPlainTextData) {
<div class="box"><span class="boxheader">readyState</span>
<pre id="id6">@@No result@@</pre>
</div>
<div class="box"><span class="boxheader"># of times onreadystatechanged handler called with INTERACTIVE status</span>
<pre id="id7">@@No result@@</pre>
</div>
</body>
</html>