Bug 308106, controls not bound to external instance data in xul, r=aaronr+allan
This commit is contained in:
Родитель
3b13246fcd
Коммит
b898baab54
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче