1/* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 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 Node_h 26#define Node_h 27 28#include "EditingBoundary.h" 29#include "EventTarget.h" 30#include "KURLHash.h" 31#include "LayoutRect.h" 32#include "MutationObserver.h" 33#include "RenderStyleConstants.h" 34#include "ScriptWrappable.h" 35#include "SimulatedClickOptions.h" 36#include "TreeScope.h" 37#include "TreeShared.h" 38#include <wtf/Forward.h> 39#include <wtf/ListHashSet.h> 40#include <wtf/text/AtomicString.h> 41 42namespace JSC { 43 class VM; 44 class SlotVisitor; 45} 46 47// This needs to be here because Document.h also depends on it. 48#define DUMP_NODE_STATISTICS 0 49 50namespace WebCore { 51 52class Attribute; 53class ClassNodeList; 54class ContainerNode; 55class DOMSettableTokenList; 56class Document; 57class Element; 58class Event; 59class EventContext; 60class EventDispatchMediator; 61class EventListener; 62class FloatPoint; 63class Frame; 64class HTMLInputElement; 65class IntRect; 66class KeyboardEvent; 67class NSResolver; 68class NamedNodeMap; 69class NameNodeList; 70class NodeList; 71class NodeListsNodeData; 72class NodeRareData; 73class NodeRenderingContext; 74class PlatformKeyboardEvent; 75class PlatformMouseEvent; 76class PlatformWheelEvent; 77class QualifiedName; 78class RadioNodeList; 79class RegisteredEventListener; 80class RenderArena; 81class RenderBox; 82class RenderBoxModelObject; 83class RenderObject; 84class RenderStyle; 85class ShadowRoot; 86class TagNodeList; 87 88#if ENABLE(GESTURE_EVENTS) 89class PlatformGestureEvent; 90#endif 91 92#if ENABLE(TOUCH_EVENTS) 93class TouchEvent; 94#endif 95 96#if ENABLE(MICRODATA) 97class HTMLPropertiesCollection; 98class PropertyNodeList; 99#endif 100 101typedef int ExceptionCode; 102 103const int nodeStyleChangeShift = 15; 104 105// SyntheticStyleChange means that we need to go through the entire style change logic even though 106// no style property has actually changed. It is used to restructure the tree when, for instance, 107// RenderLayers are created or destroyed due to animation changes. 108enum StyleChangeType { 109 NoStyleChange = 0, 110 InlineStyleChange = 1 << nodeStyleChangeShift, 111 FullStyleChange = 2 << nodeStyleChangeShift, 112 SyntheticStyleChange = 3 << nodeStyleChangeShift 113}; 114 115class NodeRareDataBase { 116public: 117 RenderObject* renderer() const { return m_renderer; } 118 void setRenderer(RenderObject* renderer) { m_renderer = renderer; } 119 120protected: 121 NodeRareDataBase(RenderObject* renderer) 122 : m_renderer(renderer) 123 { } 124 125private: 126 RenderObject* m_renderer; 127}; 128 129enum AttachBehavior { 130 AttachNow, 131 AttachLazily, 132}; 133 134class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> { 135 friend class Document; 136 friend class TreeScope; 137 friend class TreeScopeAdopter; 138 139public: 140 enum NodeType { 141 ELEMENT_NODE = 1, 142 ATTRIBUTE_NODE = 2, 143 TEXT_NODE = 3, 144 CDATA_SECTION_NODE = 4, 145 ENTITY_REFERENCE_NODE = 5, 146 ENTITY_NODE = 6, 147 PROCESSING_INSTRUCTION_NODE = 7, 148 COMMENT_NODE = 8, 149 DOCUMENT_NODE = 9, 150 DOCUMENT_TYPE_NODE = 10, 151 DOCUMENT_FRAGMENT_NODE = 11, 152 NOTATION_NODE = 12, 153 XPATH_NAMESPACE_NODE = 13, 154 }; 155 enum DocumentPosition { 156 DOCUMENT_POSITION_EQUIVALENT = 0x00, 157 DOCUMENT_POSITION_DISCONNECTED = 0x01, 158 DOCUMENT_POSITION_PRECEDING = 0x02, 159 DOCUMENT_POSITION_FOLLOWING = 0x04, 160 DOCUMENT_POSITION_CONTAINS = 0x08, 161 DOCUMENT_POSITION_CONTAINED_BY = 0x10, 162 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20, 163 }; 164 165 static bool isSupported(const String& feature, const String& version); 166 167 static void startIgnoringLeaks(); 168 static void stopIgnoringLeaks(); 169 170 static void dumpStatistics(); 171 172 enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force }; 173 static StyleChange diff(const RenderStyle*, const RenderStyle*, Document*); 174 175 virtual ~Node(); 176 void willBeDeletedFrom(Document*); 177 178 // DOM methods & attributes for Node 179 180 bool hasTagName(const QualifiedName&) const; 181 bool hasLocalName(const AtomicString&) const; 182 virtual String nodeName() const = 0; 183 virtual String nodeValue() const; 184 virtual void setNodeValue(const String&, ExceptionCode&); 185 virtual NodeType nodeType() const = 0; 186 ContainerNode* parentNode() const; 187 Element* parentElement() const; 188 Node* previousSibling() const { return m_previous; } 189 Node* nextSibling() const { return m_next; } 190 PassRefPtr<NodeList> childNodes(); 191 Node* firstChild() const; 192 Node* lastChild() const; 193 bool hasAttributes() const; 194 NamedNodeMap* attributes() const; 195 Node* pseudoAwareNextSibling() const; 196 Node* pseudoAwarePreviousSibling() const; 197 Node* pseudoAwareFirstChild() const; 198 Node* pseudoAwareLastChild() const; 199 200 virtual KURL baseURI() const; 201 202 void getSubresourceURLs(ListHashSet<KURL>&) const; 203 204 // These should all actually return a node, but this is only important for language bindings, 205 // which will already know and hold a ref on the right node to return. Returning bool allows 206 // these methods to be more efficient since they don't need to return a ref 207 bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, AttachBehavior = AttachNow); 208 bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, AttachBehavior = AttachNow); 209 bool removeChild(Node* child, ExceptionCode&); 210 bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, AttachBehavior = AttachNow); 211 212 void remove(ExceptionCode&); 213 bool hasChildNodes() const { return firstChild(); } 214 virtual PassRefPtr<Node> cloneNode(bool deep) = 0; 215 virtual const AtomicString& localName() const; 216 virtual const AtomicString& namespaceURI() const; 217 virtual const AtomicString& prefix() const; 218 virtual void setPrefix(const AtomicString&, ExceptionCode&); 219 void normalize(); 220 221 bool isSameNode(Node* other) const { return this == other; } 222 bool isEqualNode(Node*) const; 223 bool isDefaultNamespace(const AtomicString& namespaceURI) const; 224 String lookupPrefix(const AtomicString& namespaceURI) const; 225 String lookupNamespaceURI(const String& prefix) const; 226 String lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const; 227 228 String textContent(bool convertBRsToNewlines = false) const; 229 void setTextContent(const String&, ExceptionCode&); 230 231 Node* lastDescendant() const; 232 Node* firstDescendant() const; 233 234 // Other methods (not part of DOM) 235 236 bool isElementNode() const { return getFlag(IsElementFlag); } 237 bool isContainerNode() const { return getFlag(IsContainerFlag); } 238 bool isTextNode() const { return getFlag(IsTextFlag); } 239 bool isHTMLElement() const { return getFlag(IsHTMLFlag); } 240 bool isSVGElement() const { return getFlag(IsSVGFlag); } 241 242 bool isPseudoElement() const { return pseudoId() != NOPSEUDO; } 243 bool isBeforePseudoElement() const { return pseudoId() == BEFORE; } 244 bool isAfterPseudoElement() const { return pseudoId() == AFTER; } 245 PseudoId pseudoId() const { return (isElementNode() && hasCustomStyleCallbacks()) ? customPseudoId() : NOPSEUDO; } 246 247 virtual bool isMediaControlElement() const { return false; } 248 virtual bool isMediaControls() const { return false; } 249#if ENABLE(VIDEO_TRACK) 250 virtual bool isWebVTTElement() const { return false; } 251#endif 252 bool isStyledElement() const { return getFlag(IsStyledElementFlag); } 253 virtual bool isAttributeNode() const { return false; } 254 virtual bool isCharacterDataNode() const { return false; } 255 virtual bool isFrameOwnerElement() const { return false; } 256 virtual bool isPluginElement() const { return false; } 257 virtual bool isInsertionPointNode() const { return false; } 258 259 bool isDocumentNode() const; 260 bool isTreeScope() const; 261 bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); } 262 bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); } 263 bool isInsertionPoint() const { return getFlag(NeedsShadowTreeWalkerFlag) && isInsertionPointNode(); } 264 // Returns Node rather than InsertionPoint. Should be used only for language bindings. 265 Node* insertionParentForBinding() const; 266 267 bool needsShadowTreeWalker() const; 268 bool needsShadowTreeWalkerSlow() const; 269 void setNeedsShadowTreeWalker() { setFlag(NeedsShadowTreeWalkerFlag); } 270 void resetNeedsShadowTreeWalker() { setFlag(needsShadowTreeWalkerSlow(), NeedsShadowTreeWalkerFlag); } 271 272 bool inNamedFlow() const { return getFlag(InNamedFlowFlag); } 273 bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); } 274 275 bool isRegisteredWithNamedFlow() const; 276 277 bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); } 278 void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); } 279 280 // If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0. 281 Element* shadowHost() const; 282 // If this node is in a shadow tree, returns its shadow host. Otherwise, returns this. 283 // Deprecated. Should use shadowHost() and check the return value. 284 Node* deprecatedShadowAncestorNode() const; 285 ShadowRoot* containingShadowRoot() const; 286 ShadowRoot* shadowRoot() const; 287 288 // Returns 0, a child of ShadowRoot, or a legacy shadow root. 289 Node* nonBoundaryShadowTreeRootNode(); 290 291 // Node's parent, shadow tree host. 292 ContainerNode* parentOrShadowHostNode() const; 293 Element* parentOrShadowHostElement() const; 294 void setParentOrShadowHostNode(ContainerNode*); 295 Node* highestAncestor() const; 296 297 // Use when it's guaranteed to that shadowHost is 0. 298 ContainerNode* parentNodeGuaranteedHostFree() const; 299 // Returns the parent node, but 0 if the parent node is a ShadowRoot. 300 ContainerNode* nonShadowBoundaryParentNode() const; 301 302 bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); } 303 void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); } 304 305 // Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation. 306 Node* enclosingLinkEventParentOrSelf(); 307 308 // These low-level calls give the caller responsibility for maintaining the integrity of the tree. 309 void setPreviousSibling(Node* previous) { m_previous = previous; } 310 void setNextSibling(Node* next) { m_next = next; } 311 312 virtual bool canContainRangeEndPoint() const { return false; } 313 314 bool isRootEditableElement() const; 315 Element* rootEditableElement() const; 316 Element* rootEditableElement(EditableType) const; 317 318 // Called by the parser when this element's close tag is reached, 319 // signaling that all child tags have been parsed and added. 320 // This is needed for <applet> and <object> elements, which can't lay themselves out 321 // until they know all of their nested <param>s. [Radar 3603191, 4040848]. 322 // Also used for script elements and some SVG elements for similar purposes, 323 // but making parsing a special case in this respect should be avoided if possible. 324 virtual void finishParsingChildren() { } 325 virtual void beginParsingChildren() { } 326 327 // For <link> and <style> elements. 328 virtual bool sheetLoaded() { return true; } 329 virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { } 330 virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); } 331 332 bool isUserActionElement() const { return getFlag(IsUserActionElement); } 333 void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElement); } 334 335 bool attached() const { return getFlag(IsAttachedFlag); } 336 void setAttached() { setFlag(IsAttachedFlag); } 337 bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; } 338 StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); } 339 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); } 340 bool isLink() const { return getFlag(IsLinkFlag); } 341 bool isEditingText() const { return getFlag(IsEditingTextFlag); } 342 343 void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); } 344 void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); } 345 346 void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange); 347 void clearNeedsStyleRecalc() { m_nodeFlags &= ~StyleChangeMask; } 348 virtual void scheduleSetNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange) { setNeedsStyleRecalc(changeType); } 349 350 void setIsLink(bool f) { setFlag(f, IsLinkFlag); } 351 void setIsLink() { setFlag(IsLinkFlag); } 352 void clearIsLink() { clearFlag(IsLinkFlag); } 353 354 void setInNamedFlow() { setFlag(InNamedFlowFlag); } 355 void clearInNamedFlow() { clearFlag(InNamedFlowFlag); } 356 357 bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); } 358 void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); } 359 360 bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); } 361 void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); } 362 363 enum ShouldSetAttached { 364 SetAttached, 365 DoNotSetAttached 366 }; 367 void lazyAttach(ShouldSetAttached = SetAttached); 368 void lazyReattach(ShouldSetAttached = SetAttached); 369 370 enum UserSelectAllTreatment { 371 UserSelectAllDoesNotAffectEditability, 372 UserSelectAllIsAlwaysNonEditable 373 }; 374 bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability); 375 bool isContentRichlyEditable(); 376 377 void inspect(); 378 379 bool rendererIsEditable(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const 380 { 381 switch (editableType) { 382 case ContentIsEditable: 383 return rendererIsEditable(Editable, treatment); 384 case HasEditableAXRole: 385 return isEditableToAccessibility(Editable); 386 } 387 ASSERT_NOT_REACHED(); 388 return false; 389 } 390 391 bool rendererIsRichlyEditable(EditableType editableType = ContentIsEditable) const 392 { 393 switch (editableType) { 394 case ContentIsEditable: 395 return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable); 396 case HasEditableAXRole: 397 return isEditableToAccessibility(RichlyEditable); 398 } 399 ASSERT_NOT_REACHED(); 400 return false; 401 } 402 403 virtual LayoutRect boundingBox() const; 404 IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); } 405 LayoutRect renderRect(bool* isReplaced); 406 IntRect pixelSnappedRenderRect(bool* isReplaced) { return pixelSnappedIntRect(renderRect(isReplaced)); } 407 408 unsigned nodeIndex() const; 409 410 // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case 411 // of (1) a Document node or (2) a DocumentType node that is not used with any Document yet. 412 Document* ownerDocument() const; 413 414 // Returns the document associated with this node. This method never returns NULL, except in the case 415 // of a DocumentType node that is not used with any Document yet. A Document node returns itself. 416 Document* document() const 417 { 418 ASSERT(this); 419 // FIXME: below ASSERT is useful, but prevents the use of document() in the constructor or destructor 420 // due to the virtual function call to nodeType(). 421 ASSERT(documentInternal() || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument())); 422 return documentInternal(); 423 } 424 425 TreeScope* treeScope() const { return m_treeScope; } 426 427 // Returns true if this node is associated with a document and is in its associated document's 428 // node tree, false otherwise. 429 bool inDocument() const 430 { 431 ASSERT(documentInternal() || !getFlag(InDocumentFlag)); 432 return getFlag(InDocumentFlag); 433 } 434 bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); } 435 bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); } 436 437 bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; } 438 bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; } 439 virtual bool childTypeAllowed(NodeType) const { return false; } 440 unsigned childNodeCount() const; 441 Node* childNode(unsigned index) const; 442 443 void checkSetPrefix(const AtomicString& prefix, ExceptionCode&); 444 bool isDescendantOf(const Node*) const; 445 bool contains(const Node*) const; 446 bool containsIncludingShadowDOM(const Node*) const; 447 bool containsIncludingHostElements(const Node*) const; 448 449 // Used to determine whether range offsets use characters or node indices. 450 virtual bool offsetInCharacters() const; 451 // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of 452 // css-transform:capitalize breaking up precomposed characters and ligatures. 453 virtual int maxCharacterOffset() const; 454 455 // Whether or not a selection can be started in this object 456 virtual bool canStartSelection() const; 457 458 // Getting points into and out of screen space 459 FloatPoint convertToPage(const FloatPoint&) const; 460 FloatPoint convertFromPage(const FloatPoint&) const; 461 462 // ----------------------------------------------------------------------------- 463 // Integration with rendering tree 464 465 // As renderer() includes a branch you should avoid calling it repeatedly in hot code paths. 466 RenderObject* renderer() const { return hasRareData() ? m_data.m_rareData->renderer() : m_data.m_renderer; }; 467 void setRenderer(RenderObject* renderer) 468 { 469 if (hasRareData()) 470 m_data.m_rareData->setRenderer(renderer); 471 else 472 m_data.m_renderer = renderer; 473 } 474 475 // Use these two methods with caution. 476 RenderBox* renderBox() const; 477 RenderBoxModelObject* renderBoxModelObject() const; 478 479 struct AttachContext { 480 RenderStyle* resolvedStyle; 481 bool performingReattach; 482 483 AttachContext() : resolvedStyle(0), performingReattach(false) { } 484 }; 485 486 // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an 487 // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This 488 // makes the node visible in the FrameView. 489 virtual void attach(const AttachContext& = AttachContext()); 490 491 // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove 492 // the node's rendering object from the rendering tree and delete it. 493 virtual void detach(const AttachContext& = AttachContext()); 494 495#ifndef NDEBUG 496 bool inDetach() const; 497#endif 498 499 void reattach(const AttachContext& = AttachContext()); 500 void reattachIfAttached(const AttachContext& = AttachContext()); 501 ContainerNode* parentNodeForRenderingAndStyle(); 502 503 // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement). 504 RenderStyle* renderStyle() const; 505 506 RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); } 507 508 // ----------------------------------------------------------------------------- 509 // Notification of document structure changes (see ContainerNode.h for more notification methods) 510 // 511 // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also 512 // when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). The call happens _after_ the node has been added to the tree. 513 // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event 514 // dispatching. 515 // 516 // WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree. 517 // Implementation can determine the type of subtree by seeing insertionPoint->inDocument(). 518 // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document. 519 // 520 // There are another callback named didNotifyDescendantInsertions(), which is called after all the descendant is notified. 521 // Only a few subclasses actually need this. To utilize this, the node should return InsertionShouldCallDidNotifyDescendantInsertions 522 // from insrtedInto(). 523 // 524 enum InsertionNotificationRequest { 525 InsertionDone, 526 InsertionShouldCallDidNotifySubtreeInsertions 527 }; 528 529 virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint); 530 virtual void didNotifySubtreeInsertions(ContainerNode*) { } 531 532 // Notifies the node that it is no longer part of the tree. 533 // 534 // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event 535 // dispatching, and is called _after_ the node is removed from the tree. 536 // 537 virtual void removedFrom(ContainerNode* insertionPoint); 538 539#ifndef NDEBUG 540 virtual void formatForDebugger(char* buffer, unsigned length) const; 541 542 void showNode(const char* prefix = "") const; 543 void showTreeForThis() const; 544 void showNodePathForThis() const; 545 void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const; 546 void showTreeForThisAcrossFrame() const; 547#endif 548 549 void invalidateNodeListCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0); 550 NodeListsNodeData* nodeLists(); 551 void clearNodeLists(); 552 553 PassRefPtr<NodeList> getElementsByTagName(const AtomicString&); 554 PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName); 555 PassRefPtr<NodeList> getElementsByName(const String& elementName); 556 PassRefPtr<NodeList> getElementsByClassName(const String& classNames); 557 PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&); 558 559 virtual bool willRespondToMouseMoveEvents(); 560 virtual bool willRespondToMouseClickEvents(); 561 virtual bool willRespondToTouchEvents(); 562 563 PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionCode&); 564 PassRefPtr<NodeList> querySelectorAll(const AtomicString& selectors, ExceptionCode&); 565 566 unsigned short compareDocumentPosition(Node*); 567 568 virtual Node* toNode(); 569 virtual HTMLInputElement* toInputElement(); 570 571 virtual const AtomicString& interfaceName() const; 572 virtual ScriptExecutionContext* scriptExecutionContext() const; 573 574 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 575 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 576 577 // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event 578 // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. 579 virtual void* preDispatchEventHandler(Event*) { return 0; } 580 virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } 581 582 using EventTarget::dispatchEvent; 583 virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE; 584 585 void dispatchScopedEvent(PassRefPtr<Event>); 586 void dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator>); 587 588 virtual void handleLocalEvents(Event*); 589 590 void dispatchSubtreeModifiedEvent(); 591 bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent); 592 593 bool dispatchKeyEvent(const PlatformKeyboardEvent&); 594 bool dispatchWheelEvent(const PlatformWheelEvent&); 595 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0); 596#if ENABLE(GESTURE_EVENTS) 597 bool dispatchGestureEvent(const PlatformGestureEvent&); 598#endif 599#if ENABLE(TOUCH_EVENTS) 600 bool dispatchTouchEvent(PassRefPtr<TouchEvent>); 601#endif 602 603 bool dispatchBeforeLoadEvent(const String& sourceURL); 604 605 virtual void dispatchInputEvent(); 606 607 // Perform the default action for an event. 608 virtual void defaultEventHandler(Event*); 609 610 using TreeShared<Node>::ref; 611 using TreeShared<Node>::deref; 612 613 virtual EventTargetData* eventTargetData(); 614 virtual EventTargetData* ensureEventTargetData(); 615 616#if ENABLE(MICRODATA) 617 DOMSettableTokenList* itemProp(); 618 DOMSettableTokenList* itemRef(); 619 DOMSettableTokenList* itemType(); 620 PassRefPtr<PropertyNodeList> propertyNodeList(const String&); 621#endif 622 623 void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName); 624 void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter); 625 void unregisterMutationObserver(MutationObserverRegistration*); 626 void registerTransientMutationObserver(MutationObserverRegistration*); 627 void unregisterTransientMutationObserver(MutationObserverRegistration*); 628 void notifyMutationObserversNodeWillDetach(); 629 630 virtual void registerScopedHTMLStyleChild(); 631 virtual void unregisterScopedHTMLStyleChild(); 632 size_t numberOfScopedHTMLStyleChildren() const; 633 634 void textRects(Vector<IntRect>&) const; 635 636 unsigned connectedSubframeCount() const; 637 void incrementConnectedSubframeCount(unsigned amount = 1); 638 void decrementConnectedSubframeCount(unsigned amount = 1); 639 void updateAncestorConnectedSubframeCountForRemoval() const; 640 void updateAncestorConnectedSubframeCountForInsertion() const; 641 642private: 643 enum NodeFlags { 644 IsTextFlag = 1, 645 IsContainerFlag = 1 << 1, 646 IsElementFlag = 1 << 2, 647 IsStyledElementFlag = 1 << 3, 648 IsHTMLFlag = 1 << 4, 649 IsSVGFlag = 1 << 5, 650 IsAttachedFlag = 1 << 6, 651 ChildNeedsStyleRecalcFlag = 1 << 7, 652 InDocumentFlag = 1 << 8, 653 IsLinkFlag = 1 << 9, 654 IsUserActionElement = 1 << 10, 655 HasRareDataFlag = 1 << 11, 656 IsDocumentFragmentFlag = 1 << 12, 657 658 // These bits are used by derived classes, pulled up here so they can 659 // be stored in the same memory word as the Node bits above. 660 IsParsingChildrenFinishedFlag = 1 << 13, // Element 661#if ENABLE(SVG) 662 HasSVGRareDataFlag = 1 << 14, // SVGElement 663#endif 664 665 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1), 666 667 SelfOrAncestorHasDirAutoFlag = 1 << 17, 668 669 IsEditingTextFlag = 1 << 18, 670 671 InNamedFlowFlag = 1 << 19, 672 HasSyntheticAttrChildNodesFlag = 1 << 20, 673 HasCustomStyleCallbacksFlag = 1 << 21, 674 HasScopedHTMLStyleChildFlag = 1 << 22, 675 HasEventTargetDataFlag = 1 << 23, 676 NeedsShadowTreeWalkerFlag = 1 << 25, 677 IsInShadowTreeFlag = 1 << 26, 678 679 DefaultNodeFlags = IsParsingChildrenFinishedFlag 680 }; 681 682 // 5 bits remaining 683 684 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } 685 void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } 686 void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; } 687 void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; } 688 689protected: 690 enum ConstructionType { 691 CreateOther = DefaultNodeFlags, 692 CreateText = DefaultNodeFlags | IsTextFlag, 693 CreateContainer = DefaultNodeFlags | IsContainerFlag, 694 CreateElement = CreateContainer | IsElementFlag, 695 CreatePseudoElement = CreateElement | InDocumentFlag | NeedsShadowTreeWalkerFlag, 696 CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | NeedsShadowTreeWalkerFlag | IsInShadowTreeFlag, 697 CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag, 698 CreateStyledElement = CreateElement | IsStyledElementFlag, 699 CreateHTMLElement = CreateStyledElement | IsHTMLFlag, 700 CreateSVGElement = CreateStyledElement | IsSVGFlag, 701 CreateDocument = CreateContainer | InDocumentFlag, 702 CreateInsertionPoint = CreateHTMLElement | NeedsShadowTreeWalkerFlag, 703 CreateEditingText = CreateText | IsEditingTextFlag, 704 }; 705 Node(Document*, ConstructionType); 706 707 virtual void didMoveToNewDocument(Document* oldDocument); 708 709 virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { } 710 711 bool hasRareData() const { return getFlag(HasRareDataFlag); } 712 713 NodeRareData* rareData() const; 714 NodeRareData* ensureRareData(); 715 void clearRareData(); 716 717 void clearEventTargetData(); 718 719 void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); } 720 721 Document* documentInternal() const { return treeScope()->documentScope(); } 722 void setTreeScope(TreeScope* scope) { m_treeScope = scope; } 723 724private: 725 friend class TreeShared<Node>; 726 727 virtual PseudoId customPseudoId() const 728 { 729 ASSERT(hasCustomStyleCallbacks()); 730 return NOPSEUDO; 731 } 732 733 void removedLastRef(); 734 bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); } 735 736 enum EditableLevel { Editable, RichlyEditable }; 737 bool rendererIsEditable(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const; 738 bool isEditableToAccessibility(EditableLevel) const; 739 740 void setStyleChange(StyleChangeType); 741 742 // Used to share code between lazyAttach and setNeedsStyleRecalc. 743 void markAncestorsWithChildNeedsStyleRecalc(); 744 745 virtual void refEventTarget(); 746 virtual void derefEventTarget(); 747 748 virtual RenderStyle* nonRendererStyle() const { return 0; } 749 virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO); 750 751 Element* ancestorElement() const; 752 753 void trackForDebugging(); 754 755 Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry(); 756 HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry(); 757 758 mutable uint32_t m_nodeFlags; 759 ContainerNode* m_parentOrShadowHostNode; 760 TreeScope* m_treeScope; 761 Node* m_previous; 762 Node* m_next; 763 // When a node has rare data we move the renderer into the rare data. 764 union DataUnion { 765 DataUnion() : m_renderer(0) { } 766 RenderObject* m_renderer; 767 NodeRareDataBase* m_rareData; 768 } m_data; 769 770protected: 771 bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); } 772 void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); } 773 void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); } 774 775#if ENABLE(SVG) 776 bool hasSVGRareData() const { return getFlag(HasSVGRareDataFlag); } 777 void setHasSVGRareData() { setFlag(HasSVGRareDataFlag); } 778 void clearHasSVGRareData() { clearFlag(HasSVGRareDataFlag); } 779#endif 780 781#if ENABLE(MICRODATA) 782 void setItemProp(const String&); 783 void setItemRef(const String&); 784 void setItemType(const String&); 785#endif 786}; 787 788// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs() 789inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url) 790{ 791 if (!url.isNull()) 792 urls.add(url); 793} 794 795inline void Node::setParentOrShadowHostNode(ContainerNode* parent) 796{ 797 ASSERT(isMainThread()); 798 m_parentOrShadowHostNode = parent; 799} 800 801inline ContainerNode* Node::parentOrShadowHostNode() const 802{ 803 ASSERT(isMainThreadOrGCThread()); 804 return m_parentOrShadowHostNode; 805} 806 807inline ContainerNode* Node::parentNode() const 808{ 809 return isShadowRoot() ? 0 : parentOrShadowHostNode(); 810} 811 812inline ContainerNode* Node::parentNodeGuaranteedHostFree() const 813{ 814 ASSERT(!isShadowRoot()); 815 return parentOrShadowHostNode(); 816} 817 818inline void Node::reattach(const AttachContext& context) 819{ 820 AttachContext reattachContext(context); 821 reattachContext.performingReattach = true; 822 823 if (attached()) 824 detach(reattachContext); 825 attach(reattachContext); 826} 827 828inline void Node::reattachIfAttached(const AttachContext& context) 829{ 830 if (attached()) 831 reattach(context); 832} 833 834inline void Node::lazyReattach(ShouldSetAttached shouldSetAttached) 835{ 836 if (attached()) 837 detach(); 838 lazyAttach(shouldSetAttached); 839} 840 841} //namespace 842 843#ifndef NDEBUG 844// Outside the WebCore namespace for ease of invocation from gdb. 845void showTree(const WebCore::Node*); 846void showNodePath(const WebCore::Node*); 847#endif 848 849#endif 850