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