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