Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: components/test_runner/event_sender.cc

Issue 929053004: [KeyboardEvent] Add embedder APIs to translate between Dom |key| enum and strings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup of the dom_key.h Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/test_runner/event_sender.h" 5 #include "components/test_runner/event_sender.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
11 #include "components/test_runner/mock_spell_check.h" 12 #include "components/test_runner/mock_spell_check.h"
12 #include "components/test_runner/test_interfaces.h" 13 #include "components/test_runner/test_interfaces.h"
13 #include "components/test_runner/web_test_delegate.h" 14 #include "components/test_runner/web_test_delegate.h"
14 #include "components/test_runner/web_test_proxy.h" 15 #include "components/test_runner/web_test_proxy.h"
15 #include "gin/handle.h" 16 #include "gin/handle.h"
16 #include "gin/object_template_builder.h" 17 #include "gin/object_template_builder.h"
17 #include "gin/wrappable.h" 18 #include "gin/wrappable.h"
18 #include "third_party/WebKit/public/platform/WebString.h" 19 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "third_party/WebKit/public/platform/WebVector.h" 20 #include "third_party/WebKit/public/platform/WebVector.h"
20 #include "third_party/WebKit/public/web/WebContextMenuData.h" 21 #include "third_party/WebKit/public/web/WebContextMenuData.h"
21 #include "third_party/WebKit/public/web/WebFrame.h" 22 #include "third_party/WebKit/public/web/WebFrame.h"
22 #include "third_party/WebKit/public/web/WebKit.h" 23 #include "third_party/WebKit/public/web/WebKit.h"
23 #include "third_party/WebKit/public/web/WebPagePopup.h" 24 #include "third_party/WebKit/public/web/WebPagePopup.h"
24 #include "third_party/WebKit/public/web/WebView.h" 25 #include "third_party/WebKit/public/web/WebView.h"
26 #include "ui/events/event_constants.h"
27 #include "ui/events/keycodes/dom/dom_code.h"
28 #include "ui/events/keycodes/dom/dom_key.h"
25 #include "ui/events/keycodes/dom/keycode_converter.h" 29 #include "ui/events/keycodes/dom/keycode_converter.h"
30 #include "ui/events/keycodes/dom_us_layout_data.h"
31 #include "ui/events/keycodes/keyboard_code_conversion.h"
26 #include "ui/events/keycodes/keyboard_codes.h" 32 #include "ui/events/keycodes/keyboard_codes.h"
27 #include "v8/include/v8.h" 33 #include "v8/include/v8.h"
28 34
29 using blink::WebContextMenuData; 35 using blink::WebContextMenuData;
30 using blink::WebDragData; 36 using blink::WebDragData;
31 using blink::WebDragOperationsMask; 37 using blink::WebDragOperationsMask;
32 using blink::WebFloatPoint; 38 using blink::WebFloatPoint;
33 using blink::WebFrame; 39 using blink::WebFrame;
34 using blink::WebGestureEvent; 40 using blink::WebGestureEvent;
35 using blink::WebInputEvent; 41 using blink::WebInputEvent;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 void RunIfValid() override { 291 void RunIfValid() override {
286 object_->KeyDown(code_str_, modifiers_, location_); 292 object_->KeyDown(code_str_, modifiers_, location_);
287 } 293 }
288 294
289 private: 295 private:
290 std::string code_str_; 296 std::string code_str_;
291 int modifiers_; 297 int modifiers_;
292 KeyLocationCode location_; 298 KeyLocationCode location_;
293 }; 299 };
294 300
295 bool NeedsShiftModifier(int keyCode) {
296 // If code is an uppercase letter, assign a SHIFT key to eventDown.modifier.
297 return (keyCode & 0xFF) >= 'A' && (keyCode & 0xFF) <= 'Z';
298 }
299
300 // Get the edit command corresponding to a keyboard event. 301 // Get the edit command corresponding to a keyboard event.
301 // Returns true if the specified event corresponds to an edit command, the name 302 // Returns true if the specified event corresponds to an edit command, the name
302 // of the edit command will be stored in |*name|. 303 // of the edit command will be stored in |*name|.
303 bool GetEditCommand(const WebKeyboardEvent& event, std::string* name) { 304 bool GetEditCommand(const WebKeyboardEvent& event, std::string* name) {
304 #if defined(OS_MACOSX) 305 #if defined(OS_MACOSX)
305 // We only cares about Left,Right,Up,Down keys with Command or Command+Shift 306 // We only cares about Left,Right,Up,Down keys with Command or Command+Shift
306 // modifiers. These key events correspond to some special movement and 307 // modifiers. These key events correspond to some special movement and
307 // selection editor commands. These keys will be marked as system key, which 308 // selection editor commands. These keys will be marked as system key, which
308 // prevents them from being handled. Thus they must be handled specially. 309 // prevents them from being handled. Thus they must be handled specially.
309 if ((event.modifiers & ~WebKeyboardEvent::ShiftKey) != 310 if ((event.modifiers & ~WebKeyboardEvent::ShiftKey) !=
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 button_type, 1249 button_type,
1249 last_mouse_pos_, 1250 last_mouse_pos_,
1250 GetCurrentEventTimeSec(), 1251 GetCurrentEventTimeSec(),
1251 click_count_, 1252 click_count_,
1252 modifiers, 1253 modifiers,
1253 &event); 1254 &event);
1254 DoMouseUp(event); 1255 DoMouseUp(event);
1255 } 1256 }
1256 } 1257 }
1257 1258
1258 void EventSender::KeyDown(const std::string& code_str, 1259 ui::DomCode convertKeyCodeStrToDomCode(const std::string key_code_str,
1260 bool &need_modifier)
1261 {
1262 // Convert key_code_str to DomCode passed from the layout tests.
1263 const struct DomCodeToKeyCodeStr {
1264 ui::DomCode dom_code;
1265 std::string key_code_str;
dtapuska 2015/08/13 13:36:47 I'm not sure we should use a std::string here; wha
1266 } kDomCodeToKeyCodeStrMap[] = {
1267 {ui::DomCode::ENTER, "\n"},
1268 {ui::DomCode::ENTER, "\r"},
1269 {ui::DomCode::ARROW_RIGHT, "rightArrow"},
1270 {ui::DomCode::ARROW_LEFT, "leftArrow"},
1271 {ui::DomCode::ARROW_DOWN, "downArrow"},
1272 {ui::DomCode::ARROW_UP, "upArrow"},
1273 {ui::DomCode::INSERT, "insert"},
1274 {ui::DomCode::DEL, "delete"},
1275 {ui::DomCode::PAGE_UP, "pageUp"},
1276 {ui::DomCode::PAGE_DOWN, "pageDown"},
1277 {ui::DomCode::HOME, "home"},
1278 {ui::DomCode::END, "end"},
1279 {ui::DomCode::PRINT_SCREEN, "printScreen"},
1280 {ui::DomCode::CONTEXT_MENU, "menu"},
1281 {ui::DomCode::CONTROL_LEFT, "leftControl"},
1282 {ui::DomCode::CONTROL_RIGHT, "rightControl"},
1283 {ui::DomCode::SHIFT_LEFT, "leftShift"},
1284 {ui::DomCode::SHIFT_RIGHT, "rightShift"},
1285 {ui::DomCode::ALT_LEFT, "leftAlt"},
1286 {ui::DomCode::ALT_RIGHT, "rightAlt"},
1287 {ui::DomCode::NUM_LOCK, "numLock"},
1288 {ui::DomCode::BACKSPACE, "backspace"},
1289 {ui::DomCode::ESCAPE, "escape"},
1290 };
1291
1292 for (const auto& it : kDomCodeToKeyCodeStrMap) {
1293 if (it.key_code_str == key_code_str)
1294 return it.dom_code;
1295 }
1296
1297 // F1..24 DomCode Value.
1298 for (int i = 1; i <= 24; ++i) {
dtapuska 2015/08/13 13:36:47 This would benefit of a prefix match on F...
1299 std::string function_key_name = base::StringPrintf("F%d", i);
1300 if (function_key_name == key_code_str) {
1301 int num = static_cast<int>(ui::DomCode::F1) + ( i -1);
1302 return static_cast<ui::DomCode>(num);
1303 }
1304 }
1305
1306 // Printable Value
1307 for (const auto& it : ui::kPrintableCodeMap) {
1308 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
1309 if (it.character[0] == str || it.character[1] == str) {
1310 if (it.character[1] == str && it.character[0] != it.character[1])
1311 need_modifier = true;
1312 return it.dom_code;
1313 }
1314 }
1315
1316 // Fallback to get corresponding DomCode value.
1317 return ui::UsLayoutKeyboardCodeToDomCode(
1318 static_cast<ui::KeyboardCode>(key_code_str.at(0)));
1319 }
1320
1321 void EventSender::KeyDown(const std::string& key_code_str,
1259 int modifiers, 1322 int modifiers,
1260 KeyLocationCode location) { 1323 KeyLocationCode location) {
1261 // FIXME: I'm not exactly sure how we should convert the string to a key 1324 // FIXME: I'm not exactly sure how we should convert the string to a key
1262 // event. This seems to work in the cases I tested. 1325 // event. This seems to work in the cases I tested.
1263 // FIXME: Should we also generate a KEY_UP? 1326 // FIXME: Should we also generate a KEY_UP?
1264 1327
1265 bool generate_char = false; 1328 bool generate_char = false;
1329 bool need_modifier = false;
1330 int flag = ui::EF_NONE;
1266 1331
1267 // Convert \n -> VK_RETURN. Some layout tests use \n to mean "Enter", when 1332 ui::DomCode dom_code = convertKeyCodeStrToDomCode(key_code_str,
1268 // Windows uses \r for "Enter". 1333 need_modifier);
1269 int code = 0; 1334 ui::KeyboardCode key_code;
1270 int text = 0; 1335 ui::DomKey dom_key;
1271 bool needs_shift_key_modifier = false; 1336 base::char16 dom_key_char = 0;
1272 std::string domString;
1273 1337
1274 if ("\n" == code_str) { 1338 // Modifier helps in getting correct dom_key_char.
1275 generate_char = true; 1339 if (need_modifier)
1276 text = code = ui::VKEY_RETURN; 1340 flag |= ui::EF_SHIFT_DOWN;
1277 domString.assign("Enter");
1278 } else if ("rightArrow" == code_str) {
1279 code = ui::VKEY_RIGHT;
1280 domString.assign("ArrowRight");
1281 } else if ("downArrow" == code_str) {
1282 code = ui::VKEY_DOWN;
1283 domString.assign("ArrowDown");
1284 } else if ("leftArrow" == code_str) {
1285 code = ui::VKEY_LEFT;
1286 domString.assign("ArrowLeft");
1287 } else if ("upArrow" == code_str) {
1288 code = ui::VKEY_UP;
1289 domString.assign("ArrowUp");
1290 } else if ("insert" == code_str) {
1291 code = ui::VKEY_INSERT;
1292 domString.assign("Insert");
1293 } else if ("delete" == code_str) {
1294 code = ui::VKEY_DELETE;
1295 domString.assign("Delete");
1296 } else if ("pageUp" == code_str) {
1297 code = ui::VKEY_PRIOR;
1298 domString.assign("PageUp");
1299 } else if ("pageDown" == code_str) {
1300 code = ui::VKEY_NEXT;
1301 domString.assign("PageDown");
1302 } else if ("home" == code_str) {
1303 code = ui::VKEY_HOME;
1304 domString.assign("Home");
1305 } else if ("end" == code_str) {
1306 code = ui::VKEY_END;
1307 domString.assign("End");
1308 } else if ("printScreen" == code_str) {
1309 code = ui::VKEY_SNAPSHOT;
1310 domString.assign("PrintScreen");
1311 } else if ("menu" == code_str) {
1312 code = ui::VKEY_APPS;
1313 domString.assign("ContextMenu");
1314 } else if ("leftControl" == code_str) {
1315 code = ui::VKEY_LCONTROL;
1316 domString.assign("ControlLeft");
1317 } else if ("rightControl" == code_str) {
1318 code = ui::VKEY_RCONTROL;
1319 domString.assign("ControlRight");
1320 } else if ("leftShift" == code_str) {
1321 code = ui::VKEY_LSHIFT;
1322 domString.assign("ShiftLeft");
1323 } else if ("rightShift" == code_str) {
1324 code = ui::VKEY_RSHIFT;
1325 domString.assign("ShiftRight");
1326 } else if ("leftAlt" == code_str) {
1327 code = ui::VKEY_LMENU;
1328 domString.assign("AltLeft");
1329 } else if ("rightAlt" == code_str) {
1330 code = ui::VKEY_RMENU;
1331 domString.assign("AltRight");
1332 } else if ("numLock" == code_str) {
1333 code = ui::VKEY_NUMLOCK;
1334 domString.assign("NumLock");
1335 } else if ("backspace" == code_str) {
1336 code = ui::VKEY_BACK;
1337 domString.assign("Backspace");
1338 } else if ("escape" == code_str) {
1339 code = ui::VKEY_ESCAPE;
1340 domString.assign("Escape");
1341 } else {
1342 // Compare the input string with the function-key names defined by the
1343 // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key
1344 // name, set its key code.
1345 for (int i = 1; i <= 24; ++i) {
1346 std::string function_key_name = base::StringPrintf("F%d", i);
1347 if (function_key_name == code_str) {
1348 code = ui::VKEY_F1 + (i - 1);
1349 domString = function_key_name;
1350 break;
1351 }
1352 }
1353 if (!code) {
1354 WebString web_code_str =
1355 WebString::fromUTF8(code_str.data(), code_str.size());
1356 if (web_code_str.length() != 1u) {
1357 v8::Isolate* isolate = blink::mainThreadIsolate();
1358 isolate->ThrowException(v8::Exception::TypeError(
1359 gin::StringToV8(isolate, "Invalid web code.")));
1360 return;
1361 }
1362 text = code = web_code_str.at(0);
1363 needs_shift_key_modifier = NeedsShiftModifier(code);
1364 if ((code & 0xFF) >= 'a' && (code & 0xFF) <= 'z')
1365 code -= 'a' - 'A';
1366 if ((code >= 'A' && code <= 'Z') || (code >= 'a' && code <= 'z')) {
1367 domString.assign("Key");
1368 domString.push_back(base::ToUpperASCII(code));
1369 } else if (code >= '0' && code <= '9') {
1370 domString.assign("Digit");
1371 domString.push_back(code);
1372 } else if (code == ' ') {
1373 domString.assign("Space");
1374 } else if (code == 9) {
1375 domString.assign("Tab");
1376 }
1377 generate_char = true;
1378 }
1379 1341
1380 if ("(" == code_str) { 1342 if (!DomCodeToUsLayoutMeaning(dom_code, flag, &dom_key, &dom_key_char,
1381 code = '9'; 1343 &key_code)) {
1382 needs_shift_key_modifier = true; 1344 dom_key = ui::DomKey::NONE;
1383 }
1384 } 1345 }
1385 1346
1347 key_code = NonLocatedToLocatedKeyboardCode(key_code, dom_code);
1348
1386 // For one generated keyboard event, we need to generate a keyDown/keyUp 1349 // For one generated keyboard event, we need to generate a keyDown/keyUp
1387 // pair; 1350 // pair;
1388 // On Windows, we might also need to generate a char event to mimic the 1351 // On Windows, we might also need to generate a char event to mimic the
1389 // Windows event flow; on other platforms we create a merged event and test 1352 // Windows event flow; on other platforms we create a merged event and test
1390 // the event flow that that platform provides. 1353 // the event flow that that platform provides.
1391 WebKeyboardEvent event_down; 1354 WebKeyboardEvent event_down;
1392 event_down.type = WebInputEvent::RawKeyDown; 1355 event_down.type = WebInputEvent::RawKeyDown;
1393 event_down.modifiers = modifiers; 1356 event_down.modifiers = modifiers;
1394 event_down.windowsKeyCode = code; 1357 event_down.windowsKeyCode = key_code;
1395 event_down.domCode = static_cast<int>( 1358 event_down.domCode = static_cast<int>(dom_code);
1396 ui::KeycodeConverter::CodeStringToDomCode(domString.c_str()));
1397 1359
1398 if (generate_char) { 1360 if (dom_key == ui::DomKey::CHARACTER) {
1399 event_down.text[0] = text; 1361 event_down.domKey = static_cast<int>(dom_key_char) +
1400 event_down.unmodifiedText[0] = text; 1362 static_cast<int>(ui::DomKey::CHARACTER);
1363 } else {
1364 event_down.domKey = static_cast<int>(dom_key);
1365 }
1366
1367 if (dom_key_char != 0)
1368 {
1369 event_down.unmodifiedText[0] = event_down.text[0] = dom_key_char;
1370 generate_char = true;
1401 } 1371 }
1402 1372
1403 event_down.setKeyIdentifierFromWindowsKeyCode(); 1373 event_down.setKeyIdentifierFromWindowsKeyCode();
1404 1374
1405 if (event_down.modifiers != 0) 1375 if (event_down.modifiers != 0)
1406 event_down.isSystemKey = IsSystemKeyEvent(event_down); 1376 event_down.isSystemKey = IsSystemKeyEvent(event_down);
1407 1377
1408 if (needs_shift_key_modifier) 1378 if (need_modifier)
1409 event_down.modifiers |= WebInputEvent::ShiftKey; 1379 event_down.modifiers |= WebInputEvent::ShiftKey;
1410 1380
1411 // See if KeyLocation argument is given. 1381 // See if KeyLocation argument is given.
1412 if (location == DOMKeyLocationNumpad) 1382 if (location == DOMKeyLocationNumpad)
1413 event_down.modifiers |= WebInputEvent::IsKeyPad; 1383 event_down.modifiers |= WebInputEvent::IsKeyPad;
1414 1384
1415 WebKeyboardEvent event_up; 1385 WebKeyboardEvent event_up;
1416 event_up = event_down; 1386 event_up = event_down;
1417 event_up.type = WebInputEvent::KeyUp; 1387 event_up.type = WebInputEvent::KeyUp;
1418 // EventSender.m forces a layout here, with at least one 1388 // EventSender.m forces a layout here, with at least one
1419 // test (fast/forms/focus-control-to-page.html) relying on this. 1389 // test (fast/forms/focus-control-to-page.html) relying on this.
1420 if (force_layout_on_events_) 1390 if (force_layout_on_events_)
1421 view_->layout(); 1391 view_->layout();
1422 1392
1423 // In the browser, if a keyboard event corresponds to an editor command, 1393 // In the browser, if a keyboard event corresponds to an editor command,
1424 // the command will be dispatched to the renderer just before dispatching 1394 // the command will be dispatched to the renderer just before dispatching
1425 // the keyboard event, and then it will be executed in the 1395 // the keyboard event, and then it will be executed in the
1426 // RenderView::handleCurrentKeyboardEvent() method. 1396 // RenderView::handleCurrentKeyboardEvent() method.
1427 // We just simulate the same behavior here. 1397 // We just simulate the same behavior here.
1428 std::string edit_command; 1398 std::string edit_command;
1429 if (GetEditCommand(event_down, &edit_command)) 1399 if (GetEditCommand(event_down, &edit_command))
1430 delegate_->SetEditCommand(edit_command, ""); 1400 delegate_->SetEditCommand(edit_command, "");
1431 1401
1432 HandleInputEventOnViewOrPopup(event_down); 1402 HandleInputEventOnViewOrPopup(event_down);
1433 1403
1434 if (code == ui::VKEY_ESCAPE && !current_drag_data_.isNull()) { 1404 if (dom_code == ui::DomCode::ESCAPE && !current_drag_data_.isNull()) {
1435 WebMouseEvent event; 1405 WebMouseEvent event;
1436 InitMouseEvent(WebInputEvent::MouseDown, 1406 InitMouseEvent(WebInputEvent::MouseDown,
1437 pressed_button_, 1407 pressed_button_,
1438 last_mouse_pos_, 1408 last_mouse_pos_,
1439 GetCurrentEventTimeSec(), 1409 GetCurrentEventTimeSec(),
1440 click_count_, 1410 click_count_,
1441 0, 1411 0,
1442 &event); 1412 &event);
1443 FinishDragAndDrop(event, blink::WebDragOperationNone); 1413 FinishDragAndDrop(event, blink::WebDragOperationNone);
1444 } 1414 }
1445 1415
1446 delegate_->ClearEditCommand(); 1416 delegate_->ClearEditCommand();
1447 1417
1448 if (generate_char) { 1418 if (generate_char) {
1449 WebKeyboardEvent event_char = event_up; 1419 WebKeyboardEvent event_char = event_up;
1450 event_char.type = WebInputEvent::Char; 1420 event_char.type = WebInputEvent::Char;
1451 // keyIdentifier is an empty string, unless the Enter key was pressed. 1421 // keyIdentifier is an empty string, unless the Enter key was pressed.
1452 // This behavior is not standard (keyIdentifier itself is not even a 1422 // This behavior is not standard (keyIdentifier itself is not even a
1453 // standard any more), but it matches the actual behavior in Blink. 1423 // standard any more), but it matches the actual behavior in Blink.
1454 if (code != ui::VKEY_RETURN) 1424 if (dom_code != ui::DomCode::ENTER)
1455 event_char.keyIdentifier[0] = '\0'; 1425 event_char.keyIdentifier[0] = '\0';
1456 HandleInputEventOnViewOrPopup(event_char); 1426 HandleInputEventOnViewOrPopup(event_char);
1457 } 1427 }
1458 1428
1459 HandleInputEventOnViewOrPopup(event_up); 1429 HandleInputEventOnViewOrPopup(event_up);
1460 } 1430 }
1461 1431
1462 void EventSender::EnableDOMUIEventLogging() {} 1432 void EventSender::EnableDOMUIEventLogging() {}
1463 1433
1464 void EventSender::FireKeyboardEventsToElement() {} 1434 void EventSender::FireKeyboardEventsToElement() {}
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 2515
2546 bool EventSender::HandleInputEventOnViewOrPopup(const WebInputEvent& event) { 2516 bool EventSender::HandleInputEventOnViewOrPopup(const WebInputEvent& event) {
2547 if (WebPagePopup* popup = view_->pagePopup()) { 2517 if (WebPagePopup* popup = view_->pagePopup()) {
2548 if (!WebInputEvent::isKeyboardEventType(event.type)) 2518 if (!WebInputEvent::isKeyboardEventType(event.type))
2549 return popup->handleInputEvent(event); 2519 return popup->handleInputEvent(event);
2550 } 2520 }
2551 return view_->handleInputEvent(event); 2521 return view_->handleInputEvent(event);
2552 } 2522 }
2553 2523
2554 } // namespace test_runner 2524 } // namespace test_runner
OLDNEW
« no previous file with comments | « no previous file | content/browser/renderer_host/web_input_event_aura.cc » ('j') | content/child/blink_platform_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698