Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/EventStates.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_EventStates_h_
8
#define mozilla_EventStates_h_
9
10
#include "mozilla/Attributes.h"
11
#include "nsDebug.h"
12
13
namespace mozilla {
14
15
/**
16
 * EventStates is the class used to represent the event states of nsIContent
17
 * instances. These states are calculated by IntrinsicState() and
18
 * ContentStatesChanged() has to be called when one of them changes thus
19
 * informing the layout/style engine of the change.
20
 * Event states are associated with pseudo-classes.
21
 */
22
class EventStates
23
{
24
public:
25
  typedef uint64_t InternalType;
26
  typedef uint64_t ServoType;
27
28
  constexpr EventStates()
29
    : mStates(0)
30
0
  {
31
0
  }
32
33
  // NOTE: the ideal scenario would be to have the default constructor public
34
  // setting mStates to 0 and this constructor (without = 0) private.
35
  // In that case, we could be sure that only macros at the end were creating
36
  // EventStates instances with mStates set to something else than 0.
37
  // Unfortunately, this constructor is needed at at least two places now.
38
  explicit constexpr EventStates(InternalType aStates)
39
    : mStates(aStates)
40
0
  {
41
0
  }
42
43
  EventStates constexpr operator|(const EventStates& aEventStates) const
44
0
  {
45
0
    return EventStates(mStates | aEventStates.mStates);
46
0
  }
47
48
  EventStates& operator|=(const EventStates& aEventStates)
49
0
  {
50
0
    mStates |= aEventStates.mStates;
51
0
    return *this;
52
0
  }
53
54
  // NOTE: calling if (eventStates1 & eventStates2) will not build.
55
  // This might work correctly if operator bool() is defined
56
  // but using HasState, HasAllStates or HasAtLeastOneOfStates is recommended.
57
  EventStates constexpr operator&(const EventStates& aEventStates) const
58
0
  {
59
0
    return EventStates(mStates & aEventStates.mStates);
60
0
  }
61
62
  EventStates& operator&=(const EventStates& aEventStates)
63
0
  {
64
0
    mStates &= aEventStates.mStates;
65
0
    return *this;
66
0
  }
67
68
  bool operator==(const EventStates& aEventStates) const
69
0
  {
70
0
    return mStates == aEventStates.mStates;
71
0
  }
72
73
  bool operator!=(const EventStates& aEventStates) const
74
0
  {
75
0
    return mStates != aEventStates.mStates;
76
0
  }
77
78
  EventStates operator~() const
79
0
  {
80
0
    return EventStates(~mStates);
81
0
  }
82
83
  EventStates operator^(const EventStates& aEventStates) const
84
0
  {
85
0
    return EventStates(mStates ^ aEventStates.mStates);
86
0
  }
87
88
  EventStates& operator^=(const EventStates& aEventStates)
89
0
  {
90
0
    mStates ^= aEventStates.mStates;
91
0
    return *this;
92
0
  }
93
94
  /**
95
   * Returns true if the EventStates instance is empty.
96
   * A EventStates instance is empty if it contains no state.
97
   *
98
   * @return Whether if the object is empty.
99
   */
100
  bool IsEmpty() const
101
0
  {
102
0
    return mStates == 0;
103
0
  }
104
105
  /**
106
   * Returns true if the EventStates instance contains the state
107
   * contained in aEventStates.
108
   * @note aEventStates should contain only one state.
109
   *
110
   * @param aEventStates The state to check.
111
   *
112
   * @return Whether the object has the state from aEventStates
113
   */
114
  bool HasState(EventStates aEventStates) const
115
0
  {
116
#ifdef DEBUG
117
    // If aEventStates.mStates is a power of two, it contains only one state
118
    // (or none, but we don't really care).
119
    if ((aEventStates.mStates & (aEventStates.mStates - 1))) {
120
      NS_ERROR("When calling HasState, "
121
               "EventStates object has to contain only one state!");
122
    }
123
#endif // DEBUG
124
    return mStates & aEventStates.mStates;
125
0
  }
126
127
  /**
128
   * Returns true if the EventStates instance contains one of the states
129
   * contained in aEventStates.
130
   *
131
   * @param aEventStates The states to check.
132
   *
133
   * @return Whether the object has at least one state from aEventStates
134
   */
135
  bool HasAtLeastOneOfStates(EventStates aEventStates) const
136
0
  {
137
0
    return mStates & aEventStates.mStates;
138
0
  }
139
140
  /**
141
   * Returns true if the EventStates instance contains all states
142
   * contained in aEventStates.
143
   *
144
   * @param aEventStates The states to check.
145
   *
146
   * @return Whether the object has all states from aEventStates
147
   */
148
  bool HasAllStates(EventStates aEventStates) const
149
0
  {
150
0
    return (mStates & aEventStates.mStates) == aEventStates.mStates;
151
0
  }
152
153
  // We only need that method for InspectorUtils::GetContentState.
154
  // If InspectorUtils::GetContentState is removed, this method should
155
  // be removed.
156
0
  InternalType GetInternalValue() const {
157
0
    return mStates;
158
0
  }
159
160
  /**
161
   * Method used to get the appropriate state representation for Servo.
162
   */
163
  ServoType ServoValue() const
164
0
  {
165
0
    return mStates;
166
0
  }
167
168
private:
169
  InternalType mStates;
170
};
171
172
} // namespace mozilla
173
174
/**
175
 * The following macros are creating EventStates instance with different
176
 * values depending of their meaning.
177
 * Ideally, EventStates instance with values different than 0 should only be
178
 * created that way.
179
 */
180
181
// Helper to define a new EventStates macro.
182
#define NS_DEFINE_EVENT_STATE_MACRO(_val)               \
183
0
  (mozilla::EventStates(mozilla::EventStates::InternalType(1) << _val))
184
185
/*
186
 * In order to efficiently convert Gecko EventState values into Servo
187
 * ElementState values [1], we maintain the invariant that the low bits of
188
 * EventState can be masked off to form an ElementState (this works so
189
 * long as Servo never supports a state that Gecko doesn't).
190
 *
191
 * This is unfortunately rather fragile for now, but we should soon have
192
 * the infrastructure to statically-assert that these match up. If you
193
 * need to change these, please notify somebody involved with Stylo.
194
 *
195
 * [1] https://github.com/servo/servo/blob/master/components/style/element_state.rs
196
 */
197
198
// Mouse is down on content.
199
0
#define NS_EVENT_STATE_ACTIVE        NS_DEFINE_EVENT_STATE_MACRO(0)
200
// Content has focus.
201
0
#define NS_EVENT_STATE_FOCUS         NS_DEFINE_EVENT_STATE_MACRO(1)
202
// Mouse is hovering over content.
203
0
#define NS_EVENT_STATE_HOVER         NS_DEFINE_EVENT_STATE_MACRO(2)
204
// Content is enabled (and can be disabled).
205
0
#define NS_EVENT_STATE_ENABLED       NS_DEFINE_EVENT_STATE_MACRO(3)
206
// Content is disabled.
207
0
#define NS_EVENT_STATE_DISABLED      NS_DEFINE_EVENT_STATE_MACRO(4)
208
// Content is checked.
209
0
#define NS_EVENT_STATE_CHECKED       NS_DEFINE_EVENT_STATE_MACRO(5)
210
// Content is in the indeterminate state.
211
0
#define NS_EVENT_STATE_INDETERMINATE NS_DEFINE_EVENT_STATE_MACRO(6)
212
// Content shows its placeholder
213
0
#define NS_EVENT_STATE_PLACEHOLDERSHOWN NS_DEFINE_EVENT_STATE_MACRO(7)
214
// Content is URL's target (ref).
215
0
#define NS_EVENT_STATE_URLTARGET     NS_DEFINE_EVENT_STATE_MACRO(8)
216
// Content is the full screen element, or a frame containing the
217
// current fullscreen element.
218
0
#define NS_EVENT_STATE_FULLSCREEN    NS_DEFINE_EVENT_STATE_MACRO(9)
219
// Content is valid (and can be invalid).
220
0
#define NS_EVENT_STATE_VALID         NS_DEFINE_EVENT_STATE_MACRO(10)
221
// Content is invalid.
222
0
#define NS_EVENT_STATE_INVALID       NS_DEFINE_EVENT_STATE_MACRO(11)
223
// UI friendly version of :valid pseudo-class.
224
0
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
225
// UI friendly version of :invalid pseudo-class.
226
0
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(13)
227
// Content could not be rendered (image/object/etc).
228
0
#define NS_EVENT_STATE_BROKEN        NS_DEFINE_EVENT_STATE_MACRO(14)
229
// Content disabled by the user (images turned off, say).
230
0
#define NS_EVENT_STATE_USERDISABLED  NS_DEFINE_EVENT_STATE_MACRO(15)
231
// Content suppressed by the user (ad blocking, etc).
232
0
#define NS_EVENT_STATE_SUPPRESSED    NS_DEFINE_EVENT_STATE_MACRO(16)
233
// Content is still loading such that there is nothing to show the
234
// user (eg an image which hasn't started coming in yet).
235
0
#define NS_EVENT_STATE_LOADING       NS_DEFINE_EVENT_STATE_MACRO(17)
236
// Handler for the content has been blocked.
237
0
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(18)
238
// Handler for the content has been disabled.
239
0
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(19)
240
// Handler for the content has crashed
241
0
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(20)
242
// Content is required.
243
0
#define NS_EVENT_STATE_REQUIRED      NS_DEFINE_EVENT_STATE_MACRO(21)
244
// Content is optional (and can be required).
245
0
#define NS_EVENT_STATE_OPTIONAL      NS_DEFINE_EVENT_STATE_MACRO(22)
246
// Element is either a defined custom element or uncustomized element.
247
0
#define NS_EVENT_STATE_DEFINED       NS_DEFINE_EVENT_STATE_MACRO(23)
248
// Link has been visited.
249
0
#define NS_EVENT_STATE_VISITED       NS_DEFINE_EVENT_STATE_MACRO(24)
250
// Link hasn't been visited.
251
0
#define NS_EVENT_STATE_UNVISITED     NS_DEFINE_EVENT_STATE_MACRO(25)
252
// Drag is hovering over content.
253
0
#define NS_EVENT_STATE_DRAGOVER      NS_DEFINE_EVENT_STATE_MACRO(26)
254
// Content value is in-range (and can be out-of-range).
255
0
#define NS_EVENT_STATE_INRANGE       NS_DEFINE_EVENT_STATE_MACRO(27)
256
// Content value is out-of-range.
257
0
#define NS_EVENT_STATE_OUTOFRANGE    NS_DEFINE_EVENT_STATE_MACRO(28)
258
// These two are temporary (see bug 302188)
259
// Content is read-only.
260
0
#define NS_EVENT_STATE_MOZ_READONLY  NS_DEFINE_EVENT_STATE_MACRO(29)
261
// Content is editable.
262
0
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(30)
263
// Content is the default one (meaning depends of the context).
264
0
#define NS_EVENT_STATE_DEFAULT       NS_DEFINE_EVENT_STATE_MACRO(31)
265
// Content is a submit control and the form isn't valid.
266
0
#define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(32)
267
// Content is in the optimum region.
268
0
#define NS_EVENT_STATE_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(33)
269
// Content is in the suboptimal region.
270
0
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(34)
271
// Content is in the sub-suboptimal region.
272
0
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(35)
273
// Element is highlighted (devtools inspector)
274
#define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(36)
275
// Element is transitioning for rules changed by style editor
276
#define NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING NS_DEFINE_EVENT_STATE_MACRO(37)
277
0
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(38)
278
// Content has focus and should show a ring.
279
0
#define NS_EVENT_STATE_FOCUSRING     NS_DEFINE_EVENT_STATE_MACRO(39)
280
// Handler for click to play plugin
281
0
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(40)
282
// Handler for click to play plugin (vulnerable w/update)
283
0
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(41)
284
// Handler for click to play plugin (vulnerable w/no update)
285
0
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(42)
286
// Element has focus-within.
287
0
#define NS_EVENT_STATE_FOCUS_WITHIN NS_DEFINE_EVENT_STATE_MACRO(43)
288
// Element is ltr (for :dir pseudo-class)
289
0
#define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(44)
290
// Element is rtl (for :dir pseudo-class)
291
0
#define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(45)
292
// States for tracking the state of the "dir" attribute for HTML elements.  We
293
// use these to avoid having to get "dir" attributes all the time during
294
// selector matching for some parts of the UA stylesheet.
295
//
296
// These states are externally managed, because we also don't want to keep
297
// getting "dir" attributes in IntrinsicState.
298
//
299
// Element is HTML and has a "dir" attibute.  This state might go away depending
300
// on how https://github.com/whatwg/html/issues/2769 gets resolved.  The value
301
// could be anything.
302
0
#define NS_EVENT_STATE_HAS_DIR_ATTR NS_DEFINE_EVENT_STATE_MACRO(46)
303
// Element is HTML, has a "dir" attribute, and the attribute's value is
304
// case-insensitively equal to "ltr".
305
0
#define NS_EVENT_STATE_DIR_ATTR_LTR NS_DEFINE_EVENT_STATE_MACRO(47)
306
// Element is HTML, has a "dir" attribute, and the attribute's value is
307
// case-insensitively equal to "rtl".
308
0
#define NS_EVENT_STATE_DIR_ATTR_RTL NS_DEFINE_EVENT_STATE_MACRO(48)
309
// Element is HTML, and is either a <bdi> element with no valid-valued "dir"
310
// attribute or any HTML element which has a "dir" attribute whose value is
311
// "auto".
312
0
#define NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO NS_DEFINE_EVENT_STATE_MACRO(49)
313
// Element is filled by Autofill feature.
314
0
#define NS_EVENT_STATE_AUTOFILL NS_DEFINE_EVENT_STATE_MACRO(50)
315
// Element is filled with preview data by Autofill feature.
316
0
#define NS_EVENT_STATE_AUTOFILL_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(51)
317
318
// Event state that is used for values that need to be parsed but do nothing.
319
#define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
320
321
/**
322
 * NOTE: do not go over 63 without updating EventStates::InternalType!
323
 */
324
325
0
#define DIRECTION_STATES (NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
326
327
0
#define DIR_ATTR_STATES (NS_EVENT_STATE_HAS_DIR_ATTR |          \
328
0
                         NS_EVENT_STATE_DIR_ATTR_LTR |          \
329
0
                         NS_EVENT_STATE_DIR_ATTR_RTL |          \
330
0
                         NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO)
331
332
0
#define DISABLED_STATES (NS_EVENT_STATE_DISABLED | NS_EVENT_STATE_ENABLED)
333
334
0
#define REQUIRED_STATES (NS_EVENT_STATE_REQUIRED | NS_EVENT_STATE_OPTIONAL)
335
336
// Event states that can be added and removed through
337
// Element::{Add,Remove}ManuallyManagedStates.
338
//
339
// Take care when manually managing state bits.  You are responsible for
340
// setting or clearing the bit when an Element is added or removed from a
341
// document (e.g. in BindToTree and UnbindFromTree), if that is an
342
// appropriate thing to do for your state bit.
343
0
#define MANUALLY_MANAGED_STATES (             \
344
0
  NS_EVENT_STATE_AUTOFILL |                   \
345
0
  NS_EVENT_STATE_AUTOFILL_PREVIEW             \
346
0
)
347
348
// Event states that are managed externally to an element (by the
349
// EventStateManager, or by other code).  As opposed to those in
350
// INTRINSIC_STATES, which are are computed by the element itself
351
// and returned from Element::IntrinsicState.
352
0
#define EXTERNALLY_MANAGED_STATES (           \
353
0
  MANUALLY_MANAGED_STATES |                   \
354
0
  DIR_ATTR_STATES |                           \
355
0
  DISABLED_STATES |                           \
356
0
  REQUIRED_STATES |                           \
357
0
  NS_EVENT_STATE_ACTIVE |                     \
358
0
  NS_EVENT_STATE_DEFINED |                    \
359
0
  NS_EVENT_STATE_DRAGOVER |                   \
360
0
  NS_EVENT_STATE_FOCUS |                      \
361
0
  NS_EVENT_STATE_FOCUSRING |                  \
362
0
  NS_EVENT_STATE_FOCUS_WITHIN |               \
363
0
  NS_EVENT_STATE_FULLSCREEN |                 \
364
0
  NS_EVENT_STATE_HOVER |                      \
365
0
  NS_EVENT_STATE_URLTARGET                    \
366
0
)
367
368
#define INTRINSIC_STATES (~EXTERNALLY_MANAGED_STATES)
369
370
#endif // mozilla_EventStates_h_