Home | History | Annotate | Download | only in html
      1 /*
      2  * Copyright (c) 2012 Motorola Mobility, Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY MOTOROLA MOBILITY, INC. AND ITS CONTRIBUTORS
     14  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY, INC. OR ITS
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "core/html/RadioNodeList.h"
     28 
     29 #include "core/HTMLNames.h"
     30 #include "core/dom/Element.h"
     31 #include "core/dom/NodeRareData.h"
     32 #include "core/html/HTMLFormElement.h"
     33 #include "core/html/HTMLInputElement.h"
     34 #include "core/html/HTMLObjectElement.h"
     35 
     36 namespace WebCore {
     37 
     38 using namespace HTMLNames;
     39 
     40 RadioNodeList::RadioNodeList(ContainerNode& rootNode, const AtomicString& name, CollectionType type)
     41     : LiveNodeList(rootNode, type, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
     42     , m_name(name)
     43     , m_onlyMatchImgElements(type == RadioImgNodeListType)
     44 {
     45     ScriptWrappable::init(this);
     46 }
     47 
     48 RadioNodeList::~RadioNodeList()
     49 {
     50 #if !ENABLE(OILPAN)
     51     ownerNode().nodeLists()->removeCache(this, m_onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType, m_name);
     52 #endif
     53 }
     54 
     55 static inline HTMLInputElement* toRadioButtonInputElement(Element& element)
     56 {
     57     if (!isHTMLInputElement(element))
     58         return 0;
     59     HTMLInputElement& inputElement = toHTMLInputElement(element);
     60     if (!inputElement.isRadioButton() || inputElement.value().isEmpty())
     61         return 0;
     62     return &inputElement;
     63 }
     64 
     65 String RadioNodeList::value() const
     66 {
     67     if (m_onlyMatchImgElements)
     68         return String();
     69     unsigned length = this->length();
     70     for (unsigned i = 0; i < length; ++i) {
     71         const HTMLInputElement* inputElement = toRadioButtonInputElement(*item(i));
     72         if (!inputElement || !inputElement->checked())
     73             continue;
     74         return inputElement->value();
     75     }
     76     return String();
     77 }
     78 
     79 void RadioNodeList::setValue(const String& value)
     80 {
     81     if (m_onlyMatchImgElements)
     82         return;
     83     unsigned length = this->length();
     84     for (unsigned i = 0; i < length; ++i) {
     85         HTMLInputElement* inputElement = toRadioButtonInputElement(*item(i));
     86         if (!inputElement || inputElement->value() != value)
     87             continue;
     88         inputElement->setChecked(true);
     89         return;
     90     }
     91 }
     92 
     93 bool RadioNodeList::matchesByIdOrName(const Element& testElement) const
     94 {
     95     return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
     96 }
     97 
     98 bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
     99 {
    100     ASSERT(!m_onlyMatchImgElements);
    101     ASSERT(isHTMLObjectElement(testElement) || testElement.isFormControlElement());
    102     if (isHTMLFormElement(ownerNode())) {
    103         HTMLFormElement* formElement = toHTMLElement(testElement).formOwner();
    104         if (!formElement || formElement != ownerNode())
    105             return false;
    106     }
    107 
    108     return matchesByIdOrName(testElement);
    109 }
    110 
    111 bool RadioNodeList::elementMatches(const Element& element) const
    112 {
    113     if (m_onlyMatchImgElements) {
    114         if (!isHTMLImageElement(element))
    115             return false;
    116 
    117         if (toHTMLElement(element).formOwner() != ownerNode())
    118             return false;
    119 
    120         return matchesByIdOrName(element);
    121     }
    122 
    123     if (!isHTMLObjectElement(element) && !element.isFormControlElement())
    124         return false;
    125 
    126     if (isHTMLInputElement(element) && toHTMLInputElement(element).isImageButton())
    127         return false;
    128 
    129     return checkElementMatchesRadioNodeListFilter(element);
    130 }
    131 
    132 } // namespace
    133