зеркало из https://github.com/mozilla/pjs.git
Bug 166978, XMLHttpRequest does not load synchronously in embedding applications, r=sicking, sr=darin. Bug 111614, DOMParser.parseFromString in modal dialog makes it non-modal. parseFromString also does not work in embedding when loading files that block the parser (like files with xml-stylesheet PI). r=sicking, sr=darin.
This commit is contained in:
Родитель
1c9034bc64
Коммит
eb03cb31f6
|
@ -58,21 +58,9 @@
|
|||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.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 "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsLoadListenerProxy.h"
|
||||
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
#endif
|
||||
|
||||
static const char* kLoadAsData = "loadAsData";
|
||||
|
||||
|
@ -293,20 +281,6 @@ 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)
|
||||
|
@ -318,11 +292,7 @@ nsDOMParser::HandleEvent(nsIDOMEvent* aEvent)
|
|||
nsresult
|
||||
nsDOMParser::Load(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (IsModal(mChromeWindow)) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
}
|
||||
|
||||
mChromeWindow = nsnull;
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -336,11 +306,7 @@ nsDOMParser::Unload(nsIDOMEvent* aEvent)
|
|||
nsresult
|
||||
nsDOMParser::Abort(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (IsModal(mChromeWindow)) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
}
|
||||
|
||||
mChromeWindow = nsnull;
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -348,27 +314,21 @@ nsDOMParser::Abort(nsIDOMEvent* aEvent)
|
|||
nsresult
|
||||
nsDOMParser::Error(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (IsModal(mChromeWindow)) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
}
|
||||
|
||||
mChromeWindow = nsnull;
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsDOMParser::nsDOMParser()
|
||||
: mLoopingForSyncLoad(PR_FALSE)
|
||||
{
|
||||
mEventQService = do_GetService(kEventQueueServiceCID);
|
||||
}
|
||||
|
||||
nsDOMParser::~nsDOMParser()
|
||||
{
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (IsModal(mChromeWindow)) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
}
|
||||
#endif
|
||||
NS_ABORT_IF_FALSE(!mLoopingForSyncLoad, "we rather crash than hang");
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -376,10 +336,8 @@ nsDOMParser::~nsDOMParser()
|
|||
NS_INTERFACE_MAP_BEGIN(nsDOMParser)
|
||||
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_EXTERNAL_DOM_CLASSINFO(DOMParser)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -549,7 +507,6 @@ 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) {
|
||||
|
@ -563,7 +520,6 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
|
|||
NS_GET_IID(nsIDOMLoadListener));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create a fake channel
|
||||
nsDOMParserChannel* parserChannel = new nsDOMParserChannel(baseURI, contentType);
|
||||
|
@ -581,67 +537,30 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
|
|||
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;
|
||||
}
|
||||
if(!mEventQService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mLoopingForSyncLoad = PR_TRUE;
|
||||
|
||||
rv = mEventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
#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);
|
||||
mEventQService->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;
|
||||
|
@ -655,29 +574,19 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
|
|||
}
|
||||
|
||||
rv = listener->OnStopRequest(request, nsnull, status);
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (modalEventQueue) {
|
||||
eventQService->PopThreadEventQueue(modalEventQueue);
|
||||
mEventQService->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);
|
||||
while (mLoopingForSyncLoad) {
|
||||
modalEventQueue->ProcessPendingEvents();
|
||||
}
|
||||
#endif
|
||||
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
|
||||
*_retval = domDocument;
|
||||
NS_ADDREF(*_retval);
|
||||
|
|
|
@ -44,19 +44,13 @@
|
|||
#include "nsISupportsUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
#define IMPLEMENT_SYNC_LOAD
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
#endif
|
||||
|
||||
class nsDOMParser : public nsIDOMParser
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
, public nsIDOMLoadListener
|
||||
, public nsSupportsWeakReference
|
||||
#endif
|
||||
class nsDOMParser : public nsIDOMParser,
|
||||
public nsIDOMLoadListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsDOMParser();
|
||||
|
@ -67,7 +61,6 @@ public:
|
|||
// nsIDOMParser
|
||||
NS_DECL_NSIDOMPARSER
|
||||
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
|
@ -76,14 +69,11 @@ public:
|
|||
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
|
||||
nsCOMPtr<nsIEventQueueService> mEventQService;
|
||||
PRBool mLoopingForSyncLoad;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -64,19 +64,9 @@
|
|||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsICodebasePrincipal.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsICharsetAlias.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 "nsIInterfaceRequestorUtils.h"
|
||||
#endif
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -94,9 +84,7 @@ static const char* kLoadAsData = "loadAsData";
|
|||
// CIDs
|
||||
static NS_DEFINE_CID(kIDOMDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID);
|
||||
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
#endif
|
||||
|
||||
static void
|
||||
GetCurrentContext(nsIScriptContext **aScriptContext)
|
||||
|
@ -143,6 +131,8 @@ nsXMLHttpRequest::nsXMLHttpRequest()
|
|||
ChangeState(XML_HTTP_REQUEST_UNINITIALIZED,PR_FALSE);
|
||||
mAsync = PR_TRUE;
|
||||
mCrossSiteAccessEnabled = PR_FALSE;
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
mEventQService = do_GetService(kEventQueueServiceCID);
|
||||
}
|
||||
|
||||
nsXMLHttpRequest::~nsXMLHttpRequest()
|
||||
|
@ -150,11 +140,9 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
|
|||
if (XML_HTTP_REQUEST_SENT == mStatus) {
|
||||
Abort();
|
||||
}
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (mChromeWindow) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_ABORT_IF_FALSE(!mLoopingForSyncLoad, "we rather crash than hang");
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -592,6 +580,34 @@ nsXMLHttpRequest::GetLoadGroup(nsILoadGroup **aLoadGroup)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLHttpRequest::GetBaseURI(nsIURI **aBaseURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aBaseURI);
|
||||
*aBaseURI = nsnull;
|
||||
|
||||
if (!mScriptContext) {
|
||||
GetCurrentContext(getter_AddRefs(mScriptContext));
|
||||
if (!mScriptContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
mScriptContext->GetGlobalObject(getter_AddRefs(global));
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(global);
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
window->GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (doc) {
|
||||
doc->GetBaseURL(*aBaseURI);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* noscript void openRequest (in string method, in string url, in boolean async, in string user, in string password); */
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::OpenRequest(const char *method,
|
||||
|
@ -680,23 +696,16 @@ nsXMLHttpRequest::Open(const char *method, const char *url)
|
|||
rv = cc->GetJSContext(&cx);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
|
||||
if (codebase) {
|
||||
codebase->GetURI(getter_AddRefs(mBaseURI));
|
||||
}
|
||||
}
|
||||
GetBaseURI(getter_AddRefs(mBaseURI));
|
||||
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
rv = NS_NewURI(getter_AddRefs(targetURI), url, mBaseURI);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = secMan->CheckConnect(cx, targetURI, "XMLHttpRequest","open");
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
|
@ -947,6 +956,8 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult
|
|||
ChangeState(XML_HTTP_REQUEST_STOPPED, PR_FALSE);
|
||||
}
|
||||
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -955,6 +966,8 @@ nsXMLHttpRequest::RequestCompleted()
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
// If we're uninitialized at this point, we encountered an error
|
||||
// earlier and listeners have already been notified. Also we do
|
||||
// not want to do this if we already completed.
|
||||
|
@ -1005,13 +1018,6 @@ nsXMLHttpRequest::RequestCompleted()
|
|||
|
||||
ChangeState(XML_HTTP_REQUEST_COMPLETED);
|
||||
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (mChromeWindow) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
mChromeWindow = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIJSContextStack> stack;
|
||||
JSContext *cx = nsnull;
|
||||
|
||||
|
@ -1204,59 +1210,20 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
nsCOMPtr<nsIEventQueue> modalEventQueue;
|
||||
nsCOMPtr<nsIEventQueueService> eventQService;
|
||||
|
||||
if (!mAsync) {
|
||||
nsCOMPtr<nsIXPCNativeCallContext> cc;
|
||||
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
|
||||
if(NS_SUCCEEDED(rv)) {
|
||||
rv = xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
|
||||
|
||||
if (!mAsync) {
|
||||
if(!mEventQService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && cc) {
|
||||
JSContext* cx;
|
||||
rv = cc->GetJSContext(&cx);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
mLoopingForSyncLoad = PR_TRUE;
|
||||
|
||||
// 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;
|
||||
}
|
||||
rv = mEventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mScriptContext) {
|
||||
// We need a context to check if redirect (if any) is allowed
|
||||
|
@ -1271,16 +1238,12 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
getter_AddRefs(listener),
|
||||
PR_TRUE);
|
||||
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (NS_FAILED(rv)) {
|
||||
if (modalEventQueue) {
|
||||
eventQService->PopThreadEventQueue(modalEventQueue);
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#else
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
|
||||
// Hook us up to listen to redirects and the like
|
||||
mChannel->SetNotificationCallbacks(this);
|
||||
|
@ -1290,27 +1253,21 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
mXMLParserStreamListener = listener;
|
||||
rv = mChannel->AsyncOpen(this, nsnull);
|
||||
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (NS_FAILED(rv)) {
|
||||
if (modalEventQueue) {
|
||||
eventQService->PopThreadEventQueue(modalEventQueue);
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#else
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
// If we're synchronous, spin an event loop here and wait
|
||||
if (!mAsync && mChromeWindow) {
|
||||
rv = mChromeWindow->ShowAsModal();
|
||||
|
||||
eventQService->PopThreadEventQueue(modalEventQueue);
|
||||
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
if (!mAsync) {
|
||||
while (mLoopingForSyncLoad) {
|
||||
modalEventQueue->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1411,12 +1368,8 @@ nsXMLHttpRequest::Abort(nsIDOMEvent* aEvent)
|
|||
}
|
||||
mDocument = nsnull;
|
||||
ChangeState(XML_HTTP_REQUEST_UNINITIALIZED);
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (mChromeWindow) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
mChromeWindow = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1426,12 +1379,8 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEvent)
|
|||
{
|
||||
mDocument = nsnull;
|
||||
ChangeState(XML_HTTP_REQUEST_UNINITIALIZED);
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
if (mChromeWindow) {
|
||||
mChromeWindow->ExitModalEventLoop(NS_OK);
|
||||
mChromeWindow = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIJSContextStack> stack;
|
||||
JSContext *cx = nsnull;
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#ifndef nsXMLHttpRequest_h__
|
||||
#define nsXMLHttpRequest_h__
|
||||
|
||||
#define IMPLEMENT_SYNC_LOAD
|
||||
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -52,9 +50,8 @@
|
|||
#include "nsIHttpChannel.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#endif
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -135,15 +132,13 @@ protected:
|
|||
nsresult ChangeState(nsXMLHttpRequestState aState, PRBool aBroadcast = PR_TRUE);
|
||||
nsresult RequestCompleted();
|
||||
nsresult GetLoadGroup(nsILoadGroup **aLoadGroup);
|
||||
nsresult GetBaseURI(nsIURI **aBaseURI);
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsIRequest> mReadRequest;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
#ifdef IMPLEMENT_SYNC_LOAD
|
||||
nsCOMPtr<nsIWebBrowserChrome> mChromeWindow;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsISupportsArray> mLoadEventListeners;
|
||||
nsCOMPtr<nsISupportsArray> mErrorEventListeners;
|
||||
|
@ -154,6 +149,9 @@ protected:
|
|||
|
||||
nsCOMPtr<nsIOnReadystatechangeHandler> mOnReadystatechangeListener;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
|
||||
nsCOMPtr<nsIEventQueueService> mEventQService;
|
||||
|
||||
// used to implement getAllResponseHeaders()
|
||||
class nsHeaderVisitor : public nsIHttpHeaderVisitor {
|
||||
public:
|
||||
|
@ -167,14 +165,14 @@ protected:
|
|||
};
|
||||
|
||||
nsCString mResponseBody;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
|
||||
|
||||
nsCString mOverrideMimeType;
|
||||
|
||||
PRInt32 mStatus;
|
||||
PRPackedBool mAsync;
|
||||
PRPackedBool mParseResponseBody;
|
||||
PRPackedBool mCrossSiteAccessEnabled;
|
||||
nsCString mOverrideMimeType;
|
||||
PRPackedBool mLoopingForSyncLoad;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<head><title>Synchronized GET test</title>
|
||||
<style type="text/css">
|
||||
.box {
|
||||
display: box;
|
||||
display: block;
|
||||
border: 1px solid black;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
@ -22,9 +22,14 @@ function execute()
|
|||
p.open("GET", "http://green/heikki/data.xml",false);
|
||||
p.send(null);
|
||||
|
||||
var str;
|
||||
try {
|
||||
var s = new XMLSerializer();
|
||||
var d = p.responseXML;
|
||||
var str = s.serializeToString(d);
|
||||
str = s.serializeToString(d);
|
||||
} catch (e) {
|
||||
str = e;
|
||||
}
|
||||
document.getElementById("id1").firstChild.nodeValue = p.responseText;
|
||||
document.getElementById("id2").firstChild.nodeValue = str;
|
||||
document.getElementById("id3").firstChild.nodeValue = p.getAllResponseHeaders();
|
||||
|
@ -33,10 +38,9 @@ function execute()
|
|||
document.getElementById("id6").firstChild.nodeValue = p.readyState;
|
||||
}
|
||||
|
||||
setTimeout(execute,0); // Enable the rest of this document to load before executing
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="execute();">
|
||||
<h1>Synchronized GET test</h1>
|
||||
|
||||
<div class="box"><span class="boxheader">responseText</span>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<head><title>Synchronized POST test</title>
|
||||
<style type="text/css">
|
||||
.box {
|
||||
display: box;
|
||||
display: block;
|
||||
border: 1px solid black;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ function execute()
|
|||
x.documentElement.appendChild(document.createTextNode("Foo"));
|
||||
x.documentElement.appendChild(x.createElementNS("http://www.w3.org/1999/xhtml","h1"));
|
||||
x.documentElement.lastChild.appendChild(document.createTextNode("My Document Header"));
|
||||
x.documentElement.lastChild.setAttributeNS("http://www.w3.org/1999/xhtml","id","id1")
|
||||
x.documentElement.lastChild.setAttribute("id","id1")
|
||||
|
||||
var p = new XMLHttpRequest();
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
|
||||
|
@ -30,10 +30,14 @@ function execute()
|
|||
|
||||
document.getElementById("id1").firstChild.nodeValue = p.responseText;
|
||||
if (p.responseXML) {
|
||||
try {
|
||||
var s = new XMLSerializer();
|
||||
var d = p.responseXML;
|
||||
var str = s.serializeToString(d);
|
||||
document.getElementById("id2").firstChild.nodeValue = str;
|
||||
} catch (e) {
|
||||
document.getElementById("id2").firstChild.nodeValue = e;
|
||||
}
|
||||
}
|
||||
document.getElementById("id3").firstChild.nodeValue = p.getAllResponseHeaders();
|
||||
document.getElementById("id4").firstChild.nodeValue = p.status;
|
||||
|
@ -41,10 +45,9 @@ function execute()
|
|||
document.getElementById("id6").firstChild.nodeValue = p.readyState;
|
||||
}
|
||||
|
||||
setTimeout(execute,0); // Enable the rest of this document to load before executing
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="execute();">
|
||||
<h1>Synchronized POST test</h1>
|
||||
|
||||
<div class="box"><span class="boxheader">responseText</span>
|
||||
|
|
Загрузка…
Ссылка в новой задаче