зеркало из https://github.com/mozilla/pjs.git
XForms bug 310109 - XForms model-destruct event doesn't work with fastback. Patch by aaronr, r=smaug,me
This commit is contained in:
Родитель
a0bcb37a51
Коммит
c75e9de394
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче