Chromium Code Reviews| Index: components/test_runner/event_sender.cc |
| diff --git a/components/test_runner/event_sender.cc b/components/test_runner/event_sender.cc |
| index 521d780d6fcf28dea83b8a932623f0ba69d9635c..73dfe76d40607627808f618436f16e2aba802458 100644 |
| --- a/components/test_runner/event_sender.cc |
| +++ b/components/test_runner/event_sender.cc |
| @@ -6,6 +6,7 @@ |
| #include "base/basictypes.h" |
| #include "base/logging.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "components/test_runner/mock_spell_check.h" |
| @@ -22,7 +23,12 @@ |
| #include "third_party/WebKit/public/web/WebKit.h" |
| #include "third_party/WebKit/public/web/WebPagePopup.h" |
| #include "third_party/WebKit/public/web/WebView.h" |
| +#include "ui/events/event_constants.h" |
| +#include "ui/events/keycodes/dom/dom_code.h" |
| +#include "ui/events/keycodes/dom/dom_key.h" |
| #include "ui/events/keycodes/dom/keycode_converter.h" |
| +#include "ui/events/keycodes/dom_us_layout_data.h" |
| +#include "ui/events/keycodes/keyboard_code_conversion.h" |
| #include "ui/events/keycodes/keyboard_codes.h" |
| #include "v8/include/v8.h" |
| @@ -292,11 +298,6 @@ class KeyDownTask : public WebMethodTask<EventSender> { |
| KeyLocationCode location_; |
| }; |
| -bool NeedsShiftModifier(int keyCode) { |
| - // If code is an uppercase letter, assign a SHIFT key to eventDown.modifier. |
| - return (keyCode & 0xFF) >= 'A' && (keyCode & 0xFF) <= 'Z'; |
| -} |
| - |
| // Get the edit command corresponding to a keyboard event. |
| // Returns true if the specified event corresponds to an edit command, the name |
| // of the edit command will be stored in |*name|. |
| @@ -1255,7 +1256,69 @@ void EventSender::MouseUp(int button_number, int modifiers) { |
| } |
| } |
| -void EventSender::KeyDown(const std::string& code_str, |
| +ui::DomCode convertKeyCodeStrToDomCode(const std::string key_code_str, |
| + bool &need_modifier) |
| +{ |
| + // Convert key_code_str to DomCode passed from the layout tests. |
| + const struct DomCodeToKeyCodeStr { |
| + ui::DomCode dom_code; |
| + std::string key_code_str; |
|
dtapuska
2015/08/13 13:36:47
I'm not sure we should use a std::string here; wha
|
| + } kDomCodeToKeyCodeStrMap[] = { |
| + {ui::DomCode::ENTER, "\n"}, |
| + {ui::DomCode::ENTER, "\r"}, |
| + {ui::DomCode::ARROW_RIGHT, "rightArrow"}, |
| + {ui::DomCode::ARROW_LEFT, "leftArrow"}, |
| + {ui::DomCode::ARROW_DOWN, "downArrow"}, |
| + {ui::DomCode::ARROW_UP, "upArrow"}, |
| + {ui::DomCode::INSERT, "insert"}, |
| + {ui::DomCode::DEL, "delete"}, |
| + {ui::DomCode::PAGE_UP, "pageUp"}, |
| + {ui::DomCode::PAGE_DOWN, "pageDown"}, |
| + {ui::DomCode::HOME, "home"}, |
| + {ui::DomCode::END, "end"}, |
| + {ui::DomCode::PRINT_SCREEN, "printScreen"}, |
| + {ui::DomCode::CONTEXT_MENU, "menu"}, |
| + {ui::DomCode::CONTROL_LEFT, "leftControl"}, |
| + {ui::DomCode::CONTROL_RIGHT, "rightControl"}, |
| + {ui::DomCode::SHIFT_LEFT, "leftShift"}, |
| + {ui::DomCode::SHIFT_RIGHT, "rightShift"}, |
| + {ui::DomCode::ALT_LEFT, "leftAlt"}, |
| + {ui::DomCode::ALT_RIGHT, "rightAlt"}, |
| + {ui::DomCode::NUM_LOCK, "numLock"}, |
| + {ui::DomCode::BACKSPACE, "backspace"}, |
| + {ui::DomCode::ESCAPE, "escape"}, |
| + }; |
| + |
| + for (const auto& it : kDomCodeToKeyCodeStrMap) { |
| + if (it.key_code_str == key_code_str) |
| + return it.dom_code; |
| + } |
| + |
| + // F1..24 DomCode Value. |
| + for (int i = 1; i <= 24; ++i) { |
|
dtapuska
2015/08/13 13:36:47
This would benefit of a prefix match on F...
|
| + std::string function_key_name = base::StringPrintf("F%d", i); |
| + if (function_key_name == key_code_str) { |
| + int num = static_cast<int>(ui::DomCode::F1) + ( i -1); |
| + return static_cast<ui::DomCode>(num); |
| + } |
| + } |
| + |
| + // Printable Value |
| + for (const auto& it : ui::kPrintableCodeMap) { |
| + base::char16 str = static_cast<base::char16>(key_code_str.at(0)); |
|
dtapuska
2015/08/13 13:36:47
This doesn't need to be in the loop; it is const f
|
| + if (it.character[0] == str || it.character[1] == str) { |
| + if (it.character[1] == str && it.character[0] != it.character[1]) |
| + need_modifier = true; |
| + return it.dom_code; |
| + } |
| + } |
| + |
| + // Fallback to get corresponding DomCode value. |
| + return ui::UsLayoutKeyboardCodeToDomCode( |
| + static_cast<ui::KeyboardCode>(key_code_str.at(0))); |
| +} |
| + |
| +void EventSender::KeyDown(const std::string& key_code_str, |
| int modifiers, |
| KeyLocationCode location) { |
| // FIXME: I'm not exactly sure how we should convert the string to a key |
| @@ -1263,126 +1326,26 @@ void EventSender::KeyDown(const std::string& code_str, |
| // FIXME: Should we also generate a KEY_UP? |
| bool generate_char = false; |
| - |
| - // Convert \n -> VK_RETURN. Some layout tests use \n to mean "Enter", when |
| - // Windows uses \r for "Enter". |
| - int code = 0; |
| - int text = 0; |
| - bool needs_shift_key_modifier = false; |
| - std::string domString; |
| - |
| - if ("\n" == code_str) { |
| - generate_char = true; |
| - text = code = ui::VKEY_RETURN; |
| - domString.assign("Enter"); |
| - } else if ("rightArrow" == code_str) { |
| - code = ui::VKEY_RIGHT; |
| - domString.assign("ArrowRight"); |
| - } else if ("downArrow" == code_str) { |
| - code = ui::VKEY_DOWN; |
| - domString.assign("ArrowDown"); |
| - } else if ("leftArrow" == code_str) { |
| - code = ui::VKEY_LEFT; |
| - domString.assign("ArrowLeft"); |
| - } else if ("upArrow" == code_str) { |
| - code = ui::VKEY_UP; |
| - domString.assign("ArrowUp"); |
| - } else if ("insert" == code_str) { |
| - code = ui::VKEY_INSERT; |
| - domString.assign("Insert"); |
| - } else if ("delete" == code_str) { |
| - code = ui::VKEY_DELETE; |
| - domString.assign("Delete"); |
| - } else if ("pageUp" == code_str) { |
| - code = ui::VKEY_PRIOR; |
| - domString.assign("PageUp"); |
| - } else if ("pageDown" == code_str) { |
| - code = ui::VKEY_NEXT; |
| - domString.assign("PageDown"); |
| - } else if ("home" == code_str) { |
| - code = ui::VKEY_HOME; |
| - domString.assign("Home"); |
| - } else if ("end" == code_str) { |
| - code = ui::VKEY_END; |
| - domString.assign("End"); |
| - } else if ("printScreen" == code_str) { |
| - code = ui::VKEY_SNAPSHOT; |
| - domString.assign("PrintScreen"); |
| - } else if ("menu" == code_str) { |
| - code = ui::VKEY_APPS; |
| - domString.assign("ContextMenu"); |
| - } else if ("leftControl" == code_str) { |
| - code = ui::VKEY_LCONTROL; |
| - domString.assign("ControlLeft"); |
| - } else if ("rightControl" == code_str) { |
| - code = ui::VKEY_RCONTROL; |
| - domString.assign("ControlRight"); |
| - } else if ("leftShift" == code_str) { |
| - code = ui::VKEY_LSHIFT; |
| - domString.assign("ShiftLeft"); |
| - } else if ("rightShift" == code_str) { |
| - code = ui::VKEY_RSHIFT; |
| - domString.assign("ShiftRight"); |
| - } else if ("leftAlt" == code_str) { |
| - code = ui::VKEY_LMENU; |
| - domString.assign("AltLeft"); |
| - } else if ("rightAlt" == code_str) { |
| - code = ui::VKEY_RMENU; |
| - domString.assign("AltRight"); |
| - } else if ("numLock" == code_str) { |
| - code = ui::VKEY_NUMLOCK; |
| - domString.assign("NumLock"); |
| - } else if ("backspace" == code_str) { |
| - code = ui::VKEY_BACK; |
| - domString.assign("Backspace"); |
| - } else if ("escape" == code_str) { |
| - code = ui::VKEY_ESCAPE; |
| - domString.assign("Escape"); |
| - } else { |
| - // Compare the input string with the function-key names defined by the |
| - // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key |
| - // name, set its key code. |
| - for (int i = 1; i <= 24; ++i) { |
| - std::string function_key_name = base::StringPrintf("F%d", i); |
| - if (function_key_name == code_str) { |
| - code = ui::VKEY_F1 + (i - 1); |
| - domString = function_key_name; |
| - break; |
| - } |
| - } |
| - if (!code) { |
| - WebString web_code_str = |
| - WebString::fromUTF8(code_str.data(), code_str.size()); |
| - if (web_code_str.length() != 1u) { |
| - v8::Isolate* isolate = blink::mainThreadIsolate(); |
| - isolate->ThrowException(v8::Exception::TypeError( |
| - gin::StringToV8(isolate, "Invalid web code."))); |
| - return; |
| - } |
| - text = code = web_code_str.at(0); |
| - needs_shift_key_modifier = NeedsShiftModifier(code); |
| - if ((code & 0xFF) >= 'a' && (code & 0xFF) <= 'z') |
| - code -= 'a' - 'A'; |
| - if ((code >= 'A' && code <= 'Z') || (code >= 'a' && code <= 'z')) { |
| - domString.assign("Key"); |
| - domString.push_back(base::ToUpperASCII(code)); |
| - } else if (code >= '0' && code <= '9') { |
| - domString.assign("Digit"); |
| - domString.push_back(code); |
| - } else if (code == ' ') { |
| - domString.assign("Space"); |
| - } else if (code == 9) { |
| - domString.assign("Tab"); |
| - } |
| - generate_char = true; |
| - } |
| - |
| - if ("(" == code_str) { |
| - code = '9'; |
| - needs_shift_key_modifier = true; |
| - } |
| + bool need_modifier = false; |
| + int flag = ui::EF_NONE; |
| + |
| + ui::DomCode dom_code = convertKeyCodeStrToDomCode(key_code_str, |
| + need_modifier); |
| + ui::KeyboardCode key_code; |
| + ui::DomKey dom_key; |
| + base::char16 dom_key_char = 0; |
| + |
| + // Modifier helps in getting correct dom_key_char. |
| + if (need_modifier) |
| + flag |= ui::EF_SHIFT_DOWN; |
| + |
| + if (!DomCodeToUsLayoutMeaning(dom_code, flag, &dom_key, &dom_key_char, |
| + &key_code)) { |
| + dom_key = ui::DomKey::NONE; |
| } |
| + key_code = NonLocatedToLocatedKeyboardCode(key_code, dom_code); |
| + |
| // For one generated keyboard event, we need to generate a keyDown/keyUp |
| // pair; |
| // On Windows, we might also need to generate a char event to mimic the |
| @@ -1391,13 +1354,20 @@ void EventSender::KeyDown(const std::string& code_str, |
| WebKeyboardEvent event_down; |
| event_down.type = WebInputEvent::RawKeyDown; |
| event_down.modifiers = modifiers; |
| - event_down.windowsKeyCode = code; |
| - event_down.domCode = static_cast<int>( |
| - ui::KeycodeConverter::CodeStringToDomCode(domString.c_str())); |
| + event_down.windowsKeyCode = key_code; |
| + event_down.domCode = static_cast<int>(dom_code); |
| - if (generate_char) { |
| - event_down.text[0] = text; |
| - event_down.unmodifiedText[0] = text; |
| + if (dom_key == ui::DomKey::CHARACTER) { |
| + event_down.domKey = static_cast<int>(dom_key_char) + |
| + static_cast<int>(ui::DomKey::CHARACTER); |
| + } else { |
| + event_down.domKey = static_cast<int>(dom_key); |
| + } |
| + |
| + if (dom_key_char != 0) |
| + { |
| + event_down.unmodifiedText[0] = event_down.text[0] = dom_key_char; |
| + generate_char = true; |
| } |
| event_down.setKeyIdentifierFromWindowsKeyCode(); |
| @@ -1405,7 +1375,7 @@ void EventSender::KeyDown(const std::string& code_str, |
| if (event_down.modifiers != 0) |
| event_down.isSystemKey = IsSystemKeyEvent(event_down); |
| - if (needs_shift_key_modifier) |
| + if (need_modifier) |
| event_down.modifiers |= WebInputEvent::ShiftKey; |
| // See if KeyLocation argument is given. |
| @@ -1431,7 +1401,7 @@ void EventSender::KeyDown(const std::string& code_str, |
| HandleInputEventOnViewOrPopup(event_down); |
| - if (code == ui::VKEY_ESCAPE && !current_drag_data_.isNull()) { |
| + if (dom_code == ui::DomCode::ESCAPE && !current_drag_data_.isNull()) { |
| WebMouseEvent event; |
| InitMouseEvent(WebInputEvent::MouseDown, |
| pressed_button_, |
| @@ -1451,7 +1421,7 @@ void EventSender::KeyDown(const std::string& code_str, |
| // keyIdentifier is an empty string, unless the Enter key was pressed. |
| // This behavior is not standard (keyIdentifier itself is not even a |
| // standard any more), but it matches the actual behavior in Blink. |
| - if (code != ui::VKEY_RETURN) |
| + if (dom_code != ui::DomCode::ENTER) |
| event_char.keyIdentifier[0] = '\0'; |
| HandleInputEventOnViewOrPopup(event_char); |
| } |