content/base/public/Element.h

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

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__

mercurial