diff --git a/mozilla/extensions/xforms/Makefile.in b/mozilla/extensions/xforms/Makefile.in index 551fecec5cf..a5fc5fb25b3 100644 --- a/mozilla/extensions/xforms/Makefile.in +++ b/mozilla/extensions/xforms/Makefile.in @@ -151,7 +151,6 @@ CPPSRCS = \ nsXFormsControlStub.cpp \ nsXFormsUtilityService.cpp \ nsXFormsDelegateStub.cpp \ - nsXFormsLazyInstanceElement.cpp \ $(NULL) EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS) diff --git a/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl b/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl index a114bd55447..1caef76db2f 100644 --- a/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl +++ b/mozilla/extensions/xforms/nsIInstanceElementPrivate.idl @@ -44,7 +44,7 @@ interface nsIDOMElement; /** * Private interface implemented by the instance element. */ -[uuid(8c9dd10d-4189-4a7b-a2eb-fd695cf33b27)] +[uuid(446dc7b6-91fc-4de5-b6de-5ac22538ee5e)] interface nsIInstanceElementPrivate : nsISupports { /** @@ -54,4 +54,5 @@ interface nsIInstanceElementPrivate : nsISupports readonly attribute nsIDOMElement element; void backupOriginalDocument(); void restoreOriginalDocument(); + void initializeLazyInstance(); }; diff --git a/mozilla/extensions/xforms/nsXFormsAtoms.cpp b/mozilla/extensions/xforms/nsXFormsAtoms.cpp index 252113a51a4..b134e959deb 100644 --- a/mozilla/extensions/xforms/nsXFormsAtoms.cpp +++ b/mozilla/extensions/xforms/nsXFormsAtoms.cpp @@ -64,6 +64,7 @@ nsIAtom *nsXFormsAtoms::readyForBindProperty; nsIAtom *nsXFormsAtoms::accesskey; nsIAtom *nsXFormsAtoms::fatalError; nsIAtom *nsXFormsAtoms::isInstanceDocument; +nsIAtom *nsXFormsAtoms::instanceDocumentOwner; const nsStaticAtom nsXFormsAtoms::Atoms_info[] = { { "src", &nsXFormsAtoms::src }, @@ -90,7 +91,8 @@ const nsStaticAtom nsXFormsAtoms::Atoms_info[] = { { "ReadyForBindProperty", &nsXFormsAtoms::readyForBindProperty }, { "accesskey", &nsXFormsAtoms::accesskey }, { "fatalError", &nsXFormsAtoms::fatalError }, - { "isInstanceDocument", &nsXFormsAtoms::isInstanceDocument } + { "isInstanceDocument", &nsXFormsAtoms::isInstanceDocument }, + { "instanceDocumentOwner", &nsXFormsAtoms::instanceDocumentOwner } }; void diff --git a/mozilla/extensions/xforms/nsXFormsAtoms.h b/mozilla/extensions/xforms/nsXFormsAtoms.h index e88f7a09a82..8168ee6638e 100644 --- a/mozilla/extensions/xforms/nsXFormsAtoms.h +++ b/mozilla/extensions/xforms/nsXFormsAtoms.h @@ -72,6 +72,7 @@ class nsXFormsAtoms static NS_HIDDEN_(nsIAtom *) accesskey; static NS_HIDDEN_(nsIAtom *) fatalError; static NS_HIDDEN_(nsIAtom *) isInstanceDocument; + static NS_HIDDEN_(nsIAtom *) instanceDocumentOwner; static NS_HIDDEN_(void) InitAtoms(); diff --git a/mozilla/extensions/xforms/nsXFormsInsertDeleteElement.cpp b/mozilla/extensions/xforms/nsXFormsInsertDeleteElement.cpp index a1ffa898048..4063887c7c8 100644 --- a/mozilla/extensions/xforms/nsXFormsInsertDeleteElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInsertDeleteElement.cpp @@ -221,7 +221,7 @@ nsXFormsInsertDeleteElement::HandleAction(nsIDOMEvent *aEvent, NS_ENSURE_STATE(modelElem); nsCOMPtr instNode; - rv = nsXFormsUtils::GetInstanceNodeForData(resNode, model, getter_AddRefs(instNode)); + rv = nsXFormsUtils::GetInstanceNodeForData(resNode, getter_AddRefs(instNode)); NS_ENSURE_SUCCESS(rv, rv); rv = nsXFormsUtils::DispatchEvent(instNode, diff --git a/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp b/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp index 2c3055eb403..46d60e02545 100644 --- a/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp @@ -63,7 +63,8 @@ NS_IMPL_ISUPPORTS_INHERITED5(nsXFormsInstanceElement, nsXFormsInstanceElement::nsXFormsInstanceElement() : mElement(nsnull) - , mIgnoreAttributeChanges(PR_FALSE) + , mAddingChildren(PR_FALSE) + , mLazy(PR_FALSE) { } @@ -77,6 +78,7 @@ nsXFormsInstanceElement::OnDestroyed() mChannel = nsnull; } mListener = nsnull; + SetDocument(nsnull); mElement = nsnull; return NS_OK; } @@ -85,7 +87,7 @@ NS_IMETHODIMP nsXFormsInstanceElement::AttributeSet(nsIAtom *aName, const nsAString &aNewValue) { - if (mIgnoreAttributeChanges) + if (mAddingChildren || mLazy) return NS_OK; if (aName == nsXFormsAtoms::src) { @@ -98,7 +100,7 @@ nsXFormsInstanceElement::AttributeSet(nsIAtom *aName, NS_IMETHODIMP nsXFormsInstanceElement::AttributeRemoved(nsIAtom *aName) { - if (mIgnoreAttributeChanges) + if (mAddingChildren || mLazy) return NS_OK; if (aName == nsXFormsAtoms::src) { @@ -136,31 +138,37 @@ nsXFormsInstanceElement::AttributeRemoved(nsIAtom *aName) NS_IMETHODIMP nsXFormsInstanceElement::BeginAddingChildren() { - // Ignore attribute changes during document construction. Attributes will be - // handled in the DoneAddingChildren. - mIgnoreAttributeChanges = PR_TRUE; + mAddingChildren = PR_TRUE; return NS_OK; } NS_IMETHODIMP nsXFormsInstanceElement::DoneAddingChildren() { - // By the time this is called, we should be inserted in the document and have - // all of our child elements, so this is our first opportunity to create the - // instance document. + + mElement->HasAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_MOZ_XFORMS_LAZY), + NS_LITERAL_STRING("lazy"), &mLazy); + if (!mLazy) { + nsCOMPtr model = GetModel(); + NS_ENSURE_TRUE(model, NS_ERROR_FAILURE); + model->AddInstanceElement(this); - nsAutoString src; - mElement->GetAttribute(NS_LITERAL_STRING("src"), src); - - if (src.IsEmpty()) { - // If we don't have a linked external instance, use our inline data. - CloneInlineInstance(); - } else { - LoadExternalInstance(src); + // By the time this is called, we should be inserted in the document and + // have all of our child elements, so this is our first opportunity to + // create the instance document. + + nsAutoString src; + mElement->GetAttribute(NS_LITERAL_STRING("src"), src); + + if (src.IsEmpty()) { + // If we don't have a linked external instance, use our inline data. + CloneInlineInstance(); + } else { + LoadExternalInstance(src); + } } - // Now, observe changes to the "src" attribute. - mIgnoreAttributeChanges = PR_FALSE; + mAddingChildren = PR_FALSE; return NS_OK; } @@ -189,14 +197,15 @@ nsXFormsInstanceElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) NS_IMETHODIMP nsXFormsInstanceElement::ParentChanged(nsIDOMElement *aNewParent) { - if (!aNewParent) + if (!aNewParent || mAddingChildren || mLazy) return NS_OK; // Once we are set up in the DOM, can find the model and make sure that this // instance is on the list of instance elements that model keeps nsCOMPtr model = GetModel(); - NS_ENSURE_TRUE(model, NS_ERROR_FAILURE); - model->AddInstanceElement(this); + if (model) { + model->AddInstanceElement(this); + } return NS_OK; } @@ -218,6 +227,8 @@ nsXFormsInstanceElement::OnChannelRedirect(nsIChannel *OldChannel, PRUint32 aFlags) { NS_PRECONDITION(aNewChannel, "Redirect without a channel?"); + NS_PRECONDITION(!mLazy, "Loading an instance document for a lazy instance?"); + nsCOMPtr newURI; nsresult rv = aNewChannel->GetURI(getter_AddRefs(newURI)); NS_ENSURE_SUCCESS(rv, rv); @@ -252,6 +263,7 @@ nsXFormsInstanceElement::OnChannelRedirect(nsIChannel *OldChannel, NS_IMETHODIMP nsXFormsInstanceElement::OnStartRequest(nsIRequest *request, nsISupports *ctx) { + NS_PRECONDITION(!mLazy, "Loading an instance document for a lazy instance?"); if (!mElement || !mListener) { return NS_OK; } @@ -265,6 +277,7 @@ nsXFormsInstanceElement::OnDataAvailable(nsIRequest *aRequest, PRUint32 sourceOffset, PRUint32 count) { + NS_PRECONDITION(!mLazy, "Loading an instance document for a lazy instance?"); if (!mElement || !mListener) { return NS_OK; } @@ -275,6 +288,7 @@ NS_IMETHODIMP nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult status) { + NS_PRECONDITION(!mLazy, "Loading an instance document for a lazy instance?"); if (status == NS_BINDING_ABORTED) { // looks like our element has already been destroyed. No use continuing on. return NS_OK; @@ -285,8 +299,9 @@ nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx, mListener->OnStopRequest(request, ctx, status); PRBool succeeded = NS_SUCCEEDED(status); - if (!succeeded) - mDocument = nsnull; + if (!succeeded) { + SetDocument(nsnull); + } if (mDocument) { nsCOMPtr docElem; @@ -300,7 +315,7 @@ nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx, namespaceURI.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) { NS_WARNING("resulting instance document could not be parsed"); succeeded = PR_FALSE; - mDocument = nsnull; + SetDocument(nsnull); } } } @@ -326,7 +341,26 @@ nsXFormsInstanceElement::GetDocument(nsIDOMDocument **aDocument) NS_IMETHODIMP nsXFormsInstanceElement::SetDocument(nsIDOMDocument *aDocument) { + nsCOMPtr doc(do_QueryInterface(mDocument)); + if (doc) { + doc->UnsetProperty(nsXFormsAtoms::instanceDocumentOwner); + } + mDocument = aDocument; + + doc = do_QueryInterface(mDocument); + if (doc) { + // Set property to prevent an instance document loading an external instance + // document + nsresult rv = doc->SetProperty(nsXFormsAtoms::isInstanceDocument, doc); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr owner(do_QueryInterface(mElement)); + NS_ENSURE_STATE(owner); + rv = doc->SetProperty(nsXFormsAtoms::instanceDocumentOwner, owner); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; } @@ -340,7 +374,12 @@ nsXFormsInstanceElement::BackupOriginalDocument() // that the instance document, whether external or inline, is loaded into // mDocument. Get the root node, clone it, and insert it into our copy of // the document. This is the magic behind getting xforms-reset to work. - if(mDocument && mOriginalDocument) { + nsCOMPtr origDoc(do_QueryInterface(mOriginalDocument)); + if(mDocument && origDoc) { + // xf:instance elements in original document must not try to load anything. + rv = origDoc->SetProperty(nsXFormsAtoms::isInstanceDocument, origDoc); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr newNode; nsCOMPtr instanceRoot; rv = mDocument->GetDocumentElement(getter_AddRefs(instanceRoot)); @@ -405,6 +444,54 @@ nsXFormsInstanceElement::GetElement(nsIDOMElement **aElement) return NS_OK; } +NS_IMETHODIMP +nsXFormsInstanceElement::InitializeLazyInstance() +{ + NS_ENSURE_STATE(mElement); + if (!mLazy) { + mElement->HasAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_MOZ_XFORMS_LAZY), + NS_LITERAL_STRING("lazy"), &mLazy); + } + + NS_ENSURE_STATE(mLazy); + + nsCOMPtr domDoc; + mElement->GetOwnerDocument(getter_AddRefs(domDoc)); + NS_ENSURE_STATE(domDoc); + + nsCOMPtr domImpl; + nsresult rv = domDoc->GetImplementation(getter_AddRefs(domImpl)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr newDoc; + rv = domImpl->CreateDocument(EmptyString(), EmptyString(), nsnull, + getter_AddRefs(newDoc)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = SetDocument(newDoc); + NS_ENSURE_SUCCESS(rv, rv); + + // Lazy authored instance documents have a root named "instanceData" + nsCOMPtr instanceDataElement; + nsCOMPtr childReturn; + rv = mDocument->CreateElementNS(EmptyString(), + NS_LITERAL_STRING("instanceData"), + getter_AddRefs(instanceDataElement)); + NS_ENSURE_SUCCESS(rv, rv); + rv = mDocument->AppendChild(instanceDataElement, getter_AddRefs(childReturn)); + NS_ENSURE_SUCCESS(rv, rv); + + // I don't know if not being able to create a backup document is worth + // failing this function. Since it probably won't be used often, we'll + // let it slide. But it probably does mean that things are going south + // with the browser. + domImpl->CreateDocument(EmptyString(), EmptyString(), nsnull, + getter_AddRefs(mOriginalDocument)); + NS_WARN_IF_FALSE(mOriginalDocument, "Couldn't create mOriginalDocument!!"); + + return NS_OK; +} + // private methods nsresult @@ -539,15 +626,12 @@ nsXFormsInstanceElement::CreateInstanceDocument() rv = doc->GetImplementation(getter_AddRefs(domImpl)); NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr newDoc; rv = domImpl->CreateDocument(EmptyString(), EmptyString(), nsnull, - getter_AddRefs(mDocument)); + getter_AddRefs(newDoc)); NS_ENSURE_SUCCESS(rv, rv); - // Set property to prevent an instance document loading an external instance - // document - nsCOMPtr idoc(do_QueryInterface(mDocument)); - NS_ENSURE_STATE(idoc); - rv = idoc->SetProperty(nsXFormsAtoms::isInstanceDocument, idoc); + rv = SetDocument(newDoc); NS_ENSURE_SUCCESS(rv, rv); // I don't know if not being able to create a backup document is worth diff --git a/mozilla/extensions/xforms/nsXFormsInstanceElement.h b/mozilla/extensions/xforms/nsXFormsInstanceElement.h index 0a40c2d0a46..f0531da5a88 100644 --- a/mozilla/extensions/xforms/nsXFormsInstanceElement.h +++ b/mozilla/extensions/xforms/nsXFormsInstanceElement.h @@ -92,7 +92,8 @@ private: nsCOMPtr mOriginalDocument; nsIDOMElement *mElement; nsCOMPtr mListener; - PRBool mIgnoreAttributeChanges; + PRBool mAddingChildren; + PRBool mLazy; nsCOMPtr mChannel; }; diff --git a/mozilla/extensions/xforms/nsXFormsLazyInstanceElement.cpp b/mozilla/extensions/xforms/nsXFormsLazyInstanceElement.cpp deleted file mode 100644 index 6a85a8d0731..00000000000 --- a/mozilla/extensions/xforms/nsXFormsLazyInstanceElement.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla XForms support. - * - * The Initial Developer of the Original Code is - * IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Aaron Reed - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsXFormsLazyInstanceElement.h" -#include "nsIDOMElement.h" -#include "nsIDocument.h" -#include "nsIDOMDOMImplementation.h" - -NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsLazyInstanceElement, - nsXFormsStubElement, - nsIInstanceElementPrivate, - nsIInterfaceRequestor) - -nsXFormsLazyInstanceElement::nsXFormsLazyInstanceElement() -{ -} - -// nsIInstanceElementPrivate - -NS_IMETHODIMP -nsXFormsLazyInstanceElement::GetDocument(nsIDOMDocument **aDocument) -{ - NS_IF_ADDREF(*aDocument = mDocument); - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsLazyInstanceElement::SetDocument(nsIDOMDocument *aDocument) -{ - mDocument = aDocument; - return NS_OK; -} - - -NS_IMETHODIMP -nsXFormsLazyInstanceElement::BackupOriginalDocument() -{ - nsresult rv = NS_OK; - - // This is called when xforms-ready is received by the model. By now we know - // that the lazy instance document has been populated and is loaded into - // mDocument. Get the root node, clone it, and insert it into our copy of - // the document. This is the magic behind getting xforms-reset to work. - if(mDocument && mOriginalDocument) { - nsCOMPtr newNode; - nsCOMPtr instanceRoot; - rv = mDocument->GetDocumentElement(getter_AddRefs(instanceRoot)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(instanceRoot, NS_ERROR_FAILURE); - - nsCOMPtr nodeReturn; - rv = instanceRoot->CloneNode(PR_TRUE, getter_AddRefs(newNode)); - if(NS_SUCCEEDED(rv)) { - rv = mOriginalDocument->AppendChild(newNode, getter_AddRefs(nodeReturn)); - NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), - "failed to set up original instance document"); - } - } - return rv; -} - -NS_IMETHODIMP -nsXFormsLazyInstanceElement::RestoreOriginalDocument() -{ - nsresult rv = NS_OK; - - // This is called when xforms-reset is received by the model. We assume - // that the backup of the lazy instance document has been populated and is - // loaded into mOriginalDocument. Get the backup's root node, clone it, and - // insert it into the live copy of the instance document. This is the magic - // behind getting xforms-reset to work. - if(mDocument && mOriginalDocument) { - nsCOMPtr newNode, instanceRootNode, nodeReturn; - nsCOMPtr instanceRoot; - - // first remove all the old stuff - rv = mDocument->GetDocumentElement(getter_AddRefs(instanceRoot)); - if(NS_SUCCEEDED(rv)) { - if(instanceRoot) { - rv = mDocument->RemoveChild(instanceRoot, getter_AddRefs(nodeReturn)); - NS_ENSURE_SUCCESS(rv, rv); - } - } - - // now all of the garbage is out o' there! Put the original data back - // into mDocument - rv = mOriginalDocument->GetDocumentElement(getter_AddRefs(instanceRoot)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(instanceRoot, NS_ERROR_FAILURE); - instanceRootNode = do_QueryInterface(instanceRoot); - - rv = instanceRootNode->CloneNode(PR_TRUE, getter_AddRefs(newNode)); - if(NS_SUCCEEDED(rv)) { - rv = mDocument->AppendChild(newNode, getter_AddRefs(nodeReturn)); - NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), - "failed to restore original instance document"); - } - } - return rv; -} - -NS_IMETHODIMP -nsXFormsLazyInstanceElement::GetElement(nsIDOMElement **aElement) -{ - *aElement = nsnull; - return NS_OK; -} - -// nsIInterfaceRequestor - -NS_IMETHODIMP -nsXFormsLazyInstanceElement::GetInterface(const nsIID & aIID, void **aResult) -{ - *aResult = nsnull; - return QueryInterface(aIID, aResult); -} - -nsresult -nsXFormsLazyInstanceElement::CreateLazyInstanceDocument(nsIDOMDocument *aXFormsDocument) -{ - NS_ENSURE_ARG(aXFormsDocument); - - // Do not try to load an instance document if the current document is not - // associated with a DOM window. This could happen, for example, if some - // XForms document loaded itself as instance data (which is what the Forms - // 1.0 testsuite does). - nsCOMPtr d = do_QueryInterface(aXFormsDocument); - if (d && !d->GetScriptGlobalObject()) - return NS_ERROR_FAILURE; - - nsCOMPtr domImpl; - nsresult rv = aXFormsDocument->GetImplementation(getter_AddRefs(domImpl)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = domImpl->CreateDocument(EmptyString(), EmptyString(), nsnull, - getter_AddRefs(mDocument)); - NS_ENSURE_SUCCESS(rv, rv); - - // Lazy authored instance documents have a root named "instanceData" - nsCOMPtr instanceDataElement; - nsCOMPtr childReturn; - rv = mDocument->CreateElementNS(EmptyString(), - NS_LITERAL_STRING("instanceData"), - getter_AddRefs(instanceDataElement)); - NS_ENSURE_SUCCESS(rv, rv); - rv = mDocument->AppendChild(instanceDataElement, getter_AddRefs(childReturn)); - NS_ENSURE_SUCCESS(rv, rv); - - // I don't know if not being able to create a backup document is worth - // failing this function. Since it probably won't be used often, we'll - // let it slide. But it probably does mean that things are going south - // with the browser. - domImpl->CreateDocument(EmptyString(), EmptyString(), nsnull, - getter_AddRefs(mOriginalDocument)); - return rv; -} diff --git a/mozilla/extensions/xforms/nsXFormsLazyInstanceElement.h b/mozilla/extensions/xforms/nsXFormsLazyInstanceElement.h deleted file mode 100644 index e4a4cf4b759..00000000000 --- a/mozilla/extensions/xforms/nsXFormsLazyInstanceElement.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla XForms support. - * - * The Initial Developer of the Original Code is - * IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Aaron Reed - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsXFormsLazyInstanceElement_h_ -#define nsXFormsLazyInstanceElement_h_ - -#include "nsXFormsStubElement.h" -#include "nsIDOMDocument.h" -#include "nsCOMPtr.h" -#include "nsIModelElementPrivate.h" -#include "nsIInstanceElementPrivate.h" -#include "nsIInterfaceRequestor.h" - -class nsIDOMElement; - -/** - * Implementation of the XForms \ element created through lazy - * authoring. It creates an instance document by cloning the contained - * instance data. - */ - -class nsXFormsLazyInstanceElement : public nsXFormsStubElement, - public nsIInstanceElementPrivate, - public nsIInterfaceRequestor -{ -public: - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIINSTANCEELEMENTPRIVATE - NS_DECL_NSIINTERFACEREQUESTOR - - NS_HIDDEN_(nsresult) CreateLazyInstanceDocument(nsIDOMDocument *aXFormsDocument); - - nsXFormsLazyInstanceElement() NS_HIDDEN; - -private: - - nsCOMPtr mDocument; - nsCOMPtr mOriginalDocument; -}; - -#endif diff --git a/mozilla/extensions/xforms/nsXFormsModelElement.cpp b/mozilla/extensions/xforms/nsXFormsModelElement.cpp index 738b6fd816f..4dccb731abc 100644 --- a/mozilla/extensions/xforms/nsXFormsModelElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsModelElement.cpp @@ -75,7 +75,10 @@ #include "nsISchema.h" #include "nsAutoPtr.h" #include "nsArray.h" -#include "nsXFormsLazyInstanceElement.h" +#include "nsIDOMDocumentXBL.h" + +#define XFORMS_LAZY_INSTANCE_BINDING \ + "chrome://xforms/content/xforms.xml#xforms-lazy-instance" #ifdef DEBUG //#define DEBUG_MODEL @@ -411,16 +414,43 @@ nsXFormsModelElement::DoneAddingChildren() // If all of the children are added and there aren't any instance elements, // yet, then we need to make sure that one is ready in case the form author // is using lazy authoring. + // Lazy element is created in anonymous content using XBL. PRUint32 instCount = mInstanceList.Count(); if (!instCount) { nsCOMPtr domDoc; mElement->GetOwnerDocument(getter_AddRefs(domDoc)); - if (domDoc) { - nsXFormsLazyInstanceElement *lazyInstance = - new nsXFormsLazyInstanceElement(); - lazyInstance->CreateLazyInstanceDocument(domDoc); - AddInstanceElement(lazyInstance); - mLazyModel = PR_TRUE; + nsCOMPtr xblDoc(do_QueryInterface(domDoc)); + if (xblDoc) { + nsresult rv = + xblDoc->AddBinding(mElement, + NS_LITERAL_STRING(XFORMS_LAZY_INSTANCE_BINDING)); + NS_ENSURE_SUCCESS(rv, rv); + + NS_WARN_IF_FALSE(mInstanceList.Count() == 1, + "Installing lazy instance didn't succeed!"); + + nsCOMPtr list; + xblDoc->GetAnonymousNodes(mElement, getter_AddRefs(list)); + if (list) { + PRUint32 childCount = 0; + if (list) { + list->GetLength(&childCount); + } + + for (PRUint32 i = 0; i < childCount; ++i) { + nsCOMPtr item; + list->Item(i, getter_AddRefs(item)); + nsCOMPtr instance = + do_QueryInterface(item); + if (instance) { + rv = instance->InitializeLazyInstance(); + NS_ENSURE_SUCCESS(rv, rv); + + mLazyModel = PR_TRUE; + break; + } + } + } } } diff --git a/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp b/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp index af36fe75a7c..7f367809c3c 100644 --- a/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsSubmissionElement.cpp @@ -526,7 +526,7 @@ nsXFormsSubmissionElement::LoadReplaceInstance(nsIChannel *channel) rv = GetBoundInstanceData(getter_AddRefs(data)); if (NS_SUCCEEDED(rv)) { nsCOMPtr instanceNode; - rv = nsXFormsUtils::GetInstanceNodeForData(data, model, + rv = nsXFormsUtils::GetInstanceNodeForData(data, getter_AddRefs(instanceNode)); NS_ENSURE_SUCCESS(rv, rv); @@ -839,8 +839,7 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data, newDoc->GetDocumentElement(getter_AddRefs(newDocElm)); nsCOMPtr instanceNode; - nsCOMPtr model = GetModel(); - rv = nsXFormsUtils::GetInstanceNodeForData(data, model, getter_AddRefs(instanceNode)); + rv = nsXFormsUtils::GetInstanceNodeForData(data, getter_AddRefs(instanceNode)); NS_ENSURE_SUCCESS(rv, rv); // add namespaces from the main document to the submission document, but only @@ -873,6 +872,7 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data, NS_ENSURE_SUCCESS(rv, rv); // handle namespaces on the model + nsCOMPtr model = GetModel(); node = do_QueryInterface(model); NS_ENSURE_STATE(node); rv = AddNameSpaces(newDocElm, node, prefixHash); diff --git a/mozilla/extensions/xforms/nsXFormsUtils.cpp b/mozilla/extensions/xforms/nsXFormsUtils.cpp index dee3a83209c..9d6de8ddcc2 100644 --- a/mozilla/extensions/xforms/nsXFormsUtils.cpp +++ b/mozilla/extensions/xforms/nsXFormsUtils.cpp @@ -1176,50 +1176,31 @@ nsXFormsUtils::MakeUniqueAndSort(nsCOMArray *aArray) /* static */ nsresult nsXFormsUtils::GetInstanceNodeForData(nsIDOMNode *aInstanceDataNode, - nsIModelElementPrivate *aModel, nsIDOMNode **aInstanceNode) { NS_ENSURE_ARG(aInstanceDataNode); - NS_ENSURE_ARG(aModel); NS_ENSURE_ARG_POINTER(aInstanceNode); *aInstanceNode = nsnull; - /* We want to get at the that aInstanceDataNode belongs to. - We get all xf:instance nodes in the aModel, QI it to nsIInstanceElementPrivate - and compare its document to the document aInstanceDataNode lives in. - */ - - nsCOMPtr instanceDoc; - aInstanceDataNode->GetOwnerDocument(getter_AddRefs(instanceDoc)); + nsCOMPtr instanceDOMDoc; + aInstanceDataNode->GetOwnerDocument(getter_AddRefs(instanceDOMDoc)); // owner doc is null when the data node is the document (e.g., ref="/") - if (!instanceDoc) - instanceDoc = do_QueryInterface(aInstanceDataNode); + if (!instanceDOMDoc) { + instanceDOMDoc = do_QueryInterface(aInstanceDataNode); + } + + nsCOMPtr instanceDoc(do_QueryInterface(instanceDOMDoc)); NS_ENSURE_TRUE(instanceDoc, NS_ERROR_UNEXPECTED); - nsCOMArray *instList = nsnull; - aModel->GetInstanceList(&instList); - NS_ENSURE_TRUE(instList, NS_ERROR_FAILURE); + nsISupports* owner = + NS_STATIC_CAST( + nsISupports*, + instanceDoc->GetProperty(nsXFormsAtoms::instanceDocumentOwner)); - PRUint32 i; - PRUint32 childCount = instList->Count(); - for (i = 0; i < childCount; ++i) { - nsCOMPtr instPriv = instList->ObjectAt(i); - - nsCOMPtr tmpDoc; - instPriv->GetDocument(getter_AddRefs(tmpDoc)); - - if (tmpDoc == instanceDoc) { - // ok, so we found the instance element that contains the provided - // aInstanceDataNode. Now set the return value. - nsCOMPtr instanceElement; - instPriv->GetElement(getter_AddRefs(instanceElement)); - if (instanceElement) { - nsCOMPtr node = do_QueryInterface(instanceElement); - node.swap(*aInstanceNode); - return NS_OK; - } - - } + nsCOMPtr instanceNode(do_QueryInterface(owner)); + if (instanceNode) { + NS_ADDREF(*aInstanceNode = instanceNode); + return NS_OK; } // Two possibilities. No instance nodes in model (which should never happen) @@ -1430,7 +1411,7 @@ FindRepeatContext(nsIDOMElement *aElement, PRBool aFindContainer) // save running up the tree? nsCOMPtr context, temp; aElement->GetParentNode(getter_AddRefs(context)); - nsresult rv; + nsresult rv = NS_OK; while (context) { if (nsXFormsUtils::IsXFormsElement(context, aFindContainer ? diff --git a/mozilla/extensions/xforms/nsXFormsUtils.h b/mozilla/extensions/xforms/nsXFormsUtils.h index 6f321df7901..1e4e17aff13 100644 --- a/mozilla/extensions/xforms/nsXFormsUtils.h +++ b/mozilla/extensions/xforms/nsXFormsUtils.h @@ -61,6 +61,7 @@ class nsIDOMEvent; #define NS_NAMESPACE_XML_SCHEMA "http://www.w3.org/2001/XMLSchema" #define NS_NAMESPACE_XML_SCHEMA_INSTANCE "http://www.w3.org/2001/XMLSchema-instance" #define NS_NAMESPACE_MOZ_XFORMS_TYPE "http://www.mozilla.org/projects/xforms/2005/type" +#define NS_NAMESPACE_MOZ_XFORMS_LAZY "http://www.mozilla.org/projects/xforms/2005/lazy" /** * XForms event types @@ -367,7 +368,6 @@ public: * Returns the for a given instance data node. */ static NS_HIDDEN_(nsresult) GetInstanceNodeForData(nsIDOMNode *aInstanceDataNode, - nsIModelElementPrivate *aModel, nsIDOMNode **aInstanceNode); /** diff --git a/mozilla/extensions/xforms/resources/content/xforms.xml b/mozilla/extensions/xforms/resources/content/xforms.xml index a7bce23dca9..ce772a26a49 100644 --- a/mozilla/extensions/xforms/resources/content/xforms.xml +++ b/mozilla/extensions/xforms/resources/content/xforms.xml @@ -42,7 +42,12 @@ xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xbl="http://www.mozilla.org/xbl" - xmlns:xforms="http://www.w3.org/2002/xforms"> + xmlns:xforms="http://www.w3.org/2002/xforms" + xmlns:lazy="http://www.mozilla.org/projects/xforms/2005/lazy"> + + + +