2 * This file is part of the DOM implementation for KDE.
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 * Copyright (C) 2004 Apple Computer, Inc.
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.
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.
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., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 #ifndef _DOM_NodeImpl_h_
26 #define _DOM_NodeImpl_h_
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 "dom_atomicstring.h"
36 template <class type> class QPtrList;
52 class CSSStyleDeclarationImpl;
56 class NamedNodeMapImpl;
61 class RegisteredEventListener;
63 // The namespace used for XHTML elements
64 #define XHTML_NAMESPACE "http://www.w3.org/1999/xhtml"
66 const Q_UINT16 noNamespace = 0;
67 const Q_UINT16 anyNamespace = 1;
68 const Q_UINT16 xhtmlNamespace = 2;
69 const Q_UINT16 anyLocalName = 0;
71 const Q_UINT32 namespaceMask = 0xFFFF0000U;
72 const Q_UINT32 localNameMask = 0x0000FFFFU;
74 inline Q_UINT16 namespacePart(Q_UINT32 i) { return i >> 16; }
75 inline Q_UINT16 localNamePart(Q_UINT32 i) { return i; }
76 inline Q_UINT32 makeId(Q_UINT16 n, Q_UINT16 l) { return (n << 16) | l; }
78 const Q_UINT32 anyQName = makeId(anyNamespace, anyLocalName);
80 class DocumentPtr : public khtml::Shared<DocumentPtr>
83 DocumentImpl *document() const { return doc; }
85 DocumentPtr() { doc = 0; }
86 friend class DocumentImpl;
87 friend class DOMImplementationImpl;
92 // this class implements nodes, which can have a parent but no children:
93 class NodeImpl : public khtml::TreeShared<NodeImpl>
95 friend class DocumentImpl;
97 NodeImpl(DocumentPtr *doc);
100 // DOM methods & attributes for Node
101 virtual DOMString nodeName() const;
102 virtual DOMString nodeValue() const;
103 virtual void setNodeValue( const DOMString &_nodeValue, int &exceptioncode );
104 virtual unsigned short nodeType() const;
105 NodeImpl *parentNode() const { return m_parent; }
106 NodeImpl *previousSibling() const { return m_previous; }
107 NodeImpl *nextSibling() const { return m_next; }
108 virtual NodeListImpl *childNodes();
109 virtual NodeImpl *firstChild() const;
110 virtual NodeImpl *lastChild() const;
111 virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
112 virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
113 virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
114 virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
115 virtual void remove(int &exceptioncode);
116 virtual bool hasChildNodes ( ) const;
117 virtual NodeImpl *cloneNode ( bool deep ) = 0;
118 virtual DOMString localName() const;
119 virtual DOMString prefix() const;
120 virtual void setPrefix(const DOMString &_prefix, int &exceptioncode );
123 // Other methods (not part of DOM)
124 virtual bool isElementNode() const { return false; }
125 virtual bool isHTMLElement() const { return false; }
126 virtual bool isAttributeNode() const { return false; }
127 virtual bool isTextNode() const { return false; }
128 virtual bool isDocumentNode() const { return false; }
129 virtual bool isXMLElementNode() const { return false; }
130 bool isBlockFlow() const;
132 // Used by <form> elements to indicate a malformed state of some kind, typically
133 // used to keep from applying the bottom margin of the form.
134 virtual bool isMalformed() { return false; }
135 virtual void setMalformed(bool malformed) {};
137 virtual bool containsOnlyWhitespace() const { return false; }
139 // helper functions not being part of the DOM
140 // Attention: they assume that the caller did the consistency checking!
141 void setPreviousSibling(NodeImpl *previous) { m_previous = previous; }
142 void setNextSibling(NodeImpl *next) { m_next = next; }
144 virtual void setFirstChild(NodeImpl *child);
145 virtual void setLastChild(NodeImpl *child);
147 bool isAtomicNode() const;
148 NodeImpl *previousNodeConsideringAtomicNodes() const;
149 NodeImpl *nextNodeConsideringAtomicNodes() const;
151 /** (Not part of the official DOM)
152 * Returns the next leaf node.
154 * Using this function delivers leaf nodes as if the whole DOM tree
155 * were a linear chain of its leaf nodes.
156 * @return next leaf node or 0 if there are no more.
158 NodeImpl *nextLeafNode() const;
160 /** (Not part of the official DOM)
161 * Returns the previous leaf node.
163 * Using this function delivers leaf nodes as if the whole DOM tree
164 * were a linear chain of its leaf nodes.
165 * @return previous leaf node or 0 if there are no more.
167 NodeImpl *previousLeafNode() const;
169 bool isEditableBlock() const;
170 ElementImpl *enclosingBlockFlowElement() const;
171 ElementImpl *rootEditableElement() const;
173 bool inSameRootEditableElement(NodeImpl *);
174 bool inSameContainingBlockFlowElement(NodeImpl *);
176 Position positionForCoordinates(int x, int y);
178 // used by the parser. Doesn't do as many error checkings as
179 // appendChild(), and returns the node into which will be parsed next.
180 virtual NodeImpl *addChild(NodeImpl *newChild);
183 // id() is used to easily and exactly identify a node. It
184 // is optimized for quick comparison and low memory consumption.
185 // its value depends on the owner document of the node and is
186 // categorized in the following way:
187 // 1..ID_LAST_TAG: the node inherits HTMLElementImpl and is
188 // part of the HTML namespace.
189 // The HTML namespace is either the global
190 // one (no namespace) or the XHTML namespace
191 // depending on the owner document's doctype
192 // ID_LAST_TAG+1..0xffff: non-HTML elements in the global namespace
193 // others non-HTML elements in a namespace.
194 // the upper 16 bit identify the namespace
195 // the lower 16 bit identify the local part of the
196 // qualified element name.
197 virtual Id id() const { return 0; };
199 Id identifier() const;
201 enum MouseEventType {
211 MouseEvent( int _button, MouseEventType _type,
212 const DOMString &_url = DOMString(), const DOMString& _target = DOMString(),
213 NodeImpl *_innerNode = 0)
215 button = _button; type = _type;
216 url = _url; target = _target;
217 innerNode = _innerNode;
222 DOMString url; // url under mouse or empty
227 // for LINK and STYLE
228 virtual void sheetLoaded() {}
230 bool hasID() const { return m_hasId; }
231 bool hasClass() const { return m_hasClass; }
232 bool hasStyle() const { return m_hasStyle; }
233 bool active() const { return m_active; }
234 bool focused() const { return m_focused; }
235 bool attached() const { return m_attached; }
236 bool changed() const { return m_changed; }
237 bool hasChangedChild() const { return m_hasChangedChild; }
238 bool hasAnchor() const { return m_hasAnchor; }
239 bool inDocument() const { return m_inDocument; }
240 bool styleElement() const { return m_styleElement; }
241 bool implicitNode() const { return m_implicit; }
242 void setHasID(bool b=true) { m_hasId = b; }
243 void setHasClass(bool b=true) { m_hasClass = b; }
244 void setHasStyle(bool b=true) { m_hasStyle = b; }
245 void setHasChangedChild( bool b = true ) { m_hasChangedChild = b; }
246 void setInDocument(bool b=true) { m_inDocument = b; }
247 virtual void setFocus(bool b=true) { m_focused = b; }
248 virtual void setActive(bool b=true) { m_active = b; }
249 void setChanged(bool b=true);
251 unsigned short tabIndex() const { return m_tabIndex; }
252 void setTabIndex(unsigned short _tabIndex) { m_tabIndex = _tabIndex; }
255 * whether this node can receive the keyboard focus.
257 virtual bool isFocusable() const;
258 virtual bool isKeyboardFocusable() const;
259 virtual bool isMouseFocusable() const;
261 virtual bool isInline() const;
262 virtual QString toHTML() const;
263 QString recursive_toHTML(bool onlyIncludeChildren=false, const DOM::RangeImpl *range=NULL, QPtrList<NodeImpl> *nodes=NULL) const;
264 static QString recursive_toString(const NodeImpl *startNode, bool onlyIncludeChildren=false, const DOM::RangeImpl *range=NULL, QPtrList<NodeImpl> *nodes=NULL);
265 void recursive_completeURLs(QString baseURL);
267 virtual bool isContentEditable() const;
268 virtual QRect getRect() const;
270 enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
271 virtual void recalcStyle( StyleChange = NoChange ) {}
272 StyleChange diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const;
274 unsigned long nodeIndex() const;
275 // Returns the document that this node is associated with. This is guaranteed to always be non-null, as opposed to
276 // DOM's ownerDocument() which is null for Document nodes (and sometimes DocumentType nodes).
277 DocumentImpl* getDocument() const { return document->document(); }
279 void setDocument(DocumentPtr *doc);
281 void addEventListener(int id, EventListener *listener, const bool useCapture);
282 void removeEventListener(int id, EventListener *listener, bool useCapture);
283 void removeHTMLEventListener(int id);
284 void setHTMLEventListener(int id, EventListener *listener);
285 EventListener *getHTMLEventListener(int id);
287 bool dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false);
288 bool dispatchGenericEvent( EventImpl *evt, int &exceptioncode);
289 bool dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg);
290 bool dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg);
291 bool dispatchMouseEvent(QMouseEvent *e, int overrideId = 0, int overrideDetail = 0);
292 bool dispatchUIEvent(int _id, int detail = 0);
293 bool dispatchSubtreeModifiedEvent();
294 bool dispatchKeyEvent(QKeyEvent *key);
296 void handleLocalEvents(EventImpl *evt, bool useCapture);
299 * Perform the default action for an event e.g. submitting a form
301 virtual void defaultEventHandler(EventImpl *evt);
304 * Used for disabled form elements; if true, prevents mouse events from being dispatched
305 * to event listeners, and prevents DOMActivate events from being sent at all.
307 virtual bool disabled() const;
309 virtual bool isReadOnly();
310 virtual bool childTypeAllowed( unsigned short /*type*/ ) { return false; }
311 virtual unsigned long childNodeCount() const;
312 virtual NodeImpl *childNode(unsigned long index);
315 * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that
316 * the tags appear in the source file.
318 * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to
319 * restrict traversal to a particular sub-tree.
321 * @return The next node, in document order
323 * see @ref traversePreviousNode()
325 NodeImpl *traverseNextNode(NodeImpl *stayWithin = 0) const;
327 /* Like traverseNextNode, but skips children and starts with the next sibling. */
328 NodeImpl *traverseNextSibling(NodeImpl *stayWithin = 0) const;
331 * Does a reverse pre-order traversal to find the node that comes before the current one in document order
333 * see @ref traverseNextNode()
335 NodeImpl *traversePreviousNode() const;
337 DocumentPtr *docPtr() const { return document; }
339 NodeImpl *previousEditable() const;
340 NodeImpl *nextEditable() const;
341 //bool isEditable() const;
343 khtml::RenderObject *renderer() const { return m_render; }
344 khtml::RenderObject *nextRenderer();
345 khtml::RenderObject *previousRenderer();
346 void setRenderer(khtml::RenderObject* renderer) { m_render = renderer; }
348 void checkSetPrefix(const DOMString &_prefix, int &exceptioncode);
349 void checkAddChild(NodeImpl *newChild, int &exceptioncode);
350 bool isAncestor(const NodeImpl *) const;
351 virtual bool childAllowed( NodeImpl *newChild );
353 virtual long maxOffset() const;
354 virtual long caretMinOffset() const;
355 virtual long caretMaxOffset() const;
356 virtual unsigned long caretMaxRenderedOffset() const;
359 virtual void dump(QTextStream *stream, QString ind = "") const;
362 // -----------------------------------------------------------------------------
363 // Integration with rendering tree
366 * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
367 * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
368 * makes the node visible in the KHTMLView.
370 virtual void attach();
373 * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
374 * the node's rendering object from the rendering tree and delete it.
376 virtual void detach();
378 void createRendererIfNeeded();
379 virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
380 virtual bool rendererIsNeeded(khtml::RenderStyle *);
381 virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
383 // -----------------------------------------------------------------------------
384 // Methods for maintaining the state of the element between history navigation
387 * Indicates whether or not this type of node maintains it's state. If so, the state of the node will be stored when
388 * the user goes to a different page using the state() method, and restored using the restoreState() method if the
389 * user returns (e.g. using the back button). This is used to ensure that user-changeable elements such as form
390 * controls maintain their contents when the user returns to a previous page in the history.
392 virtual bool maintainsState();
395 * Returns the state of this node represented as a string. This string will be passed to restoreState() if the user
396 * returns to the page.
398 * @return State information about the node represented as a string
400 virtual QString state();
403 * Sets the state of the element based on strings previously returned by state(). This is used to initialize form
404 * controls with their old values when the user returns to the page in their history. The receiver
405 * should remove the string from the list that it uses for its restore.
407 * @param states The strings previously returned by nodes' state methods.
409 virtual void restoreState(QStringList &stateList);
411 // -----------------------------------------------------------------------------
412 // Notification of document stucture changes
415 * Notifies the node that it has been inserted into the document. This is called during document parsing, and also
416 * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
417 * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
418 * the node. The call happens _after_ the node has been added to the tree.
420 * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
423 virtual void insertedIntoDocument();
426 * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
429 * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
430 * dispatching, and is called _after_ the node is removed from the tree.
432 virtual void removedFromDocument();
435 * Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
436 * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed it's value.
438 virtual void childrenChanged();
440 virtual DOMString toString() const = 0;
443 virtual void formatForDebugger(char *buffer, unsigned length) const;
447 DocumentPtr *document;
448 NodeImpl *m_previous;
451 khtml::RenderObject *m_render;
452 QPtrList<RegisteredEventListener> *m_regdListeners;
454 unsigned short m_tabIndex : 15;
455 bool m_hasTabIndex : 1;
462 bool m_hasChangedChild : 1;
463 bool m_inDocument : 1;
465 bool m_hasAnchor : 1;
466 bool m_specified : 1; // used in AttrImpl. Accessor functions there
469 bool m_styleElement : 1; // contains stylesheet text
470 bool m_implicit : 1; // implicitely generated by the parser
475 // this is the full Node Implementation with parents and children.
476 class NodeBaseImpl : public NodeImpl
479 NodeBaseImpl(DocumentPtr *doc);
480 virtual ~NodeBaseImpl();
482 // DOM methods overridden from parent classes
483 virtual NodeImpl *firstChild() const;
484 virtual NodeImpl *lastChild() const;
485 virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
486 virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
487 virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
488 virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
489 virtual bool hasChildNodes ( ) const;
491 // Other methods (not part of DOM)
492 void removeChildren();
493 void cloneChildNodes(NodeImpl *clone);
495 virtual void setFirstChild(NodeImpl *child);
496 virtual void setLastChild(NodeImpl *child);
497 virtual NodeImpl *addChild(NodeImpl *newChild);
498 virtual void attach();
499 virtual void detach();
501 virtual NodeListImpl *getElementsByTagNameNS ( DOMStringImpl* namespaceURI,
502 DOMStringImpl* localName );
504 virtual QRect getRect() const;
505 bool getUpperLeftCorner(int &xPos, int &yPos) const;
506 bool getLowerRightCorner(int &xPos, int &yPos) const;
508 virtual void setFocus(bool=true);
509 virtual void setActive(bool=true);
510 virtual unsigned long childNodeCount() const;
511 virtual NodeImpl *childNode(unsigned long index);
513 virtual void insertedIntoDocument();
514 virtual void removedFromDocument();
516 // check for being (grand-..)father:
517 bool checkNoOwner( NodeImpl *other, int &exceptioncode );
523 // helper functions for inserting children:
525 // ### this should vanish. do it in dom/ !
526 // check for same source document:
527 bool checkSameDocument( NodeImpl *newchild, int &exceptioncode );
528 // check for being child:
529 bool checkIsChild( NodeImpl *oldchild, int &exceptioncode );
532 // find out if a node is allowed to be our child
533 void dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode );
534 void dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode );
537 // --------------------------------------------------------------------------
541 class NodeListImpl : public khtml::Shared<NodeListImpl>
544 virtual ~NodeListImpl() {}
546 // DOM methods & attributes for NodeList
547 virtual unsigned long length() const;
548 virtual NodeImpl *item ( unsigned long index ) const;
550 // Other methods (not part of DOM)
553 static NodeList createInstance(NodeListImpl *impl);
556 // helper functions for searching all ElementImpls in a tree
557 unsigned long recursiveLength(NodeImpl *start) const;
558 NodeImpl *recursiveItem ( NodeImpl *start, unsigned long &offset ) const;
559 virtual bool nodeMatches( NodeImpl *testNode ) const = 0;
562 class ChildNodeListImpl : public NodeListImpl
565 ChildNodeListImpl( NodeImpl *n);
566 virtual ~ChildNodeListImpl();
568 // DOM methods overridden from parent classes
570 virtual unsigned long length() const;
571 virtual NodeImpl *item ( unsigned long index ) const;
574 virtual bool nodeMatches( NodeImpl *testNode ) const;
581 * NodeList which lists all Nodes in a document with a given tag name
583 class TagNodeListImpl : public NodeListImpl
586 TagNodeListImpl( NodeImpl *n, NodeImpl::Id tagId, NodeImpl::Id tagIdMask );
587 virtual ~TagNodeListImpl();
589 // DOM methods overridden from parent classes
591 virtual unsigned long length() const;
592 virtual NodeImpl *item ( unsigned long index ) const;
594 // Other methods (not part of DOM)
597 virtual bool nodeMatches( NodeImpl *testNode ) const;
601 NodeImpl::Id m_idMask;
606 * NodeList which lists all Nodes in a Element with a given "name=" tag
608 class NameNodeListImpl : public NodeListImpl
611 NameNodeListImpl( NodeImpl *doc, const DOMString &t );
612 virtual ~NameNodeListImpl();
614 // DOM methods overridden from parent classes
616 virtual unsigned long length() const;
617 virtual NodeImpl *item ( unsigned long index ) const;
619 // Other methods (not part of DOM)
622 virtual bool nodeMatches( NodeImpl *testNode ) const;
629 // Generic NamedNodeMap interface
630 // Other classes implement this for more specific situations e.g. attributes
632 class NamedNodeMapImpl : public khtml::Shared<NamedNodeMapImpl>
636 virtual ~NamedNodeMapImpl();
638 // DOM methods & attributes for NamedNodeMap
639 virtual NodeImpl *getNamedItem ( NodeImpl::Id id ) const = 0;
640 virtual Node removeNamedItem ( NodeImpl::Id id, int &exceptioncode ) = 0;
641 virtual Node setNamedItem ( NodeImpl* arg, int &exceptioncode ) = 0;
643 virtual NodeImpl *item ( unsigned long index ) const = 0;
644 virtual unsigned long length( ) const = 0;
646 // Other methods (not part of DOM)
647 virtual NodeImpl::Id mapId(const DOMString& namespaceURI, const DOMString& localName, bool readonly) = 0;
648 virtual bool isReadOnly() { return false; }
651 static NamedNodeMap createInstance(NamedNodeMapImpl *impl);
658 // Generic read-only NamedNodeMap implementation
659 // You can add items using the internal function addItem()
660 class GenericRONamedNodeMapImpl : public NamedNodeMapImpl
663 GenericRONamedNodeMapImpl(DocumentPtr* doc);
664 virtual ~GenericRONamedNodeMapImpl();
666 // DOM methods & attributes for NamedNodeMap
668 virtual NodeImpl *getNamedItem ( const DOMString &name, int &exceptioncode ) const;
669 virtual Node setNamedItem ( const Node &arg, int &exceptioncode );
670 virtual Node removeNamedItem ( const DOMString &name, int &exceptioncode );
671 virtual NodeImpl *item ( unsigned long index ) const;
672 virtual unsigned long length( ) const;
673 virtual NodeImpl *getNamedItemNS( const DOMString &namespaceURI, const DOMString &localName,
674 int &exceptioncode ) const;
675 virtual NodeImpl *setNamedItemNS( NodeImpl *arg, int &exceptioncode );
676 virtual NodeImpl *removeNamedItemNS( const DOMString &namespaceURI, const DOMString &localName,
677 int &exceptioncode );
679 // Other methods (not part of DOM)
681 virtual bool isReadOnly() { return true; }
683 void addNode(NodeImpl *n);
687 QPtrList<NodeImpl> *m_contents;