| 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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 | 371 |
| 372 HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChan
ge, afterChange, childCountDelta); | 372 HTMLFormControlElementWithState::childrenChanged(changedByParser, beforeChan
ge, afterChange, childCountDelta); |
| 373 } | 373 } |
| 374 | 374 |
| 375 void HTMLSelectElement::optionElementChildrenChanged() | 375 void HTMLSelectElement::optionElementChildrenChanged() |
| 376 { | 376 { |
| 377 setRecalcListItems(); | 377 setRecalcListItems(); |
| 378 setNeedsValidityCheck(); | 378 setNeedsValidityCheck(); |
| 379 | 379 |
| 380 if (renderer()) { | 380 if (renderer()) { |
| 381 if (AXObjectCache* cache = renderer()->document()->existingAXObjectCache
()) | 381 if (AXObjectCache* cache = renderer()->document().existingAXObjectCache(
)) |
| 382 cache->childrenChanged(this); | 382 cache->childrenChanged(this); |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 | 385 |
| 386 void HTMLSelectElement::accessKeyAction(bool sendMouseEvents) | 386 void HTMLSelectElement::accessKeyAction(bool sendMouseEvents) |
| 387 { | 387 { |
| 388 focus(); | 388 focus(); |
| 389 dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEv
ents); | 389 dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEv
ents); |
| 390 } | 390 } |
| 391 | 391 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 } | 439 } |
| 440 | 440 |
| 441 void HTMLSelectElement::setLength(unsigned newLen, ExceptionState& es) | 441 void HTMLSelectElement::setLength(unsigned newLen, ExceptionState& es) |
| 442 { | 442 { |
| 443 if (newLen > maxSelectItems) | 443 if (newLen > maxSelectItems) |
| 444 newLen = maxSelectItems; | 444 newLen = maxSelectItems; |
| 445 int diff = length() - newLen; | 445 int diff = length() - newLen; |
| 446 | 446 |
| 447 if (diff < 0) { // Add dummy elements. | 447 if (diff < 0) { // Add dummy elements. |
| 448 do { | 448 do { |
| 449 RefPtr<Element> option = document()->createElement(optionTag, false)
; | 449 RefPtr<Element> option = document().createElement(optionTag, false); |
| 450 ASSERT(option); | 450 ASSERT(option); |
| 451 add(toHTMLElement(option.get()), 0, es); | 451 add(toHTMLElement(option.get()), 0, es); |
| 452 if (es.hadException()) | 452 if (es.hadException()) |
| 453 break; | 453 break; |
| 454 } while (++diff); | 454 } while (++diff); |
| 455 } else { | 455 } else { |
| 456 const Vector<HTMLElement*>& items = listItems(); | 456 const Vector<HTMLElement*>& items = listItems(); |
| 457 | 457 |
| 458 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list | 458 // Removing children fires mutation events, which might mutate the DOM f
urther, so we first copy out a list |
| 459 // of elements that we intend to remove then attempt to remove them one
at a time. | 459 // of elements that we intend to remove then attempt to remove them one
at a time. |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 setOptionsChangedOnRenderer(); | 714 setOptionsChangedOnRenderer(); |
| 715 setNeedsStyleRecalc(); | 715 setNeedsStyleRecalc(); |
| 716 if (!inDocument()) { | 716 if (!inDocument()) { |
| 717 if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions)) | 717 if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions)) |
| 718 collection->invalidateCache(); | 718 collection->invalidateCache(); |
| 719 } | 719 } |
| 720 if (!inDocument()) | 720 if (!inDocument()) |
| 721 invalidateSelectedItems(); | 721 invalidateSelectedItems(); |
| 722 | 722 |
| 723 if (renderer()) { | 723 if (renderer()) { |
| 724 if (AXObjectCache* cache = renderer()->document()->existingAXObjectCache
()) | 724 if (AXObjectCache* cache = renderer()->document().existingAXObjectCache(
)) |
| 725 cache->childrenChanged(this); | 725 cache->childrenChanged(this); |
| 726 } | 726 } |
| 727 } | 727 } |
| 728 | 728 |
| 729 void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const | 729 void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const |
| 730 { | 730 { |
| 731 m_listItems.clear(); | 731 m_listItems.clear(); |
| 732 | 732 |
| 733 m_shouldRecalcListItems = false; | 733 m_shouldRecalcListItems = false; |
| 734 | 734 |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 setNeedsStyleRecalc(); | 1058 setNeedsStyleRecalc(); |
| 1059 setNeedsValidityCheck(); | 1059 setNeedsValidityCheck(); |
| 1060 } | 1060 } |
| 1061 | 1061 |
| 1062 #if !OS(WINDOWS) | 1062 #if !OS(WINDOWS) |
| 1063 bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) | 1063 bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) |
| 1064 { | 1064 { |
| 1065 if (!RenderTheme::theme().popsMenuByArrowKeys()) | 1065 if (!RenderTheme::theme().popsMenuByArrowKeys()) |
| 1066 return false; | 1066 return false; |
| 1067 | 1067 |
| 1068 if (!isSpatialNavigationEnabled(document()->frame())) { | 1068 if (!isSpatialNavigationEnabled(document().frame())) { |
| 1069 if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up")
{ | 1069 if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up")
{ |
| 1070 focus(); | 1070 focus(); |
| 1071 // Calling focus() may cause us to lose our renderer. Return true so | 1071 // Calling focus() may cause us to lose our renderer. Return true so |
| 1072 // that our caller doesn't process the event further, but don't set | 1072 // that our caller doesn't process the event further, but don't set |
| 1073 // the event as handled. | 1073 // the event as handled. |
| 1074 if (!renderer()) | 1074 if (!renderer()) |
| 1075 return true; | 1075 return true; |
| 1076 | 1076 |
| 1077 // Save the selection so it can be compared to the new selection | 1077 // Save the selection so it can be compared to the new selection |
| 1078 // when dispatching change events during selectOption, which | 1078 // when dispatching change events during selectOption, which |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1097 if (event->type() == eventNames().keydownEvent) { | 1097 if (event->type() == eventNames().keydownEvent) { |
| 1098 if (!renderer() || !event->isKeyboardEvent()) | 1098 if (!renderer() || !event->isKeyboardEvent()) |
| 1099 return; | 1099 return; |
| 1100 | 1100 |
| 1101 if (platformHandleKeydownEvent(toKeyboardEvent(event))) | 1101 if (platformHandleKeydownEvent(toKeyboardEvent(event))) |
| 1102 return; | 1102 return; |
| 1103 | 1103 |
| 1104 // When using spatial navigation, we want to be able to navigate away | 1104 // When using spatial navigation, we want to be able to navigate away |
| 1105 // from the select element when the user hits any of the arrow keys, | 1105 // from the select element when the user hits any of the arrow keys, |
| 1106 // instead of changing the selection. | 1106 // instead of changing the selection. |
| 1107 if (isSpatialNavigationEnabled(document()->frame())) { | 1107 if (isSpatialNavigationEnabled(document().frame())) { |
| 1108 if (!m_activeSelectionState) | 1108 if (!m_activeSelectionState) |
| 1109 return; | 1109 return; |
| 1110 } | 1110 } |
| 1111 | 1111 |
| 1112 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); | 1112 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); |
| 1113 bool handled = true; | 1113 bool handled = true; |
| 1114 const Vector<HTMLElement*>& listItems = this->listItems(); | 1114 const Vector<HTMLElement*>& listItems = this->listItems(); |
| 1115 int listIndex = optionToListIndex(selectedIndex()); | 1115 int listIndex = optionToListIndex(selectedIndex()); |
| 1116 | 1116 |
| 1117 if (keyIdentifier == "Down" || keyIdentifier == "Right") | 1117 if (keyIdentifier == "Down" || keyIdentifier == "Right") |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1138 | 1138 |
| 1139 // Use key press event here since sending simulated mouse events | 1139 // Use key press event here since sending simulated mouse events |
| 1140 // on key down blocks the proper sending of the key press event. | 1140 // on key down blocks the proper sending of the key press event. |
| 1141 if (event->type() == eventNames().keypressEvent) { | 1141 if (event->type() == eventNames().keypressEvent) { |
| 1142 if (!renderer() || !event->isKeyboardEvent()) | 1142 if (!renderer() || !event->isKeyboardEvent()) |
| 1143 return; | 1143 return; |
| 1144 | 1144 |
| 1145 int keyCode = toKeyboardEvent(event)->keyCode(); | 1145 int keyCode = toKeyboardEvent(event)->keyCode(); |
| 1146 bool handled = false; | 1146 bool handled = false; |
| 1147 | 1147 |
| 1148 if (keyCode == ' ' && isSpatialNavigationEnabled(document()->frame())) { | 1148 if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { |
| 1149 // Use space to toggle arrow key handling for selection change or sp
atial navigation. | 1149 // Use space to toggle arrow key handling for selection change or sp
atial navigation. |
| 1150 m_activeSelectionState = !m_activeSelectionState; | 1150 m_activeSelectionState = !m_activeSelectionState; |
| 1151 event->setDefaultHandled(); | 1151 event->setDefaultHandled(); |
| 1152 return; | 1152 return; |
| 1153 } | 1153 } |
| 1154 | 1154 |
| 1155 if (renderTheme.popsMenuBySpaceOrReturn()) { | 1155 if (renderTheme.popsMenuBySpaceOrReturn()) { |
| 1156 if (keyCode == ' ' || keyCode == '\r') { | 1156 if (keyCode == ' ' || keyCode == '\r') { |
| 1157 focus(); | 1157 focus(); |
| 1158 | 1158 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouse
Event->absoluteLocation(), UseTransforms)); | 1291 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouse
Event->absoluteLocation(), UseTransforms)); |
| 1292 int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize
(localOffset)); | 1292 int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize
(localOffset)); |
| 1293 if (listIndex >= 0) { | 1293 if (listIndex >= 0) { |
| 1294 if (!isDisabledFormControl()) { | 1294 if (!isDisabledFormControl()) { |
| 1295 #if OS(DARWIN) | 1295 #if OS(DARWIN) |
| 1296 updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent
->shiftKey()); | 1296 updateSelectedState(listIndex, mouseEvent->metaKey(), mouseEvent
->shiftKey()); |
| 1297 #else | 1297 #else |
| 1298 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent
->shiftKey()); | 1298 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent
->shiftKey()); |
| 1299 #endif | 1299 #endif |
| 1300 } | 1300 } |
| 1301 if (Frame* frame = document()->frame()) | 1301 if (Frame* frame = document().frame()) |
| 1302 frame->eventHandler()->setMouseDownMayStartAutoscroll(); | 1302 frame->eventHandler()->setMouseDownMayStartAutoscroll(); |
| 1303 | 1303 |
| 1304 event->setDefaultHandled(); | 1304 event->setDefaultHandled(); |
| 1305 } | 1305 } |
| 1306 } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEve
nt() && !toRenderBox(renderer())->canBeScrolledAndHasScrollableArea()) { | 1306 } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEve
nt() && !toRenderBox(renderer())->canBeScrolledAndHasScrollableArea()) { |
| 1307 MouseEvent* mouseEvent = toMouseEvent(event); | 1307 MouseEvent* mouseEvent = toMouseEvent(event); |
| 1308 if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) | 1308 if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) |
| 1309 return; | 1309 return; |
| 1310 | 1310 |
| 1311 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouse
Event->absoluteLocation(), UseTransforms)); | 1311 IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouse
Event->absoluteLocation(), UseTransforms)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 } | 1376 } |
| 1377 } | 1377 } |
| 1378 if (keyIdentifier == "Home") { | 1378 if (keyIdentifier == "Home") { |
| 1379 endIndex = firstSelectableListIndex(); | 1379 endIndex = firstSelectableListIndex(); |
| 1380 handled = true; | 1380 handled = true; |
| 1381 } else if (keyIdentifier == "End") { | 1381 } else if (keyIdentifier == "End") { |
| 1382 endIndex = lastSelectableListIndex(); | 1382 endIndex = lastSelectableListIndex(); |
| 1383 handled = true; | 1383 handled = true; |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 if (isSpatialNavigationEnabled(document()->frame())) | 1386 if (isSpatialNavigationEnabled(document().frame())) |
| 1387 // Check if the selection moves to the boundary. | 1387 // Check if the selection moves to the boundary. |
| 1388 if (keyIdentifier == "Left" || keyIdentifier == "Right" || ((keyIden
tifier == "Down" || keyIdentifier == "Up") && endIndex == m_activeSelectionEndIn
dex)) | 1388 if (keyIdentifier == "Left" || keyIdentifier == "Right" || ((keyIden
tifier == "Down" || keyIdentifier == "Up") && endIndex == m_activeSelectionEndIn
dex)) |
| 1389 return; | 1389 return; |
| 1390 | 1390 |
| 1391 if (endIndex >= 0 && handled) { | 1391 if (endIndex >= 0 && handled) { |
| 1392 // Save the selection so it can be compared to the new selection | 1392 // Save the selection so it can be compared to the new selection |
| 1393 // when dispatching change events immediately after making the new | 1393 // when dispatching change events immediately after making the new |
| 1394 // selection. | 1394 // selection. |
| 1395 saveLastSelection(); | 1395 saveLastSelection(); |
| 1396 | 1396 |
| 1397 ASSERT_UNUSED(listItems, !listItems.size() || static_cast<size_t>(en
dIndex) < listItems.size()); | 1397 ASSERT_UNUSED(listItems, !listItems.size() || static_cast<size_t>(en
dIndex) < listItems.size()); |
| 1398 setActiveSelectionEndIndex(endIndex); | 1398 setActiveSelectionEndIndex(endIndex); |
| 1399 | 1399 |
| 1400 bool selectNewItem = !m_multiple || toKeyboardEvent(event)->shiftKey
() || !isSpatialNavigationEnabled(document()->frame()); | 1400 bool selectNewItem = !m_multiple || toKeyboardEvent(event)->shiftKey
() || !isSpatialNavigationEnabled(document().frame()); |
| 1401 if (selectNewItem) | 1401 if (selectNewItem) |
| 1402 m_activeSelectionState = true; | 1402 m_activeSelectionState = true; |
| 1403 // If the anchor is unitialized, or if we're going to deselect all | 1403 // If the anchor is unitialized, or if we're going to deselect all |
| 1404 // other options, then set the anchor index equal to the end index. | 1404 // other options, then set the anchor index equal to the end index. |
| 1405 bool deselectOthers = !m_multiple || (!toKeyboardEvent(event)->shift
Key() && selectNewItem); | 1405 bool deselectOthers = !m_multiple || (!toKeyboardEvent(event)->shift
Key() && selectNewItem); |
| 1406 if (m_activeSelectionAnchorIndex < 0 || deselectOthers) { | 1406 if (m_activeSelectionAnchorIndex < 0 || deselectOthers) { |
| 1407 if (deselectOthers) | 1407 if (deselectOthers) |
| 1408 deselectItemsWithoutValidation(); | 1408 deselectItemsWithoutValidation(); |
| 1409 setActiveSelectionAnchorIndex(m_activeSelectionEndIndex); | 1409 setActiveSelectionAnchorIndex(m_activeSelectionEndIndex); |
| 1410 } | 1410 } |
| 1411 | 1411 |
| 1412 toRenderListBox(renderer())->scrollToRevealElementAtListIndex(endInd
ex); | 1412 toRenderListBox(renderer())->scrollToRevealElementAtListIndex(endInd
ex); |
| 1413 if (selectNewItem) { | 1413 if (selectNewItem) { |
| 1414 updateListBoxSelection(deselectOthers); | 1414 updateListBoxSelection(deselectOthers); |
| 1415 listBoxOnChange(); | 1415 listBoxOnChange(); |
| 1416 } else | 1416 } else |
| 1417 scrollToSelection(); | 1417 scrollToSelection(); |
| 1418 | 1418 |
| 1419 event->setDefaultHandled(); | 1419 event->setDefaultHandled(); |
| 1420 } | 1420 } |
| 1421 } else if (event->type() == eventNames().keypressEvent) { | 1421 } else if (event->type() == eventNames().keypressEvent) { |
| 1422 if (!event->isKeyboardEvent()) | 1422 if (!event->isKeyboardEvent()) |
| 1423 return; | 1423 return; |
| 1424 int keyCode = toKeyboardEvent(event)->keyCode(); | 1424 int keyCode = toKeyboardEvent(event)->keyCode(); |
| 1425 | 1425 |
| 1426 if (keyCode == '\r') { | 1426 if (keyCode == '\r') { |
| 1427 if (form()) | 1427 if (form()) |
| 1428 form()->submitImplicitly(event, false); | 1428 form()->submitImplicitly(event, false); |
| 1429 event->setDefaultHandled(); | 1429 event->setDefaultHandled(); |
| 1430 } else if (m_multiple && keyCode == ' ' && isSpatialNavigationEnabled(do
cument()->frame())) { | 1430 } else if (m_multiple && keyCode == ' ' && isSpatialNavigationEnabled(do
cument().frame())) { |
| 1431 // Use space to toggle selection change. | 1431 // Use space to toggle selection change. |
| 1432 m_activeSelectionState = !m_activeSelectionState; | 1432 m_activeSelectionState = !m_activeSelectionState; |
| 1433 updateSelectedState(listToOptionIndex(m_activeSelectionEndIndex), tr
ue /*multi*/, false /*shift*/); | 1433 updateSelectedState(listToOptionIndex(m_activeSelectionEndIndex), tr
ue /*multi*/, false /*shift*/); |
| 1434 listBoxOnChange(); | 1434 listBoxOnChange(); |
| 1435 event->setDefaultHandled(); | 1435 event->setDefaultHandled(); |
| 1436 } | 1436 } |
| 1437 } | 1437 } |
| 1438 } | 1438 } |
| 1439 | 1439 |
| 1440 void HTMLSelectElement::defaultEventHandler(Event* event) | 1440 void HTMLSelectElement::defaultEventHandler(Event* event) |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1573 return true; | 1573 return true; |
| 1574 } | 1574 } |
| 1575 | 1575 |
| 1576 bool HTMLSelectElement::anonymousIndexedSetterRemove(unsigned index, ExceptionSt
ate& es) | 1576 bool HTMLSelectElement::anonymousIndexedSetterRemove(unsigned index, ExceptionSt
ate& es) |
| 1577 { | 1577 { |
| 1578 remove(index); | 1578 remove(index); |
| 1579 return true; | 1579 return true; |
| 1580 } | 1580 } |
| 1581 | 1581 |
| 1582 } // namespace | 1582 } // namespace |
| OLD | NEW |