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