Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/ShadowRoot.h
Line
Count
Source (jump to first uncovered line)
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 mozilla_dom_shadowroot_h__
8
#define mozilla_dom_shadowroot_h__
9
10
#include "mozilla/dom/DocumentBinding.h"
11
#include "mozilla/dom/DocumentFragment.h"
12
#include "mozilla/dom/DocumentOrShadowRoot.h"
13
#include "mozilla/dom/NameSpaceConstants.h"
14
#include "mozilla/dom/ShadowRootBinding.h"
15
#include "mozilla/ServoBindings.h"
16
#include "nsCOMPtr.h"
17
#include "nsCycleCollectionParticipant.h"
18
#include "nsIdentifierMapEntry.h"
19
#include "nsIRadioGroupContainer.h"
20
#include "nsStubMutationObserver.h"
21
#include "nsTHashtable.h"
22
23
class nsAtom;
24
class nsIContent;
25
class nsXBLPrototypeBinding;
26
27
namespace mozilla {
28
29
class EventChainPreVisitor;
30
class ServoStyleRuleMap;
31
32
namespace css {
33
class Rule;
34
}
35
36
namespace dom {
37
38
class Element;
39
class HTMLInputElement;
40
41
class ShadowRoot final : public DocumentFragment,
42
                         public DocumentOrShadowRoot,
43
                         public nsStubMutationObserver,
44
                         public nsIRadioGroupContainer
45
{
46
public:
47
  NS_IMPL_FROMNODE_HELPER(ShadowRoot, IsShadowRoot());
48
49
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot,
50
                                           DocumentFragment)
51
  NS_DECL_ISUPPORTS_INHERITED
52
53
  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
54
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
55
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
56
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
57
58
  ShadowRoot(Element* aElement, ShadowRootMode aMode,
59
             already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
60
61
  void AddSizeOfExcludingThis(nsWindowSizes&, size_t* aNodeSize) const final;
62
63
  // Shadow DOM v1
64
  Element* Host() const
65
0
  {
66
0
    MOZ_ASSERT(GetHost(), "ShadowRoot always has a host, how did we create "
67
0
                          "this ShadowRoot?");
68
0
    return GetHost();
69
0
  }
70
71
  ShadowRootMode Mode() const
72
0
  {
73
0
    return mMode;
74
0
  }
75
  bool IsClosed() const
76
0
  {
77
0
    return mMode == ShadowRootMode::Closed;
78
0
  }
79
80
  void RemoveSheet(StyleSheet* aSheet);
81
  void RuleAdded(StyleSheet&, css::Rule&);
82
  void RuleRemoved(StyleSheet&, css::Rule&);
83
  void RuleChanged(StyleSheet&, css::Rule*);
84
  void StyleSheetApplicableStateChanged(StyleSheet&, bool aApplicable);
85
86
  StyleSheetList* StyleSheets()
87
0
  {
88
0
    return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
89
0
  }
90
91
  /**
92
   * Clones internal state, for example stylesheets, of aOther to 'this'.
93
   */
94
  void CloneInternalDataFrom(ShadowRoot* aOther);
95
  void InsertSheetAt(size_t aIndex, StyleSheet&);
96
97
  // Calls UnbindFromTree for each of our kids, and also flags us as no longer
98
  // being connected.
99
  void Unbind();
100
101
  // Calls BindToTree on each of our kids, and also maybe flags us as being
102
  // connected.
103
  nsresult Bind();
104
105
private:
106
  void InsertSheetIntoAuthorData(size_t aIndex, StyleSheet&);
107
108
  void AppendStyleSheet(StyleSheet& aSheet)
109
0
  {
110
0
    InsertSheetAt(SheetCount(), aSheet);
111
0
  }
112
113
  /**
114
   * Try to reassign an element to a slot and returns whether the assignment
115
   * changed.
116
   */
117
  void MaybeReassignElement(Element* aElement);
118
119
  /**
120
   * Represents the insertion point in a slot for a given node.
121
   */
122
  struct SlotAssignment
123
  {
124
    HTMLSlotElement* mSlot = nullptr;
125
    Maybe<uint32_t> mIndex;
126
127
0
    SlotAssignment() = default;
128
    SlotAssignment(HTMLSlotElement* aSlot, const Maybe<uint32_t>& aIndex)
129
      : mSlot(aSlot)
130
      , mIndex(aIndex)
131
0
    { }
132
  };
133
134
  /**
135
   * Return the assignment corresponding to the content node at this particular
136
   * point in time.
137
   *
138
   * It's the caller's responsibility to actually call InsertAssignedNode /
139
   * AppendAssignedNode in the slot as needed.
140
   */
141
  SlotAssignment SlotAssignmentFor(nsIContent* aContent);
142
143
  /**
144
   * Explicitly invalidates the style and layout of the flattened-tree subtree
145
   * rooted at the element.
146
   *
147
   * You need to use this whenever the flat tree is going to be shuffled in a
148
   * way that layout doesn't understand via the usual ContentInserted /
149
   * ContentAppended / ContentRemoved notifications. For example, if removing an
150
   * element will cause a change in the flat tree such that other element will
151
   * start showing up (like fallback content), this method needs to be called on
152
   * an ancestor of that element.
153
   *
154
   * It is important that this runs _before_ actually shuffling the flat tree
155
   * around, so that layout knows the actual tree that it needs to invalidate.
156
   */
157
  void InvalidateStyleAndLayoutOnSubtree(Element*);
158
159
public:
160
  void AddSlot(HTMLSlotElement* aSlot);
161
  void RemoveSlot(HTMLSlotElement* aSlot);
162
0
  bool HasSlots() const { return !mSlotMap.IsEmpty(); };
163
164
  const RawServoAuthorStyles* GetServoStyles() const
165
0
  {
166
0
    return mServoStyles.get();
167
0
  }
168
169
  RawServoAuthorStyles* GetServoStyles()
170
0
  {
171
0
    return mServoStyles.get();
172
0
  }
173
174
  mozilla::ServoStyleRuleMap& ServoStyleRuleMap();
175
176
  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
177
178
  void AddToIdTable(Element* aElement, nsAtom* aId);
179
  void RemoveFromIdTable(Element* aElement, nsAtom* aId);
180
181
  // WebIDL methods.
182
  using mozilla::dom::DocumentOrShadowRoot::GetElementById;
183
184
  Element* GetActiveElement();
185
  void GetInnerHTML(nsAString& aInnerHTML);
186
  void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
187
188
  /**
189
   * These methods allow UA Widget to insert DOM elements into the Shadow ROM
190
   * without putting their DOM reflectors to content scope first.
191
   * The inserted DOM will have their reflectors in the UA Widget scope.
192
   */
193
  nsINode* ImportNodeAndAppendChildAt(nsINode& aParentNode,
194
                                      nsINode& aNode,
195
                                      bool aDeep, mozilla::ErrorResult& rv);
196
197
  nsINode* CreateElementAndAppendChildAt(nsINode& aParentNode,
198
                                         const nsAString& aTagName,
199
                                         mozilla::ErrorResult& rv);
200
201
  bool IsUAWidget() const
202
0
  {
203
0
    return mIsUAWidget;
204
0
  }
205
206
  void SetIsUAWidget()
207
0
  {
208
0
    mIsUAWidget = true;
209
0
  }
210
211
  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
212
213
  // nsIRadioGroupContainer
214
  NS_IMETHOD WalkRadioGroup(const nsAString& aName,
215
                            nsIRadioVisitor* aVisitor,
216
                            bool aFlushContent) override
217
0
  {
218
0
    return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor, aFlushContent);
219
0
  }
220
  virtual void
221
  SetCurrentRadioButton(const nsAString& aName,
222
                        HTMLInputElement* aRadio) override
223
0
  {
224
0
    DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
225
0
  }
226
  virtual HTMLInputElement*
227
  GetCurrentRadioButton(const nsAString& aName) override
228
0
  {
229
0
    return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
230
0
  }
231
  NS_IMETHOD
232
  GetNextRadioButton(const nsAString& aName,
233
                     const bool aPrevious,
234
                     HTMLInputElement* aFocusedRadio,
235
                     HTMLInputElement** aRadioOut) override
236
0
  {
237
0
    return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
238
0
                                                    aFocusedRadio, aRadioOut);
239
0
  }
240
  virtual void AddToRadioGroup(const nsAString& aName,
241
                               HTMLInputElement* aRadio) override
242
0
  {
243
0
    DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio);
244
0
  }
245
  virtual void RemoveFromRadioGroup(const nsAString& aName,
246
                                    HTMLInputElement* aRadio) override
247
0
  {
248
0
    DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
249
0
  }
250
  virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const override
251
0
  {
252
0
    return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
253
0
  }
254
  virtual void RadioRequiredWillChange(const nsAString& aName,
255
                                       bool aRequiredAdded) override
256
0
  {
257
0
    DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
258
0
  }
259
  virtual bool GetValueMissingState(const nsAString& aName) const override
260
0
  {
261
0
    return DocumentOrShadowRoot::GetValueMissingState(aName);
262
0
  }
263
  virtual void SetValueMissingState(const nsAString& aName, bool aValue) override
264
0
  {
265
0
    return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
266
0
  }
267
268
protected:
269
  // FIXME(emilio): This will need to become more fine-grained.
270
  void ApplicableRulesChanged();
271
272
  virtual ~ShadowRoot();
273
274
  const ShadowRootMode mMode;
275
276
  // The computed data from the style sheets.
277
  UniquePtr<RawServoAuthorStyles> mServoStyles;
278
  UniquePtr<mozilla::ServoStyleRuleMap> mStyleRuleMap;
279
280
  using SlotArray = AutoTArray<HTMLSlotElement*, 1>;
281
  // Map from name of slot to an array of all slots in the shadow DOM with with
282
  // the given name. The slots are stored as a weak pointer because the elements
283
  // are in the shadow tree and should be kept alive by its parent.
284
  nsClassHashtable<nsStringHashKey, SlotArray> mSlotMap;
285
286
  bool mIsUAWidget;
287
288
  nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
289
};
290
291
} // namespace dom
292
} // namespace mozilla
293
294
#endif // mozilla_dom_shadowroot_h__