Reviewed by Darin.
[WebKit-https.git] / WebCore / khtml / xml / dom_nodeimpl.h
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  * Copyright (C) 2004 Apple Computer, Inc.
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., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  *
24  */
25 #ifndef _DOM_NodeImpl_h_
26 #define _DOM_NodeImpl_h_
27
28 #include "dom/dom_string.h"
29 #include "dom/dom_node.h"
30 #include "misc/main_thread_malloc.h"
31 #include "misc/helper.h"
32 #include "misc/shared.h"
33 #include "dom_atomicstring.h"
34
35 class QPainter;
36 template <class type> class QPtrList;
37 template <class type> class QPtrDict;
38 class KHTMLView;
39 class RenderArena;
40 class QRect;
41 class QMouseEvent;
42 class QKeyEvent;
43 class QTextStream;
44 class QStringList;
45 class QWheelEvent;
46
47 namespace khtml {
48     class RenderObject;
49     class RenderStyle;
50 };
51
52 namespace DOM {
53
54 using khtml::SharedPtr;
55
56 class DocumentImpl;
57 class ElementImpl;
58 class EventImpl;
59 class EventListener;
60 class NodeListImpl;
61 class NamedAttrMapImpl;
62 class RegisteredEventListener;
63
64 // The namespace used for XHTML elements
65 #define XHTML_NAMESPACE "http://www.w3.org/1999/xhtml"
66
67 const Q_UINT16 noNamespace = 0;
68 const Q_UINT16 anyNamespace = 1;
69 const Q_UINT16 xhtmlNamespace = 2;
70 const Q_UINT16 anyLocalName = 0;
71
72 const Q_UINT32 namespaceMask = 0xFFFF0000U;
73 const Q_UINT32 localNameMask = 0x0000FFFFU;
74
75 inline Q_UINT16 namespacePart(Q_UINT32 i) { return i >> 16; }
76 inline Q_UINT16 localNamePart(Q_UINT32 i) { return i; }
77 inline Q_UINT32 makeId(Q_UINT16 n, Q_UINT16 l) { return (n << 16) | l; }
78
79 // Can't use makeId here because it results in an "initroutine".
80 const Q_UINT32 anyQName = anyNamespace << 16 | anyLocalName;
81
82 class DocumentPtr : public khtml::Shared<DocumentPtr>
83 {
84 public:
85     DocumentImpl *document() const { return doc; }
86 private:
87     DocumentPtr() { doc = 0; }
88     friend class DocumentImpl;
89     friend class DOMImplementationImpl;
90
91     DocumentImpl *doc;
92 };
93
94 // this class implements nodes, which can have a parent but no children:
95 class NodeImpl : public khtml::TreeShared<NodeImpl>
96 {
97     friend class DocumentImpl;
98 public:
99     NodeImpl(DocumentPtr *doc);
100     virtual ~NodeImpl();
101
102     MAIN_THREAD_ALLOCATED;
103
104     // DOM methods & attributes for Node
105     virtual DOMString nodeName() const = 0;
106     virtual DOMString nodeValue() const;
107     virtual void setNodeValue( const DOMString &_nodeValue, int &exceptioncode );
108     virtual unsigned short nodeType() const = 0;
109     NodeImpl *parentNode() const { return m_parent; }
110     NodeImpl *previousSibling() const { return m_previous; }
111     NodeImpl *nextSibling() const { return m_next; }
112     virtual NodeListImpl *childNodes();
113     virtual NodeImpl *firstChild() const;
114     virtual NodeImpl *lastChild() const;
115     virtual bool hasAttributes() const;
116     virtual NamedAttrMapImpl *attributes() const;
117     virtual DocumentImpl *ownerDocument() const;
118     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
119     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
120     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
121     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
122     virtual void remove(int &exceptioncode);
123     virtual bool hasChildNodes (  ) const;
124     virtual NodeImpl *cloneNode ( bool deep ) = 0;
125     virtual DOMString localName() const;
126     virtual DOMString namespaceURI() const;
127     virtual DOMString prefix() const;
128     virtual void setPrefix(const DOMString &_prefix, int &exceptioncode );
129     void normalize ();
130     static bool isSupported(const DOMString &feature, const DOMString &version);
131
132     NodeImpl *lastDescendent() const;
133
134     // Other methods (not part of DOM)
135     virtual bool isElementNode() const { return false; }
136     virtual bool isHTMLElement() const { return false; }
137     virtual bool isStyledElement() const { return false; }
138     virtual bool isAttributeNode() const { return false; }
139     virtual bool isTextNode() const { return false; }
140     virtual bool isDocumentNode() const { return false; }
141     virtual bool isXMLElementNode() const { return false; }
142     bool isBlockFlow() const;
143     bool isBlockFlowOrTable() const;
144     
145     // Used by <form> elements to indicate a malformed state of some kind, typically
146     // used to keep from applying the bottom margin of the form.
147     virtual bool isMalformed() { return false; }
148     virtual void setMalformed(bool malformed) {};
149     
150     virtual bool containsOnlyWhitespace() const { return false; }
151     
152     // helper functions not being part of the DOM
153     // Attention: they assume that the caller did the consistency checking!
154     void setPreviousSibling(NodeImpl *previous) { m_previous = previous; }
155     void setNextSibling(NodeImpl *next) { m_next = next; }
156
157     virtual void setFirstChild(NodeImpl *child);
158     virtual void setLastChild(NodeImpl *child);
159
160     bool isAtomicNode() const;
161     NodeImpl *previousNodeConsideringAtomicNodes() const;
162     NodeImpl *nextNodeConsideringAtomicNodes() const;
163     
164     /** (Not part of the official DOM)
165      * Returns the next leaf node.
166      *
167      * Using this function delivers leaf nodes as if the whole DOM tree
168      * were a linear chain of its leaf nodes.
169      * @return next leaf node or 0 if there are no more.
170      */
171     NodeImpl *nextLeafNode() const;
172
173     /** (Not part of the official DOM)
174      * Returns the previous leaf node.
175      *
176      * Using this function delivers leaf nodes as if the whole DOM tree
177      * were a linear chain of its leaf nodes.
178      * @return previous leaf node or 0 if there are no more.
179      */
180     NodeImpl *previousLeafNode() const;
181
182     bool isEditableBlock() const;
183     ElementImpl *enclosingBlockFlowElement() const;
184     ElementImpl *enclosingBlockFlowOrTableElement() const;
185     ElementImpl *enclosingInlineElement() const;
186     ElementImpl *rootEditableElement() const;
187     
188     bool inSameRootEditableElement(NodeImpl *);
189     bool inSameContainingBlockFlowElement(NodeImpl *);
190     
191     // used by the parser. Doesn't do as many error checkings as
192     // appendChild(), and returns the node into which will be parsed next.
193     virtual NodeImpl *addChild(NodeImpl *newChild);
194     
195     // called by the parser when this element's close tag is reached,
196     // signalling that all child tags have been parsed and added.
197     // This is only needed for <applet> and <object> elements, which can't lay themselves out
198     // until they know all of their nested <param>s. [3603191, 4040848]
199     virtual void closeRenderer() { }
200
201     typedef Q_UINT32 Id;
202     // id() is used to easily and exactly identify a node. It
203     // is optimized for quick comparison and low memory consumption.
204     // its value depends on the owner document of the node and is
205     // categorized in the following way:
206     // 1..ID_LAST_TAG: the node inherits HTMLElementImpl and is
207     //                 part of the HTML namespace.
208     //                 The HTML namespace is either the global
209     //                 one (no namespace) or the XHTML namespace
210     //                 depending on the owner document's doctype
211     // ID_LAST_TAG+1..0xffff: non-HTML elements in the global namespace
212     // others       non-HTML elements in a namespace.
213     //                 the upper 16 bit identify the namespace
214     //                 the lower 16 bit identify the local part of the
215     //                 qualified element name.
216     virtual Id id() const { return 0; };
217 #if APPLE_CHANGES
218     Id identifier() const;
219 #endif
220     enum MouseEventType {
221         MousePress,
222         MouseRelease,
223         MouseClick,
224         MouseDblClick,
225         MouseMove
226     };
227
228     struct MouseEvent
229     {
230         MouseEvent( int _button, MouseEventType _type,
231                     const DOMString &_url = DOMString(), const DOMString& _target = DOMString(),
232                     NodeImpl *_innerNode = 0)
233             {
234                 button = _button; type = _type;
235                 url = _url; target = _target;
236                 innerNode.reset(_innerNode);
237             }
238
239         int button;
240         MouseEventType type;
241         DOMString url; // url under mouse or empty
242         DOMString target;
243         SharedPtr<NodeImpl> innerNode;
244     };
245
246     // for LINK and STYLE
247     virtual void sheetLoaded() {}
248
249     bool hasID() const      { return m_hasId; }
250     bool hasClass() const   { return m_hasClass; }
251     bool hasStyle() const   { return m_hasStyle; }
252     bool active() const     { return m_active; }
253     bool focused() const { return m_focused; }
254     bool attached() const   { return m_attached; }
255     bool changed() const    { return m_changed; }
256     bool hasChangedChild() const { return m_hasChangedChild; }
257     bool isLink() const { return m_isLink; }
258     // inDocument should also make sure a document exists in case the document has been destroyed before the node is removed from the document.
259     bool inDocument() const { return document->document() && m_inDocument; }
260     bool styleElement() const { return m_styleElement; }
261     bool implicitNode() const { return m_implicit; }
262     void setHasID(bool b=true) { m_hasId = b; }
263     void setHasClass(bool b=true) { m_hasClass = b; }
264     void setHasStyle(bool b=true) { m_hasStyle = b; }
265     void setHasChangedChild( bool b = true ) { m_hasChangedChild = b; }
266     void setInDocument(bool b=true) { m_inDocument = b; }
267     virtual void setFocus(bool b=true) { m_focused = b; }
268     virtual void setActive(bool b=true) { m_active = b; }
269     void setChanged(bool b=true);
270
271     unsigned short tabIndex() const { return m_tabIndex; }
272     void setTabIndex(unsigned short _tabIndex) { m_tabIndex = _tabIndex; }
273
274     /**
275         * whether this node can receive the keyboard focus.
276      */
277     virtual bool isFocusable() const;
278     virtual bool isKeyboardFocusable() const;
279     virtual bool isMouseFocusable() const;
280     
281     virtual bool isInline() const;
282     
283     virtual bool isContentEditable() const;
284     virtual QRect getRect() const;
285
286     enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
287     virtual void recalcStyle( StyleChange = NoChange ) {}
288     StyleChange diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const;
289
290     unsigned long nodeIndex() const;
291     // Returns the document that this node is associated with. This is guaranteed to always be non-null, as opposed to
292     // DOM's ownerDocument() which is null for Document nodes (and sometimes DocumentType nodes).
293     DocumentImpl* getDocument() const { return document->document(); }
294
295     void setDocument(DocumentPtr *doc);
296
297     void addEventListener(const DOMString &, EventListener *listener, bool useCapture);
298     void removeEventListener(const DOMString &, EventListener *listener, bool useCapture);
299
300     void addEventListener(int id, EventListener *listener, bool useCapture);
301     void removeEventListener(int id, EventListener *listener, bool useCapture);
302     void removeHTMLEventListener(int id);
303     void setHTMLEventListener(int id, EventListener *listener);
304     EventListener *getHTMLEventListener(int id);
305     void removeAllEventListeners();
306
307     bool dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false);
308     bool dispatchGenericEvent( EventImpl *evt, int &exceptioncode);
309     bool dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg);
310     bool dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg);
311     bool dispatchMouseEvent(QMouseEvent *e, int overrideId = 0, int overrideDetail = 0);
312     bool dispatchUIEvent(int _id, int detail = 0);
313     bool dispatchSubtreeModifiedEvent(bool childrenChanged = true);
314     bool dispatchKeyEvent(QKeyEvent *key);
315     void dispatchWheelEvent(QWheelEvent *);
316
317     void handleLocalEvents(EventImpl *evt, bool useCapture);
318
319     /**
320      * Perform the default action for an event e.g. submitting a form
321      */
322     virtual void defaultEventHandler(EventImpl *evt);
323
324     /**
325      * Used for disabled form elements; if true, prevents mouse events from being dispatched
326      * to event listeners, and prevents DOMActivate events from being sent at all.
327      */
328     virtual bool disabled() const;
329
330     virtual bool isReadOnly();
331     virtual bool childTypeAllowed( unsigned short /*type*/ ) { return false; }
332     virtual unsigned long childNodeCount() const;
333     virtual NodeImpl *childNode(unsigned long index);
334
335     /**
336      * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that
337      * the tags appear in the source file.
338      *
339      * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to
340      * restrict traversal to a particular sub-tree.
341      *
342      * @return The next node, in document order
343      *
344      * see @ref traversePreviousNode()
345      */
346     NodeImpl *traverseNextNode(const NodeImpl *stayWithin = 0) const;
347     
348     /* Like traverseNextNode, but skips children and starts with the next sibling. */
349     NodeImpl *traverseNextSibling(const NodeImpl *stayWithin = 0) const;
350
351     /**
352      * Does a reverse pre-order traversal to find the node that comes before the current one in document order
353      *
354      * see @ref traverseNextNode()
355      */
356     NodeImpl *traversePreviousNode() const;
357
358     /* Like traversePreviousNode, but visits nodes before their children. */
359     NodeImpl *traversePreviousNodePostOrder(const NodeImpl *stayWithin = 0) const;
360
361     DocumentPtr *docPtr() const { return document; }
362
363     NodeImpl *previousEditable() const;
364     NodeImpl *nextEditable() const;
365     //bool isEditable() const;
366
367     khtml::RenderObject *renderer() const { return m_render; }
368     khtml::RenderObject *nextRenderer();
369     khtml::RenderObject *previousRenderer();
370     void setRenderer(khtml::RenderObject* renderer) { m_render = renderer; }
371     
372     void checkSetPrefix(const DOMString &_prefix, int &exceptioncode);
373     void checkAddChild(NodeImpl *newChild, int &exceptioncode);
374     bool isAncestor(const NodeImpl *) const;
375     virtual bool childAllowed( NodeImpl *newChild );
376
377     virtual long maxOffset() const;
378     long maxDeepOffset() const;
379     virtual long caretMinOffset() const;
380     virtual long caretMaxOffset() const;
381     virtual unsigned long caretMaxRenderedOffset() const;
382
383     virtual long previousOffset (long current) const;
384     virtual long nextOffset (long current) const;
385     
386 #ifndef NDEBUG
387     virtual void dump(QTextStream *stream, QString ind = "") const;
388 #endif
389
390     // -----------------------------------------------------------------------------
391     // Integration with rendering tree
392
393     /**
394      * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
395      * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
396      * makes the node visible in the KHTMLView.
397      */
398     virtual void attach();
399
400     /**
401      * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
402      * the node's rendering object from the rendering tree and delete it.
403      */
404     virtual void detach();
405
406     void createRendererIfNeeded();
407     virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
408     virtual bool rendererIsNeeded(khtml::RenderStyle *);
409     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
410
411     // -----------------------------------------------------------------------------
412     // Methods for maintaining the state of the element between history navigation
413
414     /**
415      * Indicates whether or not this type of node maintains it's state. If so, the state of the node will be stored when
416      * the user goes to a different page using the state() method, and restored using the restoreState() method if the
417      * user returns (e.g. using the back button). This is used to ensure that user-changeable elements such as form
418      * controls maintain their contents when the user returns to a previous page in the history.
419      */
420     virtual bool maintainsState();
421
422     /**
423      * Returns the state of this node represented as a string. This string will be passed to restoreState() if the user
424      * returns to the page.
425      *
426      * @return State information about the node represented as a string
427      */
428     virtual QString state();
429
430     /**
431      * Sets the state of the element based on strings previously returned by state(). This is used to initialize form
432      * controls with their old values when the user returns to the page in their history.  The receiver
433      * should remove the string from the list that it uses for its restore.
434      *
435      * @param states The strings previously returned by nodes' state methods.
436      */
437     virtual void restoreState(QStringList &stateList);
438
439     // -----------------------------------------------------------------------------
440     // Notification of document stucture changes
441
442     /**
443      * Notifies the node that it has been inserted into the document. This is called during document parsing, and also
444      * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
445      * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
446      * the node. The call happens _after_ the node has been added to the tree.
447      *
448      * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
449      * dispatching.
450      */
451     virtual void insertedIntoDocument();
452
453     /**
454      * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
455      * node.
456      *
457      * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
458      * dispatching, and is called _after_ the node is removed from the tree.
459      */
460     virtual void removedFromDocument();
461
462     /**
463      * Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
464      * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
465      */
466     virtual void childrenChanged();
467
468     virtual DOMString toString() const = 0;
469     
470 #ifndef NDEBUG
471     virtual void formatForDebugger(char *buffer, unsigned length) const;
472
473     void displayNode(const char *prefix="");
474     void displayTree();
475 #endif
476
477     void registerNodeList(NodeListImpl *list);
478     void unregisterNodeList(NodeListImpl *list);
479     void notifyNodeListsSubtreeModified();
480     void notifyLocalNodeListsSubtreeModified();
481
482     SharedPtr<NodeListImpl> getElementsByTagName(const DOMString &name) { return getElementsByTagNameNS(DOMString(), name); }
483     SharedPtr<NodeListImpl> getElementsByTagNameNS(const DOMString &namespaceURI, const DOMString &localName);
484
485 private: // members
486     DocumentPtr *document;
487     NodeImpl *m_previous;
488     NodeImpl *m_next;
489 protected:
490     khtml::RenderObject *m_render;
491     QPtrList<RegisteredEventListener> *m_regdListeners;
492     QPtrDict<NodeListImpl> *m_nodeLists;
493
494     unsigned short m_tabIndex : 15;
495     bool m_hasTabIndex  : 1;
496
497     bool m_hasId : 1;
498     bool m_hasClass : 1;
499     bool m_hasStyle : 1;
500     bool m_attached : 1;
501     bool m_changed : 1;
502     bool m_hasChangedChild : 1;
503     bool m_inDocument : 1;
504
505     bool m_isLink : 1;
506     bool m_specified : 1; // used in AttrImpl. Accessor functions there
507     bool m_focused : 1;
508     bool m_active : 1;
509     bool m_styleElement : 1; // contains stylesheet text
510     bool m_implicit : 1; // implicitely generated by the parser
511
512     // 3 bits unused
513 };
514
515 class ContainerNodeImpl : public NodeImpl
516 {
517 public:
518     ContainerNodeImpl(DocumentPtr *doc);
519     virtual ~ContainerNodeImpl();
520
521     // DOM methods overridden from  parent classes
522     virtual NodeImpl *firstChild() const;
523     virtual NodeImpl *lastChild() const;
524     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
525     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
526     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
527     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
528     virtual bool hasChildNodes (  ) const;
529
530     // Other methods (not part of DOM)
531     void removeChildren();
532     void cloneChildNodes(NodeImpl *clone);
533
534     virtual void setFirstChild(NodeImpl *child);
535     virtual void setLastChild(NodeImpl *child);
536     virtual NodeImpl *addChild(NodeImpl *newChild);
537     virtual void attach();
538     virtual void detach();
539
540     virtual QRect getRect() const;
541     bool getUpperLeftCorner(int &xPos, int &yPos) const;
542     bool getLowerRightCorner(int &xPos, int &yPos) const;
543
544     virtual void setFocus(bool=true);
545     virtual void setActive(bool=true);
546     virtual unsigned long childNodeCount() const;
547     virtual NodeImpl *childNode(unsigned long index);
548
549     virtual void insertedIntoDocument();
550     virtual void removedFromDocument();
551     
552 //protected:
553     NodeImpl *_first;
554     NodeImpl *_last;
555
556     // helper functions for inserting children:
557
558     // ### this should vanish. do it in dom/ !
559     // check for same source document:
560     bool checkSameDocument( NodeImpl *newchild, int &exceptioncode );
561     // check for being child:
562     bool checkIsChild( NodeImpl *oldchild, int &exceptioncode );
563     // ###
564
565     // find out if a node is allowed to be our child
566     void dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode );
567     void dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode );
568 };
569
570 // --------------------------------------------------------------------------
571 class Node;
572 class NodeImpl;
573
574 class NodeListImpl : public khtml::Shared<NodeListImpl>
575 {
576 public:
577     NodeListImpl( NodeImpl *_rootNode );
578     virtual ~NodeListImpl();
579
580     MAIN_THREAD_ALLOCATED;
581
582     // DOM methods & attributes for NodeList
583     virtual unsigned long length() const = 0;
584     virtual NodeImpl *item ( unsigned long index ) const = 0;
585     virtual NodeImpl *itemById ( const DOMString & elementId ) const;
586
587     // Other methods (not part of DOM)
588
589     void rootNodeSubtreeModified();
590
591 protected:
592     // helper functions for searching all ElementImpls in a tree
593     unsigned long recursiveLength(NodeImpl *start = 0) const;
594     NodeImpl *recursiveItem ( unsigned long offset, NodeImpl *start = 0 ) const;
595     virtual bool nodeMatches( NodeImpl *testNode ) const = 0;
596
597     NodeImpl *rootNode;
598     mutable int cachedLength;
599     mutable NodeImpl *lastItem;
600     mutable unsigned long lastItemOffset;
601     mutable bool isLengthCacheValid : 1;
602     mutable bool isItemCacheValid : 1;
603 };
604
605 class ChildNodeListImpl : public NodeListImpl
606 {
607 public:
608     ChildNodeListImpl( NodeImpl *n);
609
610     // DOM methods overridden from  parent classes
611
612     virtual unsigned long length() const;
613     virtual NodeImpl *item ( unsigned long index ) const;
614
615 protected:
616     virtual bool nodeMatches( NodeImpl *testNode ) const;
617 };
618
619
620 /**
621  * NodeList which lists all Nodes in a document with a given tag name
622  */
623 class TagNodeListImpl : public NodeListImpl
624 {
625 public:
626     TagNodeListImpl( NodeImpl *n, NodeImpl::Id tagId, NodeImpl::Id tagIdMask );
627
628     // DOM methods overridden from  parent classes
629
630     virtual unsigned long length() const;
631     virtual NodeImpl *item ( unsigned long index ) const;
632
633     // Other methods (not part of DOM)
634
635 protected:
636     virtual bool nodeMatches( NodeImpl *testNode ) const;
637
638     NodeImpl::Id m_id;
639     NodeImpl::Id m_idMask;
640 };
641
642
643 /**
644  * NodeList which lists all Nodes in a Element with a given "name=" tag
645  */
646 class NameNodeListImpl : public NodeListImpl
647 {
648 public:
649     NameNodeListImpl( NodeImpl *doc, const DOMString &t );
650
651     // DOM methods overridden from  parent classes
652
653     virtual unsigned long length() const;
654     virtual NodeImpl *item ( unsigned long index ) const;
655
656     // Other methods (not part of DOM)
657
658 protected:
659     virtual bool nodeMatches( NodeImpl *testNode ) const;
660
661     DOMString nodeName;
662 };
663
664
665 // Generic NamedNodeMap interface
666 // Other classes implement this for more specific situations e.g. attributes
667 // of an element
668 class NamedNodeMapImpl : public khtml::Shared<NamedNodeMapImpl>
669 {
670 public:
671     NamedNodeMapImpl() { }
672     virtual ~NamedNodeMapImpl();
673
674     MAIN_THREAD_ALLOCATED;
675
676     NodeImpl *getNamedItem(const DOMString &name) const { return getNamedItemNS(DOMString(), name); }
677     SharedPtr<NodeImpl> removeNamedItem(const DOMString &name, int &exception) { return removeNamedItemNS(DOMString(), name, exception); }
678
679     NodeImpl *getNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) const;
680     SharedPtr<NodeImpl> setNamedItemNS(NodeImpl *arg, int &exception) { return setNamedItem(arg, exception); }
681     SharedPtr<NodeImpl> removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName, int &exception);
682
683     // DOM methods & attributes for NamedNodeMap
684     virtual NodeImpl *getNamedItem ( NodeImpl::Id id ) const = 0;
685     virtual SharedPtr<NodeImpl> removeNamedItem ( NodeImpl::Id id, int &exceptioncode ) = 0;
686     virtual SharedPtr<NodeImpl> setNamedItem ( NodeImpl* arg, int &exceptioncode ) = 0;
687
688     virtual NodeImpl *item ( unsigned long index ) const = 0;
689     virtual unsigned long length(  ) const = 0;
690
691     // Other methods (not part of DOM)
692     virtual NodeImpl::Id mapId(const DOMString& namespaceURI,  const DOMString& localName,  bool readonly) = 0;
693     virtual bool isReadOnly() { return false; }
694 };
695
696
697 // ### fixme
698 #if 0
699 // Generic read-only NamedNodeMap implementation
700 // You can add items using the internal function addItem()
701 class GenericRONamedNodeMapImpl : public NamedNodeMapImpl
702 {
703 public:
704     GenericRONamedNodeMapImpl(DocumentPtr* doc);
705     virtual ~GenericRONamedNodeMapImpl();
706
707     // DOM methods & attributes for NamedNodeMap
708
709     virtual NodeImpl *getNamedItem ( const DOMString &name, int &exceptioncode ) const;
710     virtual Node setNamedItem ( const Node &arg, int &exceptioncode );
711     virtual Node removeNamedItem ( const DOMString &name, int &exceptioncode );
712     virtual NodeImpl *item ( unsigned long index ) const;
713     virtual unsigned long length(  ) const;
714     virtual NodeImpl *getNamedItemNS( const DOMString &namespaceURI, const DOMString &localName,
715                                       int &exceptioncode ) const;
716     virtual NodeImpl *setNamedItemNS( NodeImpl *arg, int &exceptioncode );
717     virtual NodeImpl *removeNamedItemNS( const DOMString &namespaceURI, const DOMString &localName,
718                                          int &exceptioncode );
719
720     // Other methods (not part of DOM)
721
722     virtual bool isReadOnly() { return true; }
723
724     void addNode(NodeImpl *n);
725
726 protected:
727     DocumentImpl* m_doc;
728     QPtrList<NodeImpl> *m_contents;
729 };
730 #endif
731
732 }; //namespace
733 #endif