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 37namespace WebCore { 38 39class ClientRect; 40class ClientRectList; 41class DatasetDOMStringMap; 42class DOMTokenList; 43class ElementRareData; 44class HTMLDocument; 45class IntSize; 46class Locale; 47class PlatformKeyboardEvent; 48class PlatformMouseEvent; 49class PlatformWheelEvent; 50class PseudoElement; 51class RenderNamedFlowFragment; 52class ShadowRoot; 53 54enum 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}; 63typedef int AffectedSelectorMask; 64 65enum SpellcheckAttributeState { 66 SpellcheckAttributeTrue, 67 SpellcheckAttributeFalse, 68 SpellcheckAttributeDefault 69}; 70 71class Element : public ContainerNode { 72public: 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 isHTMLContentAttribute(const Attribute&) const { return false; } 397 398 URL getURLAttribute(const QualifiedName&) const; 399 URL getNonEmptyURLAttribute(const QualifiedName&) const; 400 401 virtual const AtomicString& imageSourceURL() const; 402 virtual String target() const { return String(); } 403 404 void updateFocusAppearanceAfterAttachIfNeeded(); 405 virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone); 406 virtual void updateFocusAppearance(bool restorePreviousSelection); 407 virtual void blur(); 408 409 String innerText(); 410 String outerText(); 411 412 virtual String title() const; 413 414 const AtomicString& pseudo() const; 415 void setPseudo(const AtomicString&); 416 417 LayoutSize minimumSizeForResizing() const; 418 void setMinimumSizeForResizing(const LayoutSize&); 419 420 // Use Document::registerForDocumentActivationCallbacks() to subscribe to these 421 virtual void documentWillSuspendForPageCache() { } 422 virtual void documentDidResumeFromPageCache() { } 423 424 // Use Document::registerForMediaVolumeCallbacks() to subscribe to this 425 virtual void mediaVolumeDidChange() { } 426 427 // Use Document::registerForPrivateBrowsingStateChangedCallbacks() to subscribe to this. 428 virtual void privateBrowsingStateDidChange() { } 429 430 virtual void didBecomeFullscreenElement() { } 431 virtual void willStopBeingFullscreenElement() { } 432 433 // Use Document::registerForVisibilityStateChangedCallbacks() to subscribe to this. 434 virtual void visibilityStateChanged() { } 435 436#if ENABLE(VIDEO_TRACK) 437 virtual void captionPreferencesChanged() { } 438#endif 439 440 bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); } 441 virtual void finishParsingChildren() override; 442 virtual void beginParsingChildren() override final; 443 444 PseudoElement* beforePseudoElement() const; 445 PseudoElement* afterPseudoElement() const; 446 bool childNeedsShadowWalker() const; 447 void didShadowTreeAwareChildrenChange(); 448 449 // ElementTraversal API 450 Element* firstElementChild() const; 451 Element* lastElementChild() const; 452 Element* previousElementSibling() const; 453 Element* nextElementSibling() const; 454 unsigned childElementCount() const; 455 456 virtual bool matchesReadOnlyPseudoClass() const; 457 virtual bool matchesReadWritePseudoClass() const; 458 bool matches(const String& selectors, ExceptionCode&); 459 virtual bool shouldAppearIndeterminate() const; 460 461 DOMTokenList* classList(); 462 463 DatasetDOMStringMap* dataset(); 464 465#if ENABLE(VIDEO) 466 virtual bool isMediaElement() const { return false; } 467#endif 468 469#if ENABLE(INPUT_SPEECH) 470 virtual bool isInputFieldSpeechButtonElement() const { return false; } 471#endif 472 473 virtual bool isFormControlElement() const { return false; } 474 virtual bool isSpinButtonElement() const { return false; } 475 virtual bool isTextFormControl() const { return false; } 476 virtual bool isOptionalFormControl() const { return false; } 477 virtual bool isRequiredFormControl() const { return false; } 478 virtual bool isDefaultButtonForForm() const { return false; } 479 virtual bool willValidate() const { return false; } 480 virtual bool isValidFormControlElement() const { return false; } 481 virtual bool isInRange() const { return false; } 482 virtual bool isOutOfRange() const { return false; } 483 virtual bool isFrameElementBase() const { return false; } 484 virtual bool isSearchFieldCancelButtonElement() const { return false; } 485 486 virtual bool canContainRangeEndPoint() const override; 487 488 // Used for disabled form elements; if true, prevents mouse events from being dispatched 489 // to event listeners, and prevents DOMActivate events from being sent at all. 490 virtual bool isDisabledFormControl() const { return false; } 491 492 virtual bool childShouldCreateRenderer(const Node&) const override; 493 494 bool hasPendingResources() const; 495 void setHasPendingResources(); 496 void clearHasPendingResources(); 497 virtual void buildPendingResource() { }; 498 499#if ENABLE(FULLSCREEN_API) 500 enum { 501 ALLOW_KEYBOARD_INPUT = 1 << 0, 502 LEGACY_MOZILLA_REQUEST = 1 << 1, 503 }; 504 505 void webkitRequestFullScreen(unsigned short flags); 506 bool containsFullScreenElement() const; 507 void setContainsFullScreenElement(bool); 508 void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool); 509 510 // W3C API 511 void webkitRequestFullscreen(); 512#endif 513 514#if ENABLE(POINTER_LOCK) 515 void requestPointerLock(); 516#endif 517 518#if ENABLE(INDIE_UI) 519 void setUIActions(const AtomicString&); 520 const AtomicString& UIActions() const; 521#endif 522 523 virtual bool isSpellCheckingEnabled() const; 524 525 RenderNamedFlowFragment* renderNamedFlowFragment() const; 526 527#if ENABLE(CSS_REGIONS) 528 virtual bool shouldMoveToFlowThread(const RenderStyle&) const; 529 530 const AtomicString& webkitRegionOverset() const; 531 Vector<RefPtr<Range>> webkitGetRegionFlowRanges() const; 532#endif 533 534 bool hasID() const; 535 bool hasClass() const; 536 bool hasName() const; 537 const SpaceSplitString& classNames() const; 538 539 IntSize savedLayerScrollOffset() const; 540 void setSavedLayerScrollOffset(const IntSize&); 541 542 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Element* relatedTarget = nullptr); 543 bool dispatchWheelEvent(const PlatformWheelEvent&); 544 bool dispatchKeyEvent(const PlatformKeyboardEvent&); 545 void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents, SimulatedClickVisualOptions = ShowPressedLook); 546 void dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement); 547 void dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement); 548 virtual void dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection); 549 virtual void dispatchBlurEvent(PassRefPtr<Element> newFocusedElement); 550 551 virtual bool willRecalcStyle(Style::Change); 552 virtual void didRecalcStyle(Style::Change); 553 virtual void willAttachRenderers(); 554 virtual void didAttachRenderers(); 555 virtual void willDetachRenderers(); 556 virtual void didDetachRenderers(); 557 virtual PassRefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle); 558 559 void setBeforePseudoElement(PassRefPtr<PseudoElement>); 560 void setAfterPseudoElement(PassRefPtr<PseudoElement>); 561 void clearBeforePseudoElement(); 562 void clearAfterPseudoElement(); 563 void resetComputedStyle(); 564 void clearStyleDerivedDataBeforeDetachingRenderer(); 565 void clearHoverAndActiveStatusBeforeDetachingRenderer(); 566 567 URL absoluteLinkURL() const; 568 569protected: 570 Element(const QualifiedName& tagName, Document& document, ConstructionType type) 571 : ContainerNode(document, type) 572 , m_tagName(tagName) 573 { 574 } 575 576 virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; 577 virtual void removedFrom(ContainerNode&) override; 578 virtual void childrenChanged(const ChildChange&) override; 579 virtual void removeAllEventListeners() override final; 580 581 void clearTabIndexExplicitlyIfNeeded(); 582 void setTabIndexExplicitly(short); 583 584 PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType); 585 HTMLCollection* cachedHTMLCollection(CollectionType); 586 587 // classAttributeChanged() exists to share code between 588 // parseAttribute (called via setAttribute()) and 589 // svgAttributeChanged (called when element.className.baseValue is set) 590 void classAttributeChanged(const AtomicString& newClassString); 591 592private: 593 bool isTextNode() const; 594 595 bool isUserActionElementInActiveChain() const; 596 bool isUserActionElementActive() const; 597 bool isUserActionElementFocused() const; 598 bool isUserActionElementHovered() const; 599 600 void resetNeedsNodeRenderingTraversalSlowPath(); 601 602 virtual void didAddUserAgentShadowRoot(ShadowRoot*) { } 603 virtual bool alwaysCreateUserAgentShadowRoot() const { return false; } 604 605 // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute. 606 friend class Attr; 607 608 enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute = 0, InSynchronizationOfLazyAttribute }; 609 610 void didAddAttribute(const QualifiedName&, const AtomicString&); 611 void willModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue); 612 void didModifyAttribute(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue); 613 void didRemoveAttribute(const QualifiedName&, const AtomicString& oldValue); 614 615 void synchronizeAttribute(const QualifiedName&) const; 616 void synchronizeAttribute(const AtomicString& localName) const; 617 618 void updateName(const AtomicString& oldName, const AtomicString& newName); 619 void updateNameForTreeScope(TreeScope&, const AtomicString& oldName, const AtomicString& newName); 620 void updateNameForDocument(HTMLDocument&, const AtomicString& oldName, const AtomicString& newName); 621 void updateId(const AtomicString& oldId, const AtomicString& newId); 622 void updateIdForTreeScope(TreeScope&, const AtomicString& oldId, const AtomicString& newId); 623 enum HTMLDocumentNamedItemMapsUpdatingCondition { AlwaysUpdateHTMLDocumentNamedItemMaps, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute }; 624 void updateIdForDocument(HTMLDocument&, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition); 625 void updateLabel(TreeScope&, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue); 626 627 void scrollByUnits(int units, ScrollGranularity); 628 629 virtual void setPrefix(const AtomicString&, ExceptionCode&) override final; 630 virtual NodeType nodeType() const override final; 631 virtual bool childTypeAllowed(NodeType) const override final; 632 633 void setAttributeInternal(unsigned index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute); 634 void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute); 635 void removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute); 636 637#ifndef NDEBUG 638 virtual void formatForDebugger(char* buffer, unsigned length) const override; 639#endif 640 641 void cancelFocusAppearanceUpdate(); 642 643 // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren 644 // are used instead. 645 virtual PassRefPtr<Node> cloneNode(bool deep) override; 646 virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren(); 647 648 void addShadowRoot(PassRefPtr<ShadowRoot>); 649 void removeShadowRoot(); 650 651 bool rareDataStyleAffectedByEmpty() const; 652 bool rareDataChildrenAffectedByHover() const; 653 bool rareDataChildrenAffectedByActive() const; 654 bool rareDataChildrenAffectedByDrag() const; 655 bool rareDataChildrenAffectedByLastChildRules() const; 656 bool rareDataChildrenAffectedByForwardPositionalRules() const; 657 bool rareDataChildrenAffectedByBackwardPositionalRules() const; 658 unsigned rareDataChildIndex() const; 659 660 SpellcheckAttributeState spellcheckAttributeState() const; 661 662 void unregisterNamedFlowContentElement(); 663 664 void createUniqueElementData(); 665 666 ElementRareData* elementRareData() const; 667 ElementRareData& ensureElementRareData(); 668 669 void detachAllAttrNodesFromElement(); 670 void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value); 671 672 bool isJavaScriptURLAttribute(const Attribute&) const; 673 674 // Anyone thinking of using this should call document instead of ownerDocument. 675 void ownerDocument() const = delete; 676 677 QualifiedName m_tagName; 678 RefPtr<ElementData> m_elementData; 679}; 680 681inline bool isElement(const Node& node) { return node.isElementNode(); } 682 683NODE_TYPE_CASTS(Element) 684 685template <typename Type> bool isElementOfType(const Element&); 686template <typename Type> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const Type>(toElement(node)); } 687template <> inline bool isElementOfType<const Element>(const Element&) { return true; } 688 689inline bool Node::hasAttributes() const 690{ 691 return isElementNode() && toElement(this)->hasAttributes(); 692} 693 694inline NamedNodeMap* Node::attributes() const 695{ 696 return isElementNode() ? toElement(this)->attributes() : nullptr; 697} 698 699inline Element* Node::parentElement() const 700{ 701 ContainerNode* parent = parentNode(); 702 return parent && parent->isElementNode() ? toElement(parent) : nullptr; 703} 704 705inline bool Element::fastHasAttribute(const QualifiedName& name) const 706{ 707 ASSERT(fastAttributeLookupAllowed(name)); 708 return elementData() && findAttributeByName(name); 709} 710 711inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const 712{ 713 ASSERT(fastAttributeLookupAllowed(name)); 714 if (elementData()) { 715 if (const Attribute* attribute = findAttributeByName(name)) 716 return attribute->value(); 717 } 718 return nullAtom; 719} 720 721inline bool Element::hasAttributesWithoutUpdate() const 722{ 723 return elementData() && !elementData()->isEmpty(); 724} 725 726inline const AtomicString& Element::idForStyleResolution() const 727{ 728 ASSERT(hasID()); 729 return elementData()->idForStyleResolution(); 730} 731 732inline const AtomicString& Element::getIdAttribute() const 733{ 734 if (hasID()) 735 return elementData()->findAttributeByName(HTMLNames::idAttr)->value(); 736 return nullAtom; 737} 738 739inline const AtomicString& Element::getNameAttribute() const 740{ 741 if (hasName()) 742 return elementData()->findAttributeByName(HTMLNames::nameAttr)->value(); 743 return nullAtom; 744} 745 746inline void Element::setIdAttribute(const AtomicString& value) 747{ 748 setAttribute(HTMLNames::idAttr, value); 749} 750 751inline const SpaceSplitString& Element::classNames() const 752{ 753 ASSERT(hasClass()); 754 ASSERT(elementData()); 755 return elementData()->classNames(); 756} 757 758inline unsigned Element::attributeCount() const 759{ 760 ASSERT(elementData()); 761 return elementData()->length(); 762} 763 764inline const Attribute& Element::attributeAt(unsigned index) const 765{ 766 ASSERT(elementData()); 767 return elementData()->attributeAt(index); 768} 769 770inline const Attribute* Element::findAttributeByName(const QualifiedName& name) const 771{ 772 ASSERT(elementData()); 773 return elementData()->findAttributeByName(name); 774} 775 776inline bool Element::hasID() const 777{ 778 return elementData() && elementData()->hasID(); 779} 780 781inline bool Element::hasClass() const 782{ 783 return elementData() && elementData()->hasClass(); 784} 785 786inline bool Element::hasName() const 787{ 788 return elementData() && elementData()->hasName(); 789} 790 791inline UniqueElementData& Element::ensureUniqueElementData() 792{ 793 if (!elementData() || !elementData()->isUnique()) 794 createUniqueElementData(); 795 return static_cast<UniqueElementData&>(*m_elementData); 796} 797 798} // namespace WebCore 799 800#endif 801