Merge from Chromium at DEPS revision r200144
This commit was generated by merge_to_master.py.
Change-Id: I52995489013675af682cee321f417f624396b584
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index cd5ec55..e8645e2 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -53,9 +53,10 @@
#include "core/dom/NodeTraversal.h"
#include "core/dom/PseudoElement.h"
#include "core/dom/SelectorQuery.h"
-#include "core/dom/ShadowRoot.h"
#include "core/dom/Text.h"
#include "core/dom/WebCoreMemoryInstrumentation.h"
+#include "core/dom/shadow/InsertionPoint.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
#include "core/editing/htmlediting.h"
@@ -71,7 +72,6 @@
#include "core/html/HTMLTableRowsCollection.h"
#include "core/html/VoidCallback.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/html/shadow/InsertionPoint.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/page/FocusController.h"
#include "core/page/Frame.h"
@@ -289,18 +289,27 @@
PassRefPtr<Attr> Element::detachAttribute(size_t index)
{
ASSERT(elementData());
+ const Attribute* attribute = elementData()->attributeItem(index);
+ RefPtr<Attr> attrNode = attrIfExists(attribute->name());
+ if (attrNode)
+ detachAttrNodeAtIndex(attrNode.get(), index);
+ else {
+ attrNode = Attr::create(document(), attribute->name(), attribute->value());
+ removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
+ }
+ return attrNode.release();
+}
+
+void Element::detachAttrNodeAtIndex(Attr* attr, size_t index)
+{
+ ASSERT(attr);
+ ASSERT(elementData());
const Attribute* attribute = elementData()->attributeItem(index);
ASSERT(attribute);
-
- RefPtr<Attr> attrNode = attrIfExists(attribute->name());
- if (attrNode)
- detachAttrNodeFromElementWithValue(attrNode.get(), attribute->value());
- else
- attrNode = Attr::create(document(), attribute->name(), attribute->value());
-
+ ASSERT(attribute->name() == attr->qualifiedName());
+ detachAttrNodeFromElementWithValue(attr, attribute->value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
- return attrNode.release();
}
void Element::removeAttribute(const QualifiedName& name)
@@ -1443,12 +1452,10 @@
change = Force;
}
- if (change != Force) {
- if (styleChangeType() >= FullStyleChange)
- change = Force;
- else
- change = localChange;
- }
+ if (styleChangeType() == FullStyleChange)
+ change = Force;
+ else if (change != Force)
+ change = localChange;
}
StyleResolverParentPusher parentPusher(this);
@@ -1800,13 +1807,15 @@
synchronizeAttribute(attr->qualifiedName());
- size_t index = elementData()->getAttributeItemIndex(attr->qualifiedName());
+ size_t index = elementData()->getAttrIndex(attr);
if (index == notFound) {
ec = NOT_FOUND_ERR;
return 0;
}
- return detachAttribute(index);
+ RefPtr<Attr> guard(attr);
+ detachAttrNodeAtIndex(attr, index);
+ return guard.release();
}
bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
@@ -2336,31 +2345,6 @@
return 0;
}
-// ElementTraversal API
-Element* Element::firstElementChild() const
-{
- return ElementTraversal::firstWithin(this);
-}
-
-Element* Element::lastElementChild() const
-{
- Node* n = lastChild();
- while (n && !n->isElementNode())
- n = n->previousSibling();
- return toElement(n);
-}
-
-unsigned Element::childElementCount() const
-{
- unsigned count = 0;
- Node* n = firstChild();
- while (n) {
- count += n->isElementNode();
- n = n->nextSibling();
- }
- return count;
-}
-
bool Element::matchesReadOnlyPseudoClass() const
{
return false;
@@ -3113,6 +3097,16 @@
info.addMember(*attributeItem(i), "*attributeItem");
}
+size_t ElementData::getAttrIndex(Attr* attr) const
+{
+ // This relies on the fact that Attr's QualifiedName == the Attribute's name.
+ for (unsigned i = 0; i < length(); ++i) {
+ if (attributeItem(i)->name() == attr->qualifiedName())
+ return i;
+ }
+ return notFound;
+}
+
size_t ElementData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
// Continue to checking case-insensitively and/or full namespaced names if necessary: