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_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     void removeAllEventListeners();
281
282     bool dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent = false);
283     bool dispatchGenericEvent( EventImpl *evt, int &exceptioncode);
284     bool dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg);
285     bool dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg);
286     bool dispatchMouseEvent(QMouseEvent *e, int overrideId = 0, int overrideDetail = 0);
287     bool dispatchUIEvent(int _id, int detail = 0);
288     bool dispatchSubtreeModifiedEvent(bool childrenChanged = true);
289     bool dispatchKeyEvent(QKeyEvent *key);
290
291     void handleLocalEvents(EventImpl *evt, bool useCapture);
292
293     /**
294      * Perform the default action for an event e.g. submitting a form
295      */
296     virtual void defaultEventHandler(EventImpl *evt);
297
298     /**
299      * Used for disabled form elements; if true, prevents mouse events from being dispatched
300      * to event listeners, and prevents DOMActivate events from being sent at all.
301      */
302     virtual bool disabled() const;
303
304     virtual bool isReadOnly();
305     virtual bool childTypeAllowed( unsigned short /*type*/ ) { return false; }
306     virtual unsigned long childNodeCount() const;
307     virtual NodeImpl *childNode(unsigned long index);
308
309     /**
310      * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that
311      * the tags appear in the source file.
312      *
313      * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to
314      * restrict traversal to a particular sub-tree.
315      *
316      * @return The next node, in document order
317      *
318      * see @ref traversePreviousNode()
319      */
320     NodeImpl *traverseNextNode(const NodeImpl *stayWithin = 0) const;
321     
322     /* Like traverseNextNode, but skips children and starts with the next sibling. */
323     NodeImpl *traverseNextSibling(const NodeImpl *stayWithin = 0) const;
324
325     /**
326      * Does a reverse pre-order traversal to find the node that comes before the current one in document order
327      *
328      * see @ref traverseNextNode()
329      */
330     NodeImpl *traversePreviousNode() const;
331
332     /* Like traversePreviousNode, but visits nodes before their children. */
333     NodeImpl *traversePreviousNodePostOrder(const NodeImpl *stayWithin = 0) const;
334
335     DocumentPtr *docPtr() const { return document; }
336
337     NodeImpl *previousEditable() const;
338     NodeImpl *nextEditable() const;
339     //bool isEditable() const;
340
341     khtml::RenderObject *renderer() const { return m_render; }
342     khtml::RenderObject *nextRenderer();
343     khtml::RenderObject *previousRenderer();
344     void setRenderer(khtml::RenderObject* renderer) { m_render = renderer; }
345     
346     void checkSetPrefix(const DOMString &_prefix, int &exceptioncode);
347     void checkAddChild(NodeImpl *newChild, int &exceptioncode);
348     bool isAncestor(const NodeImpl *) const;
349     virtual bool childAllowed( NodeImpl *newChild );
350
351     virtual long maxOffset() const;
352     virtual long caretMinOffset() const;
353     virtual long caretMaxOffset() const;
354     virtual unsigned long caretMaxRenderedOffset() const;
355
356     virtual long previousOffset (long current) const;
357     virtual long nextOffset (long current) const;
358     
359 #ifndef NDEBUG
360     virtual void dump(QTextStream *stream, QString ind = "") const;
361 #endif
362
363     // -----------------------------------------------------------------------------
364     // Integration with rendering tree
365
366     /**
367      * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
368      * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
369      * makes the node visible in the KHTMLView.
370      */
371     virtual void attach();
372
373     /**
374      * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
375      * the node's rendering object from the rendering tree and delete it.
376      */
377     virtual void detach();
378
379     void createRendererIfNeeded();
380     virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
381     virtual bool rendererIsNeeded(khtml::RenderStyle *);
382     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
383
384     // -----------------------------------------------------------------------------
385     // Methods for maintaining the state of the element between history navigation
386
387     /**
388      * Indicates whether or not this type of node maintains it's state. If so, the state of the node will be stored when
389      * the user goes to a different page using the state() method, and restored using the restoreState() method if the
390      * user returns (e.g. using the back button). This is used to ensure that user-changeable elements such as form
391      * controls maintain their contents when the user returns to a previous page in the history.
392      */
393     virtual bool maintainsState();
394
395     /**
396      * Returns the state of this node represented as a string. This string will be passed to restoreState() if the user
397      * returns to the page.
398      *
399      * @return State information about the node represented as a string
400      */
401     virtual QString state();
402
403     /**
404      * Sets the state of the element based on strings previously returned by state(). This is used to initialize form
405      * controls with their old values when the user returns to the page in their history.  The receiver
406      * should remove the string from the list that it uses for its restore.
407      *
408      * @param states The strings previously returned by nodes' state methods.
409      */
410     virtual void restoreState(QStringList &stateList);
411
412     // -----------------------------------------------------------------------------
413     // Notification of document stucture changes
414
415     /**
416      * Notifies the node that it has been inserted into the document. This is called during document parsing, and also
417      * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
418      * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
419      * the node. The call happens _after_ the node has been added to the tree.
420      *
421      * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
422      * dispatching.
423      */
424     virtual void insertedIntoDocument();
425
426     /**
427      * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
428      * node.
429      *
430      * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
431      * dispatching, and is called _after_ the node is removed from the tree.
432      */
433     virtual void removedFromDocument();
434
435     /**
436      * Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
437      * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
438      */
439     virtual void childrenChanged();
440
441     virtual DOMString toString() const = 0;
442     
443 #ifndef NDEBUG
444     virtual void formatForDebugger(char *buffer, unsigned length) const;
445
446     void displayNode(const char *prefix="");
447     void displayTree();
448 #endif
449
450     void registerNodeList(NodeListImpl *list);
451     void unregisterNodeList(NodeListImpl *list);
452     void notifyNodeListsSubtreeModified();
453     void notifyLocalNodeListsSubtreeModified();
454
455 private: // members
456     DocumentPtr *document;
457     NodeImpl *m_previous;
458     NodeImpl *m_next;
459 protected:
460     khtml::RenderObject *m_render;
461     QPtrList<RegisteredEventListener> *m_regdListeners;
462     QPtrDict<NodeListImpl> *m_nodeLists;
463
464     unsigned short m_tabIndex : 15;
465     bool m_hasTabIndex  : 1;
466
467     bool m_hasId : 1;
468     bool m_hasClass : 1;
469     bool m_hasStyle : 1;
470     bool m_attached : 1;
471     bool m_changed : 1;
472     bool m_hasChangedChild : 1;
473     bool m_inDocument : 1;
474
475     bool m_hasAnchor : 1;
476     bool m_specified : 1; // used in AttrImpl. Accessor functions there
477     bool m_focused : 1;
478     bool m_active : 1;
479     bool m_styleElement : 1; // contains stylesheet text
480     bool m_implicit : 1; // implicitely generated by the parser
481
482     // 3 bits unused
483 };
484
485 // this is the full Node Implementation with parents and children.
486 class NodeBaseImpl : public NodeImpl
487 {
488 public:
489     NodeBaseImpl(DocumentPtr *doc);
490     virtual ~NodeBaseImpl();
491
492     // DOM methods overridden from  parent classes
493     virtual NodeImpl *firstChild() const;
494     virtual NodeImpl *lastChild() const;
495     virtual NodeImpl *insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode );
496     virtual NodeImpl *replaceChild ( NodeImpl *newChild, NodeImpl *oldChild, int &exceptioncode );
497     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
498     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
499     virtual bool hasChildNodes (  ) const;
500
501     // Other methods (not part of DOM)
502     void removeChildren();
503     void cloneChildNodes(NodeImpl *clone);
504
505     virtual void setFirstChild(NodeImpl *child);
506     virtual void setLastChild(NodeImpl *child);
507     virtual NodeImpl *addChild(NodeImpl *newChild);
508     virtual void attach();
509     virtual void detach();
510
511     virtual NodeListImpl *getElementsByTagNameNS ( DOMStringImpl* namespaceURI,
512                                                    DOMStringImpl* localName );
513
514     virtual QRect getRect() const;
515     bool getUpperLeftCorner(int &xPos, int &yPos) const;
516     bool getLowerRightCorner(int &xPos, int &yPos) const;
517
518     virtual void setFocus(bool=true);
519     virtual void setActive(bool=true);
520     virtual unsigned long childNodeCount() const;
521     virtual NodeImpl *childNode(unsigned long index);
522
523     virtual void insertedIntoDocument();
524     virtual void removedFromDocument();
525     
526     // check for being (grand-..)father:
527     bool checkNoOwner( NodeImpl *other, int &exceptioncode );
528
529 //protected:
530     NodeImpl *_first;
531     NodeImpl *_last;
532
533     // helper functions for inserting children:
534
535     // ### this should vanish. do it in dom/ !
536     // check for same source document:
537     bool checkSameDocument( NodeImpl *newchild, int &exceptioncode );
538     // check for being child:
539     bool checkIsChild( NodeImpl *oldchild, int &exceptioncode );
540     // ###
541
542     // find out if a node is allowed to be our child
543     void dispatchChildInsertedEvents( NodeImpl *child, int &exceptioncode );
544     void dispatchChildRemovalEvents( NodeImpl *child, int &exceptioncode );
545 };
546
547 // --------------------------------------------------------------------------
548 class Node;
549 class NodeImpl;
550
551 class NodeListImpl : public khtml::Shared<NodeListImpl>
552 {
553 public:
554     NodeListImpl( NodeImpl *_rootNode );
555     virtual ~NodeListImpl();
556
557     // DOM methods & attributes for NodeList
558     virtual unsigned long length() const = 0;
559     virtual NodeImpl *item ( unsigned long index ) const = 0;
560     virtual NodeImpl *itemById ( const DOMString & elementId ) const;
561
562     // Other methods (not part of DOM)
563
564     void rootNodeSubtreeModified();
565
566 #if APPLE_CHANGES
567     static NodeList createInstance(NodeListImpl *impl);
568 #endif
569 protected:
570     // helper functions for searching all ElementImpls in a tree
571     unsigned long recursiveLength(NodeImpl *start = 0) const;
572     NodeImpl *recursiveItem ( unsigned long offset, NodeImpl *start = 0 ) const;
573     virtual bool nodeMatches( NodeImpl *testNode ) const = 0;
574
575     NodeImpl *rootNode;
576     mutable int cachedLength;
577     mutable NodeImpl *lastItem;
578     mutable unsigned long lastItemOffset;
579     mutable bool isLengthCacheValid : 1;
580     mutable bool isItemCacheValid : 1;
581 };
582
583 class ChildNodeListImpl : public NodeListImpl
584 {
585 public:
586     ChildNodeListImpl( NodeImpl *n);
587
588     // DOM methods overridden from  parent classes
589
590     virtual unsigned long length() const;
591     virtual NodeImpl *item ( unsigned long index ) const;
592
593 protected:
594     virtual bool nodeMatches( NodeImpl *testNode ) const;
595 };
596
597
598 /**
599  * NodeList which lists all Nodes in a document with a given tag name
600  */
601 class TagNodeListImpl : public NodeListImpl
602 {
603 public:
604     TagNodeListImpl( NodeImpl *n, NodeImpl::Id tagId, NodeImpl::Id tagIdMask );
605
606     // DOM methods overridden from  parent classes
607
608     virtual unsigned long length() const;
609     virtual NodeImpl *item ( unsigned long index ) const;
610
611     // Other methods (not part of DOM)
612
613 protected:
614     virtual bool nodeMatches( NodeImpl *testNode ) const;
615
616     NodeImpl::Id m_id;
617     NodeImpl::Id m_idMask;
618 };
619
620
621 /**
622  * NodeList which lists all Nodes in a Element with a given "name=" tag
623  */
624 class NameNodeListImpl : public NodeListImpl
625 {
626 public:
627     NameNodeListImpl( NodeImpl *doc, const DOMString &t );
628
629     // DOM methods overridden from  parent classes
630
631     virtual unsigned long length() const;
632     virtual NodeImpl *item ( unsigned long index ) const;
633
634     // Other methods (not part of DOM)
635
636 protected:
637     virtual bool nodeMatches( NodeImpl *testNode ) const;
638
639     DOMString nodeName;
640 };
641
642
643 // Generic NamedNodeMap interface
644 // Other classes implement this for more specific situations e.g. attributes
645 // of an element
646 class NamedNodeMapImpl : public khtml::Shared<NamedNodeMapImpl>
647 {
648 public:
649     NamedNodeMapImpl();
650     virtual ~NamedNodeMapImpl();
651
652     // DOM methods & attributes for NamedNodeMap
653     virtual NodeImpl *getNamedItem ( NodeImpl::Id id ) const = 0;
654     virtual Node removeNamedItem ( NodeImpl::Id id, int &exceptioncode ) = 0;
655     virtual Node setNamedItem ( NodeImpl* arg, int &exceptioncode ) = 0;
656
657     virtual NodeImpl *item ( unsigned long index ) const = 0;
658     virtual unsigned long length(  ) const = 0;
659
660     // Other methods (not part of DOM)
661     virtual NodeImpl::Id mapId(const DOMString& namespaceURI,  const DOMString& localName,  bool readonly) = 0;
662     virtual bool isReadOnly() { return false; }
663
664 #if APPLE_CHANGES
665     static NamedNodeMap createInstance(NamedNodeMapImpl *impl);
666 #endif
667 };
668
669
670 // ### fixme
671 #if 0
672 // Generic read-only NamedNodeMap implementation
673 // You can add items using the internal function addItem()
674 class GenericRONamedNodeMapImpl : public NamedNodeMapImpl
675 {
676 public:
677     GenericRONamedNodeMapImpl(DocumentPtr* doc);
678     virtual ~GenericRONamedNodeMapImpl();
679
680     // DOM methods & attributes for NamedNodeMap
681
682     virtual NodeImpl *getNamedItem ( const DOMString &name, int &exceptioncode ) const;
683     virtual Node setNamedItem ( const Node &arg, int &exceptioncode );
684     virtual Node removeNamedItem ( const DOMString &name, int &exceptioncode );
685     virtual NodeImpl *item ( unsigned long index ) const;
686     virtual unsigned long length(  ) const;
687     virtual NodeImpl *getNamedItemNS( const DOMString &namespaceURI, const DOMString &localName,
688                                       int &exceptioncode ) const;
689     virtual NodeImpl *setNamedItemNS( NodeImpl *arg, int &exceptioncode );
690     virtual NodeImpl *removeNamedItemNS( const DOMString &namespaceURI, const DOMString &localName,
691                                          int &exceptioncode );
692
693     // Other methods (not part of DOM)
694
695     virtual bool isReadOnly() { return true; }
696
697     void addNode(NodeImpl *n);
698
699 protected:
700     DocumentImpl* m_doc;
701     QPtrList<NodeImpl> *m_contents;
702 };
703 #endif
704
705 }; //namespace
706 #endif