From 0259575605a14fe2280aa2b2c081bc8648acb2ce Mon Sep 17 00:00:00 2001 From: "allan%beaufour.dk" Date: Wed, 26 Apr 2006 09:54:12 +0000 Subject: [PATCH] [XForms] XBLize repeat. Bug 306247, r=me+smaug, patch by surkov@dc.baikal.ru git-svn-id: svn://10.0.0.236/trunk@195435 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/extensions/xforms/Makefile.in | 1 + .../xforms/nsIXFormsRepeatUIElement.idl | 52 ++++++ .../xforms/nsXFormsModelElement.cpp | 10 +- .../xforms/nsXFormsRepeatElement.cpp | 165 +++++++++++------- .../xforms/resources/content/xforms-xhtml.xml | 12 ++ .../xforms/resources/content/xforms-xul.xml | 14 +- .../xforms/resources/content/xforms.css | 9 + .../xforms/resources/content/xforms.xml | 20 +++ 8 files changed, 216 insertions(+), 67 deletions(-) create mode 100644 mozilla/extensions/xforms/nsIXFormsRepeatUIElement.idl diff --git a/mozilla/extensions/xforms/Makefile.in b/mozilla/extensions/xforms/Makefile.in index 11996dc8c19..f15336db750 100644 --- a/mozilla/extensions/xforms/Makefile.in +++ b/mozilla/extensions/xforms/Makefile.in @@ -142,6 +142,7 @@ XPIDLSRCS = \ nsIXFormsItemElement.idl \ nsIXFormsLabelElement.idl \ nsIXFormsItemSetUIElement.idl \ + nsIXFormsRepeatUIElement.idl \ nsIXFormsAccessors.idl \ nsIXFormsRangeAccessors.idl \ nsIXFormsUploadElement.idl \ diff --git a/mozilla/extensions/xforms/nsIXFormsRepeatUIElement.idl b/mozilla/extensions/xforms/nsIXFormsRepeatUIElement.idl new file mode 100644 index 00000000000..bba388fbdcc --- /dev/null +++ b/mozilla/extensions/xforms/nsIXFormsRepeatUIElement.idl @@ -0,0 +1,52 @@ +/* ***** 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 + * Olli Pettay. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 "nsISupports.idl" + +interface nsIDOMElement; + +/** + * Interface implemented by the XBL part of the repeat element. + */ +[scriptable, uuid(8b934d40-a382-4d57-81c1-463668486276)] +interface nsIXFormsRepeatUIElement : nsISupports +{ + /** + * Generated content will be inserted as children of this element. + */ + readonly attribute nsIDOMElement anonymousRepeatContent; +}; diff --git a/mozilla/extensions/xforms/nsXFormsModelElement.cpp b/mozilla/extensions/xforms/nsXFormsModelElement.cpp index 93d2b81a2d7..34b66246801 100644 --- a/mozilla/extensions/xforms/nsXFormsModelElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsModelElement.cpp @@ -517,8 +517,7 @@ nsPostRefresh::~nsPostRefresh() #ifdef DEBUG_smaug printf("~nsPostRefresh\n"); #endif - --sRefreshing; - if (sPostRefreshList && !sRefreshing) { + if (sPostRefreshList && sRefreshing == 1) { while (sPostRefreshList->Count()) { // Iterating this way because refresh can lead to // additions/deletions in sPostRefreshList. @@ -531,9 +530,12 @@ nsPostRefresh::~nsPostRefresh() if (control) control->Refresh(); } - delete sPostRefreshList; - sPostRefreshList = nsnull; + if (sRefreshing == 1) { + delete sPostRefreshList; + sPostRefreshList = nsnull; + } } + --sRefreshing; } const nsVoidArray* diff --git a/mozilla/extensions/xforms/nsXFormsRepeatElement.cpp b/mozilla/extensions/xforms/nsXFormsRepeatElement.cpp index ca2e92c0267..ea7b9893ff2 100644 --- a/mozilla/extensions/xforms/nsXFormsRepeatElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsRepeatElement.cpp @@ -53,17 +53,18 @@ #include "nsIDOMDocument.h" #include "nsIDOMElement.h" #include "nsIDOMEventTarget.h" -#include "nsIDOMHTMLDivElement.h" #include "nsIDOMNodeList.h" #include "nsIDOMXPathResult.h" #include "nsXFormsControlStub.h" #include "nsIXFormsContextControl.h" #include "nsIXFormsRepeatElement.h" +#include "nsIXFormsRepeatUIElement.h" #include "nsIXFormsRepeatItemElement.h" #include "nsXFormsAtoms.h" #include "nsXFormsModelElement.h" #include "nsXFormsUtils.h" +#include "nsXFormsDelegateStub.h" #ifdef DEBUG //#define DEBUG_XF_REPEAT @@ -83,14 +84,13 @@ * * 1) Creates a new \ (nsXFormsContextContainer) * - * 2) Clones all its children (that is children of its nsIXTFXMLVisualWrapper) + * 2) Clones all its children (that is children of its mElement) * and appends them as children to the nsXFormsContextContainer * * 3) Sets the context node and size for the nsXFormsContextContainer, so * that children can retrieve this through nsIXFormsContextControl. * - * 4) Inserts the nsXFormsContextContainer into its visual content node - * (mHTMLElement). + * 4) Inserts the nsXFormsContextContainer into its visual content node. * * For example, this instance data: *
@@ -112,14 +112,14 @@
  * will be expanded to:
  * 
  * 
- *   (anonymous content)
+ *   (anonymous content)          (XBL)
  *              (contextNode == "n[0]" and contextPosition == 1)
  *       Val:    (that is: 'val1')
  *     
  *              (contextNode == "n[1]" and contextPosition == 2)
  *       Val:    (that is: 'val2')
  *     
- *   (/anonymous content)
+ *   (/anonymous content)         (XBL)
  * 
  * 
* @@ -188,13 +188,10 @@ * display." * @see https://bugzilla.mozilla.org/show_bug.cgi?id=302026 */ -class nsXFormsRepeatElement : public nsXFormsControlStub, +class nsXFormsRepeatElement : public nsXFormsDelegateStub, public nsIXFormsRepeatElement { protected: - /** The HTML representation for the node */ - nsCOMPtr mHTMLElement; - /** True while children are being added */ PRBool mAddingChildren; @@ -291,14 +288,16 @@ protected: */ void SanitizeIndex(PRUint32 *aIndex, PRBool aIsScroll = PR_FALSE); + /** + * Returns either the anonymous content of the repeat or null; + */ + already_AddRefed GetAnonymousContent(); + public: NS_DECL_ISUPPORTS_INHERITED - // nsIXTFXMLVisual overrides - NS_IMETHOD OnCreated(nsIXTFXMLVisualWrapper *aWrapper); - - // nsIXTFVisual overrides - NS_IMETHOD GetVisualContent(nsIDOMElement **aElement); + // nsIXTFBindableElement overrides + NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper); // nsIXTFElement overrides NS_IMETHOD OnDestroyed(); @@ -329,40 +328,20 @@ public: }; NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsRepeatElement, - nsXFormsControlStub, + nsXFormsDelegateStub, nsIXFormsRepeatElement) // nsIXTFXMLVisual NS_IMETHODIMP -nsXFormsRepeatElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper) +nsXFormsRepeatElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) { - nsresult rv = nsXFormsControlStub::OnCreated(aWrapper); + nsresult rv = nsXFormsDelegateStub::OnCreated(aWrapper); NS_ENSURE_SUCCESS(rv, rv); aWrapper->SetNotificationMask(kStandardNotificationMask | nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN | nsIXTFElement::NOTIFY_DONE_ADDING_CHILDREN); - nsCOMPtr domDoc; - rv = mElement->GetOwnerDocument(getter_AddRefs(domDoc)); - NS_ENSURE_SUCCESS(rv, rv); - - // Create UI element - nsCOMPtr domElement; - rv = domDoc->CreateElementNS(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml"), - NS_LITERAL_STRING("div"), - getter_AddRefs(domElement)); - NS_ENSURE_SUCCESS(rv, rv); - mHTMLElement = do_QueryInterface(domElement); - NS_ENSURE_TRUE(mHTMLElement, NS_ERROR_FAILURE); - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsRepeatElement::GetVisualContent(nsIDOMElement **aElement) -{ - NS_IF_ADDREF(*aElement = mHTMLElement); return NS_OK; } @@ -370,10 +349,9 @@ nsXFormsRepeatElement::GetVisualContent(nsIDOMElement **aElement) NS_IMETHODIMP nsXFormsRepeatElement::OnDestroyed() { - mHTMLElement = nsnull; mIndexUsers.Clear(); - return nsXFormsControlStub::OnDestroyed(); + return nsXFormsDelegateStub::OnDestroyed(); } NS_IMETHODIMP @@ -389,8 +367,6 @@ nsXFormsRepeatElement::DoneAddingChildren() { mAddingChildren = PR_FALSE; - Refresh(); - return NS_OK; } @@ -543,9 +519,11 @@ nsXFormsRepeatElement::GetCurrentRepeatRow(nsIDOMNode **aRow) return mCurrentRepeat->GetCurrentRepeatRow(aRow); } + nsCOMPtr anon = GetAnonymousContent(); + NS_ENSURE_STATE(anon); + nsCOMPtr children; - NS_ENSURE_STATE(mHTMLElement); - mHTMLElement->GetChildNodes(getter_AddRefs(children)); + anon->GetChildNodes(getter_AddRefs(children)); NS_ENSURE_STATE(children); nsCOMPtr child; @@ -644,7 +622,10 @@ nsXFormsRepeatElement::GetLevel(PRUint32 *aLevel) NS_IMETHODIMP nsXFormsRepeatElement::HandleNodeInsert(nsIDOMNode *aNode) { - NS_ENSURE_STATE(mHTMLElement); + nsCOMPtr anon = GetAnonymousContent(); + if (!anon) { + return NS_OK; + } nsCOMPtr node(do_QueryInterface(aNode)); NS_ENSURE_STATE(node); @@ -661,7 +642,7 @@ nsXFormsRepeatElement::HandleNodeInsert(nsIDOMNode *aNode) NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr child; - mHTMLElement->GetFirstChild(getter_AddRefs(child)); + anon->GetFirstChild(getter_AddRefs(child)); PRUint32 index = 1; while (child) { @@ -698,28 +679,38 @@ nsXFormsRepeatElement::HandleNodeInsert(nsIDOMNode *aNode) NS_IMETHODIMP nsXFormsRepeatElement::Bind() { - if (mAddingChildren) - return NS_OK; - - return BindToModel(); + nsCOMPtr domDoc; + mElement->GetOwnerDocument(getter_AddRefs(domDoc)); + if (!nsXFormsUtils::IsDocumentReadyForBind(domDoc)) { + nsXFormsModelElement::DeferElementBind(domDoc, this); + return NS_OK_XFORMS_DEFERRED; + } + return BindToModel(PR_TRUE); } NS_IMETHODIMP nsXFormsRepeatElement::Refresh() { - if (!mHTMLElement || mAddingChildren || mIsParent) + if (!mElement || mAddingChildren || mIsParent) { return NS_OK; + } + + nsCOMPtr anon = GetAnonymousContent(); + if (!anon) { + return NS_OK; + } + nsPostRefresh postRefresh = nsPostRefresh(); nsresult rv; // Clear any existing children nsCOMPtr cNode; - mHTMLElement->GetFirstChild(getter_AddRefs(cNode)); + anon->GetFirstChild(getter_AddRefs(cNode)); while (cNode) { nsCOMPtr retNode; - mHTMLElement->RemoveChild(cNode, getter_AddRefs(retNode)); - mHTMLElement->GetFirstChild(getter_AddRefs(cNode)); + anon->RemoveChild(cNode, getter_AddRefs(retNode)); + anon->GetFirstChild(getter_AddRefs(cNode)); } // Get the nodeset we are bound to @@ -756,7 +747,7 @@ nsXFormsRepeatElement::Refresh() // Get DOM document nsCOMPtr domDoc; - rv = mHTMLElement->GetOwnerDocument(getter_AddRefs(domDoc)); + rv = mElement->GetOwnerDocument(getter_AddRefs(domDoc)); NS_ENSURE_SUCCESS(rv, rv); mMaxIndex = contextSize; @@ -791,7 +782,7 @@ nsXFormsRepeatElement::Refresh() // We need to insert the context node before adding the children, or the // children will fail to set up their proper XForms context. nsCOMPtr domNode; - rv = mHTMLElement->AppendChild(riElement, getter_AddRefs(domNode)); + rv = anon->AppendChild(riElement, getter_AddRefs(domNode)); NS_ENSURE_SUCCESS(rv, rv); // Iterate over template children, clone them, and append them to @@ -821,13 +812,42 @@ nsXFormsRepeatElement::Refresh() // refresh (either using delete or through script, so check the index // value SanitizeIndex(&mCurrentIndex); - } else if (!mParent && mMaxIndex) { + } else if (mMaxIndex) { // repeat-index has not been initialized, set it. - GetStartingIndex(&mCurrentIndex); + if (!mParent) { + GetStartingIndex(&mCurrentIndex); + } else if (mLevel > 1) { + // Set repeat-index for inner repeats. If parent + // element is selected then mCurrentIndex is setted on starting index. + + nsCOMPtr temp = mElement; + nsCOMPtr parent; + nsCOMPtr context; + + while (!context) { + rv = temp->GetParentNode(getter_AddRefs(parent)); + NS_ENSURE_SUCCESS(rv, rv); + if (!parent) + break; + context = do_QueryInterface(parent); + temp.swap(parent); + } + + if (context) { + PRBool hasIndex = PR_FALSE; + context->GetIndexState(&hasIndex); + if (hasIndex) { + PRUint32 index = 0; + GetStartingIndex(&index); + SetIndex(&index, PR_FALSE); + } + } + return NS_OK; + } } // If we have the repeat-index, set it. - if (mCurrentIndex) { + if (mCurrentIndex) { SetChildIndex(mCurrentIndex, PR_TRUE, PR_TRUE); } @@ -846,11 +866,12 @@ nsXFormsRepeatElement::SetChildIndex(PRUint32 aPosition, aPosition, aState, aIsRefresh); #endif - if (!mHTMLElement) + nsCOMPtr anon = GetAnonymousContent(); + if (!anon) return NS_OK; nsCOMPtr children; - mHTMLElement->GetChildNodes(getter_AddRefs(children)); + anon->GetChildNodes(getter_AddRefs(children)); NS_ENSURE_STATE(children); PRUint32 index = aPosition - 1; // Indexes are 1-based, the DOM is 0-based; @@ -914,6 +935,10 @@ nsXFormsRepeatElement::ResetInnerRepeats(nsIDOMNode *aNode, nsCOMPtr nodeList; nsresult rv; + + nsCOMPtr anon = GetAnonymousContent(); + NS_ENSURE_STATE(anon); + rv = element->GetElementsByTagNameNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS), NS_LITERAL_STRING("repeat"), getter_AddRefs(nodeList)); @@ -1020,13 +1045,17 @@ nsXFormsRepeatElement::TryFocus(PRBool *aOK) return NS_OK; } + nsCOMPtr anon = GetAnonymousContent(); + if (!anon) + return NS_OK; + /** * "Setting focus to a repeating structure sets the focus to * the repeat item represented by the repeat index." * @see http://www.w3.org/TR/xforms/slice10.html#action-setfocus */ nsCOMPtr children; - mHTMLElement->GetChildNodes(getter_AddRefs(children)); + anon->GetChildNodes(getter_AddRefs(children)); NS_ENSURE_STATE(children); nsCOMPtr child; @@ -1111,6 +1140,18 @@ nsXFormsRepeatElement::IsBindingAttribute(const nsIAtom *aAttr) const return PR_FALSE; } +already_AddRefed +nsXFormsRepeatElement::GetAnonymousContent() +{ + nsIDOMElement* anon = nsnull; + nsCOMPtr uiElement(do_QueryInterface(mElement)); + if (uiElement) { + // addrefs + uiElement->GetAnonymousRepeatContent(&anon); + } + return anon; +} + // Factory NS_HIDDEN_(nsresult) NS_NewXFormsRepeatElement(nsIXTFElement **aResult) diff --git a/mozilla/extensions/xforms/resources/content/xforms-xhtml.xml b/mozilla/extensions/xforms/resources/content/xforms-xhtml.xml index bc805824b8c..fb7a6ebce51 100644 --- a/mozilla/extensions/xforms/resources/content/xforms-xhtml.xml +++ b/mozilla/extensions/xforms/resources/content/xforms-xhtml.xml @@ -438,4 +438,16 @@ + + + + + + + + + + + diff --git a/mozilla/extensions/xforms/resources/content/xforms-xul.xml b/mozilla/extensions/xforms/resources/content/xforms-xul.xml index 66563b9aef4..93e05ad3585 100644 --- a/mozilla/extensions/xforms/resources/content/xforms-xul.xml +++ b/mozilla/extensions/xforms/resources/content/xforms-xul.xml @@ -210,10 +210,22 @@ - if (!this.control.isDisabled) + if (!this.control.isDisabled) this.dispatchDOMUIEvent("DOMActivate"); + + + + + + + + + diff --git a/mozilla/extensions/xforms/resources/content/xforms.css b/mozilla/extensions/xforms/resources/content/xforms.css index e3d1f3eca5b..5f522cd02c0 100755 --- a/mozilla/extensions/xforms/resources/content/xforms.css +++ b/mozilla/extensions/xforms/resources/content/xforms.css @@ -559,6 +559,15 @@ html|*:root upload[mozType|type="http://www.w3.org/2001/XMLSchema#hexBinary"] { -moz-binding: url('chrome://xforms/content/xforms-xhtml.xml#xformswidget-upload'); } +/* repeat */ +html|*:root repeat { + -moz-binding: url('chrome://xforms/content/xforms-xhtml.xml#xformswidget-repeat'); +} + +xul|*:root repeat { + -moz-binding: url('chrome://xforms/content/xforms-xul.xml#xformswidget-repeat'); +} + /* default MIP styling */ *:disabled { display: none; diff --git a/mozilla/extensions/xforms/resources/content/xforms.xml b/mozilla/extensions/xforms/resources/content/xforms.xml index d92cac7a7c8..d6ac1e02a44 100644 --- a/mozilla/extensions/xforms/resources/content/xforms.xml +++ b/mozilla/extensions/xforms/resources/content/xforms.xml @@ -488,4 +488,24 @@ + + + + + + + + + if (!this._anonymousRepeatContent) { + this._anonymousRepeatContent = + document.getAnonymousElementByAttribute(this, "anonid", "insertion"); + } + return this._anonymousRepeatContent; + + + + null + + +