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

📄 dom_elementimpl.cpp

📁 khtml在gtk上的移植版本
💻 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) *           (C) 2001 Peter Kelly (pmk@post.com) *           (C) 2001 Dirk Mueller (mueller@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. *///#define EVENT_DEBUG#include "dom/dom_exception.h"#include "dom/dom_node.h"#include "xml/dom_textimpl.h"#include "xml/dom_docimpl.h"#include "xml/dom2_eventsimpl.h"#include "xml/dom_elementimpl.h"#include "khtml_part.h"#include "html/dtd.h"#include "html/htmlparser.h"#include "rendering/render_canvas.h"#include "misc/htmlhashes.h"#include "css/css_valueimpl.h"#include "css/css_stylesheetimpl.h"#include "css/cssstyleselector.h"#include "xml/dom_selection.h"#include "xml/dom_xmlimpl.h"#include <qtextstream.h>#include <kdebug.h>using namespace DOM;using namespace khtml;AttributeImpl* AttributeImpl::clone(bool) const{    AttributeImpl* result = new AttributeImpl(m_id, _value);    result->setPrefix(_prefix);    return result;}void AttributeImpl::allocateImpl(ElementImpl* e) {    _impl = new AttrImpl(e, e->docPtr(), this);}AttrImpl::AttrImpl(ElementImpl* element, DocumentPtr* docPtr, AttributeImpl* a)    : NodeBaseImpl(docPtr),      m_element(element),      m_attribute(a){    assert(!m_attribute->_impl);    m_attribute->_impl = this;    m_attribute->ref();    m_specified = true;}AttrImpl::~AttrImpl(){    assert(m_attribute->_impl == this);    m_attribute->_impl = 0;    m_attribute->deref();}DOMString AttrImpl::nodeName() const{    return getDocument()->attrName(m_attribute->id());}unsigned short AttrImpl::nodeType() const{    return Node::ATTRIBUTE_NODE;}DOMString AttrImpl::prefix() const{    return m_attribute->prefix();}void AttrImpl::setPrefix(const DOMString &_prefix, int &exceptioncode ){    checkSetPrefix(_prefix, exceptioncode);    if (exceptioncode)        return;    m_attribute->setPrefix(_prefix.implementation());}DOMString AttrImpl::nodeValue() const {    return m_attribute->value();}void AttrImpl::setValue( const DOMString &v, int &exceptioncode ){    exceptioncode = 0;    // ### according to the DOM docs, we should create an unparsed Text child    // node here    // do not interprete entities in the string, its literal!    // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly    if (isReadOnly()) {        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;        return;    }    // ### what to do on 0 ?    if (v.isNull()) {        exceptioncode = DOMException::DOMSTRING_SIZE_ERR;        return;    }    m_attribute->setValue(v.implementation());    if (m_element)        m_element->attributeChanged(m_attribute);}void AttrImpl::setNodeValue( const DOMString &v, int &exceptioncode ){    exceptioncode = 0;    // NO_MODIFICATION_ALLOWED_ERR: taken care of by setValue()    setValue(v, exceptioncode);}NodeImpl *AttrImpl::cloneNode ( bool /*deep*/){    return new AttrImpl(0, docPtr(), m_attribute->clone());}// DOM Section 1.1.1bool AttrImpl::childAllowed( NodeImpl *newChild ){    if(!newChild)        return false;    return childTypeAllowed(newChild->nodeType());}bool AttrImpl::childTypeAllowed( unsigned short type ){    switch (type) {        case Node::TEXT_NODE:        case Node::ENTITY_REFERENCE_NODE:            return true;            break;        default:            return false;    }}DOMString AttrImpl::toString() const{    DOMString result;    result += nodeName();    // FIXME: substitute entities for any instances of " or ' --    // maybe easier to just use text value and ignore existing    // entity refs?    if (firstChild() != NULL) {	result += "=\"";	for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) {	    result += child->toString();	}		result += "\"";    }    return result;}// -------------------------------------------------------------------------ElementImpl::ElementImpl(DocumentPtr *doc)    : NodeBaseImpl(doc){    namedAttrMap = 0;    m_prefix = 0;}ElementImpl::~ElementImpl(){    if (namedAttrMap) {        namedAttrMap->detachFromElement();        namedAttrMap->deref();    }    if (m_prefix)        m_prefix->deref();}void ElementImpl::removeAttribute( NodeImpl::Id id, int &exceptioncode ){    if (namedAttrMap) {        namedAttrMap->removeNamedItem(id, exceptioncode);        if (exceptioncode == DOMException::NOT_FOUND_ERR) {            exceptioncode = 0;        }    }}void ElementImpl::setAttribute(NodeImpl::Id id, const DOMString &value){    int exceptioncode = 0;    setAttribute(id,value.implementation(),exceptioncode);}unsigned short ElementImpl::nodeType() const{    return Node::ELEMENT_NODE;}const AtomicStringList* ElementImpl::getClassList() const{    return 0;}const AtomicString& ElementImpl::getIDAttribute() const{    return namedAttrMap ? namedAttrMap->id() : nullAtom;}const AtomicString& ElementImpl::getAttribute(NodeImpl::Id id) const{    if (namedAttrMap) {        AttributeImpl* a = namedAttrMap->getAttributeItem(id);        if (a) return a->value();    }    return nullAtom;}const AtomicString& ElementImpl::getAttributeNS(const DOMString &namespaceURI,                                                const DOMString &localName) const{       NodeImpl::Id id = getDocument()->attrId(namespaceURI.implementation(),                                            localName.implementation(), true);    if (!id) return nullAtom;    return getAttribute(id);}void ElementImpl::setAttribute(NodeImpl::Id id, DOMStringImpl* value, int &exceptioncode ){    // allocate attributemap if necessary    AttributeImpl* old = attributes(false)->getAttributeItem(id);    // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly    if (namedAttrMap->isReadOnly()) {        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;        return;    }    if (id == ATTR_ID) {	updateId(old ? old->value() : nullAtom, value);    }        if (old && !value)        namedAttrMap->removeAttribute(id);    else if (!old && value)        namedAttrMap->addAttribute(createAttribute(id, value));    else if (old && value) {        old->setValue(value);        attributeChanged(old);    }}AttributeImpl* ElementImpl::createAttribute(NodeImpl::Id id, DOMStringImpl* value){    return new AttributeImpl(id, value);}void ElementImpl::setAttributeMap( NamedAttrMapImpl* list ){    // If setting the whole map changes the id attribute, we need to    // call updateId.    AttributeImpl *oldId = namedAttrMap ? namedAttrMap->getAttributeItem(ATTR_ID) : 0;    AttributeImpl *newId = list ? list->getAttributeItem(ATTR_ID) : 0;    if (oldId || newId) {	updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);    }    if(namedAttrMap)        namedAttrMap->deref();    namedAttrMap = list;    if(namedAttrMap) {        namedAttrMap->ref();        namedAttrMap->element = this;        unsigned int len = namedAttrMap->length();        for(unsigned int i = 0; i < len; i++)            attributeChanged(namedAttrMap->attrs[i]);    }}bool ElementImpl::hasAttributes() const{    return namedAttrMap && namedAttrMap->length() > 0;}NodeImpl *ElementImpl::cloneNode(bool deep){    // ### we loose the namespace here ... FIXME    int exceptioncode;    ElementImpl *clone = getDocument()->createElement(tagName(), exceptioncode);    if (!clone) return 0;    // clone attributes    if (namedAttrMap)        *(static_cast<NamedAttrMapImpl*>(clone->attributes())) = *namedAttrMap;    if (deep)        cloneChildNodes(clone);    return clone;}DOMString ElementImpl::nodeName() const{    return tagName();}DOMString ElementImpl::tagName() const{    DOMString tn = getDocument()->tagName(id());    if (m_prefix)        return DOMString(m_prefix) + ":" + tn;    return tn;}void ElementImpl::setPrefix( const DOMString &_prefix, int &exceptioncode ){    checkSetPrefix(_prefix, exceptioncode);    if (exceptioncode)        return;    if (m_prefix)        m_prefix->deref();    m_prefix = _prefix.implementation();    if (m_prefix)        m_prefix->ref();}void ElementImpl::createAttributeMap() const{    namedAttrMap = new NamedAttrMapImpl(const_cast<ElementImpl*>(this));    namedAttrMap->ref();}bool ElementImpl::isURLAttribute(AttributeImpl *attr) const{    return false;    }void ElementImpl::defaultEventHandler(EventImpl *evt){#if APPLE_CHANGES    if (evt->id() == EventImpl::KEYPRESS_EVENT && isContentEditable()) {        KHTMLPart *part = getDocument()->part();        // Don't treat command-key combos as editing key events        if (part && !static_cast<KeyboardEventImpl*>(evt)->metaKey() && KWQ(part)->interceptEditingKeyEvent())            evt->setDefaultHandled();    }#endif    NodeBaseImpl::defaultEventHandler(evt);}RenderStyle *ElementImpl::styleForRenderer(RenderObject *parentRenderer){    return getDocument()->styleSelector()->styleForElement(this);}RenderObject *ElementImpl::createRenderer(RenderArena *arena, RenderStyle *style){    if (getDocument()->documentElement() == this && style->display() == NONE) {        // Ignore display: none on root elements.  Force a display of block in that case.        RenderBlock* result = new (arena) RenderBlock(this);        if (result) result->setStyle(style);        return result;    }    return RenderObject::createObject(this, style);}void ElementImpl::attach(){#if SPEED_DEBUG < 1    createRendererIfNeeded();#endif    NodeBaseImpl::attach();    if (hasID()) {        NamedAttrMapImpl *attrs = attributes(true);        if (attrs) {            AttributeImpl *idAttr = attrs->getAttributeItem(ATTR_ID);            if (idAttr && !idAttr->isNull()) {                updateId(nullAtom, idAttr->value());            }        }    }}void ElementImpl::detach(){    if (hasID()) {        NamedAttrMapImpl *attrs = attributes(true);        if (attrs) {            AttributeImpl *idAttr = attrs->getAttributeItem(ATTR_ID);            if (idAttr && !idAttr->isNull()) {                updateId(idAttr->value(), nullAtom);            }        }    }    NodeBaseImpl::detach();}void ElementImpl::recalcStyle( StyleChange change ){    // ### should go away and be done in renderobject    RenderStyle* _style = m_render ? m_render->style() : 0;    bool hasParentRenderer = parent() ? parent()->renderer() : false;    #if 0    const char* debug;    switch(change) {    case NoChange: debug = "NoChange";        break;    case NoInherit: debug= "NoInherit";        break;    case Inherit: debug = "Inherit";        break;    case Force: debug = "Force";        break;    }    qDebug("recalcStyle(%d: %s)[%p: %s]", change, debug, this, tagName().string().latin1());#endif    if ( hasParentRenderer && (change >= Inherit || changed()) ) {        RenderStyle *newStyle = getDocument()->styleSelector()->styleForElement(this);        newStyle->ref();        StyleChange ch = diff( _style, newStyle );        if (ch == Detach) {            if (attached()) detach();            // ### Suboptimal. Style gets calculated again.            attach();            // attach recalulates the style for all children. No need to do it twice.            setChanged( false );            setHasChangedChild( false );            newStyle->deref(getDocument()->renderArena());            return;        }        else if (ch != NoChange) {            if( m_render && newStyle ) {                //qDebug("--> setting style on render element bgcolor=%s", newStyle->backgroundColor().name().latin1());                m_render->setStyle(newStyle);            }        }        newStyle->deref(getDocument()->renderArena());        if ( change != Force) {            if (getDocument()->usesDescendantRules())                change = Force;            else                change = ch;        }    }

⌨️ 快捷键说明

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