Fix nsXFormsModelElement::Rebuild() to work correctly. Patch by aaronr@us.ibm.com, r=allan@beaufour.dk, sr=me.

This commit is contained in:
bryner%brianryner.com 2005-01-31 23:41:00 +00:00
Родитель f1e0087257
Коммит 8ef2852244
17 изменённых файлов: 139 добавлений и 147 удалений

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

@ -138,4 +138,6 @@ CPPSRCS = \
EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS) EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS)
PREF_JS_EXPORTS = $(srcdir)/xforms.js
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

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

@ -89,6 +89,7 @@ public:
NS_IMETHOD CloneState(nsIDOMElement *aElement); NS_IMETHOD CloneState(nsIDOMElement *aElement);
// nsIXFormsControl // nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh(); NS_IMETHOD Refresh();
// nsIXFormsContextControl // nsIXFormsContextControl
@ -214,6 +215,13 @@ nsXFormsContextContainer::GetContext(nsAString &aModelID,
} }
// nsIXFormsControl // nsIXFormsControl
NS_IMETHODIMP
nsXFormsContextContainer::Bind()
{
return NS_OK;
}
nsresult nsresult
nsXFormsContextContainer::Refresh() nsXFormsContextContainer::Refresh()
{ {

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

@ -100,6 +100,30 @@ nsXFormsControlStub::GetElement(nsIDOMElement **aElement)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsXFormsControlStub::ResetBoundNode()
{
mBoundNode = nsnull;
nsCOMPtr<nsIModelElementPrivate> modelNode;
nsCOMPtr<nsIDOMXPathResult> result;
nsresult rv =
ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result),
getter_AddRefs(modelNode));
NS_ENSURE_SUCCESS(rv, rv);
if (!result) {
return NS_OK;
}
// Get context node, if any
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
return NS_OK;
}
/** /**
* @note Refresh() is always called after a Bind(), so if a control decides to * @note Refresh() is always called after a Bind(), so if a control decides to
* do all the work in Refresh() this function implements a NOP Bind(). * do all the work in Refresh() this function implements a NOP Bind().
@ -107,7 +131,7 @@ nsXFormsControlStub::GetElement(nsIDOMElement **aElement)
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsControlStub::Bind() nsXFormsControlStub::Bind()
{ {
return NS_OK; return ResetBoundNode();
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -83,6 +83,7 @@ public:
NS_IMETHOD GetBoundNode(nsIDOMNode **aBoundNode); NS_IMETHOD GetBoundNode(nsIDOMNode **aBoundNode);
NS_IMETHOD GetDependencies(nsIArray **aDependencies); NS_IMETHOD GetDependencies(nsIArray **aDependencies);
NS_IMETHOD GetElement(nsIDOMElement **aElement); NS_IMETHOD GetElement(nsIDOMElement **aElement);
NS_IMETHOD ResetBoundNode();
NS_IMETHOD Bind(); NS_IMETHOD Bind();
NS_IMETHOD TryFocus(PRBool* aOK); NS_IMETHOD TryFocus(PRBool* aOK);

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

@ -106,6 +106,7 @@ public:
NS_IMETHOD OnDestroyed(); NS_IMETHOD OnDestroyed();
// nsIXFormsControl // nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh(); NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK); NS_IMETHOD TryFocus(PRBool* aOK);
@ -181,6 +182,22 @@ nsXFormsGroupElement::OnDestroyed()
// nsIXFormsControl // nsIXFormsControl
NS_IMETHODIMP
nsXFormsGroupElement::Bind()
{
mModelID.Truncate();
// Re-evaluate what instance node this element is bound to.
ResetBoundNode();
// Get model ID
nsCOMPtr<nsIDOMElement> modelElement = do_QueryInterface(mModel);
NS_ENSURE_TRUE(modelElement, NS_ERROR_FAILURE);
modelElement->GetAttribute(NS_LITERAL_STRING("id"), mModelID);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsGroupElement::Refresh() nsXFormsGroupElement::Refresh()
{ {
@ -188,34 +205,6 @@ nsXFormsGroupElement::Refresh()
printf("nsXFormsGroupElement::Refresh()\n"); printf("nsXFormsGroupElement::Refresh()\n");
#endif #endif
if (!mHTMLElement)
return NS_OK;
mModelID.Truncate();
nsCOMPtr<nsIModelElementPrivate> modelNode;
nsCOMPtr<nsIDOMXPathResult> result;
nsresult rv =
ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result),
getter_AddRefs(modelNode));
NS_ENSURE_SUCCESS(rv, rv);
if (!result) {
return NS_OK;
}
// Get model ID
nsCOMPtr<nsIDOMElement> modelElement = do_QueryInterface(modelNode);
NS_ENSURE_TRUE(modelElement, NS_ERROR_FAILURE);
modelElement->GetAttribute(NS_LITERAL_STRING("id"), mModelID);
// Get context node, if any
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
NS_ENSURE_STATE(mBoundNode);
return NS_OK; return NS_OK;
} }

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

@ -77,7 +77,6 @@ public:
NS_IMETHOD OnDestroyed(); NS_IMETHOD OnDestroyed();
// nsIXFormsControl // nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh(); NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK); NS_IMETHOD TryFocus(PRBool* aOK);
@ -268,28 +267,6 @@ nsXFormsInputElement::Blur(nsIDOMEvent *aEvent)
// nsIXFormsControl // nsIXFormsControl
NS_IMETHODIMP
nsXFormsInputElement::Bind()
{
if (!mControl)
return NS_OK;
mBoundNode = nsnull;
nsCOMPtr<nsIDOMXPathResult> result;
nsresult rv = ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
if (result) {
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsInputElement::Refresh() nsXFormsInputElement::Refresh()
{ {

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

@ -168,22 +168,12 @@ nsXFormsLabelElement::RefreshLabel()
// or linking attributes are present, we don't want to show the inline text // or linking attributes are present, we don't want to show the inline text
// at all. // at all.
nsCOMPtr<nsIDOMXPathResult> result;
nsresult rv =
ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result));
nsAutoString labelValue; nsAutoString labelValue;
PRBool foundValue = PR_FALSE; PRBool foundValue = PR_FALSE;
if (NS_SUCCEEDED(rv) && result) { if (mBoundNode) {
result->GetSingleNodeValue(getter_AddRefs(mBoundNode)); nsXFormsUtils::GetNodeValue(mBoundNode, labelValue);
foundValue = PR_TRUE;
if (mBoundNode) {
nsXFormsUtils::GetNodeValue(mBoundNode, labelValue);
foundValue = PR_TRUE;
}
} }
// if (!foundValue) { // if (!foundValue) {

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

@ -423,11 +423,39 @@ nsXFormsModelElement::Rebuild()
// TODO: Clear graph and re-attach elements // TODO: Clear graph and re-attach elements
// 1 . Clear graph // 1 . Clear graph
// mMDG.Clear(); mMDG.Clear();
// 2. Re-attach all elements // 2. Re-attach all elements
// Copy the form control list as it stands right now.
nsVoidArray *oldFormList = new nsVoidArray();
*oldFormList = mFormControls;
// Clear out mFormControls so that we can rebuild the list. We'll go control
// by control over the old list and rebind the controls.
mFormControls.Clear();
PRInt32 controlCount = oldFormList->Count();
for (PRInt32 i = 0; i < controlCount; ++i) {
nsIXFormsControl* control = NS_STATIC_CAST(nsIXFormsControl*,
(*oldFormList)[i]);
/// @todo If a control is removed because of previous control has been
/// refreshed, we do, obviously, not need to refresh it. So mFormControls
/// should have weak bindings to the controls I guess? (XXX)
///
/// This could happen for \<repeatitem\>s for example.
if (!control) {
continue;
}
// run bind to reset mBoundNode for all of these controls and also, in the
// process, they will be added to the model that they should be bound to.
control->Bind();
}
// 3. Rebuild graph // 3. Rebuild graph
ProcessBindElements();
return mMDG.Rebuild(); return mMDG.Rebuild();
} }
@ -948,14 +976,13 @@ nsXFormsModelElement::FindInstanceDocument(const nsAString &aID)
} }
nsresult nsresult
nsXFormsModelElement::FinishConstruction() nsXFormsModelElement::ProcessBindElements()
{ {
// 3. if applicable, initialize P3P // ProcessBindElements() will go through each xforms:bind element in
// document order and apply all of the Model Item Properties to the
// 4. construct instance data from initial instance data. apply all // instance items in the nodeset. This information will also be entered
// <bind> elements in document order. // in the Master Dependency Graph. Most of this work is done in the
// ProcessBind() method.
// we get the instance data from our instance child nodes
nsCOMPtr<nsIDOMDocument> firstInstanceDoc = nsCOMPtr<nsIDOMDocument> firstInstanceDoc =
FindInstanceDocument(EmptyString()); FindInstanceDocument(EmptyString());
@ -996,6 +1023,21 @@ nsXFormsModelElement::FinishConstruction()
} }
} }
return NS_OK;
}
nsresult
nsXFormsModelElement::FinishConstruction()
{
// 3. if applicable, initialize P3P
// 4. construct instance data from initial instance data. apply all
// <bind> elements in document order.
// we get the instance data from our instance child nodes
ProcessBindElements();
// 5. dispatch xforms-rebuild, xforms-recalculate, xforms-revalidate // 5. dispatch xforms-rebuild, xforms-recalculate, xforms-revalidate
nsXFormsUtils::DispatchEvent(mElement, eEvent_Rebuild); nsXFormsUtils::DispatchEvent(mElement, eEvent_Rebuild);

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

@ -101,6 +101,7 @@ private:
NS_HIDDEN_(already_AddRefed<nsIDOMDocument>) NS_HIDDEN_(already_AddRefed<nsIDOMDocument>)
FindInstanceDocument(const nsAString &aID); FindInstanceDocument(const nsAString &aID);
NS_HIDDEN_(nsresult) ProcessBindElements();
NS_HIDDEN_(nsresult) FinishConstruction(); NS_HIDDEN_(nsresult) FinishConstruction();
NS_HIDDEN_(void) MaybeNotifyCompletion(); NS_HIDDEN_(void) MaybeNotifyCompletion();

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

@ -159,6 +159,7 @@ public:
NS_IMETHOD DoneAddingChildren(); NS_IMETHOD DoneAddingChildren();
// nsIXFormsControl // nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh(); NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK); NS_IMETHOD TryFocus(PRBool* aOK);
@ -280,6 +281,12 @@ nsXFormsRepeatElement::DoneAddingChildren()
// nsXFormsControl // nsXFormsControl
NS_IMETHODIMP
nsXFormsRepeatElement::Bind()
{
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsRepeatElement::Refresh() nsXFormsRepeatElement::Refresh()
{ {

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

@ -297,17 +297,11 @@ nsXFormsSelectElement::Refresh()
mSelect->SetSelectedIndex(-1); mSelect->SetSelectedIndex(-1);
} }
nsCOMPtr<nsIDOMXPathResult> result; // since single node binding is optional, we won't send an error code. But
rv = ProcessNodeBinding(NS_LITERAL_STRING("ref"), // there is no point continuing below without mBoundNode.
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE, if(!mBoundNode) {
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
if (result)
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
if (!mBoundNode)
return NS_OK; return NS_OK;
}
nsCOMPtr<nsIDOMNodeList> children; nsCOMPtr<nsIDOMNodeList> children;
mBoundNode->GetChildNodes(getter_AddRefs(children)); mBoundNode->GetChildNodes(getter_AddRefs(children));

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

@ -88,6 +88,7 @@ public:
NS_DECL_NSIXFORMSSWITCHELEMENT NS_DECL_NSIXFORMSSWITCHELEMENT
// nsIXFormsControl // nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh(); NS_IMETHOD Refresh();
NS_DECL_NSIXFORMSCONTEXTCONTROL NS_DECL_NSIXFORMSCONTEXTCONTROL
@ -117,8 +118,6 @@ private:
*/ */
void SetFocus(nsIDOMElement* aDeselected, nsIDOMElement* aSelected); void SetFocus(nsIDOMElement* aDeselected, nsIDOMElement* aSelected);
nsresult Process();
nsCOMPtr<nsIDOMElement> mVisual; nsCOMPtr<nsIDOMElement> mVisual;
nsCOMPtr<nsIDOMElement> mSelected; nsCOMPtr<nsIDOMElement> mSelected;
PRBool mDoneAddingChildren; PRBool mDoneAddingChildren;
@ -227,47 +226,29 @@ nsXFormsSwitchElement::DoneAddingChildren()
// nsIXFormsControl // nsIXFormsControl
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsSwitchElement::Refresh() nsXFormsSwitchElement::Bind()
{
nsresult rv = NS_OK;
if (mDoneAddingChildren) {
rv = Process();
}
return rv;
}
// nsXFormsSwitchElement
nsresult
nsXFormsSwitchElement::Process()
{ {
mModelID.Truncate(); mModelID.Truncate();
nsCOMPtr<nsIModelElementPrivate> modelNode; // Re-evaluate what instance node this element is bound to.
nsCOMPtr<nsIDOMXPathResult> result; ResetBoundNode();
nsresult rv =
ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result),
getter_AddRefs(modelNode));
NS_ENSURE_SUCCESS(rv, rv);
if (!result) {
return NS_OK;
}
// Get model ID // Get model ID
nsCOMPtr<nsIDOMElement> modelElement = do_QueryInterface(modelNode); nsCOMPtr<nsIDOMElement> modelElement = do_QueryInterface(mModel);
NS_ENSURE_TRUE(modelElement, NS_ERROR_FAILURE); NS_ENSURE_TRUE(modelElement, NS_ERROR_FAILURE);
modelElement->GetAttribute(NS_LITERAL_STRING("id"), mModelID); modelElement->GetAttribute(NS_LITERAL_STRING("id"), mModelID);
// Get context node, if any
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsXFormsSwitchElement::Refresh()
{
return NS_OK;
}
// nsXFormsSwitchElement
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsSwitchElement::SetContextNode(nsIDOMNode *aContextNode) nsXFormsSwitchElement::SetContextNode(nsIDOMNode *aContextNode)
{ {

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

@ -122,20 +122,6 @@ nsXFormsTriggerElement::GetInsertionPoint(nsIDOMElement **aElement)
NS_IMETHODIMP NS_IMETHODIMP
nsXFormsTriggerElement::Refresh() nsXFormsTriggerElement::Refresh()
{ {
nsCOMPtr<nsIDOMXPathResult> result;
nsresult rv =
ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
if (!result) {
return NS_OK;
}
// Get context node, if any
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
return NS_OK; return NS_OK;
} }

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

@ -248,22 +248,6 @@ nsXFormsUploadElement::Refresh()
if (!mInput) if (!mInput)
return NS_OK; return NS_OK;
mBoundNode = nsnull;
nsCOMPtr<nsIDOMXPathResult> result;
nsresult rv =
ProcessNodeBinding(NS_LITERAL_STRING("ref"),
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
if (result)
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
if (!mBoundNode)
return NS_OK;
nsCOMPtr<nsIContent> content = do_QueryInterface(mBoundNode); nsCOMPtr<nsIContent> content = do_QueryInterface(mBoundNode);
NS_ENSURE_STATE(content); NS_ENSURE_STATE(content);

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

@ -63,9 +63,11 @@ PACKAGE_VERSION = 0.1
xpi: xpi:
@echo Copying files to staging area... @echo Copying files to staging area...
rm -rf stage rm -rf stage
$(NSINSTALL) -D stage $(INSTALL) -D stage
$(PERL) $(topsrcdir)/xpinstall/packager/pkgcp.pl -o $(PKGCP_PLATFORM) -s $(DIST)/bin -d stage -f $(srcdir)/$(PACKAGE_FILE) -v $(PERL) $(topsrcdir)/xpinstall/packager/pkgcp.pl -o $(PKGCP_PLATFORM) -s $(DIST)/bin -d stage -f $(srcdir)/$(PACKAGE_FILE) -v
$(NSINSTALL) $(srcdir)/install.rdf stage/xforms $(INSTALL) $(srcdir)/install.rdf stage/xforms
$(INSTALL) -D stage/xforms/defaults/preferences
$(INSTALL) $(srcdir)/../xforms.js stage/xforms/defaults/preferences
@echo Creating install.js... @echo Creating install.js...
rm -f xforms.js rm -f xforms.js
$(PERL) $(topsrcdir)/toolkit/mozapps/installer/makejs.pl $(srcdir)/xforms.jst $(PACKAGE_VERSION) stage/xforms $(PERL) $(topsrcdir)/toolkit/mozapps/installer/makejs.pl $(srcdir)/xforms.jst $(PACKAGE_VERSION) stage/xforms

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

@ -11,6 +11,9 @@ if (verifyDiskSpace(fProgram, srChrome + srComponents))
logComment("addDirectory components: " + err); logComment("addDirectory components: " + err);
err = addDirectory("", "0.1", "chrome", fProgram, "chrome", true); err = addDirectory("", "0.1", "chrome", fProgram, "chrome", true);
logComment("addDirectory chrome: " + err); logComment("addDirectory chrome: " + err);
err = addFile("", "0.1", "defaults/preferences/xforms.js", fProgram,
"defaults/pref/xforms.js", true);
logComment("addFile xforms.js: " + err);
registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome", "xforms.jar"), registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome", "xforms.jar"),
"content/xforms/"); "content/xforms/");

1
extensions/xforms/xforms.js Executable file
Просмотреть файл

@ -0,0 +1 @@
pref("general.useragent.productComment", "xforms/1.0");