LCOV - code coverage report
Current view: top level - dom/xbl - nsXBLPrototypeBinding.h (source / functions) Hit Total Coverage
Test: output.info Lines: 38 46 82.6 %
Date: 2017-07-14 16:53:18 Functions: 24 29 82.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef nsXBLPrototypeBinding_h__
       8             : #define nsXBLPrototypeBinding_h__
       9             : 
      10             : #include "nsAutoPtr.h"
      11             : #include "nsClassHashtable.h"
      12             : #include "nsCOMArray.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsICSSLoaderObserver.h"
      15             : #include "nsInterfaceHashtable.h"
      16             : #include "nsWeakReference.h"
      17             : #include "nsXBLDocumentInfo.h"
      18             : #include "nsXBLProtoImpl.h"
      19             : #include "nsXBLProtoImplMethod.h"
      20             : #include "nsXBLPrototypeHandler.h"
      21             : #include "nsXBLPrototypeResources.h"
      22             : #include "mozilla/WeakPtr.h"
      23             : #include "mozilla/StyleSheet.h"
      24             : 
      25             : class nsIAtom;
      26             : class nsIContent;
      27             : class nsIDocument;
      28             : class nsXBLAttributeEntry;
      29             : class nsXBLBinding;
      30             : class nsXBLProtoImplField;
      31             : 
      32             : // *********************************************************************/
      33             : // The XBLPrototypeBinding class
      34             : 
      35             : // Instances of this class are owned by the nsXBLDocumentInfo object returned
      36             : // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
      37             : // that.
      38             : class nsXBLPrototypeBinding final :
      39             :   public mozilla::SupportsWeakPtr<nsXBLPrototypeBinding>
      40             : {
      41             : public:
      42        3116 :   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsXBLPrototypeBinding)
      43             : 
      44         361 :   nsIContent* GetBindingElement() const { return mBinding; }
      45             :   void SetBindingElement(nsIContent* aElement);
      46             : 
      47         994 :   nsIURI* BindingURI() const { return mBindingURI; }
      48         633 :   nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; }
      49         126 :   nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
      50         332 :   nsIURI* GetBaseBindingURI() const { return mBaseBindingURI; }
      51             : 
      52             :   // Checks if aURI refers to this binding by comparing to both possible
      53             :   // binding URIs.
      54             :   bool CompareBindingURI(nsIURI* aURI) const;
      55             : 
      56             :   bool GetAllowScripts() const;
      57             : 
      58             :   nsresult BindingAttached(nsIContent* aBoundElement);
      59             :   nsresult BindingDetached(nsIContent* aBoundElement);
      60             : 
      61             :   // aBoundElement is passed in here because we need to get owner document
      62             :   // and PresContext in nsXBLResourceLoader::LoadResources().
      63             :   bool LoadResources(nsIContent* aBoundElement);
      64             :   nsresult AddResource(nsIAtom* aResourceType, const nsAString& aSrc);
      65             : 
      66        1800 :   bool InheritsStyle() const { return mInheritStyle; }
      67           0 :   void SetInheritsStyle(bool aInheritStyle) { mInheritStyle = aInheritStyle; }
      68             : 
      69         664 :   nsXBLPrototypeHandler* GetPrototypeHandlers() { return mPrototypeHandler; }
      70          55 :   void SetPrototypeHandlers(nsXBLPrototypeHandler* aHandler) { mPrototypeHandler = aHandler; }
      71             : 
      72             :   nsXBLProtoImplAnonymousMethod* GetConstructor();
      73             :   nsresult SetConstructor(nsXBLProtoImplAnonymousMethod* aConstructor);
      74             :   nsXBLProtoImplAnonymousMethod* GetDestructor();
      75             :   nsresult SetDestructor(nsXBLProtoImplAnonymousMethod* aDestructor);
      76             : 
      77         112 :   nsXBLProtoImplField* FindField(const nsString& aFieldName) const
      78             :   {
      79         112 :     return mImplementation ? mImplementation->FindField(aFieldName) : nullptr;
      80             :   }
      81             : 
      82             :   // Resolve all the fields for this binding on the object |obj|.
      83             :   // False return means a JS exception was set.
      84           0 :   bool ResolveAllFields(JSContext* cx, JS::Handle<JSObject*> obj) const
      85             :   {
      86           0 :     return !mImplementation || mImplementation->ResolveAllFields(cx, obj);
      87             :   }
      88             : 
      89             :   // Undefine all our fields from object |obj| (which should be a
      90             :   // JSObject for a bound element).
      91          25 :   void UndefineFields(JSContext* cx, JS::Handle<JSObject*> obj) const {
      92          25 :     if (mImplementation) {
      93          25 :       mImplementation->UndefineFields(cx, obj);
      94             :     }
      95          25 :   }
      96             : 
      97          60 :   const nsString& ClassName() const {
      98          60 :     return mImplementation ? mImplementation->mClassName : EmptyString();
      99             :   }
     100             : 
     101             :   nsresult InitClass(const nsString& aClassName, JSContext* aContext,
     102             :                      JS::Handle<JSObject*> aScriptObject,
     103             :                      JS::MutableHandle<JSObject*> aClassObject,
     104             :                      bool* aNew);
     105             : 
     106             :   nsresult ConstructInterfaceTable(const nsAString& aImpls);
     107             : 
     108          83 :   void SetImplementation(nsXBLProtoImpl* aImpl) { mImplementation = aImpl; }
     109           0 :   nsXBLProtoImpl* GetImplementation() { return mImplementation; }
     110             :   nsresult InstallImplementation(nsXBLBinding* aBinding);
     111          31 :   bool HasImplementation() const { return mImplementation != nullptr; }
     112             : 
     113             :   void AttributeChanged(nsIAtom* aAttribute, int32_t aNameSpaceID,
     114             :                         bool aRemoveFlag, nsIContent* aChangedElement,
     115             :                         nsIContent* aAnonymousContent, bool aNotify);
     116             : 
     117             :   void SetBasePrototype(nsXBLPrototypeBinding* aBinding);
     118         633 :   nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
     119             : 
     120         728 :   nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; }
     121         162 :   bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
     122             : 
     123             :   void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
     124             : 
     125             :   void AppendStyleSheet(mozilla::StyleSheet* aSheet);
     126             :   void RemoveStyleSheet(mozilla::StyleSheet* aSheet);
     127             :   void InsertStyleSheetAt(size_t aIndex, mozilla::StyleSheet* aSheet);
     128             :   mozilla::StyleSheet* StyleSheetAt(size_t aIndex) const;
     129             :   size_t SheetCount() const;
     130             :   bool HasStyleSheets() const;
     131             :   void AppendStyleSheetsTo(nsTArray<mozilla::StyleSheet*>& aResult) const;
     132             : 
     133             :   nsIStyleRuleProcessor* GetRuleProcessor();
     134             :   const mozilla::ServoStyleSet* GetServoStyleSet() const;
     135             : 
     136             :   nsresult FlushSkinSheets();
     137             : 
     138             :   nsIAtom* GetBaseTag(int32_t* aNamespaceID);
     139             :   void SetBaseTag(int32_t aNamespaceID, nsIAtom* aTag);
     140             : 
     141             :   bool ImplementsInterface(REFNSIID aIID) const;
     142             : 
     143             :   nsresult AddResourceListener(nsIContent* aBoundElement);
     144             : 
     145             :   void Initialize();
     146             : 
     147             :   nsresult ResolveBaseBinding();
     148             : 
     149         162 :   const nsCOMArray<nsXBLKeyEventHandler>* GetKeyEventHandlers()
     150             :   {
     151         162 :     if (!mKeyHandlersRegistered) {
     152          36 :       CreateKeyHandlers();
     153          36 :       mKeyHandlersRegistered = true;
     154             :     }
     155             : 
     156         162 :     return &mKeyHandlers;
     157             :   }
     158             : 
     159             : private:
     160             :   nsresult Read(nsIObjectInputStream* aStream,
     161             :                 nsXBLDocumentInfo* aDocInfo,
     162             :                 nsIDocument* aDocument,
     163             :                 uint8_t aFlags);
     164             : 
     165             :   /**
     166             :    * Read a new binding from the stream aStream into the xbl document aDocument.
     167             :    * aDocInfo should be the xbl document info for the binding document.
     168             :    * aFlags can contain XBLBinding_Serialize_InheritStyle to indicate that
     169             :    * mInheritStyle flag should be set, and XBLBinding_Serialize_IsFirstBinding
     170             :    * to indicate the first binding in a document.
     171             :    * XBLBinding_Serialize_ChromeOnlyContent indicates that
     172             :    * nsXBLPrototypeBinding::mChromeOnlyContent should be true.
     173             :    * XBLBinding_Serialize_BindToUntrustedContent indicates that
     174             :    * nsXBLPrototypeBinding::mBindToUntrustedContent should be true.
     175             :    */
     176             : public:
     177             :   static nsresult ReadNewBinding(nsIObjectInputStream* aStream,
     178             :                                  nsXBLDocumentInfo* aDocInfo,
     179             :                                  nsIDocument* aDocument,
     180             :                                  uint8_t aFlags);
     181             : 
     182             :   /**
     183             :    * Write this binding to the stream.
     184             :    */
     185             :   nsresult Write(nsIObjectOutputStream* aStream);
     186             : 
     187             :   /**
     188             :    * Read a content node from aStream and return it in aChild.
     189             :    * aDocument and aNim are the document and node info manager for the document
     190             :    * the child will be inserted into.
     191             :    */
     192             :   nsresult ReadContentNode(nsIObjectInputStream* aStream,
     193             :                            nsIDocument* aDocument,
     194             :                            nsNodeInfoManager* aNim,
     195             :                            nsIContent** aChild);
     196             : 
     197             :   /**
     198             :    * Write the content node aNode to aStream.
     199             :    *
     200             :    * This method is called recursively for each child descendant. For the topmost
     201             :    * call, aNode must be an element.
     202             :    *
     203             :    * Text, CDATA and comment nodes are serialized as:
     204             :    *   the constant XBLBinding_Serialize_TextNode, XBLBinding_Serialize_CDATANode
     205             :    *     or XBLBinding_Serialize_CommentNode
     206             :    *   the text for the node
     207             :    * Elements are serialized in the following format:
     208             :    *   node's namespace, written with WriteNamespace
     209             :    *   node's namespace prefix
     210             :    *   node's tag
     211             :    *   32-bit attribute count
     212             :    *   table of attributes:
     213             :    *     attribute's namespace, written with WriteNamespace
     214             :    *     attribute's namespace prefix
     215             :    *     attribute's tag
     216             :    *     attribute's value
     217             :    *   attribute forwarding table:
     218             :    *     source namespace
     219             :    *     source attribute
     220             :    *     destination namespace
     221             :    *     destination attribute
     222             :    *   the constant XBLBinding_Serialize_NoMoreAttributes
     223             :    *   32-bit count of the number of child nodes
     224             :    *     each child node is serialized in the same manner in sequence
     225             :    *   the constant XBLBinding_Serialize_NoContent
     226             :    */
     227             :   nsresult WriteContentNode(nsIObjectOutputStream* aStream, nsIContent* aNode);
     228             : 
     229             :   /**
     230             :    * Read or write a namespace id from or to aStream. If the namespace matches
     231             :    * one of the built-in ones defined in nsNameSpaceManager.h, it will be written as
     232             :    * a single byte with that value. Otherwise, XBLBinding_Serialize_CustomNamespace is
     233             :    * written out, followed by a string written with writeWStringZ.
     234             :    */
     235             :   nsresult ReadNamespace(nsIObjectInputStream* aStream, int32_t& aNameSpaceID);
     236             :   nsresult WriteNamespace(nsIObjectOutputStream* aStream, int32_t aNameSpaceID);
     237             : 
     238             : public:
     239             :   nsXBLPrototypeBinding();
     240             :   ~nsXBLPrototypeBinding();
     241             : 
     242             :   // Init must be called after construction to initialize the prototype
     243             :   // binding.  It may well throw errors (eg on out-of-memory).  Do not confuse
     244             :   // this with the Initialize() method, which must be called after the
     245             :   // binding's handlers, properties, etc are all set.
     246             :   nsresult Init(const nsACString& aRef,
     247             :                 nsXBLDocumentInfo* aInfo,
     248             :                 nsIContent* aElement,
     249             :                 bool aFirstBinding = false);
     250             : 
     251             :   void Traverse(nsCycleCollectionTraversalCallback &cb) const;
     252             :   void Unlink();
     253             :   void Trace(const TraceCallbacks& aCallbacks, void *aClosure) const;
     254             : 
     255             : // Internal member functions.
     256             : public:
     257             :   /**
     258             :    * GetImmediateChild locates the immediate child of our binding element which
     259             :    * has the localname given by aTag and is in the XBL namespace.
     260             :    */
     261             :   nsIContent* GetImmediateChild(nsIAtom* aTag);
     262             :   nsIContent* LocateInstance(nsIContent* aBoundElt,
     263             :                              nsIContent* aTemplRoot,
     264             :                              nsIContent* aCopyRoot,
     265             :                              nsIContent* aTemplChild);
     266             : 
     267         151 :   bool ChromeOnlyContent() { return mChromeOnlyContent; }
     268         633 :   bool BindToUntrustedContent() { return mBindToUntrustedContent; }
     269             : 
     270             :   typedef nsClassHashtable<nsISupportsHashKey, nsXBLAttributeEntry> InnerAttributeTable;
     271             : 
     272             : protected:
     273             :   // Ensure that mAttributeTable has been created.
     274             :   void EnsureAttributeTable();
     275             :   // Ad an entry to the attribute table
     276             :   void AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag,
     277             :                            int32_t aDestNamespaceID, nsIAtom* aDestTag,
     278             :                            nsIContent* aContent);
     279             :   void ConstructAttributeTable(nsIContent* aElement);
     280             :   void CreateKeyHandlers();
     281             : 
     282             : private:
     283             :   void EnsureResources();
     284             : 
     285             : // MEMBER VARIABLES
     286             : protected:
     287             :   nsCOMPtr<nsIURI> mBindingURI;
     288             :   nsCOMPtr<nsIURI> mAlternateBindingURI; // Alternate id-less URI that is only non-null on the first binding.
     289             :   nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
     290             :   nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
     291             : 
     292             :   // the url of the base binding
     293             :   nsCOMPtr<nsIURI> mBaseBindingURI;
     294             : 
     295             :   nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields,
     296             :                                    // the constructor, and the destructor).
     297             : 
     298             :   // Weak.  The docinfo will own our base binding.
     299             :   mozilla::WeakPtr<nsXBLPrototypeBinding> mBaseBinding;
     300             :   bool mInheritStyle;
     301             :   bool mCheckedBaseProto;
     302             :   bool mKeyHandlersRegistered;
     303             :   bool mChromeOnlyContent;
     304             :   bool mBindToUntrustedContent;
     305             : 
     306             :   nsAutoPtr<nsXBLPrototypeResources> mResources; // If we have any resources, this will be non-null.
     307             : 
     308             :   nsXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info.  Weak, since it owns us.
     309             : 
     310             :   // A table for attribute containers. Namespace IDs are used as
     311             :   // keys in the table. Containers are InnerAttributeTables.
     312             :   // This table is used to efficiently handle attribute changes.
     313             :   nsAutoPtr<nsClassHashtable<nsUint32HashKey, InnerAttributeTable>> mAttributeTable;
     314             : 
     315             :   class IIDHashKey : public PLDHashEntryHdr
     316             :   {
     317             :   public:
     318             :     typedef const nsIID& KeyType;
     319             :     typedef const nsIID* KeyTypePointer;
     320             : 
     321          61 :     explicit IIDHashKey(const nsIID* aKey)
     322          61 :       : mKey(*aKey)
     323          61 :     {}
     324             :     IIDHashKey(const IIDHashKey& aOther)
     325             :       : mKey(aOther.GetKey())
     326             :     {}
     327           0 :     ~IIDHashKey()
     328           0 :     {}
     329             : 
     330           0 :     KeyType GetKey() const
     331             :     {
     332           0 :       return mKey;
     333             :     }
     334          66 :     bool KeyEquals(const KeyTypePointer aKey) const
     335             :     {
     336          66 :       return mKey.Equals(*aKey);
     337             :     }
     338             : 
     339         380 :     static KeyTypePointer KeyToPointer(KeyType aKey)
     340             :     {
     341         380 :       return &aKey;
     342             :     }
     343         264 :     static PLDHashNumber HashKey(const KeyTypePointer aKey)
     344             :     {
     345             :       // Just use the 32-bit m0 field.
     346         264 :       return aKey->m0;
     347             :     }
     348             : 
     349             :     enum { ALLOW_MEMMOVE = true };
     350             : 
     351             :   private:
     352             :     nsIID mKey;
     353             :   };
     354             :   nsInterfaceHashtable<IIDHashKey, nsIContent> mInterfaceTable; // A table of cached interfaces that we support.
     355             : 
     356             :   int32_t mBaseNameSpaceID;    // If we extend a tagname/namespace, then that information will
     357             :   nsCOMPtr<nsIAtom> mBaseTag;  // be stored in here.
     358             : 
     359             :   nsCOMArray<nsXBLKeyEventHandler> mKeyHandlers;
     360             : };
     361             : 
     362             : #endif

Generated by: LCOV version 1.13