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

📄 node.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#endif    Node* root = shadowTreeRootNode();    if (root)        return root->shadowParentNode();    return this;}Node* Node::shadowTreeRootNode(){    Node* root = this;    while (root) {        if (root->isShadowNode())            return root;        root = root->parentNode();    }    return 0;}bool Node::isInShadowTree(){    for (Node* n = this; n; n = n->parentNode())        if (n->isShadowNode())            return true;    return false;}bool Node::isBlockFlow() const{    return renderer() && renderer()->isBlockFlow();}bool Node::isBlockFlowOrBlockTable() const{    return renderer() && (renderer()->isBlockFlow() || renderer()->isTable() && !renderer()->isInline());}bool Node::isEditableBlock() const{    return isContentEditable() && isBlockFlow();}Element *Node::enclosingBlockFlowElement() const{    Node *n = const_cast<Node *>(this);    if (isBlockFlow())        return static_cast<Element *>(n);    while (1) {        n = n->parentNode();        if (!n)            break;        if (n->isBlockFlow() || n->hasTagName(bodyTag))            return static_cast<Element *>(n);    }    return 0;}Element *Node::enclosingInlineElement() const{    Node *n = const_cast<Node *>(this);    Node *p;    while (1) {        p = n->parentNode();        if (!p || p->isBlockFlow() || p->hasTagName(bodyTag))            return static_cast<Element *>(n);        // Also stop if any previous sibling is a block        for (Node *sibling = n->previousSibling(); sibling; sibling = sibling->previousSibling()) {            if (sibling->isBlockFlow())                return static_cast<Element *>(n);        }        n = p;    }    ASSERT_NOT_REACHED();    return 0;}Element* Node::rootEditableElement() const{    Element* result = 0;    for (Node* n = const_cast<Node*>(this); n && n->isContentEditable(); n = n->parentNode()) {        if (n->isElementNode())            result = static_cast<Element*>(n);        if (n->hasTagName(bodyTag))            break;    }    return result;}bool Node::inSameContainingBlockFlowElement(Node *n){    return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : false;}// FIXME: End of obviously misplaced HTML editing functions.  Try to move these out of Node.PassRefPtr<NodeList> Node::getElementsByTagName(const String& name){    return getElementsByTagNameNS(starAtom, name);} PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const String& localName){    if (localName.isNull())        return 0;        NodeRareData* data = ensureRareData();    if (!data->nodeLists()) {        data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));        document()->addNodeListCache();    }    String name = localName;    if (document()->isHTMLDocument())        name = localName.lower();        AtomicString localNameAtom = name;            pair<NodeListsNodeData::TagCacheMap::iterator, bool> result = data->nodeLists()->m_tagNodeListCaches.add(QualifiedName(nullAtom, localNameAtom, namespaceURI), 0);    if (result.second)        result.first->second = new DynamicNodeList::Caches;        return TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom, result.first->second);}PassRefPtr<NodeList> Node::getElementsByName(const String& elementName){    NodeRareData* data = ensureRareData();    if (!data->nodeLists()) {        data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));        document()->addNodeListCache();    }    pair<NodeListsNodeData::CacheMap::iterator, bool> result = data->nodeLists()->m_nameNodeListCaches.add(elementName, 0);    if (result.second)        result.first->second = new DynamicNodeList::Caches;        return NameNodeList::create(this, elementName, result.first->second);}PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames){    NodeRareData* data = ensureRareData();    if (!data->nodeLists()) {        data->setNodeLists(auto_ptr<NodeListsNodeData>(new NodeListsNodeData));        document()->addNodeListCache();    }    pair<NodeListsNodeData::CacheMap::iterator, bool> result = data->nodeLists()->m_classNodeListCaches.add(classNames, 0);    if (result.second)        result.first->second = new DynamicNodeList::Caches;        return ClassNodeList::create(this, classNames, result.first->second);}template <typename Functor>static bool forEachTagSelector(Functor& functor, CSSSelector* selector){    ASSERT(selector);    do {        if (functor(selector))            return true;        if (CSSSelector* simpleSelector = selector->simpleSelector()) {            if (forEachTagSelector(functor, simpleSelector))                return true;        }    } while ((selector = selector->tagHistory()));    return false;}template <typename Functor>static bool forEachSelector(Functor& functor, const CSSSelectorList& selectorList){    for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {        if (forEachTagSelector(functor, selector))            return true;    }    return false;}class SelectorNeedsNamespaceResolutionFunctor {public:    bool operator()(CSSSelector* selector)    {        if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom)            return true;        if (selector->hasAttribute() && selector->attribute().prefix() != nullAtom && selector->attribute().prefix() != starAtom)            return true;        return false;    }};static bool selectorNeedsNamespaceResolution(const CSSSelectorList& selectorList){    SelectorNeedsNamespaceResolutionFunctor functor;    return forEachSelector(functor, selectorList);}PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec){    if (selectors.isEmpty()) {        ec = SYNTAX_ERR;        return 0;    }    bool strictParsing = !document()->inCompatMode();    CSSParser p(strictParsing);    CSSSelectorList querySelectorList;    p.parseSelector(selectors, document(), querySelectorList);    if (!querySelectorList.first()) {        ec = SYNTAX_ERR;        return 0;    }    // throw a NAMESPACE_ERR if the selector includes any namespace prefixes.    if (selectorNeedsNamespaceResolution(querySelectorList)) {        ec = NAMESPACE_ERR;        return 0;    }    CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing);    // FIXME: we could also optimize for the the [id="foo"] case    if (strictParsing && inDocument() && querySelectorList.hasOneSelector() && querySelectorList.first()->m_match == CSSSelector::Id) {        ASSERT(querySelectorList.first()->attribute() == idAttr);        Element* element = document()->getElementById(querySelectorList.first()->m_value);        if (element && (isDocumentNode() || element->isDescendantOf(this)) && selectorChecker.checkSelector(querySelectorList.first(), element))            return element;        return 0;    }    // FIXME: We can speed this up by implementing caching similar to the one use by getElementById    for (Node* n = firstChild(); n; n = n->traverseNextNode(this)) {        if (n->isElementNode()) {            Element* element = static_cast<Element*>(n);            for (CSSSelector* selector = querySelectorList.first(); selector; selector = CSSSelectorList::next(selector)) {                if (selectorChecker.checkSelector(selector, element))                    return element;            }        }    }        return 0;}PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCode& ec){    if (selectors.isEmpty()) {        ec = SYNTAX_ERR;        return 0;    }    bool strictParsing = !document()->inCompatMode();    CSSParser p(strictParsing);    CSSSelectorList querySelectorList;    p.parseSelector(selectors, document(), querySelectorList);    if (!querySelectorList.first()) {        ec = SYNTAX_ERR;        return 0;    }    // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.    if (selectorNeedsNamespaceResolution(querySelectorList)) {        ec = NAMESPACE_ERR;        return 0;    }    return createSelectorNodeList(this, querySelectorList);}Document *Node::ownerDocument() const{    Document *doc = document();    return doc == this ? 0 : doc;}KURL Node::baseURI() const{    return parentNode() ? parentNode()->baseURI() : KURL();}bool Node::isEqualNode(Node *other) const{    if (!other)        return false;        if (nodeType() != other->nodeType())        return false;        if (nodeName() != other->nodeName())        return false;        if (localName() != other->localName())        return false;        if (namespaceURI() != other->namespaceURI())        return false;        if (prefix() != other->prefix())        return false;        if (nodeValue() != other->nodeValue())        return false;        NamedAttrMap *attrs = attributes();    NamedAttrMap *otherAttrs = other->attributes();        if (!attrs && otherAttrs)        return false;        if (attrs && !attrs->mapsEquivalent(otherAttrs))        return false;        Node *child = firstChild();    Node *otherChild = other->firstChild();        while (child) {        if (!child->isEqualNode(otherChild))            return false;                child = child->nextSibling();        otherChild = otherChild->nextSibling();    }        if (otherChild)        return false;        // FIXME: For DocumentType nodes we should check equality on    // the entities and notations NamedNodeMaps as well.        return true;}bool Node::isDefaultNamespace(const AtomicString &namespaceURI) const{    // Implemented according to    // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#isDefaultNamespaceAlgo        switch (nodeType()) {        case ELEMENT_NODE: {            const Element *elem = static_cast<const Element *>(this);                        if (elem->prefix().isNull())                return elem->namespaceURI() == namespaceURI;            if (elem->hasAttributes()) {                NamedAttrMap *attrs = elem->attributes();                                for (unsigned i = 0; i < attrs->length(); i++) {                    Attribute *attr = attrs->attributeItem(i);                                        if (attr->localName() == "xmlns")                        return attr->value() == namespaceURI;                }            }            if (Element* ancestor = ancestorElement())                return ancestor->isDefaultNamespace(namespaceURI);            return false;        }        case DOCUMENT_NODE:            if (Element* de = static_cast<const Document*>(this)->documentElement())                return de->isDefaultNamespace(namespaceURI);            return false;        case ENTITY_NODE:        case NOTATION_NODE:        case DOCUMENT_TYPE_NODE:        case DOCUMENT_FRAGMENT_NODE:            return false;        case ATTRIBUTE_NODE: {            const Attr *attr = static_cast<const Attr *>(this);            if (attr->ownerElement())                return attr->ownerElement()->isDefaultNamespace(namespaceURI);            return false;        }        default:            if (Element* ancestor = ancestorElement())                return ancestor->isDefaultNamespace(namespaceURI);            return false;    }}String Node::lookupPrefix(const AtomicString &namespaceURI) const{    // Implemented according to    // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespacePrefixAlgo        if (namespaceURI.isEmpty())        return String();        switch (nodeType()) {        case ELEMENT_NODE:            return lookupNamespacePrefix(namespaceURI, static_cast<const Element *>(this));        case DOCUMENT_NODE:            if (Element* de = static_cast<const Document*>(this)->documentElement())                return de->lookupPrefix(namespaceURI);            return String();        case ENTITY_NODE:        case NOTATION_NODE:        case DOCUMENT_FRAGMENT_NODE:        case DOCUMENT_TYPE_NODE:            return String();        case ATTRIBUTE_NODE: {            const Attr *attr = static_cast<const Attr *>(this);            if (attr->ownerElement())                return attr->ownerElement()->lookupPrefix(namespaceURI);            return String();        }        default:            if (Element* ancestor = ancestorElement())                return ancestor->lookupPrefix(namespaceURI);            return String();    }}String Node::lookupNamespaceURI(const String &prefix) const{    // Implemented according to    // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo        if (!prefix.isNull() && prefix.isEmpty())        return String();        switch (nodeType()) {        case ELEMENT_NODE: {            const Element *elem = static_cast<const Element *>(this);                        if (!elem->namespaceURI().isNull() && elem->prefix() == prefix)

⌨️ 快捷键说明

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