| 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 PassOwnPtrWillBeRawPtr<DocumentOrderedMap> DocumentOrderedMap::create() | 44 PassOwnPtrWillBeRawPtr<DocumentOrderedMap> DocumentOrderedMap::create() |
| 45 { | 45 { |
| 46 return adoptPtrWillBeNoop(new DocumentOrderedMap); | 46 return adoptPtrWillBeNoop(new DocumentOrderedMap); |
| 47 } | 47 } |
| 48 | 48 |
| 49 DocumentOrderedMap::DocumentOrderedMap() | 49 DocumentOrderedMap::DocumentOrderedMap() |
| 50 { | 50 { |
| 51 } | 51 } |
| 52 | 52 |
| 53 DocumentOrderedMap::~DocumentOrderedMap() | 53 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentOrderedMap); |
| 54 |
| 55 #if ENABLE(ASSERT) |
| 56 static int s_removeScopeLevel = 0; |
| 57 |
| 58 DocumentOrderedMap::RemoveScope::RemoveScope() |
| 54 { | 59 { |
| 60 s_removeScopeLevel++; |
| 55 } | 61 } |
| 56 | 62 |
| 63 DocumentOrderedMap::RemoveScope::~RemoveScope() |
| 64 { |
| 65 ASSERT(s_removeScopeLevel); |
| 66 s_removeScopeLevel--; |
| 67 } |
| 68 #endif |
| 69 |
| 57 inline bool keyMatchesId(const AtomicString& key, const Element& element) | 70 inline bool keyMatchesId(const AtomicString& key, const Element& element) |
| 58 { | 71 { |
| 59 return element.getIdAttribute() == key; | 72 return element.getIdAttribute() == key; |
| 60 } | 73 } |
| 61 | 74 |
| 62 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) | 75 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) |
| 63 { | 76 { |
| 64 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k
ey; | 77 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k
ey; |
| 65 } | 78 } |
| 66 | 79 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 } else { | 120 } else { |
| 108 if (entry->element == element) { | 121 if (entry->element == element) { |
| 109 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() ==
element); | 122 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() ==
element); |
| 110 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[
1] : nullptr; | 123 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[
1] : nullptr; |
| 111 } | 124 } |
| 112 entry->count--; | 125 entry->count--; |
| 113 entry->orderedList.clear(); | 126 entry->orderedList.clear(); |
| 114 } | 127 } |
| 115 } | 128 } |
| 116 | 129 |
| 117 #if ENABLE(ASSERT) | |
| 118 void DocumentOrderedMap::willRemoveId(const AtomicString& key) | |
| 119 { | |
| 120 ASSERT(m_removingId.isNull() || key.isNull()); | |
| 121 m_removingId = key; | |
| 122 } | |
| 123 #endif | |
| 124 | |
| 125 template<bool keyMatches(const AtomicString&, const Element&)> | 130 template<bool keyMatches(const AtomicString&, const Element&)> |
| 126 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope
* scope) const | 131 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope
* scope) const |
| 127 { | 132 { |
| 128 ASSERT(key); | 133 ASSERT(key); |
| 129 ASSERT(scope); | 134 ASSERT(scope); |
| 130 | 135 |
| 131 MapEntry* entry = m_map.get(key); | 136 MapEntry* entry = m_map.get(key); |
| 132 if (!entry) | 137 if (!entry) |
| 133 return 0; | 138 return 0; |
| 134 | 139 |
| 135 ASSERT(entry->count); | 140 ASSERT(entry->count); |
| 136 if (entry->element) | 141 if (entry->element) |
| 137 return entry->element; | 142 return entry->element; |
| 138 | 143 |
| 139 // Iterate to find the node that matches. Nothing will match iff an element | 144 // Iterate to find the node that matches. Nothing will match iff an element |
| 140 // with children having duplicate IDs is being removed -- the tree traversal | 145 // with children having duplicate IDs is being removed -- the tree traversal |
| 141 // will be over an updated tree not having that element. In all other cases, | 146 // will be over an updated tree not having that subtree. In all other cases, |
| 142 // a match is expected. | 147 // a match is expected. |
| 143 // | |
| 144 // Such calls to get()/getElementById() while handling element removals will | |
| 145 // legitimately happen when e.g., adjusting form ID associations. Quietly | |
| 146 // allow those lookups to (expectedly) fail by having the tree scope removal | |
| 147 // register the element ID it is in the process of removing. | |
| 148 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { | 148 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { |
| 149 if (!keyMatches(key, element)) | 149 if (!keyMatches(key, element)) |
| 150 continue; | 150 continue; |
| 151 entry->element = &element; | 151 entry->element = &element; |
| 152 return &element; | 152 return &element; |
| 153 } | 153 } |
| 154 ASSERT(key == m_removingId); | 154 // As get()/getElementById() can legitimately be called while handling eleme
nt |
| 155 // removals, allow failure iff we're in the scope of node removals. |
| 156 ASSERT(s_removeScopeLevel); |
| 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 WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE
lementsById(const AtomicString& key, const TreeScope* scope) const | 165 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE
lementsById(const AtomicString& key, const TreeScope* scope) const |
| 164 { | 166 { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 214 |
| 213 DEFINE_TRACE(DocumentOrderedMap::MapEntry) | 215 DEFINE_TRACE(DocumentOrderedMap::MapEntry) |
| 214 { | 216 { |
| 215 visitor->trace(element); | 217 visitor->trace(element); |
| 216 #if ENABLE(OILPAN) | 218 #if ENABLE(OILPAN) |
| 217 visitor->trace(orderedList); | 219 visitor->trace(orderedList); |
| 218 #endif | 220 #endif |
| 219 } | 221 } |
| 220 | 222 |
| 221 } // namespace blink | 223 } // namespace blink |
| OLD | NEW |