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

📄 dom_elementimpl.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    NodeImpl *n;    for (n = _first; n; n = n->nextSibling()) {	//qDebug("    (%p) calling recalcStyle on child %s/%p, change=%d", this, n, n->isElementNode() ? ((ElementImpl *)n)->tagName().string().latin1() : n->isTextNode() ? "text" : "unknown", change );        if ( change >= Inherit || n->isTextNode() ||             n->hasChangedChild() || n->changed() )            n->recalcStyle( change );    }    setChanged( false );    setHasChangedChild( false );}// DOM Section 1.1.1bool ElementImpl::childAllowed( NodeImpl *newChild ){    if (!childTypeAllowed(newChild->nodeType()))        return false;    // For XML documents, we are non-validating and do not check against a DTD, even for HTML elements.    if (getDocument()->isHTMLDocument())        return checkChild(id(), newChild->id());    return true;}bool ElementImpl::childTypeAllowed( unsigned short type ){    switch (type) {        case Node::ELEMENT_NODE:        case Node::TEXT_NODE:        case Node::COMMENT_NODE:        case Node::PROCESSING_INSTRUCTION_NODE:        case Node::CDATA_SECTION_NODE:        case Node::ENTITY_REFERENCE_NODE:            return true;            break;        default:            return false;    }}void ElementImpl::dispatchAttrRemovalEvent(AttributeImpl *attr){    if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER))	return;    //int exceptioncode = 0;//     dispatchEvent(new MutationEventImpl(EventImpl::DOMATTRMODIFIED_EVENT,true,false,attr,attr->value(),// 		  attr->value(), getDocument()->attrName(attr->id()),MutationEvent::REMOVAL),exceptioncode);}void ElementImpl::dispatchAttrAdditionEvent(AttributeImpl *attr){    if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER))	return;   // int exceptioncode = 0;//     dispatchEvent(new MutationEventImpl(EventImpl::DOMATTRMODIFIED_EVENT,true,false,attr,attr->value(),//                                         attr->value(),getDocument()->attrName(attr->id()),MutationEvent::ADDITION),exceptioncode);}DOMString ElementImpl::openTagStartToString() const{    DOMString result = DOMString("<") + tagName();    NamedAttrMapImpl *attrMap = attributes(true);    if (attrMap) {	unsigned long numAttrs = attrMap->length();	for (unsigned long i = 0; i < numAttrs; i++) {	    result += " ";	    AttributeImpl *attribute = attrMap->attributeItem(i);	    AttrImpl *attr = attribute->attrImpl();	    if (attr) {		result += attr->toString();	    } else {		result += getDocument()->attrName(attribute->id());		if (!attribute->value().isNull()) {		    result += "=\"";		    // FIXME: substitute entities for any instances of " or '		    result += attribute->value();		    result += "\"";		}	    }	}    }    return result;}DOMString ElementImpl::toString() const{    DOMString result = openTagStartToString();    if (hasChildNodes()) {	result += ">";	for (NodeImpl *child = firstChild(); child != NULL; child = child->nextSibling()) {	    result += child->toString();	}	result += "</";	result += tagName();	result += ">";    } else {	result += " />";    }    return result;}void ElementImpl::updateId(const AtomicString& oldId, const AtomicString& newId){    if (!attached())	return;    if (oldId == newId)	return;    DocumentImpl* doc = getDocument();    if (!oldId.isEmpty())	doc->removeElementById(oldId, this);    if (!newId.isEmpty())	doc->addElementById(newId, this);}#ifndef NDEBUGvoid ElementImpl::dump(QTextStream *stream, QString ind) const{    if (namedAttrMap) {        for (uint i = 0; i < namedAttrMap->length(); i++) {            AttributeImpl *attr = namedAttrMap->attributeItem(i);            *stream << " " << DOMString(getDocument()->attrName(attr->id())).string().ascii()                    << "=\"" << DOMString(attr->value()).string().ascii() << "\"";        }    }    NodeBaseImpl::dump(stream,ind);}#endif// -------------------------------------------------------------------------XMLElementImpl::XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_tagName)    : ElementImpl(doc){    m_id = doc->document()->tagId(0 /* no namespace */, _tagName,  false /* allocate */);}XMLElementImpl::XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_qualifiedName, DOMStringImpl *_namespaceURI)    : ElementImpl(doc){    int colonpos = -1;    for (uint i = 0; i < _qualifiedName->l; ++i)        if (_qualifiedName->s[i] == ':') {            colonpos = i;            break;        }    if (colonpos >= 0) {        // we have a prefix        DOMStringImpl* localName = _qualifiedName->copy();        localName->ref();        localName->remove(0,colonpos+1);        m_id = doc->document()->tagId(_namespaceURI, localName, false /* allocate */);        localName->deref();        m_prefix = _qualifiedName->copy();        m_prefix->ref();        m_prefix->truncate(colonpos);    }    else {        // no prefix        m_id = doc->document()->tagId(_namespaceURI, _qualifiedName, false /* allocate */);        m_prefix = 0;    }}XMLElementImpl::~XMLElementImpl(){}DOMString XMLElementImpl::localName() const{    return getDocument()->tagName(m_id);}NodeImpl *XMLElementImpl::cloneNode ( bool deep ){    // ### we loose namespace here FIXME    // should pass id around    XMLElementImpl *clone = new XMLElementImpl(docPtr(), getDocument()->tagName(m_id).implementation());    clone->m_id = m_id;    // clone attributes    if(namedAttrMap)        *(static_cast<NamedAttrMapImpl*>(clone->attributes())) = *namedAttrMap;    if (deep)        cloneChildNodes(clone);    return clone;}// -------------------------------------------------------------------------NamedAttrMapImpl::NamedAttrMapImpl(ElementImpl *e)    : element(e){    attrs = 0;    len = 0;}NamedAttrMapImpl::~NamedAttrMapImpl(){    NamedAttrMapImpl::clearAttributes(); // virtual method, so qualify just to be explicit}bool NamedAttrMapImpl::isHTMLAttributeMap() const{    return false;}AttrImpl *NamedAttrMapImpl::getNamedItem ( NodeImpl::Id id ) const{    AttributeImpl* a = getAttributeItem(id);    if (!a) return 0;    if (!a->attrImpl())        a->allocateImpl(element);    return a->attrImpl();}Node NamedAttrMapImpl::setNamedItem ( NodeImpl* arg, int &exceptioncode ){    if (!element) {        exceptioncode = DOMException::NOT_FOUND_ERR;        return 0;    }    // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.    if (isReadOnly()) {        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;        return 0;    }    // WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.    if (arg->getDocument() != element->getDocument()) {        exceptioncode = DOMException::WRONG_DOCUMENT_ERR;        return 0;    }    // Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node    if (!arg->isAttributeNode()) {        exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;        return 0;    }    AttrImpl *attr = static_cast<AttrImpl*>(arg);    AttributeImpl* a = attr->attrImpl();    AttributeImpl* old = getAttributeItem(a->id());    if (old == a) return arg; // we know about it already    // INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.    // The DOM user must explicitly clone Attr nodes to re-use them in other elements.    if (attr->ownerElement()) {        exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR;        return 0;    }    if (a->id() == ATTR_ID) {	element->updateId(old ? old->value() : nullAtom, a->value());    }    // ### slightly inefficient - resizes attribute array twice.    Node r;    if (old) {        if (!old->attrImpl())            old->allocateImpl(element);        r = old->_impl;        removeAttribute(a->id());    }    addAttribute(a);    return r;}// The DOM2 spec doesn't say that removeAttribute[NS] throws NOT_FOUND_ERR// if the attribute is not found, but at this level we have to throw NOT_FOUND_ERR// because of removeNamedItem, removeNamedItemNS, and removeAttributeNode.Node NamedAttrMapImpl::removeNamedItem ( NodeImpl::Id id, int &exceptioncode ){    // ### should this really be raised when the attribute to remove isn't there at all?    // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly    if (isReadOnly()) {        exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;        return Node();    }    AttributeImpl* a = getAttributeItem(id);    if (!a) {        exceptioncode = DOMException::NOT_FOUND_ERR;        return Node();    }    if (!a->attrImpl())  a->allocateImpl(element);    Node r(a->attrImpl());    if (id == ATTR_ID) {	element->updateId(a->value(), nullAtom);    }    removeAttribute(id);    return r;}AttrImpl *NamedAttrMapImpl::item ( unsigned long index ) const{    if (index >= len)        return 0;    if (!attrs[index]->attrImpl())        attrs[index]->allocateImpl(element);    return attrs[index]->attrImpl();}AttributeImpl* NamedAttrMapImpl::getAttributeItem(NodeImpl::Id id) const{    bool matchAnyNamespace = (namespacePart(id) == anyNamespace);    for (unsigned long i = 0; i < len; ++i) {        if (attrs[i]->id() == id)            return attrs[i];        else if (matchAnyNamespace) {            if (localNamePart(attrs[i]->id()) == localNamePart(id))                return attrs[i];        }    }    return 0;}NodeImpl::Id NamedAttrMapImpl::mapId(const DOMString& namespaceURI,                                     const DOMString& localName, bool readonly){    assert(element);    if (!element) return 0;    return element->getDocument()->attrId(namespaceURI.implementation(),                                            localName.implementation(), readonly);}void NamedAttrMapImpl::clearAttributes(){    if (attrs) {        uint i;        for (i = 0; i < len; i++) {            if (attrs[i]->_impl)                attrs[i]->_impl->m_element = 0;            attrs[i]->deref();        }        delete [] attrs;        attrs = 0;    }    len = 0;}void NamedAttrMapImpl::detachFromElement(){    // we allow a NamedAttrMapImpl w/o an element in case someone still has a reference    // to if after the element gets deleted - but the map is now invalid    element = 0;    clearAttributes();}NamedAttrMapImpl& NamedAttrMapImpl::operator=(const NamedAttrMapImpl& other){    // clone all attributes in the other map, but attach to our element    if (!element) return *this;    // If assigning the map changes the id attribute, we need to call    // updateId.    AttributeImpl *oldId = getAttributeItem(ATTR_ID);    AttributeImpl *newId = other.getAttributeItem(ATTR_ID);    if (oldId || newId) {	element->updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);    }    clearAttributes();    len = other.len;    attrs = new AttributeImpl* [len];    // first initialize attrs vector, then call attributeChanged on it    // this allows attributeChanged to use getAttribute    for (uint i = 0; i < len; i++) {        attrs[i] = other.attrs[i]->clone();        attrs[i]->ref();    }    // FIXME: This is wasteful.  The class list could be preserved on a copy, and we    // wouldn't have to waste time reparsing the attribute.    // The derived class, HTMLNamedAttrMapImpl, which manages a parsed class list for the CLASS attribute,    // will update its member variable when parse attribute is called.    for(uint i = 0; i < len; i++)        element->attributeChanged(attrs[i], true);    return *this;}void NamedAttrMapImpl::addAttribute(AttributeImpl *attr){    // Add the attribute to the list    AttributeImpl **newAttrs = new AttributeImpl* [len+1];    if (attrs) {      for (uint i = 0; i < len; i++)        newAttrs[i] = attrs[i];      delete [] attrs;    }    attrs = newAttrs;    attrs[len++] = attr;    attr->ref();    AttrImpl * const attrImpl = attr->_impl;    if (attrImpl)        attrImpl->m_element = element;    // Notify the element that the attribute has been added, and dispatch appropriate mutation events    // Note that element may be null here if we are called from insertAttr() during parsing    if (element) {        element->attributeChanged(attr);        element->dispatchAttrAdditionEvent(attr);        element->dispatchSubtreeModifiedEvent();    }}void NamedAttrMapImpl::removeAttribute(NodeImpl::Id id){    unsigned long index = len+1;    for (unsigned long i = 0; i < len; ++i)        if (attrs[i]->id() == id) {            index = i;            break;        }    if (index >= len) return;    // Remove the attribute from the list    AttributeImpl* attr = attrs[index];    if (attrs[index]->_impl)        attrs[index]->_impl->m_element = 0;    if (len == 1) {        delete [] attrs;        attrs = 0;        len = 0;    }    else {        AttributeImpl **newAttrs = new AttributeImpl* [len-1];        uint i;        for (i = 0; i < uint(index); i++)            newAttrs[i] = attrs[i];        len--;        for (; i < len; i++)            newAttrs[i] = attrs[i+1];        delete [] attrs;        attrs = newAttrs;    }    // Notify the element that the attribute has been removed    // dispatch appropriate mutation events    if (element && !attr->_value.isNull()) {        AtomicString value = attr->_value;        attr->_value = nullAtom;        element->attributeChanged(attr);        attr->_value = value;    }    if (element) {        element->dispatchAttrRemovalEvent(attr);        element->dispatchSubtreeModifiedEvent();    }    attr->deref();}

⌨️ 快捷键说明

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