OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |