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 |