content/base/public/Element.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/base/public/Element.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1628 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: sw=2 ts=2 et :
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/*
    1.11 + * Base class for all element classes; this provides an implementation
    1.12 + * of DOM Core's nsIDOMElement, implements nsIContent, provides
    1.13 + * utility methods for subclasses, and so forth.
    1.14 + */
    1.15 +
    1.16 +#ifndef mozilla_dom_Element_h__
    1.17 +#define mozilla_dom_Element_h__
    1.18 +
    1.19 +#include "mozilla/dom/FragmentOrElement.h" // for base class
    1.20 +#include "nsChangeHint.h"                  // for enum
    1.21 +#include "mozilla/EventStates.h"           // for member
    1.22 +#include "mozilla/dom/DirectionalityUtils.h"
    1.23 +#include "nsIDOMElement.h"
    1.24 +#include "nsILinkHandler.h"
    1.25 +#include "nsNodeUtils.h"
    1.26 +#include "nsAttrAndChildArray.h"
    1.27 +#include "mozFlushType.h"
    1.28 +#include "nsDOMAttributeMap.h"
    1.29 +#include "nsIDOMXPathNSResolver.h"
    1.30 +#include "nsPresContext.h"
    1.31 +#include "nsDOMClassInfoID.h" // DOMCI_DATA
    1.32 +#include "mozilla/CORSMode.h"
    1.33 +#include "mozilla/Attributes.h"
    1.34 +#include "nsIScrollableFrame.h"
    1.35 +#include "mozilla/dom/Attr.h"
    1.36 +#include "nsISMILAttr.h"
    1.37 +#include "mozilla/dom/DOMRect.h"
    1.38 +#include "nsAttrValue.h"
    1.39 +#include "mozilla/EventForwards.h"
    1.40 +#include "mozilla/dom/BindingDeclarations.h"
    1.41 +#include "Units.h"
    1.42 +
    1.43 +class nsIDOMEventListener;
    1.44 +class nsIFrame;
    1.45 +class nsIDOMMozNamedAttrMap;
    1.46 +class nsIDOMCSSStyleDeclaration;
    1.47 +class nsIURI;
    1.48 +class nsINodeInfo;
    1.49 +class nsIControllers;
    1.50 +class nsEventChainVisitor;
    1.51 +class nsIScrollableFrame;
    1.52 +class nsAttrValueOrString;
    1.53 +class ContentUnbinder;
    1.54 +class nsContentList;
    1.55 +class nsDOMTokenList;
    1.56 +struct nsRect;
    1.57 +class nsFocusManager;
    1.58 +class nsGlobalWindow;
    1.59 +class nsICSSDeclaration;
    1.60 +class nsISMILAttr;
    1.61 +
    1.62 +already_AddRefed<nsContentList>
    1.63 +NS_GetContentList(nsINode* aRootNode,
    1.64 +                  int32_t  aMatchNameSpaceId,
    1.65 +                  const nsAString& aTagname);
    1.66 +
    1.67 +#define ELEMENT_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_))
    1.68 +
    1.69 +// Element-specific flags
    1.70 +enum {
    1.71 +  // Set if the element has a pending style change.
    1.72 +  ELEMENT_HAS_PENDING_RESTYLE =                 ELEMENT_FLAG_BIT(0),
    1.73 +
    1.74 +  // Set if the element is a potential restyle root (that is, has a style
    1.75 +  // change pending _and_ that style change will attempt to restyle
    1.76 +  // descendants).
    1.77 +  ELEMENT_IS_POTENTIAL_RESTYLE_ROOT =           ELEMENT_FLAG_BIT(1),
    1.78 +
    1.79 +  // Set if the element has a pending animation style change.
    1.80 +  ELEMENT_HAS_PENDING_ANIMATION_RESTYLE =       ELEMENT_FLAG_BIT(2),
    1.81 +
    1.82 +  // Set if the element is a potential animation restyle root (that is,
    1.83 +  // has an animation style change pending _and_ that style change
    1.84 +  // will attempt to restyle descendants).
    1.85 +  ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT = ELEMENT_FLAG_BIT(3),
    1.86 +
    1.87 +  // All of those bits together, for convenience.
    1.88 +  ELEMENT_ALL_RESTYLE_FLAGS = ELEMENT_HAS_PENDING_RESTYLE |
    1.89 +                              ELEMENT_IS_POTENTIAL_RESTYLE_ROOT |
    1.90 +                              ELEMENT_HAS_PENDING_ANIMATION_RESTYLE |
    1.91 +                              ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT,
    1.92 +
    1.93 +  // Just the HAS_PENDING bits, for convenience
    1.94 +  ELEMENT_PENDING_RESTYLE_FLAGS = ELEMENT_HAS_PENDING_RESTYLE |
    1.95 +                                  ELEMENT_HAS_PENDING_ANIMATION_RESTYLE,
    1.96 +
    1.97 +  // Remaining bits are for subclasses
    1.98 +  ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 4
    1.99 +};
   1.100 +
   1.101 +#undef ELEMENT_FLAG_BIT
   1.102 +
   1.103 +// Make sure we have space for our bits
   1.104 +ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
   1.105 +
   1.106 +namespace mozilla {
   1.107 +class EventChainPostVisitor;
   1.108 +class EventChainPreVisitor;
   1.109 +class EventChainVisitor;
   1.110 +class EventListenerManager;
   1.111 +class EventStateManager;
   1.112 +
   1.113 +namespace dom {
   1.114 +
   1.115 +class Link;
   1.116 +class UndoManager;
   1.117 +class DOMRect;
   1.118 +class DOMRectList;
   1.119 +
   1.120 +// IID for the dom::Element interface
   1.121 +#define NS_ELEMENT_IID \
   1.122 +{ 0xf7c18f0f, 0xa8fd, 0x4a95, \
   1.123 +  { 0x91, 0x72, 0xd3, 0xa7, 0x4a, 0xb8, 0xc4, 0xbe } }
   1.124 +
   1.125 +class Element : public FragmentOrElement
   1.126 +{
   1.127 +public:
   1.128 +#ifdef MOZILLA_INTERNAL_API
   1.129 +  Element(already_AddRefed<nsINodeInfo>& aNodeInfo) :
   1.130 +    FragmentOrElement(aNodeInfo),
   1.131 +    mState(NS_EVENT_STATE_MOZ_READONLY)
   1.132 +  {
   1.133 +    NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
   1.134 +                      "Bad NodeType in aNodeInfo");
   1.135 +    SetIsElement();
   1.136 +  }
   1.137 +#endif // MOZILLA_INTERNAL_API
   1.138 +
   1.139 +  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
   1.140 +
   1.141 +  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
   1.142 +
   1.143 +  /**
   1.144 +   * Method to get the full state of this element.  See mozilla/EventStates.h
   1.145 +   * for the possible bits that could be set here.
   1.146 +   */
   1.147 +  EventStates State() const
   1.148 +  {
   1.149 +    // mState is maintained by having whoever might have changed it
   1.150 +    // call UpdateState() or one of the other mState mutators.
   1.151 +    return mState;
   1.152 +  }
   1.153 +
   1.154 +  /**
   1.155 +   * Ask this element to update its state.  If aNotify is false, then
   1.156 +   * state change notifications will not be dispatched; in that
   1.157 +   * situation it is the caller's responsibility to dispatch them.
   1.158 +   *
   1.159 +   * In general, aNotify should only be false if we're guaranteed that
   1.160 +   * the element can't have a frame no matter what its style is
   1.161 +   * (e.g. if we're in the middle of adding it to the document or
   1.162 +   * removing it from the document).
   1.163 +   */
   1.164 +  void UpdateState(bool aNotify);
   1.165 +  
   1.166 +  /**
   1.167 +   * Method to update mState with link state information.  This does not notify.
   1.168 +   */
   1.169 +  void UpdateLinkState(EventStates aState);
   1.170 +
   1.171 +  /**
   1.172 +   * Returns true if this element is either a full-screen element or an
   1.173 +   * ancestor of the full-screen element.
   1.174 +   */
   1.175 +  bool IsFullScreenAncestor() const {
   1.176 +    return mState.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR |
   1.177 +                                        NS_EVENT_STATE_FULL_SCREEN);
   1.178 +  }
   1.179 +
   1.180 +  /**
   1.181 +   * The style state of this element. This is the real state of the element
   1.182 +   * with any style locks applied for pseudo-class inspecting.
   1.183 +   */
   1.184 +  EventStates StyleState() const
   1.185 +  {
   1.186 +    if (!HasLockedStyleStates()) {
   1.187 +      return mState;
   1.188 +    }
   1.189 +    return StyleStateFromLocks();
   1.190 +  }
   1.191 +
   1.192 +  /**
   1.193 +   * The style state locks applied to this element.
   1.194 +   */
   1.195 +  EventStates LockedStyleStates() const;
   1.196 +
   1.197 +  /**
   1.198 +   * Add a style state lock on this element.
   1.199 +   */
   1.200 +  void LockStyleStates(EventStates aStates);
   1.201 +
   1.202 +  /**
   1.203 +   * Remove a style state lock on this element.
   1.204 +   */
   1.205 +  void UnlockStyleStates(EventStates aStates);
   1.206 +
   1.207 +  /**
   1.208 +   * Clear all style state locks on this element.
   1.209 +   */
   1.210 +  void ClearStyleStateLocks();
   1.211 +
   1.212 +  /**
   1.213 +   * Get the inline style rule, if any, for this element.
   1.214 +   */
   1.215 +  virtual css::StyleRule* GetInlineStyleRule();
   1.216 +
   1.217 +  /**
   1.218 +   * Set the inline style rule for this element. This will send an appropriate
   1.219 +   * AttributeChanged notification if aNotify is true.
   1.220 +   */
   1.221 +  virtual nsresult SetInlineStyleRule(css::StyleRule* aStyleRule,
   1.222 +                                      const nsAString* aSerialized,
   1.223 +                                      bool aNotify);
   1.224 +
   1.225 +  /**
   1.226 +   * Get the SMIL override style rule for this element. If the rule hasn't been
   1.227 +   * created, this method simply returns null.
   1.228 +   */
   1.229 +  virtual css::StyleRule* GetSMILOverrideStyleRule();
   1.230 +
   1.231 +  /**
   1.232 +   * Set the SMIL override style rule for this element. If aNotify is true, this
   1.233 +   * method will notify the document's pres context, so that the style changes
   1.234 +   * will be noticed.
   1.235 +   */
   1.236 +  virtual nsresult SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
   1.237 +                                            bool aNotify);
   1.238 +
   1.239 +  /**
   1.240 +   * Returns a new nsISMILAttr that allows the caller to animate the given
   1.241 +   * attribute on this element.
   1.242 +   *
   1.243 +   * The CALLER OWNS the result and is responsible for deleting it.
   1.244 +   */
   1.245 +  virtual nsISMILAttr* GetAnimatedAttr(int32_t aNamespaceID, nsIAtom* aName)
   1.246 +  {
   1.247 +    return nullptr;
   1.248 +  }
   1.249 +
   1.250 +  /**
   1.251 +   * Get the SMIL override style for this element. This is a style declaration
   1.252 +   * that is applied *after* the inline style, and it can be used e.g. to store
   1.253 +   * animated style values.
   1.254 +   *
   1.255 +   * Note: This method is analogous to the 'GetStyle' method in
   1.256 +   * nsGenericHTMLElement and nsStyledElement.
   1.257 +   */
   1.258 +  virtual nsICSSDeclaration* GetSMILOverrideStyle();
   1.259 +
   1.260 +  /**
   1.261 +   * Returns if the element is labelable as per HTML specification.
   1.262 +   */
   1.263 +  virtual bool IsLabelable() const;
   1.264 +
   1.265 +  /**
   1.266 +   * Is the attribute named stored in the mapped attributes?
   1.267 +   *
   1.268 +   * // XXXbz we use this method in HasAttributeDependentStyle, so svg
   1.269 +   *    returns true here even though it stores nothing in the mapped
   1.270 +   *    attributes.
   1.271 +   */
   1.272 +  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
   1.273 +
   1.274 +  /**
   1.275 +   * Get a hint that tells the style system what to do when
   1.276 +   * an attribute on this node changes, if something needs to happen
   1.277 +   * in response to the change *other* than the result of what is
   1.278 +   * mapped into style data via any type of style rule.
   1.279 +   */
   1.280 +  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
   1.281 +                                              int32_t aModType) const;
   1.282 +
   1.283 +  /**
   1.284 +   * Returns an atom holding the name of the "class" attribute on this
   1.285 +   * content node (if applicable).  Returns null if there is no
   1.286 +   * "class" attribute for this type of content node.
   1.287 +   */
   1.288 +  virtual nsIAtom *GetClassAttributeName() const;
   1.289 +
   1.290 +  inline Directionality GetDirectionality() const {
   1.291 +    if (HasFlag(NODE_HAS_DIRECTION_RTL)) {
   1.292 +      return eDir_RTL;
   1.293 +    }
   1.294 +
   1.295 +    if (HasFlag(NODE_HAS_DIRECTION_LTR)) {
   1.296 +      return eDir_LTR;
   1.297 +    }
   1.298 +
   1.299 +    return eDir_NotSet;
   1.300 +  }
   1.301 +
   1.302 +  inline void SetDirectionality(Directionality aDir, bool aNotify) {
   1.303 +    UnsetFlags(NODE_ALL_DIRECTION_FLAGS);
   1.304 +    if (!aNotify) {
   1.305 +      RemoveStatesSilently(DIRECTION_STATES);
   1.306 +    }
   1.307 +
   1.308 +    switch (aDir) {
   1.309 +      case (eDir_RTL):
   1.310 +        SetFlags(NODE_HAS_DIRECTION_RTL);
   1.311 +        if (!aNotify) {
   1.312 +          AddStatesSilently(NS_EVENT_STATE_RTL);
   1.313 +        }
   1.314 +        break;
   1.315 +
   1.316 +      case(eDir_LTR):
   1.317 +        SetFlags(NODE_HAS_DIRECTION_LTR);
   1.318 +        if (!aNotify) {
   1.319 +          AddStatesSilently(NS_EVENT_STATE_LTR);
   1.320 +        }
   1.321 +        break;
   1.322 +
   1.323 +      default:
   1.324 +        break;
   1.325 +    }
   1.326 +
   1.327 +    /* 
   1.328 +     * Only call UpdateState if we need to notify, because we call
   1.329 +     * SetDirectionality for every element, and UpdateState is very very slow
   1.330 +     * for some elements.
   1.331 +     */
   1.332 +    if (aNotify) {
   1.333 +      UpdateState(true);
   1.334 +    }
   1.335 +  }
   1.336 +
   1.337 +  bool GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult);
   1.338 +
   1.339 +  // The bdi element defaults to dir=auto if it has no dir attribute set.
   1.340 +  // Other elements will only have dir=auto if they have an explicit dir=auto,
   1.341 +  // which will mean that HasValidDir() returns true but HasFixedDir() returns
   1.342 +  // false
   1.343 +  inline bool HasDirAuto() const {
   1.344 +    return (!HasFixedDir() &&
   1.345 +            (HasValidDir() || IsHTML(nsGkAtoms::bdi)));
   1.346 +  }
   1.347 +
   1.348 +  Directionality GetComputedDirectionality() const;
   1.349 +
   1.350 +protected:
   1.351 +  /**
   1.352 +   * Method to get the _intrinsic_ content state of this element.  This is the
   1.353 +   * state that is independent of the element's presentation.  To get the full
   1.354 +   * content state, use State().  See mozilla/EventStates.h for
   1.355 +   * the possible bits that could be set here.
   1.356 +   */
   1.357 +  virtual EventStates IntrinsicState() const;
   1.358 +
   1.359 +  /**
   1.360 +   * Method to add state bits.  This should be called from subclass
   1.361 +   * constructors to set up our event state correctly at construction
   1.362 +   * time and other places where we don't want to notify a state
   1.363 +   * change.
   1.364 +   */
   1.365 +  void AddStatesSilently(EventStates aStates)
   1.366 +  {
   1.367 +    mState |= aStates;
   1.368 +  }
   1.369 +
   1.370 +  /**
   1.371 +   * Method to remove state bits.  This should be called from subclass
   1.372 +   * constructors to set up our event state correctly at construction
   1.373 +   * time and other places where we don't want to notify a state
   1.374 +   * change.
   1.375 +   */
   1.376 +  void RemoveStatesSilently(EventStates aStates)
   1.377 +  {
   1.378 +    mState &= ~aStates;
   1.379 +  }
   1.380 +
   1.381 +private:
   1.382 +  // Need to allow the ESM, nsGlobalWindow, and the focus manager to
   1.383 +  // set our state
   1.384 +  friend class mozilla::EventStateManager;
   1.385 +  friend class ::nsGlobalWindow;
   1.386 +  friend class ::nsFocusManager;
   1.387 +
   1.388 +  // Also need to allow Link to call UpdateLinkState.
   1.389 +  friend class Link;
   1.390 +
   1.391 +  void NotifyStateChange(EventStates aStates);
   1.392 +
   1.393 +  void NotifyStyleStateChange(EventStates aStates);
   1.394 +
   1.395 +  // Style state computed from element's state and style locks.
   1.396 +  EventStates StyleStateFromLocks() const;
   1.397 +
   1.398 +protected:
   1.399 +  // Methods for the ESM to manage state bits.  These will handle
   1.400 +  // setting up script blockers when they notify, so no need to do it
   1.401 +  // in the callers unless desired.
   1.402 +  virtual void AddStates(EventStates aStates)
   1.403 +  {
   1.404 +    NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
   1.405 +                    "Should only be adding ESM-managed states here");
   1.406 +    AddStatesSilently(aStates);
   1.407 +    NotifyStateChange(aStates);
   1.408 +  }
   1.409 +  virtual void RemoveStates(EventStates aStates)
   1.410 +  {
   1.411 +    NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
   1.412 +                    "Should only be removing ESM-managed states here");
   1.413 +    RemoveStatesSilently(aStates);
   1.414 +    NotifyStateChange(aStates);
   1.415 +  }
   1.416 +public:
   1.417 +  virtual void UpdateEditableState(bool aNotify) MOZ_OVERRIDE;
   1.418 +
   1.419 +  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
   1.420 +                              nsIContent* aBindingParent,
   1.421 +                              bool aCompileEventHandlers) MOZ_OVERRIDE;
   1.422 +  virtual void UnbindFromTree(bool aDeep = true,
   1.423 +                              bool aNullParent = true) MOZ_OVERRIDE;
   1.424 +
   1.425 +  /**
   1.426 +   * Normalizes an attribute name and returns it as a nodeinfo if an attribute
   1.427 +   * with that name exists. This method is intended for character case
   1.428 +   * conversion if the content object is case insensitive (e.g. HTML). Returns
   1.429 +   * the nodeinfo of the attribute with the specified name if one exists or
   1.430 +   * null otherwise.
   1.431 +   *
   1.432 +   * @param aStr the unparsed attribute string
   1.433 +   * @return the node info. May be nullptr.
   1.434 +   */
   1.435 +  already_AddRefed<nsINodeInfo>
   1.436 +  GetExistingAttrNameFromQName(const nsAString& aStr) const;
   1.437 +
   1.438 +  nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
   1.439 +                   const nsAString& aValue, bool aNotify)
   1.440 +  {
   1.441 +    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   1.442 +  }
   1.443 +
   1.444 +  /**
   1.445 +   * Helper for SetAttr/SetParsedAttr. This method will return true if aNotify
   1.446 +   * is true or there are mutation listeners that must be triggered, the
   1.447 +   * attribute is currently set, and the new value that is about to be set is
   1.448 +   * different to the current value. As a perf optimization the new and old
   1.449 +   * values will not actually be compared if we aren't notifying and we don't
   1.450 +   * have mutation listeners (in which case it's cheap to just return false
   1.451 +   * and let the caller go ahead and set the value).
   1.452 +   * @param aOldValue Set to the old value of the attribute, but only if there
   1.453 +   *   are event listeners. If set, the type of aOldValue will be either
   1.454 +   *   nsAttrValue::eString or nsAttrValue::eAtom.
   1.455 +   * @param aModType Set to nsIDOMMutationEvent::MODIFICATION or to
   1.456 +   *   nsIDOMMutationEvent::ADDITION, but only if this helper returns true
   1.457 +   * @param aHasListeners Set to true if there are mutation event listeners
   1.458 +   *   listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
   1.459 +   */
   1.460 +  bool MaybeCheckSameAttrVal(int32_t aNamespaceID, nsIAtom* aName,
   1.461 +                             nsIAtom* aPrefix,
   1.462 +                             const nsAttrValueOrString& aValue,
   1.463 +                             bool aNotify, nsAttrValue& aOldValue,
   1.464 +                             uint8_t* aModType, bool* aHasListeners);
   1.465 +
   1.466 +  bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName,
   1.467 +                              nsIAtom* aPrefix,
   1.468 +                              const nsAttrValueOrString& aValue,
   1.469 +                              bool aNotify, nsAttrValue& aOldValue,
   1.470 +                              uint8_t* aModType, bool* aHasListeners);
   1.471 +
   1.472 +  virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
   1.473 +                           const nsAString& aValue, bool aNotify) MOZ_OVERRIDE;
   1.474 +  nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
   1.475 +                         nsAttrValue& aParsedValue, bool aNotify);
   1.476 +  // GetAttr is not inlined on purpose, to keep down codesize from all
   1.477 +  // the inlined nsAttrValue bits for C++ callers.
   1.478 +  bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
   1.479 +               nsAString& aResult) const;
   1.480 +  inline bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
   1.481 +  // aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching.
   1.482 +  inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
   1.483 +                          const nsAString& aValue,
   1.484 +                          nsCaseTreatment aCaseSensitive) const;
   1.485 +  inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
   1.486 +                          nsIAtom* aValue,
   1.487 +                          nsCaseTreatment aCaseSensitive) const;
   1.488 +  virtual int32_t FindAttrValueIn(int32_t aNameSpaceID,
   1.489 +                                  nsIAtom* aName,
   1.490 +                                  AttrValuesArray* aValues,
   1.491 +                                  nsCaseTreatment aCaseSensitive) const MOZ_OVERRIDE;
   1.492 +  virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
   1.493 +                             bool aNotify) MOZ_OVERRIDE;
   1.494 +  virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const MOZ_OVERRIDE;
   1.495 +  virtual uint32_t GetAttrCount() const MOZ_OVERRIDE;
   1.496 +  virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
   1.497 +
   1.498 +#ifdef DEBUG
   1.499 +  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE
   1.500 +  {
   1.501 +    List(out, aIndent, EmptyCString());
   1.502 +  }
   1.503 +  virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const MOZ_OVERRIDE;
   1.504 +  void List(FILE* out, int32_t aIndent, const nsCString& aPrefix) const;
   1.505 +  void ListAttributes(FILE* out) const;
   1.506 +#endif
   1.507 +
   1.508 +  void Describe(nsAString& aOutDescription) const MOZ_OVERRIDE;
   1.509 +
   1.510 +  /*
   1.511 +   * Attribute Mapping Helpers
   1.512 +   */
   1.513 +  struct MappedAttributeEntry {
   1.514 +    nsIAtom** attribute;
   1.515 +  };
   1.516 +
   1.517 +  /**
   1.518 +   * A common method where you can just pass in a list of maps to check
   1.519 +   * for attribute dependence. Most implementations of
   1.520 +   * IsAttributeMapped should use this function as a default
   1.521 +   * handler.
   1.522 +   */
   1.523 +  template<size_t N>
   1.524 +  static bool
   1.525 +  FindAttributeDependence(const nsIAtom* aAttribute,
   1.526 +                          const MappedAttributeEntry* const (&aMaps)[N])
   1.527 +  {
   1.528 +    return FindAttributeDependence(aAttribute, aMaps, N);
   1.529 +  }
   1.530 +
   1.531 +private:
   1.532 +  void DescribeAttribute(uint32_t index, nsAString& aOutDescription) const;
   1.533 +
   1.534 +  static bool
   1.535 +  FindAttributeDependence(const nsIAtom* aAttribute,
   1.536 +                          const MappedAttributeEntry* const aMaps[],
   1.537 +                          uint32_t aMapCount);
   1.538 +
   1.539 +protected:
   1.540 +  inline bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
   1.541 +                      DOMString& aResult) const
   1.542 +  {
   1.543 +    NS_ASSERTION(nullptr != aName, "must have attribute name");
   1.544 +    NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
   1.545 +                 "must have a real namespace ID!");
   1.546 +    MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0,
   1.547 +               "Should have empty string coming in");
   1.548 +    const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
   1.549 +    if (val) {
   1.550 +      val->ToString(aResult);
   1.551 +      return true;
   1.552 +    }
   1.553 +    // else DOMString comes pre-emptied.
   1.554 +    return false;
   1.555 +  }
   1.556 +
   1.557 +public:
   1.558 +  bool HasAttrs() const { return mAttrsAndChildren.HasAttrs(); }
   1.559 +
   1.560 +  inline bool GetAttr(const nsAString& aName, DOMString& aResult) const
   1.561 +  {
   1.562 +    MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0,
   1.563 +               "Should have empty string coming in");
   1.564 +    const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName);
   1.565 +    if (val) {
   1.566 +      val->ToString(aResult);
   1.567 +      return true;
   1.568 +    }
   1.569 +    // else DOMString comes pre-emptied.
   1.570 +    return false;
   1.571 +  }
   1.572 +
   1.573 +  void GetTagName(nsAString& aTagName) const
   1.574 +  {
   1.575 +    aTagName = NodeName();
   1.576 +  }
   1.577 +  void GetId(nsAString& aId) const
   1.578 +  {
   1.579 +    GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
   1.580 +  }
   1.581 +  void GetId(DOMString& aId) const
   1.582 +  {
   1.583 +    GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
   1.584 +  }
   1.585 +  void SetId(const nsAString& aId)
   1.586 +  {
   1.587 +    SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
   1.588 +  }
   1.589 +
   1.590 +  nsDOMTokenList* GetClassList();
   1.591 +  nsDOMAttributeMap* Attributes()
   1.592 +  {
   1.593 +    nsDOMSlots* slots = DOMSlots();
   1.594 +    if (!slots->mAttributeMap) {
   1.595 +      slots->mAttributeMap = new nsDOMAttributeMap(this);
   1.596 +    }
   1.597 +
   1.598 +    return slots->mAttributeMap;
   1.599 +  }
   1.600 +  void GetAttribute(const nsAString& aName, nsString& aReturn)
   1.601 +  {
   1.602 +    DOMString str;
   1.603 +    GetAttribute(aName, str);
   1.604 +    str.ToString(aReturn);
   1.605 +  }
   1.606 +
   1.607 +  void GetAttribute(const nsAString& aName, DOMString& aReturn);
   1.608 +  void GetAttributeNS(const nsAString& aNamespaceURI,
   1.609 +                      const nsAString& aLocalName,
   1.610 +                      nsAString& aReturn);
   1.611 +  void SetAttribute(const nsAString& aName, const nsAString& aValue,
   1.612 +                    ErrorResult& aError);
   1.613 +  void SetAttributeNS(const nsAString& aNamespaceURI,
   1.614 +                      const nsAString& aLocalName,
   1.615 +                      const nsAString& aValue,
   1.616 +                      ErrorResult& aError);
   1.617 +  void RemoveAttribute(const nsAString& aName,
   1.618 +                       ErrorResult& aError);
   1.619 +  void RemoveAttributeNS(const nsAString& aNamespaceURI,
   1.620 +                         const nsAString& aLocalName,
   1.621 +                         ErrorResult& aError);
   1.622 +  bool HasAttribute(const nsAString& aName) const
   1.623 +  {
   1.624 +    return InternalGetExistingAttrNameFromQName(aName) != nullptr;
   1.625 +  }
   1.626 +  bool HasAttributeNS(const nsAString& aNamespaceURI,
   1.627 +                      const nsAString& aLocalName) const;
   1.628 +  already_AddRefed<nsIHTMLCollection>
   1.629 +    GetElementsByTagName(const nsAString& aQualifiedName);
   1.630 +  already_AddRefed<nsIHTMLCollection>
   1.631 +    GetElementsByTagNameNS(const nsAString& aNamespaceURI,
   1.632 +                           const nsAString& aLocalName,
   1.633 +                           ErrorResult& aError);
   1.634 +  already_AddRefed<nsIHTMLCollection>
   1.635 +    GetElementsByClassName(const nsAString& aClassNames);
   1.636 +  bool MozMatchesSelector(const nsAString& aSelector,
   1.637 +                          ErrorResult& aError);
   1.638 +  void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
   1.639 +  {
   1.640 +    bool activeState = false;
   1.641 +    if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
   1.642 +      aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
   1.643 +      return;
   1.644 +    }
   1.645 +    if (!activeState) {
   1.646 +      return;
   1.647 +    }
   1.648 +    nsIPresShell::SetPointerCapturingContent(aPointerId, this);
   1.649 +  }
   1.650 +  void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError)
   1.651 +  {
   1.652 +    bool activeState = false;
   1.653 +    if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
   1.654 +      aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
   1.655 +      return;
   1.656 +    }
   1.657 +
   1.658 +    // Ignoring ReleasePointerCapture call on incorrect element (on element
   1.659 +    // that didn't have capture before).
   1.660 +    if (nsIPresShell::GetPointerCapturingContent(aPointerId) == this) {
   1.661 +      nsIPresShell::ReleasePointerCapturingContent(aPointerId, this);
   1.662 +    }
   1.663 +  }
   1.664 +  void SetCapture(bool aRetargetToElement)
   1.665 +  {
   1.666 +    // If there is already an active capture, ignore this request. This would
   1.667 +    // occur if a splitter, frame resizer, etc had already captured and we don't
   1.668 +    // want to override those.
   1.669 +    if (!nsIPresShell::GetCapturingContent()) {
   1.670 +      nsIPresShell::SetCapturingContent(this, CAPTURE_PREVENTDRAG |
   1.671 +        (aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
   1.672 +    }
   1.673 +  }
   1.674 +  void ReleaseCapture()
   1.675 +  {
   1.676 +    if (nsIPresShell::GetCapturingContent() == this) {
   1.677 +      nsIPresShell::SetCapturingContent(nullptr, 0);
   1.678 +    }
   1.679 +  }
   1.680 +  void MozRequestFullScreen();
   1.681 +  void MozRequestPointerLock();
   1.682 +  Attr* GetAttributeNode(const nsAString& aName);
   1.683 +  already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr,
   1.684 +                                          ErrorResult& aError);
   1.685 +  already_AddRefed<Attr> RemoveAttributeNode(Attr& aOldAttr,
   1.686 +                                             ErrorResult& aError);
   1.687 +  Attr* GetAttributeNodeNS(const nsAString& aNamespaceURI,
   1.688 +                           const nsAString& aLocalName);
   1.689 +  already_AddRefed<Attr> SetAttributeNodeNS(Attr& aNewAttr,
   1.690 +                                            ErrorResult& aError);
   1.691 +
   1.692 +  already_AddRefed<DOMRectList> GetClientRects();
   1.693 +  already_AddRefed<DOMRect> GetBoundingClientRect();
   1.694 +
   1.695 +  already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
   1.696 +
   1.697 +  void ScrollIntoView()
   1.698 +  {
   1.699 +    ScrollIntoView(true);
   1.700 +  }
   1.701 +  void ScrollIntoView(bool aTop);
   1.702 +  int32_t ScrollTop()
   1.703 +  {
   1.704 +    nsIScrollableFrame* sf = GetScrollFrame();
   1.705 +    return sf ? sf->GetScrollPositionCSSPixels().y : 0;
   1.706 +  }
   1.707 +  void SetScrollTop(int32_t aScrollTop)
   1.708 +  {
   1.709 +    nsIScrollableFrame* sf = GetScrollFrame();
   1.710 +    if (sf) {
   1.711 +      sf->ScrollToCSSPixels(CSSIntPoint(sf->GetScrollPositionCSSPixels().x,
   1.712 +                                        aScrollTop));
   1.713 +    }
   1.714 +  }
   1.715 +  int32_t ScrollLeft()
   1.716 +  {
   1.717 +    nsIScrollableFrame* sf = GetScrollFrame();
   1.718 +    return sf ? sf->GetScrollPositionCSSPixels().x : 0;
   1.719 +  }
   1.720 +  void SetScrollLeft(int32_t aScrollLeft)
   1.721 +  {
   1.722 +    nsIScrollableFrame* sf = GetScrollFrame();
   1.723 +    if (sf) {
   1.724 +      sf->ScrollToCSSPixels(CSSIntPoint(aScrollLeft,
   1.725 +                                        sf->GetScrollPositionCSSPixels().y));
   1.726 +    }
   1.727 +  }
   1.728 +  /* Scrolls without flushing the layout.
   1.729 +   * aDx is the x offset, aDy the y offset in CSS pixels.
   1.730 +   * Returns true if we actually scrolled.
   1.731 +   */
   1.732 +  bool ScrollByNoFlush(int32_t aDx, int32_t aDy);
   1.733 +  int32_t ScrollWidth();
   1.734 +  int32_t ScrollHeight();
   1.735 +  int32_t ClientTop()
   1.736 +  {
   1.737 +    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y);
   1.738 +  }
   1.739 +  int32_t ClientLeft()
   1.740 +  {
   1.741 +    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x);
   1.742 +  }
   1.743 +  int32_t ClientWidth()
   1.744 +  {
   1.745 +    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width);
   1.746 +  }
   1.747 +  int32_t ClientHeight()
   1.748 +  {
   1.749 +    return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height);
   1.750 +  }
   1.751 +  int32_t ScrollTopMax()
   1.752 +  {
   1.753 +    nsIScrollableFrame* sf = GetScrollFrame();
   1.754 +    return sf ?
   1.755 +           nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().YMost()) :
   1.756 +           0;
   1.757 +  }
   1.758 +  int32_t ScrollLeftMax()
   1.759 +  {
   1.760 +    nsIScrollableFrame* sf = GetScrollFrame();
   1.761 +    return sf ?
   1.762 +           nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().XMost()) :
   1.763 +           0;
   1.764 +  }
   1.765 +
   1.766 +  virtual already_AddRefed<UndoManager> GetUndoManager()
   1.767 +  {
   1.768 +    return nullptr;
   1.769 +  }
   1.770 +
   1.771 +  virtual bool UndoScope()
   1.772 +  {
   1.773 +    return false;
   1.774 +  }
   1.775 +
   1.776 +  virtual void SetUndoScope(bool aUndoScope, ErrorResult& aError)
   1.777 +  {
   1.778 +  }
   1.779 +
   1.780 +  NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   1.781 +  virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
   1.782 +  void GetOuterHTML(nsAString& aOuterHTML);
   1.783 +  void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
   1.784 +  void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
   1.785 +                          ErrorResult& aError);
   1.786 +
   1.787 +  //----------------------------------------
   1.788 +
   1.789 +  /**
   1.790 +   * Add a script event listener with the given event handler name
   1.791 +   * (like onclick) and with the value as JS
   1.792 +   * @param aEventName the event listener name
   1.793 +   * @param aValue the JS to attach
   1.794 +   * @param aDefer indicates if deferred execution is allowed
   1.795 +   */
   1.796 +  nsresult SetEventHandler(nsIAtom* aEventName,
   1.797 +                           const nsAString& aValue,
   1.798 +                           bool aDefer = true);
   1.799 +
   1.800 +  /**
   1.801 +   * Do whatever needs to be done when the mouse leaves a link
   1.802 +   */
   1.803 +  nsresult LeaveLink(nsPresContext* aPresContext);
   1.804 +
   1.805 +  static bool ShouldBlur(nsIContent *aContent);
   1.806 +
   1.807 +  /**
   1.808 +   * Method to create and dispatch a left-click event loosely based on
   1.809 +   * aSourceEvent. If aFullDispatch is true, the event will be dispatched
   1.810 +   * through the full dispatching of the presshell of the aPresContext; if it's
   1.811 +   * false the event will be dispatched only as a DOM event.
   1.812 +   * If aPresContext is nullptr, this does nothing.
   1.813 +   *
   1.814 +   * @param aFlags      Extra flags for the dispatching event.  The true flags
   1.815 +   *                    will be respected.
   1.816 +   */
   1.817 +  static nsresult DispatchClickEvent(nsPresContext* aPresContext,
   1.818 +                                     WidgetInputEvent* aSourceEvent,
   1.819 +                                     nsIContent* aTarget,
   1.820 +                                     bool aFullDispatch,
   1.821 +                                     const EventFlags* aFlags,
   1.822 +                                     nsEventStatus* aStatus);
   1.823 +
   1.824 +  /**
   1.825 +   * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event
   1.826 +   * will be dispatched through the full dispatching of the presshell of the
   1.827 +   * aPresContext; if it's false the event will be dispatched only as a DOM
   1.828 +   * event.
   1.829 +   * If aPresContext is nullptr, this does nothing.
   1.830 +   */
   1.831 +  using nsIContent::DispatchEvent;
   1.832 +  static nsresult DispatchEvent(nsPresContext* aPresContext,
   1.833 +                                WidgetEvent* aEvent,
   1.834 +                                nsIContent* aTarget,
   1.835 +                                bool aFullDispatch,
   1.836 +                                nsEventStatus* aStatus);
   1.837 +
   1.838 +  /**
   1.839 +   * Get the primary frame for this content with flushing
   1.840 +   *
   1.841 +   * @param aType the kind of flush to do, typically Flush_Frames or
   1.842 +   *              Flush_Layout
   1.843 +   * @return the primary frame
   1.844 +   */
   1.845 +  nsIFrame* GetPrimaryFrame(mozFlushType aType);
   1.846 +  // Work around silly C++ name hiding stuff
   1.847 +  nsIFrame* GetPrimaryFrame() const { return nsIContent::GetPrimaryFrame(); }
   1.848 +
   1.849 +  /**
   1.850 +   * Struct that stores info on an attribute.  The name and value must
   1.851 +   * either both be null or both be non-null.
   1.852 +   */
   1.853 +  struct nsAttrInfo {
   1.854 +    nsAttrInfo(const nsAttrName* aName, const nsAttrValue* aValue) :
   1.855 +      mName(aName), mValue(aValue) {}
   1.856 +    nsAttrInfo(const nsAttrInfo& aOther) :
   1.857 +      mName(aOther.mName), mValue(aOther.mValue) {}
   1.858 +
   1.859 +    const nsAttrName* mName;
   1.860 +    const nsAttrValue* mValue;
   1.861 +  };
   1.862 +
   1.863 +  // Be careful when using this method. This does *NOT* handle
   1.864 +  // XUL prototypes. You may want to use GetAttrInfo.
   1.865 +  const nsAttrValue* GetParsedAttr(nsIAtom* aAttr) const
   1.866 +  {
   1.867 +    return mAttrsAndChildren.GetAttr(aAttr);
   1.868 +  }
   1.869 +
   1.870 +  /**
   1.871 +   * Returns the attribute map, if there is one.
   1.872 +   *
   1.873 +   * @return existing attribute map or nullptr.
   1.874 +   */
   1.875 +  nsDOMAttributeMap *GetAttributeMap()
   1.876 +  {
   1.877 +    nsDOMSlots *slots = GetExistingDOMSlots();
   1.878 +
   1.879 +    return slots ? slots->mAttributeMap.get() : nullptr;
   1.880 +  }
   1.881 +
   1.882 +  virtual void RecompileScriptEventListeners()
   1.883 +  {
   1.884 +  }
   1.885 +
   1.886 +  /**
   1.887 +   * Get the attr info for the given namespace ID and attribute name.  The
   1.888 +   * namespace ID must not be kNameSpaceID_Unknown and the name must not be
   1.889 +   * null.  Note that this can only return info on attributes that actually
   1.890 +   * live on this element (and is only virtual to handle XUL prototypes).  That
   1.891 +   * is, this should only be called from methods that only care about attrs
   1.892 +   * that effectively live in mAttrsAndChildren.
   1.893 +   */
   1.894 +  virtual nsAttrInfo GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const;
   1.895 +
   1.896 +  virtual void NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
   1.897 +  {
   1.898 +  }
   1.899 +
   1.900 +  /**
   1.901 +   * Parse a string into an nsAttrValue for a CORS attribute.  This
   1.902 +   * never fails.  The resulting value is an enumerated value whose
   1.903 +   * GetEnumValue() returns one of the above constants.
   1.904 +   */
   1.905 +  static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
   1.906 +
   1.907 +  /**
   1.908 +   * Return the CORS mode for a given string
   1.909 +   */
   1.910 +  static CORSMode StringToCORSMode(const nsAString& aValue);
   1.911 +  
   1.912 +  /**
   1.913 +   * Return the CORS mode for a given nsAttrValue (which may be null,
   1.914 +   * but if not should have been parsed via ParseCORSValue).
   1.915 +   */
   1.916 +  static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
   1.917 +
   1.918 +  // These are just used to implement nsIDOMElement using
   1.919 +  // NS_FORWARD_NSIDOMELEMENT_TO_GENERIC and for quickstubs.
   1.920 +  void
   1.921 +    GetElementsByTagName(const nsAString& aQualifiedName,
   1.922 +                         nsIDOMHTMLCollection** aResult);
   1.923 +  nsresult
   1.924 +    GetElementsByTagNameNS(const nsAString& aNamespaceURI,
   1.925 +                           const nsAString& aLocalName,
   1.926 +                           nsIDOMHTMLCollection** aResult);
   1.927 +  nsresult
   1.928 +    GetElementsByClassName(const nsAString& aClassNames,
   1.929 +                           nsIDOMHTMLCollection** aResult);
   1.930 +  void GetClassList(nsISupports** aClassList);
   1.931 +
   1.932 +  virtual JSObject* WrapObject(JSContext *aCx) MOZ_FINAL MOZ_OVERRIDE;
   1.933 +
   1.934 +  /**
   1.935 +   * Locate an nsIEditor rooted at this content node, if there is one.
   1.936 +   */
   1.937 +  nsIEditor* GetEditorInternal();
   1.938 +
   1.939 +  /**
   1.940 +   * Helper method for NS_IMPL_BOOL_ATTR macro.
   1.941 +   * Gets value of boolean attribute. Only works for attributes in null
   1.942 +   * namespace.
   1.943 +   *
   1.944 +   * @param aAttr    name of attribute.
   1.945 +   * @param aValue   Boolean value of attribute.
   1.946 +   */
   1.947 +  NS_HIDDEN_(bool) GetBoolAttr(nsIAtom* aAttr) const
   1.948 +  {
   1.949 +    return HasAttr(kNameSpaceID_None, aAttr);
   1.950 +  }
   1.951 +
   1.952 +  /**
   1.953 +   * Helper method for NS_IMPL_BOOL_ATTR macro.
   1.954 +   * Sets value of boolean attribute by removing attribute or setting it to
   1.955 +   * the empty string. Only works for attributes in null namespace.
   1.956 +   *
   1.957 +   * @param aAttr    name of attribute.
   1.958 +   * @param aValue   Boolean value of attribute.
   1.959 +   */
   1.960 +  NS_HIDDEN_(nsresult) SetBoolAttr(nsIAtom* aAttr, bool aValue);
   1.961 +
   1.962 +  /**
   1.963 +   * Retrieve the ratio of font-size-inflated text font size to computed font
   1.964 +   * size for this element. This will query the element for its primary frame,
   1.965 +   * and then use this to get font size inflation information about the frame.
   1.966 +   *
   1.967 +   * @returns The font size inflation ratio (inflated font size to uninflated
   1.968 +   *          font size) for the primary frame of this element. Returns 1.0
   1.969 +   *          by default if font size inflation is not enabled. Returns -1
   1.970 +   *          if the element does not have a primary frame.
   1.971 +   *
   1.972 +   * @note The font size inflation ratio that is returned is actually the
   1.973 +   *       font size inflation data for the element's _primary frame_, not the
   1.974 +   *       element itself, but for most purposes, this should be sufficient.
   1.975 +   */
   1.976 +  float FontSizeInflation();
   1.977 +
   1.978 +protected:
   1.979 +  /*
   1.980 +   * Named-bools for use with SetAttrAndNotify to make call sites easier to
   1.981 +   * read.
   1.982 +   */
   1.983 +  static const bool kFireMutationEvent           = true;
   1.984 +  static const bool kDontFireMutationEvent       = false;
   1.985 +  static const bool kNotifyDocumentObservers     = true;
   1.986 +  static const bool kDontNotifyDocumentObservers = false;
   1.987 +  static const bool kCallAfterSetAttr            = true;
   1.988 +  static const bool kDontCallAfterSetAttr        = false;
   1.989 +
   1.990 +  /**
   1.991 +   * Set attribute and (if needed) notify documentobservers and fire off
   1.992 +   * mutation events.  This will send the AttributeChanged notification.
   1.993 +   * Callers of this method are responsible for calling AttributeWillChange,
   1.994 +   * since that needs to happen before the new attr value has been set, and
   1.995 +   * in particular before it has been parsed.
   1.996 +   *
   1.997 +   * For the boolean parameters, consider using the named bools above to aid
   1.998 +   * code readability.
   1.999 +   *
  1.1000 +   * @param aNamespaceID  namespace of attribute
  1.1001 +   * @param aAttribute    local-name of attribute
  1.1002 +   * @param aPrefix       aPrefix of attribute
  1.1003 +   * @param aOldValue     previous value of attribute. Only needed if
  1.1004 +   *                      aFireMutation is true or if the element is a
  1.1005 +   *                      custom element (in web components).
  1.1006 +   * @param aParsedValue  parsed new value of attribute
  1.1007 +   * @param aModType      nsIDOMMutationEvent::MODIFICATION or ADDITION.  Only
  1.1008 +   *                      needed if aFireMutation or aNotify is true.
  1.1009 +   * @param aFireMutation should mutation-events be fired?
  1.1010 +   * @param aNotify       should we notify document-observers?
  1.1011 +   * @param aCallAfterSetAttr should we call AfterSetAttr?
  1.1012 +   */
  1.1013 +  nsresult SetAttrAndNotify(int32_t aNamespaceID,
  1.1014 +                            nsIAtom* aName,
  1.1015 +                            nsIAtom* aPrefix,
  1.1016 +                            const nsAttrValue& aOldValue,
  1.1017 +                            nsAttrValue& aParsedValue,
  1.1018 +                            uint8_t aModType,
  1.1019 +                            bool aFireMutation,
  1.1020 +                            bool aNotify,
  1.1021 +                            bool aCallAfterSetAttr);
  1.1022 +
  1.1023 +  /**
  1.1024 +   * Convert an attribute string value to attribute type based on the type of
  1.1025 +   * attribute.  Called by SetAttr().  Note that at the moment we only do this
  1.1026 +   * for attributes in the null namespace (kNameSpaceID_None).
  1.1027 +   *
  1.1028 +   * @param aNamespaceID the namespace of the attribute to convert
  1.1029 +   * @param aAttribute the attribute to convert
  1.1030 +   * @param aValue the string value to convert
  1.1031 +   * @param aResult the nsAttrValue [OUT]
  1.1032 +   * @return true if the parsing was successful, false otherwise
  1.1033 +   */
  1.1034 +  virtual bool ParseAttribute(int32_t aNamespaceID,
  1.1035 +                                nsIAtom* aAttribute,
  1.1036 +                                const nsAString& aValue,
  1.1037 +                                nsAttrValue& aResult);
  1.1038 +
  1.1039 +  /**
  1.1040 +   * Try to set the attribute as a mapped attribute, if applicable.  This will
  1.1041 +   * only be called for attributes that are in the null namespace and only on
  1.1042 +   * attributes that returned true when passed to IsAttributeMapped.  The
  1.1043 +   * caller will not try to set the attr in any other way if this method
  1.1044 +   * returns true (the value of aRetval does not matter for that purpose).
  1.1045 +   *
  1.1046 +   * @param aDocument the current document of this node (an optimization)
  1.1047 +   * @param aName the name of the attribute
  1.1048 +   * @param aValue the nsAttrValue to set
  1.1049 +   * @param [out] aRetval the nsresult status of the operation, if any.
  1.1050 +   * @return true if the setting was attempted, false otherwise.
  1.1051 +   */
  1.1052 +  virtual bool SetMappedAttribute(nsIDocument* aDocument,
  1.1053 +                                    nsIAtom* aName,
  1.1054 +                                    nsAttrValue& aValue,
  1.1055 +                                    nsresult* aRetval);
  1.1056 +
  1.1057 +  /**
  1.1058 +   * Hook that is called by Element::SetAttr to allow subclasses to
  1.1059 +   * deal with attribute sets.  This will only be called after we verify that
  1.1060 +   * we're actually doing an attr set and will be called before
  1.1061 +   * AttributeWillChange and before ParseAttribute and hence before we've set
  1.1062 +   * the new value.
  1.1063 +   *
  1.1064 +   * @param aNamespaceID the namespace of the attr being set
  1.1065 +   * @param aName the localname of the attribute being set
  1.1066 +   * @param aValue the value it's being set to represented as either a string or
  1.1067 +   *        a parsed nsAttrValue. Alternatively, if the attr is being removed it
  1.1068 +   *        will be null.
  1.1069 +   * @param aNotify Whether we plan to notify document observers.
  1.1070 +   */
  1.1071 +  // Note that this is inlined so that when subclasses call it it gets
  1.1072 +  // inlined.  Those calls don't go through a vtable.
  1.1073 +  virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
  1.1074 +                                 const nsAttrValueOrString* aValue,
  1.1075 +                                 bool aNotify)
  1.1076 +  {
  1.1077 +    return NS_OK;
  1.1078 +  }
  1.1079 +
  1.1080 +  /**
  1.1081 +   * Hook that is called by Element::SetAttr to allow subclasses to
  1.1082 +   * deal with attribute sets.  This will only be called after we have called
  1.1083 +   * SetAndTakeAttr and AttributeChanged (that is, after we have actually set
  1.1084 +   * the attr).  It will always be called under a scriptblocker.
  1.1085 +   *
  1.1086 +   * @param aNamespaceID the namespace of the attr being set
  1.1087 +   * @param aName the localname of the attribute being set
  1.1088 +   * @param aValue the value it's being set to.  If null, the attr is being
  1.1089 +   *        removed.
  1.1090 +   * @param aNotify Whether we plan to notify document observers.
  1.1091 +   */
  1.1092 +  // Note that this is inlined so that when subclasses call it it gets
  1.1093 +  // inlined.  Those calls don't go through a vtable.
  1.1094 +  virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
  1.1095 +                                const nsAttrValue* aValue, bool aNotify)
  1.1096 +  {
  1.1097 +    return NS_OK;
  1.1098 +  }
  1.1099 +
  1.1100 +  /**
  1.1101 +   * Hook to allow subclasses to produce a different EventListenerManager if
  1.1102 +   * needed for attachment of attribute-defined handlers
  1.1103 +   */
  1.1104 +  virtual EventListenerManager*
  1.1105 +    GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
  1.1106 +
  1.1107 +  /**
  1.1108 +   * Internal hook for converting an attribute name-string to an atomized name
  1.1109 +   */
  1.1110 +  virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
  1.1111 +
  1.1112 +  nsIFrame* GetStyledFrame();
  1.1113 +
  1.1114 +  virtual Element* GetNameSpaceElement()
  1.1115 +  {
  1.1116 +    return this;
  1.1117 +  }
  1.1118 +
  1.1119 +  Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
  1.1120 +                                   const nsAString& aLocalName);
  1.1121 +
  1.1122 +  inline void RegisterFreezableElement();
  1.1123 +  inline void UnregisterFreezableElement();
  1.1124 +
  1.1125 +  /**
  1.1126 +   * Add/remove this element to the documents id cache
  1.1127 +   */
  1.1128 +  void AddToIdTable(nsIAtom* aId);
  1.1129 +  void RemoveFromIdTable(); // checks HasID() and uses DoGetID()
  1.1130 +  void RemoveFromIdTable(nsIAtom* aId);
  1.1131 +
  1.1132 +  /**
  1.1133 +   * Functions to carry out event default actions for links of all types
  1.1134 +   * (HTML links, XLinks, SVG "XLinks", etc.)
  1.1135 +   */
  1.1136 +
  1.1137 +  /**
  1.1138 +   * Check that we meet the conditions to handle a link event
  1.1139 +   * and that we are actually on a link.
  1.1140 +   *
  1.1141 +   * @param aVisitor event visitor
  1.1142 +   * @param aURI the uri of the link, set only if the return value is true [OUT]
  1.1143 +   * @return true if we can handle the link event, false otherwise
  1.1144 +   */
  1.1145 +  bool CheckHandleEventForLinksPrecondition(EventChainVisitor& aVisitor,
  1.1146 +                                            nsIURI** aURI) const;
  1.1147 +
  1.1148 +  /**
  1.1149 +   * Handle status bar updates before they can be cancelled.
  1.1150 +   */
  1.1151 +  nsresult PreHandleEventForLinks(EventChainPreVisitor& aVisitor);
  1.1152 +
  1.1153 +  /**
  1.1154 +   * Handle default actions for link event if the event isn't consumed yet.
  1.1155 +   */
  1.1156 +  nsresult PostHandleEventForLinks(EventChainPostVisitor& aVisitor);
  1.1157 +
  1.1158 +  /**
  1.1159 +   * Get the target of this link element. Consumers should established that
  1.1160 +   * this element is a link (probably using IsLink) before calling this
  1.1161 +   * function (or else why call it?)
  1.1162 +   *
  1.1163 +   * Note: for HTML this gets the value of the 'target' attribute; for XLink
  1.1164 +   * this gets the value of the xlink:_moz_target attribute, or failing that,
  1.1165 +   * the value of xlink:show, converted to a suitably equivalent named target
  1.1166 +   * (e.g. _blank).
  1.1167 +   */
  1.1168 +  virtual void GetLinkTarget(nsAString& aTarget);
  1.1169 +
  1.1170 +private:
  1.1171 +  /**
  1.1172 +   * Get this element's client area rect in app units.
  1.1173 +   * @return the frame's client area
  1.1174 +   */
  1.1175 +  nsRect GetClientAreaRect();
  1.1176 +
  1.1177 +  nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr,
  1.1178 +                                     bool aFlushLayout = true);
  1.1179 +
  1.1180 +  // Data members
  1.1181 +  EventStates mState;
  1.1182 +};
  1.1183 +
  1.1184 +NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
  1.1185 +
  1.1186 +inline bool
  1.1187 +Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
  1.1188 +{
  1.1189 +  NS_ASSERTION(nullptr != aName, "must have attribute name");
  1.1190 +  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
  1.1191 +               "must have a real namespace ID!");
  1.1192 +
  1.1193 +  return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0;
  1.1194 +}
  1.1195 +
  1.1196 +inline bool
  1.1197 +Element::AttrValueIs(int32_t aNameSpaceID,
  1.1198 +                     nsIAtom* aName,
  1.1199 +                     const nsAString& aValue,
  1.1200 +                     nsCaseTreatment aCaseSensitive) const
  1.1201 +{
  1.1202 +  NS_ASSERTION(aName, "Must have attr name");
  1.1203 +  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
  1.1204 +
  1.1205 +  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
  1.1206 +  return val && val->Equals(aValue, aCaseSensitive);
  1.1207 +}
  1.1208 +
  1.1209 +inline bool
  1.1210 +Element::AttrValueIs(int32_t aNameSpaceID,
  1.1211 +                     nsIAtom* aName,
  1.1212 +                     nsIAtom* aValue,
  1.1213 +                     nsCaseTreatment aCaseSensitive) const
  1.1214 +{
  1.1215 +  NS_ASSERTION(aName, "Must have attr name");
  1.1216 +  NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
  1.1217 +  NS_ASSERTION(aValue, "Null value atom");
  1.1218 +
  1.1219 +  const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
  1.1220 +  return val && val->Equals(aValue, aCaseSensitive);
  1.1221 +}
  1.1222 +
  1.1223 +} // namespace dom
  1.1224 +} // namespace mozilla
  1.1225 +
  1.1226 +inline mozilla::dom::Element* nsINode::AsElement()
  1.1227 +{
  1.1228 +  MOZ_ASSERT(IsElement());
  1.1229 +  return static_cast<mozilla::dom::Element*>(this);
  1.1230 +}
  1.1231 +
  1.1232 +inline const mozilla::dom::Element* nsINode::AsElement() const
  1.1233 +{
  1.1234 +  MOZ_ASSERT(IsElement());
  1.1235 +  return static_cast<const mozilla::dom::Element*>(this);
  1.1236 +}
  1.1237 +
  1.1238 +inline bool nsINode::HasAttributes() const
  1.1239 +{
  1.1240 +  return IsElement() && AsElement()->HasAttrs();
  1.1241 +}
  1.1242 +
  1.1243 +/**
  1.1244 + * Macros to implement Clone(). _elementName is the class for which to implement
  1.1245 + * Clone.
  1.1246 + */
  1.1247 +#define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
  1.1248 +nsresult                                                                    \
  1.1249 +_elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
  1.1250 +{                                                                           \
  1.1251 +  *aResult = nullptr;                                                       \
  1.1252 +  already_AddRefed<nsINodeInfo> ni =                                        \
  1.1253 +    nsCOMPtr<nsINodeInfo>(aNodeInfo).forget();                              \
  1.1254 +  _elementName *it = new _elementName(ni);                                  \
  1.1255 +  if (!it) {                                                                \
  1.1256 +    return NS_ERROR_OUT_OF_MEMORY;                                          \
  1.1257 +  }                                                                         \
  1.1258 +                                                                            \
  1.1259 +  nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
  1.1260 +  nsresult rv = const_cast<_elementName*>(this)->CopyInnerTo(it);           \
  1.1261 +  if (NS_SUCCEEDED(rv)) {                                                   \
  1.1262 +    kungFuDeathGrip.swap(*aResult);                                         \
  1.1263 +  }                                                                         \
  1.1264 +                                                                            \
  1.1265 +  return rv;                                                                \
  1.1266 +}
  1.1267 +
  1.1268 +#define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName)                       \
  1.1269 +nsresult                                                                    \
  1.1270 +_elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
  1.1271 +{                                                                           \
  1.1272 +  *aResult = nullptr;                                                       \
  1.1273 +  already_AddRefed<nsINodeInfo> ni =                                        \
  1.1274 +    nsCOMPtr<nsINodeInfo>(aNodeInfo).forget();                              \
  1.1275 +  _elementName *it = new _elementName(ni);                                  \
  1.1276 +  if (!it) {                                                                \
  1.1277 +    return NS_ERROR_OUT_OF_MEMORY;                                          \
  1.1278 +  }                                                                         \
  1.1279 +                                                                            \
  1.1280 +  nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
  1.1281 +  nsresult rv = it->Init();                                                 \
  1.1282 +  nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it);          \
  1.1283 +  if (NS_FAILED(rv2)) {                                                     \
  1.1284 +    rv = rv2;                                                               \
  1.1285 +  }                                                                         \
  1.1286 +  if (NS_SUCCEEDED(rv)) {                                                   \
  1.1287 +    kungFuDeathGrip.swap(*aResult);                                         \
  1.1288 +  }                                                                         \
  1.1289 +                                                                            \
  1.1290 +  return rv;                                                                \
  1.1291 +}
  1.1292 +
  1.1293 +/**
  1.1294 + * A macro to implement the getter and setter for a given string
  1.1295 + * valued content property. The method uses the generic GetAttr and
  1.1296 + * SetAttr methods.  We use the 5-argument form of SetAttr, because
  1.1297 + * some consumers only implement that one, hiding superclass
  1.1298 + * 4-argument forms.
  1.1299 + */
  1.1300 +#define NS_IMPL_STRING_ATTR(_class, _method, _atom)                     \
  1.1301 +  NS_IMETHODIMP                                                         \
  1.1302 +  _class::Get##_method(nsAString& aValue)                               \
  1.1303 +  {                                                                     \
  1.1304 +    GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue);               \
  1.1305 +    return NS_OK;                                                       \
  1.1306 +  }                                                                     \
  1.1307 +  NS_IMETHODIMP                                                         \
  1.1308 +  _class::Set##_method(const nsAString& aValue)                         \
  1.1309 +  {                                                                     \
  1.1310 +    return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, nullptr, aValue, true); \
  1.1311 +  }
  1.1312 +
  1.1313 +/**
  1.1314 + * A macro to implement the getter and setter for a given boolean
  1.1315 + * valued content property. The method uses the GetBoolAttr and
  1.1316 + * SetBoolAttr methods.
  1.1317 + */
  1.1318 +#define NS_IMPL_BOOL_ATTR(_class, _method, _atom)                     \
  1.1319 +  NS_IMETHODIMP                                                       \
  1.1320 +  _class::Get##_method(bool* aValue)                                  \
  1.1321 +  {                                                                   \
  1.1322 +    *aValue = GetBoolAttr(nsGkAtoms::_atom);                          \
  1.1323 +    return NS_OK;                                                     \
  1.1324 +  }                                                                   \
  1.1325 +  NS_IMETHODIMP                                                       \
  1.1326 +  _class::Set##_method(bool aValue)                                   \
  1.1327 +  {                                                                   \
  1.1328 +    return SetBoolAttr(nsGkAtoms::_atom, aValue);                     \
  1.1329 +  }
  1.1330 +
  1.1331 +#define NS_FORWARD_NSIDOMELEMENT_TO_GENERIC                                   \
  1.1332 +typedef mozilla::dom::Element Element;                                        \
  1.1333 +NS_IMETHOD GetTagName(nsAString& aTagName) MOZ_FINAL                          \
  1.1334 +{                                                                             \
  1.1335 +  Element::GetTagName(aTagName);                                              \
  1.1336 +  return NS_OK;                                                               \
  1.1337 +}                                                                             \
  1.1338 +NS_IMETHOD GetClassList(nsISupports** aClassList) MOZ_FINAL                   \
  1.1339 +{                                                                             \
  1.1340 +  Element::GetClassList(aClassList);                                          \
  1.1341 +  return NS_OK;                                                               \
  1.1342 +}                                                                             \
  1.1343 +NS_IMETHOD GetAttributes(nsIDOMMozNamedAttrMap** aAttributes) MOZ_FINAL       \
  1.1344 +{                                                                             \
  1.1345 +  NS_ADDREF(*aAttributes = Attributes());                                     \
  1.1346 +  return NS_OK;                                                               \
  1.1347 +}                                                                             \
  1.1348 +using Element::GetAttribute;                                                  \
  1.1349 +NS_IMETHOD GetAttribute(const nsAString& name, nsAString& _retval) MOZ_FINAL  \
  1.1350 +{                                                                             \
  1.1351 +  nsString attr;                                                              \
  1.1352 +  GetAttribute(name, attr);                                                   \
  1.1353 +  _retval = attr;                                                             \
  1.1354 +  return NS_OK;                                                               \
  1.1355 +}                                                                             \
  1.1356 +NS_IMETHOD GetAttributeNS(const nsAString& namespaceURI,                      \
  1.1357 +                          const nsAString& localName,                         \
  1.1358 +                          nsAString& _retval) MOZ_FINAL                       \
  1.1359 +{                                                                             \
  1.1360 +  Element::GetAttributeNS(namespaceURI, localName, _retval);                  \
  1.1361 +  return NS_OK;                                                               \
  1.1362 +}                                                                             \
  1.1363 +NS_IMETHOD SetAttribute(const nsAString& name,                                \
  1.1364 +                        const nsAString& value)                               \
  1.1365 +{                                                                             \
  1.1366 +  mozilla::ErrorResult rv;                                                    \
  1.1367 +  Element::SetAttribute(name, value, rv);                                     \
  1.1368 +  return rv.ErrorCode();                                                      \
  1.1369 +}                                                                             \
  1.1370 +NS_IMETHOD SetAttributeNS(const nsAString& namespaceURI,                      \
  1.1371 +                          const nsAString& qualifiedName,                     \
  1.1372 +                          const nsAString& value) MOZ_FINAL                   \
  1.1373 +{                                                                             \
  1.1374 +  mozilla::ErrorResult rv;                                                    \
  1.1375 +  Element::SetAttributeNS(namespaceURI, qualifiedName, value, rv);            \
  1.1376 +  return rv.ErrorCode();                                                      \
  1.1377 +}                                                                             \
  1.1378 +using Element::RemoveAttribute;                                               \
  1.1379 +NS_IMETHOD RemoveAttribute(const nsAString& name) MOZ_FINAL                   \
  1.1380 +{                                                                             \
  1.1381 +  mozilla::ErrorResult rv;                                                    \
  1.1382 +  RemoveAttribute(name, rv);                                                  \
  1.1383 +  return rv.ErrorCode();                                                      \
  1.1384 +}                                                                             \
  1.1385 +NS_IMETHOD RemoveAttributeNS(const nsAString& namespaceURI,                   \
  1.1386 +                             const nsAString& localName) MOZ_FINAL            \
  1.1387 +{                                                                             \
  1.1388 +  mozilla::ErrorResult rv;                                                    \
  1.1389 +  Element::RemoveAttributeNS(namespaceURI, localName, rv);                    \
  1.1390 +  return rv.ErrorCode();                                                      \
  1.1391 +}                                                                             \
  1.1392 +using Element::HasAttribute;                                                  \
  1.1393 +NS_IMETHOD HasAttribute(const nsAString& name,                                \
  1.1394 +                           bool* _retval) MOZ_FINAL                           \
  1.1395 +{                                                                             \
  1.1396 +  *_retval = HasAttribute(name);                                              \
  1.1397 +  return NS_OK;                                                               \
  1.1398 +}                                                                             \
  1.1399 +NS_IMETHOD HasAttributeNS(const nsAString& namespaceURI,                      \
  1.1400 +                          const nsAString& localName,                         \
  1.1401 +                          bool* _retval) MOZ_FINAL                            \
  1.1402 +{                                                                             \
  1.1403 +  *_retval = Element::HasAttributeNS(namespaceURI, localName);                \
  1.1404 +  return NS_OK;                                                               \
  1.1405 +}                                                                             \
  1.1406 +NS_IMETHOD GetAttributeNode(const nsAString& name,                            \
  1.1407 +                            nsIDOMAttr** _retval) MOZ_FINAL                   \
  1.1408 +{                                                                             \
  1.1409 +  NS_IF_ADDREF(*_retval = Element::GetAttributeNode(name));                   \
  1.1410 +  return NS_OK;                                                               \
  1.1411 +}                                                                             \
  1.1412 +NS_IMETHOD SetAttributeNode(nsIDOMAttr* newAttr,                              \
  1.1413 +                            nsIDOMAttr** _retval) MOZ_FINAL                   \
  1.1414 +{                                                                             \
  1.1415 +  if (!newAttr) {                                                             \
  1.1416 +    return NS_ERROR_INVALID_POINTER;                                          \
  1.1417 +  }                                                                           \
  1.1418 +  mozilla::ErrorResult rv;                                                    \
  1.1419 +  mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr);       \
  1.1420 +  *_retval = Element::SetAttributeNode(*attr, rv).take();                     \
  1.1421 +  return rv.ErrorCode();                                                      \
  1.1422 +}                                                                             \
  1.1423 +NS_IMETHOD RemoveAttributeNode(nsIDOMAttr* oldAttr,                           \
  1.1424 +                               nsIDOMAttr** _retval) MOZ_FINAL                \
  1.1425 +{                                                                             \
  1.1426 +  if (!oldAttr) {                                                             \
  1.1427 +    return NS_ERROR_INVALID_POINTER;                                          \
  1.1428 +  }                                                                           \
  1.1429 +  mozilla::ErrorResult rv;                                                    \
  1.1430 +  mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(oldAttr);       \
  1.1431 +  *_retval = Element::RemoveAttributeNode(*attr, rv).take();                  \
  1.1432 +  return rv.ErrorCode();                                                      \
  1.1433 +}                                                                             \
  1.1434 +NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI,                  \
  1.1435 +                              const nsAString& localName,                     \
  1.1436 +                              nsIDOMAttr** _retval) MOZ_FINAL                 \
  1.1437 +{                                                                             \
  1.1438 +  NS_IF_ADDREF(*_retval = Element::GetAttributeNodeNS(namespaceURI,           \
  1.1439 +                                                      localName));            \
  1.1440 +  return NS_OK;                                                               \
  1.1441 +}                                                                             \
  1.1442 +NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* newAttr,                            \
  1.1443 +                              nsIDOMAttr** _retval) MOZ_FINAL                 \
  1.1444 +{                                                                             \
  1.1445 +  mozilla::ErrorResult rv;                                                    \
  1.1446 +  mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr);       \
  1.1447 +  *_retval = Element::SetAttributeNodeNS(*attr, rv).take();                   \
  1.1448 +  return rv.ErrorCode();                                                      \
  1.1449 +}                                                                             \
  1.1450 +NS_IMETHOD GetElementsByTagName(const nsAString& name,                        \
  1.1451 +                                nsIDOMHTMLCollection** _retval) MOZ_FINAL     \
  1.1452 +{                                                                             \
  1.1453 +  Element::GetElementsByTagName(name, _retval);                               \
  1.1454 +  return NS_OK;                                                               \
  1.1455 +}                                                                             \
  1.1456 +NS_IMETHOD GetElementsByTagNameNS(const nsAString& namespaceURI,              \
  1.1457 +                                  const nsAString& localName,                 \
  1.1458 +                                  nsIDOMHTMLCollection** _retval) MOZ_FINAL   \
  1.1459 +{                                                                             \
  1.1460 +  return Element::GetElementsByTagNameNS(namespaceURI, localName,             \
  1.1461 +                                         _retval);                            \
  1.1462 +}                                                                             \
  1.1463 +NS_IMETHOD GetElementsByClassName(const nsAString& classes,                   \
  1.1464 +                                  nsIDOMHTMLCollection** _retval) MOZ_FINAL   \
  1.1465 +{                                                                             \
  1.1466 +  return Element::GetElementsByClassName(classes, _retval);                   \
  1.1467 +}                                                                             \
  1.1468 +NS_IMETHOD GetChildElements(nsIDOMNodeList** aChildElements) MOZ_FINAL        \
  1.1469 +{                                                                             \
  1.1470 +  nsIHTMLCollection* list = FragmentOrElement::Children();                    \
  1.1471 +  return CallQueryInterface(list, aChildElements);                            \
  1.1472 +}                                                                             \
  1.1473 +NS_IMETHOD GetFirstElementChild(nsIDOMElement** aFirstElementChild) MOZ_FINAL \
  1.1474 +{                                                                             \
  1.1475 +  Element* element = Element::GetFirstElementChild();                         \
  1.1476 +  if (!element) {                                                             \
  1.1477 +    *aFirstElementChild = nullptr;                                            \
  1.1478 +    return NS_OK;                                                             \
  1.1479 +  }                                                                           \
  1.1480 +  return CallQueryInterface(element, aFirstElementChild);                     \
  1.1481 +}                                                                             \
  1.1482 +NS_IMETHOD GetLastElementChild(nsIDOMElement** aLastElementChild) MOZ_FINAL   \
  1.1483 +{                                                                             \
  1.1484 +  Element* element = Element::GetLastElementChild();                          \
  1.1485 +  if (!element) {                                                             \
  1.1486 +    *aLastElementChild = nullptr;                                             \
  1.1487 +    return NS_OK;                                                             \
  1.1488 +  }                                                                           \
  1.1489 +  return CallQueryInterface(element, aLastElementChild);                      \
  1.1490 +}                                                                             \
  1.1491 +NS_IMETHOD GetPreviousElementSibling(nsIDOMElement** aPreviousElementSibling) \
  1.1492 +  MOZ_FINAL                                                                   \
  1.1493 +{                                                                             \
  1.1494 +  Element* element = Element::GetPreviousElementSibling();                    \
  1.1495 +  if (!element) {                                                             \
  1.1496 +    *aPreviousElementSibling = nullptr;                                       \
  1.1497 +    return NS_OK;                                                             \
  1.1498 +  }                                                                           \
  1.1499 +  return CallQueryInterface(element, aPreviousElementSibling);                \
  1.1500 +}                                                                             \
  1.1501 +NS_IMETHOD GetNextElementSibling(nsIDOMElement** aNextElementSibling)         \
  1.1502 +  MOZ_FINAL                                                                   \
  1.1503 +{                                                                             \
  1.1504 +  Element* element = Element::GetNextElementSibling();                        \
  1.1505 +  if (!element) {                                                             \
  1.1506 +    *aNextElementSibling = nullptr;                                           \
  1.1507 +    return NS_OK;                                                             \
  1.1508 +  }                                                                           \
  1.1509 +  return CallQueryInterface(element, aNextElementSibling);                    \
  1.1510 +}                                                                             \
  1.1511 +NS_IMETHOD GetChildElementCount(uint32_t* aChildElementCount) MOZ_FINAL       \
  1.1512 +{                                                                             \
  1.1513 +  *aChildElementCount = Element::ChildElementCount();                         \
  1.1514 +  return NS_OK;                                                               \
  1.1515 +}                                                                             \
  1.1516 +NS_IMETHOD MozRemove() MOZ_FINAL                                              \
  1.1517 +{                                                                             \
  1.1518 +  nsINode::Remove();                                                          \
  1.1519 +  return NS_OK;                                                               \
  1.1520 +}                                                                             \
  1.1521 +NS_IMETHOD GetClientRects(nsIDOMClientRectList** _retval) MOZ_FINAL           \
  1.1522 +{                                                                             \
  1.1523 +  *_retval = Element::GetClientRects().take();                                \
  1.1524 +  return NS_OK;                                                               \
  1.1525 +}                                                                             \
  1.1526 +NS_IMETHOD GetBoundingClientRect(nsIDOMClientRect** _retval) MOZ_FINAL        \
  1.1527 +{                                                                             \
  1.1528 +  *_retval = Element::GetBoundingClientRect().take();                         \
  1.1529 +  return NS_OK;                                                               \
  1.1530 +}                                                                             \
  1.1531 +NS_IMETHOD GetScrollTop(int32_t* aScrollTop) MOZ_FINAL                        \
  1.1532 +{                                                                             \
  1.1533 +  *aScrollTop = Element::ScrollTop();                                         \
  1.1534 +  return NS_OK;                                                               \
  1.1535 +}                                                                             \
  1.1536 +NS_IMETHOD SetScrollTop(int32_t aScrollTop) MOZ_FINAL                         \
  1.1537 +{                                                                             \
  1.1538 +  Element::SetScrollTop(aScrollTop);                                          \
  1.1539 +  return NS_OK;                                                               \
  1.1540 +}                                                                             \
  1.1541 +NS_IMETHOD GetScrollLeft(int32_t* aScrollLeft) MOZ_FINAL                      \
  1.1542 +{                                                                             \
  1.1543 +  *aScrollLeft = Element::ScrollLeft();                                       \
  1.1544 +  return NS_OK;                                                               \
  1.1545 +}                                                                             \
  1.1546 +NS_IMETHOD SetScrollLeft(int32_t aScrollLeft) MOZ_FINAL                       \
  1.1547 +{                                                                             \
  1.1548 +  Element::SetScrollLeft(aScrollLeft);                                        \
  1.1549 +  return NS_OK;                                                               \
  1.1550 +}                                                                             \
  1.1551 +NS_IMETHOD GetScrollWidth(int32_t* aScrollWidth) MOZ_FINAL                    \
  1.1552 +{                                                                             \
  1.1553 +  *aScrollWidth = Element::ScrollWidth();                                     \
  1.1554 +  return NS_OK;                                                               \
  1.1555 +}                                                                             \
  1.1556 +NS_IMETHOD GetScrollHeight(int32_t* aScrollHeight) MOZ_FINAL                  \
  1.1557 +{                                                                             \
  1.1558 +  *aScrollHeight = Element::ScrollHeight();                                   \
  1.1559 +  return NS_OK;                                                               \
  1.1560 +}                                                                             \
  1.1561 +NS_IMETHOD GetClientTop(int32_t* aClientTop) MOZ_FINAL                        \
  1.1562 +{                                                                             \
  1.1563 +  *aClientTop = Element::ClientTop();                                         \
  1.1564 +  return NS_OK;                                                               \
  1.1565 +}                                                                             \
  1.1566 +NS_IMETHOD GetClientLeft(int32_t* aClientLeft) MOZ_FINAL                      \
  1.1567 +{                                                                             \
  1.1568 +  *aClientLeft = Element::ClientLeft();                                       \
  1.1569 +  return NS_OK;                                                               \
  1.1570 +}                                                                             \
  1.1571 +NS_IMETHOD GetClientWidth(int32_t* aClientWidth) MOZ_FINAL                    \
  1.1572 +{                                                                             \
  1.1573 +  *aClientWidth = Element::ClientWidth();                                     \
  1.1574 +  return NS_OK;                                                               \
  1.1575 +}                                                                             \
  1.1576 +NS_IMETHOD GetClientHeight(int32_t* aClientHeight) MOZ_FINAL                  \
  1.1577 +{                                                                             \
  1.1578 +  *aClientHeight = Element::ClientHeight();                                   \
  1.1579 +  return NS_OK;                                                               \
  1.1580 +}                                                                             \
  1.1581 +NS_IMETHOD GetScrollLeftMax(int32_t* aScrollLeftMax) MOZ_FINAL                \
  1.1582 +{                                                                             \
  1.1583 +  *aScrollLeftMax = Element::ScrollLeftMax();                                 \
  1.1584 +  return NS_OK;                                                               \
  1.1585 +}                                                                             \
  1.1586 +NS_IMETHOD GetScrollTopMax(int32_t* aScrollTopMax) MOZ_FINAL                  \
  1.1587 +{                                                                             \
  1.1588 +  *aScrollTopMax = Element::ScrollTopMax();                                   \
  1.1589 +  return NS_OK;                                                               \
  1.1590 +}                                                                             \
  1.1591 +NS_IMETHOD MozMatchesSelector(const nsAString& selector,                      \
  1.1592 +                              bool* _retval) MOZ_FINAL                        \
  1.1593 +{                                                                             \
  1.1594 +  mozilla::ErrorResult rv;                                                    \
  1.1595 +  *_retval = Element::MozMatchesSelector(selector, rv);                       \
  1.1596 +  return rv.ErrorCode();                                                      \
  1.1597 +}                                                                             \
  1.1598 +NS_IMETHOD SetCapture(bool retargetToElement) MOZ_FINAL                       \
  1.1599 +{                                                                             \
  1.1600 +  Element::SetCapture(retargetToElement);                                     \
  1.1601 +  return NS_OK;                                                               \
  1.1602 +}                                                                             \
  1.1603 +NS_IMETHOD ReleaseCapture(void) MOZ_FINAL                                     \
  1.1604 +{                                                                             \
  1.1605 +  Element::ReleaseCapture();                                                  \
  1.1606 +  return NS_OK;                                                               \
  1.1607 +}                                                                             \
  1.1608 +NS_IMETHOD MozRequestFullScreen(void) MOZ_FINAL                               \
  1.1609 +{                                                                             \
  1.1610 +  Element::MozRequestFullScreen();                                            \
  1.1611 +  return NS_OK;                                                               \
  1.1612 +}                                                                             \
  1.1613 +NS_IMETHOD MozRequestPointerLock(void) MOZ_FINAL                              \
  1.1614 +{                                                                             \
  1.1615 +  Element::MozRequestPointerLock();                                           \
  1.1616 +  return NS_OK;                                                               \
  1.1617 +}                                                                             \
  1.1618 +using nsINode::QuerySelector;                                                 \
  1.1619 +NS_IMETHOD QuerySelector(const nsAString& aSelector,                          \
  1.1620 +                         nsIDOMElement **aReturn) MOZ_FINAL                   \
  1.1621 +{                                                                             \
  1.1622 +  return nsINode::QuerySelector(aSelector, aReturn);                          \
  1.1623 +}                                                                             \
  1.1624 +using nsINode::QuerySelectorAll;                                              \
  1.1625 +NS_IMETHOD QuerySelectorAll(const nsAString& aSelector,                       \
  1.1626 +                            nsIDOMNodeList **aReturn) MOZ_FINAL               \
  1.1627 +{                                                                             \
  1.1628 +  return nsINode::QuerySelectorAll(aSelector, aReturn);                       \
  1.1629 +}
  1.1630 +
  1.1631 +#endif // mozilla_dom_Element_h__

mercurial