/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_ |