Source code

Revision control

Other Tools

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