OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "core/dom/Element.h" | 35 #include "core/dom/Element.h" |
36 #include "core/dom/NodeTraversal.h" | 36 #include "core/dom/NodeTraversal.h" |
37 #include "core/dom/TreeScope.h" | 37 #include "core/dom/TreeScope.h" |
38 #include "core/html/HTMLLabelElement.h" | 38 #include "core/html/HTMLLabelElement.h" |
39 #include "core/html/HTMLMapElement.h" | 39 #include "core/html/HTMLMapElement.h" |
40 | 40 |
41 namespace WebCore { | 41 namespace WebCore { |
42 | 42 |
43 using namespace HTMLNames; | 43 using namespace HTMLNames; |
44 | 44 |
45 inline bool keyMatchesId(AtomicStringImpl* key, Element* element) | 45 inline bool keyMatchesId(StringImpl* key, Element* element) |
46 { | 46 { |
47 return element->getIdAttribute().impl() == key; | 47 return element->getIdAttribute().impl() == key; |
48 } | 48 } |
49 | 49 |
50 inline bool keyMatchesMapName(AtomicStringImpl* key, Element* element) | 50 inline bool keyMatchesMapName(StringImpl* key, Element* element) |
51 { | 51 { |
52 return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().i
mpl() == key; | 52 return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().i
mpl() == key; |
53 } | 53 } |
54 | 54 |
55 inline bool keyMatchesLowercasedMapName(AtomicStringImpl* key, Element* element) | 55 inline bool keyMatchesLowercasedMapName(StringImpl* key, Element* element) |
56 { | 56 { |
57 return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().l
ower().impl() == key; | 57 return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().l
ower().impl() == key; |
58 } | 58 } |
59 | 59 |
60 inline bool keyMatchesLabelForAttribute(AtomicStringImpl* key, Element* element) | 60 inline bool keyMatchesLabelForAttribute(StringImpl* key, Element* element) |
61 { | 61 { |
62 return isHTMLLabelElement(element) && element->getAttribute(forAttr).impl()
== key; | 62 return isHTMLLabelElement(element) && element->getAttribute(forAttr).impl()
== key; |
63 } | 63 } |
64 | 64 |
65 void DocumentOrderedMap::clear() | 65 void DocumentOrderedMap::clear() |
66 { | 66 { |
67 m_map.clear(); | 67 m_map.clear(); |
68 m_duplicateCounts.clear(); | 68 m_duplicateCounts.clear(); |
69 } | 69 } |
70 | 70 |
71 void DocumentOrderedMap::add(AtomicStringImpl* key, Element* element) | 71 void DocumentOrderedMap::add(StringImpl* key, Element* element) |
72 { | 72 { |
73 ASSERT(key); | 73 ASSERT(key); |
74 ASSERT(element); | 74 ASSERT(element); |
75 | 75 |
76 if (!m_duplicateCounts.contains(key)) { | 76 if (!m_duplicateCounts.contains(key)) { |
77 // Fast path. The key is not already in m_duplicateCounts, so we assume
that it's | 77 // Fast path. The key is not already in m_duplicateCounts, so we assume
that it's |
78 // also not already in m_map and try to add it. If that add succeeds, we
're done. | 78 // also not already in m_map and try to add it. If that add succeeds, we
're done. |
79 Map::AddResult addResult = m_map.add(key, element); | 79 Map::AddResult addResult = m_map.add(key, element); |
80 if (addResult.isNewEntry) | 80 if (addResult.isNewEntry) |
81 return; | 81 return; |
82 | 82 |
83 // The add failed, so this key was already cached in m_map. | 83 // The add failed, so this key was already cached in m_map. |
84 // There are multiple elements with this key. Remove the m_map | 84 // There are multiple elements with this key. Remove the m_map |
85 // cache for this key so get searches for it next time it is called. | 85 // cache for this key so get searches for it next time it is called. |
86 m_map.remove(addResult.iterator); | 86 m_map.remove(addResult.iterator); |
87 m_duplicateCounts.add(key); | 87 m_duplicateCounts.add(key); |
88 } else { | 88 } else { |
89 // There are multiple elements with this key. Remove the m_map | 89 // There are multiple elements with this key. Remove the m_map |
90 // cache for this key so get will search for it next time it is called. | 90 // cache for this key so get will search for it next time it is called. |
91 Map::iterator cachedItem = m_map.find(key); | 91 Map::iterator cachedItem = m_map.find(key); |
92 if (cachedItem != m_map.end()) { | 92 if (cachedItem != m_map.end()) { |
93 m_map.remove(cachedItem); | 93 m_map.remove(cachedItem); |
94 m_duplicateCounts.add(key); | 94 m_duplicateCounts.add(key); |
95 } | 95 } |
96 } | 96 } |
97 | 97 |
98 m_duplicateCounts.add(key); | 98 m_duplicateCounts.add(key); |
99 } | 99 } |
100 | 100 |
101 void DocumentOrderedMap::remove(AtomicStringImpl* key, Element* element) | 101 void DocumentOrderedMap::remove(StringImpl* key, Element* element) |
102 { | 102 { |
103 ASSERT(key); | 103 ASSERT(key); |
104 ASSERT(element); | 104 ASSERT(element); |
105 | 105 |
106 m_map.checkConsistency(); | 106 m_map.checkConsistency(); |
107 Map::iterator cachedItem = m_map.find(key); | 107 Map::iterator cachedItem = m_map.find(key); |
108 if (cachedItem != m_map.end() && cachedItem->value == element) | 108 if (cachedItem != m_map.end() && cachedItem->value == element) |
109 m_map.remove(cachedItem); | 109 m_map.remove(cachedItem); |
110 else | 110 else |
111 m_duplicateCounts.remove(key); | 111 m_duplicateCounts.remove(key); |
112 } | 112 } |
113 | 113 |
114 template<bool keyMatches(AtomicStringImpl*, Element*)> | 114 template<bool keyMatches(StringImpl*, Element*)> |
115 inline Element* DocumentOrderedMap::get(AtomicStringImpl* key, const TreeScope*
scope) const | 115 inline Element* DocumentOrderedMap::get(StringImpl* key, const TreeScope* scope)
const |
116 { | 116 { |
117 ASSERT(key); | 117 ASSERT(key); |
118 ASSERT(scope); | 118 ASSERT(scope); |
119 | 119 |
120 m_map.checkConsistency(); | 120 m_map.checkConsistency(); |
121 | 121 |
122 Element* element = m_map.get(key); | 122 Element* element = m_map.get(key); |
123 if (element) | 123 if (element) |
124 return element; | 124 return element; |
125 | 125 |
126 if (m_duplicateCounts.contains(key)) { | 126 if (m_duplicateCounts.contains(key)) { |
127 // We know there's at least one node that matches; iterate to find the f
irst one. | 127 // We know there's at least one node that matches; iterate to find the f
irst one. |
128 for (element = ElementTraversal::firstWithin(scope->rootNode()); element
; element = ElementTraversal::next(element)) { | 128 for (element = ElementTraversal::firstWithin(scope->rootNode()); element
; element = ElementTraversal::next(element)) { |
129 if (!keyMatches(key, element)) | 129 if (!keyMatches(key, element)) |
130 continue; | 130 continue; |
131 m_duplicateCounts.remove(key); | 131 m_duplicateCounts.remove(key); |
132 m_map.set(key, element); | 132 m_map.set(key, element); |
133 return element; | 133 return element; |
134 } | 134 } |
135 ASSERT_NOT_REACHED(); | 135 ASSERT_NOT_REACHED(); |
136 } | 136 } |
137 | 137 |
138 return 0; | 138 return 0; |
139 } | 139 } |
140 | 140 |
141 Element* DocumentOrderedMap::getElementById(AtomicStringImpl* key, const TreeSco
pe* scope) const | 141 Element* DocumentOrderedMap::getElementById(StringImpl* key, const TreeScope* sc
ope) const |
142 { | 142 { |
143 return get<keyMatchesId>(key, scope); | 143 return get<keyMatchesId>(key, scope); |
144 } | 144 } |
145 | 145 |
146 Element* DocumentOrderedMap::getElementByMapName(AtomicStringImpl* key, const Tr
eeScope* scope) const | 146 Element* DocumentOrderedMap::getElementByMapName(StringImpl* key, const TreeScop
e* scope) const |
147 { | 147 { |
148 return get<keyMatchesMapName>(key, scope); | 148 return get<keyMatchesMapName>(key, scope); |
149 } | 149 } |
150 | 150 |
151 Element* DocumentOrderedMap::getElementByLowercasedMapName(AtomicStringImpl* key
, const TreeScope* scope) const | 151 Element* DocumentOrderedMap::getElementByLowercasedMapName(StringImpl* key, cons
t TreeScope* scope) const |
152 { | 152 { |
153 return get<keyMatchesLowercasedMapName>(key, scope); | 153 return get<keyMatchesLowercasedMapName>(key, scope); |
154 } | 154 } |
155 | 155 |
156 Element* DocumentOrderedMap::getElementByLabelForAttribute(AtomicStringImpl* key
, const TreeScope* scope) const | 156 Element* DocumentOrderedMap::getElementByLabelForAttribute(StringImpl* key, cons
t TreeScope* scope) const |
157 { | 157 { |
158 return get<keyMatchesLabelForAttribute>(key, scope); | 158 return get<keyMatchesLabelForAttribute>(key, scope); |
159 } | 159 } |
160 | 160 |
161 } // namespace WebCore | 161 } // namespace WebCore |
OLD | NEW |