| 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 void HTMLSelectElement::handlePopupOpenKeyboardEvent(Event* event) | 
| 1118 bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) |  | 
| 1119 { | 1118 { | 
| 1120     if (!RenderTheme::theme().popsMenuByArrowKeys()) | 1119     focus(); | 
|  | 1120     // Calling focus() may cause us to lose our renderer. Return true so | 
|  | 1121     // that our caller doesn't process the event further, but don't set | 
|  | 1122     // the event as handled. | 
|  | 1123     if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl()) | 
|  | 1124         return; | 
|  | 1125     // Save the selection so it can be compared to the new selection | 
|  | 1126     // when dispatching change events during selectOption, which | 
|  | 1127     // gets called from RenderMenuList::valueChanged, which gets called | 
|  | 1128     // after the user makes a selection from the menu. | 
|  | 1129     saveLastSelection(); | 
|  | 1130     if (RenderMenuList* menuList = toRenderMenuList(renderer())) | 
|  | 1131         menuList->showPopup(); | 
|  | 1132     int index = selectedIndex(); | 
|  | 1133     ASSERT(index >= 0); | 
|  | 1134     ASSERT_WITH_SECURITY_IMPLICATION(index < static_cast<int>(listItems().size()
      )); | 
|  | 1135     setSelectedIndex(index); | 
|  | 1136     event->setDefaultHandled(); | 
|  | 1137     return; | 
|  | 1138 } | 
|  | 1139 | 
|  | 1140 bool HTMLSelectElement::shouldOpenPopupForKeyDownEvent(KeyboardEvent* keyEvent) | 
|  | 1141 { | 
|  | 1142     const String& keyIdentifier = keyEvent->keyIdentifier(); | 
|  | 1143     RenderTheme& renderTheme = RenderTheme::theme(); | 
|  | 1144 | 
|  | 1145     if (isSpatialNavigationEnabled(document().frame())) | 
| 1121         return false; | 1146         return false; | 
| 1122 | 1147 | 
| 1123     if (!isSpatialNavigationEnabled(document().frame())) { | 1148     return ((renderTheme.popsMenuByArrowKeys() &&  (keyIdentifier == "Down" || k
      eyIdentifier == "Up")) | 
| 1124         if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") 
      { | 1149         || (renderTheme.popsMenuByAltDownUpOrF4Key() && (keyIdentifier == "Down"
       || keyIdentifier == "Up") && (keyEvent->altKey() || keyEvent->altGraphKey())) | 
| 1125             focus(); | 1150         || (renderTheme.popsMenuByAltDownUpOrF4Key() && (!keyEvent->altKey() && 
      !keyEvent->ctrlKey() && keyIdentifier == "F4"))); | 
| 1126             // Calling focus() may cause us to lose our renderer. Return true so | 1151 } | 
| 1127             // that our caller doesn't process the event further, but don't set |  | 
| 1128             // the event as handled. |  | 
| 1129             if (!renderer() || !renderer()->isMenuList() || isDisabledFormContro
      l()) |  | 
| 1130                 return true; |  | 
| 1131 | 1152 | 
| 1132             // Save the selection so it can be compared to the new selection | 1153 bool HTMLSelectElement::shouldOpenPopupForKeyPressEvent(KeyboardEvent *event) | 
| 1133             // when dispatching change events during selectOption, which | 1154 { | 
| 1134             // gets called from RenderMenuList::valueChanged, which gets called | 1155     RenderTheme& renderTheme = RenderTheme::theme(); | 
| 1135             // after the user makes a selection from the menu. | 1156     int keyCode = event->keyCode(); | 
| 1136             saveLastSelection(); |  | 
| 1137             if (RenderMenuList* menuList = toRenderMenuList(renderer())) |  | 
| 1138                 menuList->showPopup(); |  | 
| 1139             event->setDefaultHandled(); |  | 
| 1140         } |  | 
| 1141         return true; |  | 
| 1142     } |  | 
| 1143 | 1157 | 
| 1144     return false; | 1158     return ((renderTheme.popsMenuBySpaceKey() && event->keyCode() == ' ') | 
|  | 1159         || (renderTheme.popsMenuByReturnKey() && keyCode == '\r')); | 
| 1145 } | 1160 } | 
| 1146 #endif |  | 
| 1147 | 1161 | 
| 1148 void HTMLSelectElement::menuListDefaultEventHandler(Event* event) | 1162 void HTMLSelectElement::menuListDefaultEventHandler(Event* event) | 
| 1149 { | 1163 { | 
| 1150     RenderTheme& renderTheme = RenderTheme::theme(); |  | 
| 1151 |  | 
| 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))) | 1168         KeyboardEvent* keyEvent = toKeyboardEvent(event); | 
|  | 1169         if (shouldOpenPopupForKeyDownEvent(keyEvent)) { | 
|  | 1170             handlePopupOpenKeyboardEvent(event); | 
| 1157             return; | 1171             return; | 
|  | 1172         } | 
| 1158 | 1173 | 
| 1159         // When using spatial navigation, we want to be able to navigate away | 1174         // 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, | 1175         // from the select element when the user hits any of the arrow keys, | 
| 1161         // instead of changing the selection. | 1176         // instead of changing the selection. | 
| 1162         if (isSpatialNavigationEnabled(document().frame())) { | 1177         if (isSpatialNavigationEnabled(document().frame())) { | 
| 1163             if (!m_activeSelectionState) | 1178             if (!m_activeSelectionState) | 
| 1164                 return; | 1179                 return; | 
| 1165         } | 1180         } | 
| 1166 | 1181 | 
| 1167         const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier(); | 1182         // The key handling below shouldn't be used for non spatial navigation m
      ode Mac | 
|  | 1183         if (RenderTheme::theme().popsMenuByArrowKeys() && !isSpatialNavigationEn
      abled(document().frame())) | 
|  | 1184             return; | 
|  | 1185 | 
|  | 1186         const String& keyIdentifier = keyEvent->keyIdentifier(); | 
| 1168         bool handled = true; | 1187         bool handled = true; | 
| 1169         const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = th
      is->listItems(); | 1188         const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = th
      is->listItems(); | 
| 1170         int listIndex = optionToListIndex(selectedIndex()); | 1189         int listIndex = optionToListIndex(selectedIndex()); | 
| 1171 | 1190 | 
| 1172         if (keyIdentifier == "Down" || keyIdentifier == "Right") | 1191         if (keyIdentifier == "Down" || keyIdentifier == "Right") | 
| 1173             listIndex = nextValidIndex(listIndex, SkipForwards, 1); | 1192             listIndex = nextValidIndex(listIndex, SkipForwards, 1); | 
| 1174         else if (keyIdentifier == "Up" || keyIdentifier == "Left") | 1193         else if (keyIdentifier == "Up" || keyIdentifier == "Left") | 
| 1175             listIndex = nextValidIndex(listIndex, SkipBackwards, 1); | 1194             listIndex = nextValidIndex(listIndex, SkipBackwards, 1); | 
| 1176         else if (keyIdentifier == "PageDown") | 1195         else if (keyIdentifier == "PageDown") | 
| 1177             listIndex = nextValidIndex(listIndex, SkipForwards, 3); | 1196             listIndex = nextValidIndex(listIndex, SkipForwards, 3); | 
| 1178         else if (keyIdentifier == "PageUp") | 1197         else if (keyIdentifier == "PageUp") | 
| 1179             listIndex = nextValidIndex(listIndex, SkipBackwards, 3); | 1198             listIndex = nextValidIndex(listIndex, SkipBackwards, 3); | 
| 1180         else if (keyIdentifier == "Home") | 1199         else if (keyIdentifier == "Home") | 
| 1181             listIndex = nextValidIndex(-1, SkipForwards, 1); | 1200             listIndex = nextValidIndex(-1, SkipForwards, 1); | 
| 1182         else if (keyIdentifier == "End") | 1201         else if (keyIdentifier == "End") | 
| 1183             listIndex = nextValidIndex(listItems.size(), SkipBackwards, 1); | 1202             listIndex = nextValidIndex(listItems.size(), SkipBackwards, 1); | 
| 1184         else | 1203         else | 
| 1185             handled = false; | 1204             handled = false; | 
| 1186 | 1205 | 
| 1187         if (handled && static_cast<size_t>(listIndex) < listItems.size()) | 1206         if (handled && static_cast<size_t>(listIndex) < listItems.size()) | 
| 1188             selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | Di
      spatchInputAndChangeEvent | UserDriven); | 1207             selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | Di
      spatchInputAndChangeEvent | UserDriven); | 
| 1189 | 1208 | 
| 1190         if (handled) | 1209         if (handled) | 
| 1191             event->setDefaultHandled(); | 1210             event->setDefaultHandled(); | 
| 1192     } | 1211     } | 
| 1193 | 1212 | 
| 1194     // Use key press event here since sending simulated mouse events |  | 
| 1195     // on key down blocks the proper sending of the key press event. |  | 
| 1196     if (event->type() == EventTypeNames::keypress) { | 1213     if (event->type() == EventTypeNames::keypress) { | 
| 1197         if (!renderer() || !event->isKeyboardEvent()) | 1214         if (!renderer() || !event->isKeyboardEvent()) | 
| 1198             return; | 1215             return; | 
| 1199 | 1216 | 
| 1200         int keyCode = toKeyboardEvent(event)->keyCode(); | 1217         int keyCode = toKeyboardEvent(event)->keyCode(); | 
| 1201         bool handled = false; |  | 
| 1202 |  | 
| 1203         if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { | 1218         if (keyCode == ' ' && isSpatialNavigationEnabled(document().frame())) { | 
| 1204             // Use space to toggle arrow key handling for selection change or sp
      atial navigation. | 1219             // Use space to toggle arrow key handling for selection change or sp
      atial navigation. | 
| 1205             m_activeSelectionState = !m_activeSelectionState; | 1220             m_activeSelectionState = !m_activeSelectionState; | 
| 1206             event->setDefaultHandled(); | 1221             event->setDefaultHandled(); | 
| 1207             return; | 1222             return; | 
| 1208         } | 1223         } | 
| 1209 | 1224 | 
| 1210         if (renderTheme.popsMenuBySpaceOrReturn()) { | 1225         KeyboardEvent* keyEvent = toKeyboardEvent(event); | 
| 1211             if (keyCode == ' ' || keyCode == '\r') { | 1226         if (shouldOpenPopupForKeyPressEvent(keyEvent)) { | 
| 1212                 focus(); | 1227             handlePopupOpenKeyboardEvent(event); | 
| 1213 | 1228             return; | 
| 1214                 // Calling focus() may remove the renderer or change the |  | 
| 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         } | 1229         } | 
| 1252 | 1230 | 
| 1253         if (handled) | 1231         if (!RenderTheme::theme().popsMenuByReturnKey() && keyCode == '\r') { | 
|  | 1232             if (form()) | 
|  | 1233                 form()->submitImplicitly(event, false); | 
|  | 1234             dispatchInputAndChangeEventForMenuList(); | 
| 1254             event->setDefaultHandled(); | 1235             event->setDefaultHandled(); | 
|  | 1236         } | 
| 1255     } | 1237     } | 
| 1256 | 1238 | 
| 1257     if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && t
      oMouseEvent(event)->button() == LeftButton) { | 1239     if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && t
      oMouseEvent(event)->button() == LeftButton) { | 
| 1258         focus(); | 1240         focus(); | 
| 1259         if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) 
      { | 1241         if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) 
      { | 
| 1260             if (RenderMenuList* menuList = toRenderMenuList(renderer())) { | 1242             if (RenderMenuList* menuList = toRenderMenuList(renderer())) { | 
| 1261                 if (menuList->popupIsVisible()) | 1243                 if (menuList->popupIsVisible()) | 
| 1262                     menuList->hidePopup(); | 1244                     menuList->hidePopup(); | 
| 1263                 else { | 1245                 else { | 
| 1264                     // Save the selection so it can be compared to the new | 1246                     // 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 | 1640 | 
| 1659 void HTMLSelectElement::trace(Visitor* visitor) | 1641 void HTMLSelectElement::trace(Visitor* visitor) | 
| 1660 { | 1642 { | 
| 1661 #if ENABLE(OILPAN) | 1643 #if ENABLE(OILPAN) | 
| 1662     visitor->trace(m_listItems); | 1644     visitor->trace(m_listItems); | 
| 1663 #endif | 1645 #endif | 
| 1664     HTMLFormControlElementWithState::trace(visitor); | 1646     HTMLFormControlElementWithState::trace(visitor); | 
| 1665 } | 1647 } | 
| 1666 | 1648 | 
| 1667 } // namespace | 1649 } // namespace | 
| OLD | NEW | 
|---|