⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dom_nodeimpl.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/** * 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) * * 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 <qrect.h>#include "htmlattrs.h"#include "dom_nodeimpl.h"#include "dom_node.h"#include "dom_exception.h"#include "dom_elementimpl.h"#include "dom_docimpl.h"#include "render_object.h"#include "kdebug.h"#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ 2*( N ) ]#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P ))using namespace DOM;using namespace khtml;const QChar NodeImpl::LESSTHAN = '<';const QChar NodeImpl::MORETHAN = '>';const QChar NodeImpl::SLASH = '/';const QChar NodeImpl::SPACE = ' ';const QChar NodeImpl::EQUALS = '=';const QChar NodeImpl::QUOTE = '"';NodeImpl::NodeImpl(DocumentImpl *doc)    : document(doc),      m_render(0),      m_complexText( false ),      m_hasEvents( false ),      m_hasId( false ),      m_hasClass( false ),      m_hasStyle( false ),      m_hasTooltip( false ),      m_pressed( false ),      m_mouseInside( false ),      m_attached( false ),      m_changed( false ),      m_specified( false ){}NodeImpl::~NodeImpl(){    setOwnerDocument(0);}DOMString NodeImpl::nodeValue() const{  return 0;}void NodeImpl::setNodeValue( const DOMString & ){  throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR);}const DOMString NodeImpl::nodeName() const{  return 0;}unsigned short NodeImpl::nodeType() const{  return 0;}NodeImpl *NodeImpl::parentNode() const{  return 0;}NodeListImpl *NodeImpl::childNodes(){  return new ChildNodeListImpl(this);}NodeImpl *NodeImpl::firstChild() const{  return 0;}NodeImpl *NodeImpl::lastChild() const{  return 0;}NodeImpl *NodeImpl::previousSibling() const{  return 0;}NodeImpl *NodeImpl::nextSibling() const{  return 0;}NamedNodeMapImpl *NodeImpl::attributes() const{  return 0;}void NodeImpl::setPreviousSibling(NodeImpl *){}void NodeImpl::setNextSibling(NodeImpl *){}void NodeImpl::setOwnerDocument(DocumentImpl *_document){    if (document)	document->changedNodes.remove(this);    document = _document;}NodeImpl *NodeImpl::insertBefore( NodeImpl *, NodeImpl * ){  throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);}NodeImpl *NodeImpl::replaceChild( NodeImpl *, NodeImpl * ){  throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);}NodeImpl *NodeImpl::removeChild( NodeImpl * ){  throw DOMException(DOMException::NOT_FOUND_ERR);}NodeImpl *NodeImpl::appendChild( NodeImpl * ){  throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);}bool NodeImpl::hasChildNodes(  ){  return false;}NodeImpl *NodeImpl::cloneNode( bool ){  // we have no childs, so we just clone this Node  return new NodeImpl(document);}// helper functions not being part of the DOMvoid NodeImpl::setParent(NodeImpl *){}void NodeImpl::setFirstChild(NodeImpl *){}void NodeImpl::setLastChild(NodeImpl *){}NodeImpl *NodeImpl::addChild(NodeImpl *){  throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);  return 0;}QString NodeImpl::toHTML(){    long offset = 0;    const int stdInc = 10000;    long currentLength = stdInc;    QChar *htmlText = QT_ALLOC_QCHAR_VEC(stdInc);    recursive( htmlText, currentLength, offset, stdInc );    QString finishedHtmlText( htmlText, offset );    return finishedHtmlText;}void NodeImpl::recursive( QChar *&htmlText, long &currentLength, long &offset, int stdInc ){    DOMString me;    // Copy who I am into the htmlText string    if ( nodeType() == Node::TEXT_NODE )    {        me = nodeValue();        int i = me.length();        while( (currentLength - offset) <= i*2+4)            increaseStringLength( htmlText, currentLength, offset, stdInc);        memcpy(htmlText+offset, me.stringPtr(), i*2);        offset += i;    }    else    {   // If I am an element, not a text        me = nodeName();        int i = me.length();        while( (currentLength - offset) <= i*2+4)            increaseStringLength( htmlText, currentLength, offset, stdInc);        memcpy(htmlText+offset, &LESSTHAN, 2);              // prints <        memcpy(htmlText+offset+1, me.stringPtr(), i*2);     // prints tagname        // print attributes        if( nodeType() == Node::ELEMENT_NODE )        {            int lattrs = 0;            ElementImpl *el = static_cast<ElementImpl *>(this);            AttrImpl *attr;            NamedNodeMapImpl *attrs = static_cast<NamedNodeMapImpl*>(el->attributes());            unsigned long lmap = attrs->length();            for( uint j=0; j<lmap; j++ )            {                attr = static_cast<AttrImpl*>(attrs->item(i));                unsigned long lname = attr->name().length();                unsigned long lvalue = attr->value().length();                while( (currentLength - offset) <= (signed)(i*2+lattrs+lname+lvalue+4) )                    increaseStringLength( htmlText, currentLength, offset, stdInc);                memcpy(htmlText+offset+i+lattrs+1, &SPACE, 2);                 // prints a space                memcpy(htmlText+offset+i+lattrs+2, attr->name().stringPtr(), lname*2);                memcpy(htmlText+offset+i+lattrs+lname+2, &EQUALS, 2);          // prints =                memcpy(htmlText+offset+i+lattrs+lname+3, &QUOTE, 2);           // prints "                memcpy(htmlText+offset+i+lattrs+lname+4, attr->value().stringPtr(), lvalue*2);                memcpy(htmlText+offset+i+lattrs+lname+lvalue+4, &QUOTE, 2);    // prints "                lattrs += lname + lvalue + 4;            }            offset += lattrs;        }        // print ending bracket of start tag        if( firstChild() == 0 )     // if element has no endtag        {            memcpy(htmlText+offset+i+1, &SPACE, 2);      // prints a space            memcpy(htmlText+offset+i+2, &SLASH, 2);      // prints /            memcpy(htmlText+offset+i+3, &MORETHAN, 2);   // prints >            offset += i+4;        }        else                        // if element has endtag        {            memcpy(htmlText+offset+i+1, &MORETHAN, 2);     // prints >            offset += i+2;        }    }    if( firstChild() != 0 )    {        // print firstChild        firstChild()->recursive( htmlText, currentLength, offset, stdInc);        // Print my ending tag        if ( nodeType() != Node::TEXT_NODE )        {            me = nodeName();            int i = me.length();            while( (currentLength - offset) <= i*2+3)                increaseStringLength( htmlText, currentLength, offset, stdInc);            memcpy(htmlText+offset, &LESSTHAN, 2);             // prints <            memcpy(htmlText+offset+1, &SLASH, 2);              // prints /            memcpy(htmlText+offset+2, me.stringPtr(), i*2);    // prints tagname            memcpy(htmlText+offset+i+2, &MORETHAN, 2);         // prints >            offset += i+3;        }    }    // print next sibling    if( nextSibling() )        nextSibling()->recursive( htmlText, currentLength, offset, stdInc);}bool NodeImpl::increaseStringLength( QChar *&htmlText, long &currentLength, long offset, int stdInc){    currentLength += stdInc;    QChar *htmlTextTmp = QT_ALLOC_QCHAR_VEC( currentLength );    memcpy( htmlTextTmp, htmlText, offset*sizeof(QChar) );    QT_DELETE_QCHAR_VEC( htmlText );    htmlText = htmlTextTmp;    return true;       // should return false if not enough memory}void NodeImpl::applyChanges(bool, bool){    setChanged(false);}void NodeImpl::getCursor(int offset, int &_x, int &_y, int &height){    if(m_render) m_render->cursorPos(offset, _x, _y, height);    else _x = _y = height = -1;}QRect NodeImpl::getRect(){    int _x, _y;    if(m_render)        {            m_render->absolutePosition(_x, _y);            return QRect( _x, _y, m_render->width(), m_render->height() );        }    return QRect();}void NodeImpl::setKeyboardFocus(ActivationState b){  if (m_render)    {      m_render->setKeyboardFocus(b);      RenderObject *cb = m_render->containingBlock();      // repaint one pixel outside the element`s dimensions to make      // sure that a Selection (that can be larger than the object)      // is completely redrawn.      cb->repaintRectangle(-3, -1, cb->width()+5, cb->height()+3);    }}void NodeImpl::setChanged(bool b){    if (b && !changed() && document)	document->changedNodes.append(this);    m_changed = b;}//--------------------------------------------------------------------NodeWParentImpl::NodeWParentImpl(DocumentImpl *doc) : NodeImpl(doc){    _parent = 0;    _previous = 0;    _next = 0;}NodeWParentImpl::~NodeWParentImpl(){    // previous and next node may still reference this!!!    // hope this fix is fine...    if(_previous) _previous->setNextSibling(0);    if(_next) _next->setPreviousSibling(0);}NodeImpl *NodeWParentImpl::parentNode() const{    return _parent;}NodeImpl *NodeWParentImpl::previousSibling() const{    return _previous;}NodeImpl *NodeWParentImpl::nextSibling() const{    return _next;}NodeImpl *NodeWParentImpl::cloneNode( bool ){    // we have no childs, so we just clone this Node    // the parent is set to 0 anyway...    return new NodeWParentImpl(document);}// not part of the DOMvoid NodeWParentImpl::setParent(NodeImpl *n){    _parent = n;}bool NodeWParentImpl::deleteMe(){    if(!_parent && _ref <= 0) return true;    return false;}void NodeWParentImpl::setPreviousSibling(NodeImpl *n){    if(!_parent)	throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);    _previous = n;}void NodeWParentImpl::setNextSibling(NodeImpl *n){    if(!_parent)	throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);    _next = n;}void NodeWParentImpl::checkReadOnly(){}//-------------------------------------------------------------------------NodeBaseImpl::NodeBaseImpl(DocumentImpl *doc) : NodeWParentImpl(doc){    _first = _last = 0;}NodeBaseImpl::~NodeBaseImpl(){    //kdDebug( 6020 ) << "NodeBaseImpl destructor" << endl;    // we have to tell all children, that the parent has died...    NodeImpl *n;    NodeImpl *next;    for( n = _first; n != 0; n = next )    {	next = n->nextSibling();        n->setPreviousSibling(0);        n->setNextSibling(0);	n->setParent(0);	if(n->deleteMe())	    delete n;	else	    n->setOwnerDocument(0);    }}NodeImpl *NodeBaseImpl::firstChild() const{    return _first;}NodeImpl *NodeBaseImpl::lastChild() const{    return _last;}NodeImpl *NodeBaseImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild ){    checkReadOnly();    if (!newChild || (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE && !newChild->firstChild()))	throw DOMException(DOMException::NOT_FOUND_ERR);    if(!refChild)	return appendChild(newChild);    checkSameDocument(newChild);    checkNoOwner(newChild);    checkIsChild(refChild);    if(newChild->parentNode() == this)	removeChild(newChild);    bool isFragment = newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE;    NodeImpl *nextChild;    NodeImpl *child = isFragment ? newChild->firstChild() : newChild;    NodeImpl *prev = refChild->previousSibling();    while (child) {	nextChild = isFragment ? child->nextSibling() : 0;	checkNoOwner(child);	if(!childAllowed(child))	    throw DOMException(DOMException::HIERARCHY_REQUEST_ERR);	// if already in the tree, remove it first!	NodeImpl *newParent = child->parentNode();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -