Source/WebCore: Invalid cast in WebCore::toRenderMathMLBlock
[WebKit-https.git] / Source / WebCore / 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, 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 "CollectionType.h"
29 #include "Document.h"
30 #include "ElementData.h"
31 #include "HTMLNames.h"
32 #include "RegionOversetState.h"
33 #include "ScrollTypes.h"
34 #include "StyleResolveTree.h"
35
36 namespace WebCore {
37
38 class ClientRect;
39 class ClientRectList;
40 class DOMStringMap;
41 class DOMTokenList;
42 class ElementRareData;
43 class HTMLDocument;
44 class IntSize;
45 class Locale;
46 class PlatformKeyboardEvent;
47 class PlatformMouseEvent;
48 class PlatformWheelEvent;
49 class PseudoElement;
50 class RenderRegion;
51 class ShadowRoot;
52
53 enum AffectedSelectorType {
54     AffectedSelectorChecked = 1,
55     AffectedSelectorEnabled = 1 << 1,
56     AffectedSelectorDisabled = 1 << 2,
57     AffectedSelectorIndeterminate = 1 << 3,
58     AffectedSelectorLink = 1 << 4,
59     AffectedSelectorTarget = 1 << 5,
60     AffectedSelectorVisited = 1 << 6
61 };
62 typedef int AffectedSelectorMask;
63
64 enum SpellcheckAttributeState {
65     SpellcheckAttributeTrue,
66     SpellcheckAttributeFalse,
67     SpellcheckAttributeDefault
68 };
69
70 class Element : public ContainerNode {
71 public:
72     static PassRefPtr<Element> create(const QualifiedName&, Document&);
73     virtual ~Element();
74
75     DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
76     DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
77     DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
78     DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
79     DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
80     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
81     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
82     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
83     DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
84     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
85     DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
86     DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
87     DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
88     DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
89     DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
90     DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
91     DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
92     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
93     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
94     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
95     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
96     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
97     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
98     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
99     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
100     DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
101     DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
102     DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
103     DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
104
105     // These four attribute event handler attributes are overridden by HTMLBodyElement
106     // and HTMLFrameSetElement to forward to the DOMWindow.
107     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur);
108     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error);
109     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus);
110     DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load);
111
112     // WebKit extensions
113     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
114     DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
115     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
116     DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
117     DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
118     DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
119     DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
120     DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
121     DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
122 #if ENABLE(TOUCH_EVENTS)
123     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
124     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
125     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
126     DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
127 #endif
128 #if ENABLE(FULLSCREEN_API)
129     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
130     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror);
131 #endif
132
133     bool hasAttribute(const QualifiedName&) const;
134     const AtomicString& getAttribute(const QualifiedName&) const;
135     void setAttribute(const QualifiedName&, const AtomicString& value);
136     void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value);
137     void removeAttribute(const QualifiedName&);
138
139     // Typed getters and setters for language bindings.
140     int getIntegralAttribute(const QualifiedName& attributeName) const;
141     void setIntegralAttribute(const QualifiedName& attributeName, int value);
142     unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const;
143     void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value);
144
145     // Call this to get the value of an attribute that is known not to be the style
146     // attribute or one of the SVG animatable attributes.
147     bool fastHasAttribute(const QualifiedName&) const;
148     const AtomicString& fastGetAttribute(const QualifiedName&) const;
149 #ifndef NDEBUG
150     bool fastAttributeLookupAllowed(const QualifiedName&) const;
151 #endif
152
153 #ifdef DUMP_NODE_STATISTICS
154     bool hasNamedNodeMap() const;
155 #endif
156     bool hasAttributes() const;
157     // This variant will not update the potentially invalid attributes. To be used when not interested
158     // in style attribute or one of the SVG animation attributes.
159     bool hasAttributesWithoutUpdate() const;
160
161     bool hasAttribute(const AtomicString& name) const;
162     bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
163
164     const AtomicString& getAttribute(const AtomicString& name) const;
165     const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
166
167     void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
168     static bool parseAttributeName(QualifiedName&, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode&);
169     void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&);
170
171     bool isIdAttributeName(const QualifiedName&) const;
172     const AtomicString& getIdAttribute() const;
173     void setIdAttribute(const AtomicString&);
174
175     const AtomicString& getNameAttribute() const;
176
177     // Call this to get the value of the id attribute for style resolution purposes.
178     // The value will already be lowercased if the document is in compatibility mode,
179     // so this function is not suitable for non-style uses.
180     const AtomicString& idForStyleResolution() const;
181
182     // Internal methods that assume the existence of attribute storage, one should use hasAttributes()
183     // before calling them.
184     unsigned attributeCount() const;
185     const Attribute& attributeAt(unsigned index) const;
186     const Attribute* findAttributeByName(const QualifiedName&) const;
187     unsigned findAttributeIndexByName(const QualifiedName& name) const { return elementData()->findAttributeIndexByName(name); }
188     unsigned findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->findAttributeIndexByName(name, shouldIgnoreAttributeCase); }
189
190     void scrollIntoView(bool alignToTop = true);
191     void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
192
193     void scrollByLines(int lines);
194     void scrollByPages(int pages);
195
196     int offsetLeft();
197     int offsetTop();
198     int offsetWidth();
199     int offsetHeight();
200
201     // FIXME: Replace uses of offsetParent in the platform with calls
202     // to the render layer and merge bindingsOffsetParent and offsetParent.
203     Element* bindingsOffsetParent();
204
205     Element* offsetParent();
206     int clientLeft();
207     int clientTop();
208     int clientWidth();
209     int clientHeight();
210     virtual int scrollLeft();
211     virtual int scrollTop();
212     virtual void setScrollLeft(int);
213     virtual void setScrollTop(int);
214     virtual int scrollWidth();
215     virtual int scrollHeight();
216
217     IntRect boundsInRootViewSpace();
218
219     PassRefPtr<ClientRectList> getClientRects();
220     PassRefPtr<ClientRect> getBoundingClientRect();
221     
222     // Returns the absolute bounding box translated into screen coordinates:
223     IntRect screenRect() const;
224
225     void removeAttribute(const AtomicString& name);
226     void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
227
228     PassRefPtr<Attr> detachAttribute(unsigned index);
229
230     PassRefPtr<Attr> getAttributeNode(const AtomicString& name);
231     PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
232     PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
233     PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
234     PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
235
236     PassRefPtr<Attr> attrIfExists(const QualifiedName&);
237     PassRefPtr<Attr> ensureAttr(const QualifiedName&);
238
239     const Vector<RefPtr<Attr>>& attrNodeList();
240
241     virtual CSSStyleDeclaration* style();
242
243     const QualifiedName& tagQName() const { return m_tagName; }
244     String tagName() const { return nodeName(); }
245     bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
246     
247     // A fast function for checking the local name against another atomic string.
248     bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
249     bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
250
251     virtual const AtomicString& localName() const OVERRIDE FINAL { return m_tagName.localName(); }
252     virtual const AtomicString& prefix() const OVERRIDE FINAL { return m_tagName.prefix(); }
253     virtual const AtomicString& namespaceURI() const OVERRIDE FINAL { return m_tagName.namespaceURI(); }
254
255     virtual URL baseURI() const OVERRIDE FINAL;
256
257     virtual String nodeName() const OVERRIDE;
258
259     PassRefPtr<Element> cloneElementWithChildren();
260     PassRefPtr<Element> cloneElementWithoutChildren();
261
262     void normalizeAttributes();
263     String nodeNamePreservingCase() const;
264
265     void setBooleanAttribute(const QualifiedName& name, bool);
266
267     // For exposing to DOM only.
268     NamedNodeMap* attributes() 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 attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly);
277     virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
278
279     // Only called by the parser immediately after element construction.
280     void parserSetAttributes(const Vector<Attribute>&);
281
282     // Remove attributes that might introduce scripting from the vector leaving the element unchanged.
283     void stripScriptingAttributes(Vector<Attribute>&) const;
284
285     const ElementData* elementData() const { return m_elementData.get(); }
286     UniqueElementData& ensureUniqueElementData();
287
288     void synchronizeAllAttributes() const;
289
290     // Clones attributes only.
291     void cloneAttributesFromElement(const Element&);
292
293     // Clones all attribute-derived data, including subclass specifics (through copyNonAttributeProperties.)
294     void cloneDataFromElement(const Element&);
295
296     bool hasEquivalentAttributes(const Element* other) const;
297
298     virtual void copyNonAttributePropertiesFromElement(const Element&) { }
299
300     enum ShouldSetAttached {
301         SetAttached,
302         DoNotSetAttached
303     };
304     void lazyAttach(ShouldSetAttached = SetAttached);
305     void lazyReattach(ShouldSetAttached = SetAttached);
306
307     virtual RenderElement* createRenderer(PassRef<RenderStyle>);
308     virtual bool rendererIsNeeded(const RenderStyle&);
309     void didAffectSelector(AffectedSelectorMask);
310
311     ShadowRoot* shadowRoot() const;
312     PassRefPtr<ShadowRoot> createShadowRoot(ExceptionCode&);
313     ShadowRoot* authorShadowRoot() const;
314
315     bool hasAuthorShadowRoot() const { return authorShadowRoot(); }
316
317     ShadowRoot* userAgentShadowRoot() const;
318     ShadowRoot& ensureUserAgentShadowRoot();
319
320     virtual const AtomicString& shadowPseudoId() const;
321
322     bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
323     bool active() const { return isUserActionElement() && isUserActionElementActive(); }
324     bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
325     bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
326
327     virtual void setActive(bool flag = true, bool pause = false);
328     virtual void setHovered(bool flag = true);
329     virtual void setFocus(bool flag);
330
331     virtual bool supportsFocus() const;
332     virtual bool isFocusable() const;
333     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
334     virtual bool isMouseFocusable() const;
335
336     virtual bool shouldUseInputMethod();
337
338     virtual short tabIndex() const;
339     virtual Element* focusDelegate();
340
341     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
342
343     // Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
344     bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); }
345     bool childrenAffectedByHover() const { return hasRareData() && rareDataChildrenAffectedByHover(); }
346     bool childrenAffectedByActive() const { return hasRareData() && rareDataChildrenAffectedByActive(); }
347     bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
348     bool childrenAffectedByPositionalRules() const { return hasRareData() && (rareDataChildrenAffectedByForwardPositionalRules() || rareDataChildrenAffectedByBackwardPositionalRules()); }
349     bool childrenAffectedByFirstChildRules() const { return hasRareData() && rareDataChildrenAffectedByFirstChildRules(); }
350     bool childrenAffectedByLastChildRules() const { return hasRareData() && rareDataChildrenAffectedByLastChildRules(); }
351     bool childrenAffectedByDirectAdjacentRules() const { return hasRareData() && rareDataChildrenAffectedByDirectAdjacentRules(); }
352     bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); }
353     bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
354     unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; }
355
356     bool hasFlagsSetDuringStylingOfChildren() const;
357
358     void setStyleAffectedByEmpty();
359     void setChildrenAffectedByHover(bool);
360     void setChildrenAffectedByActive(bool);
361     void setChildrenAffectedByDrag(bool);
362     void setChildrenAffectedByFirstChildRules();
363     void setChildrenAffectedByLastChildRules();
364     void setChildrenAffectedByDirectAdjacentRules();
365     void setChildrenAffectedByForwardPositionalRules();
366     void setChildrenAffectedByBackwardPositionalRules();
367     void setChildIndex(unsigned);
368
369     void setIsInCanvasSubtree(bool);
370     bool isInCanvasSubtree() const;
371
372     void setIsInsideRegion(bool);
373     bool isInsideRegion() const;
374
375     void setRegionOversetState(RegionOversetState);
376     RegionOversetState regionOversetState() const;
377
378     AtomicString computeInheritedLanguage() const;
379     Locale& locale() const;
380
381     virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
382
383     virtual bool isURLAttribute(const Attribute&) const { return false; }
384     virtual bool isHTMLContentAttribute(const Attribute&) const { return false; }
385
386     URL getURLAttribute(const QualifiedName&) const;
387     URL getNonEmptyURLAttribute(const QualifiedName&) const;
388
389     virtual const AtomicString& imageSourceURL() const;
390     virtual String target() const { return String(); }
391
392     void updateFocusAppearanceAfterAttachIfNeeded();
393     virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone);
394     virtual void updateFocusAppearance(bool restorePreviousSelection);
395     virtual void blur();
396
397     String innerText();
398     String outerText();
399  
400     virtual String title() const;
401
402     const AtomicString& pseudo() const;
403     void setPseudo(const AtomicString&);
404
405     LayoutSize minimumSizeForResizing() const;
406     void setMinimumSizeForResizing(const LayoutSize&);
407
408     // Use Document::registerForDocumentActivationCallbacks() to subscribe to these
409     virtual void documentWillSuspendForPageCache() { }
410     virtual void documentDidResumeFromPageCache() { }
411
412     // Use Document::registerForMediaVolumeCallbacks() to subscribe to this
413     virtual void mediaVolumeDidChange() { }
414
415     // Use Document::registerForPrivateBrowsingStateChangedCallbacks() to subscribe to this.
416     virtual void privateBrowsingStateDidChange() { }
417
418     virtual void didBecomeFullscreenElement() { }
419     virtual void willStopBeingFullscreenElement() { }
420
421 #if ENABLE(PAGE_VISIBILITY_API)
422     // Use Document::registerForVisibilityStateChangedCallbacks() to subscribe to this.
423     virtual void visibilityStateChanged() { }
424 #endif
425
426 #if ENABLE(VIDEO_TRACK)
427     virtual void captionPreferencesChanged() { }
428 #endif
429
430     bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
431     virtual void finishParsingChildren() OVERRIDE;
432     virtual void beginParsingChildren() OVERRIDE FINAL;
433
434     PseudoElement* beforePseudoElement() const;
435     PseudoElement* afterPseudoElement() const;
436     bool childNeedsShadowWalker() const;
437     void didShadowTreeAwareChildrenChange();
438
439     // ElementTraversal API
440     Element* firstElementChild() const;
441     Element* lastElementChild() const;
442     Element* previousElementSibling() const;
443     Element* nextElementSibling() const;
444     unsigned childElementCount() const;
445
446     virtual bool matchesReadOnlyPseudoClass() const;
447     virtual bool matchesReadWritePseudoClass() const;
448     bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
449     virtual bool shouldAppearIndeterminate() const;
450
451     DOMTokenList* classList();
452
453     DOMStringMap* dataset();
454
455 #if ENABLE(VIDEO)
456     virtual bool isMediaElement() const { return false; }
457 #endif
458
459 #if ENABLE(INPUT_SPEECH)
460     virtual bool isInputFieldSpeechButtonElement() const { return false; }
461 #endif
462
463     virtual bool isFormControlElement() const { return false; }
464     virtual bool isSpinButtonElement() const { return false; }
465     virtual bool isTextFormControl() const { return false; }
466     virtual bool isOptionalFormControl() const { return false; }
467     virtual bool isRequiredFormControl() const { return false; }
468     virtual bool isDefaultButtonForForm() const { return false; }
469     virtual bool willValidate() const { return false; }
470     virtual bool isValidFormControlElement() { return false; }
471     virtual bool isInRange() const { return false; }
472     virtual bool isOutOfRange() const { return false; }
473     virtual bool isFrameElementBase() const { return false; }
474     virtual bool isSearchFieldCancelButtonElement() const { return false; }
475
476     virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
477
478     // Used for disabled form elements; if true, prevents mouse events from being dispatched
479     // to event listeners, and prevents DOMActivate events from being sent at all.
480     virtual bool isDisabledFormControl() const { return false; }
481
482
483 #if ENABLE(SVG) || ENABLE(MATHML)
484     virtual bool childShouldCreateRenderer(const Node*) const OVERRIDE;
485 #endif
486 #if ENABLE(SVG)
487     bool hasPendingResources() const;
488     void setHasPendingResources();
489     void clearHasPendingResources();
490     virtual void buildPendingResource() { };
491 #endif
492
493 #if ENABLE(FULLSCREEN_API)
494     enum {
495         ALLOW_KEYBOARD_INPUT = 1 << 0,
496         LEGACY_MOZILLA_REQUEST = 1 << 1,
497     };
498     
499     void webkitRequestFullScreen(unsigned short flags);
500     bool containsFullScreenElement() const;
501     void setContainsFullScreenElement(bool);
502     void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool);
503
504     // W3C API
505     void webkitRequestFullscreen();
506 #endif
507
508 #if ENABLE(POINTER_LOCK)
509     void webkitRequestPointerLock();
510 #endif
511
512 #if ENABLE(INDIE_UI)
513     void setUIActions(const AtomicString&);
514     const AtomicString& UIActions() const;
515 #endif
516     
517     virtual bool isSpellCheckingEnabled() const;
518
519     PassRef<RenderStyle> styleForRenderer();
520
521     RenderRegion* renderRegion() const;
522
523 #if ENABLE(CSS_REGIONS)
524     virtual bool shouldMoveToFlowThread(const RenderStyle&) const;
525     
526     const AtomicString& webkitRegionOverset() const;
527     Vector<RefPtr<Range>> webkitGetRegionFlowRanges() const;
528 #endif
529
530     bool hasID() const;
531     bool hasClass() const;
532     bool hasName() const;
533     const SpaceSplitString& classNames() const;
534
535     IntSize savedLayerScrollOffset() const;
536     void setSavedLayerScrollOffset(const IntSize&);
537
538     bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Element* relatedTarget = nullptr);
539     bool dispatchWheelEvent(const PlatformWheelEvent&);
540     bool dispatchKeyEvent(const PlatformKeyboardEvent&);
541     void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook);
542     void dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement);
543     void dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement);
544     virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection);
545     virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement);
546
547     virtual bool willRecalcStyle(Style::Change);
548     virtual void didRecalcStyle(Style::Change);
549     virtual void willAttachRenderers();
550     virtual void didAttachRenderers();
551     virtual void willDetachRenderers();
552     virtual void didDetachRenderers();
553
554     void updateBeforePseudoElement(Style::Change);
555     void updateAfterPseudoElement(Style::Change);
556     void resetComputedStyle();
557     void clearStyleDerivedDataBeforeDetachingRenderer();
558     void clearHoverAndActiveStatusBeforeDetachingRenderer();
559
560 protected:
561     Element(const QualifiedName& tagName, Document& document, ConstructionType type)
562         : ContainerNode(&document, type)
563         , m_tagName(tagName)
564     {
565     }
566
567     virtual InsertionNotificationRequest insertedInto(ContainerNode&) OVERRIDE;
568     virtual void removedFrom(ContainerNode&) OVERRIDE;
569     virtual void childrenChanged(const ChildChange&) OVERRIDE;
570     virtual void removeAllEventListeners() OVERRIDE FINAL;
571
572     virtual PassRefPtr<RenderStyle> customStyleForRenderer();
573
574     void clearTabIndexExplicitlyIfNeeded();    
575     void setTabIndexExplicitly(short);
576
577     PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
578     HTMLCollection* cachedHTMLCollection(CollectionType);
579
580     // classAttributeChanged() exists to share code between
581     // parseAttribute (called via setAttribute()) and
582     // svgAttributeChanged (called when element.className.baseValue is set)
583     void classAttributeChanged(const AtomicString& newClassString);
584
585 private:
586     bool isTextNode() const;
587
588     bool isUserActionElementInActiveChain() const;
589     bool isUserActionElementActive() const;
590     bool isUserActionElementFocused() const;
591     bool isUserActionElementHovered() const;
592
593     PassRefPtr<PseudoElement> createPseudoElementIfNeeded(PseudoId);
594     bool updateExistingPseudoElement(PseudoElement* existing, Style::Change);
595
596     void setBeforePseudoElement(PassRefPtr<PseudoElement>);
597     void setAfterPseudoElement(PassRefPtr<PseudoElement>);
598     void clearBeforePseudoElement();
599     void clearAfterPseudoElement();
600     void resetNeedsNodeRenderingTraversalSlowPath();
601
602     virtual bool areAuthorShadowsAllowed() const { return true; }
603     virtual void didAddUserAgentShadowRoot(ShadowRoot*) { }
604     virtual bool alwaysCreateUserAgentShadowRoot() const { return false; }
605
606     // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
607     friend class Attr;
608
609     enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute = 0, InSynchronizationOfLazyAttribute };
610
611     void didAddAttribute(const QualifiedName&, const AtomicString&);
612     void willModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
613     void didModifyAttribute(const QualifiedName&, const AtomicString&);
614     void didRemoveAttribute(const QualifiedName&);
615
616     void synchronizeAttribute(const QualifiedName&) const;
617     void synchronizeAttribute(const AtomicString& localName) const;
618
619     void updateName(const AtomicString& oldName, const AtomicString& newName);
620     void updateNameForTreeScope(TreeScope&, const AtomicString& oldName, const AtomicString& newName);
621     void updateNameForDocument(HTMLDocument&, const AtomicString& oldName, const AtomicString& newName);
622     void updateId(const AtomicString& oldId, const AtomicString& newId);
623     void updateIdForTreeScope(TreeScope&, const AtomicString& oldId, const AtomicString& newId);
624     enum HTMLDocumentNamedItemMapsUpdatingCondition { AlwaysUpdateHTMLDocumentNamedItemMaps, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute };
625     void updateIdForDocument(HTMLDocument&, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition);
626     void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
627
628     void scrollByUnits(int units, ScrollGranularity);
629
630     virtual void setPrefix(const AtomicString&, ExceptionCode&) OVERRIDE FINAL;
631     virtual NodeType nodeType() const OVERRIDE FINAL;
632     virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
633
634     void setAttributeInternal(unsigned index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
635     void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
636     void removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute);
637
638 #ifndef NDEBUG
639     virtual void formatForDebugger(char* buffer, unsigned length) const OVERRIDE;
640 #endif
641
642     void cancelFocusAppearanceUpdate();
643
644     virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE { return computedStyle(pseudoElementSpecifier); }
645     
646     // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
647     // are used instead.
648     virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
649     virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
650
651     void addShadowRoot(PassRefPtr<ShadowRoot>);
652     void removeShadowRoot();
653
654     bool rareDataStyleAffectedByEmpty() const;
655     bool rareDataChildrenAffectedByHover() const;
656     bool rareDataChildrenAffectedByActive() const;
657     bool rareDataChildrenAffectedByDrag() const;
658     bool rareDataChildrenAffectedByFirstChildRules() const;
659     bool rareDataChildrenAffectedByLastChildRules() const;
660     bool rareDataChildrenAffectedByDirectAdjacentRules() const;
661     bool rareDataChildrenAffectedByForwardPositionalRules() const;
662     bool rareDataChildrenAffectedByBackwardPositionalRules() const;
663     unsigned rareDataChildIndex() const;
664
665     SpellcheckAttributeState spellcheckAttributeState() const;
666
667     void unregisterNamedFlowContentElement();
668
669     void createUniqueElementData();
670
671     ElementRareData* elementRareData() const;
672     ElementRareData& ensureElementRareData();
673
674     void detachAllAttrNodesFromElement();
675     void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
676
677     bool isJavaScriptURLAttribute(const Attribute&) const;
678
679     // Anyone thinking of using this should call document instead of ownerDocument.
680     void ownerDocument() const WTF_DELETED_FUNCTION;
681
682     QualifiedName m_tagName;
683     RefPtr<ElementData> m_elementData;
684 };
685
686 inline bool isElement(const Node& node) { return node.isElementNode(); }
687
688 NODE_TYPE_CASTS(Element)
689
690 template <typename Type> bool isElementOfType(const Element&);
691 template <typename Type> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const Type>(toElement(node)); }
692 template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
693
694 inline bool Node::hasTagName(const QualifiedName& name) const
695 {
696     return isElementNode() && toElement(this)->hasTagName(name);
697 }
698     
699 inline bool Node::hasLocalName(const AtomicString& name) const
700 {
701     return isElementNode() && toElement(this)->hasLocalName(name);
702 }
703
704 inline bool Node::hasAttributes() const
705 {
706     return isElementNode() && toElement(this)->hasAttributes();
707 }
708
709 inline NamedNodeMap* Node::attributes() const
710 {
711     return isElementNode() ? toElement(this)->attributes() : nullptr;
712 }
713
714 inline Element* Node::parentElement() const
715 {
716     ContainerNode* parent = parentNode();
717     return parent && parent->isElementNode() ? toElement(parent) : nullptr;
718 }
719
720 inline bool Element::fastHasAttribute(const QualifiedName& name) const
721 {
722     ASSERT(fastAttributeLookupAllowed(name));
723     return elementData() && findAttributeByName(name);
724 }
725
726 inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const
727 {
728     ASSERT(fastAttributeLookupAllowed(name));
729     if (elementData()) {
730         if (const Attribute* attribute = findAttributeByName(name))
731             return attribute->value();
732     }
733     return nullAtom;
734 }
735
736 inline bool Element::hasAttributesWithoutUpdate() const
737 {
738     return elementData() && !elementData()->isEmpty();
739 }
740
741 inline const AtomicString& Element::idForStyleResolution() const
742 {
743     ASSERT(hasID());
744     return elementData()->idForStyleResolution();
745 }
746
747 inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const
748 {
749     // FIXME: This check is probably not correct for the case where the document has an id attribute
750     // with a non-null namespace, because it will return false, a false negative, if the prefixes
751     // don't match but the local name and namespace both do. However, since this has been like this
752     // for a while and the code paths may be hot, we'll have to measure performance if we fix it.
753     return attributeName == document().idAttributeName();
754 }
755
756 inline const AtomicString& Element::getIdAttribute() const
757 {
758     return hasID() ? fastGetAttribute(document().idAttributeName()) : nullAtom;
759 }
760
761 inline const AtomicString& Element::getNameAttribute() const
762 {
763     return hasName() ? fastGetAttribute(HTMLNames::nameAttr) : nullAtom;
764 }
765
766 inline void Element::setIdAttribute(const AtomicString& value)
767 {
768     setAttribute(document().idAttributeName(), value);
769 }
770
771 inline const SpaceSplitString& Element::classNames() const
772 {
773     ASSERT(hasClass());
774     ASSERT(elementData());
775     return elementData()->classNames();
776 }
777
778 inline unsigned Element::attributeCount() const
779 {
780     ASSERT(elementData());
781     return elementData()->length();
782 }
783
784 inline const Attribute& Element::attributeAt(unsigned index) const
785 {
786     ASSERT(elementData());
787     return elementData()->attributeAt(index);
788 }
789
790 inline const Attribute* Element::findAttributeByName(const QualifiedName& name) const
791 {
792     ASSERT(elementData());
793     return elementData()->findAttributeByName(name);
794 }
795
796 inline bool Element::hasID() const
797 {
798     return elementData() && elementData()->hasID();
799 }
800
801 inline bool Element::hasClass() const
802 {
803     return elementData() && elementData()->hasClass();
804 }
805
806 inline bool Element::hasName() const
807 {
808     return elementData() && elementData()->hasName();
809 }
810
811 inline UniqueElementData& Element::ensureUniqueElementData()
812 {
813     if (!elementData() || !elementData()->isUnique())
814         createUniqueElementData();
815     return static_cast<UniqueElementData&>(*m_elementData);
816 }
817
818 } // namespace
819
820 #endif