| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 RawPtr<DocumentOrderedMap> DocumentOrderedMap::create() | 44 RawPtr<DocumentOrderedMap> DocumentOrderedMap::create() |
| 45 { | 45 { |
| 46 return new DocumentOrderedMap; | 46 return new DocumentOrderedMap; |
| 47 } | 47 } |
| 48 | 48 |
| 49 DocumentOrderedMap::DocumentOrderedMap() | 49 DocumentOrderedMap::DocumentOrderedMap() |
| 50 { | 50 { |
| 51 } | 51 } |
| 52 | 52 |
| 53 #if ENABLE(ASSERT) | 53 #if DCHECK_IS_ON() |
| 54 static int s_removeScopeLevel = 0; | 54 static int s_removeScopeLevel = 0; |
| 55 | 55 |
| 56 DocumentOrderedMap::RemoveScope::RemoveScope() | 56 DocumentOrderedMap::RemoveScope::RemoveScope() |
| 57 { | 57 { |
| 58 s_removeScopeLevel++; | 58 s_removeScopeLevel++; |
| 59 } | 59 } |
| 60 | 60 |
| 61 DocumentOrderedMap::RemoveScope::~RemoveScope() | 61 DocumentOrderedMap::RemoveScope::~RemoveScope() |
| 62 { | 62 { |
| 63 ASSERT(s_removeScopeLevel); | 63 DCHECK(s_removeScopeLevel); |
| 64 s_removeScopeLevel--; | 64 s_removeScopeLevel--; |
| 65 } | 65 } |
| 66 #endif | 66 #endif |
| 67 | 67 |
| 68 inline bool keyMatchesId(const AtomicString& key, const Element& element) | 68 inline bool keyMatchesId(const AtomicString& key, const Element& element) |
| 69 { | 69 { |
| 70 return element.getIdAttribute() == key; | 70 return element.getIdAttribute() == key; |
| 71 } | 71 } |
| 72 | 72 |
| 73 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) | 73 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) |
| 74 { | 74 { |
| 75 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k
ey; | 75 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k
ey; |
| 76 } | 76 } |
| 77 | 77 |
| 78 inline bool keyMatchesLowercasedMapName(const AtomicString& key, const Element&
element) | 78 inline bool keyMatchesLowercasedMapName(const AtomicString& key, const Element&
element) |
| 79 { | 79 { |
| 80 return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lowe
r() == key; | 80 return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lowe
r() == key; |
| 81 } | 81 } |
| 82 | 82 |
| 83 inline bool keyMatchesLabelForAttribute(const AtomicString& key, const Element&
element) | 83 inline bool keyMatchesLabelForAttribute(const AtomicString& key, const Element&
element) |
| 84 { | 84 { |
| 85 return isHTMLLabelElement(element) && element.getAttribute(forAttr) == key; | 85 return isHTMLLabelElement(element) && element.getAttribute(forAttr) == key; |
| 86 } | 86 } |
| 87 | 87 |
| 88 void DocumentOrderedMap::add(const AtomicString& key, Element* element) | 88 void DocumentOrderedMap::add(const AtomicString& key, Element* element) |
| 89 { | 89 { |
| 90 ASSERT(key); | 90 DCHECK(key); |
| 91 ASSERT(element); | 91 DCHECK(element); |
| 92 | 92 |
| 93 Map::AddResult addResult = m_map.add(key, new MapEntry(element)); | 93 Map::AddResult addResult = m_map.add(key, new MapEntry(element)); |
| 94 if (addResult.isNewEntry) | 94 if (addResult.isNewEntry) |
| 95 return; | 95 return; |
| 96 | 96 |
| 97 Member<MapEntry>& entry = addResult.storedValue->value; | 97 Member<MapEntry>& entry = addResult.storedValue->value; |
| 98 ASSERT(entry->count); | 98 DCHECK(entry->count); |
| 99 entry->element = nullptr; | 99 entry->element = nullptr; |
| 100 entry->count++; | 100 entry->count++; |
| 101 entry->orderedList.clear(); | 101 entry->orderedList.clear(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 void DocumentOrderedMap::remove(const AtomicString& key, Element* element) | 104 void DocumentOrderedMap::remove(const AtomicString& key, Element* element) |
| 105 { | 105 { |
| 106 ASSERT(key); | 106 DCHECK(key); |
| 107 ASSERT(element); | 107 DCHECK(element); |
| 108 | 108 |
| 109 Map::iterator it = m_map.find(key); | 109 Map::iterator it = m_map.find(key); |
| 110 if (it == m_map.end()) | 110 if (it == m_map.end()) |
| 111 return; | 111 return; |
| 112 | 112 |
| 113 Member<MapEntry>& entry = it->value; | 113 Member<MapEntry>& entry = it->value; |
| 114 ASSERT(entry->count); | 114 DCHECK(entry->count); |
| 115 if (entry->count == 1) { | 115 if (entry->count == 1) { |
| 116 ASSERT(!entry->element || entry->element == element); | 116 DCHECK(!entry->element || entry->element == element); |
| 117 m_map.remove(it); | 117 m_map.remove(it); |
| 118 } else { | 118 } else { |
| 119 if (entry->element == element) { | 119 if (entry->element == element) { |
| 120 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() ==
element); | 120 DCHECK(entry->orderedList.isEmpty() || entry->orderedList.first() ==
element); |
| 121 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[
1] : nullptr; | 121 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[
1] : nullptr; |
| 122 } | 122 } |
| 123 entry->count--; | 123 entry->count--; |
| 124 entry->orderedList.clear(); | 124 entry->orderedList.clear(); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 template<bool keyMatches(const AtomicString&, const Element&)> | 128 template<bool keyMatches(const AtomicString&, const Element&)> |
| 129 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope
* scope) const | 129 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope
* scope) const |
| 130 { | 130 { |
| 131 ASSERT(key); | 131 DCHECK(key); |
| 132 ASSERT(scope); | 132 DCHECK(scope); |
| 133 | 133 |
| 134 MapEntry* entry = m_map.get(key); | 134 MapEntry* entry = m_map.get(key); |
| 135 if (!entry) | 135 if (!entry) |
| 136 return 0; | 136 return 0; |
| 137 | 137 |
| 138 ASSERT(entry->count); | 138 DCHECK(entry->count); |
| 139 if (entry->element) | 139 if (entry->element) |
| 140 return entry->element; | 140 return entry->element; |
| 141 | 141 |
| 142 // Iterate to find the node that matches. Nothing will match iff an element | 142 // Iterate to find the node that matches. Nothing will match iff an element |
| 143 // with children having duplicate IDs is being removed -- the tree traversal | 143 // with children having duplicate IDs is being removed -- the tree traversal |
| 144 // will be over an updated tree not having that subtree. In all other cases, | 144 // will be over an updated tree not having that subtree. In all other cases, |
| 145 // a match is expected. | 145 // a match is expected. |
| 146 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { | 146 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { |
| 147 if (!keyMatches(key, element)) | 147 if (!keyMatches(key, element)) |
| 148 continue; | 148 continue; |
| 149 entry->element = &element; | 149 entry->element = &element; |
| 150 return &element; | 150 return &element; |
| 151 } | 151 } |
| 152 // As get()/getElementById() can legitimately be called while handling eleme
nt | 152 // As get()/getElementById() can legitimately be called while handling eleme
nt |
| 153 // removals, allow failure iff we're in the scope of node removals. | 153 // removals, allow failure iff we're in the scope of node removals. |
| 154 ASSERT(s_removeScopeLevel); | 154 #if DCHECK_IS_ON() |
| 155 DCHECK(s_removeScopeLevel); |
| 156 #endif |
| 155 return 0; | 157 return 0; |
| 156 } | 158 } |
| 157 | 159 |
| 158 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS
cope* scope) const | 160 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS
cope* scope) const |
| 159 { | 161 { |
| 160 return get<keyMatchesId>(key, scope); | 162 return get<keyMatchesId>(key, scope); |
| 161 } | 163 } |
| 162 | 164 |
| 163 const HeapVector<Member<Element>>& DocumentOrderedMap::getAllElementsById(const
AtomicString& key, const TreeScope* scope) const | 165 const HeapVector<Member<Element>>& DocumentOrderedMap::getAllElementsById(const
AtomicString& key, const TreeScope* scope) const |
| 164 { | 166 { |
| 165 ASSERT(key); | 167 DCHECK(key); |
| 166 ASSERT(scope); | 168 DCHECK(scope); |
| 167 DEFINE_STATIC_LOCAL(HeapVector<Member<Element>>, emptyVector, (new HeapVecto
r<Member<Element>>)); | 169 DEFINE_STATIC_LOCAL(HeapVector<Member<Element>>, emptyVector, (new HeapVecto
r<Member<Element>>)); |
| 168 | 170 |
| 169 Map::iterator it = m_map.find(key); | 171 Map::iterator it = m_map.find(key); |
| 170 if (it == m_map.end()) | 172 if (it == m_map.end()) |
| 171 return emptyVector; | 173 return emptyVector; |
| 172 | 174 |
| 173 Member<MapEntry>& entry = it->value; | 175 Member<MapEntry>& entry = it->value; |
| 174 ASSERT(entry->count); | 176 DCHECK(entry->count); |
| 175 | 177 |
| 176 if (entry->orderedList.isEmpty()) { | 178 if (entry->orderedList.isEmpty()) { |
| 177 entry->orderedList.reserveCapacity(entry->count); | 179 entry->orderedList.reserveCapacity(entry->count); |
| 178 for (Element* element = entry->element ? entry->element.get() : ElementT
raversal::firstWithin(scope->rootNode()); entry->orderedList.size() < entry->cou
nt; element = ElementTraversal::next(*element)) { | 180 for (Element* element = entry->element ? entry->element.get() : ElementT
raversal::firstWithin(scope->rootNode()); entry->orderedList.size() < entry->cou
nt; element = ElementTraversal::next(*element)) { |
| 179 ASSERT(element); | 181 DCHECK(element); |
| 180 if (!keyMatchesId(key, *element)) | 182 if (!keyMatchesId(key, *element)) |
| 181 continue; | 183 continue; |
| 182 entry->orderedList.uncheckedAppend(element); | 184 entry->orderedList.uncheckedAppend(element); |
| 183 } | 185 } |
| 184 if (!entry->element) | 186 if (!entry->element) |
| 185 entry->element = entry->orderedList.first(); | 187 entry->element = entry->orderedList.first(); |
| 186 } | 188 } |
| 187 | 189 |
| 188 return entry->orderedList; | 190 return entry->orderedList; |
| 189 } | 191 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 208 visitor->trace(m_map); | 210 visitor->trace(m_map); |
| 209 } | 211 } |
| 210 | 212 |
| 211 DEFINE_TRACE(DocumentOrderedMap::MapEntry) | 213 DEFINE_TRACE(DocumentOrderedMap::MapEntry) |
| 212 { | 214 { |
| 213 visitor->trace(element); | 215 visitor->trace(element); |
| 214 visitor->trace(orderedList); | 216 visitor->trace(orderedList); |
| 215 } | 217 } |
| 216 | 218 |
| 217 } // namespace blink | 219 } // namespace blink |
| OLD | NEW |