Merge master
This commit is contained in:
commit
bd20104e5a
89 changed files with 1741 additions and 1059 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
### [Electron](https://github.com/atom/electron/) 한국어 참조문서
|
||||
|
||||
:zap: *이전까지 Atom Shell로 알려져 있었습니다* :zap:
|
||||
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 바뀌었습니다* :zap:
|
||||
|
||||
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [io.js](http://iojs.org) 와
|
||||
[Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
|
||||
|
@ -36,7 +36,7 @@ npm install electron-prebuilt --save-dev
|
|||
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 가이드와 API 레퍼런스가 있습니다.
|
||||
Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문서에 포함되어 있으니 참고하시기 바랍니다.
|
||||
|
||||
## 참조 문서(번역)
|
||||
## 참조 문서 (번역)
|
||||
|
||||
- [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko)
|
||||
- [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
|
|
|
@ -48,6 +48,7 @@ contains documents describing how to build and contribute to Electron.
|
|||
- [Korean](https://github.com/atom/electron/tree/master/docs-translations/ko)
|
||||
- [Japanese](https://github.com/atom/electron/tree/master/docs-translations/jp)
|
||||
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
|
||||
## Community
|
||||
|
||||
|
|
2
atom.gyp
2
atom.gyp
|
@ -4,7 +4,7 @@
|
|||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.31.0',
|
||||
'version%': '0.31.2',
|
||||
},
|
||||
'includes': [
|
||||
'filenames.gypi',
|
||||
|
|
|
@ -107,6 +107,10 @@ void Menu::SetSublabel(int index, const base::string16& sublabel) {
|
|||
model_->SetSublabel(index, sublabel);
|
||||
}
|
||||
|
||||
void Menu::SetRole(int index, const base::string16& role) {
|
||||
model_->SetRole(index, role);
|
||||
}
|
||||
|
||||
void Menu::Clear() {
|
||||
model_->Clear();
|
||||
}
|
||||
|
@ -154,6 +158,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
|
||||
.SetMethod("setIcon", &Menu::SetIcon)
|
||||
.SetMethod("setSublabel", &Menu::SetSublabel)
|
||||
.SetMethod("setRole", &Menu::SetRole)
|
||||
.SetMethod("clear", &Menu::Clear)
|
||||
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
|
||||
.SetMethod("getItemCount", &Menu::GetItemCount)
|
||||
|
|
|
@ -73,6 +73,7 @@ class Menu : public mate::Wrappable,
|
|||
Menu* menu);
|
||||
void SetIcon(int index, const gfx::Image& image);
|
||||
void SetSublabel(int index, const base::string16& sublabel);
|
||||
void SetRole(int index, const base::string16& role);
|
||||
void Clear();
|
||||
int GetIndexOfCommandId(int command_id);
|
||||
int GetItemCount() const;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
|
@ -101,6 +102,19 @@ struct Converter<ClearStorageDataOptions> {
|
|||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<content::DownloadItem*> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
content::DownloadItem* val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("url", val->GetURL());
|
||||
dict.Set("filename", val->GetSuggestedFilename());
|
||||
dict.Set("mimeType", val->GetMimeType());
|
||||
dict.Set("hasUserGesture", val->HasUserGesture());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
@ -109,6 +123,10 @@ namespace api {
|
|||
|
||||
namespace {
|
||||
|
||||
// The wrapSession funtion which is implemented in JavaScript
|
||||
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapSessionCallback g_wrap_session;
|
||||
|
||||
class ResolveProxyHelper {
|
||||
public:
|
||||
ResolveProxyHelper(AtomBrowserContext* browser_context,
|
||||
|
@ -215,9 +233,28 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
|
|||
Session::Session(AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
AttachAsUserData(browser_context);
|
||||
// Observe DownloadManger to get download notifications.
|
||||
auto download_manager =
|
||||
content::BrowserContext::GetDownloadManager(browser_context);
|
||||
download_manager->AddObserver(this);
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
auto download_manager =
|
||||
content::BrowserContext::GetDownloadManager(browser_context_);
|
||||
download_manager->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) {
|
||||
auto web_contents = item->GetWebContents();
|
||||
bool prevent_default = Emit("will-download", item,
|
||||
api::WebContents::CreateFrom(isolate(),
|
||||
web_contents));
|
||||
if (prevent_default) {
|
||||
item->Cancel(true);
|
||||
item->Remove();
|
||||
}
|
||||
}
|
||||
|
||||
void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
||||
|
@ -288,9 +325,33 @@ mate::Handle<Session> Session::CreateFrom(
|
|||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
||||
|
||||
return mate::CreateHandle(isolate, new Session(browser_context));
|
||||
auto handle = mate::CreateHandle(isolate, new Session(browser_context));
|
||||
g_wrap_session.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SetWrapSession(const WrapSessionCallback& callback) {
|
||||
g_wrap_session = callback;
|
||||
}
|
||||
|
||||
void ClearWrapSession() {
|
||||
g_wrap_session.Reset();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
||||
dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_session, Initialize)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
|
||||
|
@ -27,7 +28,8 @@ class AtomBrowserContext;
|
|||
|
||||
namespace api {
|
||||
|
||||
class Session: public mate::TrackableObject<Session> {
|
||||
class Session: public mate::TrackableObject<Session>,
|
||||
public content::DownloadManager::Observer {
|
||||
public:
|
||||
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
||||
|
||||
|
@ -41,6 +43,10 @@ class Session: public mate::TrackableObject<Session> {
|
|||
explicit Session(AtomBrowserContext* browser_context);
|
||||
~Session();
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
bindings = process.atomBinding 'app'
|
||||
sessionBindings = process.atomBinding 'session'
|
||||
|
||||
app = bindings.app
|
||||
app.__proto__ = EventEmitter.prototype
|
||||
|
||||
wrapSession = (session) ->
|
||||
# session is an Event Emitter.
|
||||
session.__proto__ = EventEmitter.prototype
|
||||
|
||||
app.setApplicationMenu = (menu) ->
|
||||
require('menu').setApplicationMenu menu
|
||||
|
||||
|
@ -41,5 +46,9 @@ app.getDataPath = -> @getPath 'userData'
|
|||
app.setDataPath = (path) -> @setPath 'userData', path
|
||||
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
|
||||
|
||||
# Session wrapper.
|
||||
sessionBindings._setWrapSession wrapSession
|
||||
process.once 'exit', sessionBindings._clearWrapSession
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
|
|
|
@ -62,6 +62,12 @@ BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
|||
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||
|
||||
# Be compatible with old API.
|
||||
BrowserWindow::undo = -> @webContents.undo()
|
||||
BrowserWindow::redo = -> @webContents.redo()
|
||||
BrowserWindow::cut = -> @webContents.cut()
|
||||
BrowserWindow::copy = -> @webContents.copy()
|
||||
BrowserWindow::paste = -> @webContents.paste()
|
||||
BrowserWindow::selectAll = -> @webContents.selectAll()
|
||||
BrowserWindow::restart = -> @webContents.reload()
|
||||
BrowserWindow::getUrl = -> @webContents.getUrl()
|
||||
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
|
||||
|
|
|
@ -3,18 +3,30 @@ v8Util = process.atomBinding 'v8_util'
|
|||
|
||||
nextCommandId = 0
|
||||
|
||||
# Maps role to methods of webContents
|
||||
rolesMap =
|
||||
undo: 'undo'
|
||||
redo: 'redo'
|
||||
cut: 'cut'
|
||||
copy: 'copy'
|
||||
paste: 'paste'
|
||||
selectall: 'selectAll'
|
||||
minimize: 'minimize'
|
||||
close: 'close'
|
||||
|
||||
class MenuItem
|
||||
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
|
||||
|
||||
constructor: (options) ->
|
||||
Menu = require 'menu'
|
||||
|
||||
{click, @selector, @type, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||
|
||||
@type = 'submenu' if not @type? and @submenu?
|
||||
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
||||
|
||||
@overrideReadOnlyProperty 'type', 'normal'
|
||||
@overrideReadOnlyProperty 'role'
|
||||
@overrideReadOnlyProperty 'accelerator'
|
||||
@overrideReadOnlyProperty 'icon'
|
||||
@overrideReadOnlyProperty 'submenu'
|
||||
|
@ -27,12 +39,14 @@ class MenuItem
|
|||
throw new Error("Unknown menu type #{@type}") if MenuItem.types.indexOf(@type) is -1
|
||||
|
||||
@commandId = ++nextCommandId
|
||||
@click = =>
|
||||
@click = (focusedWindow) =>
|
||||
# Manually flip the checked flags when clicked.
|
||||
@checked = !@checked if @type in ['checkbox', 'radio']
|
||||
|
||||
if typeof click is 'function'
|
||||
click this, BrowserWindow.getFocusedWindow()
|
||||
if @role and rolesMap[@role] and process.platform isnt 'darwin'
|
||||
focusedWindow?[rolesMap[@role]]()
|
||||
else if typeof click is 'function'
|
||||
click this, focusedWindow
|
||||
else if typeof @selector is 'string'
|
||||
Menu.sendActionToFirstResponder @selector
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@ Menu::_init = ->
|
|||
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
|
||||
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
|
||||
getIconForCommandId: (commandId) => @commandsMap[commandId]?.icon
|
||||
executeCommand: (commandId) => @commandsMap[commandId]?.click()
|
||||
executeCommand: (commandId) =>
|
||||
@commandsMap[commandId]?.click BrowserWindow.getFocusedWindow()
|
||||
menuWillShow: =>
|
||||
# Make sure radio groups have at least one menu item seleted.
|
||||
for id, group of @groupsMap
|
||||
|
@ -115,6 +116,7 @@ Menu::insert = (pos, item) ->
|
|||
|
||||
@setSublabel pos, item.sublabel if item.sublabel?
|
||||
@setIcon pos, item.icon if item.icon?
|
||||
@setRole pos, item.role if item.role?
|
||||
|
||||
# Make menu accessable to items.
|
||||
item.overrideReadOnlyProperty 'menu', this
|
||||
|
|
|
@ -36,238 +36,176 @@ app.once('ready', function() {
|
|||
if (Menu.getApplicationMenu())
|
||||
return;
|
||||
|
||||
var template;
|
||||
var template = [
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
role: 'undo'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+CmdOrCtrl+Z',
|
||||
role: 'redo'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
role: 'paste'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
role: 'selectall'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'CmdOrCtrl+R',
|
||||
click: function(item, focusedWindow) {
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: (function() {
|
||||
if (process.platform == 'darwin')
|
||||
return 'Ctrl+Command+F';
|
||||
else
|
||||
return 'F11';
|
||||
})(),
|
||||
click: function(item, focusedWindow) {
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: (function() {
|
||||
if (process.platform == 'darwin')
|
||||
return 'Alt+Command+I';
|
||||
else
|
||||
return 'Ctrl+Shift+I';
|
||||
})(),
|
||||
click: function(item, focusedWindow) {
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
role: 'minimize'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
role: 'close'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
if (process.platform == 'darwin') {
|
||||
template = [
|
||||
template.unshift({
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
role: 'about'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
role: 'services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
role: 'hide'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
role: 'hideothers:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
role: 'unhide:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
});
|
||||
template[3].submenu.push(
|
||||
{
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
label: 'Bring All to Front',
|
||||
role: 'front'
|
||||
}
|
||||
];
|
||||
} else {
|
||||
template = [
|
||||
{
|
||||
label: '&File',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: '&Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.close();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Developer Tools',
|
||||
accelerator: 'Shift+Ctrl+I',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
var menu = Menu.buildFromTemplate(template);
|
||||
|
|
|
@ -57,13 +57,19 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, me
|
|||
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, message, targetOrigin) ->
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
|
||||
embedder = v8Util.getHiddenValue event.sender, 'embedder'
|
||||
if embedder?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
|
||||
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, sourceOrigin
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
|
||||
BrowserWindow.fromId(guestId)?.webContents?[method] args...
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_IS_GUEST_WINDOW', (event) ->
|
||||
event.returnValue = v8Util.getHiddenValue(event.sender, 'embedder') isnt undefined
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID', (event) ->
|
||||
embedder = v8Util.getHiddenValue event.sender, 'embedder'
|
||||
if embedder?
|
||||
guest = BrowserWindow.fromWebContents event.sender
|
||||
if guest?
|
||||
event.returnValue = guest.id
|
||||
return
|
||||
event.returnValue = null
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>atom.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.31.0</string>
|
||||
<string>0.31.2</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.8.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
|
|
@ -56,8 +56,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,31,0,0
|
||||
PRODUCTVERSION 0,31,0,0
|
||||
FILEVERSION 0,31,2,0
|
||||
PRODUCTVERSION 0,31,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -74,12 +74,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "0.31.0"
|
||||
VALUE "FileVersion", "0.31.2"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "0.31.0"
|
||||
VALUE "ProductVersion", "0.31.2"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomMenuModel::AtomMenuModel(Delegate* delegate)
|
||||
|
@ -14,6 +16,17 @@ AtomMenuModel::AtomMenuModel(Delegate* delegate)
|
|||
AtomMenuModel::~AtomMenuModel() {
|
||||
}
|
||||
|
||||
void AtomMenuModel::SetRole(int index, const base::string16& role) {
|
||||
roles_[index] = role;
|
||||
}
|
||||
|
||||
base::string16 AtomMenuModel::GetRoleAt(int index) {
|
||||
if (ContainsKey(roles_, index))
|
||||
return roles_[index];
|
||||
else
|
||||
return base::string16();
|
||||
}
|
||||
|
||||
void AtomMenuModel::MenuClosed() {
|
||||
ui::SimpleMenuModel::MenuClosed();
|
||||
FOR_EACH_OBSERVER(Observer, observers_, MenuClosed());
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef ATOM_BROWSER_UI_ATOM_MENU_MODEL_H_
|
||||
#define ATOM_BROWSER_UI_ATOM_MENU_MODEL_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/observer_list.h"
|
||||
#include "ui/base/models/simple_menu_model.h"
|
||||
|
||||
|
@ -31,12 +33,16 @@ class AtomMenuModel : public ui::SimpleMenuModel {
|
|||
void AddObserver(Observer* obs) { observers_.AddObserver(obs); }
|
||||
void RemoveObserver(Observer* obs) { observers_.RemoveObserver(obs); }
|
||||
|
||||
void SetRole(int index, const base::string16& role);
|
||||
base::string16 GetRoleAt(int index);
|
||||
|
||||
// ui::SimpleMenuModel:
|
||||
void MenuClosed() override;
|
||||
|
||||
private:
|
||||
Delegate* delegate_; // weak ref.
|
||||
|
||||
std::map<int, base::string16> roles_;
|
||||
ObserverList<Observer> observers_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMenuModel);
|
||||
|
|
|
@ -59,17 +59,4 @@ class MenuModel;
|
|||
|
||||
@end
|
||||
|
||||
// Exposed only for unit testing, do not call directly.
|
||||
@interface AtomMenuController (PrivateExposedForTesting)
|
||||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item;
|
||||
@end
|
||||
|
||||
// Protected methods that subclassers can override.
|
||||
@interface AtomMenuController (Protected)
|
||||
- (void)addItemToMenu:(NSMenu*)menu
|
||||
atIndex:(NSInteger)index
|
||||
fromModel:(ui::MenuModel*)model;
|
||||
- (NSMenu*)menuFromModel:(ui::MenuModel*)model;
|
||||
@end
|
||||
|
||||
#endif // ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_
|
||||
|
|
|
@ -8,16 +8,36 @@
|
|||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
#include "ui/base/accelerators/platform_accelerator_cocoa.h"
|
||||
#include "ui/base/l10n/l10n_util_mac.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
@interface AtomMenuController (Private)
|
||||
- (void)addSeparatorToMenu:(NSMenu*)menu
|
||||
atIndex:(int)index;
|
||||
@end
|
||||
namespace {
|
||||
|
||||
struct Role {
|
||||
SEL selector;
|
||||
const char* role;
|
||||
};
|
||||
Role kRolesMap[] = {
|
||||
{ @selector(orderFrontStandardAboutPanel:), "about" },
|
||||
{ @selector(hide:), "hide" },
|
||||
{ @selector(hideOtherApplications:), "hideothers" },
|
||||
{ @selector(unhideAllApplications:), "unhide" },
|
||||
{ @selector(arrangeInFront:), "front" },
|
||||
{ @selector(undo:), "undo" },
|
||||
{ @selector(redo:), "redo" },
|
||||
{ @selector(cut:), "cut" },
|
||||
{ @selector(copy:), "copy" },
|
||||
{ @selector(paste:), "paste" },
|
||||
{ @selector(selectAll:), "selectall" },
|
||||
{ @selector(performMiniaturize:), "minimize" },
|
||||
{ @selector(performClose:), "close" },
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@implementation AtomMenuController
|
||||
|
||||
|
@ -101,7 +121,9 @@
|
|||
// associated with the entry in the model identified by |modelIndex|.
|
||||
- (void)addItemToMenu:(NSMenu*)menu
|
||||
atIndex:(NSInteger)index
|
||||
fromModel:(ui::MenuModel*)model {
|
||||
fromModel:(ui::MenuModel*)ui_model {
|
||||
atom::AtomMenuModel* model = static_cast<atom::AtomMenuModel*>(ui_model);
|
||||
|
||||
base::string16 label16 = model->GetLabelAt(index);
|
||||
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
|
||||
base::scoped_nsobject<NSMenuItem> item(
|
||||
|
@ -124,13 +146,13 @@
|
|||
[submenu setTitle:[item title]];
|
||||
[item setSubmenu:submenu];
|
||||
|
||||
// Hack to set window and help menu.
|
||||
if ([[item title] isEqualToString:@"Window"] && [submenu numberOfItems] > 0)
|
||||
// Set submenu's role.
|
||||
base::string16 role = model->GetRoleAt(index);
|
||||
if (role == base::ASCIIToUTF16("window"))
|
||||
[NSApp setWindowsMenu:submenu];
|
||||
else if ([[item title] isEqualToString:@"Help"])
|
||||
else if (role == base::ASCIIToUTF16("help"))
|
||||
[NSApp setHelpMenu:submenu];
|
||||
if ([[item title] isEqualToString:@"Services"] &&
|
||||
[submenu numberOfItems] == 0)
|
||||
if (role == base::ASCIIToUTF16("services"))
|
||||
[NSApp setServicesMenu:submenu];
|
||||
} else {
|
||||
// The MenuModel works on indexes so we can't just set the command id as the
|
||||
|
@ -139,7 +161,6 @@
|
|||
// model. Setting the target to |self| allows this class to participate
|
||||
// in validation of the menu items.
|
||||
[item setTag:index];
|
||||
[item setTarget:self];
|
||||
NSValue* modelObject = [NSValue valueWithPointer:model];
|
||||
[item setRepresentedObject:modelObject]; // Retains |modelObject|.
|
||||
ui::Accelerator accelerator;
|
||||
|
@ -153,6 +174,19 @@
|
|||
platformAccelerator->modifier_mask()];
|
||||
}
|
||||
}
|
||||
|
||||
// Set menu item's role.
|
||||
base::string16 role = model->GetRoleAt(index);
|
||||
if (role.empty()) {
|
||||
[item setTarget:self];
|
||||
} else {
|
||||
for (const Role& pair : kRolesMap) {
|
||||
if (role == base::ASCIIToUTF16(pair.role)) {
|
||||
[item setAction:pair.selector];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[menu insertItem:item atIndex:index];
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/process/process_metrics.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
@ -61,6 +62,9 @@ void AtomBindings::BindTo(v8::Isolate* isolate,
|
|||
dict.SetMethod("crash", &Crash);
|
||||
dict.SetMethod("hang", &Hang);
|
||||
dict.SetMethod("log", &Log);
|
||||
#if defined(OS_POSIX)
|
||||
dict.SetMethod("setFdLimit", &base::SetFdLimit);
|
||||
#endif
|
||||
dict.SetMethod("activateUvLoop",
|
||||
base::Bind(&AtomBindings::ActivateUVLoop, base::Unretained(this)));
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#define ATOM_MAJOR_VERSION 0
|
||||
#define ATOM_MINOR_VERSION 31
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
|
||||
#define ATOM_VERSION_IS_RELEASE 1
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ REFERENCE_MODULE(atom_browser_power_monitor);
|
|||
REFERENCE_MODULE(atom_browser_power_save_blocker);
|
||||
REFERENCE_MODULE(atom_browser_protocol);
|
||||
REFERENCE_MODULE(atom_browser_global_shortcut);
|
||||
REFERENCE_MODULE(atom_browser_session);
|
||||
REFERENCE_MODULE(atom_browser_tray);
|
||||
REFERENCE_MODULE(atom_browser_web_contents);
|
||||
REFERENCE_MODULE(atom_browser_web_view_manager);
|
||||
|
|
|
@ -52,10 +52,6 @@ bool IsSwitchEnabled(base::CommandLine* command_line,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool IsGuestFrame(blink::WebFrame* frame) {
|
||||
return frame->uniqueName().utf8() == "ATOM_SHELL_GUEST_WEB_VIEW";
|
||||
}
|
||||
|
||||
// global.Uint8Array;
|
||||
v8::Local<v8::Function> GetUint8ArrayConstructor(
|
||||
v8::Isolate* isolate, v8::Local<v8::Context> context) {
|
||||
|
@ -113,8 +109,7 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
|
|||
|
||||
AtomRendererClient::AtomRendererClient()
|
||||
: node_bindings_(NodeBindings::Create(false)),
|
||||
atom_bindings_(new AtomBindings),
|
||||
main_frame_(nullptr) {
|
||||
atom_bindings_(new AtomBindings) {
|
||||
}
|
||||
|
||||
AtomRendererClient::~AtomRendererClient() {
|
||||
|
@ -189,14 +184,9 @@ bool AtomRendererClient::OverrideCreatePlugin(
|
|||
void AtomRendererClient::DidCreateScriptContext(
|
||||
blink::WebFrame* frame,
|
||||
v8::Handle<v8::Context> context) {
|
||||
// Only attach node bindings in main frame or guest frame.
|
||||
if (!IsGuestFrame(frame)) {
|
||||
if (main_frame_)
|
||||
return;
|
||||
|
||||
// The first web frame is the main frame.
|
||||
main_frame_ = frame;
|
||||
}
|
||||
// Only insert node integration for the main frame.
|
||||
if (frame->parent())
|
||||
return;
|
||||
|
||||
// Give the node loop a run to make sure everything is ready.
|
||||
node_bindings_->RunMessageLoop();
|
||||
|
@ -221,10 +211,6 @@ bool AtomRendererClient::ShouldFork(blink::WebFrame* frame,
|
|||
bool is_initial_navigation,
|
||||
bool is_server_redirect,
|
||||
bool* send_referrer) {
|
||||
// Never fork renderer process for guests.
|
||||
if (IsGuestFrame(frame))
|
||||
return false;
|
||||
|
||||
// Handle all the navigations and reloads in browser.
|
||||
// FIXME We only support GET here because http method will be ignored when
|
||||
// the OpenURLFromTab is triggered, which means form posting would not work,
|
||||
|
|
|
@ -64,9 +64,6 @@ class AtomRendererClient : public content::ContentRendererClient,
|
|||
scoped_ptr<NodeBindings> node_bindings_;
|
||||
scoped_ptr<AtomBindings> atom_bindings_;
|
||||
|
||||
// The main frame.
|
||||
blink::WebFrame* main_frame_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomRendererClient);
|
||||
};
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@ for arg in process.argv
|
|||
if arg.indexOf('--guest-instance-id=') == 0
|
||||
# This is a guest web view.
|
||||
process.guestInstanceId = parseInt arg.substr(arg.indexOf('=') + 1)
|
||||
# Set the frame name to make AtomRendererClient recognize this guest.
|
||||
require('web-frame').setName 'ATOM_SHELL_GUEST_WEB_VIEW'
|
||||
else if arg.indexOf('--node-integration=') == 0
|
||||
nodeIntegration = arg.substr arg.indexOf('=') + 1
|
||||
else if arg.indexOf('--preload=') == 0
|
||||
|
|
|
@ -94,14 +94,22 @@ window.confirm = (message, title='') ->
|
|||
window.prompt = ->
|
||||
throw new Error('prompt() is and will not be supported.')
|
||||
|
||||
# Simple implementation of postMessage.
|
||||
if ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_IS_GUEST_WINDOW'
|
||||
# Implement window.postMessage if current window is a guest window.
|
||||
guestId = ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID'
|
||||
if guestId?
|
||||
window.opener =
|
||||
postMessage: (message, targetOrigin='*') ->
|
||||
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', message, targetOrigin
|
||||
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', guestId, message, targetOrigin, location.origin
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (message, targetOrigin) ->
|
||||
window.postMessage message, targetOrigin
|
||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (guestId, message, sourceOrigin) ->
|
||||
# Manually dispatch event instead of using postMessage because we also need to
|
||||
# set event.source.
|
||||
event = document.createEvent 'Event'
|
||||
event.initEvent 'message', false, false
|
||||
event.data = message
|
||||
event.origin = sourceOrigin
|
||||
event.source = new BrowserWindowProxy(guestId)
|
||||
window.dispatchEvent event
|
||||
|
||||
# Forward history operations to browser.
|
||||
sendHistoryOperation = (args...) ->
|
||||
|
|
|
@ -220,64 +220,6 @@ PrintedDocument* PrintJob::document() const {
|
|||
return document_.get();
|
||||
}
|
||||
|
||||
void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
|
||||
if (document_.get() == new_document)
|
||||
return;
|
||||
|
||||
document_ = new_document;
|
||||
|
||||
if (document_.get()) {
|
||||
settings_ = document_->settings();
|
||||
}
|
||||
|
||||
if (worker_) {
|
||||
DCHECK(!is_job_pending_);
|
||||
// Sync the document with the worker.
|
||||
worker_->PostTask(FROM_HERE,
|
||||
base::Bind(&HoldRefCallback,
|
||||
make_scoped_refptr(this),
|
||||
base::Bind(&PrintJobWorker::OnDocumentChanged,
|
||||
base::Unretained(worker_.get()),
|
||||
document_)));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
|
||||
switch (event_details.type()) {
|
||||
case JobEventDetails::FAILED: {
|
||||
settings_.Clear();
|
||||
// No need to cancel since the worker already canceled itself.
|
||||
Stop();
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::USER_INIT_DONE:
|
||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
||||
case JobEventDetails::USER_INIT_CANCELED: {
|
||||
DCHECK_EQ(event_details.document(), document_.get());
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::NEW_DOC:
|
||||
case JobEventDetails::NEW_PAGE:
|
||||
case JobEventDetails::JOB_DONE:
|
||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
||||
// Don't care.
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::DOC_DONE: {
|
||||
// This will call Stop() and broadcast a JOB_DONE message.
|
||||
base::MessageLoop::current()->PostTask(
|
||||
FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::PAGE_DONE:
|
||||
break;
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
class PrintJob::PdfToEmfState {
|
||||
|
@ -375,6 +317,68 @@ void PrintJob::OnPdfToEmfPageConverted(int page_number,
|
|||
|
||||
#endif // OS_WIN
|
||||
|
||||
void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
|
||||
if (document_.get() == new_document)
|
||||
return;
|
||||
|
||||
document_ = new_document;
|
||||
|
||||
if (document_.get()) {
|
||||
settings_ = document_->settings();
|
||||
}
|
||||
|
||||
if (worker_) {
|
||||
DCHECK(!is_job_pending_);
|
||||
// Sync the document with the worker.
|
||||
worker_->PostTask(FROM_HERE,
|
||||
base::Bind(&HoldRefCallback,
|
||||
make_scoped_refptr(this),
|
||||
base::Bind(&PrintJobWorker::OnDocumentChanged,
|
||||
base::Unretained(worker_.get()),
|
||||
document_)));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
|
||||
switch (event_details.type()) {
|
||||
case JobEventDetails::FAILED: {
|
||||
settings_.Clear();
|
||||
// No need to cancel since the worker already canceled itself.
|
||||
Stop();
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::USER_INIT_DONE:
|
||||
case JobEventDetails::DEFAULT_INIT_DONE:
|
||||
case JobEventDetails::USER_INIT_CANCELED: {
|
||||
DCHECK_EQ(event_details.document(), document_.get());
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::NEW_DOC:
|
||||
case JobEventDetails::NEW_PAGE:
|
||||
case JobEventDetails::JOB_DONE:
|
||||
case JobEventDetails::ALL_PAGES_REQUESTED: {
|
||||
// Don't care.
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::DOC_DONE: {
|
||||
// This will call Stop() and broadcast a JOB_DONE message.
|
||||
base::MessageLoop::current()->PostTask(
|
||||
FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
|
||||
break;
|
||||
}
|
||||
case JobEventDetails::PAGE_DONE:
|
||||
#if defined(OS_WIN)
|
||||
ptd_to_emf_state_->OnPageProcessed(
|
||||
base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
|
||||
#endif // OS_WIN
|
||||
break;
|
||||
default: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJob::OnDocumentDone() {
|
||||
// Be sure to live long enough. The instance could be destroyed by the
|
||||
// JOB_DONE broadcast.
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
* [프로세스 객체](api/process.md)
|
||||
* [크롬 Command-Line 스위치 지원](api/chrome-command-line-switches.md)
|
||||
|
||||
커스텀 DOM Element:
|
||||
커스텀 DOM elements:
|
||||
|
||||
* [`File` 객체](api/file-object.md)
|
||||
* [`<webview>` 태그](api/web-view-tag.md)
|
||||
* [`window.open` 함수](api/window-open.md)
|
||||
* [`window.open` 메서드](api/window-open.md)
|
||||
|
||||
메인 프로세스를 위한 모듈들:
|
||||
|
||||
|
@ -40,6 +40,8 @@
|
|||
* [power-monitor](api/power-monitor.md)
|
||||
* [power-save-blocker](api/power-save-blocker.md)
|
||||
* [protocol](api/protocol.md)
|
||||
* [session](api/session.md)
|
||||
* [webContents](api/web-contents.md)
|
||||
* [tray](api/tray.md)
|
||||
|
||||
랜더러 프로세스를 위한 모듈들 (웹 페이지):
|
||||
|
@ -60,7 +62,7 @@
|
|||
|
||||
* [코딩 스타일](development/coding-style.md)
|
||||
* [소스 코드 디렉터리 구조](development/source-code-directory-structure.md)
|
||||
* [NW.js와 기술적으로 다른점 (이전 node-webkit)](development/atom-shell-vs-node-webkit.md)
|
||||
* [NW.js(node-webkit)와 기술적으로 다른점](development/atom-shell-vs-node-webkit.md)
|
||||
* [빌드 시스템 개요](development/build-system-overview.md)
|
||||
* [빌드 설명서 (Mac)](development/build-instructions-osx.md)
|
||||
* [빌드 설명서 (Windows)](development/build-instructions-windows.md)
|
||||
|
|
|
@ -17,7 +17,7 @@ Squirrel은 어플리케이션이 **안전하고 투명한 업데이트**를 제
|
|||
Squirrel은 사용자에게 어플리케이션의 업데이트를 알릴 필요 없이 서버가 지시하는 버전을 받아온 후 자동으로 업데이트합니다.
|
||||
이 기능을 사용하면 Squirrel을 통해 클라이언트의 어플리케이션을 지능적으로 업데이트 할 수 있습니다.
|
||||
|
||||
요청시 커스텀 헤더 또는 요청 본문에 인증 정보를 포함시킬 수도 있습니다.
|
||||
또한 요청시 커스텀 헤더 또는 요청 본문에 인증 정보를 포함시킬 수 있습니다.
|
||||
서버에선 이러한 요청을 분류 처리하여 적당한 업데이트를 제공할 수 있습니다.
|
||||
|
||||
Squirrel JSON 업데이트 요청시 처리는 반드시 어떤 업데이트가 필요한지 요청의 기준에 맞춰 동적으로 생성되어야 합니다.
|
||||
|
@ -76,6 +76,12 @@ Squirrel은 "url"로 `Accept: application/zip` 헤더와 함께 업데이트 zip
|
|||
|
||||
`pub_date`은 ISO 8601 표준에 따라 포맷된 날짜입니다.
|
||||
|
||||
## 업데이트 서버 구현
|
||||
|
||||
[Nuts](https://github.com/GitbookIO/nuts)는 위에서 설명한 업데이트 서버의 오픈 소스 구현입니다.
|
||||
이 구현은 Github 릴리즈와 완벽하게 통합되어 있습니다. Nuts는 `Squirrel.Mac`과 `Squirrel.Windows`를 지원하고 다운로드와 업데이트를 관리합니다.
|
||||
이 구현을 사용하면 cross-platform 지원을 신경 쓸 필요가 없습니다.
|
||||
|
||||
## Events
|
||||
|
||||
`autoUpdater` 객체는 다음과 같은 이벤트를 발생시킵니다:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# clipboard
|
||||
|
||||
`clipboard`는 복사/붙여넣기 작업을 수행하는 방법을 제공합니다. 다음 예제는 클립보드에 문자열을 씁니다:
|
||||
`clipboard` 모듈은 복사/붙여넣기 작업을 수행하는 방법을 제공합니다. 다음 예제는 클립보드에 문자열을 씁니다:
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
|
@ -15,59 +15,65 @@ clipboard.writeText('Example String', 'selection');
|
|||
console.log(clipboard.readText('selection'));
|
||||
```
|
||||
|
||||
## clipboard.readText([type])
|
||||
## Methods
|
||||
|
||||
* `type` String
|
||||
`clipboard` 모듈은 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
||||
**참고:** Experimental 마크가 붙은 API는 실험적인 기능이며 차후 최신 버전에서 제거될 수 있습니다.
|
||||
|
||||
### `clipboard.readText([type])`
|
||||
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드 컨텐츠를 `plain text`로 반환합니다.
|
||||
|
||||
## clipboard.writeText(text[, type])
|
||||
### `clipboard.writeText(text[, type])`
|
||||
|
||||
* `text` String
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드에 `plain text`로 문자열을 씁니다.
|
||||
|
||||
## clipboard.readHtml([type])
|
||||
### `clipboard.readHtml([type])`
|
||||
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드 컨텐츠를 `markup`으로 반환합니다.
|
||||
|
||||
## clipboard.writeHtml(markup[, type])
|
||||
### `clipboard.writeHtml(markup[, type])`
|
||||
|
||||
* `markup` String
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드에 `markup`으로 씁니다.
|
||||
|
||||
## clipboard.readImage([type])
|
||||
### `clipboard.readImage([type])`
|
||||
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드로부터 [NativeImage](native-image.md)로 이미지를 읽어들입니다.
|
||||
|
||||
## clipboard.writeImage(image[, type])
|
||||
### `clipboard.writeImage(image[, type])`
|
||||
|
||||
* `image` [NativeImage](native-image.md)
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드에 `image`를 씁니다.
|
||||
|
||||
## clipboard.clear([type])
|
||||
### `clipboard.clear([type])`
|
||||
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드에 저장된 모든 컨텐츠를 삭제합니다.
|
||||
|
||||
## clipboard.availableFormats([type])
|
||||
### clipboard.availableFormats([type])
|
||||
|
||||
클립보드의 `type`에 해당하는 지원하는 `format`을 문자열로 반환합니다.
|
||||
|
||||
## clipboard.has(data[, type])
|
||||
### `clipboard.has(data[, type])`
|
||||
|
||||
* `data` String
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드가 지정한 `data`의 형식을 지원하는지 확인합니다.
|
||||
|
||||
|
@ -76,24 +82,20 @@ var clipboard = require('clipboard');
|
|||
console.log(clipboard.has('<p>selection</p>'));
|
||||
```
|
||||
|
||||
**알림:** 이 API는 실험적인 기능이며 차후 최신버전에서 제외될 수 있습니다.
|
||||
|
||||
## clipboard.read(data[, type])
|
||||
### `clipboard.read(data[, type])` _Experimental_
|
||||
|
||||
* `data` String
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
클립보드로부터 `data`를 읽어들입니다.
|
||||
|
||||
**알림:** 이 API는 실험적인 기능이며 차후 최신버전에서 제외될 수 있습니다.
|
||||
|
||||
## clipboard.write(data[, type])
|
||||
### `clipboard.write(data[, type])` _Experimental_
|
||||
|
||||
* `data` Object
|
||||
* `text` String
|
||||
* `html` String
|
||||
* `image` [NativeImage](native-image.md)
|
||||
* `type` String
|
||||
* `type` String (optional)
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
|
|
|
@ -1,30 +1,35 @@
|
|||
# content-tracing
|
||||
# contentTracing
|
||||
|
||||
`content-trace` 모듈은 Chromium 컨텐츠 모듈단에서 생성된 데이터를 수집하고 추적하는데 사용됩니다.
|
||||
`content-tracing` 모듈은 Chromium 컨텐츠 모듈단에서 생성된 데이터를 수집하고 추적하는데 사용됩니다.
|
||||
이 모듈은 웹 인터페이스를 포함하고 있지 않으며 크롬 브라우저에서 `chrome://tracing/` 페이지를 열어 생성된 파일을 로드하면 결과를 볼 수 있습니다.
|
||||
|
||||
```javascript
|
||||
var tracing = require('content-tracing');
|
||||
tracing.startRecording('*', tracing.DEFAULT_OPTIONS, function() {
|
||||
var contentTracing = require('content-tracing');
|
||||
|
||||
contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() {
|
||||
console.log('Tracing started');
|
||||
|
||||
setTimeout(function() {
|
||||
tracing.stopRecording('', function(path) {
|
||||
contentTracing.stopRecording('', function(path) {
|
||||
console.log('Tracing data recorded to ' + path);
|
||||
});
|
||||
}, 5000);
|
||||
});
|
||||
```
|
||||
``
|
||||
|
||||
## tracing.getCategories(callback)
|
||||
## Methods
|
||||
|
||||
`content-tracing` 모듈은 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
||||
### `contentTracing.getCategories(callback)`
|
||||
|
||||
* `callback` Function
|
||||
|
||||
카테고리 그룹 세트를 가져옵니다. 카테고리 그룹은 도달된 코드 경로를 변경할 수 있습니다.
|
||||
|
||||
모든 child 프로세스가 `getCategories` 요청을 받으면 `callback`이 호출되며 인자에 카테고리 그룹의 배열이 전달됩니다.
|
||||
모든 child 프로세스가 `getCategories` 요청을 승인하면 `callback`이 한 번 호출되며 인자에 카테고리 그룹의 배열이 전달됩니다.
|
||||
|
||||
## tracing.startRecording(categoryFilter, traceOptions, callback)
|
||||
### `contentTracing.startRecording(categoryFilter, traceOptions, callback)`
|
||||
|
||||
* `categoryFilter` String
|
||||
* `traceOptions` String
|
||||
|
@ -33,7 +38,7 @@ tracing.startRecording('*', tracing.DEFAULT_OPTIONS, function() {
|
|||
모든 프로세스에서 레코딩을 시작합니다.
|
||||
|
||||
레코딩은 지역적으로 즉시 실행됩니다. 그리고 비동기로 child 프로세스는 곧 EnableRecording 요청을 받게 됩니다.
|
||||
모든 child 프로세스가 `startRecording` 요청을 받으면 `callback`이 호출됩니다.
|
||||
모든 child 프로세스가 `startRecording` 요청을 승인하면 `callback`이 한 번 호출됩니다.
|
||||
|
||||
`categoryFilter`는 어떤 카테고리 그룹이 트레이싱 되어야 하는지 필터링할 수 있습니다.
|
||||
필터는 `-` 접두사를 통해 특정 카테고리 그룹을 제외할 수 있습니다.
|
||||
|
@ -63,7 +68,7 @@ tracing.startRecording('*', tracing.DEFAULT_OPTIONS, function() {
|
|||
|
||||
`record-until-full`이 기본 모드, `enable-sampling`과 `enable-systrace`옵션은 포함되지 않음
|
||||
|
||||
## tracing.stopRecording(resultFilePath, callback)
|
||||
## `contentTracing.stopRecording(resultFilePath, callback)`
|
||||
|
||||
* `resultFilePath` String
|
||||
* `callback` Function
|
||||
|
@ -75,12 +80,12 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시
|
|||
우리는 추적에 의한 런타임 오버헤드를 피하고자 합니다.
|
||||
그래서 추적이 끝나면 모든 child 프로세스에 보류된 추적 데이터를 플러시 할 것인지 물어봅니다.
|
||||
|
||||
모든 child 프로세스가 `stopRecording` 요청을 받으면 `callback`에 추적 데이터를 포함한 파일을 전달됩니다.
|
||||
모든 child 프로세스가 `stopRecording` 요청을 승인하면 `callback`에 추적 데이터 파일을 포함하여 한 번 호출됩니다.
|
||||
|
||||
추적 데이터는 `resultFilePath` 해당 경로가 비어있는 경우에 한 해 해당 경로에 작성되거나 임시 파일에 작성됩니다.
|
||||
실제 파일 경로는 null이 아닌 이상 `callback`을 통해 전달됩니다.
|
||||
|
||||
## tracing.startMonitoring(categoryFilter, traceOptions, callback)
|
||||
### `contentTracing.startMonitoring(categoryFilter, traceOptions, callback)`
|
||||
|
||||
* `categoryFilter` String
|
||||
* `traceOptions` String
|
||||
|
@ -90,17 +95,17 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시
|
|||
|
||||
모니터링은 지역적으로 즉시 시작됩니다. 그리고 이내 자식 프로세스들이 `startMonitoring` 비동기 요청을 받습니다.
|
||||
|
||||
모든 자식 프로세스가 `startMonitoring` 요청을 받으면 `callback`이 호출됩니다.
|
||||
모든 자식 프로세스가 `startMonitoring` 요청을 승인하면 `callback`이 한 번 호출됩니다.
|
||||
|
||||
## tracing.stopMonitoring(callback);
|
||||
### `contentTracing.stopMonitoring(callback)`
|
||||
|
||||
* `callback` Function
|
||||
|
||||
모든 프로세스에서 모니터링을 중단합니다.
|
||||
|
||||
모든 자식 프로세스가 `stopMonitoring` 요청을 받으면 `callback`이 호출됩니다.
|
||||
모든 자식 프로세스가 `stopMonitoring` 요청을 승인하면 `callback`이 한 번 호출됩니다.
|
||||
|
||||
## tracing.captureMonitoringSnapshot(resultFilePath, callback)
|
||||
### `contentTracing.captureMonitoringSnapshot(resultFilePath, callback)`
|
||||
|
||||
* `resultFilePath` String
|
||||
* `callback` Function
|
||||
|
@ -112,15 +117,15 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시
|
|||
그리고 우리는 추적시 발생하는 불필요한 런타임 오버헤드를 피하고자 합니다.
|
||||
그래서 추적이 끝나면 반드시 비동기로 자식 프로세스들의 보류된 추적 데이터를 플러시 할 것인지 물어봅니다.
|
||||
|
||||
모든 자식 프로세스가 `captureMonitoringSnapshot` 요청을 받으면 추적 데이터 파일을 포함하는 `callback`이 호출됩니다.
|
||||
모든 자식 프로세스가 `captureMonitoringSnapshot` 요청을 승인하면 추적 데이터 파일을 포함하는 `callback`이 한 번 호출됩니다.
|
||||
|
||||
## tracing.getTraceBufferUsage(callback)
|
||||
### `contentTracing.getTraceBufferUsage(callback)`
|
||||
|
||||
* `callback` Function
|
||||
|
||||
추적 버퍼 % 전체 상태의 프로세스간 최대치를 가져옵니다. TraceBufferUsage 값이 결정되면 `callback`이 호출됩니다.
|
||||
추적 버퍼 % 전체 상태의 프로세스간 최대치를 가져옵니다. TraceBufferUsage 값이 결정되면 `callback`이 한 번 호출됩니다.
|
||||
|
||||
## tracing.setWatchEvent(categoryName, eventName, callback)
|
||||
### `contentTracing.setWatchEvent(categoryName, eventName, callback)`
|
||||
|
||||
* `categoryName` String
|
||||
* `eventName` String
|
||||
|
@ -128,6 +133,6 @@ Child 프로세스는 일반적으로 추적 데이터와 희귀한 플러시
|
|||
|
||||
`callback`은 지정된 이벤트가 어떤 작업을 발생시킬 때마다 호출됩니다.
|
||||
|
||||
## tracing.cancelWatchEvent()
|
||||
### `contentTracing.cancelWatchEvent()`
|
||||
|
||||
Watch 이벤트를 중단합니다. 만약 추적이 활성화되어 있다면 이 함수는 watch 이벤트 콜백과 race가 일어날 것입니다.
|
||||
Watch 이벤트를 중단합니다. 만약 추적이 활성화되어 있다면 이 메서드는 watch 이벤트 콜백과 race가 일어날 것입니다.
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
# crash-reporter
|
||||
# crashReporter
|
||||
|
||||
다음 예제는 윈격 서버에 어플리케이션 오류 정보를 자동으로 보고하는 예제입니다:
|
||||
`crash-reporter` 모듈은 어플리케이션의 크래시 정보를 자동으로 원격 서버에 업로드하는데 사용합니다.
|
||||
|
||||
다음 예제는 윈격 서버에 어플리케이션 크래시 정보를 자동으로 보고하는 예제입니다:
|
||||
|
||||
```javascript
|
||||
crashReporter = require('crash-reporter');
|
||||
var crashReporter = require('crash-reporter');
|
||||
|
||||
crashReporter.start({
|
||||
productName: 'YourName',
|
||||
companyName: 'YourCompany',
|
||||
|
@ -12,38 +15,42 @@ crashReporter.start({
|
|||
});
|
||||
```
|
||||
|
||||
## crashReporter.start(options)
|
||||
## Methods
|
||||
|
||||
* `options` Object
|
||||
* `productName` String, 기본값: Electron
|
||||
* `companyName` String, 기본값: GitHub, Inc
|
||||
* `submitUrl` String, 기본값: http://54.249.141.255:1127/post
|
||||
* Crash Reporter는 POST 방식으로 해당 URL에 전송됩니다.
|
||||
* `autoSubmit` Boolean, 기본값: true
|
||||
* true로 지정할 경우 유저의 승인 없이 자동으로 오류를 보고합니다.
|
||||
* `ignoreSystemCrashHandler` Boolean, 기본값: false
|
||||
* `extra` Object
|
||||
* 오류보고 시 같이 보낼 추가 정보를 지정하는 객체입니다.
|
||||
* 문자열로 된 속성만 정상적으로 보내집니다.
|
||||
* 중첩 객체는 지원되지 않습니다. (Nested objects are not supported)
|
||||
`crash-reporter` 모듈은 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
||||
### `crashReporter.start(options)`
|
||||
|
||||
* `options` Object, properties:
|
||||
|
||||
* `productName` String, 기본값: Electron
|
||||
* `companyName` String, 기본값: GitHub, Inc
|
||||
* `submitUrl` String, 기본값: http://54.249.141.255:1127/post
|
||||
* 크래시 리포트는 POST 방식으로 이 URL로 전송됩니다.
|
||||
* `autoSubmit` Boolean, 기본값: true
|
||||
* true로 지정할 경우 유저의 승인 없이 자동으로 오류를 보고합니다.
|
||||
* `ignoreSystemCrashHandler` Boolean, 기본값: false
|
||||
* `extra` Object
|
||||
* 크래시 리포트 시 같이 보낼 추가 정보를 지정하는 객체입니다.
|
||||
* 문자열로 된 속성만 정상적으로 보내집니다.
|
||||
* 중첩 객체는 지원되지 않습니다. (Nested objects are not supported)
|
||||
|
||||
다른 crashReporter API들을 사용하기 전에 이 함수를 먼저 호출해야 합니다.
|
||||
다른 crashReporter API를 사용하기 전에 이 메서드를 먼저 호출해야 합니다.
|
||||
|
||||
|
||||
**알림:** OS X에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad` 클라이언트를 사용합니다.
|
||||
**참고:** OS X에선 Windows와 Linux의 `breakpad`와 달리 새로운 `crashpad` 클라이언트를 사용합니다.
|
||||
오류 수집 기능을 활성화 시키려면 오류를 수집하고 싶은 메인 프로세스나 랜더러 프로세스에서
|
||||
`crashReporter.start` 함수를 호출하여 `crashpad`를 초기화 해야합니다.
|
||||
`crashReporter.start` 메서드를 호출하여 `crashpad`를 초기화 해야합니다.
|
||||
|
||||
## crashReporter.getLastCrashReport()
|
||||
### `crashReporter.getLastCrashReport()`
|
||||
|
||||
마지막 오류보고의 날짜와 ID를 반환합니다.
|
||||
이전 오류보고가 없거나 Crash Reporter가 시작되지 않았을 경우 `null`이 반환됩니다.
|
||||
마지막 크래시 리포트의 날짜와 ID를 반환합니다.
|
||||
이전 크래시 리포트가 없거나 Crash Reporter가 시작되지 않았을 경우 `null`이 반환됩니다.
|
||||
|
||||
## crashReporter.getUploadedReports()
|
||||
### `crashReporter.getUploadedReports()`
|
||||
|
||||
모든 업로드된 오류보고를 반환합니다. 각 보고는 날짜와 업로드 ID를 포함하고 있습니다.
|
||||
모든 업로드된 크래시 리포트를 반환합니다. 각 보고는 날짜와 업로드 ID를 포함하고 있습니다.
|
||||
|
||||
# crash-reporter 오류보고 형식
|
||||
## crash-reporter 업로드 형식
|
||||
|
||||
Crash Reporter는 다음과 같은 데이터를 `submitUrl`에 `POST` 방식으로 전송합니다:
|
||||
|
||||
|
@ -56,5 +63,5 @@ Crash Reporter는 다음과 같은 데이터를 `submitUrl`에 `POST` 방식으
|
|||
* `_productName` String - Crash Reporter의 `options` 객체에서 정의한 제품명.
|
||||
* `prod` String - 기본 제품의 이름. 이 경우 Electron으로 표시됩니다.
|
||||
* `_companyName` String - Crash Reporter의 `options` 객체에서 정의한 회사명.
|
||||
* `upload_file_minidump` File - 오류보고 파일
|
||||
* `upload_file_minidump` File - 크래시 리포트 파일
|
||||
* Crash Reporter의 `options` 객체에서 정의한 `extra` 객체의 속성들.
|
||||
|
|
|
@ -1,34 +1,39 @@
|
|||
# dialog
|
||||
|
||||
`dialog` 모듈은 네이티브 시스템의 대화 상자를 조작할 때 사용할 수 있는 API입니다.
|
||||
웹 어플리케이션에서 일반 네이티브 어플리케이션과 같은 사용자 경험을 제공할 수 있습니다.
|
||||
`dialog` 모듈은 파일 열기, 알림과 같은 네이티브 시스템의 대화 상자를 조작할 때 사용할 수 있는 모듈입니다.
|
||||
이 모듈을 사용하면 웹 어플리케이션에서 일반 네이티브 어플리케이션과 비슷한 사용자 경험을 제공할 수 있습니다.
|
||||
|
||||
다음 예제는 파일과 디렉터리를 다중으로 선택하는 대화 상자를 표시하는 예제입니다:
|
||||
|
||||
```javascript
|
||||
var win = ...; // 대화 상자를 사용할 창 객체
|
||||
var win = ...; // 대화 상자를 사용할 BrowserWindow 객체
|
||||
var dialog = require('dialog');
|
||||
console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]}));
|
||||
```
|
||||
|
||||
**OS X 주의**: 대화 상자를 시트처럼 보여지게 하려면 `browserWindow` 인자에 `BrowserWindow` 객체의 참조를 제공하면 됩니다.
|
||||
**OS X 알림**: 대화 상자를 시트처럼 보여지게 하려면 `browserWindow` 인자에 `BrowserWindow` 객체의 참조를 제공하면 됩니다.
|
||||
|
||||
## dialog.showOpenDialog([browserWindow], [options], [callback])
|
||||
## Methods
|
||||
|
||||
* `browserWindow` BrowserWindow
|
||||
* `options` Object
|
||||
`dialog` 모듈은 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
||||
### `dialog.showOpenDialog([browserWindow][, options][, callback])`
|
||||
|
||||
* `browserWindow` BrowserWindow (optional)
|
||||
* `options` Object (optional)
|
||||
* `title` String
|
||||
* `defaultPath` String
|
||||
* `filters` Array
|
||||
* `properties` Array - 대화 상자가 사용할 기능(모드)이 담긴 배열입니다.
|
||||
다음을 포함할 수 있습니다: `openFile`, `openDirectory`, `multiSelections`, `createDirectory`
|
||||
* `callback` Function
|
||||
* `callback` Function (optional)
|
||||
|
||||
사용할 대화 상자의 기능이 담긴 배열입니다. 다음을 포함할 수 있습니다: `openFile`, `openDirectory`, `multiSelections`, `createDirectory`
|
||||
|
||||
작업에 성공하면 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외의 경우엔 `undefined`를 반환합니다.
|
||||
작업에 성공하면 콜백으로 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외엔 `undefined`를 반환합니다.
|
||||
|
||||
`filters`를 지정하면 유저가 선택 가능한 파일 형식을 지정할 수 있습니다. 예제는 다음과 같습니다:
|
||||
`filters`를 지정하면 유저가 선택 가능한 파일 형식을 지정할 수 있습니다.
|
||||
유저가 선택할 수 있는 타입에 제한을 두려면 다음과 같이 할 수 있습니다:
|
||||
|
||||
```javascript
|
||||
{
|
||||
|
@ -42,32 +47,30 @@ console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', '
|
|||
```
|
||||
|
||||
`extensions` 배열은 반드시 와일드카드와 마침표를 제외한 파일 확장자를 포함시켜야 합니다.
|
||||
예를 들어 `'png'`는 가능하지만 `'.png'`와 `'*.png'`는 안됩니다.
|
||||
(예를 들어 `'png'`는 가능하지만 `'.png'`와 `'*.png'`는 안됩니다)
|
||||
모든 파일을 보여주려면 `'*'`와 같은 와일드카드를 사용하면 됩니다. (다른 와일드카드는 지원하지 않습니다)
|
||||
|
||||
`callback`이 전달되면 메소드가 비동기로 작동되며 결과는 `callback(filenames)`을 통해 전달됩니다.
|
||||
|
||||
Windows와 Linux에선 파일 선택 모드, 디렉터리 선택 모드를 동시에 사용할 수 없습니다.
|
||||
그래서 이 두 플랫폼에선 `properties`를 `['openFile', 'openDirectory']`로 설정하면 디렉터리 선택 대화 상자가 표시됩니다.
|
||||
**참고:** Windows와 Linux에선 파일 선택 모드, 디렉터리 선택 모드를 동시에 사용할 수 없습니다.
|
||||
이러한 이유로 `properties`를 `['openFile', 'openDirectory']`로 설정하면 디렉터리 선택 대화 상자가 표시됩니다.
|
||||
|
||||
## dialog.showSaveDialog([browserWindow], [options], [callback])
|
||||
### `dialog.showSaveDialog([browserWindow][, options][, callback])`
|
||||
|
||||
* `browserWindow` BrowserWindow
|
||||
* `options` Object
|
||||
* `browserWindow` BrowserWindow (optional)
|
||||
* `options` Object (optional)
|
||||
* `title` String
|
||||
* `defaultPath` String
|
||||
* `filters` Array
|
||||
* `callback` Function
|
||||
* `callback` Function (optional)
|
||||
|
||||
작업에 성공하면
|
||||
|
||||
작업에 성공하면 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외의 경우엔 `undefined`를 반환합니다.
|
||||
작업에 성공하면 콜백으로 유저가 선택한 파일의 경로를 포함한 배열을 반환합니다. 그 외엔 `undefined`를 반환합니다.
|
||||
|
||||
`filters`를 지정하면 유저가 저장 가능한 파일 형식을 지정할 수 있습니다. 사용 방법은 `dialog.showOpenDialog`의 `filters` 속성과 같습니다.
|
||||
|
||||
`callback`이 전달되면 메소드가 비동기로 작동되며 결과는 `callback(filename)`을 통해 전달됩니다.
|
||||
|
||||
## dialog.showMessageBox([browserWindow], options, [callback])
|
||||
### `dialog.showMessageBox([browserWindow][, options][, callback])`
|
||||
|
||||
* `browserWindow` BrowserWindow
|
||||
* `options` Object
|
||||
|
@ -78,26 +81,26 @@ Windows와 Linux에선 파일 선택 모드, 디렉터리 선택 모드를 동
|
|||
* `message` String - 대화 상자의 본문 내용입니다.
|
||||
* `detail` String - 메시지의 추가 정보입니다.
|
||||
* `icon` [NativeImage](native-image.md)
|
||||
* `cancelId` Integer - 유저가 대화 상자의 버튼을 클릭하지 않고 대화 상자를 취소했을 때 반환되는 버튼의 index입니다.
|
||||
기본적으로 버튼 리스트가 "cancel" 또는 "no" 라벨을 가지고 있을 때 해당 버튼의 index를 반환합니다. 따로 두 라벨이 지정되지 않은 경우 0을 반환합니다.
|
||||
* `cancelId` Integer - 유저가 대화 상자의 버튼을 클릭하지 않고 대화 상자를 취소했을 때 반환되는 버튼의 인덱스입니다.
|
||||
기본적으로 버튼 리스트가 "cancel" 또는 "no" 라벨을 가지고 있을 때 해당 버튼의 인덱스를 반환합니다. 따로 두 라벨이 지정되지 않은 경우 0을 반환합니다.
|
||||
OS X와 Windows에선 `cancelId` 지정 여부에 상관없이 "Cancel" 버튼이 언제나 `cancelId`로 지정됩니다.
|
||||
* `noLink` Boolean - Windows Electron은 "Cancel"이나 "Yes"와 같은 흔히 사용되는 버튼을 찾으려고 시도하고
|
||||
대화 상자 내에서 해당 버튼을 커맨드 링크처럼 만듭니다. 이 기능으로 앱을 좀 더 Modern Windows 앱처럼 만들 수 있습니다.
|
||||
이 기능을 원하지 않으면 `noLink`를 true로 지정하면 됩니다.
|
||||
* `callback` Function
|
||||
|
||||
대화 상자를 표시합니다. `browserWindow`를 지정하면 대화 상자가 완전히 닫힐 때까지는 창을 사용할 수 없습니다.
|
||||
완료시 유저가 선택한 버튼의 index를 반환합니다.
|
||||
대화 상자를 표시합니다. `browserWindow`를 지정하면 대화 상자가 완전히 닫힐 때까지 지정한 창을 사용할 수 없습니다.
|
||||
완료 시 유저가 선택한 버튼의 인덱스를 반환합니다.
|
||||
|
||||
역주: 부정을 표현하는 "아니오", "취소"와 같은 한글 단어는 지원되지 않습니다.
|
||||
만약 OS X 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지정하게 될 때 Alt + f4로 해당 대화 상자를 끄게 되면 "확인"을 누른걸로 판단되어 버립니다.
|
||||
만약 OS X 또는 Windows에서 "확인", "취소"와 같은 순서로 버튼을 지정하게 될 때 Alt + f4로 해당 대화 상자를 끄게 되면 "확인"을 누른 것으로 판단되어 버립니다.
|
||||
이를 해결하려면 "Cancel"을 대신 사용하거나 BrowserWindow API를 사용하여 대화 상자를 직접 구현해야합니다.
|
||||
|
||||
`callback`이 전달되면 메소드가 비동기로 작동되며 결과는 `callback(response)`을 통해 전달됩니다.
|
||||
|
||||
## dialog.showErrorBox(title, content)
|
||||
### `dialog.showErrorBox(title, content)`
|
||||
|
||||
에러 메시지를 보여주는 모달 대화 상자를 표시합니다.
|
||||
에러 메시지를 보여주는 대화 상자를 표시합니다.
|
||||
|
||||
이 API는 `app` 모듈의 `ready` 이벤트가 발생하기 전에 사용할 수 있습니다.
|
||||
이 메소드는 보통 어플리케이션이 시작되기 전에 특정한 에러를 표시하기 위해 사용됩니다.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
# `File` 객체
|
||||
|
||||
DOM의 File 인터페이스는 네이티브 파일을 추상화 합니다. 유저가 직접적으로 HTML5 File API를 사용하여 작업할 때 파일의 경로를
|
||||
알 수 있도록 Electron은 파일시스템의 실제 파일 경로를 담은 `path` 속성을 File 인터페이스에 추가하였습니다.
|
||||
DOM의 File 인터페이스는 네이티브 파일을 추상화 합니다.
|
||||
유저가 직접 HTML5 File API를 이용하여 작업할 때 선택된 파일의 경로를 알 수 있도록
|
||||
Electron은 파일의 실제 경로를 담은 `path` 속성을 File 인터페이스에 추가하였습니다.
|
||||
|
||||
다음 예제는 drag n drop한 파일의 실제 경로를 가져옵니다:
|
||||
다음 예제는 앱으로 드래그 앤 드롭한 파일의 실제 경로를 가져옵니다:
|
||||
|
||||
```html
|
||||
<div id="holder">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# Frameless 윈도우
|
||||
# Frameless Window
|
||||
|
||||
Frameless 윈도우는 테두리가 없는 윈도우 창을 말합니다.
|
||||
Frameless Window는 [테두리](https://developer.mozilla.org/en-US/docs/Glossary/Chrome)가 없는 창입니다.
|
||||
이 기능은 윈도우 창의 일부분인 툴바와 같이 웹 페이지의 일부분이 아닌 부분을 보이지 않도록 합니다.
|
||||
[`BrowserWindow`](browser-window.md) 클래스의 옵션에서 설정할 수 있습니다.
|
||||
|
||||
## Frameless 윈도우 만들기
|
||||
## Frameless Window 만들기
|
||||
|
||||
Frameless 윈도우를 만드려면 [BrowserWindow](browser-window.md) 객체의 `options`에서 `frame` 옵션을 `false`로 지정하기만 하면됩니다:
|
||||
Frameless Window를 만드려면 [BrowserWindow](browser-window.md) 객체의 `options`에서 `frame` 옵션을 `false`로 지정하면 됩니다:
|
||||
|
||||
```javascript
|
||||
var BrowserWindow = require('browser-window');
|
||||
|
@ -13,7 +15,7 @@ var win = new BrowserWindow({ width: 800, height: 600, frame: false });
|
|||
|
||||
## 투명한 창 만들기
|
||||
|
||||
Frameless 윈도우의 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`로 바꿔주기만 하면됩니다:
|
||||
Frameless Window의 창의 배경을 투명하게 만들고 싶다면 `transparent` 옵션을 `true`로 바꿔주기만 하면됩니다:
|
||||
|
||||
```javascript
|
||||
var win = new BrowserWindow({ transparent: true, frame: false });
|
||||
|
@ -21,22 +23,20 @@ var win = new BrowserWindow({ transparent: true, frame: false });
|
|||
|
||||
### API의 한계
|
||||
|
||||
|
||||
|
||||
* 투명한 영역을 통과하여 클릭할 수 없습니다. 우리는 이 문제를 해결하기 위해 API를 제공할 예정이지만 현재로써는
|
||||
* 투명한 영역을 통과하여 클릭할 수 없습니다. 우리는 이 문제를 해결하기 위해 API를 제공할 예정이었지만 현재로써는
|
||||
[upstream 버그](https://code.google.com/p/chromium/issues/detail?id=387234)로 인해 중단된 상태입니다.
|
||||
* 투명한 창은 크기를 조절할 수 없습니다. `resizable` 속성을 `true`로 할 경우 몇몇 플랫폼에선 윈도우 크래시가 일어납니다.
|
||||
* `blur` 필터는 웹 페이지에서만 적용됩니다. 윈도우 아래 컨텐츠에는 블러 효과를 적용할 방법이 없습니다.
|
||||
* Windows에선 DWM(데스크톱 창 관리자)가 비활성화되어 있을 경우 작동하지 않습니다.
|
||||
* Linux를 사용할 경우 [alpha channel doesn't work on some NVidia drivers](https://code.google.com/p/chromium/issues/detail?id=369209)
|
||||
upstream 버그가 있으므로 CLI 옵션에 `--enable-transparent-visuals --disable-gpu`을 추가해야 합니다.
|
||||
* 투명한 창은 크기를 조절할 수 없습니다. `resizable` 속성을 `true`로 할 경우 몇몇 플랫폼에선 크래시가 일어납니다.
|
||||
* `blur` 필터는 웹 페이지에서만 적용됩니다. 윈도우 아래 컨텐츠에는 블러 효과를 적용할 방법이 없습니다. (예시: 유저의 시스템에 열린 다른 어플리케이션)
|
||||
* Windows에선 DWM(데스크톱 창 관리자)가 비활성화되어 있을 경우 투명한 창이 작동하지 않습니다.
|
||||
* Linux를 사용할 경우 [alpha channel doesn't work on some NVidia drivers](https://code.google.com/p/chromium/issues/detail?id=369209)
|
||||
upstream 버그가 있는 관계로 투명한 창 기능을 사용하려면 CLI 옵션에 `--enable-transparent-visuals --disable-gpu`을 추가해야 합니다.
|
||||
이 옵션은 GPU의 사용을 중단하고 윈도우를 생성하는데 ARGB를 사용할 수 있도록 해줍니다.
|
||||
* OS X(Mac)에선 네이티브 윈도우의 그림자가 투명한 창에선 보이지 않습니다.
|
||||
* OS X(Mac)에선 네이티브 창에서 보여지는 그림자가 투명한 창에선 보이지 않습니다.
|
||||
|
||||
## 드래그 가능 위치 지정
|
||||
|
||||
기본적으로 Frameless 윈도우는 드래그 할 수 없습니다.
|
||||
어플리케이션의 CSS에서 특정 범위를 `-webkit-app-region: drag`로 지정하면 OS의 기본 타이틀바 처럼 드래그 되도록 할 수 있습니다.
|
||||
기본적으로 Frameless Window는 드래그 할 수 없습니다.
|
||||
어플리케이션의 CSS에서 특정 범위를 `-webkit-app-region: drag`로 지정하면 OS의 기본 타이틀 바 처럼 드래그 되도록 할 수 있습니다.
|
||||
그리고 `-webkit-app-region: no-drag`를 지정해서 드래그 불가능 영역을 만들 수도 있습니다. 현재 사각형 형태의 범위만 지원합니다.
|
||||
|
||||
창 전체를 드래그 가능하게 만드려면 `-webkit-app-region: drag`을 `body`의 스타일에 지정하면 됩니다:
|
||||
|
@ -54,13 +54,13 @@ button {
|
|||
}
|
||||
```
|
||||
|
||||
또한 커스텀 타이틀바를 만들어 사용할 때 타이틀바 내부의 버튼도 드래그 불가능 영역으로 지정해야 합니다.
|
||||
따로 커스텀 타이틀 바를 만들어 사용할 때는 타이틀 바 내부의 모든 버튼을 드래그 불가능 영역으로 지정해야 합니다.
|
||||
|
||||
## 텍스트 선택
|
||||
|
||||
한가지, Frameless 윈도우에서 텍스트가 선택되는 드래그 동작은 혼란을 야기할 수 있습니다.
|
||||
예를 들어 타이틀바를 드래그 할 때 타이틀바의 텍스트를 실수로 선택할 수 있습니다.
|
||||
이를 방지하기 위해선 다음과 같이 드래그 영역의 텍스트 선택 동작을 비활성화해야 할 필요가 있습니다:
|
||||
Frameless Window에서 텍스트가 선택되는 드래그 동작은 혼란을 야기할 수 있습니다.
|
||||
예를 들어 타이틀 바를 드래그 할 때 타이틀 바의 텍스트를 실수로 선택할 수 있습니다.
|
||||
이를 방지하기 위해 다음과 같이 드래그 영역의 텍스트 선택 기능을 비활성화해야 할 필요가 있습니다:
|
||||
|
||||
```css
|
||||
.titlebar {
|
||||
|
@ -71,5 +71,5 @@ button {
|
|||
|
||||
## 컨텍스트 메뉴
|
||||
|
||||
몇몇 플랫폼에선 드래그 가능 영역이 non-client 프레임으로 처리됩니다. 그래서 이 영역에서 오른쪽 클릭을 할 경우 시스템 메뉴가 팝업 됩니다.
|
||||
그래서 컨텍스트 메뉴 지정이 모든 플랫폼에서 정상적으로 작동하게 하려면 커스텀 컨텍스트 메뉴를 드래그 영역 내에 만들어선 안됩니다.
|
||||
몇몇 플랫폼에선 드래그 가능 영역이 non-client 프레임으로 처리됩니다. 이러한 플랫폼에선 드래그 가능 영역에서 오른쪽 클릭 할 경우 시스템 메뉴가 팝업 됩니다.
|
||||
이러한 이유로 컨텍스트 메뉴 지정 시 모든 플랫폼에서 정상적으로 작동하게 하려면 커스텀 컨텍스트 메뉴를 드래그 영역 내에 만들어선 안됩니다.
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# global-shortcut
|
||||
|
||||
`global-shortcut` 모듈은 운영체제의 전역 키보드 단축키를 설정 등록/해제 하는 방법을 제공합니다.
|
||||
`global-shortcut` 모듈은 운영체제의 전역 키보드 단축키를 등록/해제 하는 방법을 제공합니다.
|
||||
이 모듈을 사용하여 사용자가 다양한 단축키 작업을 할 수 있도록 단축키를 정의 할 수 있습니다.
|
||||
참고로 설정된 단축키는 어플리케이션이 백그라운드로 작동(창이 포커스 되지 않음) 할 때도 여전히 계속 작동합니다.
|
||||
|
||||
**참고:** 등록된 단축키는 어플리케이션이 백그라운드로 작동(창이 포커스 되지 않음) 할 때도 계속해서 작동합니다.
|
||||
이 모듈은 `app` 모듈의 `ready` 이벤트 이전에 사용할 수 없습니다.
|
||||
|
||||
```javascript
|
||||
|
@ -30,25 +31,29 @@ app.on('will-quit', function() {
|
|||
});
|
||||
```
|
||||
|
||||
## globalShortcut.register(accelerator, callback)
|
||||
## Methods
|
||||
|
||||
`global-shortcut` 모듈은 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
||||
### `globalShortcut.register(accelerator, callback)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
* `callback` Function
|
||||
|
||||
`accelerator`로 표현된 전역 단축키를 등록합니다. 유저로부터 등록된 단축키가 눌렸을 경우 `callback` 함수가 호출됩니다.
|
||||
|
||||
## globalShortcut.isRegistered(accelerator)
|
||||
### `globalShortcut.isRegistered(accelerator)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
|
||||
지정된 `accelerator` 단축키가 등록되었는지 여부를 확인합니다. 반환값은 boolean(true, false) 입니다.
|
||||
|
||||
## globalShortcut.unregister(accelerator)
|
||||
### `globalShortcut.unregister(accelerator)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
|
||||
`키코드`에 해당하는 전역 단축키를 등록 해제합니다.
|
||||
`accelerator`에 해당하는 전역 단축키를 등록 해제합니다.
|
||||
|
||||
## globalShortcut.unregisterAll()
|
||||
### `globalShortcut.unregisterAll()`
|
||||
|
||||
모든 전역 단축키 등록을 해제합니다.
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
# ipc (main process)
|
||||
|
||||
랜더러 프로세스(웹 페이지)로 부터 동기 또는 비동기로 메시지를 받아 처리합니다.
|
||||
`ipc` (main process) 모듈은 메인 프로세스에서 사용할 때 랜더러 프로세스(웹 페이지)에서 전달된 동기 또는 비동기 메시지를 보내고 받는 방법을 제공합니다.
|
||||
랜더러 프로세스에서 메시지를 전달하면 이 모듈을 통해 메시지를 받을 수 있습니다.
|
||||
|
||||
랜더러로부터 발신된 메시지들은 모두 이 모듈에서 `channel` 이라는 특정 이벤트 이름을 통해 수신할 수 있습니다.
|
||||
동기 메시지는 `event.returnValue`를 이용하여 반환값(답장)을 설정할 수 있습니다. 비동기 메시지라면 `event.sender.send(...)`를 사용하면 됩니다.
|
||||
## 메시지 전송
|
||||
|
||||
또한 메인 프로세스에서 랜더러 프로세스로 메시지를 보내는 것도 가능합니다.
|
||||
자세한 내용은 [WebContents.send](browser-window.md#webcontentssendchannel-args)를 참고 하세요.
|
||||
물론 메인 프로세스에서 랜더러 프로세스로 메시지를 보내는 것도 가능합니다.
|
||||
자세한 내용은 [WebContents.send](browser-window.md#webcontentssendchannel-args)를 참고하세요.
|
||||
|
||||
보내진 메시지들을 처리하는 예제입니다:
|
||||
- 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다.
|
||||
- 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다.
|
||||
- 메시지를 비동기로 응답할 땐 `event.sender.send(...)` 메서드를 사용할 수 있습니다.
|
||||
|
||||
랜더러 프로세스와 메인 프로세스간에 메시지를 전달하고 받는 예제입니다:
|
||||
|
||||
```javascript
|
||||
// 메인 프로세스에서 처리.
|
||||
// 메인 프로세스
|
||||
var ipc = require('ipc');
|
||||
ipc.on('asynchronous-message', function(event, arg) {
|
||||
console.log(arg); // prints "ping"
|
||||
|
@ -25,7 +29,7 @@ ipc.on('synchronous-message', function(event, arg) {
|
|||
```
|
||||
|
||||
```javascript
|
||||
// 랜더러 프로세스에서의 처리 (web page).
|
||||
// 랜더러 프로세스 (web page)
|
||||
var ipc = require('ipc');
|
||||
console.log(ipc.sendSync('synchronous-message', 'ping')); // prints "pong"
|
||||
|
||||
|
@ -35,12 +39,33 @@ ipc.on('asynchronous-reply', function(arg) {
|
|||
ipc.send('asynchronous-message', 'ping');
|
||||
```
|
||||
|
||||
## Class: Event
|
||||
## 메시지 리스닝
|
||||
|
||||
### Event.returnValue
|
||||
`ipc` 모듈은 다음과 같은 이벤트 메서드를 가지고 있습니다:
|
||||
|
||||
동기 메시지를 설정합니다.
|
||||
### `ipc.on(channel, callback)`
|
||||
|
||||
### Event.sender
|
||||
* `channel` String - 이벤트 이름
|
||||
* `callback` Function
|
||||
|
||||
메시지를 보내온 sender `WebContents` 객체입니다.
|
||||
이벤트가 발생하면 `callback`에 `event` 객체와 `arg` 메시지가 포함되어 호출됩니다.
|
||||
|
||||
## IPC Events
|
||||
|
||||
`callback`에서 전달된 `event` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다:
|
||||
|
||||
### `Event.returnValue`
|
||||
|
||||
이 메시지를 지정하면 동기 메시지를 전달합니다.
|
||||
|
||||
### `Event.sender`
|
||||
|
||||
메시지를 보낸 `WebContents` 객체를 반환합니다.
|
||||
|
||||
### `Event.sender.send(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
* `channel` String - The event name.
|
||||
* `arg` (optional)
|
||||
|
||||
랜더러 프로세스로 비동기 메시지를 전달합니다.
|
||||
옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다.
|
||||
|
|
|
@ -1,25 +1,45 @@
|
|||
# ipc (renderer)
|
||||
|
||||
`ipc` 모듈은 메인 프로세스로 메시지를 동기 또는 비동기로 보내고 받을 수 있는 몇 가지 방법을 제공합니다.
|
||||
만약 랜더러 프로세스에서 메인 프로세스의 모듈을 직접적으로 사용하고 싶다면 [remote](remote.md) 모듈을 사용하는 것을 고려해보는 것이 좋습니다.
|
||||
`ipc` (renderer) 모듈은 메인 프로세스로 동기 또는 비동기 메시지를 보내고 받는 방법을 제공합니다.
|
||||
물론 메인 프로세스로부터 받은 메시지에 응답할 수도 있습니다.
|
||||
|
||||
[ipc (main process)](ipc-main-process.md)에서 예제를 볼 수 있습니다.
|
||||
**참고:** 만약 랜더러 프로세스에서 메인 프로세스의 모듈을 직접적 사용하고 싶다면 [remote](remote.md) 모듈을 사용하는 것을 고려해보는 것이 좋습니다.
|
||||
|
||||
## ipc.send(channel[, args...])
|
||||
[ipc (main process)](ipc-main-process.md)에서 예제를 확인 할 수 있습니다.
|
||||
|
||||
지정한 `channel`을 통해 `args..`를 비동기로 메시지를 보냅니다. 메인 프로세스는 `ipc` 모듈의 `channel` 이벤트를 통해 메시지를 받을 수 있습니다.
|
||||
## Methods
|
||||
|
||||
## ipc.sendSync(channel[, args...])
|
||||
`ipc` 모듈은 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
||||
지정한 `channel`을 통해 `args..`를 동기로 메시지를 보냅니다. 그리고 메인 프로세스에서 보낸 결과를 반환합니다.
|
||||
메인 프로세스는 `ipc` 모듈의 `channel` 이벤트를 통해 메시지를 받을 수 있습니다. 그리고 `event.returnValue`를 통해 반환값을 설정할 수 있습니다.
|
||||
**참고:** 이 메소드들을 사용하여 `message`를 보낼 땐 반드시 메인 프로세스의
|
||||
[`ipc (main process)`](ipc-main-process.md) 모듈에서도 이벤트 리스너를 등록해 두어야 합니다.
|
||||
|
||||
역자 주: `channel`은 이벤트 이름입니다.
|
||||
### `ipc.send(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
**알림:** 보통 개발자들은 해당 API를 사용하려 하지 않습니다. 동기 ipc 작업은 랜더러 프로세스의 모든 작업을 중단시킵니다.
|
||||
* `channel` String - 이벤트 이름
|
||||
* `arg` (optional)
|
||||
|
||||
## ipc.sendToHost(channel[, args...])
|
||||
`channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다.
|
||||
옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다.
|
||||
메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 할 수 있습니다.
|
||||
|
||||
`ipc.send`와 비슷하지만 메시지를 메인 프로세스 대신 호스트 페이지로 보냅니다.
|
||||
### `ipc.sendSync(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
이 메소드는 보통 `<webview>`와 호스트 페이지 간의 통신에 사용됩니다.
|
||||
* `channel` String - 이벤트 이름
|
||||
* `arg` (optional)
|
||||
|
||||
`channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다.
|
||||
옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다.
|
||||
메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 할 수 있습니다.
|
||||
|
||||
메인 프로세스에선 `ipc` 모듈의 `channel` 이벤트를 통해 받은 `event.returnValue`로 회신 할 수 있습니다.
|
||||
|
||||
**참고:** 동기 메시징은 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 이 메서드를 사용하는 것을 권장하지 않습니다.
|
||||
|
||||
### `ipc.sendToHost(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
* `channel` String - 이벤트 이름
|
||||
* `arg` (optional)
|
||||
|
||||
`ipc.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 `<webview>`로 보냅니다.
|
||||
옵션으로 `arg`에 한 개 또는 여러 개의 메시지를 포함할 수 있습니다. 모든 타입을 사용할 수 있습니다.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
### new MenuItem(options)
|
||||
|
||||
* `options` Object
|
||||
* `click` Function - 메뉴 아이템이 클릭될 때 호출되는 콜백함수
|
||||
* `click` Function - 메뉴 아이템이 클릭될 때 호출되는 콜백 함수
|
||||
* `selector` String - First Responder가 클릭될 때 호출 되는 선택자 (OS X 전용)
|
||||
* `type` String - `MenuItem`의 타입 `normal`, `separator`, `submenu`, `checkbox` 또는 `radio` 사용가능
|
||||
* `label` String
|
||||
|
|
|
@ -181,9 +181,9 @@ Menu.setApplicationMenu(menu);
|
|||
* `action` String
|
||||
|
||||
`action`을 어플리케이션의 first responder에 전달합니다.
|
||||
이 함수는 Cocoa 메뉴 동작을 에뮬레이트 하는데 사용되며 보통 `MenuItem`의 `selector` 속성에 사용됩니다.
|
||||
이 메서드는 Cocoa 메뉴 동작을 에뮬레이트 하는데 사용되며 보통 `MenuItem`의 `selector` 속성에 사용됩니다.
|
||||
|
||||
**알림:** 이 함수는 OS X에서만 사용할 수 있습니다.
|
||||
**참고:** 이 메서드는 OS X에서만 사용할 수 있습니다.
|
||||
|
||||
### Class Method: Menu.buildFromTemplate(template)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ powerSaveBlocker.stop(id);
|
|||
|
||||
Power save blocker를 시작하고 시스템이 저전력 모드(슬립)로 진입하는 것을 막습니다. 정수로 된 식별 ID를 반환합니다.
|
||||
|
||||
**알림:**
|
||||
**참고:**
|
||||
`prevent-display-sleep` 모드는 `prevent-app-suspension` 보다 우선순위가 높습니다.
|
||||
가장 높은 우선순위의 모드만 작동합니다. 다시 말해 `prevent-display-sleep` 모드는 언제나 `prevent-app-suspension` 모드의 효과를 덮어씌웁니다.
|
||||
|
||||
|
|
|
@ -10,3 +10,9 @@ Electron의 `process` 객체는 기존의 node와는 달리 약간의 차이점
|
|||
## process.hang
|
||||
|
||||
현재 프로세스의 주 스레드를 중단시킵니다.
|
||||
|
||||
## process.setFdLimit(maxDescriptors) _OS X_ _Linux_
|
||||
|
||||
* `maxDescriptors` Integer
|
||||
|
||||
`maxDescriptors`에 file descriptor 소프트 리미트를 설정하거나 OS 하드 리미트를 설정합니다. 값은 현재 프로세스에 대해 낮은 값이어야 합니다.
|
||||
|
|
|
@ -20,7 +20,7 @@ app.on('ready', function() {
|
|||
});
|
||||
```
|
||||
|
||||
**알림:** 이 모듈은 `ready` 이벤트가 호출된 이후에만 사용할 수 있습니다.
|
||||
**참고:** 이 모듈은 `ready` 이벤트가 호출된 이후에만 사용할 수 있습니다.
|
||||
|
||||
## protocol.registerStandardSchemes(schemes)
|
||||
|
||||
|
|
|
@ -16,12 +16,12 @@ var win = new BrowserWindow({ width: 800, height: 600 });
|
|||
win.loadUrl('https://github.com');
|
||||
```
|
||||
|
||||
알림: 반대로 하려면(메인 프로세스에서 랜더러 프로세스에 접근) [webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code) API를 사용하면 됩니다.
|
||||
**참고:** 반대로 하려면(메인 프로세스에서 랜더러 프로세스에 접근) [webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code) API를 사용하면 됩니다.
|
||||
|
||||
## Remote 객체
|
||||
|
||||
`remote` 모듈로부터 반환된 각 객체(함수 포함)는 메인 프로세스의 객체를 추상화 한 객체입니다. (우리는 그것을 remote 객체 또는 remote 함수라고 부릅니다)
|
||||
Remote 모듈의 함수를 호출하거나, 객체에 접근하거나, 생성자로 객체를 생성하는 등의 작업은 실질적으로 동기형 inter-process 메시지를 보냅니다.
|
||||
`remote` 모듈로부터 반환된 각 객체(메서드 포함)는 메인 프로세스의 객체를 추상화 한 객체입니다. (우리는 그것을 remote 객체 또는 remote 함수라고 부릅니다)
|
||||
Remote 모듈의 메서드를 호출하거나, 객체에 접근하거나, 생성자로 객체를 생성하는 등의 작업은 실질적으로 동기형 inter-process 메시지를 보냅니다.
|
||||
|
||||
위의 예제에서 사용한 두 `BrowserWindow`와 `win`은 remote 객체입니다. 그리고 `new BrowserWindow`이 생성하는 `BrowserWindow` 객체는 랜더러 프로세스에서 생성되지 않습니다.
|
||||
대신에 이 `BrowserWindow` 객체는 메인 프로세스에서 생성되며 랜더러 프로세스에 `win` 객체와 같이 이에 대응하는 remote 객체를 반환합니다.
|
||||
|
@ -38,16 +38,45 @@ Remote 객체가 GC 되려면 대응하는 메인 프로세스 내부 객체의
|
|||
|
||||
## 메인 프로세스로 콜백 넘기기
|
||||
|
||||
몇몇 메인 프로세스의 API는 콜백 함수를 사용합니다. 그리고 보통 remote 함수를 호출할 때 콜백 함수를 넘길 것입니다.
|
||||
`remote` 모듈은 이를 지원합니다. 하지만 반드시 주의해서 사용해야 합니다.
|
||||
메인 프로세스의 코드는 `remote` 모듈을 통해 랜더러 프로세스가 전달하는 콜백 함수를 받을 수 있습니다.
|
||||
하지만 이 작업은 반드시 주의를 기울여 사용해야 합니다.
|
||||
|
||||
첫째, 데드락을 피하기 위해 메인 프로세스로 전달된 콜백들은 비동기로 호출됩니다.
|
||||
그래서 전달된 콜백들이 언제나 값을 반환할 것이라고 기대하면 안 됩니다.
|
||||
이러한 이유로 메인 프로세스로 전달된 콜백들의 반환 값을 내부 함수에서 언제나 정상적으로 받을 것이라고 예측해선 안됩니다.
|
||||
|
||||
둘째, 콜백들은 메인 프로세스로 전송되고 호출된 후에도 자동으로 참조가 릴리즈 되지 않습니다.
|
||||
참조는 메인 프로세스에서 GC가 일어나기 전까지 계속 남아있게 됩니다.
|
||||
예를 들어 메인 프로세스에서 `Array.map` 같은 메서드를 사용할 때 랜더러 프로세스에서 전달된 함수를 사용해선 안됩니다:
|
||||
|
||||
다음 코드를 보면 느낌이 팟 하고 올 것입니다. 이 예제는 remote 객체에 `close` 이벤트 콜백을 설치합니다:
|
||||
```javascript
|
||||
// mapNumbers.js 메인 프로세스
|
||||
exports.withRendererCallback = function(mapper) {
|
||||
return [1,2,3].map(mapper);
|
||||
}
|
||||
|
||||
exports.withLocalCallback = function() {
|
||||
return exports.mapNumbers(function(x) {
|
||||
return x + 1;
|
||||
});
|
||||
}
|
||||
|
||||
// 랜더러 프로세스
|
||||
var mapNumbers = require("remote").require("mapNumbers");
|
||||
|
||||
var withRendererCb = mapNumbers.withRendererCallback(function(x) {
|
||||
return x + 1;
|
||||
})
|
||||
|
||||
var withLocalCb = mapNumbers.withLocalCallback()
|
||||
|
||||
console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4]
|
||||
```
|
||||
|
||||
보다시피 랜더러 콜백의 동기 반환 값은 예상되지 않은 처리입니다.
|
||||
그리고 메인 프로세스에서 처리한 함수의 반환 값과 일치하지 않습니다.
|
||||
|
||||
둘째, 콜백들은 메인 프로세스로 전달, 호출된 이후에도 자동으로 함수의 참조가 릴리즈 되지 않습니다.
|
||||
함수 참조는 메인 프로세스에서 GC가 일어나기 전까지 계속 프로세스에 남아있게 됩니다.
|
||||
|
||||
다음 코드를 보면 느낌이 올 것입니다. 이 예제는 remote 객체에 `close` 이벤트 콜백을 설치합니다:
|
||||
|
||||
```javascript
|
||||
var remote = require('remote');
|
||||
|
@ -56,11 +85,14 @@ remote.getCurrentWindow().on('close', function() {
|
|||
});
|
||||
```
|
||||
|
||||
문제는 이 이벤트는 명시적으로 제거하지 않는 이상 계속해서 메인 프로세스에 남아있게 된다는 것입니다.
|
||||
그래서 매 창을 새로고침 할 때마다 콜백이 새롭게 설치되며 이전 콜백은 떨궈져 누수가 됩니다.
|
||||
설상가상으로 이전에 설치한 콜백의 콘텍스트가 릴리즈 되고 나서 `close` 이벤트가 발생하면 예외가 발생하고 메인 프로세스가 작동 중지됩니다.
|
||||
하지만 이 코드 처럼 이벤트를 명시적으로 제거하지 않는 이상 콜백 함수의 참조가 계속해서 메인 프로세스에 남아있게 됩니다.
|
||||
만약 명시적으로 콜백을 제거하지 않으면 매 번 창을 새로고침 할 때마다 콜백을 새로 설치합니다.
|
||||
게다가 이전 콜백이 제거되지 않고 계속해서 쌓이면서 메모리 누수가 발생합니다.
|
||||
|
||||
일반적으로 정확히 무엇을 할 것인지 잘 알고 있지 않는 이상 웬만하면 메인 프로세스로 콜백 함수를 넘기는 건 자제하는 게 좋습니다.
|
||||
설상가상으로 이전에 설치된 콜백의 콘텍스트가 릴리즈 되고 난 후(예: 페이지 새로고침) `close` 이벤트가 발생하면 예외가 발생하고 메인 프로세스가 작동 중지됩니다.
|
||||
|
||||
이러한 문제를 피하려면 랜더러 프로세스에서 메인 프로세스로 넘긴 함수의 참조를 사용 후 확실하게 제거해야 합니다.
|
||||
작업 후 이벤트 콜백을 포함하여 책임 있게 함수의 참조를 제거하거나 메인 프로세스에서 랜더러 프로세스가 종료될 때 내부적으로 함수 참조를 제거하도록 설계해야 합니다.
|
||||
|
||||
## remote.require(module)
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ __주의:__ 이 기능은 OS X에서만 작동합니다.
|
|||
|
||||
트레이에 알림풍선을 생성합니다.
|
||||
|
||||
__알림:__ 이 기능은 Windows에서만 작동합니다.
|
||||
__주의:__ 이 기능은 Windows에서만 작동합니다.
|
||||
|
||||
### Tray.popContextMenu([position])
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# web-frame
|
||||
|
||||
`web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 해줍니다.
|
||||
`web-frame` 모듈은 현재 웹 페이지의 랜더링 상태를 설정 할 수 있도록 관련 유틸리티를 제공하는 모듈입니다.
|
||||
|
||||
다음 예제는 현재 페이지를 200% 줌 합니다.
|
||||
다음 예제는 현재 페이지를 200% 줌 합니다:
|
||||
|
||||
```javascript
|
||||
var webFrame = require('web-frame');
|
||||
|
@ -30,6 +30,13 @@ webFrame.setZoomFactor(2);
|
|||
|
||||
현재 줌 레벨을 반환합니다.
|
||||
|
||||
## webFrame.setZoomLevelLimits(minimumLevel, maximumLevel)
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
|
||||
줌 레벨의 최대, 최소치를 지정합니다.
|
||||
|
||||
## webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)
|
||||
|
||||
* `language` String
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# `window.open` 함수
|
||||
# `window.open` 메서드
|
||||
|
||||
`window.open` 함수가 호출되면 새 창에서 새로운 페이지를 불러옵니다.
|
||||
이 창은 `url`로 부터 만들어진 `BrowserWindow`의 새 인스턴스이며 본 객체 대신 페이지의 컨트롤이 제한된 프록시 객체를 반환합니다.
|
||||
`window.open` 메서드가 호출되면 새 창을 생성하고 `url` 페이지를 불러옵니다.
|
||||
이 창은 지정한 `url`을 로드하여 만들어진 `BrowserWindow`의 새 인스턴스이며 본래 창 객체 대신 페이지의 컨트롤이 제한된 프록시 객체를 반환합니다.
|
||||
|
||||
프록시 객체는 기존의 웹 페이지와 호환될 수 있도록 일부 제한된 표준 기능만 가지고 있습니다.
|
||||
프록시 객체는 브라우저의 웹 페이지 창과 호환될 수 있도록 일부 제한된 표준 기능만 가지고 있습니다.
|
||||
창의 모든 컨트롤을 가지려면 `BrowserWindow`를 직접 생성하여 작업해야 합니다.
|
||||
|
||||
## window.open(url, [frameName[, features]])
|
||||
|
@ -19,7 +19,7 @@
|
|||
* `message` String
|
||||
* `targetOrigin` String
|
||||
|
||||
부모 윈도우에 메시지를 보냅니다. 특정한 origin을 지정할 수도 있으며 `*`를 지정하면 따로 origin 설정을 사용하지 않습니다.
|
||||
부모 윈도우에 메시지를 보냅니다. origin을 특정할 수 있으며 `*`를 지정하면 따로 origin 설정을 사용하지 않습니다.
|
||||
|
||||
## Class: BrowserWindowProxy
|
||||
|
||||
|
@ -52,6 +52,6 @@ Forcefully closes the child window without calling its unload event.
|
|||
* `message` String
|
||||
* `targetOrigin` String
|
||||
|
||||
자식 윈도우에 메시지를 보냅니다. 특정한 origin을 지정할 수도 있으며 `*`를 지정하면 따로 origin 설정을 사용하지 않습니다.
|
||||
자식 윈도우에 메시지를 보냅니다. origin을 특정할 수 있으며 `*`를 지정하면 따로 origin 설정을 사용하지 않습니다.
|
||||
|
||||
참고로 자식 윈도우의 `window.opener` 객체에는 다른 속성 없이 이 함수 하나만 구현되어 있습니다.
|
||||
참고로 자식 윈도우의 `window.opener` 객체에는 다른 속성 없이 이 메서드 한 개만 구현되어 있습니다.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# NW.js와 기술적으로 다른점 (이전 node-webkit)
|
||||
|
||||
__알림: Electron은 이전까지 Atom Shell로 불려졌습니다.__
|
||||
__주의: Electron은 Atom Shell의 새로운 이름입니다.__
|
||||
|
||||
NW.js 처럼 Electron은 JavaScript와 HTML 그리고 Node 통합환경을 제공함으로써 웹 페이지에서 저수준 시스템에 접근할 수 있는 웹 기반 데스크탑 어플리케이션을 작성할 수 있도록 합니다.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
* Python 2.7.x. 몇몇 CentOS와 같은 배포판들은 아직도 Python 2.6.x 버전을 사용합니다. 그래서 `python -V`를 통해 버전을 확인해 줄 필요가 있습니다.
|
||||
* Node.js v0.12.x. Node를 설치하는 방법은 여러가지가 있습니다. 그중 하나는 [Node.js](http://nodejs.org) 사이트에서 소스코드를 받아 빌드하는 방법입니다.
|
||||
이렇게 하면 Node를 일반 유저로 홈 디렉터리에 설치할 수 있습니다. 또는 [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories) 에서 받아올 수도 있습니다.
|
||||
이렇게 하면 Node를 일반 유저로 홈 디렉터리에 설치할 수 있습니다. 또는 [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)에서 소스 파일을 받아올 수 있습니다.
|
||||
자세한 내용은 [Node.js 설치 방법](https://github.com/joyent/node/wiki/Installation) 을 참고하세요.
|
||||
* Clang 3.4 또는 최신 버전
|
||||
* GTK+ 와 libnotify의 개발용 헤더
|
||||
|
@ -78,7 +78,7 @@ $ ./script/create-dist.py
|
|||
이 스크립트는 매우 작은 배포판을 `dist` 디렉터리에 생성합니다.
|
||||
create-dist.py 스크립트를 실행한 이후 1.3GB를 초과하는 공간을 차지하는 out/R 폴더의 실행파일 바이너리는 삭제해도 됩니다.
|
||||
|
||||
`Debug` 타겟만 빌드 할 수도 있습니다:
|
||||
또는 `Debug` 타겟만 빌드 할 수 있습니다:
|
||||
|
||||
```bash
|
||||
$ ./script/build.py -c D
|
||||
|
|
|
@ -34,7 +34,7 @@ $ ./script/bootstrap.py -v
|
|||
$ ./script/build.py
|
||||
```
|
||||
|
||||
`Debug` 타겟만 빌드 할 수도 있습니다:
|
||||
또는 `Debug` 타겟만 빌드 할 수 있습니다:
|
||||
|
||||
```bash
|
||||
$ ./script/build.py -c D
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* [git](http://git-scm.com)
|
||||
|
||||
현재 Windows를 설치하지 않았다면 [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads)에서
|
||||
사용기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 빌드할 수도 있습니다.
|
||||
사용 기한이 정해져있는 무료 가상머신 버전의 Windows를 받아 Electron을 빌드하는 방법도 있습니다.
|
||||
|
||||
Electron은 전적으로 command-line 스크립트를 사용하여 빌드합니다. 그렇기에 Electron을 개발하는데 아무런 에디터나 사용할 수 있습니다.
|
||||
하지만 이 말은 Visual Studio를 개발을 위해 사용할 수 없다는 말이 됩니다. 나중에 Visual Studio를 이용한 빌드 방법도 제공할 예정입니다.
|
||||
|
@ -40,7 +40,7 @@ python script\bootstrap.py -v
|
|||
python script\build.py
|
||||
```
|
||||
|
||||
`Debug` 타겟만 빌드 할 수도 있습니다:
|
||||
또는 `Debug` 타겟만 빌드 할 수 있습니다:
|
||||
|
||||
```powershell
|
||||
python script\build.py -c D
|
||||
|
@ -72,6 +72,15 @@ python script\cpplint.py
|
|||
python script\test.py
|
||||
```
|
||||
|
||||
테스트 실행시 `runas`와 같은 네이티브 모듈을 포함하는데 이 모듈은 디버그 빌드에서 같이 사용할 수 없습니다.
|
||||
하지만 여전히 릴리즈 빌드에선 사용할 수 있습니다.
|
||||
|
||||
릴리즈 빌드로 테스트를 실행하려면 다음 커맨드를 사용하면 됩니다:
|
||||
|
||||
```powershell
|
||||
python script\test.py -R
|
||||
```
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### Command xxxx not found
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 디버거에서 디버그 심볼 서버 설정
|
||||
|
||||
디버그 심볼은 디버깅 세션을 더 좋게 개선해 줍니다. 디버그 심볼은 실행 파일과 동적 링크 라이브러리에서 함수에 대한 정보를 담고 있으며 명료한 함수 호출 스텍 정보를 제공합니다.
|
||||
디버그 심볼은 디버깅 세션을 더 좋게 개선해 줍니다. 디버그 심볼은 실행 파일과 동적 링크 라이브러리에서 메서드에 대한 정보를 담고 있으며 명료한 함수 호출 스텍 정보를 제공합니다.
|
||||
심볼 서버는 유저가 크기가 큰 디버깅용 파일을 필수적으로 다운로드 받지 않고도 디버거가 알맞은 심볼, 바이너리 그리고 소스를 자동적으로 로드할 수 있도록 해줍니다.
|
||||
서버 사용법은 [Microsoft의 심볼 서버](http://support.microsoft.com/kb/311503)와 비슷합니다. 이 문서를 참조하세요.
|
||||
|
||||
|
|
|
@ -1,61 +1,55 @@
|
|||
# Electron Documentation Styleguide
|
||||
# Electron 문서 스타일 가이드
|
||||
|
||||
Find the appropriate section for your task: [reading Electron documentation](#)
|
||||
or [writing Electron documentation](#).
|
||||
[Electron 문서 읽기](#) 와 [Electron 문서 작성하기](#) 중 적당히 필요한 부분을 찾아 참고하세요:
|
||||
|
||||
## Writing Electron Documentation
|
||||
## Electron 문서 작성하기
|
||||
|
||||
These are the ways that we construct the Electron documentation.
|
||||
Electron 문서를 작성하는 규칙은 다음과 같습니다.
|
||||
|
||||
- Maximum one `h1` title per page.
|
||||
- Use `bash` instead of `cmd` in code blocks (because of syntax highlighter).
|
||||
- Doc `h1` titles should match object name (i.e. `browser-window` ¡æ
|
||||
`BrowserWindow`).
|
||||
- Hyphen separated filenames, however, are fine.
|
||||
- No headers following headers, add at least a one-sentence description.
|
||||
- Methods headers are wrapped in `code` ticks.
|
||||
- Event headers are wrapped in single 'quotation' marks.
|
||||
- No nesting lists more than 2 levels (unfortunately because of markdown
|
||||
renderer).
|
||||
- Add section titles: Events, Class Methods and Instance Methods.
|
||||
- Use 'will' over 'would' when describing outcomes.
|
||||
- Events and methods are `h3` headers.
|
||||
- Optional arguments written as `function (required[, optional])`.
|
||||
- Optional arguments are denoted when called out in list.
|
||||
- Line length is 80-column wrapped.
|
||||
- Platform specific methods are noted in italics following method header.
|
||||
- `h1` 제목은 페이지당 한 개만 사용할 수 있습니다.
|
||||
- 코드 블럭에서 터미널 언어 선택시 `cmd` 대신 `bash`를 사용합니다. (syntax highlighter를 사용하기 위해서)
|
||||
- 문서의 `h1` 제목은 반드시 현재 객체 이름과 같게 해야 합니다. (예시: `browser-window` → `BrowserWindow`)
|
||||
- 하이픈(-)으로 구분되었던 어떻게 되었던 간에 예시와 같이 작성합니다.
|
||||
- 헤더 밑에 헤더를 바로 사용하지 않습니다. 한 줄이라도 좋으니 헤더와 헤더 사이에 설명 추가합니다.
|
||||
- 메서드 헤더는 `code` 틱으로 표시합니다.
|
||||
- 이벤트 헤더는 한 '따옴표'로 표시합니다.
|
||||
- 리스트를 2 단계 이상 중첩하지 않습니다. (안타깝게도 markdown 랜더러가 지원하지 않습니다)
|
||||
- 섹션에 대한 제목을 추가합니다: Events, Class 메서드 그리고 인스턴스 메서드등.
|
||||
- 어떤 '것'의 사용 결과를 설명할 때 '될 것입니다' 형식을 사용하여 설명합니다.
|
||||
- 이벤트와 메서드에는 `h3` 헤더를 사용합니다.
|
||||
- 선택적 인수는 `function (required[, optional])` 형식으로 작성합니다.
|
||||
- 선택적 인수는 목록에서 호출되면 표시합니다.
|
||||
- 문장의 길이는 한 줄당 80 칸을 유지합니다.
|
||||
- 플랫폼 특정 메서드 헤더는 이탈릭체로 표시합니다.
|
||||
- ```### `method(foo, bar)` _OS X_```
|
||||
|
||||
## Reading Electron Documentation
|
||||
## Electron 문서 읽기
|
||||
|
||||
Here are some tips for understanding Electron documentation syntax.
|
||||
Electron 문서 구조를 이해하는 데 참고할 수 있는 유용한 도움말입니다.
|
||||
|
||||
### Methods
|
||||
|
||||
An example of [method](https://developer.mozilla.org/en-US/docs/Glossary/Method)
|
||||
documentation:
|
||||
[Method](https://developer.mozilla.org/en-US/docs/Glossary/Method) 문서의 예제입니다:
|
||||
|
||||
---
|
||||
|
||||
`methodName(required[, optional]))`
|
||||
|
||||
* `require` String, **required**
|
||||
* `require` String, **필수**
|
||||
* `optional` Integer
|
||||
|
||||
---
|
||||
|
||||
The method name is followed by the arguments it takes. Optional arguments are
|
||||
notated by brackets surrounding the optional argument as well as the comma
|
||||
required if this optional argument follows another argument.
|
||||
메서드 이름은 인수가 무엇을 받는지에 따라 결정됩니다. 선택적 인수는 브라켓([, ])으로 묶어
|
||||
이 인수가 다른 인수뒤에서 선택적으로 사용될 수 있다는 것을 표시합니다.
|
||||
|
||||
Below the method is more detailed information on each of the arguments. The type
|
||||
of argument is notated by either the common types: [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
||||
or a custom type like Electron's [`webContent`](api/web-content.md).
|
||||
메서드의 밑에선 각 인수에 대해 자세한 설명을 합니다. 인수의 타입은 일반적인 타입 중 하나를 받거나:
|
||||
[`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
||||
Electron의 [`webContent`](api/web-content.md)같은 커스텀 타입을 받습니다.
|
||||
|
||||
### Events
|
||||
|
||||
An example of [event](https://developer.mozilla.org/en-US/docs/Web/API/Event)
|
||||
documentation:
|
||||
[Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) 문서의 예제입니다:
|
||||
|
||||
---
|
||||
|
||||
|
@ -67,12 +61,11 @@ Returns:
|
|||
|
||||
---
|
||||
|
||||
The event is a string that is used after a `.on` listener method. If it returns
|
||||
a value it and its type is noted below. If you were to listen and respond to
|
||||
this event it might look something like this:
|
||||
이벤트는 `.on` 리스너 메서드로 사용할 수 있습니다. 만약 이벤트에서 값을 반환한다면 문서에서 표시된 대로
|
||||
일정한 타입의 값을 반환합니다. 이벤트를 처리하거나 응답하려 한다면 다음과 같이 사용할 수 있습니다:
|
||||
|
||||
```javascript
|
||||
Alarm.on('wake-up', function(time) {
|
||||
console.log(time)
|
||||
})
|
||||
```
|
||||
```
|
||||
|
|
|
@ -118,7 +118,7 @@ originalFs.readFileSync('/path/to/example.asar');
|
|||
몇몇 API는 시스템의 실제 파일의 경로를 기반으로 작동하므로 이 API들을 사용할 땐 Electron은
|
||||
이 API가 원할하게 작동할 수 있도록 하기 위해 임시경로에 해당 파일들의 압축을 해제합니다. 이 작업은 약간의 오버헤드를 불러 일으킬 수 있습니다.
|
||||
|
||||
해당하는 API 함수는 다음과 같습니다:
|
||||
해당하는 API 메서드는 다음과 같습니다:
|
||||
|
||||
* `child_process.execFile`
|
||||
* `fs.open`
|
||||
|
@ -134,7 +134,7 @@ originalFs.readFileSync('/path/to/example.asar');
|
|||
## `asar` 아카이브에 미리 압축 해제된 파일 추가하기
|
||||
|
||||
전술한 바와 같이 몇몇 Node API는 호출 시 해당 파일을 임시폴더에 압축을 해제합니다.
|
||||
따로 성능문제가 발생할 수 있습니다. 그리고 백신 소프트웨어의 잘못된 오진을 일으킬 수도 있습니다.
|
||||
이 방법은 성능문제가 발생할 수 있습니다. 그리고 설계상 백신 소프트웨어에서 잘못 진단하여 바이러스로 판단 할 수도 있습니다.
|
||||
|
||||
이 문제를 해결하려면 `--unpack` 옵션을 활용하여 파일을 압축이 풀려진 상태로 유지해야 합니다.
|
||||
다음의 예제는 node 네이티브 모듈의 공유 라이브러리를 unpack 상태로 유지합니다:
|
||||
|
|
|
@ -26,13 +26,13 @@ $ node-inspector
|
|||
|
||||
### 2. Electron용 디버그 모드 활성화
|
||||
|
||||
다음과 같이 debung 플래그로 Electron을 실행할 수도 있습니다:
|
||||
다음과 같이 debung 플래그로 Electron을 실행할 수 있습니다:
|
||||
|
||||
```bash
|
||||
$ electron --debug=5858 your/app
|
||||
```
|
||||
|
||||
또는 스크립트 첫번째 라인에서 일시정지:
|
||||
또는 스크립트 첫번째 라인에서 일시 정지할 수 있습니다:
|
||||
|
||||
```bash
|
||||
$ electron --debug-brk=5858 your/app
|
||||
|
|
|
@ -35,10 +35,10 @@ _online-status.html_
|
|||
</html>
|
||||
```
|
||||
|
||||
필요한 경우 이 이벤트를 메인 프로세스로 보낼 수도 있습니다.
|
||||
메인 프로세스는 `navigator` 오브젝트를 가지고 있지 않기 때문에 이 이벤트를 직접 사용할 수 없습니다.
|
||||
이는 다음 예제와 같이 electron의 inter-process communication(ipc)유틸리티를 사용하여
|
||||
이벤트를 메인 프로세스로 전달하는 것으로 해결할 수 있습니다.
|
||||
물론 필요하다면 이 이벤트를 메인 프로세스로 보낼 수도 있습니다.
|
||||
하지만 메인 프로세스는 `navigator` 객체를 가지고 있지 않기 때문에 이 이벤트를 직접 사용할 수 없습니다.
|
||||
|
||||
대신 다음 예제와 같이 Electron의 inter-process communication(ipc) 유틸리티를 사용하면 이벤트를 메인 프로세스로 전달할 수 있습니다.
|
||||
|
||||
_main.js_
|
||||
|
||||
|
|
|
@ -10,23 +10,24 @@ Electron은 자바스크립트와 함께 제공된 풍부한 네이티브 API를
|
|||
|
||||
### 메인 프로세스
|
||||
|
||||
Electron은 실행될 때 __메인 프로세스__ 로 불리는 `package.json`의 `main` 스크립트를 호출합니다.
|
||||
Electron은 실행될 때 __메인 프로세스__로 불리는 `package.json`의 `main` 스크립트를 호출합니다.
|
||||
이 스크립트는 메인 프로세스에서 작동합니다. GUI 컴포넌트를 조작하거나 웹 페이지 창을 생성할 수 있습니다.
|
||||
|
||||
### 랜더러 프로세스
|
||||
|
||||
Electron이 웹페이지를 보여줄 때 Chromium의 multi-processes 구조도 같이 사용됩니다.
|
||||
Electron 프로세스 내에서 작동하는 웹 페이지는 __랜더러 프로세스__ 라고 불립니다.
|
||||
Electron 프로세스 내에서 작동하는 웹 페이지를 __랜더러 프로세스__ 라고 불립니다.
|
||||
|
||||
보통 일반 브라우저의 웹 페이지들은 샌드박스가 적용된 환경에서 작동하며 네이티브 리소스에는 접근할 수 없도록 되어 있습니다.
|
||||
하지만 Electron은 웹 페이지 내에서 io.js(node.js) API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 있습니다.
|
||||
|
||||
### 메인 프로세스와 랜더러 프로세스의 차이점
|
||||
|
||||
메인 프로세스는 `BrowserWindow` Class를 이용하여 창을 만들 수 있습니다. `BrowserWindow` 인스턴스는
|
||||
따로 분리된 프로세스에서 랜더링 되며 `BrowserWindow` 인스턴스가 소멸할 때 해당하는 랜더러 프로세스도 같이 소멸합니다.
|
||||
메인 프로세스는 `BrowserWindow` Class를 사용하여 새로운 창을 만들 수 있습니다.
|
||||
`BrowserWindow` 인스턴스는 따로 분리된 프로세스에서 랜더링 되며 이 프로세스를 랜더러 프로세스라고 합니다.
|
||||
`BrowserWindow` 인스턴스가 소멸할 때 그 창의 랜더러 프로세스도 같이 소멸합니다.
|
||||
|
||||
메인 프로세스는 모든 웹 페이지와 그에 해당하는 랜더러 프로세스를 관리하며
|
||||
메인 프로세스는 모든 웹 페이지와 랜더러 프로세스를 관리하며
|
||||
랜더러 프로세스는 각각의 프로세스에 고립되며 웹 페이지의 작동에만 영향을 끼칩니다.
|
||||
|
||||
웹 페이지 내에서 네이티브 GUI 리소스를 관리하는 것은 보안에 취약하고 리소스를 누수시킬 수 있기 때문에
|
||||
|
@ -124,7 +125,7 @@ app.on('ready', function() {
|
|||
## 앱 실행하기
|
||||
|
||||
앱을 작성한 후 [어플리케이션 배포](application-distribution.md) 가이드를 따라 앱을 패키징 하고 패키징한 앱을 실행할 수 있습니다.
|
||||
또는 Electron 실행파일을 다운로드 받아 바로 실행해 볼 수도 있습니다.
|
||||
또한 Electron 실행파일을 다운로드 받아 바로 실행해 볼 수도 있습니다.
|
||||
|
||||
### electron-prebuilt
|
||||
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
# 네이티브 node 모듈 사용하기
|
||||
# 네이티브 node 모듈 사용하기
|
||||
|
||||
__역주: 현재 Electron은 node.js대신 io.js를 사용합니다. 문서에 기재된 버전과 다를 수 있습니다__
|
||||
|
||||
Electron에선 node.js 네이티브 모듈이 지원됩니다. 하지만 Electron은 공식 node.js의 V8 엔진과는 달리 다른 V8 버전을 사용합니다.
|
||||
그런 이유로 네이티브 모듈을 사용하기 위해선 Electron의 V8 버전에 맞춰 네이티브 모듈을 다시 빌드하고 헤더를 변경해야 합니다.
|
||||
Electron에선 node.js 네이티브 모듈이 지원됩니다. 하지만 Electron은 공식 node.js의 V8 엔진과는 다른 V8 버전을 사용합니다.
|
||||
이러한 이유로 네이티브 모듈을 사용하기 위해선 Electron의 V8 버전에 맞춰 네이티브 모듈을 다시 빌드하고 헤더를 변경해야 합니다.
|
||||
|
||||
## 네이티브 node 모듈 호환성
|
||||
|
||||
Node v0.11.x 버전부터는 V8 API의 중대한 변경이 있었습니다. 하지만 일반적으로 모든 네이티브 모듈은 Node v0.10.x 버전을 타겟으로 작성 되었기 때문에
|
||||
Node v0.11.x 버전에선 작동하지 않습니다. Electron은 내부적으로 Node v0.11.13 버전을 사용합니다. 그래서 위에서 설명한 문제가 발생합니다.
|
||||
Node v0.11.x 버전부터는 V8 API의 중대한 변경이 있었습니다. 하지만 대부분의 네이티브 모듈은 Node v0.10.x 버전을 타겟으로 작성 되었기 때문에
|
||||
새로운 Node 또는 io.js 버전에서 작동하지 않을 수 있습니다. Electron은 내부적으로 __io.js v3.1.0__ 버전을 사용하기 때문에 이러한 호환성 문제가 발생할 수 있습니다.
|
||||
|
||||
이 문제를 해결하기 위해 모듈이 Node v0.11.x 버전을 지원할 수 있도록 해야합니다.
|
||||
현재 [많은 모듈들](https://www.npmjs.org/browse/depended/nan)이 안정적으로 두 버전 모두 지원하고 있지만 오래된 모듈의 경우 Node v0.10.x 버전만을 지원하고 있습니다.
|
||||
예를 들어 [nan](https://github.com/rvagg/nan) 모듈을 사용해야 하는 경우 Node v0.11.x 버전으로 포팅 할 필요가 있습니다.
|
||||
이 문제를 해결하기 위해선 모듈이 v0.11.x 또는 최신 버전을 지원할 수 있도록 변경해야 합니다.
|
||||
현재 [많은 모듈들](https://www.npmjs.org/browse/depended/nan)이 안정적으로 두 버전 모두 지원하고 있지만 오래된 모듈의 경우 여전히 Node v0.10.x 버전만을 지원하고 있습니다.
|
||||
예를 들어 [nan](https://github.com/rvagg/nan) 모듈을 사용해야 한다면 Node v0.11.x 또는 최신 버전의 Node와 io.js로 포팅 할 필요가 있습니다.
|
||||
|
||||
## 네이티브 모듈 설치하는 방법
|
||||
|
||||
### 쉬운 방법 - 권장
|
||||
### 쉬운 방법
|
||||
|
||||
[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 패키지를 사용하면 아주 빠르고 정확하게 네이티브 모듈을 다시 빌드할 수 있습니다.
|
||||
다음의 간단한 절차를 통해 자동으로 헤더를 다운로드하고 네이티브 모듈을 빌드할 수 있습니다:
|
||||
[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 패키지를 사용하면 빠르고 간단하게 네이티브 모듈을 다시 빌드할 수 있습니다.
|
||||
간단한 절차를 통해 자동으로 헤더를 다운로드하고 네이티브 모듈을 빌드할 수 있습니다:
|
||||
|
||||
```sh
|
||||
npm install --save-dev electron-rebuild
|
||||
|
@ -30,7 +28,7 @@ npm install --save-dev electron-rebuild
|
|||
|
||||
### node-gyp을 이용한 방법
|
||||
|
||||
Node 모듈을 `node-gyp`를 사용하여 Electron을 타겟으로 빌드할 땐 `node-gyp`에 헤더 다운로드 주소와 버전을 알려주어야합니다:
|
||||
Node 모듈을 `node-gyp`를 사용하여 Electron을 타겟으로 빌드할 때는 `node-gyp`에 헤더 다운로드 주소와 버전을 알려주어야 합니다:
|
||||
|
||||
```bash
|
||||
$ cd /path-to-module/
|
||||
|
@ -42,8 +40,8 @@ $ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=ht
|
|||
|
||||
### npm을 이용한 방법
|
||||
|
||||
또한 `npm`을 사용하여 모듈을 설치할 수도 있습니다.
|
||||
환경변수가 필요한 것을 제외하고는 일반 Node 모듈을 설치하는 방법과 완전히 똑같습니다:
|
||||
또한 `npm`을 통해 설치할 수도 있습니다.
|
||||
환경변수가 필요한 것을 제외하고 일반 Node 모듈을 설치하는 방법과 완전히 똑같습니다:
|
||||
|
||||
```bash
|
||||
export npm_config_disturl=https://atom.io/download/atom-shell
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Pepper 플래시 플러그인 사용하기
|
||||
|
||||
필요하다면 Pepper 플래시 플러그인을 사용할 수 있습니다. Electron에서 pepper 플래시 플러그인을 사용하기 위해선 따로 pepper 플래시 플러그인의 위치를 지정해 주어야합니다.
|
||||
작업에 필요한 경우 pepper 플래시 플러그인을 사용할 수 있습니다.
|
||||
Electron에서 pepper 플래시 플러그인을 사용하기 위해선 따로 pepper 플래시 플러그인의 위치를 지정해 주어야합니다.
|
||||
|
||||
## 플래시 플러그인 준비하기
|
||||
|
||||
|
|
70
docs-translations/zh-CN/README.md
Normal file
70
docs-translations/zh-CN/README.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
## 向导
|
||||
|
||||
* [应用部署](tutorial/application-distribution.md)
|
||||
* [应用打包](tutorial/application-packaging.md)
|
||||
* [使用原生模块](tutorial/using-native-node-modules.md)
|
||||
* [主进程调试](tutorial/debugging-main-process.md)
|
||||
* [使用 Selenium 和 WebDriver](tutorial/using-selenium-and-webdriver.md)
|
||||
* [调试工具扩展](tutorial/devtools-extension.md)
|
||||
* [使用 PepperFlash 插件](tutorial/using-pepper-flash-plugin.md)
|
||||
|
||||
## 教程
|
||||
|
||||
* [快速入门](tutorial/quick-start.md)
|
||||
* [桌面环境集成](tutorial/desktop-environment-integration.md)
|
||||
* [在线/离线事件探测](tutorial/online-offline-events.md)
|
||||
|
||||
## API文档
|
||||
|
||||
* [简介](api/synopsis.md)
|
||||
* [进程对象](api/process.md)
|
||||
* [支持的Chrome命令行开关](api/chrome-command-line-switches.md)
|
||||
|
||||
定制的DOM元素:
|
||||
|
||||
* [`File`对象](api/file-object.md)
|
||||
* [`<webview>`标签](api/web-view-tag.md)
|
||||
* [`window.open`函数](api/window-open.md)
|
||||
|
||||
主进程可用的模块:
|
||||
|
||||
* [app](api/app.md)
|
||||
* [auto-updater](api/auto-updater.md)
|
||||
* [browser-window](api/browser-window.md)
|
||||
* [content-tracing](api/content-tracing.md)
|
||||
* [dialog](api/dialog.md)
|
||||
* [global-shortcut](api/global-shortcut.md)
|
||||
* [ipc (main process)](api/ipc-main-process.md)
|
||||
* [menu](api/menu.md)
|
||||
* [menu-item](api/menu-item.md)
|
||||
* [power-monitor](api/power-monitor.md)
|
||||
* [power-save-blocker](api/power-save-blocker.md)
|
||||
* [protocol](api/protocol.md)
|
||||
* [session](api/session.md)
|
||||
* [webContents](api/web-contents.md)
|
||||
* [tray](api/tray.md)
|
||||
|
||||
渲染进程(网页)可用的模块:
|
||||
|
||||
* [ipc (renderer)](api/ipc-renderer.md)
|
||||
* [remote](api/remote.md)
|
||||
* [web-frame](api/web-frame.md)
|
||||
|
||||
两种进程都可用的模块:
|
||||
|
||||
* [clipboard](api/clipboard.md)
|
||||
* [crash-reporter](api/crash-reporter.md)
|
||||
* [native-image](api/native-image.md)
|
||||
* [screen](api/screen.md)
|
||||
* [shell](api/shell.md)
|
||||
|
||||
## 开发
|
||||
|
||||
* [编码规范](development/coding-style.md)
|
||||
* [源码文件结构](development/source-code-directory-structure.md)
|
||||
* [与 NW.js (原名 node-webkit) 在技术上的差异](development/atom-shell-vs-node-webkit.md)
|
||||
* [构建系统概况](development/build-system-overview.md)
|
||||
* [构建步骤 (Mac)](development/build-instructions-mac.md)
|
||||
* [构建步骤 (Windows)](development/build-instructions-windows.md)
|
||||
* [构建步骤 (Linux)](development/build-instructions-linux.md)
|
||||
* [在调试中使用 SymbolServer](development/setting-up-symbol-server.md)
|
136
docs-translations/zh-CN/tutorial/quick-start.md
Normal file
136
docs-translations/zh-CN/tutorial/quick-start.md
Normal file
|
@ -0,0 +1,136 @@
|
|||
# 快速入门
|
||||
|
||||
## 简介
|
||||
Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用而不是 web 服务器的,io.js 的一个变体。
|
||||
|
||||
这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相反,Electron 使用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 控制的,精简版的 Chromium 浏览器。
|
||||
|
||||
## 主进程
|
||||
在 Electron 里,运行 `package.json` 里 `main` 脚本的进程被称为**主进程**。在主进程运行的脚本可以以创建 web 页面的形式展示 GUI。
|
||||
|
||||
## 渲染进程
|
||||
由于 Electron 使用 Chromium 来展示页面,所以 Chromium 的多进程结构也被充分利用。每个 Electron 的页面都在运行着自己的进程,这样的进程我们称之为**渲染进程**。
|
||||
|
||||
在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然后,Electron 用户拥有在网页中调用 io.js 的 APIs 的能力,从而创造出低等的、与操作系统的交互。
|
||||
|
||||
## 主进程与渲染进程的区别
|
||||
主进程使用 BroswerWindow 实例创建网页。每个 BroswerWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BroswerWindow 实例被销毁,相应的渲染进程也会被终止。
|
||||
|
||||
主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的网页。
|
||||
|
||||
由于在网页里管理原生 GUI 资源是非常危险而且容易造成资源泄露的,所以在网页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。
|
||||
|
||||
在 Electron,我们提供用于在主进程与渲染进程之间通讯的 [ipc][1] 模块。并且也有一个远程进程调用风格的通讯模块 [remote][2]。
|
||||
|
||||
# 打造你第一个 Electron 应用
|
||||
大体上,一个 Electron 应用的目录结构如下:
|
||||
````
|
||||
your-app/
|
||||
├── package.json
|
||||
├── main.js
|
||||
└── index.html
|
||||
````
|
||||
`package.json `的格式和 Node 的完全一致,并且那个被 `main` 字段声明的脚本文件是你的应用的启动脚本,它运行在主进程上。你应用里的 `package.json` 看起来应该像:
|
||||
````
|
||||
{
|
||||
"name" : "your-app",
|
||||
"version" : "0.1.0",
|
||||
"main" : "main.js"
|
||||
}
|
||||
````
|
||||
**注意**:如果 `main` 字段没有在 `package.json` 声明,Electron会优先加载 `index.js`。
|
||||
|
||||
`main.js` 应该用于创建窗口和处理系统时间,一个典型的例子如下:
|
||||
````
|
||||
var app = require('app'); // 控制应用生命周期的模块。
|
||||
var BrowserWindow = require('browser-window'); // 创建原生浏览器窗口的模块
|
||||
|
||||
// 给我们的服务器发送异常报告。
|
||||
require('crash-reporter').start();
|
||||
|
||||
// 保持一个对于 window 对象的全局引用,不然,当 JavaScript 被 GC,
|
||||
// window 会被自动地关闭
|
||||
var mainWindow = null;
|
||||
|
||||
// 当所有窗口被关闭了,退出。
|
||||
app.on('window-all-closed', function() {
|
||||
// 在 OS X 上,通常用户在明确地按下 Cmd + Q 之前
|
||||
// 应用会保持活动状态
|
||||
if (process.platform != 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
// 当 Electron 完成了初始化并且准备创建浏览器窗口的时候
|
||||
// 这个方法就被调用
|
||||
app.on('ready', function() {
|
||||
// 创建浏览器窗口。
|
||||
mainWindow = new BrowserWindow({width: 800, height: 600});
|
||||
|
||||
// 加载应用的 index.html
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
|
||||
// 打开开发工具
|
||||
mainWindow.openDevTools();
|
||||
|
||||
// 当 window 被关闭,这个事件会被发出
|
||||
mainWindow.on('closed', function() {
|
||||
// 取消引用 window 对象,如果你的应用支持多窗口的话,
|
||||
// 通常会把多个 window 对象存放在一个数组里面,
|
||||
// 但这次不是。
|
||||
mainWindow = null;
|
||||
});
|
||||
});
|
||||
````
|
||||
最后,你想展示的 `index.html` :
|
||||
````
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using io.js <script>document.write(process.version)</script>
|
||||
and Electron <script>document.write(process.versions['electron'])</script>.
|
||||
</body>
|
||||
</html>
|
||||
````
|
||||
|
||||
# 运行你的应用
|
||||
一旦你创建了最初的 `main.js`, `index.html` 和 `package.json` 这几个文件,你可能会想尝试在本地运行并测试,看看是不是和期望的那样正常运行。
|
||||
|
||||
## electron-prebuild
|
||||
如果你已经用 `npm` 全局安装了 `electron-prebuilt`,你只需要按照如下方式直接运行你的应用:
|
||||
````
|
||||
electron .
|
||||
````
|
||||
如果你是局部安装,那运行:
|
||||
````
|
||||
./node_modules/.bin/electron .
|
||||
````
|
||||
|
||||
## 手工下载 Electron 二进制文件
|
||||
如果你手工下载了 Electron 的二进制文件,你也可以直接使用其中的二进制文件直接运行你的应用。
|
||||
### Windows
|
||||
````
|
||||
$ .\electron\electron.exe your-app\
|
||||
````
|
||||
### Linux
|
||||
````
|
||||
$ ./electron/electron your-app/
|
||||
````
|
||||
### OS X
|
||||
````
|
||||
$ ./Electron.app/Contents/MacOS/Electron your-app/
|
||||
````
|
||||
`Electron.app` 里面是 Electron 发布包,你可以在[这里][3]下载到。
|
||||
|
||||
# 以发行版本运行
|
||||
在你完成了你的应用后,你可以按照[应用部署][4]指导发布一个版本,并且以已经打包好的形式运行应用。
|
||||
|
||||
|
||||
[1]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/ipc-renderer.md
|
||||
[2]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/remote.md
|
||||
[3]: https://github.com/atom/electron/releases
|
||||
[4]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/tutorial/application-distribution.md
|
|
@ -269,7 +269,6 @@ Adds `tasks` to the [Tasks][tasks] category of the JumpList on Windows.
|
|||
consists of two or more icons, set this value to identify the icon. If an
|
||||
icon file consists of one icon, this value is 0.
|
||||
|
||||
|
||||
### `app.commandLine.appendSwitch(switch[, value])`
|
||||
|
||||
Append a switch (with optional `value`) to Chromium's command line.
|
||||
|
|
|
@ -98,6 +98,10 @@ appropriate format.
|
|||
|
||||
`pub_date` (if present) must be formatted according to ISO 8601.
|
||||
|
||||
## Update server implementations
|
||||
|
||||
[Nuts](https://github.com/GitbookIO/nuts) is an open source implementation of the update server described above, it integrates beautifully with GitHub releases. Nuts manages downloads and updates, it’s compatible with `Squirrel.Mac` and `Squirrel.Windows` so you get cross-platform support out of the box.
|
||||
|
||||
## Events
|
||||
|
||||
The `autoUpdater` object emits the following events:
|
||||
|
|
|
@ -8,11 +8,11 @@ generated file to view the result.
|
|||
```javascript
|
||||
var contentTracing = require('content-tracing');
|
||||
|
||||
tracing.startRecording('*', tracing.DEFAULT_OPTIONS, function() {
|
||||
contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() {
|
||||
console.log('Tracing started');
|
||||
|
||||
setTimeout(function() {
|
||||
tracing.stopRecording('', function(path) {
|
||||
contentTracing.stopRecording('', function(path) {
|
||||
console.log('Tracing data recorded to ' + path);
|
||||
});
|
||||
}, 5000);
|
||||
|
|
|
@ -48,12 +48,13 @@ selected when you want to limit the user to a specific type. For example:
|
|||
]
|
||||
}
|
||||
```
|
||||
|
||||
The `extensions` array should contain extensions without wildcards or dots (e.g.
|
||||
`'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the
|
||||
`'*'` wildcard (no other wildcard is supported).
|
||||
|
||||
If a `callback` is passed, the API call will be asynchronous and the result
|
||||
wil be passed via `callback(filenames)`
|
||||
will be passed via `callback(filenames)`
|
||||
|
||||
**Note:** On Windows and Linux an open dialog can not be both a file selector
|
||||
and a directory selector, so if you set `properties` to
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
# global-shortcut
|
||||
|
||||
The `global-shortcut` module can register/unregister a global keyboard shortcut
|
||||
with the operating system, so that you can customize the operations for various shortcuts.
|
||||
Note that the shortcut is global; it will work even if the app does not have the keyboard focus.
|
||||
You should not use this module until the `ready` event of the app module is emitted.
|
||||
with the operating system so that you can customize the operations for various
|
||||
shortcuts.
|
||||
|
||||
**Note**: The shortcut is global; it will work even if the app does
|
||||
not have the keyboard focus. You should not use this module until the `ready`
|
||||
event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
|
@ -32,7 +35,11 @@ app.on('will-quit', function() {
|
|||
});
|
||||
```
|
||||
|
||||
## globalShortcut.register(accelerator, callback)
|
||||
## Methods
|
||||
|
||||
The `global-shortcut` module has the following methods:
|
||||
|
||||
### `globalShortcut.register(accelerator, callback)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
* `callback` Function
|
||||
|
@ -40,18 +47,19 @@ app.on('will-quit', function() {
|
|||
Registers a global shortcut of `accelerator`. The `callback` is called when
|
||||
the registered shortcut is pressed by the user.
|
||||
|
||||
## globalShortcut.isRegistered(accelerator)
|
||||
### `globalShortcut.isRegistered(accelerator)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
|
||||
Returns `true` or `false` depending on whether the shortcut `accelerator` is registered.
|
||||
Returns `true` or `false` depending on whether the shortcut `accelerator` is
|
||||
registered.
|
||||
|
||||
## globalShortcut.unregister(accelerator)
|
||||
### `globalShortcut.unregister(accelerator)`
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
|
||||
Unregisters the global shortcut of `keycode`.
|
||||
Unregisters the global shortcut of `accelerator`.
|
||||
|
||||
## globalShortcut.unregisterAll()
|
||||
### `globalShortcut.unregisterAll()`
|
||||
|
||||
Unregisters all the global shortcuts.
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
# ipc (main process)
|
||||
|
||||
Handles asynchronous and synchronous message sent from a renderer process (web
|
||||
page).
|
||||
The `ipc` module, when used in the main process, handles asynchronous and
|
||||
synchronous messages sent from a renderer process (web page). Messages sent from
|
||||
a renderer will be emitted to this module.
|
||||
|
||||
The messages sent from a renderer would be emitted to this module, the event name
|
||||
is the `channel` when sending message. To reply a synchronous message, you need
|
||||
to set `event.returnValue`, to send an asynchronous back to the sender, you can
|
||||
use `event.sender.send(...)`.
|
||||
## Sending Messages
|
||||
|
||||
It's also possible to send messages from main process to the renderer process,
|
||||
see [WebContents.send](browser-window.md#webcontentssendchannel-args) for more.
|
||||
It is also possible to send messages from the main process to the renderer
|
||||
process, see [WebContents.send](browser-window.md#webcontentssendchannel-args)
|
||||
for more information.
|
||||
|
||||
An example of sending and handling messages:
|
||||
- When sending a message, the event name is the `channel`.
|
||||
- To reply a synchronous message, you need to set `event.returnValue`.
|
||||
- To send an asynchronous back to the sender, you can use
|
||||
`event.sender.send(...)`.
|
||||
|
||||
An example of sending and handling messages between the render and main
|
||||
processes:
|
||||
|
||||
```javascript
|
||||
// In main process.
|
||||
|
@ -38,12 +43,34 @@ ipc.on('asynchronous-reply', function(arg) {
|
|||
ipc.send('asynchronous-message', 'ping');
|
||||
```
|
||||
|
||||
## Class: Event
|
||||
## Listening for Messages
|
||||
|
||||
### Event.returnValue
|
||||
The `ipc` module has the following method to listen for events:
|
||||
|
||||
Assign to this to return an value to synchronous messages.
|
||||
### `ipc.on(channel, callback)`
|
||||
|
||||
### Event.sender
|
||||
* `channel` String - The event name.
|
||||
* `callback` Function
|
||||
|
||||
The `WebContents` that sent the message.
|
||||
When the event occurs the `callback` is called with an `event` object and a
|
||||
message, `arg`.
|
||||
|
||||
## IPC Events
|
||||
|
||||
The `event` object passed to the `callback` has the following methods:
|
||||
|
||||
### `Event.returnValue`
|
||||
|
||||
Set this to the value to be returned in a synchronous message.
|
||||
|
||||
### `Event.sender`
|
||||
|
||||
Returns the `WebContents` that sent the message.
|
||||
|
||||
### `Event.sender.send(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
* `channel` String - The event name.
|
||||
* `arg` (optional)
|
||||
|
||||
This sends an asynchronous message back to the render process. Optionally, there
|
||||
can be one or a series of arguments, `arg`, which can have any type.
|
||||
|
|
|
@ -1,29 +1,52 @@
|
|||
# ipc (renderer)
|
||||
|
||||
The `ipc` module provides a few methods so you can send synchronous and
|
||||
asynchronous messages to the main process, and also receive messages sent from
|
||||
main process. If you want to make use of modules of main process from renderer
|
||||
asynchronous messages from the render process (web page) to the main process.
|
||||
You can also receive replies from the main process.
|
||||
|
||||
**Note**: If you want to make use of modules in the main process from the renderer
|
||||
process, you might consider using the [remote](remote.md) module.
|
||||
|
||||
See [ipc (main process)](ipc-main-process.md) for examples.
|
||||
See [ipc (main process)](ipc-main-process.md) for code examples.
|
||||
|
||||
## ipc.send(channel[, args...])
|
||||
## Methods
|
||||
|
||||
Send `args..` to the renderer via `channel` in asynchronous message, the main
|
||||
process can handle it by listening to the `channel` event of `ipc` module.
|
||||
The `ipc` module has the following methods for sending messages:
|
||||
|
||||
## ipc.sendSync(channel[, args...])
|
||||
**Note**: When using these methods to send a `message` you must also listen
|
||||
for it in the main process with [`ipc (main process)`](ipc-main-process.md).
|
||||
|
||||
Send `args..` to the renderer via `channel` in synchronous message, and returns
|
||||
the result sent from main process. The main process can handle it by listening to
|
||||
the `channel` event of `ipc` module, and returns by setting `event.returnValue`.
|
||||
### `ipc.send(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
**Note:** Usually developers should never use this API, since sending
|
||||
synchronous message would block the whole renderer process.
|
||||
* `channel` String - The event name.
|
||||
* `arg` (optional)
|
||||
|
||||
## ipc.sendToHost(channel[, args...])
|
||||
Send an event to the main process asynchronously via a `channel`. Optionally,
|
||||
there can be a message: one or a series of arguments, `arg`, which can have any
|
||||
type. The main process handles it by listening for the `channel` event with
|
||||
`ipc`.
|
||||
|
||||
Like `ipc.send` but the message will be sent to the host page instead of the
|
||||
main process.
|
||||
### `ipc.sendSync(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
This is mainly used by the page in `<webview>` to communicate with host page.
|
||||
* `channel` String - The event name.
|
||||
* `arg` (optional)
|
||||
|
||||
Send an event to the main process synchronously via a `channel`. Optionally,
|
||||
there can be a message: one or a series of arguments, `arg`, which can have any
|
||||
type. The main process handles it by listening for the `channel` event with
|
||||
`ipc`.
|
||||
|
||||
The main process handles it by listening for the `channel` event with `ipc` and
|
||||
replies by setting the `event.returnValue`.
|
||||
|
||||
**Note:** Sending a synchronous message will block the whole renderer process so
|
||||
using this method is not recommended.
|
||||
|
||||
### `ipc.sendToHost(channel[, arg1][, arg2][, ...])`
|
||||
|
||||
* `channel` String - The event name.
|
||||
* `arg` (optional)
|
||||
|
||||
Like `ipc.send` but the event will be sent to the host page in a `<webview>`
|
||||
instead of the main process. Optionally, there can be a message: one or a series
|
||||
of arguments, `arg`, which can have any type.
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
# menu-item
|
||||
# MenuItem
|
||||
|
||||
The `menu-item` module allows you to add items to an application or content
|
||||
[`menu`](menu.md).
|
||||
|
||||
See [`menu`](menu.md) for examples.
|
||||
|
||||
## Class: MenuItem
|
||||
|
||||
Create a new `MenuItem` with the following method:
|
||||
|
||||
### new MenuItem(options)
|
||||
|
||||
* `options` Object
|
||||
* `click` Function - Callback when the menu item is clicked
|
||||
* `selector` String - Call the selector of first responder when clicked (OS
|
||||
X only)
|
||||
* `click` Function - Will be called with `click(menuItem, browserWindow)` when
|
||||
the menu item is clicked
|
||||
* `role` String - Define the action of the menu item, when specified the
|
||||
`click` property will be ignored
|
||||
* `type` String - Can be `normal`, `separator`, `submenu`, `checkbox` or
|
||||
`radio`
|
||||
* `label` String
|
||||
|
@ -23,3 +31,29 @@
|
|||
as a reference to this item by the position attribute.
|
||||
* `position` String - This field allows fine-grained definition of the
|
||||
specific location within a given menu.
|
||||
|
||||
When creating menu items, it is recommended to specify `role` instead of
|
||||
manually implementing the behavior if there is matching action, so menu can have
|
||||
best native experience.
|
||||
|
||||
The `role` property can have following values:
|
||||
|
||||
* `undo`
|
||||
* `redo`
|
||||
* `cut`
|
||||
* `copy`
|
||||
* `paste`
|
||||
* `selectall`
|
||||
* `minimize` - Minimize current window
|
||||
* `close` - Close current window
|
||||
|
||||
On OS X `role` can also have following additional values:
|
||||
|
||||
* `about` - Map to the `orderFrontStandardAboutPanel` action
|
||||
* `hide` - Map to the `hide` action
|
||||
* `hideothers` - Map to the `hideOtherApplications` action
|
||||
* `unhide` - Map to the `unhideAllApplications` action
|
||||
* `front` - Map to the `arrangeInFront` action
|
||||
* `window` - The submenu is a "Window" menu
|
||||
* `help` - The submenu is a "Help" menu
|
||||
* `services` - The submenu is a "Services" menu
|
||||
|
|
290
docs/api/menu.md
290
docs/api/menu.md
|
@ -1,12 +1,17 @@
|
|||
# menu
|
||||
# Menu
|
||||
|
||||
The `Menu` class is used to create native menus that can be used as
|
||||
application menus and context menus. Each menu consists of multiple menu
|
||||
items, and each menu item can have a submenu.
|
||||
The `menu` class is used to create native menus that can be used as
|
||||
application menus and
|
||||
[context menus](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus).
|
||||
This module is a main process module which can be used in a render process via
|
||||
the `remote` module.
|
||||
|
||||
Below is an example of creating a menu dynamically in a web page by using
|
||||
the [remote](remote.md) module, and showing it when the user right clicks
|
||||
the page:
|
||||
Each menu consists of multiple [menu items](menu-item.md) and each menu item can
|
||||
have a submenu.
|
||||
|
||||
Below is an example of creating a menu dynamically in a web page
|
||||
(render process) by using the [remote](remote.md) module, and showing it when
|
||||
the user right clicks the page:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
@ -27,69 +32,23 @@ window.addEventListener('contextmenu', function (e) {
|
|||
</script>
|
||||
```
|
||||
|
||||
Another example of creating the application menu with the simple template API:
|
||||
An example of creating the application menu in the render process with the
|
||||
simple template API:
|
||||
|
||||
**Note to Window and Linux users** the `selector` member of each menu item is a Mac-only [Accelerator option](https://github.com/atom/electron/blob/master/docs/api/accelerator.md).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<script>
|
||||
var remote = require('remote');
|
||||
var Menu = remote.require('menu');
|
||||
```javascript
|
||||
var template = [
|
||||
{
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'CmdOrCtrl+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'CmdOrCtrl+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'CmdOrCtrl+Q',
|
||||
selector: 'terminate:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
selector: 'undo:'
|
||||
role: 'undo'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+CmdOrCtrl+Z',
|
||||
selector: 'redo:'
|
||||
role: 'redo'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
|
@ -97,23 +56,23 @@ var template = [
|
|||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
selector: 'cut:'
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
selector: 'copy:'
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
selector: 'paste:'
|
||||
role: 'paste'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
selector: 'selectAll:'
|
||||
}
|
||||
role: 'selectall'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -122,147 +81,224 @@ var template = [
|
|||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'CmdOrCtrl+R',
|
||||
click: function() { remote.getCurrentWindow().reload(); }
|
||||
click: function(item, focusedWindow) {
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle DevTools',
|
||||
accelerator: 'Alt+CmdOrCtrl+I',
|
||||
click: function() { remote.getCurrentWindow().toggleDevTools(); }
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: (function() {
|
||||
if (process.platform == 'darwin')
|
||||
return 'Ctrl+Command+F';
|
||||
else
|
||||
return 'F11';
|
||||
})(),
|
||||
click: function(item, focusedWindow) {
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: (function() {
|
||||
if (process.platform == 'darwin')
|
||||
return 'Alt+Command+I';
|
||||
else
|
||||
return 'Ctrl+Shift+I';
|
||||
})(),
|
||||
click: function(item, focusedWindow) {
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
selector: 'performMiniaturize:'
|
||||
role: 'minimize'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
selector: 'performClose:'
|
||||
role: 'close'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
if (process.platform == 'darwin') {
|
||||
var name = require('app').getName();
|
||||
template.unshift({
|
||||
label: name,
|
||||
submenu: [
|
||||
{
|
||||
label: 'About ' + name,
|
||||
role: 'about'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
}
|
||||
label: 'Services',
|
||||
role: 'services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide ' + name,
|
||||
accelerator: 'Command+H',
|
||||
role: 'hide'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
role: 'hideothers:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
role: 'unhide:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: []
|
||||
}
|
||||
];
|
||||
});
|
||||
// Window menu.
|
||||
template[3].submenu.push(
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
role: 'front'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
menu = Menu.buildFromTemplate(template);
|
||||
|
||||
Menu.setApplicationMenu(menu);
|
||||
</script>
|
||||
```
|
||||
|
||||
## Class: Menu
|
||||
|
||||
### new Menu()
|
||||
### `new Menu()`
|
||||
|
||||
Creates a new menu.
|
||||
|
||||
### Class Method: Menu.setApplicationMenu(menu)
|
||||
## Methods
|
||||
|
||||
The `menu` class has the following methods:
|
||||
|
||||
### `Menu.setApplicationMenu(menu)`
|
||||
|
||||
* `menu` Menu
|
||||
|
||||
Sets `menu` as the application menu on OS X. On Windows and Linux, the `menu`
|
||||
will be set as each window's top menu.
|
||||
|
||||
### Class Method: Menu.sendActionToFirstResponder(action)
|
||||
### `Menu.sendActionToFirstResponder(action)` _OS X_
|
||||
|
||||
* `action` String
|
||||
|
||||
Sends the `action` to the first responder of application, this is used for
|
||||
Sends the `action` to the first responder of application. This is used for
|
||||
emulating default Cocoa menu behaviors, usually you would just use the
|
||||
`selector` property of `MenuItem`.
|
||||
|
||||
**Note:** This method is OS X only.
|
||||
|
||||
### Class Method: Menu.buildFromTemplate(template)
|
||||
### `Menu.buildFromTemplate(template)`
|
||||
|
||||
* `template` Array
|
||||
|
||||
Generally, the `template` is just an array of `options` for constructing
|
||||
[MenuItem](menu-item.md), the usage can be referenced above.
|
||||
Generally, the `template` is just an array of `options` for constructing a
|
||||
[MenuItem](menu-item.md). The usage can be referenced above.
|
||||
|
||||
You can also attach other fields to element of the `template`, and they will
|
||||
become properties of the constructed menu items.
|
||||
You can also attach other fields to the element of the `template` and they
|
||||
will become properties of the constructed menu items.
|
||||
|
||||
### Menu.popup(browserWindow, [x, y])
|
||||
### `Menu.popup(browserWindow[, x, y])`
|
||||
|
||||
* `browserWindow` BrowserWindow
|
||||
* `x` Number
|
||||
* `y` Number
|
||||
* `x` Number (optional)
|
||||
* `y` Number (**required** if `x` is used)
|
||||
|
||||
Popups this menu as a context menu in the `browserWindow`. You can optionally
|
||||
provide a `(x,y)` coordinate to place the menu at, otherwise it will be placed
|
||||
at the current mouse cursor position.
|
||||
Pops up this menu as a context menu in the `browserWindow`. You
|
||||
can optionally provide a `x,y` coordinate to place the menu at, otherwise it
|
||||
will be placed at the current mouse cursor position.
|
||||
|
||||
### Menu.append(menuItem)
|
||||
### `Menu.append(menuItem)`
|
||||
|
||||
* `menuItem` MenuItem
|
||||
|
||||
Appends the `menuItem` to the menu.
|
||||
|
||||
### Menu.insert(pos, menuItem)
|
||||
### `Menu.insert(pos, menuItem)`
|
||||
|
||||
* `pos` Integer
|
||||
* `menuItem` MenuItem
|
||||
|
||||
Inserts the `menuItem` to the `pos` position of the menu.
|
||||
|
||||
### Menu.items
|
||||
### `Menu.items()`
|
||||
|
||||
Get the array containing the menu's items.
|
||||
Get an array containing the menu's items.
|
||||
|
||||
## Notes on OS X application menu
|
||||
## Notes on OS X Application Menu
|
||||
|
||||
OS X has a completely different style of application menu from Windows and
|
||||
Linux, and here are some notes on making your app's menu more native-like.
|
||||
Linux, here are some notes on making your app's menu more native-like.
|
||||
|
||||
### Standard menus
|
||||
### Standard Menus
|
||||
|
||||
On OS X there are many system defined standard menus, like the `Services` and
|
||||
`Windows` menus. To make your menu a standard menu, you can just set your menu's
|
||||
label to one of followings, and Electron will recognize them and make them
|
||||
`Windows` menus. To make your menu a standard menu, you should set your menu's
|
||||
`role` to one of following and Electron will recognize them and make them
|
||||
become standard menus:
|
||||
|
||||
* `Window`
|
||||
* `Help`
|
||||
* `Services`
|
||||
* `window`
|
||||
* `help`
|
||||
* `services`
|
||||
|
||||
### Standard menu item actions
|
||||
### Standard Menu Item Actions
|
||||
|
||||
OS X has provided standard actions for some menu items (which are called
|
||||
`selector`s), like `About xxx`, `Hide xxx`, and `Hide Others`. To set the action
|
||||
of a menu item to a standard action, you can set the `selector` attribute of the
|
||||
menu item.
|
||||
OS X has provided standard actions for some menu items, like `About xxx`,
|
||||
`Hide xxx`, and `Hide Others`. To set the action of a menu item to a standard
|
||||
action, you should set the `role` attribute of the menu item.
|
||||
|
||||
### Main menu's name
|
||||
### Main Menu's Name
|
||||
|
||||
On OS X the label of application menu's first item is always your app's name,
|
||||
no matter what label you set. To change it you have to change your app's name
|
||||
by modifying your app bundle's `Info.plist` file. See
|
||||
[About Information Property List Files](https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html)
|
||||
for more.
|
||||
by modifying your app bundle's `Info.plist` file. See [About Information
|
||||
Property List Files][AboutInformationPropertyListFiles] for more information.
|
||||
|
||||
## Menu Item Position
|
||||
|
||||
## Menu item position
|
||||
|
||||
You can make use of `position` and `id` to control how the item would be placed
|
||||
You can make use of `position` and `id` to control how the item will be placed
|
||||
when building a menu with `Menu.buildFromTemplate`.
|
||||
|
||||
The `position` attribute of `MenuItem` has the form `[placement]=[id]` where
|
||||
The `position` attribute of `MenuItem` has the form `[placement]=[id]`, where
|
||||
placement is one of `before`, `after`, or `endof` and `id` is the unique ID of
|
||||
an existing item in the menu:
|
||||
|
||||
|
@ -272,12 +308,12 @@ an existing item in the menu:
|
|||
* `after` - Inserts this item after id referenced item. If the referenced
|
||||
item doesn't exist the item will be inserted at the end of the menu.
|
||||
* `endof` - Inserts this item at the end of the logical group containing
|
||||
the id referenced item. (Groups are created by separator items). If
|
||||
the referenced item doesn't exist a new separator group is created with
|
||||
the id referenced item (groups are created by separator items). If
|
||||
the referenced item doesn't exist, a new separator group is created with
|
||||
the given id and this item is inserted after that separator.
|
||||
|
||||
When an item is positioned following unpositioned items are inserted after
|
||||
it, until a new item is positioned. So if you want to position a group of
|
||||
When an item is positioned, all un-positioned items are inserted after
|
||||
it until a new item is positioned. So if you want to position a group of
|
||||
menu items in the same location you only need to specify a position for
|
||||
the first item.
|
||||
|
||||
|
@ -330,3 +366,5 @@ Menu:
|
|||
- 2
|
||||
- 3
|
||||
```
|
||||
|
||||
[AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
# NativeImage
|
||||
|
||||
In Electron for the APIs that take images, you can pass either file paths or
|
||||
`NativeImage` instances. When passing `null`, an empty image will be used.
|
||||
In Electron, for the APIs that take images, you can pass either file paths or
|
||||
`NativeImage` instances. An empty image will be used when `null` is passed.
|
||||
|
||||
For example, when creating a tray or setting a window's icon, you can pass an image
|
||||
file path as a `String`:
|
||||
For example, when creating a tray or setting a window's icon, you can pass an
|
||||
image file path as a `String`:
|
||||
|
||||
```javascript
|
||||
var appIcon = new Tray('/Users/somebody/images/icon.png');
|
||||
var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'});
|
||||
```
|
||||
|
||||
Or read the image from the clipboard:
|
||||
Or read the image from the clipboard which returns a `NativeImage`:
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
|
@ -19,25 +19,25 @@ var image = clipboard.readImage();
|
|||
var appIcon = new Tray(image);
|
||||
```
|
||||
|
||||
## Supported formats
|
||||
## Supported Formats
|
||||
|
||||
Currently `PNG` and `JPEG` are supported. It is recommended to use `PNG` because
|
||||
of its support for transparency and lossless compression.
|
||||
Currently `PNG` and `JPEG` image formats are supported. `PNG` is recommended
|
||||
because of its support for transparency and lossless compression.
|
||||
|
||||
On Windows, you can also load `ICO` icon from a file path.
|
||||
On Windows, you can also load an `ICO` icon from a file path.
|
||||
|
||||
## High resolution image
|
||||
## High Resolution Image
|
||||
|
||||
On platforms that have high-DPI support, you can append `@2x` after image's
|
||||
file name's base name to mark it as a high resolution image.
|
||||
base filename to mark it as a high resolution image.
|
||||
|
||||
For example if `icon.png` is a normal image that has standard resolution, the
|
||||
`icon@2x.png` would be treated as a high resolution image that has double DPI
|
||||
For example if `icon.png` is a normal image that has standard resolution, then
|
||||
`icon@2x.png` will be treated as a high resolution image that has double DPI
|
||||
density.
|
||||
|
||||
If you want to support displays with different DPI density at the same time, you
|
||||
can put images with different sizes in the same folder, and use the filename
|
||||
without DPI suffixes, like this:
|
||||
If you want to support displays with different DPI densities at the same time,
|
||||
you can put images with different sizes in the same folder and use the filename
|
||||
without DPI suffixes. For example:
|
||||
|
||||
```text
|
||||
images/
|
||||
|
@ -51,7 +51,7 @@ images/
|
|||
var appIcon = new Tray('/Users/somebody/images/icon.png');
|
||||
```
|
||||
|
||||
Following suffixes as DPI denses are also supported:
|
||||
Following suffixes for DPI are also supported:
|
||||
|
||||
* `@1x`
|
||||
* `@1.25x`
|
||||
|
@ -65,81 +65,91 @@ Following suffixes as DPI denses are also supported:
|
|||
* `@4x`
|
||||
* `@5x`
|
||||
|
||||
## Template image
|
||||
## Template Image
|
||||
|
||||
Template images consist of black and clear colors (and an alpha channel).
|
||||
Template images are not intended to be used as standalone images and are usually
|
||||
mixed with other content to create the desired final appearance.
|
||||
|
||||
The most common case is to use template image for menu bar icon so it can adapt
|
||||
to both light and dark menu bars.
|
||||
The most common case is to use template images for a menu bar icon so it can
|
||||
adapt to both light and dark menu bars.
|
||||
|
||||
Template image is only supported on Mac.
|
||||
**Note**: Template image is only supported on OS X.
|
||||
|
||||
To mark an image as template image, its filename should end with the word
|
||||
`Template`, examples are:
|
||||
To mark an image as a template image, its filename should end with the word
|
||||
`Template`. For example:
|
||||
|
||||
* `xxxTemplate.png`
|
||||
* `xxxTemplate@2x.png`
|
||||
|
||||
## nativeImage.createEmpty()
|
||||
## Methods
|
||||
|
||||
The `NativeImage` class has the following methods:
|
||||
|
||||
### `NativeImage.createEmpty()`
|
||||
|
||||
Creates an empty `NativeImage` instance.
|
||||
|
||||
## nativeImage.createFromPath(path)
|
||||
### `NativeImage.createFromPath(path)`
|
||||
|
||||
* `path` String
|
||||
|
||||
Creates a new `NativeImage` instance from a file located at `path`.
|
||||
|
||||
## nativeImage.createFromBuffer(buffer[, scaleFactor])
|
||||
### `NativeImage.createFromBuffer(buffer[, scaleFactor])`
|
||||
|
||||
* `buffer` [Buffer][buffer]
|
||||
* `scaleFactor` Double
|
||||
* `scaleFactor` Double (optional)
|
||||
|
||||
Creates a new `NativeImage` instance from `buffer`. The `scaleFactor` is 1.0 by
|
||||
default.
|
||||
Creates a new `NativeImage` instance from `buffer`. The default `scaleFactor` is
|
||||
1.0.
|
||||
|
||||
## nativeImage.createFromDataUrl(dataUrl)
|
||||
### `NativeImage.createFromDataUrl(dataUrl)`
|
||||
|
||||
* `dataUrl` String
|
||||
|
||||
Creates a new `NativeImage` instance from `dataUrl`.
|
||||
|
||||
## Class: NativeImage
|
||||
## Instance Methods
|
||||
|
||||
This class is used to represent an image.
|
||||
The following methods are available on instances of `nativeImage`:
|
||||
|
||||
### NativeImage.toPng()
|
||||
```javascript
|
||||
var NativeImage = require('native-image');
|
||||
|
||||
Returns a [Buffer][buffer] that contains image's `PNG` encoded data.
|
||||
var image = NativeImage.createFromPath('/Users/somebody/images/icon.png');
|
||||
```
|
||||
|
||||
### NativeImage.toJpeg(quality)
|
||||
### `image.toPng()`
|
||||
|
||||
* `quality` Integer between 0 - 100 (required)
|
||||
Returns a [Buffer][buffer] that contains the image's `PNG` encoded data.
|
||||
|
||||
Returns a [Buffer][buffer] that contains image's `JPEG` encoded data.
|
||||
### `image.toJpeg(quality)`
|
||||
|
||||
### NativeImage.toDataUrl()
|
||||
* `quality` Integer between 0 - 100 (**required**)
|
||||
|
||||
Returns the data URL of image.
|
||||
Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data.
|
||||
|
||||
### NativeImage.isEmpty()
|
||||
### `image.toDataUrl()`
|
||||
|
||||
Returns whether the image is empty.
|
||||
Returns the data URL of the image.
|
||||
|
||||
### NativeImage.getSize()
|
||||
### `image.isEmpty()`
|
||||
|
||||
Returns a boolean whether the image is empty.
|
||||
|
||||
### `image.getSize()`
|
||||
|
||||
Returns the size of the image.
|
||||
|
||||
[buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer
|
||||
|
||||
### NativeImage.setTemplateImage(option)
|
||||
### `image.setTemplateImage(option)`
|
||||
|
||||
* `option` Boolean
|
||||
|
||||
Marks the image as template image.
|
||||
|
||||
### NativeImage.isTemplateImage()
|
||||
### `image.isTemplateImage()`
|
||||
|
||||
Returns whether the image is a template image.
|
||||
Returns a boolean whether the image is a template image.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# power-monitor
|
||||
|
||||
The `power-monitor` module is used to monitor the power state change. You can
|
||||
only use it on the main process. You should not use this module until the `ready`
|
||||
event of `app` module gets emitted.
|
||||
The `power-monitor` module is used to monitor power state changes. You can
|
||||
only use it on the main process. You should not use this module until the `ready`
|
||||
event of the `app` module is emitted.
|
||||
|
||||
An example is:
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
|
@ -16,18 +16,22 @@ app.on('ready', function() {
|
|||
});
|
||||
```
|
||||
|
||||
## Event: suspend
|
||||
## Events
|
||||
|
||||
The `power-monitor` module emits the following events:
|
||||
|
||||
### Event: 'suspend'
|
||||
|
||||
Emitted when the system is suspending.
|
||||
|
||||
## Event: resume
|
||||
### Event: 'resume'
|
||||
|
||||
Emitted when system is resuming.
|
||||
|
||||
## Event: on-ac
|
||||
### Event: 'on-ac'
|
||||
|
||||
Emitted when the system changes to AC power.
|
||||
|
||||
## Event: on-battery
|
||||
### Event: 'on-battery'
|
||||
|
||||
Emitted when system changes to battery power.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
# power-save-blocker
|
||||
# powerSaveBlocker
|
||||
|
||||
The `power-save-blocker` module is used to block the system from entering
|
||||
low-power(sleep) mode, allowing app to keep system and screen active.
|
||||
low-power (sleep) mode and thus allowing the app to keep the system and screen
|
||||
active.
|
||||
|
||||
An example is:
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
var powerSaveBlocker = require('power-save-blocker');
|
||||
|
@ -14,35 +15,40 @@ console.log(powerSaveBlocker.isStarted(id));
|
|||
powerSaveBlocker.stop(id);
|
||||
```
|
||||
|
||||
## powerSaveBlocker.start(type)
|
||||
## Methods
|
||||
|
||||
* `type` String - Power save blocker type
|
||||
The `powerSaveBlocker` module has the following methods:
|
||||
|
||||
### `powerSaveBlocker.start(type)`
|
||||
|
||||
* `type` String - Power save blocker type.
|
||||
* `prevent-app-suspension` - Prevent the application from being suspended.
|
||||
Keeps system active, but allows screen to be turned off. Example use cases:
|
||||
downloading a file, playing audio.
|
||||
* `prevent-display-sleep`- Prevent the display from going to sleep. Keeps system
|
||||
and screen active. Example use case: playing video.
|
||||
Keeps system active but allows screen to be turned off. Example use cases:
|
||||
downloading a file or playing audio.
|
||||
* `prevent-display-sleep`- Prevent the display from going to sleep. Keeps
|
||||
system and screen active. Example use case: playing video.
|
||||
|
||||
Starts the power save blocker preventing the system entering lower-power mode.
|
||||
Returns an integer identified the power save blocker.
|
||||
Starts preventing the system from entering lower-power mode. Returns an integer
|
||||
identifying the power save blocker.
|
||||
|
||||
**Note:**
|
||||
`prevent-display-sleep` has higher precedence level than `prevent-app-suspension`.
|
||||
Only the highest precedence type takes effect. In other words, `prevent-display-sleep`
|
||||
always take precedence over `prevent-app-suspension`.
|
||||
**Note:** `prevent-display-sleep` has higher has precedence over
|
||||
`prevent-app-suspension`. Only the highest precedence type takes effect. In
|
||||
other words, `prevent-display-sleep` always takes precedence over
|
||||
`prevent-app-suspension`.
|
||||
|
||||
For example, an API calling A requests for `prevent-app-suspension`, and
|
||||
another calling B requests for `prevent-display-sleep`. `prevent-display-sleep`
|
||||
will be used until B stops its request. After that, `prevent-app-suspension` is used.
|
||||
will be used until B stops its request. After that, `prevent-app-suspension`
|
||||
is used.
|
||||
|
||||
## powerSaveBlocker.stop(id)
|
||||
### `powerSaveBlocker.stop(id)`
|
||||
|
||||
* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`.
|
||||
|
||||
Stops the specified power save blocker.
|
||||
|
||||
## powerSaveBlocker.isStarted(id)
|
||||
### `powerSaveBlocker.isStarted(id)`
|
||||
|
||||
* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`.
|
||||
|
||||
Returns whether the corresponding `powerSaveBlocker` starts.
|
||||
Returns a boolean whether the corresponding `powerSaveBlocker` has started.
|
||||
|
|
|
@ -1,13 +1,25 @@
|
|||
# Process object
|
||||
# process
|
||||
|
||||
The `process` object in Electron has the following differences from the one in
|
||||
upstream node:
|
||||
|
||||
* `process.type` String - Process's type, can be `browser` (i.e. main process) or `renderer`.
|
||||
* `process.type` String - Process's type, can be `browser` (i.e. main process)
|
||||
or `renderer`.
|
||||
* `process.versions['electron']` String - Version of Electron.
|
||||
* `process.versions['chrome']` String - Version of Chromium.
|
||||
* `process.resourcesPath` String - Path to JavaScript source code.
|
||||
|
||||
## process.hang
|
||||
# Methods
|
||||
|
||||
The `process` object has the following method:
|
||||
|
||||
### `process.hang`
|
||||
|
||||
Causes the main thread of the current process hang.
|
||||
|
||||
## process.setFdLimit(maxDescriptors) _OS X_ _Linux_
|
||||
|
||||
* `maxDescriptors` Integer
|
||||
|
||||
Sets the file descriptor soft limit to `maxDescriptors` or the OS hard
|
||||
limit, whichever is lower for the current process.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
The `protocol` module can register a custom protocol or intercept an existing
|
||||
protocol.
|
||||
|
||||
An example of implementing a protocol that has the same effect with the
|
||||
An example of implementing a protocol that has the same effect as the
|
||||
`file://` protocol:
|
||||
|
||||
```javascript
|
||||
|
@ -22,50 +22,56 @@ app.on('ready', function() {
|
|||
});
|
||||
```
|
||||
|
||||
**Note:** This module can only be used after the `ready` event was emitted.
|
||||
**Note:** This module can only be used after the `ready` event in the `app`
|
||||
module is emitted.
|
||||
|
||||
## protocol.registerStandardSchemes(schemes)
|
||||
## Methods
|
||||
|
||||
The `protocol` module has the following methods:
|
||||
|
||||
### `protocol.registerStandardSchemes(schemes)`
|
||||
|
||||
* `schemes` Array - Custom schemes to be registered as standard schemes.
|
||||
|
||||
A standard scheme adheres to what RFC 3986 calls
|
||||
A standard `scheme` adheres to what RFC 3986 calls
|
||||
[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3). This
|
||||
includes `file:` and `filesystem:`.
|
||||
|
||||
## protocol.registerFileProtocol(scheme, handler[, completion])
|
||||
### `protocol.registerFileProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Registers a protocol of `scheme` that will send file as response, the `handler`
|
||||
will be called with `handler(request, callback)` when a `request` is going to be
|
||||
created with `scheme`, and `completion` will be called with `completion(null)`
|
||||
when `scheme` is successfully registered, or `completion(error)` when failed.
|
||||
Registers a protocol of `scheme` that will send the file as a response. The
|
||||
`handler` will be called with `handler(request, callback)` when a `request` is
|
||||
going to be created with `scheme`. `completion` will be called with
|
||||
`completion(null)` when `scheme` is successfully registered or
|
||||
`completion(error)` when failed.
|
||||
|
||||
To handle the `request`, the `callback` should be called with either file's path
|
||||
or an object that has `path` property, e.g. `callback(filePath)` or
|
||||
To handle the `request`, the `callback` should be called with either the file's
|
||||
path or an object that has a `path` property, e.g. `callback(filePath)` or
|
||||
`callback({path: filePath})`.
|
||||
|
||||
When `callback` is called with nothing, or a number, or an object that has
|
||||
`error` property, the `request` will be failed with the `error` number you
|
||||
specified. For the available error numbers you can use, please check:
|
||||
https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h
|
||||
When `callback` is called with nothing, a number, or an object that has an
|
||||
`error` property, the `request` will fail with the `error` number you
|
||||
specified. For the available error numbers you can use, please see the
|
||||
[net error list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h).
|
||||
|
||||
By default the scheme is treated like `http:`, which is parsed differently
|
||||
from protocols that follows "generic URI syntax" like `file:`, so you probably
|
||||
want to call `protocol.registerStandardSchemes` to make your scheme treated as
|
||||
standard scheme.
|
||||
By default the `scheme` is treated like `http:`, which is parsed differently
|
||||
than protocols that follow the "generic URI syntax" like `file:`, so you
|
||||
probably want to call `protocol.registerStandardSchemes` to have your scheme
|
||||
treated as a standard scheme.
|
||||
|
||||
## protocol.registerBufferProtocol(scheme, handler[, completion])
|
||||
### `protocol.registerBufferProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Registers a protocol of `scheme` that will send `Buffer` as response, the
|
||||
`callback` should be called with either an `Buffer` object, or an object that
|
||||
has `data`, `mimeType`, `chart` properties.
|
||||
Registers a protocol of `scheme` that will send a `Buffer` as a response. The
|
||||
`callback` should be called with either a `Buffer` object or an object that
|
||||
has the `data`, `mimeType`, and `chart` properties.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -78,37 +84,37 @@ protocol.registerBufferProtocol('atom', function(request, callback) {
|
|||
});
|
||||
```
|
||||
|
||||
## protocol.registerStringProtocol(scheme, handler[, completion])
|
||||
### `protocol.registerStringProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Registers a protocol of `scheme` that will send `String` as response, the
|
||||
`callback` should be called with either a `String`, or an object that
|
||||
has `data`, `mimeType`, `chart` properties.
|
||||
Registers a protocol of `scheme` that will send a `String` as a response. The
|
||||
`callback` should be called with either a `String` or an object that has the
|
||||
`data`, `mimeType`, and `chart` properties.
|
||||
|
||||
## protocol.registerHttpProtocol(scheme, handler[, completion])
|
||||
### `protocol.registerHttpProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Registers a protocol of `scheme` that will send a HTTP request as response, the
|
||||
`callback` should be called with an object that has `url`, `method`, `referer`,
|
||||
`session` properties.
|
||||
Registers a protocol of `scheme` that will send an HTTP request as a response.
|
||||
The `callback` should be called with an object that has the `url`, `method`,
|
||||
`referer`, and `session` properties.
|
||||
|
||||
By default the HTTP request will reuse current session, if you want the request
|
||||
to have different session you should specify `session` to `null`.
|
||||
By default the HTTP request will reuse the current session. If you want the
|
||||
request to have a different session you should set `session` to `null`.
|
||||
|
||||
## protocol.unregisterProtocol(scheme[, completion])
|
||||
### `protocol.unregisterProtocol(scheme[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Unregisters the custom protocol of `scheme`.
|
||||
|
||||
## protocol.isProtocolHandled(scheme, callback)
|
||||
### `protocol.isProtocolHandled(scheme, callback)`
|
||||
|
||||
* `scheme` String
|
||||
* `callback` Function
|
||||
|
@ -116,43 +122,43 @@ Unregisters the custom protocol of `scheme`.
|
|||
The `callback` will be called with a boolean that indicates whether there is
|
||||
already a handler for `scheme`.
|
||||
|
||||
## protocol.interceptFileProtocol(scheme, handler[, completion])
|
||||
### `protocol.interceptFileProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Intercepts `scheme` protocol and use `handler` as the protocol's new handler
|
||||
which sends file as response.
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a file as a response.
|
||||
|
||||
## protocol.interceptStringProtocol(scheme, handler[, completion])
|
||||
### `protocol.interceptStringProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Intercepts `scheme` protocol and use `handler` as the protocol's new handler
|
||||
which sends String as response.
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a `String` as a response.
|
||||
|
||||
## protocol.interceptBufferProtocol(scheme, handler[, completion])
|
||||
## `protocol.interceptBufferProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Intercepts `scheme` protocol and use `handler` as the protocol's new handler
|
||||
which sends `Buffer` as response.
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a `Buffer` as a response.
|
||||
|
||||
## protocol.interceptHttpProtocol(scheme, handler[, completion])
|
||||
## `protocol.interceptHttpProtocol(scheme, handler[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `completion` Function
|
||||
* `completion` Function (optional)
|
||||
|
||||
Intercepts `scheme` protocol and use `handler` as the protocol's new handler
|
||||
which sends a new HTTP request as response.
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a new HTTP request as a response.
|
||||
|
||||
## protocol.uninterceptProtocol(scheme[, completion])
|
||||
## `protocol.uninterceptProtocol(scheme[, completion])`
|
||||
|
||||
* `scheme` String
|
||||
* `completion` Function
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
# remote
|
||||
|
||||
The `remote` module provides a simple way to do inter-process communication
|
||||
between the renderer process and the main process.
|
||||
(IPC) between the renderer process (web page) and the main process.
|
||||
|
||||
In Electron, only GUI-unrelated modules are available in the renderer process.
|
||||
Without the `remote` module, users who wanted to call a main process API in
|
||||
the renderer process would have to explicitly send inter-process messages
|
||||
to the main process. With the `remote` module, users can invoke methods of
|
||||
main process object without explicitly sending inter-process messages,
|
||||
similar to Java's
|
||||
[RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation).
|
||||
Without the `remote` module, users who want to call a main process API in
|
||||
the renderer process will have to explicitly send inter-process messages
|
||||
to the main process. With the `remote` module, you can invoke methods of the
|
||||
main process object without explicitly sending inter-process messages, similar
|
||||
to Java's [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation).
|
||||
|
||||
An example of creating a browser window in renderer process:
|
||||
An example of creating a browser window from a renderer process:
|
||||
|
||||
```javascript
|
||||
var remote = require('remote');
|
||||
var BrowserWindow = remote.require('browser-window');
|
||||
|
||||
var win = new BrowserWindow({ width: 800, height: 600 });
|
||||
win.loadUrl('https://github.com');
|
||||
```
|
||||
|
||||
Note: for the reverse (access renderer process from main process), you can use
|
||||
[webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code).
|
||||
**Note**: for the reverse (access the renderer process from the main process),
|
||||
you can use [webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code).
|
||||
|
||||
## Remote objects
|
||||
## Remote Objects
|
||||
|
||||
Each object (including functions) returned by the `remote` module represents an
|
||||
object in the main process (we call it a remote object or remote function).
|
||||
|
@ -32,34 +32,37 @@ a new object with the remote constructor (function), you are actually sending
|
|||
synchronous inter-process messages.
|
||||
|
||||
In the example above, both `BrowserWindow` and `win` were remote objects and
|
||||
`new BrowserWindow` didn't create a `BrowserWindow` object in the renderer process.
|
||||
Instead, it created a `BrowserWindow` object in the main process and returned the
|
||||
corresponding remote object in the renderer process, namely the `win` object.
|
||||
`new BrowserWindow` didn't create a `BrowserWindow` object in the renderer
|
||||
process. Instead, it created a `BrowserWindow` object in the main process and
|
||||
returned the corresponding remote object in the renderer process, namely the
|
||||
`win` object.
|
||||
|
||||
## Lifetime of remote objects
|
||||
## Lifetime of Remote Objects
|
||||
|
||||
Electron makes sure that as long as the remote object in the renderer process
|
||||
lives (in other words, has not been garbage collected), the corresponding object
|
||||
in the main process would never be released. When the remote object has been
|
||||
garbage collected, the corresponding object in the main process would be
|
||||
in the main process will not be released. When the remote object has been
|
||||
garbage collected, the corresponding object in the main process will be
|
||||
dereferenced.
|
||||
|
||||
If the remote object is leaked in renderer process (e.g. stored in a map but never
|
||||
freed), the corresponding object in the main process would also be leaked,
|
||||
If the remote object is leaked in the renderer process (e.g. stored in a map but
|
||||
never freed), the corresponding object in the main process will also be leaked,
|
||||
so you should be very careful not to leak remote objects.
|
||||
|
||||
Primary value types like strings and numbers, however, are sent by copy.
|
||||
|
||||
## Passing callbacks to the main process
|
||||
|
||||
Code in the main process can accept callbacks from the renderer - for instance the `remote` module -
|
||||
but you should be extremely careful when using this feature.
|
||||
Code in the main process can accept callbacks from the renderer - for instance
|
||||
the `remote` module - but you should be extremely careful when using this
|
||||
feature.
|
||||
|
||||
First, in order to avoid deadlocks, the callbacks passed to the main process
|
||||
are called asynchronously. You should not expect the main process to
|
||||
get the return value of the passed callbacks.
|
||||
|
||||
For instance you can't use a function from the renderer process in a `Array.map` called in the main process:
|
||||
For instance you can't use a function from the renderer process in an
|
||||
`Array.map` called in the main process:
|
||||
|
||||
```javascript
|
||||
// main process mapNumbers.js
|
||||
|
@ -69,10 +72,12 @@ exports.withRendererCallback = function(mapper) {
|
|||
|
||||
exports.withLocalCallback = function() {
|
||||
return exports.mapNumbers(function(x) {
|
||||
return x + 1;
|
||||
return x + 1;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
// renderer process
|
||||
var mapNumbers = require("remote").require("mapNumbers");
|
||||
|
||||
|
@ -85,8 +90,9 @@ var withLocalCb = mapNumbers.withLocalCallback()
|
|||
console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4]
|
||||
```
|
||||
|
||||
As you can see, the renderer callback's synchronous return value was not as expected,
|
||||
and didn't match the return value of an indentical callback that lives in the main process.
|
||||
As you can see, the renderer callback's synchronous return value was not as
|
||||
expected, and didn't match the return value of an identical callback that lives
|
||||
in the main process.
|
||||
|
||||
Second, the callbacks passed to the main process will persist until the
|
||||
main process garbage-collects them.
|
||||
|
@ -96,45 +102,52 @@ callback for the `close` event on a remote object:
|
|||
|
||||
```javascript
|
||||
var remote = require('remote');
|
||||
|
||||
remote.getCurrentWindow().on('close', function() {
|
||||
// blabla...
|
||||
});
|
||||
```
|
||||
|
||||
But remember the callback is referenced by the main process until you
|
||||
explicitly uninstall it! If you do not, each time you reload your window the callback will
|
||||
be installed again, leaking one callback each restart.
|
||||
explicitly uninstall it. If you do not, each time you reload your window the
|
||||
callback will be installed again, leaking one callback for each restart.
|
||||
|
||||
To make things worse, since the context of previously installed callbacks have been released,
|
||||
when the `close` event was emitted exceptions would be raised in the main process.
|
||||
To make things worse, since the context of previously installed callbacks has
|
||||
been released, exceptions will be raised in the main process when the `close`
|
||||
event is emitted.
|
||||
|
||||
To avoid this problem, ensure you clean up any references to renderer callbacks passed to the main
|
||||
process. This involves cleaning up event handlers, or ensuring the main process is explicitly told to deference
|
||||
callbacks that came from a renderer process that is exiting.
|
||||
To avoid this problem, ensure you clean up any references to renderer callbacks
|
||||
passed to the main process. This involves cleaning up event handlers, or
|
||||
ensuring the main process is explicitly told to deference callbacks that came
|
||||
from a renderer process that is exiting.
|
||||
|
||||
## remote.require(module)
|
||||
## Methods
|
||||
|
||||
The `remote` module has the following methods:
|
||||
|
||||
### `remote.require(module)`
|
||||
|
||||
* `module` String
|
||||
|
||||
Returns the object returned by `require(module)` in the main process.
|
||||
|
||||
## remote.getCurrentWindow()
|
||||
### `remote.getCurrentWindow()`
|
||||
|
||||
Returns the [BrowserWindow](browser-window.md) object which this web page
|
||||
belongs to.
|
||||
Returns the [`BrowserWindow`](browser-window.md) object to which this web page
|
||||
belongs.
|
||||
|
||||
## remote.getCurrentWebContents()
|
||||
### `remote.getCurrentWebContents()`
|
||||
|
||||
Returns the WebContents object of this web page.
|
||||
Returns the [`WebContents`](web-contents.md) object of this web page.
|
||||
|
||||
## remote.getGlobal(name)
|
||||
### `remote.getGlobal(name)`
|
||||
|
||||
* `name` String
|
||||
|
||||
Returns the global variable of `name` (e.g. `global[name]`) in the main
|
||||
process.
|
||||
|
||||
## remote.process
|
||||
### `remote.process`
|
||||
|
||||
Returns the `process` object in the main process. This is the same as
|
||||
`remote.getGlobal('process')`, but gets cached.
|
||||
`remote.getGlobal('process')` but is cached.
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
# screen
|
||||
|
||||
Gets various info about screen size, displays, cursor position, etc. You should
|
||||
not use this module until the `ready` event of `app` module gets emitted.
|
||||
The `screen` module retrieves information about screen size, displays, cursor
|
||||
position, etc. You should not use this module until the `ready` event of the
|
||||
`app` module is emitted.
|
||||
|
||||
`screen` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter).
|
||||
|
||||
Make sure to note that in the renderer / DevTools, `window.screen` is a reserved DOM property, so writing `screen = require('screen')` won't work. In our examples below, we use `atomScreen` as the variable name instead.
|
||||
**Note**: In the renderer / DevTools, `window.screen` is a reserved
|
||||
DOM property, so writing `var screen = require('screen')` will not work. In our
|
||||
examples below, we use `atomScreen` as the variable name instead.
|
||||
|
||||
An example of creating a window that fills the whole screen:
|
||||
|
||||
|
@ -50,43 +53,57 @@ app.on('ready', function() {
|
|||
});
|
||||
```
|
||||
|
||||
## Event: display-added
|
||||
## Events
|
||||
|
||||
The `screen` module emits the following events:
|
||||
|
||||
### Event: 'display-added'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `newDisplay` Object
|
||||
|
||||
Emitted when `newDisplay` has been added.
|
||||
|
||||
## Event: display-removed
|
||||
### Event: 'display-removed'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `oldDisplay` Object
|
||||
|
||||
Emitted when `oldDisplay` has been removed.
|
||||
|
||||
## Event: display-metrics-changed
|
||||
### Event: 'display-metrics-changed'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `display` Object
|
||||
* `changedMetrics` Array
|
||||
|
||||
Emitted when a `display` has one or more metrics changed, `changedMetrics` is
|
||||
Emitted when one or more metrics change in a `display`. The `changedMetrics` is
|
||||
an array of strings that describe the changes. Possible changes are `bounds`,
|
||||
`workArea`, `scaleFactor` and `rotation`.
|
||||
|
||||
## screen.getCursorScreenPoint()
|
||||
## Methods
|
||||
|
||||
The `screen` module has the following methods:
|
||||
|
||||
### `screen.getCursorScreenPoint()`
|
||||
|
||||
Returns the current absolute position of the mouse pointer.
|
||||
|
||||
## screen.getPrimaryDisplay()
|
||||
### `screen.getPrimaryDisplay()`
|
||||
|
||||
Returns the primary display.
|
||||
|
||||
## screen.getAllDisplays()
|
||||
### `screen.getAllDisplays()`
|
||||
|
||||
Returns an array of displays that are currently available.
|
||||
|
||||
## screen.getDisplayNearestPoint(point)
|
||||
### `screen.getDisplayNearestPoint(point)`
|
||||
|
||||
* `point` Object
|
||||
* `x` Integer
|
||||
|
@ -94,7 +111,7 @@ Returns an array of displays that are currently available.
|
|||
|
||||
Returns the display nearest the specified point.
|
||||
|
||||
## screen.getDisplayMatching(rect)
|
||||
### `screen.getDisplayMatching(rect)`
|
||||
|
||||
* `rect` Object
|
||||
* `x` Integer
|
||||
|
|
|
@ -13,6 +13,31 @@ win.loadUrl("http://github.com");
|
|||
var session = win.webContents.session
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
### Event: 'will-download'
|
||||
|
||||
* `event` Event
|
||||
* `item` Object
|
||||
* `url` String
|
||||
* `filename` String
|
||||
* `mimeType` String
|
||||
* `hasUserGesture` Boolean
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
|
||||
Fired when Electron is about to download `item` in `webContents`.
|
||||
|
||||
Calling `event.preventDefault()` will cancel the download.
|
||||
|
||||
```javascript
|
||||
session.on('will-download', function(event, item, webContents) {
|
||||
event.preventDefault();
|
||||
require('request')(item.url, function(data) {
|
||||
require('fs').writeFileSync('/somewhere', data);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `session` object has the following methods:
|
||||
|
|
|
@ -2,38 +2,43 @@
|
|||
|
||||
The `shell` module provides functions related to desktop integration.
|
||||
|
||||
An example of opening a URL in default browser:
|
||||
An example of opening a URL in the user's default browser:
|
||||
|
||||
```javascript
|
||||
var shell = require('shell');
|
||||
|
||||
shell.openExternal('https://github.com');
|
||||
```
|
||||
|
||||
## shell.showItemInFolder(fullPath)
|
||||
## Methods
|
||||
|
||||
The `shell` module has the following methods:
|
||||
|
||||
### `shell.showItemInFolder(fullPath)`
|
||||
|
||||
* `fullPath` String
|
||||
|
||||
Show the given file in a file manager. If possible, select the file.
|
||||
|
||||
## shell.openItem(fullPath)
|
||||
### `shell.openItem(fullPath)`
|
||||
|
||||
* `fullPath` String
|
||||
|
||||
Open the given file in the desktop's default manner.
|
||||
|
||||
## shell.openExternal(url)
|
||||
### `shell.openExternal(url)`
|
||||
|
||||
* `url` String
|
||||
|
||||
Open the given external protocol URL in the desktop's default manner. (For
|
||||
example, mailto: URLs in the default mail user agent.)
|
||||
example, mailto: URLs in the user's default mail agent.)
|
||||
|
||||
## shell.moveItemToTrash(fullPath)
|
||||
### `shell.moveItemToTrash(fullPath)`
|
||||
|
||||
* `fullPath` String
|
||||
|
||||
Move the given file to trash and returns boolean status for the operation.
|
||||
Move the given file to trash and returns a boolean status for the operation.
|
||||
|
||||
## shell.beep()
|
||||
### `shell.beep()`
|
||||
|
||||
Play the beep sound.
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
# Synopsis
|
||||
|
||||
All of [node.js's built-in modules](http://nodejs.org/api/) are available in
|
||||
Electron, and third-party node modules are fully supported too (including the
|
||||
[native modules](../tutorial/using-native-node-modules.md)).
|
||||
All of [Node.js's built-in modules](http://nodejs.org/api/) are available in
|
||||
Electron and third-party node modules also fully supported as well (including
|
||||
the [native modules](../tutorial/using-native-node-modules.md)).
|
||||
|
||||
Electron also provides some extra built-in modules for developing native
|
||||
desktop applications. Some modules are only available on the main process, some
|
||||
are only available on the renderer process, and some can be used on both processes.
|
||||
The basic rule is: if a module is GUI or low-level system related, then it should
|
||||
be only available on the main process. You need to be familiar with the concept of
|
||||
are only available in the renderer process (web page), and some can be used in
|
||||
both processes.
|
||||
|
||||
The basic rule is: if a module is
|
||||
[GUI](https://en.wikipedia.org/wiki/Graphical_user_interface) or low-level
|
||||
system related, then it should be only available on the main process. You need
|
||||
to be familiar with the concept of
|
||||
[main process vs. renderer process](../tutorial/quick-start.md#the-main-process)
|
||||
scripts to be able to use those modules.
|
||||
|
||||
The main process script is just like a normal `node.js` script:
|
||||
The main process script is just like a normal Node.js script:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
|
@ -26,7 +30,7 @@ app.on('ready', function() {
|
|||
});
|
||||
```
|
||||
|
||||
The web page is no different than a normal web page, except for the extra
|
||||
The renderer process is no different than a normal web page, except for the extra
|
||||
ability to use node modules:
|
||||
|
||||
```html
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# tray
|
||||
# Tray
|
||||
|
||||
A `Tray` represents an icon in operating system's notification area, it is
|
||||
A `Tray` represents an icon in an operating system's notification area, it is
|
||||
usually attached with a context menu.
|
||||
|
||||
```javascript
|
||||
|
@ -25,26 +25,33 @@ app.on('ready', function(){
|
|||
|
||||
__Platform limitations:__
|
||||
|
||||
* On Linux app indicator will be used if it is supported, otherwise
|
||||
* On Linux the app indicator will be used if it is supported, otherwise
|
||||
`GtkStatusIcon` will be used instead.
|
||||
* On Linux distributions that only have app indicator support, you have to
|
||||
install `libappindicator1` to make tray icon work.
|
||||
* App indicator will only be showed when it has context menu.
|
||||
* When app indicator is used on Linux, `clicked` event is ignored.
|
||||
install `libappindicator1` to make the tray icon work.
|
||||
* App indicator will only be shown when it has a context menu.
|
||||
* When app indicator is used on Linux, the `clicked` event is ignored.
|
||||
|
||||
So if you want to keep exact same behaviors on all platforms, you should not
|
||||
rely on `clicked` event and always attach a context menu to the tray icon.
|
||||
If you want to keep exact same behaviors on all platforms, you should not
|
||||
rely on the `clicked` event and always attach a context menu to the tray icon.
|
||||
|
||||
## Class: Tray
|
||||
|
||||
`Tray` is an [EventEmitter][event-emitter].
|
||||
|
||||
### new Tray(image)
|
||||
### `new Tray(image)`
|
||||
|
||||
* `image` [NativeImage](native-image.md)
|
||||
|
||||
Creates a new tray icon associated with the `image`.
|
||||
|
||||
## Events
|
||||
|
||||
The `Tray` module emits the following events:
|
||||
|
||||
**Note:** Some events are only available on specific operating systems and are
|
||||
labeled as such.
|
||||
|
||||
### Event: 'clicked'
|
||||
|
||||
* `event` Event
|
||||
|
@ -52,7 +59,7 @@ Creates a new tray icon associated with the `image`.
|
|||
* `shiftKey` Boolean
|
||||
* `ctrlKey` Boolean
|
||||
* `metaKey` Boolean
|
||||
* `bounds` Object - the bounds of tray icon
|
||||
* `bounds` Object - the bounds of tray icon.
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
|
@ -62,14 +69,14 @@ Emitted when the tray icon is clicked.
|
|||
|
||||
__Note:__ The `bounds` payload is only implemented on OS X and Windows.
|
||||
|
||||
### Event: 'right-clicked'
|
||||
### Event: 'right-clicked' _OS X_ _Windows_
|
||||
|
||||
* `event` Event
|
||||
* `altKey` Boolean
|
||||
* `shiftKey` Boolean
|
||||
* `ctrlKey` Boolean
|
||||
* `metaKey` Boolean
|
||||
* `bounds` Object - the bounds of tray icon
|
||||
* `bounds` Object - the bounds of tray icon.
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
|
@ -77,9 +84,7 @@ __Note:__ The `bounds` payload is only implemented on OS X and Windows.
|
|||
|
||||
Emitted when the tray icon is right clicked.
|
||||
|
||||
__Note:__ This is only implemented on OS X and Windows.
|
||||
|
||||
### Event: 'double-clicked'
|
||||
### Event: 'double-clicked' _OS X_ _Windows_
|
||||
|
||||
* `event` Event
|
||||
* `altKey` Boolean
|
||||
|
@ -94,75 +99,68 @@ __Note:__ This is only implemented on OS X and Windows.
|
|||
|
||||
Emitted when the tray icon is double clicked.
|
||||
|
||||
__Note:__ This is only implemented on OS X and Windows.
|
||||
|
||||
### Event: 'balloon-show'
|
||||
### Event: 'balloon-show' _Windows_
|
||||
|
||||
Emitted when the tray balloon shows.
|
||||
|
||||
__Note:__ This is only implemented on Windows.
|
||||
|
||||
### Event: 'balloon-clicked'
|
||||
### Event: 'balloon-clicked' _Windows_
|
||||
|
||||
Emitted when the tray balloon is clicked.
|
||||
|
||||
__Note:__ This is only implemented on Windows.
|
||||
|
||||
### Event: 'balloon-closed'
|
||||
### Event: 'balloon-closed' _Windows_
|
||||
|
||||
Emitted when the tray balloon is closed because of timeout or user manually
|
||||
closes it.
|
||||
|
||||
__Note:__ This is only implemented on Windows.
|
||||
|
||||
### Event: 'drop-files'
|
||||
### Event: 'drop-files' _OS X_
|
||||
|
||||
* `event`
|
||||
* `files` Array - the file path of dropped files.
|
||||
|
||||
Emitted when dragged files are dropped in the tray icon.
|
||||
|
||||
__Note:__ This is only implemented on OS X.
|
||||
## Methods
|
||||
|
||||
### Tray.destroy()
|
||||
The `Tray` module has the following methods:
|
||||
|
||||
**Note**: Some methods are only available on specific operating systems and are
|
||||
labeled as such.
|
||||
|
||||
### `Tray.destroy()`
|
||||
|
||||
Destroys the tray icon immediately.
|
||||
|
||||
### Tray.setImage(image)
|
||||
### `Tray.setImage(image)`
|
||||
|
||||
* `image` [NativeImage](native-image.md)
|
||||
|
||||
Sets the `image` associated with this tray icon.
|
||||
|
||||
### Tray.setPressedImage(image)
|
||||
### `Tray.setPressedImage(image)` _OS X_
|
||||
|
||||
* `image` [NativeImage](native-image.md)
|
||||
|
||||
Sets the `image` associated with this tray icon when pressed on OS X.
|
||||
|
||||
### Tray.setToolTip(toolTip)
|
||||
### `Tray.setToolTip(toolTip)`
|
||||
|
||||
* `toolTip` String
|
||||
|
||||
Sets the hover text for this tray icon.
|
||||
|
||||
### Tray.setTitle(title)
|
||||
### `Tray.setTitle(title)` _OS X_
|
||||
|
||||
* `title` String
|
||||
|
||||
Sets the title displayed aside of the tray icon in the status bar.
|
||||
|
||||
__Note:__ This is only implemented on OS X.
|
||||
|
||||
### Tray.setHighlightMode(highlight)
|
||||
### `Tray.setHighlightMode(highlight)` _OS X_
|
||||
|
||||
* `highlight` Boolean
|
||||
|
||||
Sets whether the tray icon is highlighted when it is clicked.
|
||||
|
||||
__Note:__ This is only implemented on OS X.
|
||||
|
||||
### Tray.displayBalloon(options)
|
||||
### `Tray.displayBalloon(options)` _Windows_
|
||||
|
||||
* `options` Object
|
||||
* `icon` [NativeImage](native-image.md)
|
||||
|
@ -171,19 +169,15 @@ __Note:__ This is only implemented on OS X.
|
|||
|
||||
Displays a tray balloon.
|
||||
|
||||
__Note:__ This is only implemented on Windows.
|
||||
### `Tray.popUpContextMenu([position])` _OS X_ _Windows_
|
||||
|
||||
### Tray.popUpContextMenu([position])
|
||||
|
||||
* `position` Object - The pop position
|
||||
* `position` Object (optional)- The pop up position.
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
The `position` is only available on Windows, and it is (0, 0) by default.
|
||||
|
||||
__Note:__ This is only implemented on OS X and Windows.
|
||||
|
||||
### Tray.setContextMenu(menu)
|
||||
### `Tray.setContextMenu(menu)`
|
||||
|
||||
* `menu` Menu
|
||||
|
||||
|
|
|
@ -22,8 +22,16 @@ $ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \
|
|||
libxss1 libnss3-dev gcc-multilib g++-multilib
|
||||
```
|
||||
|
||||
On Fedora, install the following libraries:
|
||||
|
||||
```bash
|
||||
$ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring-devel \
|
||||
xorg-x11-server-utils libcap-devel cups-devel libXtst-devel \
|
||||
alsa-lib-devel libXrandr-devel GConf2-devel nss-devel
|
||||
```
|
||||
|
||||
Other distributions may offer similar packages for installation via package
|
||||
managers such as `yum`. Or you can compile from source code.
|
||||
managers such as pacman. Or one can compile from source code.
|
||||
|
||||
## If You Use Virtual Machines For Building
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ var app = require('app');
|
|||
app.addRecentDocument('/Users/USERNAME/Desktop/work.type');
|
||||
```
|
||||
|
||||
And you can use [app.clearRecentDocuments](clearrecentdocuments) API to empty
|
||||
And you can use [app.clearRecentDocuments][clearrecentdocuments] API to empty
|
||||
the recent documents list:
|
||||
|
||||
```javascript
|
||||
|
|
|
@ -8,14 +8,8 @@ From [ChromeDriver - WebDriver for Chrome][chrome-driver]:
|
|||
> implements WebDriver's wire protocol for Chromium. It is being developed by
|
||||
> members of the Chromium and WebDriver teams.
|
||||
|
||||
In Electron's [releases](https://github.com/atom/electron/releases) page you
|
||||
can find archives of `chromedriver`, there is no difference between Electron's
|
||||
distribution of `chromedriver` and upstream ones, so in order to use
|
||||
`chromedriver` together with Electron, you will need some special setup.
|
||||
|
||||
Also notice that only minor version update releases (e.g. `vX.X.0` releases)
|
||||
include `chromedriver` archives, because `chromedriver` doesn't change as
|
||||
frequent as Electron itself.
|
||||
In order to use `chromedriver` together with Electron you have to tell it where to
|
||||
find Electron and make it think Electron is Chrome browser.
|
||||
|
||||
## Setting up with WebDriverJs
|
||||
|
||||
|
|
|
@ -63,6 +63,15 @@ describe 'chromium feature', ->
|
|||
b.close()
|
||||
done(if opener isnt null then undefined else opener)
|
||||
|
||||
describe 'window.opener.postMessage', ->
|
||||
it 'sets source and origin correctly', (done) ->
|
||||
b = window.open "file://#{fixtures}/pages/window-opener-postMessage.html", 'test', 'show=no'
|
||||
window.addEventListener 'message', (event) ->
|
||||
b.close()
|
||||
assert.equal event.source.guestId, b.guestId
|
||||
assert.equal event.origin, 'file://'
|
||||
done()
|
||||
|
||||
describe 'creating a Uint8Array under browser side', ->
|
||||
it 'does not crash', ->
|
||||
RUint8Array = remote.getGlobal 'Uint8Array'
|
||||
|
|
10
spec/fixtures/pages/post.html
vendored
Normal file
10
spec/fixtures/pages/post.html
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<body>
|
||||
<form id="form" action="d.html" method="post" accept-charset="utf-8">
|
||||
<p><input type="submit" value="submit"></p>
|
||||
</form>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
document.getElementById("form").submit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
7
spec/fixtures/pages/window-opener-postMessage.html
vendored
Normal file
7
spec/fixtures/pages/window-opener-postMessage.html
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
window.opener.postMessage('message', '*');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -48,6 +48,14 @@ describe '<webview> tag', ->
|
|||
webview.src = "file://#{fixtures}/pages/d.html"
|
||||
document.body.appendChild webview
|
||||
|
||||
it 'loads node symbols after POST navigation when set', (done) ->
|
||||
webview.addEventListener 'console-message', (e) ->
|
||||
assert.equal e.message, 'function object object'
|
||||
done()
|
||||
webview.setAttribute 'nodeintegration', 'on'
|
||||
webview.src = "file://#{fixtures}/pages/post.html"
|
||||
document.body.appendChild webview
|
||||
|
||||
# If the test is executed with the debug build on Windows, we will skip it
|
||||
# because native modules don't work with the debug build (see issue #2558).
|
||||
if process.platform isnt 'win32' or
|
||||
|
|
Loading…
Reference in a new issue