blob: d025ca8647ffb7a6b6532e341005f7aa29f8d445 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/render_view_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/common/webpreferences.h"
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h> // for the kVK_* constants.
namespace content {
NSEvent* CmdDeadKeyEvent(NSEventType type, unsigned short code) {
UniChar uniChar = 0;
switch(code) {
case kVK_UpArrow:
uniChar = NSUpArrowFunctionKey;
break;
case kVK_DownArrow:
uniChar = NSDownArrowFunctionKey;
break;
default:
CHECK(false);
}
NSString* s = [NSString stringWithFormat:@"%C", uniChar];
return [NSEvent keyEventWithType:type
location:NSZeroPoint
modifierFlags:NSCommandKeyMask
timestamp:0.0
windowNumber:0
context:nil
characters:s
charactersIgnoringModifiers:s
isARepeat:NO
keyCode:code];
}
// Test that cmd-up/down scrolls the page exactly if it is not intercepted by
// javascript.
TEST_F(RenderViewTest, MacTestCmdUp) {
// Some preprocessor trickery so that we can have literal html in our source,
// makes it easier to copy html to and from an html file for testing (the
// preprocessor will remove the newlines at the line ends, turning this into
// a single long line).
#define HTML(s) #s
const char* kRawHtml = HTML(
<html>
<head><title></title>
<script type='text/javascript' language='javascript'>
function OnKeyEvent(ev) {
var result = document.getElementById(ev.type);
result.innerText = (ev.which || ev.keyCode) + ',' +
ev.shiftKey + ',' +
ev.ctrlKey + ',' +
ev.metaKey + ',' +
ev.altKey;
return %s; /* Replace with "return true;" when testing in an html file. */
}
function OnScroll(ev) {
var result = document.getElementById("scroll");
result.innerText = window.pageYOffset;
return true;
}
</script>
<style type="text/css">
p { border-bottom:5000px solid black; } /* enforce vertical scroll bar */
</style>
</head>
<body
onscroll='return OnScroll(event);'
onkeydown='return OnKeyEvent(event);'>
<div id='keydown' contenteditable='true'> </div>
<div id='scroll' contenteditable='true'> </div>
<p>p1
<p>p2
</body>
</html>
);
#undef HTML
WebPreferences prefs;
prefs.enable_scroll_animator = false;
RenderViewImpl* view = static_cast<RenderViewImpl*>(view_);
view->OnUpdateWebPreferences(prefs);
const int kMaxOutputCharacters = 1024;
string16 output;
char htmlBuffer[2048];
NSEvent* arrowDownKeyDown = CmdDeadKeyEvent(NSKeyDown, kVK_DownArrow);
NSEvent* arrowUpKeyDown = CmdDeadKeyEvent(NSKeyDown, kVK_UpArrow);
// First test when javascript does not eat keypresses -- should scroll.
sprintf(htmlBuffer, kRawHtml, "true");
view->set_send_content_state_immediately(true);
LoadHTML(htmlBuffer);
render_thread_->sink().ClearMessages();
const char* kArrowDownScrollDown =
"40,false,false,true,false\n10128\np1\n\np2";
view->OnSetEditCommandsForNextKeyEvent(
EditCommands(1, EditCommand("moveToEndOfDocument", "")));
SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
ProcessPendingMessages();
output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
EXPECT_EQ(kArrowDownScrollDown, UTF16ToASCII(output));
const char* kArrowUpScrollUp =
"38,false,false,true,false\n0\np1\n\np2";
view->OnSetEditCommandsForNextKeyEvent(
EditCommands(1, EditCommand("moveToBeginningOfDocument", "")));
SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
ProcessPendingMessages();
output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
EXPECT_EQ(kArrowUpScrollUp, UTF16ToASCII(output));
// Now let javascript eat the key events -- no scrolling should happen
sprintf(htmlBuffer, kRawHtml, "false");
view->set_send_content_state_immediately(true);
LoadHTML(htmlBuffer);
render_thread_->sink().ClearMessages();
const char* kArrowDownNoScroll =
"40,false,false,true,false\np1\n\np2";
view->OnSetEditCommandsForNextKeyEvent(
EditCommands(1, EditCommand("moveToEndOfDocument", "")));
SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown));
ProcessPendingMessages();
output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
EXPECT_EQ(kArrowDownNoScroll, UTF16ToASCII(output));
const char* kArrowUpNoScroll =
"38,false,false,true,false\np1\n\np2";
view->OnSetEditCommandsForNextKeyEvent(
EditCommands(1, EditCommand("moveToBeginningOfDocument", "")));
SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown));
ProcessPendingMessages();
output = GetMainFrame()->contentAsText(kMaxOutputCharacters);
EXPECT_EQ(kArrowUpNoScroll, UTF16ToASCII(output));
}
} // namespace content