OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/common/native_web_keyboard_event.h" | 5 #include "chrome/common/native_web_keyboard_event.h" |
6 #include "chrome/common/render_messages.h" | 6 #include "chrome/common/render_messages.h" |
7 #include "chrome/test/render_view_test.h" | 7 #include "chrome/test/render_view_test.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 | 9 |
10 TEST_F(RenderViewTest, OnLoadAlternateHTMLText) { | 10 TEST_F(RenderViewTest, OnLoadAlternateHTMLText) { |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 EXPECT_EQ(0, post_did_print_page_param.page_number); | 308 EXPECT_EQ(0, post_did_print_page_param.page_number); |
309 #else | 309 #else |
310 NOTIMPLEMENTED(); | 310 NOTIMPLEMENTED(); |
311 #endif | 311 #endif |
312 } | 312 } |
313 | 313 |
314 // Test that we can receive correct DOM events when we send input events | 314 // Test that we can receive correct DOM events when we send input events |
315 // through the RenderWidget::OnHandleInputEvent() function. | 315 // through the RenderWidget::OnHandleInputEvent() function. |
316 TEST_F(RenderViewTest, OnHandleKeyboardEvent) { | 316 TEST_F(RenderViewTest, OnHandleKeyboardEvent) { |
317 #if defined(OS_WIN) | 317 #if defined(OS_WIN) |
318 // Save the keyboard layout and the status. | |
319 // This test changes the keyboard layout and status. This may break | |
320 // succeeding tests. To prevent this possible break, we should save the | |
321 // layout and status here to restore when this test is finished. | |
322 HKL original_layout = GetKeyboardLayout(0); | |
323 BYTE original_key_states[256]; | |
324 GetKeyboardState(&original_key_states[0]); | |
325 | |
326 // Load an HTML page consisting of one <input> element and three | 318 // Load an HTML page consisting of one <input> element and three |
327 // contentediable <div> elements. | 319 // contentediable <div> elements. |
328 // The <input> element is used for sending keyboard events, and the <div> | 320 // The <input> element is used for sending keyboard events, and the <div> |
329 // elements are used for writing DOM events in the following format: | 321 // elements are used for writing DOM events in the following format: |
330 // "<keyCode>,<shiftKey>,<controlKey>,<altKey>,<metaKey>". | 322 // "<keyCode>,<shiftKey>,<controlKey>,<altKey>". |
| 323 // TODO(hbono): <http://crbug.com/2215> Our WebKit port set |ev.metaKey| to |
| 324 // true when pressing an alt key, i.e. the |ev.metaKey| value is not |
| 325 // trustworthy. We will check the |ev.metaKey| value when this issue is fixed. |
331 view_->set_delay_seconds_for_form_state_sync(0); | 326 view_->set_delay_seconds_for_form_state_sync(0); |
332 LoadHTML("<html>" | 327 LoadHTML("<html>" |
333 "<head>" | 328 "<head>" |
334 "<title></title>" | 329 "<title></title>" |
335 "<script type='text/javascript' language='javascript'>" | 330 "<script type='text/javascript' language='javascript'>" |
336 "function OnKeyEvent(ev) {" | 331 "function OnKeyEvent(ev) {" |
337 " var result = document.getElementById(ev.type);" | 332 " var result = document.getElementById(ev.type);" |
338 " result.innerText =" | 333 " result.innerText =" |
339 " (ev.which || ev.keyCode) + ',' +" | 334 " (ev.which || ev.keyCode) + ',' +" |
340 " ev.shiftKey + ',' +" | 335 " ev.shiftKey + ',' +" |
341 " ev.ctrlKey + ',' +" | 336 " ev.ctrlKey + ',' +" |
342 " ev.altKey + ',' +" | 337 " ev.altKey;" |
343 " ev.metaKey;" | |
344 " return true;" | 338 " return true;" |
345 "}" | 339 "}" |
346 "</script>" | 340 "</script>" |
347 "</head>" | 341 "</head>" |
348 "<body>" | 342 "<body>" |
349 "<input id='test' type='text'" | 343 "<input id='test' type='text'" |
350 " onkeydown='return OnKeyEvent(event);'" | 344 " onkeydown='return OnKeyEvent(event);'" |
351 " onkeypress='return OnKeyEvent(event);'" | 345 " onkeypress='return OnKeyEvent(event);'" |
352 " onkeyup='return OnKeyEvent(event);'>" | 346 " onkeyup='return OnKeyEvent(event);'>" |
353 "</input>" | 347 "</input>" |
354 "<div id='keydown' contenteditable='true'>" | 348 "<div id='keydown' contenteditable='true'>" |
355 "</div>" | 349 "</div>" |
356 "<div id='keypress' contenteditable='true'>" | 350 "<div id='keypress' contenteditable='true'>" |
357 "</div>" | 351 "</div>" |
358 "<div id='keyup' contenteditable='true'>" | 352 "<div id='keyup' contenteditable='true'>" |
359 "</div>" | 353 "</div>" |
360 "</body>" | 354 "</body>" |
361 "</html>"); | 355 "</html>"); |
362 ExecuteJavaScript("document.getElementById('test').focus();"); | 356 ExecuteJavaScript("document.getElementById('test').focus();"); |
363 render_thread_.sink().ClearMessages(); | 357 render_thread_.sink().ClearMessages(); |
364 | 358 |
365 // Language IDs used in this test. | 359 static const MockKeyboard::Layout kLayouts[] = { |
366 // This test directly loads keyboard-layout drivers and use them for | 360 MockKeyboard::LAYOUT_ARABIC, |
367 // emulating non-US keyboard layouts. | 361 MockKeyboard::LAYOUT_CANADIAN_FRENCH, |
368 static const wchar_t* kLanguageIDs[] = { | 362 MockKeyboard::LAYOUT_FRENCH, |
369 L"00000401", // Arabic | 363 MockKeyboard::LAYOUT_HEBREW, |
370 L"00000409", // United States | 364 MockKeyboard::LAYOUT_RUSSIAN, |
371 L"0000040c", // French | 365 MockKeyboard::LAYOUT_UNITED_STATES, |
372 L"0000040d", // Hebrew | |
373 L"00001009", // Canadian French | |
374 }; | 366 }; |
375 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLanguageIDs); ++i) { | |
376 // Load a keyboard-layout driver. | |
377 HKL handle = LoadKeyboardLayout(kLanguageIDs[i], KLF_ACTIVATE); | |
378 EXPECT_TRUE(handle != NULL); | |
379 | 367 |
380 // For each key code, we send two keyboard events: one when we only press | 368 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLayouts); ++i) { |
381 // the key, and one when we press the key and a shift key. | 369 // For each key code, we send three keyboard events. |
382 for (int modifiers = 0; modifiers < 2; ++modifiers) { | 370 // * we press only the key; |
| 371 // * we press the key and a left-shift key, and; |
| 372 // * we press the key and a right-alt (AltGr) key. |
| 373 // For each modifiers, we need a string used for formatting its expected |
| 374 // result. (See the above comment for its format.) |
| 375 static const struct { |
| 376 MockKeyboard::Modifiers modifiers; |
| 377 const wchar_t* expected_result; |
| 378 } kModifierData[] = { |
| 379 {MockKeyboard::NONE, L"false,false,false"}, |
| 380 {MockKeyboard::LEFT_SHIFT, L"true,false,false"}, |
| 381 {MockKeyboard::RIGHT_ALT, L"false,false,true"}, |
| 382 }; |
| 383 |
| 384 MockKeyboard::Layout layout = kLayouts[i]; |
| 385 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kModifierData); ++j) { |
383 // Virtual key codes used for this test. | 386 // Virtual key codes used for this test. |
384 static const int kKeyCodes[] = { | 387 static const int kKeyCodes[] = { |
385 '0', '1', '2', '3', '4', '5', '6', '7', | 388 '0', '1', '2', '3', '4', '5', '6', '7', |
386 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', | 389 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', |
387 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', | 390 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', |
388 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', | 391 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', |
389 'W', 'X', 'Y', 'Z', | 392 'W', 'X', 'Y', 'Z', |
390 VK_OEM_1, | 393 VK_OEM_1, |
391 VK_OEM_PLUS, | 394 VK_OEM_PLUS, |
392 VK_OEM_COMMA, | 395 VK_OEM_COMMA, |
393 VK_OEM_MINUS, | 396 VK_OEM_MINUS, |
394 VK_OEM_PERIOD, | 397 VK_OEM_PERIOD, |
395 VK_OEM_2, | 398 VK_OEM_2, |
396 VK_OEM_3, | 399 VK_OEM_3, |
397 VK_OEM_4, | 400 VK_OEM_4, |
398 VK_OEM_5, | 401 VK_OEM_5, |
399 VK_OEM_6, | 402 VK_OEM_6, |
400 VK_OEM_7, | 403 VK_OEM_7, |
401 VK_OEM_8, | 404 VK_OEM_8, |
402 }; | 405 }; |
403 | 406 |
404 // Over-write the keyboard status with our modifier-key status. | 407 MockKeyboard::Modifiers modifiers = kModifierData[j].modifiers; |
405 // WebInputEventFactory::keyboardEvent() uses GetKeyState() to retrive | 408 for (size_t k = 0; k <= ARRAYSIZE_UNSAFE(kKeyCodes); ++k) { |
406 // modifier-key status. So, we update the modifier-key status with this | 409 // Send a keyboard event to the RenderView object. |
407 // SetKeyboardState() call before creating NativeWebKeyboardEvent | 410 // We should test a keyboard event only when the given keyboard-layout |
408 // instances. | 411 // driver is installed in a PC and the driver can assign a Unicode |
409 BYTE key_states[256]; | 412 // charcter for the given tuple (key-code and modifiers). |
410 memset(&key_states[0], 0, sizeof(key_states)); | 413 int key_code = kKeyCodes[k]; |
411 key_states[VK_SHIFT] = (modifiers & 0x01) ? 0x80 : 0; | 414 std::wstring char_code; |
412 SetKeyboardState(&key_states[0]); | 415 if (SendKeyEvent(layout, key_code, modifiers, &char_code) < 0) |
413 | |
414 for (size_t j = 0; j <= ARRAYSIZE_UNSAFE(kKeyCodes); ++j) { | |
415 // Retrieve the Unicode character composed from the virtual-key code | |
416 // and our modifier-key status from the keyboard-layout driver. | |
417 // This character is used for creating a WM_CHAR message and an | |
418 // expected result. | |
419 int key_code = kKeyCodes[j]; | |
420 wchar_t codes[4]; | |
421 int length = ToUnicodeEx(key_code, MapVirtualKey(key_code, 0), | |
422 &key_states[0], &codes[0], | |
423 ARRAYSIZE_UNSAFE(codes), 0, handle); | |
424 if (length != 1) | |
425 continue; | 416 continue; |
426 | 417 |
427 // Create IPC messages from Windows messages and send them to our | |
428 // back-end. | |
429 // A keyboard event of Windows consists of three Windows messages: | |
430 // WM_KEYDOWN, WM_CHAR, and WM_KEYUP. | |
431 // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand, | |
432 // WM_CHAR sends a composed Unicode character. | |
433 NativeWebKeyboardEvent keydown_event(NULL, WM_KEYDOWN, key_code, 0); | |
434 scoped_ptr<IPC::Message> keydown_message( | |
435 new ViewMsg_HandleInputEvent(0)); | |
436 keydown_message->WriteData( | |
437 reinterpret_cast<const char*>(&keydown_event), | |
438 sizeof(WebKit::WebKeyboardEvent)); | |
439 view_->OnHandleInputEvent(*keydown_message); | |
440 | |
441 NativeWebKeyboardEvent char_event(NULL, WM_CHAR, codes[0], 0); | |
442 scoped_ptr<IPC::Message> char_message(new ViewMsg_HandleInputEvent(0)); | |
443 char_message->WriteData(reinterpret_cast<const char*>(&char_event), | |
444 sizeof(WebKit::WebKeyboardEvent)); | |
445 view_->OnHandleInputEvent(*char_message); | |
446 | |
447 NativeWebKeyboardEvent keyup_event(NULL, WM_KEYUP, key_code, 0); | |
448 scoped_ptr<IPC::Message> keyup_message(new ViewMsg_HandleInputEvent(0)); | |
449 keyup_message->WriteData(reinterpret_cast<const char*>(&keyup_event), | |
450 sizeof(WebKit::WebKeyboardEvent)); | |
451 view_->OnHandleInputEvent(*keyup_message); | |
452 | |
453 // Create an expected result from the virtual-key code, the character | 418 // Create an expected result from the virtual-key code, the character |
454 // code, and the modifier-key status. | 419 // code, and the modifier-key status. |
455 // We format a string that emulates a DOM-event string produced hy | 420 // We format a string that emulates a DOM-event string produced hy |
456 // our JavaScript function. (See the above comment for the format.) | 421 // our JavaScript function. (See the above comment for the format.) |
457 static const wchar_t* kModifiers[] = { | |
458 L"false,false,false,false", | |
459 L"true,false,false,false", | |
460 }; | |
461 static wchar_t expected_result[1024]; | 422 static wchar_t expected_result[1024]; |
462 wsprintf(&expected_result[0], | 423 wsprintf(&expected_result[0], |
463 L"\x000A" // texts in the <input> element | 424 L"\x000A" // texts in the <input> element |
464 L"%d,%s\x000A" // texts in the first <div> element | 425 L"%d,%s\x000A" // texts in the first <div> element |
465 L"%d,%s\x000A" // texts in the second <div> element | 426 L"%d,%s\x000A" // texts in the second <div> element |
466 L"%d,%s", // texts in the third <div> element | 427 L"%d,%s", // texts in the third <div> element |
467 key_code, kModifiers[modifiers], | 428 key_code, kModifierData[j].expected_result, |
468 codes[0], kModifiers[modifiers], | 429 char_code[0], kModifierData[j].expected_result, |
469 key_code, kModifiers[modifiers]); | 430 key_code, kModifierData[j].expected_result); |
470 | 431 |
471 // Retrieve the text in the test page and compare it with the expected | 432 // Retrieve the text in the test page and compare it with the expected |
472 // text created from a virtual-key code, a character code, and the | 433 // text created from a virtual-key code, a character code, and the |
473 // modifier-key status. | 434 // modifier-key status. |
474 const int kMaxOutputCharacters = 1024; | 435 const int kMaxOutputCharacters = 1024; |
475 std::wstring output; | 436 std::wstring output; |
476 GetMainFrame()->GetContentAsPlainText(kMaxOutputCharacters, &output); | 437 GetMainFrame()->GetContentAsPlainText(kMaxOutputCharacters, &output); |
477 | 438 |
478 EXPECT_EQ(expected_result, output); | 439 EXPECT_EQ(expected_result, output); |
479 } | 440 } |
480 } | 441 } |
481 | |
482 UnloadKeyboardLayout(handle); | |
483 } | 442 } |
484 | |
485 // Restore the keyboard layout and status. | |
486 SetKeyboardState(&original_key_states[0]); | |
487 ActivateKeyboardLayout(original_layout, KLF_RESET); | |
488 #else | 443 #else |
489 NOTIMPLEMENTED(); | 444 NOTIMPLEMENTED(); |
490 #endif | 445 #endif |
| 446 } |
| 447 |
| 448 // Test that our EditorClientImpl class can insert characters when we send |
| 449 // keyboard events through the RenderWidget::OnHandleInputEvent() function. |
| 450 // This test is for preventing regressions caused only when we use non-US |
| 451 // keyboards, such as Issue 10846. |
| 452 TEST_F(RenderViewTest, InsertCharacters) { |
| 453 #if defined(OS_WIN) |
| 454 static const struct { |
| 455 MockKeyboard::Layout layout; |
| 456 const wchar_t* expected_result; |
| 457 } kLayouts[] = { |
| 458 #if 0 |
| 459 // Disabled these keyboard layouts because buildbots do not have their |
| 460 // keyboard-layout drivers installed. |
| 461 {MockKeyboard::LAYOUT_ARABIC, |
| 462 L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037" |
| 463 L"\x0038\x0039\x0634\x0624\x064a\x062b\x0628\x0644" |
| 464 L"\x0627\x0647\x062a\x0646\x0645\x0629\x0649\x062e" |
| 465 L"\x062d\x0636\x0642\x0633\x0641\x0639\x0631\x0635" |
| 466 L"\x0621\x063a\x0626\x0643\x003d\x0648\x002d\x0632" |
| 467 L"\x0638\x0630\x062c\x005c\x062f\x0637\x0028\x0021" |
| 468 L"\x0040\x0023\x0024\x0025\x005e\x0026\x002a\x0029" |
| 469 L"\x0650\x007d\x005d\x064f\x005b\x0623\x00f7\x0640" |
| 470 L"\x060c\x002f\x2019\x0622\x00d7\x061b\x064e\x064c" |
| 471 L"\x064d\x2018\x007b\x064b\x0652\x0625\x007e\x003a" |
| 472 L"\x002b\x002c\x005f\x002e\x061f\x0651\x003c\x007c" |
| 473 L"\x003e\x0022\x0030\x0031\x0032\x0033\x0034\x0035" |
| 474 L"\x0036\x0037\x0038\x0039\x0634\x0624\x064a\x062b" |
| 475 L"\x0628\x0644\x0627\x0647\x062a\x0646\x0645\x0629" |
| 476 L"\x0649\x062e\x062d\x0636\x0642\x0633\x0641\x0639" |
| 477 L"\x0631\x0635\x0621\x063a\x0626\x0643\x003d\x0648" |
| 478 L"\x002d\x0632\x0638\x0630\x062c\x005c\x062f\x0637" |
| 479 }, |
| 480 {MockKeyboard::LAYOUT_HEBREW, |
| 481 L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037" |
| 482 L"\x0038\x0039\x05e9\x05e0\x05d1\x05d2\x05e7\x05db" |
| 483 L"\x05e2\x05d9\x05df\x05d7\x05dc\x05da\x05e6\x05de" |
| 484 L"\x05dd\x05e4\x002f\x05e8\x05d3\x05d0\x05d5\x05d4" |
| 485 L"\x0027\x05e1\x05d8\x05d6\x05e3\x003d\x05ea\x002d" |
| 486 L"\x05e5\x002e\x003b\x005d\x005c\x005b\x002c\x0028" |
| 487 L"\x0021\x0040\x0023\x0024\x0025\x005e\x0026\x002a" |
| 488 L"\x0029\x0041\x0042\x0043\x0044\x0045\x0046\x0047" |
| 489 L"\x0048\x0049\x004a\x004b\x004c\x004d\x004e\x004f" |
| 490 L"\x0050\x0051\x0052\x0053\x0054\x0055\x0056\x0057" |
| 491 L"\x0058\x0059\x005a\x003a\x002b\x003e\x005f\x003c" |
| 492 L"\x003f\x007e\x007d\x007c\x007b\x0022\x0030\x0031" |
| 493 L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039" |
| 494 L"\x05e9\x05e0\x05d1\x05d2\x05e7\x05db\x05e2\x05d9" |
| 495 L"\x05df\x05d7\x05dc\x05da\x05e6\x05de\x05dd\x05e4" |
| 496 L"\x002f\x05e8\x05d3\x05d0\x05d5\x05d4\x0027\x05e1" |
| 497 L"\x05d8\x05d6\x05e3\x003d\x05ea\x002d\x05e5\x002e" |
| 498 L"\x003b\x005d\x005c\x005b\x002c" |
| 499 }, |
| 500 #endif |
| 501 {MockKeyboard::LAYOUT_CANADIAN_FRENCH, |
| 502 L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037" |
| 503 L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066" |
| 504 L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e" |
| 505 L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076" |
| 506 L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d" |
| 507 L"\x002e\x00e9\x003c\x0029\x0021\x0022\x002f\x0024" |
| 508 L"\x0025\x003f\x0026\x002a\x0028\x0041\x0042\x0043" |
| 509 L"\x0044\x0045\x0046\x0047\x0048\x0049\x004a\x004b" |
| 510 L"\x004c\x004d\x004e\x004f\x0050\x0051\x0052\x0053" |
| 511 L"\x0054\x0055\x0056\x0057\x0058\x0059\x005a\x003a" |
| 512 L"\x002b\x0027\x005f\x002e\x00c9\x003e\x0030\x0031" |
| 513 L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039" |
| 514 L"\x0061\x0062\x0063\x0064\x0065\x0066\x0067\x0068" |
| 515 L"\x0069\x006a\x006b\x006c\x006d\x006e\x006f\x0070" |
| 516 L"\x0071\x0072\x0073\x0074\x0075\x0076\x0077\x0078" |
| 517 L"\x0079\x007a\x003b\x003d\x002c\x002d\x002e\x00e9" |
| 518 L"\x003c" |
| 519 }, |
| 520 {MockKeyboard::LAYOUT_FRENCH, |
| 521 L"\x00e0\x0026\x00e9\x0022\x0027\x0028\x002d\x00e8" |
| 522 L"\x005f\x00e7\x0061\x0062\x0063\x0064\x0065\x0066" |
| 523 L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e" |
| 524 L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076" |
| 525 L"\x0077\x0078\x0079\x007a\x0024\x003d\x002c\x003b" |
| 526 L"\x003a\x00f9\x0029\x002a\x0021\x0030\x0031\x0032" |
| 527 L"\x0033\x0034\x0035\x0036\x0037\x0038\x0039\x0041" |
| 528 L"\x0042\x0043\x0044\x0045\x0046\x0047\x0048\x0049" |
| 529 L"\x004a\x004b\x004c\x004d\x004e\x004f\x0050\x0051" |
| 530 L"\x0052\x0053\x0054\x0055\x0056\x0057\x0058\x0059" |
| 531 L"\x005a\x00a3\x002b\x003f\x002e\x002f\x0025\x00b0" |
| 532 L"\x00b5\x00e0\x0026\x00e9\x0022\x0027\x0028\x002d" |
| 533 L"\x00e8\x005f\x00e7\x0061\x0062\x0063\x0064\x0065" |
| 534 L"\x0066\x0067\x0068\x0069\x006a\x006b\x006c\x006d" |
| 535 L"\x006e\x006f\x0070\x0071\x0072\x0073\x0074\x0075" |
| 536 L"\x0076\x0077\x0078\x0079\x007a\x0024\x003d\x002c" |
| 537 L"\x003b\x003a\x00f9\x0029\x002a\x0021" |
| 538 }, |
| 539 {MockKeyboard::LAYOUT_RUSSIAN, |
| 540 L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037" |
| 541 L"\x0038\x0039\x0444\x0438\x0441\x0432\x0443\x0430" |
| 542 L"\x043f\x0440\x0448\x043e\x043b\x0434\x044c\x0442" |
| 543 L"\x0449\x0437\x0439\x043a\x044b\x0435\x0433\x043c" |
| 544 L"\x0446\x0447\x043d\x044f\x0436\x003d\x0431\x002d" |
| 545 L"\x044e\x002e\x0451\x0445\x005c\x044a\x044d\x0029" |
| 546 L"\x0021\x0022\x2116\x003b\x0025\x003a\x003f\x002a" |
| 547 L"\x0028\x0424\x0418\x0421\x0412\x0423\x0410\x041f" |
| 548 L"\x0420\x0428\x041e\x041b\x0414\x042c\x0422\x0429" |
| 549 L"\x0417\x0419\x041a\x042b\x0415\x0413\x041c\x0426" |
| 550 L"\x0427\x041d\x042f\x0416\x002b\x0411\x005f\x042e" |
| 551 L"\x002c\x0401\x0425\x002f\x042a\x042d\x0030\x0031" |
| 552 L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039" |
| 553 L"\x0444\x0438\x0441\x0432\x0443\x0430\x043f\x0440" |
| 554 L"\x0448\x043e\x043b\x0434\x044c\x0442\x0449\x0437" |
| 555 L"\x0439\x043a\x044b\x0435\x0433\x043c\x0446\x0447" |
| 556 L"\x043d\x044f\x0436\x003d\x0431\x002d\x044e\x002e" |
| 557 L"\x0451\x0445\x005c\x044a\x044d" |
| 558 }, |
| 559 {MockKeyboard::LAYOUT_UNITED_STATES, |
| 560 L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037" |
| 561 L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066" |
| 562 L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e" |
| 563 L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076" |
| 564 L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d" |
| 565 L"\x002e\x002f\x0060\x005b\x005c\x005d\x0027\x0029" |
| 566 L"\x0021\x0040\x0023\x0024\x0025\x005e\x0026\x002a" |
| 567 L"\x0028\x0041\x0042\x0043\x0044\x0045\x0046\x0047" |
| 568 L"\x0048\x0049\x004a\x004b\x004c\x004d\x004e\x004f" |
| 569 L"\x0050\x0051\x0052\x0053\x0054\x0055\x0056\x0057" |
| 570 L"\x0058\x0059\x005a\x003a\x002b\x003c\x005f\x003e" |
| 571 L"\x003f\x007e\x007b\x007c\x007d\x0022\x0030\x0031" |
| 572 L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039" |
| 573 L"\x0061\x0062\x0063\x0064\x0065\x0066\x0067\x0068" |
| 574 L"\x0069\x006a\x006b\x006c\x006d\x006e\x006f\x0070" |
| 575 L"\x0071\x0072\x0073\x0074\x0075\x0076\x0077\x0078" |
| 576 L"\x0079\x007a\x003b\x003d\x002c\x002d\x002e\x002f" |
| 577 L"\x0060\x005b\x005c\x005d\x0027" |
| 578 }, |
| 579 }; |
| 580 |
| 581 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLayouts); ++i) { |
| 582 // Load an HTML page consisting of one <div> element. |
| 583 // This <div> element is used by the EditorClientImpl class to insert |
| 584 // characters received through the RenderWidget::OnHandleInputEvent() |
| 585 // function. |
| 586 view_->set_delay_seconds_for_form_state_sync(0); |
| 587 LoadHTML("<html>" |
| 588 "<head>" |
| 589 "<title></title>" |
| 590 "</head>" |
| 591 "<body>" |
| 592 "<div id='test' contenteditable='true'>" |
| 593 "</div>" |
| 594 "</body>" |
| 595 "</html>"); |
| 596 ExecuteJavaScript("document.getElementById('test').focus();"); |
| 597 render_thread_.sink().ClearMessages(); |
| 598 |
| 599 // For each key code, we send three keyboard events. |
| 600 // * Pressing only the key; |
| 601 // * Pressing the key and a left-shift key, and; |
| 602 // * Pressing the key and a right-alt (AltGr) key. |
| 603 static const MockKeyboard::Modifiers kModifiers[] = { |
| 604 MockKeyboard::NONE, |
| 605 MockKeyboard::LEFT_SHIFT, |
| 606 MockKeyboard::RIGHT_ALT, |
| 607 }; |
| 608 |
| 609 MockKeyboard::Layout layout = kLayouts[i].layout; |
| 610 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kModifiers); ++j) { |
| 611 // Virtual key codes used for this test. |
| 612 static const int kKeyCodes[] = { |
| 613 '0', '1', '2', '3', '4', '5', '6', '7', |
| 614 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', |
| 615 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', |
| 616 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', |
| 617 'W', 'X', 'Y', 'Z', |
| 618 VK_OEM_1, |
| 619 VK_OEM_PLUS, |
| 620 VK_OEM_COMMA, |
| 621 VK_OEM_MINUS, |
| 622 VK_OEM_PERIOD, |
| 623 VK_OEM_2, |
| 624 VK_OEM_3, |
| 625 VK_OEM_4, |
| 626 VK_OEM_5, |
| 627 VK_OEM_6, |
| 628 VK_OEM_7, |
| 629 VK_OEM_8, |
| 630 }; |
| 631 |
| 632 MockKeyboard::Modifiers modifiers = kModifiers[j]; |
| 633 for (size_t k = 0; k <= ARRAYSIZE_UNSAFE(kKeyCodes); ++k) { |
| 634 // Send a keyboard event to the RenderView object. |
| 635 // We should test a keyboard event only when the given keyboard-layout |
| 636 // driver is installed in a PC and the driver can assign a Unicode |
| 637 // charcter for the given tuple (layout, key-code, and modifiers). |
| 638 int key_code = kKeyCodes[k]; |
| 639 std::wstring char_code; |
| 640 if (SendKeyEvent(layout, key_code, modifiers, &char_code) < 0) |
| 641 continue; |
| 642 } |
| 643 } |
| 644 |
| 645 // Retrieve the text in the test page and compare it with the expected |
| 646 // text created from a virtual-key code, a character code, and the |
| 647 // modifier-key status. |
| 648 const int kMaxOutputCharacters = 4096; |
| 649 std::wstring output; |
| 650 GetMainFrame()->GetContentAsPlainText(kMaxOutputCharacters, &output); |
| 651 EXPECT_EQ(kLayouts[i].expected_result, output); |
| 652 } |
| 653 #else |
| 654 NOTIMPLEMENTED(); |
| 655 #endif |
491 } | 656 } |
OLD | NEW |