diff options
Diffstat (limited to 'WebCore/dom/NamedAttrMap.cpp')
| -rw-r--r-- | WebCore/dom/NamedAttrMap.cpp | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/WebCore/dom/NamedAttrMap.cpp b/WebCore/dom/NamedAttrMap.cpp index fe631c8..56b40b9 100644 --- a/WebCore/dom/NamedAttrMap.cpp +++ b/WebCore/dom/NamedAttrMap.cpp @@ -177,13 +177,33 @@ PassRefPtr<Node> NamedNodeMap::item(unsigned index) const Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const { unsigned len = length(); + bool doSlowCheck = shouldIgnoreAttributeCase; + + // Optimize for the case where the attribute exists and its name exactly matches. for (unsigned i = 0; i < len; ++i) { - if (!m_attributes[i]->name().hasPrefix() && - m_attributes[i]->name().localName() == name) + const QualifiedName& attrName = m_attributes[i]->name(); + if (!attrName.hasPrefix()) { + if (name == attrName.localName()) return m_attributes[i].get(); - - if (shouldIgnoreAttributeCase ? equalIgnoringCase(m_attributes[i]->name().toString(), name) : name == m_attributes[i]->name().toString()) - return m_attributes[i].get(); + } else + doSlowCheck = true; + } + + // Continue to checking case-insensitively and/or full namespaced names if necessary: + if (doSlowCheck) { + for (unsigned i = 0; i < len; ++i) { + const QualifiedName& attrName = m_attributes[i]->name(); + if (!attrName.hasPrefix()) { + if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attrName.localName())) + return m_attributes[i].get(); + } else { + // FIXME: Would be faster to do this comparison without calling toString, which + // generates a temporary string by concatenation. But this branch is only reached + // if the attribute name has a prefix, which is rare in HTML. + if (equalPossiblyIgnoringCase(name, attrName.toString(), shouldIgnoreAttributeCase)) + return m_attributes[i].get(); + } + } } return 0; } @@ -206,10 +226,12 @@ void NamedNodeMap::clearAttributes() void NamedNodeMap::detachFromElement() { - // we allow a NamedNodeMap w/o an element in case someone still has a reference - // to if after the element gets deleted - but the map is now invalid + // This can't happen if the holder of the map is JavaScript, because we mark the + // element if the map is alive. So it has no impact on web page behavior. Because + // of that, we can simply clear all the attributes to avoid accessing stale + // pointers to do things like create Attr objects. m_element = 0; - detachAttributesFromElement(); + clearAttributes(); } void NamedNodeMap::setAttributes(const NamedNodeMap& other) @@ -251,7 +273,7 @@ void NamedNodeMap::addAttribute(PassRefPtr<Attribute> prpAttribute) attr->m_element = m_element; // Notify the element that the attribute has been added, and dispatch appropriate mutation events - // Note that element may be null here if we are called from insertAttr() during parsing + // Note that element may be null here if we are called from insertAttribute() during parsing if (m_element) { m_element->attributeChanged(attribute.get()); // Because of our updateStyleAttribute() style modification events are never sent at the right time, so don't bother sending them. @@ -265,12 +287,13 @@ void NamedNodeMap::addAttribute(PassRefPtr<Attribute> prpAttribute) void NamedNodeMap::removeAttribute(const QualifiedName& name) { unsigned len = length(); - unsigned index = len + 1; - for (unsigned i = 0; i < len; ++i) + unsigned index = len; + for (unsigned i = 0; i < len; ++i) { if (m_attributes[i]->name().matches(name)) { index = i; break; } + } if (index >= len) return; |
