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