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 |