Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(518)

Side by Side Diff: Source/core/html/HTMLSelectElement.cpp

Issue 195813003: Use new is*Element() helper functions further more in HTML code (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix bad assertion Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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(&current); 736 m_listItems.append(&current);
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(&current); 744 m_listItems.append(&current);
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(&current); 762 m_listItems.append(&current);
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698