| 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 { | 233 { |
| 234 int listIndex = optionToListIndex(optionIndex); | 234 int listIndex = optionToListIndex(optionIndex); |
| 235 if (listIndex < 0) | 235 if (listIndex < 0) |
| 236 return; | 236 return; |
| 237 | 237 |
| 238 listItems()[listIndex]->remove(IGNORE_EXCEPTION); | 238 listItems()[listIndex]->remove(IGNORE_EXCEPTION); |
| 239 } | 239 } |
| 240 | 240 |
| 241 String HTMLSelectElement::value() const | 241 String HTMLSelectElement::value() const |
| 242 { | 242 { |
| 243 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 243 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 244 for (unsigned i = 0; i < items.size(); i++) { | 244 for (unsigned i = 0; i < items.size(); i++) { |
| 245 if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->sele
cted()) | 245 if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->sele
cted()) |
| 246 return toHTMLOptionElement(items[i])->value(); | 246 return toHTMLOptionElement(items[i])->value(); |
| 247 } | 247 } |
| 248 return ""; | 248 return ""; |
| 249 } | 249 } |
| 250 | 250 |
| 251 void HTMLSelectElement::setValue(const String &value, bool sendEvents) | 251 void HTMLSelectElement::setValue(const String &value, bool sendEvents) |
| 252 { | 252 { |
| 253 // We clear the previously selected option(s) when needed, to guarantee call
ing setSelectedIndex() only once. | 253 // We clear the previously selected option(s) when needed, to guarantee call
ing setSelectedIndex() only once. |
| 254 int optionIndex = 0; | 254 int optionIndex = 0; |
| 255 if (value.isNull()) { | 255 if (value.isNull()) { |
| 256 optionIndex = -1; | 256 optionIndex = -1; |
| 257 } else { | 257 } else { |
| 258 // Find the option with value() matching the given parameter and make it
the current selection. | 258 // Find the option with value() matching the given parameter and make it
the current selection. |
| 259 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listIt
ems(); | 259 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listIte
ms(); |
| 260 for (unsigned i = 0; i < items.size(); i++) { | 260 for (unsigned i = 0; i < items.size(); i++) { |
| 261 if (isHTMLOptionElement(items[i])) { | 261 if (isHTMLOptionElement(items[i])) { |
| 262 if (toHTMLOptionElement(items[i])->value() == value) | 262 if (toHTMLOptionElement(items[i])->value() == value) |
| 263 break; | 263 break; |
| 264 optionIndex++; | 264 optionIndex++; |
| 265 } | 265 } |
| 266 } | 266 } |
| 267 if (optionIndex >= static_cast<int>(items.size())) | 267 if (optionIndex >= static_cast<int>(items.size())) |
| 268 optionIndex = -1; | 268 optionIndex = -1; |
| 269 } | 269 } |
| 270 | 270 |
| 271 int previousSelectedIndex = selectedIndex(); | 271 int previousSelectedIndex = selectedIndex(); |
| 272 setSuggestedIndex(-1); | 272 setSuggestedIndex(-1); |
| 273 if (m_isAutofilledByPreview) | 273 if (m_isAutofilledByPreview) |
| 274 setAutofilled(false); | 274 setAutofilled(false); |
| 275 setSelectedIndex(optionIndex); | 275 setSelectedIndex(optionIndex); |
| 276 | 276 |
| 277 if (sendEvents && previousSelectedIndex != selectedIndex()) { | 277 if (sendEvents && previousSelectedIndex != selectedIndex()) { |
| 278 if (usesMenuList()) | 278 if (usesMenuList()) |
| 279 dispatchInputAndChangeEventForMenuList(false); | 279 dispatchInputAndChangeEventForMenuList(false); |
| 280 else | 280 else |
| 281 listBoxOnChange(); | 281 listBoxOnChange(); |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 String HTMLSelectElement::suggestedValue() const | 285 String HTMLSelectElement::suggestedValue() const |
| 286 { | 286 { |
| 287 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 287 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 288 for (unsigned i = 0; i < items.size(); ++i) { | 288 for (unsigned i = 0; i < items.size(); ++i) { |
| 289 if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) { | 289 if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) { |
| 290 if (i == static_cast<unsigned>(m_suggestedIndex)) | 290 if (i == static_cast<unsigned>(m_suggestedIndex)) |
| 291 return toHTMLOptionElement(items[i])->value(); | 291 return toHTMLOptionElement(items[i])->value(); |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 return ""; | 294 return ""; |
| 295 } | 295 } |
| 296 | 296 |
| 297 void HTMLSelectElement::setSuggestedValue(const String& value) | 297 void HTMLSelectElement::setSuggestedValue(const String& value) |
| 298 { | 298 { |
| 299 if (value.isNull()) { | 299 if (value.isNull()) { |
| 300 setSuggestedIndex(-1); | 300 setSuggestedIndex(-1); |
| 301 return; | 301 return; |
| 302 } | 302 } |
| 303 | 303 |
| 304 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 304 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 305 unsigned optionIndex = 0; | 305 unsigned optionIndex = 0; |
| 306 for (unsigned i = 0; i < items.size(); ++i) { | 306 for (unsigned i = 0; i < items.size(); ++i) { |
| 307 if (isHTMLOptionElement(items[i])) { | 307 if (isHTMLOptionElement(items[i])) { |
| 308 if (toHTMLOptionElement(items[i])->value() == value) { | 308 if (toHTMLOptionElement(items[i])->value() == value) { |
| 309 setSuggestedIndex(optionIndex); | 309 setSuggestedIndex(optionIndex); |
| 310 m_isAutofilledByPreview = true; | 310 m_isAutofilledByPreview = true; |
| 311 return; | 311 return; |
| 312 } | 312 } |
| 313 optionIndex++; | 313 optionIndex++; |
| 314 } | 314 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 490 |
| 491 if (diff < 0) { // Add dummy elements. | 491 if (diff < 0) { // Add dummy elements. |
| 492 do { | 492 do { |
| 493 RefPtrWillBeRawPtr<Element> option = document().createElement(option
Tag, false); | 493 RefPtrWillBeRawPtr<Element> option = document().createElement(option
Tag, false); |
| 494 ASSERT(option); | 494 ASSERT(option); |
| 495 add(toHTMLElement(option), 0, exceptionState); | 495 add(toHTMLElement(option), 0, exceptionState); |
| 496 if (exceptionState.hadException()) | 496 if (exceptionState.hadException()) |
| 497 break; | 497 break; |
| 498 } while (++diff); | 498 } while (++diff); |
| 499 } else { | 499 } else { |
| 500 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listIt
ems(); | 500 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listIte
ms(); |
| 501 | 501 |
| 502 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list | 502 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list |
| 503 // of elements that we intend to remove then attempt to remove them one
at a time. | 503 // of elements that we intend to remove then attempt to remove them one
at a time. |
| 504 WillBeHeapVector<RefPtrWillBeMember<Element> > itemsToRemove; | 504 WillBeHeapVector<RefPtrWillBeMember<Element>> itemsToRemove; |
| 505 size_t optionIndex = 0; | 505 size_t optionIndex = 0; |
| 506 for (size_t i = 0; i < items.size(); ++i) { | 506 for (size_t i = 0; i < items.size(); ++i) { |
| 507 Element* item = items[i]; | 507 Element* item = items[i]; |
| 508 if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) { | 508 if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) { |
| 509 ASSERT(item->parentNode()); | 509 ASSERT(item->parentNode()); |
| 510 itemsToRemove.append(item); | 510 itemsToRemove.append(item); |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 | 513 |
| 514 for (size_t i = 0; i < itemsToRemove.size(); ++i) { | 514 for (size_t i = 0; i < itemsToRemove.size(); ++i) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 525 return isRequired(); | 525 return isRequired(); |
| 526 } | 526 } |
| 527 | 527 |
| 528 // Returns the 1st valid item |skip| items from |listIndex| in direction |direct
ion| if there is one. | 528 // Returns the 1st valid item |skip| items from |listIndex| in direction |direct
ion| if there is one. |
| 529 // Otherwise, it returns the valid item closest to that boundary which is past |
listIndex| if there is one. | 529 // Otherwise, it returns the valid item closest to that boundary which is past |
listIndex| if there is one. |
| 530 // Otherwise, it returns |listIndex|. | 530 // Otherwise, it returns |listIndex|. |
| 531 // Valid means that it is enabled and an option element. | 531 // Valid means that it is enabled and an option element. |
| 532 int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in
t skip) const | 532 int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, in
t skip) const |
| 533 { | 533 { |
| 534 ASSERT(direction == -1 || direction == 1); | 534 ASSERT(direction == -1 || direction == 1); |
| 535 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->
listItems(); | 535 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = this->l
istItems(); |
| 536 int lastGoodIndex = listIndex; | 536 int lastGoodIndex = listIndex; |
| 537 int size = listItems.size(); | 537 int size = listItems.size(); |
| 538 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex +
= direction) { | 538 for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex +
= direction) { |
| 539 --skip; | 539 --skip; |
| 540 HTMLElement* element = listItems[listIndex]; | 540 HTMLElement* element = listItems[listIndex]; |
| 541 if (!isHTMLOptionElement(*element)) | 541 if (!isHTMLOptionElement(*element)) |
| 542 continue; | 542 continue; |
| 543 if (toHTMLOptionElement(*element).isDisplayNone()) | 543 if (toHTMLOptionElement(*element).isDisplayNone()) |
| 544 continue; | 544 continue; |
| 545 if (element->isDisabledFormControl()) | 545 if (element->isDisabledFormControl()) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 560 | 560 |
| 561 int HTMLSelectElement::previousSelectableListIndex(int startIndex) const | 561 int HTMLSelectElement::previousSelectableListIndex(int startIndex) const |
| 562 { | 562 { |
| 563 if (startIndex == -1) | 563 if (startIndex == -1) |
| 564 startIndex = listItems().size(); | 564 startIndex = listItems().size(); |
| 565 return nextValidIndex(startIndex, SkipBackwards, 1); | 565 return nextValidIndex(startIndex, SkipBackwards, 1); |
| 566 } | 566 } |
| 567 | 567 |
| 568 int HTMLSelectElement::firstSelectableListIndex() const | 568 int HTMLSelectElement::firstSelectableListIndex() const |
| 569 { | 569 { |
| 570 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 570 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 571 int index = nextValidIndex(items.size(), SkipBackwards, INT_MAX); | 571 int index = nextValidIndex(items.size(), SkipBackwards, INT_MAX); |
| 572 if (static_cast<size_t>(index) == items.size()) | 572 if (static_cast<size_t>(index) == items.size()) |
| 573 return -1; | 573 return -1; |
| 574 return index; | 574 return index; |
| 575 } | 575 } |
| 576 | 576 |
| 577 int HTMLSelectElement::lastSelectableListIndex() const | 577 int HTMLSelectElement::lastSelectableListIndex() const |
| 578 { | 578 { |
| 579 return nextValidIndex(-1, SkipForwards, INT_MAX); | 579 return nextValidIndex(-1, SkipForwards, INT_MAX); |
| 580 } | 580 } |
| 581 | 581 |
| 582 // Returns the index of the next valid item one page away from |startIndex| in d
irection |direction|. | 582 // Returns the index of the next valid item one page away from |startIndex| in d
irection |direction|. |
| 583 int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec
tion direction) const | 583 int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirec
tion direction) const |
| 584 { | 584 { |
| 585 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 585 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 586 // Can't use m_size because renderer forces a minimum size. | 586 // Can't use m_size because renderer forces a minimum size. |
| 587 int pageSize = 0; | 587 int pageSize = 0; |
| 588 if (renderer()->isListBox()) | 588 if (renderer()->isListBox()) |
| 589 pageSize = toRenderListBox(renderer())->size() - 1; // -1 so we still sh
ow context. | 589 pageSize = toRenderListBox(renderer())->size() - 1; // -1 so we still sh
ow context. |
| 590 | 590 |
| 591 // One page away, but not outside valid bounds. | 591 // One page away, but not outside valid bounds. |
| 592 // If there is a valid option item one page away, the index is chosen. | 592 // If there is a valid option item one page away, the index is chosen. |
| 593 // If there is no exact one page away valid option, returns startIndex or th
e most far index. | 593 // If there is no exact one page away valid option, returns startIndex or th
e most far index. |
| 594 int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1); | 594 int edgeIndex = (direction == SkipForwards) ? 0 : (items.size() - 1); |
| 595 int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edg
eIndex - startIndex)); | 595 int skipAmount = pageSize + ((direction == SkipForwards) ? startIndex : (edg
eIndex - startIndex)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 616 } | 616 } |
| 617 | 617 |
| 618 void HTMLSelectElement::saveLastSelection() | 618 void HTMLSelectElement::saveLastSelection() |
| 619 { | 619 { |
| 620 if (usesMenuList()) { | 620 if (usesMenuList()) { |
| 621 m_lastOnChangeIndex = selectedIndex(); | 621 m_lastOnChangeIndex = selectedIndex(); |
| 622 return; | 622 return; |
| 623 } | 623 } |
| 624 | 624 |
| 625 m_lastOnChangeSelection.clear(); | 625 m_lastOnChangeSelection.clear(); |
| 626 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 626 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 627 for (unsigned i = 0; i < items.size(); ++i) { | 627 for (unsigned i = 0; i < items.size(); ++i) { |
| 628 HTMLElement* element = items[i]; | 628 HTMLElement* element = items[i]; |
| 629 m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOp
tionElement(element)->selected()); | 629 m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOp
tionElement(element)->selected()); |
| 630 } | 630 } |
| 631 } | 631 } |
| 632 | 632 |
| 633 void HTMLSelectElement::setActiveSelectionAnchorIndex(int index) | 633 void HTMLSelectElement::setActiveSelectionAnchorIndex(int index) |
| 634 { | 634 { |
| 635 m_activeSelectionAnchorIndex = index; | 635 m_activeSelectionAnchorIndex = index; |
| 636 | 636 |
| 637 // Cache the selection state so we can restore the old selection as the new | 637 // Cache the selection state so we can restore the old selection as the new |
| 638 // selection pivots around this anchor index. | 638 // selection pivots around this anchor index. |
| 639 m_cachedStateForActiveSelection.clear(); | 639 m_cachedStateForActiveSelection.clear(); |
| 640 | 640 |
| 641 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 641 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 642 for (unsigned i = 0; i < items.size(); ++i) { | 642 for (unsigned i = 0; i < items.size(); ++i) { |
| 643 HTMLElement* element = items[i]; | 643 HTMLElement* element = items[i]; |
| 644 m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) &&
toHTMLOptionElement(element)->selected()); | 644 m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) &&
toHTMLOptionElement(element)->selected()); |
| 645 } | 645 } |
| 646 } | 646 } |
| 647 | 647 |
| 648 void HTMLSelectElement::setActiveSelectionEndIndex(int index) | 648 void HTMLSelectElement::setActiveSelectionEndIndex(int index) |
| 649 { | 649 { |
| 650 if (index == m_activeSelectionEndIndex) | 650 if (index == m_activeSelectionEndIndex) |
| 651 return; | 651 return; |
| 652 m_activeSelectionEndIndex = index; | 652 m_activeSelectionEndIndex = index; |
| 653 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::Control)); | 653 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(
StyleChangeReason::Control)); |
| 654 } | 654 } |
| 655 | 655 |
| 656 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions, bool s
croll) | 656 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions, bool s
croll) |
| 657 { | 657 { |
| 658 ASSERT(renderer() && (renderer()->isListBox() || m_multiple)); | 658 ASSERT(renderer() && (renderer()->isListBox() || m_multiple)); |
| 659 ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0); | 659 ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0); |
| 660 | 660 |
| 661 unsigned start = std::min(m_activeSelectionAnchorIndex, m_activeSelectionEnd
Index); | 661 unsigned start = std::min(m_activeSelectionAnchorIndex, m_activeSelectionEnd
Index); |
| 662 unsigned end = std::max(m_activeSelectionAnchorIndex, m_activeSelectionEndIn
dex); | 662 unsigned end = std::max(m_activeSelectionAnchorIndex, m_activeSelectionEndIn
dex); |
| 663 | 663 |
| 664 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 664 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 665 for (unsigned i = 0; i < items.size(); ++i) { | 665 for (unsigned i = 0; i < items.size(); ++i) { |
| 666 HTMLElement* element = items[i]; | 666 HTMLElement* element = items[i]; |
| 667 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi
sabledFormControl() || !toHTMLOptionElement(element)->renderer()) | 667 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDi
sabledFormControl() || !toHTMLOptionElement(element)->renderer()) |
| 668 continue; | 668 continue; |
| 669 | 669 |
| 670 if (i >= start && i <= end) | 670 if (i >= start && i <= end) |
| 671 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat
e); | 671 toHTMLOptionElement(element)->setSelectedState(m_activeSelectionStat
e); |
| 672 else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.si
ze()) | 672 else if (deselectOtherOptions || i >= m_cachedStateForActiveSelection.si
ze()) |
| 673 toHTMLOptionElement(element)->setSelectedState(false); | 673 toHTMLOptionElement(element)->setSelectedState(false); |
| 674 else | 674 else |
| 675 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv
eSelection[i]); | 675 toHTMLOptionElement(element)->setSelectedState(m_cachedStateForActiv
eSelection[i]); |
| 676 } | 676 } |
| 677 | 677 |
| 678 setNeedsValidityCheck(); | 678 setNeedsValidityCheck(); |
| 679 if (scroll) | 679 if (scroll) |
| 680 scrollToSelection(); | 680 scrollToSelection(); |
| 681 notifyFormStateChanged(); | 681 notifyFormStateChanged(); |
| 682 } | 682 } |
| 683 | 683 |
| 684 void HTMLSelectElement::listBoxOnChange() | 684 void HTMLSelectElement::listBoxOnChange() |
| 685 { | 685 { |
| 686 ASSERT(!usesMenuList() || m_multiple); | 686 ASSERT(!usesMenuList() || m_multiple); |
| 687 | 687 |
| 688 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 688 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 689 | 689 |
| 690 // If the cached selection list is empty, or the size has changed, then fire | 690 // If the cached selection list is empty, or the size has changed, then fire |
| 691 // dispatchFormControlChangeEvent, and return early. | 691 // dispatchFormControlChangeEvent, and return early. |
| 692 // FIXME: Why? This looks unreasonable. | 692 // FIXME: Why? This looks unreasonable. |
| 693 if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != i
tems.size()) { | 693 if (m_lastOnChangeSelection.isEmpty() || m_lastOnChangeSelection.size() != i
tems.size()) { |
| 694 dispatchFormControlChangeEvent(); | 694 dispatchFormControlChangeEvent(); |
| 695 return; | 695 return; |
| 696 } | 696 } |
| 697 | 697 |
| 698 // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent. | 698 // Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 } | 738 } |
| 739 | 739 |
| 740 void HTMLSelectElement::setOptionsChangedOnRenderer() | 740 void HTMLSelectElement::setOptionsChangedOnRenderer() |
| 741 { | 741 { |
| 742 if (RenderObject* renderer = this->renderer()) { | 742 if (RenderObject* renderer = this->renderer()) { |
| 743 if (usesMenuList()) | 743 if (usesMenuList()) |
| 744 toRenderMenuList(renderer)->setOptionsChanged(true); | 744 toRenderMenuList(renderer)->setOptionsChanged(true); |
| 745 } | 745 } |
| 746 } | 746 } |
| 747 | 747 |
| 748 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& HTMLSelectElement::lis
tItems() const | 748 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& HTMLSelectElement::list
Items() const |
| 749 { | 749 { |
| 750 if (m_shouldRecalcListItems) | 750 if (m_shouldRecalcListItems) |
| 751 recalcListItems(); | 751 recalcListItems(); |
| 752 else { | 752 else { |
| 753 #if ENABLE(ASSERT) | 753 #if ENABLE(ASSERT) |
| 754 WillBeHeapVector<RawPtrWillBeMember<HTMLElement> > items = m_listItems; | 754 WillBeHeapVector<RawPtrWillBeMember<HTMLElement>> items = m_listItems; |
| 755 recalcListItems(false); | 755 recalcListItems(false); |
| 756 ASSERT(items == m_listItems); | 756 ASSERT(items == m_listItems); |
| 757 #endif | 757 #endif |
| 758 } | 758 } |
| 759 | 759 |
| 760 return m_listItems; | 760 return m_listItems; |
| 761 } | 761 } |
| 762 | 762 |
| 763 void HTMLSelectElement::invalidateSelectedItems() | 763 void HTMLSelectElement::invalidateSelectedItems() |
| 764 { | 764 { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 | 847 |
| 848 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected()
) | 848 if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected()
) |
| 849 firstOption->setSelectedState(true); | 849 firstOption->setSelectedState(true); |
| 850 } | 850 } |
| 851 | 851 |
| 852 int HTMLSelectElement::selectedIndex() const | 852 int HTMLSelectElement::selectedIndex() const |
| 853 { | 853 { |
| 854 unsigned index = 0; | 854 unsigned index = 0; |
| 855 | 855 |
| 856 // Return the number of the first option selected. | 856 // Return the number of the first option selected. |
| 857 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 857 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 858 for (size_t i = 0; i < items.size(); ++i) { | 858 for (size_t i = 0; i < items.size(); ++i) { |
| 859 HTMLElement* element = items[i]; | 859 HTMLElement* element = items[i]; |
| 860 if (isHTMLOptionElement(*element)) { | 860 if (isHTMLOptionElement(*element)) { |
| 861 if (toHTMLOptionElement(*element).selected()) | 861 if (toHTMLOptionElement(*element).selected()) |
| 862 return index; | 862 return index; |
| 863 ++index; | 863 ++index; |
| 864 } | 864 } |
| 865 } | 865 } |
| 866 | 866 |
| 867 return -1; | 867 return -1; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 886 scrollTo(suggestedIndex); | 886 scrollTo(suggestedIndex); |
| 887 } | 887 } |
| 888 } | 888 } |
| 889 | 889 |
| 890 void HTMLSelectElement::scrollTo(int listIndex) | 890 void HTMLSelectElement::scrollTo(int listIndex) |
| 891 { | 891 { |
| 892 if (listIndex < 0) | 892 if (listIndex < 0) |
| 893 return; | 893 return; |
| 894 if (usesMenuList()) | 894 if (usesMenuList()) |
| 895 return; | 895 return; |
| 896 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 896 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 897 int listSize = static_cast<int>(items.size()); | 897 int listSize = static_cast<int>(items.size()); |
| 898 if (listIndex >= listSize) | 898 if (listIndex >= listSize) |
| 899 return; | 899 return; |
| 900 document().updateLayoutIgnorePendingStylesheets(); | 900 document().updateLayoutIgnorePendingStylesheets(); |
| 901 if (!renderer() || !renderer()->isListBox()) | 901 if (!renderer() || !renderer()->isListBox()) |
| 902 return; | 902 return; |
| 903 LayoutRect bounds = items[listIndex]->boundingBox(); | 903 LayoutRect bounds = items[listIndex]->boundingBox(); |
| 904 toRenderListBox(renderer())->scrollToRect(bounds); | 904 toRenderListBox(renderer())->scrollToRect(bounds); |
| 905 } | 905 } |
| 906 | 906 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 925 if (listIndex <= m_activeSelectionEndIndex) | 925 if (listIndex <= m_activeSelectionEndIndex) |
| 926 m_activeSelectionEndIndex--; | 926 m_activeSelectionEndIndex--; |
| 927 if (listIndex == selectedIndex()) | 927 if (listIndex == selectedIndex()) |
| 928 setAutofilled(false); | 928 setAutofilled(false); |
| 929 } | 929 } |
| 930 | 930 |
| 931 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) | 931 void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) |
| 932 { | 932 { |
| 933 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions); | 933 bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions); |
| 934 | 934 |
| 935 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 935 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 936 int listIndex = optionToListIndex(optionIndex); | 936 int listIndex = optionToListIndex(optionIndex); |
| 937 | 937 |
| 938 if (selectedIndex() != optionIndex && isAutofilled()) | 938 if (selectedIndex() != optionIndex && isAutofilled()) |
| 939 setAutofilled(false); | 939 setAutofilled(false); |
| 940 | 940 |
| 941 HTMLElement* element = 0; | 941 HTMLElement* element = 0; |
| 942 if (listIndex >= 0) { | 942 if (listIndex >= 0) { |
| 943 element = items[listIndex]; | 943 element = items[listIndex]; |
| 944 if (isHTMLOptionElement(*element)) { | 944 if (isHTMLOptionElement(*element)) { |
| 945 if (m_activeSelectionAnchorIndex < 0 || shouldDeselect) | 945 if (m_activeSelectionAnchorIndex < 0 || shouldDeselect) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 973 cache->selectedChildrenChanged(this); | 973 cache->selectedChildrenChanged(this); |
| 974 } | 974 } |
| 975 } | 975 } |
| 976 } | 976 } |
| 977 | 977 |
| 978 notifyFormStateChanged(); | 978 notifyFormStateChanged(); |
| 979 } | 979 } |
| 980 | 980 |
| 981 int HTMLSelectElement::optionToListIndex(int optionIndex) const | 981 int HTMLSelectElement::optionToListIndex(int optionIndex) const |
| 982 { | 982 { |
| 983 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 983 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 984 int listSize = static_cast<int>(items.size()); | 984 int listSize = static_cast<int>(items.size()); |
| 985 if (optionIndex < 0 || optionIndex >= listSize) | 985 if (optionIndex < 0 || optionIndex >= listSize) |
| 986 return -1; | 986 return -1; |
| 987 | 987 |
| 988 int optionIndex2 = -1; | 988 int optionIndex2 = -1; |
| 989 for (int listIndex = 0; listIndex < listSize; ++listIndex) { | 989 for (int listIndex = 0; listIndex < listSize; ++listIndex) { |
| 990 if (isHTMLOptionElement(*items[listIndex])) { | 990 if (isHTMLOptionElement(*items[listIndex])) { |
| 991 ++optionIndex2; | 991 ++optionIndex2; |
| 992 if (optionIndex2 == optionIndex) | 992 if (optionIndex2 == optionIndex) |
| 993 return listIndex; | 993 return listIndex; |
| 994 } | 994 } |
| 995 } | 995 } |
| 996 | 996 |
| 997 return -1; | 997 return -1; |
| 998 } | 998 } |
| 999 | 999 |
| 1000 int HTMLSelectElement::listToOptionIndex(int listIndex) const | 1000 int HTMLSelectElement::listToOptionIndex(int listIndex) const |
| 1001 { | 1001 { |
| 1002 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1002 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1003 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLO
ptionElement(*items[listIndex])) | 1003 if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLO
ptionElement(*items[listIndex])) |
| 1004 return -1; | 1004 return -1; |
| 1005 | 1005 |
| 1006 // Actual index of option not counting OPTGROUP entries that may be in list. | 1006 // Actual index of option not counting OPTGROUP entries that may be in list. |
| 1007 int optionIndex = 0; | 1007 int optionIndex = 0; |
| 1008 for (int i = 0; i < listIndex; ++i) { | 1008 for (int i = 0; i < listIndex; ++i) { |
| 1009 if (isHTMLOptionElement(*items[i])) | 1009 if (isHTMLOptionElement(*items[i])) |
| 1010 ++optionIndex; | 1010 ++optionIndex; |
| 1011 } | 1011 } |
| 1012 | 1012 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1027 // We only need to fire change events here for menu lists, because we fire | 1027 // We only need to fire change events here for menu lists, because we fire |
| 1028 // change events for list boxes whenever the selection change is actually ma
de. | 1028 // change events for list boxes whenever the selection change is actually ma
de. |
| 1029 // This matches other browsers' behavior. | 1029 // This matches other browsers' behavior. |
| 1030 if (usesMenuList()) | 1030 if (usesMenuList()) |
| 1031 dispatchInputAndChangeEventForMenuList(); | 1031 dispatchInputAndChangeEventForMenuList(); |
| 1032 HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement); | 1032 HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement); |
| 1033 } | 1033 } |
| 1034 | 1034 |
| 1035 void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme
nt) | 1035 void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeEleme
nt) |
| 1036 { | 1036 { |
| 1037 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1037 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1038 for (unsigned i = 0; i < items.size(); ++i) { | 1038 for (unsigned i = 0; i < items.size(); ++i) { |
| 1039 HTMLElement* element = items[i]; | 1039 HTMLElement* element = items[i]; |
| 1040 if (element != excludeElement && isHTMLOptionElement(*element)) | 1040 if (element != excludeElement && isHTMLOptionElement(*element)) |
| 1041 toHTMLOptionElement(element)->setSelectedState(false); | 1041 toHTMLOptionElement(element)->setSelectedState(false); |
| 1042 } | 1042 } |
| 1043 } | 1043 } |
| 1044 | 1044 |
| 1045 FormControlState HTMLSelectElement::saveFormControlState() const | 1045 FormControlState HTMLSelectElement::saveFormControlState() const |
| 1046 { | 1046 { |
| 1047 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1047 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1048 size_t length = items.size(); | 1048 size_t length = items.size(); |
| 1049 FormControlState state; | 1049 FormControlState state; |
| 1050 for (unsigned i = 0; i < length; ++i) { | 1050 for (unsigned i = 0; i < length; ++i) { |
| 1051 if (!isHTMLOptionElement(*items[i])) | 1051 if (!isHTMLOptionElement(*items[i])) |
| 1052 continue; | 1052 continue; |
| 1053 HTMLOptionElement* option = toHTMLOptionElement(items[i]); | 1053 HTMLOptionElement* option = toHTMLOptionElement(items[i]); |
| 1054 if (!option->selected()) | 1054 if (!option->selected()) |
| 1055 continue; | 1055 continue; |
| 1056 state.append(option->value()); | 1056 state.append(option->value()); |
| 1057 state.append(String::number(i)); | 1057 state.append(String::number(i)); |
| 1058 if (!multiple()) | 1058 if (!multiple()) |
| 1059 break; | 1059 break; |
| 1060 } | 1060 } |
| 1061 return state; | 1061 return state; |
| 1062 } | 1062 } |
| 1063 | 1063 |
| 1064 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list
IndexStart, size_t listIndexEnd) const | 1064 size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list
IndexStart, size_t listIndexEnd) const |
| 1065 { | 1065 { |
| 1066 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1066 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1067 size_t loopEndIndex = std::min(items.size(), listIndexEnd); | 1067 size_t loopEndIndex = std::min(items.size(), listIndexEnd); |
| 1068 for (size_t i = listIndexStart; i < loopEndIndex; ++i) { | 1068 for (size_t i = listIndexStart; i < loopEndIndex; ++i) { |
| 1069 if (!isHTMLOptionElement(items[i])) | 1069 if (!isHTMLOptionElement(items[i])) |
| 1070 continue; | 1070 continue; |
| 1071 if (toHTMLOptionElement(items[i])->value() == value) | 1071 if (toHTMLOptionElement(items[i])->value() == value) |
| 1072 return i; | 1072 return i; |
| 1073 } | 1073 } |
| 1074 return kNotFound; | 1074 return kNotFound; |
| 1075 } | 1075 } |
| 1076 | 1076 |
| 1077 void HTMLSelectElement::restoreFormControlState(const FormControlState& state) | 1077 void HTMLSelectElement::restoreFormControlState(const FormControlState& state) |
| 1078 { | 1078 { |
| 1079 recalcListItems(); | 1079 recalcListItems(); |
| 1080 | 1080 |
| 1081 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1081 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1082 size_t itemsSize = items.size(); | 1082 size_t itemsSize = items.size(); |
| 1083 if (!itemsSize) | 1083 if (!itemsSize) |
| 1084 return; | 1084 return; |
| 1085 | 1085 |
| 1086 for (size_t i = 0; i < itemsSize; ++i) { | 1086 for (size_t i = 0; i < itemsSize; ++i) { |
| 1087 if (!isHTMLOptionElement(items[i])) | 1087 if (!isHTMLOptionElement(items[i])) |
| 1088 continue; | 1088 continue; |
| 1089 toHTMLOptionElement(items[i])->setSelectedState(false); | 1089 toHTMLOptionElement(items[i])->setSelectedState(false); |
| 1090 } | 1090 } |
| 1091 | 1091 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 lazyReattachIfAttached(); | 1132 lazyReattachIfAttached(); |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 bool HTMLSelectElement::appendFormData(FormDataList& list, bool) | 1135 bool HTMLSelectElement::appendFormData(FormDataList& list, bool) |
| 1136 { | 1136 { |
| 1137 const AtomicString& name = this->name(); | 1137 const AtomicString& name = this->name(); |
| 1138 if (name.isEmpty()) | 1138 if (name.isEmpty()) |
| 1139 return false; | 1139 return false; |
| 1140 | 1140 |
| 1141 bool successful = false; | 1141 bool successful = false; |
| 1142 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1142 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1143 | 1143 |
| 1144 for (unsigned i = 0; i < items.size(); ++i) { | 1144 for (unsigned i = 0; i < items.size(); ++i) { |
| 1145 HTMLElement* element = items[i]; | 1145 HTMLElement* element = items[i]; |
| 1146 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) { | 1146 if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selec
ted() && !toHTMLOptionElement(*element).isDisabledFormControl()) { |
| 1147 list.appendData(name, toHTMLOptionElement(*element).value()); | 1147 list.appendData(name, toHTMLOptionElement(*element).value()); |
| 1148 successful = true; | 1148 successful = true; |
| 1149 } | 1149 } |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 // It's possible that this is a menulist with multiple options and nothing | 1152 // It's possible that this is a menulist with multiple options and nothing |
| 1153 // will be submitted (!successful). We won't send a unselected non-disabled | 1153 // will be submitted (!successful). We won't send a unselected non-disabled |
| 1154 // option as fallback. This behavior matches to other browsers. | 1154 // option as fallback. This behavior matches to other browsers. |
| 1155 return successful; | 1155 return successful; |
| 1156 } | 1156 } |
| 1157 | 1157 |
| 1158 void HTMLSelectElement::resetImpl() | 1158 void HTMLSelectElement::resetImpl() |
| 1159 { | 1159 { |
| 1160 HTMLOptionElement* firstOption = 0; | 1160 HTMLOptionElement* firstOption = 0; |
| 1161 HTMLOptionElement* selectedOption = 0; | 1161 HTMLOptionElement* selectedOption = 0; |
| 1162 | 1162 |
| 1163 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1163 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1164 for (unsigned i = 0; i < items.size(); ++i) { | 1164 for (unsigned i = 0; i < items.size(); ++i) { |
| 1165 HTMLElement* element = items[i]; | 1165 HTMLElement* element = items[i]; |
| 1166 if (!isHTMLOptionElement(*element)) | 1166 if (!isHTMLOptionElement(*element)) |
| 1167 continue; | 1167 continue; |
| 1168 | 1168 |
| 1169 if (items[i]->fastHasAttribute(selectedAttr)) { | 1169 if (items[i]->fastHasAttribute(selectedAttr)) { |
| 1170 if (selectedOption && !m_multiple) | 1170 if (selectedOption && !m_multiple) |
| 1171 selectedOption->setSelectedState(false); | 1171 selectedOption->setSelectedState(false); |
| 1172 toHTMLOptionElement(element)->setSelectedState(true); | 1172 toHTMLOptionElement(element)->setSelectedState(true); |
| 1173 selectedOption = toHTMLOptionElement(element); | 1173 selectedOption = toHTMLOptionElement(element); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1250 if (!m_activeSelectionState) | 1250 if (!m_activeSelectionState) |
| 1251 return; | 1251 return; |
| 1252 } | 1252 } |
| 1253 | 1253 |
| 1254 // The key handling below shouldn't be used for non spatial navigation m
ode Mac | 1254 // The key handling below shouldn't be used for non spatial navigation m
ode Mac |
| 1255 if (RenderTheme::theme().popsMenuByArrowKeys() && !isSpatialNavigationEn
abled(document().frame())) | 1255 if (RenderTheme::theme().popsMenuByArrowKeys() && !isSpatialNavigationEn
abled(document().frame())) |
| 1256 return; | 1256 return; |
| 1257 | 1257 |
| 1258 const String& keyIdentifier = keyEvent->keyIdentifier(); | 1258 const String& keyIdentifier = keyEvent->keyIdentifier(); |
| 1259 bool handled = true; | 1259 bool handled = true; |
| 1260 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = th
is->listItems(); | 1260 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = thi
s->listItems(); |
| 1261 int listIndex = optionToListIndex(selectedIndex()); | 1261 int listIndex = optionToListIndex(selectedIndex()); |
| 1262 | 1262 |
| 1263 if (keyIdentifier == "Down" || keyIdentifier == "Right") | 1263 if (keyIdentifier == "Down" || keyIdentifier == "Right") |
| 1264 listIndex = nextValidIndex(listIndex, SkipForwards, 1); | 1264 listIndex = nextValidIndex(listIndex, SkipForwards, 1); |
| 1265 else if (keyIdentifier == "Up" || keyIdentifier == "Left") | 1265 else if (keyIdentifier == "Up" || keyIdentifier == "Left") |
| 1266 listIndex = nextValidIndex(listIndex, SkipBackwards, 1); | 1266 listIndex = nextValidIndex(listIndex, SkipBackwards, 1); |
| 1267 else if (keyIdentifier == "PageDown") | 1267 else if (keyIdentifier == "PageDown") |
| 1268 listIndex = nextValidIndex(listIndex, SkipForwards, 3); | 1268 listIndex = nextValidIndex(listIndex, SkipForwards, 3); |
| 1269 else if (keyIdentifier == "PageUp") | 1269 else if (keyIdentifier == "PageUp") |
| 1270 listIndex = nextValidIndex(listIndex, SkipBackwards, 3); | 1270 listIndex = nextValidIndex(listIndex, SkipBackwards, 3); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 int HTMLSelectElement::listIndexForEventTargetOption(const Event& event) | 1392 int HTMLSelectElement::listIndexForEventTargetOption(const Event& event) |
| 1393 { | 1393 { |
| 1394 Node* targetNode = event.target()->toNode(); | 1394 Node* targetNode = event.target()->toNode(); |
| 1395 if (!targetNode || !isHTMLOptionElement(*targetNode)) | 1395 if (!targetNode || !isHTMLOptionElement(*targetNode)) |
| 1396 return -1; | 1396 return -1; |
| 1397 return listIndexForOption(toHTMLOptionElement(*targetNode)); | 1397 return listIndexForOption(toHTMLOptionElement(*targetNode)); |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 int HTMLSelectElement::listIndexForOption(const HTMLOptionElement& option) | 1400 int HTMLSelectElement::listIndexForOption(const HTMLOptionElement& option) |
| 1401 { | 1401 { |
| 1402 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = this->list
Items(); | 1402 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = this->listI
tems(); |
| 1403 size_t length = items.size(); | 1403 size_t length = items.size(); |
| 1404 for (size_t i = 0; i < length; ++i) { | 1404 for (size_t i = 0; i < length; ++i) { |
| 1405 if (items[i].get() == &option) | 1405 if (items[i].get() == &option) |
| 1406 return i; | 1406 return i; |
| 1407 } | 1407 } |
| 1408 return -1; | 1408 return -1; |
| 1409 } | 1409 } |
| 1410 | 1410 |
| 1411 AutoscrollController* HTMLSelectElement::autoscrollController() const | 1411 AutoscrollController* HTMLSelectElement::autoscrollController() const |
| 1412 { | 1412 { |
| 1413 if (Page* page = document().page()) | 1413 if (Page* page = document().page()) |
| 1414 return &page->autoscrollController(); | 1414 return &page->autoscrollController(); |
| 1415 return 0; | 1415 return 0; |
| 1416 } | 1416 } |
| 1417 | 1417 |
| 1418 void HTMLSelectElement::handleMouseRelease() | 1418 void HTMLSelectElement::handleMouseRelease() |
| 1419 { | 1419 { |
| 1420 // We didn't start this click/drag on any options. | 1420 // We didn't start this click/drag on any options. |
| 1421 if (m_lastOnChangeSelection.isEmpty()) | 1421 if (m_lastOnChangeSelection.isEmpty()) |
| 1422 return; | 1422 return; |
| 1423 listBoxOnChange(); | 1423 listBoxOnChange(); |
| 1424 } | 1424 } |
| 1425 | 1425 |
| 1426 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) | 1426 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
| 1427 { | 1427 { |
| 1428 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->
listItems(); | 1428 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = this->l
istItems(); |
| 1429 if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent())
{ | 1429 if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent())
{ |
| 1430 focus(); | 1430 focus(); |
| 1431 // 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. | 1431 // 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. |
| 1432 if (!renderer() || !renderer()->isListBox()) | 1432 if (!renderer() || !renderer()->isListBox()) |
| 1433 return; | 1433 return; |
| 1434 | 1434 |
| 1435 // Convert to coords relative to the list box if needed. | 1435 // Convert to coords relative to the list box if needed. |
| 1436 GestureEvent& gestureEvent = toGestureEvent(*event); | 1436 GestureEvent& gestureEvent = toGestureEvent(*event); |
| 1437 int listIndex = listIndexForEventTargetOption(gestureEvent); | 1437 int listIndex = listIndexForEventTargetOption(gestureEvent); |
| 1438 if (listIndex >= 0) { | 1438 if (listIndex >= 0) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 typeAheadFind(keyboardEvent); | 1619 typeAheadFind(keyboardEvent); |
| 1620 event->setDefaultHandled(); | 1620 event->setDefaultHandled(); |
| 1621 return; | 1621 return; |
| 1622 } | 1622 } |
| 1623 } | 1623 } |
| 1624 HTMLFormControlElementWithState::defaultEventHandler(event); | 1624 HTMLFormControlElementWithState::defaultEventHandler(event); |
| 1625 } | 1625 } |
| 1626 | 1626 |
| 1627 int HTMLSelectElement::lastSelectedListIndex() const | 1627 int HTMLSelectElement::lastSelectedListIndex() const |
| 1628 { | 1628 { |
| 1629 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1629 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1630 for (size_t i = items.size(); i;) { | 1630 for (size_t i = items.size(); i;) { |
| 1631 HTMLElement* element = items[--i]; | 1631 HTMLElement* element = items[--i]; |
| 1632 if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selec
ted()) | 1632 if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selec
ted()) |
| 1633 return i; | 1633 return i; |
| 1634 } | 1634 } |
| 1635 return -1; | 1635 return -1; |
| 1636 } | 1636 } |
| 1637 | 1637 |
| 1638 int HTMLSelectElement::indexOfSelectedOption() const | 1638 int HTMLSelectElement::indexOfSelectedOption() const |
| 1639 { | 1639 { |
| 1640 return optionToListIndex(selectedIndex()); | 1640 return optionToListIndex(selectedIndex()); |
| 1641 } | 1641 } |
| 1642 | 1642 |
| 1643 int HTMLSelectElement::optionCount() const | 1643 int HTMLSelectElement::optionCount() const |
| 1644 { | 1644 { |
| 1645 return listItems().size(); | 1645 return listItems().size(); |
| 1646 } | 1646 } |
| 1647 | 1647 |
| 1648 String HTMLSelectElement::optionAtIndex(int index) const | 1648 String HTMLSelectElement::optionAtIndex(int index) const |
| 1649 { | 1649 { |
| 1650 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1650 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1651 | 1651 |
| 1652 HTMLElement* element = items[index]; | 1652 HTMLElement* element = items[index]; |
| 1653 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabl
edFormControl()) | 1653 if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabl
edFormControl()) |
| 1654 return String(); | 1654 return String(); |
| 1655 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); | 1655 return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel(); |
| 1656 } | 1656 } |
| 1657 | 1657 |
| 1658 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) | 1658 void HTMLSelectElement::typeAheadFind(KeyboardEvent* event) |
| 1659 { | 1659 { |
| 1660 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea
d::CycleFirstChar); | 1660 int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhea
d::CycleFirstChar); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1675 return InsertionDone; | 1675 return InsertionDone; |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 void HTMLSelectElement::accessKeySetSelectedIndex(int index) | 1678 void HTMLSelectElement::accessKeySetSelectedIndex(int index) |
| 1679 { | 1679 { |
| 1680 // First bring into focus the list box. | 1680 // First bring into focus the list box. |
| 1681 if (!focused()) | 1681 if (!focused()) |
| 1682 accessKeyAction(false); | 1682 accessKeyAction(false); |
| 1683 | 1683 |
| 1684 // If this index is already selected, unselect. otherwise update the selecte
d index. | 1684 // If this index is already selected, unselect. otherwise update the selecte
d index. |
| 1685 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1685 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1686 int listIndex = optionToListIndex(index); | 1686 int listIndex = optionToListIndex(index); |
| 1687 if (listIndex >= 0) { | 1687 if (listIndex >= 0) { |
| 1688 HTMLElement* element = items[listIndex]; | 1688 HTMLElement* element = items[listIndex]; |
| 1689 if (isHTMLOptionElement(*element)) { | 1689 if (isHTMLOptionElement(*element)) { |
| 1690 if (toHTMLOptionElement(*element).selected()) | 1690 if (toHTMLOptionElement(*element).selected()) |
| 1691 toHTMLOptionElement(*element).setSelectedState(false); | 1691 toHTMLOptionElement(*element).setSelectedState(false); |
| 1692 else | 1692 else |
| 1693 selectOption(index, DispatchInputAndChangeEvent | UserDriven); | 1693 selectOption(index, DispatchInputAndChangeEvent | UserDriven); |
| 1694 } | 1694 } |
| 1695 } | 1695 } |
| 1696 | 1696 |
| 1697 if (usesMenuList()) | 1697 if (usesMenuList()) |
| 1698 dispatchInputAndChangeEventForMenuList(); | 1698 dispatchInputAndChangeEventForMenuList(); |
| 1699 else | 1699 else |
| 1700 listBoxOnChange(); | 1700 listBoxOnChange(); |
| 1701 | 1701 |
| 1702 scrollToSelection(); | 1702 scrollToSelection(); |
| 1703 } | 1703 } |
| 1704 | 1704 |
| 1705 unsigned HTMLSelectElement::length() const | 1705 unsigned HTMLSelectElement::length() const |
| 1706 { | 1706 { |
| 1707 unsigned options = 0; | 1707 unsigned options = 0; |
| 1708 | 1708 |
| 1709 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems(
); | 1709 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& items = listItems()
; |
| 1710 for (unsigned i = 0; i < items.size(); ++i) { | 1710 for (unsigned i = 0; i < items.size(); ++i) { |
| 1711 if (isHTMLOptionElement(*items[i])) | 1711 if (isHTMLOptionElement(*items[i])) |
| 1712 ++options; | 1712 ++options; |
| 1713 } | 1713 } |
| 1714 | 1714 |
| 1715 return options; | 1715 return options; |
| 1716 } | 1716 } |
| 1717 | 1717 |
| 1718 void HTMLSelectElement::finishParsingChildren() | 1718 void HTMLSelectElement::finishParsingChildren() |
| 1719 { | 1719 { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 int focusedIndex = activeSelectionEndListIndex(); | 1770 int focusedIndex = activeSelectionEndListIndex(); |
| 1771 if (focusedIndex < 0) | 1771 if (focusedIndex < 0) |
| 1772 focusedIndex = firstSelectableListIndex(); | 1772 focusedIndex = firstSelectableListIndex(); |
| 1773 if (focusedIndex < 0) | 1773 if (focusedIndex < 0) |
| 1774 return nullptr; | 1774 return nullptr; |
| 1775 HTMLElement* focused = listItems()[focusedIndex]; | 1775 HTMLElement* focused = listItems()[focusedIndex]; |
| 1776 return isHTMLOptionElement(focused) ? toHTMLOptionElement(focused) : nullptr
; | 1776 return isHTMLOptionElement(focused) ? toHTMLOptionElement(focused) : nullptr
; |
| 1777 } | 1777 } |
| 1778 | 1778 |
| 1779 } // namespace | 1779 } // namespace |
| OLD | NEW |