nsXBLBinding.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 nsXBLBinding_h_
  6. #define nsXBLBinding_h_
  7. #include "nsXBLService.h"
  8. #include "nsCOMPtr.h"
  9. #include "nsINodeList.h"
  10. #include "nsIStyleRuleProcessor.h"
  11. #include "nsClassHashtable.h"
  12. #include "nsTArray.h"
  13. #include "nsCycleCollectionParticipant.h"
  14. #include "nsISupportsImpl.h"
  15. #include "js/TypeDecls.h"
  16. class nsXBLPrototypeBinding;
  17. class nsIContent;
  18. class nsIAtom;
  19. class nsIDocument;
  20. namespace mozilla {
  21. namespace dom {
  22. class ShadowRoot;
  23. class XBLChildrenElement;
  24. } // namespace dom
  25. } // namespace mozilla
  26. class nsAnonymousContentList;
  27. // *********************************************************************/
  28. // The XBLBinding class
  29. class nsXBLBinding final
  30. {
  31. public:
  32. explicit nsXBLBinding(nsXBLPrototypeBinding* aProtoBinding);
  33. nsXBLBinding(mozilla::dom::ShadowRoot* aShadowRoot, nsXBLPrototypeBinding* aProtoBinding);
  34. /**
  35. * XBLBindings are refcounted. They are held onto in 3 ways:
  36. * 1. The binding manager's binding table holds onto all bindings that are
  37. * currently attached to a content node.
  38. * 2. Bindings hold onto their base binding. This is important since
  39. * the base binding itself may not be attached to anything.
  40. * 3. The binding manager holds an additional reference to bindings
  41. * which are queued to fire their constructors.
  42. */
  43. NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsXBLBinding)
  44. NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding)
  45. nsXBLPrototypeBinding* PrototypeBinding() const { return mPrototypeBinding; }
  46. nsIContent* GetAnonymousContent() { return mContent.get(); }
  47. nsXBLBinding* GetBindingWithContent();
  48. nsXBLBinding* GetBaseBinding() const { return mNextBinding; }
  49. void SetBaseBinding(nsXBLBinding *aBinding);
  50. nsIContent* GetBoundElement() { return mBoundElement; }
  51. void SetBoundElement(nsIContent *aElement);
  52. /*
  53. * Does a lookup for a method or attribute provided by one of the bindings'
  54. * prototype implementation. If found, |desc| will be set up appropriately,
  55. * and wrapped into cx->compartment.
  56. *
  57. * May only be called when XBL code is being run in a separate scope, because
  58. * otherwise we don't have untainted data with which to do a proper lookup.
  59. */
  60. bool LookupMember(JSContext* aCx, JS::Handle<jsid> aId,
  61. JS::MutableHandle<JS::PropertyDescriptor> aDesc);
  62. /*
  63. * Determines whether the binding has a field with the given name.
  64. */
  65. bool HasField(nsString& aName);
  66. protected:
  67. ~nsXBLBinding();
  68. /*
  69. * Internal version. Requires that aCx is in appropriate xbl scope.
  70. */
  71. bool LookupMemberInternal(JSContext* aCx, nsString& aName,
  72. JS::Handle<jsid> aNameAsId,
  73. JS::MutableHandle<JS::PropertyDescriptor> aDesc,
  74. JS::Handle<JSObject*> aXBLScope);
  75. public:
  76. void MarkForDeath();
  77. bool MarkedForDeath() const { return mMarkedForDeath; }
  78. bool HasStyleSheets() const;
  79. bool InheritsStyle() const;
  80. bool ImplementsInterface(REFNSIID aIID) const;
  81. void GenerateAnonymousContent();
  82. void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement,
  83. bool aNativeAnon);
  84. static void UninstallAnonymousContent(nsIDocument* aDocument,
  85. nsIContent* aAnonParent);
  86. void InstallEventHandlers();
  87. nsresult InstallImplementation();
  88. void ExecuteAttachedHandler();
  89. void ExecuteDetachedHandler();
  90. void UnhookEventHandlers();
  91. nsIAtom* GetBaseTag(int32_t* aNameSpaceID);
  92. nsXBLBinding* RootBinding();
  93. // Resolve all the fields for this binding and all ancestor bindings on the
  94. // object |obj|. False return means a JS exception was set.
  95. bool ResolveAllFields(JSContext *cx, JS::Handle<JSObject*> obj) const;
  96. void AttributeChanged(nsIAtom* aAttribute, int32_t aNameSpaceID,
  97. bool aRemoveFlag, bool aNotify);
  98. void ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument);
  99. void WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc, void* aData);
  100. static nsresult DoInitJSClass(JSContext *cx, JS::Handle<JSObject*> obj,
  101. const nsAFlatString& aClassName,
  102. nsXBLPrototypeBinding* aProtoBinding,
  103. JS::MutableHandle<JSObject*> aClassObject,
  104. bool* aNew);
  105. bool AllowScripts();
  106. mozilla::dom::XBLChildrenElement* FindInsertionPointFor(nsIContent* aChild);
  107. bool HasFilteredInsertionPoints()
  108. {
  109. return !mInsertionPoints.IsEmpty();
  110. }
  111. mozilla::dom::XBLChildrenElement* GetDefaultInsertionPoint()
  112. {
  113. return mDefaultInsertionPoint;
  114. }
  115. // Removes all inserted node from <xbl:children> insertion points under us.
  116. void ClearInsertionPoints();
  117. // Returns a live node list that iterates over the anonymous nodes generated
  118. // by this binding.
  119. nsAnonymousContentList* GetAnonymousNodeList();
  120. nsIURI* GetSourceDocURI();
  121. // MEMBER VARIABLES
  122. protected:
  123. bool mMarkedForDeath;
  124. bool mUsingContentXBLScope;
  125. bool mIsShadowRootBinding;
  126. nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
  127. nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
  128. RefPtr<nsXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
  129. nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
  130. // The <xbl:children> elements that we found in our <xbl:content> when we
  131. // processed this binding. The default insertion point has no includes
  132. // attribute and all other insertion points must have at least one includes
  133. // attribute. These points must be up-to-date with respect to their parent's
  134. // children, even if their parent has another binding attached to it,
  135. // preventing us from rendering their contents directly.
  136. RefPtr<mozilla::dom::XBLChildrenElement> mDefaultInsertionPoint;
  137. nsTArray<RefPtr<mozilla::dom::XBLChildrenElement> > mInsertionPoints;
  138. RefPtr<nsAnonymousContentList> mAnonymousContentList;
  139. mozilla::dom::XBLChildrenElement* FindInsertionPointForInternal(nsIContent* aChild);
  140. };
  141. #endif // nsXBLBinding_h_