Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: Source/WebCore/dom/Node.cpp

Issue 10695128: Merge 120979 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1180/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/WebCore/dom/Node.h ('k') | Source/WebCore/dom/NodeRareData.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved.
6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 return; 973 return;
974 974
975 for (Node* node = this; node; node = node->parentNode()) { 975 for (Node* node = this; node; node = node->parentNode()) {
976 ASSERT(this == node || !node->isAttributeNode()); 976 ASSERT(this == node || !node->isAttributeNode());
977 if (!node->hasRareData()) 977 if (!node->hasRareData())
978 continue; 978 continue;
979 NodeRareData* data = node->rareData(); 979 NodeRareData* data = node->rareData();
980 if (!data->nodeLists()) 980 if (!data->nodeLists())
981 continue; 981 continue;
982 982
983 data->nodeLists()->invalidateCachesThatDependOnAttributes(); 983 data->nodeLists()->invalidateCaches(&attrName);
984 } 984 }
985 } 985 }
986 986
987 void Node::invalidateNodeListsCacheAfterChildrenChanged() 987 void Node::invalidateNodeListsCacheAfterChildrenChanged()
988 { 988 {
989 if (hasRareData()) 989 if (hasRareData())
990 rareData()->clearChildNodeListCache(); 990 rareData()->clearChildNodeListCache();
991 991
992 document()->clearNodeListCaches(); 992 document()->clearNodeListCaches();
993 993
994 if (!treeScope()->hasNodeListCaches()) 994 if (!treeScope()->hasNodeListCaches())
995 return; 995 return;
996 996
997 for (Node* node = this; node; node = node->parentNode()) { 997 for (Node* node = this; node; node = node->parentNode()) {
998 if (!node->hasRareData()) 998 if (!node->hasRareData())
999 continue; 999 continue;
1000 NodeRareData* data = node->rareData(); 1000 NodeRareData* data = node->rareData();
1001 if (!data->nodeLists()) 1001 if (!data->nodeLists())
1002 continue; 1002 continue;
1003 1003
1004 data->nodeLists()->invalidateCaches(); 1004 data->nodeLists()->invalidateCaches();
1005 } 1005 }
1006 } 1006 }
1007 1007
1008 void Node::removeCachedClassNodeList(ClassNodeList* list, const String& classNam e) 1008 NodeListsNodeData* Node::nodeLists()
1009 { 1009 {
1010 ASSERT(rareData()); 1010 return hasRareData() ? rareData()->nodeLists() : 0;
1011 ASSERT(rareData()->nodeLists());
1012
1013 NodeListsNodeData* data = rareData()->nodeLists();
1014 ASSERT_UNUSED(list, list == data->m_classNodeListCache.get(className));
1015 data->m_classNodeListCache.remove(className);
1016 }
1017
1018 void Node::removeCachedNameNodeList(NameNodeList* list, const String& nodeName)
1019 {
1020 ASSERT(rareData());
1021 ASSERT(rareData()->nodeLists());
1022
1023 NodeListsNodeData* data = rareData()->nodeLists();
1024 ASSERT_UNUSED(list, list == data->m_nameNodeListCache.get(nodeName));
1025 data->m_nameNodeListCache.remove(nodeName);
1026 }
1027
1028 void Node::removeCachedTagNodeList(TagNodeList* list, const AtomicString& name)
1029 {
1030 ASSERT(rareData());
1031 ASSERT(rareData()->nodeLists());
1032
1033 NodeListsNodeData* data = rareData()->nodeLists();
1034 ASSERT_UNUSED(list, list == data->m_tagNodeListCache.get(name.impl()));
1035 data->m_tagNodeListCache.remove(name.impl());
1036 }
1037
1038 void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)
1039 {
1040 ASSERT(rareData());
1041 ASSERT(rareData()->nodeLists());
1042
1043 NodeListsNodeData* data = rareData()->nodeLists();
1044 ASSERT_UNUSED(list, list == data->m_tagNodeListCacheNS.get(name.impl()));
1045 data->m_tagNodeListCacheNS.remove(name.impl());
1046 }
1047
1048 void Node::removeCachedLabelsNodeList(DynamicSubtreeNodeList* list)
1049 {
1050 ASSERT(rareData());
1051 ASSERT(rareData()->nodeLists());
1052
1053 NodeListsNodeData* data = rareData()->nodeLists();
1054 ASSERT_UNUSED(list, list == data->m_labelsNodeListCache);
1055 data->m_labelsNodeListCache = 0;
1056 } 1011 }
1057 1012
1058 void Node::removeCachedChildNodeList() 1013 void Node::removeCachedChildNodeList()
1059 { 1014 {
1060 ASSERT(rareData()); 1015 ASSERT(rareData());
1061 rareData()->setChildNodeList(0); 1016 rareData()->setChildNodeList(0);
1062 } 1017 }
1063 1018
1064 Node* Node::traverseNextAncestorSibling() const 1019 Node* Node::traverseNextAncestorSibling() const
1065 { 1020 {
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : f alse; 1540 return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : f alse;
1586 } 1541 }
1587 1542
1588 // FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node. 1543 // FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node.
1589 1544
1590 PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& localName) 1545 PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& localName)
1591 { 1546 {
1592 if (localName.isNull()) 1547 if (localName.isNull())
1593 return 0; 1548 return 0;
1594 1549
1595 AtomicString localNameAtom = localName;
1596
1597 NodeListsNodeData::TagNodeListCache::AddResult result = ensureRareData()->en sureNodeLists(this)->m_tagNodeListCache.add(localNameAtom, 0);
1598 if (!result.isNewEntry)
1599 return PassRefPtr<TagNodeList>(result.iterator->second);
1600
1601 RefPtr<TagNodeList> list;
1602 if (document()->isHTMLDocument()) 1550 if (document()->isHTMLDocument())
1603 list = HTMLTagNodeList::create(this, starAtom, localNameAtom); 1551 return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<H TMLTagNodeList>(this, DynamicNodeList::TagNodeListType, localName);
1604 else 1552 return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<TagNo deList>(this, DynamicNodeList::TagNodeListType, localName);
1605 list = TagNodeList::create(this, starAtom, localNameAtom);
1606 result.iterator->second = list.get();
1607 return list.release();
1608 } 1553 }
1609 1554
1610 PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceU RI, const AtomicString& localName) 1555 PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceU RI, const AtomicString& localName)
1611 { 1556 {
1612 if (localName.isNull()) 1557 if (localName.isNull())
1613 return 0; 1558 return 0;
1614 1559
1615 if (namespaceURI == starAtom) 1560 if (namespaceURI == starAtom)
1616 return getElementsByTagName(localName); 1561 return getElementsByTagName(localName);
1617 1562
1618 AtomicString localNameAtom = localName; 1563 return ensureRareData()->ensureNodeLists(this)->addCacheWithQualifiedName(th is, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
1619
1620 NodeListsNodeData::TagNodeListCacheNS::AddResult result
1621 = ensureRareData()->ensureNodeLists(this)->m_tagNodeListCacheNS.add(Qual ifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0);
1622 if (!result.isNewEntry)
1623 return PassRefPtr<TagNodeList>(result.iterator->second);
1624
1625 RefPtr<TagNodeList> list = TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom);
1626 result.iterator->second = list.get();
1627 return list.release();
1628 } 1564 }
1629 1565
1630 PassRefPtr<NodeList> Node::getElementsByName(const String& elementName) 1566 PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
1631 { 1567 {
1632 NodeListsNodeData::NameNodeListCache::AddResult result = ensureRareData()->e nsureNodeLists(this)->m_nameNodeListCache.add(elementName, 0); 1568 return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<NameN odeList>(this, DynamicNodeList::NameNodeListType, elementName);
1633 if (!result.isNewEntry)
1634 return PassRefPtr<NodeList>(result.iterator->second);
1635
1636 RefPtr<NameNodeList> list = NameNodeList::create(this, elementName);
1637 result.iterator->second = list.get();
1638 return list.release();
1639 } 1569 }
1640 1570
1641 PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames) 1571 PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
1642 { 1572 {
1643 NodeListsNodeData::ClassNodeListCache::AddResult result 1573 return ensureRareData()->ensureNodeLists(this)->addCacheWithName<ClassNodeLi st>(this, DynamicNodeList::ClassNodeListType, classNames);
1644 = ensureRareData()->ensureNodeLists(this)->m_classNodeListCache.add(clas sNames, 0); 1574 }
1645 if (!result.isNewEntry)
1646 return PassRefPtr<NodeList>(result.iterator->second);
1647 1575
1648 RefPtr<ClassNodeList> list = ClassNodeList::create(this, classNames); 1576 PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
1649 result.iterator->second = list.get(); 1577 {
1650 return list.release(); 1578 ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
1579 return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<Radio NodeList>(this, DynamicNodeList::RadioNodeListType, name);
1651 } 1580 }
1652 1581
1653 PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, Exception Code& ec) 1582 PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, Exception Code& ec)
1654 { 1583 {
1655 if (selectors.isEmpty()) { 1584 if (selectors.isEmpty()) {
1656 ec = SYNTAX_ERR; 1585 ec = SYNTAX_ERR;
1657 return 0; 1586 return 0;
1658 } 1587 }
1659 1588
1660 SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selecto rs, document(), ec); 1589 SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selecto rs, document(), ec);
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 Node* rootNode = const_cast<Node*>(this); 2231 Node* rootNode = const_cast<Node*>(this);
2303 while (parentOrHostOrFrameOwner(rootNode)) 2232 while (parentOrHostOrFrameOwner(rootNode))
2304 rootNode = parentOrHostOrFrameOwner(rootNode); 2233 rootNode = parentOrHostOrFrameOwner(rootNode);
2305 showSubTreeAcrossFrame(rootNode, this, ""); 2234 showSubTreeAcrossFrame(rootNode, this, "");
2306 } 2235 }
2307 2236
2308 #endif 2237 #endif
2309 2238
2310 // -------- 2239 // --------
2311 2240
2312 void NodeListsNodeData::invalidateCaches() 2241 void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
2313 { 2242 {
2314 TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end(); 2243 NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicName Caches.end();
2315 for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it) 2244 for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begi n(); it != atomicNameCacheEnd; ++it) {
2245 if (!attrName || it->second->shouldInvalidateOnAttributeChange())
2246 it->second->invalidateCache();
2247 }
2248
2249 NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
2250 for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != n ameCacheEnd; ++it) {
2251 if (!attrName || it->second->shouldInvalidateOnAttributeChange())
2252 it->second->invalidateCache();
2253 }
2254
2255 if (!attrName)
2256 return;
2257
2258 TagNodeListCacheNS::iterator tagCacheEnd = m_tagNodeListCacheNS.end();
2259 for (TagNodeListCacheNS::iterator it = m_tagNodeListCacheNS.begin(); it != t agCacheEnd; ++it)
2316 it->second->invalidateCache(); 2260 it->second->invalidateCache();
2317 TagNodeListCacheNS::const_iterator tagCacheNSEnd = m_tagNodeListCacheNS.end( );
2318 for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); i t != tagCacheNSEnd; ++it)
2319 it->second->invalidateCache();
2320 invalidateCachesThatDependOnAttributes();
2321 }
2322
2323 void NodeListsNodeData::invalidateCachesThatDependOnAttributes()
2324 {
2325 ClassNodeListCache::iterator classCacheEnd = m_classNodeListCache.end();
2326 for (ClassNodeListCache::iterator it = m_classNodeListCache.begin(); it != c lassCacheEnd; ++it)
2327 it->second->invalidateCache();
2328
2329 NameNodeListCache::iterator nameCacheEnd = m_nameNodeListCache.end();
2330 for (NameNodeListCache::iterator it = m_nameNodeListCache.begin(); it != nam eCacheEnd; ++it)
2331 it->second->invalidateCache();
2332 if (m_labelsNodeListCache)
2333 m_labelsNodeListCache->invalidateCache();
2334
2335 #if ENABLE(MICRODATA)
2336 MicroDataItemListCache::iterator itemListCacheEnd = m_microDataItemListCache .end();
2337 for (MicroDataItemListCache::iterator it = m_microDataItemListCache.begin(); it != itemListCacheEnd; ++it)
2338 it->second->invalidateCache();
2339 #endif
2340 }
2341
2342 bool NodeListsNodeData::isEmpty() const
2343 {
2344 if (!m_tagNodeListCache.isEmpty())
2345 return false;
2346 if (!m_tagNodeListCacheNS.isEmpty())
2347 return false;
2348 if (!m_classNodeListCache.isEmpty())
2349 return false;
2350 if (!m_nameNodeListCache.isEmpty())
2351 return false;
2352 #if ENABLE(MICRODATA)
2353 if (!m_microDataItemListCache.isEmpty())
2354 return false;
2355 #endif
2356
2357 if (m_labelsNodeListCache)
2358 return false;
2359
2360 if (!m_radioNodeListCache.isEmpty())
2361 return false;
2362
2363 return true;
2364 } 2261 }
2365 2262
2366 void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const 2263 void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const
2367 { 2264 {
2368 addSubresourceAttributeURLs(urls); 2265 addSubresourceAttributeURLs(urls);
2369 } 2266 }
2370 2267
2371 Node* Node::enclosingLinkEventParentOrSelf() 2268 Node* Node::enclosingLinkEventParentOrSelf()
2372 { 2269 {
2373 for (Node* node = this; node; node = node->parentOrHostNode()) { 2270 for (Node* node = this; node; node = node->parentOrHostNode()) {
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
2864 if (TreeScope* treeScope = node->treeScope()) 2761 if (TreeScope* treeScope = node->treeScope())
2865 treeScope->addNodeListCache(); 2762 treeScope->addNodeListCache();
2866 } 2763 }
2867 2764
2868 void NodeRareData::clearChildNodeListCache() 2765 void NodeRareData::clearChildNodeListCache()
2869 { 2766 {
2870 if (m_childNodeList) 2767 if (m_childNodeList)
2871 m_childNodeList->invalidateCache(); 2768 m_childNodeList->invalidateCache();
2872 } 2769 }
2873 2770
2874 PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
2875 {
2876 ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
2877
2878 NodeListsNodeData* nodeLists = ensureRareData()->ensureNodeLists(this);
2879
2880 NodeListsNodeData::RadioNodeListCache::AddResult result = nodeLists->m_radio NodeListCache.add(name, 0);
2881 if (!result.isNewEntry)
2882 return PassRefPtr<RadioNodeList>(result.iterator->second);
2883
2884 RefPtr<RadioNodeList> list = RadioNodeList::create(toElement(this), name);
2885 result.iterator->second = list.get();
2886 return list.release();
2887 }
2888
2889 void Node::removeCachedRadioNodeList(RadioNodeList* list, const AtomicString& na me)
2890 {
2891 ASSERT(rareData());
2892 ASSERT(rareData()->nodeLists());
2893
2894 NodeListsNodeData* data = rareData()->nodeLists();
2895 ASSERT_UNUSED(list, list == data->m_radioNodeListCache.get(name));
2896 data->m_radioNodeListCache.remove(name);
2897 }
2898
2899 // It's important not to inline removedLastRef, because we don't want to inline the code to 2771 // It's important not to inline removedLastRef, because we don't want to inline the code to
2900 // delete a Node at each deref call site. 2772 // delete a Node at each deref call site.
2901 void Node::removedLastRef() 2773 void Node::removedLastRef()
2902 { 2774 {
2903 // An explicit check for Document here is better than a virtual function sin ce it is 2775 // An explicit check for Document here is better than a virtual function sin ce it is
2904 // faster for non-Document nodes, and because the call to removedLastRef tha t is inlined 2776 // faster for non-Document nodes, and because the call to removedLastRef tha t is inlined
2905 // at all deref call sites is smaller if it's a non-virtual function. 2777 // at all deref call sites is smaller if it's a non-virtual function.
2906 if (isDocumentNode()) { 2778 if (isDocumentNode()) {
2907 static_cast<Document*>(this)->removedLastRef(); 2779 static_cast<Document*>(this)->removedLastRef();
2908 return; 2780 return;
(...skipping 14 matching lines...) Expand all
2923 node->showTreeForThis(); 2795 node->showTreeForThis();
2924 } 2796 }
2925 2797
2926 void showNodePath(const WebCore::Node* node) 2798 void showNodePath(const WebCore::Node* node)
2927 { 2799 {
2928 if (node) 2800 if (node)
2929 node->showNodePathForThis(); 2801 node->showNodePathForThis();
2930 } 2802 }
2931 2803
2932 #endif 2804 #endif
OLDNEW
« no previous file with comments | « Source/WebCore/dom/Node.h ('k') | Source/WebCore/dom/NodeRareData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698