OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 entry->element = | 111 entry->element = |
112 entry->ordered_list.size() > 1 ? entry->ordered_list[1] : nullptr; | 112 entry->ordered_list.size() > 1 ? entry->ordered_list[1] : nullptr; |
113 } | 113 } |
114 entry->count--; | 114 entry->count--; |
115 entry->ordered_list.clear(); | 115 entry->ordered_list.clear(); |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 template <bool keyMatches(const AtomicString&, const Element&)> | 119 template <bool keyMatches(const AtomicString&, const Element&)> |
120 inline Element* DocumentOrderedMap::Get(const AtomicString& key, | 120 inline Element* DocumentOrderedMap::Get(const AtomicString& key, |
121 const TreeScope* scope) const { | 121 const TreeScope& scope) const { |
122 DCHECK(key); | 122 DCHECK(key); |
123 DCHECK(scope); | |
124 | 123 |
125 MapEntry* entry = map_.at(key); | 124 MapEntry* entry = map_.at(key); |
126 if (!entry) | 125 if (!entry) |
127 return 0; | 126 return 0; |
128 | 127 |
129 DCHECK(entry->count); | 128 DCHECK(entry->count); |
130 if (entry->element) | 129 if (entry->element) |
131 return entry->element; | 130 return entry->element; |
132 | 131 |
133 // Iterate to find the node that matches. Nothing will match iff an element | 132 // Iterate to find the node that matches. Nothing will match iff an element |
134 // with children having duplicate IDs is being removed -- the tree traversal | 133 // with children having duplicate IDs is being removed -- the tree traversal |
135 // will be over an updated tree not having that subtree. In all other cases, | 134 // will be over an updated tree not having that subtree. In all other cases, |
136 // a match is expected. | 135 // a match is expected. |
137 for (Element& element : ElementTraversal::StartsAfter(scope->RootNode())) { | 136 for (Element& element : ElementTraversal::StartsAfter(scope.RootNode())) { |
138 if (!keyMatches(key, element)) | 137 if (!keyMatches(key, element)) |
139 continue; | 138 continue; |
140 entry->element = &element; | 139 entry->element = &element; |
141 return &element; | 140 return &element; |
142 } | 141 } |
143 // As get()/getElementById() can legitimately be called while handling element | 142 // As get()/getElementById() can legitimately be called while handling element |
144 // removals, allow failure iff we're in the scope of node removals. | 143 // removals, allow failure iff we're in the scope of node removals. |
145 #if DCHECK_IS_ON() | 144 #if DCHECK_IS_ON() |
146 DCHECK(g_remove_scope_level); | 145 DCHECK(g_remove_scope_level); |
147 #endif | 146 #endif |
148 return 0; | 147 return 0; |
149 } | 148 } |
150 | 149 |
151 Element* DocumentOrderedMap::GetElementById(const AtomicString& key, | 150 Element* DocumentOrderedMap::GetElementById(const AtomicString& key, |
152 const TreeScope* scope) const { | 151 const TreeScope& scope) const { |
153 return Get<KeyMatchesId>(key, scope); | 152 return Get<KeyMatchesId>(key, scope); |
154 } | 153 } |
155 | 154 |
156 const HeapVector<Member<Element>>& DocumentOrderedMap::GetAllElementsById( | 155 const HeapVector<Member<Element>>& DocumentOrderedMap::GetAllElementsById( |
157 const AtomicString& key, | 156 const AtomicString& key, |
158 const TreeScope* scope) const { | 157 const TreeScope& scope) const { |
159 DCHECK(key); | 158 DCHECK(key); |
160 DCHECK(scope); | |
161 DEFINE_STATIC_LOCAL(HeapVector<Member<Element>>, empty_vector, | 159 DEFINE_STATIC_LOCAL(HeapVector<Member<Element>>, empty_vector, |
162 (new HeapVector<Member<Element>>)); | 160 (new HeapVector<Member<Element>>)); |
163 | 161 |
164 Map::iterator it = map_.find(key); | 162 Map::iterator it = map_.find(key); |
165 if (it == map_.end()) | 163 if (it == map_.end()) |
166 return empty_vector; | 164 return empty_vector; |
167 | 165 |
168 Member<MapEntry>& entry = it->value; | 166 Member<MapEntry>& entry = it->value; |
169 DCHECK(entry->count); | 167 DCHECK(entry->count); |
170 | 168 |
171 if (entry->ordered_list.IsEmpty()) { | 169 if (entry->ordered_list.IsEmpty()) { |
172 entry->ordered_list.ReserveCapacity(entry->count); | 170 entry->ordered_list.ReserveCapacity(entry->count); |
173 for (Element* element = | 171 for (Element* element = |
174 entry->element ? entry->element.Get() | 172 entry->element ? entry->element.Get() |
175 : ElementTraversal::FirstWithin(scope->RootNode()); | 173 : ElementTraversal::FirstWithin(scope.RootNode()); |
176 entry->ordered_list.size() < entry->count; | 174 entry->ordered_list.size() < entry->count; |
177 element = ElementTraversal::Next(*element)) { | 175 element = ElementTraversal::Next(*element)) { |
178 DCHECK(element); | 176 DCHECK(element); |
179 if (!KeyMatchesId(key, *element)) | 177 if (!KeyMatchesId(key, *element)) |
180 continue; | 178 continue; |
181 entry->ordered_list.UncheckedAppend(element); | 179 entry->ordered_list.UncheckedAppend(element); |
182 } | 180 } |
183 if (!entry->element) | 181 if (!entry->element) |
184 entry->element = entry->ordered_list.front(); | 182 entry->element = entry->ordered_list.front(); |
185 } | 183 } |
186 | 184 |
187 return entry->ordered_list; | 185 return entry->ordered_list; |
188 } | 186 } |
189 | 187 |
190 Element* DocumentOrderedMap::GetElementByMapName(const AtomicString& key, | 188 Element* DocumentOrderedMap::GetElementByMapName(const AtomicString& key, |
191 const TreeScope* scope) const { | 189 const TreeScope& scope) const { |
192 return Get<KeyMatchesMapName>(key, scope); | 190 return Get<KeyMatchesMapName>(key, scope); |
193 } | 191 } |
194 | 192 |
195 // TODO(hayato): Template get<> by return type. | 193 // TODO(hayato): Template get<> by return type. |
196 HTMLSlotElement* DocumentOrderedMap::GetSlotByName( | 194 HTMLSlotElement* DocumentOrderedMap::GetSlotByName( |
197 const AtomicString& key, | 195 const AtomicString& key, |
198 const TreeScope* scope) const { | 196 const TreeScope& scope) const { |
199 if (Element* slot = Get<KeyMatchesSlotName>(key, scope)) { | 197 if (Element* slot = Get<KeyMatchesSlotName>(key, scope)) { |
200 DCHECK(isHTMLSlotElement(slot)); | 198 DCHECK(isHTMLSlotElement(slot)); |
201 return toHTMLSlotElement(slot); | 199 return toHTMLSlotElement(slot); |
202 } | 200 } |
203 return nullptr; | 201 return nullptr; |
204 } | 202 } |
205 | 203 |
206 DEFINE_TRACE(DocumentOrderedMap) { | 204 DEFINE_TRACE(DocumentOrderedMap) { |
207 visitor->Trace(map_); | 205 visitor->Trace(map_); |
208 } | 206 } |
209 | 207 |
210 DEFINE_TRACE(DocumentOrderedMap::MapEntry) { | 208 DEFINE_TRACE(DocumentOrderedMap::MapEntry) { |
211 visitor->Trace(element); | 209 visitor->Trace(element); |
212 visitor->Trace(ordered_list); | 210 visitor->Trace(ordered_list); |
213 } | 211 } |
214 | 212 |
215 } // namespace blink | 213 } // namespace blink |
OLD | NEW |