XForms bug 310109 - XForms model-destruct event doesn't work with fastback. Patch by aaronr, r=smaug,me

This commit is contained in:
doronr%us.ibm.com 2005-12-13 21:19:58 +00:00
Родитель a0bcb37a51
Коммит c75e9de394
7 изменённых файлов: 153 добавлений и 105 удалений

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

@ -80,19 +80,13 @@ nsXFormsLoadElement::HandleAction(nsIDOMEvent* aEvent,
return NS_OK;
nsCOMPtr<nsIDOMDocument> doc;
nsCOMPtr<nsIDOMWindowInternal> internal;
mElement->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocumentView> dview(do_QueryInterface(doc));
if (!dview)
return NS_OK;
nsCOMPtr<nsIDOMAbstractView> aview;
dview->GetDefaultView(getter_AddRefs(aview));
nsCOMPtr<nsIDOMWindowInternal> internal(do_QueryInterface(aview));
NS_ASSERTION(internal, "No AbstractView or it isn't an nsIDOMWindowInternal");
if (!internal)
nsXFormsUtils::GetWindowFromDocument(doc, getter_AddRefs(internal));
if (!internal) {
NS_ASSERTION(internal, "No AbstractView or it isn't an nsIDOMWindowInternal");
return NS_OK;
}
PRBool openNew = PR_FALSE;
nsAutoString show;

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

@ -457,20 +457,12 @@ PRBool
nsXFormsMessageElement::HandleInlineAlert(nsIDOMEvent* aEvent)
{
nsCOMPtr<nsIDOMDocument> doc;
nsCOMPtr<nsIDOMWindowInternal> internal;
mElement->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocumentView> dview(do_QueryInterface(doc));
if (!dview)
return PR_FALSE;
nsCOMPtr<nsIDOMAbstractView> aview;
dview->GetDefaultView(getter_AddRefs(aview));
if (!aview)
return PR_FALSE;
nsCOMPtr<nsIDOMWindowInternal> internal(do_QueryInterface(aview));
if (!internal)
nsXFormsUtils::GetWindowFromDocument(doc, getter_AddRefs(internal));
if (!internal) {
return PR_FALSE;
}
nsCOMPtr<nsIDOMViewCSS> cssView(do_QueryInterface(internal));
if (!cssView)
@ -601,16 +593,11 @@ nsresult
nsXFormsMessageElement::HandleModalAndModelessMessage(nsIDOMDocument* aDoc,
nsAString& aLevel)
{
nsCOMPtr<nsIDOMDocumentView> dview(do_QueryInterface(aDoc));
if (!dview)
return NS_OK;
nsCOMPtr<nsIDOMAbstractView> aview;
dview->GetDefaultView(getter_AddRefs(aview));
nsCOMPtr<nsIDOMWindowInternal> internal(do_QueryInterface(aview));
if (!internal)
nsCOMPtr<nsIDOMWindowInternal> internal;
nsXFormsUtils::GetWindowFromDocument(aDoc, getter_AddRefs(internal));
if (!internal) {
return NS_OK;
}
nsAutoString instanceData;
PRBool hasBinding = nsXFormsUtils::GetSingleNodeBindingValue(mElement,

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

@ -305,8 +305,16 @@ nsXFormsModelElement::RemoveModelFromDocument()
RemoveFromModelList(domDoc, this);
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(domDoc);
if (targ)
if (targ) {
targ->RemoveEventListener(NS_LITERAL_STRING("DOMContentLoaded"), this, PR_TRUE);
nsCOMPtr<nsIDOMWindowInternal> window;
nsXFormsUtils::GetWindowFromDocument(domDoc, getter_AddRefs(window));
targ = do_QueryInterface(window);
if (targ) {
targ->RemoveEventListener(NS_LITERAL_STRING("unload"), this, PR_TRUE);
}
}
}
NS_IMETHODIMP
@ -321,10 +329,6 @@ NS_IMETHODIMP
nsXFormsModelElement::WillChangeDocument(nsIDOMDocument* aNewDocument)
{
RemoveModelFromDocument();
if(!aNewDocument) {
// can't send this much later or the model won't still be in the document!
nsXFormsUtils::DispatchEvent(mElement, eEvent_ModelDestruct);
}
return NS_OK;
}
@ -337,8 +341,16 @@ nsXFormsModelElement::DocumentChanged(nsIDOMDocument* aNewDocument)
AddToModelList(aNewDocument, this);
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(aNewDocument);
if (targ)
if (targ) {
targ->AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"), this, PR_TRUE);
nsCOMPtr<nsIDOMWindowInternal> window;
nsXFormsUtils::GetWindowFromDocument(aNewDocument, getter_AddRefs(window));
targ = do_QueryInterface(window);
if (targ) {
targ->AddEventListener(NS_LITERAL_STRING("unload"), this, PR_TRUE);
}
}
return NS_OK;
}
@ -924,63 +936,13 @@ nsXFormsModelElement::HandleEvent(nsIDOMEvent* aEvent)
nsAutoString type;
aEvent->GetType(type);
if (!type.EqualsLiteral("DOMContentLoaded"))
return NS_OK;
if (!mInstancesInitialized) {
// XXX This is for Bug 308106. In Gecko 1.8 DoneAddingChildren is not
// called in XUL if the element doesn't have any child nodes.
InitializeInstances();
if (type.EqualsLiteral("DOMContentLoaded")) {
return HandleLoad(aEvent);
}else if (type.EqualsLiteral("unload")) {
return HandleUnload(aEvent);
}
mDocumentLoaded = PR_TRUE;
// dispatch xforms-model-construct, xforms-rebuild, xforms-recalculate,
// xforms-revalidate
// We wait until DOMContentLoaded to dispatch xforms-model-construct,
// since the model may have an action handler for this event and Mozilla
// doesn't register XML Event listeners until the document is loaded.
// xforms-model-construct is not cancellable, so always proceed.
nsXFormsUtils::DispatchEvent(mElement, eEvent_ModelConstruct);
if (mPendingInlineSchemas.Count() > 0) {
nsCOMPtr<nsIDOMElement> el;
nsresult rv;
for (PRInt32 i=0; i<mPendingInlineSchemas.Count(); ++i) {
GetSchemaElementById(mElement, *mPendingInlineSchemas[i],
getter_AddRefs(el));
if (!el) {
rv = NS_ERROR_UNEXPECTED;
} else {
nsCOMPtr<nsISchema> schema;
// no need to observe errors via the callback. instead, rely on
// this method returning a failure code when it encounters errors.
rv = mSchemas->ProcessSchemaElement(el, nsnull,
getter_AddRefs(schema));
if (NS_SUCCEEDED(rv))
mSchemaCount++;
}
if (NS_FAILED(rv)) {
// this is a fatal error (XXX)
nsXFormsUtils::ReportError(NS_LITERAL_STRING("schemaLoadError"), mElement);
nsXFormsUtils::DispatchEvent(mElement, eEvent_LinkException);
return NS_OK;
}
}
if (IsComplete()) {
rv = FinishConstruction();
NS_ENSURE_SUCCESS(rv, rv);
nsXFormsUtils::DispatchEvent(mElement, eEvent_Refresh);
}
mPendingInlineSchemas.Clear();
}
// We may still be waiting on external documents to load.
MaybeNotifyCompletion();
return NS_OK;
}
@ -1820,6 +1782,74 @@ nsXFormsModelElement::ProcessDeferredBinds(nsIDOMDocument *aDoc)
}
}
nsresult
nsXFormsModelElement::HandleLoad(nsIDOMEvent* aEvent)
{
if (!mInstancesInitialized) {
// XXX This is for Bug 308106. In Gecko 1.8 DoneAddingChildren is not
// called in XUL if the element doesn't have any child nodes.
InitializeInstances();
}
mDocumentLoaded = PR_TRUE;
// dispatch xforms-model-construct, xforms-rebuild, xforms-recalculate,
// xforms-revalidate
// We wait until DOMContentLoaded to dispatch xforms-model-construct,
// since the model may have an action handler for this event and Mozilla
// doesn't register XML Event listeners until the document is loaded.
// xforms-model-construct is not cancellable, so always proceed.
nsXFormsUtils::DispatchEvent(mElement, eEvent_ModelConstruct);
if (mPendingInlineSchemas.Count() > 0) {
nsCOMPtr<nsIDOMElement> el;
nsresult rv;
for (PRInt32 i=0; i<mPendingInlineSchemas.Count(); ++i) {
GetSchemaElementById(mElement, *mPendingInlineSchemas[i],
getter_AddRefs(el));
if (!el) {
rv = NS_ERROR_UNEXPECTED;
} else {
nsCOMPtr<nsISchema> schema;
// no need to observe errors via the callback. instead, rely on
// this method returning a failure code when it encounters errors.
rv = mSchemas->ProcessSchemaElement(el, nsnull,
getter_AddRefs(schema));
if (NS_SUCCEEDED(rv))
mSchemaCount++;
}
if (NS_FAILED(rv)) {
// this is a fatal error (XXX)
nsXFormsUtils::ReportError(NS_LITERAL_STRING("schemaLoadError"), mElement);
nsXFormsUtils::DispatchEvent(mElement, eEvent_LinkException);
return NS_OK;
}
}
if (IsComplete()) {
rv = FinishConstruction();
NS_ENSURE_SUCCESS(rv, rv);
nsXFormsUtils::DispatchEvent(mElement, eEvent_Refresh);
}
mPendingInlineSchemas.Clear();
}
// We may still be waiting on external documents to load.
MaybeNotifyCompletion();
return NS_OK;
}
nsresult
nsXFormsModelElement::HandleUnload(nsIDOMEvent* aEvent)
{
// due to fastback changes, had to move this notification out from under
// model's WillChangeDocument override.
return nsXFormsUtils::DispatchEvent(mElement, eEvent_ModelDestruct);
}
nsresult
NS_NewXFormsModelElement(nsIXTFElement **aResult)
{

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

@ -230,6 +230,16 @@ private:
PRBool IsComplete() const { return (mSchemaTotal == mSchemaCount
&& mPendingInstanceCount == 0); }
/**
* Called by HandleEvent. Event handler for the 'DOMContentLoaded' event.
*/
NS_HIDDEN_(nsresult) HandleLoad(nsIDOMEvent *aEvent);
/**
* Called by HandleEvent. Event handler for the 'unload' event.
*/
NS_HIDDEN_(nsresult) HandleUnload(nsIDOMEvent *aEvent);
nsIDOMElement *mElement;
nsCOMPtr<nsISchemaLoader> mSchemas;
nsStringArray mPendingInlineSchemas;

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

@ -198,12 +198,9 @@ nsXFormsUploadElement::PickFile()
// get nsIDOMWindowInternal
nsCOMPtr<nsIDOMDocument> doc;
nsCOMPtr<nsIDOMWindowInternal> internal;
mElement->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocumentView> dview = do_QueryInterface(doc);
NS_ENSURE_STATE(dview);
nsCOMPtr<nsIDOMAbstractView> aview;
dview->GetDefaultView(getter_AddRefs(aview));
nsCOMPtr<nsIDOMWindowInternal> internal = do_QueryInterface(aview);
rv = nsXFormsUtils::GetWindowFromDocument(doc, getter_AddRefs(internal));
NS_ENSURE_STATE(internal);
// init filepicker

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

@ -1610,16 +1610,12 @@ nsXFormsUtils::HandleBindingException(nsIDOMElement *aElement)
return PR_FALSE;
// Get nsIDOMWindowInternal
nsCOMPtr<nsIDOMDocumentView> dview(do_QueryInterface(doc));
if (!dview)
nsCOMPtr<nsIDOMWindowInternal> internal;
rv = nsXFormsUtils::GetWindowFromDocument(doc, getter_AddRefs(internal));
if (NS_FAILED(rv) || !internal) {
return PR_FALSE;
}
nsCOMPtr<nsIDOMAbstractView> aview;
dview->GetDefaultView(getter_AddRefs(aview));
nsCOMPtr<nsIDOMWindowInternal> internal(do_QueryInterface(aview));
if (!internal)
return PR_FALSE;
// Show popup
nsCOMPtr<nsIDOMWindow> messageWindow;
@ -1991,3 +1987,27 @@ nsXFormsUtils::AreNodesEqual(nsIDOMNode *aFirstNode, nsIDOMNode *aSecondNode,
return PR_TRUE;
}
/* static */
nsresult
nsXFormsUtils::GetWindowFromDocument(nsIDOMDocument *aDoc,
nsIDOMWindowInternal **aWindow)
{
NS_ENSURE_ARG(aDoc);
NS_ENSURE_ARG_POINTER(aWindow);
*aWindow = nsnull;
// Get nsIDOMWindowInternal
nsCOMPtr<nsIDOMDocumentView> dview(do_QueryInterface(aDoc));
NS_ENSURE_STATE(dview);
nsCOMPtr<nsIDOMAbstractView> aview;
dview->GetDefaultView(getter_AddRefs(aview));
nsCOMPtr<nsIDOMWindowInternal> internal(do_QueryInterface(aview));
NS_ENSURE_STATE(internal);
NS_ADDREF(*aWindow = internal);
return NS_OK;
}

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

@ -48,6 +48,7 @@
#include "nsIModelElementPrivate.h"
#include "nsIScriptError.h"
#include "nsVoidArray.h"
#include "nsIDOMWindowInternal.h"
class nsIDOMElement;
class nsIXFormsModelElement;
@ -498,6 +499,15 @@ public:
static NS_HIDDEN_(PRBool) AreNodesEqual(nsIDOMNode *aFirstNode,
nsIDOMNode *aSecondNode,
PRBool aAlreadyNormalized = PR_FALSE);
/**
* Retrieve the window object from the given document
*
* @param aDoc The document to get window object from
* @param aWindow The found window object
*/
static NS_HIDDEN_(nsresult) GetWindowFromDocument(nsIDOMDocument *aDoc,
nsIDOMWindowInternal **aWindow);
};
#endif