Bug 308106, controls not bound to external instance data in xul, r=aaronr+allan

This commit is contained in:
Olli.Pettay%helsinki.fi 2005-10-28 18:52:56 +00:00
Родитель 8082f3a4a0
Коммит 24c4b2f21e
5 изменённых файлов: 114 добавлений и 105 удалений

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

@ -44,7 +44,7 @@ interface nsIDOMElement;
/**
* Private interface implemented by the instance element.
*/
[uuid(446dc7b6-91fc-4de5-b6de-5ac22538ee5e)]
[uuid(debb24ef-7ba1-4e01-9f62-18106b25c993)]
interface nsIInstanceElementPrivate : nsISupports
{
/**
@ -54,5 +54,5 @@ interface nsIInstanceElementPrivate : nsISupports
readonly attribute nsIDOMElement element;
void backupOriginalDocument();
void restoreOriginalDocument();
void initializeLazyInstance();
void initialize();
};

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

@ -63,7 +63,7 @@ NS_IMPL_ISUPPORTS_INHERITED5(nsXFormsInstanceElement,
nsXFormsInstanceElement::nsXFormsInstanceElement()
: mElement(nsnull)
, mAddingChildren(PR_FALSE)
, mInitialized(PR_FALSE)
, mLazy(PR_FALSE)
{
}
@ -87,7 +87,7 @@ NS_IMETHODIMP
nsXFormsInstanceElement::AttributeSet(nsIAtom *aName,
const nsAString &aNewValue)
{
if (mAddingChildren || mLazy)
if (!mInitialized || mLazy)
return NS_OK;
if (aName == nsXFormsAtoms::src) {
@ -100,7 +100,7 @@ nsXFormsInstanceElement::AttributeSet(nsIAtom *aName,
NS_IMETHODIMP
nsXFormsInstanceElement::AttributeRemoved(nsIAtom *aName)
{
if (mAddingChildren || mLazy)
if (!mInitialized || mLazy)
return NS_OK;
if (aName == nsXFormsAtoms::src) {
@ -135,51 +135,11 @@ nsXFormsInstanceElement::AttributeRemoved(nsIAtom *aName)
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::BeginAddingChildren()
{
mAddingChildren = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::DoneAddingChildren()
{
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);
// 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);
}
}
mAddingChildren = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper)
{
aWrapper->SetNotificationMask(nsIXTFElement::NOTIFY_ATTRIBUTE_SET |
nsIXTFElement::NOTIFY_ATTRIBUTE_REMOVED |
nsIXTFElement::NOTIFY_PARENT_CHANGED |
nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN |
nsIXTFElement::NOTIFY_DONE_ADDING_CHILDREN);
nsIXTFElement::NOTIFY_ATTRIBUTE_REMOVED);
nsCOMPtr<nsIDOMElement> node;
aWrapper->GetElementNode(getter_AddRefs(node));
@ -194,22 +154,6 @@ nsXFormsInstanceElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper)
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInstanceElement::ParentChanged(nsIDOMElement *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();
if (model) {
model->AddInstanceElement(this);
}
return NS_OK;
}
// nsIInterfaceRequestor
NS_IMETHODIMP
@ -445,49 +389,73 @@ nsXFormsInstanceElement::GetElement(nsIDOMElement **aElement)
}
NS_IMETHODIMP
nsXFormsInstanceElement::InitializeLazyInstance()
nsXFormsInstanceElement::Initialize()
{
NS_ENSURE_STATE(mElement);
if (!mLazy) {
mElement->HasAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_MOZ_XFORMS_LAZY),
NS_LITERAL_STRING("lazy"), &mLazy);
if (mInitialized || !mElement) {
return NS_OK;
}
NS_ENSURE_STATE(mLazy);
mInitialized = PR_TRUE;
nsCOMPtr<nsIDOMDocument> domDoc;
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_STATE(domDoc);
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
NS_ENSURE_TRUE(model, NS_ERROR_FAILURE);
model->AddInstanceElement(this);
nsCOMPtr<nsIDOMDOMImplementation> domImpl;
nsresult rv = domDoc->GetImplementation(getter_AddRefs(domImpl));
NS_ENSURE_SUCCESS(rv, rv);
mElement->HasAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_MOZ_XFORMS_LAZY),
NS_LITERAL_STRING("lazy"), &mLazy);
nsCOMPtr<nsIDOMDocument> newDoc;
rv = domImpl->CreateDocument(EmptyString(), EmptyString(), nsnull,
getter_AddRefs(newDoc));
NS_ENSURE_SUCCESS(rv, rv);
// Lazy instance
if (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!!");
} else {
// Normal instance
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!!");
// 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);
}
}
return NS_OK;
}

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

@ -75,10 +75,7 @@ public:
NS_IMETHOD OnDestroyed();
NS_IMETHOD AttributeSet(nsIAtom *aName, const nsAString &aNewValue);
NS_IMETHOD AttributeRemoved(nsIAtom *aName);
NS_IMETHOD BeginAddingChildren();
NS_IMETHOD DoneAddingChildren();
NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper);
NS_IMETHOD ParentChanged(nsIDOMElement *aNewParent);
nsXFormsInstanceElement() NS_HIDDEN;
@ -92,7 +89,7 @@ private:
nsCOMPtr<nsIDOMDocument> mOriginalDocument;
nsIDOMElement *mElement;
nsCOMPtr<nsIStreamListener> mListener;
PRBool mAddingChildren;
PRBool mInitialized;
PRBool mLazy;
nsCOMPtr<nsIChannel> mChannel;
};

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

@ -260,6 +260,7 @@ nsXFormsModelElement::nsXFormsModelElement()
mPendingInstanceCount(0),
mDocumentLoaded(PR_FALSE),
mNeedsRefresh(PR_FALSE),
mInstancesInitialized(PR_FALSE),
mInstanceDocuments(nsnull),
mLazyModel(PR_FALSE)
{
@ -346,6 +347,36 @@ nsXFormsModelElement::DocumentChanged(nsIDOMDocument* aNewDocument)
NS_IMETHODIMP
nsXFormsModelElement::DoneAddingChildren()
{
return InitializeInstances();
}
nsresult
nsXFormsModelElement::InitializeInstances()
{
if (mInstancesInitialized || !mElement) {
return NS_OK;
}
mInstancesInitialized = PR_TRUE;
nsCOMPtr<nsIDOMNodeList> children;
mElement->GetChildNodes(getter_AddRefs(children));
PRUint32 childCount = 0;
if (children) {
children->GetLength(&childCount);
}
for (PRUint32 i = 0; i < childCount; ++i) {
nsCOMPtr<nsIDOMNode> child;
children->Item(i, getter_AddRefs(child));
if (nsXFormsUtils::IsXFormsElement(child, NS_LITERAL_STRING("instance"))) {
nsCOMPtr<nsIInstanceElementPrivate> instance(do_QueryInterface(child));
if (instance) {
instance->Initialize();
}
}
}
// (XForms 4.2.1)
// 1. load xml schemas
@ -427,6 +458,9 @@ nsXFormsModelElement::DoneAddingChildren()
PRUint32 instCount;
mInstanceDocuments->GetLength(&instCount);
if (!instCount) {
#ifdef DEBUG
printf("Creating lazy instance\n");
#endif
nsCOMPtr<nsIDOMDocument> domDoc;
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(domDoc));
@ -437,8 +471,6 @@ nsXFormsModelElement::DoneAddingChildren()
NS_ENSURE_SUCCESS(rv, rv);
mInstanceDocuments->GetLength(&instCount);
NS_WARN_IF_FALSE(instCount == 1,
"Installing lazy instance didn't succeed!");
nsCOMPtr<nsIDOMNodeList> list;
xblDoc->GetAnonymousNodes(mElement, getter_AddRefs(list));
@ -454,7 +486,7 @@ nsXFormsModelElement::DoneAddingChildren()
nsCOMPtr<nsIInstanceElementPrivate> instance =
do_QueryInterface(item);
if (instance) {
rv = instance->InitializeLazyInstance();
rv = instance->Initialize();
NS_ENSURE_SUCCESS(rv, rv);
mLazyModel = PR_TRUE;
@ -463,6 +495,7 @@ nsXFormsModelElement::DoneAddingChildren()
}
}
}
NS_WARN_IF_FALSE(mLazyModel, "Installing lazy instance didn't succeed!");
}
// (XForms 4.2.1 - cont)
@ -893,6 +926,12 @@ nsXFormsModelElement::HandleEvent(nsIDOMEvent* aEvent)
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();
}
mDocumentLoaded = PR_TRUE;
// dispatch xforms-model-construct, xforms-rebuild, xforms-recalculate,

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

@ -178,6 +178,8 @@ private:
/** Initializes the MIPs on all form controls */
NS_HIDDEN_(nsresult) InitializeControls();
NS_HIDDEN_(nsresult) InitializeInstances();
NS_HIDDEN_(nsresult) ProcessBindElements();
NS_HIDDEN_(nsresult) FinishConstruction();
NS_HIDDEN_(nsresult) ConstructDone();
@ -253,6 +255,9 @@ private:
// xforms-revalidate yet
PRBool mNeedsRefresh;
// This flag indicates whether instance elements have been initialized
PRBool mInstancesInitialized;
/**
* All instance documents contained by this model, including lazy-authored
* instance documents.