From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/xbl/nsXBLPrototypeBinding.h | 359 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 dom/xbl/nsXBLPrototypeBinding.h (limited to 'dom/xbl/nsXBLPrototypeBinding.h') diff --git a/dom/xbl/nsXBLPrototypeBinding.h b/dom/xbl/nsXBLPrototypeBinding.h new file mode 100644 index 000000000..4c51a2083 --- /dev/null +++ b/dom/xbl/nsXBLPrototypeBinding.h @@ -0,0 +1,359 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsXBLPrototypeBinding_h__ +#define nsXBLPrototypeBinding_h__ + +#include "nsAutoPtr.h" +#include "nsClassHashtable.h" +#include "nsCOMArray.h" +#include "nsCOMPtr.h" +#include "nsICSSLoaderObserver.h" +#include "nsInterfaceHashtable.h" +#include "nsWeakReference.h" +#include "nsXBLDocumentInfo.h" +#include "nsXBLProtoImpl.h" +#include "nsXBLProtoImplMethod.h" +#include "nsXBLPrototypeHandler.h" +#include "nsXBLPrototypeResources.h" +#include "mozilla/WeakPtr.h" +#include "mozilla/StyleSheet.h" + +class nsIAtom; +class nsIContent; +class nsIDocument; +class nsXBLAttributeEntry; +class nsXBLBinding; +class nsXBLProtoImplField; + +// *********************************************************************/ +// The XBLPrototypeBinding class + +// Instances of this class are owned by the nsXBLDocumentInfo object returned +// by XBLDocumentInfo(). Consumers who want to refcount things should refcount +// that. +class nsXBLPrototypeBinding final : + public mozilla::SupportsWeakPtr +{ +public: + MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsXBLPrototypeBinding) + + nsIContent* GetBindingElement() const { return mBinding; } + void SetBindingElement(nsIContent* aElement); + + nsIURI* BindingURI() const { return mBindingURI; } + nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; } + nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); } + nsIURI* GetBaseBindingURI() const { return mBaseBindingURI; } + + // Checks if aURI refers to this binding by comparing to both possible + // binding URIs. + bool CompareBindingURI(nsIURI* aURI) const; + + bool GetAllowScripts() const; + + nsresult BindingAttached(nsIContent* aBoundElement); + nsresult BindingDetached(nsIContent* aBoundElement); + + bool LoadResources(); + nsresult AddResource(nsIAtom* aResourceType, const nsAString& aSrc); + + bool InheritsStyle() const { return mInheritStyle; } + void SetInheritsStyle(bool aInheritStyle) { mInheritStyle = aInheritStyle; } + + nsXBLPrototypeHandler* GetPrototypeHandlers() { return mPrototypeHandler; } + void SetPrototypeHandlers(nsXBLPrototypeHandler* aHandler) { mPrototypeHandler = aHandler; } + + nsXBLProtoImplAnonymousMethod* GetConstructor(); + nsresult SetConstructor(nsXBLProtoImplAnonymousMethod* aConstructor); + nsXBLProtoImplAnonymousMethod* GetDestructor(); + nsresult SetDestructor(nsXBLProtoImplAnonymousMethod* aDestructor); + + nsXBLProtoImplField* FindField(const nsString& aFieldName) const + { + return mImplementation ? mImplementation->FindField(aFieldName) : nullptr; + } + + // Resolve all the fields for this binding on the object |obj|. + // False return means a JS exception was set. + bool ResolveAllFields(JSContext* cx, JS::Handle obj) const + { + return !mImplementation || mImplementation->ResolveAllFields(cx, obj); + } + + // Undefine all our fields from object |obj| (which should be a + // JSObject for a bound element). + void UndefineFields(JSContext* cx, JS::Handle obj) const { + if (mImplementation) { + mImplementation->UndefineFields(cx, obj); + } + } + + const nsString& ClassName() const { + return mImplementation ? mImplementation->mClassName : EmptyString(); + } + + nsresult InitClass(const nsString& aClassName, JSContext* aContext, + JS::Handle aScriptObject, + JS::MutableHandle aClassObject, + bool* aNew); + + nsresult ConstructInterfaceTable(const nsAString& aImpls); + + void SetImplementation(nsXBLProtoImpl* aImpl) { mImplementation = aImpl; } + nsXBLProtoImpl* GetImplementation() { return mImplementation; } + nsresult InstallImplementation(nsXBLBinding* aBinding); + bool HasImplementation() const { return mImplementation != nullptr; } + + void AttributeChanged(nsIAtom* aAttribute, int32_t aNameSpaceID, + bool aRemoveFlag, nsIContent* aChangedElement, + nsIContent* aAnonymousContent, bool aNotify); + + void SetBasePrototype(nsXBLPrototypeBinding* aBinding); + nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; } + + nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; } + bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); } + + void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent); + + void AppendStyleSheet(mozilla::StyleSheet* aSheet); + void RemoveStyleSheet(mozilla::StyleSheet* aSheet); + void InsertStyleSheetAt(size_t aIndex, mozilla::StyleSheet* aSheet); + mozilla::StyleSheet* StyleSheetAt(size_t aIndex) const; + size_t SheetCount() const; + bool HasStyleSheets() const; + void AppendStyleSheetsTo(nsTArray& aResult) const; + + nsIStyleRuleProcessor* GetRuleProcessor(); + + nsresult FlushSkinSheets(); + + nsIAtom* GetBaseTag(int32_t* aNamespaceID); + void SetBaseTag(int32_t aNamespaceID, nsIAtom* aTag); + + bool ImplementsInterface(REFNSIID aIID) const; + + nsresult AddResourceListener(nsIContent* aBoundElement); + + void Initialize(); + + nsresult ResolveBaseBinding(); + + const nsCOMArray* GetKeyEventHandlers() + { + if (!mKeyHandlersRegistered) { + CreateKeyHandlers(); + mKeyHandlersRegistered = true; + } + + return &mKeyHandlers; + } + +private: + nsresult Read(nsIObjectInputStream* aStream, + nsXBLDocumentInfo* aDocInfo, + nsIDocument* aDocument, + uint8_t aFlags); + + /** + * Read a new binding from the stream aStream into the xbl document aDocument. + * aDocInfo should be the xbl document info for the binding document. + * aFlags can contain XBLBinding_Serialize_InheritStyle to indicate that + * mInheritStyle flag should be set, and XBLBinding_Serialize_IsFirstBinding + * to indicate the first binding in a document. + * XBLBinding_Serialize_ChromeOnlyContent indicates that + * nsXBLPrototypeBinding::mChromeOnlyContent should be true. + * XBLBinding_Serialize_BindToUntrustedContent indicates that + * nsXBLPrototypeBinding::mBindToUntrustedContent should be true. + */ +public: + static nsresult ReadNewBinding(nsIObjectInputStream* aStream, + nsXBLDocumentInfo* aDocInfo, + nsIDocument* aDocument, + uint8_t aFlags); + + /** + * Write this binding to the stream. + */ + nsresult Write(nsIObjectOutputStream* aStream); + + /** + * Read a content node from aStream and return it in aChild. + * aDocument and aNim are the document and node info manager for the document + * the child will be inserted into. + */ + nsresult ReadContentNode(nsIObjectInputStream* aStream, + nsIDocument* aDocument, + nsNodeInfoManager* aNim, + nsIContent** aChild); + + /** + * Write the content node aNode to aStream. + * + * This method is called recursively for each child descendant. For the topmost + * call, aNode must be an element. + * + * Text, CDATA and comment nodes are serialized as: + * the constant XBLBinding_Serialize_TextNode, XBLBinding_Serialize_CDATANode + * or XBLBinding_Serialize_CommentNode + * the text for the node + * Elements are serialized in the following format: + * node's namespace, written with WriteNamespace + * node's namespace prefix + * node's tag + * 32-bit attribute count + * table of attributes: + * attribute's namespace, written with WriteNamespace + * attribute's namespace prefix + * attribute's tag + * attribute's value + * attribute forwarding table: + * source namespace + * source attribute + * destination namespace + * destination attribute + * the constant XBLBinding_Serialize_NoMoreAttributes + * 32-bit count of the number of child nodes + * each child node is serialized in the same manner in sequence + * the constant XBLBinding_Serialize_NoContent + */ + nsresult WriteContentNode(nsIObjectOutputStream* aStream, nsIContent* aNode); + + /** + * Read or write a namespace id from or to aStream. If the namespace matches + * one of the built-in ones defined in nsNameSpaceManager.h, it will be written as + * a single byte with that value. Otherwise, XBLBinding_Serialize_CustomNamespace is + * written out, followed by a string written with writeWStringZ. + */ + nsresult ReadNamespace(nsIObjectInputStream* aStream, int32_t& aNameSpaceID); + nsresult WriteNamespace(nsIObjectOutputStream* aStream, int32_t aNameSpaceID); + +public: + nsXBLPrototypeBinding(); + ~nsXBLPrototypeBinding(); + + // Init must be called after construction to initialize the prototype + // binding. It may well throw errors (eg on out-of-memory). Do not confuse + // this with the Initialize() method, which must be called after the + // binding's handlers, properties, etc are all set. + nsresult Init(const nsACString& aRef, + nsXBLDocumentInfo* aInfo, + nsIContent* aElement, + bool aFirstBinding = false); + + void Traverse(nsCycleCollectionTraversalCallback &cb) const; + void Unlink(); + void Trace(const TraceCallbacks& aCallbacks, void *aClosure) const; + +// Internal member functions. +public: + /** + * GetImmediateChild locates the immediate child of our binding element which + * has the localname given by aTag and is in the XBL namespace. + */ + nsIContent* GetImmediateChild(nsIAtom* aTag); + nsIContent* LocateInstance(nsIContent* aBoundElt, + nsIContent* aTemplRoot, + nsIContent* aCopyRoot, + nsIContent* aTemplChild); + + bool ChromeOnlyContent() { return mChromeOnlyContent; } + bool BindToUntrustedContent() { return mBindToUntrustedContent; } + + typedef nsClassHashtable InnerAttributeTable; + +protected: + // Ensure that mAttributeTable has been created. + void EnsureAttributeTable(); + // Ad an entry to the attribute table + void AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag, + int32_t aDestNamespaceID, nsIAtom* aDestTag, + nsIContent* aContent); + void ConstructAttributeTable(nsIContent* aElement); + void CreateKeyHandlers(); + +private: + void EnsureResources(); + +// MEMBER VARIABLES +protected: + nsCOMPtr mBindingURI; + nsCOMPtr mAlternateBindingURI; // Alternate id-less URI that is only non-null on the first binding. + nsCOMPtr mBinding; // Strong. We own a ref to our content element in the binding doc. + nsAutoPtr mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers. + + // the url of the base binding + nsCOMPtr mBaseBindingURI; + + nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields, + // the constructor, and the destructor). + + // Weak. The docinfo will own our base binding. + mozilla::WeakPtr mBaseBinding; + bool mInheritStyle; + bool mCheckedBaseProto; + bool mKeyHandlersRegistered; + bool mChromeOnlyContent; + bool mBindToUntrustedContent; + + nsAutoPtr mResources; // If we have any resources, this will be non-null. + + nsXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info. Weak, since it owns us. + + // A table for attribute containers. Namespace IDs are used as + // keys in the table. Containers are InnerAttributeTables. + // This table is used to efficiently handle attribute changes. + nsAutoPtr> mAttributeTable; + + class IIDHashKey : public PLDHashEntryHdr + { + public: + typedef const nsIID& KeyType; + typedef const nsIID* KeyTypePointer; + + explicit IIDHashKey(const nsIID* aKey) + : mKey(*aKey) + {} + IIDHashKey(const IIDHashKey& aOther) + : mKey(aOther.GetKey()) + {} + ~IIDHashKey() + {} + + KeyType GetKey() const + { + return mKey; + } + bool KeyEquals(const KeyTypePointer aKey) const + { + return mKey.Equals(*aKey); + } + + static KeyTypePointer KeyToPointer(KeyType aKey) + { + return &aKey; + } + static PLDHashNumber HashKey(const KeyTypePointer aKey) + { + // Just use the 32-bit m0 field. + return aKey->m0; + } + + enum { ALLOW_MEMMOVE = true }; + + private: + nsIID mKey; + }; + nsInterfaceHashtable mInterfaceTable; // A table of cached interfaces that we support. + + int32_t mBaseNameSpaceID; // If we extend a tagname/namespace, then that information will + nsCOMPtr mBaseTag; // be stored in here. + + nsCOMArray mKeyHandlers; +}; + +#endif -- cgit v1.2.3