/* * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Peter Kelly (pmk@post.com) * (C) 2001 Dirk Mueller (mueller@kde.org) * (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DOM_ELEMENTImpl_h_ #define _DOM_ELEMENTImpl_h_ #include "dom_nodeimpl.h" #include "dom/dom_exception.h" #include "dom/dom_element.h" #include "xml/dom_stringimpl.h" #include "misc/shared.h" namespace khtml { class CSSStyleSelector; } namespace DOM { class ElementImpl; class DocumentImpl; class NamedAttrMapImpl; // Attr can have Text and EntityReference children // therefore it has to be a fullblown Node. The plan // is to dynamically allocate a textchild and store the // resulting nodevalue in the AttributeImpl upon // destruction. however, this is not yet implemented. class AttrImpl : public NodeBaseImpl { friend class ElementImpl; friend class NamedAttrMapImpl; public: AttrImpl(ElementImpl* element, DocumentImpl* docPtr, NodeImpl::Id attrId, DOMStringImpl *value, DOMStringImpl *prefix = 0); ~AttrImpl(); private: AttrImpl(const AttrImpl &other); AttrImpl &operator = (const AttrImpl &other); public: // DOM methods & attributes for Attr bool specified() const { return m_specified; } ElementImpl* ownerElement() const { return m_element; } void setOwnerElement( ElementImpl* impl ) { m_element = impl; } DOMString name() const; //DOMString value() const; void setValue( const DOMString &v, int &exceptioncode ); // DOM methods overridden from parent classes virtual DOMString nodeName() const; virtual unsigned short nodeType() const; virtual DOMString prefix() const; virtual void setPrefix(const DOMString &_prefix, int &exceptioncode ); virtual DOMString namespaceURI() const; virtual DOMString localName() const; virtual DOMString nodeValue() const; virtual void setNodeValue( const DOMString &, int &exceptioncode ); virtual NodeImpl *cloneNode ( bool deep ); virtual DOMStringImpl* textContent() const; virtual void setTextContent( const DOMString &text, int& exceptioncode ); // Other methods (not part of DOM) virtual bool isAttributeNode() const { return true; } virtual bool childAllowed( NodeImpl *newChild ); virtual bool childTypeAllowed( unsigned short type ); virtual NodeImpl::Id id() const { return m_attrId; } virtual DOMString toString() const; void setElement(ElementImpl *element); DOMStringImpl *val() { return m_value; } protected: ElementImpl *m_element; NodeImpl::Id m_attrId; DOMStringImpl *m_value; DOMStringImpl *m_prefix; DOMStringImpl *m_localName; }; // Mini version of AttrImpl internal to NamedAttrMapImpl. // Stores either the id and value of an attribute // (in the case of m_attrId != 0), or a pointer to an AttrImpl (if m_attrId == 0) // The latter case only happens when the Attr node is requested by some DOM // code or is an XML attribute. // In most cases the id and value is all we need to store, which is more // memory efficient. struct AttributeImpl { NodeImpl::Id id() const { return m_attrId ? m_attrId : m_data.attr->id(); } DOMStringImpl *val() const { return m_attrId ? m_data.value : m_data.attr->val(); } DOMString value() const { return val(); } AttrImpl *attr() const { return m_attrId ? 0 : m_data.attr; } DOMString namespaceURI() { return m_attrId ? DOMString() : m_data.attr->namespaceURI(); } DOMString prefix() { return m_attrId ? DOMString() : m_data.attr->prefix(); } DOMString localName() { return m_attrId ? DOMString() : m_data.attr->localName(); } DOMString name() { return m_attrId ? DOMString() : m_data.attr->name(); } void setValue(DOMStringImpl *value, ElementImpl *element); AttrImpl *createAttr(ElementImpl *element, DocumentImpl *docPtr); void free(); NodeImpl::Id m_attrId; union { DOMStringImpl *value; AttrImpl *attr; } m_data; }; class ElementImpl : public NodeBaseImpl { friend class DocumentImpl; friend class NamedAttrMapImpl; friend class AttrImpl; friend class NodeImpl; friend class khtml::CSSStyleSelector; public: ElementImpl(DocumentImpl *doc); ~ElementImpl(); DOMString getAttribute( NodeImpl::Id id, bool nsAware = 0, const DOMString& qName = DOMString() ) const; DOMStringImpl* getAttributeImpl( NodeImpl::Id id, bool nsAware = 0, DOMStringImpl* qName = 0 ) const; void setAttribute( NodeImpl::Id id, const DOMString &value, const DOMString &qName, int &exceptioncode ); void setAttributeNS( const DOMString &namespaceURI, const DOMString &qualifiedName, const DOMString& value, int &exceptioncode ); virtual DOMString prefix() const; void setPrefix(const DOMString &_prefix, int &exceptioncode ); virtual DOMString namespaceURI() const; // DOM methods overridden from parent classes virtual DOMString tagName() const = 0; virtual unsigned short nodeType() const; virtual NodeImpl *cloneNode ( bool deep ); virtual DOMString nodeName() const; virtual NodeImpl::Id id() const = 0; virtual bool isElementNode() const { return true; } virtual void insertedIntoDocument(); virtual void removedFromDocument(); // convenience methods which ignore exceptions void setAttribute (NodeImpl::Id id, const DOMString &value); NamedAttrMapImpl* attributes(bool readonly = false) const { if (!readonly && !namedAttrMap) createAttributeMap(); return namedAttrMap; } //This is always called, whenever an attribute changed virtual void parseAttribute(AttributeImpl *) {} void parseAttribute(NodeImpl::Id attrId, DOMStringImpl *value) { AttributeImpl aimpl; aimpl.m_attrId = attrId; aimpl.m_data.value = value; parseAttribute(&aimpl); } // not part of the DOM void setAttributeMap ( NamedAttrMapImpl* list ); // State of the element. virtual TQString state() { return TQString::null; } virtual void attach(); virtual void close(); virtual void detach(); virtual void structureChanged(); virtual void backwardsStructureChanged(); virtual void attributeChanged(NodeImpl::Id attrId); virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent); virtual khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *); virtual void recalcStyle( StyleChange = NoChange ); virtual void mouseEventHandler( MouseEvent* /*ev*/, bool /*inside*/ ) {} virtual bool isFocusable() const; virtual bool childAllowed( NodeImpl *newChild ); virtual bool childTypeAllowed( unsigned short type ); DOM::CSSStyleDeclarationImpl *styleRules() { if (!m_styleDecls) createDecl(); return m_styleDecls; } void dispatchAttrRemovalEvent(NodeImpl::Id id, DOMStringImpl *value); void dispatchAttrAdditionEvent(NodeImpl::Id id, DOMStringImpl *value); virtual DOMString toString() const; virtual DOMString selectionToString(NodeImpl *selectionStart, NodeImpl *selectionEnd, int startOffset, int endOffset, bool &found) const; virtual bool contentEditable() const; void setContentEditable(bool enabled); void scrollIntoView(bool alignToTop); /** Returns the opening tag and properties. * Examples: 'l ; i++) { if ((*qname)[i] == ':') { colonpos = i; break; } } if (((!qualifiedName.isNull()) && Element::khtmlMalformedQualifiedName(qualifiedName)) || (colonpos >= 0 && namespaceURI.isNull()) || (qualifiedName.isNull() && !namespaceURI.isNull()) || ((colonpos == 3) && (qualifiedName[0] == 'x') && (qualifiedName[1] == 'm') && (qualifiedName[2] == 'l') && (namespaceURI != "http://www.w3.org/XML/1998/namespace"))) { if (pExceptioncode) *pExceptioncode = DOMException::NAMESPACE_ERR; return false; } if(colonPos) *colonPos = colonpos; return true; } inline void splitPrefixLocalName(DOMStringImpl *qualifiedName, DOMString &prefix, DOMString &localName, int colonPos = -2) { if (colonPos == -2) for (uint i = 0 ; i < qualifiedName->l ; ++i) if (qualifiedName->s[i] == ':') { colonPos = i; break; } if (colonPos >= 0) { prefix = qualifiedName->copy(); localName = prefix.split(colonPos+1); prefix.implementation()->truncate(colonPos); } else localName = qualifiedName->copy(); } } //namespace #endif