1197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch/*
2197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Copyright (C) 2013 Google Inc. All rights reserved.
3197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Copyright (C) 2014 Apple Inc. All rights reserved.
4197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Copyright (C) 2014 Samsung Electronics. All rights reserved.
5197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
6197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Redistribution and use in source and binary forms, with or without
7197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * modification, are permitted provided that the following conditions are
8197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * met:
9197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
10197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *     * Redistributions of source code must retain the above copyright
11197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * notice, this list of conditions and the following disclaimer.
12197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *     * Redistributions in binary form must reproduce the above
13197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
14197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * in the documentation and/or other materials provided with the
15197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * distribution.
16197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
17197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * contributors may be used to endorse or promote products derived from
18197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * this software without specific prior written permission.
19197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
20197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch */
32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#ifndef AttributeCollection_h
34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define AttributeCollection_h
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/Attr.h"
37197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Attribute.h"
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/Vector.h"
39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType = Container>
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class AttributeCollectionGeneric {
44197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic:
45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef typename Container::ValueType ValueType;
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef ValueType* iterator;
47197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeCollectionGeneric(Container& attributes)
49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : m_attributes(attributes)
50197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    { }
51197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ValueType& operator[](unsigned index) const { return at(index); }
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ValueType& at(unsigned index) const
54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        RELEASE_ASSERT(index < size());
56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return begin()[index];
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator begin() const { return m_attributes.data(); }
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator end() const { return begin() + size(); }
61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    unsigned size() const { return m_attributes.size(); }
63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool isEmpty() const { return !size(); }
64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
65c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator find(const QualifiedName&) const;
66c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator find(const AtomicString& name, bool shouldIgnoreCase) const;
67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t findIndex(const QualifiedName&, bool shouldIgnoreCase = false) const;
68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t findIndex(const AtomicString& name, bool shouldIgnoreCase) const;
69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t findIndex(Attr*) const;
70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)protected:
72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t findSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ContainerMemberType m_attributes;
75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class AttributeArray {
78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef const Attribute ValueType;
80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
81c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeArray(const Attribute* array, unsigned size)
82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : m_array(array)
83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        , m_size(size)
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    { }
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const Attribute* data() const { return m_array; }
87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned size() const { return m_size; }
88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
89197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate:
90197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const Attribute* m_array;
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned m_size;
92197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
94c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class AttributeCollection : public AttributeCollectionGeneric<const AttributeArray> {
95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeCollection()
97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : AttributeCollectionGeneric<const AttributeArray>(AttributeArray(nullptr, 0))
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    { }
99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
100c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeCollection(const Attribute* array, unsigned size)
101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : AttributeCollectionGeneric<const AttributeArray>(AttributeArray(array, size))
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    { }
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)typedef Vector<Attribute, 4> AttributeVector;
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class MutableAttributeCollection : public AttributeCollectionGeneric<AttributeVector, AttributeVector&> {
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    explicit MutableAttributeCollection(AttributeVector& attributes)
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : AttributeCollectionGeneric<AttributeVector, AttributeVector&>(attributes)
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    { }
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // These functions do no error/duplicate checking.
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void append(const QualifiedName&, const AtomicString& value);
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void remove(unsigned index);
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline void MutableAttributeCollection::append(const QualifiedName& name, const AtomicString& value)
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_attributes.append(Attribute(name, value));
120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline void MutableAttributeCollection::remove(unsigned index)
123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_attributes.remove(index);
125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
126c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType>
128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline typename AttributeCollectionGeneric<Container, ContainerMemberType>::iterator AttributeCollectionGeneric<Container, ContainerMemberType>::find(const AtomicString& name, bool shouldIgnoreCase) const
129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t index = findIndex(name, shouldIgnoreCase);
131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return index != kNotFound ? &at(index) : 0;
132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
133197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType>
135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findIndex(const QualifiedName& name, bool shouldIgnoreCase) const
136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator end = this->end();
138197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned index = 0;
139c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (iterator it = begin(); it != end; ++it, ++index) {
140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return index;
142197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return kNotFound;
144197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
146197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
147197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
148c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType>
149c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findIndex(const AtomicString& name, bool shouldIgnoreCase) const
150197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
151197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool doSlowCheck = shouldIgnoreCase;
152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Optimize for the case where the attribute exists and its name exactly matches.
154c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator end = this->end();
155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    unsigned index = 0;
156c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (iterator it = begin(); it != end; ++it, ++index) {
157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // FIXME: Why check the prefix? Namespaces should be all that matter.
158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Most attributes (all of HTML and CSS) have no namespace.
159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!it->name().hasPrefix()) {
160197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (name == it->localName())
161197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                return index;
162197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        } else {
163197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            doSlowCheck = true;
164197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
167197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (doSlowCheck)
168197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return findSlowCase(name, shouldIgnoreCase);
169197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return kNotFound;
170197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
171197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
172c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType>
173c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline typename AttributeCollectionGeneric<Container, ContainerMemberType>::iterator AttributeCollectionGeneric<Container, ContainerMemberType>::find(const QualifiedName& name) const
174197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator end = this->end();
176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (iterator it = begin(); it != end; ++it) {
177197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (it->name().matches(name))
178197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return it;
179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return 0;
181197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
183c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType>
184c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findIndex(Attr* attr) const
185c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
186c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // This relies on the fact that Attr's QualifiedName == the Attribute's name.
187c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator end = this->end();
188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    unsigned index = 0;
189c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (iterator it = begin(); it != end; ++it, ++index) {
190c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (it->name() == attr->qualifiedName())
191c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return index;
192c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return kNotFound;
194c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
195c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template <typename Container, typename ContainerMemberType>
197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
199c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Continue to checking case-insensitively and/or full namespaced names if necessary:
200c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    iterator end = this->end();
201c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    unsigned index = 0;
202c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (iterator it = begin(); it != end; ++it, ++index) {
203c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // FIXME: Why check the prefix? Namespace is all that should matter
204c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // and all HTML/SVG attributes have a null namespace!
205c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (!it->name().hasPrefix()) {
206c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (shouldIgnoreAttributeCase && equalIgnoringCase(name, it->localName()))
207c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return index;
208c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        } else {
209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            // FIXME: Would be faster to do this comparison without calling toString, which
210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            // generates a temporary string by concatenation. But this branch is only reached
211c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            // if the attribute name has a prefix, which is rare in HTML.
212c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (equalPossiblyIgnoringCase(name, it->name().toString(), shouldIgnoreAttributeCase))
213c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return index;
214c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
215c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
216c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return kNotFound;
217c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
218c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
219c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
220197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
221197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif // AttributeCollection_h
222