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