dom/xbl/nsXBLPrototypeBinding.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/xbl/nsXBLPrototypeBinding.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,342 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsXBLPrototypeBinding_h__
    1.10 +#define nsXBLPrototypeBinding_h__
    1.11 +
    1.12 +#include "nsClassHashtable.h"
    1.13 +#include "nsCOMArray.h"
    1.14 +#include "nsCOMPtr.h"
    1.15 +#include "nsICSSLoaderObserver.h"
    1.16 +#include "nsInterfaceHashtable.h"
    1.17 +#include "nsWeakReference.h"
    1.18 +#include "nsXBLDocumentInfo.h"
    1.19 +#include "nsXBLProtoImpl.h"
    1.20 +#include "nsXBLProtoImplMethod.h"
    1.21 +#include "nsXBLPrototypeHandler.h"
    1.22 +#include "nsXBLPrototypeResources.h"
    1.23 +
    1.24 +class nsIAtom;
    1.25 +class nsIContent;
    1.26 +class nsIDocument;
    1.27 +class nsXBLAttributeEntry;
    1.28 +class nsXBLBinding;
    1.29 +class nsXBLProtoImplField;
    1.30 +
    1.31 +// *********************************************************************/
    1.32 +// The XBLPrototypeBinding class
    1.33 +
    1.34 +// Instances of this class are owned by the nsXBLDocumentInfo object returned
    1.35 +// by XBLDocumentInfo().  Consumers who want to refcount things should refcount
    1.36 +// that.
    1.37 +class nsXBLPrototypeBinding MOZ_FINAL
    1.38 +{
    1.39 +public:
    1.40 +  nsIContent* GetBindingElement() const { return mBinding; }
    1.41 +  void SetBindingElement(nsIContent* aElement);
    1.42 +
    1.43 +  nsIURI* BindingURI() const { return mBindingURI; }
    1.44 +  nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; }
    1.45 +  nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
    1.46 +  nsIURI* GetBaseBindingURI() const { return mBaseBindingURI; }
    1.47 +
    1.48 +  // Checks if aURI refers to this binding by comparing to both possible
    1.49 +  // binding URIs.
    1.50 +  bool CompareBindingURI(nsIURI* aURI) const;
    1.51 +
    1.52 +  bool GetAllowScripts() const;
    1.53 +
    1.54 +  nsresult BindingAttached(nsIContent* aBoundElement);
    1.55 +  nsresult BindingDetached(nsIContent* aBoundElement);
    1.56 +
    1.57 +  bool LoadResources();
    1.58 +  nsresult AddResource(nsIAtom* aResourceType, const nsAString& aSrc);
    1.59 +
    1.60 +  bool InheritsStyle() const { return mInheritStyle; }
    1.61 +  void SetInheritsStyle(bool aInheritStyle) { mInheritStyle = aInheritStyle; }
    1.62 +
    1.63 +  nsXBLPrototypeHandler* GetPrototypeHandlers() { return mPrototypeHandler; }
    1.64 +  void SetPrototypeHandlers(nsXBLPrototypeHandler* aHandler) { mPrototypeHandler = aHandler; }
    1.65 +
    1.66 +  nsXBLProtoImplAnonymousMethod* GetConstructor();
    1.67 +  nsresult SetConstructor(nsXBLProtoImplAnonymousMethod* aConstructor);
    1.68 +  nsXBLProtoImplAnonymousMethod* GetDestructor();
    1.69 +  nsresult SetDestructor(nsXBLProtoImplAnonymousMethod* aDestructor);
    1.70 +
    1.71 +  nsXBLProtoImplField* FindField(const nsString& aFieldName) const
    1.72 +  {
    1.73 +    return mImplementation ? mImplementation->FindField(aFieldName) : nullptr;
    1.74 +  }
    1.75 +
    1.76 +  // Resolve all the fields for this binding on the object |obj|.
    1.77 +  // False return means a JS exception was set.
    1.78 +  bool ResolveAllFields(JSContext* cx, JS::Handle<JSObject*> obj) const
    1.79 +  {
    1.80 +    return !mImplementation || mImplementation->ResolveAllFields(cx, obj);
    1.81 +  }
    1.82 +
    1.83 +  // Undefine all our fields from object |obj| (which should be a
    1.84 +  // JSObject for a bound element).
    1.85 +  void UndefineFields(JSContext* cx, JS::Handle<JSObject*> obj) const {
    1.86 +    if (mImplementation) {
    1.87 +      mImplementation->UndefineFields(cx, obj);
    1.88 +    }
    1.89 +  }
    1.90 +
    1.91 +  const nsCString& ClassName() const {
    1.92 +    return mImplementation ? mImplementation->mClassName : EmptyCString();
    1.93 +  }
    1.94 +
    1.95 +  nsresult InitClass(const nsCString& aClassName, JSContext * aContext,
    1.96 +                     JS::Handle<JSObject*> aScriptObject,
    1.97 +                     JS::MutableHandle<JSObject*> aClassObject,
    1.98 +                     bool* aNew);
    1.99 +
   1.100 +  nsresult ConstructInterfaceTable(const nsAString& aImpls);
   1.101 +
   1.102 +  void SetImplementation(nsXBLProtoImpl* aImpl) { mImplementation = aImpl; }
   1.103 +  nsXBLProtoImpl* GetImplementation() { return mImplementation; }
   1.104 +  nsresult InstallImplementation(nsXBLBinding* aBinding);
   1.105 +  bool HasImplementation() const { return mImplementation != nullptr; }
   1.106 +
   1.107 +  void AttributeChanged(nsIAtom* aAttribute, int32_t aNameSpaceID,
   1.108 +                        bool aRemoveFlag, nsIContent* aChangedElement,
   1.109 +                        nsIContent* aAnonymousContent, bool aNotify);
   1.110 +
   1.111 +  void SetBasePrototype(nsXBLPrototypeBinding* aBinding);
   1.112 +  nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
   1.113 +
   1.114 +  nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; }
   1.115 +  bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
   1.116 +
   1.117 +  void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
   1.118 +
   1.119 +  nsIStyleRuleProcessor* GetRuleProcessor();
   1.120 +  nsXBLPrototypeResources::sheet_array_type* GetOrCreateStyleSheets();
   1.121 +  nsXBLPrototypeResources::sheet_array_type* GetStyleSheets();
   1.122 +
   1.123 +  bool HasStyleSheets() {
   1.124 +    return mResources && mResources->mStyleSheetList.Length() > 0;
   1.125 +  }
   1.126 +
   1.127 +  nsresult FlushSkinSheets();
   1.128 +
   1.129 +  nsIAtom* GetBaseTag(int32_t* aNamespaceID);
   1.130 +  void SetBaseTag(int32_t aNamespaceID, nsIAtom* aTag);
   1.131 +
   1.132 +  bool ImplementsInterface(REFNSIID aIID) const;
   1.133 +
   1.134 +  nsresult AddResourceListener(nsIContent* aBoundElement);
   1.135 +
   1.136 +  void Initialize();
   1.137 +
   1.138 +  nsresult ResolveBaseBinding();
   1.139 +
   1.140 +  const nsCOMArray<nsXBLKeyEventHandler>* GetKeyEventHandlers()
   1.141 +  {
   1.142 +    if (!mKeyHandlersRegistered) {
   1.143 +      CreateKeyHandlers();
   1.144 +      mKeyHandlersRegistered = true;
   1.145 +    }
   1.146 +
   1.147 +    return &mKeyHandlers;
   1.148 +  }
   1.149 +
   1.150 +private:
   1.151 +  nsresult Read(nsIObjectInputStream* aStream,
   1.152 +                nsXBLDocumentInfo* aDocInfo,
   1.153 +                nsIDocument* aDocument,
   1.154 +                uint8_t aFlags);
   1.155 +
   1.156 +  /**
   1.157 +   * Read a new binding from the stream aStream into the xbl document aDocument.
   1.158 +   * aDocInfo should be the xbl document info for the binding document.
   1.159 +   * aFlags can contain XBLBinding_Serialize_InheritStyle to indicate that
   1.160 +   * mInheritStyle flag should be set, and XBLBinding_Serialize_IsFirstBinding
   1.161 +   * to indicate the first binding in a document.
   1.162 +   * XBLBinding_Serialize_ChromeOnlyContent indicates that
   1.163 +   * nsXBLPrototypeBinding::mChromeOnlyContent should be true.
   1.164 +   */
   1.165 +public:
   1.166 +  static nsresult ReadNewBinding(nsIObjectInputStream* aStream,
   1.167 +                                 nsXBLDocumentInfo* aDocInfo,
   1.168 +                                 nsIDocument* aDocument,
   1.169 +                                 uint8_t aFlags);
   1.170 +
   1.171 +  /**
   1.172 +   * Write this binding to the stream.
   1.173 +   */
   1.174 +  nsresult Write(nsIObjectOutputStream* aStream);
   1.175 +
   1.176 +  /**
   1.177 +   * Read a content node from aStream and return it in aChild.
   1.178 +   * aDocument and aNim are the document and node info manager for the document
   1.179 +   * the child will be inserted into.
   1.180 +   */
   1.181 +  nsresult ReadContentNode(nsIObjectInputStream* aStream,
   1.182 +                           nsIDocument* aDocument,
   1.183 +                           nsNodeInfoManager* aNim,
   1.184 +                           nsIContent** aChild);
   1.185 +
   1.186 +  /**
   1.187 +   * Write the content node aNode to aStream.
   1.188 +   *
   1.189 +   * This method is called recursively for each child descendant. For the topmost
   1.190 +   * call, aNode must be an element.
   1.191 +   *
   1.192 +   * Text, CDATA and comment nodes are serialized as:
   1.193 +   *   the constant XBLBinding_Serialize_TextNode, XBLBinding_Serialize_CDATANode
   1.194 +   *     or XBLBinding_Serialize_CommentNode
   1.195 +   *   the text for the node
   1.196 +   * Elements are serialized in the following format:
   1.197 +   *   node's namespace, written with WriteNamespace
   1.198 +   *   node's namespace prefix
   1.199 +   *   node's tag
   1.200 +   *   32-bit attribute count
   1.201 +   *   table of attributes:
   1.202 +   *     attribute's namespace, written with WriteNamespace
   1.203 +   *     attribute's namespace prefix
   1.204 +   *     attribute's tag
   1.205 +   *     attribute's value
   1.206 +   *   attribute forwarding table:
   1.207 +   *     source namespace
   1.208 +   *     source attribute
   1.209 +   *     destination namespace
   1.210 +   *     destination attribute
   1.211 +   *   the constant XBLBinding_Serialize_NoMoreAttributes
   1.212 +   *   32-bit count of the number of child nodes
   1.213 +   *     each child node is serialized in the same manner in sequence
   1.214 +   *   the constant XBLBinding_Serialize_NoContent
   1.215 +   */
   1.216 +  nsresult WriteContentNode(nsIObjectOutputStream* aStream, nsIContent* aNode);
   1.217 +
   1.218 +  /**
   1.219 +   * Read or write a namespace id from or to aStream. If the namespace matches
   1.220 +   * one of the built-in ones defined in nsNameSpaceManager.h, it will be written as
   1.221 +   * a single byte with that value. Otherwise, XBLBinding_Serialize_CustomNamespace is
   1.222 +   * written out, followed by a string written with writeWStringZ.
   1.223 +   */
   1.224 +  nsresult ReadNamespace(nsIObjectInputStream* aStream, int32_t& aNameSpaceID);
   1.225 +  nsresult WriteNamespace(nsIObjectOutputStream* aStream, int32_t aNameSpaceID);
   1.226 +
   1.227 +public:
   1.228 +  nsXBLPrototypeBinding();
   1.229 +  ~nsXBLPrototypeBinding();
   1.230 +
   1.231 +  // Init must be called after construction to initialize the prototype
   1.232 +  // binding.  It may well throw errors (eg on out-of-memory).  Do not confuse
   1.233 +  // this with the Initialize() method, which must be called after the
   1.234 +  // binding's handlers, properties, etc are all set.
   1.235 +  nsresult Init(const nsACString& aRef,
   1.236 +                nsXBLDocumentInfo* aInfo,
   1.237 +                nsIContent* aElement,
   1.238 +                bool aFirstBinding = false);
   1.239 +
   1.240 +  void Traverse(nsCycleCollectionTraversalCallback &cb) const;
   1.241 +  void UnlinkJSObjects();
   1.242 +  void Trace(const TraceCallbacks& aCallbacks, void *aClosure) const;
   1.243 +
   1.244 +// Internal member functions.
   1.245 +public:
   1.246 +  /**
   1.247 +   * GetImmediateChild locates the immediate child of our binding element which
   1.248 +   * has the localname given by aTag and is in the XBL namespace.
   1.249 +   */
   1.250 +  nsIContent* GetImmediateChild(nsIAtom* aTag);
   1.251 +  nsIContent* LocateInstance(nsIContent* aBoundElt,
   1.252 +                             nsIContent* aTemplRoot,
   1.253 +                             nsIContent* aCopyRoot,
   1.254 +                             nsIContent* aTemplChild);
   1.255 +
   1.256 +  bool ChromeOnlyContent() { return mChromeOnlyContent; }
   1.257 +
   1.258 +  typedef nsClassHashtable<nsISupportsHashKey, nsXBLAttributeEntry> InnerAttributeTable;
   1.259 +
   1.260 +protected:
   1.261 +  // Ensure that mAttributeTable has been created.
   1.262 +  void EnsureAttributeTable();
   1.263 +  // Ad an entry to the attribute table
   1.264 +  void AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag,
   1.265 +                           int32_t aDestNamespaceID, nsIAtom* aDestTag,
   1.266 +                           nsIContent* aContent);
   1.267 +  void ConstructAttributeTable(nsIContent* aElement);
   1.268 +  void CreateKeyHandlers();
   1.269 +
   1.270 +// MEMBER VARIABLES
   1.271 +protected:
   1.272 +  nsCOMPtr<nsIURI> mBindingURI;
   1.273 +  nsCOMPtr<nsIURI> mAlternateBindingURI; // Alternate id-less URI that is only non-null on the first binding.
   1.274 +  nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
   1.275 +  nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
   1.276 +
   1.277 +  // the url of the base binding
   1.278 +  nsCOMPtr<nsIURI> mBaseBindingURI;
   1.279 +
   1.280 +  nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields,
   1.281 +                                   // the constructor, and the destructor).
   1.282 +
   1.283 +  nsXBLPrototypeBinding* mBaseBinding; // Weak.  The docinfo will own our base binding.
   1.284 +  bool mInheritStyle;
   1.285 +  bool mCheckedBaseProto;
   1.286 +  bool mKeyHandlersRegistered;
   1.287 +  bool mChromeOnlyContent;
   1.288 +
   1.289 +  nsAutoPtr<nsXBLPrototypeResources> mResources; // If we have any resources, this will be non-null.
   1.290 +
   1.291 +  nsXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info.  Weak, since it owns us.
   1.292 +
   1.293 +  // A table for attribute containers. Namespace IDs are used as
   1.294 +  // keys in the table. Containers are InnerAttributeTables.
   1.295 +  // This table is used to efficiently handle attribute changes.
   1.296 +  nsAutoPtr<nsClassHashtable<nsUint32HashKey, InnerAttributeTable>> mAttributeTable;
   1.297 +
   1.298 +  class IIDHashKey : public PLDHashEntryHdr
   1.299 +  {
   1.300 +  public:
   1.301 +    typedef const nsIID& KeyType;
   1.302 +    typedef const nsIID* KeyTypePointer;
   1.303 +
   1.304 +    IIDHashKey(const nsIID* aKey)
   1.305 +      : mKey(*aKey)
   1.306 +    {}
   1.307 +    IIDHashKey(const IIDHashKey& aOther)
   1.308 +      : mKey(aOther.GetKey())
   1.309 +    {}
   1.310 +    ~IIDHashKey()
   1.311 +    {}
   1.312 +
   1.313 +    KeyType GetKey() const
   1.314 +    {
   1.315 +      return mKey;
   1.316 +    }
   1.317 +    bool KeyEquals(const KeyTypePointer aKey) const
   1.318 +    {
   1.319 +      return mKey.Equals(*aKey);
   1.320 +    }
   1.321 +
   1.322 +    static KeyTypePointer KeyToPointer(KeyType aKey)
   1.323 +    {
   1.324 +      return &aKey;
   1.325 +    }
   1.326 +    static PLDHashNumber HashKey(const KeyTypePointer aKey)
   1.327 +    {
   1.328 +      // Just use the 32-bit m0 field.
   1.329 +      return aKey->m0;
   1.330 +    }
   1.331 +
   1.332 +    enum { ALLOW_MEMMOVE = true };
   1.333 +
   1.334 +  private:
   1.335 +    nsIID mKey;
   1.336 +  };
   1.337 +  nsInterfaceHashtable<IIDHashKey, nsIContent> mInterfaceTable; // A table of cached interfaces that we support.
   1.338 +
   1.339 +  int32_t mBaseNameSpaceID;    // If we extend a tagname/namespace, then that information will
   1.340 +  nsCOMPtr<nsIAtom> mBaseTag;  // be stored in here.
   1.341 +
   1.342 +  nsCOMArray<nsXBLKeyEventHandler> mKeyHandlers;
   1.343 +};
   1.344 +
   1.345 +#endif

mercurial