Back to index

lightning-sunbird  0.9+nobinonly
nsXFormsModelElement.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla XForms support.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * IBM Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2004
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *  Brian Ryner <bryner@brianryner.com>
00024  *  Olli Pettay <Olli.Pettay@helsinki.fi>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #ifndef nsXFormsModelElement_h_
00041 #define nsXFormsModelElement_h_
00042 
00043 #include "nsXFormsStubElement.h"
00044 #include "nsIModelElementPrivate.h"
00045 #include "nsIXFormsNSModelElement.h"
00046 #include "nsIDOMEventListener.h"
00047 #include "nsISchema.h"
00048 #include "nsCOMArray.h"
00049 #include "nsVoidArray.h"
00050 #include "nsCOMPtr.h"
00051 #include "nsIDOMDocument.h"
00052 #include "nsIDOMNodeList.h"
00053 #include "nsXFormsMDGEngine.h"
00054 #include "nsXFormsUtils.h"
00055 #include "nsIClassInfo.h"
00056 
00057 #include "nsISchemaLoader.h"
00058 #include "nsISchema.h"
00059 #include "nsIXFormsContextControl.h"
00060 #include "nsDataHashtable.h"
00061 #include "nsRefPtrHashtable.h"
00062 
00063 class nsIDOMElement;
00064 class nsIDOMNode;
00065 class nsIXFormsXPathEvaluator;
00066 class nsIDOMXPathResult;
00067 class nsXFormsControl;
00068 class nsXFormsModelInstanceDocuments;
00069 
00077 class nsXFormsModelInstanceDocuments : public nsIDOMNodeList,
00078                                        public nsIClassInfo
00079 {
00080 public:
00081   nsXFormsModelInstanceDocuments();
00082 
00083   NS_DECL_ISUPPORTS
00084   NS_DECL_NSICLASSINFO
00085   NS_DECL_NSIDOMNODELIST
00086 
00092   void AddInstance(nsIInstanceElementPrivate *aInstance);
00093 
00099   void RemoveInstance(nsIInstanceElementPrivate *aInstance);
00100 
00109   nsIInstanceElementPrivate* GetInstanceAt(PRUint32 aIndex);
00110 
00114   void DropReferences();
00115 
00116 protected:
00118   nsCOMArray<nsIInstanceElementPrivate>    mInstanceList;
00119 };
00120 
00130 class nsXFormsControlListItem
00131 {
00132 protected:
00133 
00134   nsAutoRefCnt                      mRefCnt;
00135 
00137   nsCOMPtr<nsIXFormsControl>        mNode;
00138 
00140   nsRefPtr<nsXFormsControlListItem> mNextSibling;
00141 
00143   nsRefPtr<nsXFormsControlListItem> mFirstChild;
00144 
00145   nsRefPtrHashtable<nsISupportsHashKey, nsXFormsControlListItem> *mControlListHash;
00146 
00147 public:
00148 
00154   nsXFormsControlListItem(
00155     nsIXFormsControl* aControl,
00156     nsRefPtrHashtable<nsISupportsHashKey,nsXFormsControlListItem> *aHash);
00157   nsXFormsControlListItem();
00158   ~nsXFormsControlListItem();
00159   nsXFormsControlListItem(const nsXFormsControlListItem& aCopy);
00160 
00161   nsrefcnt AddRef()
00162   {
00163     ++mRefCnt;
00164     NS_LOG_ADDREF(this, mRefCnt, "nsXFormsControlListItem",
00165                   sizeof(nsXFormsControlListItem));
00166     return mRefCnt;
00167   }
00168 
00169   nsrefcnt Release()
00170   {
00171     --mRefCnt;
00172     NS_LOG_RELEASE(this, mRefCnt, "nsXFormsControlListItem");
00173     if (mRefCnt == 0) {
00174       mRefCnt = 1;
00175       delete this;
00176       return 0;
00177     }
00178     return mRefCnt;
00179   }
00180 
00182   void Clear();
00183 
00191   nsresult RemoveControl(nsIXFormsControl *aControl, PRBool &aRemoved);
00192 
00201   nsresult AddControl(nsIXFormsControl *aControl,
00202                       nsIXFormsControl *aParent);
00203 
00209   nsXFormsControlListItem* FindControl(nsIXFormsControl *aControl);
00210 
00214   already_AddRefed<nsIXFormsControl> Control();
00215 
00217   nsXFormsControlListItem* FirstChild() { return mFirstChild; };
00218 
00220   nsXFormsControlListItem* NextSibling() { return mNextSibling; };
00221 
00225   class iterator
00226   {
00227   private:
00229     nsRefPtr<nsXFormsControlListItem> mCur;
00230 
00232     nsVoidArray                       mStack;
00233 
00234   public:
00235     iterator();
00236     iterator(const iterator&);
00237     iterator operator=(nsXFormsControlListItem*);
00238     bool operator!=(const nsXFormsControlListItem*);
00239     iterator operator++();
00240     nsXFormsControlListItem* operator*();
00241   };
00242   friend class nsXFormsControlListItem::iterator;
00243 
00245   nsXFormsControlListItem* begin();
00246 
00248   nsXFormsControlListItem* end();
00249 };
00250 
00259 class nsXFormsModelElement : public nsXFormsStubElement,
00260                              public nsIModelElementPrivate,
00261                              public nsIXFormsNSModelElement,
00262                              public nsISchemaLoadListener,
00263                              public nsIDOMEventListener,
00264                              public nsIXFormsContextControl
00265 {
00266 public:
00267   nsXFormsModelElement() NS_HIDDEN;
00268 
00269   NS_DECL_ISUPPORTS_INHERITED
00270   NS_DECL_NSIXFORMSMODELELEMENT
00271   NS_DECL_NSIMODELELEMENTPRIVATE
00272   NS_DECL_NSIXFORMSNSMODELELEMENT
00273   NS_DECL_NSISCHEMALOADLISTENER
00274   NS_DECL_NSIWEBSERVICEERRORHANDLER
00275   NS_DECL_NSIDOMEVENTLISTENER
00276   NS_DECL_NSIXFORMSCONTEXTCONTROL
00277 
00278   // nsIXTFGenericElement overrides
00279   NS_IMETHOD OnDestroyed();
00280   NS_IMETHOD GetScriptingInterfaces(PRUint32 *aCount, nsIID ***aArray);
00281   NS_IMETHOD WillChangeDocument(nsIDOMDocument *aNewDocument);
00282   NS_IMETHOD DocumentChanged(nsIDOMDocument *aNewDocument);
00283   NS_IMETHOD DoneAddingChildren();
00284   NS_IMETHOD HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled);
00285   NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper);
00286 
00287   // nsIXFormsControlBase overrides
00288   NS_IMETHOD Bind(PRBool *aContextChanged) {
00289     // dummy method, so does nothing
00290     return NS_OK;
00291   };
00292 
00293   NS_IMETHOD GetOnDeferredBindList(PRBool *onList) {
00294     // dummy method, so does nothing
00295     return NS_OK;
00296   };
00297 
00298   NS_IMETHOD SetOnDeferredBindList(PRBool putOnList) {
00299     // dummy method, so does nothing
00300     return NS_OK;
00301   };
00302 
00303   // Called after nsXFormsAtoms is registered
00304   static NS_HIDDEN_(void) Startup();
00305 
00313   static NS_HIDDEN_(nsresult) DeferElementBind(nsIXFormsControl  *aControl);
00314 
00315   static nsresult NeedsPostRefresh(nsIXFormsControl* aControl);
00316 
00317   // Sometimes a child that is on the post refresh list will want to force
00318   // its containing xforms control to refresh.  Like if an xf:item's label
00319   // refreshes, it wants to reflect any of its changes in the xf:select or
00320   // xf:select1 that contains it.  This function will try to minimize that by
00321   // allowing xforms controls that function as containers (like select/select1)
00322   // to defer their refresh until most or all of its children have refreshed.
00323   // Well, at least until every control on the sPostRefreshList has been
00324   // processed.  This will return PR_TRUE if the refresh will be deferred.
00325   static PRBool ContainerNeedsPostRefresh(nsIXFormsControl* aControl);
00326   static void CancelPostRefresh(nsIXFormsControl* aControl);
00327 
00331   already_AddRefed<nsIDOMElement> GetDOMElement();
00332 
00333 private:
00334 
00335   NS_HIDDEN_(already_AddRefed<nsIDOMDocument>)
00336     FindInstanceDocument(const nsAString &aID);
00337   NS_HIDDEN_(void)     Reset();
00338   NS_HIDDEN_(void)     BackupOrRestoreInstanceData(PRBool restore);
00339 
00341   NS_HIDDEN_(nsresult) InitializeControls();
00342 
00343   NS_HIDDEN_(nsresult) InitializeInstances();
00344 
00345   NS_HIDDEN_(nsresult) ProcessBindElements();
00346   NS_HIDDEN_(nsresult) FinishConstruction();
00347   NS_HIDDEN_(nsresult) ConstructDone();
00348   NS_HIDDEN_(void)     MaybeNotifyCompletion();
00349 
00350   NS_HIDDEN_(nsresult) ProcessBind(nsIXFormsXPathEvaluator   *aEvaluator,
00351                                    nsIDOMNode                *aContextNode,
00352                                    PRInt32                    aContextPosition,
00353                                    PRInt32                    aContextSize,
00354                                    nsIDOMElement             *aBindElement,
00355                                    PRBool                     aIsOuter = PR_FALSE);
00356 
00357   NS_HIDDEN_(void)     RemoveModelFromDocument();
00358 
00366   NS_HIDDEN_(void)     SetSingleState(nsIDOMElement *aElement,
00367                                       PRBool         aState,
00368                                       nsXFormsEvent  aOnEvent);
00369 
00379   static NS_HIDDEN_(void) ProcessDeferredBinds(nsIDOMDocument *aDoc);
00380 
00381   // Returns true when all external documents have been loaded
00382   PRBool IsComplete() const { return (mSchemaTotal == mSchemaCount
00383                                       && mPendingInstanceCount == 0);  }
00384 
00388   NS_HIDDEN_(nsresult) HandleLoad(nsIDOMEvent *aEvent);
00389 
00393   NS_HIDDEN_(nsresult) HandleUnload(nsIDOMEvent *aEvent);
00394 
00395   NS_HIDDEN_(nsresult) RefreshSubTree(nsXFormsControlListItem *aCurrent,
00396                                       PRBool                   aForceRebind);
00397 
00398   NS_HIDDEN_(nsresult) ValidateDocument(nsIDOMDocument *aInstanceDocument,
00399                                         PRBool         *aResult);
00400 
00408   NS_HIDDEN_(nsresult) RequestUpdateEvent(nsXFormsEvent aEvent);
00409   
00418   PRBool IsDuplicateSchema(nsIDOMElement *aSchemaElement);
00419 
00423   void ValidateInstanceDocuments();
00424 
00431   NS_HIDDEN_(nsresult) GetBuiltinTypeName(PRUint16   aType,
00432                                           nsAString& aName);
00433 
00439   NS_HIDDEN_(nsresult) GetBuiltinTypesNames(PRUint16       aType,
00440                                             nsStringArray *aNameArray);
00441 
00457   NS_HIDDEN_(nsresult) WalkTypeChainInternal(nsISchemaType *aType,
00458                                              PRBool         aFindRootBuiltin,
00459                                              PRUint16      *aBuiltinType,
00460                                              nsStringArray *aTypeArray = nsnull);
00464   NS_HIDDEN_(nsresult) BuiltinTypeToPrimative(nsISchemaBuiltinType *aSchemaType,
00465                                               PRUint16             *aPrimType);
00466 
00472   nsresult SetContextInfo(const char *aName, const nsAString &aValue);
00473 
00474   nsIDOMElement            *mElement;
00475   nsCOMPtr<nsISchemaLoader> mSchemas;
00476   nsStringArray             mPendingInlineSchemas;
00477   nsXFormsControlListItem   mFormControls;
00478   nsRefPtrHashtable<nsISupportsHashKey, nsXFormsControlListItem> mControlListHash;
00479 
00480   PRInt32 mSchemaCount;
00481   PRInt32 mSchemaTotal;
00482   PRInt32 mPendingInstanceCount;
00483 
00485   nsXFormsMDGEngine mMDG;
00486 
00491   nsCOMArray<nsIDOMNode>    mChangedNodes;
00492 
00497   PRPackedBool mDocumentLoaded;
00498 
00503   PRPackedBool mRebindAllControls;
00504 
00508   PRPackedBool mInstancesInitialized;
00509 
00513   PRPackedBool mReadyHandled;
00514 
00518   PRPackedBool mLazyModel;
00519 
00524   PRPackedBool mConstructDoneHandled;
00525 
00531   PRPackedBool mProcessingUpdateEvent;
00532 
00537   nsVoidArray mUpdateEventQueue;
00538 
00544   PRInt32 mLoopMax;
00545 
00550   nsRefPtr<nsXFormsModelInstanceDocuments> mInstanceDocuments;
00551 
00557   nsClassHashtable<nsISupportsHashKey, nsString> mNodeToType;
00558 
00565   nsClassHashtable<nsISupportsHashKey, nsString> mNodeToP3PType;
00566 
00567   // Context Info for events.
00568   nsCOMArray<nsIXFormsContextInfo> mContextInfo;
00569 
00570   friend class Updating;
00571 };
00572 
00580 class nsPostRefresh {
00581 public:
00582   nsPostRefresh();
00583   ~nsPostRefresh();
00584   static const nsVoidArray* PostRefreshList();
00585 };
00586 
00587 NS_HIDDEN_(nsresult) NS_NewXFormsModelElement(nsIXTFElement **aResult);
00588 
00589 #endif