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

📄 node.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2001 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * 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 "config.h"#include "Node.h"#include "CSSParser.h"#include "CSSRule.h"#include "CSSRuleList.h"#include "CSSSelector.h"#include "CSSSelectorList.h"#include "CSSStyleRule.h"#include "CSSStyleSelector.h"#include "CSSStyleSheet.h"#include "CString.h"#include "ChildNodeList.h"#include "ClassNodeList.h"#include "DOMImplementation.h"#include "Document.h"#include "DynamicNodeList.h"#include "Element.h"#include "Event.h"#include "EventException.h"#include "EventHandler.h"#include "EventListener.h"#include "EventNames.h"#include "ExceptionCode.h"#include "Frame.h"#include "FrameView.h"#include "HTMLNames.h"#include "JSDOMBinding.h"#include "KeyboardEvent.h"#include "Logging.h"#include "MouseEvent.h"#include "MutationEvent.h"#include "NameNodeList.h"#include "NamedAttrMap.h"#include "NodeRareData.h"#include "Page.h"#include "PlatformMouseEvent.h"#include "PlatformWheelEvent.h"#include "ProcessingInstruction.h"#include "ProgressEvent.h"#include "RegisteredEventListener.h"#include "RenderObject.h"#include "ScriptController.h"#include "SelectorNodeList.h"#include "StringBuilder.h"#include "TagNodeList.h"#include "Text.h"#include "TextEvent.h"#include "UIEvent.h"#include "UIEventWithKeyState.h"#include "WebKitAnimationEvent.h"#include "WebKitTransitionEvent.h"#include "WheelEvent.h"#include "XMLNames.h"#include "htmlediting.h"#include <wtf/HashSet.h>#include <wtf/RefCountedLeakCounter.h>#if ENABLE(DOM_STORAGE)#include "StorageEvent.h"#endif#if ENABLE(SVG)#include "SVGElementInstance.h"#include "SVGUseElement.h"#endif#define DUMP_NODE_STATISTICS 0using namespace std;namespace WebCore {using namespace HTMLNames;static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;bool Node::isSupported(const String& feature, const String& version){    return DOMImplementation::hasFeature(feature, version);}#if DUMP_NODE_STATISTICSstatic HashSet<Node*> liveNodeSet;#endifvoid Node::dumpStatistics(){#if DUMP_NODE_STATISTICS    size_t nodesWithRareData = 0;    size_t elementNodes = 0;    size_t attrNodes = 0;    size_t textNodes = 0;    size_t cdataNodes = 0;    size_t commentNodes = 0;    size_t entityReferenceNodes = 0;    size_t entityNodes = 0;    size_t piNodes = 0;    size_t documentNodes = 0;    size_t docTypeNodes = 0;    size_t fragmentNodes = 0;    size_t notationNodes = 0;    size_t xpathNSNodes = 0;    HashMap<String, size_t> perTagCount;    size_t attributes = 0;    size_t mappedAttributes = 0;    size_t mappedAttributesWithStyleDecl = 0;    size_t attributesWithAttr = 0;    size_t attrMaps = 0;    size_t mappedAttrMaps = 0;    for (HashSet<Node*>::const_iterator it = liveNodeSet.begin(); it != liveNodeSet.end(); ++it) {        Node* node = *it;        if (node->hasRareData())            ++nodesWithRareData;        switch (node->nodeType()) {            case ELEMENT_NODE: {                ++elementNodes;                // Tag stats                Element* element = static_cast<Element*>(node);                pair<HashMap<String, size_t>::iterator, bool> result = perTagCount.add(element->tagName(), 1);                if (!result.second)                    result.first->second++;                // AttributeMap stats                if (NamedAttrMap* attrMap = element->attributes(true)) {                    attributes += attrMap->length();                    ++attrMaps;                    if (attrMap->isMappedAttributeMap())                        ++mappedAttrMaps;                    for (unsigned i = 0; i < attrMap->length(); ++i) {                        Attribute* attr = attrMap->attributeItem(i);                        if (attr->attr())                            ++attributesWithAttr;                        if (attr->isMappedAttribute()) {                            ++mappedAttributes;                            if (attr->style())                                ++mappedAttributesWithStyleDecl;                        }                    }                }                break;            }            case ATTRIBUTE_NODE: {                ++attrNodes;                break;            }            case TEXT_NODE: {                ++textNodes;                break;            }            case CDATA_SECTION_NODE: {                ++cdataNodes;                break;            }            case COMMENT_NODE: {                ++commentNodes;                break;            }            case ENTITY_REFERENCE_NODE: {                ++entityReferenceNodes;                break;            }            case ENTITY_NODE: {                ++entityNodes;                break;            }            case PROCESSING_INSTRUCTION_NODE: {                ++piNodes;                break;            }            case DOCUMENT_NODE: {                ++documentNodes;                break;            }            case DOCUMENT_TYPE_NODE: {                ++docTypeNodes;                break;            }            case DOCUMENT_FRAGMENT_NODE: {                ++fragmentNodes;                break;            }            case NOTATION_NODE: {                ++notationNodes;                break;            }            case XPATH_NAMESPACE_NODE: {                ++xpathNSNodes;                break;            }        }                }    printf("Number of Nodes: %d\n\n", liveNodeSet.size());    printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);    printf("NodeType distrubution:\n");    printf("  Number of Element nodes: %zu\n", elementNodes);    printf("  Number of Attribute nodes: %zu\n", attrNodes);    printf("  Number of Text nodes: %zu\n", textNodes);    printf("  Number of CDATASection nodes: %zu\n", cdataNodes);    printf("  Number of Comment nodes: %zu\n", commentNodes);    printf("  Number of EntityReference nodes: %zu\n", entityReferenceNodes);    printf("  Number of Entity nodes: %zu\n", entityNodes);    printf("  Number of ProcessingInstruction nodes: %zu\n", piNodes);    printf("  Number of Document nodes: %zu\n", documentNodes);    printf("  Number of DocumentType nodes: %zu\n", docTypeNodes);    printf("  Number of DocumentFragment nodes: %zu\n", fragmentNodes);    printf("  Number of Notation nodes: %zu\n", notationNodes);    printf("  Number of XPathNS nodes: %zu\n", xpathNSNodes);    printf("Element tag name distibution:\n");    for (HashMap<String, size_t>::const_iterator it = perTagCount.begin(); it != perTagCount.end(); ++it)        printf("  Number of <%s> tags: %zu\n", it->first.utf8().data(), it->second);    printf("Attribute Maps:\n");    printf("  Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));    printf("  Number of MappedAttributes: %zu [%zu]\n", mappedAttributes, sizeof(MappedAttribute));    printf("  Number of MappedAttributes with a StyleDeclaration: %zu\n", mappedAttributesWithStyleDecl);    printf("  Number of Attributes with an Attr: %zu\n", attributesWithAttr);    printf("  Number of NamedAttrMaps: %zu\n", attrMaps);    printf("  Number of NamedMappedAttrMap: %zu\n", mappedAttrMaps);#endif}#ifndef NDEBUGstatic WTF::RefCountedLeakCounter nodeCounter("WebCoreNode");static bool shouldIgnoreLeaks = false;static HashSet<Node*> ignoreSet;#endifvoid Node::startIgnoringLeaks(){#ifndef NDEBUG    shouldIgnoreLeaks = true;#endif}void Node::stopIgnoringLeaks(){#ifndef NDEBUG    shouldIgnoreLeaks = false;#endif}Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 ){    // FIXME: The behavior of this function is just totally wrong.  It doesn't handle    // explicit inheritance of non-inherited properties and so you end up not re-resolving    // style in cases where you need to.    StyleChange ch = NoInherit;    EDisplay display1 = s1 ? s1->display() : NONE;    bool fl1 = s1 && s1->hasPseudoStyle(FIRST_LETTER);    EDisplay display2 = s2 ? s2->display() : NONE;    bool fl2 = s2 && s2->hasPseudoStyle(FIRST_LETTER);            if (display1 != display2 || fl1 != fl2 || (s1 && s2 && !s1->contentDataEquivalent(s2)))        ch = Detach;    else if (!s1 || !s2)        ch = Inherit;    else if (*s1 == *s2)        ch = NoChange;    else if (s1->inheritedNotEqual(s2))        ch = Inherit;        // If the pseudoStyles have changed, we want any StyleChange that is not NoChange    // because setStyle will do the right thing with anything else.    if (ch == NoChange && s1->hasPseudoStyle(BEFORE)) {        RenderStyle* ps2 = s2->getCachedPseudoStyle(BEFORE);        if (!ps2)            ch = NoInherit;        else {            RenderStyle* ps1 = s1->getCachedPseudoStyle(BEFORE);            ch = ps1 && *ps1 == *ps2 ? NoChange : NoInherit;        }    }    if (ch == NoChange && s1->hasPseudoStyle(AFTER)) {        RenderStyle* ps2 = s2->getCachedPseudoStyle(AFTER);        if (!ps2)            ch = NoInherit;        else {            RenderStyle* ps1 = s1->getCachedPseudoStyle(AFTER);            ch = ps2 && *ps1 == *ps2 ? NoChange : NoInherit;        }    }        return ch;}Node::Node(Document* doc, bool isElement, bool isContainer, bool isText)    : m_document(doc)    , m_previous(0)    , m_next(0)    , m_renderer(0)    , m_styleChange(NoStyleChange)    , m_hasId(false)    , m_hasClass(false)    , m_attached(false)    , m_hasChangedChild(false)    , m_inDocument(false)    , m_isLink(false)    , m_active(false)    , m_hovered(false)    , m_inActiveChain(false)    , m_inDetach(false)    , m_inSubtreeMark(false)    , m_hasRareData(false)    , m_isElement(isElement)    , m_isContainer(isContainer)    , m_isText(isText)    , m_parsingChildrenFinished(true)#if ENABLE(SVG)    , m_areSVGAttributesValid(true)#endif    , m_isStyleAttributeValid(true)    , m_synchronizingStyleAttribute(false)#if ENABLE(SVG)    , m_synchronizingSVGAttributes(false)#endif{#ifndef NDEBUG    if (shouldIgnoreLeaks)        ignoreSet.add(this);    else        nodeCounter.increment();#endif#if DUMP_NODE_STATISTICS    liveNodeSet.add(this);#endif}Node::~Node(){#ifndef NDEBUG    HashSet<Node*>::iterator it = ignoreSet.find(this);    if (it != ignoreSet.end())        ignoreSet.remove(it);    else        nodeCounter.decrement();#endif#if DUMP_NODE_STATISTICS    liveNodeSet.remove(this);#endif    if (!eventListeners().isEmpty() && !inDocument())        document()->unregisterDisconnectedNodeWithEventListeners(this);    if (!hasRareData())        ASSERT(!NodeRareData::rareDataMap().contains(this));    else {        if (m_document && rareData()->nodeLists())            m_document->removeNodeListCache();                NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();        NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);        ASSERT(it != dataMap.end());        delete it->second;        dataMap.remove(it);    }    if (renderer())        detach();    if (m_previous)        m_previous->setNextSibling(0);    if (m_next)        m_next->setPreviousSibling(0);}void Node::setDocument(Document* doc){    if (inDocument() || m_document == doc)        return;    willMoveToNewOwnerDocument();    updateDOMNodeDocument(this, m_document.get(), doc);    m_document = doc;    didMoveToNewOwnerDocument();}NodeRareData* Node::rareData() const{    ASSERT(hasRareData());    return NodeRareData::rareDataFromMap(this);}NodeRareData* Node::ensureRareData(){    if (hasRareData())        return rareData();        ASSERT(!NodeRareData::rareDataMap().contains(this));    NodeRareData* data = createRareData();    NodeRareData::rareDataMap().set(this, data);    m_hasRareData = true;    return data;}    NodeRareData* Node::createRareData()

⌨️ 快捷键说明

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