summaryrefslogtreecommitdiffstats
path: root/webkit/tools/test_shell
diff options
context:
space:
mode:
authoramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-15 19:54:42 +0000
committeramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-15 19:54:42 +0000
commitfaf19bbf27a42842d4d2bc9a1e689dfcac3bd675 (patch)
treeffd7eb58cac407e6f66595f5201fb4b394260d17 /webkit/tools/test_shell
parent8dd3dddd1cd80d28cc8237a5dbcf9f60e3c24566 (diff)
downloadchromium_src-faf19bbf27a42842d4d2bc9a1e689dfcac3bd675.zip
chromium_src-faf19bbf27a42842d4d2bc9a1e689dfcac3bd675.tar.gz
chromium_src-faf19bbf27a42842d4d2bc9a1e689dfcac3bd675.tar.bz2
Add test shell WebView and WebWidget host classes. This are stopgaps and
are subject to change as the rest of the rendering and event handling paths come together. Review URL: http://codereview.chromium.org/3062 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2230 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/test_shell')
-rw-r--r--webkit/tools/test_shell/mac/Info.plist2
-rw-r--r--webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj6
-rw-r--r--webkit/tools/test_shell/mac/test_webview_delegate.mm838
-rw-r--r--webkit/tools/test_shell/mac/webview_host.mm42
-rw-r--r--webkit/tools/test_shell/mac/webwidget_host.mm260
5 files changed, 1144 insertions, 4 deletions
diff --git a/webkit/tools/test_shell/mac/Info.plist b/webkit/tools/test_shell/mac/Info.plist
index d9a2cdb..7747ba0 100644
--- a/webkit/tools/test_shell/mac/Info.plist
+++ b/webkit/tools/test_shell/mac/Info.plist
@@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
- <string>com.yourcompany.TestShell</string>
+ <string>com.google.TestShell</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
diff --git a/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj b/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj
index e72b12d..b5f988b 100644
--- a/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj
+++ b/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj
@@ -347,11 +347,11 @@
AB8A78520DC553A8005C27B8 /* event_sending_controller.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event_sending_controller.cc; sourceTree = "<group>"; };
AB8A78540DC553BC005C27B8 /* node_leak_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_leak_test.cc; sourceTree = "<group>"; };
AB8A78560DC553C7005C27B8 /* test_shell_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_shell_test.cc; sourceTree = "<group>"; };
- AB8A78580DC553D7005C27B8 /* test_webview_delegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = test_webview_delegate.mm; sourceTree = "<group>"; };
+ AB8A78580DC553D7005C27B8 /* test_webview_delegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = test_webview_delegate.mm; path = mac/test_webview_delegate.mm; sourceTree = "<group>"; };
AB8A78590DC553D7005C27B8 /* test_webview_delegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_webview_delegate.h; sourceTree = "<group>"; };
AB8A785B0DC553E4005C27B8 /* text_input_controller.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_input_controller.cc; sourceTree = "<group>"; };
AB8A785C0DC553E4005C27B8 /* text_input_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_input_controller.h; sourceTree = "<group>"; };
- AB8A785E0DC553EE005C27B8 /* webview_host.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = webview_host.mm; sourceTree = "<group>"; };
+ AB8A785E0DC553EE005C27B8 /* webview_host.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = webview_host.mm; path = mac/webview_host.mm; sourceTree = "<group>"; };
AB8A78600DC553EE005C27B8 /* webview_host.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = webview_host.h; sourceTree = "<group>"; };
AB8A786E0DC5544D005C27B8 /* test_shell_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_shell_test.h; sourceTree = "<group>"; };
ABA65EFD0DD50BFF003A4FC8 /* test_shell_webview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_shell_webview.h; sourceTree = "<group>"; };
@@ -362,7 +362,7 @@
ABC8C4180DC7F7D000B59C21 /* zlib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = zlib.xcodeproj; path = third_party/zlib/zlib.xcodeproj; sourceTree = "<group>"; };
ABCF253B0DB8436B00099567 /* test_shell_switches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_shell_switches.h; sourceTree = "<group>"; };
ABCF253C0DB8436B00099567 /* test_shell_switches.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_shell_switches.cc; sourceTree = "<group>"; };
- ABD16F380DC6A73B0013D3AA /* webwidget_host.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = webwidget_host.mm; sourceTree = "<group>"; };
+ ABD16F380DC6A73B0013D3AA /* webwidget_host.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = webwidget_host.mm; path = mac/webwidget_host.mm; sourceTree = "<group>"; };
ABD16F390DC6A73B0013D3AA /* webwidget_host.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = webwidget_host.h; sourceTree = "<group>"; };
ABD16F700DC6CBDF0013D3AA /* base.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = base.xcodeproj; path = base/base.xcodeproj; sourceTree = "<group>"; };
E450637C0E4100740025A81A /* test_shell_request_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_shell_request_context.h; sourceTree = "<group>"; };
diff --git a/webkit/tools/test_shell/mac/test_webview_delegate.mm b/webkit/tools/test_shell/mac/test_webview_delegate.mm
new file mode 100644
index 0000000..746835e
--- /dev/null
+++ b/webkit/tools/test_shell/mac/test_webview_delegate.mm
@@ -0,0 +1,838 @@
+// Copyright (c) 2008 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 "webkit/tools/test_shell/test_webview_delegate.h"
+
+#import <Cocoa/Cocoa.h>
+#include "base/gfx/point.h"
+#include "base/string_util.h"
+#include "net/base/net_errors.h"
+#include "chrome/common/page_transition_types.h"
+#include "webkit/glue/webdatasource.h"
+#include "webkit/glue/webdropdata.h"
+#include "webkit/glue/weberror.h"
+#include "webkit/glue/webframe.h"
+#include "webkit/glue/webpreferences.h"
+#include "webkit/glue/weburlrequest.h"
+#include "webkit/glue/webkit_glue.h"
+#include "webkit/glue/webview.h"
+// #include "webkit/glue/plugins/plugin_list.h"
+// #include "webkit/glue/plugins/webplugin_delegate_impl.h"
+#include "webkit/glue/window_open_disposition.h"
+// #include "webkit/tools/test_shell/drag_delegate.h"
+// #include "webkit/tools/test_shell/drop_delegate.h"
+#include "webkit/tools/test_shell/test_navigation_controller.h"
+#include "webkit/tools/test_shell/test_shell.h"
+
+
+static int32 next_page_id_ = 1;
+
+// WebViewDelegate -----------------------------------------------------------
+
+TestWebViewDelegate::~TestWebViewDelegate() {
+}
+
+WebView* TestWebViewDelegate::CreateWebView(WebView* webview,
+ bool user_gesture) {
+ return shell_->CreateWebView(webview);
+}
+
+WebWidget* TestWebViewDelegate::CreatePopupWidget(WebView* webview) {
+ return shell_->CreatePopupWidget(webview);
+}
+
+WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate(
+ WebView* webview,
+ const GURL& url,
+ const std::string& mime_type,
+ const std::string& clsid,
+ std::string* actual_mime_type) {
+ // TODO(awalker): once Mac plugins are working, enable this code to
+ // connect up the web plugin delegate for a plugin.
+#if 0
+ WindowHandle WindowHandle = GetContainingWindow(webview);
+ if (!WindowHandle)
+ return NULL;
+
+ bool allow_wildcard = true;
+ WebPluginInfo info;
+ if (!NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
+ allow_wildcard, &info,
+ actual_mime_type))
+ return NULL;
+
+ if (actual_mime_type && !actual_mime_type->empty())
+ return WebPluginDelegateImpl::Create(info.file, *actual_mime_type,
+ WindowHandle);
+ else
+ return WebPluginDelegateImpl::Create(info.file, mime_type, WindowHandle);
+#else
+ return NULL;
+#endif
+}
+
+void TestWebViewDelegate::OpenURL(WebView* webview, const GURL& url,
+ WindowOpenDisposition disposition) {
+ DCHECK_NE(disposition, CURRENT_TAB); // No code for this
+ if (disposition == SUPPRESS_OPEN)
+ return;
+ TestShell* shell = NULL;
+ if (TestShell::CreateNewWindow(UTF8ToWide(url.spec()), &shell))
+ shell->Show(shell->webView(), disposition);
+}
+
+void TestWebViewDelegate::DidStartLoading(WebView* webview) {
+ if (page_is_loading_) {
+ LOG(ERROR) << "DidStartLoading called while loading";
+ return;
+ }
+ page_is_loading_ = true;
+}
+
+void TestWebViewDelegate::DidStopLoading(WebView* webview) {
+ if (!page_is_loading_) {
+ LOG(ERROR) << "DidStopLoading called while not loading";
+ return;
+ }
+ page_is_loading_ = false;
+}
+
+void TestWebViewDelegate::WindowObjectCleared(WebFrame* webframe) {
+ shell_->BindJSObjectsToWindow(webframe);
+}
+
+WindowOpenDisposition TestWebViewDelegate::DispositionForNavigationAction(
+ WebView* webview,
+ WebFrame* frame,
+ const WebRequest* request,
+ WebNavigationType type,
+ WindowOpenDisposition disposition,
+ bool is_redirect) {
+ if (is_custom_policy_delegate_) {
+ std::wstring frame_name = frame->GetName();
+ printf("Policy delegate: attempt to load %s\n",
+ request->GetURL().spec().c_str());
+ return IGNORE_ACTION;
+ } else {
+ return static_cast<WindowOpenDisposition>(
+ WebViewDelegate::DispositionForNavigationAction(webview, frame, request,
+ type, disposition,
+ is_redirect));
+ }
+}
+
+void TestWebViewDelegate::SetCustomPolicyDelegate(bool isCustom) {
+ is_custom_policy_delegate_ = isCustom;
+}
+
+void TestWebViewDelegate::AssignIdentifierToRequest(WebView* webview,
+ uint32 identifier,
+ const WebRequest& request) {
+ if (shell_->ShouldDumpResourceLoadCallbacks()) {
+ resource_identifier_map_[identifier] = request.GetURL().spec();
+ }
+}
+
+std::string TestWebViewDelegate::GetResourceDescription(uint32 identifier) {
+ ResourceMap::iterator it = resource_identifier_map_.find(identifier);
+ return it != resource_identifier_map_.end() ? it->second : "<unknown>";
+}
+
+void TestWebViewDelegate::WillSendRequest(WebView* webview,
+ uint32 identifier,
+ WebRequest* request) {
+ std::string request_url = request->GetURL().spec();
+
+ if (shell_->ShouldDumpResourceLoadCallbacks()) {
+ printf("%s - willSendRequest <WebRequest URL \"%s\">\n",
+ GetResourceDescription(identifier).c_str(),
+ request_url.c_str());
+ }
+
+ // Set the new substituted URL.
+ request->SetURL(GURL(TestShell::RewriteLocalUrl(request_url)));
+}
+
+void TestWebViewDelegate::DidFinishLoading(WebView* webview,
+ uint32 identifier) {
+ if (shell_->ShouldDumpResourceLoadCallbacks()) {
+ printf("%s - didFinishLoading\n",
+ GetResourceDescription(identifier).c_str());
+ }
+
+ resource_identifier_map_.erase(identifier);
+}
+
+void TestWebViewDelegate::DidFailLoadingWithError(WebView* webview,
+ uint32 identifier,
+ const WebError& error) {
+ if (shell_->ShouldDumpResourceLoadCallbacks()) {
+ printf("%s - didFailLoadingWithError <WebError code %d,"
+ " failing URL \"%s\">\n",
+ GetResourceDescription(identifier).c_str(),
+ error.GetErrorCode(),
+ error.GetFailedURL().spec().c_str());
+ }
+
+ resource_identifier_map_.erase(identifier);
+}
+
+void TestWebViewDelegate::DidStartProvisionalLoadForFrame(
+ WebView* webview,
+ WebFrame* frame,
+ NavigationGesture gesture) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didStartProvisionalLoadForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ if (!top_loading_frame_) {
+ top_loading_frame_ = frame;
+ }
+ UpdateAddressBar(webview);
+}
+
+void TestWebViewDelegate::DidReceiveServerRedirectForProvisionalLoadForFrame(
+ WebView* webview,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didReceiveServerRedirectForProvisionalLoadForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ UpdateAddressBar(webview);
+}
+
+void TestWebViewDelegate::DidFailProvisionalLoadWithError(
+ WebView* webview,
+ const WebError& error,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didFailProvisionalLoadWithError\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ if (page_is_loading_)
+ DidStopLoading(webview);
+ LocationChangeDone(frame->GetProvisionalDataSource());
+
+ // Don't display an error page if we're running layout tests, because
+ // DumpRenderTree doesn't.
+ if (!shell_->interactive())
+ return;
+
+ // Don't display an error page if this is simply a cancelled load. Aside
+ // from being dumb, WebCore doesn't expect it and it will cause a crash.
+ if (error.GetErrorCode() == net::ERR_ABORTED)
+ return;
+
+ const WebRequest& failed_request =
+ frame->GetProvisionalDataSource()->GetRequest();
+ TestShellExtraRequestData* extra_data =
+ static_cast<TestShellExtraRequestData*>(failed_request.GetExtraData());
+ bool replace = extra_data && extra_data->pending_page_id != -1;
+
+ scoped_ptr<WebRequest> request(failed_request.Clone());
+ request->SetURL(GURL("testshell-error:"));
+
+ std::string error_text =
+ StringPrintf("Error loading url: %d", error.GetErrorCode());
+
+ frame->LoadAlternateHTMLString(request.get(), error_text,
+ error.GetFailedURL(), replace);
+}
+
+void TestWebViewDelegate::DidCommitLoadForFrame(WebView* webview,
+ WebFrame* frame,
+ bool is_new_navigation) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didCommitLoadForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ UpdateForCommittedLoad(frame, is_new_navigation);
+}
+
+void TestWebViewDelegate::DidReceiveTitle(WebView* webview,
+ const std::wstring& title,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didReceiveTitle\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ if (shell_->ShouldDumpTitleChanges()) {
+ printf("TITLE CHANGED: %S\n", title.c_str());
+ }
+ [[shell_->webViewHost()->window_handle() window]
+ setTitle:[NSString stringWithUTF8String:WideToUTF8(title).c_str()]];
+}
+
+void TestWebViewDelegate::DidFinishLoadForFrame(WebView* webview,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didFinishLoadForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ UpdateAddressBar(webview);
+ LocationChangeDone(frame->GetDataSource());
+}
+
+void TestWebViewDelegate::DidFailLoadWithError(WebView* webview,
+ const WebError& error,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didFailLoadWithError\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ if (page_is_loading_)
+ DidStopLoading(webview);
+ LocationChangeDone(frame->GetDataSource());
+}
+
+void TestWebViewDelegate::DidFinishDocumentLoadForFrame(WebView* webview,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didFinishDocumentLoadForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+}
+
+void TestWebViewDelegate::DidHandleOnloadEventsForFrame(WebView* webview,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didHandleOnloadEventsForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+}
+
+void TestWebViewDelegate::DidChangeLocationWithinPageForFrame(
+ WebView* webview, WebFrame* frame, bool is_new_navigation) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didChangeLocationWithinPageForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+
+ UpdateForCommittedLoad(frame, is_new_navigation);
+}
+
+void TestWebViewDelegate::DidReceiveIconForFrame(WebView* webview,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didReceiveIconForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+}
+
+void TestWebViewDelegate::WillPerformClientRedirect(
+ WebView* webview, WebFrame* frame, const std::wstring& dest_url,
+ unsigned int delay_seconds, unsigned int fire_date) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ // TODO: prettyprint the url?
+ printf("%S - willPerformClientRedirectToURL: %S\n",
+ GetFrameDescription(frame).c_str(), dest_url.c_str());
+ }
+}
+
+void TestWebViewDelegate::DidCancelClientRedirect(WebView* webview,
+ WebFrame* frame) {
+ if (shell_->ShouldDumpFrameLoadCallbacks()) {
+ printf("%S - didCancelClientRedirectForFrame\n",
+ GetFrameDescription(frame).c_str());
+ }
+}
+
+void TestWebViewDelegate::AddMessageToConsole(WebView* webview,
+ const std::wstring& message,
+ unsigned int line_no,
+ const std::wstring& source_id) {
+ if (shell_->interactive()) {
+ logging::LogMessage("CONSOLE", 0).stream() << "\""
+ << message.c_str()
+ << ",\" source: "
+ << source_id.c_str()
+ << "("
+ << line_no
+ << ")";
+ } else {
+ // This matches win DumpRenderTree's UIDelegate.cpp.
+ std::wstring new_message = message;
+ if (!message.empty()) {
+ new_message = message;
+ size_t file_protocol = new_message.find(L"file://");
+ if (file_protocol != std::wstring::npos) {
+ new_message = new_message.substr(0, file_protocol) + new_message;
+ // UrlSuitableForTestResult(new_message);
+ }
+ }
+
+ std::string utf8 = WideToUTF8(new_message);
+ printf("CONSOLE MESSAGE: line %d: %s\n", line_no, utf8.c_str());
+ }
+}
+
+void TestWebViewDelegate::RunJavaScriptAlert(WebView* webview,
+ const std::wstring& message) {
+ if (shell_->interactive()) {
+ NSString *text =
+ [NSString stringWithUTF8String:WideToUTF8(message).c_str()];
+ NSAlert *alert = [NSAlert alertWithMessageText:@"JavaScript Alert"
+ defaultButton:@"OK"
+ alternateButton:nil
+ otherButton:nil
+ informativeTextWithFormat:text];
+ [alert runModal];
+ } else {
+ std::string utf8 = WideToUTF8(message);
+ printf("ALERT: %s\n", utf8.c_str());
+ }
+}
+
+bool TestWebViewDelegate::RunJavaScriptConfirm(WebView* webview,
+ const std::wstring& message) {
+ if (!shell_->interactive()) {
+ // When running tests, write to stdout.
+ std::string utf8 = WideToUTF8(message);
+ printf("CONFIRM: %s\n", utf8.c_str());
+ return true;
+ }
+ return false;
+}
+
+bool TestWebViewDelegate::RunJavaScriptPrompt(WebView* webview,
+ const std::wstring& message, const std::wstring& default_value,
+ std::wstring* result) {
+ if (!shell_->interactive()) {
+ // When running tests, write to stdout.
+ std::string utf8_message = WideToUTF8(message);
+ std::string utf8_default_value = WideToUTF8(default_value);
+ printf("PROMPT: %s, default text: %s\n", utf8_message.c_str(),
+ utf8_default_value.c_str());
+ return true;
+ }
+ return false;
+}
+
+void TestWebViewDelegate::StartDragging(WebView* webview,
+ const WebDropData& drop_data) {
+#if 0
+// TODO(pinkerton): fill in drag&drop code later.
+ if (!drag_delegate_)
+ drag_delegate_ = new TestDragDelegate(shell_->webViewWnd(),
+ shell_->webView());
+ if (webkit_glue::IsLayoutTestMode()) {
+ if (shell_->layout_test_controller()->ShouldAddFileToPasteboard()) {
+ // Add a file called DRTFakeFile to the drag&drop clipboard.
+ // AddDRTFakeFileToDataObject(drop_data.data_object);
+ }
+
+ // When running a test, we need to fake a drag drop operation otherwise
+ // Windows waits for real mouse events to know when the drag is over.
+ EventSendingController::DoDragDrop(drop_data.data_object);
+ } else {
+ // Process a real drag and drop
+ }
+ webview->DragSourceSystemDragEnded();
+#endif
+}
+
+void TestWebViewDelegate::ShowContextMenu(WebView* webview,
+ ContextNode::Type type,
+ int x,
+ int y,
+ const GURL& link_url,
+ const GURL& image_url,
+ const GURL& page_url,
+ const GURL& frame_url,
+ const std::wstring& selection_text,
+ const std::wstring& misspelled_word,
+ int edit_flags) {
+ CapturedContextMenuEvent context(type, x, y);
+ captured_context_menu_events_.push_back(context);
+}
+
+// The output from these methods in non-interactive mode should match that
+// expected by the layout tests. See EditingDelegate.m in DumpRenderTree.
+bool TestWebViewDelegate::ShouldBeginEditing(WebView* webview,
+ std::wstring range) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8 = WideToUTF8(range);
+ printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n",
+ utf8.c_str());
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::ShouldEndEditing(WebView* webview,
+ std::wstring range) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8 = WideToUTF8(range);
+ printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n",
+ utf8.c_str());
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::ShouldInsertNode(WebView* webview,
+ std::wstring node,
+ std::wstring range,
+ std::wstring action) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8_node = WideToUTF8(node);
+ std::string utf8_range = WideToUTF8(range);
+ std::string utf8_action = WideToUTF8(action);
+ printf("EDITING DELEGATE: shouldInsertNode:%s "
+ "replacingDOMRange:%s givenAction:%s\n",
+ utf8_node.c_str(), utf8_range.c_str(), utf8_action.c_str());
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::ShouldInsertText(WebView* webview,
+ std::wstring text,
+ std::wstring range,
+ std::wstring action) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8_text = WideToUTF8(text);
+ std::string utf8_range = WideToUTF8(range);
+ std::string utf8_action = WideToUTF8(action);
+ printf("EDITING DELEGATE: shouldInsertText:%s "
+ "replacingDOMRange:%s givenAction:%s\n",
+ utf8_text.c_str(), utf8_range.c_str(), utf8_action.c_str());
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::ShouldChangeSelectedRange(WebView* webview,
+ std::wstring fromRange,
+ std::wstring toRange,
+ std::wstring affinity,
+ bool stillSelecting) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8_from = WideToUTF8(fromRange);
+ std::string utf8_to = WideToUTF8(toRange);
+ std::string utf8_affinity = WideToUTF8(affinity);
+ printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s "
+ "toDOMRange:%s affinity:%s stillSelecting:%s\n",
+ utf8_from.c_str(),
+ utf8_to.c_str(),
+ utf8_affinity.c_str(),
+ (stillSelecting ? "TRUE" : "FALSE"));
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::ShouldDeleteRange(WebView* webview,
+ std::wstring range) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8 = WideToUTF8(range);
+ printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", utf8.c_str());
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::ShouldApplyStyle(WebView* webview,
+ std::wstring style,
+ std::wstring range) {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ std::string utf8_style = WideToUTF8(style);
+ std::string utf8_range = WideToUTF8(range);
+ printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n",
+ utf8_style.c_str(), utf8_range.c_str());
+ }
+ return shell_->AcceptsEditing();
+}
+
+bool TestWebViewDelegate::SmartInsertDeleteEnabled() {
+ return true;
+}
+
+void TestWebViewDelegate::DidBeginEditing() {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: "
+ "webViewDidBeginEditing:WebViewDidBeginEditingNotification\n");
+ }
+}
+
+void TestWebViewDelegate::DidChangeSelection() {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: "
+ "webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n");
+ }
+}
+
+void TestWebViewDelegate::DidChangeContents() {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: "
+ "webViewDidChange:WebViewDidChangeNotification\n");
+ }
+}
+
+void TestWebViewDelegate::DidEndEditing() {
+ if (shell_->ShouldDumpEditingCallbacks()) {
+ printf("EDITING DELEGATE: "
+ "webViewDidEndEditing:WebViewDidEndEditingNotification\n");
+ }
+}
+
+WebHistoryItem* TestWebViewDelegate::GetHistoryEntryAtOffset(int offset) {
+ TestNavigationEntry* entry = static_cast<TestNavigationEntry*>(
+ shell_->navigation_controller()->GetEntryAtOffset(offset));
+ if (!entry)
+ return NULL;
+
+ return entry->GetHistoryItem();
+}
+
+void TestWebViewDelegate::GoToEntryAtOffsetAsync(int offset) {
+ shell_->navigation_controller()->GoToOffset(offset);
+}
+
+int TestWebViewDelegate::GetHistoryBackListCount() {
+ int current_index =
+ shell_->navigation_controller()->GetLastCommittedEntryIndex();
+ return current_index;
+}
+
+int TestWebViewDelegate::GetHistoryForwardListCount() {
+ int current_index =
+ shell_->navigation_controller()->GetLastCommittedEntryIndex();
+ return shell_->navigation_controller()->GetEntryCount() - current_index - 1;
+}
+
+void TestWebViewDelegate::SetUserStyleSheetEnabled(bool is_enabled) {
+ WebPreferences* prefs = shell_->GetWebPreferences();
+ prefs->user_style_sheet_enabled = is_enabled;
+ shell_->webView()->SetPreferences(*prefs);
+}
+
+void TestWebViewDelegate::SetUserStyleSheetLocation(const GURL& location) {
+ WebPreferences* prefs = shell_->GetWebPreferences();
+ prefs->user_style_sheet_location = location;
+ shell_->webView()->SetPreferences(*prefs);
+}
+
+void TestWebViewDelegate::SetDashboardCompatibilityMode(bool use_mode) {
+ WebPreferences* prefs = shell_->GetWebPreferences();
+ prefs->dashboard_compatibility_mode = use_mode;
+ shell_->webView()->SetPreferences(*prefs);
+}
+
+// WebWidgetDelegate ---------------------------------------------------------
+
+gfx::ViewHandle TestWebViewDelegate::GetContainingWindow(WebWidget* webwidget) {
+ if (WebWidgetHost* host = GetHostForWidget(webwidget))
+ return host->window_handle();
+
+ return NULL;
+}
+
+void TestWebViewDelegate::DidInvalidateRect(WebWidget* webwidget,
+ const gfx::Rect& rect) {
+ if (shell_ && shell_->webViewHost() && shell_->webViewHost()->window_handle())
+ [shell_->webViewHost()->window_handle() setNeedsDisplay:YES];
+}
+
+void TestWebViewDelegate::DidScrollRect(WebWidget* webwidget, int dx, int dy,
+ const gfx::Rect& clip_rect) {
+ if (WebWidgetHost* host = GetHostForWidget(webwidget))
+ host->DidScrollRect(dx, dy, clip_rect);
+}
+
+void TestWebViewDelegate::Show(WebWidget* webview,
+ WindowOpenDisposition disposition) {
+}
+
+void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) {
+ if (webwidget == shell_->webView()) {
+ NSWindow *win = shell_->mainWnd();
+ // Tell Cocoa to close the window. When the view is deallocated,
+ // the delegate (and therefore shell_) will be destroyed as well, so
+ // we do not need to explicitly null out the pointer shell_ is
+ // holding to the window.
+ [win performClose:nil];
+ } else if (webwidget == shell_->popup()) {
+ shell_->ClosePopup();
+ }
+}
+
+void TestWebViewDelegate::Focus(WebWidget* webwidget) {
+ if (WebWidgetHost* host = GetHostForWidget(webwidget))
+ shell_->SetFocus(host, true);
+}
+
+void TestWebViewDelegate::Blur(WebWidget* webwidget) {
+ if (WebWidgetHost* host = GetHostForWidget(webwidget))
+ shell_->SetFocus(host, false);
+}
+
+void TestWebViewDelegate::SetCursor(WebWidget* webwidget,
+ const WebCursor& cursor) {
+ //TODO: Mac cursor handling
+}
+
+void TestWebViewDelegate::GetWindowRect(WebWidget* webwidget,
+ gfx::Rect* out_rect) {
+ DCHECK(out_rect);
+ if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
+ NSView *view = host->window_handle();
+ NSRect rect = [[[view window] contentView] frame];
+ *out_rect = gfx::Rect(NSRectToCGRect(rect));
+ }
+}
+
+void TestWebViewDelegate::SetWindowRect(WebWidget* webwidget,
+ const gfx::Rect& rect) {
+ // TODO: Mac window movement
+ if (webwidget == shell_->webView()) {
+ // ignored
+ } else if (webwidget == shell_->popup()) {
+ // MoveWindow(shell_->popupWnd(),
+ // rect.x(), rect.y(), rect.width(), rect.height(), FALSE);
+ }
+}
+
+void TestWebViewDelegate::DidMove(WebWidget* webwidget,
+ const WebPluginGeometry& move) {
+ // TODO: uncomment when Mac plugins are working
+ // WebPluginDelegateImpl::MoveWindow(
+ // move.window, move.window_rect, move.clip_rect, move.visible); */
+}
+
+void TestWebViewDelegate::RegisterDragDrop() {
+ // TODO: uncomment when Mac drag and drop is working
+ // DCHECK(!drop_delegate_);
+ // drop_delegate_ = new TestDropDelegate(shell_->webViewWnd(),
+ // shell_->webView());
+}
+
+void TestWebViewDelegate::RunModal(WebWidget* webwidget) {
+ // TODO(pinkerton): implement me
+}
+
+// Private methods -----------------------------------------------------------
+
+void TestWebViewDelegate::UpdateAddressBar(WebView* webView) {
+ WebFrame* mainFrame = webView->GetMainFrame();
+
+ WebDataSource* dataSource = mainFrame->GetDataSource();
+ if (!dataSource)
+ dataSource = mainFrame->GetProvisionalDataSource();
+ if (!dataSource)
+ return;
+
+ std::string frameURL = dataSource->GetRequest().GetMainDocumentURL().spec();
+ NSString *address = [NSString stringWithUTF8String:frameURL.c_str()];
+ [shell_->editWnd() setStringValue:address];
+}
+
+void TestWebViewDelegate::LocationChangeDone(WebDataSource* data_source) {
+ if (data_source->GetWebFrame() == top_loading_frame_) {
+ top_loading_frame_ = NULL;
+ [shell_->webViewHost()->window_handle() setNeedsDisplay:YES];
+
+ if (!shell_->interactive())
+ shell_->layout_test_controller()->LocationChangeDone();
+ }
+}
+
+WebWidgetHost* TestWebViewDelegate::GetHostForWidget(WebWidget* webwidget) {
+ if (webwidget == shell_->webView())
+ return shell_->webViewHost();
+ if (webwidget == shell_->popup())
+ return shell_->popupHost();
+ return NULL;
+}
+
+void TestWebViewDelegate::UpdateForCommittedLoad(WebFrame* frame,
+ bool is_new_navigation) {
+ WebView* webview = shell_->webView();
+
+ // Code duplicated from RenderView::DidCommitLoadForFrame.
+ const WebRequest& request =
+ webview->GetMainFrame()->GetDataSource()->GetRequest();
+ TestShellExtraRequestData* extra_data =
+ static_cast<TestShellExtraRequestData*>(request.GetExtraData());
+
+ if (is_new_navigation) {
+ // New navigation.
+ UpdateSessionHistory(frame);
+ page_id_ = next_page_id_++;
+ } else if (extra_data && extra_data->pending_page_id != -1 &&
+ !extra_data->request_committed) {
+ // This is a successful session history navigation!
+ UpdateSessionHistory(frame);
+ page_id_ = extra_data->pending_page_id;
+ }
+
+ // Don't update session history multiple times.
+ if (extra_data)
+ extra_data->request_committed = true;
+
+ UpdateURL(frame);
+}
+
+void TestWebViewDelegate::UpdateURL(WebFrame* frame) {
+ WebDataSource* ds = frame->GetDataSource();
+ DCHECK(ds);
+
+ const WebRequest& request = ds->GetRequest();
+
+ scoped_ptr<TestNavigationEntry> entry(new TestNavigationEntry);
+
+ // Bug 654101: the referrer will be empty on https->http transitions. It
+ // would be nice if we could get the real referrer from somewhere.
+ entry->SetPageID(page_id_);
+ if (ds->HasUnreachableURL()) {
+ entry->SetURL(GURL(ds->GetUnreachableURL()));
+ } else {
+ entry->SetURL(GURL(request.GetURL()));
+ }
+
+ shell_->navigation_controller()->DidNavigateToEntry(entry.release());
+
+ last_page_id_updated_ = std::max(last_page_id_updated_, page_id_);
+}
+
+void TestWebViewDelegate::UpdateSessionHistory(WebFrame* frame) {
+ // If we have a valid page ID at this point, then it corresponds to the page
+ // we are navigating away from. Otherwise, this is the first navigation, so
+ // there is no past session history to record.
+ if (page_id_ == -1)
+ return;
+
+ TestNavigationEntry* entry = static_cast<TestNavigationEntry*>(
+ shell_->navigation_controller()->GetEntryWithPageID(page_id_));
+ if (!entry)
+ return;
+
+ GURL url;
+ std::wstring title;
+ std::string state;
+ if (!shell_->webView()->GetMainFrame()->
+ GetPreviousState(&url, &title, &state))
+ return;
+
+ entry->SetURL(url);
+ entry->SetTitle(title);
+ entry->SetContentState(state);
+}
+
+std::wstring TestWebViewDelegate::GetFrameDescription(WebFrame* webframe) {
+ std::wstring name = webframe->GetName();
+
+ if (webframe == shell_->webView()->GetMainFrame()) {
+ if (name.length())
+ return L"main frame \"" + name + L"\"";
+ else
+ return L"main frame";
+ } else {
+ if (name.length())
+ return L"frame \"" + name + L"\"";
+ else
+ return L"frame (anonymous)";
+ }
+}
diff --git a/webkit/tools/test_shell/mac/webview_host.mm b/webkit/tools/test_shell/mac/webview_host.mm
new file mode 100644
index 0000000..803555a
--- /dev/null
+++ b/webkit/tools/test_shell/mac/webview_host.mm
@@ -0,0 +1,42 @@
+// Copyright (c) 2008 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.
+
+#import <Cocoa/Cocoa.h>
+
+#include "webkit/tools/test_shell/webview_host.h"
+#include "webkit/tools/test_shell/mac/test_shell_webview.h"
+
+#include "base/gfx/platform_canvas.h"
+#include "base/gfx/rect.h"
+#include "base/gfx/size.h"
+#include "webkit/glue/webinputevent.h"
+#include "webkit/glue/webview.h"
+
+/*static*/
+WebViewHost* WebViewHost::Create(NSWindow *parent_window,
+ WebViewDelegate* delegate,
+ const WebPreferences& prefs) {
+ WebViewHost* host = new WebViewHost();
+
+ NSRect content_rect = [[parent_window contentView] frame];
+ // bump down the top of the view so that it doesn't overlap the buttons
+ // and URL field. 32 is an ad hoc constant.
+ // TODO(awalker): replace explicit view layout with a little nib file
+ // and use that for view geometry.
+ content_rect.size.height -= 32;
+ host->view_ = [[TestShellWebView alloc] initWithFrame:content_rect];
+ // make the height and width track the window size.
+ [host->view_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
+ [[parent_window contentView] addSubview:host->view_];
+
+ host->webwidget_ = WebView::Create(delegate, prefs);
+ host->webwidget_->Resize(gfx::Size(content_rect.size.width,
+ content_rect.size.height));
+
+ return host;
+}
+
+WebView* WebViewHost::webview() const {
+ return static_cast<WebView*>(webwidget_);
+}
diff --git a/webkit/tools/test_shell/mac/webwidget_host.mm b/webkit/tools/test_shell/mac/webwidget_host.mm
new file mode 100644
index 0000000..bf38fc4
--- /dev/null
+++ b/webkit/tools/test_shell/mac/webwidget_host.mm
@@ -0,0 +1,260 @@
+// Copyright (c) 2008 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.
+
+#import <Cocoa/Cocoa.h>
+
+#include "webkit/tools/test_shell/webwidget_host.h"
+
+#include "base/gfx/platform_canvas_mac.h"
+#include "base/gfx/rect.h"
+#include "base/gfx/size.h"
+#include "base/logging.h"
+#include "webkit/glue/webinputevent.h"
+#include "webkit/glue/webwidget.h"
+
+/*static*/
+WebWidgetHost* WebWidgetHost::Create(NSWindow* parent_window,
+ WebWidgetDelegate* delegate) {
+ WebWidgetHost* host = new WebWidgetHost();
+
+ NSRect content_rect = [parent_window frame];
+ content_rect.origin.y += 64;
+ content_rect.size.height -= 64;
+ host->view_ = [[NSView alloc] initWithFrame:content_rect];
+ [[parent_window contentView] addSubview:host->view_];
+
+ // win_util::SetWindowUserData(host->hwnd_, host);
+
+ host->webwidget_ = WebWidget::Create(delegate);
+ host->webwidget_->Resize(gfx::Size(content_rect.size.width,
+ content_rect.size.height));
+ return host;
+}
+
+/*static*/
+WebWidgetHost* WebWidgetHost::FromWindow(NSWindow* hwnd) {
+ return NULL;
+}
+
+/*static*/
+void WebWidgetHost::HandleEvent(NSWindow *window, NSEvent *event) {
+ WebWidgetHost* host = FromWindow(window);
+ if (host) {
+ switch ([event type]) {
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSMouseEntered:
+ case NSMouseExited:
+ host->MouseEvent(event);
+ break;
+
+ case NSScrollWheel:
+ host->WheelEvent(event);
+ break;
+
+ case NSKeyDown:
+ case NSKeyUp:
+ host->KeyEvent(event);
+ break;
+
+ case NSAppKitDefined:
+ switch ([event subtype]) {
+ case NSApplicationActivatedEventType:
+ host->SetFocus(true);
+ break;
+ case NSApplicationDeactivatedEventType:
+ host->SetFocus(false);
+ break;
+ }
+ break;
+ }
+ }
+}
+
+void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
+ DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";
+
+ // If this invalidate overlaps with a pending scroll, then we have to
+ // downgrade to invalidating the scroll rect.
+ if (damaged_rect.Intersects(scroll_rect_)) {
+ paint_rect_ = paint_rect_.Union(scroll_rect_);
+ ResetScrollRect();
+ }
+ paint_rect_ = paint_rect_.Union(damaged_rect);
+
+ NSRect r = NSRectFromCGRect(damaged_rect.ToCGRect());
+ [view_ setNeedsDisplayInRect:r];
+}
+
+void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
+ DCHECK(dx || dy);
+
+ // If we already have a pending scroll operation or if this scroll operation
+ // intersects the existing paint region, then just failover to invalidating.
+ if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) {
+ paint_rect_ = paint_rect_.Union(scroll_rect_);
+ ResetScrollRect();
+ paint_rect_ = paint_rect_.Union(clip_rect);
+ }
+
+ // We will perform scrolling lazily, when requested to actually paint.
+ scroll_rect_ = clip_rect;
+ scroll_dx_ = dx;
+ scroll_dy_ = dy;
+
+ NSRect r = NSRectFromCGRect(clip_rect.ToCGRect());
+ [view_ setNeedsDisplayInRect:r];
+}
+
+// void WebWidgetHost::SetCursor(HCURSOR cursor) {
+// }
+
+void WebWidgetHost::DiscardBackingStore() {
+ canvas_.reset();
+}
+
+WebWidgetHost::WebWidgetHost()
+ : view_(NULL),
+ webwidget_(NULL),
+ scroll_dx_(0),
+ scroll_dy_(0),
+ track_mouse_leave_(false)
+{
+ set_painting(false);
+}
+
+WebWidgetHost::~WebWidgetHost() {
+ // win_util::SetWindowUserData(hwnd_, 0);
+
+ TrackMouseLeave(false);
+
+ webwidget_->Close();
+ webwidget_->Release();
+}
+
+void WebWidgetHost::Paint() {
+ NSRect r = [view_ frame];
+ gfx::Rect client_rect(NSRectToCGRect(r));
+ NSGraphicsContext* view_context = [NSGraphicsContext currentContext];
+ CGContextRef context = static_cast<CGContextRef>([view_context graphicsPort]);
+
+ // Allocate a canvas if necessary
+ if (!canvas_.get()) {
+ ResetScrollRect();
+ paint_rect_ = client_rect;
+ canvas_.reset(new gfx::PlatformCanvas(
+ paint_rect_.width(), paint_rect_.height(), true));
+ }
+
+ // make sure webkit draws into our bitmap, not the window
+ CGContextRef bitmap_context =
+ canvas_->getTopPlatformDevice().GetBitmapContext();
+ [NSGraphicsContext setCurrentContext:
+ [NSGraphicsContext graphicsContextWithGraphicsPort:bitmap_context
+ flipped:NO]];
+
+ // This may result in more invalidation
+ webwidget_->Layout();
+
+ // Scroll the canvas if necessary
+ scroll_rect_ = client_rect.Intersect(scroll_rect_);
+ if (!scroll_rect_.IsEmpty()) {
+ // add to invalidate rect, since there's no equivalent of ScrollDC.
+ paint_rect_.Union(scroll_rect_);
+ }
+ ResetScrollRect();
+
+ // Paint the canvas if necessary. Allow painting to generate extra rects the
+ // first time we call it. This is necessary because some WebCore rendering
+ // objects update their layout only when painted.
+ for (int i = 0; i < 2; ++i) {
+ paint_rect_ = client_rect;//.Intersect(paint_rect_);
+ if (!paint_rect_.IsEmpty()) {
+ gfx::Rect rect(paint_rect_);
+ paint_rect_ = gfx::Rect();
+
+// DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
+ PaintRect(rect);
+ }
+ }
+ DCHECK(paint_rect_.IsEmpty());
+
+ // set the context back to our window
+ [NSGraphicsContext setCurrentContext: view_context];
+
+ // Paint to the screen
+ if ([view_ lockFocusIfCanDraw]) {
+ CGRect paint_rect = NSRectToCGRect(r);
+ int bitmap_height = CGBitmapContextGetHeight(bitmap_context);
+ int bitmap_width = CGBitmapContextGetWidth(bitmap_context);
+ CGRect bitmap_rect = { { 0, 0 },
+ { bitmap_width, bitmap_height } };
+ canvas_->getTopPlatformDevice().DrawToContext(
+ context, 0, client_rect.height() - bitmap_height, &bitmap_rect);
+
+ [view_ unlockFocus];
+ }
+
+ // Draw children
+ // UpdateWindow(hwnd_);
+}
+
+void WebWidgetHost::Resize(const gfx::Rect& rect) {
+ // Force an entire re-paint. TODO(darin): Maybe reuse this memory buffer.
+ DiscardBackingStore();
+ webwidget_->Resize(gfx::Size(rect.width(), rect.height()));
+}
+
+void WebWidgetHost::MouseEvent(NSEvent *event) {
+ WebMouseEvent web_event(event);
+ switch (event.type) {
+ case WebInputEvent::MOUSE_MOVE:
+ TrackMouseLeave(true);
+ break;
+ case WebInputEvent::MOUSE_LEAVE:
+ TrackMouseLeave(false);
+ break;
+ case WebInputEvent::MOUSE_DOWN:
+ break;
+ case WebInputEvent::MOUSE_UP:
+ break;
+ }
+ webwidget_->HandleInputEvent(&web_event);
+}
+
+void WebWidgetHost::WheelEvent(NSEvent *event) {
+ WebMouseWheelEvent web_event(event);
+ webwidget_->HandleInputEvent(&web_event);
+}
+
+void WebWidgetHost::KeyEvent(NSEvent *event) {
+ WebKeyboardEvent web_event(event);
+ webwidget_->HandleInputEvent(&web_event);
+}
+
+void WebWidgetHost::SetFocus(bool enable) {
+ webwidget_->SetFocus(enable);
+}
+
+void WebWidgetHost::TrackMouseLeave(bool track) {
+}
+
+void WebWidgetHost::ResetScrollRect() {
+ scroll_rect_ = gfx::Rect();
+ scroll_dx_ = 0;
+ scroll_dy_ = 0;
+}
+
+void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
+ DCHECK(!painting_);
+ DCHECK(canvas_.get());
+
+ set_painting(true);
+ webwidget_->Paint(canvas_.get(), rect);
+ set_painting(false);
+}