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