summaryrefslogtreecommitdiffstats
path: root/khtml/xml/dom_docimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khtml/xml/dom_docimpl.cpp')
-rw-r--r--khtml/xml/dom_docimpl.cpp2892
1 files changed, 0 insertions, 2892 deletions
diff --git a/khtml/xml/dom_docimpl.cpp b/khtml/xml/dom_docimpl.cpp
deleted file mode 100644
index ff206a1cc..000000000
--- a/khtml/xml/dom_docimpl.cpp
+++ /dev/null
@@ -1,2892 +0,0 @@
-/**
- * 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 Dirk Mueller (mueller@kde.org)
- * (C) 2002-2006 Apple Computer, Inc.
- * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.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_textimpl.h"
-#include "xml/dom_xmlimpl.h"
-#include "xml/dom2_rangeimpl.h"
-#include "xml/dom2_eventsimpl.h"
-#include "xml/xml_tokenizer.h"
-#include "html/htmltokenizer.h"
-#include "xml/dom_restyler.h"
-
-#include "css/csshelper.h"
-#include "css/cssstyleselector.h"
-#include "css/css_stylesheetimpl.h"
-#include "misc/htmlhashes.h"
-#include "misc/helper.h"
-#include "misc/seed.h"
-#include "misc/loader.h"
-#include "ecma/kjs_proxy.h"
-#include "ecma/kjs_binding.h"
-
-#include <tqptrstack.h>
-#include <tqpaintdevicemetrics.h>
-#include <kdebug.h>
-#include <klocale.h>
-#include <kstaticdeleter.h>
-
-#include "rendering/counter_tree.h"
-#include "rendering/render_canvas.h"
-#include "rendering/render_replaced.h"
-#include "rendering/render_arena.h"
-#include "rendering/render_layer.h"
-#include "rendering/render_frames.h"
-#include "rendering/render_image.h"
-
-#include "khtmlview.h"
-#include "khtml_part.h"
-
-#include <kglobalsettings.h>
-#include <kstringhandler.h>
-#include <krfcdate.h>
-#include "khtml_settings.h"
-#include "khtmlpart_p.h"
-
-#include "html/html_baseimpl.h"
-#include "html/html_blockimpl.h"
-#include "html/html_documentimpl.h"
-#include "html/html_formimpl.h"
-#include "html/html_headimpl.h"
-#include "html/html_imageimpl.h"
-#include "html/html_listimpl.h"
-#include "html/html_miscimpl.h"
-#include "html/html_tableimpl.h"
-#include "html/html_objectimpl.h"
-
-#include <kapplication.h>
-#include <kio/job.h>
-
-#include <stdlib.h>
-#include "dom_docimpl.h"
-
-using namespace DOM;
-using namespace khtml;
-
-// ------------------------------------------------------------------------
-
-DOMImplementationImpl *DOMImplementationImpl::m_instance = 0;
-
-DOMImplementationImpl::DOMImplementationImpl()
-{
-}
-
-DOMImplementationImpl::~DOMImplementationImpl()
-{
-}
-
-bool DOMImplementationImpl::hasFeature ( const DOMString &feature, const DOMString &version )
-{
- // ### update when we (fully) support the relevant features
- TQString lower = feature.string().lower();
- if ((lower == "html" || lower == "xml") &&
- (version.isEmpty() || version == "1.0" || version == "2.0" || version == "null"))
- return true;
-
- // ## Do we support Core Level 3 ?
- if ((lower == "core" ) &&
- (version.isEmpty() || version == "2.0" || version == "null"))
- return true;
-
- if ((lower == "events" || lower == "uievents" ||
- lower == "mouseevents" || lower == "mutationevents" ||
- lower == "htmlevents" || lower == "textevents" ) &&
- (version.isEmpty() || version == "2.0" || version == "3.0" || version == "null"))
- return true;
- return false;
-}
-
-DocumentTypeImpl *DOMImplementationImpl::createDocumentType( const DOMString &qualifiedName, const DOMString &publicId,
- const DOMString &systemId, int &exceptioncode )
-{
- // Not mentioned in spec: throw NAMESPACE_ERR if no qualifiedName supplied
- if (qualifiedName.isNull()) {
- exceptioncode = DOMException::NAMESPACE_ERR;
- return 0;
- }
-
- // INVALID_CHARACTER_ERR: Raised if the specified qualified name contains an illegal character.
- if (!Element::khtmlValidQualifiedName(qualifiedName)) {
- exceptioncode = DOMException::INVALID_CHARACTER_ERR;
- return 0;
- }
-
- // NAMESPACE_ERR: Raised if the qualifiedName is malformed.
- // Added special case for the empty string, which seems to be a common pre-DOM2 misuse
- if (!qualifiedName.isEmpty() && Element::khtmlMalformedQualifiedName(qualifiedName)) {
- exceptioncode = DOMException::NAMESPACE_ERR;
- return 0;
- }
-
- return new DocumentTypeImpl(this,0,qualifiedName,publicId,systemId);
-}
-
-DOMImplementationImpl* DOMImplementationImpl::getInterface(const DOMString& /*feature*/) const
-{
- // ###
- return 0;
-}
-
-DocumentImpl *DOMImplementationImpl::createDocument( const DOMString &namespaceURI, const DOMString &qualifiedName,
- const DocumentType &doctype, int &exceptioncode )
-{
- exceptioncode = 0;
-
- if (!checkQualifiedName(qualifiedName, namespaceURI, 0, true/*nameCanBeNull*/,
- true /*nameCanBeEmpty, see #61650*/, &exceptioncode) )
- return 0;
-
- DocumentTypeImpl *dtype = static_cast<DocumentTypeImpl*>(doctype.handle());
- // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was
- // created from a different implementation.
- if (dtype && (dtype->getDocument() || dtype->implementation() != this)) {
- exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
- return 0;
- }
-
- // ### this is completely broken.. without a view it will not work (Dirk)
- DocumentImpl *doc = new DocumentImpl(this, 0);
-
- // now get the interesting parts of the doctype
- // ### create new one if not there (currently always there)
- if (doc->doctype() && dtype)
- doc->doctype()->copyFrom(*dtype);
-
- // the document must be created empty if all parameters are null
- // (or empty for qName/nsURI as a tolerance) - see DOM 3 Core.
- if (dtype || !qualifiedName.isEmpty() || !namespaceURI.isEmpty()) {
- ElementImpl *element = doc->createElementNS(namespaceURI,qualifiedName);
- doc->appendChild(element,exceptioncode);
- if (exceptioncode) {
- delete element;
- delete doc;
- return 0;
- }
- }
- return doc;
-}
-
-CSSStyleSheetImpl *DOMImplementationImpl::createCSSStyleSheet(DOMStringImpl* /*title*/, DOMStringImpl *media,
- int &/*exceptioncode*/)
-{
- // ### TODO : title should be set, and media could have wrong syntax, in which case we should
- // generate an exception.
- CSSStyleSheetImpl *parent = 0L;
- CSSStyleSheetImpl *sheet = new CSSStyleSheetImpl(parent, DOMString());
- sheet->setMedia(new MediaListImpl(sheet, media));
- return sheet;
-}
-
-DocumentImpl *DOMImplementationImpl::createDocument( KHTMLView *v )
-{
- return new DocumentImpl(this, v);
-}
-
-HTMLDocumentImpl *DOMImplementationImpl::createHTMLDocument( KHTMLView *v )
-{
- return new HTMLDocumentImpl(this, v);
-}
-
-DOMImplementationImpl *DOMImplementationImpl::instance()
-{
- if (!m_instance) {
- m_instance = new DOMImplementationImpl();
- m_instance->ref();
- }
-
- return m_instance;
-}
-
-// ------------------------------------------------------------------------
-
-
-ElementMappingCache::ElementMappingCache():m_dict(257)
-{
- m_dict.setAutoDelete(true);
-}
-
-void ElementMappingCache::add(const TQString& id, ElementImpl* nd)
-{
- if (id.isEmpty()) return;
-
- ItemInfo* info = m_dict.find(id);
- if (info)
- {
- info->ref++;
- info->nd = 0; //Now ambigous
- }
- else
- {
- ItemInfo* info = new ItemInfo();
- info->ref = 1;
- info->nd = nd;
- m_dict.insert(id, info);
- }
-}
-
-void ElementMappingCache::set(const TQString& id, ElementImpl* nd)
-{
- if (id.isEmpty()) return;
-
- ItemInfo* info = m_dict.find(id);
- info->nd = nd;
-}
-
-void ElementMappingCache::remove(const TQString& id, ElementImpl* nd)
-{
- if (id.isEmpty()) return;
-
- ItemInfo* info = m_dict.find(id);
- info->ref--;
- if (info->ref == 0)
- {
- m_dict.take(id);
- delete info;
- }
- else
- {
- if (info->nd == nd)
- info->nd = 0;
- }
-}
-
-bool ElementMappingCache::contains(const TQString& id)
-{
- if (id.isEmpty()) return false;
- return m_dict.find(id);
-}
-
-ElementMappingCache::ItemInfo* ElementMappingCache::get(const TQString& id)
-{
- if (id.isEmpty()) return 0;
- return m_dict.find(id);
-}
-
-static KStaticDeleter< TQPtrList<DocumentImpl> > s_changedDocumentsDeleter;
-TQPtrList<DocumentImpl> * DocumentImpl::changedDocuments;
-
-// KHTMLView might be 0
-DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
- : NodeBaseImpl( 0 ), m_domtree_version(0), m_counterDict(257),
- m_imageLoadEventTimer(0)
-{
- m_document.resetSkippingRef(this); //Make getDocument return us..
- m_selfOnlyRefCount = 0;
-
- m_paintDeviceMetrics = 0;
- m_paintDevice = 0;
- m_decoderMibEnum = 0;
- m_textColor = Qt::black;
-
- m_view = v;
- m_renderArena.reset();
-
- KHTMLFactory::ref();
-
- if ( v ) {
- m_docLoader = new DocLoader(v->part(), this );
- setPaintDevice( TQT_TQPAINTDEVICE(m_view) );
- }
- else
- m_docLoader = new DocLoader( 0, this );
-
- visuallyOrdered = false;
- m_bParsing = false;
- m_docChanged = false;
- m_elemSheet = 0;
- m_tokenizer = 0;
-
- // ### this should be created during parsing a <!DOCTYPE>
- // not during construction. Not sure who added that and why (Dirk)
- m_doctype = new DocumentTypeImpl(_implementation, getDocument(),
- DOMString() /* qualifiedName */,
- DOMString() /* publicId */,
- DOMString() /* systemId */);
- m_doctype->ref();
-
- m_implementation = _implementation;
- m_implementation->ref();
- pMode = Strict;
- hMode = XHtml;
- m_textColor = "#000000";
- m_attrMap = new IdNameMapping(ATTR_LAST_ATTR+1);
- m_elementMap = new IdNameMapping(ID_LAST_TAG+1);
- m_namespaceMap = new IdNameMapping(1);
- TQString xhtml(XHTML_NAMESPACE);
- m_namespaceMap->names.insert(emptyNamespace, new DOMStringImpl(""));
- m_namespaceMap->names.insert(xhtmlNamespace, new DOMStringImpl(xhtml.unicode(), xhtml.length()));
- m_namespaceMap->names[emptyNamespace]->ref();
- m_namespaceMap->names[xhtmlNamespace]->ref();
- m_namespaceMap->count+=2;
- m_focusNode = 0;
- m_hoverNode = 0;
- m_activeNode = 0;
- m_defaultView = new AbstractViewImpl(this);
- m_defaultView->ref();
- m_listenerTypes = 0;
- m_styleSheets = new StyleSheetListImpl;
- m_styleSheets->ref();
- m_addedStyleSheets = 0;
- m_inDocument = true;
- m_styleSelectorDirty = false;
- m_styleSelector = 0;
- m_counterDict.setAutoDelete(true);
-
- m_inStyleRecalc = false;
- m_pendingStylesheets = 0;
- m_ignorePendingStylesheets = false;
- m_async = true;
- m_hadLoadError = false;
- m_docLoading = false;
- m_inSyncLoad = false;
- m_loadingXMLDoc = 0;
- m_cssTarget = 0;
- m_dynamicDomRestyler = new khtml::DynamicDomRestyler();
-}
-
-void DocumentImpl::removedLastRef()
-{
- if (m_selfOnlyRefCount) {
- /* In this case, the only references to us are from children,
- so we have a cycle. We'll try to break it by disconnecting the
- children from us; this sucks/is wrong, but it's pretty much
- the best we can do without tracing.
-
- Of course, if dumping the children causes the refcount from them to
- drop to 0 we can get killed right here, so better hold
- a temporary reference, too
- */
- DocPtr<DocumentImpl> guard(this);
-
- // we must make sure not to be retaining any of our children through
- // these extra pointers or we will create a reference cycle
- if (m_doctype) {
- m_doctype->deref();
- m_doctype = 0;
- }
-
- if (m_cssTarget) {
- m_cssTarget->deref();
- m_cssTarget = 0;
- }
-
- if (m_focusNode) {
- m_focusNode->deref();
- m_focusNode = 0;
- }
-
- if (m_hoverNode) {
- m_hoverNode->deref();
- m_hoverNode = 0;
- }
-
- if (m_activeNode) {
- m_activeNode->deref();
- m_activeNode = 0;
- }
-
- removeChildren();
-
- delete m_tokenizer;
- m_tokenizer = 0;
- } else {
- delete this;
- }
-}
-
-DocumentImpl::~DocumentImpl()
-{
- //Important: if you need to remove stuff here,
- //you may also have to fix removedLastRef() above - M.O.
- assert( !m_render );
-
- TQIntDictIterator<NodeListImpl::Cache> it(m_nodeListCache);
- for (; it.current(); ++it)
- it.current()->deref();
-
- if (m_loadingXMLDoc)
- m_loadingXMLDoc->deref(this);
- if (changedDocuments && m_docChanged)
- changedDocuments->remove(this);
- delete m_tokenizer;
- m_document.resetSkippingRef(0);
- delete m_styleSelector;
- delete m_docLoader;
- if (m_elemSheet ) m_elemSheet->deref();
- if (m_doctype)
- m_doctype->deref();
- m_implementation->deref();
- delete m_paintDeviceMetrics;
- delete m_elementMap;
- delete m_attrMap;
- delete m_namespaceMap;
- delete m_dynamicDomRestyler;
- m_defaultView->deref();
- m_styleSheets->deref();
- if (m_addedStyleSheets)
- m_addedStyleSheets->deref();
- if (m_cssTarget)
- m_cssTarget->deref();
- if (m_focusNode)
- m_focusNode->deref();
- if ( m_hoverNode )
- m_hoverNode->deref();
- if (m_activeNode)
- m_activeNode->deref();
-
- m_renderArena.reset();
-
- KHTMLFactory::deref();
-}
-
-
-DocumentTypeImpl *DocumentImpl::doctype() const
-{
- return m_doctype;
-}
-
-DOMImplementationImpl *DocumentImpl::implementation() const
-{
- return m_implementation;
-}
-
-ElementImpl *DocumentImpl::documentElement() const
-{
- NodeImpl *n = firstChild();
- while (n && n->nodeType() != Node::ELEMENT_NODE)
- n = n->nextSibling();
- return static_cast<ElementImpl*>(n);
-}
-
-ElementImpl *DocumentImpl::createElement( const DOMString &name, int* pExceptioncode )
-{
- Id id = getId( NodeImpl::ElementId, name.implementation(),
- false /* allocate */, false /*HTMLDocumentImpl::createElement looked for HTML elements already*/,
- pExceptioncode);
- if ( pExceptioncode && *pExceptioncode )
- return 0;
-
- XMLElementImpl* e = new XMLElementImpl( getDocument(), id );
- e->setHTMLCompat( htmlMode() != XHtml ); // Not a real HTML element, but inside an html-compat doc all tags are uppercase.
- return e;
-}
-
-AttrImpl *DocumentImpl::createAttribute( const DOMString &tagName, int* pExceptioncode )
-{
- Id id = getId( NodeImpl::AttributeId, tagName.implementation(),
- false /* allocate */, isHTMLDocument(), pExceptioncode);
- if ( pExceptioncode && *pExceptioncode )
- return 0;
- AttrImpl* attr = new AttrImpl( 0, getDocument(), id, DOMString("").implementation());
- attr->setHTMLCompat( htmlMode() != XHtml );
- return attr;
-}
-
-DocumentFragmentImpl *DocumentImpl::createDocumentFragment( )
-{
- return new DocumentFragmentImpl( docPtr() );
-}
-
-CommentImpl *DocumentImpl::createComment ( DOMStringImpl* data )
-{
- return new CommentImpl( docPtr(), data );
-}
-
-CDATASectionImpl *DocumentImpl::createCDATASection ( DOMStringImpl* data )
-{
- return new CDATASectionImpl( docPtr(), data );
-}
-
-ProcessingInstructionImpl *DocumentImpl::createProcessingInstruction ( const DOMString &target, DOMStringImpl* data )
-{
- return new ProcessingInstructionImpl( docPtr(),target,data);
-}
-
-EntityReferenceImpl *DocumentImpl::createEntityReference ( const DOMString &name )
-{
- return new EntityReferenceImpl(docPtr(), name.implementation());
-}
-
-NodeImpl *DocumentImpl::importNode(NodeImpl *importedNode, bool deep, int &exceptioncode)
-{
- NodeImpl *result = 0;
-
- // Not mentioned in spec: throw NOT_FOUND_ERR if evt is null
- if (!importedNode) {
- exceptioncode = DOMException::NOT_FOUND_ERR;
- return 0;
- }
-
- if(importedNode->nodeType() == Node::ELEMENT_NODE)
- {
- // Why not use cloneNode?
- ElementImpl *otherElem = static_cast<ElementImpl*>(importedNode);
- NamedAttrMapImpl *otherMap = static_cast<ElementImpl *>(importedNode)->attributes(true);
-
- ElementImpl *tempElementImpl;
- if (!importedNode->localName().isNull())
- tempElementImpl = createElementNS(otherElem->namespaceURI(),otherElem->nodeName());
- else
- tempElementImpl = createElement(otherElem->nodeName());
- result = tempElementImpl;
-
-
- if(otherMap) {
- for(unsigned long i = 0; i < otherMap->length(); i++)
- {
- AttrImpl *otherAttr = otherMap->attrAt(i)->createAttr(otherElem,otherElem->docPtr());
-
- if (!otherAttr->localName().isNull()) {
- // attr was created via createElementNS()
- tempElementImpl->setAttributeNS(otherAttr->namespaceURI(),
- otherAttr->name(),
- otherAttr->nodeValue(),
- exceptioncode);
- }
- else {
- // attr was created via createElement()
- tempElementImpl->setAttribute(otherAttr->id(),
- otherAttr->nodeValue(),
- otherAttr->name(),
- exceptioncode);
- }
-
- if(exceptioncode != 0)
- break; // ### properly cleanup here
- }
- }
- }
- else if(importedNode->nodeType() == Node::TEXT_NODE)
- {
- result = createTextNode(static_cast<TextImpl*>(importedNode)->string());
- deep = false;
- }
- else if(importedNode->nodeType() == Node::CDATA_SECTION_NODE)
- {
- result = createCDATASection(static_cast<CDATASectionImpl*>(importedNode)->string());
- deep = false;
- }
- else if(importedNode->nodeType() == Node::ENTITY_REFERENCE_NODE)
- result = createEntityReference(importedNode->nodeName());
- else if(importedNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
- {
- result = createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue().implementation());
- deep = false;
- }
- else if(importedNode->nodeType() == Node::COMMENT_NODE)
- {
- result = createComment(static_cast<CommentImpl*>(importedNode)->string());
- deep = false;
- }
- else if (importedNode->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
- result = createDocumentFragment();
- else
- exceptioncode = DOMException::NOT_SUPPORTED_ERR;
-
- //### FIXME: This should handle Attributes, and a few other things
-
- if(deep && result)
- {
- for(Node n = importedNode->firstChild(); !n.isNull(); n = n.nextSibling())
- result->appendChild(importNode(n.handle(), true, exceptioncode), exceptioncode);
- }
-
- return result;
-}
-
-ElementImpl *DocumentImpl::createElementNS( const DOMString &_namespaceURI, const DOMString &_qualifiedName, int* pExceptioncode )
-{
- ElementImpl *e = 0;
- int colonPos = -2;
- // check NAMESPACE_ERR/INVALID_CHARACTER_ERR
- if (pExceptioncode && !checkQualifiedName(_qualifiedName, _namespaceURI, &colonPos,
- false/*nameCanBeNull*/, false/*nameCanBeEmpty*/,
- pExceptioncode))
- return 0;
- DOMString prefix, localName;
- splitPrefixLocalName(_qualifiedName.implementation(), prefix, localName, colonPos);
-
- if ((isHTMLDocument() && _namespaceURI.isNull()) ||
- (strcasecmp(_namespaceURI, XHTML_NAMESPACE) == 0 && localName == localName.lower())) {
- e = createHTMLElement(localName);
- if (e) {
- int _exceptioncode = 0;
- if (!prefix.isNull())
- e->setPrefix(prefix, _exceptioncode);
- if ( _exceptioncode ) {
- if ( pExceptioncode ) *pExceptioncode = _exceptioncode;
- delete e;
- return 0;
- }
- e->setHTMLCompat( _namespaceURI.isNull() && htmlMode() != XHtml );
- }
- }
- if (!e) {
- Id id = getId(NodeImpl::ElementId, _namespaceURI.implementation(), prefix.implementation(),
- localName.implementation(), false, false /*HTML already looked up*/);
- e = new XMLElementImpl( getDocument(), id, prefix.implementation() );
- }
-
- return e;
-}
-
-AttrImpl *DocumentImpl::createAttributeNS( const DOMString &_namespaceURI,
- const DOMString &_qualifiedName, int* pExceptioncode)
-{
- int colonPos = -2;
- // check NAMESPACE_ERR/INVALID_CHARACTER_ERR
- if (pExceptioncode && !checkQualifiedName(_qualifiedName, _namespaceURI, &colonPos,
- false/*nameCanBeNull*/, false/*nameCanBeEmpty*/,
- pExceptioncode))
- return 0;
- DOMString prefix, localName;
- splitPrefixLocalName(_qualifiedName.implementation(), prefix, localName, colonPos);
- Id id = getId(NodeImpl::AttributeId, _namespaceURI.implementation(), prefix.implementation(),
- localName.implementation(), false, true /*lookupHTML*/);
- AttrImpl* attr = new AttrImpl(0, getDocument(), id, DOMString("").implementation(),
- prefix.implementation());
- attr->setHTMLCompat( _namespaceURI.isNull() && htmlMode() != XHtml );
- return attr;
-}
-
-ElementImpl *DocumentImpl::getElementById( const DOMString &elementId ) const
-{
- TQString stringKey = elementId.string();
-
- ElementMappingCache::ItemInfo* info = m_getElementByIdCache.get(stringKey);
-
- if (!info)
- return 0;
-
- //See if cache has an unambiguous answer.
- if (info->nd)
- return info->nd;
-
- //Now we actually have to walk.
- TQPtrStack<NodeImpl> nodeStack;
- NodeImpl *current = _first;
-
- while(1)
- {
- if(!current)
- {
- if(nodeStack.isEmpty()) break;
- current = nodeStack.pop();
- current = current->nextSibling();
- }
- else
- {
- if(current->isElementNode())
- {
- ElementImpl *e = static_cast<ElementImpl *>(current);
- if(e->getAttribute(ATTR_ID) == elementId) {
- info->nd = e;
- return e;
- }
- }
-
- NodeImpl *child = current->firstChild();
- if(child)
- {
- nodeStack.push(current);
- current = child;
- }
- else
- {
- current = current->nextSibling();
- }
- }
- }
-
- assert(0); //If there is no item with such an ID, we should never get here
-
- //kdDebug() << "WARNING: *DocumentImpl::getElementById not found " << elementId.string() << endl;
-
- return 0;
-}
-
-void DocumentImpl::setTitle(const DOMString& _title)
-{
- if (_title == m_title && !m_title.isNull()) return;
-
- m_title = _title;
-
- TQString titleStr = m_title.string();
- for (unsigned int i = 0; i < titleStr.length(); ++i)
- if (titleStr[i] < ' ')
- titleStr[i] = ' ';
- titleStr = titleStr.simplifyWhiteSpace();
- titleStr.compose();
- if ( view() && !view()->part()->parentPart() ) {
- if (titleStr.isNull() || titleStr.isEmpty()) {
- // empty title... set window caption as the URL
- KURL url = m_url;
- url.setRef(TQString::null);
- url.setQuery(TQString::null);
- titleStr = url.prettyURL();
- }
-
- emit view()->part()->setWindowCaption( KStringHandler::csqueeze( titleStr, 128 ) );
- }
-}
-
-DOMString DocumentImpl::nodeName() const
-{
- return "#document";
-}
-
-unsigned short DocumentImpl::nodeType() const
-{
- return Node::DOCUMENT_NODE;
-}
-
-DOMStringImpl* DocumentImpl::textContent() const
-{
- return 0;
-}
-
-void DocumentImpl::setTextContent( const DOMString&, int& )
-{}
-
-ElementImpl *DocumentImpl::createHTMLElement( const DOMString &name )
-{
- uint id = khtml::getTagID( name.string().lower().latin1(), name.string().length() );
-// id = makeId(xhtmlNamespace, id);
-
- ElementImpl *n = 0;
- switch(id)
- {
- case ID_HTML:
- n = new HTMLHtmlElementImpl(docPtr());
- break;
- case ID_HEAD:
- n = new HTMLHeadElementImpl(docPtr());
- break;
- case ID_BODY:
- n = new HTMLBodyElementImpl(docPtr());
- break;
-
-// head elements
- case ID_BASE:
- n = new HTMLBaseElementImpl(docPtr());
- break;
- case ID_LINK:
- n = new HTMLLinkElementImpl(docPtr());
- break;
- case ID_META:
- n = new HTMLMetaElementImpl(docPtr());
- break;
- case ID_STYLE:
- n = new HTMLStyleElementImpl(docPtr());
- break;
- case ID_TITLE:
- n = new HTMLTitleElementImpl(docPtr());
- break;
-
-// frames
- case ID_FRAME:
- n = new HTMLFrameElementImpl(docPtr());
- break;
- case ID_FRAMESET:
- n = new HTMLFrameSetElementImpl(docPtr());
- break;
- case ID_IFRAME:
- n = new HTMLIFrameElementImpl(docPtr());
- break;
-
-// form elements
-// ### FIXME: we need a way to set form dependency after we have made the form elements
- case ID_FORM:
- n = new HTMLFormElementImpl(docPtr(), false);
- break;
- case ID_BUTTON:
- n = new HTMLButtonElementImpl(docPtr());
- break;
- case ID_FIELDSET:
- n = new HTMLFieldSetElementImpl(docPtr());
- break;
- case ID_INPUT:
- n = new HTMLInputElementImpl(docPtr());
- break;
- case ID_ISINDEX:
- n = new HTMLIsIndexElementImpl(docPtr());
- break;
- case ID_LABEL:
- n = new HTMLLabelElementImpl(docPtr());
- break;
- case ID_LEGEND:
- n = new HTMLLegendElementImpl(docPtr());
- break;
- case ID_OPTGROUP:
- n = new HTMLOptGroupElementImpl(docPtr());
- break;
- case ID_OPTION:
- n = new HTMLOptionElementImpl(docPtr());
- break;
- case ID_SELECT:
- n = new HTMLSelectElementImpl(docPtr());
- break;
- case ID_TEXTAREA:
- n = new HTMLTextAreaElementImpl(docPtr());
- break;
-
-// lists
- case ID_DL:
- n = new HTMLDListElementImpl(docPtr());
- break;
- case ID_DD:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
- case ID_DT:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
- case ID_UL:
- n = new HTMLUListElementImpl(docPtr());
- break;
- case ID_OL:
- n = new HTMLOListElementImpl(docPtr());
- break;
- case ID_DIR:
- n = new HTMLDirectoryElementImpl(docPtr());
- break;
- case ID_MENU:
- n = new HTMLMenuElementImpl(docPtr());
- break;
- case ID_LI:
- n = new HTMLLIElementImpl(docPtr());
- break;
-
-// formatting elements (block)
- case ID_DIV:
- case ID_P:
- n = new HTMLDivElementImpl( docPtr(), id );
- break;
- case ID_BLOCKQUOTE:
- case ID_H1:
- case ID_H2:
- case ID_H3:
- case ID_H4:
- case ID_H5:
- case ID_H6:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
- case ID_HR:
- n = new HTMLHRElementImpl(docPtr());
- break;
- case ID_PLAINTEXT:
- case ID_XMP:
- case ID_PRE:
- n = new HTMLPreElementImpl(docPtr(), id);
- break;
-
-// font stuff
- case ID_BASEFONT:
- n = new HTMLBaseFontElementImpl(docPtr());
- break;
- case ID_FONT:
- n = new HTMLFontElementImpl(docPtr());
- break;
-
-// ins/del
- case ID_DEL:
- case ID_INS:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
-
-// anchor
- case ID_A:
- n = new HTMLAnchorElementImpl(docPtr());
- break;
-
-// images
- case ID_IMG:
- n = new HTMLImageElementImpl(docPtr());
- break;
- case ID_MAP:
- n = new HTMLMapElementImpl(docPtr());
- /*n = map;*/
- break;
- case ID_AREA:
- n = new HTMLAreaElementImpl(docPtr());
- break;
-
-// objects, applets and scripts
- case ID_APPLET:
- n = new HTMLAppletElementImpl(docPtr());
- break;
- case ID_OBJECT:
- n = new HTMLObjectElementImpl(docPtr());
- break;
- case ID_EMBED:
- n = new HTMLEmbedElementImpl(docPtr());
- break;
- case ID_PARAM:
- n = new HTMLParamElementImpl(docPtr());
- break;
- case ID_SCRIPT:
- n = new HTMLScriptElementImpl(docPtr());
- break;
-
-// tables
- case ID_TABLE:
- n = new HTMLTableElementImpl(docPtr());
- break;
- case ID_CAPTION:
- n = new HTMLTableCaptionElementImpl(docPtr());
- break;
- case ID_COLGROUP:
- case ID_COL:
- n = new HTMLTableColElementImpl(docPtr(), id);
- break;
- case ID_TR:
- n = new HTMLTableRowElementImpl(docPtr());
- break;
- case ID_TD:
- case ID_TH:
- n = new HTMLTableCellElementImpl(docPtr(), id);
- break;
- case ID_THEAD:
- case ID_TBODY:
- case ID_TFOOT:
- n = new HTMLTableSectionElementImpl(docPtr(), id, false);
- break;
-
-// inline elements
- case ID_BR:
- n = new HTMLBRElementImpl(docPtr());
- break;
- case ID_Q:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
-
-// elements with no special representation in the DOM
-
-// block:
- case ID_ADDRESS:
- case ID_CENTER:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
-// inline
- // %fontstyle
- case ID_TT:
- case ID_U:
- case ID_B:
- case ID_I:
- case ID_S:
- case ID_STRIKE:
- case ID_BIG:
- case ID_SMALL:
-
- // %phrase
- case ID_EM:
- case ID_STRONG:
- case ID_DFN:
- case ID_CODE:
- case ID_SAMP:
- case ID_KBD:
- case ID_VAR:
- case ID_CITE:
- case ID_ABBR:
- case ID_ACRONYM:
-
- // %special
- case ID_SUB:
- case ID_SUP:
- case ID_SPAN:
- case ID_NOBR:
- case ID_WBR:
- case ID_BDO:
- case ID_NOFRAMES:
- n = new HTMLGenericElementImpl(docPtr(), id);
- break;
-
- case ID_MARQUEE:
- n = new HTMLMarqueeElementImpl(docPtr());
- break;
-// text
- case ID_TEXT:
- kdDebug( 6020 ) << "Use document->createTextNode()" << endl;
- break;
-
- default:
- break;
- }
- return n;
-}
-
-TQString DocumentImpl::nextState()
-{
- TQString state;
- if (!m_state.isEmpty())
- {
- state = m_state.first();
- m_state.remove(m_state.begin());
- }
- return state;
-}
-
-TQStringList DocumentImpl::docState()
-{
- TQStringList s;
- for (TQPtrListIterator<NodeImpl> it(m_maintainsState); it.current(); ++it)
- s.append(it.current()->state());
-
- return s;
-}
-
-bool DocumentImpl::unsubmittedFormChanges()
-{
- for (TQPtrListIterator<NodeImpl> it(m_maintainsState); it.current(); ++it)
- if (it.current()->state().right(1)=="M")
- return true;
-
- return false;
-}
-
-RangeImpl *DocumentImpl::createRange()
-{
- return new RangeImpl( docPtr() );
-}
-
-NodeIteratorImpl *DocumentImpl::createNodeIterator(NodeImpl *root, unsigned long whatToShow,
- NodeFilter &filter, bool entityReferenceExpansion,
- int &exceptioncode)
-{
- if (!root) {
- exceptioncode = DOMException::NOT_SUPPORTED_ERR;
- return 0;
- }
-
- return new NodeIteratorImpl(root,whatToShow,filter,entityReferenceExpansion);
-}
-
-TreeWalkerImpl *DocumentImpl::createTreeWalker(NodeImpl *root, unsigned long whatToShow, NodeFilterImpl *filter,
- bool entityReferenceExpansion, int &exceptioncode)
-{
- if (!root) {
- exceptioncode = DOMException::NOT_SUPPORTED_ERR;
- return 0;
- }
-
- return new TreeWalkerImpl( root, whatToShow, filter, entityReferenceExpansion );
-}
-
-void DocumentImpl::setDocumentChanged(bool b)
-{
- if (!changedDocuments)
- changedDocuments = s_changedDocumentsDeleter.setObject( changedDocuments, new TQPtrList<DocumentImpl>() );
-
- if (b && !m_docChanged)
- changedDocuments->append(this);
- else if (!b && m_docChanged)
- changedDocuments->remove(this);
- m_docChanged = b;
-}
-
-void DocumentImpl::recalcStyle( StyleChange change )
-{
-// tqDebug("recalcStyle(%p)", this);
-// TQTime qt;
-// qt.start();
- if (m_inStyleRecalc)
- return; // Guard against re-entrancy. -dwh
-
- m_inStyleRecalc = true;
-
- if( !m_render ) goto bail_out;
-
- if ( change == Force ) {
- RenderStyle* oldStyle = m_render->style();
- if ( oldStyle ) oldStyle->ref();
- RenderStyle* _style = new RenderStyle();
- _style->setDisplay(BLOCK);
- _style->setVisuallyOrdered( visuallyOrdered );
- // ### make the font stuff _really_ work!!!!
-
- khtml::FontDef fontDef;
- TQFont f = TDEGlobalSettings::generalFont();
- fontDef.family = f.family();
- fontDef.italic = f.italic();
- fontDef.weight = f.weight();
- if (m_view) {
- const KHTMLSettings *settings = m_view->part()->settings();
- TQString stdfont = settings->stdFontName();
- if ( !stdfont.isEmpty() )
- fontDef.family = stdfont;
-
- fontDef.size = m_styleSelector->fontSizes()[3];
- }
-
- //kdDebug() << "DocumentImpl::attach: setting to charset " << settings->charset() << endl;
- _style->setFontDef(fontDef);
- _style->htmlFont().update( paintDeviceMetrics() );
- if ( inCompatMode() )
- _style->setHtmlHacks(true); // enable html specific rendering tricks
-
- StyleChange ch = diff( _style, oldStyle );
- if(m_render && ch != NoChange)
- m_render->setStyle(_style);
- else
- delete _style;
- if ( change != Force )
- change = ch;
-
- if (oldStyle)
- oldStyle->deref();
- }
-
- NodeImpl *n;
- for (n = _first; n; n = n->nextSibling())
- if ( change>= Inherit || n->hasChangedChild() || n->changed() )
- n->recalcStyle( change );
- //kdDebug( 6020 ) << "TIME: recalcStyle() dt=" << qt.elapsed() << endl;
-
- if (changed() && m_view)
- m_view->layout();
-
-bail_out:
- setChanged( false );
- setHasChangedChild( false );
- setDocumentChanged( false );
-
- m_inStyleRecalc = false;
-}
-
-void DocumentImpl::updateRendering()
-{
- if (!hasChangedChild()) return;
-
-// TQTime time;
-// time.start();
-// kdDebug() << "UPDATERENDERING: "<<endl;
-
- StyleChange change = NoChange;
-#if 0
- if ( m_styleSelectorDirty ) {
- recalcStyleSelector();
- change = Force;
- }
-#endif
- recalcStyle( change );
-
-// kdDebug() << "UPDATERENDERING time used="<<time.elapsed()<<endl;
-}
-
-void DocumentImpl::updateDocumentsRendering()
-{
- if (!changedDocuments)
- return;
-
- while ( !changedDocuments->isEmpty() ) {
- changedDocuments->first();
- DocumentImpl* it = changedDocuments->take();
- if (it->isDocumentChanged())
- it->updateRendering();
- }
-}
-
-void DocumentImpl::updateLayout()
-{
- bool oldIgnore = m_ignorePendingStylesheets;
-
- if (!haveStylesheetsLoaded()) {
- m_ignorePendingStylesheets = true;
- updateStyleSelector();
- }
-
- updateRendering();
-
- // Only do a layout if changes have occurred that make it necessary.
- if (m_view && renderer() && renderer()->needsLayout())
- m_view->layout();
-
- m_ignorePendingStylesheets = oldIgnore;
-}
-
-void DocumentImpl::attach()
-{
- assert(!attached());
-
- if ( m_view )
- setPaintDevice( TQT_TQPAINTDEVICE(m_view) );
-
- if (!m_renderArena)
- m_renderArena.reset(new RenderArena());
-
- // Create the rendering tree
- assert(!m_styleSelector);
- m_styleSelector = new CSSStyleSelector( this, m_usersheet, m_styleSheets, m_url,
- !inCompatMode() );
- m_render = new (m_renderArena.get()) RenderCanvas(this, m_view);
- m_styleSelector->computeFontSizes(paintDeviceMetrics(), m_view ? m_view->part()->zoomFactor() : 100);
- recalcStyle( Force );
-
- RenderObject* render = m_render;
- m_render = 0;
-
- NodeBaseImpl::attach();
- m_render = render;
-}
-
-void DocumentImpl::detach()
-{
- RenderObject* render = m_render;
-
- // indicate destruction mode, i.e. attached() but m_render == 0
- m_render = 0;
-
- delete m_tokenizer;
- m_tokenizer = 0;
-
- // Empty out these lists as a performance optimization
- m_imageLoadEventDispatchSoonList.clear();
- m_imageLoadEventDispatchingList.clear();
- NodeBaseImpl::detach();
-
- if ( render )
- render->detach();
-
- m_view = 0;
-
- m_renderArena.reset();
-}
-
-void DocumentImpl::setVisuallyOrdered()
-{
- visuallyOrdered = true;
- if (m_render)
- m_render->style()->setVisuallyOrdered(true);
-}
-
-void DocumentImpl::setSelection(NodeImpl* s, int sp, NodeImpl* e, int ep)
-{
- if ( m_render )
- static_cast<RenderCanvas*>(m_render)->setSelection(s->renderer(),sp,e->renderer(),ep);
-}
-
-void DocumentImpl::clearSelection()
-{
- if ( m_render )
- static_cast<RenderCanvas*>(m_render)->clearSelection();
-}
-
-khtml::Tokenizer *DocumentImpl::createTokenizer()
-{
- return new khtml::XMLTokenizer(docPtr(),m_view);
-}
-
-void DocumentImpl::setPaintDevice( TQPaintDevice *dev )
-{
- if (m_paintDevice != dev) {
- m_paintDevice = dev;
- delete m_paintDeviceMetrics;
- m_paintDeviceMetrics = new TQPaintDeviceMetrics( dev );
- }
-}
-
-void DocumentImpl::open( bool clearEventListeners )
-{
- if (parsing()) return;
-
- if (m_tokenizer)
- close();
-
- delete m_tokenizer;
- m_tokenizer = 0;
-
- KHTMLView* view = m_view;
- bool was_attached = attached();
- if ( was_attached )
- detach();
-
- removeChildren();
- delete m_styleSelector;
- m_styleSelector = 0;
- m_view = view;
- if ( was_attached )
- attach();
-
- if (clearEventListeners)
- m_windowEventListeners.clear();
-
- m_tokenizer = createTokenizer();
- m_decoderMibEnum = 0;
- connect(m_tokenizer,TQT_SIGNAL(finishedParsing()),this,TQT_SIGNAL(finishedParsing()));
- m_tokenizer->begin();
-}
-
-HTMLElementImpl* DocumentImpl::body()
-{
- NodeImpl *de = documentElement();
- if (!de)
- return 0;
-
- // try to prefer a FRAMESET element over BODY
- NodeImpl* body = 0;
- for (NodeImpl* i = de->firstChild(); i; i = i->nextSibling()) {
- if (i->id() == ID_FRAMESET)
- return static_cast<HTMLElementImpl*>(i);
-
- if (i->id() == ID_BODY)
- body = i;
- }
- return static_cast<HTMLElementImpl *>(body);
-}
-
-void DocumentImpl::close( )
-{
- if (parsing() || !m_tokenizer) return;
-
- if ( m_render )
- m_render->close();
-
- // on an explicit document.close(), the tokenizer might still be waiting on scripts,
- // and in that case we don't want to destroy it because that will prevent the
- // scripts from getting processed.
- if (m_tokenizer && !m_tokenizer->isWaitingForScripts() && !m_tokenizer->isExecutingScript()) {
- delete m_tokenizer;
- m_tokenizer = 0;
- }
-
- if (m_view)
- m_view->part()->checkEmitLoadEvent();
-}
-
-void DocumentImpl::write( const DOMString &text )
-{
- write(text.string());
-}
-
-void DocumentImpl::write( const TQString &text )
-{
- if (!m_tokenizer) {
- open();
- if (m_view)
- m_view->part()->resetFromScript();
- m_tokenizer->setAutoClose();
- write(TQString::fromLatin1("<html>"));
- }
- m_tokenizer->write(text, false);
-}
-
-void DocumentImpl::writeln( const DOMString &text )
-{
- write(text);
- write(DOMString("\n"));
-}
-
-void DocumentImpl::finishParsing ( )
-{
- if(m_tokenizer)
- m_tokenizer->finish();
-}
-
-void DocumentImpl::setUserStyleSheet( const TQString& sheet )
-{
- if ( m_usersheet != sheet ) {
- m_usersheet = sheet;
- updateStyleSelector();
- }
-}
-
-CSSStyleSheetImpl* DocumentImpl::elementSheet()
-{
- if (!m_elemSheet) {
- m_elemSheet = new CSSStyleSheetImpl(this, baseURL().url() );
- m_elemSheet->ref();
- }
- return m_elemSheet;
-}
-
-void DocumentImpl::determineParseMode( const TQString &/*str*/ )
-{
- // For XML documents, use strict parse mode
- pMode = Strict;
- hMode = XHtml;
- kdDebug(6020) << " using strict parseMode" << endl;
-}
-
-NodeImpl *DocumentImpl::nextFocusNode(NodeImpl *fromNode)
-{
- unsigned short fromTabIndex;
-
- if (!fromNode) {
- // No starting node supplied; begin with the top of the document
- NodeImpl *n;
-
- int lowestTabIndex = 65535;
- for (n = this; n != 0; n = n->traverseNextNode()) {
- if (n->isTabFocusable()) {
- if ((n->tabIndex() > 0) && (n->tabIndex() < lowestTabIndex))
- lowestTabIndex = n->tabIndex();
- }
- }
-
- if (lowestTabIndex == 65535)
- lowestTabIndex = 0;
-
- // Go to the first node in the document that has the desired tab index
- for (n = this; n != 0; n = n->traverseNextNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == lowestTabIndex))
- return n;
- }
-
- return 0;
- }
- else {
- fromTabIndex = fromNode->tabIndex();
- }
-
- if (fromTabIndex == 0) {
- // Just need to find the next selectable node after fromNode (in document order) that doesn't have a tab index
- NodeImpl *n = fromNode->traverseNextNode();
- while (n && !(n->isTabFocusable() && n->tabIndex() == 0))
- n = n->traverseNextNode();
- return n;
- }
- else {
- // Find the lowest tab index out of all the nodes except fromNode, that is greater than or equal to fromNode's
- // tab index. For nodes with the same tab index as fromNode, we are only interested in those that come after
- // fromNode in document order.
- // If we don't find a suitable tab index, the next focus node will be one with a tab index of 0.
- unsigned short lowestSuitableTabIndex = 65535;
- NodeImpl *n;
-
- bool reachedFromNode = false;
- for (n = this; n != 0; n = n->traverseNextNode()) {
- if (n->isTabFocusable() &&
- ((reachedFromNode && (n->tabIndex() >= fromTabIndex)) ||
- (!reachedFromNode && (n->tabIndex() > fromTabIndex))) &&
- (n->tabIndex() < lowestSuitableTabIndex) &&
- (n != fromNode)) {
-
- // We found a selectable node with a tab index at least as high as fromNode's. Keep searching though,
- // as there may be another node which has a lower tab index but is still suitable for use.
- lowestSuitableTabIndex = n->tabIndex();
- }
-
- if (n == fromNode)
- reachedFromNode = true;
- }
-
- if (lowestSuitableTabIndex == 65535) {
- // No next node with a tab index -> just take first node with tab index of 0
- NodeImpl *n = this;
- while (n && !(n->isTabFocusable() && n->tabIndex() == 0))
- n = n->traverseNextNode();
- return n;
- }
-
- // Search forwards from fromNode
- for (n = fromNode->traverseNextNode(); n != 0; n = n->traverseNextNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == lowestSuitableTabIndex))
- return n;
- }
-
- // The next node isn't after fromNode, start from the beginning of the document
- for (n = this; n != fromNode; n = n->traverseNextNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == lowestSuitableTabIndex))
- return n;
- }
-
- assert(false); // should never get here
- return 0;
- }
-}
-
-NodeImpl *DocumentImpl::previousFocusNode(NodeImpl *fromNode)
-{
- NodeImpl *lastNode = this;
- while (lastNode->lastChild())
- lastNode = lastNode->lastChild();
-
- if (!fromNode) {
- // No starting node supplied; begin with the very last node in the document
- NodeImpl *n;
-
- int highestTabIndex = 0;
- for (n = lastNode; n != 0; n = n->traversePreviousNode()) {
- if (n->isTabFocusable()) {
- if (n->tabIndex() == 0)
- return n;
- else if (n->tabIndex() > highestTabIndex)
- highestTabIndex = n->tabIndex();
- }
- }
-
- // No node with a tab index of 0; just go to the last node with the highest tab index
- for (n = lastNode; n != 0; n = n->traversePreviousNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == highestTabIndex))
- return n;
- }
-
- return 0;
- }
- else {
- unsigned short fromTabIndex = fromNode->tabIndex();
-
- if (fromTabIndex == 0) {
- // Find the previous selectable node before fromNode (in document order) that doesn't have a tab index
- NodeImpl *n = fromNode->traversePreviousNode();
- while (n && !(n->isTabFocusable() && n->tabIndex() == 0))
- n = n->traversePreviousNode();
- if (n)
- return n;
-
- // No previous nodes with a 0 tab index, go to the last node in the document that has the highest tab index
- int highestTabIndex = 0;
- for (n = this; n != 0; n = n->traverseNextNode()) {
- if (n->isTabFocusable() && (n->tabIndex() > highestTabIndex))
- highestTabIndex = n->tabIndex();
- }
-
- if (highestTabIndex == 0)
- return 0;
-
- for (n = lastNode; n != 0; n = n->traversePreviousNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == highestTabIndex))
- return n;
- }
-
- assert(false); // should never get here
- return 0;
- }
- else {
- // Find the lowest tab index out of all the nodes except fromNode, that is less than or equal to fromNode's
- // tab index. For nodes with the same tab index as fromNode, we are only interested in those before
- // fromNode.
- // If we don't find a suitable tab index, then there will be no previous focus node.
- unsigned short highestSuitableTabIndex = 0;
- NodeImpl *n;
-
- bool reachedFromNode = false;
- for (n = this; n != 0; n = n->traverseNextNode()) {
- if (n->isTabFocusable() &&
- ((!reachedFromNode && (n->tabIndex() <= fromTabIndex)) ||
- (reachedFromNode && (n->tabIndex() < fromTabIndex))) &&
- (n->tabIndex() > highestSuitableTabIndex) &&
- (n != fromNode)) {
-
- // We found a selectable node with a tab index no higher than fromNode's. Keep searching though, as
- // there may be another node which has a higher tab index but is still suitable for use.
- highestSuitableTabIndex = n->tabIndex();
- }
-
- if (n == fromNode)
- reachedFromNode = true;
- }
-
- if (highestSuitableTabIndex == 0) {
- // No previous node with a tab index. Since the order specified by HTML is nodes with tab index > 0
- // first, this means that there is no previous node.
- return 0;
- }
-
- // Search backwards from fromNode
- for (n = fromNode->traversePreviousNode(); n != 0; n = n->traversePreviousNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == highestSuitableTabIndex))
- return n;
- }
- // The previous node isn't before fromNode, start from the end of the document
- for (n = lastNode; n != fromNode; n = n->traversePreviousNode()) {
- if (n->isTabFocusable() && (n->tabIndex() == highestSuitableTabIndex))
- return n;
- }
-
- assert(false); // should never get here
- return 0;
- }
- }
-}
-
-ElementImpl* DocumentImpl::findAccessKeyElement(TQChar c)
-{
- c = c.upper();
- for( NodeImpl* n = this;
- n != NULL;
- n = n->traverseNextNode()) {
- if( n->isElementNode()) {
- ElementImpl* en = static_cast< ElementImpl* >( n );
- DOMString s = en->getAttribute( ATTR_ACCESSKEY );
- if( s.length() == 1
- && s[ 0 ].upper() == c )
- return en;
- }
- }
- return NULL;
-}
-
-int DocumentImpl::nodeAbsIndex(NodeImpl *node)
-{
- assert(node->getDocument() == this);
-
- int absIndex = 0;
- for (NodeImpl *n = node; n && n != this; n = n->traversePreviousNode())
- absIndex++;
- return absIndex;
-}
-
-NodeImpl *DocumentImpl::nodeWithAbsIndex(int absIndex)
-{
- NodeImpl *n = this;
- for (int i = 0; n && (i < absIndex); i++) {
- n = n->traverseNextNode();
- }
- return n;
-}
-
-void DocumentImpl::processHttpEquiv(const DOMString &equiv, const DOMString &content)
-{
- assert(!equiv.isNull() && !content.isNull());
-
- KHTMLView *v = getDocument()->view();
-
- if(strcasecmp(equiv, "refresh") == 0 && v && v->part()->metaRefreshEnabled())
- {
- // get delay and url
- TQString str = content.string().stripWhiteSpace();
- int pos = str.find(TQRegExp("[;,]"));
- if ( pos == -1 )
- pos = str.find(TQRegExp("[ \t]"));
-
- bool ok = false;
- int delay = kMax( 0, content.implementation()->toInt(&ok) );
- if ( !ok && str.length() && str[0] == '.' )
- ok = true;
-
- if (pos == -1) // There can be no url (David)
- {
- if(ok)
- v->part()->scheduleRedirection(delay, v->part()->url().url() );
- } else {
- pos++;
- while(pos < (int)str.length() && str[pos].isSpace()) pos++;
- str = str.mid(pos);
- if(str.find("url", 0, false ) == 0) str = str.mid(3);
- str = str.stripWhiteSpace();
- if ( str.length() && str[0] == '=' ) str = str.mid( 1 ).stripWhiteSpace();
- while(str.length() &&
- (str[str.length()-1] == ';' || str[str.length()-1] == ','))
- str.setLength(str.length()-1);
- str = parseURL( DOMString(str) ).string();
- TQString newURL = getDocument()->completeURL( str );
- if ( ok )
- v->part()->scheduleRedirection(delay, getDocument()->completeURL( str ), delay < 2 || newURL == URL().url());
- }
- }
- else if(strcasecmp(equiv, "expires") == 0)
- {
- bool relative = false;
- TQString str = content.string().stripWhiteSpace();
- time_t expire_date = KRFCDate::parseDate(str);
- if (!expire_date)
- {
- expire_date = str.toULong();
- relative = true;
- }
- if (!expire_date)
- expire_date = 1; // expire now
- if (m_docLoader)
- m_docLoader->setExpireDate(expire_date, relative);
- }
- else if(v && (strcasecmp(equiv, "pragma") == 0 || strcasecmp(equiv, "cache-control") == 0))
- {
- TQString str = content.string().lower().stripWhiteSpace();
- KURL url = v->part()->url();
- if ((str == "no-cache") && url.protocol().startsWith("http"))
- {
- TDEIO::http_update_cache(url, true, 0);
- }
- }
- else if( (strcasecmp(equiv, "set-cookie") == 0))
- {
- // ### make setCookie work on XML documents too; e.g. in case of <html:meta .....>
- HTMLDocumentImpl *d = static_cast<HTMLDocumentImpl *>(this);
- d->setCookie(content);
- }
- else if (strcasecmp(equiv, "default-style") == 0) {
- // HTML 4.0 14.3.2
- // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
- m_preferredStylesheetSet = content;
- updateStyleSelector();
- }
- else if (strcasecmp(equiv, "content-language") == 0) {
- m_contentLanguage = content.string();
- }
-}
-
-bool DocumentImpl::prepareMouseEvent( bool readonly, int _x, int _y, MouseEvent *ev )
-{
- if ( m_render ) {
- assert(m_render->isCanvas());
- RenderObject::NodeInfo renderInfo(readonly, ev->type == MousePress);
- bool isInside = m_render->layer()->nodeAtPoint(renderInfo, _x, _y);
- ev->innerNode = renderInfo.innerNode();
- ev->innerNonSharedNode = renderInfo.innerNonSharedNode();
-
- if (renderInfo.URLElement()) {
- assert(renderInfo.URLElement()->isElementNode());
- //tqDebug("urlnode: %s (%d)", getTagName(renderInfo.URLElement()->id()).string().latin1(), renderInfo.URLElement()->id());
-
- ElementImpl* e = static_cast<ElementImpl*>(renderInfo.URLElement());
- DOMString href = khtml::parseURL(e->getAttribute(ATTR_HREF));
- DOMString target = e->getAttribute(ATTR_TARGET);
-
- if (!target.isNull() && !href.isNull()) {
- ev->target = target;
- ev->url = href;
- }
- else
- ev->url = href;
- }
-
- if (!readonly)
- updateRendering();
-
- return isInside;
- }
-
-
- return false;
-}
-
-
-// DOM Section 1.1.1
-bool DocumentImpl::childTypeAllowed( unsigned short type )
-{
- switch (type) {
- case Node::ATTRIBUTE_NODE:
- case Node::CDATA_SECTION_NODE:
- case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::DOCUMENT_NODE:
- case Node::ENTITY_NODE:
- case Node::ENTITY_REFERENCE_NODE:
- case Node::NOTATION_NODE:
- case Node::TEXT_NODE:
-// case Node::XPATH_NAMESPACE_NODE:
- return false;
- case Node::COMMENT_NODE:
- case Node::PROCESSING_INSTRUCTION_NODE:
- return true;
- case Node::DOCUMENT_TYPE_NODE:
- case Node::ELEMENT_NODE:
- // Documents may contain no more than one of each of these.
- // (One Element and one DocumentType.)
- for (NodeImpl* c = firstChild(); c; c = c->nextSibling())
- if (c->nodeType() == type)
- return false;
- return true;
- }
- return false;
-}
-
-NodeImpl *DocumentImpl::cloneNode ( bool /*deep*/ )
-{
- // Spec says cloning Document nodes is "implementation dependent"
- // so we do not support it...
- return 0;
-}
-
-
-typedef const char* (*NameLookupFunction)(unsigned short id);
-typedef int (*IdLookupFunction)(const char *tagStr, int len);
-
-NodeImpl::Id DocumentImpl::getId( NodeImpl::IdType _type, DOMStringImpl* _nsURI, DOMStringImpl *_prefix,
- DOMStringImpl *_name, bool readonly, bool /*lookupHTML*/, int *pExceptioncode)
-{
- /*kdDebug() << "DocumentImpl::getId( type: " << _type << ", uri: " << DOMString(_nsURI).string()
- << ", prefix: " << DOMString(_prefix).string() << ", name: " << DOMString(_name).string()
- << ", readonly: " << readonly
- << ", lookupHTML: " << lookupHTML
- << ", exceptions: " << (pExceptioncode ? "yes" : "no")
- << " )" << endl;*/
-
- if(!_name) return 0;
- IdNameMapping *map;
- IdLookupFunction lookup;
-
- switch (_type) {
- case NodeImpl::ElementId:
- map = m_elementMap;
- lookup = getTagID;
- break;
- case NodeImpl::AttributeId:
- map = m_attrMap;
- lookup = getAttrID;
- break;
- case NodeImpl::NamespaceId:
- if( strcasecmp(_name, XHTML_NAMESPACE) == 0)
- return xhtmlNamespace;
- if( _name->l == 0)
- return emptyNamespace;
- // defaultNamespace handled by "if (!_name) return 0"
- map = m_namespaceMap;
- lookup = 0;
- break;
- default:
- return 0;
- }
- // Names and attributes with ""
- if (_name->l == 0) return 0;
-
- NodeImpl::Id id, nsid = 0;
- TQConstString n(_name->s, _name->l);
- bool cs = true; // case sensitive
- if (_type != NodeImpl::NamespaceId) {
- if (_nsURI)
- nsid = getId( NodeImpl::NamespaceId, 0, 0, _nsURI, false, false, 0 ) << 16;
-
- // Each document maintains a mapping of tag name -> id for every tag name encountered
- // in the document.
- cs = (htmlMode() == XHtml) || (_nsURI && _type != NodeImpl::AttributeId);
-
- // First see if it's a HTML element name
- // xhtml is lower case - case sensitive, easy to implement
- if ( cs && (id = lookup(n.string().ascii(), _name->l)) ) {
- map->addAlias(_prefix, _name, cs, id);
- return nsid + id;
- }
- // compatibility: upper case - case insensitive
- if ( !cs && (id = lookup(n.string().lower().ascii(), _name->l )) ) {
- map->addAlias(_prefix, _name, cs, id);
- return nsid + id;
- }
- }
-
- // Look in the names array for the name
- // compatibility mode has to lookup upper case
- TQString name = cs ? n.string() : n.string().upper();
-
- if (!_nsURI) {
- id = (NodeImpl::Id)(long) map->ids.find( name );
- if (!id && _type != NodeImpl::NamespaceId) {
- id = (NodeImpl::Id)(long) map->ids.find( "aliases: " + name );
- }
- } else {
- id = (NodeImpl::Id)(long) map->ids.find( name );
- if (!readonly && id && _prefix && _prefix->l) {
- // we were called in registration mode... check if the alias exists
- TQConstString px( _prefix->s, _prefix->l );
- TQString qn("aliases: " + (cs ? px.string() : px.string().upper()) + ":" + name);
- if (!map->ids.find( qn )) {
- map->ids.insert( qn, (void*)id );
- }
- }
- }
-
- if (id) return nsid + id;
-
- // unknown
- if (readonly) return 0;
-
- if ( pExceptioncode && _type != NodeImpl::NamespaceId && !Element::khtmlValidQualifiedName(_name)) {
- *pExceptioncode = DOMException::INVALID_CHARACTER_ERR;
- return 0;
- }
-
- // Name not found, so let's add it
- NodeImpl::Id cid = map->count++ + map->idStart;
- map->names.insert( cid, _name );
- _name->ref();
-
- map->ids.insert( name, (void*)cid );
-
- // and register an alias if needed for DOM1 methods compatibility
- map->addAlias(_prefix, _name, cs, cid);
-
- return nsid + cid;
- }
-
-NodeImpl::Id DocumentImpl::getId( NodeImpl::IdType _type, DOMStringImpl *_nodeName, bool readonly, bool lookupHTML, int *pExceptioncode)
-{
- return getId(_type, 0, 0, _nodeName, readonly, lookupHTML, pExceptioncode);
-}
-
-DOMString DocumentImpl::getName( NodeImpl::IdType _type, NodeImpl::Id _id ) const
-{
- IdNameMapping *map;
- NameLookupFunction lookup;
- bool hasNS = (namespacePart(_id) != defaultNamespace);
- switch (_type) {
- case NodeImpl::ElementId:
- map = m_elementMap;
- lookup = getTagName;
- break;
- case NodeImpl::AttributeId:
- map = m_attrMap;
- lookup = getAttrName;
- break;
- case NodeImpl::NamespaceId:
- if( _id == xhtmlNamespace )
- return XHTML_NAMESPACE;
- else
- if( _id == emptyNamespace )
- return DOMString("");
- else
- if ( _id == defaultNamespace )
- return DOMString();
- map = m_namespaceMap;
- lookup = 0;
- break;
- default:
- return DOMString();;
- }
- _id = localNamePart(_id) ;
- if (_id >= map->idStart) {
- return map->names[_id];
- }
- else if (lookup) {
- // ### put them in a cache
- if (hasNS)
- return DOMString(lookup(_id)).lower();
- else
- return lookup(_id);
- } else
- return DOMString();
-}
-
-// This method is called whenever a top-level stylesheet has finished loading.
-void DocumentImpl::styleSheetLoaded()
-{
- // Make sure we knew this sheet was pending, and that our count isn't out of sync.
- assert(m_pendingStylesheets > 0);
-
- m_pendingStylesheets--;
- updateStyleSelector();
-}
-
-DOMString DocumentImpl::selectedStylesheetSet() const
-{
- if (!view()) return DOMString();
-
- return view()->part()->d->m_sheetUsed;
-}
-
-void DocumentImpl::setSelectedStylesheetSet(const DOMString& s)
-{
- // this code is evil
- if (view() && view()->part()->d->m_sheetUsed != s.string()) {
- view()->part()->d->m_sheetUsed = s.string();
- updateStyleSelector();
- }
-}
-
-void DocumentImpl::addStyleSheet(StyleSheetImpl *sheet, int *exceptioncode)
-{
- int excode = 0;
-
- if (!m_addedStyleSheets) {
- m_addedStyleSheets = new StyleSheetListImpl;
- m_addedStyleSheets->ref();
- }
-
- m_addedStyleSheets->add(sheet);
- if (sheet->isCSSStyleSheet()) updateStyleSelector();
-
- if (exceptioncode) *exceptioncode = excode;
-}
-
-void DocumentImpl::removeStyleSheet(StyleSheetImpl *sheet, int *exceptioncode)
-{
- int excode = 0;
- bool removed = false;
- bool is_css = sheet->isCSSStyleSheet();
-
- if (m_addedStyleSheets) {
- bool in_main_list = !sheet->hasOneRef();
- removed = m_addedStyleSheets->styleSheets.removeRef(sheet);
- sheet->deref();
-
- if (m_addedStyleSheets->styleSheets.count() == 0) {
- bool reset = m_addedStyleSheets->hasOneRef();
- m_addedStyleSheets->deref();
- if (reset) m_addedStyleSheets = 0;
- }
-
- // remove from main list, too
- if (in_main_list) m_styleSheets->remove(sheet);
- }
-
- if (removed) {
- if (is_css) updateStyleSelector();
- } else
- excode = DOMException::NOT_FOUND_ERR;
-
- if (exceptioncode) *exceptioncode = excode;
-}
-
-void DocumentImpl::updateStyleSelector(bool shallow)
-{
-// kdDebug() << "PENDING " << m_pendingStylesheets << endl;
-
- // Don't bother updating, since we haven't loaded all our style info yet.
- if (m_pendingStylesheets > 0)
- return;
-
- if (shallow)
- rebuildStyleSelector();
- else
- recalcStyleSelector();
- recalcStyle(Force);
-#if 0
-
- m_styleSelectorDirty = true;
-#endif
- if ( renderer() )
- renderer()->setNeedsLayoutAndMinMaxRecalc();
-}
-
-void DocumentImpl::recalcStyleSelector()
-{
- if ( !m_render || !attached() ) return;
-
- assert(m_pendingStylesheets==0);
-
- TQPtrList<StyleSheetImpl> oldStyleSheets = m_styleSheets->styleSheets;
- m_styleSheets->styleSheets.clear();
- TQString sheetUsed = view() ? view()->part()->d->m_sheetUsed.replace("&&", "&") : TQString();
- bool autoselect = sheetUsed.isEmpty();
- if (autoselect && !m_preferredStylesheetSet.isEmpty())
- sheetUsed = m_preferredStylesheetSet.string();
- NodeImpl *n;
- for (int i=0 ; i<2 ; i++) {
- m_availableSheets.clear();
- m_availableSheets << i18n("Basic Page Style");
- bool canResetSheet = false;
-
- for (n = this; n; n = n->traverseNextNode()) {
- StyleSheetImpl *sheet = 0;
-
- if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
- {
- // Processing instruction (XML documents only)
- ProcessingInstructionImpl* pi = static_cast<ProcessingInstructionImpl*>(n);
- sheet = pi->sheet();
- if (!sheet && !pi->localHref().isEmpty())
- {
- // Processing instruction with reference to an element in this document - e.g.
- // <?xml-stylesheet href="#mystyle">, with the element
- // <foo id="mystyle">heading { color: red; }</foo> at some location in
- // the document
- ElementImpl* elem = getElementById(pi->localHref());
- if (elem) {
- DOMString sheetText("");
- NodeImpl *c;
- for (c = elem->firstChild(); c; c = c->nextSibling()) {
- if (c->nodeType() == Node::TEXT_NODE || c->nodeType() == Node::CDATA_SECTION_NODE)
- sheetText += c->nodeValue();
- }
-
- CSSStyleSheetImpl *cssSheet = new CSSStyleSheetImpl(this);
- cssSheet->parseString(sheetText);
- pi->setStyleSheet(cssSheet);
- sheet = cssSheet;
- }
- }
-
- }
- else if (n->isHTMLElement() && ( n->id() == ID_LINK || n->id() == ID_STYLE) ) {
- TQString title;
- if ( n->id() == ID_LINK ) {
- HTMLLinkElementImpl* l = static_cast<HTMLLinkElementImpl*>(n);
- if (l->isCSSStyleSheet()) {
- sheet = l->sheet();
-
- if (sheet || l->isLoading() || l->isAlternate() )
- title = l->getAttribute(ATTR_TITLE).string();
-
- if ((autoselect || title != sheetUsed) && l->isDisabled()) {
- sheet = 0;
- } else if (!title.isEmpty() && !l->isAlternate() && sheetUsed.isEmpty()) {
- sheetUsed = title;
- l->setDisabled(false);
- }
- }
- }
- else {
- // <STYLE> element
- HTMLStyleElementImpl* s = static_cast<HTMLStyleElementImpl*>(n);
- if (!s->isLoading()) {
- sheet = s->sheet();
- if (sheet) title = s->getAttribute(ATTR_TITLE).string();
- }
- if (!title.isEmpty() && sheetUsed.isEmpty())
- sheetUsed = title;
- }
-
- if ( !title.isEmpty() ) {
- if ( title != sheetUsed )
- sheet = 0; // don't use it
-
- title = title.replace('&', "&&");
-
- if ( !m_availableSheets.contains( title ) )
- m_availableSheets.append( title );
- }
- }
- else if (n->isHTMLElement() && n->id() == ID_BODY) {
- // <BODY> element (doesn't contain styles as such but vlink="..." and friends
- // are treated as style declarations)
- sheet = static_cast<HTMLBodyElementImpl*>(n)->sheet();
- }
-
- if (sheet) {
- sheet->ref();
- m_styleSheets->styleSheets.append(sheet);
- }
-
- // For HTML documents, stylesheets are not allowed within/after the <BODY> tag. So we
- // can stop searching here.
- if (isHTMLDocument() && n->id() == ID_BODY) {
- canResetSheet = !canResetSheet;
- break;
- }
- }
-
- // we're done if we don't select an alternative sheet
- // or we found the sheet we selected
- if (sheetUsed.isEmpty() ||
- (!canResetSheet && tokenizer()) ||
- m_availableSheets.contains(sheetUsed)) {
- break;
- }
-
- // the alternative sheet we used doesn't exist anymore
- // so try from scratch again
- if (view())
- view()->part()->d->m_sheetUsed = TQString::null;
- if (!m_preferredStylesheetSet.isEmpty() && !(sheetUsed == m_preferredStylesheetSet))
- sheetUsed = m_preferredStylesheetSet.string();
- else
- sheetUsed = TQString::null;
- autoselect = true;
- }
-
- // Include programmatically added style sheets
- if (m_addedStyleSheets) {
- TQPtrListIterator<StyleSheetImpl> it = m_addedStyleSheets->styleSheets;
- for (; *it; ++it) {
- if ((*it)->isCSSStyleSheet() && !(*it)->disabled())
- m_styleSheets->add(*it);
- }
- }
-
- // De-reference all the stylesheets in the old list
- TQPtrListIterator<StyleSheetImpl> it(oldStyleSheets);
- for (; it.current(); ++it)
- it.current()->deref();
-
- rebuildStyleSelector();
-}
-
-void DocumentImpl::rebuildStyleSelector()
-{
- // Create a new style selector
- delete m_styleSelector;
- TQString usersheet = m_usersheet;
- if ( m_view && m_view->mediaType() == "print" )
- usersheet += m_printSheet;
- m_styleSelector = new CSSStyleSelector( this, usersheet, m_styleSheets, m_url,
- !inCompatMode() );
-
- m_styleSelectorDirty = false;
-}
-
-void DocumentImpl::setHoverNode(NodeImpl *newHoverNode)
-{
- NodeImpl* oldHoverNode = m_hoverNode;
- if (newHoverNode ) newHoverNode->ref();
- m_hoverNode = newHoverNode;
- if ( oldHoverNode ) oldHoverNode->deref();
-}
-
-void DocumentImpl::setActiveNode(NodeImpl* newActiveNode)
-{
- NodeImpl* oldActiveNode = m_activeNode;
- if (newActiveNode ) newActiveNode->ref();
- m_activeNode = newActiveNode;
- if ( oldActiveNode ) oldActiveNode->deref();
-}
-
-void DocumentImpl::setFocusNode(NodeImpl *newFocusNode)
-{
- // don't process focus changes while detaching
- if( !m_render ) return;
-
- // We do want to blur if a widget is being detached,
- // but we don't want to emit events since that
- // triggers updateLayout() and may recurse detach()
- bool widgetDetach = m_focusNode && m_focusNode != this &&
- m_focusNode->renderer() && !m_focusNode->renderer()->parent();
-
- // Make sure newFocusNode is actually in this document
- if (newFocusNode && (newFocusNode->getDocument() != this))
- return;
-
- if (m_focusNode != newFocusNode) {
- NodeImpl *oldFocusNode = m_focusNode;
- // Set focus on the new node
- m_focusNode = newFocusNode;
- // Remove focus from the existing focus node (if any)
- if (oldFocusNode) {
- if (oldFocusNode->active())
- oldFocusNode->setActive(false);
-
- oldFocusNode->setFocus(false);
-
- if (!widgetDetach) {
- oldFocusNode->dispatchHTMLEvent(EventImpl::BLUR_EVENT,false,false);
- oldFocusNode->dispatchUIEvent(EventImpl::DOMFOCUSOUT_EVENT);
- }
- if ((oldFocusNode == this) && oldFocusNode->hasOneRef()) {
- oldFocusNode->deref(); // deletes this
- return;
- }
- else {
- oldFocusNode->deref();
- }
- }
-
- if (m_focusNode) {
- m_focusNode->ref();
- m_focusNode->dispatchHTMLEvent(EventImpl::FOCUS_EVENT,false,false);
- if (m_focusNode != newFocusNode) return;
- m_focusNode->dispatchUIEvent(EventImpl::DOMFOCUSIN_EVENT);
- if (m_focusNode != newFocusNode) return;
- m_focusNode->setFocus();
- if (m_focusNode != newFocusNode) return;
-
- // eww, I suck. set the qt focus correctly
- // ### find a better place in the code for this
- if (view()) {
- if (!m_focusNode->renderer() || !m_focusNode->renderer()->isWidget())
- view()->setFocus();
- else if (static_cast<RenderWidget*>(m_focusNode->renderer())->widget())
- {
- if (view()->isVisible())
- static_cast<RenderWidget*>(m_focusNode->renderer())->widget()->setFocus();
- }
- }
- } else {
- //We're blurring. Better clear the Qt focus/give it to the view...
- if (view())
- view()->setFocus();
- }
-
- if (!widgetDetach)
- updateRendering();
- }
-}
-
-void DocumentImpl::setCSSTarget(NodeImpl* n)
-{
- if (n == m_cssTarget)
- return;
-
- if (m_cssTarget) {
- m_cssTarget->setChanged();
- m_cssTarget->deref();
- }
- m_cssTarget = n;
- if (n) {
- n->setChanged();
- n->ref();
- }
-}
-
-void DocumentImpl::attachNodeIterator(NodeIteratorImpl *ni)
-{
- m_nodeIterators.append(ni);
-}
-
-void DocumentImpl::detachNodeIterator(NodeIteratorImpl *ni)
-{
- m_nodeIterators.remove(ni);
-}
-
-void DocumentImpl::notifyBeforeNodeRemoval(NodeImpl *n)
-{
- TQPtrListIterator<NodeIteratorImpl> it(m_nodeIterators);
- for (; it.current(); ++it)
- it.current()->notifyBeforeNodeRemoval(n);
-}
-
-bool DocumentImpl::isURLAllowed(const TQString& url) const
-{
- KHTMLPart *thisPart = part();
-
- KURL newURL(completeURL(url));
- newURL.setRef(TQString::null);
-
- if (KHTMLFactory::defaultHTMLSettings()->isAdFiltered( newURL.url() ))
- return false;
-
- // Prohibit non-file URLs if we are asked to.
- if (!thisPart || thisPart->onlyLocalReferences() && newURL.protocol() != "file" && newURL.protocol() != "data")
- return false;
-
- // do we allow this suburl ?
- if ( !kapp || (newURL.protocol() != "javascript" && !kapp->authorizeURLAction("redirect", thisPart->url(), newURL)) )
- return false;
-
- // We allow one level of self-reference because some sites depend on that.
- // But we don't allow more than one.
- bool foundSelfReference = false;
- for (KHTMLPart *part = thisPart; part; part = part->parentPart()) {
- KURL partURL = part->url();
- partURL.setRef(TQString::null);
- if (partURL == newURL) {
- if (foundSelfReference)
- return false;
- foundSelfReference = true;
- }
- }
-
- return true;
-}
-
-void DocumentImpl::setDesignMode(bool b)
-{
- if (part())
- part()->setEditable(b);
-}
-
-bool DocumentImpl::designMode() const
-{
- return part() ? part()->isEditable() : false;
-}
-
-EventImpl *DocumentImpl::createEvent(const DOMString &eventType, int &exceptioncode)
-{
- if (eventType == "UIEvents" || eventType == "UIEvent")
- return new UIEventImpl();
- else if (eventType == "MouseEvents" || eventType == "MouseEvent")
- return new MouseEventImpl();
- else if (eventType == "TextEvent")
- return new TextEventImpl();
- else if (eventType == "KeyboardEvent")
- return new KeyboardEventImpl();
- else if (eventType == "MutationEvents" || eventType == "MutationEvent")
- return new MutationEventImpl();
- else if (eventType == "HTMLEvents" || eventType == "Events" ||
- eventType == "HTMLEvent" || eventType == "Event")
- return new EventImpl();
- else {
- exceptioncode = DOMException::NOT_SUPPORTED_ERR;
- return 0;
- }
-}
-
-CSSStyleDeclarationImpl *DocumentImpl::getOverrideStyle(ElementImpl* /*elt*/, DOMStringImpl* /*pseudoElt*/)
-{
- return 0; // ###
-}
-
-void DocumentImpl::abort()
-{
- if (m_inSyncLoad) {
- m_inSyncLoad = false;
- kapp->exit_loop();
- }
-
- if (m_loadingXMLDoc)
- m_loadingXMLDoc->deref(this);
- m_loadingXMLDoc = 0;
-}
-
-void DocumentImpl::load(const DOMString &uri)
-{
- if (m_inSyncLoad) {
- m_inSyncLoad = false;
- kapp->exit_loop();
- }
-
- m_hadLoadError = false;
- if (m_loadingXMLDoc)
- m_loadingXMLDoc->deref(this);
-
- // Use the document loader to retrieve the XML file. We use CachedCSSStyleSheet because
- // this is an easy way to retrieve an arbitrary text file... it is not specific to
- // stylesheets.
-
- // ### Note: By loading the XML document this way we do not get the proper decoding
- // of the data retrieved from the server based on the character set, as happens with
- // HTML files. Need to look into a way of using the decoder in CachedCSSStyleSheet.
- m_docLoading = true;
- m_loadingXMLDoc = m_docLoader->requestStyleSheet(uri.string(),TQString(),"text/xml");
-
- if (!m_loadingXMLDoc) {
- m_docLoading = false;
- return;
- }
-
- m_loadingXMLDoc->ref(this);
-
- if (!m_async && m_docLoading) {
- m_inSyncLoad = true;
- kapp->enter_loop();
- }
-}
-
-void DocumentImpl::loadXML(const DOMString &source)
-{
- open(false);
- write(source);
- finishParsing();
- close();
- dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false);
-}
-
-void DocumentImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset)
-{
- if (!m_hadLoadError) {
- m_url = url.string();
- loadXML(sheet);
- }
-
- m_docLoading = false;
- if (m_inSyncLoad) {
- m_inSyncLoad = false;
- kapp->exit_loop();
- }
-
- assert(m_loadingXMLDoc != 0);
- m_loadingXMLDoc->deref(this);
- m_loadingXMLDoc = 0;
-}
-
-void DocumentImpl::error(int err, const TQString &text)
-{
- m_docLoading = false;
- if (m_inSyncLoad) {
- m_inSyncLoad = false;
- kapp->exit_loop();
- }
-
- m_hadLoadError = true;
-
- int exceptioncode = 0;
- EventImpl *evt = new EventImpl(EventImpl::ERROR_EVENT,false,false);
- if (err != 0)
- evt->setMessage(TDEIO::buildErrorString(err,text));
- else
- evt->setMessage(text);
- evt->ref();
- dispatchEvent(evt,exceptioncode,true);
- evt->deref();
-
- assert(m_loadingXMLDoc != 0);
- m_loadingXMLDoc->deref(this);
- m_loadingXMLDoc = 0;
-}
-
-void DocumentImpl::defaultEventHandler(EventImpl *evt)
-{
- // if any html event listeners are registered on the window, then dispatch them here
- if (!m_windowEventListeners.listeners || evt->propagationStopped())
- return;
-
- TQValueList<RegisteredEventListener>::iterator it;
-
- //Grab a copy in case of clear
- TQValueList<RegisteredEventListener> listeners = *m_windowEventListeners.listeners;
- Event ev(evt);
- for (it = listeners.begin(); it != listeners.end(); ++it) {
- //Check to make sure it didn't get removed. KDE4: use Java-style iterators
- if (!m_windowEventListeners.stillContainsListener(*it))
- continue;
-
- if ((*it).id == evt->id()) {
- // currentTarget must be 0 in khtml for kjs_events to set "this" correctly.
- // (this is how we identify events dispatched to the window, like window.onmousedown)
- // ## currentTarget is unimplemented in IE, and is "window" in Mozilla (how? not a DOM node)
- evt->setCurrentTarget(0);
- (*it).listener->handleEvent(ev);
- }
- }
-}
-
-void DocumentImpl::setHTMLWindowEventListener(int id, EventListener *listener)
-{
- m_windowEventListeners.setHTMLEventListener(id, listener);
-}
-
-EventListener *DocumentImpl::getHTMLWindowEventListener(int id)
-{
- return m_windowEventListeners.getHTMLEventListener(id);
-}
-
-void DocumentImpl::addWindowEventListener(int id, EventListener *listener, const bool useCapture)
-{
- m_windowEventListeners.addEventListener(id, listener, useCapture);
-}
-
-void DocumentImpl::removeWindowEventListener(int id, EventListener *listener, bool useCapture)
-{
- m_windowEventListeners.removeEventListener(id, listener, useCapture);
-}
-
-bool DocumentImpl::hasWindowEventListener(int id)
-{
- return m_windowEventListeners.hasEventListener(id);
-}
-
-EventListener *DocumentImpl::createHTMLEventListener(const TQString& code, const TQString& name, NodeImpl* node)
-{
- return part() ? part()->createHTMLEventListener(code, name, node) : 0;
-}
-
-void DocumentImpl::dispatchImageLoadEventSoon(HTMLImageElementImpl *image)
-{
- m_imageLoadEventDispatchSoonList.append(image);
- if (!m_imageLoadEventTimer) {
- m_imageLoadEventTimer = startTimer(0);
- }
-}
-
-void DocumentImpl::removeImage(HTMLImageElementImpl *image)
-{
- // Remove instances of this image from both lists.
- // Use loops because we allow multiple instances to get into the lists.
- while (m_imageLoadEventDispatchSoonList.removeRef(image)) { }
- while (m_imageLoadEventDispatchingList.removeRef(image)) { }
- if (m_imageLoadEventDispatchSoonList.isEmpty() && m_imageLoadEventTimer) {
- killTimer(m_imageLoadEventTimer);
- m_imageLoadEventTimer = 0;
- }
-}
-
-void DocumentImpl::dispatchImageLoadEventsNow()
-{
- // need to avoid re-entering this function; if new dispatches are
- // scheduled before the parent finishes processing the list, they
- // will set a timer and eventually be processed
- if (!m_imageLoadEventDispatchingList.isEmpty()) {
- return;
- }
-
- if (m_imageLoadEventTimer) {
- killTimer(m_imageLoadEventTimer);
- m_imageLoadEventTimer = 0;
- }
-
- m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList;
- m_imageLoadEventDispatchSoonList.clear();
- for (TQPtrListIterator<HTMLImageElementImpl> it(m_imageLoadEventDispatchingList); it.current(); ) {
- HTMLImageElementImpl* image = it.current();
- // Must advance iterator *before* dispatching call.
- // Otherwise, it might be advanced automatically if dispatching the call had a side effect
- // of destroying the current HTMLImageElementImpl, and then we would advance past the *next*
- // item, missing one altogether.
- ++it;
- image->dispatchLoadEvent();
- }
- m_imageLoadEventDispatchingList.clear();
-}
-
-void DocumentImpl::timerEvent(TQTimerEvent *)
-{
- dispatchImageLoadEventsNow();
-}
-
-void DocumentImpl::setDecoderCodec(const TQTextCodec *codec)
-{
- m_decoderMibEnum = codec->mibEnum();
-}
-
-ElementImpl *DocumentImpl::ownerElement() const
-{
- KHTMLPart *childPart = part();
- if (!childPart)
- return 0;
- ChildFrame *childFrame = childPart->d->m_frame;
- if (!childFrame)
- return 0;
- RenderPart *renderPart = childFrame->m_frame;
- if (!renderPart)
- return 0;
- return static_cast<ElementImpl *>(renderPart->element());
-}
-
-DOMString DocumentImpl::domain() const
-{
- if ( m_domain.isEmpty() ) // not set yet (we set it on demand to save time and space)
- m_domain = URL().host(); // Initially set to the host
- return m_domain;
-}
-
-void DocumentImpl::setDomain(const DOMString &newDomain)
-{
- if ( m_domain.isEmpty() ) // not set yet (we set it on demand to save time and space)
- m_domain = URL().host().lower(); // Initially set to the host
-
- if ( m_domain.isEmpty() /*&& part() && part()->openedByJS()*/ )
- m_domain = newDomain.lower();
-
- // Both NS and IE specify that changing the domain is only allowed when
- // the new domain is a suffix of the old domain.
- int oldLength = m_domain.length();
- int newLength = newDomain.length();
- if ( newLength < oldLength ) // e.g. newDomain=kde.org (7) and m_domain=www.kde.org (11)
- {
- DOMString test = m_domain.copy();
- DOMString reference = newDomain.lower();
- if ( test[oldLength - newLength - 1] == '.' ) // Check that it's a subdomain, not e.g. "de.org"
- {
- test.remove( 0, oldLength - newLength ); // now test is "kde.org" from m_domain
- if ( test == reference ) // and we check that it's the same thing as newDomain
- m_domain = reference;
- }
- }
-}
-
-DOMString DocumentImpl::toString() const
-{
- DOMString result;
-
- for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) {
- result += child->toString();
- }
-
- return result;
-}
-
-
-KHTMLPart* DOM::DocumentImpl::part() const
-{
- // ### TODO: make this independent from a KHTMLView one day.
- return view() ? view()->part() : 0;
-}
-
-NodeListImpl::Cache* DOM::DocumentImpl::acquireCachedNodeListInfo(
- NodeListImpl::CacheFactory* factory, NodeImpl* base, int type)
-{
- //### might want to flush the dict when the version number
- //changes
- NodeListImpl::CacheKey key(base, type);
-
- //Check to see if we have this sort of item cached.
- NodeListImpl::Cache* cached =
- (type == NodeListImpl::UNCACHEABLE) ? 0 : m_nodeListCache.find(key.hash());
-
- if (cached) {
- if (cached->key == key) {
- cached->ref(); //Add the nodelist's reference
- return cached;
- } else {
- //Conflict. Drop our reference to the old item.
- cached->deref();
- }
- }
-
- //Nothing to reuse, make a new item.
- NodeListImpl::Cache* newInfo = factory();
- newInfo->key = key;
- newInfo->clear(this);
- newInfo->ref(); //Add the nodelist's reference
-
- if (type != NodeListImpl::UNCACHEABLE) {
- newInfo->ref(); //Add the cache's reference
- m_nodeListCache.replace(key.hash(), newInfo);
- }
-
- return newInfo;
-}
-
-void DOM::DocumentImpl::releaseCachedNodeListInfo(NodeListImpl::Cache* entry)
-{
- entry->deref();
-}
-
-// ----------------------------------------------------------------------------
-
-DocumentFragmentImpl::DocumentFragmentImpl(DocumentImpl *doc) : NodeBaseImpl(doc)
-{
-}
-
-DocumentFragmentImpl::DocumentFragmentImpl(const DocumentFragmentImpl &other)
- : NodeBaseImpl(other)
-{
-}
-
-DOMString DocumentFragmentImpl::nodeName() const
-{
- return "#document-fragment";
-}
-
-unsigned short DocumentFragmentImpl::nodeType() const
-{
- return Node::DOCUMENT_FRAGMENT_NODE;
-}
-
-// DOM Section 1.1.1
-bool DocumentFragmentImpl::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 DocumentFragmentImpl::toString() const
-{
- DOMString result;
-
- for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) {
- result += child->toString();
- }
-
- return result;
-}
-
-NodeImpl *DocumentFragmentImpl::cloneNode ( bool deep )
-{
- DocumentFragmentImpl *clone = new DocumentFragmentImpl( docPtr() );
- if (deep)
- cloneChildNodes(clone);
- return clone;
-}
-
-
-// ----------------------------------------------------------------------------
-
-DocumentTypeImpl::DocumentTypeImpl(DOMImplementationImpl *implementation, DocumentImpl *doc,
- const DOMString &qualifiedName, const DOMString &publicId,
- const DOMString &systemId)
- : NodeImpl(doc), m_implementation(implementation),
- m_qualifiedName(qualifiedName), m_publicId(publicId), m_systemId(systemId)
-{
- m_implementation->ref();
-
- m_entities = 0;
- m_notations = 0;
-
- // if doc is 0, it is not attached to a document and / or
- // therefore does not provide entities or notations. (DOM Level 3)
-}
-
-DocumentTypeImpl::~DocumentTypeImpl()
-{
- m_implementation->deref();
- if (m_entities)
- m_entities->deref();
- if (m_notations)
- m_notations->deref();
-}
-
-void DocumentTypeImpl::copyFrom(const DocumentTypeImpl& other)
-{
- m_qualifiedName = other.m_qualifiedName;
- m_publicId = other.m_publicId;
- m_systemId = other.m_systemId;
- m_subset = other.m_subset;
-}
-
-DOMString DocumentTypeImpl::toString() const
-{
- DOMString result = "<!DOCTYPE";
- result += m_qualifiedName;
- if (!m_publicId.isEmpty()) {
- result += " PUBLIC \"";
- result += m_publicId;
- result += "\" \"";
- result += m_systemId;
- result += "\"";
- } else if (!m_systemId.isEmpty()) {
- result += " SYSTEM \"";
- result += m_systemId;
- result += "\"";
- }
-
- if (!m_subset.isEmpty()) {
- result += " [";
- result += m_subset;
- result += "]";
- }
-
- result += ">";
-
- return result;
-}
-
-DOMString DocumentTypeImpl::nodeName() const
-{
- return name();
-}
-
-unsigned short DocumentTypeImpl::nodeType() const
-{
- return Node::DOCUMENT_TYPE_NODE;
-}
-
-// DOM Section 1.1.1
-bool DocumentTypeImpl::childTypeAllowed( unsigned short /*type*/ )
-{
- return false;
-}
-
-NodeImpl *DocumentTypeImpl::cloneNode ( bool /*deep*/ )
-{
- // Spec says cloning Document nodes is "implementation dependent"
- // so we do not support it...
- return 0;
-}
-
-DOMStringImpl* DocumentTypeImpl::textContent() const
-{
- return 0;
-}
-
-void DocumentTypeImpl::setTextContent( const DOMString&, int& )
-{}
-
-NamedNodeMapImpl * DocumentTypeImpl::entities() const
-{
- if ( !m_entities ) {
- m_entities = new GenericRONamedNodeMapImpl( docPtr() );
- m_entities->ref();
- }
- return m_entities;
-}
-
-NamedNodeMapImpl * DocumentTypeImpl::notations() const
-{
- if ( !m_notations ) {
- m_notations = new GenericRONamedNodeMapImpl( docPtr() );
- m_notations->ref();
- }
- return m_notations;
-}
-
-#include "dom_docimpl.moc"