📄 xml_tokenizer.cpp
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 2000 Peter Kelly (pmk@post.com) * 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 "xml_tokenizer.h"#include "xml/dom_docimpl.h"#include "xml/dom_textimpl.h"#include "xml/dom_xmlimpl.h"#include "html/html_headimpl.h"#ifdef KWIQ#include "html/html_tableimpl.h"#endif#include "rendering/render_object.h"#include "misc/htmltags.h"#include "misc/htmlattrs.h"#include "misc/loader.h"#include "khtmlview.h"#include "khtml_part.h"#include <qvariant.h>#include <kdebug.h>#include <klocale.h>// Commented out for testing - psalmi// #ifdef KWIQ //FIXME: Why HTMLTableSectionElement is not found (webcore-106 import)// #include "html/html_tableimpl.h"// #endifusing namespace DOM;namespace khtml {const int maxErrors = 25;XMLHandler::XMLHandler(DocumentPtr *_doc, KHTMLView *_view) : errorLine(0), m_errorCount(0){ m_doc = _doc; if ( m_doc ) m_doc->ref(); m_view = _view; m_currentNode = _doc->document();}XMLHandler::~XMLHandler(){ if ( m_doc ) m_doc->deref();}QString XMLHandler::errorProtocol(){ return errorProt;}bool XMLHandler::startDocument(){ // at the beginning of parsing: do some initialization errorProt = ""; m_errorCount = 0; state = StateInit; return true;}bool XMLHandler::startElement( const QString& namespaceURI, const QString& /*localName*/, const QString& qName, const QXmlAttributes& atts ){ if (m_errorCount) return true; if (m_currentNode->nodeType() == Node::TEXT_NODE) exitText(); int exceptioncode = 0; ElementImpl *newElement = m_doc->document()->createElementNS(namespaceURI,qName,exceptioncode); if (!newElement) return false; int i; for (i = 0; i < atts.length(); i++) { // FIXME: qualified name not supported for attributes! The prefix has been lost. DOMString uri(atts.uri(i)); DOMString ln(atts.localName(i)); DOMString val(atts.value(i)); NodeImpl::Id id = m_doc->document()->attrId(uri.implementation(), ln.implementation(), false /* allocate */); newElement->setAttribute(id, val.implementation(), exceptioncode); if (exceptioncode) // exception setting attributes return false; } // FIXME: This hack ensures implicit table bodies get constructed in XHTML and XML files. // We want to consolidate this with the HTML parser and HTML DOM code at some point. // For now, it's too risky to rip that code up. if (m_currentNode->id() == ID_TABLE && newElement->id() == ID_TR && m_currentNode->isHTMLElement() && newElement->isHTMLElement()) { NodeImpl* implicitTBody = new HTMLTableSectionElementImpl ( m_doc, ID_TBODY, true /* implicit */ ); m_currentNode->addChild(implicitTBody); if (m_view && !implicitTBody->attached()) implicitTBody->attach(); m_currentNode = implicitTBody; } if (m_currentNode->addChild(newElement)) { if (m_view && !newElement->attached()) newElement->attach(); m_currentNode = newElement; return true; } else { delete newElement; return false; } // ### DOM spec states: "if there is no markup inside an element's content, the text is contained in a // single object implementing the Text interface that is the only child of the element."... do we // need to ensure that empty elements always have an empty text child?}bool XMLHandler::endElement( const QString& /*namespaceURI*/, const QString& /*localName*/, const QString& /*qName*/ ){ if (m_errorCount) return true; if (m_currentNode->nodeType() == Node::TEXT_NODE) exitText(); if (m_currentNode->parentNode() != 0) { m_currentNode->closeRenderer(); do { m_currentNode = m_currentNode->parentNode(); } while (m_currentNode && m_currentNode->implicitNode()); }// ### else error return true;}bool XMLHandler::startCDATA(){ if (m_errorCount) return true; if (m_currentNode->nodeType() == Node::TEXT_NODE) exitText(); NodeImpl *newNode = m_doc->document()->createCDATASection(""); if (m_currentNode->addChild(newNode)) { if (m_view && !newNode->attached()) newNode->attach(); m_currentNode = newNode; return true; } else { delete newNode; return false; }}bool XMLHandler::endCDATA(){ if (m_errorCount) return true; if (m_currentNode->parentNode() != 0) m_currentNode = m_currentNode->parentNode(); return true;}bool XMLHandler::characters( const QString& ch ){ if (m_errorCount) return true; if (m_currentNode->nodeType() == Node::TEXT_NODE || m_currentNode->nodeType() == Node::CDATA_SECTION_NODE || enterText()) { int exceptioncode = 0; static_cast<TextImpl*>(m_currentNode)->appendData(ch,exceptioncode); if (exceptioncode) return false; return true; } else return false;}bool XMLHandler::comment(const QString & ch){ if (m_errorCount) return true; if (m_currentNode->nodeType() == Node::TEXT_NODE) exitText(); // ### handle exceptions m_currentNode->addChild(m_doc->document()->createComment(ch)); return true;}bool XMLHandler::processingInstruction(const QString &target, const QString &data){ if (m_errorCount) return true; if (m_currentNode->nodeType() == Node::TEXT_NODE) exitText(); // ### handle exceptions ProcessingInstructionImpl *pi = m_doc->document()->createProcessingInstruction(target,data); m_currentNode->addChild(pi); // don't load stylesheets for standalone documents if (m_doc->document()->part()) { pi->checkStyleSheet(); } return true;}QString XMLHandler::errorString(){#if APPLE_CHANGES // FIXME: Does the user ever see this? return "error";#else return i18n("the document is not in the correct file format");#endif}bool XMLHandler::warning( const QXmlParseException& exception ){#if APPLE_CHANGES errorProt += QString("warning on line %2 at column %3: %1")#else errorProt += i18n( "warning: %1 in line %2, column %3\n" )#endif .arg( exception.message() ) .arg( exception.lineNumber() ) .arg( exception.columnNumber() ); errorLine = exception.lineNumber(); errorCol = exception.columnNumber(); return true;}bool XMLHandler::error( const QXmlParseException& exception ){ if (m_errorCount >= maxErrors) return true; if (errorLine == exception.lineNumber() && errorCol == exception.columnNumber()) return true; // Only report 1 error for any given line/col position to reduce noise. m_errorCount++; #if APPLE_CHANGES errorProt += QString("error on line %2 at column %3: %1")#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -