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 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 // Otherwise, it returns |listIndex|. | 466 // Otherwise, it returns |listIndex|. |
467 // Valid means that it is enabled and an option element. | 467 // Valid means that it is enabled and an option element. |
468 int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in
t skip) const | 468 int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in
t skip) const |
469 { | 469 { |
470 ASSERT(direction == -1 || direction == 1); | 470 ASSERT(direction == -1 || direction == 1); |
471 const Vector<HTMLElement*>& listItems = this->listItems(); | 471 const Vector<HTMLElement*>& listItems = this->listItems(); |
472 int lastGoodIndex = listIndex; | 472 int lastGoodIndex = listIndex; |
473 int size = listItems.size(); | 473 int size = listItems.size(); |
474 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex +
= direction) { | 474 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex +
= direction) { |
475 --skip; | 475 --skip; |
476 if (!listItems[listIndex]->isDisabledFormControl() && listItems[listInde
x]->hasTagName(optionTag)) { | 476 if (!listItems[listIndex]->isDisabledFormControl() && isHTMLOptionElemen
t(*listItems[listIndex])) { |
477 lastGoodIndex = listIndex; | 477 lastGoodIndex = listIndex; |
478 if (skip <= 0) | 478 if (skip <= 0) |
479 break; | 479 break; |
480 } | 480 } |
481 } | 481 } |
482 return lastGoodIndex; | 482 return lastGoodIndex; |
483 } | 483 } |
484 | 484 |
485 int HTMLSelectElement::nextSelectableListIndex(int startIndex) const | 485 int HTMLSelectElement::nextSelectableListIndex(int startIndex) const |
486 { | 486 { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 { | 548 { |
549 if (usesMenuList()) { | 549 if (usesMenuList()) { |
550 m_lastOnChangeIndex = selectedIndex(); | 550 m_lastOnChangeIndex = selectedIndex(); |
551 return; | 551 return; |
552 } | 552 } |
553 | 553 |
554 m_lastOnChangeSelection.clear(); | 554 m_lastOnChangeSelection.clear(); |
555 const Vector<HTMLElement*>& items = listItems(); | 555 const Vector<HTMLElement*>& items = listItems(); |
556 for (unsigned i = 0; i < items.size(); ++i) { | 556 for (unsigned i = 0; i < items.size(); ++i) { |
557 HTMLElement* element = items[i]; | 557 HTMLElement* element = items[i]; |
558 m_lastOnChangeSelection.append(element->hasTagName(optionTag) && toHTMLO
ptionElement(element)->selected()); | 558 m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOp
tionElement(element)->selected()); |
559 } | 559 } |
560 } | 560 } |
561 | 561 |
562 void HTMLSelectElement::setActiveSelectionAnchorIndex(int index) | 562 void HTMLSelectElement::setActiveSelectionAnchorIndex(int index) |
563 { | 563 { |
564 m_activeSelectionAnchorIndex = index; | 564 m_activeSelectionAnchorIndex = index; |
565 | 565 |
566 // Cache the selection state so we can restore the old selection as the new | 566 // Cache the selection state so we can restore the old selection as the new |
567 // selection pivots around this anchor index. | 567 // selection pivots around this anchor index. |
568 m_cachedStateForActiveSelection.clear(); | 568 m_cachedStateForActiveSelection.clear(); |
569 | 569 |
570 const Vector<HTMLElement*>& items = listItems(); | 570 const Vector<HTMLElement*>& items = listItems(); |
571 for (unsigned i = 0; i < items.size(); ++i) { | 571 for (unsigned i = 0; i < items.size(); ++i) { |
572 HTMLElement* element = items[i]; | 572 HTMLElement* element = items[i]; |
573 m_cachedStateForActiveSelection.append(element->hasTagName(optionTag) &&
toHTMLOptionElement(element)->selected()); | 573 m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) &&
toHTMLOptionElement(element)->selected()); |
574 } | 574 } |
575 } | 575 } |
576 | 576 |
577 void HTMLSelectElement::setActiveSelectionEndIndex(int index) | 577 void HTMLSelectElement::setActiveSelectionEndIndex(int index) |
578 { | 578 { |
579 m_activeSelectionEndIndex = index; | 579 m_activeSelectionEndIndex = index; |
580 } | 580 } |
581 | 581 |
582 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions) | 582 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions) |
583 { | 583 { |
584 ASSERT(renderer() && (renderer()->isListBox() || m_multiple)); | 584 ASSERT(renderer() && (renderer()->isListBox() || m_multiple)); |
585 ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0); | 585 ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0); |
586 | 586 |
587 unsigned start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex
); | 587 unsigned start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex
); |
588 unsigned end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex); | 588 unsigned end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex); |
589 | 589 |
590 const Vector<HTMLElement*>& items = listItems(); | 590 const Vector<HTMLElement*>& items = listItems(); |
591 for (unsigned i = 0; i < items.size(); ++i) { | 591 for (unsigned i = 0; i < items.size(); ++i) { |
592 HTMLElement* element = items[i]; | 592 HTMLElement* element = items[i]; |
593 if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isD
isabledFormControl()) | 593 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi
sabledFormControl()) |
594 continue; | 594 continue; |
595 | 595 |
596 if (i >= start && i <= end) | 596 if (i >= start && i <= end) |
597 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat
e); | 597 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat
e); |
598 else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.si
ze()) | 598 else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.si
ze()) |
599 toHTMLOptionElement(element)->setSelectedState(false); | 599 toHTMLOptionElement(element)->setSelectedState(false); |
600 else | 600 else |
601 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv
eSelection[i]); | 601 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv
eSelection[i]); |
602 } | 602 } |
603 | 603 |
(...skipping 13 matching lines...) Expand all Loading... |
617 // FIXME: Why? This looks unreasonable. | 617 // FIXME: Why? This looks unreasonable. |
618 if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != i
tems.size()) { | 618 if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != i
tems.size()) { |
619 dispatchFormControlChangeEvent(); | 619 dispatchFormControlChangeEvent(); |
620 return; | 620 return; |
621 } | 621 } |
622 | 622 |
623 // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent. | 623 // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent. |
624 bool fireOnChange = false; | 624 bool fireOnChange = false; |
625 for (unsigned i = 0; i < items.size(); ++i) { | 625 for (unsigned i = 0; i < items.size(); ++i) { |
626 HTMLElement* element = items[i]; | 626 HTMLElement* element = items[i]; |
627 bool selected = element->hasTagName(optionTag) && toHTMLOptionElement(el
ement)->selected(); | 627 bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(ele
ment)->selected(); |
628 if (selected != m_lastOnChangeSelection[i]) | 628 if (selected != m_lastOnChangeSelection[i]) |
629 fireOnChange = true; | 629 fireOnChange = true; |
630 m_lastOnChangeSelection[i] = selected; | 630 m_lastOnChangeSelection[i] = selected; |
631 } | 631 } |
632 | 632 |
633 if (fireOnChange) { | 633 if (fireOnChange) { |
634 RefPtr<HTMLSelectElement> protector(this); | 634 RefPtr<HTMLSelectElement> protector(this); |
635 dispatchInputEvent(); | 635 dispatchInputEvent(); |
636 dispatchFormControlChangeEvent(); | 636 dispatchFormControlChangeEvent(); |
637 } | 637 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 for (Element* currentElement = ElementTraversal::firstWithin(*this); current
Element; ) { | 725 for (Element* currentElement = ElementTraversal::firstWithin(*this); current
Element; ) { |
726 if (!currentElement->isHTMLElement()) { | 726 if (!currentElement->isHTMLElement()) { |
727 currentElement = ElementTraversal::nextSkippingChildren(*currentElem
ent, this); | 727 currentElement = ElementTraversal::nextSkippingChildren(*currentElem
ent, this); |
728 continue; | 728 continue; |
729 } | 729 } |
730 HTMLElement& current = toHTMLElement(*currentElement); | 730 HTMLElement& current = toHTMLElement(*currentElement); |
731 | 731 |
732 // optgroup tags may not nest. However, both FireFox and IE will | 732 // optgroup tags may not nest. However, both FireFox and IE will |
733 // flatten the tree automatically, so we follow suit. | 733 // flatten the tree automatically, so we follow suit. |
734 // (http://www.w3.org/TR/html401/interact/forms.html#h-17.6) | 734 // (http://www.w3.org/TR/html401/interact/forms.html#h-17.6) |
735 if (current.hasTagName(optgroupTag)) { | 735 if (isHTMLOptGroupElement(current)) { |
736 m_listItems.append(¤t); | 736 m_listItems.append(¤t); |
737 if (Element* nextElement = ElementTraversal::firstWithin(current)) { | 737 if (Element* nextElement = ElementTraversal::firstWithin(current)) { |
738 currentElement = nextElement; | 738 currentElement = nextElement; |
739 continue; | 739 continue; |
740 } | 740 } |
741 } | 741 } |
742 | 742 |
743 if (current.hasTagName(optionTag)) { | 743 if (isHTMLOptionElement(current)) { |
744 m_listItems.append(¤t); | 744 m_listItems.append(¤t); |
745 | 745 |
746 if (updateSelectedStates && !m_multiple) { | 746 if (updateSelectedStates && !m_multiple) { |
747 HTMLOptionElement& option = toHTMLOptionElement(current); | 747 HTMLOptionElement& option = toHTMLOptionElement(current); |
748 if (!firstOption) | 748 if (!firstOption) |
749 firstOption = &option; | 749 firstOption = &option; |
750 if (option.selected()) { | 750 if (option.selected()) { |
751 if (foundSelected) | 751 if (foundSelected) |
752 foundSelected->setSelectedState(false); | 752 foundSelected->setSelectedState(false); |
753 foundSelected = &option; | 753 foundSelected = &option; |
754 } else if (m_size <= 1 && !foundSelected && !option.isDisabledFo
rmControl()) { | 754 } else if (m_size <= 1 && !foundSelected && !option.isDisabledFo
rmControl()) { |
755 foundSelected = &option; | 755 foundSelected = &option; |
756 foundSelected->setSelectedState(true); | 756 foundSelected->setSelectedState(true); |
757 } | 757 } |
758 } | 758 } |
759 } | 759 } |
760 | 760 |
761 if (current.hasTagName(hrTag)) | 761 if (isHTMLHRElement(current)) |
762 m_listItems.append(¤t); | 762 m_listItems.append(¤t); |
763 | 763 |
764 // In conforming HTML code, only <optgroup> and <option> will be found | 764 // In conforming HTML code, only <optgroup> and <option> will be found |
765 // within a <select>. We call NodeTraversal::nextSkippingChildren so tha
t we only step | 765 // within a <select>. We call NodeTraversal::nextSkippingChildren so tha
t we only step |
766 // into those tags that we choose to. For web-compat, we should cope | 766 // into those tags that we choose to. For web-compat, we should cope |
767 // with the case where odd tags like a <div> have been added but we | 767 // with the case where odd tags like a <div> have been added but we |
768 // handle this because such tags have already been removed from the | 768 // handle this because such tags have already been removed from the |
769 // <select>'s subtree at this point. | 769 // <select>'s subtree at this point. |
770 currentElement = ElementTraversal::nextSkippingChildren(*currentElement,
this); | 770 currentElement = ElementTraversal::nextSkippingChildren(*currentElement,
this); |
771 } | 771 } |
772 | 772 |
773 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected()
) | 773 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected()
) |
774 firstOption->setSelectedState(true); | 774 firstOption->setSelectedState(true); |
775 } | 775 } |
776 | 776 |
777 int HTMLSelectElement::selectedIndex() const | 777 int HTMLSelectElement::selectedIndex() const |
778 { | 778 { |
779 unsigned index = 0; | 779 unsigned index = 0; |
780 | 780 |
781 // Return the number of the first option selected. | 781 // Return the number of the first option selected. |
782 const Vector<HTMLElement*>& items = listItems(); | 782 const Vector<HTMLElement*>& items = listItems(); |
783 for (size_t i = 0; i < items.size(); ++i) { | 783 for (size_t i = 0; i < items.size(); ++i) { |
784 HTMLElement* element = items[i]; | 784 HTMLElement* element = items[i]; |
785 if (element->hasTagName(optionTag)) { | 785 if (isHTMLOptionElement(*element)) { |
786 if (toHTMLOptionElement(element)->selected()) | 786 if (toHTMLOptionElement(*element).selected()) |
787 return index; | 787 return index; |
788 ++index; | 788 ++index; |
789 } | 789 } |
790 } | 790 } |
791 | 791 |
792 return -1; | 792 return -1; |
793 } | 793 } |
794 | 794 |
795 void HTMLSelectElement::setSelectedIndex(int index) | 795 void HTMLSelectElement::setSelectedIndex(int index) |
796 { | 796 { |
(...skipping 14 matching lines...) Expand all Loading... |
811 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) | 811 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) |
812 { | 812 { |
813 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions); | 813 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions); |
814 | 814 |
815 const Vector<HTMLElement*>& items = listItems(); | 815 const Vector<HTMLElement*>& items = listItems(); |
816 int listIndex = optionToListIndex(optionIndex); | 816 int listIndex = optionToListIndex(optionIndex); |
817 | 817 |
818 HTMLElement* element = 0; | 818 HTMLElement* element = 0; |
819 if (listIndex >= 0) { | 819 if (listIndex >= 0) { |
820 element = items[listIndex]; | 820 element = items[listIndex]; |
821 if (element->hasTagName(optionTag)) { | 821 if (isHTMLOptionElement(*element)) { |
822 if (m_activeSelectionAnchorIndex < 0 || shouldDeselect) | 822 if (m_activeSelectionAnchorIndex < 0 || shouldDeselect) |
823 setActiveSelectionAnchorIndex(listIndex); | 823 setActiveSelectionAnchorIndex(listIndex); |
824 if (m_activeSelectionEndIndex < 0 || shouldDeselect) | 824 if (m_activeSelectionEndIndex < 0 || shouldDeselect) |
825 setActiveSelectionEndIndex(listIndex); | 825 setActiveSelectionEndIndex(listIndex); |
826 toHTMLOptionElement(element)->setSelectedState(true); | 826 toHTMLOptionElement(*element).setSelectedState(true); |
827 } | 827 } |
828 } | 828 } |
829 | 829 |
830 if (shouldDeselect) | 830 if (shouldDeselect) |
831 deselectItemsWithoutValidation(element); | 831 deselectItemsWithoutValidation(element); |
832 | 832 |
833 // For the menu list case, this is what makes the selected element appear. | 833 // For the menu list case, this is what makes the selected element appear. |
834 if (RenderObject* renderer = this->renderer()) | 834 if (RenderObject* renderer = this->renderer()) |
835 renderer->updateFromElement(); | 835 renderer->updateFromElement(); |
836 | 836 |
(...skipping 17 matching lines...) Expand all Loading... |
854 | 854 |
855 int HTMLSelectElement::optionToListIndex(int optionIndex) const | 855 int HTMLSelectElement::optionToListIndex(int optionIndex) const |
856 { | 856 { |
857 const Vector<HTMLElement*>& items = listItems(); | 857 const Vector<HTMLElement*>& items = listItems(); |
858 int listSize = static_cast<int>(items.size()); | 858 int listSize = static_cast<int>(items.size()); |
859 if (optionIndex < 0 || optionIndex >= listSize) | 859 if (optionIndex < 0 || optionIndex >= listSize) |
860 return -1; | 860 return -1; |
861 | 861 |
862 int optionIndex2 = -1; | 862 int optionIndex2 = -1; |
863 for (int listIndex = 0; listIndex < listSize; ++listIndex) { | 863 for (int listIndex = 0; listIndex < listSize; ++listIndex) { |
864 if (items[listIndex]->hasTagName(optionTag)) { | 864 if (isHTMLOptionElement(*items[listIndex])) { |
865 ++optionIndex2; | 865 ++optionIndex2; |
866 if (optionIndex2 == optionIndex) | 866 if (optionIndex2 == optionIndex) |
867 return listIndex; | 867 return listIndex; |
868 } | 868 } |
869 } | 869 } |
870 | 870 |
871 return -1; | 871 return -1; |
872 } | 872 } |
873 | 873 |
874 int HTMLSelectElement::listToOptionIndex(int listIndex) const | 874 int HTMLSelectElement::listToOptionIndex(int listIndex) const |
875 { | 875 { |
876 const Vector<HTMLElement*>& items = listItems(); | 876 const Vector<HTMLElement*>& items = listItems(); |
877 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !items[l
istIndex]->hasTagName(optionTag)) | 877 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLO
ptionElement(*items[listIndex])) |
878 return -1; | 878 return -1; |
879 | 879 |
880 // Actual index of option not counting OPTGROUP entries that may be in list. | 880 // Actual index of option not counting OPTGROUP entries that may be in list. |
881 int optionIndex = 0; | 881 int optionIndex = 0; |
882 for (int i = 0; i < listIndex; ++i) { | 882 for (int i = 0; i < listIndex; ++i) { |
883 if (items[i]->hasTagName(optionTag)) | 883 if (isHTMLOptionElement(*items[i])) |
884 ++optionIndex; | 884 ++optionIndex; |
885 } | 885 } |
886 | 886 |
887 return optionIndex; | 887 return optionIndex; |
888 } | 888 } |
889 | 889 |
890 void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType
type) | 890 void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType
type) |
891 { | 891 { |
892 // Save the selection so it can be compared to the new selection when | 892 // Save the selection so it can be compared to the new selection when |
893 // dispatching change events during blur event dispatch. | 893 // dispatching change events during blur event dispatch. |
(...skipping 10 matching lines...) Expand all Loading... |
904 if (usesMenuList()) | 904 if (usesMenuList()) |
905 dispatchInputAndChangeEventForMenuList(); | 905 dispatchInputAndChangeEventForMenuList(); |
906 HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement); | 906 HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement); |
907 } | 907 } |
908 | 908 |
909 void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme
nt) | 909 void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme
nt) |
910 { | 910 { |
911 const Vector<HTMLElement*>& items = listItems(); | 911 const Vector<HTMLElement*>& items = listItems(); |
912 for (unsigned i = 0; i < items.size(); ++i) { | 912 for (unsigned i = 0; i < items.size(); ++i) { |
913 HTMLElement* element = items[i]; | 913 HTMLElement* element = items[i]; |
914 if (element != excludeElement && element->hasTagName(optionTag)) | 914 if (element != excludeElement && isHTMLOptionElement(*element)) |
915 toHTMLOptionElement(element)->setSelectedState(false); | 915 toHTMLOptionElement(element)->setSelectedState(false); |
916 } | 916 } |
917 } | 917 } |
918 | 918 |
919 FormControlState HTMLSelectElement::saveFormControlState() const | 919 FormControlState HTMLSelectElement::saveFormControlState() const |
920 { | 920 { |
921 const Vector<HTMLElement*>& items = listItems(); | 921 const Vector<HTMLElement*>& items = listItems(); |
922 size_t length = items.size(); | 922 size_t length = items.size(); |
923 FormControlState state; | 923 FormControlState state; |
924 for (unsigned i = 0; i < length; ++i) { | 924 for (unsigned i = 0; i < length; ++i) { |
925 if (!items[i]->hasTagName(optionTag)) | 925 if (!isHTMLOptionElement(*items[i])) |
926 continue; | 926 continue; |
927 HTMLOptionElement* option = toHTMLOptionElement(items[i]); | 927 HTMLOptionElement* option = toHTMLOptionElement(items[i]); |
928 if (!option->selected()) | 928 if (!option->selected()) |
929 continue; | 929 continue; |
930 state.append(option->value()); | 930 state.append(option->value()); |
931 if (!multiple()) | 931 if (!multiple()) |
932 break; | 932 break; |
933 } | 933 } |
934 return state; | 934 return state; |
935 } | 935 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 { | 997 { |
998 const AtomicString& name = this->name(); | 998 const AtomicString& name = this->name(); |
999 if (name.isEmpty()) | 999 if (name.isEmpty()) |
1000 return false; | 1000 return false; |
1001 | 1001 |
1002 bool successful = false; | 1002 bool successful = false; |
1003 const Vector<HTMLElement*>& items = listItems(); | 1003 const Vector<HTMLElement*>& items = listItems(); |
1004 | 1004 |
1005 for (unsigned i = 0; i < items.size(); ++i) { | 1005 for (unsigned i = 0; i < items.size(); ++i) { |
1006 HTMLElement* element = items[i]; | 1006 HTMLElement* element = items[i]; |
1007 if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->sele
cted() && !toHTMLOptionElement(element)->isDisabledFormControl()) { | 1007 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) { |
1008 list.appendData(name, toHTMLOptionElement(element)->value()); | 1008 list.appendData(name, toHTMLOptionElement(*element).value()); |
1009 successful = true; | 1009 successful = true; |
1010 } | 1010 } |
1011 } | 1011 } |
1012 | 1012 |
1013 // It's possible that this is a menulist with multiple options and nothing | 1013 // It's possible that this is a menulist with multiple options and nothing |
1014 // will be submitted (!successful). We won't send a unselected non-disabled | 1014 // will be submitted (!successful). We won't send a unselected non-disabled |
1015 // option as fallback. This behavior matches to other browsers. | 1015 // option as fallback. This behavior matches to other browsers. |
1016 return successful; | 1016 return successful; |
1017 } | 1017 } |
1018 | 1018 |
1019 void HTMLSelectElement::resetImpl() | 1019 void HTMLSelectElement::resetImpl() |
1020 { | 1020 { |
1021 HTMLOptionElement* firstOption = 0; | 1021 HTMLOptionElement* firstOption = 0; |
1022 HTMLOptionElement* selectedOption = 0; | 1022 HTMLOptionElement* selectedOption = 0; |
1023 | 1023 |
1024 const Vector<HTMLElement*>& items = listItems(); | 1024 const Vector<HTMLElement*>& items = listItems(); |
1025 for (unsigned i = 0; i < items.size(); ++i) { | 1025 for (unsigned i = 0; i < items.size(); ++i) { |
1026 HTMLElement* element = items[i]; | 1026 HTMLElement* element = items[i]; |
1027 if (!element->hasTagName(optionTag)) | 1027 if (!isHTMLOptionElement(*element)) |
1028 continue; | 1028 continue; |
1029 | 1029 |
1030 if (items[i]->fastHasAttribute(selectedAttr)) { | 1030 if (items[i]->fastHasAttribute(selectedAttr)) { |
1031 if (selectedOption && !m_multiple) | 1031 if (selectedOption && !m_multiple) |
1032 selectedOption->setSelectedState(false); | 1032 selectedOption->setSelectedState(false); |
1033 toHTMLOptionElement(element)->setSelectedState(true); | 1033 toHTMLOptionElement(element)->setSelectedState(true); |
1034 selectedOption = toHTMLOptionElement(element); | 1034 selectedOption = toHTMLOptionElement(element); |
1035 } else | 1035 } else |
1036 toHTMLOptionElement(element)->setSelectedState(false); | 1036 toHTMLOptionElement(element)->setSelectedState(false); |
1037 | 1037 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 // Save the selection so it can be compared to the new selection when | 1222 // Save the selection so it can be compared to the new selection when |
1223 // dispatching change events during mouseup, or after autoscroll finishes. | 1223 // dispatching change events during mouseup, or after autoscroll finishes. |
1224 saveLastSelection(); | 1224 saveLastSelection(); |
1225 | 1225 |
1226 m_activeSelectionState = true; | 1226 m_activeSelectionState = true; |
1227 | 1227 |
1228 bool shiftSelect = m_multiple && shift; | 1228 bool shiftSelect = m_multiple && shift; |
1229 bool multiSelect = m_multiple && multi && !shift; | 1229 bool multiSelect = m_multiple && multi && !shift; |
1230 | 1230 |
1231 HTMLElement* clickedElement = listItems()[listIndex]; | 1231 HTMLElement* clickedElement = listItems()[listIndex]; |
1232 if (clickedElement->hasTagName(optionTag)) { | 1232 ASSERT(clickedElement); |
| 1233 if (isHTMLOptionElement(*clickedElement)) { |
1233 // Keep track of whether an active selection (like during drag | 1234 // Keep track of whether an active selection (like during drag |
1234 // selection), should select or deselect. | 1235 // selection), should select or deselect. |
1235 if (toHTMLOptionElement(clickedElement)->selected() && multiSelect) | 1236 if (toHTMLOptionElement(*clickedElement).selected() && multiSelect) |
1236 m_activeSelectionState = false; | 1237 m_activeSelectionState = false; |
1237 if (!m_activeSelectionState) | 1238 if (!m_activeSelectionState) |
1238 toHTMLOptionElement(clickedElement)->setSelectedState(false); | 1239 toHTMLOptionElement(*clickedElement).setSelectedState(false); |
1239 } | 1240 } |
1240 | 1241 |
1241 // If we're not in any special multiple selection mode, then deselect all | 1242 // If we're not in any special multiple selection mode, then deselect all |
1242 // other items, excluding the clicked option. If no option was clicked, then | 1243 // other items, excluding the clicked option. If no option was clicked, then |
1243 // this will deselect all items in the list. | 1244 // this will deselect all items in the list. |
1244 if (!shiftSelect && !multiSelect) | 1245 if (!shiftSelect && !multiSelect) |
1245 deselectItemsWithoutValidation(clickedElement); | 1246 deselectItemsWithoutValidation(clickedElement); |
1246 | 1247 |
1247 // If the anchor hasn't been set, and we're doing a single selection or a | 1248 // If the anchor hasn't been set, and we're doing a single selection or a |
1248 // shift selection, then initialize the anchor to the first selected index. | 1249 // shift selection, then initialize the anchor to the first selected index. |
1249 if (m_activeSelectionAnchorIndex < 0 && !multiSelect) | 1250 if (m_activeSelectionAnchorIndex < 0 && !multiSelect) |
1250 setActiveSelectionAnchorIndex(selectedIndex()); | 1251 setActiveSelectionAnchorIndex(selectedIndex()); |
1251 | 1252 |
1252 // Set the selection state of the clicked option. | 1253 // Set the selection state of the clicked option. |
1253 if (clickedElement->hasTagName(optionTag) && !toHTMLOptionElement(clickedEle
ment)->isDisabledFormControl()) | 1254 if (isHTMLOptionElement(*clickedElement) && !toHTMLOptionElement(*clickedEle
ment).isDisabledFormControl()) |
1254 toHTMLOptionElement(clickedElement)->setSelectedState(true); | 1255 toHTMLOptionElement(*clickedElement).setSelectedState(true); |
1255 | 1256 |
1256 // If there was no selectedIndex() for the previous initialization, or If | 1257 // If there was no selectedIndex() for the previous initialization, or If |
1257 // we're doing a single selection, or a multiple selection (using cmd or | 1258 // we're doing a single selection, or a multiple selection (using cmd or |
1258 // ctrl), then initialize the anchor index to the listIndex that just got | 1259 // ctrl), then initialize the anchor index to the listIndex that just got |
1259 // clicked. | 1260 // clicked. |
1260 if (m_activeSelectionAnchorIndex < 0 || !shiftSelect) | 1261 if (m_activeSelectionAnchorIndex < 0 || !shiftSelect) |
1261 setActiveSelectionAnchorIndex(listIndex); | 1262 setActiveSelectionAnchorIndex(listIndex); |
1262 | 1263 |
1263 setActiveSelectionEndIndex(listIndex); | 1264 setActiveSelectionEndIndex(listIndex); |
1264 updateListBoxSelection(!multiSelect); | 1265 updateListBoxSelection(!multiSelect); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 } | 1454 } |
1454 } | 1455 } |
1455 HTMLFormControlElementWithState::defaultEventHandler(event); | 1456 HTMLFormControlElementWithState::defaultEventHandler(event); |
1456 } | 1457 } |
1457 | 1458 |
1458 int HTMLSelectElement::lastSelectedListIndex() const | 1459 int HTMLSelectElement::lastSelectedListIndex() const |
1459 { | 1460 { |
1460 const Vector<HTMLElement*>& items = listItems(); | 1461 const Vector<HTMLElement*>& items = listItems(); |
1461 for (size_t i = items.size(); i;) { | 1462 for (size_t i = items.size(); i;) { |
1462 HTMLElement* element = items[--i]; | 1463 HTMLElement* element = items[--i]; |
1463 if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->sele
cted()) | 1464 if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selec
ted()) |
1464 return i; | 1465 return i; |
1465 } | 1466 } |
1466 return -1; | 1467 return -1; |
1467 } | 1468 } |
1468 | 1469 |
1469 int HTMLSelectElement::indexOfSelectedOption() const | 1470 int HTMLSelectElement::indexOfSelectedOption() const |
1470 { | 1471 { |
1471 return optionToListIndex(selectedIndex()); | 1472 return optionToListIndex(selectedIndex()); |
1472 } | 1473 } |
1473 | 1474 |
1474 int HTMLSelectElement::optionCount() const | 1475 int HTMLSelectElement::optionCount() const |
1475 { | 1476 { |
1476 return listItems().size(); | 1477 return listItems().size(); |
1477 } | 1478 } |
1478 | 1479 |
1479 String HTMLSelectElement::optionAtIndex(int index) const | 1480 String HTMLSelectElement::optionAtIndex(int index) const |
1480 { | 1481 { |
1481 const Vector<HTMLElement*>& items = listItems(); | 1482 const Vector<HTMLElement*>& items = listItems(); |
1482 | 1483 |
1483 HTMLElement* element = items[index]; | 1484 HTMLElement* element = items[index]; |
1484 if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisab
ledFormControl()) | 1485 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabl
edFormControl()) |
1485 return String(); | 1486 return String(); |
1486 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); | 1487 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); |
1487 } | 1488 } |
1488 | 1489 |
1489 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) | 1490 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) |
1490 { | 1491 { |
1491 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea
d::CycleFirstChar); | 1492 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea
d::CycleFirstChar); |
1492 if (index < 0) | 1493 if (index < 0) |
1493 return; | 1494 return; |
1494 selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchInputA
ndChangeEvent | UserDriven); | 1495 selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchInputA
ndChangeEvent | UserDriven); |
(...skipping 15 matching lines...) Expand all Loading... |
1510 { | 1511 { |
1511 // First bring into focus the list box. | 1512 // First bring into focus the list box. |
1512 if (!focused()) | 1513 if (!focused()) |
1513 accessKeyAction(false); | 1514 accessKeyAction(false); |
1514 | 1515 |
1515 // If this index is already selected, unselect. otherwise update the selecte
d index. | 1516 // If this index is already selected, unselect. otherwise update the selecte
d index. |
1516 const Vector<HTMLElement*>& items = listItems(); | 1517 const Vector<HTMLElement*>& items = listItems(); |
1517 int listIndex = optionToListIndex(index); | 1518 int listIndex = optionToListIndex(index); |
1518 if (listIndex >= 0) { | 1519 if (listIndex >= 0) { |
1519 HTMLElement* element = items[listIndex]; | 1520 HTMLElement* element = items[listIndex]; |
1520 if (element->hasTagName(optionTag)) { | 1521 if (isHTMLOptionElement(*element)) { |
1521 if (toHTMLOptionElement(element)->selected()) | 1522 if (toHTMLOptionElement(*element).selected()) |
1522 toHTMLOptionElement(element)->setSelectedState(false); | 1523 toHTMLOptionElement(*element).setSelectedState(false); |
1523 else | 1524 else |
1524 selectOption(index, DispatchInputAndChangeEvent | UserDriven); | 1525 selectOption(index, DispatchInputAndChangeEvent | UserDriven); |
1525 } | 1526 } |
1526 } | 1527 } |
1527 | 1528 |
1528 if (usesMenuList()) | 1529 if (usesMenuList()) |
1529 dispatchInputAndChangeEventForMenuList(); | 1530 dispatchInputAndChangeEventForMenuList(); |
1530 else | 1531 else |
1531 listBoxOnChange(); | 1532 listBoxOnChange(); |
1532 | 1533 |
1533 scrollToSelection(); | 1534 scrollToSelection(); |
1534 } | 1535 } |
1535 | 1536 |
1536 unsigned HTMLSelectElement::length() const | 1537 unsigned HTMLSelectElement::length() const |
1537 { | 1538 { |
1538 unsigned options = 0; | 1539 unsigned options = 0; |
1539 | 1540 |
1540 const Vector<HTMLElement*>& items = listItems(); | 1541 const Vector<HTMLElement*>& items = listItems(); |
1541 for (unsigned i = 0; i < items.size(); ++i) { | 1542 for (unsigned i = 0; i < items.size(); ++i) { |
1542 if (items[i]->hasTagName(optionTag)) | 1543 if (isHTMLOptionElement(*items[i])) |
1543 ++options; | 1544 ++options; |
1544 } | 1545 } |
1545 | 1546 |
1546 return options; | 1547 return options; |
1547 } | 1548 } |
1548 | 1549 |
1549 void HTMLSelectElement::finishParsingChildren() | 1550 void HTMLSelectElement::finishParsingChildren() |
1550 { | 1551 { |
1551 HTMLFormControlElementWithState::finishParsingChildren(); | 1552 HTMLFormControlElementWithState::finishParsingChildren(); |
1552 updateListItemSelectedStates(); | 1553 updateListItemSelectedStates(); |
(...skipping 13 matching lines...) Expand all Loading... |
1566 { | 1567 { |
1567 return true; | 1568 return true; |
1568 } | 1569 } |
1569 | 1570 |
1570 bool HTMLSelectElement::supportsAutofocus() const | 1571 bool HTMLSelectElement::supportsAutofocus() const |
1571 { | 1572 { |
1572 return true; | 1573 return true; |
1573 } | 1574 } |
1574 | 1575 |
1575 } // namespace | 1576 } // namespace |
OLD | NEW |