7604b3f8551a850c159661a50574663bceda3111
[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 "xml/dom_stringimpl.h"
31 #include "misc/shared.h"
32 #include "css/css_valueimpl.h"
33 #include "dom_qname.h"
34
35 #if APPLE_CHANGES
36 #ifdef __OBJC__
37 #define id id_AVOID_KEYWORD
38 #endif
39 #endif
40
41 #include "dom_atomicstringlist.h"
42
43 namespace khtml {
44     class CSSStyleSelector;
45 }
46
47 namespace DOM {
48
49 class AtomicStringList;
50 class DocumentImpl;
51 class CSSStyleDeclarationImpl;
52 class ElementImpl;
53 class NamedAttrMapImpl;
54
55 // this has no counterpart in DOM, purely internal
56 // representation of the nodevalue of an Attr.
57 // the actual Attr (AttrImpl) with its value as textchild
58 // is only allocated on demand by the DOM bindings.
59 // Any use of AttrImpl inside khtml should be avoided.
60 class AttributeImpl : public khtml::Shared<AttributeImpl>
61 {
62     friend class NamedAttrMapImpl;
63     friend class ElementImpl;
64     friend class AttrImpl;
65
66 public:
67     // null value is forbidden !
68     AttributeImpl(NodeImpl::Id id, const AtomicString& value)
69         : m_id(id), _value(value), _impl(0)
70         { };
71     virtual ~AttributeImpl() {};
72     
73     MAIN_THREAD_ALLOCATED;
74
75     const AtomicString& value() const { return _value; }
76     const AtomicString& prefix() const { return _prefix; }
77     NodeImpl::Id id() const { return m_id; }
78     AttrImpl* attrImpl() const { return _impl; }
79
80     bool isNull() const { return _value.isNull(); }
81     bool isEmpty() const { return _value.isEmpty(); }
82     
83     virtual AttributeImpl* clone(bool preserveDecl=true) const;
84
85 private:
86     void setValue(const AtomicString& value) {
87         _value = value;
88     }
89     void setPrefix(const AtomicString& prefix) {
90         _prefix = prefix;
91     }
92     void allocateImpl(ElementImpl* e);
93
94 protected:
95     NodeImpl::Id m_id;
96     AtomicString _prefix;
97     AtomicString _value;
98     AttrImpl* _impl;
99 };
100
101 // Attr can have Text and EntityReference children
102 // therefore it has to be a fullblown Node. The plan
103 // is to dynamically allocate a textchild and store the
104 // resulting nodevalue in the AttributeImpl upon
105 // destruction. however, this is not yet implemented.
106 class AttrImpl : public ContainerNodeImpl
107 {
108     friend class ElementImpl;
109     friend class NamedAttrMapImpl;
110
111 public:
112     AttrImpl(ElementImpl* element, DocumentPtr* docPtr, AttributeImpl* a);
113     ~AttrImpl();
114
115 private:
116     AttrImpl(const AttrImpl &other);
117     AttrImpl &operator = (const AttrImpl &other);
118 public:
119
120     // DOM methods & attributes for Attr
121     DOMString name() const;
122     bool specified() const { return m_specified; }
123     ElementImpl* ownerElement() const { return m_element; }
124     AttributeImpl* attrImpl() const { return m_attribute; }
125
126     DOMString value() const;
127     void setValue( const DOMString &v, int &exceptioncode );
128
129     // DOM methods overridden from  parent classes
130     virtual DOMString nodeName() const;
131     virtual unsigned short nodeType() const;
132     virtual const AtomicString& prefix() const;
133     virtual void setPrefix(const AtomicString &_prefix, int &exceptioncode );
134
135     virtual DOMString nodeValue() const;
136     virtual void setNodeValue( const DOMString &, int &exceptioncode );
137     virtual NodeImpl *cloneNode ( bool deep );
138
139     // Other methods (not part of DOM)
140     virtual bool isAttributeNode() const { return true; }
141     virtual bool childAllowed( NodeImpl *newChild );
142     virtual bool childTypeAllowed( unsigned short type );
143
144     virtual DOMString toString() const;
145
146 protected:
147     ElementImpl* m_element;
148     AttributeImpl* m_attribute;
149 };
150
151
152 class ElementImpl : public ContainerNodeImpl
153 {
154     friend class DocumentImpl;
155     friend class NamedAttrMapImpl;
156     friend class AttrImpl;
157     friend class NodeImpl;
158     friend class khtml::CSSStyleSelector;
159 public:
160     ElementImpl(const QualifiedName& tagName, DocumentPtr *doc);
161     ~ElementImpl();
162
163     // Used to quickly determine whether or not an element has a given CSS class.
164     virtual const AtomicStringList* getClassList() const;
165     const AtomicString& getIDAttribute() const;
166     const AtomicString& getAttribute(Id id ) const;
167     void setAttribute( Id id, DOMStringImpl* value, int &exceptioncode );
168     void removeAttribute( Id id, int &exceptioncode );
169
170     bool hasAttributes() const;
171
172     bool hasAttribute(const DOMString &name) const { return hasAttributeNS(DOMString(), name); }
173     bool hasAttributeNS(const DOMString &namespaceURI, const DOMString &localName) const;
174
175     const AtomicString& getAttribute(const DOMString& name) const { return getAttributeNS(DOMString(), name); }
176     const AtomicString& getAttributeNS(const DOMString &namespaceURI, const DOMString &localName) const;
177
178     void setAttribute(const DOMString &name, const DOMString &value, int &exception) { setAttributeNS(DOMString(), name, value, exception); }
179     void setAttributeNS(const DOMString &namespaceURI, const DOMString &qualifiedName, const DOMString &value, int &exception);
180
181     void removeAttribute(const DOMString &name, int &exception) { removeAttributeNS(DOMString(), name, exception); }
182     void removeAttributeNS(const DOMString &namespaceURI, const DOMString &localName, int &exception);
183
184     AttrImpl *getAttributeNode(const DOMString &name) { return getAttributeNodeNS(DOMString(), name); }
185     AttrImpl *getAttributeNodeNS(const DOMString &namespaceURI, const DOMString &localName);
186     SharedPtr<AttrImpl> setAttributeNode(AttrImpl *newAttr, int &exception);
187     SharedPtr<AttrImpl> setAttributeNodeNS(AttrImpl *newAttr, int &exception) { return setAttributeNode(newAttr, exception); }
188     SharedPtr<AttrImpl> removeAttributeNode(AttrImpl *oldAttr, int &exception);
189     
190     virtual CSSStyleDeclarationImpl *style();
191
192     virtual const QualifiedName& tagName() const { return m_tagName; }
193     virtual bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
194     
195     // A fast function for checking the local name against another atomic string.
196     bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
197     bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
198
199     virtual const AtomicString& localName() const { return m_tagName.localName(); }
200     virtual const AtomicString& prefix() const { return m_tagName.prefix(); }
201     virtual void setPrefix(const AtomicString &_prefix, int &exceptioncode);
202     virtual const AtomicString& namespaceURI() const { return m_tagName.namespaceURI(); }
203     
204     // DOM methods overridden from  parent classes
205     virtual unsigned short nodeType() const;
206     virtual NodeImpl *cloneNode(bool deep);
207     virtual DOMString nodeName() const;
208     virtual bool isElementNode() const { return true; }
209     virtual void insertedIntoDocument();
210     virtual void removedFromDocument();
211
212     // convenience methods which ignore exceptions
213     void setAttribute(Id id, const DOMString &value);
214
215     virtual NamedAttrMapImpl *attributes() const;
216     NamedAttrMapImpl* attributes(bool readonly) const;
217
218     // This method is called whenever an attribute is added, changed or removed.
219     virtual void attributeChanged(AttributeImpl* attr, bool preserveDecls = false) {}
220
221     // not part of the DOM
222     void setAttributeMap ( NamedAttrMapImpl* list );
223
224     // State of the element.
225     virtual QString state() { return QString::null; }
226
227     virtual void attach();
228     virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
229     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
230     virtual void recalcStyle( StyleChange = NoChange );
231
232     virtual void mouseEventHandler( MouseEvent */*ev*/, bool /*inside*/ ) {};
233     virtual bool childTypeAllowed( unsigned short type );
234  
235     virtual AttributeImpl* createAttribute(Id id, DOMStringImpl* value);
236     
237     void dispatchAttrRemovalEvent(AttributeImpl *attr);
238     void dispatchAttrAdditionEvent(AttributeImpl *attr);
239
240     virtual void accessKeyAction(bool sendToAnyEvent) { };
241
242     virtual DOMString toString() const;
243
244     virtual bool isURLAttribute(AttributeImpl *attr) const;
245     
246 #ifndef NDEBUG
247     virtual void dump(QTextStream *stream, QString ind = "") const;
248 #endif
249
250 #ifndef NDEBUG
251     virtual void formatForDebugger(char *buffer, unsigned length) const;
252 #endif
253
254 protected:
255     virtual void createAttributeMap() const;
256     DOMString openTagStartToString() const;
257
258 private:
259     void updateId(const AtomicString& oldId, const AtomicString& newId);
260
261     virtual void updateStyleAttributeIfNeeded() const {};
262
263 protected: // member variables
264     mutable NamedAttrMapImpl *namedAttrMap;
265     QualifiedName m_tagName;
266 };
267
268 // the map of attributes of an element
269 class NamedAttrMapImpl : public NamedNodeMapImpl
270 {
271     friend class ElementImpl;
272 public:
273     NamedAttrMapImpl(ElementImpl *e);
274     virtual ~NamedAttrMapImpl();
275     NamedAttrMapImpl(const NamedAttrMapImpl&);
276     NamedAttrMapImpl &operator =(const NamedAttrMapImpl &other);
277
278     // DOM methods & attributes for NamedNodeMap
279     virtual AttrImpl *getNamedItem ( NodeImpl::Id id ) const;
280
281     virtual SharedPtr<NodeImpl> removeNamedItem ( NodeImpl::Id id, int &exceptioncode );
282     virtual SharedPtr<NodeImpl> setNamedItem ( NodeImpl* arg, int &exceptioncode );
283
284     virtual AttrImpl *item ( unsigned long index ) const;
285     unsigned long length() const { return len; }
286
287     // Other methods (not part of DOM)
288     virtual NodeImpl::Id mapId(const DOMString& namespaceURI,  const DOMString& localName,  bool readonly);
289     AttributeImpl* attributeItem(unsigned long index) const { return attrs ? attrs[index] : 0; }
290     AttributeImpl* getAttributeItem(NodeImpl::Id id) const;
291     virtual bool isReadOnly() { return element ? element->isReadOnly() : false; }
292
293     // used during parsing: only inserts if not already there
294     // no error checking!
295     void insertAttribute(AttributeImpl* newAttribute) {
296         if (!getAttributeItem(newAttribute->id()))
297             addAttribute(newAttribute);
298         else
299             newAttribute->deref();
300     }
301
302     virtual bool isMappedAttributeMap() const;
303
304     const AtomicString& id() const { return m_id; }
305     void setID(const AtomicString& _id) { m_id = _id; }
306     
307 protected:
308     // this method is internal, does no error checking at all
309     void addAttribute(AttributeImpl* newAttribute);
310     // this method is internal, does no error checking at all
311     void removeAttribute(NodeImpl::Id id);
312     virtual void clearAttributes();
313     void detachFromElement();
314
315 protected:
316     ElementImpl *element;
317     AttributeImpl **attrs;
318     uint len;
319     AtomicString m_id;
320 };
321
322 // When adding new entries, make sure to keep eLastEntry at the end of the list.
323 enum MappedAttributeEntry { eNone, eUniversal, ePersistent, eReplaced, eBlock, eHR, eUnorderedList, eListItem,
324     eTable, eCell, eCaption, eMarquee, eLastEntry };
325
326 class CSSMappedAttributeDeclarationImpl : public CSSMutableStyleDeclarationImpl
327 {
328 public:
329     CSSMappedAttributeDeclarationImpl(CSSRuleImpl *parentRule)
330     : CSSMutableStyleDeclarationImpl(parentRule), m_entryType(eNone), m_attrName(0)
331     {}
332     
333     virtual ~CSSMappedAttributeDeclarationImpl();
334
335     void setMappedState(MappedAttributeEntry type, NodeImpl::Id attr, const AtomicString& val)
336     {
337         m_entryType = type;
338         m_attrName = attr;
339         m_attrValue = val;
340     }
341
342 private:
343     MappedAttributeEntry m_entryType;
344     NodeImpl::Id m_attrName;
345     AtomicString m_attrValue;
346 };
347
348 class MappedAttributeImpl : public AttributeImpl
349 {
350 public:
351     MappedAttributeImpl(NodeImpl::Id _id, const AtomicString& value, CSSMappedAttributeDeclarationImpl* decl = 0)
352     : AttributeImpl(_id, value), m_styleDecl(decl)
353     {
354         if (decl)
355             decl->ref();
356     }
357
358     ~MappedAttributeImpl();
359
360     virtual AttributeImpl* clone(bool preserveDecl=true) const;
361
362     CSSMappedAttributeDeclarationImpl* decl() const { return m_styleDecl; }
363     void setDecl(CSSMappedAttributeDeclarationImpl* decl) 
364     { 
365         if (m_styleDecl) m_styleDecl->deref();
366         m_styleDecl = decl;
367         if (m_styleDecl) m_styleDecl->ref();
368     }
369
370 private:
371     CSSMappedAttributeDeclarationImpl* m_styleDecl;
372 };
373
374 class NamedMappedAttrMapImpl : public NamedAttrMapImpl
375 {
376 public:
377     NamedMappedAttrMapImpl(ElementImpl *e);
378
379     virtual void clearAttributes();
380     
381     virtual bool isMappedAttributeMap() const;
382     
383     virtual void parseClassAttribute(const DOMString& classAttr);
384     const AtomicStringList* getClassList() const { return &m_classList; }
385     
386     virtual bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
387     void declRemoved() { m_mappedAttributeCount--; }
388     void declAdded() { m_mappedAttributeCount++; }
389     
390     bool mapsEquivalent(const NamedMappedAttrMapImpl* otherMap) const;
391     int declCount() const;
392
393     MappedAttributeImpl* attributeItem(unsigned long index) const
394     { return attrs ? static_cast<MappedAttributeImpl*>(attrs[index]) : 0; }
395     
396 private:
397     AtomicStringList m_classList;
398     int m_mappedAttributeCount;
399 };
400
401 class StyledElementImpl : public ElementImpl
402 {
403 public:
404     StyledElementImpl(const QualifiedName& tagName, DocumentPtr *doc);
405     virtual ~StyledElementImpl();
406
407     virtual bool isStyledElement() const { return true; }
408
409     bool hasMappedAttributes() const { return namedAttrMap ? static_cast<NamedMappedAttrMapImpl*>(namedAttrMap)->hasMappedAttributes() : false; }
410     const NamedMappedAttrMapImpl* mappedAttributes() const { return static_cast<NamedMappedAttrMapImpl*>(namedAttrMap); }
411     bool isMappedAttribute(NodeImpl::Id attr) const { MappedAttributeEntry res = eNone; mapToEntry(attr, res); return res != eNone; }
412
413     void addCSSLength(MappedAttributeImpl* attr, int id, const DOMString &value);
414     void addCSSProperty(MappedAttributeImpl* attr, int id, const DOMString &value);
415     void addCSSProperty(MappedAttributeImpl* attr, int id, int value);
416     void addCSSStringProperty(MappedAttributeImpl* attr, int id, const DOMString &value, DOM::CSSPrimitiveValue::UnitTypes = DOM::CSSPrimitiveValue::CSS_STRING);
417     void addCSSImageProperty(MappedAttributeImpl* attr, int id, const DOMString &URL);
418     void addCSSColor(MappedAttributeImpl* attr, int id, const DOMString &c);
419     void createMappedDecl(MappedAttributeImpl* attr);
420     
421     static CSSMappedAttributeDeclarationImpl* getMappedAttributeDecl(MappedAttributeEntry type, AttributeImpl* attr);
422     static void setMappedAttributeDecl(MappedAttributeEntry type, AttributeImpl* attr, CSSMappedAttributeDeclarationImpl* decl);
423     static void removeMappedAttributeDecl(MappedAttributeEntry type, NodeImpl::Id attrName, const AtomicString& attrValue);
424     static QPtrDict<QPtrDict<QPtrDict<CSSMappedAttributeDeclarationImpl> > >* m_mappedAttributeDecls;
425     
426     CSSMutableStyleDeclarationImpl* inlineStyleDecl() const { return m_inlineStyleDecl; }
427     virtual CSSMutableStyleDeclarationImpl* additionalAttributeStyleDecl();
428     CSSMutableStyleDeclarationImpl* getInlineStyleDecl();
429     CSSStyleDeclarationImpl* style();
430     void createInlineStyleDecl();
431     void destroyInlineStyleDecl();
432     void invalidateStyleAttribute();
433     virtual void updateStyleAttributeIfNeeded() const;
434     
435     virtual const AtomicStringList* getClassList() const;
436     virtual void attributeChanged(AttributeImpl* attr, bool preserveDecls = false);
437     virtual void parseMappedAttribute(MappedAttributeImpl* attr);
438     virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
439     virtual void createAttributeMap() const;
440     virtual AttributeImpl* createAttribute(NodeImpl::Id id, DOMStringImpl* value);
441
442 protected:
443     CSSMutableStyleDeclarationImpl* m_inlineStyleDecl;
444     mutable bool m_isStyleAttributeValid : 1;
445     mutable bool m_synchronizingStyleAttribute : 1;
446 };
447
448 }; //namespace
449
450 #if APPLE_CHANGES
451 #undef id
452 #endif
453
454 #endif