📄 dom_docimpl.cpp
字号:
/** * 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) * Copyright (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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include "dom/dom_exception.h"#include "xml/dom_textimpl.h"#include "xml/dom_xmlimpl.h"#include "xml/dom2_rangeimpl.h"#include "xml/dom_selection.h"#include "xml/dom2_eventsimpl.h"#include "xml/xml_tokenizer.h"#include "xml_namespace_table.h"#include "css/csshelper.h"#include "css/cssstyleselector.h"#include "css/css_stylesheetimpl.h"#include "css/css_valueimpl.h"#include "misc/htmlhashes.h"#include "misc/helper.h"#include "ecma/kjs_proxy.h"#include "ecma/kjs_binding.h"#include <qptrstack.h>#include <qpaintdevicemetrics.h>#include <kdebug.h>#include <kstaticdeleter.h>#include "rendering/render_canvas.h"#include "rendering/render_frames.h"#include "rendering/render_image.h"#include "render_arena.h"#include "khtmlview.h"#include "khtml_part.h"#include <kglobalsettings.h>#include <kstringhandler.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 "cssvalues.h"#include "jsediting.h"#include <kio/job.h>#ifndef KHTML_NO_XBL#include "xbl/xbl_binding_manager.h"using XBL::XBLBindingManager;#endif#if APPLE_CHANGES#include "KWQAccObjectCache.h"#include "KWQLogging.h"#endifusing namespace DOM;using namespace khtml;//#define INSTRUMENT_LAYOUT_SCHEDULING 1DOMImplementationImpl *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 QString lower = feature.string().lower(); if ((lower == "html" || lower == "xml") && (version == "1.0" || version == "null" || version == "" || version.isNull())) return true; else 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. if (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; // 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, // - if the qualifiedName has a prefix and the namespaceURI is null, or // - if the qualifiedName has a prefix that is "xml" and the namespaceURI is different // from "http://www.w3.org/XML/1998/namespace" [Namespaces]. int colonpos = -1; uint i; DOMStringImpl *qname = qualifiedName.implementation(); for (i = 0; i < qname->l && colonpos < 0; i++) { if ((*qname)[i] == ':') colonpos = i; } if (Element::khtmlMalformedQualifiedName(qualifiedName) || (colonpos >= 0 && namespaceURI.isNull()) || (colonpos == 3 && qualifiedName[0] == 'x' && qualifiedName[1] == 'm' && qualifiedName[2] == 'l' && namespaceURI != "http://www.w3.org/XML/1998/namespace")) { exceptioncode = DOMException::NAMESPACE_ERR; 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); 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;}// ------------------------------------------------------------------------KStaticDeleter< QPtrList<DocumentImpl> > s_changedDocumentsDeleter;QPtrList<DocumentImpl> * DocumentImpl::changedDocuments = 0;// KHTMLView might be 0DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v) : NodeBaseImpl( new DocumentPtr() ) , m_imageLoadEventTimer(0)#ifndef KHTML_NO_XBL , m_bindingManager(new XBLBindingManager(this))#endif#if APPLE_CHANGES , m_finishedParsing(this, SIGNAL(finishedParsing())) , m_inPageCache(false), m_savedRenderer(0) , m_passwordFields(0), m_secureForms(0) , m_decoder(0), m_createRenderers(true)#endif{#if KWIQ QOBJECT_TYPE(DOM::DocumentImpl);#endif document->doc = this; m_paintDevice = 0; m_paintDeviceMetrics = 0; m_view = v; m_renderArena = 0;#if APPLE_CHANGES m_accCache = 0;#endif if ( v ) { m_docLoader = new DocLoader(v->part(), this ); setPaintDevice( m_view ); } else m_docLoader = new DocLoader( 0, this ); visuallyOrdered = false; m_loadingSheet = false; m_bParsing = false; m_bAllDataReceived = false; m_docChanged = false; m_sheet = 0; 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, document, DOMString() /* qualifiedName */, DOMString() /* publicId */, DOMString() /* systemId */); m_doctype->ref(); m_implementation = _implementation; if (m_implementation) m_implementation->ref(); pMode = Strict; hMode = XHtml; m_textColor = Qt::black; m_elementNames = 0; m_elementNameAlloc = 0; m_elementNameCount = 0; m_attrNames = 0; m_attrNameAlloc = 0; m_attrNameCount = 0; m_focusNode = 0; m_hoverNode = 0; m_defaultView = new AbstractViewImpl(this); m_defaultView->ref(); m_listenerTypes = 0; m_styleSheets = new StyleSheetListImpl; m_styleSheets->ref(); m_inDocument = true; m_styleSelectorDirty = false; m_inStyleRecalc = false; m_usesDescendantRules = false; m_usesSiblingRules = false; m_styleSelector = new CSSStyleSelector( this, m_usersheet, m_styleSheets, m_url, !inCompatMode() ); m_windowEventListeners.setAutoDelete(true); m_pendingStylesheets = 0; m_ignorePendingStylesheets = false; m_cssTarget = 0; m_accessKeyDictValid = false; resetLinkColor(); resetVisitedLinkColor(); resetActiveLinkColor(); m_processingLoadEvent = false; m_startTime.restart(); m_overMinimumLayoutThreshold = false; m_jsEditor = 0;}DocumentImpl::~DocumentImpl(){ assert(!m_render);#if APPLE_CHANGES assert(!m_inPageCache); assert(m_savedRenderer == 0);#endif KJS::ScriptInterpreter::forgetDOMObjectsForDocument(this); if (changedDocuments && m_docChanged) changedDocuments->remove(this); delete m_tokenizer; document->doc = 0; delete m_sheet; delete m_styleSelector; delete m_docLoader; if (m_elemSheet ) m_elemSheet->deref(); if (m_doctype) m_doctype->deref(); if (m_implementation) m_implementation->deref(); delete m_paintDeviceMetrics; if (m_elementNames) { for (unsigned short id = 0; id < m_elementNameCount; id++) m_elementNames[id]->deref(); delete [] m_elementNames; } if (m_attrNames) { for (unsigned short id = 0; id < m_attrNameCount; id++) m_attrNames[id]->deref(); delete [] m_attrNames; } m_defaultView->deref(); m_styleSheets->deref(); if (m_focusNode) m_focusNode->deref(); if (m_hoverNode) m_hoverNode->deref(); if (m_renderArena){ delete m_renderArena; m_renderArena = 0; }#ifndef KHTML_NO_XBL delete m_bindingManager;#endif#if APPLE_CHANGES if (m_accCache){ delete m_accCache; m_accCache = 0; }#endif if (m_decoder){ m_decoder->deref(); m_decoder = 0; } if (m_jsEditor) { delete m_jsEditor; m_jsEditor = 0; }}void DocumentImpl::resetLinkColor(){ m_linkColor = QColor(0, 0, 238);}void DocumentImpl::resetVisitedLinkColor(){ m_visitedLinkColor = QColor(85, 26, 139); }void DocumentImpl::resetActiveLinkColor(){ m_activeLinkColor.setNamedColor(QString("red"));}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 &exceptioncode ){ return new XMLElementImpl( document, name.implementation() );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -