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