diff --git a/atom.gyp b/atom.gyp index 73f8e8dbf3..9813108306 100644 --- a/atom.gyp +++ b/atom.gyp @@ -13,6 +13,7 @@ 'browser/atom/objects_registry.coffee', 'browser/atom/rpc_server.coffee', 'common/api/lib/id_weak_map.coffee', + 'common/api/lib/shell.coffee', 'renderer/api/lib/ipc.coffee', 'renderer/api/lib/remote.coffee', ], @@ -47,6 +48,8 @@ 'common/api/atom_api_idle_gc.cc', 'common/api/atom_api_id_weak_map.cc', 'common/api/atom_api_id_weak_map.h', + 'common/api/atom_api_shell.cc', + 'common/api/atom_api_shell.h', 'common/api/atom_api_v8_util.cc', 'common/api/atom_bindings.cc', 'common/api/atom_bindings.h', @@ -160,6 +163,15 @@ '.', 'vendor', ], + 'conditions': [ + ['OS=="mac"', { + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', + ], + }, + }], + ], }, { 'target_name': 'generated_sources', diff --git a/common/api/atom_api_shell.cc b/common/api/atom_api_shell.cc new file mode 100644 index 0000000000..5e99b3cd57 --- /dev/null +++ b/common/api/atom_api_shell.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "common/api/atom_api_shell.h" + +#include + +#include "base/files/file_path.h" +#include "common/platform_util.h" +#include "googleurl/src/gurl.h" +#include "vendor/node/src/node.h" + +namespace atom { + +namespace api { + +namespace { + +bool V8ValueToFilePath(v8::Handle value, base::FilePath* path) { + if (!value->IsString()) + return false; + + std::string file_path_string(*v8::String::Utf8Value(value)); + base::FilePath file_path = base::FilePath::FromUTF8Unsafe(file_path_string); + + if (file_path.empty()) + return false; + + *path = file_path; + return true; +} + +} // namespace + +// static +v8::Handle Shell::ShowItemInFolder(const v8::Arguments &args) { + v8::HandleScope scope; + + base::FilePath file_path; + if (!V8ValueToFilePath(args[0], &file_path)) + return node::ThrowTypeError("Bad argument"); + + platform_util::ShowItemInFolder(file_path); + return v8::Undefined(); +} + +// static +v8::Handle Shell::OpenItem(const v8::Arguments &args) { + v8::HandleScope scope; + + base::FilePath file_path; + if (!V8ValueToFilePath(args[0], &file_path)) + return node::ThrowTypeError("Bad argument"); + + platform_util::OpenItem(file_path); + return v8::Undefined(); +} + +// static +v8::Handle Shell::OpenExternal(const v8::Arguments &args) { + v8::HandleScope scope; + + if (!args[0]->IsString()) + return node::ThrowTypeError("Bad argument"); + + platform_util::OpenExternal(GURL(*v8::String::Utf8Value(args[0]))); + return v8::Undefined(); +} + +// static +v8::Handle Shell::MoveItemToTrash(const v8::Arguments &args) { + v8::HandleScope scope; + + base::FilePath file_path; + if (!V8ValueToFilePath(args[0], &file_path)) + return node::ThrowTypeError("Bad argument"); + + platform_util::MoveItemToTrash(file_path); + return v8::Undefined(); +} + +// static +void Shell::Initialize(v8::Handle target) { + node::SetMethod(target, "showItemInFolder", ShowItemInFolder); + node::SetMethod(target, "openItem", OpenItem); + node::SetMethod(target, "openExternal", OpenExternal); + node::SetMethod(target, "moveItemToTrash", MoveItemToTrash); +} + +} // namespace api + +} // namespace atom + +NODE_MODULE(atom_common_shell, atom::api::Shell::Initialize) diff --git a/common/api/atom_api_shell.h b/common/api/atom_api_shell.h new file mode 100644 index 0000000000..4188413665 --- /dev/null +++ b/common/api/atom_api_shell.h @@ -0,0 +1,32 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_API_ATOM_API_SHELL_H_ +#define ATOM_COMMON_API_ATOM_API_SHELL_H_ + +#include "base/basictypes.h" +#include "v8/include/v8.h" + +namespace atom { + +namespace api { + +class Shell { + public: + static void Initialize(v8::Handle target); + + private: + static v8::Handle ShowItemInFolder(const v8::Arguments &args); + static v8::Handle OpenItem(const v8::Arguments &args); + static v8::Handle OpenExternal(const v8::Arguments &args); + static v8::Handle MoveItemToTrash(const v8::Arguments &args); + + DISALLOW_IMPLICIT_CONSTRUCTORS(Shell); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_COMMON_API_ATOM_API_SHELL_H_ diff --git a/common/api/atom_extensions.h b/common/api/atom_extensions.h index 4967dd4809..1aa20408a6 100644 --- a/common/api/atom_extensions.h +++ b/common/api/atom_extensions.h @@ -20,6 +20,7 @@ NODE_EXT_LIST_ITEM(atom_renderer_ipc) // renderer processes. NODE_EXT_LIST_ITEM(atom_common_idle_gc) NODE_EXT_LIST_ITEM(atom_common_id_weak_map) +NODE_EXT_LIST_ITEM(atom_common_shell) NODE_EXT_LIST_ITEM(atom_common_v8_util) NODE_EXT_LIST_END diff --git a/common/api/lib/shell.coffee b/common/api/lib/shell.coffee new file mode 100644 index 0000000000..5fb935bacd --- /dev/null +++ b/common/api/lib/shell.coffee @@ -0,0 +1 @@ +module.exports = process.atomBinding 'shell' diff --git a/common/platform_util.h b/common/platform_util.h index 9878b770a9..5e8c561d5a 100644 --- a/common/platform_util.h +++ b/common/platform_util.h @@ -25,6 +25,9 @@ void OpenItem(const base::FilePath& full_path); // (For example, mailto: URLs in the default mail user agent.) void OpenExternal(const GURL& url); +// Move a file to trash. +void MoveItemToTrash(const base::FilePath& full_path); + } // platform_util #endif // ATOM_COMMON_PLATFORM_UTIL_H_ diff --git a/common/platform_util_mac.mm b/common/platform_util_mac.mm index 2d4cfa0ff9..2652586c26 100644 --- a/common/platform_util_mac.mm +++ b/common/platform_util_mac.mm @@ -126,4 +126,19 @@ void OpenExternal(const GURL& url) { LOG(WARNING) << "NSWorkspace failed to open URL " << url; } +void MoveItemToTrash(const base::FilePath& full_path) { + DCHECK([NSThread isMainThread]); + NSString* path_string = base::SysUTF8ToNSString(full_path.value()); + NSArray* file_array = + [NSArray arrayWithObject:[path_string lastPathComponent]]; + if (!path_string || !file_array || ![[NSWorkspace sharedWorkspace] + performFileOperation:NSWorkspaceRecycleOperation + source:[path_string stringByDeletingLastPathComponent] + destination:@"" + files:file_array + tag:nil]) + LOG(WARNING) << "NSWorkspace failed to move file " << full_path.value() + << " to trash"; +} + } // namespace platform_util