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-2016 Apple Inc. All rights reserved.
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.
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.
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.
28 #include "AXTextStateChangeIntent.h"
30 #include "ElementData.h"
31 #include "HTMLNames.h"
32 #include "RegionOversetState.h"
33 #include "ScrollTypes.h"
34 #include "SimulatedClickOptions.h"
35 #include "StyleChange.h"
41 class DatasetDOMStringMap;
44 class ElementRareData;
49 class PlatformKeyboardEvent;
50 class PlatformMouseEvent;
51 class PlatformWheelEvent;
53 class RenderNamedFlowFragment;
54 class RenderTreePosition;
57 enum SpellcheckAttributeState {
58 SpellcheckAttributeTrue,
59 SpellcheckAttributeFalse,
60 SpellcheckAttributeDefault
63 enum class SelectionRevealMode {
65 RevealUpToMainFrame, // Scroll overflow and iframes, but not the main frame.
69 class Element : public ContainerNode {
71 static Ref<Element> create(const QualifiedName&, Document&);
74 WEBCORE_EXPORT bool hasAttribute(const QualifiedName&) const;
75 WEBCORE_EXPORT const AtomicString& getAttribute(const QualifiedName&) const;
76 WEBCORE_EXPORT void setAttribute(const QualifiedName&, const AtomicString& value);
77 WEBCORE_EXPORT void setAttributeWithoutSynchronization(const QualifiedName&, const AtomicString& value);
78 void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value);
79 bool removeAttribute(const QualifiedName&);
80 Vector<String> getAttributeNames() const;
82 // Typed getters and setters for language bindings.
83 int getIntegralAttribute(const QualifiedName& attributeName) const;
84 void setIntegralAttribute(const QualifiedName& attributeName, int value);
85 unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const;
86 void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value);
88 // Call this to get the value of an attribute that is known not to be the style
89 // attribute or one of the SVG animatable attributes.
90 bool hasAttributeWithoutSynchronization(const QualifiedName&) const;
91 const AtomicString& attributeWithoutSynchronization(const QualifiedName&) const;
93 WEBCORE_EXPORT bool fastAttributeLookupAllowed(const QualifiedName&) const;
96 #ifdef DUMP_NODE_STATISTICS
97 bool hasNamedNodeMap() const;
99 bool hasAttributes() const;
100 // This variant will not update the potentially invalid attributes. To be used when not interested
101 // in style attribute or one of the SVG animation attributes.
102 bool hasAttributesWithoutUpdate() const;
104 WEBCORE_EXPORT bool hasAttribute(const AtomicString& name) const;
105 bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
107 WEBCORE_EXPORT const AtomicString& getAttribute(const AtomicString& name) const;
108 const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
110 WEBCORE_EXPORT void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
111 static bool parseAttributeName(QualifiedName&, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode&);
112 void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&);
114 const AtomicString& getIdAttribute() const;
115 void setIdAttribute(const AtomicString&);
117 const AtomicString& getNameAttribute() const;
119 // Call this to get the value of the id attribute for style resolution purposes.
120 // The value will already be lowercased if the document is in compatibility mode,
121 // so this function is not suitable for non-style uses.
122 const AtomicString& idForStyleResolution() const;
124 // Internal methods that assume the existence of attribute storage, one should use hasAttributes()
125 // before calling them.
126 AttributeIteratorAccessor attributesIterator() const { return elementData()->attributesIterator(); }
127 unsigned attributeCount() const;
128 const Attribute& attributeAt(unsigned index) const;
129 const Attribute* findAttributeByName(const QualifiedName&) const;
130 unsigned findAttributeIndexByName(const QualifiedName& name) const { return elementData()->findAttributeIndexByName(name); }
131 unsigned findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->findAttributeIndexByName(name, shouldIgnoreAttributeCase); }
133 void scrollIntoView(bool alignToTop = true);
134 WEBCORE_EXPORT void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
135 WEBCORE_EXPORT void scrollIntoViewIfNotVisible(bool centerIfNotVisible = true);
137 void scrollByLines(int lines);
138 void scrollByPages(int pages);
142 double offsetWidth();
143 double offsetHeight();
145 bool mayCauseRepaintInsideViewport(const IntRect* visibleRect = nullptr) const;
147 // FIXME: Replace uses of offsetParent in the platform with calls
148 // to the render layer and merge bindingsOffsetParent and offsetParent.
149 Element* bindingsOffsetParent();
151 const Element* rootElement() const;
153 Element* offsetParent();
156 double clientWidth();
157 double clientHeight();
158 virtual int scrollLeft();
159 virtual int scrollTop();
160 virtual void setScrollLeft(int);
161 virtual void setScrollTop(int);
162 virtual int scrollWidth();
163 virtual int scrollHeight();
165 WEBCORE_EXPORT IntRect boundsInRootViewSpace();
167 Ref<ClientRectList> getClientRects();
168 Ref<ClientRect> getBoundingClientRect();
170 // Returns the absolute bounding box translated into client coordinates.
171 WEBCORE_EXPORT IntRect clientRect() const;
172 // Returns the absolute bounding box translated into screen coordinates.
173 WEBCORE_EXPORT IntRect screenRect() const;
175 bool removeAttribute(const AtomicString& name);
176 bool removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
178 Ref<Attr> detachAttribute(unsigned index);
180 RefPtr<Attr> getAttributeNode(const AtomicString& name);
181 RefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
182 RefPtr<Attr> setAttributeNode(Attr&, ExceptionCode&);
183 RefPtr<Attr> setAttributeNodeNS(Attr&, ExceptionCode&);
184 RefPtr<Attr> removeAttributeNode(Attr&, ExceptionCode&);
186 RefPtr<Attr> attrIfExists(const QualifiedName&);
187 RefPtr<Attr> attrIfExists(const AtomicString& localName, bool shouldIgnoreAttributeCase);
188 Ref<Attr> ensureAttr(const QualifiedName&);
190 const Vector<RefPtr<Attr>>& attrNodeList();
192 virtual CSSStyleDeclaration* cssomStyle();
194 const QualifiedName& tagQName() const { return m_tagName; }
195 #if ENABLE(CSS_SELECTOR_JIT)
196 static ptrdiff_t tagQNameMemoryOffset() { return OBJECT_OFFSETOF(Element, m_tagName); }
197 #endif // ENABLE(CSS_SELECTOR_JIT)
198 String tagName() const { return nodeName(); }
199 bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
200 bool hasTagName(const HTMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
201 bool hasTagName(const MathMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
202 bool hasTagName(const SVGQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
204 // A fast function for checking the local name against another atomic string.
205 bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
207 const AtomicString& localName() const final { return m_tagName.localName(); }
208 const AtomicString& prefix() const final { return m_tagName.prefix(); }
209 const AtomicString& namespaceURI() const final { return m_tagName.namespaceURI(); }
211 String nodeName() const override;
213 Ref<Element> cloneElementWithChildren(Document&);
214 Ref<Element> cloneElementWithoutChildren(Document&);
216 void normalizeAttributes();
217 String nodeNamePreservingCase() const;
219 void setBooleanAttribute(const QualifiedName& name, bool);
221 // For exposing to DOM only.
222 NamedNodeMap& attributes() const;
224 enum AttributeModificationReason {
229 // This method is called whenever an attribute is added, changed or removed.
230 virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly);
231 virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
233 // Only called by the parser immediately after element construction.
234 void parserSetAttributes(const Vector<Attribute>&);
236 // Remove attributes that might introduce scripting from the vector leaving the element unchanged.
237 void stripScriptingAttributes(Vector<Attribute>&) const;
239 const ElementData* elementData() const { return m_elementData.get(); }
240 static ptrdiff_t elementDataMemoryOffset() { return OBJECT_OFFSETOF(Element, m_elementData); }
241 UniqueElementData& ensureUniqueElementData();
243 void synchronizeAllAttributes() const;
245 // Clones attributes only.
246 void cloneAttributesFromElement(const Element&);
248 // Clones all attribute-derived data, including subclass specifics (through copyNonAttributeProperties.)
249 void cloneDataFromElement(const Element&);
251 bool hasEquivalentAttributes(const Element* other) const;
253 virtual void copyNonAttributePropertiesFromElement(const Element&) { }
255 virtual RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&);
256 virtual bool rendererIsNeeded(const RenderStyle&);
258 WEBCORE_EXPORT ShadowRoot* shadowRoot() const;
259 WEBCORE_EXPORT RefPtr<ShadowRoot> createShadowRoot(ExceptionCode&);
261 enum class ShadowRootMode { Open, Closed };
262 struct ShadowRootInit {
266 ShadowRoot* shadowRootForBindings(JSC::ExecState&) const;
267 RefPtr<ShadowRoot> attachShadow(const ShadowRootInit&, ExceptionCode&);
269 ShadowRoot* userAgentShadowRoot() const;
270 WEBCORE_EXPORT ShadowRoot& ensureUserAgentShadowRoot();
272 // FIXME: this should not be virtual, do not override this.
273 virtual const AtomicString& shadowPseudoId() const;
275 bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
276 bool active() const { return isUserActionElement() && isUserActionElementActive(); }
277 bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
278 bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
279 bool hasFocusWithin() const { return getFlag(HasFocusWithin); };
281 virtual void setActive(bool flag = true, bool pause = false);
282 virtual void setHovered(bool flag = true);
283 virtual void setFocus(bool flag);
284 void setHasFocusWithin(bool flag);
286 bool tabIndexSetExplicitly() const;
287 virtual bool supportsFocus() const;
288 virtual bool isFocusable() const;
289 virtual bool isKeyboardFocusable(KeyboardEvent*) const;
290 virtual bool isMouseFocusable() const;
292 virtual bool shouldUseInputMethod();
294 virtual int tabIndex() const;
295 void setTabIndex(int);
296 virtual Element* focusDelegate();
298 Element* insertAdjacentElement(const String& where, Element& newChild, ExceptionCode&);
299 void insertAdjacentHTML(const String& where, const String& html, ExceptionCode&);
300 void insertAdjacentText(const String& where, const String& text, ExceptionCode&);
302 const RenderStyle* computedStyle(PseudoId = NOPSEUDO) override;
304 bool needsStyleInvalidation() const;
306 // Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
307 bool styleAffectedByActive() const { return hasRareData() && rareDataStyleAffectedByActive(); }
308 bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); }
309 bool styleAffectedByFocusWithin() const { return hasRareData() && rareDataStyleAffectedByFocusWithin(); }
310 bool childrenAffectedByHover() const { return getFlag(ChildrenAffectedByHoverRulesFlag); }
311 bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
312 bool childrenAffectedByFirstChildRules() const { return getFlag(ChildrenAffectedByFirstChildRulesFlag); }
313 bool childrenAffectedByLastChildRules() const { return getFlag(ChildrenAffectedByLastChildRulesFlag); }
314 bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
315 bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules(); }
316 bool affectsNextSiblingElementStyle() const { return getFlag(AffectsNextSiblingElementStyle); }
317 unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; }
319 bool hasFlagsSetDuringStylingOfChildren() const;
321 void setStyleAffectedByEmpty();
322 void setStyleAffectedByFocusWithin();
323 void setChildrenAffectedByHover() { setFlag(ChildrenAffectedByHoverRulesFlag); }
324 void setStyleAffectedByActive();
325 void setChildrenAffectedByDrag();
326 void setChildrenAffectedByFirstChildRules() { setFlag(ChildrenAffectedByFirstChildRulesFlag); }
327 void setChildrenAffectedByLastChildRules() { setFlag(ChildrenAffectedByLastChildRulesFlag); }
328 void setChildrenAffectedByBackwardPositionalRules();
329 void setChildrenAffectedByPropertyBasedBackwardPositionalRules();
330 void setAffectsNextSiblingElementStyle() { setFlag(AffectsNextSiblingElementStyle); }
331 void setStyleIsAffectedByPreviousSibling() { setFlag(StyleIsAffectedByPreviousSibling); }
332 void setChildIndex(unsigned);
334 void setRegionOversetState(RegionOversetState);
335 RegionOversetState regionOversetState() const;
337 AtomicString computeInheritedLanguage() const;
338 Locale& locale() const;
340 virtual void accessKeyAction(bool /*sendToAnyEvent*/) { }
342 virtual bool isURLAttribute(const Attribute&) const { return false; }
343 virtual bool attributeContainsURL(const Attribute& attribute) const { return isURLAttribute(attribute); }
344 virtual String completeURLsInAttributeValue(const URL& base, const Attribute&) const;
345 virtual bool isHTMLContentAttribute(const Attribute&) const { return false; }
347 WEBCORE_EXPORT URL getURLAttribute(const QualifiedName&) const;
348 URL getNonEmptyURLAttribute(const QualifiedName&) const;
350 virtual const AtomicString& imageSourceURL() const;
351 virtual String target() const { return String(); }
353 static AXTextStateChangeIntent defaultFocusTextStateChangeIntent() { return AXTextStateChangeIntent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, true }); }
354 void updateFocusAppearanceAfterAttachIfNeeded();
355 virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone);
356 virtual void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode = SelectionRevealMode::Reveal);
359 String innerHTML() const;
360 String outerHTML() const;
361 void setInnerHTML(const String&, ExceptionCode&);
362 void setOuterHTML(const String&, ExceptionCode&);
363 WEBCORE_EXPORT String innerText();
366 virtual String title() const;
368 const AtomicString& pseudo() const;
369 WEBCORE_EXPORT void setPseudo(const AtomicString&);
371 LayoutSize minimumSizeForResizing() const;
372 void setMinimumSizeForResizing(const LayoutSize&);
374 // Use Document::registerForDocumentActivationCallbacks() to subscribe to these
375 virtual void prepareForDocumentSuspension() { }
376 virtual void resumeFromDocumentSuspension() { }
378 // Use Document::registerForMediaVolumeCallbacks() to subscribe to this
379 virtual void mediaVolumeDidChange() { }
381 // Use Document::registerForPrivateBrowsingStateChangedCallbacks() to subscribe to this.
382 virtual void privateBrowsingStateDidChange() { }
384 virtual void willBecomeFullscreenElement();
385 virtual void ancestorWillEnterFullscreen() { }
386 virtual void didBecomeFullscreenElement() { }
387 virtual void willStopBeingFullscreenElement() { }
389 // Use Document::registerForVisibilityStateChangedCallbacks() to subscribe to this.
390 virtual void visibilityStateChanged() { }
392 #if ENABLE(VIDEO_TRACK)
393 virtual void captionPreferencesChanged() { }
396 bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
397 void finishParsingChildren() override;
398 void beginParsingChildren() final;
400 WEBCORE_EXPORT PseudoElement* beforePseudoElement() const;
401 WEBCORE_EXPORT PseudoElement* afterPseudoElement() const;
402 bool childNeedsShadowWalker() const;
403 void didShadowTreeAwareChildrenChange();
405 virtual bool matchesValidPseudoClass() const;
406 virtual bool matchesInvalidPseudoClass() const;
407 virtual bool matchesReadWritePseudoClass() const;
408 virtual bool matchesIndeterminatePseudoClass() const;
409 virtual bool matchesDefaultPseudoClass() const;
410 bool matches(const String& selectors, ExceptionCode&);
411 Element* closest(const String& selectors, ExceptionCode&);
412 virtual bool shouldAppearIndeterminate() const;
414 DOMTokenList& classList();
416 DatasetDOMStringMap& dataset();
419 virtual bool isMediaElement() const { return false; }
422 virtual bool isFormControlElement() const { return false; }
423 virtual bool isSpinButtonElement() const { return false; }
424 virtual bool isTextFormControl() const { return false; }
425 virtual bool isOptionalFormControl() const { return false; }
426 virtual bool isRequiredFormControl() const { return false; }
427 virtual bool isInRange() const { return false; }
428 virtual bool isOutOfRange() const { return false; }
429 virtual bool isFrameElementBase() const { return false; }
431 bool canContainRangeEndPoint() const override;
433 // Used for disabled form elements; if true, prevents mouse events from being dispatched
434 // to event listeners, and prevents DOMActivate events from being sent at all.
435 virtual bool isDisabledFormControl() const { return false; }
437 virtual bool childShouldCreateRenderer(const Node&) const;
439 bool hasPendingResources() const;
440 void setHasPendingResources();
441 void clearHasPendingResources();
442 virtual void buildPendingResource() { };
444 #if ENABLE(FULLSCREEN_API)
446 ALLOW_KEYBOARD_INPUT = 1 << 0,
447 LEGACY_MOZILLA_REQUEST = 1 << 1,
450 void webkitRequestFullScreen(unsigned short flags);
451 WEBCORE_EXPORT bool containsFullScreenElement() const;
452 void setContainsFullScreenElement(bool);
453 void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool);
456 void webkitRequestFullscreen();
459 #if ENABLE(POINTER_LOCK)
460 void requestPointerLock();
464 void setUIActions(const AtomicString&);
465 const AtomicString& UIActions() const;
468 virtual bool isSpellCheckingEnabled() const;
470 RenderNamedFlowFragment* renderNamedFlowFragment() const;
472 #if ENABLE(CSS_REGIONS)
473 virtual bool shouldMoveToFlowThread(const RenderStyle&) const;
475 const AtomicString& webkitRegionOverset() const;
476 Vector<RefPtr<Range>> webkitGetRegionFlowRanges() const;
480 bool hasClass() const;
481 bool hasName() const;
482 const SpaceSplitString& classNames() const;
484 IntPoint savedLayerScrollPosition() const;
485 void setSavedLayerScrollPosition(const IntPoint&);
487 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Element* relatedTarget = nullptr);
488 bool dispatchWheelEvent(const PlatformWheelEvent&);
489 bool dispatchKeyEvent(const PlatformKeyboardEvent&);
490 void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook);
491 void dispatchSimulatedClickForBindings(Event* underlyingEvent);
492 void dispatchFocusInEvent(const AtomicString& eventType, RefPtr<Element>&& oldFocusedElement);
493 void dispatchFocusOutEvent(const AtomicString& eventType, RefPtr<Element>&& newFocusedElement);
494 virtual void dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection);
495 virtual void dispatchBlurEvent(RefPtr<Element>&& newFocusedElement);
497 WEBCORE_EXPORT bool dispatchMouseForceWillBegin();
499 virtual bool willRecalcStyle(Style::Change);
500 virtual void didRecalcStyle(Style::Change);
501 virtual void willResetComputedStyle();
502 virtual void willAttachRenderers();
503 virtual void didAttachRenderers();
504 virtual void willDetachRenderers();
505 virtual void didDetachRenderers();
506 virtual Optional<ElementStyle> resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle);
508 LayoutRect absoluteEventHandlerBounds(bool& includesFixedPositionElements) override;
510 void setBeforePseudoElement(Ref<PseudoElement>&&);
511 void setAfterPseudoElement(Ref<PseudoElement>&&);
512 void clearBeforePseudoElement();
513 void clearAfterPseudoElement();
514 void resetComputedStyle();
515 void clearStyleDerivedDataBeforeDetachingRenderer();
516 void clearHoverAndActiveStatusBeforeDetachingRenderer();
518 WEBCORE_EXPORT URL absoluteLinkURL() const;
520 #if ENABLE(TOUCH_EVENTS)
521 bool allowsDoubleTapGesture() const override;
524 StyleResolver& styleResolver();
525 ElementStyle resolveStyle(const RenderStyle* parentStyle);
527 bool hasDisplayContents() const;
528 void setHasDisplayContents(bool);
530 virtual void isVisibleInViewportChanged() { }
532 using ContainerNode::setAttributeEventListener;
533 void setAttributeEventListener(const AtomicString& eventType, const QualifiedName& attributeName, const AtomicString& value);
535 bool isNamedFlowContentElement() const { return hasRareData() && rareDataIsNamedFlowContentElement(); }
536 void setIsNamedFlowContentElement();
537 void clearIsNamedFlowContentElement();
540 Element(const QualifiedName&, Document&, ConstructionType);
542 InsertionNotificationRequest insertedInto(ContainerNode&) override;
543 void removedFrom(ContainerNode&) override;
544 void childrenChanged(const ChildChange&) override;
545 void removeAllEventListeners() final;
546 virtual void parserDidSetAttributes();
547 void didMoveToNewDocument(Document*) override;
549 void clearTabIndexExplicitlyIfNeeded();
550 void setTabIndexExplicitly(int);
552 // classAttributeChanged() exists to share code between
553 // parseAttribute (called via setAttribute()) and
554 // svgAttributeChanged (called when element.className.baseValue is set)
555 void classAttributeChanged(const AtomicString& newClassString);
557 void addShadowRoot(Ref<ShadowRoot>&&);
559 static void mergeWithNextTextNode(Text& node, ExceptionCode&);
562 bool isTextNode() const;
564 bool isUserActionElementInActiveChain() const;
565 bool isUserActionElementActive() const;
566 bool isUserActionElementFocused() const;
567 bool isUserActionElementHovered() const;
569 virtual void didAddUserAgentShadowRoot(ShadowRoot*) { }
570 virtual bool alwaysCreateUserAgentShadowRoot() const { return false; }
572 // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
575 enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute = 0, InSynchronizationOfLazyAttribute };
577 void didAddAttribute(const QualifiedName&, const AtomicString&);
578 void willModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
579 void didModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
580 void didRemoveAttribute(const QualifiedName&, const AtomicString& oldValue);
582 void synchronizeAttribute(const QualifiedName&) const;
583 void synchronizeAttribute(const AtomicString& localName) const;
585 void updateName(const AtomicString& oldName, const AtomicString& newName);
586 void updateNameForTreeScope(TreeScope&, const AtomicString& oldName, const AtomicString& newName);
587 void updateNameForDocument(HTMLDocument&, const AtomicString& oldName, const AtomicString& newName);
589 enum class NotifyObservers { No, Yes };
590 void updateId(const AtomicString& oldId, const AtomicString& newId, NotifyObservers = NotifyObservers::Yes);
591 void updateIdForTreeScope(TreeScope&, const AtomicString& oldId, const AtomicString& newId, NotifyObservers = NotifyObservers::Yes);
593 enum HTMLDocumentNamedItemMapsUpdatingCondition { AlwaysUpdateHTMLDocumentNamedItemMaps, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute };
594 void updateIdForDocument(HTMLDocument&, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition);
595 void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue);
597 Node* insertAdjacent(const String& where, Ref<Node>&& newChild, ExceptionCode&);
599 void scrollByUnits(int units, ScrollGranularity);
601 void setPrefix(const AtomicString&, ExceptionCode&) final;
602 NodeType nodeType() const final;
603 bool childTypeAllowed(NodeType) const final;
605 void setAttributeInternal(unsigned index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
606 void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
607 void removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute);
609 LayoutRect absoluteEventBounds(bool& boundsIncludeAllDescendantElements, bool& includesFixedPositionElements);
610 LayoutRect absoluteEventBoundsOfElementAndDescendants(bool& includesFixedPositionElements);
612 #if ENABLE(TREE_DEBUGGING)
613 void formatForDebugger(char* buffer, unsigned length) const override;
616 void cancelFocusAppearanceUpdate();
618 // The cloneNode function is private so that non-virtual cloneElementWith/WithoutChildren are used instead.
619 Ref<Node> cloneNodeInternal(Document&, CloningOperation) override;
620 virtual Ref<Element> cloneElementWithoutAttributesAndChildren(Document&);
622 void removeShadowRoot();
624 const RenderStyle* existingComputedStyle();
625 const RenderStyle& resolveComputedStyle();
627 bool rareDataStyleAffectedByEmpty() const;
628 bool rareDataStyleAffectedByFocusWithin() const;
629 bool rareDataIsNamedFlowContentElement() const;
630 bool rareDataChildrenAffectedByHover() const;
631 bool rareDataStyleAffectedByActive() const;
632 bool rareDataChildrenAffectedByDrag() const;
633 bool rareDataChildrenAffectedByLastChildRules() const;
634 bool rareDataChildrenAffectedByBackwardPositionalRules() const;
635 bool rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules() const;
636 unsigned rareDataChildIndex() const;
638 SpellcheckAttributeState spellcheckAttributeState() const;
640 void unregisterNamedFlowContentElement();
642 void createUniqueElementData();
644 ElementRareData* elementRareData() const;
645 ElementRareData& ensureElementRareData();
647 void detachAllAttrNodesFromElement();
648 void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
650 bool isJavaScriptURLAttribute(const Attribute&) const;
652 // Anyone thinking of using this should call document instead of ownerDocument.
653 void ownerDocument() const = delete;
655 QualifiedName m_tagName;
656 RefPtr<ElementData> m_elementData;
659 inline bool Node::hasAttributes() const
661 return is<Element>(*this) && downcast<Element>(*this).hasAttributes();
664 inline NamedNodeMap* Node::attributes() const
666 return is<Element>(*this) ? &downcast<Element>(*this).attributes() : nullptr;
669 inline Element* Node::parentElement() const
671 ContainerNode* parent = parentNode();
672 return is<Element>(parent) ? downcast<Element>(parent) : nullptr;
675 inline const Element* Element::rootElement() const
678 return document().documentElement();
680 const Element* highest = this;
681 while (highest->parentElement())
682 highest = highest->parentElement();
686 inline bool Element::hasAttributeWithoutSynchronization(const QualifiedName& name) const
688 ASSERT(fastAttributeLookupAllowed(name));
689 return elementData() && findAttributeByName(name);
692 inline const AtomicString& Element::attributeWithoutSynchronization(const QualifiedName& name) const
694 ASSERT(fastAttributeLookupAllowed(name));
696 if (const Attribute* attribute = findAttributeByName(name))
697 return attribute->value();
702 inline bool Element::hasAttributesWithoutUpdate() const
704 return elementData() && !elementData()->isEmpty();
707 inline const AtomicString& Element::idForStyleResolution() const
709 return hasID() ? elementData()->idForStyleResolution() : nullAtom;
712 inline const AtomicString& Element::getIdAttribute() const
715 return elementData()->findAttributeByName(HTMLNames::idAttr)->value();
719 inline const AtomicString& Element::getNameAttribute() const
722 return elementData()->findAttributeByName(HTMLNames::nameAttr)->value();
726 inline void Element::setIdAttribute(const AtomicString& value)
728 setAttributeWithoutSynchronization(HTMLNames::idAttr, value);
731 inline const SpaceSplitString& Element::classNames() const
734 ASSERT(elementData());
735 return elementData()->classNames();
738 inline unsigned Element::attributeCount() const
740 ASSERT(elementData());
741 return elementData()->length();
744 inline const Attribute& Element::attributeAt(unsigned index) const
746 ASSERT(elementData());
747 return elementData()->attributeAt(index);
750 inline const Attribute* Element::findAttributeByName(const QualifiedName& name) const
752 ASSERT(elementData());
753 return elementData()->findAttributeByName(name);
756 inline bool Element::hasID() const
758 return elementData() && elementData()->hasID();
761 inline bool Element::hasClass() const
763 return elementData() && elementData()->hasClass();
766 inline bool Element::hasName() const
768 return elementData() && elementData()->hasName();
771 inline UniqueElementData& Element::ensureUniqueElementData()
773 if (!elementData() || !elementData()->isUnique())
774 createUniqueElementData();
775 return static_cast<UniqueElementData&>(*m_elementData);
778 inline bool shouldIgnoreAttributeCase(const Element& element)
780 return element.isHTMLElement() && element.document().isHTMLDocument();
783 inline void Element::setHasFocusWithin(bool flag)
785 if (hasFocusWithin() == flag)
787 setFlag(flag, HasFocusWithin);
788 if (styleAffectedByFocusWithin())
789 setNeedsStyleRecalc();
792 } // namespace WebCore
794 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::Element)
795 static bool isType(const WebCore::Node& node) { return node.isElementNode(); }
796 SPECIALIZE_TYPE_TRAITS_END()