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

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

Issue 275573003: Oilpan: Prepare to move select and option elements to Oilpan heap. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 { 222 {
223 int listIndex = optionToListIndex(optionIndex); 223 int listIndex = optionToListIndex(optionIndex);
224 if (listIndex < 0) 224 if (listIndex < 0)
225 return; 225 return;
226 226
227 listItems()[listIndex]->remove(IGNORE_EXCEPTION); 227 listItems()[listIndex]->remove(IGNORE_EXCEPTION);
228 } 228 }
229 229
230 String HTMLSelectElement::value() const 230 String HTMLSelectElement::value() const
231 { 231 {
232 const Vector<HTMLElement*>& items = listItems(); 232 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
233 for (unsigned i = 0; i < items.size(); i++) { 233 for (unsigned i = 0; i < items.size(); i++) {
234 if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->sele cted()) 234 if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->sele cted())
235 return toHTMLOptionElement(items[i])->value(); 235 return toHTMLOptionElement(items[i])->value();
236 } 236 }
237 return ""; 237 return "";
238 } 238 }
239 239
240 void HTMLSelectElement::setValue(const String &value, bool sendEvents) 240 void HTMLSelectElement::setValue(const String &value, bool sendEvents)
241 { 241 {
242 // We clear the previously selected option(s) when needed, to guarantee call ing setSelectedIndex() only once. 242 // We clear the previously selected option(s) when needed, to guarantee call ing setSelectedIndex() only once.
243 int optionIndex = 0; 243 int optionIndex = 0;
244 if (value.isNull()) { 244 if (value.isNull()) {
245 optionIndex = -1; 245 optionIndex = -1;
246 } else { 246 } else {
247 // Find the option with value() matching the given parameter and make it the current selection. 247 // Find the option with value() matching the given parameter and make it the current selection.
248 const Vector<HTMLElement*>& items = listItems(); 248 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listIt ems();
249 for (unsigned i = 0; i < items.size(); i++) { 249 for (unsigned i = 0; i < items.size(); i++) {
250 if (isHTMLOptionElement(items[i])) { 250 if (isHTMLOptionElement(items[i])) {
251 if (toHTMLOptionElement(items[i])->value() == value) 251 if (toHTMLOptionElement(items[i])->value() == value)
252 break; 252 break;
253 optionIndex++; 253 optionIndex++;
254 } 254 }
255 } 255 }
256 if (optionIndex >= static_cast<int>(items.size())) 256 if (optionIndex >= static_cast<int>(items.size()))
257 optionIndex = -1; 257 optionIndex = -1;
258 } 258 }
259 259
260 int previousSelectedIndex = selectedIndex(); 260 int previousSelectedIndex = selectedIndex();
261 setSelectedIndex(optionIndex); 261 setSelectedIndex(optionIndex);
262 262
263 if (sendEvents && previousSelectedIndex != selectedIndex()) { 263 if (sendEvents && previousSelectedIndex != selectedIndex()) {
264 if (usesMenuList()) 264 if (usesMenuList())
265 dispatchInputAndChangeEventForMenuList(false); 265 dispatchInputAndChangeEventForMenuList(false);
266 else 266 else
267 listBoxOnChange(); 267 listBoxOnChange();
268 } 268 }
269 } 269 }
270 270
271 String HTMLSelectElement::suggestedValue() const 271 String HTMLSelectElement::suggestedValue() const
272 { 272 {
273 const Vector<HTMLElement*>& items = listItems(); 273 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
274 for (unsigned i = 0; i < items.size(); ++i) { 274 for (unsigned i = 0; i < items.size(); ++i) {
275 if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) { 275 if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) {
276 if (i == static_cast<unsigned>(m_suggestedIndex)) 276 if (i == static_cast<unsigned>(m_suggestedIndex))
277 return toHTMLOptionElement(items[i])->value(); 277 return toHTMLOptionElement(items[i])->value();
278 } 278 }
279 } 279 }
280 return ""; 280 return "";
281 } 281 }
282 282
283 void HTMLSelectElement::setSuggestedValue(const String& value) 283 void HTMLSelectElement::setSuggestedValue(const String& value)
284 { 284 {
285 if (value.isNull()) { 285 if (value.isNull()) {
286 setSuggestedIndex(-1); 286 setSuggestedIndex(-1);
287 return; 287 return;
288 } 288 }
289 289
290 const Vector<HTMLElement*>& items = listItems(); 290 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
291 unsigned optionIndex = 0; 291 unsigned optionIndex = 0;
292 for (unsigned i = 0; i < items.size(); ++i) { 292 for (unsigned i = 0; i < items.size(); ++i) {
293 if (isHTMLOptionElement(items[i])) { 293 if (isHTMLOptionElement(items[i])) {
294 if (toHTMLOptionElement(items[i])->value() == value) { 294 if (toHTMLOptionElement(items[i])->value() == value) {
295 setSuggestedIndex(optionIndex); 295 setSuggestedIndex(optionIndex);
296 return; 296 return;
297 } 297 }
298 optionIndex++; 298 optionIndex++;
299 } 299 }
300 } 300 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 475
476 if (diff < 0) { // Add dummy elements. 476 if (diff < 0) { // Add dummy elements.
477 do { 477 do {
478 RefPtr<Element> option = document().createElement(optionTag, false); 478 RefPtr<Element> option = document().createElement(optionTag, false);
479 ASSERT(option); 479 ASSERT(option);
480 add(toHTMLElement(option), 0, exceptionState); 480 add(toHTMLElement(option), 0, exceptionState);
481 if (exceptionState.hadException()) 481 if (exceptionState.hadException())
482 break; 482 break;
483 } while (++diff); 483 } while (++diff);
484 } else { 484 } else {
485 const Vector<HTMLElement*>& items = listItems(); 485 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listIt ems();
486 486
487 // Removing children fires mutation events, which might mutate the DOM f urther, so we first copy out a list 487 // Removing children fires mutation events, which might mutate the DOM f urther, so we first copy out a list
488 // of elements that we intend to remove then attempt to remove them one at a time. 488 // of elements that we intend to remove then attempt to remove them one at a time.
489 Vector<RefPtr<Element> > itemsToRemove; 489 Vector<RefPtr<Element> > itemsToRemove;
490 size_t optionIndex = 0; 490 size_t optionIndex = 0;
491 for (size_t i = 0; i < items.size(); ++i) { 491 for (size_t i = 0; i < items.size(); ++i) {
492 Element* item = items[i]; 492 Element* item = items[i];
493 if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) { 493 if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) {
494 ASSERT(item->parentNode()); 494 ASSERT(item->parentNode());
495 itemsToRemove.append(item); 495 itemsToRemove.append(item);
(...skipping 14 matching lines...) Expand all
510 return isRequired(); 510 return isRequired();
511 } 511 }
512 512
513 // Returns the 1st valid item |skip| items from |listIndex| in direction |direct ion| if there is one. 513 // Returns the 1st valid item |skip| items from |listIndex| in direction |direct ion| if there is one.
514 // Otherwise, it returns the valid item closest to that boundary which is past | listIndex| if there is one. 514 // Otherwise, it returns the valid item closest to that boundary which is past | listIndex| if there is one.
515 // Otherwise, it returns |listIndex|. 515 // Otherwise, it returns |listIndex|.
516 // Valid means that it is enabled and an option element. 516 // Valid means that it is enabled and an option element.
517 int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in t skip) const 517 int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in t skip) const
518 { 518 {
519 ASSERT(direction == -1 || direction == 1); 519 ASSERT(direction == -1 || direction == 1);
520 const Vector<HTMLElement*>& listItems = this->listItems(); 520 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this-> listItems();
521 int lastGoodIndex = listIndex; 521 int lastGoodIndex = listIndex;
522 int size = listItems.size(); 522 int size = listItems.size();
523 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex + = direction) { 523 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex + = direction) {
524 --skip; 524 --skip;
525 HTMLElement* element = listItems[listIndex]; 525 HTMLElement* element = listItems[listIndex];
526 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi sabledFormControl() || toHTMLOptionElement(element)->isDisplayNone()) 526 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi sabledFormControl() || toHTMLOptionElement(element)->isDisplayNone())
527 continue; 527 continue;
528 lastGoodIndex = listIndex; 528 lastGoodIndex = listIndex;
529 if (skip <= 0) 529 if (skip <= 0)
530 break; 530 break;
531 } 531 }
532 return lastGoodIndex; 532 return lastGoodIndex;
533 } 533 }
534 534
535 int HTMLSelectElement::nextSelectableListIndex(int startIndex) const 535 int HTMLSelectElement::nextSelectableListIndex(int startIndex) const
536 { 536 {
537 return nextValidIndex(startIndex, SkipForwards, 1); 537 return nextValidIndex(startIndex, SkipForwards, 1);
538 } 538 }
539 539
540 int HTMLSelectElement::previousSelectableListIndex(int startIndex) const 540 int HTMLSelectElement::previousSelectableListIndex(int startIndex) const
541 { 541 {
542 if (startIndex == -1) 542 if (startIndex == -1)
543 startIndex = listItems().size(); 543 startIndex = listItems().size();
544 return nextValidIndex(startIndex, SkipBackwards, 1); 544 return nextValidIndex(startIndex, SkipBackwards, 1);
545 } 545 }
546 546
547 int HTMLSelectElement::firstSelectableListIndex() const 547 int HTMLSelectElement::firstSelectableListIndex() const
548 { 548 {
549 const Vector<HTMLElement*>& items = listItems(); 549 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
550 int index = nextValidIndex(items.size(), SkipBackwards, INT_MAX); 550 int index = nextValidIndex(items.size(), SkipBackwards, INT_MAX);
551 if (static_cast<size_t>(index) == items.size()) 551 if (static_cast<size_t>(index) == items.size())
552 return -1; 552 return -1;
553 return index; 553 return index;
554 } 554 }
555 555
556 int HTMLSelectElement::lastSelectableListIndex() const 556 int HTMLSelectElement::lastSelectableListIndex() const
557 { 557 {
558 return nextValidIndex(-1, SkipForwards, INT_MAX); 558 return nextValidIndex(-1, SkipForwards, INT_MAX);
559 } 559 }
560 560
561 // Returns the index of the next valid item one page away from |startIndex| in d irection |direction|. 561 // Returns the index of the next valid item one page away from |startIndex| in d irection |direction|.
562 int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec tion direction) const 562 int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec tion direction) const
563 { 563 {
564 const Vector<HTMLElement*>& items = listItems(); 564 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
565 // Can't use m_size because renderer forces a minimum size. 565 // Can't use m_size because renderer forces a minimum size.
566 int pageSize = 0; 566 int pageSize = 0;
567 if (renderer()->isListBox()) 567 if (renderer()->isListBox())
568 pageSize = toRenderListBox(renderer())->size() - 1; // -1 so we still sh ow context. 568 pageSize = toRenderListBox(renderer())->size() - 1; // -1 so we still sh ow context.
569 569
570 // One page away, but not outside valid bounds. 570 // One page away, but not outside valid bounds.
571 // If there is a valid option item one page away, the index is chosen. 571 // If there is a valid option item one page away, the index is chosen.
572 // If there is no exact one page away valid option, returns startIndex or th e most far index. 572 // If there is no exact one page away valid option, returns startIndex or th e most far index.
573 int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1); 573 int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1);
574 int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edg eIndex - startIndex)); 574 int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edg eIndex - startIndex));
(...skipping 20 matching lines...) Expand all
595 } 595 }
596 596
597 void HTMLSelectElement::saveLastSelection() 597 void HTMLSelectElement::saveLastSelection()
598 { 598 {
599 if (usesMenuList()) { 599 if (usesMenuList()) {
600 m_lastOnChangeIndex = selectedIndex(); 600 m_lastOnChangeIndex = selectedIndex();
601 return; 601 return;
602 } 602 }
603 603
604 m_lastOnChangeSelection.clear(); 604 m_lastOnChangeSelection.clear();
605 const Vector<HTMLElement*>& items = listItems(); 605 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
606 for (unsigned i = 0; i < items.size(); ++i) { 606 for (unsigned i = 0; i < items.size(); ++i) {
607 HTMLElement* element = items[i]; 607 HTMLElement* element = items[i];
608 m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOp tionElement(element)->selected()); 608 m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOp tionElement(element)->selected());
609 } 609 }
610 } 610 }
611 611
612 void HTMLSelectElement::setActiveSelectionAnchorIndex(int index) 612 void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
613 { 613 {
614 m_activeSelectionAnchorIndex = index; 614 m_activeSelectionAnchorIndex = index;
615 615
616 // Cache the selection state so we can restore the old selection as the new 616 // Cache the selection state so we can restore the old selection as the new
617 // selection pivots around this anchor index. 617 // selection pivots around this anchor index.
618 m_cachedStateForActiveSelection.clear(); 618 m_cachedStateForActiveSelection.clear();
619 619
620 const Vector<HTMLElement*>& items = listItems(); 620 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
621 for (unsigned i = 0; i < items.size(); ++i) { 621 for (unsigned i = 0; i < items.size(); ++i) {
622 HTMLElement* element = items[i]; 622 HTMLElement* element = items[i];
623 m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected()); 623 m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
624 } 624 }
625 } 625 }
626 626
627 void HTMLSelectElement::setActiveSelectionEndIndex(int index) 627 void HTMLSelectElement::setActiveSelectionEndIndex(int index)
628 { 628 {
629 m_activeSelectionEndIndex = index; 629 m_activeSelectionEndIndex = index;
630 } 630 }
631 631
632 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions) 632 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
633 { 633 {
634 ASSERT(renderer() && (renderer()->isListBox() || m_multiple)); 634 ASSERT(renderer() && (renderer()->isListBox() || m_multiple));
635 ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0); 635 ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0);
636 636
637 unsigned start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex ); 637 unsigned start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex );
638 unsigned end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex); 638 unsigned end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
639 639
640 const Vector<HTMLElement*>& items = listItems(); 640 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
641 for (unsigned i = 0; i < items.size(); ++i) { 641 for (unsigned i = 0; i < items.size(); ++i) {
642 HTMLElement* element = items[i]; 642 HTMLElement* element = items[i];
643 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi sabledFormControl() || toHTMLOptionElement(element)->isDisplayNone()) 643 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi sabledFormControl() || toHTMLOptionElement(element)->isDisplayNone())
644 continue; 644 continue;
645 645
646 if (i >= start && i <= end) 646 if (i >= start && i <= end)
647 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat e); 647 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat e);
648 else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.si ze()) 648 else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.si ze())
649 toHTMLOptionElement(element)->setSelectedState(false); 649 toHTMLOptionElement(element)->setSelectedState(false);
650 else 650 else
651 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv eSelection[i]); 651 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv eSelection[i]);
652 } 652 }
653 653
654 scrollToSelection(); 654 scrollToSelection();
655 setNeedsValidityCheck(); 655 setNeedsValidityCheck();
656 notifyFormStateChanged(); 656 notifyFormStateChanged();
657 } 657 }
658 658
659 void HTMLSelectElement::listBoxOnChange() 659 void HTMLSelectElement::listBoxOnChange()
660 { 660 {
661 ASSERT(!usesMenuList() || m_multiple); 661 ASSERT(!usesMenuList() || m_multiple);
662 662
663 const Vector<HTMLElement*>& items = listItems(); 663 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
664 664
665 // If the cached selection list is empty, or the size has changed, then fire 665 // If the cached selection list is empty, or the size has changed, then fire
666 // dispatchFormControlChangeEvent, and return early. 666 // dispatchFormControlChangeEvent, and return early.
667 // FIXME: Why? This looks unreasonable. 667 // FIXME: Why? This looks unreasonable.
668 if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != i tems.size()) { 668 if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != i tems.size()) {
669 dispatchFormControlChangeEvent(); 669 dispatchFormControlChangeEvent();
670 return; 670 return;
671 } 671 }
672 672
673 // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent. 673 // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent.
674 bool fireOnChange = false; 674 bool fireOnChange = false;
675 for (unsigned i = 0; i < items.size(); ++i) { 675 for (unsigned i = 0; i < items.size(); ++i) {
676 HTMLElement* element = items[i]; 676 HTMLElement* element = items[i];
677 bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(ele ment)->selected(); 677 bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(ele ment)->selected();
678 if (selected != m_lastOnChangeSelection[i]) 678 if (selected != m_lastOnChangeSelection[i])
679 fireOnChange = true; 679 fireOnChange = true;
680 m_lastOnChangeSelection[i] = selected; 680 m_lastOnChangeSelection[i] = selected;
681 } 681 }
682 682
683 if (fireOnChange) { 683 if (fireOnChange) {
684 RefPtr<HTMLSelectElement> protector(this); 684 RefPtrWillBeRawPtr<HTMLSelectElement> protector(this);
685 dispatchInputEvent(); 685 dispatchInputEvent();
686 dispatchFormControlChangeEvent(); 686 dispatchFormControlChangeEvent();
687 } 687 }
688 } 688 }
689 689
690 void HTMLSelectElement::dispatchInputAndChangeEventForMenuList(bool requiresUser Gesture) 690 void HTMLSelectElement::dispatchInputAndChangeEventForMenuList(bool requiresUser Gesture)
691 { 691 {
692 ASSERT(usesMenuList()); 692 ASSERT(usesMenuList());
693 693
694 int selected = selectedIndex(); 694 int selected = selectedIndex();
695 if (m_lastOnChangeIndex != selected && (!requiresUserGesture || m_isProcessi ngUserDrivenChange)) { 695 if (m_lastOnChangeIndex != selected && (!requiresUserGesture || m_isProcessi ngUserDrivenChange)) {
696 m_lastOnChangeIndex = selected; 696 m_lastOnChangeIndex = selected;
697 m_isProcessingUserDrivenChange = false; 697 m_isProcessingUserDrivenChange = false;
698 RefPtr<HTMLSelectElement> protector(this); 698 RefPtrWillBeRawPtr<HTMLSelectElement> protector(this);
699 dispatchInputEvent(); 699 dispatchInputEvent();
700 dispatchFormControlChangeEvent(); 700 dispatchFormControlChangeEvent();
701 } 701 }
702 } 702 }
703 703
704 void HTMLSelectElement::scrollToSelection() 704 void HTMLSelectElement::scrollToSelection()
705 { 705 {
706 if (usesMenuList()) 706 if (usesMenuList())
707 return; 707 return;
708 708
709 if (RenderObject* renderer = this->renderer()) 709 if (RenderObject* renderer = this->renderer())
710 toRenderListBox(renderer)->selectionChanged(); 710 toRenderListBox(renderer)->selectionChanged();
711 } 711 }
712 712
713 void HTMLSelectElement::setOptionsChangedOnRenderer() 713 void HTMLSelectElement::setOptionsChangedOnRenderer()
714 { 714 {
715 if (RenderObject* renderer = this->renderer()) { 715 if (RenderObject* renderer = this->renderer()) {
716 if (usesMenuList()) 716 if (usesMenuList())
717 toRenderMenuList(renderer)->setOptionsChanged(true); 717 toRenderMenuList(renderer)->setOptionsChanged(true);
718 else 718 else
719 toRenderListBox(renderer)->setOptionsChanged(true); 719 toRenderListBox(renderer)->setOptionsChanged(true);
720 } 720 }
721 } 721 }
722 722
723 const Vector<HTMLElement*>& HTMLSelectElement::listItems() const 723 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& HTMLSelectElement::lis tItems() const
724 { 724 {
725 if (m_shouldRecalcListItems) 725 if (m_shouldRecalcListItems)
726 recalcListItems(); 726 recalcListItems();
727 else { 727 else {
728 #if !ASSERT_DISABLED 728 #if !ASSERT_DISABLED
729 Vector<HTMLElement*> items = m_listItems; 729 WillBeHeapVector<RawPtrWillBeMember<HTMLElement> > items = m_listItems;
730 recalcListItems(false); 730 recalcListItems(false);
731 ASSERT(items == m_listItems); 731 ASSERT(items == m_listItems);
732 #endif 732 #endif
733 } 733 }
734 734
735 return m_listItems; 735 return m_listItems;
736 } 736 }
737 737
738 void HTMLSelectElement::invalidateSelectedItems() 738 void HTMLSelectElement::invalidateSelectedItems()
739 { 739 {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 822
823 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected() ) 823 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected() )
824 firstOption->setSelectedState(true); 824 firstOption->setSelectedState(true);
825 } 825 }
826 826
827 int HTMLSelectElement::selectedIndex() const 827 int HTMLSelectElement::selectedIndex() const
828 { 828 {
829 unsigned index = 0; 829 unsigned index = 0;
830 830
831 // Return the number of the first option selected. 831 // Return the number of the first option selected.
832 const Vector<HTMLElement*>& items = listItems(); 832 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
833 for (size_t i = 0; i < items.size(); ++i) { 833 for (size_t i = 0; i < items.size(); ++i) {
834 HTMLElement* element = items[i]; 834 HTMLElement* element = items[i];
835 if (isHTMLOptionElement(*element)) { 835 if (isHTMLOptionElement(*element)) {
836 if (toHTMLOptionElement(*element).selected()) 836 if (toHTMLOptionElement(*element).selected())
837 return index; 837 return index;
838 ++index; 838 ++index;
839 } 839 }
840 } 840 }
841 841
842 return -1; 842 return -1;
(...skipping 28 matching lines...) Expand all
871 else if (!usesMenuList() || multiple()) 871 else if (!usesMenuList() || multiple())
872 selectOption(-1); 872 selectOption(-1);
873 else 873 else
874 selectOption(nextSelectableListIndex(-1)); 874 selectOption(nextSelectableListIndex(-1));
875 } 875 }
876 876
877 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) 877 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
878 { 878 {
879 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions); 879 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions);
880 880
881 const Vector<HTMLElement*>& items = listItems(); 881 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
882 int listIndex = optionToListIndex(optionIndex); 882 int listIndex = optionToListIndex(optionIndex);
883 883
884 HTMLElement* element = 0; 884 HTMLElement* element = 0;
885 if (listIndex >= 0) { 885 if (listIndex >= 0) {
886 element = items[listIndex]; 886 element = items[listIndex];
887 if (isHTMLOptionElement(*element)) { 887 if (isHTMLOptionElement(*element)) {
888 if (m_activeSelectionAnchorIndex < 0 || shouldDeselect) 888 if (m_activeSelectionAnchorIndex < 0 || shouldDeselect)
889 setActiveSelectionAnchorIndex(listIndex); 889 setActiveSelectionAnchorIndex(listIndex);
890 if (m_activeSelectionEndIndex < 0 || shouldDeselect) 890 if (m_activeSelectionEndIndex < 0 || shouldDeselect)
891 setActiveSelectionEndIndex(listIndex); 891 setActiveSelectionEndIndex(listIndex);
(...skipping 22 matching lines...) Expand all
914 else if (renderer->isListBox()) 914 else if (renderer->isListBox())
915 toRenderListBox(renderer)->selectionChanged(); 915 toRenderListBox(renderer)->selectionChanged();
916 } 916 }
917 } 917 }
918 918
919 notifyFormStateChanged(); 919 notifyFormStateChanged();
920 } 920 }
921 921
922 int HTMLSelectElement::optionToListIndex(int optionIndex) const 922 int HTMLSelectElement::optionToListIndex(int optionIndex) const
923 { 923 {
924 const Vector<HTMLElement*>& items = listItems(); 924 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
925 int listSize = static_cast<int>(items.size()); 925 int listSize = static_cast<int>(items.size());
926 if (optionIndex < 0 || optionIndex >= listSize) 926 if (optionIndex < 0 || optionIndex >= listSize)
927 return -1; 927 return -1;
928 928
929 int optionIndex2 = -1; 929 int optionIndex2 = -1;
930 for (int listIndex = 0; listIndex < listSize; ++listIndex) { 930 for (int listIndex = 0; listIndex < listSize; ++listIndex) {
931 if (isHTMLOptionElement(*items[listIndex])) { 931 if (isHTMLOptionElement(*items[listIndex])) {
932 ++optionIndex2; 932 ++optionIndex2;
933 if (optionIndex2 == optionIndex) 933 if (optionIndex2 == optionIndex)
934 return listIndex; 934 return listIndex;
935 } 935 }
936 } 936 }
937 937
938 return -1; 938 return -1;
939 } 939 }
940 940
941 int HTMLSelectElement::listToOptionIndex(int listIndex) const 941 int HTMLSelectElement::listToOptionIndex(int listIndex) const
942 { 942 {
943 const Vector<HTMLElement*>& items = listItems(); 943 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
944 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLO ptionElement(*items[listIndex])) 944 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLO ptionElement(*items[listIndex]))
945 return -1; 945 return -1;
946 946
947 // Actual index of option not counting OPTGROUP entries that may be in list. 947 // Actual index of option not counting OPTGROUP entries that may be in list.
948 int optionIndex = 0; 948 int optionIndex = 0;
949 for (int i = 0; i < listIndex; ++i) { 949 for (int i = 0; i < listIndex; ++i) {
950 if (isHTMLOptionElement(*items[i])) 950 if (isHTMLOptionElement(*items[i]))
951 ++optionIndex; 951 ++optionIndex;
952 } 952 }
953 953
(...skipping 14 matching lines...) Expand all
968 // We only need to fire change events here for menu lists, because we fire 968 // We only need to fire change events here for menu lists, because we fire
969 // change events for list boxes whenever the selection change is actually ma de. 969 // change events for list boxes whenever the selection change is actually ma de.
970 // This matches other browsers' behavior. 970 // This matches other browsers' behavior.
971 if (usesMenuList()) 971 if (usesMenuList())
972 dispatchInputAndChangeEventForMenuList(); 972 dispatchInputAndChangeEventForMenuList();
973 HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement); 973 HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
974 } 974 }
975 975
976 void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme nt) 976 void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme nt)
977 { 977 {
978 const Vector<HTMLElement*>& items = listItems(); 978 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
979 for (unsigned i = 0; i < items.size(); ++i) { 979 for (unsigned i = 0; i < items.size(); ++i) {
980 HTMLElement* element = items[i]; 980 HTMLElement* element = items[i];
981 if (element != excludeElement && isHTMLOptionElement(*element)) 981 if (element != excludeElement && isHTMLOptionElement(*element))
982 toHTMLOptionElement(element)->setSelectedState(false); 982 toHTMLOptionElement(element)->setSelectedState(false);
983 } 983 }
984 } 984 }
985 985
986 FormControlState HTMLSelectElement::saveFormControlState() const 986 FormControlState HTMLSelectElement::saveFormControlState() const
987 { 987 {
988 const Vector<HTMLElement*>& items = listItems(); 988 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
989 size_t length = items.size(); 989 size_t length = items.size();
990 FormControlState state; 990 FormControlState state;
991 for (unsigned i = 0; i < length; ++i) { 991 for (unsigned i = 0; i < length; ++i) {
992 if (!isHTMLOptionElement(*items[i])) 992 if (!isHTMLOptionElement(*items[i]))
993 continue; 993 continue;
994 HTMLOptionElement* option = toHTMLOptionElement(items[i]); 994 HTMLOptionElement* option = toHTMLOptionElement(items[i]);
995 if (!option->selected()) 995 if (!option->selected())
996 continue; 996 continue;
997 state.append(option->value()); 997 state.append(option->value());
998 if (!multiple()) 998 if (!multiple())
999 break; 999 break;
1000 } 1000 }
1001 return state; 1001 return state;
1002 } 1002 }
1003 1003
1004 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list IndexStart, size_t listIndexEnd) const 1004 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list IndexStart, size_t listIndexEnd) const
1005 { 1005 {
1006 const Vector<HTMLElement*>& items = listItems(); 1006 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1007 size_t loopEndIndex = std::min(items.size(), listIndexEnd); 1007 size_t loopEndIndex = std::min(items.size(), listIndexEnd);
1008 for (size_t i = listIndexStart; i < loopEndIndex; ++i) { 1008 for (size_t i = listIndexStart; i < loopEndIndex; ++i) {
1009 if (!isHTMLOptionElement(items[i])) 1009 if (!isHTMLOptionElement(items[i]))
1010 continue; 1010 continue;
1011 if (toHTMLOptionElement(items[i])->value() == value) 1011 if (toHTMLOptionElement(items[i])->value() == value)
1012 return i; 1012 return i;
1013 } 1013 }
1014 return kNotFound; 1014 return kNotFound;
1015 } 1015 }
1016 1016
1017 void HTMLSelectElement::restoreFormControlState(const FormControlState& state) 1017 void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
1018 { 1018 {
1019 recalcListItems(); 1019 recalcListItems();
1020 1020
1021 const Vector<HTMLElement*>& items = listItems(); 1021 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1022 size_t itemsSize = items.size(); 1022 size_t itemsSize = items.size();
1023 if (!itemsSize) 1023 if (!itemsSize)
1024 return; 1024 return;
1025 1025
1026 for (size_t i = 0; i < itemsSize; ++i) { 1026 for (size_t i = 0; i < itemsSize; ++i) {
1027 if (!isHTMLOptionElement(items[i])) 1027 if (!isHTMLOptionElement(items[i]))
1028 continue; 1028 continue;
1029 toHTMLOptionElement(items[i])->setSelectedState(false); 1029 toHTMLOptionElement(items[i])->setSelectedState(false);
1030 } 1030 }
1031 1031
(...skipping 28 matching lines...) Expand all
1060 lazyReattachIfAttached(); 1060 lazyReattachIfAttached();
1061 } 1061 }
1062 1062
1063 bool HTMLSelectElement::appendFormData(FormDataList& list, bool) 1063 bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
1064 { 1064 {
1065 const AtomicString& name = this->name(); 1065 const AtomicString& name = this->name();
1066 if (name.isEmpty()) 1066 if (name.isEmpty())
1067 return false; 1067 return false;
1068 1068
1069 bool successful = false; 1069 bool successful = false;
1070 const Vector<HTMLElement*>& items = listItems(); 1070 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1071 1071
1072 for (unsigned i = 0; i < items.size(); ++i) { 1072 for (unsigned i = 0; i < items.size(); ++i) {
1073 HTMLElement* element = items[i]; 1073 HTMLElement* element = items[i];
1074 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) { 1074 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) {
1075 list.appendData(name, toHTMLOptionElement(*element).value()); 1075 list.appendData(name, toHTMLOptionElement(*element).value());
1076 successful = true; 1076 successful = true;
1077 } 1077 }
1078 } 1078 }
1079 1079
1080 // It's possible that this is a menulist with multiple options and nothing 1080 // It's possible that this is a menulist with multiple options and nothing
1081 // will be submitted (!successful). We won't send a unselected non-disabled 1081 // will be submitted (!successful). We won't send a unselected non-disabled
1082 // option as fallback. This behavior matches to other browsers. 1082 // option as fallback. This behavior matches to other browsers.
1083 return successful; 1083 return successful;
1084 } 1084 }
1085 1085
1086 void HTMLSelectElement::resetImpl() 1086 void HTMLSelectElement::resetImpl()
1087 { 1087 {
1088 HTMLOptionElement* firstOption = 0; 1088 HTMLOptionElement* firstOption = 0;
1089 HTMLOptionElement* selectedOption = 0; 1089 HTMLOptionElement* selectedOption = 0;
1090 1090
1091 const Vector<HTMLElement*>& items = listItems(); 1091 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1092 for (unsigned i = 0; i < items.size(); ++i) { 1092 for (unsigned i = 0; i < items.size(); ++i) {
1093 HTMLElement* element = items[i]; 1093 HTMLElement* element = items[i];
1094 if (!isHTMLOptionElement(*element)) 1094 if (!isHTMLOptionElement(*element))
1095 continue; 1095 continue;
1096 1096
1097 if (items[i]->fastHasAttribute(selectedAttr)) { 1097 if (items[i]->fastHasAttribute(selectedAttr)) {
1098 if (selectedOption && !m_multiple) 1098 if (selectedOption && !m_multiple)
1099 selectedOption->setSelectedState(false); 1099 selectedOption->setSelectedState(false);
1100 toHTMLOptionElement(element)->setSelectedState(true); 1100 toHTMLOptionElement(element)->setSelectedState(true);
1101 selectedOption = toHTMLOptionElement(element); 1101 selectedOption = toHTMLOptionElement(element);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 // When using spatial navigation, we want to be able to navigate away 1159 // When using spatial navigation, we want to be able to navigate away
1160 // from the select element when the user hits any of the arrow keys, 1160 // from the select element when the user hits any of the arrow keys,
1161 // instead of changing the selection. 1161 // instead of changing the selection.
1162 if (isSpatialNavigationEnabled(document().frame())) { 1162 if (isSpatialNavigationEnabled(document().frame())) {
1163 if (!m_activeSelectionState) 1163 if (!m_activeSelectionState)
1164 return; 1164 return;
1165 } 1165 }
1166 1166
1167 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); 1167 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier();
1168 bool handled = true; 1168 bool handled = true;
1169 const Vector<HTMLElement*>& listItems = this->listItems(); 1169 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = th is->listItems();
1170 int listIndex = optionToListIndex(selectedIndex()); 1170 int listIndex = optionToListIndex(selectedIndex());
1171 1171
1172 if (keyIdentifier == "Down" || keyIdentifier == "Right") 1172 if (keyIdentifier == "Down" || keyIdentifier == "Right")
1173 listIndex = nextValidIndex(listIndex, SkipForwards, 1); 1173 listIndex = nextValidIndex(listIndex, SkipForwards, 1);
1174 else if (keyIdentifier == "Up" || keyIdentifier == "Left") 1174 else if (keyIdentifier == "Up" || keyIdentifier == "Left")
1175 listIndex = nextValidIndex(listIndex, SkipBackwards, 1); 1175 listIndex = nextValidIndex(listIndex, SkipBackwards, 1);
1176 else if (keyIdentifier == "PageDown") 1176 else if (keyIdentifier == "PageDown")
1177 listIndex = nextValidIndex(listIndex, SkipForwards, 3); 1177 listIndex = nextValidIndex(listIndex, SkipForwards, 3);
1178 else if (keyIdentifier == "PageUp") 1178 else if (keyIdentifier == "PageUp")
1179 listIndex = nextValidIndex(listIndex, SkipBackwards, 3); 1179 listIndex = nextValidIndex(listIndex, SkipBackwards, 3);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 // clicked. 1330 // clicked.
1331 if (m_activeSelectionAnchorIndex < 0 || !shiftSelect) 1331 if (m_activeSelectionAnchorIndex < 0 || !shiftSelect)
1332 setActiveSelectionAnchorIndex(listIndex); 1332 setActiveSelectionAnchorIndex(listIndex);
1333 1333
1334 setActiveSelectionEndIndex(listIndex); 1334 setActiveSelectionEndIndex(listIndex);
1335 updateListBoxSelection(!multiSelect); 1335 updateListBoxSelection(!multiSelect);
1336 } 1336 }
1337 1337
1338 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) 1338 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
1339 { 1339 {
1340 const Vector<HTMLElement*>& listItems = this->listItems(); 1340 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this-> listItems();
1341 if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent()) { 1341 if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent()) {
1342 focus(); 1342 focus();
1343 // 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. 1343 // 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.
1344 if (!renderer() || !renderer()->isListBox()) 1344 if (!renderer() || !renderer()->isListBox())
1345 return; 1345 return;
1346 1346
1347 // Convert to coords relative to the list box if needed. 1347 // Convert to coords relative to the list box if needed.
1348 GestureEvent& gestureEvent = toGestureEvent(*event); 1348 GestureEvent& gestureEvent = toGestureEvent(*event);
1349 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(gestu reEvent.absoluteLocation(), UseTransforms)); 1349 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(gestu reEvent.absoluteLocation(), UseTransforms));
1350 int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize (localOffset)); 1350 int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize (localOffset));
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 typeAheadFind(keyboardEvent); 1529 typeAheadFind(keyboardEvent);
1530 event->setDefaultHandled(); 1530 event->setDefaultHandled();
1531 return; 1531 return;
1532 } 1532 }
1533 } 1533 }
1534 HTMLFormControlElementWithState::defaultEventHandler(event); 1534 HTMLFormControlElementWithState::defaultEventHandler(event);
1535 } 1535 }
1536 1536
1537 int HTMLSelectElement::lastSelectedListIndex() const 1537 int HTMLSelectElement::lastSelectedListIndex() const
1538 { 1538 {
1539 const Vector<HTMLElement*>& items = listItems(); 1539 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1540 for (size_t i = items.size(); i;) { 1540 for (size_t i = items.size(); i;) {
1541 HTMLElement* element = items[--i]; 1541 HTMLElement* element = items[--i];
1542 if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selec ted()) 1542 if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selec ted())
1543 return i; 1543 return i;
1544 } 1544 }
1545 return -1; 1545 return -1;
1546 } 1546 }
1547 1547
1548 int HTMLSelectElement::indexOfSelectedOption() const 1548 int HTMLSelectElement::indexOfSelectedOption() const
1549 { 1549 {
1550 return optionToListIndex(selectedIndex()); 1550 return optionToListIndex(selectedIndex());
1551 } 1551 }
1552 1552
1553 int HTMLSelectElement::optionCount() const 1553 int HTMLSelectElement::optionCount() const
1554 { 1554 {
1555 return listItems().size(); 1555 return listItems().size();
1556 } 1556 }
1557 1557
1558 String HTMLSelectElement::optionAtIndex(int index) const 1558 String HTMLSelectElement::optionAtIndex(int index) const
1559 { 1559 {
1560 const Vector<HTMLElement*>& items = listItems(); 1560 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1561 1561
1562 HTMLElement* element = items[index]; 1562 HTMLElement* element = items[index];
1563 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabl edFormControl()) 1563 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabl edFormControl())
1564 return String(); 1564 return String();
1565 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); 1565 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
1566 } 1566 }
1567 1567
1568 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) 1568 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
1569 { 1569 {
1570 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea d::CycleFirstChar); 1570 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea d::CycleFirstChar);
(...skipping 14 matching lines...) Expand all
1585 return InsertionDone; 1585 return InsertionDone;
1586 } 1586 }
1587 1587
1588 void HTMLSelectElement::accessKeySetSelectedIndex(int index) 1588 void HTMLSelectElement::accessKeySetSelectedIndex(int index)
1589 { 1589 {
1590 // First bring into focus the list box. 1590 // First bring into focus the list box.
1591 if (!focused()) 1591 if (!focused())
1592 accessKeyAction(false); 1592 accessKeyAction(false);
1593 1593
1594 // If this index is already selected, unselect. otherwise update the selecte d index. 1594 // If this index is already selected, unselect. otherwise update the selecte d index.
1595 const Vector<HTMLElement*>& items = listItems(); 1595 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1596 int listIndex = optionToListIndex(index); 1596 int listIndex = optionToListIndex(index);
1597 if (listIndex >= 0) { 1597 if (listIndex >= 0) {
1598 HTMLElement* element = items[listIndex]; 1598 HTMLElement* element = items[listIndex];
1599 if (isHTMLOptionElement(*element)) { 1599 if (isHTMLOptionElement(*element)) {
1600 if (toHTMLOptionElement(*element).selected()) 1600 if (toHTMLOptionElement(*element).selected())
1601 toHTMLOptionElement(*element).setSelectedState(false); 1601 toHTMLOptionElement(*element).setSelectedState(false);
1602 else 1602 else
1603 selectOption(index, DispatchInputAndChangeEvent | UserDriven); 1603 selectOption(index, DispatchInputAndChangeEvent | UserDriven);
1604 } 1604 }
1605 } 1605 }
1606 1606
1607 if (usesMenuList()) 1607 if (usesMenuList())
1608 dispatchInputAndChangeEventForMenuList(); 1608 dispatchInputAndChangeEventForMenuList();
1609 else 1609 else
1610 listBoxOnChange(); 1610 listBoxOnChange();
1611 1611
1612 scrollToSelection(); 1612 scrollToSelection();
1613 } 1613 }
1614 1614
1615 unsigned HTMLSelectElement::length() const 1615 unsigned HTMLSelectElement::length() const
1616 { 1616 {
1617 unsigned options = 0; 1617 unsigned options = 0;
1618 1618
1619 const Vector<HTMLElement*>& items = listItems(); 1619 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems( );
1620 for (unsigned i = 0; i < items.size(); ++i) { 1620 for (unsigned i = 0; i < items.size(); ++i) {
1621 if (isHTMLOptionElement(*items[i])) 1621 if (isHTMLOptionElement(*items[i]))
1622 ++options; 1622 ++options;
1623 } 1623 }
1624 1624
1625 return options; 1625 return options;
1626 } 1626 }
1627 1627
1628 void HTMLSelectElement::finishParsingChildren() 1628 void HTMLSelectElement::finishParsingChildren()
1629 { 1629 {
1630 HTMLFormControlElementWithState::finishParsingChildren(); 1630 HTMLFormControlElementWithState::finishParsingChildren();
1631 updateListItemSelectedStates(); 1631 updateListItemSelectedStates();
1632 } 1632 }
1633 1633
1634 bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOp tionElement> value, ExceptionState& exceptionState) 1634 bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeR awPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
1635 { 1635 {
1636 if (!value) { // undefined or null 1636 if (!value) { // undefined or null
1637 remove(index); 1637 remove(index);
1638 return true; 1638 return true;
1639 } 1639 }
1640 setOption(index, value.get(), exceptionState); 1640 setOption(index, value.get(), exceptionState);
1641 return true; 1641 return true;
1642 } 1642 }
1643 1643
1644 bool HTMLSelectElement::isInteractiveContent() const 1644 bool HTMLSelectElement::isInteractiveContent() const
1645 { 1645 {
1646 return true; 1646 return true;
1647 } 1647 }
1648 1648
1649 bool HTMLSelectElement::supportsAutofocus() const 1649 bool HTMLSelectElement::supportsAutofocus() const
1650 { 1650 {
1651 return true; 1651 return true;
1652 } 1652 }
1653 1653
1654 void HTMLSelectElement::updateListOnRenderer() 1654 void HTMLSelectElement::updateListOnRenderer()
1655 { 1655 {
1656 setOptionsChangedOnRenderer(); 1656 setOptionsChangedOnRenderer();
1657 } 1657 }
1658 1658
1659 void HTMLSelectElement::trace(Visitor* visitor)
1660 {
1661 visitor->trace(m_listItems);
1662 HTMLFormControlElementWithState::trace(visitor);
1663 }
1664
1659 } // namespace 1665 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698