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