1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=2 et :
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Mozilla Foundation.
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Boris Zbarsky <bzbarsky@mit.edu> (Original Author)
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef mozilla_dom_Element_h__
41 : #define mozilla_dom_Element_h__
42 :
43 : #include "nsIContent.h"
44 : #include "nsEventStates.h"
45 :
46 : class nsEventStateManager;
47 : class nsGlobalWindow;
48 : class nsFocusManager;
49 :
50 : // Element-specific flags
51 : enum {
52 : // Set if the element has a pending style change.
53 : ELEMENT_HAS_PENDING_RESTYLE = (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET),
54 :
55 : // Set if the element is a potential restyle root (that is, has a style
56 : // change pending _and_ that style change will attempt to restyle
57 : // descendants).
58 : ELEMENT_IS_POTENTIAL_RESTYLE_ROOT =
59 : (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 1)),
60 :
61 : // Set if the element has a pending animation style change.
62 : ELEMENT_HAS_PENDING_ANIMATION_RESTYLE =
63 : (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 2)),
64 :
65 : // Set if the element is a potential animation restyle root (that is,
66 : // has an animation style change pending _and_ that style change
67 : // will attempt to restyle descendants).
68 : ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT =
69 : (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 3)),
70 :
71 : // All of those bits together, for convenience.
72 : ELEMENT_ALL_RESTYLE_FLAGS = ELEMENT_HAS_PENDING_RESTYLE |
73 : ELEMENT_IS_POTENTIAL_RESTYLE_ROOT |
74 : ELEMENT_HAS_PENDING_ANIMATION_RESTYLE |
75 : ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT,
76 :
77 : // Just the HAS_PENDING bits, for convenience
78 : ELEMENT_PENDING_RESTYLE_FLAGS = ELEMENT_HAS_PENDING_RESTYLE |
79 : ELEMENT_HAS_PENDING_ANIMATION_RESTYLE,
80 :
81 : // Remaining bits are for subclasses
82 : ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 4
83 : };
84 :
85 : namespace mozilla {
86 : namespace dom {
87 :
88 : class Link;
89 :
90 : // IID for the dom::Element interface
91 : #define NS_ELEMENT_IID \
92 : { 0xa1588efb, 0x5a84, 0x49cd, \
93 : { 0x99, 0x1a, 0xac, 0x84, 0x9d, 0x92, 0x05, 0x0f } }
94 :
95 : class Element : public nsIContent
96 76062 : {
97 : public:
98 : #ifdef MOZILLA_INTERNAL_API
99 38033 : Element(already_AddRefed<nsINodeInfo> aNodeInfo) :
100 : nsIContent(aNodeInfo),
101 38033 : mState(NS_EVENT_STATE_MOZ_READONLY)
102 38033 : {}
103 : #endif // MOZILLA_INTERNAL_API
104 :
105 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
106 :
107 : /**
108 : * Method to get the full state of this element. See nsEventStates.h for
109 : * the possible bits that could be set here.
110 : */
111 0 : nsEventStates State() const {
112 : // mState is maintained by having whoever might have changed it
113 : // call UpdateState() or one of the other mState mutators.
114 0 : return mState;
115 : }
116 :
117 : /**
118 : * Ask this element to update its state. If aNotify is false, then
119 : * state change notifications will not be dispatched; in that
120 : * situation it is the caller's responsibility to dispatch them.
121 : *
122 : * In general, aNotify should only be false if we're guaranteed that
123 : * the element can't have a frame no matter what its style is
124 : * (e.g. if we're in the middle of adding it to the document or
125 : * removing it from the document).
126 : */
127 : void UpdateState(bool aNotify);
128 :
129 : /**
130 : * Method to update mState with link state information. This does not notify.
131 : */
132 : void UpdateLinkState(nsEventStates aState);
133 :
134 : /**
135 : * Returns true if this element is either a full-screen element or an
136 : * ancestor of the full-screen element.
137 : */
138 37956 : bool IsFullScreenAncestor() const {
139 : return mState.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR |
140 37956 : NS_EVENT_STATE_FULL_SCREEN);
141 : }
142 :
143 : /**
144 : * The style state of this element. This is the real state of the element
145 : * with any style locks applied for pseudo-class inspecting.
146 : */
147 0 : nsEventStates StyleState() const {
148 0 : if (!HasLockedStyleStates()) {
149 0 : return mState;
150 : }
151 0 : return StyleStateFromLocks();
152 : };
153 :
154 : /**
155 : * The style state locks applied to this element.
156 : */
157 : nsEventStates LockedStyleStates() const;
158 :
159 : /**
160 : * Add a style state lock on this element.
161 : */
162 : void LockStyleStates(nsEventStates aStates);
163 :
164 : /**
165 : * Remove a style state lock on this element.
166 : */
167 : void UnlockStyleStates(nsEventStates aStates);
168 :
169 : /**
170 : * Clear all style state locks on this element.
171 : */
172 : void ClearStyleStateLocks();
173 :
174 : protected:
175 : /**
176 : * Method to get the _intrinsic_ content state of this element. This is the
177 : * state that is independent of the element's presentation. To get the full
178 : * content state, use State(). See nsEventStates.h for
179 : * the possible bits that could be set here.
180 : */
181 : virtual nsEventStates IntrinsicState() const;
182 :
183 : /**
184 : * Method to add state bits. This should be called from subclass
185 : * constructors to set up our event state correctly at construction
186 : * time and other places where we don't want to notify a state
187 : * change.
188 : */
189 37894 : void AddStatesSilently(nsEventStates aStates) {
190 37894 : mState |= aStates;
191 37894 : }
192 :
193 : /**
194 : * Method to remove state bits. This should be called from subclass
195 : * constructors to set up our event state correctly at construction
196 : * time and other places where we don't want to notify a state
197 : * change.
198 : */
199 37893 : void RemoveStatesSilently(nsEventStates aStates) {
200 37893 : mState &= ~aStates;
201 37893 : }
202 :
203 : private:
204 : // Need to allow the ESM, nsGlobalWindow, and the focus manager to
205 : // set our state
206 : friend class ::nsEventStateManager;
207 : friend class ::nsGlobalWindow;
208 : friend class ::nsFocusManager;
209 :
210 : // Also need to allow Link to call UpdateLinkState.
211 : friend class Link;
212 :
213 : void NotifyStateChange(nsEventStates aStates);
214 :
215 : void NotifyStyleStateChange(nsEventStates aStates);
216 :
217 : // Style state computed from element's state and style locks.
218 : nsEventStates StyleStateFromLocks() const;
219 :
220 : // Methods for the ESM to manage state bits. These will handle
221 : // setting up script blockers when they notify, so no need to do it
222 : // in the callers unless desired.
223 0 : void AddStates(nsEventStates aStates) {
224 0 : NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
225 : "Should only be adding ESM-managed states here");
226 0 : AddStatesSilently(aStates);
227 0 : NotifyStateChange(aStates);
228 0 : }
229 0 : void RemoveStates(nsEventStates aStates) {
230 0 : NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
231 : "Should only be removing ESM-managed states here");
232 0 : RemoveStatesSilently(aStates);
233 0 : NotifyStateChange(aStates);
234 0 : }
235 :
236 : nsEventStates mState;
237 : };
238 :
239 : NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
240 :
241 : } // namespace dom
242 : } // namespace mozilla
243 :
244 362829 : inline mozilla::dom::Element* nsINode::AsElement() {
245 362829 : NS_ASSERTION(IsElement(), "Not an element?");
246 362829 : return static_cast<mozilla::dom::Element*>(this);
247 : }
248 :
249 : #endif // mozilla_dom_Element_h__
|