summaryrefslogtreecommitdiffstats
path: root/tdehtml/xml/dom_xmlimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdehtml/xml/dom_xmlimpl.cpp')
-rw-r--r--tdehtml/xml/dom_xmlimpl.cpp498
1 files changed, 498 insertions, 0 deletions
diff --git a/tdehtml/xml/dom_xmlimpl.cpp b/tdehtml/xml/dom_xmlimpl.cpp
new file mode 100644
index 000000000..121ad436a
--- /dev/null
+++ b/tdehtml/xml/dom_xmlimpl.cpp
@@ -0,0 +1,498 @@
+/**
+ * This file is part of the DOM implementation for KDE.
+ *
+ * Copyright (C) 2000 Peter Kelly (pmk@post.com)
+ *
+ * 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.
+ */
+
+#include "dom/dom_exception.h"
+
+#include "xml/dom_xmlimpl.h"
+#include "xml/dom_docimpl.h"
+#include "xml/dom_stringimpl.h"
+#include "css/css_stylesheetimpl.h"
+#include "misc/loader.h"
+
+using namespace DOM;
+
+EntityImpl::EntityImpl(DocumentImpl *doc) : NodeBaseImpl(doc)
+{
+ m_publicId = 0;
+ m_systemId = 0;
+ m_notationName = 0;
+ m_name = 0;
+}
+
+EntityImpl::EntityImpl(DocumentImpl *doc, DOMString _name) : NodeBaseImpl(doc)
+{
+ m_publicId = 0;
+ m_systemId = 0;
+ m_notationName = 0;
+ m_name = _name.implementation();
+ if (m_name)
+ m_name->ref();
+}
+
+EntityImpl::EntityImpl(DocumentImpl *doc, DOMString _publicId, DOMString _systemId, DOMString _notationName) : NodeBaseImpl(doc)
+{
+ m_publicId = _publicId.implementation();
+ if (m_publicId)
+ m_publicId->ref();
+ m_systemId = _systemId.implementation();
+ if (m_systemId)
+ m_systemId->ref();
+ m_notationName = _notationName.implementation();
+ if (m_notationName)
+ m_notationName->ref();
+ m_name = 0;
+}
+
+
+EntityImpl::~EntityImpl()
+{
+ if (m_publicId)
+ m_publicId->deref();
+ if (m_systemId)
+ m_systemId->deref();
+ if (m_notationName)
+ m_notationName->deref();
+ if (m_name)
+ m_name->deref();
+}
+
+DOMString EntityImpl::publicId() const
+{
+ return m_publicId;
+}
+
+DOMString EntityImpl::systemId() const
+{
+ return m_systemId;
+}
+
+DOMString EntityImpl::notationName() const
+{
+ return m_notationName;
+}
+
+DOMString EntityImpl::nodeName() const
+{
+ return m_name;
+}
+
+unsigned short EntityImpl::nodeType() const
+{
+ return Node::ENTITY_NODE;
+}
+
+NodeImpl *EntityImpl::cloneNode ( bool /*deep*/)
+{
+ // Spec says cloning Document nodes is "implementation dependent"
+ // so we do not support it...
+ return 0;
+}
+
+// DOM Section 1.1.1
+bool EntityImpl::childTypeAllowed( unsigned short type )
+{
+ switch (type) {
+ case Node::ELEMENT_NODE:
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ case Node::COMMENT_NODE:
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::ENTITY_REFERENCE_NODE:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+DOMString EntityImpl::toString() const
+{
+ DOMString result = "<!ENTITY' ";
+
+ if (m_name && m_name->l != 0) {
+ result += " ";
+ result += m_name;
+ }
+
+ if (m_publicId && m_publicId->l != 0) {
+ result += " PUBLIC \"";
+ result += m_publicId;
+ result += "\" \"";
+ result += m_systemId;
+ result += "\"";
+ } else if (m_systemId && m_systemId->l != 0) {
+ result += " SYSTEM \"";
+ result += m_systemId;
+ result += "\"";
+ }
+
+ if (m_notationName && m_notationName->l != 0) {
+ result += " NDATA ";
+ result += m_notationName;
+ }
+
+ result += ">";
+
+ return result;
+}
+
+// -------------------------------------------------------------------------
+
+EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *doc) : NodeBaseImpl(doc)
+{
+ m_entityName = 0;
+}
+
+EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *doc, DOMStringImpl *_entityName) : NodeBaseImpl(doc)
+{
+ m_entityName = _entityName;
+ if (m_entityName)
+ m_entityName->ref();
+}
+
+EntityReferenceImpl::~EntityReferenceImpl()
+{
+ if (m_entityName)
+ m_entityName->deref();
+}
+
+DOMString EntityReferenceImpl::nodeName() const
+{
+ return m_entityName;
+}
+
+unsigned short EntityReferenceImpl::nodeType() const
+{
+ return Node::ENTITY_REFERENCE_NODE;
+}
+
+NodeImpl *EntityReferenceImpl::cloneNode ( bool deep )
+{
+ EntityReferenceImpl *clone = new EntityReferenceImpl(docPtr(),m_entityName);
+ // ### make sure children are readonly
+ // ### since we are a reference, should we clone children anyway (even if not deep?)
+ if (deep)
+ cloneChildNodes(clone);
+ return clone;
+}
+
+// DOM Section 1.1.1
+bool EntityReferenceImpl::childTypeAllowed( unsigned short type )
+{
+ switch (type) {
+ case Node::ELEMENT_NODE:
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ case Node::COMMENT_NODE:
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::ENTITY_REFERENCE_NODE:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+DOMString EntityReferenceImpl::toString() const
+{
+ DOMString result = "&";
+ result += m_entityName;
+ result += ";";
+
+ return result;
+}
+
+// -------------------------------------------------------------------------
+
+NotationImpl::NotationImpl(DocumentImpl *doc) : NodeBaseImpl(doc)
+{
+ m_publicId = 0;
+ m_systemId = 0;
+ m_name = 0;
+}
+
+NotationImpl::NotationImpl(DocumentImpl *doc, DOMString _name, DOMString _publicId, DOMString _systemId) : NodeBaseImpl(doc)
+{
+ m_name = _name.implementation();
+ if (m_name)
+ m_name->ref();
+ m_publicId = _publicId.implementation();
+ if (m_publicId)
+ m_publicId->ref();
+ m_systemId = _systemId.implementation();
+ if (m_systemId)
+ m_systemId->ref();
+}
+
+NotationImpl::~NotationImpl()
+{
+ if (m_name)
+ m_name->deref();
+ if (m_publicId)
+ m_publicId->deref();
+ if (m_systemId)
+ m_systemId->deref();
+}
+
+DOMString NotationImpl::publicId() const
+{
+ return m_publicId;
+}
+
+DOMString NotationImpl::systemId() const
+{
+ return m_systemId;
+}
+
+DOMString NotationImpl::nodeName() const
+{
+ return m_name;
+}
+
+unsigned short NotationImpl::nodeType() const
+{
+ return Node::NOTATION_NODE;
+}
+
+NodeImpl *NotationImpl::cloneNode ( bool /*deep*/)
+{
+ // Spec says cloning Document nodes is "implementation dependent"
+ // so we do not support it...
+ return 0;
+}
+
+// DOM Section 1.1.1
+bool NotationImpl::childTypeAllowed( unsigned short /*type*/ )
+{
+ return false;
+}
+
+// -------------------------------------------------------------------------
+
+// ### need a way of updating these properly whenever child nodes of the processing instruction
+// change or are added/removed
+
+ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *doc) : NodeBaseImpl(doc)
+{
+ m_target = 0;
+ m_data = 0;
+ m_localHref = 0;
+ m_sheet = 0;
+ m_cachedSheet = 0;
+}
+
+ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *doc, DOMString _target, DOMString _data) : NodeBaseImpl(doc)
+{
+ m_target = _target.implementation();
+ if (m_target)
+ m_target->ref();
+ m_data = _data.implementation();
+ if (m_data)
+ m_data->ref();
+ m_sheet = 0;
+ m_cachedSheet = 0;
+ m_localHref = 0;
+}
+
+ProcessingInstructionImpl::~ProcessingInstructionImpl()
+{
+ if (m_target)
+ m_target->deref();
+ if (m_data)
+ m_data->deref();
+ if (m_cachedSheet)
+ m_cachedSheet->deref(this);
+ if (m_sheet)
+ m_sheet->deref();
+}
+
+DOMString ProcessingInstructionImpl::target() const
+{
+ return m_target;
+}
+
+void ProcessingInstructionImpl::setData( const DOMString &_data, int &exceptioncode )
+{
+ // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+ if (isReadOnly()) {
+ exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
+ return;
+ }
+
+ if (m_data)
+ m_data->deref();
+ m_data = _data.implementation();
+ if (m_data)
+ m_data->ref();
+}
+
+DOMString ProcessingInstructionImpl::nodeName() const
+{
+ return m_target;
+}
+
+unsigned short ProcessingInstructionImpl::nodeType() const
+{
+ return Node::PROCESSING_INSTRUCTION_NODE;
+}
+
+DOMString ProcessingInstructionImpl::nodeValue() const
+{
+ return m_data;
+}
+
+void ProcessingInstructionImpl::setNodeValue( const DOMString &_nodeValue, int &exceptioncode )
+{
+ // NO_MODIFICATION_ALLOWED_ERR: taken care of by setData()
+ setData(_nodeValue, exceptioncode);
+}
+
+NodeImpl *ProcessingInstructionImpl::cloneNode ( bool /*deep*/)
+{
+ // ### copy m_localHref
+ return new ProcessingInstructionImpl(docPtr(),m_target,m_data);
+}
+
+DOMString ProcessingInstructionImpl::localHref() const
+{
+ return m_localHref;
+}
+
+// DOM Section 1.1.1
+bool ProcessingInstructionImpl::childTypeAllowed( unsigned short /*type*/ )
+{
+ return false;
+}
+
+void ProcessingInstructionImpl::checkStyleSheet()
+{
+ if (m_target && DOMString(m_target) == "xml-stylesheet") {
+ // see http://www.w3.org/TR/xml-stylesheet/
+ // ### check that this occurs only in the prolog
+ // ### support stylesheet included in a fragment of this (or another) document
+ // ### make sure this gets called when adding from javascript
+ XMLAttributeReader attrReader(DOMString(m_data).string());
+ bool attrsOk;
+ TQXmlAttributes attrs = attrReader.readAttrs(attrsOk);
+ if (!attrsOk)
+ return;
+ if (attrs.value("type") != "text/css" && !attrs.value("type").isEmpty())
+ return;
+
+ DOMString href = attrs.value("href");
+
+ if (href.length()>1)
+ {
+ if (href[0]=='#')
+ {
+ if (m_localHref)
+ m_localHref->deref();
+ m_localHref=href.implementation()->split(1);
+ if (m_localHref)
+ m_localHref->ref();
+ }
+ else
+ {
+ // ### some validation on the URL?
+ // ### FIXME charset
+ if (m_cachedSheet) m_cachedSheet->deref(this);
+ m_cachedSheet = getDocument()->docLoader()->requestStyleSheet(getDocument()->completeURL(href.string()), TQString::null);
+ if (m_cachedSheet) {
+ getDocument()->addPendingSheet(); //before ref, because during the ref it might load!
+ m_cachedSheet->ref( this );
+ }
+ }
+
+ }
+ }
+}
+
+StyleSheetImpl *ProcessingInstructionImpl::sheet() const
+{
+ return m_sheet;
+}
+
+void ProcessingInstructionImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset)
+{
+ if (m_sheet)
+ m_sheet->deref();
+ m_sheet = new CSSStyleSheetImpl(getDocument(), url);
+ m_sheet->ref();
+ m_sheet->setCharset(charset);
+ m_sheet->parseString(sheet);
+ if (m_cachedSheet)
+ m_cachedSheet->deref(this);
+ m_cachedSheet = 0;
+
+ getDocument()->styleSheetLoaded();
+}
+
+void ProcessingInstructionImpl::setStyleSheet(CSSStyleSheetImpl* sheet)
+{
+ if (m_sheet)
+ m_sheet->deref();
+ m_sheet = sheet;
+ if (m_sheet)
+ m_sheet->ref();
+}
+
+DOMString ProcessingInstructionImpl::toString() const
+{
+ DOMString result = "<?";
+ result += m_target;
+ result += " ";
+ result += m_data;
+ result += ">";
+ return result;
+}
+
+// -------------------------------------------------------------------------
+
+XMLAttributeReader::XMLAttributeReader(const TQString& _attrString)
+{
+ m_attrString = _attrString;
+}
+
+XMLAttributeReader::~XMLAttributeReader()
+{
+}
+
+TQXmlAttributes XMLAttributeReader::readAttrs(bool &ok)
+{
+ // parse xml file
+ TQXmlInputSource source;
+ source.setData("<?xml version=\"1.0\"?><attrs "+m_attrString+" />");
+ TQXmlSimpleReader reader;
+ reader.setContentHandler( this );
+ ok = reader.parse( source );
+ return attrs;
+}
+
+bool XMLAttributeReader::startElement(const TQString& /*namespaceURI*/, const TQString& localName,
+ const TQString& /*qName*/, const TQXmlAttributes& atts)
+{
+ if (localName == "attrs") {
+ attrs = atts;
+ return true;
+ }
+ else
+ return false; // we shouldn't have any other elements
+}