| 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 |