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 |