1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2001 Dirk Mueller (mueller (at) 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 "EventTarget.h" 29 #include "KURLHash.h" 30 #include "RenderStyleConstants.h" 31 #include "ScriptWrappable.h" 32 #include "TreeShared.h" 33 #include <wtf/Forward.h> 34 #include <wtf/ListHashSet.h> 35 36 #if USE(JSC) 37 namespace JSC { 38 class JSGlobalData; 39 class MarkStack; 40 } 41 #endif 42 43 namespace WebCore { 44 45 class Attribute; 46 class ClassNodeList; 47 class ContainerNode; 48 class Document; 49 class DynamicNodeList; 50 class Element; 51 class Event; 52 class EventContext; 53 class EventListener; 54 class FloatPoint; 55 class Frame; 56 class InputElement; 57 class IntRect; 58 class KeyboardEvent; 59 class NSResolver; 60 class NamedNodeMap; 61 class NameNodeList; 62 class NodeList; 63 class NodeRareData; 64 class PlatformKeyboardEvent; 65 class PlatformMouseEvent; 66 class PlatformWheelEvent; 67 class QualifiedName; 68 class RegisteredEventListener; 69 class RenderArena; 70 class RenderBox; 71 class RenderBoxModelObject; 72 class RenderObject; 73 class RenderStyle; 74 #if ENABLE(SVG) 75 class SVGUseElement; 76 #endif 77 class TagNodeList; 78 class TreeScope; 79 80 typedef int ExceptionCode; 81 82 const int nodeStyleChangeShift = 25; 83 84 // SyntheticStyleChange means that we need to go through the entire style change logic even though 85 // no style property has actually changed. It is used to restructure the tree when, for instance, 86 // RenderLayers are created or destroyed due to animation changes. 87 enum StyleChangeType { 88 NoStyleChange = 0, 89 InlineStyleChange = 1 << nodeStyleChangeShift, 90 FullStyleChange = 2 << nodeStyleChangeShift, 91 SyntheticStyleChange = 3 << nodeStyleChangeShift 92 }; 93 94 class Node : public EventTarget, public TreeShared<ContainerNode>, public ScriptWrappable { 95 friend class Document; 96 friend class TreeScope; 97 98 public: 99 enum NodeType { 100 ELEMENT_NODE = 1, 101 ATTRIBUTE_NODE = 2, 102 TEXT_NODE = 3, 103 CDATA_SECTION_NODE = 4, 104 ENTITY_REFERENCE_NODE = 5, 105 ENTITY_NODE = 6, 106 PROCESSING_INSTRUCTION_NODE = 7, 107 COMMENT_NODE = 8, 108 DOCUMENT_NODE = 9, 109 DOCUMENT_TYPE_NODE = 10, 110 DOCUMENT_FRAGMENT_NODE = 11, 111 NOTATION_NODE = 12, 112 XPATH_NAMESPACE_NODE = 13 113 }; 114 enum DocumentPosition { 115 DOCUMENT_POSITION_EQUIVALENT = 0x00, 116 DOCUMENT_POSITION_DISCONNECTED = 0x01, 117 DOCUMENT_POSITION_PRECEDING = 0x02, 118 DOCUMENT_POSITION_FOLLOWING = 0x04, 119 DOCUMENT_POSITION_CONTAINS = 0x08, 120 DOCUMENT_POSITION_CONTAINED_BY = 0x10, 121 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20, 122 }; 123 124 static bool isSupported(const String& feature, const String& version); 125 126 static void startIgnoringLeaks(); 127 static void stopIgnoringLeaks(); 128 129 static void dumpStatistics(); 130 131 enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force }; 132 static StyleChange diff(const RenderStyle*, const RenderStyle*); 133 134 virtual ~Node(); 135 136 // DOM methods & attributes for Node 137 138 bool hasTagName(const QualifiedName&) const; 139 bool hasLocalName(const AtomicString&) const; 140 virtual String nodeName() const = 0; 141 virtual String nodeValue() const; 142 virtual void setNodeValue(const String&, ExceptionCode&); 143 virtual NodeType nodeType() const = 0; 144 ContainerNode* parentNode() const; 145 Element* parentElement() const; 146 Node* previousSibling() const { return m_previous; } 147 Node* nextSibling() const { return m_next; } 148 PassRefPtr<NodeList> childNodes(); 149 Node* firstChild() const; 150 Node* lastChild() const; 151 bool hasAttributes() const; 152 NamedNodeMap* attributes() const; 153 154 virtual KURL baseURI() const; 155 156 void getSubresourceURLs(ListHashSet<KURL>&) const; 157 158 // These should all actually return a node, but this is only important for language bindings, 159 // which will already know and hold a ref on the right node to return. Returning bool allows 160 // these methods to be more efficient since they don't need to return a ref 161 bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false); 162 bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false); 163 bool removeChild(Node* child, ExceptionCode&); 164 bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false); 165 166 void remove(ExceptionCode&); 167 bool hasChildNodes() const { return firstChild(); } 168 virtual PassRefPtr<Node> cloneNode(bool deep) = 0; 169 const AtomicString& localName() const { return virtualLocalName(); } 170 const AtomicString& namespaceURI() const { return virtualNamespaceURI(); } 171 const AtomicString& prefix() const { return virtualPrefix(); } 172 virtual void setPrefix(const AtomicString&, ExceptionCode&); 173 void normalize(); 174 175 bool isSameNode(Node* other) const { return this == other; } 176 bool isEqualNode(Node*) const; 177 bool isDefaultNamespace(const AtomicString& namespaceURI) const; 178 String lookupPrefix(const AtomicString& namespaceURI) const; 179 String lookupNamespaceURI(const String& prefix) const; 180 String lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const; 181 182 String textContent(bool convertBRsToNewlines = false) const; 183 void setTextContent(const String&, ExceptionCode&); 184 185 Node* lastDescendant() const; 186 Node* firstDescendant() const; 187 188 // Other methods (not part of DOM) 189 190 bool isElementNode() const { return getFlag(IsElementFlag); } 191 bool isContainerNode() const { return getFlag(IsContainerFlag); } 192 bool isTextNode() const { return getFlag(IsTextFlag); } 193 194 bool isHTMLElement() const { return getFlag(IsHTMLFlag); } 195 196 bool isSVGElement() const { return getFlag(IsSVGFlag); } 197 virtual bool isSVGShadowRoot() const { return false; } 198 #if ENABLE(SVG) 199 SVGUseElement* svgShadowHost() const; 200 #endif 201 202 #if ENABLE(WML) 203 virtual bool isWMLElement() const { return false; } 204 #else 205 static bool isWMLElement() { return false; } 206 #endif 207 208 virtual bool isMediaControlElement() const { return false; } 209 virtual bool isMediaControls() const { return false; } 210 bool isStyledElement() const { return getFlag(IsStyledElementFlag); } 211 virtual bool isFrameOwnerElement() const { return false; } 212 virtual bool isAttributeNode() const { return false; } 213 bool isCommentNode() const { return getFlag(IsCommentFlag); } 214 virtual bool isCharacterDataNode() const { return false; } 215 bool isDocumentNode() const; 216 bool isShadowRoot() const { return getFlag(IsShadowRootFlag); } 217 // FIXME: Remove this when all shadow roots are ShadowRoots. 218 virtual bool isShadowBoundary() const { return false; } 219 virtual bool canHaveLightChildRendererWithShadow() const { return false; } 220 221 Node* shadowAncestorNode() const; 222 Node* shadowTreeRootNode() const; 223 bool isInShadowTree(); 224 // Node's parent, shadow tree host, or SVG use. 225 ContainerNode* parentOrHostNode() const; 226 // Use when it's guaranteed to that shadowHost is 0 and svgShadowHost is 0. 227 ContainerNode* parentNodeGuaranteedHostFree() const; 228 229 Element* shadowHost() const; 230 void setShadowHost(Element*); 231 232 bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); } 233 void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); } 234 235 // Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation. 236 Node* enclosingLinkEventParentOrSelf(); 237 238 bool isBlockFlow() const; 239 bool isBlockFlowOrBlockTable() const; 240 241 // These low-level calls give the caller responsibility for maintaining the integrity of the tree. 242 void setPreviousSibling(Node* previous) { m_previous = previous; } 243 void setNextSibling(Node* next) { m_next = next; } 244 245 // FIXME: These two functions belong in editing -- "atomic node" is an editing concept. 246 Node* previousNodeConsideringAtomicNodes() const; 247 Node* nextNodeConsideringAtomicNodes() const; 248 249 // Returns the next leaf node or 0 if there are no more. 250 // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. 251 // Uses an editing-specific concept of what a leaf node is, and should probably be moved 252 // out of the Node class into an editing-specific source file. 253 Node* nextLeafNode() const; 254 255 // Returns the previous leaf node or 0 if there are no more. 256 // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. 257 // Uses an editing-specific concept of what a leaf node is, and should probably be moved 258 // out of the Node class into an editing-specific source file. 259 Node* previousLeafNode() const; 260 261 // enclosingBlockFlowElement() is deprecated. Use enclosingBlock instead. 262 Element* enclosingBlockFlowElement() const; 263 264 Element* rootEditableElement() const; 265 266 bool inSameContainingBlockFlowElement(Node*); 267 268 // FIXME: All callers of this function are almost certainly wrong! 269 virtual void deprecatedParserAddChild(PassRefPtr<Node>); 270 271 // Called by the parser when this element's close tag is reached, 272 // signaling that all child tags have been parsed and added. 273 // This is needed for <applet> and <object> elements, which can't lay themselves out 274 // until they know all of their nested <param>s. [Radar 3603191, 4040848]. 275 // Also used for script elements and some SVG elements for similar purposes, 276 // but making parsing a special case in this respect should be avoided if possible. 277 virtual void finishParsingChildren() { } 278 virtual void beginParsingChildren() { } 279 280 // Called on the focused node right before dispatching an unload event. 281 virtual void aboutToUnload() { } 282 283 // For <link> and <style> elements. 284 virtual bool sheetLoaded() { return true; } 285 286 bool hasID() const { return getFlag(HasIDFlag); } 287 bool hasClass() const { return getFlag(HasClassFlag); } 288 bool active() const { return getFlag(IsActiveFlag); } 289 bool inActiveChain() const { return getFlag(InActiveChainFlag); } 290 bool inDetach() const { return getFlag(InDetachFlag); } 291 bool hovered() const { return getFlag(IsHoveredFlag); } 292 bool focused() const { return hasRareData() ? rareDataFocused() : false; } 293 bool attached() const { return getFlag(IsAttachedFlag); } 294 void setAttached() { setFlag(IsAttachedFlag); } 295 bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; } 296 StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); } 297 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); } 298 bool isLink() const { return getFlag(IsLinkFlag); } 299 300 void setHasID(bool f) { setFlag(f, HasIDFlag); } 301 void setHasClass(bool f) { setFlag(f, HasClassFlag); } 302 void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); } 303 void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); } 304 void setInDocument() { setFlag(InDocumentFlag); } 305 void clearInDocument() { clearFlag(InDocumentFlag); } 306 307 void setInActiveChain() { setFlag(InActiveChainFlag); } 308 void clearInActiveChain() { clearFlag(InActiveChainFlag); } 309 310 void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange); 311 void clearNeedsStyleRecalc() { m_nodeFlags &= ~StyleChangeMask; } 312 313 void setIsLink(bool f) { setFlag(f, IsLinkFlag); } 314 void setIsLink() { setFlag(IsLinkFlag); } 315 void clearIsLink() { clearFlag(IsLinkFlag); } 316 317 enum ShouldSetAttached { 318 SetAttached, 319 DoNotSetAttached 320 }; 321 void lazyAttach(ShouldSetAttached = SetAttached); 322 323 virtual void setFocus(bool = true); 324 virtual void setActive(bool f = true, bool /*pause*/ = false) { setFlag(f, IsActiveFlag); } 325 virtual void setHovered(bool f = true) { setFlag(f, IsHoveredFlag); } 326 327 virtual short tabIndex() const; 328 329 // Whether this kind of node can receive focus by default. Most nodes are 330 // not focusable but some elements, such as form controls and links, are. 331 virtual bool supportsFocus() const; 332 // Whether the node can actually be focused. 333 virtual bool isFocusable() const; 334 virtual bool isKeyboardFocusable(KeyboardEvent*) const; 335 virtual bool isMouseFocusable() const; 336 337 bool isContentEditable() const; 338 339 bool rendererIsEditable() const { return rendererIsEditable(Editable); } 340 bool rendererIsRichlyEditable() const { return rendererIsEditable(RichlyEditable); } 341 virtual bool shouldUseInputMethod() const; 342 virtual IntRect getRect() const; 343 IntRect renderRect(bool* isReplaced); 344 345 // Returns true if the node has a non-empty bounding box in layout. 346 // This does not 100% guarantee the user can see it, but is pretty close. 347 // Note: This method only works properly after layout has occurred. 348 bool hasNonEmptyBoundingBox() const; 349 350 virtual void recalcStyle(StyleChange = NoChange) { } 351 352 unsigned nodeIndex() const; 353 354 // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case 355 // of (1) a Document node or (2) a DocumentType node that is not used with any Document yet. 356 virtual Document* ownerDocument() const; 357 358 // Returns the document associated with this node. This method never returns NULL, except in the case 359 // of a DocumentType node that is not used with any Document yet. A Document node returns itself. 360 Document* document() const 361 { 362 ASSERT(this); 363 ASSERT(m_document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument())); 364 return m_document; 365 } 366 367 TreeScope* treeScope() const; 368 369 // Do not use this method to change the scope of a node until after the node has been 370 // removed from its previous scope. Do not use to change documents. 371 void setTreeScope(TreeScope*); 372 373 // Used by the basic DOM methods (e.g., appendChild()). 374 void setTreeScopeRecursively(TreeScope*); 375 376 // Returns true if this node is associated with a document and is in its associated document's 377 // node tree, false otherwise. 378 bool inDocument() const 379 { 380 ASSERT(m_document || !getFlag(InDocumentFlag)); 381 return getFlag(InDocumentFlag); 382 } 383 384 bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; } 385 virtual bool childTypeAllowed(NodeType) const { return false; } 386 unsigned childNodeCount() const; 387 Node* childNode(unsigned index) const; 388 389 // Does a pre-order traversal of the tree to find the next node after this one. 390 // This uses the same order that tags appear in the source file. If the stayWithin 391 // argument is non-null, the traversal will stop once the specified node is reached. 392 // This can be used to restrict traversal to a particular sub-tree. 393 Node* traverseNextNode(const Node* stayWithin = 0) const; 394 395 // Like traverseNextNode, but skips children and starts with the next sibling. 396 Node* traverseNextSibling(const Node* stayWithin = 0) const; 397 398 // Does a reverse pre-order traversal to find the node that comes before the current one in document order 399 Node* traversePreviousNode(const Node* stayWithin = 0) const; 400 401 // Like traverseNextNode, but visits parents after their children. 402 Node* traverseNextNodePostOrder() const; 403 404 // Like traversePreviousNode, but visits parents before their children. 405 Node* traversePreviousNodePostOrder(const Node* stayWithin = 0) const; 406 Node* traversePreviousSiblingPostOrder(const Node* stayWithin = 0) const; 407 408 void checkSetPrefix(const AtomicString& prefix, ExceptionCode&); 409 bool isDescendantOf(const Node*) const; 410 bool contains(const Node*) const; 411 bool containsIncludingShadowDOM(Node*); 412 413 // This method is used to do strict error-checking when adding children via 414 // the public DOM API (e.g., appendChild()). 415 void checkAddChild(Node* newChild, ExceptionCode&); // Error-checking when adding via the DOM API 416 417 void checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode&); 418 virtual bool canReplaceChild(Node* newChild, Node* oldChild); 419 420 // Used to determine whether range offsets use characters or node indices. 421 virtual bool offsetInCharacters() const; 422 // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of 423 // css-transform:capitalize breaking up precomposed characters and ligatures. 424 virtual int maxCharacterOffset() const; 425 426 // FIXME: We should try to find a better location for these methods. 427 virtual bool canSelectAll() const { return false; } 428 virtual void selectAll() { } 429 430 // Whether or not a selection can be started in this object 431 virtual bool canStartSelection() const; 432 433 // Getting points into and out of screen space 434 FloatPoint convertToPage(const FloatPoint&) const; 435 FloatPoint convertFromPage(const FloatPoint&) const; 436 437 // ----------------------------------------------------------------------------- 438 // Integration with rendering tree 439 440 RenderObject* renderer() const { return m_renderer; } 441 RenderObject* nextRenderer(); 442 RenderObject* previousRenderer(); 443 void setRenderer(RenderObject* renderer) { m_renderer = renderer; } 444 445 // Use these two methods with caution. 446 RenderBox* renderBox() const; 447 RenderBoxModelObject* renderBoxModelObject() const; 448 449 // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an 450 // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This 451 // makes the node visible in the FrameView. 452 virtual void attach(); 453 454 // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove 455 // the node's rendering object from the rendering tree and delete it. 456 virtual void detach(); 457 458 virtual void willRemove(); 459 void createRendererIfNeeded(); 460 PassRefPtr<RenderStyle> styleForRenderer(); 461 virtual bool rendererIsNeeded(RenderStyle*); 462 virtual bool childShouldCreateRenderer(Node*) const { return true; } 463 virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); 464 ContainerNode* parentNodeForRenderingAndStyle() const; 465 466 // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement). 467 RenderStyle* renderStyle() const; 468 virtual void setRenderStyle(PassRefPtr<RenderStyle>); 469 470 RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); } 471 472 // ----------------------------------------------------------------------------- 473 // Notification of document structure changes 474 475 // Notifies the node that it has been inserted into the document. This is called during document parsing, and also 476 // when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only 477 // happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of 478 // the node. The call happens _after_ the node has been added to the tree. 479 // 480 // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event 481 // dispatching. 482 virtual void insertedIntoDocument(); 483 484 // Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor 485 // node. 486 // 487 // This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event 488 // dispatching, and is called _after_ the node is removed from the tree. 489 virtual void removedFromDocument(); 490 491 // These functions are called whenever you are connected or disconnected from a tree. That tree may be the main 492 // document tree, or it could be another disconnected tree. Override these functions to do any work that depends 493 // on connectedness to some ancestor (e.g., an ancestor <form> for example). 494 virtual void insertedIntoTree(bool /*deep*/) { } 495 virtual void removedFromTree(bool /*deep*/) { } 496 497 // Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child 498 // node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value. 499 virtual void childrenChanged(bool /*changedByParser*/ = false, Node* /*beforeChange*/ = 0, Node* /*afterChange*/ = 0, int /*childCountDelta*/ = 0) { } 500 501 #if !defined(NDEBUG) || defined(ANDROID_DOM_LOGGING) 502 virtual void formatForDebugger(char* buffer, unsigned length) const; 503 504 void showNode(const char* prefix = "") const; 505 void showTreeForThis() const; 506 void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const; 507 #endif 508 509 void registerDynamicNodeList(DynamicNodeList*); 510 void unregisterDynamicNodeList(DynamicNodeList*); 511 void notifyNodeListsChildrenChanged(); 512 void notifyLocalNodeListsChildrenChanged(); 513 void notifyNodeListsAttributeChanged(); 514 void notifyLocalNodeListsAttributeChanged(); 515 void notifyLocalNodeListsLabelChanged(); 516 void removeCachedClassNodeList(ClassNodeList*, const String&); 517 void removeCachedNameNodeList(NameNodeList*, const String&); 518 void removeCachedTagNodeList(TagNodeList*, const QualifiedName&); 519 void removeCachedLabelsNodeList(DynamicNodeList*); 520 521 PassRefPtr<NodeList> getElementsByTagName(const AtomicString&); 522 PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName); 523 PassRefPtr<NodeList> getElementsByName(const String& elementName); 524 PassRefPtr<NodeList> getElementsByClassName(const String& classNames); 525 526 PassRefPtr<Element> querySelector(const String& selectors, ExceptionCode&); 527 PassRefPtr<NodeList> querySelectorAll(const String& selectors, ExceptionCode&); 528 529 unsigned short compareDocumentPosition(Node*); 530 531 virtual Node* toNode() { return this; } 532 533 virtual InputElement* toInputElement(); 534 535 virtual ScriptExecutionContext* scriptExecutionContext() const; 536 537 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); 538 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); 539 540 // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event 541 // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. 542 virtual void* preDispatchEventHandler(Event*) { return 0; } 543 virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } 544 545 using EventTarget::dispatchEvent; 546 bool dispatchEvent(PassRefPtr<Event>); 547 void dispatchScopedEvent(PassRefPtr<Event>); 548 549 virtual void handleLocalEvents(Event*); 550 551 void dispatchSubtreeModifiedEvent(); 552 void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent); 553 bool dispatchKeyEvent(const PlatformKeyboardEvent&); 554 bool dispatchWheelEvent(const PlatformWheelEvent&); 555 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0); 556 void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true); 557 558 virtual void dispatchFocusEvent(); 559 virtual void dispatchBlurEvent(); 560 virtual void dispatchChangeEvent(); 561 virtual void dispatchInputEvent(); 562 563 // Perform the default action for an event. 564 virtual void defaultEventHandler(Event*); 565 566 // Used for disabled form elements; if true, prevents mouse events from being dispatched 567 // to event listeners, and prevents DOMActivate events from being sent at all. 568 virtual bool disabled() const; 569 570 using TreeShared<ContainerNode>::ref; 571 using TreeShared<ContainerNode>::deref; 572 573 virtual EventTargetData* eventTargetData(); 574 virtual EventTargetData* ensureEventTargetData(); 575 576 private: 577 enum NodeFlags { 578 IsTextFlag = 1, 579 IsCommentFlag = 1 << 1, 580 IsContainerFlag = 1 << 2, 581 IsElementFlag = 1 << 3, 582 IsStyledElementFlag = 1 << 4, 583 IsHTMLFlag = 1 << 5, 584 IsSVGFlag = 1 << 6, 585 HasIDFlag = 1 << 7, 586 HasClassFlag = 1 << 8, 587 IsAttachedFlag = 1 << 9, 588 ChildNeedsStyleRecalcFlag = 1 << 10, 589 InDocumentFlag = 1 << 11, 590 IsLinkFlag = 1 << 12, 591 IsActiveFlag = 1 << 13, 592 IsHoveredFlag = 1 << 14, 593 InActiveChainFlag = 1 << 15, 594 InDetachFlag = 1 << 16, 595 HasRareDataFlag = 1 << 17, 596 IsShadowRootFlag = 1 << 18, 597 598 // These bits are used by derived classes, pulled up here so they can 599 // be stored in the same memory word as the Node bits above. 600 IsParsingChildrenFinishedFlag = 1 << 19, // Element 601 IsStyleAttributeValidFlag = 1 << 20, // StyledElement 602 IsSynchronizingStyleAttributeFlag = 1 << 21, // StyledElement 603 #if ENABLE(SVG) 604 AreSVGAttributesValidFlag = 1 << 22, // Element 605 IsSynchronizingSVGAttributesFlag = 1 << 23, // SVGElement 606 HasSVGRareDataFlag = 1 << 24, // SVGElement 607 #endif 608 609 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1), 610 611 SelfOrAncestorHasDirAutoFlag = 1 << 27, 612 613 #if ENABLE(SVG) 614 DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag 615 #else 616 DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag 617 #endif 618 }; 619 620 // 4 bits remaining 621 622 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } 623 void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } 624 void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; } 625 void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; } 626 627 protected: 628 enum ConstructionType { 629 CreateOther = DefaultNodeFlags, 630 CreateText = DefaultNodeFlags | IsTextFlag, 631 CreateComment = DefaultNodeFlags | IsCommentFlag, 632 CreateContainer = DefaultNodeFlags | IsContainerFlag, 633 CreateElement = CreateContainer | IsElementFlag, 634 CreateStyledElement = CreateElement | IsStyledElementFlag, 635 CreateHTMLElement = CreateStyledElement | IsHTMLFlag, 636 CreateSVGElement = CreateStyledElement | IsSVGFlag, 637 }; 638 Node(Document*, ConstructionType); 639 640 // Do not use this method to change the document of a node until after the node has been 641 // removed from its previous document. 642 void setDocument(Document*); 643 void setDocumentRecursively(Document*); 644 645 virtual void willMoveToNewOwnerDocument(); 646 virtual void didMoveToNewOwnerDocument(); 647 648 virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { } 649 void setTabIndexExplicitly(short); 650 void clearTabIndexExplicitly(); 651 652 bool hasRareData() const { return getFlag(HasRareDataFlag); } 653 654 NodeRareData* rareData() const; 655 NodeRareData* ensureRareData(); 656 657 private: 658 enum EditableLevel { Editable, RichlyEditable }; 659 bool rendererIsEditable(EditableLevel) const; 660 661 void setStyleChange(StyleChangeType); 662 663 // Used to share code between lazyAttach and setNeedsStyleRecalc. 664 void markAncestorsWithChildNeedsStyleRecalc(); 665 666 RenderObject* createRendererAndStyle(); 667 668 virtual void refEventTarget(); 669 virtual void derefEventTarget(); 670 671 virtual NodeRareData* createRareData(); 672 bool rareDataFocused() const; 673 674 virtual RenderStyle* nonRendererRenderStyle() const; 675 676 virtual const AtomicString& virtualPrefix() const; 677 virtual const AtomicString& virtualLocalName() const; 678 virtual const AtomicString& virtualNamespaceURI() const; 679 virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO); 680 681 Element* ancestorElement() const; 682 683 // Use Node::parentNode as the consistent way of querying a parent node. 684 // This method is made private to ensure a compiler error on call sites that 685 // don't follow this rule. 686 using TreeShared<ContainerNode>::parent; 687 688 void trackForDebugging(); 689 690 Document* m_document; 691 Node* m_previous; 692 Node* m_next; 693 RenderObject* m_renderer; 694 mutable uint32_t m_nodeFlags; 695 696 protected: 697 bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); } 698 void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); } 699 void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); } 700 bool isStyleAttributeValid() const { return getFlag(IsStyleAttributeValidFlag); } 701 void setIsStyleAttributeValid(bool f) { setFlag(f, IsStyleAttributeValidFlag); } 702 void setIsStyleAttributeValid() const { setFlag(IsStyleAttributeValidFlag); } 703 void clearIsStyleAttributeValid() { clearFlag(IsStyleAttributeValidFlag); } 704 bool isSynchronizingStyleAttribute() const { return getFlag(IsSynchronizingStyleAttributeFlag); } 705 void setIsSynchronizingStyleAttribute(bool f) { setFlag(f, IsSynchronizingStyleAttributeFlag); } 706 void setIsSynchronizingStyleAttribute() const { setFlag(IsSynchronizingStyleAttributeFlag); } 707 void clearIsSynchronizingStyleAttribute() const { clearFlag(IsSynchronizingStyleAttributeFlag); } 708 709 #if ENABLE(SVG) 710 bool areSVGAttributesValid() const { return getFlag(AreSVGAttributesValidFlag); } 711 void setAreSVGAttributesValid() const { setFlag(AreSVGAttributesValidFlag); } 712 void clearAreSVGAttributesValid() { clearFlag(AreSVGAttributesValidFlag); } 713 bool isSynchronizingSVGAttributes() const { return getFlag(IsSynchronizingSVGAttributesFlag); } 714 void setIsSynchronizingSVGAttributes() const { setFlag(IsSynchronizingSVGAttributesFlag); } 715 void clearIsSynchronizingSVGAttributes() const { clearFlag(IsSynchronizingSVGAttributesFlag); } 716 bool hasRareSVGData() const { return getFlag(HasSVGRareDataFlag); } 717 void setHasRareSVGData() { setFlag(HasSVGRareDataFlag); } 718 void clearHasRareSVGData() { clearFlag(HasSVGRareDataFlag); } 719 #endif 720 }; 721 722 // Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs() 723 inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url) 724 { 725 if (!url.isNull()) 726 urls.add(url); 727 } 728 729 inline ContainerNode* Node::parentNode() const 730 { 731 return getFlag(IsShadowRootFlag) || isSVGShadowRoot() ? 0 : parent(); 732 } 733 734 inline ContainerNode* Node::parentOrHostNode() const 735 { 736 return parent(); 737 } 738 739 inline ContainerNode* Node::parentNodeGuaranteedHostFree() const 740 { 741 ASSERT(!getFlag(IsShadowRootFlag) && !isSVGShadowRoot()); 742 return parentOrHostNode(); 743 } 744 745 } //namespace 746 747 #ifndef NDEBUG 748 // Outside the WebCore namespace for ease of invocation from gdb. 749 void showTree(const WebCore::Node*); 750 #endif 751 752 #endif 753