michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsBindingManager_h_ michael@0: #define nsBindingManager_h_ michael@0: michael@0: #include "nsIContent.h" michael@0: #include "nsStubMutationObserver.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsInterfaceHashtable.h" michael@0: #include "nsRefPtrHashtable.h" michael@0: #include "nsURIHashKey.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "nsXBLBinding.h" michael@0: #include "nsTArray.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: struct ElementDependentRuleProcessorData; michael@0: class nsIXPConnectWrappedJS; michael@0: class nsIAtom; michael@0: class nsIDOMNodeList; michael@0: class nsIDocument; michael@0: class nsIURI; michael@0: class nsXBLDocumentInfo; michael@0: class nsIStreamListener; michael@0: class nsStyleSet; michael@0: class nsXBLBinding; michael@0: template class nsRefPtr; michael@0: typedef nsTArray > nsBindingList; michael@0: class nsIPrincipal; michael@0: class nsCSSStyleSheet; michael@0: michael@0: class nsBindingManager MOZ_FINAL : public nsStubMutationObserver michael@0: { michael@0: public: michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED michael@0: NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED michael@0: michael@0: nsBindingManager(nsIDocument* aDocument); michael@0: ~nsBindingManager(); michael@0: michael@0: nsXBLBinding* GetBindingWithContent(nsIContent* aContent); michael@0: michael@0: void AddBoundContent(nsIContent* aContent); michael@0: void RemoveBoundContent(nsIContent* aContent); michael@0: michael@0: /** michael@0: * Notify the binding manager that an element michael@0: * has been removed from its document, michael@0: * so that it can update any bindings or michael@0: * nsIAnonymousContentCreator-created anonymous michael@0: * content that may depend on the document. michael@0: * @param aContent the element that's being moved michael@0: * @param aOldDocument the old document in which the michael@0: * content resided. michael@0: */ michael@0: void RemovedFromDocument(nsIContent* aContent, nsIDocument* aOldDocument) michael@0: { michael@0: if (aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) { michael@0: RemovedFromDocumentInternal(aContent, aOldDocument); michael@0: } michael@0: } michael@0: void RemovedFromDocumentInternal(nsIContent* aContent, michael@0: nsIDocument* aOldDocument); michael@0: michael@0: nsIAtom* ResolveTag(nsIContent* aContent, int32_t* aNameSpaceID); michael@0: michael@0: /** michael@0: * Return the nodelist of "anonymous" kids for this node. This might michael@0: * actually include some of the nodes actual DOM kids, if there are michael@0: * tags directly as kids of . This will only end up michael@0: * returning a non-null list for nodes which have a binding attached. michael@0: */ michael@0: nsresult GetAnonymousNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult); michael@0: nsINodeList* GetAnonymousNodesFor(nsIContent* aContent); michael@0: michael@0: nsresult ClearBinding(nsIContent* aContent); michael@0: nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL, michael@0: nsIPrincipal* aOriginPrincipal); michael@0: michael@0: nsresult AddToAttachedQueue(nsXBLBinding* aBinding); michael@0: void RemoveFromAttachedQueue(nsXBLBinding* aBinding); michael@0: void ProcessAttachedQueue(uint32_t aSkipSize = 0); michael@0: michael@0: void ExecuteDetachedHandlers(); michael@0: michael@0: nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo); michael@0: nsXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURI); michael@0: void RemoveXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo); michael@0: michael@0: nsresult PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener); michael@0: nsIStreamListener* GetLoadingDocListener(nsIURI* aURL); michael@0: void RemoveLoadingDocListener(nsIURI* aURL); michael@0: michael@0: void FlushSkinBindings(); michael@0: michael@0: nsresult GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult); michael@0: michael@0: // Style rule methods michael@0: nsresult WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc, michael@0: ElementDependentRuleProcessorData* aData, michael@0: bool* aCutOffInheritance); michael@0: michael@0: void WalkAllRules(nsIStyleRuleProcessor::EnumFunc aFunc, michael@0: ElementDependentRuleProcessorData* aData); michael@0: /** michael@0: * Do any processing that needs to happen as a result of a change in michael@0: * the characteristics of the medium, and return whether this rule michael@0: * processor's rules have changed (e.g., because of media queries). michael@0: */ michael@0: nsresult MediumFeaturesChanged(nsPresContext* aPresContext, michael@0: bool* aRulesChanged); michael@0: michael@0: void AppendAllSheets(nsTArray& aArray); michael@0: michael@0: NS_HIDDEN_(void) Traverse(nsIContent *aContent, michael@0: nsCycleCollectionTraversalCallback &cb); michael@0: michael@0: NS_DECL_CYCLE_COLLECTION_CLASS(nsBindingManager) michael@0: michael@0: // Notify the binding manager when an outermost update begins and michael@0: // ends. The end method can execute script. michael@0: void BeginOutermostUpdate(); michael@0: void EndOutermostUpdate(); michael@0: michael@0: // When removing an insertion point or a parent of one, clear the insertion michael@0: // points and their insertion parents. michael@0: void ClearInsertionPointsRecursively(nsIContent* aContent); michael@0: michael@0: // Called when the document is going away michael@0: void DropDocumentReference(); michael@0: michael@0: nsIContent* FindNestedInsertionPoint(nsIContent* aContainer, michael@0: nsIContent* aChild); michael@0: michael@0: nsIContent* FindNestedSingleInsertionPoint(nsIContent* aContainer, bool* aMulti); michael@0: michael@0: protected: michael@0: nsIXPConnectWrappedJS* GetWrappedJS(nsIContent* aContent); michael@0: nsresult SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aResult); michael@0: michael@0: // Called by ContentAppended and ContentInserted to handle a single child michael@0: // insertion. aChild must not be null. aContainer may be null. michael@0: // aIndexInContainer is the index of the child in the parent. aAppend is michael@0: // true if this child is being appended, not inserted. michael@0: void HandleChildInsertion(nsIContent* aContainer, nsIContent* aChild, michael@0: uint32_t aIndexInContainer, bool aAppend); michael@0: michael@0: // Same as ProcessAttachedQueue, but also nulls out michael@0: // mProcessAttachedQueueEvent michael@0: void DoProcessAttachedQueue(); michael@0: michael@0: // Post an event to process the attached queue. michael@0: void PostProcessAttachedQueueEvent(); michael@0: michael@0: // MEMBER VARIABLES michael@0: protected: michael@0: // A set of nsIContent that currently have a binding installed. michael@0: nsAutoPtr > > mBoundContentSet; michael@0: michael@0: // A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect michael@0: // wrapper for JS objects). For XBL bindings that implement XPIDL michael@0: // interfaces, and that get referred to from C++, this table caches michael@0: // the XPConnect wrapper for the binding. By caching it, I control michael@0: // its lifetime, and I prevent a re-wrap of the same script object michael@0: // (in the case where multiple bindings in an XBL inheritance chain michael@0: // both implement an XPIDL interface). michael@0: typedef nsInterfaceHashtable WrapperHashtable; michael@0: nsAutoPtr mWrapperTable; michael@0: michael@0: // A mapping from a URL (a string) to nsXBLDocumentInfo*. This table michael@0: // is the cache of all binding documents that have been loaded by a michael@0: // given bound document. michael@0: nsAutoPtr > mDocumentTable; michael@0: michael@0: // A mapping from a URL (a string) to a nsIStreamListener. This michael@0: // table is the currently loading binding docs. If they're in this michael@0: // table, they have not yet finished loading. michael@0: nsAutoPtr > mLoadingDocTable; michael@0: michael@0: // A queue of binding attached event handlers that are awaiting execution. michael@0: nsBindingList mAttachedStack; michael@0: bool mProcessingAttachedStack; michael@0: bool mDestroyed; michael@0: uint32_t mAttachedStackSizeOnOutermost; michael@0: michael@0: // Our posted event to process the attached queue, if any michael@0: friend class nsRunnableMethod; michael@0: nsRefPtr< nsRunnableMethod > mProcessAttachedQueueEvent; michael@0: michael@0: // Our document. This is a weak ref; the document owns us michael@0: nsIDocument* mDocument; michael@0: }; michael@0: michael@0: #endif