Reviewed by Chris Blumenberg.
[WebKit-https.git] / WebCore / khtml / xml / dom_elementimpl.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 Peter Kelly (pmk@post.com)
7  *           (C) 2001 Dirk Mueller (mueller@kde.org)
8  * Copyright (C) 2003 Apple Computer, Inc.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  */
26 #ifndef _DOM_ELEMENTImpl_h_
27 #define _DOM_ELEMENTImpl_h_
28
29 #include "dom_nodeimpl.h"
30 #include "dom/dom_element.h"
31 #include "xml/dom_stringimpl.h"
32 #include "misc/shared.h"
33
34 #if APPLE_CHANGES
35 #ifdef __OBJC__
36 #define id id_AVOID_KEYWORD
37 #endif
38 #endif
39
40 namespace khtml {
41     class CSSStyleSelector;
42 }
43
44 namespace DOM {
45
46 class ElementImpl;
47 class DocumentImpl;
48 class NamedAttrMapImpl;
49 class AtomicStringList;
50
51 // this has no counterpart in DOM, purely internal
52 // representation of the nodevalue of an Attr.
53 // the actual Attr (AttrImpl) with its value as textchild
54 // is only allocated on demand by the DOM bindings.
55 // Any use of AttrImpl inside khtml should be avoided.
56 class AttributeImpl : public khtml::Shared<AttributeImpl>
57 {
58     friend class NamedAttrMapImpl;
59     friend class ElementImpl;
60     friend class AttrImpl;
61
62 public:
63     // null value is forbidden !
64     AttributeImpl(NodeImpl::Id id, const AtomicString& value)
65         : m_id(id), _value(value), _impl(0)
66         { };
67     virtual ~AttributeImpl() {};
68     
69     MAIN_THREAD_ALLOCATED;
70
71     const AtomicString& value() const { return _value; }
72     const AtomicString& prefix() const { return _prefix; }
73     NodeImpl::Id id() const { return m_id; }
74     AttrImpl* attrImpl() const { return _impl; }
75
76     bool isNull() const { return _value.isNull(); }
77     bool isEmpty() const { return _value.isEmpty(); }
78     
79     virtual AttributeImpl* clone(bool preserveDecl=true) const;
80
81 private:
82     void setValue(const AtomicString& value) {
83         _value = value;
84     }
85     void setPrefix(const AtomicString& prefix) {
86         _prefix = prefix;
87     }
88     void allocateImpl(ElementImpl* e);
89
90 protected:
91     NodeImpl::Id m_id;
92     AtomicString _prefix;
93     AtomicString _value;
94     AttrImpl* _impl;
95 };
96
97 // Attr can have Text and EntityReference children
98 // therefore it has to be a fullblown Node. The plan
99 // is to dynamically allocate a textchild and store the
100 // resulting nodevalue in the AttributeImpl upon
101 // destruction. however, this is not yet implemented.
102 class AttrImpl : public NodeBaseImpl
103 {
104     friend class ElementImpl;
105     friend class NamedAttrMapImpl;
106
107 public:
108     AttrImpl(ElementImpl* element, DocumentPtr* docPtr, AttributeImpl* a);
109     ~AttrImpl();
110
111 private:
112     AttrImpl(const AttrImpl &other);
113     AttrImpl &operator = (const AttrImpl &other);
114 public:
115
116     // DOM methods & attributes for Attr
117     bool specified() const { return m_specified; }
118     ElementImpl* ownerElement() const { return m_element; }
119     AttributeImpl* attrImpl() const { return m_attribute; }
120
121     //DOMString value() const;
122     void setValue( const DOMString &v, int &exceptioncode );
123
124     // DOM methods overridden from  parent classes
125     virtual DOMString nodeName() const;
126     virtual unsigned short nodeType() const;
127     virtual DOMString prefix() const;
128     virtual void setPrefix(const DOMString &_prefix, int &exceptioncode );
129
130     virtual DOMString nodeValue() const;
131     virtual void setNodeValue( const DOMString &, int &exceptioncode );
132     virtual NodeImpl *cloneNode ( bool deep );
133
134     // Other methods (not part of DOM)
135     virtual bool isAttributeNode() const { return true; }
136     virtual bool childAllowed( NodeImpl *newChild );
137     virtual bool childTypeAllowed( unsigned short type );
138
139     virtual DOMString toString() const;
140
141 #if APPLE_CHANGES
142     static Attr createInstance(AttrImpl *impl);
143 #endif
144
145 protected:
146     ElementImpl* m_element;
147     AttributeImpl* m_attribute;
148 };
149
150
151 class ElementImpl : public NodeBaseImpl
152 {
153     friend class DocumentImpl;
154     friend class NamedAttrMapImpl;
155     friend class AttrImpl;
156     friend class NodeImpl;
157     friend class khtml::CSSStyleSelector;
158 public:
159     ElementImpl(DocumentPtr *doc);
160     ~ElementImpl();
161
162     // Used to quickly determine whether or not an element has a given CSS class.
163     virtual const AtomicStringList* getClassList() const;
164     const AtomicString& getIDAttribute() const;
165     const AtomicString& getAttribute( NodeImpl::Id id ) const;
166     const AtomicString& getAttribute(const DOMString& localName) const { return getAttributeNS(QString::null, localName); }
167     const AtomicString& getAttributeNS(const DOMString &namespaceURI,
168                                        const DOMString &localName) const;
169     void setAttribute( NodeImpl::Id id, DOMStringImpl* value, int &exceptioncode );
170     void removeAttribute( NodeImpl::Id id, int &exceptioncode );
171     bool hasAttributes() const;
172     
173     DOMString prefix() const { return m_prefix; }
174     void setPrefix(const DOMString &_prefix, int &exceptioncode );
175
176     // DOM methods overridden from  parent classes
177     virtual DOMString tagName() const;
178     virtual unsigned short nodeType() const;
179     virtual NodeImpl *cloneNode ( bool deep ) = 0;
180     virtual DOMString nodeName() const;
181     virtual bool isElementNode() const { return true; }
182     virtual void insertedIntoDocument();
183     virtual void removedFromDocument();
184
185     // convenience methods which ignore exceptions
186     void setAttribute (NodeImpl::Id id, const DOMString &value);
187
188     NamedAttrMapImpl* attributes(bool readonly = false) const;
189
190     // This method is called whenever an attribute is added, changed or removed.
191     virtual void attributeChanged(AttributeImpl* attr, bool preserveDecls = false) {}
192
193     // not part of the DOM
194     void setAttributeMap ( NamedAttrMapImpl* list );
195
196     // State of the element.
197     virtual QString state() { return QString::null; }
198
199     virtual void attach();
200     virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
201     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
202     virtual void recalcStyle( StyleChange = NoChange );
203
204     virtual void mouseEventHandler( MouseEvent */*ev*/, bool /*inside*/ ) {};
205     virtual bool childAllowed( NodeImpl *newChild );
206     virtual bool childTypeAllowed( unsigned short type );
207  
208     virtual AttributeImpl* createAttribute(NodeImpl::Id id, DOMStringImpl* value);
209     
210     void dispatchAttrRemovalEvent(AttributeImpl *attr);
211     void dispatchAttrAdditionEvent(AttributeImpl *attr);
212
213     virtual void accessKeyAction(bool sendToAnyEvent) { };
214
215     virtual DOMString toString() const;
216
217     virtual bool isURLAttribute(AttributeImpl *attr) const;
218     
219 #ifndef NDEBUG
220     virtual void dump(QTextStream *stream, QString ind = "") const;
221 #endif
222
223 #if APPLE_CHANGES
224     static Element createInstance(ElementImpl *impl);
225 #endif
226
227 #ifndef NDEBUG
228     virtual void formatForDebugger(char *buffer, unsigned length) const;
229 #endif
230
231 protected:
232     virtual void createAttributeMap() const;
233     DOMString openTagStartToString() const;
234
235 private:
236     void updateId(const AtomicString& oldId, const AtomicString& newId);
237
238     virtual void updateStyleAttributeIfNeeded() const {};
239
240 protected: // member variables
241     mutable NamedAttrMapImpl *namedAttrMap;
242     DOMStringImpl *m_prefix;
243 };
244
245
246 class XMLElementImpl : public ElementImpl
247 {
248
249 public:
250     XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_tagName);
251     XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_qualifiedName, DOMStringImpl *_namespaceURI);
252     ~XMLElementImpl();
253
254     // DOM methods overridden from  parent classes
255     virtual DOMString namespaceURI() const;
256     virtual DOMString localName() const;
257     virtual NodeImpl *cloneNode ( bool deep );
258
259     // Other methods (not part of DOM)
260     virtual bool isXMLElementNode() const { return true; }
261     virtual Id id() const { return m_id; }
262
263 protected:
264     Id m_id;
265 };
266
267 // the map of attributes of an element
268 class NamedAttrMapImpl : public NamedNodeMapImpl
269 {
270     friend class ElementImpl;
271 public:
272     NamedAttrMapImpl(ElementImpl *e);
273     virtual ~NamedAttrMapImpl();
274     NamedAttrMapImpl(const NamedAttrMapImpl&);
275     NamedAttrMapImpl &operator =(const NamedAttrMapImpl &other);
276
277     // DOM methods & attributes for NamedNodeMap
278     virtual AttrImpl *getNamedItem ( NodeImpl::Id id ) const;
279     virtual Node removeNamedItem ( NodeImpl::Id id, int &exceptioncode );
280     virtual Node setNamedItem ( NodeImpl* arg, int &exceptioncode );
281
282
283     virtual AttrImpl *item ( unsigned long index ) const;
284     unsigned long length() const { return len; }
285
286     // Other methods (not part of DOM)
287     virtual NodeImpl::Id mapId(const DOMString& namespaceURI,  const DOMString& localName,  bool readonly);
288     AttributeImpl* attributeItem(unsigned long index) const { return attrs ? attrs[index] : 0; }
289     AttributeImpl* getAttributeItem(NodeImpl::Id id) const;
290     virtual bool isReadOnly() { return element ? element->isReadOnly() : false; }
291
292     // used during parsing: only inserts if not already there
293     // no error checking!
294     void insertAttribute(AttributeImpl* newAttribute) {
295         if (!getAttributeItem(newAttribute->id()))
296             addAttribute(newAttribute);
297         else
298             newAttribute->deref();
299     }
300
301     virtual bool isHTMLAttributeMap() const;
302
303     const AtomicString& id() const { return m_id; }
304     void setID(const AtomicString& _id) { m_id = _id; }
305     
306 protected:
307     // this method is internal, does no error checking at all
308     void addAttribute(AttributeImpl* newAttribute);
309     // this method is internal, does no error checking at all
310     void removeAttribute(NodeImpl::Id id);
311     virtual void clearAttributes();
312     void detachFromElement();
313
314 protected:
315     ElementImpl *element;
316     AttributeImpl **attrs;
317     uint len;
318     AtomicString m_id;
319 };
320
321 }; //namespace
322
323 #if APPLE_CHANGES
324 #undef id
325 #endif
326
327 #endif