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