File indexing completed on 2024-04-28 15:24:51

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
0005  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
0006  *           (C) 2001 Dirk Mueller (mueller@kde.org)
0007  *           (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
0008  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Library General Public
0011  * License as published by the Free Software Foundation; either
0012  * version 2 of the License, or (at your option) any later version.
0013  *
0014  * This library is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * Library General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Library General Public License
0020  * along with this library; see the file COPYING.LIB.  If not, write to
0021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022  * Boston, MA 02110-1301, USA.
0023  *
0024  */
0025 #ifndef _DOM_NodeImpl_h_
0026 #define _DOM_NodeImpl_h_
0027 
0028 #include "dom/dom_misc.h"
0029 #include "dom/dom_string.h"
0030 #include "dom/dom_node.h"
0031 #include "misc/helper.h"
0032 #include "misc/shared.h"
0033 #include "misc/idstring.h"
0034 #include "wtf/PassRefPtr.h"
0035 #include "misc/htmlnames.h"
0036 #include "dom/QualifiedName.h"
0037 #include "xml/dom2_eventsimpl.h"
0038 
0039 template <class type> class QList;
0040 class KHTMLView;
0041 class QRect;
0042 class QMouseEvent;
0043 class QKeyEvent;
0044 
0045 namespace khtml
0046 {
0047 class RenderStyle;
0048 class RenderObject;
0049 class RenderArena;
0050 class RenderPosition;
0051 }
0052 
0053 namespace DOM
0054 {
0055 
0056 class NodeListImpl;
0057 class NamedNodeMapImpl;
0058 class DocumentImpl;
0059 class ElementImpl;
0060 class RegisteredEventListener;
0061 class EventImpl;
0062 class Selection;
0063 
0064 class NodeImpl : public EventTargetImpl
0065 {
0066     friend class DocumentImpl;
0067 public:
0068     NodeImpl(DocumentImpl *doc);
0069     virtual ~NodeImpl();
0070 
0071     //stuff for WebCore DOM & SVG
0072     virtual bool hasTagName(const QualifiedName & /*name*/) const
0073     {
0074         return false;
0075     }
0076 
0077     // EventTarget
0078     Type eventTargetType() const override
0079     {
0080         return DOM_NODE;
0081     }
0082     // covariant override
0083     NodeImpl *parent() const
0084     {
0085         return parentNode();
0086     }
0087 
0088     // DOM methods & attributes for Node
0089     virtual DOMString nodeName() const;
0090     virtual DOMString nodeValue() const;
0091     virtual void setNodeValue(const DOMString &_nodeValue, int &exceptioncode);
0092     virtual unsigned short nodeType() const;
0093     NodeImpl *parentNode() const
0094     {
0095         return static_cast<NodeImpl *>(m_parent);
0096     }
0097     NodeImpl *previousSibling() const
0098     {
0099         return m_previous;
0100     }
0101     NodeImpl *nextSibling() const
0102     {
0103         return m_next;
0104     }
0105     virtual WTF::PassRefPtr<NodeListImpl> childNodes();
0106     virtual NodeImpl *firstChild() const;
0107     virtual NodeImpl *lastChild() const;
0108 
0109     virtual bool hasAttributes() const;
0110     //OwnerDocument as specified by the DOM. Do not use for other purposes, it's weird!
0111     DocumentImpl *ownerDocument() const;
0112     NodeListImpl *getElementsByTagName(const DOMString &tagName);
0113     NodeListImpl *getElementsByTagNameNS(const DOMString &namespaceURI, const DOMString &localName);
0114 
0115     // HTML 5
0116     NodeListImpl *getElementsByClassName(const DOMString &name);
0117 
0118     // DOM3. See the wrapper (DOM::Node for the constants used in the return value
0119     unsigned compareDocumentPosition(const DOM::NodeImpl *other);
0120 
0121     // WA Selector API L1. It's specified only for some types, but we provide it here
0122     WTF::PassRefPtr<DOM::ElementImpl>  querySelector(const DOM::DOMString &query, int &ec);
0123     WTF::PassRefPtr<DOM::NodeListImpl> querySelectorAll(const DOM::DOMString &query, int &ec);
0124 
0125     // insertBefore, replaceChild and appendChild also close newChild
0126     // unlike the speed optimized addChild (which is used by the parser)
0127     virtual NodeImpl *insertBefore(NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode);
0128 
0129     /* These two methods may delete the old node, so make sure to reference it if you need it */
0130     virtual void replaceChild(NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode);
0131     virtual void removeChild(NodeImpl *oldChild, int &exceptioncode);
0132     virtual NodeImpl *appendChild(NodeImpl *newChild, int &exceptioncode);
0133     virtual void remove(int &exceptioncode);
0134     virtual bool hasChildNodes() const;
0135     virtual WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) = 0;
0136     virtual DOMString localName() const;
0137     virtual DOMString prefix() const;
0138     virtual DOMString namespaceURI() const;
0139     virtual void setPrefix(const DOMString &_prefix, int &exceptioncode);
0140     void normalize();
0141     static bool isSupported(const DOMString &feature, const DOMString &version);
0142 
0143     // Other methods (not part of DOM)
0144     virtual bool isElementNode() const
0145     {
0146         return false;
0147     }
0148     virtual bool isHTMLElement() const
0149     {
0150         return false;
0151     }
0152     virtual bool isAttributeNode() const
0153     {
0154         return false;
0155     }
0156     virtual bool isTextNode() const
0157     {
0158         return false;
0159     }
0160     virtual bool isDocumentNode() const
0161     {
0162         return false;
0163     }
0164     virtual bool isXMLElementNode() const
0165     {
0166         return false;
0167     }
0168     virtual bool isGenericFormElement() const
0169     {
0170         return false;
0171     }
0172     virtual bool containsOnlyWhitespace() const
0173     {
0174         return false;
0175     }
0176     bool isBlockFlow() const;
0177 
0178     // methods for WebCore api compat (SVG)
0179     virtual bool isSVGElement() const
0180     {
0181         return false;
0182     }
0183     virtual bool isShadowNode() const
0184     {
0185         return false;
0186     }
0187     virtual NodeImpl *shadowParentNode()
0188     {
0189         return nullptr;
0190     }
0191 
0192     DOMString textContent() const;
0193     void setTextContent(const DOMString &text, int &ec);
0194 
0195     // helper functions not being part of the DOM
0196     // Attention: they assume that the caller did the consistency checking!
0197     void setPreviousSibling(NodeImpl *previous)
0198     {
0199         m_previous = previous;
0200     }
0201     void setNextSibling(NodeImpl *next)
0202     {
0203         m_next = next;
0204     }
0205 
0206     virtual void setFirstChild(NodeImpl *child);
0207     virtual void setLastChild(NodeImpl *child);
0208 
0209     /** (Not part of the official DOM)
0210      * Returns the next leaf node.
0211      *
0212      * Using this function delivers leaf nodes as if the whole DOM tree
0213      * were a linear chain of its leaf nodes.
0214      * @return next leaf node or 0 if there are no more.
0215      */
0216     NodeImpl *nextLeafNode() const;
0217 
0218     /** (Not part of the official DOM)
0219      * Returns the previous leaf node.
0220      *
0221      * Using this function delivers leaf nodes as if the whole DOM tree
0222      * were a linear chain of its leaf nodes.
0223      * @return previous leaf node or 0 if there are no more.
0224      */
0225     NodeImpl *previousLeafNode() const;
0226 
0227     bool isEditableBlock() const;
0228     ElementImpl *enclosingBlockFlowElement() const;
0229     ElementImpl *rootEditableElement() const;
0230 
0231     bool inSameRootEditableElement(NodeImpl *);
0232     bool inSameContainingBlockFlowElement(NodeImpl *);
0233 
0234     khtml::RenderPosition positionForCoordinates(int x, int y) const;
0235     bool isPointInsideSelection(int x, int y, const Selection &) const;
0236 
0237     // used by the parser. Doesn't do as many error checkings as
0238     // appendChild(), and returns the node into which will be parsed next.
0239     virtual NodeImpl *addChild(NodeImpl *newChild);
0240 
0241     typedef quint32 Id;
0242     // id() is used to easily and exactly identify a node. It
0243     // is optimized for quick comparison and low memory consumption.
0244     // its value depends on the owner document of the node and is
0245     // categorized in the following way:
0246     // 1..ID_LAST_TAG: the node inherits HTMLElementImpl and is
0247     //                 part of the HTML namespace.
0248     //                 The HTML namespace is either the global
0249     //                 one (no namespace) or the XHTML namespace
0250     //                 depending on the owner document's doctype
0251     // ID_LAST_TAG+1..0xffff: non-HTML elements in the global namespace
0252     // others       non-HTML elements in a namespace.
0253     //                 the upper 16 bit identify the namespace
0254     //                 the lower 16 bit identify the local part of the
0255     //                 qualified element name.
0256     virtual Id id() const
0257     {
0258         return 0;
0259     }
0260 
0261     enum MouseEventType {
0262         MousePress,
0263         MouseRelease,
0264         MouseClick,
0265         MouseDblClick,
0266         MouseMove,
0267         MouseWheel
0268     };
0269 
0270     struct MouseEvent {
0271         MouseEvent(int _button, MouseEventType _type,
0272                    const DOMString &_url = DOMString(), const DOMString &_target = DOMString(),
0273                    NodeImpl *_innerNode = nullptr, NodeImpl *_innerNonSharedNode = nullptr)
0274         {
0275             button = _button; type = _type;
0276             url = _url; target = _target;
0277             innerNode = _innerNode;
0278             innerNonSharedNode = _innerNonSharedNode;
0279         }
0280 
0281         int button;
0282         MouseEventType type;
0283         DOMString url; // url under mouse or empty
0284         DOMString target;
0285         Node innerNode;
0286         Node innerNonSharedNode;
0287     };
0288 
0289     // for LINK and STYLE
0290     // will increase/decrease the document's pending sheet count if appropriate
0291     virtual bool checkAddPendingSheet()
0292     {
0293         return true;
0294     }
0295     virtual bool checkRemovePendingSheet()
0296     {
0297         return true;
0298     }
0299 
0300     bool hasID() const
0301     {
0302         return m_hasId;
0303     }
0304     bool hasClass() const
0305     {
0306         return m_hasClass;
0307     }
0308     bool hasCombinedStyle() const
0309     {
0310         return m_hasCombinedStyle;
0311     }
0312     bool active() const
0313     {
0314         return m_active;
0315     }
0316     bool focused() const
0317     {
0318         return m_focused;
0319     }
0320     bool hovered() const
0321     {
0322         return m_hovered;
0323     }
0324     bool attached() const
0325     {
0326         return m_attached;
0327     }
0328     bool closed() const
0329     {
0330         return m_closed;
0331     }
0332     bool changed() const
0333     {
0334         return m_changed;
0335     }
0336     bool hasChangedChild() const
0337     {
0338         return m_hasChangedChild;
0339     }
0340     bool hasAnchor() const
0341     {
0342         return m_hasAnchor;
0343     }
0344     bool inDocument() const
0345     {
0346         return m_inDocument;
0347     }
0348     bool implicitNode() const
0349     {
0350         return m_implicit;
0351     }
0352     bool htmlCompat() const
0353     {
0354         return m_htmlCompat;
0355     }
0356     void setHasID(bool b = true)
0357     {
0358         m_hasId = b;
0359     }
0360     void setHasClass(bool b = true)
0361     {
0362         m_hasClass = b;
0363     }
0364     void setHasChangedChild(bool b = true)
0365     {
0366         m_hasChangedChild = b;
0367     }
0368     void setInDocument(bool b = true)
0369     {
0370         m_inDocument = b;
0371     }
0372     void setHTMLCompat(bool b)
0373     {
0374         m_htmlCompat = b;
0375     }
0376     bool hasHoverDependency()
0377     {
0378         return m_hasHoverDependency;
0379     }
0380     void setHasHoverDependency(bool b = true)
0381     {
0382         m_hasHoverDependency = b;
0383     }
0384     void setNeedsStyleAttributeUpdate(bool b = true)
0385     {
0386         m_needsStyleAttributeUpdate = b;
0387     }
0388     virtual void setFocus(bool b = true)
0389     {
0390         m_focused = b;
0391     }
0392     virtual void setActive(bool b = true)
0393     {
0394         m_active = b;
0395     }
0396     virtual void setHovered(bool b = true)
0397     {
0398         m_hovered = b;
0399     }
0400     virtual void setChanged(bool b = true);
0401     // for WebCore API compatibility
0402     void setAttached(bool b = true)
0403     {
0404         m_attached = b;
0405     }
0406 
0407     // for descending restyle when ID or CLASS changes
0408     bool changedAscendentAttribute() const
0409     {
0410         return m_changedAscendentAttribute;
0411     }
0412     void setChangedAscendentAttribute(bool b)
0413     {
0414         m_changedAscendentAttribute = b;
0415     }
0416 
0417     virtual short tabIndex() const
0418     {
0419         return 0;
0420     }
0421 
0422     enum FocusType {
0423         FT_Any,
0424         FT_Mouse,
0425         FT_Tab
0426     };
0427 
0428     // Elements that are focusable by default should override this.
0429     // Warning: if they're in a language that supports tabIndex (e.g. HTML),
0430     // they must call back to the base class whenever hasTabIndex() is set.
0431     virtual bool isFocusableImpl(FocusType) const
0432     {
0433         return false;
0434     }
0435     bool isFocusable() const
0436     {
0437         return isFocusableImpl(FT_Any);
0438     }
0439     bool isMouseFocusable() const
0440     {
0441         return isFocusableImpl(FT_Mouse);
0442     }
0443     bool isTabFocusable() const
0444     {
0445         return isFocusableImpl(FT_Tab);
0446     }
0447 
0448     virtual bool isInline() const;
0449 
0450     virtual bool isContentEditable() const;
0451     virtual void getCaret(int offset, bool override, int &_x, int &_y, int &width, int &height);
0452     virtual QRect getRect() const;
0453 
0454     enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
0455     virtual void recalcStyle(StyleChange = NoChange) {}
0456     static StyleChange diff(khtml::RenderStyle *s1, khtml::RenderStyle *s2);
0457     static bool pseudoDiff(khtml::RenderStyle *s1, khtml::RenderStyle *s2, unsigned int pid);
0458 
0459     virtual bool affectedByNoInherit() const;
0460 
0461     unsigned long nodeIndex() const;
0462     // Returns the document that this node is associated with. This is guaranteed to always be non-null, as opposed to
0463     // DOM's ownerDocument() which is null for Document nodes (and sometimes DocumentType nodes).
0464     DocumentImpl *document() const
0465     {
0466         return m_document.get();
0467     }
0468     void setDocument(DocumentImpl *doc);
0469 
0470     DocumentImpl *eventTargetDocument() override;
0471 
0472     void dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false);
0473 
0474     // takes care of bubbling and the like. The target is generally 'this',
0475     // unless the event specifies something special like Window as the target,
0476     // in which case that's used for dispatch.
0477     void dispatchGenericEvent(EventImpl *evt, int &exceptioncode);
0478 
0479     // return true if event not prevented
0480     bool dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg);
0481 
0482     // Window events are special in that they're only dispatched on Window, and not
0483     // the current node.
0484     void dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg);
0485     void dispatchWindowEvent(EventImpl *evt);
0486 
0487     void dispatchMouseEvent(QMouseEvent *e, int overrideId = 0, int overrideDetail = 0);
0488     void dispatchUIEvent(int _id, int detail = 0);
0489     void dispatchSubtreeModifiedEvent();
0490     // return true if defaultPrevented (i.e. event should be swallowed)
0491     // this matches the logic in KHTMLView.
0492     bool dispatchKeyEvent(QKeyEvent *key, bool keypress);
0493 
0494     virtual bool isReadOnly();
0495     virtual bool childTypeAllowed(unsigned short /*type*/)
0496     {
0497         return false;
0498     }
0499     virtual unsigned long childNodeCount();
0500     virtual NodeImpl *childNode(unsigned long index);
0501 
0502     /**
0503      * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that
0504      * the tags appear in the source file.
0505      *
0506      * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to
0507      * restrict traversal to a particular sub-tree.
0508      *
0509      * @return The next node, in document order
0510      *
0511      * see traversePreviousNode()
0512      */
0513     NodeImpl *traverseNextNode(NodeImpl *stayWithin = nullptr) const;
0514 
0515     /**
0516      * Does a reverse pre-order traversal to find the node that comes before the current one in document order
0517      *
0518      * see traverseNextNode()
0519      */
0520     NodeImpl *traversePreviousNode() const;
0521 
0522     DocumentImpl *docPtr() const
0523     {
0524         return m_document.get();
0525     }
0526 
0527     NodeImpl *previousEditable() const;
0528     NodeImpl *nextEditable() const;
0529     //bool isEditable() const;
0530 
0531     khtml::RenderObject *renderer() const
0532     {
0533         return m_render;
0534     }
0535     khtml::RenderObject *nextRenderer();
0536     khtml::RenderObject *previousRenderer();
0537     void setRenderer(khtml::RenderObject *renderer)
0538     {
0539         m_render = renderer;
0540     }
0541 
0542     void checkSetPrefix(const DOMString &_prefix, int &exceptioncode);
0543     void checkAddChild(NodeImpl *newChild, int &exceptioncode);
0544     bool isAncestor(NodeImpl *other) const;
0545     virtual bool childAllowed(NodeImpl *newChild);
0546 
0547     // Used to determine whether range offsets use characters or node indices.
0548     virtual bool offsetInCharacters() const
0549     {
0550         return false;
0551     }
0552     // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
0553     // css-transform:capitalize breaking up precomposed characters and ligatures.
0554     virtual int maxCharacterOffset() const
0555     {
0556         return 0;
0557     }
0558 
0559     virtual long maxOffset() const;
0560     virtual long caretMinOffset() const;
0561     virtual long caretMaxOffset() const;
0562     virtual unsigned long caretMaxRenderedOffset() const;
0563 
0564     // -----------------------------------------------------------------------------
0565     // Integration with rendering tree
0566 
0567     /**
0568      * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
0569      * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
0570      * makes the node visible in the KHTMLView.
0571      */
0572     virtual void attach();
0573 
0574     /**
0575      * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
0576      * the node's rendering object from the rendering tree and delete it.
0577      */
0578     virtual void detach();
0579 
0580     /**
0581      * Notifies the node that no more children will be added during parsing.
0582      * After a node has been closed all changes must go through the DOM interface.
0583      */
0584     virtual void close();
0585 
0586     virtual void structureChanged() {}
0587     virtual void backwardsStructureChanged() {}
0588 
0589     void createRendererIfNeeded();
0590     virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
0591     virtual bool rendererIsNeeded(khtml::RenderStyle *);
0592     virtual khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *);
0593 
0594     virtual khtml::RenderStyle *computedStyle();
0595 
0596     // -----------------------------------------------------------------------------
0597     // Methods for maintaining the state of the element between history navigation
0598 
0599     /**
0600      * Indicates whether or not this type of node maintains its state. If so, the state of the node will be stored when
0601      * the user goes to a different page using the state() method, and restored using the restoreState() method if the
0602      * user returns (e.g. using the back button). This is used to ensure that user-changeable elements such as form
0603      * controls maintain their contents when the user returns to a previous page in the history.
0604      */
0605     virtual bool maintainsState();
0606 
0607     /**
0608      * Returns the state of this node represented as a string. This string will be passed to restoreState() if the user
0609      * returns to the page.
0610      *
0611      * @return State information about the node represented as a string
0612      */
0613     virtual QString state();
0614 
0615     /**
0616      * Sets the state of the element based on a string previosuly returned by state(). This is used to initialize form
0617      * controls with their old values when the user returns to the page in their history.
0618      *
0619      * @param state A string representation of the node's previously-stored state
0620      */
0621     virtual void restoreState(const QString &state);
0622 
0623     // -----------------------------------------------------------------------------
0624     // Notification of document structure changes
0625 
0626     /**
0627      * Notifies the node that it has been inserted into the document. This is called during document parsing, and also
0628      * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
0629      * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
0630      * the node. The call happens _after_ the node has been added to the tree.
0631      *
0632      * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
0633      * dispatching.
0634      */
0635     virtual void insertedIntoDocument();
0636 
0637     /**
0638      * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
0639      * node.
0640      *
0641      * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
0642      * dispatching, and is called _after_ the node is removed from the tree.
0643      */
0644     virtual void removedFromDocument();
0645 
0646     /**
0647      * Notifies the node that its list of children have changed (either by adding or removing child nodes), or a child
0648      * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
0649      */
0650     virtual void childrenChanged();
0651 
0652     virtual DOMString toString() const = 0;
0653     /**
0654      * Sometimes we need to get the string between two points on the DOM graph.  Use this function to do this.
0655      * For example, when the user copies some selected text to the clipboard as html.
0656      * @param selectionStart Where to start the selection.  If selectionStart != this, it is assumed we are after the start point
0657      * @param selectionEnd   Where to end the selection.  If selectionEnd != this, it is assumed we are before the end point (unless found is true)
0658      * @param startOffset    Number of characters into the text in selectionStart that the start of the selection is.
0659      * @param endOffset      Number of characters into the text in selectionEnd that the end of the selection is.
0660      * @param found          When this is set to true, don't print anymore but closing tags.
0661      * @return An html formatted string for this node and its children between the selectionStart and selectionEnd.
0662      */
0663     virtual DOMString selectionToString(NodeImpl *selectionStart,
0664                                         NodeImpl *selectionEnd,
0665                                         int startOffset,
0666                                         int endOffset,
0667                                         bool &found) const
0668     {
0669         Q_UNUSED(selectionStart);
0670         Q_UNUSED(selectionEnd);
0671         Q_UNUSED(startOffset);
0672         Q_UNUSED(endOffset);
0673         Q_UNUSED(found);
0674         return toString();
0675     }
0676 
0677     // FOR SVG Events support (WebCore API compatibility)
0678     QList<RegisteredEventListener> *localEventListeners()
0679     {
0680         return listenerList().listeners;
0681     }
0682 
0683     DOMString lookupNamespaceURI(const DOMString &prefix);
0684 
0685 private: // members
0686     khtml::DocPtr<DocumentImpl> m_document;
0687     NodeImpl *m_previous;
0688     NodeImpl *m_next;
0689 
0690     NodeImpl *findNextElementAncestor(NodeImpl *node);
0691 protected:
0692     khtml::RenderObject *m_render;
0693 
0694     bool m_hasId : 1;
0695     bool m_attached : 1;
0696     bool m_closed : 1;
0697     bool m_changed : 1;
0698     bool m_hasChangedChild : 1;
0699     bool m_changedAscendentAttribute : 1;
0700     bool m_inDocument : 1;
0701     bool m_hasAnchor : 1;
0702 
0703     bool m_hovered : 1;
0704     bool m_focused : 1;
0705     bool m_active : 1;
0706     bool m_implicit : 1; // implicitely generated by the parser
0707     bool m_htmlCompat : 1; // true if element was created in HTML compat mode
0708     bool m_hasClass : 1;   // true if element has a class property, as relevant to CSS
0709     bool m_hasCombinedStyle : 1; // true if element has inline styles and presentational styles
0710     bool m_hasHoverDependency : 1; // true if element has hover dependency on itself
0711 
0712     bool m_elementHasRareData : 1;
0713     mutable bool m_needsStyleAttributeUpdate : 1; // true if |style| attribute is out of sync (i.e. CSSOM modified our inline styles)
0714 
0715     // 14 bits left
0716 };
0717 
0718 // this is the full Node Implementation with parents and children.
0719 class NodeBaseImpl : public NodeImpl
0720 {
0721 public:
0722     NodeBaseImpl(DocumentImpl *doc)
0723         : NodeImpl(doc), _first(nullptr), _last(nullptr) {}
0724     virtual ~NodeBaseImpl();
0725 
0726     // DOM methods overridden from  parent classes
0727     NodeImpl *firstChild() const override;
0728     NodeImpl *lastChild() const override;
0729     NodeImpl *insertBefore(NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode) override;
0730     void replaceChild(NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode) override;
0731     void removeChild(NodeImpl *oldChild, int &exceptioncode) override;
0732     NodeImpl *appendChild(NodeImpl *newChild, int &exceptioncode) override;
0733     bool hasChildNodes() const override;
0734 
0735     // Other methods (not part of DOM)
0736     virtual void removeChildren();
0737     void cloneChildNodes(NodeImpl *clone);
0738 
0739     void setFirstChild(NodeImpl *child) override;
0740     void setLastChild(NodeImpl *child) override;
0741     NodeImpl *addChild(NodeImpl *newChild) override;
0742     void attach() override;
0743     void detach() override;
0744 
0745     bool getUpperLeftCorner(int &xPos, int &yPos) const;
0746     bool getLowerRightCorner(int &xPos, int &yPos) const;
0747 
0748     void setFocus(bool = true) override;
0749     void setActive(bool = true) override;
0750     void setHovered(bool = true) override;
0751     unsigned long childNodeCount() override;
0752     NodeImpl *childNode(unsigned long index) override;
0753 
0754 protected:
0755     NodeImpl *_first;
0756     NodeImpl *_last;
0757 
0758     // helper functions for inserting children:
0759 
0760     // ### this should vanish. do it in dom/ !
0761     // check for same source document:
0762     bool checkSameDocument(NodeImpl *newchild, int &exceptioncode);
0763     // check for being child:
0764     bool checkIsChild(NodeImpl *oldchild, int &exceptioncode);
0765     // ###
0766 
0767     // find out if a node is allowed to be our child
0768     void dispatchChildInsertedEvents(NodeImpl *child, int &exceptioncode);
0769     void dispatchChildRemovalEvents(NodeImpl *child, int &exceptioncode);
0770 };
0771 
0772 // Generic NamedNodeMap interface
0773 // Other classes implement this for more specific situations e.g. attributes
0774 // of an element
0775 class NamedNodeMapImpl : public khtml::Shared<NamedNodeMapImpl>
0776 {
0777 public:
0778     NamedNodeMapImpl();
0779     virtual ~NamedNodeMapImpl();
0780 
0781     // DOM methods & attributes for NamedNodeMap
0782     virtual NodeImpl *getNamedItem(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) = 0;
0783     virtual Node removeNamedItem(NodeImpl::Id id, const PrefixName &prefix, bool nsAware, int &exceptioncode) = 0;
0784     virtual Node setNamedItem(NodeImpl *arg, const PrefixName &prefix, bool nsAware, int &exceptioncode) = 0;
0785 
0786     //The DOM-style wrappers
0787     NodeImpl *getNamedItem(const DOMString &name);
0788     Node setNamedItem(const Node &arg, int &exceptioncode);
0789     Node removeNamedItem(const DOMString &name, int &exceptioncode);
0790     Node getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName);
0791     Node setNamedItemNS(const Node &arg, int &exceptioncode);
0792     Node removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName, int &exceptioncode);
0793 
0794     virtual NodeImpl *item(unsigned index) = 0;
0795     virtual unsigned length() const = 0;
0796 
0797     virtual bool isReadOnly()
0798     {
0799         return false;
0800     }
0801     virtual bool htmlCompat()
0802     {
0803         return false;
0804     }
0805 };
0806 
0807 // Generic read-only NamedNodeMap implementation
0808 // Used for e.g. entities and notations in DocumentType.
0809 // You can add nodes using addNode
0810 class GenericRONamedNodeMapImpl : public NamedNodeMapImpl
0811 {
0812 public:
0813     GenericRONamedNodeMapImpl(DocumentImpl *doc);
0814     virtual ~GenericRONamedNodeMapImpl();
0815 
0816     // DOM methods & attributes for NamedNodeMap
0817 
0818     NodeImpl *getNamedItem(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) override;
0819     Node removeNamedItem(NodeImpl::Id id, const PrefixName &prefix, bool nsAware, int &exceptioncode) override;
0820     Node setNamedItem(NodeImpl *arg, const PrefixName &prefix, bool nsAware, int &exceptioncode) override;
0821 
0822     NodeImpl *item(unsigned index) override;
0823     unsigned length() const override;
0824 
0825     bool isReadOnly() override
0826     {
0827         return true;
0828     }
0829 
0830     void addNode(NodeImpl *n);
0831 
0832 protected:
0833     DocumentImpl *m_doc;
0834     QList<NodeImpl *> *m_contents;
0835 };
0836 
0837 } //namespace
0838 #endif