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 13 matching lines...) Expand all Loading... |
24 * Boston, MA 02110-1301, USA. | 24 * Boston, MA 02110-1301, USA. |
25 * | 25 * |
26 */ | 26 */ |
27 | 27 |
28 #include "config.h" | 28 #include "config.h" |
29 #include "core/html/HTMLSelectElement.h" | 29 #include "core/html/HTMLSelectElement.h" |
30 | 30 |
31 #include "bindings/core/v8/ExceptionMessages.h" | 31 #include "bindings/core/v8/ExceptionMessages.h" |
32 #include "bindings/core/v8/ExceptionState.h" | 32 #include "bindings/core/v8/ExceptionState.h" |
33 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 33 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 34 #include "bindings/core/v8/UnionTypesCore.h" |
34 #include "core/HTMLNames.h" | 35 #include "core/HTMLNames.h" |
35 #include "core/accessibility/AXObjectCache.h" | 36 #include "core/accessibility/AXObjectCache.h" |
36 #include "core/dom/Attribute.h" | 37 #include "core/dom/Attribute.h" |
37 #include "core/dom/ElementTraversal.h" | 38 #include "core/dom/ElementTraversal.h" |
38 #include "core/dom/NodeListsNodeData.h" | 39 #include "core/dom/NodeListsNodeData.h" |
39 #include "core/dom/NodeRenderStyle.h" | 40 #include "core/dom/NodeRenderStyle.h" |
40 #include "core/dom/NodeTraversal.h" | 41 #include "core/dom/NodeTraversal.h" |
41 #include "core/events/GestureEvent.h" | 42 #include "core/events/GestureEvent.h" |
42 #include "core/events/KeyboardEvent.h" | 43 #include "core/events/KeyboardEvent.h" |
43 #include "core/events/MouseEvent.h" | 44 #include "core/events/MouseEvent.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 return optionToListIndex(selectedIndex()); | 205 return optionToListIndex(selectedIndex()); |
205 } | 206 } |
206 | 207 |
207 int HTMLSelectElement::activeSelectionEndListIndex() const | 208 int HTMLSelectElement::activeSelectionEndListIndex() const |
208 { | 209 { |
209 if (m_activeSelectionEndIndex >= 0) | 210 if (m_activeSelectionEndIndex >= 0) |
210 return m_activeSelectionEndIndex; | 211 return m_activeSelectionEndIndex; |
211 return lastSelectedListIndex(); | 212 return lastSelectedListIndex(); |
212 } | 213 } |
213 | 214 |
214 void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, Exception
State& exceptionState) | 215 void HTMLSelectElement::add(const HTMLOptionElementOrHTMLOptGroupElement& elemen
t, const HTMLElementOrLong& before, ExceptionState& exceptionState) |
215 { | 216 { |
216 // Make sure the element is ref'd and deref'd so we don't leak it. | 217 RefPtrWillBeRawPtr<HTMLElement> elementToInsert; |
217 RefPtrWillBeRawPtr<HTMLElement> protectNewChild(element); | 218 ASSERT(!element.isNull()); |
| 219 if (element.isHTMLOptionElement()) |
| 220 elementToInsert = element.getAsHTMLOptionElement(); |
| 221 else |
| 222 elementToInsert = element.getAsHTMLOptGroupElement(); |
218 | 223 |
219 if (!element || !(isHTMLOptionElement(element) || isHTMLOptGroupElement(elem
ent) || isHTMLHRElement(element))) | 224 RefPtrWillBeRawPtr<HTMLElement> beforeElement; |
220 return; | 225 if (before.isHTMLElement()) |
| 226 beforeElement = before.getAsHTMLElement(); |
| 227 else if (before.isLong()) |
| 228 beforeElement = options()->item(before.getAsLong()); |
| 229 else |
| 230 beforeElement = nullptr; |
221 | 231 |
222 insertBefore(element, before, exceptionState); | 232 insertBefore(elementToInsert, beforeElement.get(), exceptionState); |
223 setNeedsValidityCheck(); | 233 setNeedsValidityCheck(); |
224 } | 234 } |
225 | 235 |
226 void HTMLSelectElement::addBeforeOptionAtIndex(HTMLElement* element, int beforeI
ndex, ExceptionState& exceptionState) | |
227 { | |
228 HTMLOptionElement* beforeElement = options()->item(beforeIndex); | |
229 add(element, beforeElement, exceptionState); | |
230 } | |
231 | |
232 void HTMLSelectElement::remove(int optionIndex) | 236 void HTMLSelectElement::remove(int optionIndex) |
233 { | 237 { |
234 int listIndex = optionToListIndex(optionIndex); | 238 int listIndex = optionToListIndex(optionIndex); |
235 if (listIndex < 0) | 239 if (listIndex < 0) |
236 return; | 240 return; |
237 | 241 |
238 listItems()[listIndex]->remove(IGNORE_EXCEPTION); | 242 listItems()[listIndex]->remove(IGNORE_EXCEPTION); |
239 } | 243 } |
240 | 244 |
241 String HTMLSelectElement::value() const | 245 String HTMLSelectElement::value() const |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 HTMLOptionElement* HTMLSelectElement::item(unsigned index) | 462 HTMLOptionElement* HTMLSelectElement::item(unsigned index) |
459 { | 463 { |
460 return options()->item(index); | 464 return options()->item(index); |
461 } | 465 } |
462 | 466 |
463 void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
eptionState& exceptionState) | 467 void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
eptionState& exceptionState) |
464 { | 468 { |
465 if (index > maxSelectItems - 1) | 469 if (index > maxSelectItems - 1) |
466 index = maxSelectItems - 1; | 470 index = maxSelectItems - 1; |
467 int diff = index - length(); | 471 int diff = index - length(); |
468 RefPtrWillBeRawPtr<HTMLOptionElement> before = nullptr; | 472 HTMLOptionElementOrHTMLOptGroupElement element; |
| 473 element.setHTMLOptionElement(option); |
| 474 HTMLElementOrLong before; |
469 // Out of array bounds? First insert empty dummies. | 475 // Out of array bounds? First insert empty dummies. |
470 if (diff > 0) { | 476 if (diff > 0) { |
471 setLength(index, exceptionState); | 477 setLength(index, exceptionState); |
472 // Replace an existing entry? | 478 // Replace an existing entry? |
473 } else if (diff < 0) { | 479 } else if (diff < 0) { |
474 before = options()->item(index + 1); | 480 before.setHTMLElement(options()->item(index + 1)); |
475 remove(index); | 481 remove(index); |
476 } | 482 } |
477 // Finally add the new element. | 483 // Finally add the new element. |
478 if (!exceptionState.hadException()) { | 484 if (!exceptionState.hadException()) { |
479 add(option, before.get(), exceptionState); | 485 add(element, before, exceptionState); |
480 if (diff >= 0 && option->selected()) | 486 if (diff >= 0 && option->selected()) |
481 optionSelectionStateChanged(option, true); | 487 optionSelectionStateChanged(option, true); |
482 } | 488 } |
483 } | 489 } |
484 | 490 |
485 void HTMLSelectElement::setLength(unsigned newLen, ExceptionState& exceptionStat
e) | 491 void HTMLSelectElement::setLength(unsigned newLen, ExceptionState& exceptionStat
e) |
486 { | 492 { |
487 if (newLen > maxSelectItems) | 493 if (newLen > maxSelectItems) |
488 newLen = maxSelectItems; | 494 newLen = maxSelectItems; |
489 int diff = length() - newLen; | 495 int diff = length() - newLen; |
490 | 496 |
491 if (diff < 0) { // Add dummy elements. | 497 if (diff < 0) { // Add dummy elements. |
492 do { | 498 do { |
493 RefPtrWillBeRawPtr<Element> option = document().createElement(option
Tag, false); | 499 appendChild(document().createElement(optionTag, false), exceptionSta
te); |
494 ASSERT(option); | |
495 add(toHTMLElement(option), 0, exceptionState); | |
496 if (exceptionState.hadException()) | 500 if (exceptionState.hadException()) |
497 break; | 501 break; |
498 } while (++diff); | 502 } while (++diff); |
499 } else { | 503 } else { |
500 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listIte
ms(); | 504 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listIte
ms(); |
501 | 505 |
502 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list | 506 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list |
503 // of elements that we intend to remove then attempt to remove them one
at a time. | 507 // of elements that we intend to remove then attempt to remove them one
at a time. |
504 WillBeHeapVector<RefPtrWillBeMember<Element>> itemsToRemove; | 508 WillBeHeapVector<RefPtrWillBeMember<Element>> itemsToRemove; |
505 size_t optionIndex = 0; | 509 size_t optionIndex = 0; |
(...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 int focusedIndex = activeSelectionEndListIndex(); | 1774 int focusedIndex = activeSelectionEndListIndex(); |
1771 if (focusedIndex < 0) | 1775 if (focusedIndex < 0) |
1772 focusedIndex = firstSelectableListIndex(); | 1776 focusedIndex = firstSelectableListIndex(); |
1773 if (focusedIndex < 0) | 1777 if (focusedIndex < 0) |
1774 return nullptr; | 1778 return nullptr; |
1775 HTMLElement* focused = listItems()[focusedIndex]; | 1779 HTMLElement* focused = listItems()[focusedIndex]; |
1776 return isHTMLOptionElement(focused) ? toHTMLOptionElement(focused) : nullptr
; | 1780 return isHTMLOptionElement(focused) ? toHTMLOptionElement(focused) : nullptr
; |
1777 } | 1781 } |
1778 | 1782 |
1779 } // namespace | 1783 } // namespace |
OLD | NEW |