Chromium Code Reviews| 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 void DocumentOrderedMap::enterTreeRemoveScope() | |
|
esprehn
2016/01/05 07:48:33
no need for the methods, put the class in Document
sof
2016/01/05 07:53:37
That's what ps#1 did, but then I got worried about
| |
| 54 { | 57 { |
| 58 m_treeRemovalScopeLevel++; | |
| 55 } | 59 } |
| 56 | 60 |
| 61 void DocumentOrderedMap::leaveTreeRemoveScope() | |
| 62 { | |
| 63 ASSERT(m_treeRemovalScopeLevel); | |
| 64 m_treeRemovalScopeLevel--; | |
| 65 } | |
| 66 #endif | |
| 67 | |
| 57 inline bool keyMatchesId(const AtomicString& key, const Element& element) | 68 inline bool keyMatchesId(const AtomicString& key, const Element& element) |
| 58 { | 69 { |
| 59 return element.getIdAttribute() == key; | 70 return element.getIdAttribute() == key; |
| 60 } | 71 } |
| 61 | 72 |
| 62 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) | 73 inline bool keyMatchesMapName(const AtomicString& key, const Element& element) |
| 63 { | 74 { |
| 64 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k ey; | 75 return isHTMLMapElement(element) && toHTMLMapElement(element).getName() == k ey; |
| 65 } | 76 } |
| 66 | 77 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 } else { | 118 } else { |
| 108 if (entry->element == element) { | 119 if (entry->element == element) { |
| 109 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element); | 120 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element); |
| 110 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[ 1] : nullptr; | 121 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[ 1] : nullptr; |
| 111 } | 122 } |
| 112 entry->count--; | 123 entry->count--; |
| 113 entry->orderedList.clear(); | 124 entry->orderedList.clear(); |
| 114 } | 125 } |
| 115 } | 126 } |
| 116 | 127 |
| 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&)> | 128 template<bool keyMatches(const AtomicString&, const Element&)> |
| 126 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope * scope) const | 129 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope * scope) const |
| 127 { | 130 { |
| 128 ASSERT(key); | 131 ASSERT(key); |
| 129 ASSERT(scope); | 132 ASSERT(scope); |
| 130 | 133 |
| 131 MapEntry* entry = m_map.get(key); | 134 MapEntry* entry = m_map.get(key); |
| 132 if (!entry) | 135 if (!entry) |
| 133 return 0; | 136 return 0; |
| 134 | 137 |
| 135 ASSERT(entry->count); | 138 ASSERT(entry->count); |
| 136 if (entry->element) | 139 if (entry->element) |
| 137 return entry->element; | 140 return entry->element; |
| 138 | 141 |
| 139 // 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 |
| 140 // with children having duplicate IDs is being removed -- the tree traversal | 143 // 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, | 144 // will be over an updated tree not having that subtree. In all other cases, |
| 142 // a match is expected. | 145 // 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())) { | 146 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { |
| 149 if (!keyMatches(key, element)) | 147 if (!keyMatches(key, element)) |
| 150 continue; | 148 continue; |
| 151 entry->element = &element; | 149 entry->element = &element; |
| 152 return &element; | 150 return &element; |
| 153 } | 151 } |
| 154 ASSERT(key == m_removingId); | 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. | |
| 154 ASSERT(m_treeRemovalScopeLevel); | |
| 155 return 0; | 155 return 0; |
| 156 } | 156 } |
| 157 | 157 |
| 158 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS cope* scope) const | 158 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS cope* scope) const |
| 159 { | 159 { |
| 160 return get<keyMatchesId>(key, scope); | 160 return get<keyMatchesId>(key, scope); |
| 161 } | 161 } |
| 162 | 162 |
| 163 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE lementsById(const AtomicString& key, const TreeScope* scope) const | 163 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE lementsById(const AtomicString& key, const TreeScope* scope) const |
| 164 { | 164 { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 | 212 |
| 213 DEFINE_TRACE(DocumentOrderedMap::MapEntry) | 213 DEFINE_TRACE(DocumentOrderedMap::MapEntry) |
| 214 { | 214 { |
| 215 visitor->trace(element); | 215 visitor->trace(element); |
| 216 #if ENABLE(OILPAN) | 216 #if ENABLE(OILPAN) |
| 217 visitor->trace(orderedList); | 217 visitor->trace(orderedList); |
| 218 #endif | 218 #endif |
| 219 } | 219 } |
| 220 | 220 |
| 221 } // namespace blink | 221 } // namespace blink |
| OLD | NEW |