18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2001 Dirk Mueller (mueller@kde.org)
65af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
8d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2010 Google Inc. All rights reserved.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLSelectElement.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AXObjectCache.h"
31e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLOptionElement.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLOptionsCollection.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderListBox.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderMenuList.h"
385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "ScriptEventListener.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// Upper limit agreed upon with representatives of Opera and Mozilla.
478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic const unsigned maxSelectItems = 10000;
488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
495f1ab04193ad0130ca8204aadaceae083aca9881Feng QianHTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    : HTMLFormControlElementWithState(tagName, document, form)
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(hasTagName(selectTag));
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
555af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkePassRefPtr<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(tagName.matches(selectTag));
5806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return adoptRef(new HTMLSelectElement(tagName, document, form));
595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLSelectElement::recalcStyle(StyleChange change)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HTMLFormControlElementWithState::recalcStyle(change);
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianconst AtomicString& HTMLSelectElement::formControlType() const
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple"));
69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, selectOne, ("select-one"));
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return m_data.multiple() ? selectMultiple : selectOne;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint HTMLSelectElement::selectedIndex() const
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return SelectElement::selectedIndex(m_data, this);
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::deselectItems(m_data, this, excludeElement);
81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLSelectElement::setSelectedIndex(int optionIndex, bool deselect)
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, false, false);
87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
905abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow, bool allowMultipleSelection)
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // List box selects can fire onchange events through user interaction, such as
935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // mousedown events. This allows that same behavior programmatically.
945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (!m_data.usesMenuList()) {
955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        updateSelectedState(m_data, this, optionIndex, allowMultipleSelection, false);
96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setNeedsValidityCheck();
975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (fireOnChangeNow)
985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            listBoxOnChange();
995abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return;
1005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
1015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Bail out if this index is already the selected one, to avoid running unnecessary JavaScript that can mess up
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // autofill, when there is no actual change (see https://bugs.webkit.org/show_bug.cgi?id=35256 and rdar://7467917 ).
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Perhaps this logic could be moved into SelectElement, but some callers of SelectElement::setSelectedIndex()
105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // seem to expect it to fire its change event even when the index was already selected.
106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (optionIndex == selectedIndex())
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, fireOnChangeNow, true);
110f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
111f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
112f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
113f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool HTMLSelectElement::hasPlaceholderLabelOption() const
114f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
115f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // The select element has no placeholder label option if it has an attribute "multiple" specified or a display size of non-1.
116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    //
117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // The condition "size() > 1" is actually not compliant with the HTML5 spec as of Dec 3, 2010. "size() != 1" is correct.
118f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Using "size() > 1" here because size() may be 0 in WebKit.
119f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // See the discussion at https://bugs.webkit.org/show_bug.cgi?id=43887
120f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    //
121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // "0 size()" happens when an attribute "size" is absent or an invalid size attribute is specified.
122f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // In this case, the display size should be assumed as the default.
123f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // The default display size is 1 for non-multiple select elements, and 4 for multiple select elements.
124f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    //
125f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Finally, if size() == 0 and non-multiple, the display size can be assumed as 1.
126f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (multiple() || size() > 1)
127f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return false;
128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
129f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int listIndex = optionToListIndex(0);
130f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ASSERT(listIndex >= 0);
131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (listIndex < 0)
132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return false;
133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    HTMLOptionElement* option = static_cast<HTMLOptionElement*>(listItems()[listIndex]);
134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return !option->disabled() && !listIndex && option->value().isEmpty();
135f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
136f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
137f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool HTMLSelectElement::valueMissing() const
138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!isRequiredFormControl())
140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return false;
141f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
142f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int firstSelectionIndex = selectedIndex();
143f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // If a non-placeholer label option is selected (firstSelectionIndex > 0), it's not value-missing.
145f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return firstSelectionIndex < 0 || (!firstSelectionIndex && hasPlaceholderLabelOption());
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!multiple())
15106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        setSelectedIndexByUser(listToOptionIndex(listIndex), true, fireOnChangeNow);
152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    else {
153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        updateSelectedState(m_data, this, listIndex, allowMultiplySelections, shift);
154f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setNeedsValidityCheck();
155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (fireOnChangeNow)
156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            listBoxOnChange();
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint HTMLSelectElement::activeSelectionStartListIndex() const
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_data.activeSelectionAnchorIndex() >= 0)
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return m_data.activeSelectionAnchorIndex();
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return optionToListIndex(selectedIndex());
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint HTMLSelectElement::activeSelectionEndListIndex() const
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_data.activeSelectionEndIndex() >= 0)
1705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return m_data.activeSelectionEndIndex();
1715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return SelectElement::lastSelectedListIndex(m_data, this);
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned HTMLSelectElement::length() const
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return SelectElement::optionCount(m_data, this);
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
179cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, ExceptionCode& ec)
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<HTMLElement> protectNewChild(element); // make sure the element is ref'd and deref'd so we don't leak it
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    insertBefore(element, before, ec);
187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
190cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid HTMLSelectElement::remove(int optionIndex)
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
192cad810f21b803229eb11403f9209855525a25d57Steve Block    int listIndex = optionToListIndex(optionIndex);
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (listIndex < 0)
1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ExceptionCode ec;
197cad810f21b803229eb11403f9209855525a25d57Steve Block    listItems()[listIndex]->remove(ec);
198cad810f21b803229eb11403f9209855525a25d57Steve Block}
199cad810f21b803229eb11403f9209855525a25d57Steve Block
200cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid HTMLSelectElement::remove(HTMLOptionElement* option)
201cad810f21b803229eb11403f9209855525a25d57Steve Block{
202cad810f21b803229eb11403f9209855525a25d57Steve Block    if (option->ownerSelectElement() != this)
203cad810f21b803229eb11403f9209855525a25d57Steve Block        return;
204cad810f21b803229eb11403f9209855525a25d57Steve Block
205cad810f21b803229eb11403f9209855525a25d57Steve Block    ExceptionCode ec;
206cad810f21b803229eb11403f9209855525a25d57Steve Block    option->remove(ec);
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2092fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockString HTMLSelectElement::value() const
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    const Vector<Element*>& items = listItems();
2125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (unsigned i = 0; i < items.size(); i++) {
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (items[i]->hasLocalName(optionTag) && static_cast<HTMLOptionElement*>(items[i])->selected())
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return static_cast<HTMLOptionElement*>(items[i])->value();
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return "";
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::setValue(const String &value)
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (value.isNull())
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // find the option with value() matching the given parameter
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and make it the current selection.
2255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    const Vector<Element*>& items = listItems();
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned optionIndex = 0;
2275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (unsigned i = 0; i < items.size(); i++) {
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (items[i]->hasLocalName(optionTag)) {
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (static_cast<HTMLOptionElement*>(items[i])->value() == value) {
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                setSelectedIndex(optionIndex, true);
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            optionIndex++;
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool HTMLSelectElement::saveFormControlState(String& value) const
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return SelectElement::saveFormControlState(m_data, this, value);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLSelectElement::restoreFormControlState(const String& state)
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::restoreFormControlState(m_data, this, state);
246f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
249e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLSelectElement::parseMappedAttribute(Attribute* attr)
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool oldUsesMenuList = m_data.usesMenuList();
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attr->name() == sizeAttr) {
2535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int oldSize = m_data.size();
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Set the attribute value to a number.
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is important since the style rules for this attribute can determine the appearance property.
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int size = attr->value().toInt();
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String attrSize = String::number(size);
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (attrSize != attr->value())
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            attr->setValue(attrSize);
260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        size = max(size, 1);
261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Ensure that we've determined selectedness of the items at least once prior to changing the size.
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (oldSize != size)
264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            recalcListItemsIfNeeded();
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_data.setSize(size);
267f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setNeedsValidityCheck();
2685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((oldUsesMenuList != m_data.usesMenuList() || (!oldUsesMenuList && m_data.size() != oldSize)) && attached()) {
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            detach();
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            attach();
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setRecalcListItems();
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else if (attr->name() == multipleAttr)
2745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        SelectElement::parseMultipleAttribute(m_data, this, attr);
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    else if (attr->name() == accesskeyAttr) {
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: ignore for the moment
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == alignAttr) {
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Don't map 'align' attribute.  This matches what Firefox, Opera and IE do.
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // See http://bugs.webkit.org/show_bug.cgi?id=12072
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == onchangeAttr) {
2815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        setAttributeEventListener(eventNames().changeEvent, createAttributeEventListener(this, attr));
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLFormControlElementWithState::parseMappedAttribute(attr);
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLSelectElement::isKeyboardFocusable(KeyboardEvent* event) const
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return isFocusable();
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return HTMLFormControlElementWithState::isKeyboardFocusable(event);
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLSelectElement::isMouseFocusable() const
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return isFocusable();
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return HTMLFormControlElementWithState::isMouseFocusable();
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLSelectElement::canSelectAll() const
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return !m_data.usesMenuList();
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::selectAll()
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::selectAll(m_data, this);
308f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*)
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_data.usesMenuList())
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return new (arena) RenderMenuList(this);
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return new (arena) RenderListBox(this);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLSelectElement::appendFormData(FormDataList& list, bool)
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return SelectElement::appendFormData(m_data, this, list);
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint HTMLSelectElement::optionToListIndex(int optionIndex) const
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return SelectElement::optionToListIndex(m_data, this, optionIndex);
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint HTMLSelectElement::listToOptionIndex(int listIndex) const
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return SelectElement::listToOptionIndex(m_data, this, listIndex);
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return HTMLOptionsCollection::create(this);
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::recalcListItems(const_cast<SelectElementData&>(m_data), this, updateSelectedStates);
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
343d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid HTMLSelectElement::recalcListItemsIfNeeded()
344d0825bca7fe65beaee391d30da42e937db621564Steve Block{
345d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (m_data.shouldRecalcListItems())
346d0825bca7fe65beaee391d30da42e937db621564Steve Block        recalcListItems();
347d0825bca7fe65beaee391d30da42e937db621564Steve Block}
348d0825bca7fe65beaee391d30da42e937db621564Steve Block
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setRecalcListItems();
352f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (AXObjectCache::accessibilityEnabled() && renderer())
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->document()->axObjectCache()->childrenChanged(renderer());
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::setRecalcListItems()
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::setRecalcListItems(m_data, this);
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!inDocument())
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_collectionInfo.reset();
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::reset()
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::reset(m_data, this);
370f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::dispatchFocusEvent()
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::dispatchFocusEvent(m_data, this);
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFormControlElementWithState::dispatchFocusEvent();
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::dispatchBlurEvent()
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::dispatchBlurEvent(m_data, this);
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFormControlElementWithState::dispatchBlurEvent();
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLSelectElement::defaultEventHandler(Event* event)
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
387ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    SelectElement::defaultEventHandler(m_data, this, event, form());
3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (event->defaultHandled())
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HTMLFormControlElementWithState::defaultEventHandler(event);
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::setActiveSelectionAnchorIndex(m_data, this, index);
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLSelectElement::setActiveSelectionEndIndex(int index)
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::setActiveSelectionEndIndex(m_data, index);
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::updateListBoxSelection(m_data, this, deselectOtherOptions);
406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::menuListOnChange()
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::menuListOnChange(m_data, this);
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::listBoxOnChange()
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::listBoxOnChange(m_data, this);
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::saveLastSelection()
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::saveLastSelection(m_data, this);
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::accessKeyAction(bool sendToAnyElement)
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    focus();
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dispatchSimulatedClick(0, sendToAnyElement);
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::accessKeySetSelectedIndex(int index)
4315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
4325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::accessKeySetSelectedIndex(m_data, this, index);
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::setMultiple(bool multiple)
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4372bde8e466a4451c7319e3a072d118917957d6554Steve Block    int oldSelectedIndex = selectedIndex();
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setAttribute(multipleAttr, multiple ? "" : 0);
4392bde8e466a4451c7319e3a072d118917957d6554Steve Block
4402bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Restore selectedIndex after changing the multiple flag to preserve
4412bde8e466a4451c7319e3a072d118917957d6554Steve Block    // selection as single-line and multi-line has different defaults.
4422bde8e466a4451c7319e3a072d118917957d6554Steve Block    setSelectedIndex(oldSelectedIndex);
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::setSize(int size)
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setAttribute(sizeAttr, String::number(size));
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNode* HTMLSelectElement::namedItem(const AtomicString& name)
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
452635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return options()->namedItem(name);
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* HTMLSelectElement::item(unsigned index)
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return options()->item(index);
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, ExceptionCode& ec)
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
4638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (index > maxSelectItems - 1)
4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        index = maxSelectItems - 1;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int diff = index  - length();
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement* before = 0;
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // out of array bounds ? first insert empty dummies
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (diff > 0) {
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setLength(index, ec);
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // replace an existing entry ?
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (diff < 0) {
4722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        before = toHTMLElement(options()->item(index+1));
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        remove(index);
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // finally add the new element
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!ec) {
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        add(option, before, ec);
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (diff >= 0 && option->selected())
4795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            setSelectedIndex(index, !m_data.multiple());
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
4868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (newLen > maxSelectItems)
4878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newLen = maxSelectItems;
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int diff = length() - newLen;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (diff < 0) { // add dummy elements
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
4928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RefPtr<Element> option = document()->createElement(optionTag, false);
4938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ASSERT(option);
4942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            add(toHTMLElement(option.get()), 0, ec);
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (ec)
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (++diff);
4985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else {
4995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        const Vector<Element*>& items = listItems();
5005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
501dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Removing children fires mutation events, which might mutate the DOM further, so we first copy out a list
502dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // of elements that we intend to remove then attempt to remove them one at a time.
503dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Vector<RefPtr<Element> > itemsToRemove;
5045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        size_t optionIndex = 0;
505dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (size_t i = 0; i < items.size(); ++i) {
506dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            Element* item = items[i];
507dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (item->hasLocalName(optionTag) && optionIndex++ >= newLen) {
5085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                ASSERT(item->parentNode());
509dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                itemsToRemove.append(item);
510dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
511dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
512dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
513dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (size_t i = 0; i < itemsToRemove.size(); ++i) {
514dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            Element* item = itemsToRemove[i].get();
515dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (item->parentNode()) {
5165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                item->parentNode()->removeChild(item, ec);
5175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
5185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
520f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setNeedsValidityCheck();
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLSelectElement::scrollToSelection()
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::scrollToSelection(m_data, this);
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLSelectElement::insertedIntoTree(bool deep)
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    SelectElement::insertedIntoTree(m_data, this);
5315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HTMLFormControlElementWithState::insertedIntoTree(deep);
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
534f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool HTMLSelectElement::isRequiredFormControl() const
535f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
536f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return required();
537f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
538f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace
540