OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | 2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
3 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 3 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
4 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 4 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
reserved. |
7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
8 * Copyright (C) 2010 Google Inc. All rights reserved. | 8 * Copyright (C) 2010 Google Inc. All rights reserved. |
9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
10 * | 10 * |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 if (m_activeSelectionEndIndex >= 0) | 196 if (m_activeSelectionEndIndex >= 0) |
197 return m_activeSelectionEndIndex; | 197 return m_activeSelectionEndIndex; |
198 return lastSelectedListIndex(); | 198 return lastSelectedListIndex(); |
199 } | 199 } |
200 | 200 |
201 void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, Exception
State& exceptionState) | 201 void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, Exception
State& exceptionState) |
202 { | 202 { |
203 // Make sure the element is ref'd and deref'd so we don't leak it. | 203 // Make sure the element is ref'd and deref'd so we don't leak it. |
204 RefPtr<HTMLElement> protectNewChild(element); | 204 RefPtr<HTMLElement> protectNewChild(element); |
205 | 205 |
206 if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(
hrTag))) | 206 if (!element || !(isHTMLOptionElement(element) || isHTMLHRElement(element))) |
207 return; | 207 return; |
208 | 208 |
209 insertBefore(element, before, exceptionState); | 209 insertBefore(element, before, exceptionState); |
210 setNeedsValidityCheck(); | 210 setNeedsValidityCheck(); |
211 } | 211 } |
212 | 212 |
213 void HTMLSelectElement::remove(int optionIndex) | 213 void HTMLSelectElement::remove(int optionIndex) |
214 { | 214 { |
215 int listIndex = optionToListIndex(optionIndex); | 215 int listIndex = optionToListIndex(optionIndex); |
216 if (listIndex < 0) | 216 if (listIndex < 0) |
217 return; | 217 return; |
218 | 218 |
219 listItems()[listIndex]->remove(IGNORE_EXCEPTION); | 219 listItems()[listIndex]->remove(IGNORE_EXCEPTION); |
220 } | 220 } |
221 | 221 |
222 String HTMLSelectElement::value() const | 222 String HTMLSelectElement::value() const |
223 { | 223 { |
224 const Vector<HTMLElement*>& items = listItems(); | 224 const Vector<HTMLElement*>& items = listItems(); |
225 for (unsigned i = 0; i < items.size(); i++) { | 225 for (unsigned i = 0; i < items.size(); i++) { |
226 if (items[i]->hasLocalName(optionTag) && toHTMLOptionElement(items[i])->
selected()) | 226 if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->sele
cted()) |
227 return toHTMLOptionElement(items[i])->value(); | 227 return toHTMLOptionElement(items[i])->value(); |
228 } | 228 } |
229 return ""; | 229 return ""; |
230 } | 230 } |
231 | 231 |
232 void HTMLSelectElement::setValue(const String &value) | 232 void HTMLSelectElement::setValue(const String &value) |
233 { | 233 { |
234 // We clear the previously selected option(s) when needed, to guarantee call
ing setSelectedIndex() only once. | 234 // We clear the previously selected option(s) when needed, to guarantee call
ing setSelectedIndex() only once. |
235 if (value.isNull()) { | 235 if (value.isNull()) { |
236 setSelectedIndex(-1); | 236 setSelectedIndex(-1); |
237 return; | 237 return; |
238 } | 238 } |
239 | 239 |
240 // Find the option with value() matching the given parameter and make it the
current selection. | 240 // Find the option with value() matching the given parameter and make it the
current selection. |
241 const Vector<HTMLElement*>& items = listItems(); | 241 const Vector<HTMLElement*>& items = listItems(); |
242 unsigned optionIndex = 0; | 242 unsigned optionIndex = 0; |
243 for (unsigned i = 0; i < items.size(); i++) { | 243 for (unsigned i = 0; i < items.size(); i++) { |
244 if (items[i]->hasLocalName(optionTag)) { | 244 if (isHTMLOptionElement(items[i])) { |
245 if (toHTMLOptionElement(items[i])->value() == value) { | 245 if (toHTMLOptionElement(items[i])->value() == value) { |
246 setSelectedIndex(optionIndex); | 246 setSelectedIndex(optionIndex); |
247 return; | 247 return; |
248 } | 248 } |
249 optionIndex++; | 249 optionIndex++; |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 setSelectedIndex(-1); | 253 setSelectedIndex(-1); |
254 } | 254 } |
255 | 255 |
| 256 String HTMLSelectElement::suggestedValue() const |
| 257 { |
| 258 const Vector<HTMLElement*>& items = listItems(); |
| 259 for (unsigned i = 0; i < items.size(); ++i) { |
| 260 if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) { |
| 261 if (i == static_cast<unsigned>(m_suggestedIndex)) |
| 262 return toHTMLOptionElement(items[i])->value(); |
| 263 } |
| 264 } |
| 265 return ""; |
| 266 } |
| 267 |
| 268 void HTMLSelectElement::setSuggestedValue(const String& value) |
| 269 { |
| 270 if (value.isNull()) { |
| 271 setSuggestedIndex(-1); |
| 272 return; |
| 273 } |
| 274 |
| 275 const Vector<HTMLElement*>& items = listItems(); |
| 276 unsigned optionIndex = 0; |
| 277 for (unsigned i = 0; i < items.size(); ++i) { |
| 278 if (isHTMLOptionElement(items[i])) { |
| 279 if (toHTMLOptionElement(items[i])->value() == value) { |
| 280 setSuggestedIndex(optionIndex); |
| 281 return; |
| 282 } |
| 283 optionIndex++; |
| 284 } |
| 285 } |
| 286 |
| 287 setSuggestedIndex(-1); |
| 288 } |
| 289 |
256 bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const | 290 bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const |
257 { | 291 { |
258 if (name == alignAttr) { | 292 if (name == alignAttr) { |
259 // Don't map 'align' attribute. This matches what Firefox, Opera and IE
do. | 293 // Don't map 'align' attribute. This matches what Firefox, Opera and IE
do. |
260 // See http://bugs.webkit.org/show_bug.cgi?id=12072 | 294 // See http://bugs.webkit.org/show_bug.cgi?id=12072 |
261 return false; | 295 return false; |
262 } | 296 } |
263 | 297 |
264 return HTMLFormControlElementWithState::isPresentationAttribute(name); | 298 return HTMLFormControlElementWithState::isPresentationAttribute(name); |
265 } | 299 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } while (++diff); | 468 } while (++diff); |
435 } else { | 469 } else { |
436 const Vector<HTMLElement*>& items = listItems(); | 470 const Vector<HTMLElement*>& items = listItems(); |
437 | 471 |
438 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list | 472 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list |
439 // of elements that we intend to remove then attempt to remove them one
at a time. | 473 // of elements that we intend to remove then attempt to remove them one
at a time. |
440 Vector<RefPtr<Element> > itemsToRemove; | 474 Vector<RefPtr<Element> > itemsToRemove; |
441 size_t optionIndex = 0; | 475 size_t optionIndex = 0; |
442 for (size_t i = 0; i < items.size(); ++i) { | 476 for (size_t i = 0; i < items.size(); ++i) { |
443 Element* item = items[i]; | 477 Element* item = items[i]; |
444 if (item->hasLocalName(optionTag) && optionIndex++ >= newLen) { | 478 if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) { |
445 ASSERT(item->parentNode()); | 479 ASSERT(item->parentNode()); |
446 itemsToRemove.append(item); | 480 itemsToRemove.append(item); |
447 } | 481 } |
448 } | 482 } |
449 | 483 |
450 for (size_t i = 0; i < itemsToRemove.size(); ++i) { | 484 for (size_t i = 0; i < itemsToRemove.size(); ++i) { |
451 Element* item = itemsToRemove[i].get(); | 485 Element* item = itemsToRemove[i].get(); |
452 if (item->parentNode()) | 486 if (item->parentNode()) |
453 item->parentNode()->removeChild(item, exceptionState); | 487 item->parentNode()->removeChild(item, exceptionState); |
454 } | 488 } |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 } | 824 } |
791 | 825 |
792 return -1; | 826 return -1; |
793 } | 827 } |
794 | 828 |
795 void HTMLSelectElement::setSelectedIndex(int index) | 829 void HTMLSelectElement::setSelectedIndex(int index) |
796 { | 830 { |
797 selectOption(index, DeselectOtherOptions); | 831 selectOption(index, DeselectOtherOptions); |
798 } | 832 } |
799 | 833 |
| 834 int HTMLSelectElement::suggestedIndex() const |
| 835 { |
| 836 return m_suggestedIndex; |
| 837 } |
| 838 |
| 839 void HTMLSelectElement::setSuggestedIndex(int suggestedIndex) |
| 840 { |
| 841 m_suggestedIndex = suggestedIndex; |
| 842 |
| 843 if (RenderObject* renderer = this->renderer()) { |
| 844 renderer->updateFromElement(); |
| 845 if (renderer->isListBox()) |
| 846 toRenderListBox(renderer)->scrollToRevealElementAtListIndex(suggeste
dIndex); |
| 847 } |
| 848 } |
| 849 |
800 void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b
ool optionIsSelected) | 850 void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b
ool optionIsSelected) |
801 { | 851 { |
802 ASSERT(option->ownerSelectElement() == this); | 852 ASSERT(option->ownerSelectElement() == this); |
803 if (optionIsSelected) | 853 if (optionIsSelected) |
804 selectOption(option->index()); | 854 selectOption(option->index()); |
805 else if (!usesMenuList() || multiple()) | 855 else if (!usesMenuList() || multiple()) |
806 selectOption(-1); | 856 selectOption(-1); |
807 else | 857 else |
808 selectOption(nextSelectableListIndex(-1)); | 858 selectOption(nextSelectableListIndex(-1)); |
809 } | 859 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 break; | 982 break; |
933 } | 983 } |
934 return state; | 984 return state; |
935 } | 985 } |
936 | 986 |
937 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list
IndexStart, size_t listIndexEnd) const | 987 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list
IndexStart, size_t listIndexEnd) const |
938 { | 988 { |
939 const Vector<HTMLElement*>& items = listItems(); | 989 const Vector<HTMLElement*>& items = listItems(); |
940 size_t loopEndIndex = std::min(items.size(), listIndexEnd); | 990 size_t loopEndIndex = std::min(items.size(), listIndexEnd); |
941 for (size_t i = listIndexStart; i < loopEndIndex; ++i) { | 991 for (size_t i = listIndexStart; i < loopEndIndex; ++i) { |
942 if (!items[i]->hasLocalName(optionTag)) | 992 if (!isHTMLOptionElement(items[i])) |
943 continue; | 993 continue; |
944 if (toHTMLOptionElement(items[i])->value() == value) | 994 if (toHTMLOptionElement(items[i])->value() == value) |
945 return i; | 995 return i; |
946 } | 996 } |
947 return kNotFound; | 997 return kNotFound; |
948 } | 998 } |
949 | 999 |
950 void HTMLSelectElement::restoreFormControlState(const FormControlState& state) | 1000 void HTMLSelectElement::restoreFormControlState(const FormControlState& state) |
951 { | 1001 { |
952 recalcListItems(); | 1002 recalcListItems(); |
953 | 1003 |
954 const Vector<HTMLElement*>& items = listItems(); | 1004 const Vector<HTMLElement*>& items = listItems(); |
955 size_t itemsSize = items.size(); | 1005 size_t itemsSize = items.size(); |
956 if (!itemsSize) | 1006 if (!itemsSize) |
957 return; | 1007 return; |
958 | 1008 |
959 for (size_t i = 0; i < itemsSize; ++i) { | 1009 for (size_t i = 0; i < itemsSize; ++i) { |
960 if (!items[i]->hasLocalName(optionTag)) | 1010 if (!isHTMLOptionElement(items[i])) |
961 continue; | 1011 continue; |
962 toHTMLOptionElement(items[i])->setSelectedState(false); | 1012 toHTMLOptionElement(items[i])->setSelectedState(false); |
963 } | 1013 } |
964 | 1014 |
965 if (!multiple()) { | 1015 if (!multiple()) { |
966 size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize); | 1016 size_t foundIndex = searchOptionsForValue(state[0], 0, itemsSize); |
967 if (foundIndex != kNotFound) | 1017 if (foundIndex != kNotFound) |
968 toHTMLOptionElement(items[foundIndex])->setSelectedState(true); | 1018 toHTMLOptionElement(items[foundIndex])->setSelectedState(true); |
969 } else { | 1019 } else { |
970 size_t startIndex = 0; | 1020 size_t startIndex = 0; |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 { | 1617 { |
1568 return true; | 1618 return true; |
1569 } | 1619 } |
1570 | 1620 |
1571 bool HTMLSelectElement::supportsAutofocus() const | 1621 bool HTMLSelectElement::supportsAutofocus() const |
1572 { | 1622 { |
1573 return true; | 1623 return true; |
1574 } | 1624 } |
1575 | 1625 |
1576 } // namespace | 1626 } // namespace |
OLD | NEW |