diff options
Diffstat (limited to 'Source/WebCore/dom/Element.h')
-rw-r--r-- | Source/WebCore/dom/Element.h | 630 |
1 files changed, 309 insertions, 321 deletions
diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h index 3d2741a93..089cc1041 100644 --- a/Source/WebCore/dom/Element.h +++ b/Source/WebCore/dom/Element.h @@ -3,7 +3,7 @@ * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Peter Kelly (pmk@post.com) * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,44 +22,40 @@ * */ -#ifndef Element_h -#define Element_h +#pragma once -#include "CollectionType.h" +#include "AXTextStateChangeIntent.h" #include "Document.h" #include "ElementData.h" #include "HTMLNames.h" #include "RegionOversetState.h" +#include "ScrollToOptions.h" #include "ScrollTypes.h" -#include "StyleResolveTree.h" +#include "ShadowRootMode.h" +#include "SimulatedClickOptions.h" +#include "StyleChange.h" namespace WebCore { class ClientRect; class ClientRectList; +class CustomElementReactionQueue; class DatasetDOMStringMap; class DOMTokenList; class ElementRareData; class HTMLDocument; class IntSize; +class JSCustomElementInterface; +class KeyboardEvent; class Locale; class PlatformKeyboardEvent; class PlatformMouseEvent; class PlatformWheelEvent; class PseudoElement; -class RenderRegion; -class ShadowRoot; - -enum AffectedSelectorType { - AffectedSelectorChecked = 1, - AffectedSelectorEnabled = 1 << 1, - AffectedSelectorDisabled = 1 << 2, - AffectedSelectorIndeterminate = 1 << 3, - AffectedSelectorLink = 1 << 4, - AffectedSelectorTarget = 1 << 5, - AffectedSelectorVisited = 1 << 6 -}; -typedef int AffectedSelectorMask; +class RenderNamedFlowFragment; +class RenderTreePosition; +class WebAnimation; +struct ElementStyle; enum SpellcheckAttributeState { SpellcheckAttributeTrue, @@ -67,113 +63,57 @@ enum SpellcheckAttributeState { SpellcheckAttributeDefault }; +enum class SelectionRevealMode { + Reveal, + RevealUpToMainFrame, // Scroll overflow and iframes, but not the main frame. + DoNotReveal +}; + class Element : public ContainerNode { public: - static PassRefPtr<Element> create(const QualifiedName&, Document&); + static Ref<Element> create(const QualifiedName&, Document&); virtual ~Element(); - DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); - DEFINE_ATTRIBUTE_EVENT_LISTENER(change); - DEFINE_ATTRIBUTE_EVENT_LISTENER(click); - DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); - DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); - DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); - DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); - DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); - DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); - DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); - DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); - DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); - DEFINE_ATTRIBUTE_EVENT_LISTENER(input); - DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); - DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); - DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); - DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); - DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); - DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); - DEFINE_ATTRIBUTE_EVENT_LISTENER(select); - DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); - DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel); - - // These four attribute event handler attributes are overridden by HTMLBodyElement - // and HTMLFrameSetElement to forward to the DOMWindow. - DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(blur); - DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(error); - DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(focus); - DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(load); - - // WebKit extensions - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); - DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); - DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); - DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); - DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); - DEFINE_ATTRIBUTE_EVENT_LISTENER(search); - DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart); -#if ENABLE(TOUCH_EVENTS) - DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart); - DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove); - DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend); - DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel); -#endif -#if ENABLE(IOS_GESTURE_EVENTS) - DEFINE_ATTRIBUTE_EVENT_LISTENER(gesturestart); - DEFINE_ATTRIBUTE_EVENT_LISTENER(gesturechange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(gestureend); -#endif -#if ENABLE(FULLSCREEN_API) - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror); -#endif - - bool hasAttribute(const QualifiedName&) const; - const AtomicString& getAttribute(const QualifiedName&) const; - void setAttribute(const QualifiedName&, const AtomicString& value); + WEBCORE_EXPORT bool hasAttribute(const QualifiedName&) const; + WEBCORE_EXPORT const AtomicString& getAttribute(const QualifiedName&) const; + WEBCORE_EXPORT void setAttribute(const QualifiedName&, const AtomicString& value); + WEBCORE_EXPORT void setAttributeWithoutSynchronization(const QualifiedName&, const AtomicString& value); void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value); - void removeAttribute(const QualifiedName&); + bool removeAttribute(const QualifiedName&); + Vector<String> getAttributeNames() const; // Typed getters and setters for language bindings. - int getIntegralAttribute(const QualifiedName& attributeName) const; - void setIntegralAttribute(const QualifiedName& attributeName, int value); - unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const; - void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value); + WEBCORE_EXPORT int getIntegralAttribute(const QualifiedName& attributeName) const; + WEBCORE_EXPORT void setIntegralAttribute(const QualifiedName& attributeName, int value); + WEBCORE_EXPORT unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const; + WEBCORE_EXPORT void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value); // Call this to get the value of an attribute that is known not to be the style // attribute or one of the SVG animatable attributes. - bool fastHasAttribute(const QualifiedName&) const; - const AtomicString& fastGetAttribute(const QualifiedName&) const; + bool hasAttributeWithoutSynchronization(const QualifiedName&) const; + const AtomicString& attributeWithoutSynchronization(const QualifiedName&) const; #ifndef NDEBUG - bool fastAttributeLookupAllowed(const QualifiedName&) const; + WEBCORE_EXPORT bool fastAttributeLookupAllowed(const QualifiedName&) const; #endif #ifdef DUMP_NODE_STATISTICS bool hasNamedNodeMap() const; #endif - bool hasAttributes() const; + WEBCORE_EXPORT bool hasAttributes() const; // This variant will not update the potentially invalid attributes. To be used when not interested // in style attribute or one of the SVG animation attributes. bool hasAttributesWithoutUpdate() const; - bool hasAttribute(const AtomicString& name) const; - bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const; + WEBCORE_EXPORT bool hasAttribute(const AtomicString& name) const; + WEBCORE_EXPORT bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const; - const AtomicString& getAttribute(const AtomicString& name) const; - const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const; + WEBCORE_EXPORT const AtomicString& getAttribute(const AtomicString& name) const; + WEBCORE_EXPORT const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const; - void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&); - static bool parseAttributeName(QualifiedName&, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode&); - void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&); + WEBCORE_EXPORT ExceptionOr<void> setAttribute(const AtomicString& name, const AtomicString& value); + static ExceptionOr<QualifiedName> parseAttributeName(const AtomicString& namespaceURI, const AtomicString& qualifiedName); + WEBCORE_EXPORT ExceptionOr<void> setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value); - bool isIdAttributeName(const QualifiedName&) const; const AtomicString& getIdAttribute() const; void setIdAttribute(const AtomicString&); @@ -193,26 +133,37 @@ public: unsigned findAttributeIndexByName(const QualifiedName& name) const { return elementData()->findAttributeIndexByName(name); } unsigned findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->findAttributeIndexByName(name, shouldIgnoreAttributeCase); } - void scrollIntoView(bool alignToTop = true); - void scrollIntoViewIfNeeded(bool centerIfNeeded = true); + WEBCORE_EXPORT void scrollIntoView(bool alignToTop = true); + WEBCORE_EXPORT void scrollIntoViewIfNeeded(bool centerIfNeeded = true); + WEBCORE_EXPORT void scrollIntoViewIfNotVisible(bool centerIfNotVisible = true); - void scrollByLines(int lines); - void scrollByPages(int pages); + void scrollBy(const ScrollToOptions&); + void scrollBy(double x, double y); + virtual void scrollTo(const ScrollToOptions&); + void scrollTo(double x, double y); - int offsetLeft(); - int offsetTop(); - int offsetWidth(); - int offsetHeight(); + WEBCORE_EXPORT void scrollByLines(int lines); + WEBCORE_EXPORT void scrollByPages(int pages); + + WEBCORE_EXPORT double offsetLeft(); + WEBCORE_EXPORT double offsetTop(); + WEBCORE_EXPORT double offsetWidth(); + WEBCORE_EXPORT double offsetHeight(); + + bool mayCauseRepaintInsideViewport(const IntRect* visibleRect = nullptr) const; // FIXME: Replace uses of offsetParent in the platform with calls // to the render layer and merge bindingsOffsetParent and offsetParent. - Element* bindingsOffsetParent(); + WEBCORE_EXPORT Element* bindingsOffsetParent(); + + const Element* rootElement() const; Element* offsetParent(); - int clientLeft(); - int clientTop(); - int clientWidth(); - int clientHeight(); + WEBCORE_EXPORT double clientLeft(); + WEBCORE_EXPORT double clientTop(); + WEBCORE_EXPORT double clientWidth(); + WEBCORE_EXPORT double clientHeight(); + virtual int scrollLeft(); virtual int scrollTop(); virtual void setScrollLeft(int); @@ -220,63 +171,66 @@ public: virtual int scrollWidth(); virtual int scrollHeight(); - IntRect boundsInRootViewSpace(); + WEBCORE_EXPORT IntRect boundsInRootViewSpace(); + + Ref<ClientRectList> getClientRects(); + Ref<ClientRect> getBoundingClientRect(); - PassRefPtr<ClientRectList> getClientRects(); - PassRefPtr<ClientRect> getBoundingClientRect(); - // Returns the absolute bounding box translated into client coordinates. - IntRect clientRect() const; + WEBCORE_EXPORT IntRect clientRect() const; // Returns the absolute bounding box translated into screen coordinates. - IntRect screenRect() const; + WEBCORE_EXPORT IntRect screenRect() const; - void removeAttribute(const AtomicString& name); - void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName); + WEBCORE_EXPORT bool removeAttribute(const AtomicString& name); + WEBCORE_EXPORT bool removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName); - PassRefPtr<Attr> detachAttribute(unsigned index); + Ref<Attr> detachAttribute(unsigned index); - PassRefPtr<Attr> getAttributeNode(const AtomicString& name); - PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName); - PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&); - PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&); - PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&); + WEBCORE_EXPORT RefPtr<Attr> getAttributeNode(const AtomicString& name); + WEBCORE_EXPORT RefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName); + WEBCORE_EXPORT ExceptionOr<RefPtr<Attr>> setAttributeNode(Attr&); + WEBCORE_EXPORT ExceptionOr<RefPtr<Attr>> setAttributeNodeNS(Attr&); + WEBCORE_EXPORT ExceptionOr<Ref<Attr>> removeAttributeNode(Attr&); - PassRefPtr<Attr> attrIfExists(const QualifiedName&); - PassRefPtr<Attr> ensureAttr(const QualifiedName&); + RefPtr<Attr> attrIfExists(const QualifiedName&); + RefPtr<Attr> attrIfExists(const AtomicString& localName, bool shouldIgnoreAttributeCase); + Ref<Attr> ensureAttr(const QualifiedName&); const Vector<RefPtr<Attr>>& attrNodeList(); - virtual CSSStyleDeclaration* style(); + virtual CSSStyleDeclaration* cssomStyle(); const QualifiedName& tagQName() const { return m_tagName; } -#if ENABLE(CSS_SELECTOR_JIT) +#if ENABLE(JIT) static ptrdiff_t tagQNameMemoryOffset() { return OBJECT_OFFSETOF(Element, m_tagName); } -#endif // ENABLE(CSS_SELECTOR_JIT) +#endif // ENABLE(JIT) String tagName() const { return nodeName(); } bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); } - + bool hasTagName(const HTMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); } + bool hasTagName(const MathMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); } + bool hasTagName(const SVGQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); } + // A fast function for checking the local name against another atomic string. bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; } - bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); } - virtual const AtomicString& localName() const override final { return m_tagName.localName(); } - virtual const AtomicString& prefix() const override final { return m_tagName.prefix(); } - virtual const AtomicString& namespaceURI() const override final { return m_tagName.namespaceURI(); } + const AtomicString& localName() const final { return m_tagName.localName(); } + const AtomicString& prefix() const final { return m_tagName.prefix(); } + const AtomicString& namespaceURI() const final { return m_tagName.namespaceURI(); } - virtual URL baseURI() const override final; + ExceptionOr<void> setPrefix(const AtomicString&) final; - virtual String nodeName() const override; + String nodeName() const override; - PassRefPtr<Element> cloneElementWithChildren(); - PassRefPtr<Element> cloneElementWithoutChildren(); + Ref<Element> cloneElementWithChildren(Document&); + Ref<Element> cloneElementWithoutChildren(Document&); void normalizeAttributes(); String nodeNamePreservingCase() const; - void setBooleanAttribute(const QualifiedName& name, bool); + WEBCORE_EXPORT void setBooleanAttribute(const QualifiedName& name, bool); // For exposing to DOM only. - NamedNodeMap* attributes() const; + WEBCORE_EXPORT NamedNodeMap& attributes() const; enum AttributeModificationReason { ModifiedDirectly, @@ -309,78 +263,88 @@ public: virtual void copyNonAttributePropertiesFromElement(const Element&) { } - void lazyReattach(); - - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>); + virtual RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&); virtual bool rendererIsNeeded(const RenderStyle&); - void didAffectSelector(AffectedSelectorMask); - ShadowRoot* shadowRoot() const; - PassRefPtr<ShadowRoot> createShadowRoot(ExceptionCode&); - ShadowRoot* authorShadowRoot() const; + WEBCORE_EXPORT ShadowRoot* shadowRoot() const; + ShadowRoot* shadowRootForBindings(JSC::ExecState&) const; - bool hasAuthorShadowRoot() const { return authorShadowRoot(); } + struct ShadowRootInit { + ShadowRootMode mode; + }; + ExceptionOr<ShadowRoot&> attachShadow(const ShadowRootInit&); ShadowRoot* userAgentShadowRoot() const; - ShadowRoot& ensureUserAgentShadowRoot(); + WEBCORE_EXPORT ShadowRoot& ensureUserAgentShadowRoot(); + + void setIsDefinedCustomElement(JSCustomElementInterface&); + void setIsFailedCustomElement(JSCustomElementInterface&); + void setIsCustomElementUpgradeCandidate(); + void enqueueToUpgrade(JSCustomElementInterface&); + CustomElementReactionQueue* reactionQueue() const; + // FIXME: this should not be virtual, do not override this. virtual const AtomicString& shadowPseudoId() const; bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); } bool active() const { return isUserActionElement() && isUserActionElementActive(); } bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); } bool focused() const { return isUserActionElement() && isUserActionElementFocused(); } + bool hasFocusWithin() const { return getFlag(HasFocusWithin); }; virtual void setActive(bool flag = true, bool pause = false); virtual void setHovered(bool flag = true); virtual void setFocus(bool flag); + void setHasFocusWithin(bool flag); + bool tabIndexSetExplicitly() const; virtual bool supportsFocus() const; virtual bool isFocusable() const; - virtual bool isKeyboardFocusable(KeyboardEvent*) const; + virtual bool isKeyboardFocusable(KeyboardEvent&) const; virtual bool isMouseFocusable() const; virtual bool shouldUseInputMethod(); - virtual short tabIndex() const; + virtual int tabIndex() const; + WEBCORE_EXPORT void setTabIndex(int); virtual Element* focusDelegate(); - virtual RenderStyle* computedStyle(PseudoId = NOPSEUDO) override; + WEBCORE_EXPORT ExceptionOr<Element*> insertAdjacentElement(const String& where, Element& newChild); + WEBCORE_EXPORT ExceptionOr<void> insertAdjacentHTML(const String& where, const String& html); + WEBCORE_EXPORT ExceptionOr<void> insertAdjacentText(const String& where, const String& text); + + const RenderStyle* computedStyle(PseudoId = NOPSEUDO) override; + + bool needsStyleInvalidation() const; // Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.) + bool styleAffectedByActive() const { return hasRareData() && rareDataStyleAffectedByActive(); } bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); } + bool styleAffectedByFocusWithin() const { return hasRareData() && rareDataStyleAffectedByFocusWithin(); } bool childrenAffectedByHover() const { return getFlag(ChildrenAffectedByHoverRulesFlag); } - bool childrenAffectedByActive() const { return hasRareData() && rareDataChildrenAffectedByActive(); } bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); } - bool childrenAffectedByPositionalRules() const { return hasRareData() && (rareDataChildrenAffectedByForwardPositionalRules() || rareDataChildrenAffectedByBackwardPositionalRules()); } bool childrenAffectedByFirstChildRules() const { return getFlag(ChildrenAffectedByFirstChildRulesFlag); } bool childrenAffectedByLastChildRules() const { return getFlag(ChildrenAffectedByLastChildRulesFlag); } - bool childrenAffectedByDirectAdjacentRules() const { return getFlag(ChildrenAffectedByDirectAdjacentRulesFlag); } - bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); } bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); } + bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules(); } + bool affectsNextSiblingElementStyle() const { return getFlag(AffectsNextSiblingElementStyle); } unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; } bool hasFlagsSetDuringStylingOfChildren() const; void setStyleAffectedByEmpty(); + void setStyleAffectedByFocusWithin(); void setChildrenAffectedByHover() { setFlag(ChildrenAffectedByHoverRulesFlag); } - void setChildrenAffectedByActive(); + void setStyleAffectedByActive(); void setChildrenAffectedByDrag(); void setChildrenAffectedByFirstChildRules() { setFlag(ChildrenAffectedByFirstChildRulesFlag); } void setChildrenAffectedByLastChildRules() { setFlag(ChildrenAffectedByLastChildRulesFlag); } - static void setChildrenAffectedByDirectAdjacentRules(Element*); - void setChildrenAffectedByDirectAdjacentRules() { setFlag(ChildrenAffectedByDirectAdjacentRulesFlag); } - static void setChildrenAffectedByForwardPositionalRules(Element*); - void setChildrenAffectedByForwardPositionalRules() { setChildrenAffectedByForwardPositionalRules(this); } void setChildrenAffectedByBackwardPositionalRules(); + void setChildrenAffectedByPropertyBasedBackwardPositionalRules(); + void setAffectsNextSiblingElementStyle() { setFlag(AffectsNextSiblingElementStyle); } + void setStyleIsAffectedByPreviousSibling() { setFlag(StyleIsAffectedByPreviousSibling); } void setChildIndex(unsigned); - void setIsInCanvasSubtree(bool); - bool isInCanvasSubtree() const; - - void setIsInsideRegion(bool); - bool isInsideRegion() const; - void setRegionOversetState(RegionOversetState); RegionOversetState regionOversetState() const; @@ -390,33 +354,40 @@ public: virtual void accessKeyAction(bool /*sendToAnyEvent*/) { } virtual bool isURLAttribute(const Attribute&) const { return false; } + virtual bool attributeContainsURL(const Attribute& attribute) const { return isURLAttribute(attribute); } + virtual String completeURLsInAttributeValue(const URL& base, const Attribute&) const; virtual bool isHTMLContentAttribute(const Attribute&) const { return false; } - URL getURLAttribute(const QualifiedName&) const; + WEBCORE_EXPORT URL getURLAttribute(const QualifiedName&) const; URL getNonEmptyURLAttribute(const QualifiedName&) const; virtual const AtomicString& imageSourceURL() const; virtual String target() const { return String(); } + static AXTextStateChangeIntent defaultFocusTextStateChangeIntent() { return AXTextStateChangeIntent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, true }); } void updateFocusAppearanceAfterAttachIfNeeded(); virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone); - virtual void updateFocusAppearance(bool restorePreviousSelection); + virtual void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode = SelectionRevealMode::Reveal); virtual void blur(); - String innerText(); - String outerText(); + WEBCORE_EXPORT String innerHTML() const; + WEBCORE_EXPORT String outerHTML() const; + WEBCORE_EXPORT ExceptionOr<void> setInnerHTML(const String&); + WEBCORE_EXPORT ExceptionOr<void> setOuterHTML(const String&); + WEBCORE_EXPORT String innerText(); + WEBCORE_EXPORT String outerText(); virtual String title() const; const AtomicString& pseudo() const; - void setPseudo(const AtomicString&); + WEBCORE_EXPORT void setPseudo(const AtomicString&); LayoutSize minimumSizeForResizing() const; void setMinimumSizeForResizing(const LayoutSize&); // Use Document::registerForDocumentActivationCallbacks() to subscribe to these - virtual void documentWillSuspendForPageCache() { } - virtual void documentDidResumeFromPageCache() { } + virtual void prepareForDocumentSuspension() { } + virtual void resumeFromDocumentSuspension() { } // Use Document::registerForMediaVolumeCallbacks() to subscribe to this virtual void mediaVolumeDidChange() { } @@ -424,113 +395,87 @@ public: // Use Document::registerForPrivateBrowsingStateChangedCallbacks() to subscribe to this. virtual void privateBrowsingStateDidChange() { } + virtual void willBecomeFullscreenElement(); + virtual void ancestorWillEnterFullscreen() { } virtual void didBecomeFullscreenElement() { } virtual void willStopBeingFullscreenElement() { } -#if ENABLE(PAGE_VISIBILITY_API) // Use Document::registerForVisibilityStateChangedCallbacks() to subscribe to this. virtual void visibilityStateChanged() { } -#endif #if ENABLE(VIDEO_TRACK) virtual void captionPreferencesChanged() { } #endif bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); } - virtual void finishParsingChildren() override; - virtual void beginParsingChildren() override final; + void finishParsingChildren() override; + void beginParsingChildren() final; - PseudoElement* beforePseudoElement() const; - PseudoElement* afterPseudoElement() const; + WEBCORE_EXPORT PseudoElement* beforePseudoElement() const; + WEBCORE_EXPORT PseudoElement* afterPseudoElement() const; bool childNeedsShadowWalker() const; void didShadowTreeAwareChildrenChange(); - // ElementTraversal API - Element* firstElementChild() const; - Element* lastElementChild() const; - Element* previousElementSibling() const; - Element* nextElementSibling() const; - unsigned childElementCount() const; - - virtual bool matchesReadOnlyPseudoClass() const; + virtual bool matchesValidPseudoClass() const; + virtual bool matchesInvalidPseudoClass() const; virtual bool matchesReadWritePseudoClass() const; - bool webkitMatchesSelector(const String& selectors, ExceptionCode&); + virtual bool matchesIndeterminatePseudoClass() const; + virtual bool matchesDefaultPseudoClass() const; + WEBCORE_EXPORT ExceptionOr<bool> matches(const String& selectors); + WEBCORE_EXPORT ExceptionOr<Element*> closest(const String& selectors); virtual bool shouldAppearIndeterminate() const; - DOMTokenList* classList(); + WEBCORE_EXPORT DOMTokenList& classList(); - DatasetDOMStringMap* dataset(); + DatasetDOMStringMap& dataset(); #if ENABLE(VIDEO) virtual bool isMediaElement() const { return false; } #endif -#if ENABLE(INPUT_SPEECH) - virtual bool isInputFieldSpeechButtonElement() const { return false; } -#endif - virtual bool isFormControlElement() const { return false; } virtual bool isSpinButtonElement() const { return false; } virtual bool isTextFormControl() const { return false; } virtual bool isOptionalFormControl() const { return false; } virtual bool isRequiredFormControl() const { return false; } - virtual bool isDefaultButtonForForm() const { return false; } - virtual bool willValidate() const { return false; } - virtual bool isValidFormControlElement() { return false; } virtual bool isInRange() const { return false; } virtual bool isOutOfRange() const { return false; } virtual bool isFrameElementBase() const { return false; } - virtual bool isSearchFieldCancelButtonElement() const { return false; } + virtual bool isUploadButton() const { return false; } + virtual bool isSliderContainerElement() const { return false; } - virtual bool canContainRangeEndPoint() const override { return true; } + bool canContainRangeEndPoint() const override; // Used for disabled form elements; if true, prevents mouse events from being dispatched // to event listeners, and prevents DOMActivate events from being sent at all. virtual bool isDisabledFormControl() const { return false; } - virtual bool childShouldCreateRenderer(const Node&) const override; + virtual bool childShouldCreateRenderer(const Node&) const; -#if ENABLE(SVG) bool hasPendingResources() const; void setHasPendingResources(); void clearHasPendingResources(); virtual void buildPendingResource() { }; -#endif #if ENABLE(FULLSCREEN_API) - enum { - ALLOW_KEYBOARD_INPUT = 1 << 0, - LEGACY_MOZILLA_REQUEST = 1 << 1, - }; - - void webkitRequestFullScreen(unsigned short flags); - bool containsFullScreenElement() const; + WEBCORE_EXPORT bool containsFullScreenElement() const; void setContainsFullScreenElement(bool); void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool); - - // W3C API - void webkitRequestFullscreen(); + WEBCORE_EXPORT void webkitRequestFullscreen(); #endif #if ENABLE(POINTER_LOCK) - void webkitRequestPointerLock(); + WEBCORE_EXPORT void requestPointerLock(); #endif -#if ENABLE(INDIE_UI) - void setUIActions(const AtomicString&); - const AtomicString& UIActions() const; -#endif - - virtual bool isSpellCheckingEnabled() const; - - PassRef<RenderStyle> styleForRenderer(); + bool isSpellCheckingEnabled() const; - RenderRegion* renderRegion() const; + RenderNamedFlowFragment* renderNamedFlowFragment() const; #if ENABLE(CSS_REGIONS) virtual bool shouldMoveToFlowThread(const RenderStyle&) const; - const AtomicString& webkitRegionOverset() const; + WEBCORE_EXPORT const AtomicString& webkitRegionOverset() const; Vector<RefPtr<Range>> webkitGetRegionFlowRanges() const; #endif @@ -539,58 +484,109 @@ public: bool hasName() const; const SpaceSplitString& classNames() const; - IntSize savedLayerScrollOffset() const; - void setSavedLayerScrollOffset(const IntSize&); + IntPoint savedLayerScrollPosition() const; + void setSavedLayerScrollPosition(const IntPoint&); bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Element* relatedTarget = nullptr); bool dispatchWheelEvent(const PlatformWheelEvent&); bool dispatchKeyEvent(const PlatformKeyboardEvent&); void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook); - void dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement); - void dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement); - virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection); - virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement); + void dispatchFocusInEvent(const AtomicString& eventType, RefPtr<Element>&& oldFocusedElement); + void dispatchFocusOutEvent(const AtomicString& eventType, RefPtr<Element>&& newFocusedElement); + virtual void dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection); + virtual void dispatchBlurEvent(RefPtr<Element>&& newFocusedElement); - virtual bool willRecalcStyle(Style::Change); + WEBCORE_EXPORT bool dispatchMouseForceWillBegin(); + + virtual void willRecalcStyle(Style::Change); virtual void didRecalcStyle(Style::Change); + virtual void willResetComputedStyle(); virtual void willAttachRenderers(); virtual void didAttachRenderers(); virtual void willDetachRenderers(); virtual void didDetachRenderers(); + virtual std::optional<ElementStyle> resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle); + + LayoutRect absoluteEventHandlerBounds(bool& includesFixedPositionElements) override; - void setBeforePseudoElement(PassRefPtr<PseudoElement>); - void setAfterPseudoElement(PassRefPtr<PseudoElement>); + void setBeforePseudoElement(Ref<PseudoElement>&&); + void setAfterPseudoElement(Ref<PseudoElement>&&); void clearBeforePseudoElement(); void clearAfterPseudoElement(); void resetComputedStyle(); + void resetStyleRelations(); void clearStyleDerivedDataBeforeDetachingRenderer(); void clearHoverAndActiveStatusBeforeDetachingRenderer(); -protected: - Element(const QualifiedName& tagName, Document& document, ConstructionType type) - : ContainerNode(&document, type) - , m_tagName(tagName) - { - } + WEBCORE_EXPORT URL absoluteLinkURL() const; + +#if ENABLE(TOUCH_EVENTS) + bool allowsDoubleTapGesture() const override; +#endif + + StyleResolver& styleResolver(); + ElementStyle resolveStyle(const RenderStyle* parentStyle); + + // Invalidates the style of a single element. Style is resolved lazily. + // Descendant elements are resolved as needed, for example if an inherited property changes. + // This should be called whenever an element changes in a manner that can affect its style. + void invalidateStyle(); + + // As above but also call RenderElement::setStyle with StyleDifferenceRecompositeLayer flag for + // the element even when the style doesn't change. This is mostly needed by the animation code. + WEBCORE_EXPORT void invalidateStyleAndLayerComposition(); + + // Invalidate the element and all its descendants. This is used when there is some sort of change + // in the tree that may affect the style of any of the descendants and we don't know how to optimize + // the case to limit the scope. This is expensive and should be avoided. + void invalidateStyleForSubtree(); - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual void childrenChanged(const ChildChange&) override; - virtual void removeAllEventListeners() override final; + // Invalidates renderers for the element and all its descendants causing them to be torn down + // and rebuild during style resolution. Style is also recomputed. This is used in code dealing with + // custom (not style based) renderers. This is expensive and should be avoided. + // Elements newly added to the tree are also in this state. + void invalidateStyleAndRenderersForSubtree(); - virtual PassRefPtr<RenderStyle> customStyleForRenderer(); + bool hasDisplayContents() const; + void setHasDisplayContents(bool); - void clearTabIndexExplicitlyIfNeeded(); - void setTabIndexExplicitly(short); + virtual void isVisibleInViewportChanged() { } - PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType); - HTMLCollection* cachedHTMLCollection(CollectionType); + using ContainerNode::setAttributeEventListener; + void setAttributeEventListener(const AtomicString& eventType, const QualifiedName& attributeName, const AtomicString& value); + + bool isNamedFlowContentElement() const { return hasRareData() && rareDataIsNamedFlowContentElement(); } + void setIsNamedFlowContentElement(); + void clearIsNamedFlowContentElement(); + +#if ENABLE(WEB_ANIMATIONS) + Vector<WebAnimation*> getAnimations(); +#endif + + Element* findAnchorElementForLink(String& outAnchorName); + +protected: + Element(const QualifiedName&, Document&, ConstructionType); + + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; + void childrenChanged(const ChildChange&) override; + void removeAllEventListeners() final; + virtual void parserDidSetAttributes(); + void didMoveToNewDocument(Document&) override; + + void clearTabIndexExplicitlyIfNeeded(); + void setTabIndexExplicitly(int); // classAttributeChanged() exists to share code between // parseAttribute (called via setAttribute()) and // svgAttributeChanged (called when element.className.baseValue is set) void classAttributeChanged(const AtomicString& newClassString); + void addShadowRoot(Ref<ShadowRoot>&&); + + static ExceptionOr<void> mergeWithNextTextNode(Text&); + private: bool isTextNode() const; @@ -599,9 +595,6 @@ private: bool isUserActionElementFocused() const; bool isUserActionElementHovered() const; - void resetNeedsNodeRenderingTraversalSlowPath(); - - virtual bool areAuthorShadowsAllowed() const { return true; } virtual void didAddUserAgentShadowRoot(ShadowRoot*) { } virtual bool alwaysCreateUserAgentShadowRoot() const { return false; } @@ -630,37 +623,44 @@ private: void updateIdForDocument(HTMLDocument&, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition); void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue); + ExceptionOr<Node*> insertAdjacent(const String& where, Ref<Node>&& newChild); + void scrollByUnits(int units, ScrollGranularity); - virtual void setPrefix(const AtomicString&, ExceptionCode&) override final; - virtual NodeType nodeType() const override final; - virtual bool childTypeAllowed(NodeType) const override final; + NodeType nodeType() const final; + bool childTypeAllowed(NodeType) const final; void setAttributeInternal(unsigned index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute); void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute); void removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute); -#ifndef NDEBUG - virtual void formatForDebugger(char* buffer, unsigned length) const override; + LayoutRect absoluteEventBounds(bool& boundsIncludeAllDescendantElements, bool& includesFixedPositionElements); + LayoutRect absoluteEventBoundsOfElementAndDescendants(bool& includesFixedPositionElements); + +#if ENABLE(TREE_DEBUGGING) + void formatForDebugger(char* buffer, unsigned length) const override; #endif void cancelFocusAppearanceUpdate(); - // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren - // are used instead. - virtual PassRefPtr<Node> cloneNode(bool deep) override; - virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren(); + // The cloneNode function is private so that non-virtual cloneElementWith/WithoutChildren are used instead. + Ref<Node> cloneNodeInternal(Document&, CloningOperation) override; + virtual Ref<Element> cloneElementWithoutAttributesAndChildren(Document&); - void addShadowRoot(PassRefPtr<ShadowRoot>); void removeShadowRoot(); + const RenderStyle* existingComputedStyle(); + const RenderStyle& resolveComputedStyle(); + bool rareDataStyleAffectedByEmpty() const; + bool rareDataStyleAffectedByFocusWithin() const; + bool rareDataIsNamedFlowContentElement() const; bool rareDataChildrenAffectedByHover() const; - bool rareDataChildrenAffectedByActive() const; + bool rareDataStyleAffectedByActive() const; bool rareDataChildrenAffectedByDrag() const; bool rareDataChildrenAffectedByLastChildRules() const; - bool rareDataChildrenAffectedByForwardPositionalRules() const; bool rareDataChildrenAffectedByBackwardPositionalRules() const; + bool rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules() const; unsigned rareDataChildIndex() const; SpellcheckAttributeState spellcheckAttributeState() const; @@ -679,52 +679,47 @@ private: // Anyone thinking of using this should call document instead of ownerDocument. void ownerDocument() const = delete; + + void attachAttributeNodeIfNeeded(Attr&); QualifiedName m_tagName; RefPtr<ElementData> m_elementData; }; -inline bool isElement(const Node& node) { return node.isElementNode(); } - -NODE_TYPE_CASTS(Element) - -template <typename Type> bool isElementOfType(const Element&); -template <typename Type> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const Type>(toElement(node)); } -template <> inline bool isElementOfType<const Element>(const Element&) { return true; } - -inline bool Node::hasTagName(const QualifiedName& name) const -{ - return isElementNode() && toElement(this)->hasTagName(name); -} - -inline bool Node::hasLocalName(const AtomicString& name) const -{ - return isElementNode() && toElement(this)->hasLocalName(name); -} - inline bool Node::hasAttributes() const { - return isElementNode() && toElement(this)->hasAttributes(); + return is<Element>(*this) && downcast<Element>(*this).hasAttributes(); } inline NamedNodeMap* Node::attributes() const { - return isElementNode() ? toElement(this)->attributes() : nullptr; + return is<Element>(*this) ? &downcast<Element>(*this).attributes() : nullptr; } inline Element* Node::parentElement() const { ContainerNode* parent = parentNode(); - return parent && parent->isElementNode() ? toElement(parent) : nullptr; + return is<Element>(parent) ? downcast<Element>(parent) : nullptr; +} + +inline const Element* Element::rootElement() const +{ + if (isConnected()) + return document().documentElement(); + + const Element* highest = this; + while (highest->parentElement()) + highest = highest->parentElement(); + return highest; } -inline bool Element::fastHasAttribute(const QualifiedName& name) const +inline bool Element::hasAttributeWithoutSynchronization(const QualifiedName& name) const { ASSERT(fastAttributeLookupAllowed(name)); return elementData() && findAttributeByName(name); } -inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const +inline const AtomicString& Element::attributeWithoutSynchronization(const QualifiedName& name) const { ASSERT(fastAttributeLookupAllowed(name)); if (elementData()) { @@ -741,32 +736,26 @@ inline bool Element::hasAttributesWithoutUpdate() const inline const AtomicString& Element::idForStyleResolution() const { - ASSERT(hasID()); - return elementData()->idForStyleResolution(); -} - -inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const -{ - // FIXME: This check is probably not correct for the case where the document has an id attribute - // with a non-null namespace, because it will return false, a false negative, if the prefixes - // don't match but the local name and namespace both do. However, since this has been like this - // for a while and the code paths may be hot, we'll have to measure performance if we fix it. - return attributeName == document().idAttributeName(); + return hasID() ? elementData()->idForStyleResolution() : nullAtom; } inline const AtomicString& Element::getIdAttribute() const { - return hasID() ? fastGetAttribute(document().idAttributeName()) : nullAtom; + if (hasID()) + return elementData()->findAttributeByName(HTMLNames::idAttr)->value(); + return nullAtom; } inline const AtomicString& Element::getNameAttribute() const { - return hasName() ? fastGetAttribute(HTMLNames::nameAttr) : nullAtom; + if (hasName()) + return elementData()->findAttributeByName(HTMLNames::nameAttr)->value(); + return nullAtom; } inline void Element::setIdAttribute(const AtomicString& value) { - setAttribute(document().idAttributeName(), value); + setAttributeWithoutSynchronization(HTMLNames::idAttr, value); } inline const SpaceSplitString& Element::classNames() const @@ -816,23 +805,22 @@ inline UniqueElementData& Element::ensureUniqueElementData() return static_cast<UniqueElementData&>(*m_elementData); } -class PostAttachCallbackDisabler { -public: - explicit PostAttachCallbackDisabler(Document& document) - : m_document(document) - { - Element::suspendPostAttachCallbacks(m_document); - } - - ~PostAttachCallbackDisabler() - { - Element::resumePostAttachCallbacks(m_document); - } +inline bool shouldIgnoreAttributeCase(const Element& element) +{ + return element.isHTMLElement() && element.document().isHTMLDocument(); +} -private: - Document& m_document; -}; +inline void Element::setHasFocusWithin(bool flag) +{ + if (hasFocusWithin() == flag) + return; + setFlag(flag, HasFocusWithin); + if (styleAffectedByFocusWithin()) + invalidateStyleForSubtree(); +} } // namespace WebCore -#endif +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::Element) + static bool isType(const WebCore::Node& node) { return node.isElementNode(); } +SPECIALIZE_TYPE_TRAITS_END() |