| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "KeyboardEventManager.h" | 5 #include "KeyboardEventManager.h" |
| 6 | 6 |
| 7 #include "core/dom/Element.h" | 7 #include "core/dom/Element.h" |
| 8 #include "core/editing/Editor.h" | 8 #include "core/editing/Editor.h" |
| 9 #include "core/events/KeyboardEvent.h" | 9 #include "core/events/KeyboardEvent.h" |
| 10 #include "core/html/HTMLDialogElement.h" | 10 #include "core/html/HTMLDialogElement.h" |
| 11 #include "core/input/EventHandler.h" |
| 11 #include "core/input/EventHandlingUtil.h" | 12 #include "core/input/EventHandlingUtil.h" |
| 12 #include "core/input/ScrollManager.h" | 13 #include "core/input/ScrollManager.h" |
| 13 #include "core/layout/LayoutObject.h" | 14 #include "core/layout/LayoutObject.h" |
| 14 #include "core/layout/LayoutTextControlSingleLine.h" | 15 #include "core/layout/LayoutTextControlSingleLine.h" |
| 15 #include "core/loader/FrameLoaderClient.h" | 16 #include "core/loader/FrameLoaderClient.h" |
| 16 #include "core/page/ChromeClient.h" | 17 #include "core/page/ChromeClient.h" |
| 17 #include "core/page/FocusController.h" | 18 #include "core/page/FocusController.h" |
| 18 #include "core/page/Page.h" | 19 #include "core/page/Page.h" |
| 19 #include "core/page/SpatialNavigation.h" | 20 #include "core/page/SpatialNavigation.h" |
| 21 #include "platform/KeyboardCodes.h" |
| 20 #include "platform/UserGestureIndicator.h" | 22 #include "platform/UserGestureIndicator.h" |
| 21 #include "platform/WindowsKeyboardCodes.h" | 23 #include "platform/WindowsKeyboardCodes.h" |
| 22 #include "public/platform/WebInputEvent.h" | 24 #include "public/platform/WebInputEvent.h" |
| 23 | 25 |
| 24 #if OS(WIN) | 26 #if OS(WIN) |
| 25 #include <windows.h> | 27 #include <windows.h> |
| 26 #elif OS(MACOSX) | 28 #elif OS(MACOSX) |
| 27 #import <Carbon/Carbon.h> | 29 #import <Carbon/Carbon.h> |
| 28 #endif | 30 #endif |
| 29 | 31 |
| 30 namespace blink { | 32 namespace blink { |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 #if OS(WIN) | 36 #if OS(WIN) |
| 35 static const unsigned short HIGHBITMASKSHORT = 0x8000; | 37 static const unsigned short HIGHBITMASKSHORT = 0x8000; |
| 36 #endif | 38 #endif |
| 37 | 39 |
| 38 const int kVKeyProcessKey = 229; | 40 const int kVKeyProcessKey = 229; |
| 39 | 41 |
| 40 WebFocusType focusDirectionForKey(const String& key) { | 42 WebFocusType focusDirectionForKey(KeyboardEvent* event) { |
| 43 if (event->ctrlKey() || event->metaKey() || event->shiftKey()) |
| 44 return WebFocusTypeNone; |
| 45 |
| 41 WebFocusType retVal = WebFocusTypeNone; | 46 WebFocusType retVal = WebFocusTypeNone; |
| 42 if (key == "ArrowDown") | 47 if (event->key() == "ArrowDown") |
| 43 retVal = WebFocusTypeDown; | 48 retVal = WebFocusTypeDown; |
| 44 else if (key == "ArrowUp") | 49 else if (event->key() == "ArrowUp") |
| 45 retVal = WebFocusTypeUp; | 50 retVal = WebFocusTypeUp; |
| 46 else if (key == "ArrowLeft") | 51 else if (event->key() == "ArrowLeft") |
| 47 retVal = WebFocusTypeLeft; | 52 retVal = WebFocusTypeLeft; |
| 48 else if (key == "ArrowRight") | 53 else if (event->key() == "ArrowRight") |
| 49 retVal = WebFocusTypeRight; | 54 retVal = WebFocusTypeRight; |
| 50 return retVal; | 55 return retVal; |
| 51 } | 56 } |
| 52 | 57 |
| 58 bool mapKeyCodeForScroll(int keyCode, |
| 59 PlatformEvent::Modifiers modifiers, |
| 60 ScrollDirection* scrollDirection, |
| 61 ScrollGranularity* scrollGranularity) { |
| 62 if (modifiers & PlatformEvent::ShiftKey || modifiers & PlatformEvent::MetaKey) |
| 63 return false; |
| 64 |
| 65 if (modifiers & PlatformEvent::AltKey) { |
| 66 // Alt-Up/Down should behave like PageUp/Down on Mac. (Note that Alt-keys |
| 67 // on other platforms are suppressed due to isSystemKey being set.) |
| 68 if (keyCode == VKEY_UP) |
| 69 keyCode = VKEY_PRIOR; |
| 70 else if (keyCode == VKEY_DOWN) |
| 71 keyCode = VKEY_NEXT; |
| 72 else |
| 73 return false; |
| 74 } |
| 75 |
| 76 if (modifiers & PlatformEvent::CtrlKey) { |
| 77 // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl |
| 78 // key combinations which affect scrolling. |
| 79 if (keyCode != VKEY_HOME && keyCode != VKEY_END) |
| 80 return false; |
| 81 } |
| 82 |
| 83 switch (keyCode) { |
| 84 case VKEY_LEFT: |
| 85 *scrollDirection = ScrollLeftIgnoringWritingMode; |
| 86 *scrollGranularity = ScrollByLine; |
| 87 break; |
| 88 case VKEY_RIGHT: |
| 89 *scrollDirection = ScrollRightIgnoringWritingMode; |
| 90 *scrollGranularity = ScrollByLine; |
| 91 break; |
| 92 case VKEY_UP: |
| 93 *scrollDirection = ScrollUpIgnoringWritingMode; |
| 94 *scrollGranularity = ScrollByLine; |
| 95 break; |
| 96 case VKEY_DOWN: |
| 97 *scrollDirection = ScrollDownIgnoringWritingMode; |
| 98 *scrollGranularity = ScrollByLine; |
| 99 break; |
| 100 case VKEY_HOME: |
| 101 *scrollDirection = ScrollUpIgnoringWritingMode; |
| 102 *scrollGranularity = ScrollByDocument; |
| 103 break; |
| 104 case VKEY_END: |
| 105 *scrollDirection = ScrollDownIgnoringWritingMode; |
| 106 *scrollGranularity = ScrollByDocument; |
| 107 break; |
| 108 case VKEY_PRIOR: // page up |
| 109 *scrollDirection = ScrollUpIgnoringWritingMode; |
| 110 *scrollGranularity = ScrollByPage; |
| 111 break; |
| 112 case VKEY_NEXT: // page down |
| 113 *scrollDirection = ScrollDownIgnoringWritingMode; |
| 114 *scrollGranularity = ScrollByPage; |
| 115 break; |
| 116 default: |
| 117 return false; |
| 118 } |
| 119 |
| 120 return true; |
| 121 } |
| 122 |
| 53 } // namespace | 123 } // namespace |
| 54 | 124 |
| 55 KeyboardEventManager::KeyboardEventManager(LocalFrame* frame, | 125 KeyboardEventManager::KeyboardEventManager(LocalFrame* frame, |
| 56 ScrollManager* scrollManager) | 126 ScrollManager* scrollManager) |
| 57 : m_frame(frame), m_scrollManager(scrollManager) {} | 127 : m_frame(frame), m_scrollManager(scrollManager) {} |
| 58 | 128 |
| 59 DEFINE_TRACE(KeyboardEventManager) { | 129 DEFINE_TRACE(KeyboardEventManager) { |
| 60 visitor->trace(m_frame); | 130 visitor->trace(m_frame); |
| 61 visitor->trace(m_scrollManager); | 131 visitor->trace(m_scrollManager); |
| 62 } | 132 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 // TODO(dtapuska): Replace this with isComposing support. crbug.com/625686 | 273 // TODO(dtapuska): Replace this with isComposing support. crbug.com/625686 |
| 204 if (event->keyCode() == kVKeyProcessKey) | 274 if (event->keyCode() == kVKeyProcessKey) |
| 205 return; | 275 return; |
| 206 if (event->key() == "Tab") { | 276 if (event->key() == "Tab") { |
| 207 defaultTabEventHandler(event); | 277 defaultTabEventHandler(event); |
| 208 } else if (event->key() == "Backspace") { | 278 } else if (event->key() == "Backspace") { |
| 209 defaultBackspaceEventHandler(event); | 279 defaultBackspaceEventHandler(event); |
| 210 } else if (event->key() == "Escape") { | 280 } else if (event->key() == "Escape") { |
| 211 defaultEscapeEventHandler(event); | 281 defaultEscapeEventHandler(event); |
| 212 } else { | 282 } else { |
| 213 WebFocusType type = focusDirectionForKey(event->key()); | 283 defaultArrowEventHandler(event, possibleFocusedNode); |
| 214 if (type != WebFocusTypeNone) | |
| 215 defaultArrowEventHandler(type, event); | |
| 216 } | 284 } |
| 217 } | 285 } |
| 218 if (event->type() == EventTypeNames::keypress) { | 286 if (event->type() == EventTypeNames::keypress) { |
| 219 m_frame->editor().handleKeyboardEvent(event); | 287 m_frame->editor().handleKeyboardEvent(event); |
| 220 if (event->defaultHandled()) | 288 if (event->defaultHandled()) |
| 221 return; | 289 return; |
| 222 if (event->charCode() == ' ') | 290 if (event->charCode() == ' ') |
| 223 defaultSpaceEventHandler(event, possibleFocusedNode); | 291 defaultSpaceEventHandler(event, possibleFocusedNode); |
| 224 } | 292 } |
| 225 } | 293 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 256 UseCounter::count(m_frame->document(), UseCounter::BackspaceNavigatedBack); | 324 UseCounter::count(m_frame->document(), UseCounter::BackspaceNavigatedBack); |
| 257 if (m_frame->page()->chromeClient().hadFormInteraction()) | 325 if (m_frame->page()->chromeClient().hadFormInteraction()) |
| 258 UseCounter::count(m_frame->document(), | 326 UseCounter::count(m_frame->document(), |
| 259 UseCounter::BackspaceNavigatedBackAfterFormInteraction); | 327 UseCounter::BackspaceNavigatedBackAfterFormInteraction); |
| 260 bool handledEvent = m_frame->loader().client()->navigateBackForward( | 328 bool handledEvent = m_frame->loader().client()->navigateBackForward( |
| 261 event->shiftKey() ? 1 : -1); | 329 event->shiftKey() ? 1 : -1); |
| 262 if (handledEvent) | 330 if (handledEvent) |
| 263 event->setDefaultHandled(); | 331 event->setDefaultHandled(); |
| 264 } | 332 } |
| 265 | 333 |
| 266 void KeyboardEventManager::defaultArrowEventHandler(WebFocusType focusType, | 334 void KeyboardEventManager::defaultArrowEventHandler(KeyboardEvent* event, |
| 267 KeyboardEvent* event) { | 335 Node* possibleFocusedNode) { |
| 268 DCHECK_EQ(event->type(), EventTypeNames::keydown); | 336 DCHECK_EQ(event->type(), EventTypeNames::keydown); |
| 269 | 337 |
| 270 if (event->ctrlKey() || event->metaKey() || event->shiftKey()) | |
| 271 return; | |
| 272 | |
| 273 Page* page = m_frame->page(); | 338 Page* page = m_frame->page(); |
| 274 if (!page) | 339 if (!page) |
| 275 return; | 340 return; |
| 276 | 341 |
| 277 if (!isSpatialNavigationEnabled(m_frame)) | 342 WebFocusType type = focusDirectionForKey(event); |
| 343 if (type != WebFocusTypeNone && isSpatialNavigationEnabled(m_frame) && |
| 344 !m_frame->document()->inDesignMode()) { |
| 345 if (page->focusController().advanceFocus(type)) { |
| 346 event->setDefaultHandled(); |
| 347 return; |
| 348 } |
| 349 } |
| 350 |
| 351 if (event->keyEvent() && event->keyEvent()->isSystemKey) |
| 278 return; | 352 return; |
| 279 | 353 |
| 280 // Arrows and other possible directional navigation keys can be used in design | 354 ScrollDirection scrollDirection; |
| 281 // mode editing. | 355 ScrollGranularity scrollGranularity; |
| 282 if (m_frame->document()->inDesignMode()) | 356 if (!mapKeyCodeForScroll(event->keyCode(), event->modifiers(), |
| 357 &scrollDirection, &scrollGranularity)) |
| 283 return; | 358 return; |
| 284 | 359 |
| 285 if (page->focusController().advanceFocus(focusType)) | 360 if (m_scrollManager->bubblingScroll(scrollDirection, scrollGranularity, |
| 361 nullptr, possibleFocusedNode)) { |
| 286 event->setDefaultHandled(); | 362 event->setDefaultHandled(); |
| 363 return; |
| 364 } |
| 287 } | 365 } |
| 288 | 366 |
| 289 void KeyboardEventManager::defaultTabEventHandler(KeyboardEvent* event) { | 367 void KeyboardEventManager::defaultTabEventHandler(KeyboardEvent* event) { |
| 290 DCHECK_EQ(event->type(), EventTypeNames::keydown); | 368 DCHECK_EQ(event->type(), EventTypeNames::keydown); |
| 291 | 369 |
| 292 // We should only advance focus on tabs if no special modifier keys are held | 370 // We should only advance focus on tabs if no special modifier keys are held |
| 293 // down. | 371 // down. |
| 294 if (event->ctrlKey() || event->metaKey()) | 372 if (event->ctrlKey() || event->metaKey()) |
| 295 return; | 373 return; |
| 296 | 374 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 if (currentModifiers & ::cmdKey) | 450 if (currentModifiers & ::cmdKey) |
| 373 modifiers |= WebInputEvent::MetaKey; | 451 modifiers |= WebInputEvent::MetaKey; |
| 374 #else | 452 #else |
| 375 // TODO(crbug.com/538289): Implement on other platforms. | 453 // TODO(crbug.com/538289): Implement on other platforms. |
| 376 return static_cast<WebInputEvent::Modifiers>(0); | 454 return static_cast<WebInputEvent::Modifiers>(0); |
| 377 #endif | 455 #endif |
| 378 return static_cast<WebInputEvent::Modifiers>(modifiers); | 456 return static_cast<WebInputEvent::Modifiers>(modifiers); |
| 379 } | 457 } |
| 380 | 458 |
| 381 } // namespace blink | 459 } // namespace blink |
| OLD | NEW |