Redo Xcode project FROM SCRATCH

This commit is contained in:
Corey Johnson & Nathan Sobo
2012-02-29 15:14:56 -08:00
parent ffeaf7ed17
commit 7e6132f5b7
244 changed files with 791 additions and 1816 deletions

20
Atom/src/Atom.h Executable file
View File

@@ -0,0 +1,20 @@
#import "include/cef.h"
#import "include/cef_application_mac.h"
class ClientHandler;
@class AtomController;
@interface Atom : NSApplication<CefAppProtocol> {
NSView *_hiddenGlobalView;
BOOL handlingSendEvent_;
CefRefPtr<ClientHandler> _clientHandler;
}
- (void)open:(NSString *)path;
- (IBAction)runSpecs:(id)sender;
@end
// Returns the application settings based on command line arguments.
void AppGetSettings(CefSettings& settings);

114
Atom/src/Atom.mm Executable file
View File

@@ -0,0 +1,114 @@
#import "Atom.h"
#import "include/cef.h"
#import "AtomController.h"
#import "native_handler.h"
#import "client_handler.h"
// Provide the CefAppProtocol implementation required by CEF.
@implementation Atom
+ (NSApplication *)sharedApplication {
if (!NSApp) {
// Populate the settings based on command line arguments.
CefSettings settings;
AppGetSettings(settings);
// Initialize CEF.
CefRefPtr<CefApp> app;
CefInitialize(settings, app);
}
return [super sharedApplication];
}
- (void)dealloc {
[_hiddenGlobalView release];
[self dealloc];
}
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
handlingSendEvent_ = handlingSendEvent;
}
- (void)sendEvent:(NSEvent*)event {
CefScopedSendingEvent sendingEventScoper;
[super sendEvent:event];
}
- (void)createAtomContext {
_clientHandler = new ClientHandler(self);
CefWindowInfo window_info;
_hiddenGlobalView = [[NSView alloc] init];
window_info.SetAsChild(_hiddenGlobalView, 0, 0, 0, 0);
CefBrowserSettings settings;
NSURL *resourceDirURL = [[NSBundle mainBundle] resourceURL];
NSString *indexURLString = [[resourceDirURL URLByAppendingPathComponent:@"index.html"] absoluteString];
CefBrowser::CreateBrowser(window_info, _clientHandler.get(), [indexURLString UTF8String], settings);
}
- (void)open:(NSString *)path {
CefRefPtr<CefV8Context> atomContext = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
[[AtomController alloc] initWithPath:path atomContext:atomContext];
}
- (IBAction)runSpecs:(id)sender {
CefRefPtr<CefV8Context> atomContext = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
[[AtomController alloc] initSpecsWithAtomContext:atomContext];
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
[self createAtomContext];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
CefShutdown();
}
- (void)afterCreated:(CefRefPtr<CefBrowser>) browser {
browser->ShowDevTools();
}
- (void)loadStart:(CefRefPtr<CefBrowser>)browser {
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
CefRefPtr<CefV8Context> context = frame->GetV8Context();
CefRefPtr<CefV8Value> global = context->GetGlobal();
context->Enter();
CefRefPtr<CefV8Value> bootstrapScript = CefV8Value::CreateString("atom-bootstrap");
global->SetValue("$bootstrapScript", bootstrapScript, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<CefV8Value> atom = CefV8Value::CreateObject(NULL);
global->SetValue("atom", atom, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<NativeHandler> nativeHandler = new NativeHandler();
atom->SetValue("native", nativeHandler->m_object, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<CefV8Value> loadPath = CefV8Value::CreateString(PROJECT_DIR);
atom->SetValue("loadPath", loadPath, V8_PROPERTY_ATTRIBUTE_NONE);
context->Exit();
}
@end
// Returns the application settings based on command line arguments.
void AppGetSettings(CefSettings& settings) {
CefString(&settings.cache_path) = "";
CefString(&settings.user_agent) = "";
CefString(&settings.product_version) = "";
CefString(&settings.locale) = "";
CefString(&settings.log_file) = "";
CefString(&settings.javascript_flags) = "";
settings.log_severity = LOGSEVERITY_ERROR;
settings.local_storage_quota = 0;
settings.session_storage_quota = 0;
}

29
Atom/src/AtomController.h Normal file
View File

@@ -0,0 +1,29 @@
#import <Cocoa/Cocoa.h>
#import "include/cef.h"
class ClientHandler;
@interface AtomController : NSWindowController <NSWindowDelegate> {
NSView *_webView;
NSString *_bootstrapScript;
NSString *_pathToOpen;
CefRefPtr<CefV8Context> _atomContext;
CefRefPtr<ClientHandler> _clientHandler;
}
- (id)initWithBootstrapScript:(NSString *)bootstrapScript atomContext:(CefRefPtr<CefV8Context>) context;
- (id)initWithPath:(NSString *)path atomContext:(CefRefPtr<CefV8Context>)atomContext;
- (id)initSpecsWithAtomContext:(CefRefPtr<CefV8Context>)atomContext;
- (void)createBrowser;
- (void)afterCreated:(CefRefPtr<CefBrowser>) browser;
- (void)loadStart:(CefRefPtr<CefBrowser>) browser;
@property (nonatomic, retain) IBOutlet NSView *webView;
@end
// Returns the application browser settings based on command line arguments.
void AppGetBrowserSettings(CefBrowserSettings& settings);

157
Atom/src/AtomController.mm Normal file
View File

@@ -0,0 +1,157 @@
#import "AtomController.h"
#import "include/cef.h"
#import "client_handler.h"
@implementation AtomController
@synthesize webView=_webView;
- (void)dealloc {
[_bootstrapScript release];
[_webView release];
[_pathToOpen release];
[super dealloc];
}
- (id)initWithBootstrapScript:(NSString *)bootstrapScript atomContext:(CefRefPtr<CefV8Context>)atomContext {
self = [super initWithWindowNibName:@"ClientWindow"];
_bootstrapScript = [bootstrapScript retain];
_atomContext = atomContext;
[self.window makeKeyAndOrderFront:nil];
[self createBrowser];
return self;
}
- (id)initWithPath:(NSString *)path atomContext:(CefRefPtr<CefV8Context>)atomContext {
_pathToOpen = [path retain];
return [self initWithBootstrapScript:@"window-bootstrap" atomContext:atomContext];
}
- (id)initSpecsWithAtomContext:(CefRefPtr<CefV8Context>)atomContext {
return [self initWithBootstrapScript:@"spec-bootstrap" atomContext:atomContext];
}
- (void)windowDidLoad {
[self.window setDelegate:self];
[self.window setReleasedWhenClosed:NO];
}
- (void)createBrowser {
_clientHandler = new ClientHandler(self);
CefWindowInfo window_info;
CefBrowserSettings settings;
AppGetBrowserSettings(settings);
window_info.SetAsChild(self.webView, 0, 0, self.webView.bounds.size.width, self.webView.bounds.size.height);
NSURL *resourceDirURL = [[NSBundle mainBundle] resourceURL];
NSString *indexURLString = [[resourceDirURL URLByAppendingPathComponent:@"index.html"] absoluteString];
CefBrowser::CreateBrowser(window_info, _clientHandler.get(), [indexURLString UTF8String], settings);
}
- (void)afterCreated:(CefRefPtr<CefBrowser>) browser {
browser->ShowDevTools();
}
- (void)loadStart:(CefRefPtr<CefBrowser>) browser {
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
CefRefPtr<CefV8Context> context = frame->GetV8Context();
CefRefPtr<CefV8Value> global = context->GetGlobal();
context->Enter();
CefRefPtr<CefV8Value> bootstrapScript = CefV8Value::CreateString([_bootstrapScript UTF8String]);
global->SetValue("$bootstrapScript", bootstrapScript, V8_PROPERTY_ATTRIBUTE_NONE);
if (_pathToOpen) {
CefRefPtr<CefV8Value> pathToOpen = CefV8Value::CreateString([_pathToOpen UTF8String]);
global->SetValue("$pathToOpen", pathToOpen, V8_PROPERTY_ATTRIBUTE_NONE);
}
global->SetValue("atom", _atomContext->GetGlobal()->GetValue("atom"), V8_PROPERTY_ATTRIBUTE_NONE);
context->Exit();
}
#pragma mark NSWindowDelegate
- (BOOL)windowShouldClose:(id)window {
CefRefPtr<CefV8Context> context = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
CefRefPtr<CefV8Value> global = context->GetGlobal();
context->Enter();
CefRefPtr<CefV8Value> atom = context->GetGlobal()->GetValue("atom");
CefRefPtr<CefV8Value> retval;
CefRefPtr<CefV8Exception> exception;
CefV8ValueList arguments;
arguments.push_back(global);
atom->GetValue("windowClosed")->ExecuteFunction(atom, arguments, retval, exception, true);
context->Exit();
_clientHandler->GetBrowser()->CloseDevTools();
_atomContext = NULL;
_clientHandler = NULL;
// Clean ourselves up after clearing the stack of anything that might have the window on it.
[self autorelease];
return YES;
}
@end
// Returns the application browser settings based on command line arguments.
void AppGetBrowserSettings(CefBrowserSettings& settings) {
CefString(&settings.default_encoding) = "";
CefString(&settings.user_style_sheet_location) = "";
settings.drag_drop_disabled = false;
settings.load_drops_disabled = false;
settings.history_disabled = false;
settings.remote_fonts_disabled = false;
settings.encoding_detector_enabled = false;
settings.javascript_disabled = false;
settings.javascript_open_windows_disallowed = false;
settings.javascript_close_windows_disallowed = false;
settings.javascript_access_clipboard_disallowed = false;
settings.dom_paste_disabled = false;
settings.caret_browsing_enabled = false;
settings.java_disabled = true;
settings.plugins_disabled = true;
settings.universal_access_from_file_urls_allowed = true;
settings.file_access_from_file_urls_allowed = false;
settings.web_security_disabled = true;
settings.xss_auditor_enabled = false;
settings.image_load_disabled = false;
settings.shrink_standalone_images_to_fit = false;
settings.site_specific_quirks_disabled = false;
settings.text_area_resize_disabled = false;
settings.page_cache_disabled = false;
settings.tab_to_links_disabled = false;
settings.hyperlink_auditing_disabled = false;
settings.user_style_sheet_enabled = false;
settings.author_and_user_styles_disabled = false;
settings.local_storage_disabled = false;
settings.databases_disabled = false;
settings.application_cache_disabled = false;
settings.webgl_disabled = false;
settings.accelerated_compositing_enabled = false;
settings.threaded_compositing_enabled = false;
settings.accelerated_layers_disabled = false;
settings.accelerated_video_disabled = false;
settings.accelerated_2d_canvas_disabled = false;
settings.accelerated_drawing_disabled = false;
settings.accelerated_plugins_disabled = false;
settings.developer_tools_disabled = false;
}

128
Atom/src/client_handler.h Executable file
View File

@@ -0,0 +1,128 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef _CLIENT_HANDLER_H
#define _CLIENT_HANDLER_H
#import "include/cef.h"
@class AtomController;
// ClientHandler implementation.
class ClientHandler : public CefClient,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRequestHandler,
public CefDisplayHandler,
public CefFocusHandler,
public CefKeyboardHandler,
public CefPrintHandler,
public CefV8ContextHandler,
public CefDragHandler
{
public:
ClientHandler(id delegate);
virtual ~ClientHandler();
// CefClient methods
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefFocusHandler> GetFocusHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefV8ContextHandler> GetV8ContextHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefDragHandler> GetDragHandler() OVERRIDE
{ return this; }
// CefLifeSpanHandler methods
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefLoadHandler methods
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) OVERRIDE;
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE;
virtual bool OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& failedUrl,
CefString& errorText) OVERRIDE;
// CefRequestHandler methods
virtual bool OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
CefString& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
CefRefPtr<CefResponse> response,
int loadFlags) OVERRIDE;
// CefDisplayHandler methods
virtual void OnNavStateChange(CefRefPtr<CefBrowser> browser,
bool canGoBack,
bool canGoForward) OVERRIDE;
virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) OVERRIDE;
// CefFocusHandler methods.
virtual void OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node) OVERRIDE;
// CefKeyboardHandler methods.
virtual bool OnKeyEvent(CefRefPtr<CefBrowser> browser,
KeyEventType type,
int code,
int modifiers,
bool isSystemKey,
bool isAfterJavaScript) OVERRIDE;
// CefV8ContextHandler methods
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE;
// CefDragHandler methods.
virtual bool OnDragStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask) OVERRIDE;
virtual bool OnDragEnter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask) OVERRIDE;
CefRefPtr<CefBrowser> GetBrowser() { return m_Browser; }
CefWindowHandle GetBrowserHwnd() { return m_BrowserHwnd; }
protected:
// The child browser window
CefRefPtr<CefBrowser> m_Browser;
// The main frame window handle
CefWindowHandle m_MainHwnd;
// The child browser window handle
CefWindowHandle m_BrowserHwnd;
id m_delegate;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandler);
// Include the default locking implementation.
IMPLEMENT_LOCKING(ClientHandler);
};
#endif // _CLIENT_HANDLER_H

194
Atom/src/client_handler.mm Executable file
View File

@@ -0,0 +1,194 @@
#import "include/cef.h"
#import "include/cef_wrapper.h"
#import "client_handler.h"
#import "AtomController.h"
#import <Cocoa/Cocoa.h>
#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:browser];
}
}
}
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:browser];
}
}
void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode)
{
REQUIRE_UI_THREAD();
}
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();
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];
}

19
Atom/src/main.mm Normal file
View File

@@ -0,0 +1,19 @@
#import <Cocoa/Cocoa.h>
#include "include/cef.h"
int main(int argc, char* argv[]) {
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
Class principalClass = NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]);
NSApplication *application = [principalClass sharedApplication];
NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
NSNib *mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]];
[mainNib instantiateNibWithOwner:application topLevelObjects:nil];
// Run the application message loop.
CefRunMessageLoop();
// Don't put anything below this line because it won't be executed.
return 0;
}

18
Atom/src/native_handler.h Normal file
View File

@@ -0,0 +1,18 @@
#import "include/cef.h"
#import <Cocoa/Cocoa.h>
class NativeHandler : public CefV8Handler {
public:
NativeHandler();
CefRefPtr<CefV8Value> m_object;
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE;
// Provide the reference counting implementation for this class.
IMPLEMENT_REFCOUNTING(NativeHandler);
};

225
Atom/src/native_handler.mm Normal file
View File

@@ -0,0 +1,225 @@
#import "native_handler.h"
#import "include/cef.h"
#import "Atom.h"
NSString *stringFromCefV8Value(const CefRefPtr<CefV8Value>& value) {
std::string cc_value = value->GetStringValue().ToString();
return [NSString stringWithUTF8String:cc_value.c_str()];
}
NativeHandler::NativeHandler() : CefV8Handler() {
m_object = CefV8Value::CreateObject(NULL);
const char *functionNames[] = {"exists", "read", "write", "absolute", "list", "isFile", "isDirectory", "remove", "asyncList", "open", "quit", "writeToPasteboard", "readFromPasteboard"};
NSUInteger arrayLength = sizeof(functionNames) / sizeof(const char *);
for (NSUInteger i = 0; i < arrayLength; i++) {
const char *functionName = functionNames[i];
CefRefPtr<CefV8Value> function = CefV8Value::CreateFunction(functionName, this);
m_object->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE);
}
}
bool NativeHandler::Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception)
{
if (name == "exists") {
NSString *path = stringFromCefV8Value(arguments[0]);
bool exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil];
retval = CefV8Value::CreateBool(exists);
return true;
}
else if (name == "read") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSError *error = nil;
NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else {
retval = CefV8Value::CreateString([contents UTF8String]);
}
return true;
}
else if (name == "write") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSString *content = stringFromCefV8Value(arguments[1]);
NSError *error = nil;
BOOL success = [content writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else if (!success) {
std::string exception = "Cannot write to '";
exception += [path UTF8String];
exception += "'";
}
}
else if (name == "absolute") {
NSString *path = stringFromCefV8Value(arguments[0]);
path = [path stringByStandardizingPath];
if ([path characterAtIndex:0] == '/') {
retval = CefV8Value::CreateString([path UTF8String]);
}
return true;
}
else if (name == "list") {
NSString *path = stringFromCefV8Value(arguments[0]);
bool recursive = arguments[1]->GetBoolValue();
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *relativePaths = [NSArray array];
NSError *error = nil;
if (recursive) {
relativePaths = [fm subpathsOfDirectoryAtPath:path error:&error];
}
else {
relativePaths = [fm contentsOfDirectoryAtPath:path error:&error];
}
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else {
retval = CefV8Value::CreateArray();
for (NSUInteger i = 0; i < relativePaths.count; i++) {
NSString *relativePath = [relativePaths objectAtIndex:i];
NSString *fullPath = [path stringByAppendingPathComponent:relativePath];
retval->SetValue(i, CefV8Value::CreateString([fullPath UTF8String]));
}
}
return true;
}
else if (name == "isDirectory") {
NSString *path = stringFromCefV8Value(arguments[0]);
BOOL isDir = false;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
retval = CefV8Value::CreateBool(exists && isDir);
return true;
}
else if (name == "remove") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:path error:&error];
if (error) {
exception = [[error localizedDescription] UTF8String];
}
return true;
}
else if (name == "asyncList") {
NSString *path = stringFromCefV8Value(arguments[0]);
bool recursive = arguments[1]->GetBoolValue();
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *relativePaths = [NSArray array];
NSError *error = nil;
if (recursive) {
relativePaths = [fm subpathsOfDirectoryAtPath:path error:&error];
}
else {
relativePaths = [fm contentsOfDirectoryAtPath:path error:&error];
}
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else {
CefRefPtr<CefV8Value> paths = CefV8Value::CreateArray();
for (NSUInteger i = 0; i < relativePaths.count; i++) {
NSString *relativePath = [relativePaths objectAtIndex:i];
NSString *fullPath = [path stringByAppendingPathComponent:relativePath];
paths->SetValue(i, CefV8Value::CreateString([fullPath UTF8String]));
}
CefV8ValueList args;
args.push_back(paths);
CefRefPtr<CefV8Exception> e;
arguments[2]->ExecuteFunction(arguments[2], args, retval, e, true);
if (e) exception = e->GetMessage();
}
return true;
}
else if (name == "alert") {
NSString *message = stringFromCefV8Value(arguments[0]);
NSString *detailedMessage = stringFromCefV8Value(arguments[1]);
CefRefPtr<CefV8Value> buttons = arguments[2];
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:message];
[alert setInformativeText:detailedMessage];
std::vector<CefString> buttonTitles;
std::vector<CefString>::iterator iter;
NSMutableDictionary *titleForTag = [NSMutableDictionary dictionary];
buttons->GetKeys(buttonTitles);
for (iter = buttonTitles.begin(); iter != buttonTitles.end(); iter++) {
NSString *buttonTitle = [NSString stringWithUTF8String:(*iter).ToString().c_str()];
NSButton *button = [alert addButtonWithTitle:buttonTitle];
[titleForTag setObject:buttonTitle forKey:[NSNumber numberWithInt:button.tag]];
}
NSUInteger buttonTag = [alert runModal];
const char *buttonTitle = [[titleForTag objectForKey:[NSNumber numberWithInt:buttonTag]] UTF8String];
CefRefPtr<CefV8Value> callback = buttons->GetValue(buttonTitle);
CefV8ValueList args;
CefRefPtr<CefV8Exception> e;
callback->ExecuteFunction(callback , args, retval, e, true);
if (e) exception = e->GetMessage();
return true;
}
else if (name == "writeToPasteboard") {
NSString *text = stringFromCefV8Value(arguments[0]);
NSPasteboard *pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner:nil];
[pb setString:text forType:NSStringPboardType];
return true;
}
else if (name == "readFromPasteboard") {
NSPasteboard *pb = [NSPasteboard generalPasteboard];
NSArray *results = [pb readObjectsForClasses:[NSArray arrayWithObjects:[NSString class], nil] options:nil];
if (results) {
retval = CefV8Value::CreateString([[results objectAtIndex:0] UTF8String]);
}
return true;
}
else if (name == "open") {
NSString *path = stringFromCefV8Value(arguments[0]);
[NSApp open:path];
return true;
}
else if (name == "quit") {
[NSApp terminate:nil];
return true;
}
return false;
};