Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * vim: sw=2 ts=2 et : |
michael@0 | 3 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /* |
michael@0 | 8 | * Base class for all element classes; this provides an implementation |
michael@0 | 9 | * of DOM Core's nsIDOMElement, implements nsIContent, provides |
michael@0 | 10 | * utility methods for subclasses, and so forth. |
michael@0 | 11 | */ |
michael@0 | 12 | |
michael@0 | 13 | #ifndef mozilla_dom_Element_h__ |
michael@0 | 14 | #define mozilla_dom_Element_h__ |
michael@0 | 15 | |
michael@0 | 16 | #include "mozilla/dom/FragmentOrElement.h" // for base class |
michael@0 | 17 | #include "nsChangeHint.h" // for enum |
michael@0 | 18 | #include "mozilla/EventStates.h" // for member |
michael@0 | 19 | #include "mozilla/dom/DirectionalityUtils.h" |
michael@0 | 20 | #include "nsIDOMElement.h" |
michael@0 | 21 | #include "nsILinkHandler.h" |
michael@0 | 22 | #include "nsNodeUtils.h" |
michael@0 | 23 | #include "nsAttrAndChildArray.h" |
michael@0 | 24 | #include "mozFlushType.h" |
michael@0 | 25 | #include "nsDOMAttributeMap.h" |
michael@0 | 26 | #include "nsIDOMXPathNSResolver.h" |
michael@0 | 27 | #include "nsPresContext.h" |
michael@0 | 28 | #include "nsDOMClassInfoID.h" // DOMCI_DATA |
michael@0 | 29 | #include "mozilla/CORSMode.h" |
michael@0 | 30 | #include "mozilla/Attributes.h" |
michael@0 | 31 | #include "nsIScrollableFrame.h" |
michael@0 | 32 | #include "mozilla/dom/Attr.h" |
michael@0 | 33 | #include "nsISMILAttr.h" |
michael@0 | 34 | #include "mozilla/dom/DOMRect.h" |
michael@0 | 35 | #include "nsAttrValue.h" |
michael@0 | 36 | #include "mozilla/EventForwards.h" |
michael@0 | 37 | #include "mozilla/dom/BindingDeclarations.h" |
michael@0 | 38 | #include "Units.h" |
michael@0 | 39 | |
michael@0 | 40 | class nsIDOMEventListener; |
michael@0 | 41 | class nsIFrame; |
michael@0 | 42 | class nsIDOMMozNamedAttrMap; |
michael@0 | 43 | class nsIDOMCSSStyleDeclaration; |
michael@0 | 44 | class nsIURI; |
michael@0 | 45 | class nsINodeInfo; |
michael@0 | 46 | class nsIControllers; |
michael@0 | 47 | class nsEventChainVisitor; |
michael@0 | 48 | class nsIScrollableFrame; |
michael@0 | 49 | class nsAttrValueOrString; |
michael@0 | 50 | class ContentUnbinder; |
michael@0 | 51 | class nsContentList; |
michael@0 | 52 | class nsDOMTokenList; |
michael@0 | 53 | struct nsRect; |
michael@0 | 54 | class nsFocusManager; |
michael@0 | 55 | class nsGlobalWindow; |
michael@0 | 56 | class nsICSSDeclaration; |
michael@0 | 57 | class nsISMILAttr; |
michael@0 | 58 | |
michael@0 | 59 | already_AddRefed<nsContentList> |
michael@0 | 60 | NS_GetContentList(nsINode* aRootNode, |
michael@0 | 61 | int32_t aMatchNameSpaceId, |
michael@0 | 62 | const nsAString& aTagname); |
michael@0 | 63 | |
michael@0 | 64 | #define ELEMENT_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_)) |
michael@0 | 65 | |
michael@0 | 66 | // Element-specific flags |
michael@0 | 67 | enum { |
michael@0 | 68 | // Set if the element has a pending style change. |
michael@0 | 69 | ELEMENT_HAS_PENDING_RESTYLE = ELEMENT_FLAG_BIT(0), |
michael@0 | 70 | |
michael@0 | 71 | // Set if the element is a potential restyle root (that is, has a style |
michael@0 | 72 | // change pending _and_ that style change will attempt to restyle |
michael@0 | 73 | // descendants). |
michael@0 | 74 | ELEMENT_IS_POTENTIAL_RESTYLE_ROOT = ELEMENT_FLAG_BIT(1), |
michael@0 | 75 | |
michael@0 | 76 | // Set if the element has a pending animation style change. |
michael@0 | 77 | ELEMENT_HAS_PENDING_ANIMATION_RESTYLE = ELEMENT_FLAG_BIT(2), |
michael@0 | 78 | |
michael@0 | 79 | // Set if the element is a potential animation restyle root (that is, |
michael@0 | 80 | // has an animation style change pending _and_ that style change |
michael@0 | 81 | // will attempt to restyle descendants). |
michael@0 | 82 | ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT = ELEMENT_FLAG_BIT(3), |
michael@0 | 83 | |
michael@0 | 84 | // All of those bits together, for convenience. |
michael@0 | 85 | ELEMENT_ALL_RESTYLE_FLAGS = ELEMENT_HAS_PENDING_RESTYLE | |
michael@0 | 86 | ELEMENT_IS_POTENTIAL_RESTYLE_ROOT | |
michael@0 | 87 | ELEMENT_HAS_PENDING_ANIMATION_RESTYLE | |
michael@0 | 88 | ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT, |
michael@0 | 89 | |
michael@0 | 90 | // Just the HAS_PENDING bits, for convenience |
michael@0 | 91 | ELEMENT_PENDING_RESTYLE_FLAGS = ELEMENT_HAS_PENDING_RESTYLE | |
michael@0 | 92 | ELEMENT_HAS_PENDING_ANIMATION_RESTYLE, |
michael@0 | 93 | |
michael@0 | 94 | // Remaining bits are for subclasses |
michael@0 | 95 | ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 4 |
michael@0 | 96 | }; |
michael@0 | 97 | |
michael@0 | 98 | #undef ELEMENT_FLAG_BIT |
michael@0 | 99 | |
michael@0 | 100 | // Make sure we have space for our bits |
michael@0 | 101 | ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET); |
michael@0 | 102 | |
michael@0 | 103 | namespace mozilla { |
michael@0 | 104 | class EventChainPostVisitor; |
michael@0 | 105 | class EventChainPreVisitor; |
michael@0 | 106 | class EventChainVisitor; |
michael@0 | 107 | class EventListenerManager; |
michael@0 | 108 | class EventStateManager; |
michael@0 | 109 | |
michael@0 | 110 | namespace dom { |
michael@0 | 111 | |
michael@0 | 112 | class Link; |
michael@0 | 113 | class UndoManager; |
michael@0 | 114 | class DOMRect; |
michael@0 | 115 | class DOMRectList; |
michael@0 | 116 | |
michael@0 | 117 | // IID for the dom::Element interface |
michael@0 | 118 | #define NS_ELEMENT_IID \ |
michael@0 | 119 | { 0xf7c18f0f, 0xa8fd, 0x4a95, \ |
michael@0 | 120 | { 0x91, 0x72, 0xd3, 0xa7, 0x4a, 0xb8, 0xc4, 0xbe } } |
michael@0 | 121 | |
michael@0 | 122 | class Element : public FragmentOrElement |
michael@0 | 123 | { |
michael@0 | 124 | public: |
michael@0 | 125 | #ifdef MOZILLA_INTERNAL_API |
michael@0 | 126 | Element(already_AddRefed<nsINodeInfo>& aNodeInfo) : |
michael@0 | 127 | FragmentOrElement(aNodeInfo), |
michael@0 | 128 | mState(NS_EVENT_STATE_MOZ_READONLY) |
michael@0 | 129 | { |
michael@0 | 130 | NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE, |
michael@0 | 131 | "Bad NodeType in aNodeInfo"); |
michael@0 | 132 | SetIsElement(); |
michael@0 | 133 | } |
michael@0 | 134 | #endif // MOZILLA_INTERNAL_API |
michael@0 | 135 | |
michael@0 | 136 | NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID) |
michael@0 | 137 | |
michael@0 | 138 | NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); |
michael@0 | 139 | |
michael@0 | 140 | /** |
michael@0 | 141 | * Method to get the full state of this element. See mozilla/EventStates.h |
michael@0 | 142 | * for the possible bits that could be set here. |
michael@0 | 143 | */ |
michael@0 | 144 | EventStates State() const |
michael@0 | 145 | { |
michael@0 | 146 | // mState is maintained by having whoever might have changed it |
michael@0 | 147 | // call UpdateState() or one of the other mState mutators. |
michael@0 | 148 | return mState; |
michael@0 | 149 | } |
michael@0 | 150 | |
michael@0 | 151 | /** |
michael@0 | 152 | * Ask this element to update its state. If aNotify is false, then |
michael@0 | 153 | * state change notifications will not be dispatched; in that |
michael@0 | 154 | * situation it is the caller's responsibility to dispatch them. |
michael@0 | 155 | * |
michael@0 | 156 | * In general, aNotify should only be false if we're guaranteed that |
michael@0 | 157 | * the element can't have a frame no matter what its style is |
michael@0 | 158 | * (e.g. if we're in the middle of adding it to the document or |
michael@0 | 159 | * removing it from the document). |
michael@0 | 160 | */ |
michael@0 | 161 | void UpdateState(bool aNotify); |
michael@0 | 162 | |
michael@0 | 163 | /** |
michael@0 | 164 | * Method to update mState with link state information. This does not notify. |
michael@0 | 165 | */ |
michael@0 | 166 | void UpdateLinkState(EventStates aState); |
michael@0 | 167 | |
michael@0 | 168 | /** |
michael@0 | 169 | * Returns true if this element is either a full-screen element or an |
michael@0 | 170 | * ancestor of the full-screen element. |
michael@0 | 171 | */ |
michael@0 | 172 | bool IsFullScreenAncestor() const { |
michael@0 | 173 | return mState.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR | |
michael@0 | 174 | NS_EVENT_STATE_FULL_SCREEN); |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | /** |
michael@0 | 178 | * The style state of this element. This is the real state of the element |
michael@0 | 179 | * with any style locks applied for pseudo-class inspecting. |
michael@0 | 180 | */ |
michael@0 | 181 | EventStates StyleState() const |
michael@0 | 182 | { |
michael@0 | 183 | if (!HasLockedStyleStates()) { |
michael@0 | 184 | return mState; |
michael@0 | 185 | } |
michael@0 | 186 | return StyleStateFromLocks(); |
michael@0 | 187 | } |
michael@0 | 188 | |
michael@0 | 189 | /** |
michael@0 | 190 | * The style state locks applied to this element. |
michael@0 | 191 | */ |
michael@0 | 192 | EventStates LockedStyleStates() const; |
michael@0 | 193 | |
michael@0 | 194 | /** |
michael@0 | 195 | * Add a style state lock on this element. |
michael@0 | 196 | */ |
michael@0 | 197 | void LockStyleStates(EventStates aStates); |
michael@0 | 198 | |
michael@0 | 199 | /** |
michael@0 | 200 | * Remove a style state lock on this element. |
michael@0 | 201 | */ |
michael@0 | 202 | void UnlockStyleStates(EventStates aStates); |
michael@0 | 203 | |
michael@0 | 204 | /** |
michael@0 | 205 | * Clear all style state locks on this element. |
michael@0 | 206 | */ |
michael@0 | 207 | void ClearStyleStateLocks(); |
michael@0 | 208 | |
michael@0 | 209 | /** |
michael@0 | 210 | * Get the inline style rule, if any, for this element. |
michael@0 | 211 | */ |
michael@0 | 212 | virtual css::StyleRule* GetInlineStyleRule(); |
michael@0 | 213 | |
michael@0 | 214 | /** |
michael@0 | 215 | * Set the inline style rule for this element. This will send an appropriate |
michael@0 | 216 | * AttributeChanged notification if aNotify is true. |
michael@0 | 217 | */ |
michael@0 | 218 | virtual nsresult SetInlineStyleRule(css::StyleRule* aStyleRule, |
michael@0 | 219 | const nsAString* aSerialized, |
michael@0 | 220 | bool aNotify); |
michael@0 | 221 | |
michael@0 | 222 | /** |
michael@0 | 223 | * Get the SMIL override style rule for this element. If the rule hasn't been |
michael@0 | 224 | * created, this method simply returns null. |
michael@0 | 225 | */ |
michael@0 | 226 | virtual css::StyleRule* GetSMILOverrideStyleRule(); |
michael@0 | 227 | |
michael@0 | 228 | /** |
michael@0 | 229 | * Set the SMIL override style rule for this element. If aNotify is true, this |
michael@0 | 230 | * method will notify the document's pres context, so that the style changes |
michael@0 | 231 | * will be noticed. |
michael@0 | 232 | */ |
michael@0 | 233 | virtual nsresult SetSMILOverrideStyleRule(css::StyleRule* aStyleRule, |
michael@0 | 234 | bool aNotify); |
michael@0 | 235 | |
michael@0 | 236 | /** |
michael@0 | 237 | * Returns a new nsISMILAttr that allows the caller to animate the given |
michael@0 | 238 | * attribute on this element. |
michael@0 | 239 | * |
michael@0 | 240 | * The CALLER OWNS the result and is responsible for deleting it. |
michael@0 | 241 | */ |
michael@0 | 242 | virtual nsISMILAttr* GetAnimatedAttr(int32_t aNamespaceID, nsIAtom* aName) |
michael@0 | 243 | { |
michael@0 | 244 | return nullptr; |
michael@0 | 245 | } |
michael@0 | 246 | |
michael@0 | 247 | /** |
michael@0 | 248 | * Get the SMIL override style for this element. This is a style declaration |
michael@0 | 249 | * that is applied *after* the inline style, and it can be used e.g. to store |
michael@0 | 250 | * animated style values. |
michael@0 | 251 | * |
michael@0 | 252 | * Note: This method is analogous to the 'GetStyle' method in |
michael@0 | 253 | * nsGenericHTMLElement and nsStyledElement. |
michael@0 | 254 | */ |
michael@0 | 255 | virtual nsICSSDeclaration* GetSMILOverrideStyle(); |
michael@0 | 256 | |
michael@0 | 257 | /** |
michael@0 | 258 | * Returns if the element is labelable as per HTML specification. |
michael@0 | 259 | */ |
michael@0 | 260 | virtual bool IsLabelable() const; |
michael@0 | 261 | |
michael@0 | 262 | /** |
michael@0 | 263 | * Is the attribute named stored in the mapped attributes? |
michael@0 | 264 | * |
michael@0 | 265 | * // XXXbz we use this method in HasAttributeDependentStyle, so svg |
michael@0 | 266 | * returns true here even though it stores nothing in the mapped |
michael@0 | 267 | * attributes. |
michael@0 | 268 | */ |
michael@0 | 269 | NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; |
michael@0 | 270 | |
michael@0 | 271 | /** |
michael@0 | 272 | * Get a hint that tells the style system what to do when |
michael@0 | 273 | * an attribute on this node changes, if something needs to happen |
michael@0 | 274 | * in response to the change *other* than the result of what is |
michael@0 | 275 | * mapped into style data via any type of style rule. |
michael@0 | 276 | */ |
michael@0 | 277 | virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, |
michael@0 | 278 | int32_t aModType) const; |
michael@0 | 279 | |
michael@0 | 280 | /** |
michael@0 | 281 | * Returns an atom holding the name of the "class" attribute on this |
michael@0 | 282 | * content node (if applicable). Returns null if there is no |
michael@0 | 283 | * "class" attribute for this type of content node. |
michael@0 | 284 | */ |
michael@0 | 285 | virtual nsIAtom *GetClassAttributeName() const; |
michael@0 | 286 | |
michael@0 | 287 | inline Directionality GetDirectionality() const { |
michael@0 | 288 | if (HasFlag(NODE_HAS_DIRECTION_RTL)) { |
michael@0 | 289 | return eDir_RTL; |
michael@0 | 290 | } |
michael@0 | 291 | |
michael@0 | 292 | if (HasFlag(NODE_HAS_DIRECTION_LTR)) { |
michael@0 | 293 | return eDir_LTR; |
michael@0 | 294 | } |
michael@0 | 295 | |
michael@0 | 296 | return eDir_NotSet; |
michael@0 | 297 | } |
michael@0 | 298 | |
michael@0 | 299 | inline void SetDirectionality(Directionality aDir, bool aNotify) { |
michael@0 | 300 | UnsetFlags(NODE_ALL_DIRECTION_FLAGS); |
michael@0 | 301 | if (!aNotify) { |
michael@0 | 302 | RemoveStatesSilently(DIRECTION_STATES); |
michael@0 | 303 | } |
michael@0 | 304 | |
michael@0 | 305 | switch (aDir) { |
michael@0 | 306 | case (eDir_RTL): |
michael@0 | 307 | SetFlags(NODE_HAS_DIRECTION_RTL); |
michael@0 | 308 | if (!aNotify) { |
michael@0 | 309 | AddStatesSilently(NS_EVENT_STATE_RTL); |
michael@0 | 310 | } |
michael@0 | 311 | break; |
michael@0 | 312 | |
michael@0 | 313 | case(eDir_LTR): |
michael@0 | 314 | SetFlags(NODE_HAS_DIRECTION_LTR); |
michael@0 | 315 | if (!aNotify) { |
michael@0 | 316 | AddStatesSilently(NS_EVENT_STATE_LTR); |
michael@0 | 317 | } |
michael@0 | 318 | break; |
michael@0 | 319 | |
michael@0 | 320 | default: |
michael@0 | 321 | break; |
michael@0 | 322 | } |
michael@0 | 323 | |
michael@0 | 324 | /* |
michael@0 | 325 | * Only call UpdateState if we need to notify, because we call |
michael@0 | 326 | * SetDirectionality for every element, and UpdateState is very very slow |
michael@0 | 327 | * for some elements. |
michael@0 | 328 | */ |
michael@0 | 329 | if (aNotify) { |
michael@0 | 330 | UpdateState(true); |
michael@0 | 331 | } |
michael@0 | 332 | } |
michael@0 | 333 | |
michael@0 | 334 | bool GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult); |
michael@0 | 335 | |
michael@0 | 336 | // The bdi element defaults to dir=auto if it has no dir attribute set. |
michael@0 | 337 | // Other elements will only have dir=auto if they have an explicit dir=auto, |
michael@0 | 338 | // which will mean that HasValidDir() returns true but HasFixedDir() returns |
michael@0 | 339 | // false |
michael@0 | 340 | inline bool HasDirAuto() const { |
michael@0 | 341 | return (!HasFixedDir() && |
michael@0 | 342 | (HasValidDir() || IsHTML(nsGkAtoms::bdi))); |
michael@0 | 343 | } |
michael@0 | 344 | |
michael@0 | 345 | Directionality GetComputedDirectionality() const; |
michael@0 | 346 | |
michael@0 | 347 | protected: |
michael@0 | 348 | /** |
michael@0 | 349 | * Method to get the _intrinsic_ content state of this element. This is the |
michael@0 | 350 | * state that is independent of the element's presentation. To get the full |
michael@0 | 351 | * content state, use State(). See mozilla/EventStates.h for |
michael@0 | 352 | * the possible bits that could be set here. |
michael@0 | 353 | */ |
michael@0 | 354 | virtual EventStates IntrinsicState() const; |
michael@0 | 355 | |
michael@0 | 356 | /** |
michael@0 | 357 | * Method to add state bits. This should be called from subclass |
michael@0 | 358 | * constructors to set up our event state correctly at construction |
michael@0 | 359 | * time and other places where we don't want to notify a state |
michael@0 | 360 | * change. |
michael@0 | 361 | */ |
michael@0 | 362 | void AddStatesSilently(EventStates aStates) |
michael@0 | 363 | { |
michael@0 | 364 | mState |= aStates; |
michael@0 | 365 | } |
michael@0 | 366 | |
michael@0 | 367 | /** |
michael@0 | 368 | * Method to remove state bits. This should be called from subclass |
michael@0 | 369 | * constructors to set up our event state correctly at construction |
michael@0 | 370 | * time and other places where we don't want to notify a state |
michael@0 | 371 | * change. |
michael@0 | 372 | */ |
michael@0 | 373 | void RemoveStatesSilently(EventStates aStates) |
michael@0 | 374 | { |
michael@0 | 375 | mState &= ~aStates; |
michael@0 | 376 | } |
michael@0 | 377 | |
michael@0 | 378 | private: |
michael@0 | 379 | // Need to allow the ESM, nsGlobalWindow, and the focus manager to |
michael@0 | 380 | // set our state |
michael@0 | 381 | friend class mozilla::EventStateManager; |
michael@0 | 382 | friend class ::nsGlobalWindow; |
michael@0 | 383 | friend class ::nsFocusManager; |
michael@0 | 384 | |
michael@0 | 385 | // Also need to allow Link to call UpdateLinkState. |
michael@0 | 386 | friend class Link; |
michael@0 | 387 | |
michael@0 | 388 | void NotifyStateChange(EventStates aStates); |
michael@0 | 389 | |
michael@0 | 390 | void NotifyStyleStateChange(EventStates aStates); |
michael@0 | 391 | |
michael@0 | 392 | // Style state computed from element's state and style locks. |
michael@0 | 393 | EventStates StyleStateFromLocks() const; |
michael@0 | 394 | |
michael@0 | 395 | protected: |
michael@0 | 396 | // Methods for the ESM to manage state bits. These will handle |
michael@0 | 397 | // setting up script blockers when they notify, so no need to do it |
michael@0 | 398 | // in the callers unless desired. |
michael@0 | 399 | virtual void AddStates(EventStates aStates) |
michael@0 | 400 | { |
michael@0 | 401 | NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), |
michael@0 | 402 | "Should only be adding ESM-managed states here"); |
michael@0 | 403 | AddStatesSilently(aStates); |
michael@0 | 404 | NotifyStateChange(aStates); |
michael@0 | 405 | } |
michael@0 | 406 | virtual void RemoveStates(EventStates aStates) |
michael@0 | 407 | { |
michael@0 | 408 | NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), |
michael@0 | 409 | "Should only be removing ESM-managed states here"); |
michael@0 | 410 | RemoveStatesSilently(aStates); |
michael@0 | 411 | NotifyStateChange(aStates); |
michael@0 | 412 | } |
michael@0 | 413 | public: |
michael@0 | 414 | virtual void UpdateEditableState(bool aNotify) MOZ_OVERRIDE; |
michael@0 | 415 | |
michael@0 | 416 | virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, |
michael@0 | 417 | nsIContent* aBindingParent, |
michael@0 | 418 | bool aCompileEventHandlers) MOZ_OVERRIDE; |
michael@0 | 419 | virtual void UnbindFromTree(bool aDeep = true, |
michael@0 | 420 | bool aNullParent = true) MOZ_OVERRIDE; |
michael@0 | 421 | |
michael@0 | 422 | /** |
michael@0 | 423 | * Normalizes an attribute name and returns it as a nodeinfo if an attribute |
michael@0 | 424 | * with that name exists. This method is intended for character case |
michael@0 | 425 | * conversion if the content object is case insensitive (e.g. HTML). Returns |
michael@0 | 426 | * the nodeinfo of the attribute with the specified name if one exists or |
michael@0 | 427 | * null otherwise. |
michael@0 | 428 | * |
michael@0 | 429 | * @param aStr the unparsed attribute string |
michael@0 | 430 | * @return the node info. May be nullptr. |
michael@0 | 431 | */ |
michael@0 | 432 | already_AddRefed<nsINodeInfo> |
michael@0 | 433 | GetExistingAttrNameFromQName(const nsAString& aStr) const; |
michael@0 | 434 | |
michael@0 | 435 | nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, |
michael@0 | 436 | const nsAString& aValue, bool aNotify) |
michael@0 | 437 | { |
michael@0 | 438 | return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify); |
michael@0 | 439 | } |
michael@0 | 440 | |
michael@0 | 441 | /** |
michael@0 | 442 | * Helper for SetAttr/SetParsedAttr. This method will return true if aNotify |
michael@0 | 443 | * is true or there are mutation listeners that must be triggered, the |
michael@0 | 444 | * attribute is currently set, and the new value that is about to be set is |
michael@0 | 445 | * different to the current value. As a perf optimization the new and old |
michael@0 | 446 | * values will not actually be compared if we aren't notifying and we don't |
michael@0 | 447 | * have mutation listeners (in which case it's cheap to just return false |
michael@0 | 448 | * and let the caller go ahead and set the value). |
michael@0 | 449 | * @param aOldValue Set to the old value of the attribute, but only if there |
michael@0 | 450 | * are event listeners. If set, the type of aOldValue will be either |
michael@0 | 451 | * nsAttrValue::eString or nsAttrValue::eAtom. |
michael@0 | 452 | * @param aModType Set to nsIDOMMutationEvent::MODIFICATION or to |
michael@0 | 453 | * nsIDOMMutationEvent::ADDITION, but only if this helper returns true |
michael@0 | 454 | * @param aHasListeners Set to true if there are mutation event listeners |
michael@0 | 455 | * listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED |
michael@0 | 456 | */ |
michael@0 | 457 | bool MaybeCheckSameAttrVal(int32_t aNamespaceID, nsIAtom* aName, |
michael@0 | 458 | nsIAtom* aPrefix, |
michael@0 | 459 | const nsAttrValueOrString& aValue, |
michael@0 | 460 | bool aNotify, nsAttrValue& aOldValue, |
michael@0 | 461 | uint8_t* aModType, bool* aHasListeners); |
michael@0 | 462 | |
michael@0 | 463 | bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName, |
michael@0 | 464 | nsIAtom* aPrefix, |
michael@0 | 465 | const nsAttrValueOrString& aValue, |
michael@0 | 466 | bool aNotify, nsAttrValue& aOldValue, |
michael@0 | 467 | uint8_t* aModType, bool* aHasListeners); |
michael@0 | 468 | |
michael@0 | 469 | virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, |
michael@0 | 470 | const nsAString& aValue, bool aNotify) MOZ_OVERRIDE; |
michael@0 | 471 | nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, |
michael@0 | 472 | nsAttrValue& aParsedValue, bool aNotify); |
michael@0 | 473 | // GetAttr is not inlined on purpose, to keep down codesize from all |
michael@0 | 474 | // the inlined nsAttrValue bits for C++ callers. |
michael@0 | 475 | bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName, |
michael@0 | 476 | nsAString& aResult) const; |
michael@0 | 477 | inline bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const; |
michael@0 | 478 | // aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching. |
michael@0 | 479 | inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName, |
michael@0 | 480 | const nsAString& aValue, |
michael@0 | 481 | nsCaseTreatment aCaseSensitive) const; |
michael@0 | 482 | inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName, |
michael@0 | 483 | nsIAtom* aValue, |
michael@0 | 484 | nsCaseTreatment aCaseSensitive) const; |
michael@0 | 485 | virtual int32_t FindAttrValueIn(int32_t aNameSpaceID, |
michael@0 | 486 | nsIAtom* aName, |
michael@0 | 487 | AttrValuesArray* aValues, |
michael@0 | 488 | nsCaseTreatment aCaseSensitive) const MOZ_OVERRIDE; |
michael@0 | 489 | virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, |
michael@0 | 490 | bool aNotify) MOZ_OVERRIDE; |
michael@0 | 491 | virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const MOZ_OVERRIDE; |
michael@0 | 492 | virtual uint32_t GetAttrCount() const MOZ_OVERRIDE; |
michael@0 | 493 | virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE; |
michael@0 | 494 | |
michael@0 | 495 | #ifdef DEBUG |
michael@0 | 496 | virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE |
michael@0 | 497 | { |
michael@0 | 498 | List(out, aIndent, EmptyCString()); |
michael@0 | 499 | } |
michael@0 | 500 | virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const MOZ_OVERRIDE; |
michael@0 | 501 | void List(FILE* out, int32_t aIndent, const nsCString& aPrefix) const; |
michael@0 | 502 | void ListAttributes(FILE* out) const; |
michael@0 | 503 | #endif |
michael@0 | 504 | |
michael@0 | 505 | void Describe(nsAString& aOutDescription) const MOZ_OVERRIDE; |
michael@0 | 506 | |
michael@0 | 507 | /* |
michael@0 | 508 | * Attribute Mapping Helpers |
michael@0 | 509 | */ |
michael@0 | 510 | struct MappedAttributeEntry { |
michael@0 | 511 | nsIAtom** attribute; |
michael@0 | 512 | }; |
michael@0 | 513 | |
michael@0 | 514 | /** |
michael@0 | 515 | * A common method where you can just pass in a list of maps to check |
michael@0 | 516 | * for attribute dependence. Most implementations of |
michael@0 | 517 | * IsAttributeMapped should use this function as a default |
michael@0 | 518 | * handler. |
michael@0 | 519 | */ |
michael@0 | 520 | template<size_t N> |
michael@0 | 521 | static bool |
michael@0 | 522 | FindAttributeDependence(const nsIAtom* aAttribute, |
michael@0 | 523 | const MappedAttributeEntry* const (&aMaps)[N]) |
michael@0 | 524 | { |
michael@0 | 525 | return FindAttributeDependence(aAttribute, aMaps, N); |
michael@0 | 526 | } |
michael@0 | 527 | |
michael@0 | 528 | private: |
michael@0 | 529 | void DescribeAttribute(uint32_t index, nsAString& aOutDescription) const; |
michael@0 | 530 | |
michael@0 | 531 | static bool |
michael@0 | 532 | FindAttributeDependence(const nsIAtom* aAttribute, |
michael@0 | 533 | const MappedAttributeEntry* const aMaps[], |
michael@0 | 534 | uint32_t aMapCount); |
michael@0 | 535 | |
michael@0 | 536 | protected: |
michael@0 | 537 | inline bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName, |
michael@0 | 538 | DOMString& aResult) const |
michael@0 | 539 | { |
michael@0 | 540 | NS_ASSERTION(nullptr != aName, "must have attribute name"); |
michael@0 | 541 | NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, |
michael@0 | 542 | "must have a real namespace ID!"); |
michael@0 | 543 | MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0, |
michael@0 | 544 | "Should have empty string coming in"); |
michael@0 | 545 | const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID); |
michael@0 | 546 | if (val) { |
michael@0 | 547 | val->ToString(aResult); |
michael@0 | 548 | return true; |
michael@0 | 549 | } |
michael@0 | 550 | // else DOMString comes pre-emptied. |
michael@0 | 551 | return false; |
michael@0 | 552 | } |
michael@0 | 553 | |
michael@0 | 554 | public: |
michael@0 | 555 | bool HasAttrs() const { return mAttrsAndChildren.HasAttrs(); } |
michael@0 | 556 | |
michael@0 | 557 | inline bool GetAttr(const nsAString& aName, DOMString& aResult) const |
michael@0 | 558 | { |
michael@0 | 559 | MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0, |
michael@0 | 560 | "Should have empty string coming in"); |
michael@0 | 561 | const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName); |
michael@0 | 562 | if (val) { |
michael@0 | 563 | val->ToString(aResult); |
michael@0 | 564 | return true; |
michael@0 | 565 | } |
michael@0 | 566 | // else DOMString comes pre-emptied. |
michael@0 | 567 | return false; |
michael@0 | 568 | } |
michael@0 | 569 | |
michael@0 | 570 | void GetTagName(nsAString& aTagName) const |
michael@0 | 571 | { |
michael@0 | 572 | aTagName = NodeName(); |
michael@0 | 573 | } |
michael@0 | 574 | void GetId(nsAString& aId) const |
michael@0 | 575 | { |
michael@0 | 576 | GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId); |
michael@0 | 577 | } |
michael@0 | 578 | void GetId(DOMString& aId) const |
michael@0 | 579 | { |
michael@0 | 580 | GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId); |
michael@0 | 581 | } |
michael@0 | 582 | void SetId(const nsAString& aId) |
michael@0 | 583 | { |
michael@0 | 584 | SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true); |
michael@0 | 585 | } |
michael@0 | 586 | |
michael@0 | 587 | nsDOMTokenList* GetClassList(); |
michael@0 | 588 | nsDOMAttributeMap* Attributes() |
michael@0 | 589 | { |
michael@0 | 590 | nsDOMSlots* slots = DOMSlots(); |
michael@0 | 591 | if (!slots->mAttributeMap) { |
michael@0 | 592 | slots->mAttributeMap = new nsDOMAttributeMap(this); |
michael@0 | 593 | } |
michael@0 | 594 | |
michael@0 | 595 | return slots->mAttributeMap; |
michael@0 | 596 | } |
michael@0 | 597 | void GetAttribute(const nsAString& aName, nsString& aReturn) |
michael@0 | 598 | { |
michael@0 | 599 | DOMString str; |
michael@0 | 600 | GetAttribute(aName, str); |
michael@0 | 601 | str.ToString(aReturn); |
michael@0 | 602 | } |
michael@0 | 603 | |
michael@0 | 604 | void GetAttribute(const nsAString& aName, DOMString& aReturn); |
michael@0 | 605 | void GetAttributeNS(const nsAString& aNamespaceURI, |
michael@0 | 606 | const nsAString& aLocalName, |
michael@0 | 607 | nsAString& aReturn); |
michael@0 | 608 | void SetAttribute(const nsAString& aName, const nsAString& aValue, |
michael@0 | 609 | ErrorResult& aError); |
michael@0 | 610 | void SetAttributeNS(const nsAString& aNamespaceURI, |
michael@0 | 611 | const nsAString& aLocalName, |
michael@0 | 612 | const nsAString& aValue, |
michael@0 | 613 | ErrorResult& aError); |
michael@0 | 614 | void RemoveAttribute(const nsAString& aName, |
michael@0 | 615 | ErrorResult& aError); |
michael@0 | 616 | void RemoveAttributeNS(const nsAString& aNamespaceURI, |
michael@0 | 617 | const nsAString& aLocalName, |
michael@0 | 618 | ErrorResult& aError); |
michael@0 | 619 | bool HasAttribute(const nsAString& aName) const |
michael@0 | 620 | { |
michael@0 | 621 | return InternalGetExistingAttrNameFromQName(aName) != nullptr; |
michael@0 | 622 | } |
michael@0 | 623 | bool HasAttributeNS(const nsAString& aNamespaceURI, |
michael@0 | 624 | const nsAString& aLocalName) const; |
michael@0 | 625 | already_AddRefed<nsIHTMLCollection> |
michael@0 | 626 | GetElementsByTagName(const nsAString& aQualifiedName); |
michael@0 | 627 | already_AddRefed<nsIHTMLCollection> |
michael@0 | 628 | GetElementsByTagNameNS(const nsAString& aNamespaceURI, |
michael@0 | 629 | const nsAString& aLocalName, |
michael@0 | 630 | ErrorResult& aError); |
michael@0 | 631 | already_AddRefed<nsIHTMLCollection> |
michael@0 | 632 | GetElementsByClassName(const nsAString& aClassNames); |
michael@0 | 633 | bool MozMatchesSelector(const nsAString& aSelector, |
michael@0 | 634 | ErrorResult& aError); |
michael@0 | 635 | void SetPointerCapture(int32_t aPointerId, ErrorResult& aError) |
michael@0 | 636 | { |
michael@0 | 637 | bool activeState = false; |
michael@0 | 638 | if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) { |
michael@0 | 639 | aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR); |
michael@0 | 640 | return; |
michael@0 | 641 | } |
michael@0 | 642 | if (!activeState) { |
michael@0 | 643 | return; |
michael@0 | 644 | } |
michael@0 | 645 | nsIPresShell::SetPointerCapturingContent(aPointerId, this); |
michael@0 | 646 | } |
michael@0 | 647 | void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError) |
michael@0 | 648 | { |
michael@0 | 649 | bool activeState = false; |
michael@0 | 650 | if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) { |
michael@0 | 651 | aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR); |
michael@0 | 652 | return; |
michael@0 | 653 | } |
michael@0 | 654 | |
michael@0 | 655 | // Ignoring ReleasePointerCapture call on incorrect element (on element |
michael@0 | 656 | // that didn't have capture before). |
michael@0 | 657 | if (nsIPresShell::GetPointerCapturingContent(aPointerId) == this) { |
michael@0 | 658 | nsIPresShell::ReleasePointerCapturingContent(aPointerId, this); |
michael@0 | 659 | } |
michael@0 | 660 | } |
michael@0 | 661 | void SetCapture(bool aRetargetToElement) |
michael@0 | 662 | { |
michael@0 | 663 | // If there is already an active capture, ignore this request. This would |
michael@0 | 664 | // occur if a splitter, frame resizer, etc had already captured and we don't |
michael@0 | 665 | // want to override those. |
michael@0 | 666 | if (!nsIPresShell::GetCapturingContent()) { |
michael@0 | 667 | nsIPresShell::SetCapturingContent(this, CAPTURE_PREVENTDRAG | |
michael@0 | 668 | (aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0)); |
michael@0 | 669 | } |
michael@0 | 670 | } |
michael@0 | 671 | void ReleaseCapture() |
michael@0 | 672 | { |
michael@0 | 673 | if (nsIPresShell::GetCapturingContent() == this) { |
michael@0 | 674 | nsIPresShell::SetCapturingContent(nullptr, 0); |
michael@0 | 675 | } |
michael@0 | 676 | } |
michael@0 | 677 | void MozRequestFullScreen(); |
michael@0 | 678 | void MozRequestPointerLock(); |
michael@0 | 679 | Attr* GetAttributeNode(const nsAString& aName); |
michael@0 | 680 | already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr, |
michael@0 | 681 | ErrorResult& aError); |
michael@0 | 682 | already_AddRefed<Attr> RemoveAttributeNode(Attr& aOldAttr, |
michael@0 | 683 | ErrorResult& aError); |
michael@0 | 684 | Attr* GetAttributeNodeNS(const nsAString& aNamespaceURI, |
michael@0 | 685 | const nsAString& aLocalName); |
michael@0 | 686 | already_AddRefed<Attr> SetAttributeNodeNS(Attr& aNewAttr, |
michael@0 | 687 | ErrorResult& aError); |
michael@0 | 688 | |
michael@0 | 689 | already_AddRefed<DOMRectList> GetClientRects(); |
michael@0 | 690 | already_AddRefed<DOMRect> GetBoundingClientRect(); |
michael@0 | 691 | |
michael@0 | 692 | already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError); |
michael@0 | 693 | |
michael@0 | 694 | void ScrollIntoView() |
michael@0 | 695 | { |
michael@0 | 696 | ScrollIntoView(true); |
michael@0 | 697 | } |
michael@0 | 698 | void ScrollIntoView(bool aTop); |
michael@0 | 699 | int32_t ScrollTop() |
michael@0 | 700 | { |
michael@0 | 701 | nsIScrollableFrame* sf = GetScrollFrame(); |
michael@0 | 702 | return sf ? sf->GetScrollPositionCSSPixels().y : 0; |
michael@0 | 703 | } |
michael@0 | 704 | void SetScrollTop(int32_t aScrollTop) |
michael@0 | 705 | { |
michael@0 | 706 | nsIScrollableFrame* sf = GetScrollFrame(); |
michael@0 | 707 | if (sf) { |
michael@0 | 708 | sf->ScrollToCSSPixels(CSSIntPoint(sf->GetScrollPositionCSSPixels().x, |
michael@0 | 709 | aScrollTop)); |
michael@0 | 710 | } |
michael@0 | 711 | } |
michael@0 | 712 | int32_t ScrollLeft() |
michael@0 | 713 | { |
michael@0 | 714 | nsIScrollableFrame* sf = GetScrollFrame(); |
michael@0 | 715 | return sf ? sf->GetScrollPositionCSSPixels().x : 0; |
michael@0 | 716 | } |
michael@0 | 717 | void SetScrollLeft(int32_t aScrollLeft) |
michael@0 | 718 | { |
michael@0 | 719 | nsIScrollableFrame* sf = GetScrollFrame(); |
michael@0 | 720 | if (sf) { |
michael@0 | 721 | sf->ScrollToCSSPixels(CSSIntPoint(aScrollLeft, |
michael@0 | 722 | sf->GetScrollPositionCSSPixels().y)); |
michael@0 | 723 | } |
michael@0 | 724 | } |
michael@0 | 725 | /* Scrolls without flushing the layout. |
michael@0 | 726 | * aDx is the x offset, aDy the y offset in CSS pixels. |
michael@0 | 727 | * Returns true if we actually scrolled. |
michael@0 | 728 | */ |
michael@0 | 729 | bool ScrollByNoFlush(int32_t aDx, int32_t aDy); |
michael@0 | 730 | int32_t ScrollWidth(); |
michael@0 | 731 | int32_t ScrollHeight(); |
michael@0 | 732 | int32_t ClientTop() |
michael@0 | 733 | { |
michael@0 | 734 | return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y); |
michael@0 | 735 | } |
michael@0 | 736 | int32_t ClientLeft() |
michael@0 | 737 | { |
michael@0 | 738 | return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x); |
michael@0 | 739 | } |
michael@0 | 740 | int32_t ClientWidth() |
michael@0 | 741 | { |
michael@0 | 742 | return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width); |
michael@0 | 743 | } |
michael@0 | 744 | int32_t ClientHeight() |
michael@0 | 745 | { |
michael@0 | 746 | return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height); |
michael@0 | 747 | } |
michael@0 | 748 | int32_t ScrollTopMax() |
michael@0 | 749 | { |
michael@0 | 750 | nsIScrollableFrame* sf = GetScrollFrame(); |
michael@0 | 751 | return sf ? |
michael@0 | 752 | nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().YMost()) : |
michael@0 | 753 | 0; |
michael@0 | 754 | } |
michael@0 | 755 | int32_t ScrollLeftMax() |
michael@0 | 756 | { |
michael@0 | 757 | nsIScrollableFrame* sf = GetScrollFrame(); |
michael@0 | 758 | return sf ? |
michael@0 | 759 | nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().XMost()) : |
michael@0 | 760 | 0; |
michael@0 | 761 | } |
michael@0 | 762 | |
michael@0 | 763 | virtual already_AddRefed<UndoManager> GetUndoManager() |
michael@0 | 764 | { |
michael@0 | 765 | return nullptr; |
michael@0 | 766 | } |
michael@0 | 767 | |
michael@0 | 768 | virtual bool UndoScope() |
michael@0 | 769 | { |
michael@0 | 770 | return false; |
michael@0 | 771 | } |
michael@0 | 772 | |
michael@0 | 773 | virtual void SetUndoScope(bool aUndoScope, ErrorResult& aError) |
michael@0 | 774 | { |
michael@0 | 775 | } |
michael@0 | 776 | |
michael@0 | 777 | NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML); |
michael@0 | 778 | virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError); |
michael@0 | 779 | void GetOuterHTML(nsAString& aOuterHTML); |
michael@0 | 780 | void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError); |
michael@0 | 781 | void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText, |
michael@0 | 782 | ErrorResult& aError); |
michael@0 | 783 | |
michael@0 | 784 | //---------------------------------------- |
michael@0 | 785 | |
michael@0 | 786 | /** |
michael@0 | 787 | * Add a script event listener with the given event handler name |
michael@0 | 788 | * (like onclick) and with the value as JS |
michael@0 | 789 | * @param aEventName the event listener name |
michael@0 | 790 | * @param aValue the JS to attach |
michael@0 | 791 | * @param aDefer indicates if deferred execution is allowed |
michael@0 | 792 | */ |
michael@0 | 793 | nsresult SetEventHandler(nsIAtom* aEventName, |
michael@0 | 794 | const nsAString& aValue, |
michael@0 | 795 | bool aDefer = true); |
michael@0 | 796 | |
michael@0 | 797 | /** |
michael@0 | 798 | * Do whatever needs to be done when the mouse leaves a link |
michael@0 | 799 | */ |
michael@0 | 800 | nsresult LeaveLink(nsPresContext* aPresContext); |
michael@0 | 801 | |
michael@0 | 802 | static bool ShouldBlur(nsIContent *aContent); |
michael@0 | 803 | |
michael@0 | 804 | /** |
michael@0 | 805 | * Method to create and dispatch a left-click event loosely based on |
michael@0 | 806 | * aSourceEvent. If aFullDispatch is true, the event will be dispatched |
michael@0 | 807 | * through the full dispatching of the presshell of the aPresContext; if it's |
michael@0 | 808 | * false the event will be dispatched only as a DOM event. |
michael@0 | 809 | * If aPresContext is nullptr, this does nothing. |
michael@0 | 810 | * |
michael@0 | 811 | * @param aFlags Extra flags for the dispatching event. The true flags |
michael@0 | 812 | * will be respected. |
michael@0 | 813 | */ |
michael@0 | 814 | static nsresult DispatchClickEvent(nsPresContext* aPresContext, |
michael@0 | 815 | WidgetInputEvent* aSourceEvent, |
michael@0 | 816 | nsIContent* aTarget, |
michael@0 | 817 | bool aFullDispatch, |
michael@0 | 818 | const EventFlags* aFlags, |
michael@0 | 819 | nsEventStatus* aStatus); |
michael@0 | 820 | |
michael@0 | 821 | /** |
michael@0 | 822 | * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event |
michael@0 | 823 | * will be dispatched through the full dispatching of the presshell of the |
michael@0 | 824 | * aPresContext; if it's false the event will be dispatched only as a DOM |
michael@0 | 825 | * event. |
michael@0 | 826 | * If aPresContext is nullptr, this does nothing. |
michael@0 | 827 | */ |
michael@0 | 828 | using nsIContent::DispatchEvent; |
michael@0 | 829 | static nsresult DispatchEvent(nsPresContext* aPresContext, |
michael@0 | 830 | WidgetEvent* aEvent, |
michael@0 | 831 | nsIContent* aTarget, |
michael@0 | 832 | bool aFullDispatch, |
michael@0 | 833 | nsEventStatus* aStatus); |
michael@0 | 834 | |
michael@0 | 835 | /** |
michael@0 | 836 | * Get the primary frame for this content with flushing |
michael@0 | 837 | * |
michael@0 | 838 | * @param aType the kind of flush to do, typically Flush_Frames or |
michael@0 | 839 | * Flush_Layout |
michael@0 | 840 | * @return the primary frame |
michael@0 | 841 | */ |
michael@0 | 842 | nsIFrame* GetPrimaryFrame(mozFlushType aType); |
michael@0 | 843 | // Work around silly C++ name hiding stuff |
michael@0 | 844 | nsIFrame* GetPrimaryFrame() const { return nsIContent::GetPrimaryFrame(); } |
michael@0 | 845 | |
michael@0 | 846 | /** |
michael@0 | 847 | * Struct that stores info on an attribute. The name and value must |
michael@0 | 848 | * either both be null or both be non-null. |
michael@0 | 849 | */ |
michael@0 | 850 | struct nsAttrInfo { |
michael@0 | 851 | nsAttrInfo(const nsAttrName* aName, const nsAttrValue* aValue) : |
michael@0 | 852 | mName(aName), mValue(aValue) {} |
michael@0 | 853 | nsAttrInfo(const nsAttrInfo& aOther) : |
michael@0 | 854 | mName(aOther.mName), mValue(aOther.mValue) {} |
michael@0 | 855 | |
michael@0 | 856 | const nsAttrName* mName; |
michael@0 | 857 | const nsAttrValue* mValue; |
michael@0 | 858 | }; |
michael@0 | 859 | |
michael@0 | 860 | // Be careful when using this method. This does *NOT* handle |
michael@0 | 861 | // XUL prototypes. You may want to use GetAttrInfo. |
michael@0 | 862 | const nsAttrValue* GetParsedAttr(nsIAtom* aAttr) const |
michael@0 | 863 | { |
michael@0 | 864 | return mAttrsAndChildren.GetAttr(aAttr); |
michael@0 | 865 | } |
michael@0 | 866 | |
michael@0 | 867 | /** |
michael@0 | 868 | * Returns the attribute map, if there is one. |
michael@0 | 869 | * |
michael@0 | 870 | * @return existing attribute map or nullptr. |
michael@0 | 871 | */ |
michael@0 | 872 | nsDOMAttributeMap *GetAttributeMap() |
michael@0 | 873 | { |
michael@0 | 874 | nsDOMSlots *slots = GetExistingDOMSlots(); |
michael@0 | 875 | |
michael@0 | 876 | return slots ? slots->mAttributeMap.get() : nullptr; |
michael@0 | 877 | } |
michael@0 | 878 | |
michael@0 | 879 | virtual void RecompileScriptEventListeners() |
michael@0 | 880 | { |
michael@0 | 881 | } |
michael@0 | 882 | |
michael@0 | 883 | /** |
michael@0 | 884 | * Get the attr info for the given namespace ID and attribute name. The |
michael@0 | 885 | * namespace ID must not be kNameSpaceID_Unknown and the name must not be |
michael@0 | 886 | * null. Note that this can only return info on attributes that actually |
michael@0 | 887 | * live on this element (and is only virtual to handle XUL prototypes). That |
michael@0 | 888 | * is, this should only be called from methods that only care about attrs |
michael@0 | 889 | * that effectively live in mAttrsAndChildren. |
michael@0 | 890 | */ |
michael@0 | 891 | virtual nsAttrInfo GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const; |
michael@0 | 892 | |
michael@0 | 893 | virtual void NodeInfoChanged(nsINodeInfo* aOldNodeInfo) |
michael@0 | 894 | { |
michael@0 | 895 | } |
michael@0 | 896 | |
michael@0 | 897 | /** |
michael@0 | 898 | * Parse a string into an nsAttrValue for a CORS attribute. This |
michael@0 | 899 | * never fails. The resulting value is an enumerated value whose |
michael@0 | 900 | * GetEnumValue() returns one of the above constants. |
michael@0 | 901 | */ |
michael@0 | 902 | static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult); |
michael@0 | 903 | |
michael@0 | 904 | /** |
michael@0 | 905 | * Return the CORS mode for a given string |
michael@0 | 906 | */ |
michael@0 | 907 | static CORSMode StringToCORSMode(const nsAString& aValue); |
michael@0 | 908 | |
michael@0 | 909 | /** |
michael@0 | 910 | * Return the CORS mode for a given nsAttrValue (which may be null, |
michael@0 | 911 | * but if not should have been parsed via ParseCORSValue). |
michael@0 | 912 | */ |
michael@0 | 913 | static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue); |
michael@0 | 914 | |
michael@0 | 915 | // These are just used to implement nsIDOMElement using |
michael@0 | 916 | // NS_FORWARD_NSIDOMELEMENT_TO_GENERIC and for quickstubs. |
michael@0 | 917 | void |
michael@0 | 918 | GetElementsByTagName(const nsAString& aQualifiedName, |
michael@0 | 919 | nsIDOMHTMLCollection** aResult); |
michael@0 | 920 | nsresult |
michael@0 | 921 | GetElementsByTagNameNS(const nsAString& aNamespaceURI, |
michael@0 | 922 | const nsAString& aLocalName, |
michael@0 | 923 | nsIDOMHTMLCollection** aResult); |
michael@0 | 924 | nsresult |
michael@0 | 925 | GetElementsByClassName(const nsAString& aClassNames, |
michael@0 | 926 | nsIDOMHTMLCollection** aResult); |
michael@0 | 927 | void GetClassList(nsISupports** aClassList); |
michael@0 | 928 | |
michael@0 | 929 | virtual JSObject* WrapObject(JSContext *aCx) MOZ_FINAL MOZ_OVERRIDE; |
michael@0 | 930 | |
michael@0 | 931 | /** |
michael@0 | 932 | * Locate an nsIEditor rooted at this content node, if there is one. |
michael@0 | 933 | */ |
michael@0 | 934 | nsIEditor* GetEditorInternal(); |
michael@0 | 935 | |
michael@0 | 936 | /** |
michael@0 | 937 | * Helper method for NS_IMPL_BOOL_ATTR macro. |
michael@0 | 938 | * Gets value of boolean attribute. Only works for attributes in null |
michael@0 | 939 | * namespace. |
michael@0 | 940 | * |
michael@0 | 941 | * @param aAttr name of attribute. |
michael@0 | 942 | * @param aValue Boolean value of attribute. |
michael@0 | 943 | */ |
michael@0 | 944 | NS_HIDDEN_(bool) GetBoolAttr(nsIAtom* aAttr) const |
michael@0 | 945 | { |
michael@0 | 946 | return HasAttr(kNameSpaceID_None, aAttr); |
michael@0 | 947 | } |
michael@0 | 948 | |
michael@0 | 949 | /** |
michael@0 | 950 | * Helper method for NS_IMPL_BOOL_ATTR macro. |
michael@0 | 951 | * Sets value of boolean attribute by removing attribute or setting it to |
michael@0 | 952 | * the empty string. Only works for attributes in null namespace. |
michael@0 | 953 | * |
michael@0 | 954 | * @param aAttr name of attribute. |
michael@0 | 955 | * @param aValue Boolean value of attribute. |
michael@0 | 956 | */ |
michael@0 | 957 | NS_HIDDEN_(nsresult) SetBoolAttr(nsIAtom* aAttr, bool aValue); |
michael@0 | 958 | |
michael@0 | 959 | /** |
michael@0 | 960 | * Retrieve the ratio of font-size-inflated text font size to computed font |
michael@0 | 961 | * size for this element. This will query the element for its primary frame, |
michael@0 | 962 | * and then use this to get font size inflation information about the frame. |
michael@0 | 963 | * |
michael@0 | 964 | * @returns The font size inflation ratio (inflated font size to uninflated |
michael@0 | 965 | * font size) for the primary frame of this element. Returns 1.0 |
michael@0 | 966 | * by default if font size inflation is not enabled. Returns -1 |
michael@0 | 967 | * if the element does not have a primary frame. |
michael@0 | 968 | * |
michael@0 | 969 | * @note The font size inflation ratio that is returned is actually the |
michael@0 | 970 | * font size inflation data for the element's _primary frame_, not the |
michael@0 | 971 | * element itself, but for most purposes, this should be sufficient. |
michael@0 | 972 | */ |
michael@0 | 973 | float FontSizeInflation(); |
michael@0 | 974 | |
michael@0 | 975 | protected: |
michael@0 | 976 | /* |
michael@0 | 977 | * Named-bools for use with SetAttrAndNotify to make call sites easier to |
michael@0 | 978 | * read. |
michael@0 | 979 | */ |
michael@0 | 980 | static const bool kFireMutationEvent = true; |
michael@0 | 981 | static const bool kDontFireMutationEvent = false; |
michael@0 | 982 | static const bool kNotifyDocumentObservers = true; |
michael@0 | 983 | static const bool kDontNotifyDocumentObservers = false; |
michael@0 | 984 | static const bool kCallAfterSetAttr = true; |
michael@0 | 985 | static const bool kDontCallAfterSetAttr = false; |
michael@0 | 986 | |
michael@0 | 987 | /** |
michael@0 | 988 | * Set attribute and (if needed) notify documentobservers and fire off |
michael@0 | 989 | * mutation events. This will send the AttributeChanged notification. |
michael@0 | 990 | * Callers of this method are responsible for calling AttributeWillChange, |
michael@0 | 991 | * since that needs to happen before the new attr value has been set, and |
michael@0 | 992 | * in particular before it has been parsed. |
michael@0 | 993 | * |
michael@0 | 994 | * For the boolean parameters, consider using the named bools above to aid |
michael@0 | 995 | * code readability. |
michael@0 | 996 | * |
michael@0 | 997 | * @param aNamespaceID namespace of attribute |
michael@0 | 998 | * @param aAttribute local-name of attribute |
michael@0 | 999 | * @param aPrefix aPrefix of attribute |
michael@0 | 1000 | * @param aOldValue previous value of attribute. Only needed if |
michael@0 | 1001 | * aFireMutation is true or if the element is a |
michael@0 | 1002 | * custom element (in web components). |
michael@0 | 1003 | * @param aParsedValue parsed new value of attribute |
michael@0 | 1004 | * @param aModType nsIDOMMutationEvent::MODIFICATION or ADDITION. Only |
michael@0 | 1005 | * needed if aFireMutation or aNotify is true. |
michael@0 | 1006 | * @param aFireMutation should mutation-events be fired? |
michael@0 | 1007 | * @param aNotify should we notify document-observers? |
michael@0 | 1008 | * @param aCallAfterSetAttr should we call AfterSetAttr? |
michael@0 | 1009 | */ |
michael@0 | 1010 | nsresult SetAttrAndNotify(int32_t aNamespaceID, |
michael@0 | 1011 | nsIAtom* aName, |
michael@0 | 1012 | nsIAtom* aPrefix, |
michael@0 | 1013 | const nsAttrValue& aOldValue, |
michael@0 | 1014 | nsAttrValue& aParsedValue, |
michael@0 | 1015 | uint8_t aModType, |
michael@0 | 1016 | bool aFireMutation, |
michael@0 | 1017 | bool aNotify, |
michael@0 | 1018 | bool aCallAfterSetAttr); |
michael@0 | 1019 | |
michael@0 | 1020 | /** |
michael@0 | 1021 | * Convert an attribute string value to attribute type based on the type of |
michael@0 | 1022 | * attribute. Called by SetAttr(). Note that at the moment we only do this |
michael@0 | 1023 | * for attributes in the null namespace (kNameSpaceID_None). |
michael@0 | 1024 | * |
michael@0 | 1025 | * @param aNamespaceID the namespace of the attribute to convert |
michael@0 | 1026 | * @param aAttribute the attribute to convert |
michael@0 | 1027 | * @param aValue the string value to convert |
michael@0 | 1028 | * @param aResult the nsAttrValue [OUT] |
michael@0 | 1029 | * @return true if the parsing was successful, false otherwise |
michael@0 | 1030 | */ |
michael@0 | 1031 | virtual bool ParseAttribute(int32_t aNamespaceID, |
michael@0 | 1032 | nsIAtom* aAttribute, |
michael@0 | 1033 | const nsAString& aValue, |
michael@0 | 1034 | nsAttrValue& aResult); |
michael@0 | 1035 | |
michael@0 | 1036 | /** |
michael@0 | 1037 | * Try to set the attribute as a mapped attribute, if applicable. This will |
michael@0 | 1038 | * only be called for attributes that are in the null namespace and only on |
michael@0 | 1039 | * attributes that returned true when passed to IsAttributeMapped. The |
michael@0 | 1040 | * caller will not try to set the attr in any other way if this method |
michael@0 | 1041 | * returns true (the value of aRetval does not matter for that purpose). |
michael@0 | 1042 | * |
michael@0 | 1043 | * @param aDocument the current document of this node (an optimization) |
michael@0 | 1044 | * @param aName the name of the attribute |
michael@0 | 1045 | * @param aValue the nsAttrValue to set |
michael@0 | 1046 | * @param [out] aRetval the nsresult status of the operation, if any. |
michael@0 | 1047 | * @return true if the setting was attempted, false otherwise. |
michael@0 | 1048 | */ |
michael@0 | 1049 | virtual bool SetMappedAttribute(nsIDocument* aDocument, |
michael@0 | 1050 | nsIAtom* aName, |
michael@0 | 1051 | nsAttrValue& aValue, |
michael@0 | 1052 | nsresult* aRetval); |
michael@0 | 1053 | |
michael@0 | 1054 | /** |
michael@0 | 1055 | * Hook that is called by Element::SetAttr to allow subclasses to |
michael@0 | 1056 | * deal with attribute sets. This will only be called after we verify that |
michael@0 | 1057 | * we're actually doing an attr set and will be called before |
michael@0 | 1058 | * AttributeWillChange and before ParseAttribute and hence before we've set |
michael@0 | 1059 | * the new value. |
michael@0 | 1060 | * |
michael@0 | 1061 | * @param aNamespaceID the namespace of the attr being set |
michael@0 | 1062 | * @param aName the localname of the attribute being set |
michael@0 | 1063 | * @param aValue the value it's being set to represented as either a string or |
michael@0 | 1064 | * a parsed nsAttrValue. Alternatively, if the attr is being removed it |
michael@0 | 1065 | * will be null. |
michael@0 | 1066 | * @param aNotify Whether we plan to notify document observers. |
michael@0 | 1067 | */ |
michael@0 | 1068 | // Note that this is inlined so that when subclasses call it it gets |
michael@0 | 1069 | // inlined. Those calls don't go through a vtable. |
michael@0 | 1070 | virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, |
michael@0 | 1071 | const nsAttrValueOrString* aValue, |
michael@0 | 1072 | bool aNotify) |
michael@0 | 1073 | { |
michael@0 | 1074 | return NS_OK; |
michael@0 | 1075 | } |
michael@0 | 1076 | |
michael@0 | 1077 | /** |
michael@0 | 1078 | * Hook that is called by Element::SetAttr to allow subclasses to |
michael@0 | 1079 | * deal with attribute sets. This will only be called after we have called |
michael@0 | 1080 | * SetAndTakeAttr and AttributeChanged (that is, after we have actually set |
michael@0 | 1081 | * the attr). It will always be called under a scriptblocker. |
michael@0 | 1082 | * |
michael@0 | 1083 | * @param aNamespaceID the namespace of the attr being set |
michael@0 | 1084 | * @param aName the localname of the attribute being set |
michael@0 | 1085 | * @param aValue the value it's being set to. If null, the attr is being |
michael@0 | 1086 | * removed. |
michael@0 | 1087 | * @param aNotify Whether we plan to notify document observers. |
michael@0 | 1088 | */ |
michael@0 | 1089 | // Note that this is inlined so that when subclasses call it it gets |
michael@0 | 1090 | // inlined. Those calls don't go through a vtable. |
michael@0 | 1091 | virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, |
michael@0 | 1092 | const nsAttrValue* aValue, bool aNotify) |
michael@0 | 1093 | { |
michael@0 | 1094 | return NS_OK; |
michael@0 | 1095 | } |
michael@0 | 1096 | |
michael@0 | 1097 | /** |
michael@0 | 1098 | * Hook to allow subclasses to produce a different EventListenerManager if |
michael@0 | 1099 | * needed for attachment of attribute-defined handlers |
michael@0 | 1100 | */ |
michael@0 | 1101 | virtual EventListenerManager* |
michael@0 | 1102 | GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer); |
michael@0 | 1103 | |
michael@0 | 1104 | /** |
michael@0 | 1105 | * Internal hook for converting an attribute name-string to an atomized name |
michael@0 | 1106 | */ |
michael@0 | 1107 | virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const; |
michael@0 | 1108 | |
michael@0 | 1109 | nsIFrame* GetStyledFrame(); |
michael@0 | 1110 | |
michael@0 | 1111 | virtual Element* GetNameSpaceElement() |
michael@0 | 1112 | { |
michael@0 | 1113 | return this; |
michael@0 | 1114 | } |
michael@0 | 1115 | |
michael@0 | 1116 | Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI, |
michael@0 | 1117 | const nsAString& aLocalName); |
michael@0 | 1118 | |
michael@0 | 1119 | inline void RegisterFreezableElement(); |
michael@0 | 1120 | inline void UnregisterFreezableElement(); |
michael@0 | 1121 | |
michael@0 | 1122 | /** |
michael@0 | 1123 | * Add/remove this element to the documents id cache |
michael@0 | 1124 | */ |
michael@0 | 1125 | void AddToIdTable(nsIAtom* aId); |
michael@0 | 1126 | void RemoveFromIdTable(); // checks HasID() and uses DoGetID() |
michael@0 | 1127 | void RemoveFromIdTable(nsIAtom* aId); |
michael@0 | 1128 | |
michael@0 | 1129 | /** |
michael@0 | 1130 | * Functions to carry out event default actions for links of all types |
michael@0 | 1131 | * (HTML links, XLinks, SVG "XLinks", etc.) |
michael@0 | 1132 | */ |
michael@0 | 1133 | |
michael@0 | 1134 | /** |
michael@0 | 1135 | * Check that we meet the conditions to handle a link event |
michael@0 | 1136 | * and that we are actually on a link. |
michael@0 | 1137 | * |
michael@0 | 1138 | * @param aVisitor event visitor |
michael@0 | 1139 | * @param aURI the uri of the link, set only if the return value is true [OUT] |
michael@0 | 1140 | * @return true if we can handle the link event, false otherwise |
michael@0 | 1141 | */ |
michael@0 | 1142 | bool CheckHandleEventForLinksPrecondition(EventChainVisitor& aVisitor, |
michael@0 | 1143 | nsIURI** aURI) const; |
michael@0 | 1144 | |
michael@0 | 1145 | /** |
michael@0 | 1146 | * Handle status bar updates before they can be cancelled. |
michael@0 | 1147 | */ |
michael@0 | 1148 | nsresult PreHandleEventForLinks(EventChainPreVisitor& aVisitor); |
michael@0 | 1149 | |
michael@0 | 1150 | /** |
michael@0 | 1151 | * Handle default actions for link event if the event isn't consumed yet. |
michael@0 | 1152 | */ |
michael@0 | 1153 | nsresult PostHandleEventForLinks(EventChainPostVisitor& aVisitor); |
michael@0 | 1154 | |
michael@0 | 1155 | /** |
michael@0 | 1156 | * Get the target of this link element. Consumers should established that |
michael@0 | 1157 | * this element is a link (probably using IsLink) before calling this |
michael@0 | 1158 | * function (or else why call it?) |
michael@0 | 1159 | * |
michael@0 | 1160 | * Note: for HTML this gets the value of the 'target' attribute; for XLink |
michael@0 | 1161 | * this gets the value of the xlink:_moz_target attribute, or failing that, |
michael@0 | 1162 | * the value of xlink:show, converted to a suitably equivalent named target |
michael@0 | 1163 | * (e.g. _blank). |
michael@0 | 1164 | */ |
michael@0 | 1165 | virtual void GetLinkTarget(nsAString& aTarget); |
michael@0 | 1166 | |
michael@0 | 1167 | private: |
michael@0 | 1168 | /** |
michael@0 | 1169 | * Get this element's client area rect in app units. |
michael@0 | 1170 | * @return the frame's client area |
michael@0 | 1171 | */ |
michael@0 | 1172 | nsRect GetClientAreaRect(); |
michael@0 | 1173 | |
michael@0 | 1174 | nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr, |
michael@0 | 1175 | bool aFlushLayout = true); |
michael@0 | 1176 | |
michael@0 | 1177 | // Data members |
michael@0 | 1178 | EventStates mState; |
michael@0 | 1179 | }; |
michael@0 | 1180 | |
michael@0 | 1181 | NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID) |
michael@0 | 1182 | |
michael@0 | 1183 | inline bool |
michael@0 | 1184 | Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const |
michael@0 | 1185 | { |
michael@0 | 1186 | NS_ASSERTION(nullptr != aName, "must have attribute name"); |
michael@0 | 1187 | NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, |
michael@0 | 1188 | "must have a real namespace ID!"); |
michael@0 | 1189 | |
michael@0 | 1190 | return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0; |
michael@0 | 1191 | } |
michael@0 | 1192 | |
michael@0 | 1193 | inline bool |
michael@0 | 1194 | Element::AttrValueIs(int32_t aNameSpaceID, |
michael@0 | 1195 | nsIAtom* aName, |
michael@0 | 1196 | const nsAString& aValue, |
michael@0 | 1197 | nsCaseTreatment aCaseSensitive) const |
michael@0 | 1198 | { |
michael@0 | 1199 | NS_ASSERTION(aName, "Must have attr name"); |
michael@0 | 1200 | NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace"); |
michael@0 | 1201 | |
michael@0 | 1202 | const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID); |
michael@0 | 1203 | return val && val->Equals(aValue, aCaseSensitive); |
michael@0 | 1204 | } |
michael@0 | 1205 | |
michael@0 | 1206 | inline bool |
michael@0 | 1207 | Element::AttrValueIs(int32_t aNameSpaceID, |
michael@0 | 1208 | nsIAtom* aName, |
michael@0 | 1209 | nsIAtom* aValue, |
michael@0 | 1210 | nsCaseTreatment aCaseSensitive) const |
michael@0 | 1211 | { |
michael@0 | 1212 | NS_ASSERTION(aName, "Must have attr name"); |
michael@0 | 1213 | NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace"); |
michael@0 | 1214 | NS_ASSERTION(aValue, "Null value atom"); |
michael@0 | 1215 | |
michael@0 | 1216 | const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID); |
michael@0 | 1217 | return val && val->Equals(aValue, aCaseSensitive); |
michael@0 | 1218 | } |
michael@0 | 1219 | |
michael@0 | 1220 | } // namespace dom |
michael@0 | 1221 | } // namespace mozilla |
michael@0 | 1222 | |
michael@0 | 1223 | inline mozilla::dom::Element* nsINode::AsElement() |
michael@0 | 1224 | { |
michael@0 | 1225 | MOZ_ASSERT(IsElement()); |
michael@0 | 1226 | return static_cast<mozilla::dom::Element*>(this); |
michael@0 | 1227 | } |
michael@0 | 1228 | |
michael@0 | 1229 | inline const mozilla::dom::Element* nsINode::AsElement() const |
michael@0 | 1230 | { |
michael@0 | 1231 | MOZ_ASSERT(IsElement()); |
michael@0 | 1232 | return static_cast<const mozilla::dom::Element*>(this); |
michael@0 | 1233 | } |
michael@0 | 1234 | |
michael@0 | 1235 | inline bool nsINode::HasAttributes() const |
michael@0 | 1236 | { |
michael@0 | 1237 | return IsElement() && AsElement()->HasAttrs(); |
michael@0 | 1238 | } |
michael@0 | 1239 | |
michael@0 | 1240 | /** |
michael@0 | 1241 | * Macros to implement Clone(). _elementName is the class for which to implement |
michael@0 | 1242 | * Clone. |
michael@0 | 1243 | */ |
michael@0 | 1244 | #define NS_IMPL_ELEMENT_CLONE(_elementName) \ |
michael@0 | 1245 | nsresult \ |
michael@0 | 1246 | _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \ |
michael@0 | 1247 | { \ |
michael@0 | 1248 | *aResult = nullptr; \ |
michael@0 | 1249 | already_AddRefed<nsINodeInfo> ni = \ |
michael@0 | 1250 | nsCOMPtr<nsINodeInfo>(aNodeInfo).forget(); \ |
michael@0 | 1251 | _elementName *it = new _elementName(ni); \ |
michael@0 | 1252 | if (!it) { \ |
michael@0 | 1253 | return NS_ERROR_OUT_OF_MEMORY; \ |
michael@0 | 1254 | } \ |
michael@0 | 1255 | \ |
michael@0 | 1256 | nsCOMPtr<nsINode> kungFuDeathGrip = it; \ |
michael@0 | 1257 | nsresult rv = const_cast<_elementName*>(this)->CopyInnerTo(it); \ |
michael@0 | 1258 | if (NS_SUCCEEDED(rv)) { \ |
michael@0 | 1259 | kungFuDeathGrip.swap(*aResult); \ |
michael@0 | 1260 | } \ |
michael@0 | 1261 | \ |
michael@0 | 1262 | return rv; \ |
michael@0 | 1263 | } |
michael@0 | 1264 | |
michael@0 | 1265 | #define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName) \ |
michael@0 | 1266 | nsresult \ |
michael@0 | 1267 | _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \ |
michael@0 | 1268 | { \ |
michael@0 | 1269 | *aResult = nullptr; \ |
michael@0 | 1270 | already_AddRefed<nsINodeInfo> ni = \ |
michael@0 | 1271 | nsCOMPtr<nsINodeInfo>(aNodeInfo).forget(); \ |
michael@0 | 1272 | _elementName *it = new _elementName(ni); \ |
michael@0 | 1273 | if (!it) { \ |
michael@0 | 1274 | return NS_ERROR_OUT_OF_MEMORY; \ |
michael@0 | 1275 | } \ |
michael@0 | 1276 | \ |
michael@0 | 1277 | nsCOMPtr<nsINode> kungFuDeathGrip = it; \ |
michael@0 | 1278 | nsresult rv = it->Init(); \ |
michael@0 | 1279 | nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it); \ |
michael@0 | 1280 | if (NS_FAILED(rv2)) { \ |
michael@0 | 1281 | rv = rv2; \ |
michael@0 | 1282 | } \ |
michael@0 | 1283 | if (NS_SUCCEEDED(rv)) { \ |
michael@0 | 1284 | kungFuDeathGrip.swap(*aResult); \ |
michael@0 | 1285 | } \ |
michael@0 | 1286 | \ |
michael@0 | 1287 | return rv; \ |
michael@0 | 1288 | } |
michael@0 | 1289 | |
michael@0 | 1290 | /** |
michael@0 | 1291 | * A macro to implement the getter and setter for a given string |
michael@0 | 1292 | * valued content property. The method uses the generic GetAttr and |
michael@0 | 1293 | * SetAttr methods. We use the 5-argument form of SetAttr, because |
michael@0 | 1294 | * some consumers only implement that one, hiding superclass |
michael@0 | 1295 | * 4-argument forms. |
michael@0 | 1296 | */ |
michael@0 | 1297 | #define NS_IMPL_STRING_ATTR(_class, _method, _atom) \ |
michael@0 | 1298 | NS_IMETHODIMP \ |
michael@0 | 1299 | _class::Get##_method(nsAString& aValue) \ |
michael@0 | 1300 | { \ |
michael@0 | 1301 | GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue); \ |
michael@0 | 1302 | return NS_OK; \ |
michael@0 | 1303 | } \ |
michael@0 | 1304 | NS_IMETHODIMP \ |
michael@0 | 1305 | _class::Set##_method(const nsAString& aValue) \ |
michael@0 | 1306 | { \ |
michael@0 | 1307 | return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, nullptr, aValue, true); \ |
michael@0 | 1308 | } |
michael@0 | 1309 | |
michael@0 | 1310 | /** |
michael@0 | 1311 | * A macro to implement the getter and setter for a given boolean |
michael@0 | 1312 | * valued content property. The method uses the GetBoolAttr and |
michael@0 | 1313 | * SetBoolAttr methods. |
michael@0 | 1314 | */ |
michael@0 | 1315 | #define NS_IMPL_BOOL_ATTR(_class, _method, _atom) \ |
michael@0 | 1316 | NS_IMETHODIMP \ |
michael@0 | 1317 | _class::Get##_method(bool* aValue) \ |
michael@0 | 1318 | { \ |
michael@0 | 1319 | *aValue = GetBoolAttr(nsGkAtoms::_atom); \ |
michael@0 | 1320 | return NS_OK; \ |
michael@0 | 1321 | } \ |
michael@0 | 1322 | NS_IMETHODIMP \ |
michael@0 | 1323 | _class::Set##_method(bool aValue) \ |
michael@0 | 1324 | { \ |
michael@0 | 1325 | return SetBoolAttr(nsGkAtoms::_atom, aValue); \ |
michael@0 | 1326 | } |
michael@0 | 1327 | |
michael@0 | 1328 | #define NS_FORWARD_NSIDOMELEMENT_TO_GENERIC \ |
michael@0 | 1329 | typedef mozilla::dom::Element Element; \ |
michael@0 | 1330 | NS_IMETHOD GetTagName(nsAString& aTagName) MOZ_FINAL \ |
michael@0 | 1331 | { \ |
michael@0 | 1332 | Element::GetTagName(aTagName); \ |
michael@0 | 1333 | return NS_OK; \ |
michael@0 | 1334 | } \ |
michael@0 | 1335 | NS_IMETHOD GetClassList(nsISupports** aClassList) MOZ_FINAL \ |
michael@0 | 1336 | { \ |
michael@0 | 1337 | Element::GetClassList(aClassList); \ |
michael@0 | 1338 | return NS_OK; \ |
michael@0 | 1339 | } \ |
michael@0 | 1340 | NS_IMETHOD GetAttributes(nsIDOMMozNamedAttrMap** aAttributes) MOZ_FINAL \ |
michael@0 | 1341 | { \ |
michael@0 | 1342 | NS_ADDREF(*aAttributes = Attributes()); \ |
michael@0 | 1343 | return NS_OK; \ |
michael@0 | 1344 | } \ |
michael@0 | 1345 | using Element::GetAttribute; \ |
michael@0 | 1346 | NS_IMETHOD GetAttribute(const nsAString& name, nsAString& _retval) MOZ_FINAL \ |
michael@0 | 1347 | { \ |
michael@0 | 1348 | nsString attr; \ |
michael@0 | 1349 | GetAttribute(name, attr); \ |
michael@0 | 1350 | _retval = attr; \ |
michael@0 | 1351 | return NS_OK; \ |
michael@0 | 1352 | } \ |
michael@0 | 1353 | NS_IMETHOD GetAttributeNS(const nsAString& namespaceURI, \ |
michael@0 | 1354 | const nsAString& localName, \ |
michael@0 | 1355 | nsAString& _retval) MOZ_FINAL \ |
michael@0 | 1356 | { \ |
michael@0 | 1357 | Element::GetAttributeNS(namespaceURI, localName, _retval); \ |
michael@0 | 1358 | return NS_OK; \ |
michael@0 | 1359 | } \ |
michael@0 | 1360 | NS_IMETHOD SetAttribute(const nsAString& name, \ |
michael@0 | 1361 | const nsAString& value) \ |
michael@0 | 1362 | { \ |
michael@0 | 1363 | mozilla::ErrorResult rv; \ |
michael@0 | 1364 | Element::SetAttribute(name, value, rv); \ |
michael@0 | 1365 | return rv.ErrorCode(); \ |
michael@0 | 1366 | } \ |
michael@0 | 1367 | NS_IMETHOD SetAttributeNS(const nsAString& namespaceURI, \ |
michael@0 | 1368 | const nsAString& qualifiedName, \ |
michael@0 | 1369 | const nsAString& value) MOZ_FINAL \ |
michael@0 | 1370 | { \ |
michael@0 | 1371 | mozilla::ErrorResult rv; \ |
michael@0 | 1372 | Element::SetAttributeNS(namespaceURI, qualifiedName, value, rv); \ |
michael@0 | 1373 | return rv.ErrorCode(); \ |
michael@0 | 1374 | } \ |
michael@0 | 1375 | using Element::RemoveAttribute; \ |
michael@0 | 1376 | NS_IMETHOD RemoveAttribute(const nsAString& name) MOZ_FINAL \ |
michael@0 | 1377 | { \ |
michael@0 | 1378 | mozilla::ErrorResult rv; \ |
michael@0 | 1379 | RemoveAttribute(name, rv); \ |
michael@0 | 1380 | return rv.ErrorCode(); \ |
michael@0 | 1381 | } \ |
michael@0 | 1382 | NS_IMETHOD RemoveAttributeNS(const nsAString& namespaceURI, \ |
michael@0 | 1383 | const nsAString& localName) MOZ_FINAL \ |
michael@0 | 1384 | { \ |
michael@0 | 1385 | mozilla::ErrorResult rv; \ |
michael@0 | 1386 | Element::RemoveAttributeNS(namespaceURI, localName, rv); \ |
michael@0 | 1387 | return rv.ErrorCode(); \ |
michael@0 | 1388 | } \ |
michael@0 | 1389 | using Element::HasAttribute; \ |
michael@0 | 1390 | NS_IMETHOD HasAttribute(const nsAString& name, \ |
michael@0 | 1391 | bool* _retval) MOZ_FINAL \ |
michael@0 | 1392 | { \ |
michael@0 | 1393 | *_retval = HasAttribute(name); \ |
michael@0 | 1394 | return NS_OK; \ |
michael@0 | 1395 | } \ |
michael@0 | 1396 | NS_IMETHOD HasAttributeNS(const nsAString& namespaceURI, \ |
michael@0 | 1397 | const nsAString& localName, \ |
michael@0 | 1398 | bool* _retval) MOZ_FINAL \ |
michael@0 | 1399 | { \ |
michael@0 | 1400 | *_retval = Element::HasAttributeNS(namespaceURI, localName); \ |
michael@0 | 1401 | return NS_OK; \ |
michael@0 | 1402 | } \ |
michael@0 | 1403 | NS_IMETHOD GetAttributeNode(const nsAString& name, \ |
michael@0 | 1404 | nsIDOMAttr** _retval) MOZ_FINAL \ |
michael@0 | 1405 | { \ |
michael@0 | 1406 | NS_IF_ADDREF(*_retval = Element::GetAttributeNode(name)); \ |
michael@0 | 1407 | return NS_OK; \ |
michael@0 | 1408 | } \ |
michael@0 | 1409 | NS_IMETHOD SetAttributeNode(nsIDOMAttr* newAttr, \ |
michael@0 | 1410 | nsIDOMAttr** _retval) MOZ_FINAL \ |
michael@0 | 1411 | { \ |
michael@0 | 1412 | if (!newAttr) { \ |
michael@0 | 1413 | return NS_ERROR_INVALID_POINTER; \ |
michael@0 | 1414 | } \ |
michael@0 | 1415 | mozilla::ErrorResult rv; \ |
michael@0 | 1416 | mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr); \ |
michael@0 | 1417 | *_retval = Element::SetAttributeNode(*attr, rv).take(); \ |
michael@0 | 1418 | return rv.ErrorCode(); \ |
michael@0 | 1419 | } \ |
michael@0 | 1420 | NS_IMETHOD RemoveAttributeNode(nsIDOMAttr* oldAttr, \ |
michael@0 | 1421 | nsIDOMAttr** _retval) MOZ_FINAL \ |
michael@0 | 1422 | { \ |
michael@0 | 1423 | if (!oldAttr) { \ |
michael@0 | 1424 | return NS_ERROR_INVALID_POINTER; \ |
michael@0 | 1425 | } \ |
michael@0 | 1426 | mozilla::ErrorResult rv; \ |
michael@0 | 1427 | mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(oldAttr); \ |
michael@0 | 1428 | *_retval = Element::RemoveAttributeNode(*attr, rv).take(); \ |
michael@0 | 1429 | return rv.ErrorCode(); \ |
michael@0 | 1430 | } \ |
michael@0 | 1431 | NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI, \ |
michael@0 | 1432 | const nsAString& localName, \ |
michael@0 | 1433 | nsIDOMAttr** _retval) MOZ_FINAL \ |
michael@0 | 1434 | { \ |
michael@0 | 1435 | NS_IF_ADDREF(*_retval = Element::GetAttributeNodeNS(namespaceURI, \ |
michael@0 | 1436 | localName)); \ |
michael@0 | 1437 | return NS_OK; \ |
michael@0 | 1438 | } \ |
michael@0 | 1439 | NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* newAttr, \ |
michael@0 | 1440 | nsIDOMAttr** _retval) MOZ_FINAL \ |
michael@0 | 1441 | { \ |
michael@0 | 1442 | mozilla::ErrorResult rv; \ |
michael@0 | 1443 | mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr); \ |
michael@0 | 1444 | *_retval = Element::SetAttributeNodeNS(*attr, rv).take(); \ |
michael@0 | 1445 | return rv.ErrorCode(); \ |
michael@0 | 1446 | } \ |
michael@0 | 1447 | NS_IMETHOD GetElementsByTagName(const nsAString& name, \ |
michael@0 | 1448 | nsIDOMHTMLCollection** _retval) MOZ_FINAL \ |
michael@0 | 1449 | { \ |
michael@0 | 1450 | Element::GetElementsByTagName(name, _retval); \ |
michael@0 | 1451 | return NS_OK; \ |
michael@0 | 1452 | } \ |
michael@0 | 1453 | NS_IMETHOD GetElementsByTagNameNS(const nsAString& namespaceURI, \ |
michael@0 | 1454 | const nsAString& localName, \ |
michael@0 | 1455 | nsIDOMHTMLCollection** _retval) MOZ_FINAL \ |
michael@0 | 1456 | { \ |
michael@0 | 1457 | return Element::GetElementsByTagNameNS(namespaceURI, localName, \ |
michael@0 | 1458 | _retval); \ |
michael@0 | 1459 | } \ |
michael@0 | 1460 | NS_IMETHOD GetElementsByClassName(const nsAString& classes, \ |
michael@0 | 1461 | nsIDOMHTMLCollection** _retval) MOZ_FINAL \ |
michael@0 | 1462 | { \ |
michael@0 | 1463 | return Element::GetElementsByClassName(classes, _retval); \ |
michael@0 | 1464 | } \ |
michael@0 | 1465 | NS_IMETHOD GetChildElements(nsIDOMNodeList** aChildElements) MOZ_FINAL \ |
michael@0 | 1466 | { \ |
michael@0 | 1467 | nsIHTMLCollection* list = FragmentOrElement::Children(); \ |
michael@0 | 1468 | return CallQueryInterface(list, aChildElements); \ |
michael@0 | 1469 | } \ |
michael@0 | 1470 | NS_IMETHOD GetFirstElementChild(nsIDOMElement** aFirstElementChild) MOZ_FINAL \ |
michael@0 | 1471 | { \ |
michael@0 | 1472 | Element* element = Element::GetFirstElementChild(); \ |
michael@0 | 1473 | if (!element) { \ |
michael@0 | 1474 | *aFirstElementChild = nullptr; \ |
michael@0 | 1475 | return NS_OK; \ |
michael@0 | 1476 | } \ |
michael@0 | 1477 | return CallQueryInterface(element, aFirstElementChild); \ |
michael@0 | 1478 | } \ |
michael@0 | 1479 | NS_IMETHOD GetLastElementChild(nsIDOMElement** aLastElementChild) MOZ_FINAL \ |
michael@0 | 1480 | { \ |
michael@0 | 1481 | Element* element = Element::GetLastElementChild(); \ |
michael@0 | 1482 | if (!element) { \ |
michael@0 | 1483 | *aLastElementChild = nullptr; \ |
michael@0 | 1484 | return NS_OK; \ |
michael@0 | 1485 | } \ |
michael@0 | 1486 | return CallQueryInterface(element, aLastElementChild); \ |
michael@0 | 1487 | } \ |
michael@0 | 1488 | NS_IMETHOD GetPreviousElementSibling(nsIDOMElement** aPreviousElementSibling) \ |
michael@0 | 1489 | MOZ_FINAL \ |
michael@0 | 1490 | { \ |
michael@0 | 1491 | Element* element = Element::GetPreviousElementSibling(); \ |
michael@0 | 1492 | if (!element) { \ |
michael@0 | 1493 | *aPreviousElementSibling = nullptr; \ |
michael@0 | 1494 | return NS_OK; \ |
michael@0 | 1495 | } \ |
michael@0 | 1496 | return CallQueryInterface(element, aPreviousElementSibling); \ |
michael@0 | 1497 | } \ |
michael@0 | 1498 | NS_IMETHOD GetNextElementSibling(nsIDOMElement** aNextElementSibling) \ |
michael@0 | 1499 | MOZ_FINAL \ |
michael@0 | 1500 | { \ |
michael@0 | 1501 | Element* element = Element::GetNextElementSibling(); \ |
michael@0 | 1502 | if (!element) { \ |
michael@0 | 1503 | *aNextElementSibling = nullptr; \ |
michael@0 | 1504 | return NS_OK; \ |
michael@0 | 1505 | } \ |
michael@0 | 1506 | return CallQueryInterface(element, aNextElementSibling); \ |
michael@0 | 1507 | } \ |
michael@0 | 1508 | NS_IMETHOD GetChildElementCount(uint32_t* aChildElementCount) MOZ_FINAL \ |
michael@0 | 1509 | { \ |
michael@0 | 1510 | *aChildElementCount = Element::ChildElementCount(); \ |
michael@0 | 1511 | return NS_OK; \ |
michael@0 | 1512 | } \ |
michael@0 | 1513 | NS_IMETHOD MozRemove() MOZ_FINAL \ |
michael@0 | 1514 | { \ |
michael@0 | 1515 | nsINode::Remove(); \ |
michael@0 | 1516 | return NS_OK; \ |
michael@0 | 1517 | } \ |
michael@0 | 1518 | NS_IMETHOD GetClientRects(nsIDOMClientRectList** _retval) MOZ_FINAL \ |
michael@0 | 1519 | { \ |
michael@0 | 1520 | *_retval = Element::GetClientRects().take(); \ |
michael@0 | 1521 | return NS_OK; \ |
michael@0 | 1522 | } \ |
michael@0 | 1523 | NS_IMETHOD GetBoundingClientRect(nsIDOMClientRect** _retval) MOZ_FINAL \ |
michael@0 | 1524 | { \ |
michael@0 | 1525 | *_retval = Element::GetBoundingClientRect().take(); \ |
michael@0 | 1526 | return NS_OK; \ |
michael@0 | 1527 | } \ |
michael@0 | 1528 | NS_IMETHOD GetScrollTop(int32_t* aScrollTop) MOZ_FINAL \ |
michael@0 | 1529 | { \ |
michael@0 | 1530 | *aScrollTop = Element::ScrollTop(); \ |
michael@0 | 1531 | return NS_OK; \ |
michael@0 | 1532 | } \ |
michael@0 | 1533 | NS_IMETHOD SetScrollTop(int32_t aScrollTop) MOZ_FINAL \ |
michael@0 | 1534 | { \ |
michael@0 | 1535 | Element::SetScrollTop(aScrollTop); \ |
michael@0 | 1536 | return NS_OK; \ |
michael@0 | 1537 | } \ |
michael@0 | 1538 | NS_IMETHOD GetScrollLeft(int32_t* aScrollLeft) MOZ_FINAL \ |
michael@0 | 1539 | { \ |
michael@0 | 1540 | *aScrollLeft = Element::ScrollLeft(); \ |
michael@0 | 1541 | return NS_OK; \ |
michael@0 | 1542 | } \ |
michael@0 | 1543 | NS_IMETHOD SetScrollLeft(int32_t aScrollLeft) MOZ_FINAL \ |
michael@0 | 1544 | { \ |
michael@0 | 1545 | Element::SetScrollLeft(aScrollLeft); \ |
michael@0 | 1546 | return NS_OK; \ |
michael@0 | 1547 | } \ |
michael@0 | 1548 | NS_IMETHOD GetScrollWidth(int32_t* aScrollWidth) MOZ_FINAL \ |
michael@0 | 1549 | { \ |
michael@0 | 1550 | *aScrollWidth = Element::ScrollWidth(); \ |
michael@0 | 1551 | return NS_OK; \ |
michael@0 | 1552 | } \ |
michael@0 | 1553 | NS_IMETHOD GetScrollHeight(int32_t* aScrollHeight) MOZ_FINAL \ |
michael@0 | 1554 | { \ |
michael@0 | 1555 | *aScrollHeight = Element::ScrollHeight(); \ |
michael@0 | 1556 | return NS_OK; \ |
michael@0 | 1557 | } \ |
michael@0 | 1558 | NS_IMETHOD GetClientTop(int32_t* aClientTop) MOZ_FINAL \ |
michael@0 | 1559 | { \ |
michael@0 | 1560 | *aClientTop = Element::ClientTop(); \ |
michael@0 | 1561 | return NS_OK; \ |
michael@0 | 1562 | } \ |
michael@0 | 1563 | NS_IMETHOD GetClientLeft(int32_t* aClientLeft) MOZ_FINAL \ |
michael@0 | 1564 | { \ |
michael@0 | 1565 | *aClientLeft = Element::ClientLeft(); \ |
michael@0 | 1566 | return NS_OK; \ |
michael@0 | 1567 | } \ |
michael@0 | 1568 | NS_IMETHOD GetClientWidth(int32_t* aClientWidth) MOZ_FINAL \ |
michael@0 | 1569 | { \ |
michael@0 | 1570 | *aClientWidth = Element::ClientWidth(); \ |
michael@0 | 1571 | return NS_OK; \ |
michael@0 | 1572 | } \ |
michael@0 | 1573 | NS_IMETHOD GetClientHeight(int32_t* aClientHeight) MOZ_FINAL \ |
michael@0 | 1574 | { \ |
michael@0 | 1575 | *aClientHeight = Element::ClientHeight(); \ |
michael@0 | 1576 | return NS_OK; \ |
michael@0 | 1577 | } \ |
michael@0 | 1578 | NS_IMETHOD GetScrollLeftMax(int32_t* aScrollLeftMax) MOZ_FINAL \ |
michael@0 | 1579 | { \ |
michael@0 | 1580 | *aScrollLeftMax = Element::ScrollLeftMax(); \ |
michael@0 | 1581 | return NS_OK; \ |
michael@0 | 1582 | } \ |
michael@0 | 1583 | NS_IMETHOD GetScrollTopMax(int32_t* aScrollTopMax) MOZ_FINAL \ |
michael@0 | 1584 | { \ |
michael@0 | 1585 | *aScrollTopMax = Element::ScrollTopMax(); \ |
michael@0 | 1586 | return NS_OK; \ |
michael@0 | 1587 | } \ |
michael@0 | 1588 | NS_IMETHOD MozMatchesSelector(const nsAString& selector, \ |
michael@0 | 1589 | bool* _retval) MOZ_FINAL \ |
michael@0 | 1590 | { \ |
michael@0 | 1591 | mozilla::ErrorResult rv; \ |
michael@0 | 1592 | *_retval = Element::MozMatchesSelector(selector, rv); \ |
michael@0 | 1593 | return rv.ErrorCode(); \ |
michael@0 | 1594 | } \ |
michael@0 | 1595 | NS_IMETHOD SetCapture(bool retargetToElement) MOZ_FINAL \ |
michael@0 | 1596 | { \ |
michael@0 | 1597 | Element::SetCapture(retargetToElement); \ |
michael@0 | 1598 | return NS_OK; \ |
michael@0 | 1599 | } \ |
michael@0 | 1600 | NS_IMETHOD ReleaseCapture(void) MOZ_FINAL \ |
michael@0 | 1601 | { \ |
michael@0 | 1602 | Element::ReleaseCapture(); \ |
michael@0 | 1603 | return NS_OK; \ |
michael@0 | 1604 | } \ |
michael@0 | 1605 | NS_IMETHOD MozRequestFullScreen(void) MOZ_FINAL \ |
michael@0 | 1606 | { \ |
michael@0 | 1607 | Element::MozRequestFullScreen(); \ |
michael@0 | 1608 | return NS_OK; \ |
michael@0 | 1609 | } \ |
michael@0 | 1610 | NS_IMETHOD MozRequestPointerLock(void) MOZ_FINAL \ |
michael@0 | 1611 | { \ |
michael@0 | 1612 | Element::MozRequestPointerLock(); \ |
michael@0 | 1613 | return NS_OK; \ |
michael@0 | 1614 | } \ |
michael@0 | 1615 | using nsINode::QuerySelector; \ |
michael@0 | 1616 | NS_IMETHOD QuerySelector(const nsAString& aSelector, \ |
michael@0 | 1617 | nsIDOMElement **aReturn) MOZ_FINAL \ |
michael@0 | 1618 | { \ |
michael@0 | 1619 | return nsINode::QuerySelector(aSelector, aReturn); \ |
michael@0 | 1620 | } \ |
michael@0 | 1621 | using nsINode::QuerySelectorAll; \ |
michael@0 | 1622 | NS_IMETHOD QuerySelectorAll(const nsAString& aSelector, \ |
michael@0 | 1623 | nsIDOMNodeList **aReturn) MOZ_FINAL \ |
michael@0 | 1624 | { \ |
michael@0 | 1625 | return nsINode::QuerySelectorAll(aSelector, aReturn); \ |
michael@0 | 1626 | } |
michael@0 | 1627 | |
michael@0 | 1628 | #endif // mozilla_dom_Element_h__ |