1 /* 2 * This file is part of the DOM implementation for KDE. 3 * 4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 2001 Dirk Mueller (mueller@kde.org) 7 * (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Library General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Library General Public License for more details. 18 * 19 * You should have received a copy of the GNU Library General Public License 20 * along with this library; see the file COPYING.LIB. If not, write to 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 */ 25 #ifndef _DOM_NodeImpl_h_ 26 #define _DOM_NodeImpl_h_ 27 28 #include "dom/dom_misc.h" 29 #include "dom/dom_string.h" 30 #include "dom/dom_node.h" 31 #include "misc/helper.h" 32 #include "misc/shared.h" 33 #include "misc/idstring.h" 34 #include "wtf/PassRefPtr.h" 35 #include "misc/htmlnames.h" 36 #include "dom/QualifiedName.h" 37 #include "xml/dom2_eventsimpl.h" 38 39 template <class type> class QList; 40 class KHTMLView; 41 class QRect; 42 class QMouseEvent; 43 class QKeyEvent; 44 45 namespace khtml 46 { 47 class RenderStyle; 48 class RenderObject; 49 class RenderArena; 50 class RenderPosition; 51 } 52 53 namespace DOM 54 { 55 56 class NodeListImpl; 57 class NamedNodeMapImpl; 58 class DocumentImpl; 59 class ElementImpl; 60 class RegisteredEventListener; 61 class EventImpl; 62 class Selection; 63 64 class NodeImpl : public EventTargetImpl 65 { 66 friend class DocumentImpl; 67 public: 68 NodeImpl(DocumentImpl *doc); 69 virtual ~NodeImpl(); 70 71 //stuff for WebCore DOM & SVG hasTagName(const QualifiedName &)72 virtual bool hasTagName(const QualifiedName & /*name*/) const 73 { 74 return false; 75 } 76 77 // EventTarget eventTargetType()78 Type eventTargetType() const override 79 { 80 return DOM_NODE; 81 } 82 // covariant override parent()83 NodeImpl *parent() const 84 { 85 return parentNode(); 86 } 87 88 // DOM methods & attributes for Node 89 virtual DOMString nodeName() const; 90 virtual DOMString nodeValue() const; 91 virtual void setNodeValue(const DOMString &_nodeValue, int &exceptioncode); 92 virtual unsigned short nodeType() const; parentNode()93 NodeImpl *parentNode() const 94 { 95 return static_cast<NodeImpl *>(m_parent); 96 } previousSibling()97 NodeImpl *previousSibling() const 98 { 99 return m_previous; 100 } nextSibling()101 NodeImpl *nextSibling() const 102 { 103 return m_next; 104 } 105 virtual WTF::PassRefPtr<NodeListImpl> childNodes(); 106 virtual NodeImpl *firstChild() const; 107 virtual NodeImpl *lastChild() const; 108 109 virtual bool hasAttributes() const; 110 //OwnerDocument as specified by the DOM. Do not use for other purposes, it's weird! 111 DocumentImpl *ownerDocument() const; 112 NodeListImpl *getElementsByTagName(const DOMString &tagName); 113 NodeListImpl *getElementsByTagNameNS(const DOMString &namespaceURI, const DOMString &localName); 114 115 // HTML 5 116 NodeListImpl *getElementsByClassName(const DOMString &name); 117 118 // DOM3. See the wrapper (DOM::Node for the constants used in the return value 119 unsigned compareDocumentPosition(const DOM::NodeImpl *other); 120 121 // WA Selector API L1. It's specified only for some types, but we provide it here 122 WTF::PassRefPtr<DOM::ElementImpl> querySelector(const DOM::DOMString &query, int &ec); 123 WTF::PassRefPtr<DOM::NodeListImpl> querySelectorAll(const DOM::DOMString &query, int &ec); 124 125 // insertBefore, replaceChild and appendChild also close newChild 126 // unlike the speed optimized addChild (which is used by the parser) 127 virtual NodeImpl *insertBefore(NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode); 128 129 /* These two methods may delete the old node, so make sure to reference it if you need it */ 130 virtual void replaceChild(NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode); 131 virtual void removeChild(NodeImpl *oldChild, int &exceptioncode); 132 virtual NodeImpl *appendChild(NodeImpl *newChild, int &exceptioncode); 133 virtual void remove(int &exceptioncode); 134 virtual bool hasChildNodes() const; 135 virtual WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) = 0; 136 virtual DOMString localName() const; 137 virtual DOMString prefix() const; 138 virtual DOMString namespaceURI() const; 139 virtual void setPrefix(const DOMString &_prefix, int &exceptioncode); 140 void normalize(); 141 static bool isSupported(const DOMString &feature, const DOMString &version); 142 143 // Other methods (not part of DOM) isElementNode()144 virtual bool isElementNode() const 145 { 146 return false; 147 } isHTMLElement()148 virtual bool isHTMLElement() const 149 { 150 return false; 151 } isAttributeNode()152 virtual bool isAttributeNode() const 153 { 154 return false; 155 } isTextNode()156 virtual bool isTextNode() const 157 { 158 return false; 159 } isDocumentNode()160 virtual bool isDocumentNode() const 161 { 162 return false; 163 } isXMLElementNode()164 virtual bool isXMLElementNode() const 165 { 166 return false; 167 } isGenericFormElement()168 virtual bool isGenericFormElement() const 169 { 170 return false; 171 } containsOnlyWhitespace()172 virtual bool containsOnlyWhitespace() const 173 { 174 return false; 175 } 176 bool isBlockFlow() const; 177 178 // methods for WebCore api compat (SVG) isSVGElement()179 virtual bool isSVGElement() const 180 { 181 return false; 182 } isShadowNode()183 virtual bool isShadowNode() const 184 { 185 return false; 186 } shadowParentNode()187 virtual NodeImpl *shadowParentNode() 188 { 189 return nullptr; 190 } 191 192 DOMString textContent() const; 193 void setTextContent(const DOMString &text, int &ec); 194 195 // helper functions not being part of the DOM 196 // Attention: they assume that the caller did the consistency checking! setPreviousSibling(NodeImpl * previous)197 void setPreviousSibling(NodeImpl *previous) 198 { 199 m_previous = previous; 200 } setNextSibling(NodeImpl * next)201 void setNextSibling(NodeImpl *next) 202 { 203 m_next = next; 204 } 205 206 virtual void setFirstChild(NodeImpl *child); 207 virtual void setLastChild(NodeImpl *child); 208 209 /** (Not part of the official DOM) 210 * Returns the next leaf node. 211 * 212 * Using this function delivers leaf nodes as if the whole DOM tree 213 * were a linear chain of its leaf nodes. 214 * @return next leaf node or 0 if there are no more. 215 */ 216 NodeImpl *nextLeafNode() const; 217 218 /** (Not part of the official DOM) 219 * Returns the previous leaf node. 220 * 221 * Using this function delivers leaf nodes as if the whole DOM tree 222 * were a linear chain of its leaf nodes. 223 * @return previous leaf node or 0 if there are no more. 224 */ 225 NodeImpl *previousLeafNode() const; 226 227 bool isEditableBlock() const; 228 ElementImpl *enclosingBlockFlowElement() const; 229 ElementImpl *rootEditableElement() const; 230 231 bool inSameRootEditableElement(NodeImpl *); 232 bool inSameContainingBlockFlowElement(NodeImpl *); 233 234 khtml::RenderPosition positionForCoordinates(int x, int y) const; 235 bool isPointInsideSelection(int x, int y, const Selection &) const; 236 237 // used by the parser. Doesn't do as many error checkings as 238 // appendChild(), and returns the node into which will be parsed next. 239 virtual NodeImpl *addChild(NodeImpl *newChild); 240 241 typedef quint32 Id; 242 // id() is used to easily and exactly identify a node. It 243 // is optimized for quick comparison and low memory consumption. 244 // its value depends on the owner document of the node and is 245 // categorized in the following way: 246 // 1..ID_LAST_TAG: the node inherits HTMLElementImpl and is 247 // part of the HTML namespace. 248 // The HTML namespace is either the global 249 // one (no namespace) or the XHTML namespace 250 // depending on the owner document's doctype 251 // ID_LAST_TAG+1..0xffff: non-HTML elements in the global namespace 252 // others non-HTML elements in a namespace. 253 // the upper 16 bit identify the namespace 254 // the lower 16 bit identify the local part of the 255 // qualified element name. id()256 virtual Id id() const 257 { 258 return 0; 259 } 260 261 enum MouseEventType { 262 MousePress, 263 MouseRelease, 264 MouseClick, 265 MouseDblClick, 266 MouseMove, 267 MouseWheel 268 }; 269 270 struct MouseEvent { 271 MouseEvent(int _button, MouseEventType _type, 272 const DOMString &_url = DOMString(), const DOMString &_target = DOMString(), 273 NodeImpl *_innerNode = nullptr, NodeImpl *_innerNonSharedNode = nullptr) 274 { 275 button = _button; type = _type; 276 url = _url; target = _target; 277 innerNode = _innerNode; 278 innerNonSharedNode = _innerNonSharedNode; 279 } 280 281 int button; 282 MouseEventType type; 283 DOMString url; // url under mouse or empty 284 DOMString target; 285 Node innerNode; 286 Node innerNonSharedNode; 287 }; 288 289 // for LINK and STYLE 290 // will increase/decrease the document's pending sheet count if appropriate checkAddPendingSheet()291 virtual bool checkAddPendingSheet() 292 { 293 return true; 294 } checkRemovePendingSheet()295 virtual bool checkRemovePendingSheet() 296 { 297 return true; 298 } 299 hasID()300 bool hasID() const 301 { 302 return m_hasId; 303 } hasClass()304 bool hasClass() const 305 { 306 return m_hasClass; 307 } hasCombinedStyle()308 bool hasCombinedStyle() const 309 { 310 return m_hasCombinedStyle; 311 } active()312 bool active() const 313 { 314 return m_active; 315 } focused()316 bool focused() const 317 { 318 return m_focused; 319 } hovered()320 bool hovered() const 321 { 322 return m_hovered; 323 } attached()324 bool attached() const 325 { 326 return m_attached; 327 } closed()328 bool closed() const 329 { 330 return m_closed; 331 } changed()332 bool changed() const 333 { 334 return m_changed; 335 } hasChangedChild()336 bool hasChangedChild() const 337 { 338 return m_hasChangedChild; 339 } hasAnchor()340 bool hasAnchor() const 341 { 342 return m_hasAnchor; 343 } inDocument()344 bool inDocument() const 345 { 346 return m_inDocument; 347 } implicitNode()348 bool implicitNode() const 349 { 350 return m_implicit; 351 } htmlCompat()352 bool htmlCompat() const 353 { 354 return m_htmlCompat; 355 } 356 void setHasID(bool b = true) 357 { 358 m_hasId = b; 359 } 360 void setHasClass(bool b = true) 361 { 362 m_hasClass = b; 363 } 364 void setHasChangedChild(bool b = true) 365 { 366 m_hasChangedChild = b; 367 } 368 void setInDocument(bool b = true) 369 { 370 m_inDocument = b; 371 } setHTMLCompat(bool b)372 void setHTMLCompat(bool b) 373 { 374 m_htmlCompat = b; 375 } hasHoverDependency()376 bool hasHoverDependency() 377 { 378 return m_hasHoverDependency; 379 } 380 void setHasHoverDependency(bool b = true) 381 { 382 m_hasHoverDependency = b; 383 } 384 void setNeedsStyleAttributeUpdate(bool b = true) 385 { 386 m_needsStyleAttributeUpdate = b; 387 } 388 virtual void setFocus(bool b = true) 389 { 390 m_focused = b; 391 } 392 virtual void setActive(bool b = true) 393 { 394 m_active = b; 395 } 396 virtual void setHovered(bool b = true) 397 { 398 m_hovered = b; 399 } 400 virtual void setChanged(bool b = true); 401 // for WebCore API compatibility 402 void setAttached(bool b = true) 403 { 404 m_attached = b; 405 } 406 407 // for descending restyle when ID or CLASS changes changedAscendentAttribute()408 bool changedAscendentAttribute() const 409 { 410 return m_changedAscendentAttribute; 411 } setChangedAscendentAttribute(bool b)412 void setChangedAscendentAttribute(bool b) 413 { 414 m_changedAscendentAttribute = b; 415 } 416 tabIndex()417 virtual short tabIndex() const 418 { 419 return 0; 420 } 421 422 enum FocusType { 423 FT_Any, 424 FT_Mouse, 425 FT_Tab 426 }; 427 428 // Elements that are focusable by default should override this. 429 // Warning: if they're in a language that supports tabIndex (e.g. HTML), 430 // they must call back to the base class whenever hasTabIndex() is set. isFocusableImpl(FocusType)431 virtual bool isFocusableImpl(FocusType) const 432 { 433 return false; 434 } isFocusable()435 bool isFocusable() const 436 { 437 return isFocusableImpl(FT_Any); 438 } isMouseFocusable()439 bool isMouseFocusable() const 440 { 441 return isFocusableImpl(FT_Mouse); 442 } isTabFocusable()443 bool isTabFocusable() const 444 { 445 return isFocusableImpl(FT_Tab); 446 } 447 448 virtual bool isInline() const; 449 450 virtual bool isContentEditable() const; 451 virtual void getCaret(int offset, bool override, int &_x, int &_y, int &width, int &height); 452 virtual QRect getRect() const; 453 454 enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force }; 455 virtual void recalcStyle(StyleChange = NoChange) {} 456 static StyleChange diff(khtml::RenderStyle *s1, khtml::RenderStyle *s2); 457 static bool pseudoDiff(khtml::RenderStyle *s1, khtml::RenderStyle *s2, unsigned int pid); 458 459 virtual bool affectedByNoInherit() const; 460 461 unsigned long nodeIndex() const; 462 // Returns the document that this node is associated with. This is guaranteed to always be non-null, as opposed to 463 // DOM's ownerDocument() which is null for Document nodes (and sometimes DocumentType nodes). document()464 DocumentImpl *document() const 465 { 466 return m_document.get(); 467 } 468 void setDocument(DocumentImpl *doc); 469 470 DocumentImpl *eventTargetDocument() override; 471 472 void dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false); 473 474 // takes care of bubbling and the like. The target is generally 'this', 475 // unless the event specifies something special like Window as the target, 476 // in which case that's used for dispatch. 477 void dispatchGenericEvent(EventImpl *evt, int &exceptioncode); 478 479 // return true if event not prevented 480 bool dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg); 481 482 // Window events are special in that they're only dispatched on Window, and not 483 // the current node. 484 void dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg); 485 void dispatchWindowEvent(EventImpl *evt); 486 487 void dispatchMouseEvent(QMouseEvent *e, int overrideId = 0, int overrideDetail = 0); 488 void dispatchUIEvent(int _id, int detail = 0); 489 void dispatchSubtreeModifiedEvent(); 490 // return true if defaultPrevented (i.e. event should be swallowed) 491 // this matches the logic in KHTMLView. 492 bool dispatchKeyEvent(QKeyEvent *key, bool keypress); 493 494 virtual bool isReadOnly(); childTypeAllowed(unsigned short)495 virtual bool childTypeAllowed(unsigned short /*type*/) 496 { 497 return false; 498 } 499 virtual unsigned long childNodeCount(); 500 virtual NodeImpl *childNode(unsigned long index); 501 502 /** 503 * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that 504 * the tags appear in the source file. 505 * 506 * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to 507 * restrict traversal to a particular sub-tree. 508 * 509 * @return The next node, in document order 510 * 511 * see traversePreviousNode() 512 */ 513 NodeImpl *traverseNextNode(NodeImpl *stayWithin = nullptr) const; 514 515 /** 516 * Does a reverse pre-order traversal to find the node that comes before the current one in document order 517 * 518 * see traverseNextNode() 519 */ 520 NodeImpl *traversePreviousNode() const; 521 docPtr()522 DocumentImpl *docPtr() const 523 { 524 return m_document.get(); 525 } 526 527 NodeImpl *previousEditable() const; 528 NodeImpl *nextEditable() const; 529 //bool isEditable() const; 530 renderer()531 khtml::RenderObject *renderer() const 532 { 533 return m_render; 534 } 535 khtml::RenderObject *nextRenderer(); 536 khtml::RenderObject *previousRenderer(); setRenderer(khtml::RenderObject * renderer)537 void setRenderer(khtml::RenderObject *renderer) 538 { 539 m_render = renderer; 540 } 541 542 void checkSetPrefix(const DOMString &_prefix, int &exceptioncode); 543 void checkAddChild(NodeImpl *newChild, int &exceptioncode); 544 bool isAncestor(NodeImpl *other) const; 545 virtual bool childAllowed(NodeImpl *newChild); 546 547 // Used to determine whether range offsets use characters or node indices. offsetInCharacters()548 virtual bool offsetInCharacters() const 549 { 550 return false; 551 } 552 // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of 553 // css-transform:capitalize breaking up precomposed characters and ligatures. maxCharacterOffset()554 virtual int maxCharacterOffset() const 555 { 556 return 0; 557 } 558 559 virtual long maxOffset() const; 560 virtual long caretMinOffset() const; 561 virtual long caretMaxOffset() const; 562 virtual unsigned long caretMaxRenderedOffset() const; 563 564 // ----------------------------------------------------------------------------- 565 // Integration with rendering tree 566 567 /** 568 * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an 569 * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This 570 * makes the node visible in the KHTMLView. 571 */ 572 virtual void attach(); 573 574 /** 575 * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove 576 * the node's rendering object from the rendering tree and delete it. 577 */ 578 virtual void detach(); 579 580 /** 581 * Notifies the node that no more children will be added during parsing. 582 * After a node has been closed all changes must go through the DOM interface. 583 */ 584 virtual void close(); 585 structureChanged()586 virtual void structureChanged() {} backwardsStructureChanged()587 virtual void backwardsStructureChanged() {} 588 589 void createRendererIfNeeded(); 590 virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent); 591 virtual bool rendererIsNeeded(khtml::RenderStyle *); 592 virtual khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *); 593 594 virtual khtml::RenderStyle *computedStyle(); 595 596 // ----------------------------------------------------------------------------- 597 // Methods for maintaining the state of the element between history navigation 598 599 /** 600 * Indicates whether or not this type of node maintains its state. If so, the state of the node will be stored when 601 * the user goes to a different page using the state() method, and restored using the restoreState() method if the 602 * user returns (e.g. using the back button). This is used to ensure that user-changeable elements such as form 603 * controls maintain their contents when the user returns to a previous page in the history. 604 */ 605 virtual bool maintainsState(); 606 607 /** 608 * Returns the state of this node represented as a string. This string will be passed to restoreState() if the user 609 * returns to the page. 610 * 611 * @return State information about the node represented as a string 612 */ 613 virtual QString state(); 614 615 /** 616 * Sets the state of the element based on a string previosuly returned by state(). This is used to initialize form 617 * controls with their old values when the user returns to the page in their history. 618 * 619 * @param state A string representation of the node's previously-stored state 620 */ 621 virtual void restoreState(const QString &state); 622 623 // ----------------------------------------------------------------------------- 624 // Notification of document structure changes 625 626 /** 627 * Notifies the node that it has been inserted into the document. This is called during document parsing, and also 628 * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only 629 * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of 630 * the node. The call happens _after_ the node has been added to the tree. 631 * 632 * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event 633 * dispatching. 634 */ 635 virtual void insertedIntoDocument(); 636 637 /** 638 * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor 639 * node. 640 * 641 * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event 642 * dispatching, and is called _after_ the node is removed from the tree. 643 */ 644 virtual void removedFromDocument(); 645 646 /** 647 * Notifies the node that its list of children have changed (either by adding or removing child nodes), or a child 648 * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value. 649 */ 650 virtual void childrenChanged(); 651 652 virtual DOMString toString() const = 0; 653 /** 654 * Sometimes we need to get the string between two points on the DOM graph. Use this function to do this. 655 * For example, when the user copies some selected text to the clipboard as html. 656 * @param selectionStart Where to start the selection. If selectionStart != this, it is assumed we are after the start point 657 * @param selectionEnd Where to end the selection. If selectionEnd != this, it is assumed we are before the end point (unless found is true) 658 * @param startOffset Number of characters into the text in selectionStart that the start of the selection is. 659 * @param endOffset Number of characters into the text in selectionEnd that the end of the selection is. 660 * @param found When this is set to true, don't print anymore but closing tags. 661 * @return An html formatted string for this node and its children between the selectionStart and selectionEnd. 662 */ selectionToString(NodeImpl * selectionStart,NodeImpl * selectionEnd,int startOffset,int endOffset,bool & found)663 virtual DOMString selectionToString(NodeImpl *selectionStart, 664 NodeImpl *selectionEnd, 665 int startOffset, 666 int endOffset, 667 bool &found) const 668 { 669 Q_UNUSED(selectionStart); 670 Q_UNUSED(selectionEnd); 671 Q_UNUSED(startOffset); 672 Q_UNUSED(endOffset); 673 Q_UNUSED(found); 674 return toString(); 675 } 676 677 // FOR SVG Events support (WebCore API compatibility) localEventListeners()678 QList<RegisteredEventListener> *localEventListeners() 679 { 680 return listenerList().listeners; 681 } 682 683 DOMString lookupNamespaceURI(const DOMString &prefix); 684 685 private: // members 686 khtml::DocPtr<DocumentImpl> m_document; 687 NodeImpl *m_previous; 688 NodeImpl *m_next; 689 690 NodeImpl *findNextElementAncestor(NodeImpl *node); 691 protected: 692 khtml::RenderObject *m_render; 693 694 bool m_hasId : 1; 695 bool m_attached : 1; 696 bool m_closed : 1; 697 bool m_changed : 1; 698 bool m_hasChangedChild : 1; 699 bool m_changedAscendentAttribute : 1; 700 bool m_inDocument : 1; 701 bool m_hasAnchor : 1; 702 703 bool m_hovered : 1; 704 bool m_focused : 1; 705 bool m_active : 1; 706 bool m_implicit : 1; // implicitely generated by the parser 707 bool m_htmlCompat : 1; // true if element was created in HTML compat mode 708 bool m_hasClass : 1; // true if element has a class property, as relevant to CSS 709 bool m_hasCombinedStyle : 1; // true if element has inline styles and presentational styles 710 bool m_hasHoverDependency : 1; // true if element has hover dependency on itself 711 712 bool m_elementHasRareData : 1; 713 mutable bool m_needsStyleAttributeUpdate : 1; // true if |style| attribute is out of sync (i.e. CSSOM modified our inline styles) 714 715 // 14 bits left 716 }; 717 718 // this is the full Node Implementation with parents and children. 719 class NodeBaseImpl : public NodeImpl 720 { 721 public: NodeBaseImpl(DocumentImpl * doc)722 NodeBaseImpl(DocumentImpl *doc) 723 : NodeImpl(doc), _first(nullptr), _last(nullptr) {} 724 virtual ~NodeBaseImpl(); 725 726 // DOM methods overridden from parent classes 727 NodeImpl *firstChild() const override; 728 NodeImpl *lastChild() const override; 729 NodeImpl *insertBefore(NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode) override; 730 void replaceChild(NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode) override; 731 void removeChild(NodeImpl *oldChild, int &exceptioncode) override; 732 NodeImpl *appendChild(NodeImpl *newChild, int &exceptioncode) override; 733 bool hasChildNodes() const override; 734 735 // Other methods (not part of DOM) 736 virtual void removeChildren(); 737 void cloneChildNodes(NodeImpl *clone); 738 739 void setFirstChild(NodeImpl *child) override; 740 void setLastChild(NodeImpl *child) override; 741 NodeImpl *addChild(NodeImpl *newChild) override; 742 void attach() override; 743 void detach() override; 744 745 bool getUpperLeftCorner(int &xPos, int &yPos) const; 746 bool getLowerRightCorner(int &xPos, int &yPos) const; 747 748 void setFocus(bool = true) override; 749 void setActive(bool = true) override; 750 void setHovered(bool = true) override; 751 unsigned long childNodeCount() override; 752 NodeImpl *childNode(unsigned long index) override; 753 754 protected: 755 NodeImpl *_first; 756 NodeImpl *_last; 757 758 // helper functions for inserting children: 759 760 // ### this should vanish. do it in dom/ ! 761 // check for same source document: 762 bool checkSameDocument(NodeImpl *newchild, int &exceptioncode); 763 // check for being child: 764 bool checkIsChild(NodeImpl *oldchild, int &exceptioncode); 765 // ### 766 767 // find out if a node is allowed to be our child 768 void dispatchChildInsertedEvents(NodeImpl *child, int &exceptioncode); 769 void dispatchChildRemovalEvents(NodeImpl *child, int &exceptioncode); 770 }; 771 772 // Generic NamedNodeMap interface 773 // Other classes implement this for more specific situations e.g. attributes 774 // of an element 775 class NamedNodeMapImpl : public khtml::Shared<NamedNodeMapImpl> 776 { 777 public: 778 NamedNodeMapImpl(); 779 virtual ~NamedNodeMapImpl(); 780 781 // DOM methods & attributes for NamedNodeMap 782 virtual NodeImpl *getNamedItem(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) = 0; 783 virtual Node removeNamedItem(NodeImpl::Id id, const PrefixName &prefix, bool nsAware, int &exceptioncode) = 0; 784 virtual Node setNamedItem(NodeImpl *arg, const PrefixName &prefix, bool nsAware, int &exceptioncode) = 0; 785 786 //The DOM-style wrappers 787 NodeImpl *getNamedItem(const DOMString &name); 788 Node setNamedItem(const Node &arg, int &exceptioncode); 789 Node removeNamedItem(const DOMString &name, int &exceptioncode); 790 Node getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName); 791 Node setNamedItemNS(const Node &arg, int &exceptioncode); 792 Node removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName, int &exceptioncode); 793 794 virtual NodeImpl *item(unsigned index) = 0; 795 virtual unsigned length() const = 0; 796 isReadOnly()797 virtual bool isReadOnly() 798 { 799 return false; 800 } htmlCompat()801 virtual bool htmlCompat() 802 { 803 return false; 804 } 805 }; 806 807 // Generic read-only NamedNodeMap implementation 808 // Used for e.g. entities and notations in DocumentType. 809 // You can add nodes using addNode 810 class GenericRONamedNodeMapImpl : public NamedNodeMapImpl 811 { 812 public: 813 GenericRONamedNodeMapImpl(DocumentImpl *doc); 814 virtual ~GenericRONamedNodeMapImpl(); 815 816 // DOM methods & attributes for NamedNodeMap 817 818 NodeImpl *getNamedItem(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) override; 819 Node removeNamedItem(NodeImpl::Id id, const PrefixName &prefix, bool nsAware, int &exceptioncode) override; 820 Node setNamedItem(NodeImpl *arg, const PrefixName &prefix, bool nsAware, int &exceptioncode) override; 821 822 NodeImpl *item(unsigned index) override; 823 unsigned length() const override; 824 isReadOnly()825 bool isReadOnly() override 826 { 827 return true; 828 } 829 830 void addNode(NodeImpl *n); 831 832 protected: 833 DocumentImpl *m_doc; 834 QList<NodeImpl *> *m_contents; 835 }; 836 837 } //namespace 838 #endif 839