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-2011, 2014 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 "bindings/core/v8/ExceptionStatePlaceholder.h" 29 #include "core/dom/MutationObserver.h" 30 #include "core/dom/SimulatedClickOptions.h" 31 #include "core/dom/TreeScope.h" 32 #include "core/dom/TreeShared.h" 33 #include "core/editing/EditingBoundary.h" 34 #include "core/events/EventTarget.h" 35 #include "core/inspector/InspectorCounters.h" 36 #include "core/rendering/style/RenderStyleConstants.h" 37 #include "platform/geometry/LayoutRect.h" 38 #include "platform/heap/Handle.h" 39 #include "platform/weborigin/KURLHash.h" 40 #include "wtf/Forward.h" 41 42 // This needs to be here because Document.h also depends on it. 43 #define DUMP_NODE_STATISTICS 0 44 45 namespace blink { 46 47 class Attribute; 48 class ClassCollection; 49 class ContainerNode; 50 class DOMSettableTokenList; 51 class Document; 52 class Element; 53 class Event; 54 class EventDispatchMediator; 55 class EventListener; 56 class ExceptionState; 57 class FloatPoint; 58 class LocalFrame; 59 class HTMLInputElement; 60 class HTMLQualifiedName; 61 class IntRect; 62 class KeyboardEvent; 63 class NSResolver; 64 class NameNodeList; 65 class NamedNodeMap; 66 class NodeEventContext; 67 class NodeList; 68 class NodeListsNodeData; 69 class NodeRareData; 70 class PlatformGestureEvent; 71 class PlatformKeyboardEvent; 72 class PlatformMouseEvent; 73 class PlatformWheelEvent; 74 class QualifiedName; 75 class RadioNodeList; 76 class RegisteredEventListener; 77 class RenderBox; 78 class RenderBoxModelObject; 79 class RenderObject; 80 class RenderStyle; 81 class SVGQualifiedName; 82 class ShadowRoot; 83 template <typename NodeType> class StaticNodeTypeList; 84 typedef StaticNodeTypeList<Node> StaticNodeList; 85 class TagCollection; 86 class Text; 87 class TouchEvent; 88 class WeakNodeMap; 89 90 const int nodeStyleChangeShift = 19; 91 92 enum StyleChangeType { 93 NoStyleChange = 0, 94 LocalStyleChange = 1 << nodeStyleChangeShift, 95 SubtreeStyleChange = 2 << nodeStyleChangeShift, 96 NeedsReattachStyleChange = 3 << nodeStyleChangeShift, 97 }; 98 99 class NodeRareDataBase { 100 public: 101 RenderObject* renderer() const { return m_renderer; } 102 void setRenderer(RenderObject* renderer) { m_renderer = renderer; } 103 104 protected: 105 NodeRareDataBase(RenderObject* renderer) 106 : m_renderer(renderer) 107 { } 108 109 protected: 110 // Oilpan: This member is traced in NodeRareData. 111 // FIXME: Can we add traceAfterDispatch and finalizeGarbageCollectedObject 112 // to NodeRareDataBase, and make m_renderer Member<>? 113 RenderObject* m_renderer; 114 }; 115 116 #if ENABLE(OILPAN) 117 #define NODE_BASE_CLASSES public GarbageCollectedFinalized<Node>, public EventTarget 118 #else 119 // TreeShared should be the last to pack TreeShared::m_refCount and 120 // Node::m_nodeFlags on 64bit platforms. 121 #define NODE_BASE_CLASSES public EventTarget, public TreeShared<Node> 122 #endif 123 124 class Node : NODE_BASE_CLASSES { 125 DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(TreeShared<Node>); 126 DEFINE_WRAPPERTYPEINFO(); 127 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Node); 128 friend class Document; 129 friend class TreeScope; 130 friend class TreeScopeAdopter; 131 public: 132 enum NodeType { 133 ELEMENT_NODE = 1, 134 ATTRIBUTE_NODE = 2, 135 TEXT_NODE = 3, 136 CDATA_SECTION_NODE = 4, 137 PROCESSING_INSTRUCTION_NODE = 7, 138 COMMENT_NODE = 8, 139 DOCUMENT_NODE = 9, 140 DOCUMENT_TYPE_NODE = 10, 141 DOCUMENT_FRAGMENT_NODE = 11, 142 }; 143 144 // Entity, EntityReference, Notation, and XPathNamespace nodes are impossible to create in Blink. 145 // But for compatibility reasons we want these enum values exist in JS, and this enum makes the bindings 146 // generation not complain about ENTITY_REFERENCE_NODE being missing from the implementation 147 // while not requiring all switch(NodeType) blocks to include this deprecated constant. 148 enum DeprecatedNodeType { 149 ENTITY_REFERENCE_NODE = 5, 150 ENTITY_NODE = 6, 151 NOTATION_NODE = 12, 152 XPATH_NAMESPACE_NODE = 13, 153 }; 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 #if !ENABLE(OILPAN) 166 // All Nodes are placed in their own heap partition for security. 167 // See http://crbug.com/246860 for detail. 168 void* operator new(size_t); 169 void operator delete(void*); 170 #endif 171 172 static void dumpStatistics(); 173 174 virtual ~Node(); 175 176 // DOM methods & attributes for Node 177 178 bool hasTagName(const HTMLQualifiedName&) const; 179 bool hasTagName(const SVGQualifiedName&) const; 180 virtual String nodeName() const = 0; 181 virtual String nodeValue() const; 182 virtual void setNodeValue(const String&); 183 virtual NodeType nodeType() const = 0; 184 ContainerNode* parentNode() const; 185 Element* parentElement() const; 186 ContainerNode* parentElementOrShadowRoot() const; 187 ContainerNode* parentElementOrDocumentFragment() const; 188 Node* previousSibling() const { return m_previous; } 189 Node* nextSibling() const { return m_next; } 190 PassRefPtrWillBeRawPtr<NodeList> childNodes(); 191 Node* firstChild() const; 192 Node* lastChild() const; 193 194 void remove(ExceptionState&); 195 196 Node* pseudoAwareNextSibling() const; 197 Node* pseudoAwarePreviousSibling() const; 198 Node* pseudoAwareFirstChild() const; 199 Node* pseudoAwareLastChild() const; 200 201 virtual KURL baseURI() const; 202 203 // These should all actually return a node, but this is only important for language bindings, 204 // which will already know and hold a ref on the right node to return. 205 PassRefPtrWillBeRawPtr<Node> insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION); 206 PassRefPtrWillBeRawPtr<Node> replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& = ASSERT_NO_EXCEPTION); 207 PassRefPtrWillBeRawPtr<Node> removeChild(PassRefPtrWillBeRawPtr<Node> child, ExceptionState& = ASSERT_NO_EXCEPTION); 208 PassRefPtrWillBeRawPtr<Node> appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION); 209 210 bool hasChildren() const { return firstChild(); } 211 virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = false) = 0; 212 virtual const AtomicString& localName() const; 213 virtual const AtomicString& namespaceURI() const; 214 void normalize(); 215 216 bool isSameNode(Node* other) const { return this == other; } 217 bool isEqualNode(Node*) const; 218 bool isDefaultNamespace(const AtomicString& namespaceURI) const; 219 const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const; 220 const AtomicString& lookupNamespaceURI(const String& prefix) const; 221 222 String textContent(bool convertBRsToNewlines = false) const; 223 void setTextContent(const String&); 224 225 // Other methods (not part of DOM) 226 227 bool isElementNode() const { return getFlag(IsElementFlag); } 228 bool isContainerNode() const { return getFlag(IsContainerFlag); } 229 bool isTextNode() const { return getFlag(IsTextFlag); } 230 bool isHTMLElement() const { return getFlag(IsHTMLFlag); } 231 bool isSVGElement() const { return getFlag(IsSVGFlag); } 232 233 bool isPseudoElement() const { return pseudoId() != NOPSEUDO; } 234 bool isBeforePseudoElement() const { return pseudoId() == BEFORE; } 235 bool isAfterPseudoElement() const { return pseudoId() == AFTER; } 236 virtual PseudoId pseudoId() const { return NOPSEUDO; } 237 238 bool isCustomElement() const { return getFlag(CustomElementFlag); } 239 enum CustomElementState { 240 NotCustomElement = 0, 241 WaitingForUpgrade = 1 << 0, 242 Upgraded = 1 << 1 243 }; 244 CustomElementState customElementState() const 245 { 246 return isCustomElement() 247 ? (getFlag(CustomElementUpgradedFlag) ? Upgraded : WaitingForUpgrade) 248 : NotCustomElement; 249 } 250 void setCustomElementState(CustomElementState newState); 251 252 virtual bool isMediaControlElement() const { return false; } 253 virtual bool isMediaControls() const { return false; } 254 virtual bool isVTTElement() const { return false; } 255 virtual bool isAttributeNode() const { return false; } 256 virtual bool isCharacterDataNode() const { return false; } 257 virtual bool isFrameOwnerElement() const { return false; } 258 259 // StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color), 260 // class names (ex. class="foo bar") and other non-basic styling features. They and also control 261 // if this element can participate in style sharing. 262 // 263 // FIXME: The only things that ever go through StyleResolver that aren't StyledElements are 264 // PseudoElements and VTTElements. It's possible we can just eliminate all the checks 265 // since those elements will never have class names, inline style, or other things that 266 // this apparently guards against. 267 bool isStyledElement() const { return isHTMLElement() || isSVGElement(); } 268 269 bool isDocumentNode() const; 270 bool isTreeScope() const; 271 bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); } 272 bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); } 273 bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); } 274 275 bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); } 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 ShadowRoot* containingShadowRoot() const; 283 ShadowRoot* youngestShadowRoot() const; 284 285 // Returns 0, a child of ShadowRoot, or a legacy shadow root. 286 Node* nonBoundaryShadowTreeRootNode(); 287 288 // Node's parent, shadow tree host. 289 ContainerNode* parentOrShadowHostNode() const; 290 Element* parentOrShadowHostElement() const; 291 void setParentOrShadowHostNode(ContainerNode*); 292 293 // Knows about all kinds of hosts. 294 ContainerNode* parentOrShadowHostOrTemplateHostNode() const; 295 296 // Returns the parent node, but 0 if the parent node is a ShadowRoot. 297 ContainerNode* nonShadowBoundaryParentNode() const; 298 299 bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); } 300 void setSelfOrAncestorHasDirAutoAttribute(bool flag) { setFlag(flag, SelfOrAncestorHasDirAutoFlag); } 301 302 // Returns the enclosing event parent Element (or self) that, when clicked, would trigger a navigation. 303 Element* enclosingLinkEventParentOrSelf(); 304 305 // These low-level calls give the caller responsibility for maintaining the integrity of the tree. 306 void setPreviousSibling(Node* previous) { m_previous = previous; } 307 void setNextSibling(Node* next) { m_next = next; } 308 309 virtual bool canContainRangeEndPoint() const { return false; } 310 311 // FIXME: These two functions belong in editing -- "atomic node" is an editing concept. 312 Node* previousNodeConsideringAtomicNodes() const; 313 Node* nextNodeConsideringAtomicNodes() const; 314 315 // Returns the next leaf node or 0 if there are no more. 316 // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. 317 // Uses an editing-specific concept of what a leaf node is, and should probably be moved 318 // out of the Node class into an editing-specific source file. 319 Node* nextLeafNode() const; 320 321 // Returns the previous leaf node or 0 if there are no more. 322 // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. 323 // Uses an editing-specific concept of what a leaf node is, and should probably be moved 324 // out of the Node class into an editing-specific source file. 325 Node* previousLeafNode() const; 326 327 bool isRootEditableElement() const; 328 Element* rootEditableElement() const; 329 Element* rootEditableElement(EditableType) const; 330 331 // For <link> and <style> elements. 332 virtual bool sheetLoaded() { return true; } 333 virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { } 334 virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); } 335 336 bool hasName() const { return !isTextNode() && getFlag(HasNameOrIsEditingTextFlag); } 337 338 bool isUserActionElement() const { return getFlag(IsUserActionElementFlag); } 339 void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElementFlag); } 340 341 bool active() const { return isUserActionElement() && isUserActionElementActive(); } 342 bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); } 343 bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); } 344 bool focused() const { return isUserActionElement() && isUserActionElementFocused(); } 345 346 bool needsAttach() const { return styleChangeType() == NeedsReattachStyleChange; } 347 bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; } 348 StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); } 349 bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); } 350 bool isLink() const { return getFlag(IsLinkFlag); } 351 bool isEditingText() const { return isTextNode() && getFlag(HasNameOrIsEditingTextFlag); } 352 353 void setHasName(bool f) { ASSERT(!isTextNode()); setFlag(f, HasNameOrIsEditingTextFlag); } 354 void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); } 355 void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); } 356 357 void setNeedsStyleRecalc(StyleChangeType); 358 void clearNeedsStyleRecalc(); 359 360 bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalcFlag); } 361 void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalcFlag); } 362 void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalcFlag); } 363 void markAncestorsWithChildNeedsDistributionRecalc(); 364 365 bool childNeedsStyleInvalidation() const { return getFlag(ChildNeedsStyleInvalidationFlag); } 366 void setChildNeedsStyleInvalidation() { setFlag(ChildNeedsStyleInvalidationFlag); } 367 void clearChildNeedsStyleInvalidation() { clearFlag(ChildNeedsStyleInvalidationFlag); } 368 void markAncestorsWithChildNeedsStyleInvalidation(); 369 bool needsStyleInvalidation() const { return getFlag(NeedsStyleInvalidationFlag); } 370 void clearNeedsStyleInvalidation() { clearFlag(NeedsStyleInvalidationFlag); } 371 void setNeedsStyleInvalidation(); 372 373 void recalcDistribution(); 374 375 bool svgFilterNeedsLayerUpdate() const { return getFlag(SVGFilterNeedsLayerUpdateFlag); } 376 void setSVGFilterNeedsLayerUpdate() { setFlag(SVGFilterNeedsLayerUpdateFlag); } 377 void clearSVGFilterNeedsLayerUpdate() { clearFlag(SVGFilterNeedsLayerUpdateFlag); } 378 379 void setIsLink(bool f); 380 381 bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); } 382 void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); } 383 384 bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); } 385 void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); } 386 void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); } 387 388 virtual void setFocus(bool flag); 389 virtual void setActive(bool flag = true); 390 virtual void setHovered(bool flag = true); 391 392 virtual short tabIndex() const; 393 394 virtual Node* focusDelegate(); 395 // This is called only when the node is focused. 396 virtual bool shouldHaveFocusAppearance() const; 397 398 // Whether the node is inert. This can't be in Element because text nodes 399 // must be recognized as inert to prevent text selection. 400 bool isInert() const; 401 402 enum UserSelectAllTreatment { 403 UserSelectAllDoesNotAffectEditability, 404 UserSelectAllIsAlwaysNonEditable 405 }; 406 bool isContentEditable(UserSelectAllTreatment = UserSelectAllDoesNotAffectEditability); 407 bool isContentRichlyEditable(); 408 409 bool hasEditableStyle(EditableType editableType = ContentIsEditable, UserSelectAllTreatment treatment = UserSelectAllIsAlwaysNonEditable) const 410 { 411 switch (editableType) { 412 case ContentIsEditable: 413 return hasEditableStyle(Editable, treatment); 414 case HasEditableAXRole: 415 return isEditableToAccessibility(Editable); 416 } 417 ASSERT_NOT_REACHED(); 418 return false; 419 } 420 421 bool rendererIsRichlyEditable(EditableType editableType = ContentIsEditable) const 422 { 423 switch (editableType) { 424 case ContentIsEditable: 425 return hasEditableStyle(RichlyEditable, UserSelectAllIsAlwaysNonEditable); 426 case HasEditableAXRole: 427 return isEditableToAccessibility(RichlyEditable); 428 } 429 ASSERT_NOT_REACHED(); 430 return false; 431 } 432 433 virtual LayoutRect boundingBox() const; 434 IntRect pixelSnappedBoundingBox() const { return pixelSnappedIntRect(boundingBox()); } 435 436 // Returns true if the node has a non-empty bounding box in layout. 437 // This does not 100% guarantee the user can see it, but is pretty close. 438 // Note: This method only works properly after layout has occurred. 439 bool hasNonEmptyBoundingBox() const; 440 441 unsigned nodeIndex() const; 442 443 // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case 444 // of a Document node. 445 Document* ownerDocument() const; 446 447 // Returns the document associated with this node. A Document node returns itself. 448 Document& document() const 449 { 450 return treeScope().document(); 451 } 452 453 TreeScope& treeScope() const 454 { 455 ASSERT(m_treeScope); 456 return *m_treeScope; 457 } 458 459 bool inActiveDocument() const; 460 461 // Returns true if this node is associated with a document and is in its associated document's 462 // node tree, false otherwise. 463 bool inDocument() const 464 { 465 return getFlag(InDocumentFlag); 466 } 467 bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); } 468 bool isInTreeScope() const { return getFlag(static_cast<NodeFlags>(InDocumentFlag | IsInShadowTreeFlag)); } 469 470 bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; } 471 virtual bool childTypeAllowed(NodeType) const { return false; } 472 unsigned countChildren() const; 473 474 bool isDescendantOf(const Node*) const; 475 bool contains(const Node*) const; 476 bool containsIncludingShadowDOM(const Node*) const; 477 bool containsIncludingHostElements(const Node&) const; 478 Node* commonAncestor(const Node&, Node* (*parent)(const Node&)); 479 480 // Used to determine whether range offsets use characters or node indices. 481 virtual bool offsetInCharacters() const; 482 // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of 483 // css-transform:capitalize breaking up precomposed characters and ligatures. 484 virtual int maxCharacterOffset() const; 485 486 // Whether or not a selection can be started in this object 487 virtual bool canStartSelection() const; 488 489 // ----------------------------------------------------------------------------- 490 // Integration with rendering tree 491 492 // As renderer() includes a branch you should avoid calling it repeatedly in hot code paths. 493 // Note that if a Node has a renderer, it's parentNode is guaranteed to have one as well. 494 RenderObject* renderer() const { return hasRareData() ? m_data.m_rareData->renderer() : m_data.m_renderer; }; 495 void setRenderer(RenderObject* renderer) 496 { 497 if (hasRareData()) 498 m_data.m_rareData->setRenderer(renderer); 499 else 500 m_data.m_renderer = renderer; 501 } 502 503 // Use these two methods with caution. 504 RenderBox* renderBox() const; 505 RenderBoxModelObject* renderBoxModelObject() const; 506 507 struct AttachContext { 508 RenderStyle* resolvedStyle; 509 bool performingReattach; 510 511 AttachContext() : resolvedStyle(0), performingReattach(false) { } 512 }; 513 514 // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an 515 // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This 516 // makes the node visible in the FrameView. 517 virtual void attach(const AttachContext& = AttachContext()); 518 519 // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove 520 // the node's rendering object from the rendering tree and delete it. 521 virtual void detach(const AttachContext& = AttachContext()); 522 523 #if ENABLE(ASSERT) 524 bool inDetach() const; 525 #endif 526 527 void reattach(const AttachContext& = AttachContext()); 528 void lazyReattachIfAttached(); 529 530 // Returns true if recalcStyle should be called on the object, if there is such a method (on Document and Element). 531 bool shouldCallRecalcStyle(StyleRecalcChange); 532 533 // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement). 534 RenderStyle* renderStyle() const; 535 RenderStyle* parentRenderStyle() const; 536 537 RenderStyle* computedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return virtualComputedStyle(pseudoElementSpecifier); } 538 539 // ----------------------------------------------------------------------------- 540 // Notification of document structure changes (see ContainerNode.h for more notification methods) 541 // 542 // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also 543 // 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. 544 // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event 545 // dispatching. 546 // 547 // WebKit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree. 548 // Implementation can determine the type of subtree by seeing insertionPoint->inDocument(). 549 // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document. 550 // 551 // There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified, 552 // if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should 553 // return InsertionShouldCallDidNotifySubtreeInsertions from insertedInto(). 554 // 555 enum InsertionNotificationRequest { 556 InsertionDone, 557 InsertionShouldCallDidNotifySubtreeInsertions 558 }; 559 560 virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint); 561 virtual void didNotifySubtreeInsertionsToDocument() { } 562 563 // Notifies the node that it is no longer part of the tree. 564 // 565 // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event 566 // dispatching, and is called _after_ the node is removed from the tree. 567 // 568 virtual void removedFrom(ContainerNode* insertionPoint); 569 570 String debugName() const; 571 572 #ifndef NDEBUG 573 virtual void formatForDebugger(char* buffer, unsigned length) const; 574 575 void showNode(const char* prefix = "") const; 576 void showTreeForThis() const; 577 void showNodePathForThis() const; 578 void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const; 579 void showTreeForThisAcrossFrame() const; 580 #endif 581 582 NodeListsNodeData* nodeLists(); 583 void clearNodeLists(); 584 585 virtual bool willRespondToMouseMoveEvents(); 586 virtual bool willRespondToMouseClickEvents(); 587 virtual bool willRespondToTouchEvents(); 588 589 enum ShadowTreesTreatment { 590 TreatShadowTreesAsDisconnected, 591 TreatShadowTreesAsComposed 592 }; 593 594 unsigned short compareDocumentPosition(const Node*, ShadowTreesTreatment = TreatShadowTreesAsDisconnected) const; 595 596 virtual Node* toNode() OVERRIDE FINAL; 597 598 virtual const AtomicString& interfaceName() const OVERRIDE; 599 virtual ExecutionContext* executionContext() const OVERRIDE FINAL; 600 601 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE; 602 virtual bool removeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE; 603 virtual void removeAllEventListeners() OVERRIDE; 604 void removeAllEventListenersRecursively(); 605 606 // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event 607 // has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch. 608 virtual void* preDispatchEventHandler(Event*) { return 0; } 609 virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { } 610 611 using EventTarget::dispatchEvent; 612 virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE; 613 614 void dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event>); 615 void dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator>); 616 617 virtual void handleLocalEvents(Event*); 618 619 void dispatchSubtreeModifiedEvent(); 620 bool dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent); 621 622 bool dispatchKeyEvent(const PlatformKeyboardEvent&); 623 bool dispatchWheelEvent(const PlatformWheelEvent&); 624 bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0); 625 bool dispatchGestureEvent(const PlatformGestureEvent&); 626 bool dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent>); 627 628 void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents); 629 630 void dispatchInputEvent(); 631 632 // Perform the default action for an event. 633 virtual void defaultEventHandler(Event*); 634 virtual void willCallDefaultEventHandler(const Event&); 635 636 virtual EventTargetData* eventTargetData() OVERRIDE; 637 virtual EventTargetData& ensureEventTargetData() OVERRIDE; 638 639 void getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName); 640 void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter); 641 void unregisterMutationObserver(MutationObserverRegistration*); 642 void registerTransientMutationObserver(MutationObserverRegistration*); 643 void unregisterTransientMutationObserver(MutationObserverRegistration*); 644 void notifyMutationObserversNodeWillDetach(); 645 646 unsigned connectedSubframeCount() const; 647 void incrementConnectedSubframeCount(unsigned amount = 1); 648 void decrementConnectedSubframeCount(unsigned amount = 1); 649 void updateAncestorConnectedSubframeCountForRemoval() const; 650 void updateAncestorConnectedSubframeCountForInsertion() const; 651 652 PassRefPtrWillBeRawPtr<StaticNodeList> getDestinationInsertionPoints(); 653 654 void setAlreadySpellChecked(bool flag) { setFlag(flag, AlreadySpellCheckedFlag); } 655 bool isAlreadySpellChecked() { return getFlag(AlreadySpellCheckedFlag); } 656 657 bool isFinishedParsingChildren() const { return getFlag(IsFinishedParsingChildrenFlag); } 658 659 virtual void trace(Visitor*) OVERRIDE; 660 661 unsigned lengthOfContents() const; 662 663 virtual v8::Handle<v8::Object> wrap(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE; 664 virtual v8::Handle<v8::Object> associateWithWrapper(const WrapperTypeInfo*, v8::Handle<v8::Object> wrapper, v8::Isolate*) OVERRIDE; 665 666 private: 667 enum NodeFlags { 668 HasRareDataFlag = 1, 669 670 // Node type flags. These never change once created. 671 IsTextFlag = 1 << 1, 672 IsContainerFlag = 1 << 2, 673 IsElementFlag = 1 << 3, 674 IsHTMLFlag = 1 << 4, 675 IsSVGFlag = 1 << 5, 676 IsDocumentFragmentFlag = 1 << 6, 677 IsInsertionPointFlag = 1 << 7, 678 679 // Changes based on if the element should be treated like a link, 680 // ex. When setting the href attribute on an <a>. 681 IsLinkFlag = 1 << 8, 682 683 // Changes based on :hover, :active and :focus state. 684 IsUserActionElementFlag = 1 << 9, 685 686 // Tree state flags. These change when the element is added/removed 687 // from a DOM tree. 688 InDocumentFlag = 1 << 10, 689 IsInShadowTreeFlag = 1 << 11, 690 691 // Set by the parser when the children are done parsing. 692 IsFinishedParsingChildrenFlag = 1 << 12, 693 694 // Flags related to recalcStyle. 695 SVGFilterNeedsLayerUpdateFlag = 1 << 13, 696 HasCustomStyleCallbacksFlag = 1 << 14, 697 ChildNeedsStyleInvalidationFlag = 1 << 15, 698 NeedsStyleInvalidationFlag = 1 << 16, 699 ChildNeedsDistributionRecalcFlag = 1 << 17, 700 ChildNeedsStyleRecalcFlag = 1 << 18, 701 StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1), 702 703 CustomElementFlag = 1 << 21, 704 CustomElementUpgradedFlag = 1 << 22, 705 706 HasNameOrIsEditingTextFlag = 1 << 23, 707 HasWeakReferencesFlag = 1 << 24, 708 V8CollectableDuringMinorGCFlag = 1 << 25, 709 HasSyntheticAttrChildNodesFlag = 1 << 26, 710 HasEventTargetDataFlag = 1 << 27, 711 AlreadySpellCheckedFlag = 1 << 28, 712 713 // HTML dir=auto. 714 SelfOrAncestorHasDirAutoFlag = 1 << 29, 715 716 DefaultNodeFlags = IsFinishedParsingChildrenFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange 717 }; 718 719 // 2 bits remaining. 720 721 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } 722 void setFlag(bool f, NodeFlags mask) { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } 723 void setFlag(NodeFlags mask) { m_nodeFlags |= mask; } 724 void clearFlag(NodeFlags mask) { m_nodeFlags &= ~mask; } 725 726 protected: 727 enum ConstructionType { 728 CreateOther = DefaultNodeFlags, 729 CreateText = DefaultNodeFlags | IsTextFlag, 730 CreateContainer = DefaultNodeFlags | IsContainerFlag, 731 CreateElement = CreateContainer | IsElementFlag, 732 CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag, 733 CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag, 734 CreateHTMLElement = CreateElement | IsHTMLFlag, 735 CreateSVGElement = CreateElement | IsSVGFlag, 736 CreateDocument = CreateContainer | InDocumentFlag, 737 CreateInsertionPoint = CreateHTMLElement | IsInsertionPointFlag, 738 CreateEditingText = CreateText | HasNameOrIsEditingTextFlag, 739 }; 740 741 Node(TreeScope*, ConstructionType); 742 743 virtual void didMoveToNewDocument(Document& oldDocument); 744 745 static void reattachWhitespaceSiblings(Text* start); 746 747 #if !ENABLE(OILPAN) 748 void willBeDeletedFromDocument(); 749 #endif 750 751 bool hasRareData() const { return getFlag(HasRareDataFlag); } 752 753 NodeRareData* rareData() const; 754 NodeRareData& ensureRareData(); 755 #if !ENABLE(OILPAN) 756 void clearRareData(); 757 758 void clearEventTargetData(); 759 #endif 760 761 void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); } 762 763 void setTreeScope(TreeScope* scope) { m_treeScope = scope; } 764 765 // isTreeScopeInitialized() can be false 766 // - in the destruction of Document or ShadowRoot where m_treeScope is set to null or 767 // - in the Node constructor called by these two classes where m_treeScope is set by TreeScope ctor. 768 bool isTreeScopeInitialized() const { return m_treeScope; } 769 770 void markAncestorsWithChildNeedsStyleRecalc(); 771 772 void setIsFinishedParsingChildren(bool value) { setFlag(value, IsFinishedParsingChildrenFlag); } 773 774 private: 775 friend class TreeShared<Node>; 776 friend class WeakNodeMap; 777 778 unsigned styledSubtreeSize() const; 779 780 #if !ENABLE(OILPAN) 781 void removedLastRef(); 782 #endif 783 bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); } 784 785 enum EditableLevel { Editable, RichlyEditable }; 786 bool hasEditableStyle(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const; 787 bool isEditableToAccessibility(EditableLevel) const; 788 789 bool isUserActionElementActive() const; 790 bool isUserActionElementInActiveChain() const; 791 bool isUserActionElementHovered() const; 792 bool isUserActionElementFocused() const; 793 794 void traceStyleChange(StyleChangeType); 795 void traceStyleChangeIfNeeded(StyleChangeType); 796 void setStyleChange(StyleChangeType); 797 798 virtual RenderStyle* nonRendererStyle() const { return 0; } 799 800 virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO); 801 802 void trackForDebugging(); 803 804 WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* mutationObserverRegistry(); 805 WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientMutationObserverRegistry(); 806 807 uint32_t m_nodeFlags; 808 RawPtrWillBeMember<ContainerNode> m_parentOrShadowHostNode; 809 RawPtrWillBeMember<TreeScope> m_treeScope; 810 RawPtrWillBeMember<Node> m_previous; 811 RawPtrWillBeMember<Node> m_next; 812 // When a node has rare data we move the renderer into the rare data. 813 union DataUnion { 814 DataUnion() : m_renderer(0) { } 815 RenderObject* m_renderer; 816 NodeRareDataBase* m_rareData; 817 } m_data; 818 }; 819 820 inline void Node::setParentOrShadowHostNode(ContainerNode* parent) 821 { 822 ASSERT(isMainThread()); 823 m_parentOrShadowHostNode = parent; 824 } 825 826 inline ContainerNode* Node::parentOrShadowHostNode() const 827 { 828 ASSERT(isMainThread()); 829 return m_parentOrShadowHostNode; 830 } 831 832 inline ContainerNode* Node::parentNode() const 833 { 834 return isShadowRoot() ? 0 : parentOrShadowHostNode(); 835 } 836 837 inline void Node::lazyReattachIfAttached() 838 { 839 if (styleChangeType() == NeedsReattachStyleChange) 840 return; 841 if (!inActiveDocument()) 842 return; 843 844 AttachContext context; 845 context.performingReattach = true; 846 847 detach(context); 848 markAncestorsWithChildNeedsStyleRecalc(); 849 } 850 851 inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change) 852 { 853 return change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc(); 854 } 855 856 inline bool isTreeScopeRoot(const Node* node) 857 { 858 return !node || node->isDocumentNode() || node->isShadowRoot(); 859 } 860 861 inline bool isTreeScopeRoot(const Node& node) 862 { 863 return node.isDocumentNode() || node.isShadowRoot(); 864 } 865 866 // Allow equality comparisons of Nodes by reference or pointer, interchangeably. 867 DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(Node) 868 869 870 #define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \ 871 template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \ 872 DEFINE_TYPE_CASTS(thisType, Node, node, node->predicate, node.predicate) 873 874 // This requires isClassName(const Node&). 875 #define DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType) \ 876 template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \ 877 DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node)) 878 879 #define DECLARE_NODE_FACTORY(T) \ 880 static PassRefPtrWillBeRawPtr<T> create(Document&) 881 #define DEFINE_NODE_FACTORY(T) \ 882 PassRefPtrWillBeRawPtr<T> T::create(Document& document) \ 883 { \ 884 return adoptRefWillBeNoop(new T(document)); \ 885 } 886 887 } // namespace blink 888 889 #ifndef NDEBUG 890 // Outside the WebCore namespace for ease of invocation from gdb. 891 void showNode(const blink::Node*); 892 void showTree(const blink::Node*); 893 void showNodePath(const blink::Node*); 894 #endif 895 896 #endif // Node_h 897