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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 inline bool keyMatchesLowercasedMapName(const AtomicString& key, const Element& element) | 54 inline bool keyMatchesLowercasedMapName(const AtomicString& key, const Element& element) |
| 55 { | 55 { |
| 56 return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lowe r() == key; | 56 return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lowe r() == key; |
| 57 } | 57 } |
| 58 | 58 |
| 59 inline bool keyMatchesLabelForAttribute(const AtomicString& key, const Element& element) | 59 inline bool keyMatchesLabelForAttribute(const AtomicString& key, const Element& element) |
| 60 { | 60 { |
| 61 return isHTMLLabelElement(element) && element.getAttribute(forAttr) == key; | 61 return isHTMLLabelElement(element) && element.getAttribute(forAttr) == key; |
| 62 } | 62 } |
| 63 | 63 |
| 64 DocumentOrderedMap::DocumentOrderedMap() | |
| 65 #if ENABLE(ASSERT) | |
| 66 : m_removingId(nullptr) | |
| 67 #endif | |
| 68 { | |
| 69 } | |
| 70 | |
| 64 PassOwnPtrWillBeRawPtr<DocumentOrderedMap> DocumentOrderedMap::create() | 71 PassOwnPtrWillBeRawPtr<DocumentOrderedMap> DocumentOrderedMap::create() |
| 65 { | 72 { |
| 66 return adoptPtrWillBeNoop(new DocumentOrderedMap()); | 73 return adoptPtrWillBeNoop(new DocumentOrderedMap); |
| 67 } | 74 } |
| 68 | 75 |
| 69 void DocumentOrderedMap::add(const AtomicString& key, Element* element) | 76 void DocumentOrderedMap::add(const AtomicString& key, Element* element) |
| 70 { | 77 { |
| 71 ASSERT(key); | 78 ASSERT(key); |
| 72 ASSERT(element); | 79 ASSERT(element); |
| 73 | 80 |
| 74 Map::AddResult addResult = m_map.add(key, adoptPtrWillBeNoop(new MapEntry(el ement))); | 81 Map::AddResult addResult = m_map.add(key, adoptPtrWillBeNoop(new MapEntry(el ement))); |
| 75 if (addResult.isNewEntry) | 82 if (addResult.isNewEntry) |
| 76 return; | 83 return; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 99 } else { | 106 } else { |
| 100 if (entry->element == element) { | 107 if (entry->element == element) { |
| 101 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element); | 108 ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element); |
| 102 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[ 1] : nullptr; | 109 entry->element = entry->orderedList.size() > 1 ? entry->orderedList[ 1] : nullptr; |
| 103 } | 110 } |
| 104 entry->count--; | 111 entry->count--; |
| 105 entry->orderedList.clear(); | 112 entry->orderedList.clear(); |
| 106 } | 113 } |
| 107 } | 114 } |
| 108 | 115 |
| 116 #if ENABLE(ASSERT) | |
| 117 void DocumentOrderedMap::willBeRemovingId(const AtomicString* key) | |
| 118 { | |
| 119 ASSERT(!m_removingId || !key); | |
| 120 m_removingId = key; | |
| 121 } | |
| 122 #endif | |
| 123 | |
| 109 template<bool keyMatches(const AtomicString&, const Element&)> | 124 template<bool keyMatches(const AtomicString&, const Element&)> |
| 110 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope * scope) const | 125 inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope * scope) const |
| 111 { | 126 { |
| 112 ASSERT(key); | 127 ASSERT(key); |
| 113 ASSERT(scope); | 128 ASSERT(scope); |
| 114 | 129 |
| 115 MapEntry* entry = m_map.get(key); | 130 MapEntry* entry = m_map.get(key); |
| 116 if (!entry) | 131 if (!entry) |
| 117 return 0; | 132 return 0; |
| 118 | 133 |
| 119 ASSERT(entry->count); | 134 ASSERT(entry->count); |
| 120 if (entry->element) | 135 if (entry->element) |
| 121 return entry->element; | 136 return entry->element; |
| 122 | 137 |
| 123 // We know there's at least one node that matches; iterate to find the first one. | 138 // Iterate to find the node that matches. Nothing will match iff an element |
| 139 // with children having duplicate IDs is being removed -- the tree traversal | |
| 140 // will be over an updated tree not having that element. In all other cases, | |
| 141 // a match is expected. | |
| 142 // | |
| 143 // Such calls to get()/getElementById() while handling element removals will | |
| 144 // legitimately happen when e.g., adjusting form ID associations. Quietly | |
| 145 // allow those lookups to (expectedly) fail by having the tree scope removal | |
| 146 // register the element ID it is in the process of removing. | |
|
esprehn
2015/12/18 00:42:26
this is bad though, it means in those cases we wal
sof
2015/12/18 07:31:53
The context is worth not losing sight of -- this i
| |
| 124 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { | 147 for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { |
| 125 if (!keyMatches(key, element)) | 148 if (!keyMatches(key, element)) |
| 126 continue; | 149 continue; |
| 127 entry->element = &element; | 150 entry->element = &element; |
| 128 return &element; | 151 return &element; |
| 129 } | 152 } |
| 130 ASSERT_NOT_REACHED(); | 153 ASSERT(m_removingId && key == *m_removingId); |
| 131 return 0; | 154 return 0; |
| 132 } | 155 } |
| 133 | 156 |
| 134 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS cope* scope) const | 157 Element* DocumentOrderedMap::getElementById(const AtomicString& key, const TreeS cope* scope) const |
| 135 { | 158 { |
| 136 return get<keyMatchesId>(key, scope); | 159 return get<keyMatchesId>(key, scope); |
| 137 } | 160 } |
| 138 | 161 |
| 139 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE lementsById(const AtomicString& key, const TreeScope* scope) const | 162 const WillBeHeapVector<RawPtrWillBeMember<Element>>& DocumentOrderedMap::getAllE lementsById(const AtomicString& key, const TreeScope* scope) const |
| 140 { | 163 { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 | 211 |
| 189 DEFINE_TRACE(DocumentOrderedMap::MapEntry) | 212 DEFINE_TRACE(DocumentOrderedMap::MapEntry) |
| 190 { | 213 { |
| 191 visitor->trace(element); | 214 visitor->trace(element); |
| 192 #if ENABLE(OILPAN) | 215 #if ENABLE(OILPAN) |
| 193 visitor->trace(orderedList); | 216 visitor->trace(orderedList); |
| 194 #endif | 217 #endif |
| 195 } | 218 } |
| 196 | 219 |
| 197 } // namespace blink | 220 } // namespace blink |
| OLD | NEW |