2 * This file is part of the DOM implementation for KDE.
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.
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.
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.
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.
26 #ifndef _DOM_ELEMENTIMPL_h_
27 #define _DOM_ELEMENTIMPL_h_
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"
37 #define id id_AVOID_KEYWORD
41 #include "dom_atomicstringlist.h"
44 class CSSStyleSelector;
49 class AtomicStringList;
51 class CSSStyleDeclarationImpl;
53 class NamedAttrMapImpl;
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>
62 friend class NamedAttrMapImpl;
63 friend class ElementImpl;
64 friend class AttrImpl;
67 // null value is forbidden !
68 AttributeImpl(NodeImpl::Id id, const AtomicString& value)
69 : m_id(id), _value(value), _impl(0)
71 virtual ~AttributeImpl() {};
73 MAIN_THREAD_ALLOCATED;
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; }
80 bool isNull() const { return _value.isNull(); }
81 bool isEmpty() const { return _value.isEmpty(); }
83 virtual AttributeImpl* clone(bool preserveDecl=true) const;
86 void setValue(const AtomicString& value) {
89 void setPrefix(const AtomicString& prefix) {
92 void allocateImpl(ElementImpl* e);
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
108 friend class ElementImpl;
109 friend class NamedAttrMapImpl;
112 AttrImpl(ElementImpl* element, DocumentPtr* docPtr, AttributeImpl* a);
116 AttrImpl(const AttrImpl &other);
117 AttrImpl &operator = (const AttrImpl &other);
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; }
126 DOMString value() const;
127 void setValue( const DOMString &v, int &exceptioncode );
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 );
135 virtual DOMString nodeValue() const;
136 virtual void setNodeValue( const DOMString &, int &exceptioncode );
137 virtual NodeImpl *cloneNode ( bool deep );
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 );
144 virtual DOMString toString() const;
147 ElementImpl* m_element;
148 AttributeImpl* m_attribute;
152 class ElementImpl : public ContainerNodeImpl
154 friend class DocumentImpl;
155 friend class NamedAttrMapImpl;
156 friend class AttrImpl;
157 friend class NodeImpl;
158 friend class khtml::CSSStyleSelector;
160 ElementImpl(const QualifiedName& tagName, DocumentPtr *doc);
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 );
170 bool hasAttributes() const;
172 bool hasAttribute(const DOMString &name) const { return hasAttributeNS(DOMString(), name); }
173 bool hasAttributeNS(const DOMString &namespaceURI, const DOMString &localName) const;
175 const AtomicString& getAttribute(const DOMString& name) const { return getAttributeNS(DOMString(), name); }
176 const AtomicString& getAttributeNS(const DOMString &namespaceURI, const DOMString &localName) const;
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);
181 void removeAttribute(const DOMString &name, int &exception) { removeAttributeNS(DOMString(), name, exception); }
182 void removeAttributeNS(const DOMString &namespaceURI, const DOMString &localName, int &exception);
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);
190 virtual CSSStyleDeclarationImpl *style();
192 virtual const QualifiedName& tagName() const { return m_tagName; }
193 virtual bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
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(); }
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(); }
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();
212 // convenience methods which ignore exceptions
213 void setAttribute(Id id, const DOMString &value);
215 virtual NamedAttrMapImpl *attributes() const;
216 NamedAttrMapImpl* attributes(bool readonly) const;
218 // This method is called whenever an attribute is added, changed or removed.
219 virtual void attributeChanged(AttributeImpl* attr, bool preserveDecls = false) {}
221 // not part of the DOM
222 void setAttributeMap ( NamedAttrMapImpl* list );
224 // State of the element.
225 virtual QString state() { return QString::null; }
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 );
232 virtual void mouseEventHandler( MouseEvent */*ev*/, bool /*inside*/ ) {};
233 virtual bool childTypeAllowed( unsigned short type );
235 virtual AttributeImpl* createAttribute(Id id, DOMStringImpl* value);
237 void dispatchAttrRemovalEvent(AttributeImpl *attr);
238 void dispatchAttrAdditionEvent(AttributeImpl *attr);
240 virtual void accessKeyAction(bool sendToAnyEvent) { };
242 virtual DOMString toString() const;
244 virtual bool isURLAttribute(AttributeImpl *attr) const;
247 virtual void dump(QTextStream *stream, QString ind = "") const;
251 virtual void formatForDebugger(char *buffer, unsigned length) const;
255 virtual void createAttributeMap() const;
256 DOMString openTagStartToString() const;
259 void updateId(const AtomicString& oldId, const AtomicString& newId);
261 virtual void updateStyleAttributeIfNeeded() const {};
263 protected: // member variables
264 mutable NamedAttrMapImpl *namedAttrMap;
265 QualifiedName m_tagName;
268 // the map of attributes of an element
269 class NamedAttrMapImpl : public NamedNodeMapImpl
271 friend class ElementImpl;
273 NamedAttrMapImpl(ElementImpl *e);
274 virtual ~NamedAttrMapImpl();
275 NamedAttrMapImpl(const NamedAttrMapImpl&);
276 NamedAttrMapImpl &operator =(const NamedAttrMapImpl &other);
278 // DOM methods & attributes for NamedNodeMap
279 virtual AttrImpl *getNamedItem ( NodeImpl::Id id ) const;
281 virtual SharedPtr<NodeImpl> removeNamedItem ( NodeImpl::Id id, int &exceptioncode );
282 virtual SharedPtr<NodeImpl> setNamedItem ( NodeImpl* arg, int &exceptioncode );
284 virtual AttrImpl *item ( unsigned long index ) const;
285 unsigned long length() const { return len; }
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; }
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);
299 newAttribute->deref();
302 virtual bool isMappedAttributeMap() const;
304 const AtomicString& id() const { return m_id; }
305 void setID(const AtomicString& _id) { m_id = _id; }
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();
316 ElementImpl *element;
317 AttributeImpl **attrs;
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, eLastEntry };
326 class CSSMappedAttributeDeclarationImpl : public CSSMutableStyleDeclarationImpl
329 CSSMappedAttributeDeclarationImpl(CSSRuleImpl *parentRule)
330 : CSSMutableStyleDeclarationImpl(parentRule), m_entryType(eNone), m_attrName(0)
333 virtual ~CSSMappedAttributeDeclarationImpl();
335 void setMappedState(MappedAttributeEntry type, NodeImpl::Id attr, const AtomicString& val)
343 MappedAttributeEntry m_entryType;
344 NodeImpl::Id m_attrName;
345 AtomicString m_attrValue;
348 class MappedAttributeImpl : public AttributeImpl
351 MappedAttributeImpl(NodeImpl::Id _id, const AtomicString& value, CSSMappedAttributeDeclarationImpl* decl = 0)
352 : AttributeImpl(_id, value), m_styleDecl(decl)
358 ~MappedAttributeImpl();
360 virtual AttributeImpl* clone(bool preserveDecl=true) const;
362 CSSMappedAttributeDeclarationImpl* decl() const { return m_styleDecl; }
363 void setDecl(CSSMappedAttributeDeclarationImpl* decl)
365 if (m_styleDecl) m_styleDecl->deref();
367 if (m_styleDecl) m_styleDecl->ref();
371 CSSMappedAttributeDeclarationImpl* m_styleDecl;
374 class NamedMappedAttrMapImpl : public NamedAttrMapImpl
377 NamedMappedAttrMapImpl(ElementImpl *e);
379 virtual void clearAttributes();
381 virtual bool isMappedAttributeMap() const;
383 virtual void parseClassAttribute(const DOMString& classAttr);
384 const AtomicStringList* getClassList() const { return &m_classList; }
386 virtual bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
387 void declRemoved() { m_mappedAttributeCount--; }
388 void declAdded() { m_mappedAttributeCount++; }
390 bool mapsEquivalent(const NamedMappedAttrMapImpl* otherMap) const;
391 int declCount() const;
393 MappedAttributeImpl* attributeItem(unsigned long index) const
394 { return attrs ? static_cast<MappedAttributeImpl*>(attrs[index]) : 0; }
397 AtomicStringList m_classList;
398 int m_mappedAttributeCount;
401 class StyledElementImpl : public ElementImpl
404 StyledElementImpl(const QualifiedName& tagName, DocumentPtr *doc);
405 virtual ~StyledElementImpl();
407 virtual bool isStyledElement() const { return true; }
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; }
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);
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;
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;
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);
443 CSSMutableStyleDeclarationImpl* m_inlineStyleDecl;
444 mutable bool m_isStyleAttributeValid : 1;
445 mutable bool m_synchronizingStyleAttribute : 1;