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

📄 node.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                return elem->namespaceURI();                        if (elem->hasAttributes()) {                NamedAttrMap *attrs = elem->attributes();                                for (unsigned i = 0; i < attrs->length(); i++) {                    Attribute *attr = attrs->attributeItem(i);                                        if (attr->prefix() == "xmlns" && attr->localName() == prefix) {                        if (!attr->value().isEmpty())                            return attr->value();                                                return String();                    } else if (attr->localName() == "xmlns" && prefix.isNull()) {                        if (!attr->value().isEmpty())                            return attr->value();                                                return String();                    }                }            }            if (Element* ancestor = ancestorElement())                return ancestor->lookupNamespaceURI(prefix);            return String();        }        case DOCUMENT_NODE:            if (Element* de = static_cast<const Document*>(this)->documentElement())                return de->lookupNamespaceURI(prefix);            return String();        case ENTITY_NODE:        case NOTATION_NODE:        case DOCUMENT_TYPE_NODE:        case DOCUMENT_FRAGMENT_NODE:            return String();        case ATTRIBUTE_NODE: {            const Attr *attr = static_cast<const Attr *>(this);                        if (attr->ownerElement())                return attr->ownerElement()->lookupNamespaceURI(prefix);            else                return String();        }        default:            if (Element* ancestor = ancestorElement())                return ancestor->lookupNamespaceURI(prefix);            return String();    }}String Node::lookupNamespacePrefix(const AtomicString &_namespaceURI, const Element *originalElement) const{    if (_namespaceURI.isNull())        return String();                if (originalElement->lookupNamespaceURI(prefix()) == _namespaceURI)        return prefix();        if (hasAttributes()) {        NamedAttrMap *attrs = attributes();                for (unsigned i = 0; i < attrs->length(); i++) {            Attribute *attr = attrs->attributeItem(i);                        if (attr->prefix() == "xmlns" &&                attr->value() == _namespaceURI &&                originalElement->lookupNamespaceURI(attr->localName()) == _namespaceURI)                return attr->localName();        }    }        if (Element* ancestor = ancestorElement())        return ancestor->lookupNamespacePrefix(_namespaceURI, originalElement);    return String();}void Node::appendTextContent(bool convertBRsToNewlines, StringBuilder& content) const{    switch (nodeType()) {        case TEXT_NODE:        case CDATA_SECTION_NODE:        case COMMENT_NODE:            content.append(static_cast<const CharacterData*>(this)->CharacterData::nodeValue());            break;        case PROCESSING_INSTRUCTION_NODE:            content.append(static_cast<const ProcessingInstruction*>(this)->ProcessingInstruction::nodeValue());            break;                case ELEMENT_NODE:            if (hasTagName(brTag) && convertBRsToNewlines) {                content.append('\n');                break;        }        // Fall through.        case ATTRIBUTE_NODE:        case ENTITY_NODE:        case ENTITY_REFERENCE_NODE:        case DOCUMENT_FRAGMENT_NODE:            content.setNonNull();            for (Node *child = firstChild(); child; child = child->nextSibling()) {                if (child->nodeType() == COMMENT_NODE || child->nodeType() == PROCESSING_INSTRUCTION_NODE)                    continue;                            child->appendTextContent(convertBRsToNewlines, content);            }            break;        case DOCUMENT_NODE:        case DOCUMENT_TYPE_NODE:        case NOTATION_NODE:        case XPATH_NAMESPACE_NODE:            break;    }}String Node::textContent(bool convertBRsToNewlines) const{    StringBuilder content;    appendTextContent(convertBRsToNewlines, content);    return content.toString();}void Node::setTextContent(const String &text, ExceptionCode& ec){               switch (nodeType()) {        case TEXT_NODE:        case CDATA_SECTION_NODE:        case COMMENT_NODE:        case PROCESSING_INSTRUCTION_NODE:            setNodeValue(text, ec);            break;        case ELEMENT_NODE:        case ATTRIBUTE_NODE:        case ENTITY_NODE:        case ENTITY_REFERENCE_NODE:        case DOCUMENT_FRAGMENT_NODE: {            ContainerNode *container = static_cast<ContainerNode *>(this);                        container->removeChildren();                        if (!text.isEmpty())                appendChild(document()->createTextNode(text), ec);            break;        }        case DOCUMENT_NODE:        case DOCUMENT_TYPE_NODE:        case NOTATION_NODE:        default:            // Do nothing            break;    }}Element* Node::ancestorElement() const{    // In theory, there can be EntityReference nodes between elements, but this is currently not supported.    for (Node* n = parentNode(); n; n = n->parentNode()) {        if (n->isElementNode())            return static_cast<Element*>(n);    }    return 0;}bool Node::offsetInCharacters() const{    return false;}unsigned short Node::compareDocumentPosition(Node* otherNode){    // It is not clear what should be done if |otherNode| is 0.    if (!otherNode)        return DOCUMENT_POSITION_DISCONNECTED;    if (otherNode == this)        return DOCUMENT_POSITION_EQUIVALENT;        Attr* attr1 = nodeType() == ATTRIBUTE_NODE ? static_cast<Attr*>(this) : 0;    Attr* attr2 = otherNode->nodeType() == ATTRIBUTE_NODE ? static_cast<Attr*>(otherNode) : 0;        Node* start1 = attr1 ? attr1->ownerElement() : this;    Node* start2 = attr2 ? attr2->ownerElement() : otherNode;        // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is    // an orphaned attribute node.    if (!start1 || !start2)        return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;    Vector<Node*, 16> chain1;    Vector<Node*, 16> chain2;    if (attr1)        chain1.append(attr1);    if (attr2)        chain2.append(attr2);        if (attr1 && attr2 && start1 == start2 && start1) {        // We are comparing two attributes on the same node.  Crawl our attribute map        // and see which one we hit first.        NamedAttrMap* map = attr1->ownerElement()->attributes(true);        unsigned length = map->length();        for (unsigned i = 0; i < length; ++i) {            // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an             // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of            // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,             // when comparing two attributes of the same element, and inserting or removing additional attributes might change             // the order between existing attributes.            Attribute* attr = map->attributeItem(i);            if (attr1->attr() == attr)                return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;            if (attr2->attr() == attr)                return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;        }                ASSERT_NOT_REACHED();        return DOCUMENT_POSITION_DISCONNECTED;    }    // If one node is in the document and the other is not, we must be disconnected.    // If the nodes have different owning documents, they must be disconnected.  Note that we avoid    // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug).    if (start1->inDocument() != start2->inDocument() ||        start1->document() != start2->document())        return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;    // We need to find a common ancestor container, and then compare the indices of the two immediate children.    Node* current;    for (current = start1; current; current = current->parentNode())        chain1.append(current);    for (current = start2; current; current = current->parentNode())        chain2.append(current);       // Walk the two chains backwards and look for the first difference.    unsigned index1 = chain1.size();    unsigned index2 = chain2.size();    for (unsigned i = min(index1, index2); i; --i) {        Node* child1 = chain1[--index1];        Node* child2 = chain2[--index2];        if (child1 != child2) {            // If one of the children is an attribute, it wins.            if (child1->nodeType() == ATTRIBUTE_NODE)                return DOCUMENT_POSITION_FOLLOWING;            if (child2->nodeType() == ATTRIBUTE_NODE)                return DOCUMENT_POSITION_PRECEDING;                        if (!child2->nextSibling())                return DOCUMENT_POSITION_FOLLOWING;            if (!child1->nextSibling())                return DOCUMENT_POSITION_PRECEDING;            // Otherwise we need to see which node occurs first.  Crawl backwards from child2 looking for child1.            for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) {                if (child == child1)                    return DOCUMENT_POSITION_FOLLOWING;            }            return DOCUMENT_POSITION_PRECEDING;        }    }        // There was no difference between the two parent chains, i.e., one was a subset of the other.  The shorter    // chain is the ancestor.    return index1 < index2 ?                DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY :               DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS;}FloatPoint Node::convertToPage(const FloatPoint& p) const{    // If there is a renderer, just ask it to do the conversion    if (renderer())        return renderer()->localToAbsolute(p, false, true);        // Otherwise go up the tree looking for a renderer    Element *parent = ancestorElement();    if (parent)        return parent->convertToPage(p);    // No parent - no conversion needed    return p;}FloatPoint Node::convertFromPage(const FloatPoint& p) const{    // If there is a renderer, just ask it to do the conversion    if (renderer())        return renderer()->absoluteToLocal(p, false, true);    // Otherwise go up the tree looking for a renderer    Element *parent = ancestorElement();    if (parent)        return parent->convertFromPage(p);    // No parent - no conversion needed    return p;}#ifndef NDEBUGstatic void appendAttributeDesc(const Node* node, String& string, const QualifiedName& name, const char* attrDesc){    if (node->isElementNode()) {        String attr = static_cast<const Element*>(node)->getAttribute(name);        if (!attr.isEmpty()) {            string += attrDesc;            string += attr;        }    }}void Node::showNode(const char* prefix) const{    if (!prefix)        prefix = "";    if (isTextNode()) {        String value = nodeValue();        value.replace('\\', "\\\\");        value.replace('\n', "\\n");        fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());    } else {        String attrs = "";        appendAttributeDesc(this, attrs, classAttr, " CLASS=");        appendAttributeDesc(this, attrs, styleAttr, " STYLE=");        fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.utf8().data());    }}void Node::showTreeForThis() const{    showTreeAndMark(this, "*");}void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char * markedLabel2) const{    const Node* rootNode;    const Node* node = this;    while (node->parentNode() && !node->hasTagName(bodyTag))        node = node->parentNode();    rootNode = node;            for (node = rootNode; node; node = node->traverseNextNode()) {        if (node == markedNode1)            fprintf(stderr, "%s", markedLabel1);        if (node == markedNode2)            fprintf(stderr, "%s", markedLabel2);                                for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentNode())            fprintf(stderr, "\t");        node->showNode();    }}void Node::formatForDebugger(char* buffer, unsigned length) const{    String result;    String s;        s = nodeName();    if (s.length() == 0)        result += "<none>";    else        result += s;              strncpy(buffer, result.utf8().data(), length - 1);}#endif// --------void NodeListsNodeData::invalidateCaches(){    m_childNodeListCaches.reset();    TagCacheMap::const_iterator tagCachesEnd = m_tagNodeListCaches.end();    for (TagCacheMap::const_iterator it = m_tagNodeListCaches.begin(); it != tagCachesEnd; ++it)        it->second->reset();    invalidateCachesThatDependOnAttributes();}void NodeListsNodeData::invalidateCachesThatDependOnAttributes(){    CacheMap::iterator classCachesEnd = m_classNodeListCaches.end();    for (CacheMap::iterator it = m_classNodeListCaches.begin(); it != classCachesEnd; ++it)        it->second->reset();    CacheMap::iterator nameCachesEnd = m_nameNodeListCaches.end();    for (CacheMap::iterator it = m_nameNodeListCaches.begin(); it != nameCachesEnd; ++it)        it->second->reset();}bool NodeListsNodeData::isEmpty() const{    if (!m_listsWithCaches.isEmpty())        return false;    if (m_childNodeListCaches.refCount)        return false;        TagCacheMap::const_iterator tagCachesEnd = m_tagNodeListCaches.end();    for (TagCacheMap::const_iterator it = m_tagNodeListCaches.begin(); it != tagCachesEnd; ++it) {        if (it->second->refCount)            return false;    }    CacheMap::const_iterator classCachesEnd = m_classNodeListCaches.end();    for (CacheMap::const_iterator it = m_classNodeListCaches.begin(); it != classCachesEnd; ++it) {        if (it->second->refCount)            return false;    }    CacheMap::const_iterator nameCachesEnd = m_nameNodeListCaches.end();    for (CacheMap::const_iterator it = m_nameNodeListCaches.begin(); it != nameCachesEnd; ++it) {        if (it->second->refCount)            return false;    }    return true;}void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const{    addSubresourceAttributeURLs(urls);}ContainerNode* Node::eventParentNode(){    Node* parent = parentNode();    ASSERT(!parent || parent->isContainerNode());    return static_cast<ContainerNode*>(parent);}// --------ScriptExecutionContext* Node::scri

⌨️ 快捷键说明

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