1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/string16.h"
6 #include "base/strings/string_util.h"
7 #include "content/public/browser/native_web_keyboard_event.h"
8 #include "content/public/test/render_view_test.h"
9 #include "content/renderer/render_view_impl.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "webkit/common/webpreferences.h"
13 #include <Cocoa/Cocoa.h>
14 #include <Carbon/Carbon.h> // for the kVK_* constants.
18 NSEvent* CmdDeadKeyEvent(NSEventType type, unsigned short code) {
22 uniChar = NSUpArrowFunctionKey;
25 uniChar = NSDownArrowFunctionKey;
30 NSString* s = [NSString stringWithFormat:@"%C", uniChar];
32 return [NSEvent keyEventWithType:type
33 location:NSMakePoint(0, 0)
34 modifierFlags:NSCommandKeyMask
39 charactersIgnoringModifiers:s
44 // Test that cmd-up/down scrolls the page exactly if it is not intercepted by
46 TEST_F(RenderViewTest, MacTestCmdUp) {
47 // Some preprocessor trickery so that we can have literal html in our source,
48 // makes it easier to copy html to and from an html file for testing (the
49 // preprocessor will remove the newlines at the line ends, turning this into
50 // a single long line).
52 const char* kRawHtml = HTML(
55 <script type='text/javascript' language='javascript'>
56 function OnKeyEvent(ev) {
57 var result = document.getElementById(ev.type);
58 result.innerText = (ev.which || ev.keyCode) + ',' +
63 return %s; /* Replace with "return true;" when testing in an html file. */
65 function OnScroll(ev) {
66 var result = document.getElementById("scroll");
67 result.innerText = window.pageYOffset;
71 <style type="text/css">
72 p { border-bottom:5000px solid black; } /* enforce vertical scroll bar */
76 onscroll='return OnScroll(event);'
77 onkeydown='return OnKeyEvent(event);'>
78 <div id='keydown' contenteditable='true'> </div>
79 <div id='scroll' contenteditable='true'> </div>
88 prefs.enable_scroll_animator = false;
90 RenderViewImpl* view = static_cast<RenderViewImpl*>(view_);
91 view->OnUpdateWebPreferences(prefs);
93 const int kMaxOutputCharacters = 1024;
95 char htmlBuffer[2048];
97 NSEvent* arrowDownKeyDown = CmdDeadKeyEvent(NSKeyDown, kVK_DownArrow);
98 NSEvent* arrowUpKeyDown = CmdDeadKeyEvent(NSKeyDown, kVK_UpArrow);
100 // First test when javascript does not eat keypresses -- should scroll.
101 sprintf(htmlBuffer, kRawHtml, "true");
102 view->set_send_content_state_immediately(true);
103 LoadHTML(htmlBuffer);
104 render_thread_->sink().ClearMessages();
106 const char* kArrowDownScrollDown =
107 "40,false,false,true,false\n10128\np1\n\np2";
108 view->OnSetEditCommandsForNextKeyEvent(
109 EditCommands(1, EditCommand("moveToEndOfDocument", "")));
110 SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
111 ProcessPendingMessages();
112 output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
113 EXPECT_EQ(kArrowDownScrollDown, UTF16ToASCII(output));
115 const char* kArrowUpScrollUp =
116 "38,false,false,true,false\n0\np1\n\np2";
117 view->OnSetEditCommandsForNextKeyEvent(
118 EditCommands(1, EditCommand("moveToBeginningOfDocument", "")));
119 SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
120 ProcessPendingMessages();
121 output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
122 EXPECT_EQ(kArrowUpScrollUp, UTF16ToASCII(output));
125 // Now let javascript eat the key events -- no scrolling should happen
126 sprintf(htmlBuffer, kRawHtml, "false");
127 view->set_send_content_state_immediately(true);
128 LoadHTML(htmlBuffer);
129 render_thread_->sink().ClearMessages();
131 const char* kArrowDownNoScroll =
132 "40,false,false,true,false\np1\n\np2";
133 view->OnSetEditCommandsForNextKeyEvent(
134 EditCommands(1, EditCommand("moveToEndOfDocument", "")));
135 SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
136 ProcessPendingMessages();
137 output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
138 EXPECT_EQ(kArrowDownNoScroll, UTF16ToASCII(output));
140 const char* kArrowUpNoScroll =
141 "38,false,false,true,false\np1\n\np2";
142 view->OnSetEditCommandsForNextKeyEvent(
143 EditCommands(1, EditCommand("moveToBeginningOfDocument", "")));
144 SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
145 ProcessPendingMessages();
146 output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
147 EXPECT_EQ(kArrowUpNoScroll, UTF16ToASCII(output));
150 } // namespace content