Back to index

lightning-sunbird  0.9+nobinonly
nsXBLPrototypeBinding.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 Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Original Author: David W. Hyatt (hyatt@netscape.com)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsXBLPrototypeBinding_h__
00040 #define nsXBLPrototypeBinding_h__
00041 
00042 #include "nsCOMPtr.h"
00043 #include "nsXBLPrototypeResources.h"
00044 #include "nsXBLPrototypeHandler.h"
00045 #include "nsXBLProtoImplMethod.h"
00046 #include "nsICSSStyleSheet.h"
00047 #include "nsICSSLoaderObserver.h"
00048 #include "nsWeakReference.h"
00049 #include "nsIContent.h"
00050 #include "nsHashtable.h"
00051 #include "nsIXBLDocumentInfo.h"
00052 #include "nsCOMArray.h"
00053 #include "nsIURL.h"
00054 
00055 class nsIAtom;
00056 class nsIDocument;
00057 class nsIScriptContext;
00058 class nsISupportsArray;
00059 class nsSupportsHashtable;
00060 class nsIXBLService;
00061 class nsFixedSizeAllocator;
00062 class nsXBLProtoImpl;
00063 class nsXBLBinding;
00064 
00065 // *********************************************************************/
00066 // The XBLPrototypeBinding class
00067 
00068 // References to the prototype binding are held by each nsXBLBinding instance
00069 // that uses this prototype binding, and also by the XBLDocumentInfo's
00070 // binding table (with the XUL cache disabled).
00071 
00072 class nsXBLPrototypeBinding
00073 {
00074 public:
00075   already_AddRefed<nsIContent> GetBindingElement();
00076   void SetBindingElement(nsIContent* aElement);
00077 
00078   nsIURI* BindingURI() const { return mBindingURI; }
00079   nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
00080   nsresult GetID(nsACString& aResult) const { return mBindingURI->GetRef(aResult); }
00081 
00082   nsresult GetAllowScripts(PRBool* aResult);
00083 
00084   PRBool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
00085 
00086   nsresult BindingAttached(nsIContent* aBoundElement);
00087   nsresult BindingDetached(nsIContent* aBoundElement);
00088 
00089   PRBool LoadResources();
00090   nsresult AddResource(nsIAtom* aResourceType, const nsAString& aSrc);
00091 
00092   PRBool InheritsStyle() const { return mInheritStyle; }
00093 
00094   nsXBLPrototypeHandler* GetPrototypeHandlers() { return mPrototypeHandler; }
00095   void SetPrototypeHandlers(nsXBLPrototypeHandler* aHandler) { mPrototypeHandler = aHandler; }
00096 
00097   nsXBLProtoImplAnonymousMethod* GetConstructor();
00098   nsresult SetConstructor(nsXBLProtoImplAnonymousMethod* aConstructor);
00099   nsXBLProtoImplAnonymousMethod* GetDestructor();
00100   nsresult SetDestructor(nsXBLProtoImplAnonymousMethod* aDestructor);
00101 
00102   nsresult InitClass(const nsCString& aClassName, JSContext * aContext,
00103                      JSObject * aGlobal, JSObject * aScriptObject,
00104                      void ** aClassObject);
00105 
00106   nsresult ConstructInterfaceTable(const nsAString& aImpls);
00107   
00108   void SetImplementation(nsXBLProtoImpl* aImpl) { mImplementation = aImpl; }
00109   nsresult InstallImplementation(nsIContent* aBoundElement);
00110 
00111   void AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID,
00112                         PRBool aRemoveFlag, nsIContent* aChangedElement,
00113                         nsIContent* aAnonymousContent, PRBool aNotify);
00114 
00115   void SetBasePrototype(nsXBLPrototypeBinding* aBinding);
00116   nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
00117 
00118   nsIXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; }
00119   
00120   PRBool HasBasePrototype() { return mHasBaseProto; }
00121   void SetHasBasePrototype(PRBool aHasBase) { mHasBaseProto = aHasBase; }
00122 
00123   void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
00124 
00125   nsIStyleRuleProcessor* GetRuleProcessor();
00126   nsCOMArray<nsICSSStyleSheet>* GetStyleSheets();
00127 
00128   PRBool HasInsertionPoints() { return mInsertionPointTable != nsnull; }
00129   
00130   PRBool HasStyleSheets() {
00131     return mResources && mResources->mStyleSheetList.Count() > 0;
00132   }
00133 
00134   nsresult FlushSkinSheets();
00135 
00136   void InstantiateInsertionPoints(nsXBLBinding* aBinding);
00137 
00138   nsIContent* GetInsertionPoint(nsIContent* aBoundElement,
00139                                 nsIContent* aCopyRoot, nsIContent *aChild,
00140                                 PRUint32* aIndex);
00141 
00142   nsIContent* GetSingleInsertionPoint(nsIContent* aBoundElement,
00143                                       nsIContent* aCopyRoot,
00144                                       PRUint32* aIndex, PRBool* aMultiple);
00145 
00146   nsIAtom* GetBaseTag(PRInt32* aNamespaceID);
00147   void SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag);
00148 
00149   PRBool ImplementsInterface(REFNSIID aIID) const;
00150 
00151   PRBool ShouldBuildChildFrames() const;
00152 
00153   nsresult AddResourceListener(nsIContent* aBoundElement);
00154 
00155   void Initialize();
00156 
00157   const nsCOMArray<nsXBLKeyEventHandler>* GetKeyEventHandlers()
00158   {
00159     if (!mKeyHandlersRegistered) {
00160       CreateKeyHandlers();
00161       mKeyHandlersRegistered = PR_TRUE;
00162     }
00163 
00164     return &mKeyHandlers;
00165   }
00166 
00167 public:
00168   nsXBLPrototypeBinding();
00169   ~nsXBLPrototypeBinding();
00170 
00171   // Init must be called after construction to initialize the prototype
00172   // binding.  It may well throw errors (eg on out-of-memory).  Do not confuse
00173   // this with the Initialize() method, which must be called after the
00174   // binding's handlers, properties, etc are all set.
00175   nsresult Init(const nsACString& aRef,
00176                 nsIXBLDocumentInfo* aInfo,
00177                 nsIContent* aElement);
00178   
00179 // Static members
00180   static PRUint32 gRefCnt;
00181  
00182   static nsFixedSizeAllocator* kAttrPool;
00183   static nsFixedSizeAllocator* kInsPool;
00184 
00185 // Internal member functions.
00186 // XXXbz GetImmediateChild needs to be public to be called by SetAttrs,
00187 // InstantiateInsertionPoints, etc; those should probably be a class static
00188 // method instead of a global (non-static!) ones.
00189 public:
00194   nsIContent* GetImmediateChild(nsIAtom* aTag);
00195   nsIContent* LocateInstance(nsIContent* aBoundElt,
00196                              nsIContent* aTemplRoot,
00197                              nsIContent* aCopyRoot,
00198                              nsIContent* aTemplChild);
00199 
00200 protected:  
00201   void ConstructAttributeTable(nsIContent* aElement);
00202   void ConstructInsertionTable(nsIContent* aElement);
00203   void GetNestedChildren(nsIAtom* aTag, PRInt32 aNamespace,
00204                          nsIContent* aContent,
00205                          nsCOMArray<nsIContent> & aList);
00206   void CreateKeyHandlers();
00207 
00208 protected:
00209   // Internal helper class for managing our IID table.
00210   class nsIIDKey : public nsHashKey {
00211     protected:
00212       nsIID mKey;
00213   
00214     public:
00215       nsIIDKey(REFNSIID key) : mKey(key) {}
00216       ~nsIIDKey(void) {}
00217 
00218       PRUint32 HashCode(void) const {
00219         // Just use the 32-bit m0 field.
00220         return mKey.m0;
00221       }
00222 
00223       PRBool Equals(const nsHashKey *aKey) const {
00224         return mKey.Equals( ((nsIIDKey*) aKey)->mKey);
00225       }
00226 
00227       nsHashKey *Clone(void) const {
00228         return new nsIIDKey(mKey);
00229       }
00230   };
00231 
00232 // MEMBER VARIABLES
00233 protected:
00234   nsCOMPtr<nsIURL> mBindingURI;
00235   nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
00236   nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
00237   
00238   nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields,
00239                                    // the constructor, and the destructor).
00240 
00241   nsXBLPrototypeBinding* mBaseBinding; // Weak.  The docinfo will own our base binding.
00242   PRPackedBool mInheritStyle;
00243   PRPackedBool mHasBaseProto;
00244   PRPackedBool mKeyHandlersRegistered;
00245  
00246   nsXBLPrototypeResources* mResources; // If we have any resources, this will be non-null.
00247                                       
00248   nsIXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info.  Weak, since it owns us.
00249 
00250   nsObjectHashtable* mAttributeTable; // A table for attribute containers. Namespace IDs are used as
00251                                       // keys in the table. Containers are nsObjectHashtables.
00252                                       // This table is used to efficiently handle attribute changes.
00253 
00254   nsObjectHashtable* mInsertionPointTable; // A table of insertion points for placing explicit content
00255                                            // underneath anonymous content.
00256 
00257   nsSupportsHashtable* mInterfaceTable; // A table of cached interfaces that we support.
00258 
00259   PRInt32 mBaseNameSpaceID;    // If we extend a tagname/namespace, then that information will
00260   nsCOMPtr<nsIAtom> mBaseTag;  // be stored in here.
00261 
00262   nsAutoRefCnt mRefCnt;
00263 
00264   nsCOMArray<nsXBLKeyEventHandler> mKeyHandlers;
00265 };
00266 
00267 #endif
00268