Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Peter Kelly (pmk (at) post.com)
      5  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      6  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
      7  *
      8  * This library is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU Library General Public
     10  * License as published by the Free Software Foundation; either
     11  * version 2 of the License, or (at your option) any later version.
     12  *
     13  * This library is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * Library General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU Library General Public License
     19  * along with this library; see the file COPYING.LIB.  If not, write to
     20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21  * Boston, MA 02110-1301, USA.
     22  *
     23  */
     24 
     25 #ifndef Element_h
     26 #define Element_h
     27 
     28 #include "core/CSSPropertyNames.h"
     29 #include "core/HTMLNames.h"
     30 #include "core/css/CSSPrimitiveValue.h"
     31 #include "core/dom/Attribute.h"
     32 #include "core/dom/ContainerNode.h"
     33 #include "core/dom/ElementData.h"
     34 #include "core/dom/SpaceSplitString.h"
     35 #include "core/html/CollectionType.h"
     36 #include "core/page/FocusType.h"
     37 #include "platform/heap/Handle.h"
     38 #include "platform/scroll/ScrollTypes.h"
     39 
     40 namespace WebCore {
     41 
     42 class ActiveAnimations;
     43 class Attr;
     44 class Attribute;
     45 class CSSStyleDeclaration;
     46 class ClientRect;
     47 class ClientRectList;
     48 class CustomElementDefinition;
     49 class DOMStringMap;
     50 class DOMTokenList;
     51 class Document;
     52 class ElementRareData;
     53 class ElementShadow;
     54 class ExceptionState;
     55 class Image;
     56 class InputMethodContext;
     57 class IntSize;
     58 class Locale;
     59 class MutableStylePropertySet;
     60 class PropertySetCSSStyleDeclaration;
     61 class PseudoElement;
     62 class ShadowRoot;
     63 class StylePropertySet;
     64 
     65 enum AffectedSelectorType {
     66     AffectedSelectorChecked = 1,
     67     AffectedSelectorEnabled = 1 << 1,
     68     AffectedSelectorDisabled = 1 << 2,
     69     AffectedSelectorIndeterminate = 1 << 3,
     70     AffectedSelectorLink = 1 << 4,
     71     AffectedSelectorTarget = 1 << 5,
     72     AffectedSelectorVisited = 1 << 6
     73 };
     74 typedef int AffectedSelectorMask;
     75 
     76 enum SpellcheckAttributeState {
     77     SpellcheckAttributeTrue,
     78     SpellcheckAttributeFalse,
     79     SpellcheckAttributeDefault
     80 };
     81 
     82 enum ElementFlags {
     83     TabIndexWasSetExplicitly = 1 << 0,
     84     StyleAffectedByEmpty = 1 << 1,
     85     IsInCanvasSubtree = 1 << 2,
     86     ContainsFullScreenElement = 1 << 3,
     87     IsInTopLayer = 1 << 4,
     88     HasPendingResources = 1 << 5,
     89 
     90     NumberOfElementFlags = 6, // Required size of bitfield used to store the flags.
     91 };
     92 
     93 class Element : public ContainerNode {
     94 public:
     95     static PassRefPtrWillBeRawPtr<Element> create(const QualifiedName&, Document*);
     96     virtual ~Element();
     97 
     98     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
     99     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
    100     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
    101     DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
    102     DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
    103     DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
    104     DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
    105     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
    106     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
    107     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
    108     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
    109     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
    110     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
    111     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror);
    112     DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
    113 
    114     bool hasAttribute(const QualifiedName&) const;
    115     const AtomicString& getAttribute(const QualifiedName&) const;
    116 
    117     // Passing nullAtom as the second parameter removes the attribute when calling either of these set methods.
    118     void setAttribute(const QualifiedName&, const AtomicString& value);
    119     void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value);
    120 
    121     void removeAttribute(const QualifiedName&);
    122 
    123     // Typed getters and setters for language bindings.
    124     int getIntegralAttribute(const QualifiedName& attributeName) const;
    125     void setIntegralAttribute(const QualifiedName& attributeName, int value);
    126     unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const;
    127     void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value);
    128     double getFloatingPointAttribute(const QualifiedName& attributeName, double fallbackValue = std::numeric_limits<double>::quiet_NaN()) const;
    129     void setFloatingPointAttribute(const QualifiedName& attributeName, double value);
    130 
    131     // Call this to get the value of an attribute that is known not to be the style
    132     // attribute or one of the SVG animatable attributes.
    133     bool fastHasAttribute(const QualifiedName&) const;
    134     const AtomicString& fastGetAttribute(const QualifiedName&) const;
    135 #ifndef NDEBUG
    136     bool fastAttributeLookupAllowed(const QualifiedName&) const;
    137 #endif
    138 
    139 #ifdef DUMP_NODE_STATISTICS
    140     bool hasNamedNodeMap() const;
    141 #endif
    142     bool hasAttributes() const;
    143     // This variant will not update the potentially invalid attributes. To be used when not interested
    144     // in style attribute or one of the SVG animation attributes.
    145     bool hasAttributesWithoutUpdate() const;
    146 
    147     bool hasAttribute(const AtomicString& name) const;
    148     bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
    149 
    150     const AtomicString& getAttribute(const AtomicString& name) const;
    151     const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
    152 
    153     void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionState&);
    154     static bool parseAttributeName(QualifiedName&, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&);
    155     void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionState&);
    156 
    157     bool isIdAttributeName(const QualifiedName&) const;
    158     const AtomicString& getIdAttribute() const;
    159     void setIdAttribute(const AtomicString&);
    160 
    161     const AtomicString& getNameAttribute() const;
    162     const AtomicString& getClassAttribute() const;
    163 
    164     bool shouldIgnoreAttributeCase() const;
    165 
    166     // Call this to get the value of the id attribute for style resolution purposes.
    167     // The value will already be lowercased if the document is in compatibility mode,
    168     // so this function is not suitable for non-style uses.
    169     const AtomicString& idForStyleResolution() const;
    170 
    171     // Internal methods that assume the existence of attribute storage, one should use hasAttributes()
    172     // before calling them. This is not a trivial getter and its return value should be cached for
    173     // performance.
    174     AttributeCollection attributes() const { return elementData()->attributes(); }
    175     size_t attributeCount() const;
    176     const Attribute& attributeAt(unsigned index) const;
    177     const Attribute* findAttributeByName(const QualifiedName&) const;
    178     size_t findAttributeIndexByName(const QualifiedName& name) const { return elementData()->findAttributeIndexByName(name); }
    179     size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->findAttributeIndexByName(name, shouldIgnoreAttributeCase); }
    180 
    181     void scrollIntoView(bool alignToTop = true);
    182     void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
    183 
    184     void scrollByLines(int lines);
    185     void scrollByPages(int pages);
    186 
    187     int offsetLeft();
    188     int offsetTop();
    189     int offsetWidth();
    190     int offsetHeight();
    191 
    192     // FIXME: Replace uses of offsetParent in the platform with calls
    193     // to the render layer and merge offsetParentForBindings and offsetParent.
    194     Element* offsetParentForBindings();
    195 
    196     Element* offsetParent();
    197     int clientLeft();
    198     int clientTop();
    199     int clientWidth();
    200     int clientHeight();
    201     virtual int scrollLeft();
    202     virtual int scrollTop();
    203     virtual void setScrollLeft(int);
    204     virtual void setScrollLeft(const Dictionary& scrollOptionsHorizontal, ExceptionState&);
    205     virtual void setScrollTop(int);
    206     virtual void setScrollTop(const Dictionary& scrollOptionsVertical, ExceptionState&);
    207     virtual int scrollWidth();
    208     virtual int scrollHeight();
    209 
    210     IntRect boundsInRootViewSpace();
    211 
    212     PassRefPtrWillBeRawPtr<ClientRectList> getClientRects();
    213     PassRefPtrWillBeRawPtr<ClientRect> getBoundingClientRect();
    214 
    215     // Returns the absolute bounding box translated into screen coordinates:
    216     IntRect screenRect() const;
    217 
    218     virtual void didMoveToNewDocument(Document&) OVERRIDE;
    219 
    220     void removeAttribute(const AtomicString& name);
    221     void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
    222 
    223     PassRefPtrWillBeRawPtr<Attr> detachAttribute(size_t index);
    224 
    225     PassRefPtrWillBeRawPtr<Attr> getAttributeNode(const AtomicString& name);
    226     PassRefPtrWillBeRawPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
    227     PassRefPtrWillBeRawPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
    228     PassRefPtrWillBeRawPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
    229     PassRefPtrWillBeRawPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
    230 
    231     PassRefPtrWillBeRawPtr<Attr> attrIfExists(const QualifiedName&);
    232     PassRefPtrWillBeRawPtr<Attr> ensureAttr(const QualifiedName&);
    233 
    234     WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList();
    235 
    236     CSSStyleDeclaration* style();
    237 
    238     const QualifiedName& tagQName() const { return m_tagName; }
    239     String tagName() const { return nodeName(); }
    240     bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
    241 
    242     // Should be called only by Document::createElementNS to fix up m_tagName immediately after construction.
    243     void setTagNameForCreateElementNS(const QualifiedName&);
    244 
    245     // A fast function for checking the local name against another atomic string.
    246     bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
    247     bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
    248 
    249     virtual const AtomicString& localName() const OVERRIDE FINAL { return m_tagName.localName(); }
    250     const AtomicString& prefix() const { return m_tagName.prefix(); }
    251     virtual const AtomicString& namespaceURI() const OVERRIDE FINAL { return m_tagName.namespaceURI(); }
    252 
    253     const AtomicString& locateNamespacePrefix(const AtomicString& namespaceURI) const;
    254 
    255     virtual KURL baseURI() const OVERRIDE FINAL;
    256 
    257     virtual String nodeName() const OVERRIDE;
    258 
    259     PassRefPtrWillBeRawPtr<Element> cloneElementWithChildren();
    260     PassRefPtrWillBeRawPtr<Element> cloneElementWithoutChildren();
    261 
    262     void scheduleSVGFilterLayerUpdateHack();
    263 
    264     void normalizeAttributes();
    265 
    266     void setBooleanAttribute(const QualifiedName& name, bool);
    267 
    268     virtual const StylePropertySet* additionalPresentationAttributeStyle() { return 0; }
    269     void invalidateStyleAttribute();
    270 
    271     const StylePropertySet* inlineStyle() const { return elementData() ? elementData()->m_inlineStyle.get() : 0; }
    272 
    273     bool setInlineStyleProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
    274     bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitType, bool important = false);
    275     bool setInlineStyleProperty(CSSPropertyID, const String& value, bool important = false);
    276     bool removeInlineStyleProperty(CSSPropertyID);
    277     void removeAllInlineStyleProperties();
    278 
    279     void synchronizeStyleAttributeInternal() const;
    280 
    281     const StylePropertySet* presentationAttributeStyle();
    282     virtual bool isPresentationAttribute(const QualifiedName&) const { return false; }
    283     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) { }
    284 
    285     // For exposing to DOM only.
    286     NamedNodeMap* attributesForBindings() const;
    287 
    288     enum AttributeModificationReason {
    289         ModifiedDirectly,
    290         ModifiedByCloning
    291     };
    292 
    293     // This method is called whenever an attribute is added, changed or removed.
    294     virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly);
    295     virtual void parseAttribute(const QualifiedName&, const AtomicString&);
    296 
    297     virtual bool hasLegalLinkAttribute(const QualifiedName&) const;
    298     virtual const QualifiedName& subResourceAttributeName() const;
    299 
    300     // Only called by the parser immediately after element construction.
    301     void parserSetAttributes(const Vector<Attribute>&);
    302 
    303     // Remove attributes that might introduce scripting from the vector leaving the element unchanged.
    304     void stripScriptingAttributes(Vector<Attribute>&) const;
    305 
    306     const ElementData* elementData() const { return m_elementData.get(); }
    307     UniqueElementData& ensureUniqueElementData();
    308 
    309     void synchronizeAllAttributes() const;
    310 
    311     // Clones attributes only.
    312     void cloneAttributesFromElement(const Element&);
    313 
    314     // Clones all attribute-derived data, including subclass specifics (through copyNonAttributeProperties.)
    315     void cloneDataFromElement(const Element&);
    316 
    317     bool hasEquivalentAttributes(const Element* other) const;
    318 
    319     virtual void copyNonAttributePropertiesFromElement(const Element&) { }
    320 
    321     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
    322     virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
    323     virtual RenderObject* createRenderer(RenderStyle*);
    324     virtual bool rendererIsNeeded(const RenderStyle&);
    325     void recalcStyle(StyleRecalcChange, Text* nextTextSibling = 0);
    326     void didAffectSelector(AffectedSelectorMask);
    327     void setAnimationStyleChange(bool);
    328     void setNeedsAnimationStyleRecalc();
    329 
    330     void setNeedsCompositingUpdate();
    331 
    332     bool supportsStyleSharing() const;
    333 
    334     ElementShadow* shadow() const;
    335     ElementShadow& ensureShadow();
    336     PassRefPtrWillBeRawPtr<ShadowRoot> createShadowRoot(ExceptionState&);
    337     ShadowRoot* shadowRoot() const;
    338     ShadowRoot* youngestShadowRoot() const;
    339 
    340     bool hasAuthorShadowRoot() const { return shadowRoot(); }
    341     ShadowRoot* userAgentShadowRoot() const;
    342     ShadowRoot& ensureUserAgentShadowRoot();
    343     virtual void willAddFirstAuthorShadowRoot() { }
    344 
    345     bool isInDescendantTreeOf(const Element* shadowHost) const;
    346 
    347     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
    348 
    349     // Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
    350     bool styleAffectedByEmpty() const { return hasElementFlag(StyleAffectedByEmpty); }
    351     void setStyleAffectedByEmpty() { setElementFlag(StyleAffectedByEmpty); }
    352 
    353     void setIsInCanvasSubtree(bool value) { setElementFlag(IsInCanvasSubtree, value); }
    354     bool isInCanvasSubtree() const { return hasElementFlag(IsInCanvasSubtree); }
    355 
    356     bool isUpgradedCustomElement() { return customElementState() == Upgraded; }
    357     bool isUnresolvedCustomElement() { return customElementState() == WaitingForUpgrade; }
    358 
    359     AtomicString computeInheritedLanguage() const;
    360     Locale& locale() const;
    361 
    362     virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
    363 
    364     virtual bool isURLAttribute(const Attribute&) const { return false; }
    365     virtual bool isHTMLContentAttribute(const Attribute&) const { return false; }
    366 
    367     KURL getURLAttribute(const QualifiedName&) const;
    368     KURL getNonEmptyURLAttribute(const QualifiedName&) const;
    369 
    370     virtual const AtomicString imageSourceURL() const;
    371     virtual Image* imageContents() { return 0; }
    372 
    373     virtual void focus(bool restorePreviousSelection = true, FocusType = FocusTypeNone);
    374     virtual void updateFocusAppearance(bool restorePreviousSelection);
    375     virtual void blur();
    376     // Whether this element can receive focus at all. Most elements are not
    377     // focusable but some elements, such as form controls and links, are. Unlike
    378     // rendererIsFocusable(), this method may be called when layout is not up to
    379     // date, so it must not use the renderer to determine focusability.
    380     virtual bool supportsFocus() const;
    381     // Whether the node can actually be focused.
    382     bool isFocusable() const;
    383     virtual bool isKeyboardFocusable() const;
    384     virtual bool isMouseFocusable() const;
    385     virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType);
    386     virtual void dispatchBlurEvent(Element* newFocusedElement);
    387     void dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement);
    388     void dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement);
    389 
    390     String innerText();
    391     String outerText();
    392     String innerHTML() const;
    393     String outerHTML() const;
    394     void setInnerHTML(const String&, ExceptionState&);
    395     void setOuterHTML(const String&, ExceptionState&);
    396 
    397     Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionState&);
    398     void insertAdjacentText(const String& where, const String& text, ExceptionState&);
    399     void insertAdjacentHTML(const String& where, const String& html, ExceptionState&);
    400 
    401     String textFromChildren();
    402 
    403     virtual String title() const { return String(); }
    404 
    405     virtual const AtomicString& shadowPseudoId() const;
    406     void setShadowPseudoId(const AtomicString&);
    407 
    408     LayoutSize minimumSizeForResizing() const;
    409     void setMinimumSizeForResizing(const LayoutSize&);
    410 
    411     virtual void didBecomeFullscreenElement() { }
    412     virtual void willStopBeingFullscreenElement() { }
    413 
    414     // Called by the parser when this element's close tag is reached,
    415     // signaling that all child tags have been parsed and added.
    416     // This is needed for <applet> and <object> elements, which can't lay themselves out
    417     // until they know all of their nested <param>s. [Radar 3603191, 4040848].
    418     // Also used for script elements and some SVG elements for similar purposes,
    419     // but making parsing a special case in this respect should be avoided if possible.
    420     virtual void finishParsingChildren();
    421 
    422     void beginParsingChildren() { setIsFinishedParsingChildren(false); }
    423 
    424     PseudoElement* pseudoElement(PseudoId) const;
    425     RenderObject* pseudoElementRenderer(PseudoId) const;
    426 
    427     virtual bool matchesReadOnlyPseudoClass() const { return false; }
    428     virtual bool matchesReadWritePseudoClass() const { return false; }
    429     bool matches(const String& selectors, ExceptionState&);
    430     virtual bool shouldAppearIndeterminate() const { return false; }
    431 
    432     DOMTokenList& classList();
    433 
    434     DOMStringMap& dataset();
    435 
    436 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
    437     virtual bool isDateTimeEditElement() const { return false; }
    438     virtual bool isDateTimeFieldElement() const { return false; }
    439     virtual bool isPickerIndicatorElement() const { return false; }
    440 #endif
    441 
    442     virtual bool isFormControlElement() const { return false; }
    443     virtual bool isSpinButtonElement() const { return false; }
    444     virtual bool isTextFormControl() const { return false; }
    445     virtual bool isOptionalFormControl() const { return false; }
    446     virtual bool isRequiredFormControl() const { return false; }
    447     virtual bool isDefaultButtonForForm() const { return false; }
    448     virtual bool willValidate() const { return false; }
    449     virtual bool isValidFormControlElement() { return false; }
    450     virtual bool isInRange() const { return false; }
    451     virtual bool isOutOfRange() const { return false; }
    452     virtual bool isClearButtonElement() const { return false; }
    453 
    454     virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
    455 
    456     // Used for disabled form elements; if true, prevents mouse events from being dispatched
    457     // to event listeners, and prevents DOMActivate events from being sent at all.
    458     virtual bool isDisabledFormControl() const { return false; }
    459 
    460     bool hasPendingResources() const { return hasElementFlag(HasPendingResources); }
    461     void setHasPendingResources() { setElementFlag(HasPendingResources); }
    462     void clearHasPendingResources() { clearElementFlag(HasPendingResources); }
    463     virtual void buildPendingResource() { };
    464 
    465     void setCustomElementDefinition(PassRefPtr<CustomElementDefinition>);
    466     CustomElementDefinition* customElementDefinition() const;
    467 
    468     enum {
    469         ALLOW_KEYBOARD_INPUT = 1 << 0,
    470         LEGACY_MOZILLA_REQUEST = 1 << 1,
    471     };
    472 
    473     void webkitRequestFullScreen(unsigned short flags);
    474     bool containsFullScreenElement() const { return hasElementFlag(ContainsFullScreenElement); }
    475     void setContainsFullScreenElement(bool);
    476     void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool);
    477 
    478     // W3C API
    479     void webkitRequestFullscreen();
    480 
    481     bool isInTopLayer() const { return hasElementFlag(IsInTopLayer); }
    482     void setIsInTopLayer(bool);
    483 
    484     void webkitRequestPointerLock();
    485     void requestPointerLock();
    486 
    487     bool isSpellCheckingEnabled() const;
    488 
    489     // FIXME: public for RenderTreeBuilder, we shouldn't expose this though.
    490     PassRefPtr<RenderStyle> styleForRenderer();
    491 
    492     bool hasID() const;
    493     bool hasClass() const;
    494     const SpaceSplitString& classNames() const;
    495 
    496     IntSize savedLayerScrollOffset() const;
    497     void setSavedLayerScrollOffset(const IntSize&);
    498 
    499     ActiveAnimations* activeAnimations() const;
    500     ActiveAnimations& ensureActiveAnimations();
    501     bool hasActiveAnimations() const;
    502 
    503     InputMethodContext& inputMethodContext();
    504     bool hasInputMethodContext() const;
    505 
    506     void setPrefix(const AtomicString&, ExceptionState&);
    507 
    508     void synchronizeAttribute(const AtomicString& localName) const;
    509 
    510     MutableStylePropertySet& ensureMutableInlineStyle();
    511     void clearMutableInlineStyleIfEmpty();
    512 
    513     void setTabIndex(int);
    514     virtual short tabIndex() const OVERRIDE;
    515 
    516     virtual void trace(Visitor*) OVERRIDE;
    517 
    518 protected:
    519     Element(const QualifiedName& tagName, Document*, ConstructionType);
    520 
    521     void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, CSSValueID identifier);
    522     void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitType);
    523     void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, const String& value);
    524 
    525     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
    526     virtual void removedFrom(ContainerNode*) OVERRIDE;
    527     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
    528 
    529     virtual void willRecalcStyle(StyleRecalcChange);
    530     virtual void didRecalcStyle(StyleRecalcChange);
    531     virtual PassRefPtr<RenderStyle> customStyleForRenderer();
    532 
    533     virtual bool shouldRegisterAsNamedItem() const { return false; }
    534     virtual bool shouldRegisterAsExtraNamedItem() const { return false; }
    535 
    536     virtual bool supportsSpatialNavigationFocus() const;
    537 
    538     void clearTabIndexExplicitlyIfNeeded();
    539     void setTabIndexExplicitly(short);
    540     // Subclasses may override this method to affect focusability. Unlike
    541     // supportsFocus, this method must be called on an up-to-date layout, so it
    542     // may use the renderer to reason about focusability. This method cannot be
    543     // moved to RenderObject because some focusable nodes don't have renderers,
    544     // e.g., HTMLOptionElement.
    545     virtual bool rendererIsFocusable() const;
    546     PassRefPtrWillBeRawPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
    547     HTMLCollection* cachedHTMLCollection(CollectionType);
    548 
    549     // classAttributeChanged() exists to share code between
    550     // parseAttribute (called via setAttribute()) and
    551     // svgAttributeChanged (called when element.className.baseValue is set)
    552     void classAttributeChanged(const AtomicString& newClassString);
    553 
    554     PassRefPtr<RenderStyle> originalStyleForRenderer();
    555 
    556     Node* insertAdjacent(const String& where, Node* newChild, ExceptionState&);
    557 
    558 private:
    559     bool hasElementFlag(ElementFlags mask) const { return hasRareData() && hasElementFlagInternal(mask); }
    560     void setElementFlag(ElementFlags, bool value = true);
    561     void clearElementFlag(ElementFlags);
    562     bool hasElementFlagInternal(ElementFlags) const;
    563 
    564     void styleAttributeChanged(const AtomicString& newStyleString, AttributeModificationReason);
    565 
    566     void updatePresentationAttributeStyle();
    567 
    568     void inlineStyleChanged();
    569     PropertySetCSSStyleDeclaration* inlineStyleCSSOMWrapper();
    570     void setInlineStyleFromString(const AtomicString&);
    571 
    572     StyleRecalcChange recalcOwnStyle(StyleRecalcChange);
    573     void recalcChildStyle(StyleRecalcChange);
    574 
    575     inline void checkForEmptyStyleChange();
    576 
    577     void updatePseudoElement(PseudoId, StyleRecalcChange);
    578 
    579     inline void createPseudoElementIfNeeded(PseudoId);
    580 
    581     // FIXME: Everyone should allow author shadows.
    582     virtual bool areAuthorShadowsAllowed() const { return true; }
    583     virtual void didAddUserAgentShadowRoot(ShadowRoot&) { }
    584     virtual bool alwaysCreateUserAgentShadowRoot() const { return false; }
    585 
    586     // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
    587     friend class Attr;
    588 
    589     enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute = 0, InSynchronizationOfLazyAttribute };
    590 
    591     void didAddAttribute(const QualifiedName&, const AtomicString&);
    592     void willModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
    593     void didModifyAttribute(const QualifiedName&, const AtomicString&);
    594     void didRemoveAttribute(const QualifiedName&);
    595 
    596     void synchronizeAttribute(const QualifiedName&) const;
    597 
    598     void updateId(const AtomicString& oldId, const AtomicString& newId);
    599     void updateId(TreeScope&, const AtomicString& oldId, const AtomicString& newId);
    600     void updateName(const AtomicString& oldName, const AtomicString& newName);
    601     void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
    602 
    603     void scrollByUnits(int units, ScrollGranularity);
    604 
    605     virtual NodeType nodeType() const OVERRIDE FINAL;
    606     virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
    607 
    608     void setAttributeInternal(size_t index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
    609     void appendAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
    610     void removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute);
    611     void attributeChangedFromParserOrByCloning(const QualifiedName&, const AtomicString&, AttributeModificationReason);
    612 
    613 #ifndef NDEBUG
    614     virtual void formatForDebugger(char* buffer, unsigned length) const OVERRIDE;
    615 #endif
    616 
    617     bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
    618 
    619     void cancelFocusAppearanceUpdate();
    620 
    621     virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE { return computedStyle(pseudoElementSpecifier); }
    622 
    623     inline void updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle);
    624     inline void removeCallbackSelectors();
    625     inline void addCallbackSelectors();
    626 
    627     // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
    628     // are used instead.
    629     virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) OVERRIDE;
    630     virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren();
    631 
    632     QualifiedName m_tagName;
    633 
    634     SpellcheckAttributeState spellcheckAttributeState() const;
    635 
    636     void updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
    637     void updateExtraNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
    638 
    639     void createUniqueElementData();
    640 
    641     bool shouldInvalidateDistributionWhenAttributeChanged(ElementShadow*, const QualifiedName&, const AtomicString&);
    642 
    643     ElementRareData* elementRareData() const;
    644     ElementRareData& ensureElementRareData();
    645 
    646     WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList();
    647     void removeAttrNodeList();
    648     void detachAllAttrNodesFromElement();
    649     void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
    650     void detachAttrNodeAtIndex(Attr*, size_t index);
    651 
    652     bool isJavaScriptURLAttribute(const Attribute&) const;
    653 
    654     RefPtr<ElementData> m_elementData;
    655 };
    656 
    657 DEFINE_NODE_TYPE_CASTS(Element, isElementNode());
    658 template <typename T> bool isElementOfType(const Element&);
    659 template <typename T> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const T>(toElement(node)); }
    660 template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
    661 
    662 // Type casting.
    663 template<typename T> inline T& toElement(Node& node)
    664 {
    665     ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
    666     return static_cast<T&>(node);
    667 }
    668 template<typename T> inline T* toElement(Node* node)
    669 {
    670     ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
    671     return static_cast<T*>(node);
    672 }
    673 template<typename T> inline const T& toElement(const Node& node)
    674 {
    675     ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
    676     return static_cast<const T&>(node);
    677 }
    678 template<typename T> inline const T* toElement(const Node* node)
    679 {
    680     ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
    681     return static_cast<const T*>(node);
    682 }
    683 template<typename T, typename U> inline T* toElement(const RefPtr<U>& node) { return toElement<T>(node.get()); }
    684 
    685 inline bool isDisabledFormControl(const Node* node)
    686 {
    687     return node->isElementNode() && toElement(node)->isDisabledFormControl();
    688 }
    689 
    690 inline bool Node::hasTagName(const QualifiedName& name) const
    691 {
    692     return isElementNode() && toElement(this)->hasTagName(name);
    693 }
    694 
    695 inline Element* Node::parentElement() const
    696 {
    697     ContainerNode* parent = parentNode();
    698     return parent && parent->isElementNode() ? toElement(parent) : 0;
    699 }
    700 
    701 inline bool Element::fastHasAttribute(const QualifiedName& name) const
    702 {
    703     ASSERT(fastAttributeLookupAllowed(name));
    704     return elementData() && findAttributeByName(name);
    705 }
    706 
    707 inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const
    708 {
    709     ASSERT(fastAttributeLookupAllowed(name));
    710     if (elementData()) {
    711         if (const Attribute* attribute = findAttributeByName(name))
    712             return attribute->value();
    713     }
    714     return nullAtom;
    715 }
    716 
    717 inline bool Element::hasAttributesWithoutUpdate() const
    718 {
    719     return elementData() && elementData()->hasAttributes();
    720 }
    721 
    722 inline const AtomicString& Element::idForStyleResolution() const
    723 {
    724     ASSERT(hasID());
    725     return elementData()->idForStyleResolution();
    726 }
    727 
    728 inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const
    729 {
    730     // FIXME: This check is probably not correct for the case where the document has an id attribute
    731     // with a non-null namespace, because it will return false, a false negative, if the prefixes
    732     // don't match but the local name and namespace both do. However, since this has been like this
    733     // for a while and the code paths may be hot, we'll have to measure performance if we fix it.
    734     return attributeName == HTMLNames::idAttr;
    735 }
    736 
    737 inline const AtomicString& Element::getIdAttribute() const
    738 {
    739     return hasID() ? fastGetAttribute(HTMLNames::idAttr) : nullAtom;
    740 }
    741 
    742 inline const AtomicString& Element::getNameAttribute() const
    743 {
    744     return hasName() ? fastGetAttribute(HTMLNames::nameAttr) : nullAtom;
    745 }
    746 
    747 inline const AtomicString& Element::getClassAttribute() const
    748 {
    749     if (!hasClass())
    750         return nullAtom;
    751     if (isSVGElement())
    752         return getAttribute(HTMLNames::classAttr);
    753     return fastGetAttribute(HTMLNames::classAttr);
    754 }
    755 
    756 inline void Element::setIdAttribute(const AtomicString& value)
    757 {
    758     setAttribute(HTMLNames::idAttr, value);
    759 }
    760 
    761 inline const SpaceSplitString& Element::classNames() const
    762 {
    763     ASSERT(hasClass());
    764     ASSERT(elementData());
    765     return elementData()->classNames();
    766 }
    767 
    768 inline size_t Element::attributeCount() const
    769 {
    770     ASSERT(elementData());
    771     return elementData()->attributeCount();
    772 }
    773 
    774 inline const Attribute& Element::attributeAt(unsigned index) const
    775 {
    776     ASSERT(elementData());
    777     return elementData()->attributeAt(index);
    778 }
    779 
    780 inline const Attribute* Element::findAttributeByName(const QualifiedName& name) const
    781 {
    782     ASSERT(elementData());
    783     return elementData()->findAttributeByName(name);
    784 }
    785 
    786 inline bool Element::hasID() const
    787 {
    788     return elementData() && elementData()->hasID();
    789 }
    790 
    791 inline bool Element::hasClass() const
    792 {
    793     return elementData() && elementData()->hasClass();
    794 }
    795 
    796 inline UniqueElementData& Element::ensureUniqueElementData()
    797 {
    798     if (!elementData() || !elementData()->isUnique())
    799         createUniqueElementData();
    800     return static_cast<UniqueElementData&>(*m_elementData);
    801 }
    802 
    803 // Put here to make them inline.
    804 inline bool Node::hasID() const
    805 {
    806     return isElementNode() && toElement(this)->hasID();
    807 }
    808 
    809 inline bool Node::hasClass() const
    810 {
    811     return isElementNode() && toElement(this)->hasClass();
    812 }
    813 
    814 inline Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* insertionPoint)
    815 {
    816     ASSERT(!childNeedsStyleInvalidation());
    817     ASSERT(!needsStyleInvalidation());
    818     ASSERT(insertionPoint->inDocument() || isContainerNode());
    819     if (insertionPoint->inDocument())
    820         setFlag(InDocumentFlag);
    821     if (parentOrShadowHostNode()->isInShadowTree())
    822         setFlag(IsInShadowTreeFlag);
    823     if (childNeedsDistributionRecalc() && !insertionPoint->childNeedsDistributionRecalc())
    824         insertionPoint->markAncestorsWithChildNeedsDistributionRecalc();
    825     return InsertionDone;
    826 }
    827 
    828 inline void Node::removedFrom(ContainerNode* insertionPoint)
    829 {
    830     ASSERT(insertionPoint->inDocument() || isContainerNode());
    831     if (insertionPoint->inDocument())
    832         clearFlag(InDocumentFlag);
    833     if (isInShadowTree() && !treeScope().rootNode().isShadowRoot())
    834         clearFlag(IsInShadowTreeFlag);
    835 }
    836 
    837 inline void Element::invalidateStyleAttribute()
    838 {
    839     ASSERT(elementData());
    840     elementData()->m_styleAttributeIsDirty = true;
    841 }
    842 
    843 inline const StylePropertySet* Element::presentationAttributeStyle()
    844 {
    845     if (!elementData())
    846         return 0;
    847     if (elementData()->m_presentationAttributeStyleIsDirty)
    848         updatePresentationAttributeStyle();
    849     // Need to call elementData() again since updatePresentationAttributeStyle()
    850     // might swap it with a UniqueElementData.
    851     return elementData()->presentationAttributeStyle();
    852 }
    853 
    854 inline void Element::setTagNameForCreateElementNS(const QualifiedName& tagName)
    855 {
    856     // We expect this method to be called only to reset the prefix.
    857     ASSERT(tagName.localName() == m_tagName.localName());
    858     ASSERT(tagName.namespaceURI() == m_tagName.namespaceURI());
    859     m_tagName = tagName;
    860 }
    861 
    862 inline bool isShadowHost(const Node* node)
    863 {
    864     return node && node->isElementNode() && toElement(node)->shadow();
    865 }
    866 
    867 inline bool isShadowHost(const Element* element)
    868 {
    869     return element && element->shadow();
    870 }
    871 
    872 // These macros do the same as their NODE equivalents but additionally provide a template specialization
    873 // for isElementOfType<>() so that the Traversal<> API works for these Element types.
    874 #define DEFINE_ELEMENT_TYPE_CASTS(thisType, predicate) \
    875     template <> inline bool isElementOfType<const thisType>(const Element& element) { return element.predicate; } \
    876     DEFINE_NODE_TYPE_CASTS(thisType, predicate)
    877 
    878 #define DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
    879     template <> inline bool isElementOfType<const thisType>(const Element& element) { return is##thisType(element); } \
    880     DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType)
    881 
    882 #define DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
    883     static PassRefPtrWillBeRawPtr<T> create(const QualifiedName&, Document&)
    884 #define DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
    885     PassRefPtrWillBeRawPtr<T> T::create(const QualifiedName& tagName, Document& document) \
    886     { \
    887         return adoptRefWillBeNoop(new T(tagName, document)); \
    888     }
    889 
    890 } // namespace
    891 
    892 #endif
    893