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

📄 dom_nodeimpl.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/** * 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) 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "dom/dom_exception.h"#include "misc/htmlattrs.h"#include "misc/htmltags.h"#include "xml/dom_elementimpl.h"#include "xml/dom_textimpl.h"#include "xml/dom2_eventsimpl.h"#include "xml/dom_docimpl.h"#include "xml/dom_nodeimpl.h"#include <kglobal.h>#include <kdebug.h>#include "rendering/render_text.h"#include "rendering/render_flow.h"#include "rendering/render_line.h"#include "ecma/kjs_proxy.h"#include "khtmlview.h"#include "khtml_part.h"#include "dom_nodeimpl.h"// from khtml_caret_p.hnamespace khtml {void /*KDE_NO_EXPORT*/ mapDOMPosToRenderPos(DOM::NodeImpl *node, long offset,		khtml::RenderObject *&r, long &r_ofs, bool &outside, bool &outsideEnd);}using namespace DOM;using namespace khtml;NodeImpl::NodeImpl(DocumentPtr *doc)    : document(doc),      m_previous(0),      m_next(0),      m_render(0),      m_tabIndex( 0 ),      m_hasId( false ),      m_hasStyle( false ),      m_attached(false),      m_closed(false),      m_changed( false ),      m_hasChangedChild( false ),      m_inDocument( false ),      m_hasAnchor( false ),      m_specified( false ),      m_focused( false ),      m_active( false ),      m_styleElement( false ),      m_implicit( false ),      m_rendererNeedsClose( false ),      m_htmlCompat( false ){    if (document)        document->ref();}NodeImpl::~NodeImpl(){    if (m_render)        detach();    if (document)        document->deref();    if (m_previous)        m_previous->setNextSibling(0);    if (m_next)        m_next->setPreviousSibling(0);}DOMString NodeImpl::nodeValue() const{  return DOMString();}void NodeImpl::setNodeValue( const DOMString &/*_nodeValue*/, int &/*exceptioncode*/ ){    // by default nodeValue is null, so setting it has no effect    // don't throw NO_MODIFICATION_ALLOWED_ERR from here, DOMTS-Core-Level1's hc_nodevalue03    // (createEntityReference().setNodeValue())) says it would be wrong.    // This must be done by subclasses instead.}DOMString NodeImpl::nodeName() const{  return DOMString();}unsigned short NodeImpl::nodeType() const{  return 0;}NodeListImpl *NodeImpl::childNodes(){  return new ChildNodeListImpl(this);}NodeImpl *NodeImpl::firstChild() const{  return 0;}NodeImpl *NodeImpl::lastChild() const{  return 0;}NodeImpl *NodeImpl::insertBefore( NodeImpl *, NodeImpl *, int &exceptioncode ){    exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;    return 0;}NodeImpl *NodeImpl::replaceChild( NodeImpl *, NodeImpl *, int &exceptioncode ){  exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;  return 0;}NodeImpl *NodeImpl::removeChild( NodeImpl *, int &exceptioncode ){  exceptioncode = DOMException::NOT_FOUND_ERR;  return 0;}NodeImpl *NodeImpl::appendChild( NodeImpl *, int &exceptioncode ){  exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;  return 0;}bool NodeImpl::hasChildNodes(  ) const{  return false;}void NodeImpl::normalize (){    // ### normalize attributes? (when we store attributes using child nodes)    int exceptioncode = 0;    NodeImpl *child = firstChild();    // Recursively go through the subtree beneath us, normalizing all nodes. In the case    // where there are two adjacent text nodes, they are merged together    while (child) {        NodeImpl *nextChild = child->nextSibling();        if (nextChild && child->nodeType() == Node::TEXT_NODE && nextChild->nodeType() == Node::TEXT_NODE) {            // Current child and the next one are both text nodes... merge them            TextImpl *currentText = static_cast<TextImpl*>(child);            TextImpl *nextText = static_cast<TextImpl*>(nextChild);            currentText->appendData(nextText->data(),exceptioncode);            if (exceptioncode)                return;            removeChild(nextChild,exceptioncode);            if (exceptioncode)                return;        }        else {            child->normalize();            child = nextChild;        }    }}DOMString NodeImpl::prefix() const{    // For nodes other than elements and attributes, the prefix is always null    return DOMString();}DOMString NodeImpl::namespaceURI() const{    return DOMString();}void NodeImpl::setPrefix(const DOMString &/*_prefix*/, int &exceptioncode ){    // The spec says that for nodes other than elements and attributes, prefix is always null.    // It does not say what to do when the user tries to set the prefix on another type of    // node, however mozilla throws a NAMESPACE_ERR exception    exceptioncode = DOMException::NAMESPACE_ERR;}DOMString NodeImpl::localName() const{    return DOMString();}void NodeImpl::setFirstChild(NodeImpl *){}void NodeImpl::setLastChild(NodeImpl *){}NodeImpl *NodeImpl::addChild(NodeImpl *){  return 0;}void NodeImpl::getCaret(int offset, bool override, int &_x, int &_y, int &width, int &height){    if (m_render) {        RenderObject *r;	long r_ofs;	bool outside, outsideEnd;#if 0kdDebug(6200) << "getCaret: node " << this << " " << nodeName().string() << " offset: " << offset << endl;#endif        mapDOMPosToRenderPos(this, offset, r, r_ofs, outside, outsideEnd);#if 0kdDebug(6200) << "getCaret: r " << r << " " << (r?r->renderName():QString::null) << " r_ofs: " << r_ofs << " outside " << outside << " outsideEnd " << outsideEnd << endl;#endif	if (r) {            r->caretPos(r_ofs, override*RenderObject::CFOverride		    + outside*RenderObject::CFOutside		    + outsideEnd*RenderObject::CFOutsideEnd, _x, _y, width, height);	} else	    _x = _y = height = -1, width = 1;    } else _x = _y = height = -1, width = 1;}QRect NodeImpl::getRect() const{    int _x, _y;    if(m_render && m_render->absolutePosition(_x, _y))        return QRect( _x + m_render->inlineXPos(), _y + m_render->inlineYPos(),        		m_render->width(), m_render->height() );    return QRect();}void NodeImpl::setChanged(bool b){    if (b && !attached()) // changed compared to what?        return;    m_changed = b;    if ( b ) {	NodeImpl *p = parentNode();	while ( p ) {	    p->setHasChangedChild( true );	    p = p->parentNode();	}        getDocument()->setDocumentChanged();    }}bool NodeImpl::isInline() const{    if (m_render) return m_render->style()->display() == khtml::INLINE;    return !isElementNode();}unsigned long NodeImpl::nodeIndex() const{    NodeImpl *_tempNode = previousSibling();    unsigned long count=0;    for( count=0; _tempNode; count++ )        _tempNode = _tempNode->previousSibling();    return count;}void NodeImpl::addEventListener(int id, EventListener *listener, const bool useCapture){    switch (id) {	case EventImpl::DOMSUBTREEMODIFIED_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER);	    break;	case EventImpl::DOMNODEINSERTED_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTED_LISTENER);	    break;	case EventImpl::DOMNODEREMOVED_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVED_LISTENER);	    break;        case EventImpl::DOMNODEREMOVEDFROMDOCUMENT_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMNODEREMOVEDFROMDOCUMENT_LISTENER);	    break;        case EventImpl::DOMNODEINSERTEDINTODOCUMENT_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMNODEINSERTEDINTODOCUMENT_LISTENER);	    break;        case EventImpl::DOMATTRMODIFIED_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER);	    break;        case EventImpl::DOMCHARACTERDATAMODIFIED_EVENT:	    getDocument()->addListenerType(DocumentImpl::DOMCHARACTERDATAMODIFIED_LISTENER);	    break;	default:	    break;    }    m_regdListeners.addEventListener(id, listener, useCapture);}void NodeImpl::removeEventListener(int id, EventListener *listener, bool useCapture){    m_regdListeners.removeEventListener(id, listener, useCapture);}void NodeImpl::setHTMLEventListener(int id, EventListener *listener){    m_regdListeners.setHTMLEventListener(id, listener);}EventListener *NodeImpl::getHTMLEventListener(int id){    return m_regdListeners.getHTMLEventListener(id);}void NodeImpl::dispatchEvent(EventImpl *evt, int &exceptioncode, bool tempEvent){    evt->setTarget(this);    // Since event handling code could cause this object to be deleted, grab a reference to the view now    KHTMLView *view = document->document()->view();    dispatchGenericEvent( evt, exceptioncode );    // If tempEvent is true, this means that the DOM implementation will not be storing a reference to the event, i.e.    // there is no way to retrieve it from javascript if a script does not already have a reference to it in a variable.    // So there is no need for the interpreter to keep the event in its cache    if (tempEvent && view && view->part() && view->part()->jScript())        view->part()->jScript()->finishedWithEvent(evt);}void NodeImpl::dispatchGenericEvent( EventImpl *evt, int &/*exceptioncode */){    // ### check that type specified    // work out what nodes to send event to    QPtrList<NodeImpl> nodeChain;    NodeImpl *n;    for (n = this; n; n = n->parentNode()) {        n->ref();        nodeChain.prepend(n);    }    // trigger any capturing event handlers on our way down    evt->setEventPhase(Event::CAPTURING_PHASE);    QPtrListIterator<NodeImpl> it(nodeChain);    for (; it.current() && it.current() != this && !evt->propagationStopped(); ++it) {        evt->setCurrentTarget(it.current());        it.current()->handleLocalEvents(evt,true);    }    // dispatch to the actual target node    it.toLast();    NodeImpl* propagationSentinel = 0;    if (!evt->propagationStopped()) {        evt->setEventPhase(Event::AT_TARGET);        evt->setCurrentTarget(it.current());        it.current()->handleLocalEvents(evt, true);        if (!evt->propagationStopped())            it.current()->handleLocalEvents(evt,false);        else            propagationSentinel = it.current();    }    --it;    if (evt->bubbles()) {        evt->setEventPhase(Event::BUBBLING_PHASE);        for (; it.current() && !evt->propagationStopped(); --it) {            if (evt->propagationStopped()) propagationSentinel = it.current();            evt->setCurrentTarget(it.current());            it.current()->handleLocalEvents(evt,false);        }        // now we call all default event handlers (this is not part of DOM - it is internal to khtml)        evt->setCurrentTarget(0);        evt->setEventPhase(0); // I guess this is correct, the spec does not seem to say        for (it.toLast(); it.current() && it.current() != propagationSentinel &&                 !evt->defaultPrevented() && !evt->defaultHandled(); --it)            it.current()->defaultEventHandler(evt);        if (evt->id() == EventImpl::CLICK_EVENT && !evt->defaultPrevented() &&             static_cast<MouseEventImpl*>( evt )->button() == 0) // LMB click            dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, static_cast<UIEventImpl*>(evt)->detail());    }    // copy this over into a local variable, as the following deref() calls might cause this to be deleted.    DocumentPtr *doc = document;    doc->ref();    // deref all nodes in chain    it.toFirst();    for (; it.current(); ++it)        it.current()->deref(); // this may delete us    DocumentImpl::updateDocumentsRendering();    doc->deref();}bool NodeImpl::dispatchHTMLEvent(int _id, bool canBubbleArg, bool cancelableArg){    int exceptioncode = 0;    EventImpl* const evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);    evt->ref();    dispatchEvent(evt,exceptioncode,true);    bool ret = !evt->defaultPrevented();    evt->deref();    return ret;}void NodeImpl::dispatchWindowEvent(int _id, bool canBubbleArg, bool cancelableArg){    int exceptioncode = 0;    EventImpl* const evt = new EventImpl(static_cast<EventImpl::EventId>(_id),canBubbleArg,cancelableArg);    evt->setTarget( 0 );    evt->ref();    DocumentPtr *doc = document;    doc->ref();    dispatchGenericEvent( evt, exceptioncode );    if (!evt->defaultPrevented() && doc->document())	doc->document()->defaultEventHandler(evt);    if (_id == EventImpl::LOAD_EVENT && !evt->propagationStopped() && doc->document()) {        // For onload events, send them to the enclosing frame only.        // This is a DOM extension and is independent of bubbling/capturing rules of        // the DOM.  You send the event only to the enclosing frame.  It does not        // bubble through the parent document.        DOM::ElementImpl* elt = doc->document()->ownerElement();        if (elt && (elt->getDocument()->domain().isNull() ||                    elt->getDocument()->domain() == doc->document()->domain())) {            // We also do a security check, since we don't want to allow the enclosing            // iframe to see loads of child documents in other domains.            evt->setCurrentTarget(elt);            // Capturing first.            elt->handleLocalEvents(evt,true);            // Bubbling second.            if (!evt->propagationStopped())                elt->handleLocalEvents(evt,false);        }    }    doc->deref();    evt->deref();}void NodeImpl::dispatchMouseEvent(QMouseEvent *_mouse, int overrideId, int overrideDetail){    bool cancelable = true;    int detail = overrideDetail; // defaults to 0    EventImpl::EventId evtId = EventImpl::UNKNOWN_EVENT;    if (overrideId) {        evtId = static_cast<EventImpl::EventId>(overrideId);    }    else {        switch (_mouse->type()) {            case QEvent::MouseButtonPress:                evtId = EventImpl::MOUSEDOWN_EVENT;                break;            case QEvent::MouseButtonRelease:                evtId = EventImpl::MOUSEUP_EVENT;                break;            case QEvent::MouseButtonDblClick:                evtId = EventImpl::CLICK_EVENT;                detail = 1; // ### support for multiple double clicks                break;            case QEvent::MouseMove:                evtId = EventImpl::MOUSEMOVE_EVENT;                cancelable = false;                break;            default:                break;        }    }

⌨️ 快捷键说明

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