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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 lazyReattachIfAttached(); | 350 lazyReattachIfAttached(); |
351 setRecalcListItems(); | 351 setRecalcListItems(); |
352 } | 352 } |
353 } else if (name == multipleAttr) | 353 } else if (name == multipleAttr) |
354 parseMultipleAttribute(value); | 354 parseMultipleAttribute(value); |
355 else if (name == accesskeyAttr) { | 355 else if (name == accesskeyAttr) { |
356 // FIXME: ignore for the moment. | 356 // FIXME: ignore for the moment. |
357 // | 357 // |
358 } else if (name == disabledAttr) { | 358 } else if (name == disabledAttr) { |
359 HTMLFormControlElementWithState::parseAttribute(name, value); | 359 HTMLFormControlElementWithState::parseAttribute(name, value); |
360 if (renderer() && renderer()->isMenuList()) { | 360 if (layoutObject() && layoutObject()->isMenuList()) { |
361 if (LayoutMenuList* menuList = toLayoutMenuList(renderer())) { | 361 if (LayoutMenuList* menuList = toLayoutMenuList(layoutObject())) { |
362 if (menuList->popupIsVisible()) | 362 if (menuList->popupIsVisible()) |
363 menuList->hidePopup(); | 363 menuList->hidePopup(); |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 } else | 367 } else |
368 HTMLFormControlElementWithState::parseAttribute(name, value); | 368 HTMLFormControlElementWithState::parseAttribute(name, value); |
369 } | 369 } |
370 | 370 |
371 bool HTMLSelectElement::shouldShowFocusRingOnMouseFocus() const | 371 bool HTMLSelectElement::shouldShowFocusRingOnMouseFocus() const |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 m_lastOnChangeSelection.clear(); | 411 m_lastOnChangeSelection.clear(); |
412 | 412 |
413 HTMLFormControlElementWithState::childrenChanged(change); | 413 HTMLFormControlElementWithState::childrenChanged(change); |
414 } | 414 } |
415 | 415 |
416 void HTMLSelectElement::optionElementChildrenChanged() | 416 void HTMLSelectElement::optionElementChildrenChanged() |
417 { | 417 { |
418 setRecalcListItems(); | 418 setRecalcListItems(); |
419 setNeedsValidityCheck(); | 419 setNeedsValidityCheck(); |
420 | 420 |
421 if (renderer()) { | 421 if (layoutObject()) { |
422 if (AXObjectCache* cache = renderer()->document().existingAXObjectCache(
)) | 422 if (AXObjectCache* cache = layoutObject()->document().existingAXObjectCa
che()) |
423 cache->childrenChanged(this); | 423 cache->childrenChanged(this); |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 void HTMLSelectElement::accessKeyAction(bool sendMouseEvents) | 427 void HTMLSelectElement::accessKeyAction(bool sendMouseEvents) |
428 { | 428 { |
429 focus(); | 429 focus(); |
430 dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEv
ents); | 430 dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEv
ents); |
431 } | 431 } |
432 | 432 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 int size = listItems.size(); | 534 int size = listItems.size(); |
535 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex +
= direction) { | 535 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex +
= direction) { |
536 --skip; | 536 --skip; |
537 HTMLElement* element = listItems[listIndex]; | 537 HTMLElement* element = listItems[listIndex]; |
538 if (!isHTMLOptionElement(*element)) | 538 if (!isHTMLOptionElement(*element)) |
539 continue; | 539 continue; |
540 if (toHTMLOptionElement(*element).isDisplayNone()) | 540 if (toHTMLOptionElement(*element).isDisplayNone()) |
541 continue; | 541 continue; |
542 if (element->isDisabledFormControl()) | 542 if (element->isDisabledFormControl()) |
543 continue; | 543 continue; |
544 if (!usesMenuList() && !element->renderer()) | 544 if (!usesMenuList() && !element->layoutObject()) |
545 continue; | 545 continue; |
546 lastGoodIndex = listIndex; | 546 lastGoodIndex = listIndex; |
547 if (skip <= 0) | 547 if (skip <= 0) |
548 break; | 548 break; |
549 } | 549 } |
550 return lastGoodIndex; | 550 return lastGoodIndex; |
551 } | 551 } |
552 | 552 |
553 int HTMLSelectElement::nextSelectableListIndex(int startIndex) const | 553 int HTMLSelectElement::nextSelectableListIndex(int startIndex) const |
554 { | 554 { |
(...skipping 20 matching lines...) Expand all Loading... |
575 { | 575 { |
576 return nextValidIndex(-1, SkipForwards, INT_MAX); | 576 return nextValidIndex(-1, SkipForwards, INT_MAX); |
577 } | 577 } |
578 | 578 |
579 // Returns the index of the next valid item one page away from |startIndex| in d
irection |direction|. | 579 // Returns the index of the next valid item one page away from |startIndex| in d
irection |direction|. |
580 int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec
tion direction) const | 580 int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec
tion direction) const |
581 { | 581 { |
582 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; | 582 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
583 // Can't use m_size because renderer forces a minimum size. | 583 // Can't use m_size because renderer forces a minimum size. |
584 int pageSize = 0; | 584 int pageSize = 0; |
585 if (renderer()->isListBox()) | 585 if (layoutObject()->isListBox()) |
586 pageSize = toLayoutListBox(renderer())->size() - 1; // -1 so we still sh
ow context. | 586 pageSize = toLayoutListBox(layoutObject())->size() - 1; // -1 so we stil
l show context. |
587 | 587 |
588 // One page away, but not outside valid bounds. | 588 // One page away, but not outside valid bounds. |
589 // If there is a valid option item one page away, the index is chosen. | 589 // If there is a valid option item one page away, the index is chosen. |
590 // If there is no exact one page away valid option, returns startIndex or th
e most far index. | 590 // If there is no exact one page away valid option, returns startIndex or th
e most far index. |
591 int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1); | 591 int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1); |
592 int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edg
eIndex - startIndex)); | 592 int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edg
eIndex - startIndex)); |
593 return nextValidIndex(edgeIndex, direction, skipAmount); | 593 return nextValidIndex(edgeIndex, direction, skipAmount); |
594 } | 594 } |
595 | 595 |
596 void HTMLSelectElement::selectAll() | 596 void HTMLSelectElement::selectAll() |
597 { | 597 { |
598 ASSERT(!usesMenuList()); | 598 ASSERT(!usesMenuList()); |
599 if (!renderer() || !m_multiple) | 599 if (!layoutObject() || !m_multiple) |
600 return; | 600 return; |
601 | 601 |
602 // Save the selection so it can be compared to the new selectAll selection | 602 // Save the selection so it can be compared to the new selectAll selection |
603 // when dispatching change events. | 603 // when dispatching change events. |
604 saveLastSelection(); | 604 saveLastSelection(); |
605 | 605 |
606 m_activeSelectionState = true; | 606 m_activeSelectionState = true; |
607 setActiveSelectionAnchorIndex(nextSelectableListIndex(-1)); | 607 setActiveSelectionAnchorIndex(nextSelectableListIndex(-1)); |
608 setActiveSelectionEndIndex(previousSelectableListIndex(-1)); | 608 setActiveSelectionEndIndex(previousSelectableListIndex(-1)); |
609 | 609 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 void HTMLSelectElement::setActiveSelectionEndIndex(int index) | 645 void HTMLSelectElement::setActiveSelectionEndIndex(int index) |
646 { | 646 { |
647 if (index == m_activeSelectionEndIndex) | 647 if (index == m_activeSelectionEndIndex) |
648 return; | 648 return; |
649 m_activeSelectionEndIndex = index; | 649 m_activeSelectionEndIndex = index; |
650 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::Control)); | 650 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::Control)); |
651 } | 651 } |
652 | 652 |
653 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions, bool s
croll) | 653 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions, bool s
croll) |
654 { | 654 { |
655 ASSERT(renderer() && (renderer()->isListBox() || m_multiple)); | 655 ASSERT(layoutObject() && (layoutObject()->isListBox() || m_multiple)); |
656 | 656 |
657 int start = std::min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex
); | 657 int start = std::min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex
); |
658 int end = std::max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex); | 658 int end = std::max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex); |
659 | 659 |
660 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; | 660 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
661 for (int i = 0; i < static_cast<int>(items.size()); ++i) { | 661 for (int i = 0; i < static_cast<int>(items.size()); ++i) { |
662 HTMLElement* element = items[i]; | 662 HTMLElement* element = items[i]; |
663 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi
sabledFormControl() || !toHTMLOptionElement(element)->renderer()) | 663 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi
sabledFormControl() || !toHTMLOptionElement(element)->layoutObject()) |
664 continue; | 664 continue; |
665 | 665 |
666 if (i >= start && i <= end) | 666 if (i >= start && i <= end) |
667 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat
e); | 667 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat
e); |
668 else if (deselectOtherOptions || i >= static_cast<int>(m_cachedStateForA
ctiveSelection.size())) | 668 else if (deselectOtherOptions || i >= static_cast<int>(m_cachedStateForA
ctiveSelection.size())) |
669 toHTMLOptionElement(element)->setSelectedState(false); | 669 toHTMLOptionElement(element)->setSelectedState(false); |
670 else | 670 else |
671 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv
eSelection[i]); | 671 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv
eSelection[i]); |
672 } | 672 } |
673 | 673 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 return; | 728 return; |
729 if (usesMenuList()) | 729 if (usesMenuList()) |
730 return; | 730 return; |
731 scrollToIndex(activeSelectionEndListIndex()); | 731 scrollToIndex(activeSelectionEndListIndex()); |
732 if (AXObjectCache* cache = document().existingAXObjectCache()) | 732 if (AXObjectCache* cache = document().existingAXObjectCache()) |
733 cache->selectedChildrenChanged(this); | 733 cache->selectedChildrenChanged(this); |
734 } | 734 } |
735 | 735 |
736 void HTMLSelectElement::setOptionsChangedOnRenderer() | 736 void HTMLSelectElement::setOptionsChangedOnRenderer() |
737 { | 737 { |
738 if (LayoutObject* renderer = this->renderer()) { | 738 if (LayoutObject* renderer = this->layoutObject()) { |
739 if (usesMenuList()) | 739 if (usesMenuList()) |
740 toLayoutMenuList(renderer)->setOptionsChanged(true); | 740 toLayoutMenuList(renderer)->setOptionsChanged(true); |
741 } | 741 } |
742 } | 742 } |
743 | 743 |
744 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& HTMLSelectElement::list
Items() const | 744 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& HTMLSelectElement::list
Items() const |
745 { | 745 { |
746 if (m_shouldRecalcListItems) | 746 if (m_shouldRecalcListItems) |
747 recalcListItems(); | 747 recalcListItems(); |
748 else { | 748 else { |
(...skipping 23 matching lines...) Expand all Loading... |
772 m_activeSelectionAnchorIndex = -1; | 772 m_activeSelectionAnchorIndex = -1; |
773 setOptionsChangedOnRenderer(); | 773 setOptionsChangedOnRenderer(); |
774 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::ControlValue)); | 774 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::ControlValue)); |
775 if (!inDocument()) { | 775 if (!inDocument()) { |
776 if (HTMLOptionsCollection* collection = cachedCollection<HTMLOptionsColl
ection>(SelectOptions)) | 776 if (HTMLOptionsCollection* collection = cachedCollection<HTMLOptionsColl
ection>(SelectOptions)) |
777 collection->invalidateCache(); | 777 collection->invalidateCache(); |
778 } | 778 } |
779 if (!inDocument()) | 779 if (!inDocument()) |
780 invalidateSelectedItems(); | 780 invalidateSelectedItems(); |
781 | 781 |
782 if (renderer()) { | 782 if (layoutObject()) { |
783 if (AXObjectCache* cache = renderer()->document().existingAXObjectCache(
)) | 783 if (AXObjectCache* cache = layoutObject()->document().existingAXObjectCa
che()) |
784 cache->childrenChanged(this); | 784 cache->childrenChanged(this); |
785 } | 785 } |
786 } | 786 } |
787 | 787 |
788 void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const | 788 void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const |
789 { | 789 { |
790 m_listItems.clear(); | 790 m_listItems.clear(); |
791 | 791 |
792 m_shouldRecalcListItems = false; | 792 m_shouldRecalcListItems = false; |
793 | 793 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 | 870 |
871 int HTMLSelectElement::suggestedIndex() const | 871 int HTMLSelectElement::suggestedIndex() const |
872 { | 872 { |
873 return m_suggestedIndex; | 873 return m_suggestedIndex; |
874 } | 874 } |
875 | 875 |
876 void HTMLSelectElement::setSuggestedIndex(int suggestedIndex) | 876 void HTMLSelectElement::setSuggestedIndex(int suggestedIndex) |
877 { | 877 { |
878 m_suggestedIndex = suggestedIndex; | 878 m_suggestedIndex = suggestedIndex; |
879 | 879 |
880 if (LayoutObject* renderer = this->renderer()) { | 880 if (LayoutObject* renderer = this->layoutObject()) { |
881 renderer->updateFromElement(); | 881 renderer->updateFromElement(); |
882 scrollToIndex(suggestedIndex); | 882 scrollToIndex(suggestedIndex); |
883 } | 883 } |
884 } | 884 } |
885 | 885 |
886 void HTMLSelectElement::scrollToIndex(int listIndex) | 886 void HTMLSelectElement::scrollToIndex(int listIndex) |
887 { | 887 { |
888 if (listIndex < 0) | 888 if (listIndex < 0) |
889 return; | 889 return; |
890 if (usesMenuList()) | 890 if (usesMenuList()) |
891 return; | 891 return; |
892 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; | 892 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
893 int listSize = static_cast<int>(items.size()); | 893 int listSize = static_cast<int>(items.size()); |
894 if (listIndex >= listSize) | 894 if (listIndex >= listSize) |
895 return; | 895 return; |
896 document().updateLayoutIgnorePendingStylesheets(); | 896 document().updateLayoutIgnorePendingStylesheets(); |
897 if (!renderer() || !renderer()->isListBox()) | 897 if (!layoutObject() || !layoutObject()->isListBox()) |
898 return; | 898 return; |
899 LayoutRect bounds = items[listIndex]->boundingBox(); | 899 LayoutRect bounds = items[listIndex]->boundingBox(); |
900 toLayoutListBox(renderer())->scrollToRect(bounds); | 900 toLayoutListBox(layoutObject())->scrollToRect(bounds); |
901 } | 901 } |
902 | 902 |
903 void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b
ool optionIsSelected) | 903 void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b
ool optionIsSelected) |
904 { | 904 { |
905 ASSERT(option->ownerSelectElement() == this); | 905 ASSERT(option->ownerSelectElement() == this); |
906 if (optionIsSelected) | 906 if (optionIsSelected) |
907 selectOption(option->index()); | 907 selectOption(option->index()); |
908 else if (!usesMenuList() || multiple()) | 908 else if (!usesMenuList() || multiple()) |
909 selectOption(-1); | 909 selectOption(-1); |
910 else | 910 else |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 if (m_activeSelectionEndIndex < 0 || shouldDeselect) | 950 if (m_activeSelectionEndIndex < 0 || shouldDeselect) |
951 setActiveSelectionEndIndex(listIndex); | 951 setActiveSelectionEndIndex(listIndex); |
952 toHTMLOptionElement(*element).setSelectedState(true); | 952 toHTMLOptionElement(*element).setSelectedState(true); |
953 } | 953 } |
954 } | 954 } |
955 | 955 |
956 if (shouldDeselect) | 956 if (shouldDeselect) |
957 deselectItemsWithoutValidation(element); | 957 deselectItemsWithoutValidation(element); |
958 | 958 |
959 // For the menu list case, this is what makes the selected element appear. | 959 // For the menu list case, this is what makes the selected element appear. |
960 if (LayoutObject* renderer = this->renderer()) | 960 if (LayoutObject* renderer = this->layoutObject()) |
961 renderer->updateFromElement(); | 961 renderer->updateFromElement(); |
962 | 962 |
963 scrollToSelection(); | 963 scrollToSelection(); |
964 setNeedsValidityCheck(); | 964 setNeedsValidityCheck(); |
965 | 965 |
966 if (usesMenuList()) { | 966 if (usesMenuList()) { |
967 m_isProcessingUserDrivenChange = flags & UserDriven; | 967 m_isProcessingUserDrivenChange = flags & UserDriven; |
968 if (flags & DispatchInputAndChangeEvent) | 968 if (flags & DispatchInputAndChangeEvent) |
969 dispatchInputAndChangeEventForMenuList(); | 969 dispatchInputAndChangeEventForMenuList(); |
970 if (LayoutObject* renderer = this->renderer()) { | 970 if (LayoutObject* renderer = this->layoutObject()) { |
971 if (usesMenuList()) { | 971 if (usesMenuList()) { |
972 toLayoutMenuList(renderer)->didSetSelectedIndex(listIndex); | 972 toLayoutMenuList(renderer)->didSetSelectedIndex(listIndex); |
973 } else if (renderer->isListBox()) { | 973 } else if (renderer->isListBox()) { |
974 if (AXObjectCache* cache = document().existingAXObjectCache()) | 974 if (AXObjectCache* cache = document().existingAXObjectCache()) |
975 cache->selectedChildrenChanged(this); | 975 cache->selectedChildrenChanged(this); |
976 } | 976 } |
977 } | 977 } |
978 } | 978 } |
979 | 979 |
980 notifyFormStateChanged(); | 980 notifyFormStateChanged(); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::ControlValue)); | 1187 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::ControlValue)); |
1188 setNeedsValidityCheck(); | 1188 setNeedsValidityCheck(); |
1189 } | 1189 } |
1190 | 1190 |
1191 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) | 1191 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) |
1192 { | 1192 { |
1193 focus(); | 1193 focus(); |
1194 // Calling focus() may cause us to lose our renderer. Return true so | 1194 // Calling focus() may cause us to lose our renderer. Return true so |
1195 // that our caller doesn't process the event further, but don't set | 1195 // that our caller doesn't process the event further, but don't set |
1196 // the event as handled. | 1196 // the event as handled. |
1197 if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl()) | 1197 if (!layoutObject() || !layoutObject()->isMenuList() || isDisabledFormContro
l()) |
1198 return; | 1198 return; |
1199 // Save the selection so it can be compared to the new selection | 1199 // Save the selection so it can be compared to the new selection |
1200 // when dispatching change events during selectOption, which | 1200 // when dispatching change events during selectOption, which |
1201 // gets called from LayoutMenuList::valueChanged, which gets called | 1201 // gets called from LayoutMenuList::valueChanged, which gets called |
1202 // after the user makes a selection from the menu. | 1202 // after the user makes a selection from the menu. |
1203 saveLastSelection(); | 1203 saveLastSelection(); |
1204 if (LayoutMenuList* menuList = toLayoutMenuList(renderer())) | 1204 if (LayoutMenuList* menuList = toLayoutMenuList(layoutObject())) |
1205 menuList->showPopup(); | 1205 menuList->showPopup(); |
1206 event->setDefaultHandled(); | 1206 event->setDefaultHandled(); |
1207 return; | 1207 return; |
1208 } | 1208 } |
1209 | 1209 |
1210 bool HTMLSelectElement::shouldOpenPopupForKeyDownEvent(KeyboardEvent* keyEvent) | 1210 bool HTMLSelectElement::shouldOpenPopupForKeyDownEvent(KeyboardEvent* keyEvent) |
1211 { | 1211 { |
1212 const String& keyIdentifier = keyEvent->keyIdentifier(); | 1212 const String& keyIdentifier = keyEvent->keyIdentifier(); |
1213 LayoutTheme& layoutTheme = LayoutTheme::theme(); | 1213 LayoutTheme& layoutTheme = LayoutTheme::theme(); |
1214 | 1214 |
(...skipping 10 matching lines...) Expand all Loading... |
1225 LayoutTheme& layoutTheme = LayoutTheme::theme(); | 1225 LayoutTheme& layoutTheme = LayoutTheme::theme(); |
1226 int keyCode = event->keyCode(); | 1226 int keyCode = event->keyCode(); |
1227 | 1227 |
1228 return ((layoutTheme.popsMenuBySpaceKey() && event->keyCode() == ' ') | 1228 return ((layoutTheme.popsMenuBySpaceKey() && event->keyCode() == ' ') |
1229 || (layoutTheme.popsMenuByReturnKey() && keyCode == '\r')); | 1229 || (layoutTheme.popsMenuByReturnKey() && keyCode == '\r')); |
1230 } | 1230 } |
1231 | 1231 |
1232 void HTMLSelectElement::menuListDefaultEventHandler(Event* event) | 1232 void HTMLSelectElement::menuListDefaultEventHandler(Event* event) |
1233 { | 1233 { |
1234 if (event->type() == EventTypeNames::keydown) { | 1234 if (event->type() == EventTypeNames::keydown) { |
1235 if (!renderer() || !event->isKeyboardEvent()) | 1235 if (!layoutObject() || !event->isKeyboardEvent()) |
1236 return; | 1236 return; |
1237 | 1237 |
1238 KeyboardEvent* keyEvent = toKeyboardEvent(event); | 1238 KeyboardEvent* keyEvent = toKeyboardEvent(event); |
1239 if (shouldOpenPopupForKeyDownEvent(keyEvent)) { | 1239 if (shouldOpenPopupForKeyDownEvent(keyEvent)) { |
1240 handlePopupOpenKeyboardEvent(event); | 1240 handlePopupOpenKeyboardEvent(event); |
1241 return; | 1241 return; |
1242 } | 1242 } |
1243 | 1243 |
1244 // When using spatial navigation, we want to be able to navigate away | 1244 // When using spatial navigation, we want to be able to navigate away |
1245 // from the select element when the user hits any of the arrow keys, | 1245 // from the select element when the user hits any of the arrow keys, |
(...skipping 28 matching lines...) Expand all Loading... |
1274 handled = false; | 1274 handled = false; |
1275 | 1275 |
1276 if (handled && static_cast<size_t>(listIndex) < listItems.size()) | 1276 if (handled && static_cast<size_t>(listIndex) < listItems.size()) |
1277 selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | Di
spatchInputAndChangeEvent | UserDriven); | 1277 selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | Di
spatchInputAndChangeEvent | UserDriven); |
1278 | 1278 |
1279 if (handled) | 1279 if (handled) |
1280 event->setDefaultHandled(); | 1280 event->setDefaultHandled(); |
1281 } | 1281 } |
1282 | 1282 |
1283 if (event->type() == EventTypeNames::keypress) { | 1283 if (event->type() == EventTypeNames::keypress) { |
1284 if (!renderer() || !event->isKeyboardEvent()) | 1284 if (!layoutObject() || !event->isKeyboardEvent()) |
1285 return; | 1285 return; |
1286 | 1286 |
1287 int keyCode = toKeyboardEvent(event)->keyCode(); | 1287 int keyCode = toKeyboardEvent(event)->keyCode(); |
1288 if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { | 1288 if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { |
1289 // Use space to toggle arrow key handling for selection change or sp
atial navigation. | 1289 // Use space to toggle arrow key handling for selection change or sp
atial navigation. |
1290 m_activeSelectionState = !m_activeSelectionState; | 1290 m_activeSelectionState = !m_activeSelectionState; |
1291 event->setDefaultHandled(); | 1291 event->setDefaultHandled(); |
1292 return; | 1292 return; |
1293 } | 1293 } |
1294 | 1294 |
1295 KeyboardEvent* keyEvent = toKeyboardEvent(event); | 1295 KeyboardEvent* keyEvent = toKeyboardEvent(event); |
1296 if (shouldOpenPopupForKeyPressEvent(keyEvent)) { | 1296 if (shouldOpenPopupForKeyPressEvent(keyEvent)) { |
1297 handlePopupOpenKeyboardEvent(event); | 1297 handlePopupOpenKeyboardEvent(event); |
1298 return; | 1298 return; |
1299 } | 1299 } |
1300 | 1300 |
1301 if (!LayoutTheme::theme().popsMenuByReturnKey() && keyCode == '\r') { | 1301 if (!LayoutTheme::theme().popsMenuByReturnKey() && keyCode == '\r') { |
1302 if (form()) | 1302 if (form()) |
1303 form()->submitImplicitly(event, false); | 1303 form()->submitImplicitly(event, false); |
1304 dispatchInputAndChangeEventForMenuList(); | 1304 dispatchInputAndChangeEventForMenuList(); |
1305 event->setDefaultHandled(); | 1305 event->setDefaultHandled(); |
1306 } | 1306 } |
1307 } | 1307 } |
1308 | 1308 |
1309 if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && t
oMouseEvent(event)->button() == LeftButton) { | 1309 if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && t
oMouseEvent(event)->button() == LeftButton) { |
1310 focus(); | 1310 focus(); |
1311 if (renderer() && renderer()->isMenuList() && !isDisabledFormControl())
{ | 1311 if (layoutObject() && layoutObject()->isMenuList() && !isDisabledFormCon
trol()) { |
1312 if (LayoutMenuList* menuList = toLayoutMenuList(renderer())) { | 1312 if (LayoutMenuList* menuList = toLayoutMenuList(layoutObject())) { |
1313 if (menuList->popupIsVisible()) | 1313 if (menuList->popupIsVisible()) |
1314 menuList->hidePopup(); | 1314 menuList->hidePopup(); |
1315 else { | 1315 else { |
1316 // Save the selection so it can be compared to the new | 1316 // Save the selection so it can be compared to the new |
1317 // selection when we call onChange during selectOption, | 1317 // selection when we call onChange during selectOption, |
1318 // which gets called from LayoutMenuList::valueChanged, | 1318 // which gets called from LayoutMenuList::valueChanged, |
1319 // which gets called after the user makes a selection from | 1319 // which gets called after the user makes a selection from |
1320 // the menu. | 1320 // the menu. |
1321 saveLastSelection(); | 1321 saveLastSelection(); |
1322 menuList->showPopup(); | 1322 menuList->showPopup(); |
1323 } | 1323 } |
1324 } | 1324 } |
1325 } | 1325 } |
1326 event->setDefaultHandled(); | 1326 event->setDefaultHandled(); |
1327 } | 1327 } |
1328 | 1328 |
1329 if (event->type() == EventTypeNames::blur) { | 1329 if (event->type() == EventTypeNames::blur) { |
1330 if (LayoutMenuList* menuList = toLayoutMenuList(renderer())) { | 1330 if (LayoutMenuList* menuList = toLayoutMenuList(layoutObject())) { |
1331 if (menuList->popupIsVisible()) | 1331 if (menuList->popupIsVisible()) |
1332 menuList->hidePopup(); | 1332 menuList->hidePopup(); |
1333 } | 1333 } |
1334 } | 1334 } |
1335 } | 1335 } |
1336 | 1336 |
1337 void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
t) | 1337 void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
t) |
1338 { | 1338 { |
1339 ASSERT(listIndex >= 0); | 1339 ASSERT(listIndex >= 0); |
1340 | 1340 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 return; | 1420 return; |
1421 listBoxOnChange(); | 1421 listBoxOnChange(); |
1422 } | 1422 } |
1423 | 1423 |
1424 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) | 1424 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
1425 { | 1425 { |
1426 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = this->l
istItems(); | 1426 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = this->l
istItems(); |
1427 if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent())
{ | 1427 if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent())
{ |
1428 focus(); | 1428 focus(); |
1429 // Calling focus() may cause us to lose our renderer or change the rende
r type, in which case do not want to handle the event. | 1429 // Calling focus() may cause us to lose our renderer or change the rende
r type, in which case do not want to handle the event. |
1430 if (!renderer() || !renderer()->isListBox()) | 1430 if (!layoutObject() || !layoutObject()->isListBox()) |
1431 return; | 1431 return; |
1432 | 1432 |
1433 // Convert to coords relative to the list box if needed. | 1433 // Convert to coords relative to the list box if needed. |
1434 GestureEvent& gestureEvent = toGestureEvent(*event); | 1434 GestureEvent& gestureEvent = toGestureEvent(*event); |
1435 int listIndex = listIndexForEventTargetOption(gestureEvent); | 1435 int listIndex = listIndexForEventTargetOption(gestureEvent); |
1436 if (listIndex >= 0) { | 1436 if (listIndex >= 0) { |
1437 if (!isDisabledFormControl()) { | 1437 if (!isDisabledFormControl()) { |
1438 updateSelectedState(listIndex, true, gestureEvent.shiftKey()); | 1438 updateSelectedState(listIndex, true, gestureEvent.shiftKey()); |
1439 listBoxOnChange(); | 1439 listBoxOnChange(); |
1440 } | 1440 } |
1441 event->setDefaultHandled(); | 1441 event->setDefaultHandled(); |
1442 } | 1442 } |
1443 } else if (event->type() == EventTypeNames::mousedown && event->isMouseEvent
() && toMouseEvent(event)->button() == LeftButton) { | 1443 } else if (event->type() == EventTypeNames::mousedown && event->isMouseEvent
() && toMouseEvent(event)->button() == LeftButton) { |
1444 focus(); | 1444 focus(); |
1445 // Calling focus() may cause us to lose our renderer, in which case do n
ot want to handle the event. | 1445 // Calling focus() may cause us to lose our renderer, in which case do n
ot want to handle the event. |
1446 if (!renderer() || !renderer()->isListBox() || isDisabledFormControl()) | 1446 if (!layoutObject() || !layoutObject()->isListBox() || isDisabledFormCon
trol()) |
1447 return; | 1447 return; |
1448 | 1448 |
1449 // Convert to coords relative to the list box if needed. | 1449 // Convert to coords relative to the list box if needed. |
1450 MouseEvent* mouseEvent = toMouseEvent(event); | 1450 MouseEvent* mouseEvent = toMouseEvent(event); |
1451 int listIndex = listIndexForEventTargetOption(*mouseEvent); | 1451 int listIndex = listIndexForEventTargetOption(*mouseEvent); |
1452 if (listIndex >= 0) { | 1452 if (listIndex >= 0) { |
1453 if (!isDisabledFormControl()) { | 1453 if (!isDisabledFormControl()) { |
1454 #if OS(MACOSX) | 1454 #if OS(MACOSX) |
1455 updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent
->shiftKey()); | 1455 updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent
->shiftKey()); |
1456 #else | 1456 #else |
1457 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent
->shiftKey()); | 1457 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent
->shiftKey()); |
1458 #endif | 1458 #endif |
1459 } | 1459 } |
1460 if (LocalFrame* frame = document().frame()) | 1460 if (LocalFrame* frame = document().frame()) |
1461 frame->eventHandler().setMouseDownMayStartAutoscroll(); | 1461 frame->eventHandler().setMouseDownMayStartAutoscroll(); |
1462 | 1462 |
1463 event->setDefaultHandled(); | 1463 event->setDefaultHandled(); |
1464 } | 1464 } |
1465 } else if (event->type() == EventTypeNames::mousemove && event->isMouseEvent
()) { | 1465 } else if (event->type() == EventTypeNames::mousemove && event->isMouseEvent
()) { |
1466 MouseEvent* mouseEvent = toMouseEvent(event); | 1466 MouseEvent* mouseEvent = toMouseEvent(event); |
1467 if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) | 1467 if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) |
1468 return; | 1468 return; |
1469 | 1469 |
1470 if (Page* page = document().page()) | 1470 if (Page* page = document().page()) |
1471 page->autoscrollController().startAutoscrollForSelection(renderer())
; | 1471 page->autoscrollController().startAutoscrollForSelection(layoutObjec
t()); |
1472 | 1472 |
1473 int listIndex = listIndexForEventTargetOption(*mouseEvent); | 1473 int listIndex = listIndexForEventTargetOption(*mouseEvent); |
1474 if (listIndex >= 0) { | 1474 if (listIndex >= 0) { |
1475 if (!isDisabledFormControl()) { | 1475 if (!isDisabledFormControl()) { |
1476 if (m_multiple) { | 1476 if (m_multiple) { |
1477 // Only extend selection if there is something selected. | 1477 // Only extend selection if there is something selected. |
1478 if (m_activeSelectionAnchorIndex < 0) | 1478 if (m_activeSelectionAnchorIndex < 0) |
1479 return; | 1479 return; |
1480 | 1480 |
1481 setActiveSelectionEndIndex(listIndex); | 1481 setActiveSelectionEndIndex(listIndex); |
1482 updateListBoxSelection(false); | 1482 updateListBoxSelection(false); |
1483 } else { | 1483 } else { |
1484 setActiveSelectionAnchorIndex(listIndex); | 1484 setActiveSelectionAnchorIndex(listIndex); |
1485 setActiveSelectionEndIndex(listIndex); | 1485 setActiveSelectionEndIndex(listIndex); |
1486 updateListBoxSelection(true); | 1486 updateListBoxSelection(true); |
1487 } | 1487 } |
1488 } | 1488 } |
1489 } | 1489 } |
1490 } else if (event->type() == EventTypeNames::mouseup && event->isMouseEvent()
&& toMouseEvent(event)->button() == LeftButton && renderer()) { | 1490 } else if (event->type() == EventTypeNames::mouseup && event->isMouseEvent()
&& toMouseEvent(event)->button() == LeftButton && layoutObject()) { |
1491 if (document().page() && document().page()->autoscrollController().autos
crollInProgress(toLayoutBox(renderer()))) | 1491 if (document().page() && document().page()->autoscrollController().autos
crollInProgress(toLayoutBox(layoutObject()))) |
1492 document().page()->autoscrollController().stopAutoscroll(); | 1492 document().page()->autoscrollController().stopAutoscroll(); |
1493 else | 1493 else |
1494 handleMouseRelease(); | 1494 handleMouseRelease(); |
1495 } else if (event->type() == EventTypeNames::keydown) { | 1495 } else if (event->type() == EventTypeNames::keydown) { |
1496 if (!event->isKeyboardEvent()) | 1496 if (!event->isKeyboardEvent()) |
1497 return; | 1497 return; |
1498 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); | 1498 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); |
1499 | 1499 |
1500 bool handled = false; | 1500 bool handled = false; |
1501 int endIndex = 0; | 1501 int endIndex = 0; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 m_activeSelectionState = !m_activeSelectionState; | 1589 m_activeSelectionState = !m_activeSelectionState; |
1590 updateSelectedState(listToOptionIndex(m_activeSelectionEndIndex), tr
ue /*multi*/, false /*shift*/); | 1590 updateSelectedState(listToOptionIndex(m_activeSelectionEndIndex), tr
ue /*multi*/, false /*shift*/); |
1591 listBoxOnChange(); | 1591 listBoxOnChange(); |
1592 event->setDefaultHandled(); | 1592 event->setDefaultHandled(); |
1593 } | 1593 } |
1594 } | 1594 } |
1595 } | 1595 } |
1596 | 1596 |
1597 void HTMLSelectElement::defaultEventHandler(Event* event) | 1597 void HTMLSelectElement::defaultEventHandler(Event* event) |
1598 { | 1598 { |
1599 if (!renderer()) | 1599 if (!layoutObject()) |
1600 return; | 1600 return; |
1601 | 1601 |
1602 if (isDisabledFormControl()) { | 1602 if (isDisabledFormControl()) { |
1603 HTMLFormControlElementWithState::defaultEventHandler(event); | 1603 HTMLFormControlElementWithState::defaultEventHandler(event); |
1604 return; | 1604 return; |
1605 } | 1605 } |
1606 | 1606 |
1607 if (usesMenuList()) | 1607 if (usesMenuList()) |
1608 menuListDefaultEventHandler(event); | 1608 menuListDefaultEventHandler(event); |
1609 else | 1609 else |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 int focusedIndex = activeSelectionEndListIndex(); | 1768 int focusedIndex = activeSelectionEndListIndex(); |
1769 if (focusedIndex < 0) | 1769 if (focusedIndex < 0) |
1770 focusedIndex = firstSelectableListIndex(); | 1770 focusedIndex = firstSelectableListIndex(); |
1771 if (focusedIndex < 0) | 1771 if (focusedIndex < 0) |
1772 return nullptr; | 1772 return nullptr; |
1773 HTMLElement* focused = listItems()[focusedIndex]; | 1773 HTMLElement* focused = listItems()[focusedIndex]; |
1774 return isHTMLOptionElement(focused) ? toHTMLOptionElement(focused) : nullptr
; | 1774 return isHTMLOptionElement(focused) ? toHTMLOptionElement(focused) : nullptr
; |
1775 } | 1775 } |
1776 | 1776 |
1777 } // namespace | 1777 } // namespace |
OLD | NEW |