Files
atom/Atom/src/client_handler.mm
2012-03-14 10:48:17 -07:00

218 lines
5.8 KiB
Plaintext
Executable File

#import "include/cef.h"
#import "include/cef_wrapper.h"
#import "client_handler.h"
#import "AtomController.h"
#import <Cocoa/Cocoa.h>
#import <iostream>
#import <sstream>
#import <stdio.h>
#import <string>
#import <assert.h>
#ifndef NDEBUG
#define ASSERT(condition) if(!(condition)) { assert(false); }
#else
#define ASSERT(condition) ((void)0)
#endif
#define REQUIRE_UI_THREAD() ASSERT(CefCurrentlyOn(TID_UI));
#define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO));
#define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE));
ClientHandler::ClientHandler(id delegate)
: m_MainHwnd(NULL),
m_BrowserHwnd(NULL)
{
m_delegate = delegate;
}
ClientHandler::~ClientHandler()
{
}
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
AutoLock lock_scope(this);
if(!m_Browser.get())
{
// We need to keep the main child window, but not popup windows
m_Browser = browser;
m_BrowserHwnd = browser->GetWindowHandle();
if ([m_delegate respondsToSelector:@selector(afterCreated)]) {
[m_delegate afterCreated];
}
}
}
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
return false;
}
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
if(m_BrowserHwnd == browser->GetWindowHandle()) {
// Free the browser pointer so that the browser can be destroyed
m_Browser = NULL;
}
}
void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame)
{
REQUIRE_UI_THREAD();
if ([m_delegate respondsToSelector:@selector(loadStart)]) {
[m_delegate loadStart];
}
}
void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode)
{
REQUIRE_UI_THREAD();
if ([m_delegate respondsToSelector:@selector(loadEnd)]) {
[m_delegate loadEnd];
}
}
bool ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& failedUrl,
CefString& errorText)
{
REQUIRE_UI_THREAD();
if(errorCode == ERR_CACHE_MISS) {
// Usually caused by navigating to a page with POST data via back or
// forward buttons.
errorText = "<html><head><title>Expired Form Data</title></head>"
"<body><h1>Expired Form Data</h1>"
"<h2>Your form request has expired. "
"Click reload to re-submit the form data.</h2></body>"
"</html>";
} else {
// All other messages.
std::stringstream ss;
ss << "<html><head><title>Load Failed</title></head>"
"<body><h1>Load Failed</h1>"
"<h2>Load of URL " << std::string(failedUrl) <<
" failed with error code " << static_cast<int>(errorCode) <<
".</h2></body>"
"</html>";
errorText = ss.str();
}
return false;
}
void ClientHandler::OnNavStateChange(CefRefPtr<CefBrowser> browser,
bool canGoBack,
bool canGoForward)
{
REQUIRE_UI_THREAD();
}
void ClientHandler::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node)
{
REQUIRE_UI_THREAD();
}
bool ClientHandler::OnKeyEvent(CefRefPtr<CefBrowser> browser,
KeyEventType type,
int code,
int modifiers,
bool isSystemKey,
bool isAfterJavaScript)
{
REQUIRE_UI_THREAD();
if ([m_delegate respondsToSelector:@selector(keyEventOfType:code:modifiers:isSystemKey:isAfterJavaScript:)]) {
return [m_delegate keyEventOfType:type code:code modifiers:modifiers isSystemKey:isSystemKey isAfterJavaScript:isAfterJavaScript];
}
else {
return false;
}
}
void ClientHandler::OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context)
{
REQUIRE_UI_THREAD();
}
bool ClientHandler::OnDragStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask)
{
REQUIRE_UI_THREAD();
return false;
}
bool ClientHandler::OnDragEnter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask)
{
REQUIRE_UI_THREAD();
return false;
}
bool ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
CefString& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
CefRefPtr<CefResponse> response,
int loadFlags)
{
REQUIRE_IO_THREAD();
return false;
}
void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title)
{
REQUIRE_UI_THREAD();
// Set the frame window title bar
NSView* view = (NSView*)browser->GetWindowHandle();
NSWindow* window = [view window];
std::string titleStr(title);
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
[window setTitle:str];
}
bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
const CefString& message,
const CefString& source,
int line)
{
REQUIRE_UI_THREAD();
std::cout << std::string(message) << "\n";
return true;
}