Delays dispatching of document load event until all instances have been loaded. Bug 282351, r=aaronr/darin/me, patch by smaug@welho.com

This commit is contained in:
allan%beaufour.dk 2005-02-21 11:20:46 +00:00
Родитель 0235b4cc5c
Коммит eabc376c3c
2 изменённых файлов: 96 добавлений и 90 удалений

Просмотреть файл

@ -21,6 +21,7 @@
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
* Olli Pettay <Olli.Pettay@helsinki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -45,17 +46,18 @@
#include "nsXFormsAtoms.h"
#include "nsString.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOMDOMImplementation.h"
#include "nsIXTFGenericElementWrapper.h"
#include "nsXFormsUtils.h"
#include "nsNetUtil.h"
static const char* kLoadAsData = "loadAsData";
NS_IMPL_ISUPPORTS_INHERITED3(nsXFormsInstanceElement,
nsXFormsStubElement,
nsIInstanceElementPrivate,
nsIDOMLoadListener,
nsIDOMEventListener)
nsIStreamListener,
nsIRequestObserver)
nsXFormsInstanceElement::nsXFormsInstanceElement()
: mElement(nsnull)
@ -66,10 +68,7 @@ nsXFormsInstanceElement::nsXFormsInstanceElement()
NS_IMETHODIMP
nsXFormsInstanceElement::OnDestroyed()
{
nsCOMPtr<nsIDOMEventReceiver> rec = do_QueryInterface(mDocument);
if (rec)
rec->RemoveEventListenerByIID(this, NS_GET_IID(nsIDOMLoadListener));
mListener = nsnull;
mElement = nsnull;
return NS_OK;
}
@ -156,55 +155,60 @@ nsXFormsInstanceElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper)
return NS_OK;
}
// nsIDOMLoadListener
// nsIStreamListener
NS_IMETHODIMP
nsXFormsInstanceElement::Load(nsIDOMEvent *aEvent)
nsXFormsInstanceElement::OnStartRequest(nsIRequest *request, nsISupports *ctx)
{
NS_ASSERTION(mListener, "No stream listener for document!");
return mListener->OnStartRequest(request, ctx);
}
NS_IMETHODIMP
nsXFormsInstanceElement::OnDataAvailable(nsIRequest *aRequest,
nsISupports *ctxt,
nsIInputStream *inStr,
PRUint32 sourceOffset,
PRUint32 count)
{
NS_ASSERTION(mListener, "No stream listener for document!");
return mListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
}
NS_IMETHODIMP
nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx,
nsresult status)
{
NS_ASSERTION(mListener, "No stream listener for document!");
mListener->OnStopRequest(request, ctx, status);
PRBool succeeded = NS_SUCCEEDED(status);
if (!succeeded)
mDocument = nsnull;
if (mDocument) {
nsCOMPtr<nsIDOMElement> docElem;
mDocument->GetDocumentElement(getter_AddRefs(docElem));
if (docElem) {
nsAutoString tagName, namespaceURI;
docElem->GetTagName(tagName);
docElem->GetNamespaceURI(namespaceURI);
if (tagName.EqualsLiteral("parsererror") &&
namespaceURI.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) {
NS_WARNING("resulting instance document could not be parsed");
succeeded = PR_FALSE;
mDocument = nsnull;
}
}
}
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
if (model)
model->InstanceLoadFinished(PR_TRUE);
return NS_OK;
if (model) {
model->InstanceLoadFinished(succeeded);
}
NS_IMETHODIMP
nsXFormsInstanceElement::BeforeUnload(nsIDOMEvent *aEvent)
{
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::Unload(nsIDOMEvent *aEvent)
{
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::Abort(nsIDOMEvent *aEvent)
{
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
if (model)
model->InstanceLoadFinished(PR_FALSE);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::Error(nsIDOMEvent *aEvent)
{
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
if (model)
model->InstanceLoadFinished(PR_FALSE);
return NS_OK;
}
// nsIDOMEventListener
NS_IMETHODIMP
nsXFormsInstanceElement::HandleEvent(nsIDOMEvent *aEvent)
{
mListener = nsnull;
return NS_OK;
}
@ -332,38 +336,46 @@ nsXFormsInstanceElement::CloneInlineInstance()
void
nsXFormsInstanceElement::LoadExternalInstance(const nsAString &aSrc)
{
nsresult rv = NS_ERROR_FAILURE;
// Clear out our existing instance data
if (NS_FAILED(CreateInstanceDocument()))
return;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
if (!doc)
return;
if (NS_SUCCEEDED(CreateInstanceDocument())) {
nsCOMPtr<nsIDocument> newDoc = do_QueryInterface(mDocument);
nsCOMPtr<nsIDOMDocument> domDoc;
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
if (doc) {
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aSrc, doc->GetDocumentCharacterSet().get(),
doc->GetDocumentURI());
if (!uri)
return;
PRBool success = PR_FALSE;
if (uri) {
if (nsXFormsUtils::CheckSameOrigin(doc->GetDocumentURI(), uri)) {
nsCOMPtr<nsIDOMEventReceiver> rec = do_QueryInterface(mDocument);
rec->AddEventListenerByIID(this, NS_GET_IID(nsIDOMLoadListener));
nsCOMPtr<nsILoadGroup> loadGroup;
loadGroup = doc->GetDocumentLoadGroup();
NS_WARN_IF_FALSE(loadGroup, "No load group!");
nsCOMPtr<nsIDOMXMLDocument> xmlDoc = do_QueryInterface(mDocument);
NS_ASSERTION(xmlDoc, "we created a document but it's not an XMLDocument?");
// Using the same load group as the main document and creating
// the channel with LOAD_NORMAL flag delays the dispatching of
// the 'load' event until all instance data documents have been loaded.
nsCOMPtr<nsIChannel> docChannel;
NS_NewChannel(getter_AddRefs(docChannel), uri, nsnull, loadGroup,
nsnull, nsIRequest::LOAD_NORMAL);
nsCAutoString spec;
uri->GetSpec(spec);
xmlDoc->Load(NS_ConvertUTF8toUTF16(spec), &success);
if (docChannel) {
rv = newDoc->StartDocumentLoad(kLoadAsData, docChannel, loadGroup, nsnull,
getter_AddRefs(mListener), PR_TRUE);
if (NS_SUCCEEDED(rv))
rv = docChannel->AsyncOpen(this, nsnull);
}
}
}
}
}
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
if (model) {
model->InstanceLoadStarted();
if (!success) {
if (NS_FAILED(rv)) {
model->InstanceLoadFinished(PR_FALSE);
}
}

Просмотреть файл

@ -42,9 +42,10 @@
#include "nsXFormsStubElement.h"
#include "nsIDOMDocument.h"
#include "nsCOMPtr.h"
#include "nsIDOMLoadListener.h"
#include "nsIModelElementPrivate.h"
#include "nsIInstanceElementPrivate.h"
#include "nsIRequestObserver.h"
#include "nsIStreamListener.h"
class nsIDOMElement;
@ -56,11 +57,13 @@ class nsIDOMElement;
class nsXFormsInstanceElement : public nsXFormsStubElement,
public nsIInstanceElementPrivate,
public nsIDOMLoadListener
public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINSTANCEELEMENTPRIVATE
NS_DECL_NSISTREAMLISTENER
// nsIXTFGenericElement overrides
NS_IMETHOD OnDestroyed();
@ -70,16 +73,6 @@ public:
NS_IMETHOD DoneAddingChildren();
NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper);
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
// nsIDOMLoadListener
NS_IMETHOD Load(nsIDOMEvent *aEvent);
NS_IMETHOD BeforeUnload(nsIDOMEvent *aEvent);
NS_IMETHOD Unload(nsIDOMEvent *aEvent);
NS_IMETHOD Abort(nsIDOMEvent *aEvent);
NS_IMETHOD Error(nsIDOMEvent *aEvent);
nsXFormsInstanceElement() NS_HIDDEN;
private:
@ -91,6 +84,7 @@ private:
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIDOMDocument> mOriginalDocument;
nsIDOMElement *mElement;
nsCOMPtr<nsIStreamListener> mListener;
PRBool mIgnoreAttributeChanges;
};