1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation
18 : * Portions created by the Initial Developer are Copyright (C) 2010
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsEventStates_h__
39 : #define nsEventStates_h__
40 :
41 : #include "nsDebug.h"
42 :
43 : /**
44 : * nsEventStates is the class used to represent the event states of nsIContent
45 : * instances. These states are calculated by IntrinsicState() and
46 : * ContentStatesChanged() has to be called when one of them changes thus
47 : * informing the layout/style engine of the change.
48 : * Event states are associated with pseudo-classes.
49 : */
50 : class nsEventStates
51 : {
52 : public:
53 : typedef PRUint64 InternalType;
54 :
55 49727 : nsEventStates()
56 49727 : : mStates(0)
57 49727 : { }
58 :
59 : // NOTE: the ideal scenario would be to have the default constructor public
60 : // setting mStates to 0 and this constructor (without = 0) private.
61 : // In that case, we could be sure that only macros at the end were creating
62 : // nsEventStates instances with mStates set to something else than 0.
63 : // Unfortunately, this constructor is needed at at least two places now.
64 534906 : explicit nsEventStates(InternalType aStates)
65 534906 : : mStates(aStates)
66 534906 : { }
67 :
68 13399 : nsEventStates(const nsEventStates& aEventStates) {
69 13399 : mStates = aEventStates.mStates;
70 13399 : }
71 :
72 11603 : nsEventStates& operator=(const nsEventStates& aEventStates) {
73 11603 : mStates = aEventStates.mStates;
74 11603 : return *this;
75 : }
76 :
77 132248 : nsEventStates operator|(const nsEventStates& aEventStates) const {
78 132248 : return nsEventStates(mStates | aEventStates.mStates);
79 : }
80 :
81 37909 : nsEventStates& operator|=(const nsEventStates& aEventStates) {
82 37909 : mStates |= aEventStates.mStates;
83 37909 : return *this;
84 : }
85 :
86 : // NOTE: calling if (eventStates1 & eventStates2) will not build.
87 : // This might work correctly if operator bool() is defined
88 : // but using HasState, HasAllStates or HasAtLeastOneOfStates is recommended.
89 11603 : nsEventStates operator&(const nsEventStates& aEventStates) const {
90 11603 : return nsEventStates(mStates & aEventStates.mStates);
91 : }
92 :
93 37898 : nsEventStates& operator&=(const nsEventStates& aEventStates) {
94 37898 : mStates &= aEventStates.mStates;
95 37898 : return *this;
96 : }
97 :
98 0 : bool operator==(const nsEventStates& aEventStates) const {
99 0 : return mStates == aEventStates.mStates;
100 : }
101 :
102 0 : bool operator!=(const nsEventStates& aEventStates) const {
103 0 : return mStates != aEventStates.mStates;
104 : }
105 :
106 37898 : nsEventStates operator~() const {
107 37898 : return nsEventStates(~mStates);
108 : }
109 :
110 1874 : nsEventStates operator^(const nsEventStates& aEventStates) const {
111 1874 : return nsEventStates(mStates ^ aEventStates.mStates);
112 : }
113 :
114 : nsEventStates& operator^=(const nsEventStates& aEventStates) {
115 : mStates ^= aEventStates.mStates;
116 : return *this;
117 : }
118 :
119 : /**
120 : * Returns true if the nsEventStates instance is empty.
121 : * A nsEventStates instance is empty if it contains no state.
122 : *
123 : * @return Whether if the object is empty.
124 : */
125 2202 : bool IsEmpty() const {
126 2202 : return mStates == 0;
127 : }
128 :
129 : /**
130 : * Returns true if the nsEventStates instance contains the state
131 : * contained in aEventStates.
132 : * @note aEventStates should contain only one state.
133 : *
134 : * @param aEventStates The state to check.
135 : *
136 : * @return Whether the object has the state from aEventStates
137 : */
138 4 : bool HasState(nsEventStates aEventStates) const {
139 : #ifdef DEBUG
140 : // If aEventStates.mStates is a power of two, it contains only one state
141 : // (or none, but we don't really care).
142 4 : if ((aEventStates.mStates & (aEventStates.mStates - 1))) {
143 : NS_ERROR("When calling HasState, "
144 0 : "nsEventStates object has to contain only one state!");
145 : }
146 : #endif // DEBUG
147 4 : return mStates & aEventStates.mStates;
148 : }
149 :
150 : /**
151 : * Returns true if the nsEventStates instance contains one of the states
152 : * contained in aEventStates.
153 : *
154 : * @param aEventStates The states to check.
155 : *
156 : * @return Whether the object has at least one state from aEventStates
157 : */
158 37956 : bool HasAtLeastOneOfStates(nsEventStates aEventStates) const {
159 37956 : return mStates & aEventStates.mStates;
160 : }
161 :
162 : /**
163 : * Returns true if the nsEventStates instance contains all states
164 : * contained in aEventStates.
165 : *
166 : * @param aEventStates The states to check.
167 : *
168 : * @return Whether the object has all states from aEventStates
169 : */
170 0 : bool HasAllStates(nsEventStates aEventStates) const {
171 0 : return (mStates & aEventStates.mStates) == aEventStates.mStates;
172 : }
173 :
174 : // We only need that method for inDOMUtils::GetContentState.
175 : // If inDOMUtils::GetContentState is removed, this method should be removed.
176 0 : InternalType GetInternalValue() const {
177 0 : return mStates;
178 : }
179 :
180 : private:
181 : InternalType mStates;
182 : };
183 :
184 : /**
185 : * The following macros are creating nsEventStates instance with different
186 : * values depending of their meaning.
187 : * Ideally, nsEventStates instance with values different than 0 should only be
188 : * created that way.
189 : */
190 :
191 : // Helper to define a new nsEventStates macro.
192 : #define NS_DEFINE_EVENT_STATE_MACRO(_val) \
193 : (nsEventStates(nsEventStates::InternalType(1) << _val))
194 :
195 : // Mouse is down on content.
196 : #define NS_EVENT_STATE_ACTIVE NS_DEFINE_EVENT_STATE_MACRO(0)
197 : // Content has focus.
198 : #define NS_EVENT_STATE_FOCUS NS_DEFINE_EVENT_STATE_MACRO(1)
199 : // Mouse is hovering over content.
200 : #define NS_EVENT_STATE_HOVER NS_DEFINE_EVENT_STATE_MACRO(2)
201 : // Drag is hovering over content.
202 : #define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(3)
203 : // Content is URL's target (ref).
204 : #define NS_EVENT_STATE_URLTARGET NS_DEFINE_EVENT_STATE_MACRO(4)
205 : // Content is checked.
206 : #define NS_EVENT_STATE_CHECKED NS_DEFINE_EVENT_STATE_MACRO(5)
207 : // Content is enabled (and can be disabled).
208 : #define NS_EVENT_STATE_ENABLED NS_DEFINE_EVENT_STATE_MACRO(6)
209 : // Content is disabled.
210 : #define NS_EVENT_STATE_DISABLED NS_DEFINE_EVENT_STATE_MACRO(7)
211 : // Content is required.
212 : #define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(8)
213 : // Content is optional (and can be required).
214 : #define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(9)
215 : // Link has been visited.
216 : #define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(10)
217 : // Link hasn't been visited.
218 : #define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(11)
219 : // Content is valid (and can be invalid).
220 : #define NS_EVENT_STATE_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
221 : // Content is invalid.
222 : #define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(13)
223 : // Content value is in-range (and can be out-of-range).
224 : #define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(14)
225 : // Content value is out-of-range.
226 : #define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(15)
227 : // These two are temporary (see bug 302188)
228 : // Content is read-only.
229 : #define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(16)
230 : // Content is editable.
231 : #define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(17)
232 : // Content is the default one (meaning depends of the context).
233 : #define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(18)
234 : // Content could not be rendered (image/object/etc).
235 : #define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(19)
236 : // Content disabled by the user (images turned off, say).
237 : #define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(20)
238 : // Content suppressed by the user (ad blocking, etc).
239 : #define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(21)
240 : // Content is still loading such that there is nothing to show the
241 : // user (eg an image which hasn't started coming in yet).
242 : #define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(22)
243 : // Content is of a type that gecko can't handle.
244 : #define NS_EVENT_STATE_TYPE_UNSUPPORTED NS_DEFINE_EVENT_STATE_MACRO(23)
245 : #define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(24)
246 : // Handler for the content has been blocked.
247 : #define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(25)
248 : // Handler for the content has been disabled.
249 : #define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(26)
250 : // Content is in the indeterminate state.
251 : #define NS_EVENT_STATE_INDETERMINATE NS_DEFINE_EVENT_STATE_MACRO(27)
252 : // Handler for the content has crashed
253 : #define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(28)
254 : // Content has focus and should show a ring.
255 : #define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(29)
256 : // Content shows its placeholder
257 : #define NS_EVENT_STATE_MOZ_PLACEHOLDER NS_DEFINE_EVENT_STATE_MACRO(30)
258 : // Content is a submit control and the form isn't valid.
259 : #define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(31)
260 : // UI friendly version of :invalid pseudo-class.
261 : #define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(32)
262 : // UI friendly version of :valid pseudo-class.
263 : #define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(33)
264 : // Content is the full screen element, or a frame containing the
265 : // current full-screen element.
266 : #define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(34)
267 : // Content is an ancestor of the DOM full-screen element.
268 : #define NS_EVENT_STATE_FULL_SCREEN_ANCESTOR NS_DEFINE_EVENT_STATE_MACRO(35)
269 : // Handler for click to play plugin
270 : #define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(36)
271 :
272 : /**
273 : * NOTE: do not go over 63 without updating nsEventStates::InternalType!
274 : */
275 :
276 : #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
277 : NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
278 : NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
279 : NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR)
280 :
281 : #define INTRINSIC_STATES (~ESM_MANAGED_STATES)
282 :
283 : #endif // nsEventStates_h__
284 :
|