| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 Apple Inc. All | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 Apple Inc. All |
| 5 * rights reserved. | 5 * rights reserved. |
| 6 * Copyright (C) 2014 Samsung Electronics. All rights reserved. | 6 * Copyright (C) 2014 Samsung Electronics. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| 11 * version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
| 12 * | 12 * |
| 13 * This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 * Library General Public License for more details. | 16 * Library General Public License for more details. |
| 17 * | 17 * |
| 18 * You should have received a copy of the GNU Library General Public License | 18 * You should have received a copy of the GNU Library General Public License |
| 19 * along with this library; see the file COPYING.LIB. If not, write to | 19 * along with this library; see the file COPYING.LIB. If not, write to |
| 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 21 * Boston, MA 02110-1301, USA. | 21 * Boston, MA 02110-1301, USA. |
| 22 * | 22 * |
| 23 */ | 23 */ |
| 24 | 24 |
| 25 #include "core/html/HTMLFormControlsCollection.h" | 25 #include "core/html/HTMLFormControlsCollection.h" |
| 26 | 26 |
| 27 #include "bindings/core/v8/RadioNodeListOrElement.h" | 27 #include "bindings/core/v8/RadioNodeListOrElement.h" |
| 28 #include "core/HTMLNames.h" | 28 #include "core/HTMLNames.h" |
| 29 #include "core/frame/UseCounter.h" | 29 #include "core/frame/UseCounter.h" |
| 30 #include "core/html/HTMLFieldSetElement.h" | |
| 31 #include "core/html/HTMLFormElement.h" | 30 #include "core/html/HTMLFormElement.h" |
| 32 #include "core/html/HTMLImageElement.h" | 31 #include "core/html/HTMLImageElement.h" |
| 33 #include "wtf/HashSet.h" | 32 #include "wtf/HashSet.h" |
| 34 | 33 |
| 35 namespace blink { | 34 namespace blink { |
| 36 | 35 |
| 37 using namespace HTMLNames; | 36 using namespace HTMLNames; |
| 38 | 37 |
| 39 // Since the collections are to be "live", we have to do the | 38 // Since the collections are to be "live", we have to do the |
| 40 // calculation every time if anything has changed. | 39 // calculation every time if anything has changed. |
| 41 | 40 |
| 42 HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode& ownerNode) | 41 HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode& ownerNode) |
| 43 : HTMLCollection(ownerNode, FormControls, OverridesItemAfter), | 42 : HTMLCollection(ownerNode, FormControls, OverridesItemAfter), |
| 44 m_cachedElement(nullptr), | 43 m_cachedElement(nullptr), |
| 45 m_cachedElementOffsetInArray(0) { | 44 m_cachedElementOffsetInArray(0) { |
| 46 DCHECK(isHTMLFormElement(ownerNode) || isHTMLFieldSetElement(ownerNode)); | 45 DCHECK(isHTMLFormElement(ownerNode)); |
| 47 } | 46 } |
| 48 | 47 |
| 49 HTMLFormControlsCollection* HTMLFormControlsCollection::create( | 48 HTMLFormControlsCollection* HTMLFormControlsCollection::create( |
| 50 ContainerNode& ownerNode, | 49 ContainerNode& ownerNode, |
| 51 CollectionType type) { | 50 CollectionType type) { |
| 52 DCHECK_EQ(type, FormControls); | 51 DCHECK_EQ(type, FormControls); |
| 53 return new HTMLFormControlsCollection(ownerNode); | 52 return new HTMLFormControlsCollection(ownerNode); |
| 54 } | 53 } |
| 55 | 54 |
| 56 HTMLFormControlsCollection::~HTMLFormControlsCollection() {} | 55 HTMLFormControlsCollection::~HTMLFormControlsCollection() {} |
| 57 | 56 |
| 58 const FormAssociatedElement::List& | 57 const FormAssociatedElement::List& |
| 59 HTMLFormControlsCollection::formControlElements() const { | 58 HTMLFormControlsCollection::formControlElements() const { |
| 60 DCHECK(isHTMLFormElement(ownerNode()) || isHTMLFieldSetElement(ownerNode())); | 59 return toHTMLFormElement(ownerNode()).associatedElements(); |
| 61 if (isHTMLFormElement(ownerNode())) | |
| 62 return toHTMLFormElement(ownerNode()).associatedElements(); | |
| 63 return toHTMLFieldSetElement(ownerNode()).associatedElements(); | |
| 64 } | 60 } |
| 65 | 61 |
| 66 const HeapVector<Member<HTMLImageElement>>& | 62 const HeapVector<Member<HTMLImageElement>>& |
| 67 HTMLFormControlsCollection::formImageElements() const { | 63 HTMLFormControlsCollection::formImageElements() const { |
| 68 return toHTMLFormElement(ownerNode()).imageElements(); | 64 return toHTMLFormElement(ownerNode()).imageElements(); |
| 69 } | 65 } |
| 70 | 66 |
| 71 static unsigned findFormAssociatedElement( | 67 static unsigned findFormAssociatedElement( |
| 72 const FormAssociatedElement::List& associatedElements, | 68 const FormAssociatedElement::List& associatedElements, |
| 73 Element* element) { | 69 Element* element) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 cache->addElementWithId(idAttrVal, element); | 151 cache->addElementWithId(idAttrVal, element); |
| 156 foundInputElements.add(idAttrVal.impl()); | 152 foundInputElements.add(idAttrVal.impl()); |
| 157 } | 153 } |
| 158 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) { | 154 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) { |
| 159 cache->addElementWithName(nameAttrVal, element); | 155 cache->addElementWithName(nameAttrVal, element); |
| 160 foundInputElements.add(nameAttrVal.impl()); | 156 foundInputElements.add(nameAttrVal.impl()); |
| 161 } | 157 } |
| 162 } | 158 } |
| 163 } | 159 } |
| 164 | 160 |
| 165 if (isHTMLFormElement(ownerNode())) { | 161 // HTMLFormControlsCollection doesn't support named getter for IMG |
| 166 // HTMLFormControlsCollection doesn't support named getter for IMG | 162 // elements. However we still need to handle IMG elements here because |
| 167 // elements. However we still need to handle IMG elements here because | 163 // HTMLFormElement named getter relies on this. |
| 168 // HTMLFormElement named getter relies on this. | 164 const HeapVector<Member<HTMLImageElement>>& imageElementsArray = |
| 169 const HeapVector<Member<HTMLImageElement>>& imageElementsArray = | 165 formImageElements(); |
| 170 formImageElements(); | 166 for (unsigned i = 0; i < imageElementsArray.size(); ++i) { |
| 171 for (unsigned i = 0; i < imageElementsArray.size(); ++i) { | 167 HTMLImageElement* element = imageElementsArray[i]; |
| 172 HTMLImageElement* element = imageElementsArray[i]; | 168 const AtomicString& idAttrVal = element->getIdAttribute(); |
| 173 const AtomicString& idAttrVal = element->getIdAttribute(); | 169 const AtomicString& nameAttrVal = element->getNameAttribute(); |
| 174 const AtomicString& nameAttrVal = element->getNameAttribute(); | 170 if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl())) |
| 175 if (!idAttrVal.isEmpty() && | 171 cache->addElementWithId(idAttrVal, element); |
| 176 !foundInputElements.contains(idAttrVal.impl())) | 172 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && |
| 177 cache->addElementWithId(idAttrVal, element); | 173 !foundInputElements.contains(nameAttrVal.impl())) |
| 178 if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && | 174 cache->addElementWithName(nameAttrVal, element); |
| 179 !foundInputElements.contains(nameAttrVal.impl())) | |
| 180 cache->addElementWithName(nameAttrVal, element); | |
| 181 } | |
| 182 } | 175 } |
| 183 | 176 |
| 184 // Set the named item cache last as traversing the tree may cause cache | 177 // Set the named item cache last as traversing the tree may cause cache |
| 185 // invalidation. | 178 // invalidation. |
| 186 setNamedItemCache(cache); | 179 setNamedItemCache(cache); |
| 187 } | 180 } |
| 188 | 181 |
| 189 void HTMLFormControlsCollection::namedGetter( | 182 void HTMLFormControlsCollection::namedGetter( |
| 190 const AtomicString& name, | 183 const AtomicString& name, |
| 191 RadioNodeListOrElement& returnValue) { | 184 RadioNodeListOrElement& returnValue) { |
| 192 HeapVector<Member<Element>> namedItems; | 185 HeapVector<Member<Element>> namedItems; |
| 193 this->namedItems(name, namedItems); | 186 this->namedItems(name, namedItems); |
| 194 | 187 |
| 195 if (namedItems.isEmpty()) | 188 if (namedItems.isEmpty()) |
| 196 return; | 189 return; |
| 197 | 190 |
| 198 if (namedItems.size() == 1) { | 191 if (namedItems.size() == 1) { |
| 199 if (!isHTMLImageElement(*namedItems[0])) | 192 if (!isHTMLImageElement(*namedItems[0])) |
| 200 returnValue.setElement(namedItems.at(0)); | 193 returnValue.setElement(namedItems.at(0)); |
| 201 return; | 194 return; |
| 202 } | 195 } |
| 203 | 196 |
| 204 // This path never returns a RadioNodeList for <img> because | 197 // This path never returns a RadioNodeList for <img> because |
| 205 // onlyMatchingImgElements flag is false by default. | 198 // onlyMatchingImgElements flag is false by default. |
| 206 returnValue.setRadioNodeList(ownerNode().radioNodeList(name)); | 199 returnValue.setRadioNodeList(ownerNode().radioNodeList(name)); |
| 207 if (isHTMLFieldSetElement(ownerNode())) | |
| 208 UseCounter::count( | |
| 209 document(), | |
| 210 UseCounter::FormControlsCollectionReturnsRadioNodeListForFieldSet); | |
| 211 } | 200 } |
| 212 | 201 |
| 213 void HTMLFormControlsCollection::supportedPropertyNames(Vector<String>& names) { | 202 void HTMLFormControlsCollection::supportedPropertyNames(Vector<String>& names) { |
| 214 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-inte
rfaces.html#htmlformcontrolscollection-0: | 203 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-inte
rfaces.html#htmlformcontrolscollection-0: |
| 215 // The supported property names consist of the non-empty values of all the id | 204 // The supported property names consist of the non-empty values of all the id |
| 216 // and name attributes of all the elements represented by the collection, in | 205 // and name attributes of all the elements represented by the collection, in |
| 217 // tree order, ignoring later duplicates, with the id of an element preceding | 206 // tree order, ignoring later duplicates, with the id of an element preceding |
| 218 // its name if it contributes both, they differ from each other, and neither | 207 // its name if it contributes both, they differ from each other, and neither |
| 219 // is the duplicate of an earlier entry. | 208 // is the duplicate of an earlier entry. |
| 220 HashSet<AtomicString> existingNames; | 209 HashSet<AtomicString> existingNames; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 238 } | 227 } |
| 239 } | 228 } |
| 240 } | 229 } |
| 241 | 230 |
| 242 DEFINE_TRACE(HTMLFormControlsCollection) { | 231 DEFINE_TRACE(HTMLFormControlsCollection) { |
| 243 visitor->trace(m_cachedElement); | 232 visitor->trace(m_cachedElement); |
| 244 HTMLCollection::trace(visitor); | 233 HTMLCollection::trace(visitor); |
| 245 } | 234 } |
| 246 | 235 |
| 247 } // namespace blink | 236 } // namespace blink |
| OLD | NEW |