summaryrefslogtreecommitdiffstats
path: root/dom/xbl/nsBindingManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xbl/nsBindingManager.h')
-rw-r--r--dom/xbl/nsBindingManager.h235
1 files changed, 235 insertions, 0 deletions
diff --git a/dom/xbl/nsBindingManager.h b/dom/xbl/nsBindingManager.h
new file mode 100644
index 000000000..a71ff2188
--- /dev/null
+++ b/dom/xbl/nsBindingManager.h
@@ -0,0 +1,235 @@
+/* -*- 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 nsBindingManager_h_
+#define nsBindingManager_h_
+
+#include "nsAutoPtr.h"
+#include "nsIContent.h"
+#include "nsStubMutationObserver.h"
+#include "nsHashKeys.h"
+#include "nsInterfaceHashtable.h"
+#include "nsRefPtrHashtable.h"
+#include "nsURIHashKey.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsXBLBinding.h"
+#include "nsTArray.h"
+#include "nsThreadUtils.h"
+#include "mozilla/StyleSheet.h"
+
+struct ElementDependentRuleProcessorData;
+class nsIXPConnectWrappedJS;
+class nsIAtom;
+class nsIDOMNodeList;
+class nsIDocument;
+class nsIURI;
+class nsXBLDocumentInfo;
+class nsIStreamListener;
+class nsXBLBinding;
+typedef nsTArray<RefPtr<nsXBLBinding> > nsBindingList;
+class nsIPrincipal;
+class nsITimer;
+
+class nsBindingManager final : public nsStubMutationObserver
+{
+ ~nsBindingManager();
+
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
+
+ explicit nsBindingManager(nsIDocument* aDocument);
+
+ nsXBLBinding* GetBindingWithContent(const nsIContent* aContent);
+
+ void AddBoundContent(nsIContent* aContent);
+ void RemoveBoundContent(nsIContent* aContent);
+
+ /**
+ * Notify the binding manager that an element
+ * has been removed from its document,
+ * so that it can update any bindings or
+ * nsIAnonymousContentCreator-created anonymous
+ * content that may depend on the document.
+ * @param aContent the element that's being moved
+ * @param aOldDocument the old document in which the
+ * content resided.
+ * @param aDestructorHandling whether or not to run the possible XBL
+ * destructor.
+ */
+
+ enum DestructorHandling {
+ eRunDtor,
+ eDoNotRunDtor
+ };
+ void RemovedFromDocument(nsIContent* aContent, nsIDocument* aOldDocument,
+ DestructorHandling aDestructorHandling)
+ {
+ if (aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
+ RemovedFromDocumentInternal(aContent, aOldDocument, aDestructorHandling);
+ }
+ }
+ void RemovedFromDocumentInternal(nsIContent* aContent,
+ nsIDocument* aOldDocument,
+ DestructorHandling aDestructorHandling);
+
+ nsIAtom* ResolveTag(nsIContent* aContent, int32_t* aNameSpaceID);
+
+ /**
+ * Return the nodelist of "anonymous" kids for this node. This might
+ * actually include some of the nodes actual DOM kids, if there are
+ * <children> tags directly as kids of <content>. This will only end up
+ * returning a non-null list for nodes which have a binding attached.
+ */
+ nsresult GetAnonymousNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult);
+ nsINodeList* GetAnonymousNodesFor(nsIContent* aContent);
+
+ nsresult ClearBinding(nsIContent* aContent);
+ nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
+ nsIPrincipal* aOriginPrincipal);
+
+ nsresult AddToAttachedQueue(nsXBLBinding* aBinding);
+ void RemoveFromAttachedQueue(nsXBLBinding* aBinding);
+ void ProcessAttachedQueue(uint32_t aSkipSize = 0)
+ {
+ if (mProcessingAttachedStack || mAttachedStack.Length() <= aSkipSize) {
+ return;
+ }
+
+ ProcessAttachedQueueInternal(aSkipSize);
+ }
+private:
+ void ProcessAttachedQueueInternal(uint32_t aSkipSize);
+
+public:
+
+ void ExecuteDetachedHandlers();
+
+ nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);
+ nsXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURI);
+ void RemoveXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);
+
+ nsresult PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener);
+ nsIStreamListener* GetLoadingDocListener(nsIURI* aURL);
+ void RemoveLoadingDocListener(nsIURI* aURL);
+
+ void FlushSkinBindings();
+
+ nsresult GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult);
+
+ // Style rule methods
+ nsresult WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc,
+ ElementDependentRuleProcessorData* aData,
+ bool* aCutOffInheritance);
+
+ void WalkAllRules(nsIStyleRuleProcessor::EnumFunc aFunc,
+ ElementDependentRuleProcessorData* aData);
+ /**
+ * Do any processing that needs to happen as a result of a change in
+ * the characteristics of the medium, and return whether this rule
+ * processor's rules have changed (e.g., because of media queries).
+ */
+ nsresult MediumFeaturesChanged(nsPresContext* aPresContext,
+ bool* aRulesChanged);
+
+ void AppendAllSheets(nsTArray<mozilla::StyleSheet*>& aArray);
+
+ void Traverse(nsIContent *aContent,
+ nsCycleCollectionTraversalCallback &cb);
+
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsBindingManager)
+
+ // Notify the binding manager when an outermost update begins and
+ // ends. The end method can execute script.
+ void BeginOutermostUpdate()
+ {
+ mAttachedStackSizeOnOutermost = mAttachedStack.Length();
+ }
+
+ void EndOutermostUpdate()
+ {
+ if (!mProcessingAttachedStack) {
+ ProcessAttachedQueue(mAttachedStackSizeOnOutermost);
+ mAttachedStackSizeOnOutermost = 0;
+ }
+ }
+
+ // When removing an insertion point or a parent of one, clear the insertion
+ // points and their insertion parents.
+ void ClearInsertionPointsRecursively(nsIContent* aContent);
+
+ // Called when the document is going away
+ void DropDocumentReference();
+
+ nsIContent* FindNestedInsertionPoint(nsIContent* aContainer,
+ nsIContent* aChild);
+
+ nsIContent* FindNestedSingleInsertionPoint(nsIContent* aContainer, bool* aMulti);
+
+protected:
+ nsIXPConnectWrappedJS* GetWrappedJS(nsIContent* aContent);
+ nsresult SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aResult);
+
+ // Called by ContentAppended and ContentInserted to handle a single child
+ // insertion. aChild must not be null. aContainer may be null.
+ // aIndexInContainer is the index of the child in the parent. aAppend is
+ // true if this child is being appended, not inserted.
+ void HandleChildInsertion(nsIContent* aContainer, nsIContent* aChild,
+ uint32_t aIndexInContainer, bool aAppend);
+
+ // Same as ProcessAttachedQueue, but also nulls out
+ // mProcessAttachedQueueEvent
+ void DoProcessAttachedQueue();
+
+ // Post an event to process the attached queue.
+ void PostProcessAttachedQueueEvent();
+
+ // Call PostProcessAttachedQueueEvent() on a timer.
+ static void PostPAQEventCallback(nsITimer* aTimer, void* aClosure);
+
+// MEMBER VARIABLES
+protected:
+ // A set of nsIContent that currently have a binding installed.
+ nsAutoPtr<nsTHashtable<nsRefPtrHashKey<nsIContent> > > mBoundContentSet;
+
+ // A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect
+ // wrapper for JS objects). For XBL bindings that implement XPIDL
+ // interfaces, and that get referred to from C++, this table caches
+ // the XPConnect wrapper for the binding. By caching it, I control
+ // its lifetime, and I prevent a re-wrap of the same script object
+ // (in the case where multiple bindings in an XBL inheritance chain
+ // both implement an XPIDL interface).
+ typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXPConnectWrappedJS> WrapperHashtable;
+ nsAutoPtr<WrapperHashtable> mWrapperTable;
+
+ // A mapping from a URL (a string) to nsXBLDocumentInfo*. This table
+ // is the cache of all binding documents that have been loaded by a
+ // given bound document.
+ nsAutoPtr<nsRefPtrHashtable<nsURIHashKey,nsXBLDocumentInfo> > mDocumentTable;
+
+ // A mapping from a URL (a string) to a nsIStreamListener. This
+ // table is the currently loading binding docs. If they're in this
+ // table, they have not yet finished loading.
+ nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIStreamListener> > mLoadingDocTable;
+
+ // A queue of binding attached event handlers that are awaiting execution.
+ nsBindingList mAttachedStack;
+ bool mProcessingAttachedStack;
+ bool mDestroyed;
+ uint32_t mAttachedStackSizeOnOutermost;
+
+ // Our posted event to process the attached queue, if any
+ friend class nsRunnableMethod<nsBindingManager>;
+ RefPtr< nsRunnableMethod<nsBindingManager> > mProcessAttachedQueueEvent;
+
+ // Our document. This is a weak ref; the document owns us
+ nsIDocument* mDocument;
+};
+
+#endif