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 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1107 } | 1107 } |
1108 | 1108 |
1109 if (!selectedOption && firstOption && !m_multiple && m_size <= 1) | 1109 if (!selectedOption && firstOption && !m_multiple && m_size <= 1) |
1110 firstOption->setSelectedState(true); | 1110 firstOption->setSelectedState(true); |
1111 | 1111 |
1112 setOptionsChangedOnRenderer(); | 1112 setOptionsChangedOnRenderer(); |
1113 setNeedsStyleRecalc(SubtreeStyleChange); | 1113 setNeedsStyleRecalc(SubtreeStyleChange); |
1114 setNeedsValidityCheck(); | 1114 setNeedsValidityCheck(); |
1115 } | 1115 } |
1116 | 1116 |
1117 #if !OS(WIN) | 1117 bool HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) |
1118 bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) | |
1119 { | 1118 { |
1120 if (!RenderTheme::theme().popsMenuByArrowKeys()) | 1119 const KeyboardEvent* keyEvent = toKeyboardEvent(event); |
1121 return false; | 1120 const String& keyIdentifier = keyEvent->keyIdentifier(); |
1121 RenderTheme& renderTheme = RenderTheme::theme(); | |
1122 int keyCode = toKeyboardEvent(event)->keyCode(); | |
1122 | 1123 |
1123 if (!isSpatialNavigationEnabled(document().frame())) { | 1124 // downUpKey and spaceKey works for mac. |
1124 if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") { | 1125 bool downUpKey = (event->type() == EventTypeNames::keydown) && !isSpatialNav igationEnabled(document().frame()) && RenderTheme::theme().popsMenuByArrowKeys() && (keyIdentifier == "Down" || keyIdentifier == "Up"); |
1125 focus(); | 1126 bool spaceKey = (event->type() == EventTypeNames::keypress) && renderTheme. popsMenuByArrowKeys() && keyCode == ' '; |
keishi
2014/07/04 01:33:50
Using RenderTheme.popsMenuByArrowKeys here seems w
Habib Virji
2014/07/08 12:21:32
Done.
| |
1126 // Calling focus() may cause us to lose our renderer. Return true so | 1127 // spaceOrEnterKey, altDownUpKey and f4Key all work for linux and windows bu t not for mac. |
1127 // that our caller doesn't process the event further, but don't set | 1128 bool spaceOrEnterKey = (event->type() == EventTypeNames::keypress) && render Theme.popsMenuBySpaceOrReturn() && (keyCode == ' ' || keyCode == '\r'); |
1128 // the event as handled. | 1129 bool altDownUpKey = (event->type() == EventTypeNames::keydown) && renderThem e.shouldOpenDropDownWithAltDownUpOrF4Key() && (keyIdentifier == "Down" || keyIde ntifier == "Up") && (keyEvent->altKey() || keyEvent->altGraphKey()); |
1129 if (!renderer() || !renderer()->isMenuList() || isDisabledFormContro l()) | 1130 bool f4Key = (event->type() == EventTypeNames::keydown) && renderTheme.shoul dOpenDropDownWithAltDownUpOrF4Key() && (!keyEvent->altKey() && !keyEvent->ctrlKe y() && keyIdentifier == "F4"); |
1130 return true; | |
1131 | 1131 |
1132 // Save the selection so it can be compared to the new selection | 1132 if (downUpKey || spaceKey || spaceOrEnterKey || altDownUpKey || f4Key) { |
keishi
2014/07/04 01:33:50
nit: I think this is kind of confusing because spa
Habib Virji
2014/07/08 12:21:32
Done.
| |
1133 // when dispatching change events during selectOption, which | 1133 focus(); |
1134 // gets called from RenderMenuList::valueChanged, which gets called | 1134 // Calling focus() may cause us to lose our renderer. Return true so |
1135 // after the user makes a selection from the menu. | 1135 // that our caller doesn't process the event further, but don't set |
1136 saveLastSelection(); | 1136 // the event as handled. |
1137 if (RenderMenuList* menuList = toRenderMenuList(renderer())) | 1137 if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl()) |
1138 menuList->showPopup(); | 1138 return true; |
1139 event->setDefaultHandled(); | 1139 // Save the selection so it can be compared to the new selection |
1140 } | 1140 // when dispatching change events during selectOption, which |
1141 // gets called from RenderMenuList::valueChanged, which gets called | |
1142 // after the user makes a selection from the menu. | |
1143 saveLastSelection(); | |
1144 if (RenderMenuList* menuList = toRenderMenuList(renderer())) | |
1145 menuList->showPopup(); | |
1146 int index = selectedIndex(); | |
1147 ASSERT(index >= 0); | |
1148 ASSERT_WITH_SECURITY_IMPLICATION(index < static_cast<int>(listItems().si ze())); | |
1149 setSelectedIndex(index); | |
1150 event->setDefaultHandled(); | |
1141 return true; | 1151 return true; |
1142 } | 1152 } |
1143 | 1153 |
1144 return false; | 1154 return false; |
1145 } | 1155 } |
1146 #endif | |
1147 | 1156 |
1148 void HTMLSelectElement::menuListDefaultEventHandler(Event* event) | 1157 void HTMLSelectElement::menuListDefaultEventHandler(Event* event) |
1149 { | 1158 { |
1150 RenderTheme& renderTheme = RenderTheme::theme(); | 1159 RenderTheme& renderTheme = RenderTheme::theme(); |
1151 | 1160 |
1161 if (renderer() && event->isKeyboardEvent() && handlePopupOpenKeyboardEvent(e vent)) | |
1162 return; | |
1163 | |
1152 if (event->type() == EventTypeNames::keydown) { | 1164 if (event->type() == EventTypeNames::keydown) { |
1153 if (!renderer() || !event->isKeyboardEvent()) | 1165 if (!renderer() || !event->isKeyboardEvent()) |
1154 return; | 1166 return; |
1155 | 1167 |
1156 if (platformHandleKeydownEvent(toKeyboardEvent(event))) | |
1157 return; | |
1158 | |
1159 // When using spatial navigation, we want to be able to navigate away | 1168 // When using spatial navigation, we want to be able to navigate away |
1160 // from the select element when the user hits any of the arrow keys, | 1169 // from the select element when the user hits any of the arrow keys, |
1161 // instead of changing the selection. | 1170 // instead of changing the selection. |
1162 if (isSpatialNavigationEnabled(document().frame())) { | 1171 if (isSpatialNavigationEnabled(document().frame())) { |
1163 if (!m_activeSelectionState) | 1172 if (!m_activeSelectionState) |
1164 return; | 1173 return; |
1165 } | 1174 } |
1166 | 1175 |
1167 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); | 1176 const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); |
1168 bool handled = true; | 1177 bool handled = true; |
(...skipping 22 matching lines...) Expand all Loading... | |
1191 event->setDefaultHandled(); | 1200 event->setDefaultHandled(); |
1192 } | 1201 } |
1193 | 1202 |
1194 // Use key press event here since sending simulated mouse events | 1203 // Use key press event here since sending simulated mouse events |
1195 // on key down blocks the proper sending of the key press event. | 1204 // on key down blocks the proper sending of the key press event. |
1196 if (event->type() == EventTypeNames::keypress) { | 1205 if (event->type() == EventTypeNames::keypress) { |
1197 if (!renderer() || !event->isKeyboardEvent()) | 1206 if (!renderer() || !event->isKeyboardEvent()) |
1198 return; | 1207 return; |
1199 | 1208 |
1200 int keyCode = toKeyboardEvent(event)->keyCode(); | 1209 int keyCode = toKeyboardEvent(event)->keyCode(); |
1201 bool handled = false; | |
1202 | 1210 |
1203 if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { | 1211 if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { |
1204 // Use space to toggle arrow key handling for selection change or sp atial navigation. | 1212 // Use space to toggle arrow key handling for selection change or sp atial navigation. |
1205 m_activeSelectionState = !m_activeSelectionState; | 1213 m_activeSelectionState = !m_activeSelectionState; |
1206 event->setDefaultHandled(); | 1214 event->setDefaultHandled(); |
1207 return; | 1215 return; |
1208 } | 1216 } |
1209 | 1217 |
1210 if (renderTheme.popsMenuBySpaceOrReturn()) { | 1218 if (renderTheme.popsMenuByArrowKeys() && keyCode == '\r') { |
1211 if (keyCode == ' ' || keyCode == '\r') { | 1219 if (form()) |
1212 focus(); | 1220 form()->submitImplicitly(event, false); |
1213 | 1221 dispatchInputAndChangeEventForMenuList(); |
1214 // Calling focus() may remove the renderer or change the | 1222 event->setDefaultHandled(); |
1215 // renderer type. | |
1216 if (!renderer() || !renderer()->isMenuList() || isDisabledFormCo ntrol()) | |
1217 return; | |
1218 | |
1219 // Save the selection so it can be compared to the new selection | |
1220 // when dispatching change events during selectOption, which | |
1221 // gets called from RenderMenuList::valueChanged, which gets cal led | |
1222 // after the user makes a selection from the menu. | |
1223 saveLastSelection(); | |
1224 if (RenderMenuList* menuList = toRenderMenuList(renderer())) | |
1225 menuList->showPopup(); | |
1226 handled = true; | |
1227 } | |
1228 } else if (renderTheme.popsMenuByArrowKeys()) { | |
1229 if (keyCode == ' ') { | |
1230 focus(); | |
1231 | |
1232 // Calling focus() may remove the renderer or change the | |
1233 // renderer type. | |
1234 if (!renderer() || !renderer()->isMenuList() || isDisabledFormCo ntrol()) | |
1235 return; | |
1236 | |
1237 // Save the selection so it can be compared to the new selection | |
1238 // when dispatching change events during selectOption, which | |
1239 // gets called from RenderMenuList::valueChanged, which gets cal led | |
1240 // after the user makes a selection from the menu. | |
1241 saveLastSelection(); | |
1242 if (RenderMenuList* menuList = toRenderMenuList(renderer())) | |
1243 menuList->showPopup(); | |
1244 handled = true; | |
1245 } else if (keyCode == '\r') { | |
1246 if (form()) | |
1247 form()->submitImplicitly(event, false); | |
1248 dispatchInputAndChangeEventForMenuList(); | |
1249 handled = true; | |
1250 } | |
1251 } | 1223 } |
1252 | |
1253 if (handled) | |
1254 event->setDefaultHandled(); | |
1255 } | 1224 } |
1256 | 1225 |
1257 if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && t oMouseEvent(event)->button() == LeftButton) { | 1226 if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && t oMouseEvent(event)->button() == LeftButton) { |
1258 focus(); | 1227 focus(); |
1259 if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) { | 1228 if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) { |
1260 if (RenderMenuList* menuList = toRenderMenuList(renderer())) { | 1229 if (RenderMenuList* menuList = toRenderMenuList(renderer())) { |
1261 if (menuList->popupIsVisible()) | 1230 if (menuList->popupIsVisible()) |
1262 menuList->hidePopup(); | 1231 menuList->hidePopup(); |
1263 else { | 1232 else { |
1264 // Save the selection so it can be compared to the new | 1233 // Save the selection so it can be compared to the new |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1658 | 1627 |
1659 void HTMLSelectElement::trace(Visitor* visitor) | 1628 void HTMLSelectElement::trace(Visitor* visitor) |
1660 { | 1629 { |
1661 #if ENABLE(OILPAN) | 1630 #if ENABLE(OILPAN) |
1662 visitor->trace(m_listItems); | 1631 visitor->trace(m_listItems); |
1663 #endif | 1632 #endif |
1664 HTMLFormControlElementWithState::trace(visitor); | 1633 HTMLFormControlElementWithState::trace(visitor); |
1665 } | 1634 } |
1666 | 1635 |
1667 } // namespace | 1636 } // namespace |
OLD | NEW |