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 656 matching lines...) Loading... |
667 m_lastOnChangeIndex = selected; | 667 m_lastOnChangeIndex = selected; |
668 m_isProcessingUserDrivenChange = false; | 668 m_isProcessingUserDrivenChange = false; |
669 dispatchFormControlChangeEvent(); | 669 dispatchFormControlChangeEvent(); |
670 } | 670 } |
671 } | 671 } |
672 | 672 |
673 void HTMLSelectElement::scrollToSelection() | 673 void HTMLSelectElement::scrollToSelection() |
674 { | 674 { |
675 if (usesMenuList()) | 675 if (usesMenuList()) |
676 return; | 676 return; |
677 | 677 int listIndex = activeSelectionEndListIndex(); |
678 if (RenderObject* renderer = this->renderer()) | 678 const Vector<HTMLElement*>& items = listItems(); |
679 toRenderListBox(renderer)->selectionChanged(); | 679 int listSize = static_cast<int>(items.size()); |
| 680 if (listIndex < 0 || listIndex >= listSize) |
| 681 return; |
| 682 Element* option = listItems()[listIndex]; |
| 683 option->scrollIntoViewIfNeeded(false); |
680 } | 684 } |
681 | 685 |
682 void HTMLSelectElement::setOptionsChangedOnRenderer() | 686 void HTMLSelectElement::setOptionsChangedOnRenderer() |
683 { | 687 { |
684 if (RenderObject* renderer = this->renderer()) { | 688 if (RenderObject* renderer = this->renderer()) { |
685 if (usesMenuList()) | 689 if (usesMenuList()) |
686 toRenderMenuList(renderer)->setOptionsChanged(true); | 690 toRenderMenuList(renderer)->setOptionsChanged(true); |
687 else | 691 // else |
688 toRenderListBox(renderer)->setOptionsChanged(true); | 692 // scrollToSelection(); |
689 } | 693 } |
690 } | 694 } |
691 | 695 |
692 const Vector<HTMLElement*>& HTMLSelectElement::listItems() const | 696 const Vector<HTMLElement*>& HTMLSelectElement::listItems() const |
693 { | 697 { |
694 if (m_shouldRecalcListItems) | 698 if (m_shouldRecalcListItems) |
695 recalcListItems(); | 699 recalcListItems(); |
696 else { | 700 else { |
697 #if !ASSERT_DISABLED | 701 #if !ASSERT_DISABLED |
698 Vector<HTMLElement*> items = m_listItems; | 702 Vector<HTMLElement*> items = m_listItems; |
(...skipping 153 matching lines...) Loading... |
852 | 856 |
853 scrollToSelection(); | 857 scrollToSelection(); |
854 | 858 |
855 if (usesMenuList()) { | 859 if (usesMenuList()) { |
856 m_isProcessingUserDrivenChange = flags & UserDriven; | 860 m_isProcessingUserDrivenChange = flags & UserDriven; |
857 if (flags & DispatchChangeEvent) | 861 if (flags & DispatchChangeEvent) |
858 dispatchChangeEventForMenuList(); | 862 dispatchChangeEventForMenuList(); |
859 if (RenderObject* renderer = this->renderer()) { | 863 if (RenderObject* renderer = this->renderer()) { |
860 if (usesMenuList()) | 864 if (usesMenuList()) |
861 toRenderMenuList(renderer)->didSetSelectedIndex(listIndex); | 865 toRenderMenuList(renderer)->didSetSelectedIndex(listIndex); |
862 else if (renderer->isListBox()) | |
863 toRenderListBox(renderer)->selectionChanged(); | |
864 } | 866 } |
865 } | 867 } |
866 | 868 |
867 setNeedsValidityCheck(); | 869 setNeedsValidityCheck(); |
868 notifyFormStateChanged(); | 870 notifyFormStateChanged(); |
869 } | 871 } |
870 | 872 |
871 int HTMLSelectElement::optionToListIndex(int optionIndex) const | 873 int HTMLSelectElement::optionToListIndex(int optionIndex) const |
872 { | 874 { |
873 const Vector<HTMLElement*>& items = listItems(); | 875 const Vector<HTMLElement*>& items = listItems(); |
(...skipping 403 matching lines...) Loading... |
1277 // we're doing a single selection, or a multiple selection (using cmd or | 1279 // we're doing a single selection, or a multiple selection (using cmd or |
1278 // ctrl), then initialize the anchor index to the listIndex that just got | 1280 // ctrl), then initialize the anchor index to the listIndex that just got |
1279 // clicked. | 1281 // clicked. |
1280 if (m_activeSelectionAnchorIndex < 0 || !shiftSelect) | 1282 if (m_activeSelectionAnchorIndex < 0 || !shiftSelect) |
1281 setActiveSelectionAnchorIndex(listIndex); | 1283 setActiveSelectionAnchorIndex(listIndex); |
1282 | 1284 |
1283 setActiveSelectionEndIndex(listIndex); | 1285 setActiveSelectionEndIndex(listIndex); |
1284 updateListBoxSelection(!multiSelect); | 1286 updateListBoxSelection(!multiSelect); |
1285 } | 1287 } |
1286 | 1288 |
| 1289 int HTMLSelectElement::listIndexForEvent(Event* event) |
| 1290 { |
| 1291 const Vector<HTMLElement*>& items = this->listItems(); |
| 1292 for (Node* node = event->target()->toNode(); node; node = node->parentOrShad
owHostNode()) { |
| 1293 if (node->isElementNode() && (toElement(node)->hasTagName(optionTag) ||
toElement(node)->hasTagName(optgroupTag))) { |
| 1294 size_t length = items.size(); |
| 1295 for (size_t i = 0; i < length; ++i) { |
| 1296 if (items[i] == node) { |
| 1297 return i; |
| 1298 } |
| 1299 } |
| 1300 } |
| 1301 } |
| 1302 return -1; |
| 1303 } |
| 1304 |
1287 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) | 1305 void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
1288 { | 1306 { |
1289 const Vector<HTMLElement*>& listItems = this->listItems(); | 1307 const Vector<HTMLElement*>& listItems = this->listItems(); |
1290 | 1308 |
1291 if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() &&
static_cast<MouseEvent*>(event)->button() == LeftButton) { | 1309 if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() &&
static_cast<MouseEvent*>(event)->button() == LeftButton) { |
1292 focus(); | 1310 focus(); |
1293 // Calling focus() may cause us to lose our renderer, in which case do n
ot want to handle the event. | 1311 // Calling focus() may cause us to lose our renderer, in which case do n
ot want to handle the event. |
1294 if (!renderer()) | 1312 if (!renderer()) |
1295 return; | 1313 return; |
1296 | 1314 |
1297 // Convert to coords relative to the list box if needed. | |
1298 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); | 1315 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); |
1299 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouse
Event->absoluteLocation(), UseTransforms)); | 1316 int listIndex = listIndexForEvent(event); |
1300 int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize
(localOffset)); | |
1301 if (listIndex >= 0) { | 1317 if (listIndex >= 0) { |
1302 if (!isDisabledFormControl()) { | 1318 if (!isDisabledFormControl()) { |
1303 #if OS(DARWIN) | 1319 #if OS(DARWIN) |
1304 updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent
->shiftKey()); | 1320 updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent
->shiftKey()); |
1305 #else | 1321 #else |
1306 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent
->shiftKey()); | 1322 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent
->shiftKey()); |
1307 #endif | 1323 #endif |
1308 } | 1324 } |
1309 if (Frame* frame = document()->frame()) | 1325 if (Frame* frame = document()->frame()) |
1310 frame->eventHandler()->setMouseDownMayStartAutoscroll(); | 1326 frame->eventHandler()->setMouseDownMayStartAutoscroll(); |
1311 | 1327 |
1312 event->setDefaultHandled(); | 1328 event->setDefaultHandled(); |
1313 } | 1329 } |
1314 } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEve
nt() && !toRenderBox(renderer())->canBeScrolledAndHasScrollableArea()) { | 1330 } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEve
nt()) { |
1315 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); | 1331 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); |
1316 if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) | 1332 if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) |
1317 return; | 1333 return; |
1318 | 1334 |
1319 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouse
Event->absoluteLocation(), UseTransforms)); | 1335 int listIndex = listIndexForEvent(event); |
1320 int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize
(localOffset)); | |
1321 if (listIndex >= 0) { | 1336 if (listIndex >= 0) { |
1322 if (!isDisabledFormControl()) { | 1337 if (!isDisabledFormControl()) { |
1323 if (m_multiple) { | 1338 if (m_multiple) { |
1324 // Only extend selection if there is something selected. | 1339 // Only extend selection if there is something selected. |
1325 if (m_activeSelectionAnchorIndex < 0) | 1340 if (m_activeSelectionAnchorIndex < 0) |
1326 return; | 1341 return; |
1327 | 1342 |
1328 setActiveSelectionEndIndex(listIndex); | 1343 setActiveSelectionEndIndex(listIndex); |
1329 updateListBoxSelection(false); | 1344 updateListBoxSelection(false); |
1330 } else { | 1345 } else { |
1331 setActiveSelectionAnchorIndex(listIndex); | 1346 setActiveSelectionAnchorIndex(listIndex); |
1332 setActiveSelectionEndIndex(listIndex); | 1347 setActiveSelectionEndIndex(listIndex); |
1333 updateListBoxSelection(true); | 1348 updateListBoxSelection(true); |
1334 } | 1349 } |
1335 } | 1350 } |
1336 event->setDefaultHandled(); | 1351 event->setDefaultHandled(); |
1337 } | 1352 } |
1338 } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent
() && static_cast<MouseEvent*>(event)->button() == LeftButton && document()->fra
me()->eventHandler()->autoscrollRenderer() != renderer()) { | 1353 } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent
() && static_cast<MouseEvent*>(event)->button() == LeftButton) |
1339 // This makes sure we fire dispatchFormControlChangeEvent for a single | |
1340 // click. For drag selection, onChange will fire when the autoscroll | |
1341 // timer stops. | |
1342 listBoxOnChange(); | 1354 listBoxOnChange(); |
1343 } else if (event->type() == eventNames().keydownEvent) { | 1355 else if (event->type() == eventNames().keydownEvent) { |
1344 if (!event->isKeyboardEvent()) | 1356 if (!event->isKeyboardEvent()) |
1345 return; | 1357 return; |
1346 const String& keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIde
ntifier(); | 1358 const String& keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIde
ntifier(); |
1347 | 1359 |
1348 bool handled = false; | 1360 bool handled = false; |
1349 int endIndex = 0; | 1361 int endIndex = 0; |
1350 if (m_activeSelectionEndIndex < 0) { | 1362 if (m_activeSelectionEndIndex < 0) { |
1351 // Initialize the end index | 1363 // Initialize the end index |
1352 if (keyIdentifier == "Down" || keyIdentifier == "PageDown") { | 1364 if (keyIdentifier == "Down" || keyIdentifier == "PageDown") { |
1353 int startIndex = lastSelectedListIndex(); | 1365 int startIndex = lastSelectedListIndex(); |
(...skipping 53 matching lines...) Loading... |
1407 m_activeSelectionState = true; | 1419 m_activeSelectionState = true; |
1408 // If the anchor is unitialized, or if we're going to deselect all | 1420 // If the anchor is unitialized, or if we're going to deselect all |
1409 // other options, then set the anchor index equal to the end index. | 1421 // other options, then set the anchor index equal to the end index. |
1410 bool deselectOthers = !m_multiple || (!static_cast<KeyboardEvent*>(e
vent)->shiftKey() && selectNewItem); | 1422 bool deselectOthers = !m_multiple || (!static_cast<KeyboardEvent*>(e
vent)->shiftKey() && selectNewItem); |
1411 if (m_activeSelectionAnchorIndex < 0 || deselectOthers) { | 1423 if (m_activeSelectionAnchorIndex < 0 || deselectOthers) { |
1412 if (deselectOthers) | 1424 if (deselectOthers) |
1413 deselectItemsWithoutValidation(); | 1425 deselectItemsWithoutValidation(); |
1414 setActiveSelectionAnchorIndex(m_activeSelectionEndIndex); | 1426 setActiveSelectionAnchorIndex(m_activeSelectionEndIndex); |
1415 } | 1427 } |
1416 | 1428 |
1417 toRenderListBox(renderer())->scrollToRevealElementAtListIndex(endInd
ex); | 1429 listItems[endIndex]->scrollIntoViewIfNeeded(false); |
1418 if (selectNewItem) { | 1430 if (selectNewItem) { |
1419 updateListBoxSelection(deselectOthers); | 1431 updateListBoxSelection(deselectOthers); |
1420 listBoxOnChange(); | 1432 listBoxOnChange(); |
1421 } else | 1433 } else |
1422 scrollToSelection(); | 1434 scrollToSelection(); |
1423 | 1435 |
1424 event->setDefaultHandled(); | 1436 event->setDefaultHandled(); |
1425 } | 1437 } |
1426 } else if (event->type() == eventNames().keypressEvent) { | 1438 } else if (event->type() == eventNames().keypressEvent) { |
1427 if (!event->isKeyboardEvent()) | 1439 if (!event->isKeyboardEvent()) |
(...skipping 127 matching lines...) Loading... |
1555 const Vector<HTMLElement*>& items = listItems(); | 1567 const Vector<HTMLElement*>& items = listItems(); |
1556 for (unsigned i = 0; i < items.size(); ++i) { | 1568 for (unsigned i = 0; i < items.size(); ++i) { |
1557 if (items[i]->hasTagName(optionTag)) | 1569 if (items[i]->hasTagName(optionTag)) |
1558 ++options; | 1570 ++options; |
1559 } | 1571 } |
1560 | 1572 |
1561 return options; | 1573 return options; |
1562 } | 1574 } |
1563 | 1575 |
1564 } // namespace | 1576 } // namespace |
OLD | NEW |