Merge remote-tracking branch 'atom/master'
This commit is contained in:
commit
e3504b2b24
77 changed files with 2166 additions and 1200 deletions
|
@ -49,6 +49,7 @@ contains documents describing how to build and contribute to Electron.
|
|||
- [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)
|
||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
|
||||
## 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];
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -62,7 +62,7 @@ Módulos de ambos procesos:
|
|||
* [Estructura de directorio](development/source-code-directory-structure.md)
|
||||
* [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md)
|
||||
* [Sistema de compilación](development/build-system-overview.md)
|
||||
* [Instrucciones de compilación (Mac)](development/build-instructions-mac.md)
|
||||
* [Instrucciones de compilación (Mac)](development/build-instructions-osx.md)
|
||||
* [Instrucciones de compilación (Windows)](development/build-instructions-windows.md)
|
||||
* [Instrucciones de compilación (Linux)](development/build-instructions-linux.md)
|
||||
* [Configurando un servidor de símbolos en el depurador](development/setting-up-symbol-server.md)
|
||||
|
|
|
@ -14,17 +14,17 @@ Electronでは、`package.json` の `main`で実行されるプロセスを __
|
|||
|
||||
Electronはウェブページを表示させるためにChromiumを使用しているので、Chromiumのマルチプロセスアーキテクチャが使用されることになります。Electronで実行されるウェブページはそれぞれ自身のプロセスで実行されます。それを __レンダラープロセス__ と呼びます。
|
||||
|
||||
通常、ブラウザのウェブページはサウンドボックス環境で実行されネイティブなリソースへのアクセスができません。Electronではウェブページからio.jsのAPIを使って、ネイティブリソースへの権限が与えられます。そのおかげでウェブページの中からJavaScriptを使って低レベルなオペレーティングシステムとのインタラクションが可能になります。
|
||||
通常、ブラウザのウェブページはサンドボックス環境で実行されネイティブなリソースへのアクセスができません。Electronではウェブページからio.jsのAPIを使って、ネイティブリソースへの権限が与えられます。そのおかげでウェブページの中からJavaScriptを使って低レベルなオペレーティングシステムとのインタラクションが可能になります。
|
||||
|
||||
### メインプロセスとリレンダラープロセスの違い
|
||||
### メインプロセスとレンダラープロセスの違い
|
||||
|
||||
メインプロセスは `BrowserWindow` インスタンスを作ることによってウェブページをつくります。それぞれの `BrowserWindow` インスタンスはそれ自身の リレンダラープロセス上でウェブページを実行します。`BrowserWindow` インスタンスが破棄されると、対応するリレンダラープロセスも終了されます。
|
||||
メインプロセスは `BrowserWindow` インスタンスを作ることによってウェブページをつくります。それぞれの `BrowserWindow` インスタンスはそれ自身の レンダラープロセス上でウェブページを実行します。`BrowserWindow` インスタンスが破棄されると、対応するレンダラープロセスも終了されます。
|
||||
|
||||
メインプロセスはすべてのウェブページとそれに対応するリレンダラープロセスを管理しています。それぞれのリレンダラープロセスは分離しているのでウェブページで実行されていることだけを気に留めておいてください。
|
||||
メインプロセスはすべてのウェブページとそれに対応するレンダラープロセスを管理しています。それぞれのレンダラープロセスは分離しているのでウェブページで実行されていることだけを気に留めておいてください。
|
||||
|
||||
ウェブページでは、GUI関連のAPIを呼ぶことはできません。なぜならば、ウェブページで管理しているネイティブのGUIリソースは非常に危険で簡単にリークしてしまうからです。もしウェブページ内でGUIを操作したい場合には、メインプロセスと通信をする必要があります。
|
||||
|
||||
Electronでは、メインプロセスとリレンダラープロセスとのコミュニケーションをするために[ipc](../api/ipc-renderer.md)モジュールを提供しています。またそれと、RPC形式の通信を行う[remote](../api/remote.md)モジュールもあります。
|
||||
Electronでは、メインプロセスとレンダラープロセスとのコミュニケーションをするために[ipc](../api/ipc-renderer.md)モジュールを提供しています。またそれと、RPC形式の通信を行う[remote](../api/remote.md)モジュールもあります。
|
||||
|
||||
## Electronアプリを作成する
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
* [소스 코드 디렉터리 구조](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)
|
||||
* [빌드 설명서 (Mac)](development/build-instructions-osx.md)
|
||||
* [빌드 설명서 (Windows)](development/build-instructions-windows.md)
|
||||
* [빌드 설명서 (Linux)](development/build-instructions-linux.md)
|
||||
* [디버거에서 디버그 심볼 서버 설정](development/setting-up-symbol-server.md)
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
# 桌面环境集成
|
||||
不同的操作系统在各自的桌面应用上提供了不同的特性。例如,在 windows 上应用曾经打开的文件会出现在任务栏的跳转列表,在 Mac 上,应用可以把自定义菜单放在鱼眼菜单上。
|
||||
|
||||
本章将会说明怎样使用 Electron APIs 把你的应用和桌面环境集成到一块。
|
||||
|
||||
## 最近文档 (Windows & OS X)
|
||||
Windows 和 OS X 提供获取最近文档列表的便捷方式,那就是打开跳转列表或者鱼眼菜单。
|
||||
|
||||
跳转列表:
|
||||
![JumpList][1]
|
||||
|
||||
鱼眼菜单:
|
||||
![Dock Menu][2]
|
||||
|
||||
为了增加一个文件到最近文件列表,你可以使用 [app.addRecentDocument][3] API:
|
||||
|
||||
````
|
||||
var app = require('app');
|
||||
app.addRecentDocument('/Users/USERNAME/Desktop/work.type');
|
||||
````
|
||||
或者你也可以使用 [app.clearRecentDocuments][4] API 来清空最近文件列表。
|
||||
````
|
||||
app.clearRecentDocuments();
|
||||
````
|
||||
## Windows 需注意
|
||||
为了这个特性在 Windows 上表现正常,你的应用需要被注册成为一种文件类型的句柄,否则,在你注册之前,文件不会出现在跳转列表。你可以在 [Application Registration][5] 里找到任何关于注册事宜的说明。
|
||||
|
||||
## OS X 需注意
|
||||
当一个文件被最近文件列表请求时,`app` 模块里的 `open-file` 事件将会被发出。
|
||||
|
||||
## 自定义的鱼眼菜单(OS X)
|
||||
OS X 可以让开发者定制自己的菜单,通常会包含一些常用特性的快捷方式。
|
||||
### 菜单中的终端
|
||||
[Dock menu of Terminal.app][6]
|
||||
|
||||
使用 `app.dock.setMenu` API 来设置你的菜单,这仅在 OS X 上可行:
|
||||
````
|
||||
var app = require('app');
|
||||
var Menu = require('menu');
|
||||
var dockMenu = Menu.buildFromTemplate([
|
||||
{ label: 'New Window', click: function() { console.log('New Window'); } },
|
||||
{ label: 'New Window with Settings', submenu: [
|
||||
{ label: 'Basic' },
|
||||
{ label: 'Pro'}
|
||||
]},
|
||||
{ label: 'New Command...'}
|
||||
]);
|
||||
app.dock.setMenu(dockMenu);
|
||||
````
|
||||
|
||||
## 用户任务(Windows)
|
||||
在 Windows,你可以特别定义跳转列表的 `Tasks` 目录的行为,引用 MSDN 的文档:
|
||||
|
||||
> Applications define tasks based on both the program's features and the key things a user is expected to do with them. Tasks should be context-free, in that the application does not need to be running for them to work. They should also be the statistically most common actions that a normal user would perform in an application, such as compose an email message or open the calendar in a mail program, create a new document in a word processor, launch an application in a certain mode, or launch one of its subcommands. An application should not clutter the menu with advanced features that standard users won't need or one-time actions such as registration. Do not use tasks for promotional items such as upgrades or special offers.
|
||||
|
||||
> It is strongly recommended that the task list be static. It should remain the same regardless of the state or status of the application. While it is possible to vary the list dynamically, you should consider that this could confuse the user who does not expect that portion of the destination list to change.
|
||||
|
||||
### IE 的任务
|
||||
![IE][7]
|
||||
不同于 OS X 的鱼眼菜单,Windows 上的用户任务表现得更像一个快捷方式,比如当用户点击一个任务,一个程序将会被传入特定的参数并且运行。
|
||||
|
||||
你可以使用 [app.setUserTasks][8] API 来设置你的应用中的用户任务:
|
||||
````
|
||||
var app = require('app');
|
||||
app.setUserTasks([
|
||||
{
|
||||
program: process.execPath,
|
||||
arguments: '--new-window',
|
||||
iconPath: process.execPath,
|
||||
iconIndex: 0,
|
||||
title: 'New Window',
|
||||
description: 'Create a new window'
|
||||
}
|
||||
]);
|
||||
````
|
||||
调用 `app.setUserTasks` 并传入空数组就可以清除你的任务列表:
|
||||
````
|
||||
app.setUserTasks([]);
|
||||
````
|
||||
当你的应用关闭时,用户任务会仍然会出现,在你的应用被卸载前,任务指定的图标和程序的路径必须是存在的。
|
||||
|
||||
### 缩略图工具栏
|
||||
在 Windows,你可以在任务栏上添加一个按钮来当作应用的缩略图工具栏。它将提供用户一种用户访问常用窗口的方式,并且不需要恢复或者激活窗口。
|
||||
|
||||
在 MSDN,它被如是说:
|
||||
> This toolbar is simply the familiar standard toolbar common control. It has a maximum of seven buttons. Each button's ID, image, tooltip, and state are defined in a structure, which is then passed to the taskbar. The application can show, enable, disable, or hide buttons from the thumbnail toolbar as required by its current state.
|
||||
|
||||
> For example, Windows Media Player might offer standard media transport controls such as play, pause, mute, and stop.
|
||||
|
||||
### Windows Media Player 的缩略图工具栏
|
||||
![Thumbnail toolbar of Windows Media Player][9]
|
||||
你可以使用 [BrowserWindow.setThumbarButtons][10] 来设置你的应用的缩略图工具栏。
|
||||
````
|
||||
var BrowserWindow = require('browser-window');
|
||||
var path = require('path');
|
||||
var win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
});
|
||||
win.setThumbarButtons([
|
||||
{
|
||||
tooltip: "button1",
|
||||
icon: path.join(__dirname, 'button1.png'),
|
||||
click: function() { console.log("button2 clicked"); }
|
||||
},
|
||||
{
|
||||
tooltip: "button2",
|
||||
icon: path.join(__dirname, 'button2.png'),
|
||||
flags:['enabled', 'dismissonclick'],
|
||||
click: function() { console.log("button2 clicked."); }
|
||||
}
|
||||
]);
|
||||
````
|
||||
调用 `BrowserWindow.setThumbarButtons` 并传入空数组即可清空缩略图工具栏:
|
||||
````
|
||||
win.setThumbarButtons([]);
|
||||
````
|
||||
|
||||
## Unity launcher 快捷方式(Linux)
|
||||
在 Unity,你可以通过改变 `.desktop` 文件来增加自定义运行器的快捷方式,详情看 [Adding shortcuts to a launcher][11]。
|
||||
### Audacious 运行器的快捷方式:
|
||||
![Launcher shortcuts of Audacious][12]
|
||||
|
||||
## 任务栏的进度条(Windows & Unity)
|
||||
在 Windows,进度条可以出现在一个任务栏按钮之上。这可以提供进度信息给用户而不需要用户切换应用窗口。
|
||||
|
||||
Unity DE 也具有同样的特性,在运行器上显示进度条。
|
||||
### 在任务栏上的进度条:
|
||||
![Progress bar in taskbar button][13]
|
||||
|
||||
### 在 Unity 运行器上的进度条
|
||||
![Progress bar in Unity launcher][14]
|
||||
|
||||
给一个窗口设置进度条,你可以调用 [BrowserWindow.setProgressBar][15] API:
|
||||
````
|
||||
var window = new BrowserWindow({...});
|
||||
window.setProgressBar(0.5);
|
||||
````
|
||||
在 OS X,一个窗口可以设置它展示的文件,文件的图标可以出现在标题栏,当用户 Command-Click 或者 Control-Click 标题栏,文件路径弹窗将会出现。
|
||||
### 展示文件弹窗菜单:
|
||||
![Represented file popup menu][16]
|
||||
|
||||
你可以调用 [BrowserWindow.setRepresentedFilename][17] 和 [BrowserWindow.setDocumentEdited][18] APIs:
|
||||
````
|
||||
var window = new BrowserWindow({...});
|
||||
window.setRepresentedFilename('/etc/passwd');
|
||||
window.setDocumentEdited(true);
|
||||
````
|
||||
|
||||
[1]:https://camo.githubusercontent.com/3310597e01f138b1d687e07aa618c50908a88dec/687474703a2f2f692e6d73646e2e6d6963726f736f66742e636f6d2f64796e696d672f49433432303533382e706e67
|
||||
[2]: https://cloud.githubusercontent.com/assets/639601/5069610/2aa80758-6e97-11e4-8cfb-c1a414a10774.png
|
||||
[3]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/app.md
|
||||
[4]: https://github.com/atom/electron/blob/master/docs/tutorial/clearrecentdocuments
|
||||
[5]: https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121%28v=vs.85%29.aspx
|
||||
[6]: https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png
|
||||
[7]: https://camo.githubusercontent.com/30154e0cc36acfc968ac9ae076a8f0d6600dd736/687474703a2f2f692e6d73646e2e6d6963726f736f66742e636f6d2f64796e696d672f49433432303533392e706e67
|
||||
[8]: https://github.com/atom/electron/blob/master/docs/api/app.md#appsetusertaskstasks
|
||||
[9]: https://camo.githubusercontent.com/098cb0f52f27084a80ec6429e51a195df3d8c333/68747470733a2f2f692d6d73646e2e7365632e732d6d7366742e636f6d2f64796e696d672f49433432303534302e706e67
|
||||
[10]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/browser-window.md
|
||||
[11]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher
|
||||
[12]: https://camo.githubusercontent.com/b6f54e2bc3206ebf8e08dd029529af9ec84d58ae/68747470733a2f2f68656c702e7562756e74752e636f6d2f636f6d6d756e6974792f556e6974794c61756e6368657273416e644465736b746f7046696c65733f616374696f6e3d41747461636846696c6526646f3d676574267461726765743d73686f7274637574732e706e67
|
||||
[13]: https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png
|
||||
[14]: https://cloud.githubusercontent.com/assets/639601/5081747/4a0a589e-6f0f-11e4-803f-91594716a546.png
|
||||
[15]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/browser-window.md
|
||||
[16]: https://cloud.githubusercontent.com/assets/639601/5082061/670a949a-6f14-11e4-987a-9aaa04b23c1d.png
|
||||
[17]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/browser-window.md
|
||||
[18]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/browser-window.md
|
72
docs-translations/zh-CN/tutorial/online-offline-events.md
Normal file
72
docs-translations/zh-CN/tutorial/online-offline-events.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
# 在线/离线事件探测
|
||||
使用标准 HTML5 APIs 可以实现在线和离线事件的探测,就像以下例子:
|
||||
|
||||
*main.js*
|
||||
````
|
||||
var app = require('app');
|
||||
var BrowserWindow = require('browser-window');
|
||||
var onlineStatusWindow;
|
||||
|
||||
app.on('ready', function() {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false });
|
||||
onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html');
|
||||
});
|
||||
````
|
||||
|
||||
*online-status.html*
|
||||
````
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var alertOnlineStatus = function() {
|
||||
window.alert(navigator.onLine ? 'online' : 'offline');
|
||||
};
|
||||
|
||||
window.addEventListener('online', alertOnlineStatus);
|
||||
window.addEventListener('offline', alertOnlineStatus);
|
||||
|
||||
alertOnlineStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
````
|
||||
|
||||
也会有人想要在主进程也有回应这些事件的实例。然后主进程没有 `navigator` 对象因此不能直接探测在线还是离线。使用 Electron 的进程间通讯工具,事件就可以在主进程被使,就像下面的例子:
|
||||
|
||||
*main.js*
|
||||
````
|
||||
var app = require('app');
|
||||
var ipc = require('ipc');
|
||||
var BrowserWindow = require('browser-window');
|
||||
var onlineStatusWindow;
|
||||
|
||||
app.on('ready', function() {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false });
|
||||
onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html');
|
||||
});
|
||||
|
||||
ipc.on('online-status-changed', function(event, status) {
|
||||
console.log(status);
|
||||
});
|
||||
````
|
||||
|
||||
*online-status.html*
|
||||
````
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var ipc = require('ipc');
|
||||
var updateOnlineStatus = function() {
|
||||
ipc.send('online-status-changed', navigator.onLine ? 'online' : 'offline');
|
||||
};
|
||||
|
||||
window.addEventListener('online', updateOnlineStatus);
|
||||
window.addEventListener('offline', updateOnlineStatus);
|
||||
|
||||
updateOnlineStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
````
|
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
|
70
docs-translations/zh-TW/README.md
Normal file
70
docs-translations/zh-TW/README.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
## 導引
|
||||
|
||||
* [應用程式發布](tutorial/application-distribution.md)
|
||||
* [應用程式打包](tutorial/application-packaging.md)
|
||||
* [使用原生模組](tutorial/using-native-node-modules.md)
|
||||
* [Debug 主行程](tutorial/debugging-main-process.md)
|
||||
* [使用 Selenium 和 WebDriver](tutorial/using-selenium-and-webdriver.md)
|
||||
* [DevTools 擴充](tutorial/devtools-extension.md)
|
||||
* [使用 Pepper Flash 套件](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)
|
||||
|
||||
## 開發
|
||||
|
||||
* [Coding style](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)
|
||||
* [在 debugger 中使用 symbol server](development/setting-up-symbol-server.md)
|
165
docs-translations/zh-TW/tutorial/quick-start.md
Normal file
165
docs-translations/zh-TW/tutorial/quick-start.md
Normal file
|
@ -0,0 +1,165 @@
|
|||
# 快速入門
|
||||
|
||||
## 簡介
|
||||
|
||||
Electron 可以讓你使用純 JavaScript 提供豐富的原生的 APIs 來創造桌面應用程式。
|
||||
你可以把它視為一個 io.js 的變體,專注於桌面應用程式而不是 web 伺服器。
|
||||
|
||||
這不表示 Electron 是一個用 JavaScript 去綁定 GUI 函式庫。取而代之的,Electron 是使用網頁介面來作為它的 GUI ,
|
||||
所以你可以把它看作是一個被 JavaScript 所控制且精簡化的 Chromium 瀏覽器。
|
||||
|
||||
## 主行程
|
||||
|
||||
在 Electron 裡,有個行程會去運行 `package.json` 裡的 `main` 腳本被稱為 __主行程__ 。
|
||||
這個腳本運行在主行程裏可以顯示一個 GUI 就由創建一個 web 頁面。
|
||||
|
||||
## 渲染行程
|
||||
|
||||
因為 Electron 使用 Chromium 來顯示網頁,所以 Chromium 的多行程架構也被充分利用。
|
||||
每一個網頁在 Electron 裏執行各自的行程,被稱為 __渲染行程__。
|
||||
|
||||
在一般瀏覽器中,網頁通常會在沙盒環境下運行,並且不允許存取原生資源。然而,
|
||||
Electron 的用戶擁有在網頁中呼叫 io.js APIs 的能力,允許低級別操作與作業系統的交互作用。
|
||||
|
||||
## 主行程與渲染行程的區別
|
||||
|
||||
主行程創造網頁透過創造 `BroswerWindow` 實例。每一個 `BroswerWindow` 實例都在自己的渲染行程裡運行著一個網頁。
|
||||
當一個 `BroswerWindow` 實例被銷毀,對應的渲染行程也會被終止。主行程管理所有網頁和與之對應的渲染行程。
|
||||
每一個渲染行程都是相互獨立的,並且只關心他們自己的網頁。
|
||||
|
||||
在網頁中,是不允許呼叫原生 GUI 相關 APIs 因為管理原生 GUI 資源在網頁上是非常危險而且容易造成資源洩露。
|
||||
如果你想要在網頁中呼叫 GUI 相關的 APIs 的操作,網頁的渲染行程必須與主行程進行通訊,請求主行程進行相關的操作。
|
||||
|
||||
在 Electron ,我們提供用於在主行程與渲染行程之間通訊的 [ipc][1] 模組。並且也有一個遠端模使用 RPC 通訊方式 [remote][2]。
|
||||
|
||||
# 打造你第一個 Electron 應用
|
||||
|
||||
一般來說,一個 Electron 應用程式的目錄結構像下面這樣:
|
||||
|
||||
```text
|
||||
your-app/
|
||||
├── package.json
|
||||
├── main.js
|
||||
└── index.html
|
||||
```
|
||||
|
||||
`package.json ` 的格式與 Node 的模組完全一樣,並且有個腳本被指定為 `main` 是用來啟動你的應用程式,它運行在主行程上。
|
||||
你應用裡的 一個範例在你的 `package.json` 看起來可能像這樣:
|
||||
|
||||
```json
|
||||
{
|
||||
"name" : "your-app",
|
||||
"version" : "0.1.0",
|
||||
"main" : "main.js"
|
||||
}
|
||||
```
|
||||
|
||||
__注意__:如果 `main` 沒有在 `package.json` 裏, Electron會嘗試載入 `index.js`。
|
||||
|
||||
`main.js` 用於創建視窗和處理系統事件,一個典型的例子如下:
|
||||
|
||||
``` javascript
|
||||
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` :
|
||||
|
||||
```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`,那麼你只需要按照如下方式直接運行你的應用程式:
|
||||
|
||||
```bash
|
||||
electron .
|
||||
```
|
||||
|
||||
如果你是局部性地安裝,那運行:
|
||||
|
||||
```bash
|
||||
./node_modules/.bin/electron .
|
||||
```
|
||||
|
||||
## 手動下載 Electron Binary
|
||||
|
||||
如果你手動下載了 Electron ,你可以直接使的 Binary 直接運行你的應用程式。
|
||||
|
||||
### Windows
|
||||
|
||||
``` bash
|
||||
$ .\electron\electron.exe your-app\
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
``` bash
|
||||
$ ./electron/electron your-app/
|
||||
```
|
||||
|
||||
### OS X
|
||||
|
||||
``` bash
|
||||
$ ./Electron.app/Contents/MacOS/Electron your-app/
|
||||
```
|
||||
|
||||
`Electron.app` 裡面是 Electron 釋出包,你可以在[這裡](https://github.com/atom/electron/releases)下載到。
|
||||
|
||||
# 作為版本發行
|
||||
在你完成了你的應用程式後,你可以依照 [應用部署](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) 指南發布一個版本,並且運行已經打包好的應用程式。
|
||||
|
||||
[1]: https://github.com/atom/electron/blob/master/docs/api/ipc-renderer.md
|
||||
|
||||
[2]: https://github.com/atom/electron/blob/master/docs/api/remote.md
|
|
@ -64,7 +64,7 @@ Modules for both processes:
|
|||
* [Source code directory structure](development/source-code-directory-structure.md)
|
||||
* [Technical differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md)
|
||||
* [Build system overview](development/build-system-overview.md)
|
||||
* [Build instructions (Mac)](development/build-instructions-mac.md)
|
||||
* [Build instructions (Mac)](development/build-instructions-osx.md)
|
||||
* [Build instructions (Windows)](development/build-instructions-windows.md)
|
||||
* [Build instructions (Linux)](development/build-instructions-linux.md)
|
||||
* [Setting up symbol server in debugger](development/setting-up-symbol-server.md)
|
||||
|
|
|
@ -236,7 +236,7 @@ Emitted when devtools is focused / opened.
|
|||
|
||||
### Event: 'app-command' _Windows_
|
||||
|
||||
Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx
|
||||
Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)
|
||||
is invoked. These are typically related to keyboard media keys or browser
|
||||
commands, as well as the "Back" button built into some mice on Windows.
|
||||
|
||||
|
|
|
@ -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,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,14 +1,19 @@
|
|||
# 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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,46 +1,51 @@
|
|||
# web-frame
|
||||
# webFrame
|
||||
|
||||
The `web-frame` module allows you to customize the rendering of the current
|
||||
The `web-frame` module allows you to customize the rendering of the current
|
||||
web page.
|
||||
|
||||
An example of zooming current page to 200%.
|
||||
|
||||
```javascript
|
||||
var webFrame = require('web-frame');
|
||||
|
||||
webFrame.setZoomFactor(2);
|
||||
```
|
||||
|
||||
## webFrame.setZoomFactor(factor)
|
||||
## Methods
|
||||
|
||||
* `factor` Number - Zoom factor
|
||||
The `web-frame` module has the following methods:
|
||||
|
||||
Changes the zoom factor to the specified factor, zoom factor is
|
||||
zoom percent / 100, so 300% = 3.0.
|
||||
### `webFrame.setZoomFactor(factor)`
|
||||
|
||||
## webFrame.getZoomFactor()
|
||||
* `factor` Number - Zoom factor.
|
||||
|
||||
Changes the zoom factor to the specified factor. Zoom factor is
|
||||
zoom percent divided by 100, so 300% = 3.0.
|
||||
|
||||
### `webFrame.getZoomFactor()`
|
||||
|
||||
Returns the current zoom factor.
|
||||
|
||||
## webFrame.setZoomLevel(level)
|
||||
### `webFrame.setZoomLevel(level)`
|
||||
|
||||
* `level` Number - Zoom level
|
||||
|
||||
Changes the zoom level to the specified level, 0 is "original size", and each
|
||||
Changes the zoom level to the specified level. The original size is 0 and each
|
||||
increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively.
|
||||
|
||||
## webFrame.getZoomLevel()
|
||||
### `webFrame.getZoomLevel()`
|
||||
|
||||
Returns the current zoom level.
|
||||
|
||||
## webFrame.setZoomLevelLimits(minimumLevel, maximumLevel)
|
||||
### `webFrame.setZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
|
||||
Sets the maximum and minimum zoom level.
|
||||
|
||||
## webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)
|
||||
### `webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)`
|
||||
|
||||
* `language` String
|
||||
* `autoCorrectWord` Boolean
|
||||
|
@ -61,7 +66,7 @@ require('web-frame').setSpellCheckProvider("en-US", true, {
|
|||
});
|
||||
```
|
||||
|
||||
## webFrame.registerUrlSchemeAsSecure(scheme)
|
||||
### `webFrame.registerUrlSchemeAsSecure(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
|
@ -71,11 +76,11 @@ Secure schemes do not trigger mixed content warnings. For example, `https` and
|
|||
`data` are secure schemes because they cannot be corrupted by active network
|
||||
attackers.
|
||||
|
||||
## webFrame.registerUrlSchemeAsBypassingCsp(scheme)
|
||||
### `webFrame.registerUrlSchemeAsBypassingCsp(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Resources will be loaded from this `scheme` regardless of
|
||||
page's Content Security Policy.
|
||||
Resources will be loaded from this `scheme` regardless of the current page's
|
||||
Content Security Policy.
|
||||
|
||||
[spellchecker]: https://github.com/atom/node-spellchecker
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# `<webview>` tag
|
||||
# The `<webview>` tag
|
||||
|
||||
Use the `webview` tag to embed 'guest' content (such as web pages) in your
|
||||
Electron app. The guest content is contained within the `webview` container;
|
||||
an embedder page within your app controls how the guest content is laid out and
|
||||
Electron app. The guest content is contained within the `webview` container.
|
||||
An embedded page within your app controls how the guest content is laid out and
|
||||
rendered.
|
||||
|
||||
Different from the `iframe`, the `webview` runs in a separate process than your
|
||||
app; it doesn't have the same permissions as your web page and all interactions
|
||||
Unlike an `iframe`, the `webview` runs in a separate process than your
|
||||
app. It doesn't have the same permissions as your web page and all interactions
|
||||
between your app and embedded content will be asynchronous. This keeps your app
|
||||
safe from the embedded content.
|
||||
|
||||
|
@ -45,9 +45,11 @@ and displays a "loading..." message during the load time:
|
|||
</script>
|
||||
```
|
||||
|
||||
## Tag attributes
|
||||
## Tag Attributes
|
||||
|
||||
### src
|
||||
The `webview` tag has the following attributes:
|
||||
|
||||
### `src`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/"></webview>
|
||||
|
@ -61,7 +63,7 @@ Assigning `src` its own value will reload the current page.
|
|||
The `src` attribute can also accept data URLs, such as
|
||||
`data:text/plain,Hello, world!`.
|
||||
|
||||
### autosize
|
||||
### `autosize`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" autosize="on" minwidth="576" minheight="432"></webview>
|
||||
|
@ -69,11 +71,11 @@ The `src` attribute can also accept data URLs, such as
|
|||
|
||||
If "on", the `webview` container will automatically resize within the
|
||||
bounds specified by the attributes `minwidth`, `minheight`, `maxwidth`, and
|
||||
`maxheight`. These contraints do not impact the `webview` UNLESS `autosize` is
|
||||
`maxheight`. These constraints do not impact the `webview` unless `autosize` is
|
||||
enabled. When `autosize` is enabled, the `webview` container size cannot be less
|
||||
than the minimum values or greater than the maximum.
|
||||
|
||||
### nodeintegration
|
||||
### `nodeintegration`
|
||||
|
||||
```html
|
||||
<webview src="http://www.google.com/" nodeintegration></webview>
|
||||
|
@ -82,7 +84,7 @@ than the minimum values or greater than the maximum.
|
|||
If "on", the guest page in `webview` will have node integration and can use node
|
||||
APIs like `require` and `process` to access low level system resources.
|
||||
|
||||
### plugins
|
||||
### `plugins`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" plugins></webview>
|
||||
|
@ -90,7 +92,7 @@ APIs like `require` and `process` to access low level system resources.
|
|||
|
||||
If "on", the guest page in `webview` will be able to use browser plugins.
|
||||
|
||||
### preload
|
||||
### `preload`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" preload="./test.js"></webview>
|
||||
|
@ -102,9 +104,9 @@ will be loaded by `require` in guest page under the hood.
|
|||
|
||||
When the guest page doesn't have node integration this script will still have
|
||||
access to all Node APIs, but global objects injected by Node will be deleted
|
||||
after this script has done execution.
|
||||
after this script has finished executing.
|
||||
|
||||
### httpreferrer
|
||||
### `httpreferrer`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" httpreferrer="http://cheng.guru"></webview>
|
||||
|
@ -112,15 +114,16 @@ after this script has done execution.
|
|||
|
||||
Sets the referrer URL for the guest page.
|
||||
|
||||
### useragent
|
||||
### `useragent`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko"></webview>
|
||||
```
|
||||
|
||||
Sets the user agent for the guest page before the page is navigated to. Once the page is loaded, use the `setUserAgent` method to change the user agent.
|
||||
Sets the user agent for the guest page before the page is navigated to. Once the
|
||||
page is loaded, use the `setUserAgent` method to change the user agent.
|
||||
|
||||
### disablewebsecurity
|
||||
### `disablewebsecurity`
|
||||
|
||||
```html
|
||||
<webview src="https://www.github.com/" disablewebsecurity></webview>
|
||||
|
@ -130,7 +133,10 @@ If "on", the guest page will have web security disabled.
|
|||
|
||||
## Methods
|
||||
|
||||
The webview element must be loaded before using the methods.
|
||||
The `webview` tag has the following methods:
|
||||
|
||||
**Note**: The webview element must be loaded before using the methods.
|
||||
|
||||
**Example**
|
||||
```javascript
|
||||
webview.addEventListener("dom-ready", function() {
|
||||
|
@ -138,194 +144,195 @@ webview.addEventListener("dom-ready", function() {
|
|||
});
|
||||
```
|
||||
|
||||
### `<webview>`.getUrl()
|
||||
### `<webview>.getUrl()`
|
||||
|
||||
Returns URL of guest page.
|
||||
|
||||
### `<webview>`.getTitle()
|
||||
### `<webview>.getTitle()`
|
||||
|
||||
Returns the title of guest page.
|
||||
|
||||
### `<webview>`.isLoading()
|
||||
### `<webview>.isLoading()`
|
||||
|
||||
Returns whether guest page is still loading resources.
|
||||
Returns a boolean whether guest page is still loading resources.
|
||||
|
||||
### `<webview>`.isWaitingForResponse()
|
||||
### `<webview>.isWaitingForResponse()`
|
||||
|
||||
Returns whether guest page is waiting for a first-response for the main resource
|
||||
of the page.
|
||||
Returns a boolean whether the guest page is waiting for a first-response for the
|
||||
main resource of the page.
|
||||
|
||||
### `<webview>`.stop()
|
||||
### `<webview>.stop()`
|
||||
|
||||
Stops any pending navigation.
|
||||
|
||||
### `<webview>`.reload()
|
||||
### `<webview>.reload()`
|
||||
|
||||
Reloads guest page.
|
||||
Reloads the guest page.
|
||||
|
||||
### `<webview>`.reloadIgnoringCache()
|
||||
### `<webview>.reloadIgnoringCache()`
|
||||
|
||||
Reloads guest page and ignores cache.
|
||||
Reloads the guest page and ignores cache.
|
||||
|
||||
### `<webview>`.canGoBack()
|
||||
### `<webview>.canGoBack()`
|
||||
|
||||
Returns whether guest page can go back.
|
||||
Returns a boolean whether the guest page can go back.
|
||||
|
||||
### `<webview>`.canGoForward()
|
||||
### `<webview>.canGoForward()`
|
||||
|
||||
Returns whether guest page can go forward.
|
||||
Returns a boolean whether the guest page can go forward.
|
||||
|
||||
### `<webview>`.canGoToOffset(offset)
|
||||
### `<webview>.canGoToOffset(offset)`
|
||||
|
||||
* `offset` Integer
|
||||
|
||||
Returns whether guest page can go to `offset`.
|
||||
Returns a boolean whether the guest page can go to `offset`.
|
||||
|
||||
### `<webview>`.clearHistory()
|
||||
### `<webview>.clearHistory()`
|
||||
|
||||
Clears the navigation history.
|
||||
|
||||
### `<webview>`.goBack()
|
||||
### `<webview>.goBack()`
|
||||
|
||||
Makes guest page go back.
|
||||
Makes the guest page go back.
|
||||
|
||||
### `<webview>`.goForward()
|
||||
### `<webview>.goForward()`
|
||||
|
||||
Makes guest page go forward.
|
||||
Makes the guest page go forward.
|
||||
|
||||
### `<webview>`.goToIndex(index)
|
||||
### `<webview>.goToIndex(index)`
|
||||
|
||||
* `index` Integer
|
||||
|
||||
Navigates to the specified absolute index.
|
||||
|
||||
### `<webview>`.goToOffset(offset)
|
||||
### `<webview>.goToOffset(offset)`
|
||||
|
||||
* `offset` Integer
|
||||
|
||||
Navigates to the specified offset from the "current entry".
|
||||
|
||||
### `<webview>`.isCrashed()
|
||||
### `<webview>.isCrashed()`
|
||||
|
||||
Whether the renderer process has crashed.
|
||||
|
||||
### `<webview>`.setUserAgent(userAgent)
|
||||
### `<webview>.setUserAgent(userAgent)`
|
||||
|
||||
* `userAgent` String
|
||||
|
||||
Overrides the user agent for guest page.
|
||||
Overrides the user agent for the guest page.
|
||||
|
||||
### `<webview>`.getUserAgent()
|
||||
### `<webview>.getUserAgent()`
|
||||
|
||||
Returns a `String` represents the user agent for guest page.
|
||||
Returns a `String` representing the user agent for guest page.
|
||||
|
||||
### `<webview>`.insertCSS(css)
|
||||
### `<webview>.insertCSS(css)`
|
||||
|
||||
* `css` String
|
||||
|
||||
Injects CSS into guest page.
|
||||
Injects CSS into the guest page.
|
||||
|
||||
### `<webview>`.executeJavaScript(code, userGesture)
|
||||
### `<webview>.executeJavaScript(code, userGesture)`
|
||||
|
||||
* `code` String
|
||||
* `userGesture` Boolean - Default false
|
||||
* `userGesture` Boolean - Default `false`.
|
||||
|
||||
Evaluates `code` in page. If `userGesture` is set will create user gesture context,
|
||||
HTML api like `requestFullScreen` which require user action can take advantage
|
||||
of this option for automation.
|
||||
Evaluates `code` in page. If `userGesture` is set, it will the create user
|
||||
gesture context in the page. HTML APIs like `requestFullScreen`, which require
|
||||
user action, can take advantage of this option for automation.
|
||||
|
||||
### `<webview>`.openDevTools()
|
||||
### `<webview>.openDevTools()`
|
||||
|
||||
Opens a devtools window for guest page.
|
||||
|
||||
### `<webview>`.closeDevTools()
|
||||
### `<webview>.closeDevTools()`
|
||||
|
||||
Closes the devtools window of guest page.
|
||||
|
||||
### `<webview>`.isDevToolsOpened()
|
||||
### `<webview>.isDevToolsOpened()`
|
||||
|
||||
Returns whether guest page has a devtools window attached.
|
||||
Returns a boolean whether guest page has a devtools window attached.
|
||||
|
||||
### `<webview>`.inspectElement(x, y)
|
||||
### `<webview>.inspectElement(x, y)`
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
Starts inspecting element at position (`x`, `y`) of guest page.
|
||||
|
||||
### `<webview>`.inspectServiceWorker()
|
||||
### `<webview>.inspectServiceWorker()`
|
||||
|
||||
Opens the devtools for the service worker context present in the guest page.
|
||||
|
||||
### `<webview>`.setAudioMuted(muted)
|
||||
### `<webview>.setAudioMuted(muted)`
|
||||
|
||||
+ `muted` Boolean
|
||||
* `muted` Boolean
|
||||
|
||||
Set guest page muted.
|
||||
|
||||
### `<webview>`.isAudioMuted()
|
||||
### `<webview>.isAudioMuted()`
|
||||
|
||||
Returns whether guest page has been muted.
|
||||
|
||||
### `<webview>`.undo()
|
||||
### `<webview>.undo()`
|
||||
|
||||
Executes editing command `undo` in page.
|
||||
|
||||
### `<webview>`.redo()
|
||||
### `<webview>.redo()`
|
||||
|
||||
Executes editing command `redo` in page.
|
||||
|
||||
### `<webview>`.cut()
|
||||
### `<webview>.cut()`
|
||||
|
||||
Executes editing command `cut` in page.
|
||||
|
||||
### `<webview>`.copy()
|
||||
### `<webview>.copy()`
|
||||
|
||||
Executes editing command `copy` in page.
|
||||
|
||||
### `<webview>`.paste()
|
||||
### `<webview>.paste()`
|
||||
|
||||
Executes editing command `paste` in page.
|
||||
|
||||
### `<webview>`.pasteAndMatchStyle()
|
||||
### `<webview>.pasteAndMatchStyle()`
|
||||
|
||||
Executes editing command `pasteAndMatchStyle` in page.
|
||||
|
||||
### `<webview>`.delete()
|
||||
### `<webview>.delete()`
|
||||
|
||||
Executes editing command `delete` in page.
|
||||
|
||||
### `<webview>`.selectAll()
|
||||
### `<webview>.selectAll()`
|
||||
|
||||
Executes editing command `selectAll` in page.
|
||||
|
||||
### `<webview>`.unselect()
|
||||
### `<webview>.unselect()`
|
||||
|
||||
Executes editing command `unselect` in page.
|
||||
|
||||
### `<webview>`.replace(text)
|
||||
### `<webview.replace(text)`
|
||||
|
||||
* `text` String
|
||||
|
||||
Executes editing command `replace` in page.
|
||||
|
||||
### `<webview>`.replaceMisspelling(text)
|
||||
### `<webview>.replaceMisspelling(text)`
|
||||
|
||||
* `text` String
|
||||
|
||||
Executes editing command `replaceMisspelling` in page.
|
||||
|
||||
### `<webview>`.print([options])
|
||||
### `<webview>.print([options])`
|
||||
|
||||
Prints webview's web page. Same with `webContents.print([options])`.
|
||||
Prints `webview`'s web page. Same with `webContents.print([options])`.
|
||||
|
||||
### `<webview>`.printToPDF(options, callback)
|
||||
### `<webview>.printToPDF(options, callback)`
|
||||
|
||||
Prints webview's web page as PDF, Same with `webContents.printToPDF(options, callback)`
|
||||
|
||||
### `<webview>`.send(channel[, args...])
|
||||
### `<webview>.send(channel[, args...])`
|
||||
|
||||
* `channel` String
|
||||
* `arg` (optional)
|
||||
|
||||
Send `args..` to guest page via `channel` in asynchronous message, the guest
|
||||
page can handle it by listening to the `channel` event of `ipc` module.
|
||||
|
@ -335,7 +342,11 @@ examples.
|
|||
|
||||
## DOM events
|
||||
|
||||
### load-commit
|
||||
The following DOM events are available to the `webview` tag:
|
||||
|
||||
### Event: 'load-commit'
|
||||
|
||||
Returns:
|
||||
|
||||
* `url` String
|
||||
* `isMainFrame` Boolean
|
||||
|
@ -344,12 +355,14 @@ Fired when a load has committed. This includes navigation within the current
|
|||
document as well as subframe document-level loads, but does not include
|
||||
asynchronous resource loads.
|
||||
|
||||
### did-finish-load
|
||||
### Event: 'did-finish-load'
|
||||
|
||||
Fired when the navigation is done, i.e. the spinner of the tab will stop
|
||||
spinning, and the `onload` event was dispatched.
|
||||
spinning, and the `onload` event is dispatched.
|
||||
|
||||
### did-fail-load
|
||||
### Event: 'did-fail-load'
|
||||
|
||||
Returns:
|
||||
|
||||
* `errorCode` Integer
|
||||
* `errorDescription` String
|
||||
|
@ -357,21 +370,25 @@ spinning, and the `onload` event was dispatched.
|
|||
This event is like `did-finish-load`, but fired when the load failed or was
|
||||
cancelled, e.g. `window.stop()` is invoked.
|
||||
|
||||
### did-frame-finish-load
|
||||
### Event: 'did-frame-finish-load'
|
||||
|
||||
Returns:
|
||||
|
||||
* `isMainFrame` Boolean
|
||||
|
||||
Fired when a frame has done navigation.
|
||||
|
||||
### did-start-loading
|
||||
### Event: 'did-start-loading'
|
||||
|
||||
Corresponds to the points in time when the spinner of the tab starts spinning.
|
||||
|
||||
### did-stop-loading
|
||||
### Event: 'did-stop-loading'
|
||||
|
||||
Corresponds to the points in time when the spinner of the tab stops spinning.
|
||||
|
||||
### did-get-response-details
|
||||
### Event: 'did-get-response-details'
|
||||
|
||||
Returns:
|
||||
|
||||
* `status` Boolean
|
||||
* `newUrl` String
|
||||
|
@ -384,7 +401,9 @@ Corresponds to the points in time when the spinner of the tab stops spinning.
|
|||
Fired when details regarding a requested resource is available.
|
||||
`status` indicates socket connection to download the resource.
|
||||
|
||||
### did-get-redirect-request
|
||||
### Event: 'did-get-redirect-request'
|
||||
|
||||
Returns:
|
||||
|
||||
* `oldUrl` String
|
||||
* `newUrl` String
|
||||
|
@ -392,11 +411,13 @@ Fired when details regarding a requested resource is available.
|
|||
|
||||
Fired when a redirect was received while requesting a resource.
|
||||
|
||||
### dom-ready
|
||||
### Event: 'dom-ready'
|
||||
|
||||
Fired when document in the given frame is loaded.
|
||||
|
||||
### page-title-set
|
||||
### Event: 'page-title-set'
|
||||
|
||||
Returns:
|
||||
|
||||
* `title` String
|
||||
* `explicitSet` Boolean
|
||||
|
@ -404,21 +425,25 @@ Fired when document in the given frame is loaded.
|
|||
Fired when page title is set during navigation. `explicitSet` is false when title is synthesised from file
|
||||
url.
|
||||
|
||||
### page-favicon-updated
|
||||
### Event: 'page-favicon-updated'
|
||||
|
||||
* `favicons` Array - Array of Urls
|
||||
Returns:
|
||||
|
||||
* `favicons` Array - Array of Urls.
|
||||
|
||||
Fired when page receives favicon urls.
|
||||
|
||||
### enter-html-full-screen
|
||||
### Event: 'enter-html-full-screen'
|
||||
|
||||
Fired when page enters fullscreen triggered by html api.
|
||||
Fired when page enters fullscreen triggered by HTML API.
|
||||
|
||||
### leave-html-full-screen
|
||||
### Event: 'leave-html-full-screen'
|
||||
|
||||
Fired when page leaves fullscreen triggered by html api.
|
||||
Fired when page leaves fullscreen triggered by HTML API.
|
||||
|
||||
### console-message
|
||||
### Event: 'console-message'
|
||||
|
||||
Returns:
|
||||
|
||||
* `level` Integer
|
||||
* `message` String
|
||||
|
@ -436,7 +461,9 @@ webview.addEventListener('console-message', function(e) {
|
|||
});
|
||||
```
|
||||
|
||||
### new-window
|
||||
### Event: 'new-window'
|
||||
|
||||
Returns:
|
||||
|
||||
* `url` String
|
||||
* `frameName` String
|
||||
|
@ -453,7 +480,7 @@ webview.addEventListener('new-window', function(e) {
|
|||
});
|
||||
```
|
||||
|
||||
### close
|
||||
### Event: 'close'
|
||||
|
||||
Fired when the guest page attempts to close itself.
|
||||
|
||||
|
@ -466,7 +493,9 @@ webview.addEventListener('close', function() {
|
|||
});
|
||||
```
|
||||
|
||||
### ipc-message
|
||||
### Event: 'ipc-message'
|
||||
|
||||
Returns:
|
||||
|
||||
* `channel` String
|
||||
* `args` Array
|
||||
|
@ -493,21 +522,23 @@ ipc.on('ping', function() {
|
|||
});
|
||||
```
|
||||
|
||||
### crashed
|
||||
### Event: 'crashed'
|
||||
|
||||
Fired when the renderer process is crashed.
|
||||
|
||||
### gpu-crashed
|
||||
### Event: 'gpu-crashed'
|
||||
|
||||
Fired when the gpu process is crashed.
|
||||
|
||||
### plugin-crashed
|
||||
### Event: 'plugin-crashed'
|
||||
|
||||
Returns:
|
||||
|
||||
* `name` String
|
||||
* `version` String
|
||||
|
||||
Fired when a plugin process is crashed.
|
||||
|
||||
### destroyed
|
||||
### Event: 'destroyed'
|
||||
|
||||
Fired when the WebContents is destroyed.
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
# `window.open` function
|
||||
# The `window.open` function
|
||||
|
||||
When `window.open` is called to create a new window in web page, a new instance
|
||||
of `BrowserWindow` will be created for the `url`, and a proxy will be returned
|
||||
When `window.open` is called to create a new window in a web page, a new instance
|
||||
of `BrowserWindow` will be created for the `url` and a proxy will be returned
|
||||
to `window.open` to let the page have limited control over it.
|
||||
|
||||
The proxy only has some limited standard functionality implemented to be
|
||||
compatible with traditional web pages, for full control of the created window
|
||||
The proxy has limited standard functionality implemented to be
|
||||
compatible with traditional web pages. For full control of the new window
|
||||
you should create a `BrowserWindow` directly.
|
||||
|
||||
## window.open(url, [frameName[, features]])
|
||||
### `window.open(url[, frameName][, features])`
|
||||
|
||||
* `url` String
|
||||
* `frameName` String
|
||||
* `features` String
|
||||
* `frameName` String (optional)
|
||||
* `features` String (optional)
|
||||
|
||||
Creates a new window and returns an instance of `BrowserWindowProxy` class.
|
||||
|
||||
## window.opener.postMessage(message, targetOrigin)
|
||||
### `window.opener.postMessage(message, targetOrigin)`
|
||||
|
||||
* `message` String
|
||||
* `targetOrigin` String
|
||||
|
@ -26,29 +26,32 @@ origin preference.
|
|||
|
||||
## Class: BrowserWindowProxy
|
||||
|
||||
### BrowserWindowProxy.blur()
|
||||
The `BrowserWindowProxy` object is returned from `window.open` and provides
|
||||
limited functionality with the child window.
|
||||
|
||||
### `BrowserWindowProxy.blur()`
|
||||
|
||||
Removes focus from the child window.
|
||||
|
||||
### BrowserWindowProxy.close()
|
||||
### `BrowserWindowProxy.close()`
|
||||
|
||||
Forcefully closes the child window without calling its unload event.
|
||||
|
||||
### BrowserWindowProxy.closed
|
||||
### `BrowserWindowProxy.closed`
|
||||
|
||||
Set to true after the child window gets closed.
|
||||
|
||||
### BrowserWindowProxy.eval(code)
|
||||
### `BrowserWindowProxy.eval(code)`
|
||||
|
||||
* `code` String
|
||||
|
||||
Evaluates the code in the child window.
|
||||
|
||||
### BrowserWindowProxy.focus()
|
||||
### `BrowserWindowProxy.focus()`
|
||||
|
||||
Focuses the child window (brings the window to front).
|
||||
|
||||
### BrowserWindowProxy.postMessage(message, targetOrigin)
|
||||
### `BrowserWindowProxy.postMessage(message, targetOrigin)`
|
||||
|
||||
* `message` String
|
||||
* `targetOrigin` String
|
||||
|
@ -57,4 +60,4 @@ Sends a message to the child window with the specified origin or `*` for no
|
|||
origin preference.
|
||||
|
||||
In addition to these methods, the child window implements `window.opener` object
|
||||
with no properties and a single method:
|
||||
with no properties and a single method.
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
# Technical differences to NW.js (formerly node-webkit)
|
||||
# Technical Differences Between Electron and NW.js (formerly node-webkit)
|
||||
|
||||
__Note: Electron was previously named Atom Shell.__
|
||||
|
||||
Like NW.js, Electron provides a platform to write desktop applications
|
||||
with JavaScript and HTML and has Node integration to grant access to low level
|
||||
system in web pages.
|
||||
with JavaScript and HTML and has Node integration to grant access to the low
|
||||
level system from web pages.
|
||||
|
||||
But there are also fundamental differences between the two projects that make
|
||||
Electron a completely separate product from NW.js:
|
||||
|
||||
__1. Entry of application__
|
||||
__1. Entry of Application__
|
||||
|
||||
In NW.js, the main entry of an application is a web page. You specify a
|
||||
main page in the `package.json` and it is opened in a browser window as
|
||||
In NW.js the main entry point of an application is a web page. You specify a
|
||||
main page URL in the `package.json` and it is opened in a browser window as
|
||||
the application's main window.
|
||||
|
||||
In Electron, the entry point is a JavaScript script. Instead of
|
||||
|
@ -23,19 +23,18 @@ to decide when to quit the application.
|
|||
Electron works more like the Node.js runtime. Electron's APIs are lower level
|
||||
so you can use it for browser testing in place of [PhantomJS](http://phantomjs.org/).
|
||||
|
||||
__2. Build system__
|
||||
__2. Build System__
|
||||
|
||||
In order to avoid the complexity of building the whole Chromium, Electron uses
|
||||
[libchromiumcontent](https://github.com/brightray/libchromiumcontent) to access
|
||||
Chromium's Content API. libchromiumcontent is a single, shared library that
|
||||
includes the Chromium Content module and all its dependencies. Users don't
|
||||
In order to avoid the complexity of building all of Chromium, Electron uses [`libchromiumcontent`](https://github.com/brightray/libchromiumcontent) to access
|
||||
Chromium's Content API. `libchromiumcontent` is a single shared library that
|
||||
includes the Chromium Content module and all of its dependencies. Users don't
|
||||
need a powerful machine to build Electron.
|
||||
|
||||
__3. Node integration__
|
||||
__3. Node Integration__
|
||||
|
||||
In NW.js, the Node integration in web pages requires patching Chromium to
|
||||
work, while in Electron we chose a different way to integrate libuv loop with
|
||||
each platform's message loop to avoid hacking Chromium. See the
|
||||
work, while in Electron we chose a different way to integrate the libuv loop
|
||||
with each platform's message loop to avoid hacking Chromium. See the
|
||||
[`node_bindings`](../../atom/common/) code for how that was done.
|
||||
|
||||
__4. Multi-context__
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
# Build instructions (Linux)
|
||||
# Build Instructions (Linux)
|
||||
|
||||
Follow the guidelines below for building Electron on Linux.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Python 2.7.x. Some distributions like CentOS still use Python 2.6.x
|
||||
so you may need to check your Python version with `python -V`.
|
||||
* Node.js v0.12.x. There are various ways to install Node. One can download
|
||||
source code from [Node.js] (http://nodejs.org) and compile from source.
|
||||
Doing so permits installing Node to your own home directory as a standard user.
|
||||
Or try repositories such as [NodeSource] (https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)
|
||||
* Clang 3.4 or later
|
||||
* Development headers of GTK+ and libnotify
|
||||
so you may need to check your Python version with `python -V`.
|
||||
* Node.js v0.12.x. There are various ways to install Node. You can download
|
||||
source code from [Node.js](http://nodejs.org) and compile from source.
|
||||
Doing so permits installing Node on your own home directory as a standard user.
|
||||
Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
|
||||
* Clang 3.4 or later.
|
||||
* Development headers of GTK+ and libnotify.
|
||||
|
||||
On Ubuntu, install the following libraries:
|
||||
|
||||
|
@ -20,15 +22,23 @@ $ 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 one can compile from source code.
|
||||
managers such as pacman. Or one can compile from source code.
|
||||
|
||||
## If You Use Virtual Machines For Building
|
||||
|
||||
If you plan to build electron on a virtual machine, you will need a fixed-size
|
||||
If you plan to build Electron on a virtual machine you will need a fixed-size
|
||||
device container of at least 25 gigabytes in size.
|
||||
|
||||
## Getting the code
|
||||
## Getting the Code
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/atom/electron.git
|
||||
|
@ -37,8 +47,8 @@ $ git clone https://github.com/atom/electron.git
|
|||
## Bootstrapping
|
||||
|
||||
The bootstrap script will download all necessary build dependencies and create
|
||||
build project files. You must have Python 2.7.x for the script to succeed.
|
||||
Downloading certain files could take a long time. Notice that we are using
|
||||
the build project files. You must have Python 2.7.x for the script to succeed.
|
||||
Downloading certain files can take a long time. Notice that we are using
|
||||
`ninja` to build Electron so there is no `Makefile` generated.
|
||||
|
||||
```bash
|
||||
|
@ -48,7 +58,7 @@ $ ./script/bootstrap.py -v
|
|||
|
||||
### Cross compilation
|
||||
|
||||
If you want to build for `arm` target, you should also install following
|
||||
If you want to build for an `arm` target you should also install the following
|
||||
dependencies:
|
||||
|
||||
```bash
|
||||
|
@ -82,7 +92,7 @@ $ ./script/create-dist.py
|
|||
|
||||
This will put a working distribution with much smaller file sizes in
|
||||
the `dist` directory. After running the create-dist.py script, you
|
||||
may want to remove the 1.3+ gigabyte binary which is still in out/R.
|
||||
may want to remove the 1.3+ gigabyte binary which is still in `out/R`.
|
||||
|
||||
You can also build the `Debug` target only:
|
||||
|
||||
|
@ -102,12 +112,12 @@ $ ./script/clean.py
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
Make sure you have installed all the build dependencies.
|
||||
Make sure you have installed all of the build dependencies.
|
||||
|
||||
### error while loading shared libraries: libtinfo.so.5
|
||||
### Error While Loading Shared Libraries: libtinfo.so.5
|
||||
|
||||
Prebulit `clang` will try to link to `libtinfo.so.5`. Depending on the host
|
||||
architecture, symlink to appropriate `libncurses`
|
||||
architecture, symlink to appropriate `libncurses`:
|
||||
|
||||
```bash
|
||||
$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
|
||||
|
@ -115,7 +125,7 @@ $ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
|
|||
|
||||
## Tests
|
||||
|
||||
Test your changes confirm to the project coding style using:
|
||||
Test your changes conform to the project coding style using:
|
||||
|
||||
```bash
|
||||
$ ./script/cpplint.py
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
# Build instructions (Mac)
|
||||
# Build Instructions (OS X)
|
||||
|
||||
Follow the guidelines below for building Electron on OS X.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* OS X >= 10.8
|
||||
* [Xcode](https://developer.apple.com/technologies/tools/) >= 5.1
|
||||
* [node.js](http://nodejs.org) (external).
|
||||
* [node.js](http://nodejs.org) (external)
|
||||
|
||||
If you are using the python downloaded by Homebrew, you also need to install
|
||||
If you are using the Python downloaded by Homebrew, you also need to install
|
||||
following python modules:
|
||||
|
||||
* pyobjc
|
||||
|
||||
## Getting the code
|
||||
## Getting the Code
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/atom/electron.git
|
||||
|
@ -20,7 +22,7 @@ $ git clone https://github.com/atom/electron.git
|
|||
## Bootstrapping
|
||||
|
||||
The bootstrap script will download all necessary build dependencies and create
|
||||
build project files. Notice that we're using `ninja` to build Electron so
|
||||
the build project files. Notice that we're using `ninja` to build Electron so
|
||||
there is no Xcode project generated.
|
||||
|
||||
```bash
|
||||
|
@ -44,14 +46,14 @@ $ ./script/build.py -c D
|
|||
|
||||
After building is done, you can find `Electron.app` under `out/D`.
|
||||
|
||||
## 32bit support
|
||||
## 32bit Support
|
||||
|
||||
Electron can only be built for 64bit target on OS X, and there is no plan to
|
||||
Electron can only be built for a 64bit target on OS X and there is no plan to
|
||||
support 32bit OS X in future.
|
||||
|
||||
## Tests
|
||||
|
||||
Test your changes confirm to the project coding style using:
|
||||
Test your changes conform to the project coding style using:
|
||||
|
||||
```bash
|
||||
$ ./script/cpplint.py
|
|
@ -1,43 +1,44 @@
|
|||
# Build instructions (Windows)
|
||||
# Build Instructions (Windows)
|
||||
|
||||
Follow the guidelines below for building Electron on Windows.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Windows 7 / Server 2008 R2 or higher
|
||||
* Visual Studio 2013 - [download VS 2013 Community Edition for
|
||||
free](https://www.visualstudio.com/downloads/download-visual-studio-vs)
|
||||
free](https://www.visualstudio.com/downloads/download-visual-studio-vs).
|
||||
* [Python 2.7](http://www.python.org/download/releases/2.7/)
|
||||
* [Node.js](http://nodejs.org/download/)
|
||||
* [git](http://git-scm.com)
|
||||
* [Git](http://git-scm.com)
|
||||
|
||||
If you don't have a Windows installation at the moment,
|
||||
[modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads) has
|
||||
timebombed versions of Windows that you can use to build Electron.
|
||||
If you don't currently have a Windows installation, [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads)
|
||||
has timebombed versions of Windows that you can use to build Electron.
|
||||
|
||||
The building of Electron is done entirely with command-line scripts, so you
|
||||
can use any editor you like to develop Electron, but it also means you can
|
||||
not use Visual Studio for the development. Support of building with Visual
|
||||
Studio will come in the future.
|
||||
Building Electron is done entirely with command-line scripts and cannot be done
|
||||
with Visual Studio. You can develop Electron with any editor but support for
|
||||
building with Visual Studio will come in the future.
|
||||
|
||||
**Note:** Even though Visual Studio is not used for building, it's still
|
||||
**required** because we need the build toolchains it provides.
|
||||
|
||||
**Note:** Visual Studio 2015 will not work. Please make sure to get MSVS **2013**.
|
||||
**Note:** Visual Studio 2015 will not work. Please make sure to get MSVS
|
||||
**2013**.
|
||||
|
||||
## Getting the code
|
||||
## Getting the Code
|
||||
|
||||
```powershell
|
||||
git clone https://github.com/atom/electron.git
|
||||
$ git clone https://github.com/atom/electron.git
|
||||
```
|
||||
|
||||
## Bootstrapping
|
||||
|
||||
The bootstrap script will download all necessary build dependencies and create
|
||||
build project files. Notice that we're using `ninja` to build Electron so
|
||||
the build project files. Notice that we're using `ninja` to build Electron so
|
||||
there is no Visual Studio project generated.
|
||||
|
||||
```powershell
|
||||
cd electron
|
||||
python script\bootstrap.py -v
|
||||
$ cd electron
|
||||
$ python script\bootstrap.py -v
|
||||
```
|
||||
|
||||
## Building
|
||||
|
@ -45,50 +46,51 @@ python script\bootstrap.py -v
|
|||
Build both Release and Debug targets:
|
||||
|
||||
```powershell
|
||||
python script\build.py
|
||||
$ python script\build.py
|
||||
```
|
||||
|
||||
You can also only build the Debug target:
|
||||
|
||||
```powershell
|
||||
python script\build.py -c D
|
||||
$ python script\build.py -c D
|
||||
```
|
||||
|
||||
After building is done, you can find `electron.exe` under `out\D` (debug
|
||||
target) or under `out\R` (release target).
|
||||
|
||||
## 64bit build
|
||||
## 64bit Build
|
||||
|
||||
To build for the 64bit target, you need to pass `--target_arch=x64` when running
|
||||
the bootstrap script:
|
||||
|
||||
```powershell
|
||||
python script\bootstrap.py -v --target_arch=x64
|
||||
$ python script\bootstrap.py -v --target_arch=x64
|
||||
```
|
||||
|
||||
The other building steps are exactly the same.
|
||||
|
||||
## Tests
|
||||
|
||||
Test your changes confirm to the project coding style using:
|
||||
Test your changes conform to the project coding style using:
|
||||
|
||||
```powershell
|
||||
python script\cpplint.py
|
||||
$ python script\cpplint.py
|
||||
```
|
||||
|
||||
Test functionality using:
|
||||
|
||||
```powershell
|
||||
python script\test.py
|
||||
$ python script\test.py
|
||||
```
|
||||
|
||||
Tests that include native modules (e.g. `runas`) can't be executed with the
|
||||
debug build (see #2558 for details), but they will work with the release build.
|
||||
debug build (see [#2558](https://github.com/atom/electron/issues/2558) for
|
||||
details), but they will work with the release build.
|
||||
|
||||
To run the tests with the release build use:
|
||||
|
||||
```powershell
|
||||
python script\test.py -R
|
||||
$ python script\test.py -R
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
@ -122,24 +124,24 @@ Traceback (most recent call last):
|
|||
subprocess.CalledProcessError: Command '['npm.cmd', 'install']' returned non-zero exit status 3
|
||||
```
|
||||
|
||||
This is caused by a bug when using Cygwin python and Win32 node together. The
|
||||
solution is to use the Win32 python to execute the bootstrap script (supposing
|
||||
you have installed python under `C:\Python27`):
|
||||
This is caused by a bug when using Cygwin Python and Win32 Node together. The
|
||||
solution is to use the Win32 Python to execute the bootstrap script (assuming
|
||||
you have installed Python under `C:\Python27`):
|
||||
|
||||
```bash
|
||||
/cygdrive/c/Python27/python.exe script/bootstrap.py
|
||||
```powershell
|
||||
$ /cygdrive/c/Python27/python.exe script/bootstrap.py
|
||||
```
|
||||
|
||||
### LNK1181: cannot open input file 'kernel32.lib'
|
||||
|
||||
Try reinstalling 32bit node.js.
|
||||
Try reinstalling 32bit Node.js.
|
||||
|
||||
### Error: ENOENT, stat 'C:\Users\USERNAME\AppData\Roaming\npm'
|
||||
|
||||
Simply making that directory [should fix the problem](http://stackoverflow.com/a/25095327/102704):
|
||||
|
||||
```powershell
|
||||
mkdir ~\AppData\Roaming\npm
|
||||
$ mkdir ~\AppData\Roaming\npm
|
||||
```
|
||||
|
||||
### node-gyp is not recognized as an internal or external command
|
||||
|
|
|
@ -1,71 +1,72 @@
|
|||
# Build system overview
|
||||
# Build System Overview
|
||||
|
||||
Electron uses `gyp` for project generation, and `ninja` for building, project
|
||||
configurations can be found in `.gyp` and `.gypi` files.
|
||||
Electron uses `gyp` for project generation and `ninja` for building. Project
|
||||
configurations can be found in the `.gyp` and `.gypi` files.
|
||||
|
||||
## Gyp files
|
||||
## Gyp Files
|
||||
|
||||
Following `gyp` files contain the main rules of building Electron:
|
||||
Following `gyp` files contain the main rules for building Electron:
|
||||
|
||||
* `atom.gyp` defines how Electron itself is built.
|
||||
* `common.gypi` adjusts the build configurations of Node to make it build
|
||||
together with Chromium.
|
||||
* `vendor/brightray/brightray.gyp` defines how `brightray` is built, and
|
||||
includes the default configurations of linking with Chromium.
|
||||
* `vendor/brightray/brightray.gyp` defines how `brightray` is built and
|
||||
includes the default configurations for linking with Chromium.
|
||||
* `vendor/brightray/brightray.gypi` includes general build configurations about
|
||||
building.
|
||||
|
||||
## Component build
|
||||
## Component Build
|
||||
|
||||
Since Chromium is quite a large project, the final linking stage would take
|
||||
quite a few minutes, making it hard for development. In order to solve this,
|
||||
Chromium introduced the "component build", which builds each component as a
|
||||
separate shared library, making linking very quick but sacrificing file size
|
||||
Since Chromium is quite a large project, the final linking stage can take
|
||||
quite a few minutes, which makes it hard for development. In order to solve
|
||||
this, Chromium introduced the "component build", which builds each component as
|
||||
a separate shared library, making linking very quick but sacrificing file size
|
||||
and performance.
|
||||
|
||||
In Electron we took a very similar approach: for `Debug` builds, the binary
|
||||
will be linked to shared library version of Chromium's components to achieve
|
||||
will be linked to a shared library version of Chromium's components to achieve
|
||||
fast linking time; for `Release` builds, the binary will be linked to the static
|
||||
library versions, so we can have the best possible binary size and performance.
|
||||
|
||||
## Minimal bootstrapping
|
||||
## Minimal Bootstrapping
|
||||
|
||||
All of Chromium's prebuilt binaries(libchromiumcontent) are downloaded when
|
||||
All of Chromium's prebuilt binaries (`libchromiumcontent`) are downloaded when
|
||||
running the bootstrap script. By default both static libraries and shared
|
||||
libraries will be downloaded and the final size should be between 800MB and 2GB
|
||||
according to the platform.
|
||||
depending on the platform.
|
||||
|
||||
By default, libchromiumcontent is downloaded from Amazon Web Services.
|
||||
If the `LIBCHROMIUMCONTENT_MIRROR` environment variable is set, bootrstrap
|
||||
By default, `libchromiumcontent` is downloaded from Amazon Web Services.
|
||||
If the `LIBCHROMIUMCONTENT_MIRROR` environment variable is set, the bootstrap
|
||||
script will download from it.
|
||||
[libchromiumcontent-qiniu-mirror](https://github.com/hokein/libchromiumcontent-qiniu-mirror)
|
||||
is a mirror for libchromiumcontent. If you have trouble in accessing AWS, you can
|
||||
switch download address to it via `export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/`
|
||||
[`libchromiumcontent-qiniu-mirror`](https://github.com/hokein/libchromiumcontent-qiniu-mirror)
|
||||
is a mirror for `libchromiumcontent`. If you have trouble in accessing AWS, you
|
||||
can switch the download address to it via
|
||||
`export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/`
|
||||
|
||||
If you only want to build Electron quickly for testing or development, you
|
||||
can only download the shared library versions by passing the `--dev` parameter:
|
||||
can download just the shared library versions by passing the `--dev` parameter:
|
||||
|
||||
```bash
|
||||
$ ./script/bootstrap.py --dev
|
||||
$ ./script/build.py -c D
|
||||
```
|
||||
|
||||
## Two-phrase project generation
|
||||
## Two-Phrase Project Generation
|
||||
|
||||
Electron links with different sets of libraries in `Release` and `Debug`
|
||||
builds, however `gyp` doesn't support configuring different link settings for
|
||||
builds. `gyp`, however, doesn't support configuring different link settings for
|
||||
different configurations.
|
||||
|
||||
To work around this Electron uses a `gyp` variable
|
||||
`libchromiumcontent_component` to control which link settings to use, and only
|
||||
`libchromiumcontent_component` to control which link settings to use and only
|
||||
generates one target when running `gyp`.
|
||||
|
||||
## Target names
|
||||
## Target Names
|
||||
|
||||
Unlike most projects that use `Release` and `Debug` as target names, Electron
|
||||
uses `R` and `D` instead. This is because `gyp` randomly crashes if there is
|
||||
only one `Release` or `Debug` build configuration is defined, and Electron has
|
||||
to only generate one target for one time as stated above.
|
||||
only one `Release` or `Debug` build configuration defined, and Electron only has
|
||||
to generate one target at a time as stated above.
|
||||
|
||||
This only affects developers, if you are only building Electron for rebranding
|
||||
This only affects developers, if you are just building Electron for rebranding
|
||||
you are not affected.
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
# Coding style
|
||||
# Coding Style
|
||||
|
||||
These are the style guidelines for coding in Electron.
|
||||
|
||||
## C++ and Python
|
||||
|
||||
For C++ and Python, we just follow Chromium's [Coding
|
||||
Style](http://www.chromium.org/developers/coding-style), there is also a
|
||||
script `script/cpplint.py` to check whether all files confirm.
|
||||
For C++ and Python, we follow Chromium's [Coding
|
||||
Style](http://www.chromium.org/developers/coding-style). There is also a
|
||||
script `script/cpplint.py` to check whether all files conform.
|
||||
|
||||
The python's version we are using now is Python 2.7.
|
||||
The Python version we are using now is Python 2.7.
|
||||
|
||||
The C++ code uses a lot of Chromium's abstractions and types, so it's
|
||||
recommended to get acquainted with them. A good place to start is
|
||||
Chromium's [Important Abstractions and Data Structures]
|
||||
(https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures)
|
||||
document. The document mentions some special types, scoped types (that
|
||||
automatically release their memory when going out of scope), logging mechanisms etc.
|
||||
The C++ code uses a lot of Chromium's abstractions and types, so it's
|
||||
recommended to get acquainted with them. A good place to start is
|
||||
Chromium's [Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures)
|
||||
document. The document mentions some special types, scoped types (that
|
||||
automatically release their memory when going out of scope), logging mechanisms
|
||||
etc.
|
||||
|
||||
## CoffeeScript
|
||||
|
||||
For CoffeeScript, we follow GitHub's [Style
|
||||
Guide](https://github.com/styleguide/javascript), and also following rules:
|
||||
Guide](https://github.com/styleguide/javascript) and the following rules:
|
||||
|
||||
* Files should **NOT** end with new line, because we want to match Google's
|
||||
styles.
|
||||
* File names should be concatenated with `-` instead of `_`, e.g.
|
||||
`file-name.coffee` rather than `file_name.coffee`, because in
|
||||
[github/atom](https://github.com/github/atom) module names are usually in
|
||||
the `module-name` form, this rule only applies to `.coffee` files.
|
||||
the `module-name` form. This rule only applies to `.coffee` files.
|
||||
|
||||
## API Names
|
||||
|
||||
When creating a new API, we should prefer getters and setters instead of
|
||||
jQuery's one-function style, for example, `.getText()` and `.setText(text)`
|
||||
jQuery's one-function style. For example, `.getText()` and `.setText(text)`
|
||||
are preferred to `.text([text])`. There is a
|
||||
[discussion](https://github.com/atom/electron/issues/46) of this.
|
||||
[discussion](https://github.com/atom/electron/issues/46) on this.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Setting up symbol server in debugger
|
||||
# Setting Up Symbol Server in Debugger
|
||||
|
||||
Debug symbols allow you to have better debugging sessions. They have information
|
||||
about the functions contained in executables and dynamic libraries and provide
|
||||
|
@ -16,16 +16,16 @@ unoptimized local build.
|
|||
|
||||
The official symbol server URL for Electron is
|
||||
http://54.249.141.255:8086/atom-shell/symbols.
|
||||
You cannot visit this URL directly: you must add it to the symbol path of your
|
||||
You cannot visit this URL directly, you must add it to the symbol path of your
|
||||
debugging tool. In the examples below, a local cache directory is used to avoid
|
||||
repeatedly fetching the PDB from the server. Replace `c:\code\symbols` with an
|
||||
repeatedly fetching the PDB from the server. Replace `c:\code\symbols` with an
|
||||
appropriate cache directory on your machine.
|
||||
|
||||
## Using the symbol server in Windbg
|
||||
## Using the Symbol Server in Windbg
|
||||
|
||||
The Windbg symbol path is configured with a string value delimited with asterisk
|
||||
characters. To use only the Electron symbol server, add the following entry to
|
||||
your symbol path (__note:__ you can replace `c:\code\symbols` with any writable
|
||||
your symbol path (__Note:__ you can replace `c:\code\symbols` with any writable
|
||||
directory on your computer, if you'd prefer a different location for downloaded
|
||||
symbols):
|
||||
|
||||
|
|
|
@ -1,62 +1,63 @@
|
|||
# Source code directory structure
|
||||
# Source Code Directory Structure
|
||||
|
||||
## Overview
|
||||
|
||||
The source code of Electron is separated into a few parts, and we are mostly
|
||||
The source code of Electron is separated into a few parts, mostly
|
||||
following Chromium on the separation conventions.
|
||||
|
||||
You may need to become familiar with [Chromium's multi-process
|
||||
architecture](http://dev.chromium.org/developers/design-documents/multi-process-architecture)
|
||||
to understand the source code better.
|
||||
|
||||
## Structure of source code
|
||||
## Structure of Source Code
|
||||
|
||||
* **atom** - Source code of Electron.
|
||||
* **app** - System entry code.
|
||||
* **browser** - The frontend including the main window, UI, and all of the
|
||||
main process things. This talks to the renderer to manage web pages.
|
||||
* **lib** - Javascript part of the main process initialization code.
|
||||
* **ui** - Implementation of UI stuff for different platforms.
|
||||
* **cocoa** - Cocoa specific source code.
|
||||
* **gtk** - GTK+ specific source code.
|
||||
* **win** - Windows GUI specific source code.
|
||||
* **default_app** - The default page to show when Electron is started
|
||||
without providing an app.
|
||||
* **api** - The implementation of the main process APIs.
|
||||
* **lib** - Javascript part of the API implementation.
|
||||
* **net** - Network related code.
|
||||
* **mac** - Mac specific Objective-C source code.
|
||||
* **resources** - Icons, platform-dependent files, etc.
|
||||
* **renderer** - Code that runs in renderer process.
|
||||
* **lib** - Javascript part of renderer initialization code.
|
||||
* **api** - The implementation of renderer process APIs.
|
||||
* **lib** - Javascript part of the API implementation.
|
||||
* **common** - Code that used by both the main and renderer processes,
|
||||
including some utility functions and code to integrate node's message
|
||||
loop into Chromium's message loop.
|
||||
* **lib** - Common Javascript initialization code.
|
||||
* **api** - The implementation of common APIs, and foundations of
|
||||
Electron's built-in modules.
|
||||
* **lib** - Javascript part of the API implementation.
|
||||
* **chromium_src** - Source code that copied from Chromium.
|
||||
* **docs** - Documentations.
|
||||
* **spec** - Automatic tests.
|
||||
* **atom.gyp** - Building rules of Electron.
|
||||
* **common.gypi** - Compiler specific settings and building rules for other
|
||||
components like `node` and `breakpad`.
|
||||
```
|
||||
Electron
|
||||
├──atom - Source code of Electron.
|
||||
| ├── app - System entry code.
|
||||
| ├── browser - The frontend including the main window, UI, and all of the
|
||||
| | main process things. This talks to the renderer to manage web pages.
|
||||
| | ├── lib - Javascript part of the main process initialization code.
|
||||
| | ├── ui - Implementation of UI stuff for different platforms.
|
||||
| | | ├── cocoa - Cocoa specific source code.
|
||||
| | | ├── gtk - GTK+ specific source code.
|
||||
| | | └── win - Windows GUI specific source code.
|
||||
| | ├── default_app - The default page to show when Electron is started
|
||||
| | | without providing an app.
|
||||
| | ├── api - The implementation of the main process APIs.
|
||||
| | | └── lib - Javascript part of the API implementation.
|
||||
| | ├── net - Network related code.
|
||||
| | ├── mac - Mac specific Objective-C source code.
|
||||
| | └── resources - Icons, platform-dependent files, etc.
|
||||
| ├── renderer - Code that runs in renderer process.
|
||||
| | ├── lib - Javascript part of renderer initialization code.
|
||||
| | └── api - The implementation of renderer process APIs.
|
||||
| | └── lib - Javascript part of the API implementation.
|
||||
| └── common - Code that used by both the main and renderer processes,
|
||||
| including some utility functions and code to integrate node's message
|
||||
| loop into Chromium's message loop.
|
||||
| ├── lib - Common Javascript initialization code.
|
||||
| └── api - The implementation of common APIs, and foundations of
|
||||
| Electron's built-in modules.
|
||||
| └── lib - Javascript part of the API implementation.
|
||||
├── chromium_src - Source code that copied from Chromium.
|
||||
├── docs - Documentations.
|
||||
├── spec - Automatic tests.
|
||||
├── atom.gyp - Building rules of Electron.
|
||||
└── common.gypi - Compiler specific settings and building rules for other
|
||||
components like `node` and `breakpad`.
|
||||
```
|
||||
|
||||
## Structure of other directories
|
||||
## Structure of Other Directories
|
||||
|
||||
* **script** - Scripts used for development purpose like building, packaging,
|
||||
testing, etc.
|
||||
* **tools** - Helper scripts used by gyp files, unlike `script`, scripts put
|
||||
here should never be invoked by users directly.
|
||||
* **vendor** - Source code of third party dependencies, we didn't use
|
||||
`third_party` as name because it would confuse with the same directory in
|
||||
`third_party` as name because it would confuse it with the same directory in
|
||||
Chromium's source code tree.
|
||||
* **node_modules** - Third party node modules used for building.
|
||||
* **out** - Temporary output directory of `ninja`.
|
||||
* **dist** - Temporary directory created by `script/create-dist.py` script
|
||||
when creating an distribution.
|
||||
* **external_binaries** - Downloaded binaries of third-party frameworks which
|
||||
do not support to be built via `gyp`.
|
||||
do not support building with `gyp`.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Application distribution
|
||||
# Application Distribution
|
||||
|
||||
To distribute your app with Electron, you should name the folder of your app
|
||||
as `app`, and put it under Electron's resources directory (on OS X it is
|
||||
`Electron.app/Contents/Resources/`, and on Linux and Windows it is
|
||||
`resources/`), like this:
|
||||
To distribute your app with Electron, the folder containing your app should be
|
||||
named `app` and placed under Electron's resources directory (on OS X it is
|
||||
`Electron.app/Contents/Resources/` and on Linux and Windows it is `resources/`),
|
||||
like this:
|
||||
|
||||
On OS X:
|
||||
|
||||
|
@ -24,12 +24,12 @@ electron/resources/app
|
|||
```
|
||||
|
||||
Then execute `Electron.app` (or `electron` on Linux, `electron.exe` on Windows),
|
||||
and Electron will start as your app. The `electron` directory would then be
|
||||
your distribution that should be delivered to final users.
|
||||
and Electron will start as your app. The `electron` directory will then be
|
||||
your distribution to deliver to final users.
|
||||
|
||||
## Packaging your app into a file
|
||||
## Packaging Your App into a File
|
||||
|
||||
Apart from shipping your app by copying all its sources files, you can also
|
||||
Apart from shipping your app by copying all of its source files, you can also
|
||||
package your app into an [asar](https://github.com/atom/asar) archive to avoid
|
||||
exposing your app's source code to users.
|
||||
|
||||
|
@ -53,7 +53,7 @@ electron/resources/
|
|||
|
||||
More details can be found in [Application packaging](application-packaging.md).
|
||||
|
||||
## Rebranding with downloaded binaries
|
||||
## Rebranding with Downloaded Binaries
|
||||
|
||||
After bundling your app into Electron, you will want to rebrand Electron
|
||||
before distributing it to users.
|
||||
|
@ -103,7 +103,7 @@ MyApp.app/Contents
|
|||
|
||||
You can rename the `electron` executable to any name you like.
|
||||
|
||||
## Rebranding by rebuilding Electron from source
|
||||
## Rebranding by Rebuilding Electron from Source
|
||||
|
||||
It is also possible to rebrand Electron by changing the product name and
|
||||
building it from source. To do this you need to modify the `atom.gyp` file and
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
# Application packaging
|
||||
# Application Packaging
|
||||
|
||||
To mitigate [issues](https://github.com/joyent/node/issues/6960) around long path names on Windows, slightly speed up `require` and conceal your source code from cursory inspection you can choose
|
||||
to package your app into an [asar][asar] archive with little changes to your
|
||||
source code.
|
||||
To mitigate [issues](https://github.com/joyent/node/issues/6960) around long
|
||||
path names on Windows, slightly speed up `require` and conceal your source code
|
||||
from cursory inspection, you can choose to package your app into an [asar][asar]
|
||||
archive with little changes to your source code.
|
||||
|
||||
## Generating `asar` archive
|
||||
## Generating `asar` Archive
|
||||
|
||||
An [asar][asar] archive is a simple tar-like format that concatenates files
|
||||
into a single file, Electron can read arbitrary files from it without unpacking
|
||||
into a single file. Electron can read arbitrary files from it without unpacking
|
||||
the whole file.
|
||||
|
||||
Following is the steps to package your app into an `asar` archive:
|
||||
Steps to package your app into an `asar` archive:
|
||||
|
||||
### 1. Install the asar utility
|
||||
### 1. Install the asar Utility
|
||||
|
||||
```bash
|
||||
$ npm install -g asar
|
||||
|
@ -24,9 +25,9 @@ $ npm install -g asar
|
|||
$ asar pack your-app app.asar
|
||||
```
|
||||
|
||||
## Using `asar` archives
|
||||
## Using `asar` Archives
|
||||
|
||||
In Electron there are two sets of APIs: Node APIs provided by Node.js, and Web
|
||||
In Electron there are two sets of APIs: Node APIs provided by Node.js and Web
|
||||
APIs provided by Chromium. Both APIs support reading files from `asar` archives.
|
||||
|
||||
### Node API
|
||||
|
@ -77,8 +78,8 @@ win.loadUrl('file:///path/to/example.asar/static/index.html');
|
|||
|
||||
### Web API
|
||||
|
||||
In a web page, files in archive can be requested with the `file:` protocol. Like
|
||||
the Node API, `asar` archives are treated as directories.
|
||||
In a web page, files in an archive can be requested with the `file:` protocol.
|
||||
Like the Node API, `asar` archives are treated as directories.
|
||||
|
||||
For example, to get a file with `$.get`:
|
||||
|
||||
|
@ -91,7 +92,7 @@ $.get('file:///path/to/example.asar/file.txt', function(data) {
|
|||
</script>
|
||||
```
|
||||
|
||||
### Treating `asar` archive as normal file
|
||||
### Treating an `asar` Archive as a Normal File
|
||||
|
||||
For some cases like verifying the `asar` archive's checksum, we need to read the
|
||||
content of `asar` archive as file. For this purpose you can use the built-in
|
||||
|
@ -108,21 +109,21 @@ Even though we tried hard to make `asar` archives in the Node API work like
|
|||
directories as much as possible, there are still limitations due to the
|
||||
low-level nature of the Node API.
|
||||
|
||||
### Archives are read only
|
||||
### Archives Are Read-only
|
||||
|
||||
The archives can not be modified so all Node APIs that can modify files will not
|
||||
work with `asar` archives.
|
||||
|
||||
### Working directory can not be set to directories in archive
|
||||
### Working Directory Can Not Be Set to Directories in Archive
|
||||
|
||||
Though `asar` archives are treated as directories, there are no actual
|
||||
directories in the filesystem, so you can never set the working directory to
|
||||
directories in `asar` archives, passing them to `cwd` option of some APIs will
|
||||
also cause errors.
|
||||
directories in `asar` archives. Passing them as the `cwd` option of some APIs
|
||||
will also cause errors.
|
||||
|
||||
### Extra unpacking on some APIs
|
||||
### Extra Unpacking on Some APIs
|
||||
|
||||
Most `fs` APIs can read file or get file's information from `asar` archives
|
||||
Most `fs` APIs can read a file or get a file's information from `asar` archives
|
||||
without unpacking, but for some APIs that rely on passing the real file path to
|
||||
underlying system calls, Electron will extract the needed file into a
|
||||
temporary file and pass the path of the temporary file to the APIs to make them
|
||||
|
@ -135,14 +136,14 @@ APIs that requires extra unpacking are:
|
|||
* `fs.openSync`
|
||||
* `process.dlopen` - Used by `require` on native modules
|
||||
|
||||
### Fake stat information of `fs.stat`
|
||||
### Fake Stat Information of `fs.stat`
|
||||
|
||||
The `Stats` object returned by `fs.stat` and its friends on files in `asar`
|
||||
archives is generated by guessing, because those files do not exist on the
|
||||
filesystem. So you should not trust the `Stats` object except for getting file
|
||||
size and checking file type.
|
||||
|
||||
## Adding unpacked files in `asar` archive
|
||||
## Adding Unpacked Files in `asar` Archive
|
||||
|
||||
As stated above, some Node APIs will unpack the file to filesystem when
|
||||
calling, apart from the performance issues, it could also lead to false alerts
|
||||
|
@ -161,4 +162,3 @@ After running the command, apart from the `app.asar`, there is also an
|
|||
should copy it together with `app.asar` when shipping it to users.
|
||||
|
||||
[asar]: https://github.com/atom/asar
|
||||
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
# Debugging the main process
|
||||
# Debugging the Main Process
|
||||
|
||||
The devtools of browser window can only debug the renderer process scripts.
|
||||
(I.e. the web pages.) In order to provide a way to debug the scripts of
|
||||
the main process, Electron has provided the `--debug` and `--debug-brk`
|
||||
switches.
|
||||
The browser window devtools can only debug the renderer process scripts (i.e.
|
||||
the web pages). In order to provide a way to debug the scripts from the main
|
||||
process, Electron has provided the `--debug` and `--debug-brk` switches.
|
||||
|
||||
## Command line switches
|
||||
## Command Line Switches
|
||||
|
||||
Use the following command line switches to debug Electron's main process:
|
||||
|
||||
### `--debug=[port]`
|
||||
|
||||
When this switch is used Electron would listen for V8 debugger protocol
|
||||
messages on `port`, the `port` is `5858` by default.
|
||||
When this switch is used Electron will listen for V8 debugger protocol
|
||||
messages on `port`. The default `port` is `5858`.
|
||||
|
||||
### `--debug-brk=[port]`
|
||||
|
||||
Like `--debug` but pauses the script on the first line.
|
||||
|
||||
## Use node-inspector for debugging
|
||||
## Use node-inspector for Debugging
|
||||
|
||||
__Note:__ Electron uses node v0.11.13, which currently doesn't work very well
|
||||
with node-inspector, and the main process would crash if you inspect the
|
||||
with node-inspector, and the main process will crash if you inspect the
|
||||
`process` object under node-inspector's console.
|
||||
|
||||
### 1. Start the [node-inspector][node-inspector] server
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Desktop environment integration
|
||||
# Desktop Environment Integration
|
||||
|
||||
Different operating systems provide different features on integrating desktop
|
||||
applications into their desktop environments. For example, on Windows
|
||||
applications can put shortcuts in the JumpList of task bar, and on Mac
|
||||
Different operating systems provide different features for integrating desktop
|
||||
applications into their desktop environments. For example, on Windows,
|
||||
applications can put shortcuts in the JumpList of task bar, and on Mac,
|
||||
applications can put a custom menu in the dock menu.
|
||||
|
||||
This guide explains how to integrate your application into those desktop
|
||||
|
@ -11,7 +11,7 @@ environments with Electron APIs.
|
|||
## Recent documents (Windows & OS X)
|
||||
|
||||
Windows and OS X provide easy access to a list of recent documents opened by
|
||||
the application via JumpList and dock menu.
|
||||
the application via JumpList or dock menu, respectively.
|
||||
|
||||
__JumpList:__
|
||||
|
||||
|
@ -21,7 +21,7 @@ __Application dock menu:__
|
|||
|
||||
<img src="https://cloud.githubusercontent.com/assets/639601/5069610/2aa80758-6e97-11e4-8cfb-c1a414a10774.png" height="353" width="428" >
|
||||
|
||||
To add a file to recent documents, you can use
|
||||
To add a file to recent documents, you can use the
|
||||
[app.addRecentDocument][addrecentdocument] API:
|
||||
|
||||
```javascript
|
||||
|
@ -29,29 +29,28 @@ 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
|
||||
app.clearRecentDocuments();
|
||||
```
|
||||
|
||||
### Windows notes
|
||||
### Windows Notes
|
||||
|
||||
In order to be able to use this feature on Windows, your application has to be
|
||||
registered as a handler of the file type of the document, otherwise the file
|
||||
won't appear in JumpList even after you have added it. You can find everything
|
||||
on registering your application in [Application Registration][app-registration].
|
||||
|
||||
When a user clicks a file from JumpList, a new instance of your application will
|
||||
be started with the path of the file added as a command line argument.
|
||||
When a user clicks a file from the JumpList, a new instance of your application will be started with the path of the file added as a command line argument.
|
||||
|
||||
### OS X notes
|
||||
### OS X Notes
|
||||
|
||||
When a file is requested from the recent documents menu, the `open-file` event
|
||||
of `app` module would be emitted for it.
|
||||
of `app` module will be emitted for it.
|
||||
|
||||
## Custom dock menu (OS X)
|
||||
## Custom Dock Menu (OS X)
|
||||
|
||||
OS X enables developers to specify a custom menu for the dock, which usually
|
||||
contains some shortcuts for commonly used features of your application:
|
||||
|
@ -77,7 +76,7 @@ var dockMenu = Menu.buildFromTemplate([
|
|||
app.dock.setMenu(dockMenu);
|
||||
```
|
||||
|
||||
## User tasks (Windows)
|
||||
## User Tasks (Windows)
|
||||
|
||||
On Windows you can specify custom actions in the `Tasks` category of JumpList,
|
||||
as quoted from MSDN:
|
||||
|
@ -104,7 +103,7 @@ __Tasks of Internet Explorer:__
|
|||
![IE](http://i.msdn.microsoft.com/dynimg/IC420539.png)
|
||||
|
||||
Unlike the dock menu in OS X which is a real menu, user tasks in Windows work
|
||||
like application shortcuts that when user clicks a task, a program would be
|
||||
like application shortcuts such that when user clicks a task, a program will be
|
||||
executed with specified arguments.
|
||||
|
||||
To set user tasks for your application, you can use
|
||||
|
@ -124,7 +123,7 @@ app.setUserTasks([
|
|||
]);
|
||||
```
|
||||
|
||||
To clean your tasks list, just call `app.setUserTasks` with empty array:
|
||||
To clean your tasks list, just call `app.setUserTasks` with an empty array:
|
||||
|
||||
```javascript
|
||||
app.setUserTasks([]);
|
||||
|
@ -136,9 +135,9 @@ uninstalled.
|
|||
|
||||
## Thumbnail Toolbars
|
||||
|
||||
On Windows, you can add a thumbnail toolbar with specified buttons in a taskbar
|
||||
layout of an application window. It provides users a way to access to a particualr
|
||||
window's command without restoring or activating the window.
|
||||
On Windows you can add a thumbnail toolbar with specified buttons in a taskbar
|
||||
layout of an application window. It provides users a way to access to a
|
||||
particular window's command without restoring or activating the window.
|
||||
|
||||
From MSDN, it's illustrated:
|
||||
|
||||
|
@ -187,18 +186,18 @@ with an empty array:
|
|||
win.setThumbarButtons([]);
|
||||
```
|
||||
|
||||
## Unity launcher shortcuts (Linux)
|
||||
## Unity Launcher Shortcuts (Linux)
|
||||
|
||||
In Unity, you can add custom entries to its launcher via modifying `.desktop`
|
||||
file, see [Adding shortcuts to a launcher][unity-launcher].
|
||||
In Unity, you can add custom entries to its launcher via modifying the `.desktop`
|
||||
file, see [Adding Shortcuts to a Launcher][unity-launcher].
|
||||
|
||||
__Launcher shortcuts of Audacious:__
|
||||
|
||||
![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png)
|
||||
|
||||
## Progress bar in taskbar (Windows & Unity)
|
||||
## Progress Bar in Taskbar (Windows & Unity)
|
||||
|
||||
On Windows, a taskbar button can be used to display a progress bar. This enables
|
||||
On Windows a taskbar button can be used to display a progress bar. This enables
|
||||
a window to provide progress information to the user without the user having to
|
||||
switch to the window itself.
|
||||
|
||||
|
@ -221,10 +220,10 @@ var window = new BrowserWindow({...});
|
|||
window.setProgressBar(0.5);
|
||||
```
|
||||
|
||||
## Represented file of window (OS X)
|
||||
## Represented File of Window (OS X)
|
||||
|
||||
On OS X a window can set its represented file, so the file's icon can show in
|
||||
the title bar, and when users Command-Click or Control-Click on the tile a path
|
||||
the title bar and when users Command-Click or Control-Click on the tile a path
|
||||
popup will show.
|
||||
|
||||
You can also set the edited state of a window so that the file icon can indicate
|
||||
|
|
|
@ -1,52 +1,57 @@
|
|||
# DevTools extension
|
||||
# DevTools Extension
|
||||
|
||||
To make debugging easier, Electron has basic support for
|
||||
To make debugging easier, Electron has basic support for the
|
||||
[Chrome DevTools Extension][devtools-extension].
|
||||
|
||||
For most devtools extensions, you can simply download the source code and use
|
||||
the `BrowserWindow.addDevToolsExtension` API to load them, the loaded extensions
|
||||
For most DevTools extensions you can simply download the source code and use
|
||||
the `BrowserWindow.addDevToolsExtension` API to load them. The loaded extensions
|
||||
will be remembered so you don't need to call the API every time when creating
|
||||
a window.
|
||||
|
||||
For example to use the [React DevTools Extension](https://github.com/facebook/react-devtools), first you need to download its
|
||||
source code:
|
||||
For example, to use the [React DevTools Extension](https://github.com/facebook/react-devtools)
|
||||
, first you need to download its source code:
|
||||
|
||||
```bash
|
||||
$ cd /some-directory
|
||||
$ git clone --recursive https://github.com/facebook/react-devtools.git
|
||||
```
|
||||
|
||||
Then you can load the extension in Electron by opening devtools in any window,
|
||||
and then running the following code in the devtools console:
|
||||
Then you can load the extension in Electron by opening DevTools in any window,
|
||||
and running the following code in the DevTools console:
|
||||
|
||||
```javascript
|
||||
require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools');
|
||||
```
|
||||
|
||||
To unload the extension, you can call `BrowserWindow.removeDevToolsExtension`
|
||||
API with its name and it will not load the next time you open the devtools:
|
||||
To unload the extension, you can call the `BrowserWindow.removeDevToolsExtension`
|
||||
API with its name and it will not load the next time you open the DevTools:
|
||||
|
||||
```javascript
|
||||
require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools');
|
||||
```
|
||||
|
||||
## Format of devtools extension
|
||||
## Format of DevTools Extension
|
||||
|
||||
Ideally all devtools extension written for Chrome browser can be loaded by
|
||||
Electron, but they have to be in a plain directory, for those packaged `crx`
|
||||
extensions, there is no way for Electron to load them unless you find a way to
|
||||
extract them into a directory.
|
||||
Ideally all DevTools extensions written for the Chrome browser can be loaded by
|
||||
Electron, but they have to be in a plain directory. For those packaged with
|
||||
`crx` extensions, there is no way for Electron to load them unless you find a
|
||||
way to extract them into a directory.
|
||||
|
||||
## Background pages
|
||||
## Background Pages
|
||||
|
||||
Currently Electron doesn't support the background pages feature in chrome extensions,
|
||||
so for some devtools extensions that rely on this feature, they may not work in Electron.
|
||||
Currently Electron doesn't support the background pages feature in Chrome
|
||||
extensions, so some DevTools extensions that rely on this feature may
|
||||
not work in Electron.
|
||||
|
||||
## `chrome.*` APIs
|
||||
|
||||
Some chrome extensions use `chrome.*` APIs for some features, there has been some
|
||||
effort to implement those APIs in Electron, however not all are implemented.
|
||||
Some Chrome extensions may use `chrome.*` APIs for features and while there has
|
||||
been some effort to implement those APIs in Electron, not all have been
|
||||
implemented.
|
||||
|
||||
Given that not all `chrome.*` APIs are implemented if the devtools extension is using APIs other than `chrome.devtools.*`, the extension is very likely not to work. You can report failing extensions in the issue tracker so that we can add support for those APIs.
|
||||
Given that not all `chrome.*` APIs are implemented if the DevTools extension is
|
||||
using APIs other than `chrome.devtools.*`, the extension is very likely not to
|
||||
work. You can report failing extensions in the issue tracker so that we can add
|
||||
support for those APIs.
|
||||
|
||||
[devtools-extension]: https://developer.chrome.com/extensions/devtools
|
||||
|
|
|
@ -36,9 +36,9 @@ _online-status.html_
|
|||
</html>
|
||||
```
|
||||
|
||||
There may be instances where one wants to respond to these events in the
|
||||
main process as well. The main process however does not have a
|
||||
`navigator` object and thus cannot detect these events directly. Using
|
||||
There may be instances where you want to respond to these events in the
|
||||
main process as well. The main process however does not have a
|
||||
`navigator` object and thus cannot detect these events directly. Using
|
||||
Electron's inter-process communication utilities, the events can be forwarded
|
||||
to the main process and handled as needed, as shown in the following example.
|
||||
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
# Quick start
|
||||
# Quick Start
|
||||
|
||||
## Introduction
|
||||
Electron enables you to create desktop applications with pure JavaScript by
|
||||
providing a runtime with rich native (operating system) APIs. You could see it
|
||||
as a variant of the io.js runtime that is focused on desktop applications
|
||||
instead of web servers.
|
||||
|
||||
Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native APIs. You could see it as a variant of the io.js runtime which is focused on desktop applications instead of web servers.
|
||||
This doesn't mean Electron is a JavaScript binding to graphical user interface
|
||||
(GUI) libraries. Instead, Electron uses web pages as its GUI, so you could also
|
||||
see it as a minimal Chromium browser, controlled by JavaScript.
|
||||
|
||||
This doesn't mean Electron is a JavaScript binding to GUI libraries. Instead,
|
||||
Electron uses web pages as its GUI, so you could also see it as a minimal
|
||||
Chromium browser, controlled by JavaScript.
|
||||
|
||||
### Main process
|
||||
### Main Process
|
||||
|
||||
In Electron, the process that runs `package.json`'s `main` script is called
|
||||
__the main process__. The script that runs in the main process can display a GUI by
|
||||
creating web pages.
|
||||
__the main process__. The script that runs in the main process can display a GUI
|
||||
by creating web pages.
|
||||
|
||||
### Renderer process
|
||||
### Renderer Process
|
||||
|
||||
Since Electron uses Chromium for displaying web pages, Chromium's
|
||||
multi-process architecture is also used. Each web page in Electron runs in
|
||||
|
@ -24,28 +25,30 @@ In normal browsers, web pages usually run in a sandboxed environment and are not
|
|||
allowed access to native resources. Electron users, however, have the power to use
|
||||
io.js APIs in web pages allowing lower level operating system interactions.
|
||||
|
||||
### Differences between main process and renderer process
|
||||
### Differences Between Main Process and Renderer Process
|
||||
|
||||
The main process creates web pages by creating `BrowserWindow` instances. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process
|
||||
The main process creates web pages by creating `BrowserWindow` instances. Each
|
||||
`BrowserWindow` instance runs the web page in its own renderer process. When a
|
||||
`BrowserWindow` instance is destroyed, the corresponding renderer process
|
||||
is also terminated.
|
||||
|
||||
The main process manages all web pages and their corresponding renderer
|
||||
processes. Each renderer process is isolated and only cares
|
||||
about the web page running in it.
|
||||
|
||||
In web pages, it is not allowed to call native GUI related APIs because managing
|
||||
native GUI resources in web pages is very dangerous and it is easy to leak resources.
|
||||
If you want to perform GUI operations in a web page, the renderer process of the web
|
||||
page must communicate with the main process to request the main process perform those
|
||||
operations.
|
||||
In web pages, calling native GUI related APIs is not allowed because managing
|
||||
native GUI resources in web pages is very dangerous and it is easy to leak
|
||||
resources. If you want to perform GUI operations in a web page, the renderer
|
||||
process of the web page must communicate with the main process to request that
|
||||
the main process perform those operations.
|
||||
|
||||
In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for
|
||||
communication between main process and renderer process. And there is also a
|
||||
communication between the main process and renderer process. There is also a
|
||||
[remote](../api/remote.md) module for RPC style communication.
|
||||
|
||||
## Write your first Electron app
|
||||
## Write your First Electron App
|
||||
|
||||
Generally, an Electron app would be structured like this:
|
||||
Generally, an Electron app is structured like this:
|
||||
|
||||
```text
|
||||
your-app/
|
||||
|
@ -56,7 +59,7 @@ your-app/
|
|||
|
||||
The format of `package.json` is exactly the same as that of Node's modules, and
|
||||
the script specified by the `main` field is the startup script of your app,
|
||||
which will run on the main process. An example of your `package.json` might look
|
||||
which will run the main process. An example of your `package.json` might look
|
||||
like this:
|
||||
|
||||
```json
|
||||
|
@ -81,7 +84,7 @@ var BrowserWindow = require('browser-window'); // Module to create native brows
|
|||
require('crash-reporter').start();
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is GCed.
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
var mainWindow = null;
|
||||
|
||||
// Quit when all windows are closed.
|
||||
|
@ -102,7 +105,7 @@ app.on('ready', function() {
|
|||
// and load the index.html of the app.
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
|
||||
// Open the devtools.
|
||||
// Open the DevTools.
|
||||
mainWindow.openDevTools();
|
||||
|
||||
// Emitted when the window is closed.
|
||||
|
@ -138,6 +141,7 @@ you'll probably want to try running your app locally to test it and make sure it
|
|||
working as expected.
|
||||
|
||||
### electron-prebuilt
|
||||
|
||||
If you've installed `electron-prebuilt` globally with `npm`, then you need only
|
||||
run the following in your app's source directory:
|
||||
|
||||
|
@ -152,6 +156,7 @@ If you've installed it locally, then run:
|
|||
```
|
||||
|
||||
### Manually Downloaded Electron Binary
|
||||
|
||||
If you downloaded Electron manually, you can also just use the included
|
||||
binary to execute your app directly.
|
||||
|
||||
|
@ -177,6 +182,7 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/
|
|||
it from [here](https://github.com/atom/electron/releases).
|
||||
|
||||
### Run as a distribution
|
||||
|
||||
After you're done writing your app, you can create a distribution by
|
||||
following the [Application distribution](./application-distribution.md) guide
|
||||
following the [Application Distribution](./application-distribution.md) guide
|
||||
and then executing the packaged app.
|
||||
|
|
|
@ -1,37 +1,40 @@
|
|||
# Using native Node modules
|
||||
# Using Native Node Modules
|
||||
|
||||
The native Node modules are supported by Electron, but since Electron is
|
||||
using a different V8 version from official Node, you have to manually specify
|
||||
the location of Electron's headers when building native modules.
|
||||
|
||||
## Native Node module compatibility
|
||||
## Native Node Module Compatibility
|
||||
|
||||
Since Node v0.11.x there were vital changes in the V8 API. So generally all
|
||||
native modules written for Node v0.10.x wouldn't work for newer Node or io.js versions. And
|
||||
because Electron internally uses __io.js v3.1.0__, it carries with the same
|
||||
problem.
|
||||
native modules written for Node v0.10.x won't work for newer Node or io.js
|
||||
versions. And because Electron internally uses __io.js v3.1.0__, it has the
|
||||
same problem.
|
||||
|
||||
To solve this, you should use modules that support Node v0.11.x or later,
|
||||
[many modules](https://www.npmjs.org/browse/depended/nan) do support both now.
|
||||
For old modules that only support Node v0.10.x, you should use the
|
||||
[nan](https://github.com/rvagg/nan) module to port it to v0.11.x or later versions of Node or io.js.
|
||||
[nan](https://github.com/rvagg/nan) module to port it to v0.11.x or later
|
||||
versions of Node or io.js.
|
||||
|
||||
## How to install native modules
|
||||
## How to Install Native Modules
|
||||
|
||||
Three ways to install native modules:
|
||||
|
||||
### The Easy Way
|
||||
|
||||
The most straightforward way to rebuild native modules is via the
|
||||
[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) package,
|
||||
The most straightforward way to rebuild native modules is via the
|
||||
[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) package,
|
||||
which handles the manual steps of downloading headers and building native modules:
|
||||
|
||||
```sh
|
||||
npm install --save-dev electron-rebuild
|
||||
|
||||
# Every time you run npm install, run this too
|
||||
# Every time you run npm install, run this
|
||||
./node_modules/.bin/electron-rebuild
|
||||
```
|
||||
|
||||
### The node-gyp way
|
||||
### The node-gyp Way
|
||||
|
||||
To build Node modules with headers of Electron, you need to tell `node-gyp`
|
||||
where to download headers and which version to use:
|
||||
|
@ -46,9 +49,9 @@ The `HOME=~/.electron-gyp` changes where to find development headers. The
|
|||
where to download the headers. The `--arch=x64` says the module is built for
|
||||
64bit system.
|
||||
|
||||
### The npm way
|
||||
### The npm Way
|
||||
|
||||
You can also use `npm` to install modules, the steps are exactly the same with
|
||||
You can also use `npm` to install modules. The steps are exactly the same with
|
||||
Node modules, except that you need to setup some environment variables:
|
||||
|
||||
```bash
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
# Using Pepper Flash Plugin
|
||||
|
||||
Pepper flash plugin is now supported. To use pepper flash plugin in Electron, you should manually specify the location of pepper flash plugin and then enable it in your application.
|
||||
Electron now supports the Pepper Flash plugin. To use the Pepper Flash plugin in
|
||||
Electron, you should manually specify the location of the Pepper Flash plugin
|
||||
and then enable it in your application.
|
||||
|
||||
## Prepare a copy of flash plugin
|
||||
## Prepare a Copy of Flash Plugin
|
||||
|
||||
On OS X and Linux, the detail of pepper flash plugin can be found by navigating `chrome://plugins` in Chrome browser. Its location and version are useful for electron's pepper flash support. You can also copy it to anywhere else.
|
||||
On OS X and Linux, the details of the Pepper Flash plugin can be found by
|
||||
navigating to `chrome://plugins` in the Chrome browser. Its location and version
|
||||
are useful for Electron's Pepper Flash support. You can also copy it to another
|
||||
location.
|
||||
|
||||
## Add Electron switch
|
||||
## Add Electron Switch
|
||||
|
||||
You can directly add `--ppapi-flash-path` and `ppapi-flash-version` to electron commandline or by `app.commandLine.appendSwitch` method before app ready event. Also, add the `plugins` switch of `browser-window`. For example,
|
||||
You can directly add `--ppapi-flash-path` and `ppapi-flash-version` to the
|
||||
Electron command line or by using the `app.commandLine.appendSwitch` method
|
||||
before the app ready event. Also, add the `plugins` switch of `browser-window`.
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
|
@ -50,8 +58,10 @@ app.on('ready', function() {
|
|||
});
|
||||
```
|
||||
|
||||
## Enable flash plugin in a `<webview>` tag
|
||||
## Enable Flash Plugin in a `<webview>` Tag
|
||||
|
||||
Add `plugins` attribute to `<webview>` tag.
|
||||
|
||||
```html
|
||||
<webview src="http://www.adobe.com/software/flash/about/" plugins></webview>
|
||||
```
|
||||
|
|
|
@ -8,21 +8,15 @@ 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` with Electron you have to tell it where to
|
||||
find Electron and make it think Electron is the Chrome browser.
|
||||
|
||||
## Setting up with WebDriverJs
|
||||
|
||||
[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provided
|
||||
[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provides
|
||||
a Node package for testing with web driver, we will use it as an example.
|
||||
|
||||
### 1. Start chrome driver
|
||||
### 1. Start ChromeDriver
|
||||
|
||||
First you need to download the `chromedriver` binary, and run it:
|
||||
|
||||
|
@ -40,7 +34,7 @@ Remember the port number `9515`, which will be used later
|
|||
$ npm install selenium-webdriver
|
||||
```
|
||||
|
||||
### 3. Connect to chrome driver
|
||||
### 3. Connect to ChromeDriver
|
||||
|
||||
The usage of `selenium-webdriver` with Electron is basically the same with
|
||||
upstream, except that you have to manually specify how to connect chrome driver
|
||||
|
@ -72,9 +66,10 @@ driver.quit();
|
|||
|
||||
## Setting up with WebdriverIO
|
||||
|
||||
[WebdriverIO](http://webdriver.io/) provides a Node package for testing with web driver.
|
||||
[WebdriverIO](http://webdriver.io/) provides a Node package for testing with web
|
||||
driver.
|
||||
|
||||
### 1. Start chrome driver
|
||||
### 1. Start ChromeDriver
|
||||
|
||||
First you need to download the `chromedriver` binary, and run it:
|
||||
|
||||
|
@ -93,10 +88,11 @@ $ npm install webdriverio
|
|||
```
|
||||
|
||||
### 3. Connect to chrome driver
|
||||
|
||||
```javascript
|
||||
var webdriverio = require('webdriverio');
|
||||
var options = {
|
||||
host: "localhost", // Use localhost as chrome driver server
|
||||
host: "localhost", // Use localhost as chrome driver server
|
||||
port: 9515, // "9515" is the port opened by chrome driver.
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
|
@ -119,8 +115,8 @@ client
|
|||
|
||||
## Workflow
|
||||
|
||||
To test your application without rebuilding Electron, simply [place](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) your app source into Electron's resource directory.
|
||||
To test your application without rebuilding Electron, simply
|
||||
[place](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md)
|
||||
your app source into Electron's resource directory.
|
||||
|
||||
[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/
|
||||
|
||||
|
||||
|
|
|
@ -71,14 +71,15 @@ def main():
|
|||
run_script('upload.py')
|
||||
else:
|
||||
run_script('build.py', ['-c', 'D'])
|
||||
if PLATFORM != 'win32' and target_arch == 'x64':
|
||||
if (is_travis or PLATFORM == 'linux') and target_arch == 'x64':
|
||||
run_script('test.py', ['--ci'])
|
||||
|
||||
run_script('clean.py')
|
||||
|
||||
|
||||
def run_script(script, args=[]):
|
||||
print 'Running', script
|
||||
sys.stderr.write('\nRunning ' + script +'\n')
|
||||
sys.stderr.flush()
|
||||
script = os.path.join(SOURCE_ROOT, 'script', script)
|
||||
subprocess.check_call([sys.executable, script] + args)
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -15,11 +15,11 @@ ipc.on('message', function(event, arg) {
|
|||
});
|
||||
|
||||
ipc.on('console.log', function(event, args) {
|
||||
console.log.apply(console, args);
|
||||
console.error.apply(console, args);
|
||||
});
|
||||
|
||||
ipc.on('console.error', function(event, args) {
|
||||
console.log.apply(console, args);
|
||||
console.error.apply(console, args);
|
||||
});
|
||||
|
||||
ipc.on('process.exit', function(event, code) {
|
||||
|
|
|
@ -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