Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/DocumentOrShadowRoot.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_DocumentOrShadowRoot_h__
8
#define mozilla_dom_DocumentOrShadowRoot_h__
9
10
#include "mozilla/dom/NameSpaceConstants.h"
11
#include "nsClassHashtable.h"
12
#include "nsContentListDeclarations.h"
13
#include "nsTArray.h"
14
#include "nsIdentifierMapEntry.h"
15
16
class nsContentList;
17
class nsCycleCollectionTraversalCallback;
18
class nsIDocument;
19
class nsINode;
20
class nsIRadioVisitor;
21
class nsWindowSizes;
22
23
namespace mozilla {
24
class StyleSheet;
25
26
namespace dom {
27
28
class Element;
29
class DocumentOrShadowRoot;
30
class HTMLInputElement;
31
struct nsRadioGroupStruct;
32
class StyleSheetList;
33
class ShadowRoot;
34
35
/**
36
 * A class meant to be shared by ShadowRoot and Document, that holds a list of
37
 * stylesheets.
38
 *
39
 * TODO(emilio, bug 1418159): In the future this should hold most of the
40
 * relevant style state, this should allow us to fix bug 548397.
41
 */
42
class DocumentOrShadowRoot
43
{
44
  enum class Kind
45
  {
46
    Document,
47
    ShadowRoot,
48
  };
49
50
public:
51
  explicit DocumentOrShadowRoot(nsIDocument&);
52
  explicit DocumentOrShadowRoot(mozilla::dom::ShadowRoot&);
53
54
  // Unusual argument naming is because of cycle collection macros.
55
  static void Traverse(DocumentOrShadowRoot* tmp,
56
                       nsCycleCollectionTraversalCallback &cb);
57
  static void Unlink(DocumentOrShadowRoot* tmp);
58
59
  nsINode& AsNode()
60
0
  {
61
0
    return mAsNode;
62
0
  }
63
64
  const nsINode& AsNode() const
65
0
  {
66
0
    return mAsNode;
67
0
  }
68
69
  StyleSheet* SheetAt(size_t aIndex) const
70
0
  {
71
0
    return mStyleSheets.SafeElementAt(aIndex);
72
0
  }
73
74
  size_t SheetCount() const
75
0
  {
76
0
    return mStyleSheets.Length();
77
0
  }
78
79
  int32_t IndexOfSheet(const StyleSheet& aSheet) const
80
0
  {
81
0
    return mStyleSheets.IndexOf(&aSheet);
82
0
  }
83
84
  StyleSheetList& EnsureDOMStyleSheets();
85
86
  Element* GetElementById(const nsAString& aElementId);
87
88
  /**
89
   * This method returns _all_ the elements in this scope which have id
90
   * aElementId, if there are any.  Otherwise it returns null.
91
   *
92
   * This is useful for stuff like QuerySelector optimization and such.
93
   */
94
  inline const nsTArray<Element*>*
95
  GetAllElementsForId(const nsAString& aElementId) const;
96
97
  already_AddRefed<nsContentList>
98
  GetElementsByTagName(const nsAString& aTagName)
99
0
  {
100
0
    return NS_GetContentList(&AsNode(), kNameSpaceID_Unknown, aTagName);
101
0
  }
102
103
  already_AddRefed<nsContentList>
104
  GetElementsByTagNameNS(const nsAString& aNamespaceURI,
105
                         const nsAString& aLocalName);
106
107
  already_AddRefed<nsContentList>
108
  GetElementsByTagNameNS(const nsAString& aNamespaceURI,
109
                         const nsAString& aLocalName,
110
                         mozilla::ErrorResult&);
111
112
  already_AddRefed<nsContentList>
113
  GetElementsByClassName(const nsAString& aClasses);
114
115
  ~DocumentOrShadowRoot();
116
117
  Element* GetPointerLockElement();
118
  Element* GetFullscreenElement();
119
120
  Element* ElementFromPoint(float aX, float aY);
121
  void ElementsFromPoint(float aX, float aY,
122
                         nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
123
124
  /**
125
   * Helper for elementFromPoint implementation that allows
126
   * ignoring the scroll frame and/or avoiding layout flushes.
127
   *
128
   * @see nsIDOMWindowUtils::elementFromPoint
129
   */
130
  Element* ElementFromPointHelper(float aX, float aY,
131
                                  bool aIgnoreRootScrollFrame,
132
                                  bool aFlushLayout);
133
  enum ElementsFromPointFlags
134
  {
135
    IGNORE_ROOT_SCROLL_FRAME = 1,
136
    FLUSH_LAYOUT = 2,
137
    IS_ELEMENT_FROM_POINT = 4
138
  };
139
140
  void ElementsFromPointHelper(float aX, float aY, uint32_t aFlags,
141
                               nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
142
143
  /**
144
   * This gets fired when the element that an id refers to changes.
145
   * This fires at difficult times. It is generally not safe to do anything
146
   * which could modify the DOM in any way. Use
147
   * nsContentUtils::AddScriptRunner.
148
   * @return true to keep the callback in the callback set, false
149
   * to remove it.
150
   */
151
  typedef bool (* IDTargetObserver)(Element* aOldElement,
152
                                    Element* aNewelement, void* aData);
153
154
  /**
155
   * Add an IDTargetObserver for a specific ID. The IDTargetObserver
156
   * will be fired whenever the content associated with the ID changes
157
   * in the future. If aForImage is true, mozSetImageElement can override
158
   * what content is associated with the ID. In that case the IDTargetObserver
159
   * will be notified at those times when the result of LookupImageElement
160
   * changes.
161
   * At most one (aObserver, aData, aForImage) triple can be
162
   * registered for each ID.
163
   * @return the content currently associated with the ID.
164
   */
165
  Element* AddIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
166
                               void* aData, bool aForImage);
167
168
  /**
169
   * Remove the (aObserver, aData, aForImage) triple for a specific ID, if
170
   * registered.
171
   */
172
  void RemoveIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
173
                              void* aData, bool aForImage);
174
175
  /**
176
   * Lookup an image element using its associated ID, which is usually provided
177
   * by |-moz-element()|. Similar to GetElementById, with the difference that
178
   * elements set using mozSetImageElement have higher priority.
179
   * @param aId the ID associated the element we want to lookup
180
   * @return the element associated with |aId|
181
   */
182
  Element* LookupImageElement(const nsAString& aElementId);
183
184
  /**
185
   * Check that aId is not empty and log a message to the console
186
   * service if it is.
187
   * @returns true if aId looks correct, false otherwise.
188
   */
189
  inline bool CheckGetElementByIdArg(const nsAString& aId)
190
0
  {
191
0
    if (aId.IsEmpty()) {
192
0
      ReportEmptyGetElementByIdArg();
193
0
      return false;
194
0
    }
195
0
    return true;
196
0
  }
197
198
  void ReportEmptyGetElementByIdArg();
199
200
  // nsIRadioGroupContainer
201
  NS_IMETHOD WalkRadioGroup(const nsAString& aName,
202
                            nsIRadioVisitor* aVisitor,
203
                            bool aFlushContent);
204
  void SetCurrentRadioButton(const nsAString& aName,
205
                             HTMLInputElement* aRadio);
206
  HTMLInputElement* GetCurrentRadioButton(const nsAString& aName);
207
  nsresult GetNextRadioButton(const nsAString& aName,
208
                              const bool aPrevious,
209
                              HTMLInputElement* aFocusedRadio,
210
                              HTMLInputElement** aRadioOut);
211
  void AddToRadioGroup(const nsAString& aName,
212
                       HTMLInputElement* aRadio);
213
  void RemoveFromRadioGroup(const nsAString& aName,
214
                            HTMLInputElement* aRadio);
215
  uint32_t GetRequiredRadioCount(const nsAString& aName) const;
216
  void RadioRequiredWillChange(const nsAString& aName,
217
                                       bool aRequiredAdded);
218
  bool GetValueMissingState(const nsAString& aName) const;
219
  void SetValueMissingState(const nsAString& aName, bool aValue);
220
221
  // for radio group
222
  nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
223
  nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
224
225
protected:
226
  // Returns the reference to the sheet, if found in mStyleSheets.
227
  already_AddRefed<StyleSheet> RemoveSheet(StyleSheet& aSheet);
228
  void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
229
230
  void AddSizeOfExcludingThis(nsWindowSizes&) const;
231
  void AddSizeOfOwnedSheetArrayExcludingThis(
232
      nsWindowSizes&,
233
      const nsTArray<RefPtr<StyleSheet>>&) const;
234
235
  nsIContent* Retarget(nsIContent* aContent) const;
236
237
  /**
238
   * If focused element's subtree root is this document or shadow root, return
239
   * focused element, otherwise, get the shadow host recursively until the
240
   * shadow host's subtree root is this document or shadow root.
241
   */
242
  Element* GetRetargetedFocusedElement();
243
244
  nsTArray<RefPtr<mozilla::StyleSheet>> mStyleSheets;
245
  RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
246
247
  /*
248
   * mIdentifierMap works as follows for IDs:
249
   * 1) Attribute changes affect the table immediately (removing and adding
250
   *    entries as needed).
251
   * 2) Removals from the DOM affect the table immediately
252
   * 3) Additions to the DOM always update existing entries for names, and add
253
   *    new ones for IDs.
254
   */
255
  nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
256
257
  nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
258
259
  nsINode& mAsNode;
260
  const Kind mKind;
261
};
262
263
inline const nsTArray<Element*>*
264
DocumentOrShadowRoot::GetAllElementsForId(const nsAString& aElementId) const
265
0
{
266
0
  if (aElementId.IsEmpty()) {
267
0
    return nullptr;
268
0
  }
269
0
270
0
  nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aElementId);
271
0
  return entry ? &entry->GetIdElements() : nullptr;
272
0
}
273
274
}
275
276
}
277
278
#endif