nsBindingManager.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* -*- Mode: C++; tab-width: 8; 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/. */
  5. #ifndef nsBindingManager_h_
  6. #define nsBindingManager_h_
  7. #include "nsAutoPtr.h"
  8. #include "nsIContent.h"
  9. #include "nsStubMutationObserver.h"
  10. #include "nsHashKeys.h"
  11. #include "nsInterfaceHashtable.h"
  12. #include "nsRefPtrHashtable.h"
  13. #include "nsURIHashKey.h"
  14. #include "nsCycleCollectionParticipant.h"
  15. #include "nsXBLBinding.h"
  16. #include "nsTArray.h"
  17. #include "nsThreadUtils.h"
  18. #include "mozilla/StyleSheet.h"
  19. struct ElementDependentRuleProcessorData;
  20. class nsIXPConnectWrappedJS;
  21. class nsIAtom;
  22. class nsIDOMNodeList;
  23. class nsIDocument;
  24. class nsIURI;
  25. class nsXBLDocumentInfo;
  26. class nsIStreamListener;
  27. class nsXBLBinding;
  28. typedef nsTArray<RefPtr<nsXBLBinding> > nsBindingList;
  29. class nsIPrincipal;
  30. class nsITimer;
  31. class nsBindingManager final : public nsStubMutationObserver
  32. {
  33. ~nsBindingManager();
  34. public:
  35. NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  36. NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
  37. NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
  38. NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
  39. explicit nsBindingManager(nsIDocument* aDocument);
  40. nsXBLBinding* GetBindingWithContent(const nsIContent* aContent);
  41. void AddBoundContent(nsIContent* aContent);
  42. void RemoveBoundContent(nsIContent* aContent);
  43. /**
  44. * Notify the binding manager that an element
  45. * has been removed from its document,
  46. * so that it can update any bindings or
  47. * nsIAnonymousContentCreator-created anonymous
  48. * content that may depend on the document.
  49. * @param aContent the element that's being moved
  50. * @param aOldDocument the old document in which the
  51. * content resided.
  52. * @param aDestructorHandling whether or not to run the possible XBL
  53. * destructor.
  54. */
  55. enum DestructorHandling {
  56. eRunDtor,
  57. eDoNotRunDtor
  58. };
  59. void RemovedFromDocument(nsIContent* aContent, nsIDocument* aOldDocument,
  60. DestructorHandling aDestructorHandling)
  61. {
  62. if (aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
  63. RemovedFromDocumentInternal(aContent, aOldDocument, aDestructorHandling);
  64. }
  65. }
  66. void RemovedFromDocumentInternal(nsIContent* aContent,
  67. nsIDocument* aOldDocument,
  68. DestructorHandling aDestructorHandling);
  69. nsIAtom* ResolveTag(nsIContent* aContent, int32_t* aNameSpaceID);
  70. /**
  71. * Return the nodelist of "anonymous" kids for this node. This might
  72. * actually include some of the nodes actual DOM kids, if there are
  73. * <children> tags directly as kids of <content>. This will only end up
  74. * returning a non-null list for nodes which have a binding attached.
  75. */
  76. nsresult GetAnonymousNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult);
  77. nsINodeList* GetAnonymousNodesFor(nsIContent* aContent);
  78. nsresult ClearBinding(nsIContent* aContent);
  79. nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
  80. nsIPrincipal* aOriginPrincipal);
  81. nsresult AddToAttachedQueue(nsXBLBinding* aBinding);
  82. void RemoveFromAttachedQueue(nsXBLBinding* aBinding);
  83. void ProcessAttachedQueue(uint32_t aSkipSize = 0)
  84. {
  85. if (mProcessingAttachedStack || mAttachedStack.Length() <= aSkipSize) {
  86. return;
  87. }
  88. ProcessAttachedQueueInternal(aSkipSize);
  89. }
  90. private:
  91. void ProcessAttachedQueueInternal(uint32_t aSkipSize);
  92. public:
  93. void ExecuteDetachedHandlers();
  94. nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);
  95. nsXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURI);
  96. void RemoveXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);
  97. nsresult PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener);
  98. nsIStreamListener* GetLoadingDocListener(nsIURI* aURL);
  99. void RemoveLoadingDocListener(nsIURI* aURL);
  100. void FlushSkinBindings();
  101. nsresult GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult);
  102. // Style rule methods
  103. nsresult WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc,
  104. ElementDependentRuleProcessorData* aData,
  105. bool* aCutOffInheritance);
  106. void WalkAllRules(nsIStyleRuleProcessor::EnumFunc aFunc,
  107. ElementDependentRuleProcessorData* aData);
  108. /**
  109. * Do any processing that needs to happen as a result of a change in
  110. * the characteristics of the medium, and return whether this rule
  111. * processor's rules have changed (e.g., because of media queries).
  112. */
  113. nsresult MediumFeaturesChanged(nsPresContext* aPresContext,
  114. bool* aRulesChanged);
  115. void AppendAllSheets(nsTArray<mozilla::StyleSheet*>& aArray);
  116. void Traverse(nsIContent *aContent,
  117. nsCycleCollectionTraversalCallback &cb);
  118. NS_DECL_CYCLE_COLLECTION_CLASS(nsBindingManager)
  119. // Notify the binding manager when an outermost update begins and
  120. // ends. The end method can execute script.
  121. void BeginOutermostUpdate()
  122. {
  123. mAttachedStackSizeOnOutermost = mAttachedStack.Length();
  124. }
  125. void EndOutermostUpdate()
  126. {
  127. if (!mProcessingAttachedStack) {
  128. ProcessAttachedQueue(mAttachedStackSizeOnOutermost);
  129. mAttachedStackSizeOnOutermost = 0;
  130. }
  131. }
  132. // When removing an insertion point or a parent of one, clear the insertion
  133. // points and their insertion parents.
  134. void ClearInsertionPointsRecursively(nsIContent* aContent);
  135. // Called when the document is going away
  136. void DropDocumentReference();
  137. nsIContent* FindNestedInsertionPoint(nsIContent* aContainer,
  138. nsIContent* aChild);
  139. nsIContent* FindNestedSingleInsertionPoint(nsIContent* aContainer, bool* aMulti);
  140. protected:
  141. nsIXPConnectWrappedJS* GetWrappedJS(nsIContent* aContent);
  142. nsresult SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aResult);
  143. // Called by ContentAppended and ContentInserted to handle a single child
  144. // insertion. aChild must not be null. aContainer may be null.
  145. // aIndexInContainer is the index of the child in the parent. aAppend is
  146. // true if this child is being appended, not inserted.
  147. void HandleChildInsertion(nsIContent* aContainer, nsIContent* aChild,
  148. uint32_t aIndexInContainer, bool aAppend);
  149. // Same as ProcessAttachedQueue, but also nulls out
  150. // mProcessAttachedQueueEvent
  151. void DoProcessAttachedQueue();
  152. // Post an event to process the attached queue.
  153. void PostProcessAttachedQueueEvent();
  154. // Call PostProcessAttachedQueueEvent() on a timer.
  155. static void PostPAQEventCallback(nsITimer* aTimer, void* aClosure);
  156. // MEMBER VARIABLES
  157. protected:
  158. // A set of nsIContent that currently have a binding installed.
  159. nsAutoPtr<nsTHashtable<nsRefPtrHashKey<nsIContent> > > mBoundContentSet;
  160. // A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect
  161. // wrapper for JS objects). For XBL bindings that implement XPIDL
  162. // interfaces, and that get referred to from C++, this table caches
  163. // the XPConnect wrapper for the binding. By caching it, I control
  164. // its lifetime, and I prevent a re-wrap of the same script object
  165. // (in the case where multiple bindings in an XBL inheritance chain
  166. // both implement an XPIDL interface).
  167. typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXPConnectWrappedJS> WrapperHashtable;
  168. nsAutoPtr<WrapperHashtable> mWrapperTable;
  169. // A mapping from a URL (a string) to nsXBLDocumentInfo*. This table
  170. // is the cache of all binding documents that have been loaded by a
  171. // given bound document.
  172. nsAutoPtr<nsRefPtrHashtable<nsURIHashKey,nsXBLDocumentInfo> > mDocumentTable;
  173. // A mapping from a URL (a string) to a nsIStreamListener. This
  174. // table is the currently loading binding docs. If they're in this
  175. // table, they have not yet finished loading.
  176. nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIStreamListener> > mLoadingDocTable;
  177. // A queue of binding attached event handlers that are awaiting execution.
  178. nsBindingList mAttachedStack;
  179. bool mProcessingAttachedStack;
  180. bool mDestroyed;
  181. uint32_t mAttachedStackSizeOnOutermost;
  182. // Our posted event to process the attached queue, if any
  183. friend class nsRunnableMethod<nsBindingManager>;
  184. RefPtr< nsRunnableMethod<nsBindingManager> > mProcessAttachedQueueEvent;
  185. // Our document. This is a weak ref; the document owns us
  186. nsIDocument* mDocument;
  187. };
  188. #endif