mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 305763, Application control models and fixes to lazy instances, r=aaronr+allan
This commit is contained in:
parent
db2b6408e1
commit
5ffd707e38
@ -151,7 +151,6 @@ CPPSRCS = \
|
||||
nsXFormsControlStub.cpp \
|
||||
nsXFormsUtilityService.cpp \
|
||||
nsXFormsDelegateStub.cpp \
|
||||
nsXFormsLazyInstanceElement.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS)
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -221,7 +221,7 @@ nsXFormsInsertDeleteElement::HandleAction(nsIDOMEvent *aEvent,
|
||||
NS_ENSURE_STATE(modelElem);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> 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,
|
||||
|
@ -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<nsIModelElementPrivate> 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<nsIModelElementPrivate> 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<nsIURI> 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<nsIDOMElement> 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<nsIDocument> 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<nsISupports> 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<nsIDocument> 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<nsIDOMNode> newNode;
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMDocument> domDoc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
NS_ENSURE_STATE(domDoc);
|
||||
|
||||
nsCOMPtr<nsIDOMDOMImplementation> domImpl;
|
||||
nsresult rv = domDoc->GetImplementation(getter_AddRefs(domImpl));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> 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<nsIDOMElement> instanceDataElement;
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMDocument> 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<nsIDocument> 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
|
||||
|
@ -92,7 +92,8 @@ private:
|
||||
nsCOMPtr<nsIDOMDocument> mOriginalDocument;
|
||||
nsIDOMElement *mElement;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
PRBool mIgnoreAttributeChanges;
|
||||
PRBool mAddingChildren;
|
||||
PRBool mLazy;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
};
|
||||
|
||||
|
@ -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 <aaronr@us.ibm.com>
|
||||
*
|
||||
* 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<nsIDOMNode> newNode;
|
||||
nsCOMPtr<nsIDOMElement> instanceRoot;
|
||||
rv = mDocument->GetDocumentElement(getter_AddRefs(instanceRoot));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(instanceRoot, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMNode> newNode, instanceRootNode, nodeReturn;
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDocument> d = do_QueryInterface(aXFormsDocument);
|
||||
if (d && !d->GetScriptGlobalObject())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMDOMImplementation> 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<nsIDOMElement> instanceDataElement;
|
||||
nsCOMPtr<nsIDOMNode> 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;
|
||||
}
|
@ -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 <aaronr@us.ibm.com>
|
||||
*
|
||||
* 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 \<instance\> 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<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIDOMDocument> mOriginalDocument;
|
||||
};
|
||||
|
||||
#endif
|
@ -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 <xforms:intance> element is created in anonymous content using XBL.
|
||||
PRUint32 instCount = mInstanceList.Count();
|
||||
if (!instCount) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (domDoc) {
|
||||
nsXFormsLazyInstanceElement *lazyInstance =
|
||||
new nsXFormsLazyInstanceElement();
|
||||
lazyInstance->CreateLazyInstanceDocument(domDoc);
|
||||
AddInstanceElement(lazyInstance);
|
||||
mLazyModel = PR_TRUE;
|
||||
nsCOMPtr<nsIDOMDocumentXBL> 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<nsIDOMNodeList> 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<nsIDOMNode> item;
|
||||
list->Item(i, getter_AddRefs(item));
|
||||
nsCOMPtr<nsIInstanceElementPrivate> instance =
|
||||
do_QueryInterface(item);
|
||||
if (instance) {
|
||||
rv = instance->InitializeLazyInstance();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mLazyModel = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,7 +526,7 @@ nsXFormsSubmissionElement::LoadReplaceInstance(nsIChannel *channel)
|
||||
rv = GetBoundInstanceData(getter_AddRefs(data));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMNode> instanceNode;
|
||||
nsCOMPtr<nsIModelElementPrivate> 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<nsIModelElementPrivate> model = GetModel();
|
||||
node = do_QueryInterface(model);
|
||||
NS_ENSURE_STATE(node);
|
||||
rv = AddNameSpaces(newDocElm, node, prefixHash);
|
||||
|
@ -1176,50 +1176,31 @@ nsXFormsUtils::MakeUniqueAndSort(nsCOMArray<nsIDOMNode> *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 <xf:instance> 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<nsIDOMDocument> instanceDoc;
|
||||
aInstanceDataNode->GetOwnerDocument(getter_AddRefs(instanceDoc));
|
||||
nsCOMPtr<nsIDOMDocument> 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<nsIDocument> instanceDoc(do_QueryInterface(instanceDOMDoc));
|
||||
NS_ENSURE_TRUE(instanceDoc, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMArray<nsIInstanceElementPrivate> *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<nsIInstanceElementPrivate> instPriv = instList->ObjectAt(i);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> 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<nsIDOMElement> instanceElement;
|
||||
instPriv->GetElement(getter_AddRefs(instanceElement));
|
||||
if (instanceElement) {
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(instanceElement);
|
||||
node.swap(*aInstanceNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMNode> context, temp;
|
||||
aElement->GetParentNode(getter_AddRefs(context));
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
while (context) {
|
||||
if (nsXFormsUtils::IsXFormsElement(context,
|
||||
aFindContainer ?
|
||||
|
@ -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 <xf:instance> for a given instance data node.
|
||||
*/
|
||||
static NS_HIDDEN_(nsresult) GetInstanceNodeForData(nsIDOMNode *aInstanceDataNode,
|
||||
nsIModelElementPrivate *aModel,
|
||||
nsIDOMNode **aInstanceNode);
|
||||
|
||||
/**
|
||||
|
@ -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">
|
||||
|
||||
<binding id="xforms-lazy-instance">
|
||||
<content><xforms:instance lazy:lazy="true"/><children/></content>
|
||||
</binding>
|
||||
|
||||
<!-- BASE -->
|
||||
<binding id="xformswidget-base">
|
||||
|
Loading…
Reference in New Issue
Block a user