| Index: Source/core/dom/Element.cpp
|
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
|
| index d7b4a1239835cec7ba4f6b992c0368b535cda941..726da802089e1035f4304140596422fe4b8e292f 100644
|
| --- a/Source/core/dom/Element.cpp
|
| +++ b/Source/core/dom/Element.cpp
|
| @@ -2533,14 +2533,15 @@ void Element::normalizeAttributes()
|
| {
|
| if (!hasAttributes())
|
| return;
|
| - // attributeCount() cannot be cached before the loop because the attributes
|
| - // list is altered while iterating.
|
| - AttributeCollection attributes = this->attributes();
|
| - AttributeCollection::const_iterator end = attributes.end();
|
| - for (AttributeCollection::const_iterator it = attributes.begin(); it < end; ++it) {
|
| - if (RefPtrWillBeRawPtr<Attr> attr = attrIfExists(it->name()))
|
| - attr->normalize();
|
| - }
|
| + WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodes = attrNodeList();
|
| + if (!attrNodes)
|
| + return;
|
| + // Copy the Attr Vector because Node::normalize() can fire synchronous JS
|
| + // events (e.g. DOMSubtreeModified) and a JS listener could add / remove
|
| + // attributes while we are iterating.
|
| + WillBeHeapVector<RefPtrWillBeMember<Attr> > attrNodesCopy(*attrNodes);
|
| + for (size_t i = 0; i < attrNodesCopy.size(); ++i)
|
| + attrNodesCopy[i]->normalize();
|
| }
|
|
|
| void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
|
|
|