Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/WebKit/Source/core/dom/TreeScope.cpp

Issue 1555653002: Handle some failing DocumentOrderedMap ID lookups across tree removals. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add test Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All Rights Reserved. 2 * Copyright (C) 2011 Google Inc. All Rights Reserved.
3 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 179
180 void TreeScope::addElementById(const AtomicString& elementId, Element* element) 180 void TreeScope::addElementById(const AtomicString& elementId, Element* element)
181 { 181 {
182 if (!m_elementsById) 182 if (!m_elementsById)
183 m_elementsById = DocumentOrderedMap::create(); 183 m_elementsById = DocumentOrderedMap::create();
184 m_elementsById->add(elementId, element); 184 m_elementsById->add(elementId, element);
185 m_idTargetObserverRegistry->notifyObservers(elementId); 185 m_idTargetObserverRegistry->notifyObservers(elementId);
186 } 186 }
187 187
188 188
189 #if ENABLE(ASSERT)
190 namespace {
191
192 class RemovingElementIdScope {
193 STACK_ALLOCATED();
194 public:
195 RemovingElementIdScope(DocumentOrderedMap& elementsById, const AtomicString& id)
196 : m_elementsById(&elementsById)
197 {
198 m_elementsById->willRemoveId(id);
199 }
200 ~RemovingElementIdScope()
201 {
202 m_elementsById->willRemoveId(nullAtom);
203 }
204
205 private:
206 RawPtrWillBeMember<DocumentOrderedMap> m_elementsById;
207 };
208
209 }
210 #endif
211
212 void TreeScope::removeElementById(const AtomicString& elementId, Element* elemen t) 189 void TreeScope::removeElementById(const AtomicString& elementId, Element* elemen t)
213 { 190 {
214 if (!m_elementsById) 191 if (!m_elementsById)
215 return; 192 return;
216 m_elementsById->remove(elementId, element); 193 m_elementsById->remove(elementId, element);
217 #if ENABLE(ASSERT)
218 // Register 'elementId' as being removed. This is done should observers
219 // attempt to also look it up, something that the underlying DocumentOrdered Map
220 // is incapable of answering precisely while an element (and its
221 // children) are being removed from the tree. This is _only_ done to avoid
222 // an assert in DocumentOrderedMap::get() from falsely triggering for such
223 // unusual and unexpected lookups.
224 RemovingElementIdScope removalScope(*m_elementsById, elementId);
225 #endif
226 m_idTargetObserverRegistry->notifyObservers(elementId); 194 m_idTargetObserverRegistry->notifyObservers(elementId);
227 } 195 }
228 196
229 Node* TreeScope::ancestorInThisScope(Node* node) const 197 Node* TreeScope::ancestorInThisScope(Node* node) const
230 { 198 {
231 while (node) { 199 while (node) {
232 if (node->treeScope() == this) 200 if (node->treeScope() == this)
233 return node; 201 return node;
234 if (!node->isInShadowTree()) 202 if (!node->isInShadowTree())
235 return 0; 203 return 0;
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 visitor->trace(m_document); 573 visitor->trace(m_document);
606 visitor->trace(m_parentTreeScope); 574 visitor->trace(m_parentTreeScope);
607 visitor->trace(m_idTargetObserverRegistry); 575 visitor->trace(m_idTargetObserverRegistry);
608 visitor->trace(m_selection); 576 visitor->trace(m_selection);
609 visitor->trace(m_elementsById); 577 visitor->trace(m_elementsById);
610 visitor->trace(m_imageMapsByName); 578 visitor->trace(m_imageMapsByName);
611 visitor->trace(m_labelsByForAttribute); 579 visitor->trace(m_labelsByForAttribute);
612 visitor->trace(m_scopedStyleResolver); 580 visitor->trace(m_scopedStyleResolver);
613 } 581 }
614 582
583 #if ENABLE(ASSERT)
584 TreeScope::RemoveScope::RemoveScope(ContainerNode* containerNode)
585 : m_idMap(containerNode->treeScope().m_elementsById.get())
586 {
587 // While removing a ContainerNode, lookups in the underlying id map will
esprehn 2016/01/05 07:48:33 this comment should be with the RemoveScope class
sof 2016/01/05 12:37:18 Done, moved to DocumentOrderedMap::RemoveScope dec
588 // not be precise should the tree have elements with duplicate IDs
589 // contained in the node being removed. Rare trees, but ID lookups may legit imately
590 // fail across such removals; inform the DocumentOrderedMap about the transi tory
591 // state of the underlying tree.
592 if (m_idMap)
593 m_idMap->enterTreeRemoveScope();
594 }
595
596 TreeScope::RemoveScope::~RemoveScope()
597 {
598 if (m_idMap)
599 m_idMap->leaveTreeRemoveScope();
600 }
601 #endif
602
615 } // namespace blink 603 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698