Merge remote-tracking branch 'refs/remotes/atom/master'

This commit is contained in:
Plusb Preco 2015-12-03 00:21:28 +09:00
Родитель 9fa6527460 4252c17db0
Коммит cc841242b5
55 изменённых файлов: 1164 добавлений и 181 удалений

Просмотреть файл

@ -57,6 +57,7 @@ possible with your report. If you can, please include:
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
* Limit the first line to 72 characters or less
* Reference issues and pull requests liberally
* When only changing documentation, include `[ci skip]` in the commit description
* Consider starting the commit message with an applicable emoji:
* :art: `:art:` when improving the format/structure of the code
* :racehorse: `:racehorse:` when improving performance

Просмотреть файл

@ -52,6 +52,7 @@ contains documents describing how to build and contribute to Electron.
- [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)
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
## Quick Start

Просмотреть файл

@ -41,7 +41,7 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
array.push_back("scaleFactor");
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION)
array.push_back("rotaion");
array.push_back("rotation");
return array;
}

Просмотреть файл

@ -137,9 +137,11 @@ void Tray::DisplayBalloon(mate::Arguments* args,
}
void Tray::PopUpContextMenu(mate::Arguments* args) {
mate::Handle<Menu> menu;
args->GetNext(&menu);
gfx::Point pos;
args->GetNext(&pos);
tray_icon_->PopUpContextMenu(pos);
tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
}
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {

Просмотреть файл

@ -460,14 +460,13 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
Emit("did-finish-load");
}
// this error occurs when host could not be found
void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
const GURL& url,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) {
Emit("did-fail-load", error_code, error_description, validated_url);
Emit("did-fail-provisional-load", error_code, error_description, url);
}
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
@ -520,9 +519,10 @@ void WebContents::DidNavigateMainFrame(
void WebContents::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
// Back/Forward navigation may have pruned entries.
if (entry)
Emit("page-title-set", entry->GetTitle(), explicit_set);
Emit("-page-title-updated", entry->GetTitle(), explicit_set);
else
Emit("-page-title-updated", "", explicit_set);
}
void WebContents::DidUpdateFaviconURL(

Просмотреть файл

@ -161,11 +161,6 @@ Window::~Window() {
Destroy();
}
void Window::OnPageTitleUpdated(bool* prevent_default,
const std::string& title) {
*prevent_default = Emit("page-title-updated", title);
}
void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}

Просмотреть файл

@ -54,8 +54,6 @@ class Window : public mate::TrackableObject<Window>,
virtual ~Window();
// NativeWindowObserver:
void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) override;
void WillCloseWindow(bool* prevent_default) override;
void OnWindowClosed() override;
void OnWindowBlur() override;

Просмотреть файл

@ -65,7 +65,6 @@ wrapDownloadItem = (downloadItem) ->
deprecate.property downloadItem, 'url', 'getURL'
deprecate.property downloadItem, 'filename', 'getFilename'
deprecate.property downloadItem, 'mimeType', 'getMimeType'
deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture'
deprecate.rename downloadItem, 'getUrl', 'getURL'
downloadItemBindings._setWrapDownloadItem wrapDownloadItem

Просмотреть файл

@ -31,6 +31,11 @@ BrowserWindow::_init = ->
@webContents.on 'crashed', =>
@emit 'crashed'
# Change window title to page title.
@webContents.on 'page-title-updated', (event, title, explicitSet) =>
@emit 'page-title-updated', event, title
@setTitle title unless event.defaultPrevented
# Sometimes the webContents doesn't get focus when window is shown, so we have
# to force focusing on webContents in this case. The safest way is to focus it
# when we first start to load URL, if we do it earlier it won't have effect,

Просмотреть файл

@ -70,9 +70,21 @@ wrapWebContents = (webContents) ->
menu = Menu.buildFromTemplate params.menu
menu.popup params.x, params.y
# This error occurs when host could not be found.
webContents.on 'did-fail-provisional-load', (args...) ->
# Calling loadURL during this event might cause crash, so delay the event
# until next tick.
setImmediate => @emit 'did-fail-load', args...
# Delays the page-title-updated event to next tick.
webContents.on '-page-title-updated', (args...) ->
setImmediate => @emit 'page-title-updated', args...
# Deprecated.
deprecate.rename webContents, 'loadUrl', 'loadURL'
deprecate.rename webContents, 'getUrl', 'getURL'
deprecate.event webContents, 'page-title-set', 'page-title-updated', (args...) ->
@emit 'page-title-set', args...
webContents.printToPDF = (options, callback) ->
printingSetting =

Просмотреть файл

@ -114,7 +114,8 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
1000));
brightray::BrowserMainParts::PreMainMessageLoopRun();
BridgeTaskRunner::MessageLoopIsReady();
bridge_task_runner_->MessageLoopIsReady();
bridge_task_runner_ = nullptr;
#if defined(USE_X11)
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());

Просмотреть файл

@ -8,11 +8,6 @@
namespace atom {
// static
std::vector<BridgeTaskRunner::TaskPair> BridgeTaskRunner::tasks_;
std::vector<BridgeTaskRunner::TaskPair> BridgeTaskRunner::non_nestable_tasks_;
// static
void BridgeTaskRunner::MessageLoopIsReady() {
auto message_loop = base::MessageLoop::current();
CHECK(message_loop);

Просмотреть файл

@ -20,7 +20,7 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
~BridgeTaskRunner() override {}
// Called when message loop is ready.
static void MessageLoopIsReady();
void MessageLoopIsReady();
// base::SingleThreadTaskRunner:
bool PostDelayedTask(const tracked_objects::Location& from_here,
@ -35,8 +35,8 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
private:
using TaskPair = base::Tuple<
tracked_objects::Location, base::Closure, base::TimeDelta>;
static std::vector<TaskPair> tasks_;
static std::vector<TaskPair> non_nestable_tasks_;
std::vector<TaskPair> tasks_;
std::vector<TaskPair> non_nestable_tasks_;
DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner);
};

Просмотреть файл

@ -19,7 +19,7 @@ supportedWebViewEvents = [
'gpu-crashed'
'plugin-crashed'
'destroyed'
'page-title-set'
'page-title-updated'
'page-favicon-updated'
'enter-html-full-screen'
'leave-html-full-screen'

Просмотреть файл

@ -505,17 +505,6 @@ void NativeWindow::BeforeUnloadDialogCancelled() {
window_unresposive_closure_.Cancel();
}
void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
bool prevent_default = false;
std::string text = entry ? base::UTF16ToUTF8(entry->GetTitle()) : "";
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default && !is_closed_)
SetTitle(text);
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)

Просмотреть файл

@ -262,7 +262,6 @@ class NativeWindow : public base::SupportsUserData,
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override;
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
bool OnMessageReceived(const IPC::Message& message) override;
private:

Просмотреть файл

@ -21,10 +21,6 @@ class NativeWindowObserver {
public:
virtual ~NativeWindowObserver() {}
// Called when the web page of the window has updated it's document title.
virtual void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) {}
// Called when the web page in window wants to create a popup window.
virtual void WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,

Просмотреть файл

@ -4,6 +4,10 @@
#include "atom/browser/net/url_request_async_asar_job.h"
#include <string>
#include "atom/common/atom_constants.h"
namespace atom {
URLRequestAsyncAsarJob::URLRequestAsyncAsarJob(
@ -34,4 +38,12 @@ void URLRequestAsyncAsarJob::StartAsync(scoped_ptr<base::Value> options) {
}
}
void URLRequestAsyncAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader);
info->headers = headers;
}
} // namespace atom

Просмотреть файл

@ -18,6 +18,9 @@ class URLRequestAsyncAsarJob : public JsAsker<asar::URLRequestAsarJob> {
// JsAsker:
void StartAsync(scoped_ptr<base::Value> options) override;
// URLRequestJob:
void GetResponseInfo(net::HttpResponseInfo* info) override;
private:
DISALLOW_COPY_AND_ASSIGN(URLRequestAsyncAsarJob);
};

Просмотреть файл

@ -6,6 +6,7 @@
#include <string>
#include "atom/common/atom_constants.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/net_errors.h"
@ -50,6 +51,8 @@ void URLRequestBufferJob::GetResponseInfo(net::HttpResponseInfo* info) {
status.append("\0\0", 2);
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader);
if (!mime_type_.empty()) {
std::string content_type_header(net::HttpRequestHeaders::kContentType);
content_type_header.append(": ");

Просмотреть файл

@ -6,6 +6,7 @@
#include <string>
#include "atom/common/atom_constants.h"
#include "net/base/net_errors.h"
namespace atom {
@ -32,6 +33,8 @@ void URLRequestStringJob::GetResponseInfo(net::HttpResponseInfo* info) {
std::string status("HTTP/1.1 200 OK");
net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
headers->AddHeader(kCORSHeader);
if (!mime_type_.empty()) {
std::string content_type_header(net::HttpRequestHeaders::kContentType);
content_type_header.append(": ");

Просмотреть файл

@ -26,7 +26,8 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon,
const base::string16& contents) {
}
void TrayIcon::PopUpContextMenu(const gfx::Point& pos) {
void TrayIcon::PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) {
}
void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) {

Просмотреть файл

@ -47,7 +47,9 @@ class TrayIcon {
const base::string16& title,
const base::string16& contents);
virtual void PopUpContextMenu(const gfx::Point& pos);
// Popups the menu.
virtual void PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model);
// Set the context menu for this icon.
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0;

Просмотреть файл

@ -29,7 +29,8 @@ class TrayIconCocoa : public TrayIcon,
void SetToolTip(const std::string& tool_tip) override;
void SetTitle(const std::string& title) override;
void SetHighlightMode(bool highlight) override;
void PopUpContextMenu(const gfx::Point& pos) override;
void PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) override;
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
protected:

Просмотреть файл

@ -23,6 +23,7 @@ const CGFloat kVerticalTitleMargin = 2;
atom::TrayIconCocoa* trayIcon_; // weak
AtomMenuController* menuController_; // weak
BOOL isHighlightEnable_;
BOOL forceHighlight_;
BOOL inMouseEventSequence_;
base::scoped_nsobject<NSImage> image_;
base::scoped_nsobject<NSImage> alternateImage_;
@ -39,6 +40,8 @@ const CGFloat kVerticalTitleMargin = 2;
image_.reset([image copy]);
trayIcon_ = icon;
isHighlightEnable_ = YES;
forceHighlight_ = NO;
inMouseEventSequence_ = NO;
if ((self = [super initWithFrame: CGRectZero])) {
// Setup the image view.
@ -238,7 +241,19 @@ const CGFloat kVerticalTitleMargin = 2;
[self setNeedsDisplay:YES];
}
- (void)popUpContextMenu {
- (void)popUpContextMenu:(ui::SimpleMenuModel*)menu_model {
// Show a custom menu.
if (menu_model) {
base::scoped_nsobject<AtomMenuController> menuController(
[[AtomMenuController alloc] initWithModel:menu_model]);
forceHighlight_ = YES; // Should highlight when showing menu.
[self setNeedsDisplay:YES];
[statusItem_ popUpStatusItemMenu:[menuController menu]];
forceHighlight_ = NO;
[self setNeedsDisplay:YES];
return;
}
if (menuController_ && ![menuController_ isMenuOpen]) {
// Redraw the dray icon to show highlight if it is enabled.
[self setNeedsDisplay:YES];
@ -288,6 +303,8 @@ const CGFloat kVerticalTitleMargin = 2;
}
- (BOOL)shouldHighlight {
if (isHighlightEnable_ && forceHighlight_)
return true;
BOOL isMenuOpen = menuController_ && [menuController_ isMenuOpen];
return isHighlightEnable_ && (inMouseEventSequence_ || isMenuOpen);
}
@ -338,8 +355,9 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) {
[status_item_view_ setHighlight:highlight];
}
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos) {
[status_item_view_ popUpContextMenu];
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) {
[status_item_view_ popUpContextMenu:menu_model];
}
void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) {

Просмотреть файл

@ -13,6 +13,7 @@
#include "ui/gfx/image/image.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
namespace atom {
@ -45,8 +46,7 @@ NotifyIcon::~NotifyIcon() {
Shell_NotifyIcon(NIM_DELETE, &icon_data);
}
void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
int modifiers,
void NotifyIcon::HandleClickEvent(int modifiers,
bool left_mouse_click,
bool double_button_click) {
NOTIFYICONIDENTIFIER icon_id;
@ -66,7 +66,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
return;
} else if (!double_button_click) { // single right click
if (menu_model_)
PopUpContextMenu(cursor_pos);
PopUpContextMenu(gfx::Point(), menu_model_);
else
NotifyRightClicked(gfx::Rect(rect), modifiers);
}
@ -142,24 +142,26 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
LOG(WARNING) << "Unable to create status tray balloon.";
}
void NotifyIcon::PopUpContextMenu(const gfx::Point& pos) {
void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) {
// Returns if context menu isn't set.
if (!menu_model_)
if (!menu_model)
return;
// Set our window as the foreground window, so the context menu closes when
// we click away from it.
if (!SetForegroundWindow(window_))
return;
// Show menu at mouse's position by default.
gfx::Rect rect(pos, gfx::Size());
if (pos.IsOrigin())
rect.set_origin(gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
views::MenuRunner menu_runner(
menu_model_,
menu_model,
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
ignore_result(menu_runner.RunMenuAt(
NULL,
NULL,
gfx::Rect(pos, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT,
ui::MENU_SOURCE_MOUSE));
NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE));
}
void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {

Просмотреть файл

@ -33,8 +33,7 @@ class NotifyIcon : public TrayIcon {
// Handles a click event from the user - if |left_button_click| is true and
// there is a registered observer, passes the click event to the observer,
// otherwise displays the context menu if there is one.
void HandleClickEvent(const gfx::Point& cursor_pos,
int modifiers,
void HandleClickEvent(int modifiers,
bool left_button_click,
bool double_button_click);
@ -52,7 +51,8 @@ class NotifyIcon : public TrayIcon {
void DisplayBalloon(const gfx::Image& icon,
const base::string16& title,
const base::string16& contents) override;
void PopUpContextMenu(const gfx::Point& pos) override;
void PopUpContextMenu(const gfx::Point& pos,
ui::SimpleMenuModel* menu_model) override;
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
private:

Просмотреть файл

@ -15,7 +15,6 @@
#include "base/win/win_util.h"
#include "base/win/wrapped_window_proc.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/win/hwnd_util.h"
namespace atom {
@ -172,10 +171,7 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd,
case WM_CONTEXTMENU:
// Walk our icons, find which one was clicked on, and invoke its
// HandleClickEvent() method.
gfx::Point cursor_pos(
gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
win_icon->HandleClickEvent(
cursor_pos,
GetKeyboardModifers(),
(lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK),
(lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK));

Просмотреть файл

@ -272,7 +272,8 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
}
scoped_ptr<ScopedTemporaryFile> temp_file(new ScopedTemporaryFile);
if (!temp_file->InitFromFile(&file_, info.offset, info.size))
base::FilePath::StringType ext = path.Extension();
if (!temp_file->InitFromFile(&file_, ext, info.offset, info.size))
return false;
#if defined(OS_POSIX)

Просмотреть файл

@ -28,20 +28,34 @@ ScopedTemporaryFile::~ScopedTemporaryFile() {
}
}
bool ScopedTemporaryFile::Init() {
bool ScopedTemporaryFile::Init(const base::FilePath::StringType& ext) {
if (!path_.empty())
return true;
base::ThreadRestrictions::ScopedAllowIO allow_io;
return base::CreateTemporaryFile(&path_);
if (!base::CreateTemporaryFile(&path_))
return false;
#if defined(OS_WIN)
// Keep the original extension.
if (!ext.empty()) {
base::FilePath new_path = path_.AddExtension(ext);
if (!base::Move(path_, new_path))
return false;
path_ = new_path;
}
#endif
return true;
}
bool ScopedTemporaryFile::InitFromFile(base::File* src,
const base::FilePath::StringType& ext,
uint64 offset, uint64 size) {
if (!src->IsValid())
return false;
if (!Init())
if (!Init(ext))
return false;
std::vector<char> buf(size);

Просмотреть файл

@ -22,11 +22,13 @@ class ScopedTemporaryFile {
ScopedTemporaryFile();
virtual ~ScopedTemporaryFile();
// Init an empty temporary file.
bool Init();
// Init an empty temporary file with a certain extension.
bool Init(const base::FilePath::StringType& ext);
// Init an temporary file and fill it with content of |path|.
bool InitFromFile(base::File* src, uint64 offset, uint64 size);
bool InitFromFile(base::File* src,
const base::FilePath::StringType& ext,
uint64 offset, uint64 size);
base::FilePath path() const { return path_; }

Просмотреть файл

@ -0,0 +1,11 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/atom_constants.h"
namespace atom {
const char* kCORSHeader = "Access-Control-Allow-Origin: *";
} // namespace atom

Просмотреть файл

@ -0,0 +1,15 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_ATOM_CONSTANTS_H_
#define ATOM_COMMON_ATOM_CONSTANTS_H_
namespace atom {
// Header to ignore CORS.
extern const char* kCORSHeader;
} // namespace atom
#endif // ATOM_COMMON_ATOM_CONSTANTS_H_

Просмотреть файл

@ -18,6 +18,7 @@ process.on 'exit', ->
# Separate asar package's path from full path.
splitPath = (p) ->
return [false] if process.noAsar # shortcut to disable asar.
return [false] if typeof p isnt 'string'
return [true, p, ''] if p.substr(-5) is '.asar'
p = path.normalize p

Просмотреть файл

@ -21,23 +21,27 @@ WEB_VIEW_EVENTS =
'gpu-crashed': []
'plugin-crashed': ['name', 'version']
'destroyed': []
'page-title-set': ['title', 'explicitSet']
'page-title-updated': ['title', 'explicitSet']
'page-favicon-updated': ['favicons']
'enter-html-full-screen': []
'leave-html-full-screen': []
dispatchEvent = (webView, event, args...) ->
throw new Error("Unknown event #{event}") unless WEB_VIEW_EVENTS[event]?
domEvent = new Event(event)
for f, i in WEB_VIEW_EVENTS[event]
DEPRECATED_EVENTS =
'page-title-updated': 'page-title-set'
dispatchEvent = (webView, eventName, eventKey, args...) ->
if DEPRECATED_EVENTS[eventName]?
dispatchEvent webView, DEPRECATED_EVENTS[eventName], eventKey, args...
domEvent = new Event(eventName)
for f, i in WEB_VIEW_EVENTS[eventKey]
domEvent[f] = args[i]
webView.dispatchEvent domEvent
webView.onLoadCommit domEvent if event == 'load-commit'
webView.onLoadCommit domEvent if eventName is 'load-commit'
module.exports =
registerEvents: (webView, viewInstanceId) ->
ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, domEvent, args...) ->
dispatchEvent webView, domEvent, args...
ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, eventName, args...) ->
dispatchEvent webView, eventName, eventName, args...
ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}", (event, channel, args...) ->
domEvent = new Event('ipc-message')

Просмотреть файл

@ -1,71 +1,82 @@
Por favor, certifique-se de que está utilizando a documentação que corresponde à sua versão do Electron.
O número da versão deve ser uma parte da URL da página. Se não for, você provavelmente está utilizando
a documentação de um branch de desenvolvimento que pode conter mudanças na API que não são compatíveis
com a sua versão do Electron. Se este for o caso, você pode mudar para uma versão diferente da
documentação na lista de [versões disponíveis](http://electron.atom.io/docs/) em atom.io,
ou se você estiver usando a interface do GitHub, abra o *dropdown* "Switch branches/tags" e
selecione a *tag* que corresponde à sua versão.
## Guias
* [Platformas Suportadas](../../tutorial/supported-platforms.md)
* [Distribuição de Aplicações](tutorial/application-distribution.md)
* [Empacotamento da aplicação](tutorial/application-packaging.md)
* [Usando módulos nativos](tutorial/using-native-node-modules.md)
* [Depuração do processo principal](tutorial/debugging-main-process.md)
* [Guia de Submissão da Mac App Store](../../tutorial/mac-app-store-submission-guide.md)
* [Empacotamento da Aplicação](tutorial/application-packaging.md)
* [Usando Módulos Nativos do Node](tutorial/using-native-node-modules.md)
* [Depuração do Processo Principal](tutorial/debugging-main-process.md)
* [Usando Selenium e WebDriver](../../docs/tutorial/using-selenium-and-webdriver.md)
* [Extensão DevTools](../../docs/tutorial/devtools-extension.md)
* [Usando o plugin papper flash](tutorial/using-pepper-flash-plugin.md)
* [Usando o Plugin Pepper Flash](tutorial/using-pepper-flash-plugin.md)
## Tutoriais
* [Introdução](tutorial/quick-start.md)
* [A integração com o ambiente de desenvolvimento](tutorial/desktop-environment-integration.md)
* [Evento de detecção on-line/off-line](tutorial/online-offline-events.md)
* [Integração com o Ambiente de Desenvolvimento](tutorial/desktop-environment-integration.md)
* [Evento de Detecção Online/Offline](tutorial/online-offline-events.md)
## API - Referencias
## API - Referências
* [Sinopse](../../docs/api/synopsis.md)
* [Processos](api/process.md)
* [Aceleradores (Teclas de Atalho)](api/accelerator.md)
* [Parâmetros CLI suportados (Chrome)](../../docs/api/chrome-command-line-switches.md)
* [Variáveis de Ambiente](../../docs/api/environment-variables.md)
DOM elementos personalizados:
### Elementos DOM Personalizados:
* [Objeto `File`](../../docs/api/file-object.md)
* [Tag `<webview>`](../../docs/api/web-view-tag.md)
* [Função `window.open`](../../docs/api/window-open.md)
Os principais módulos:
### Módulos para o Processo Principal:
* [app](../../docs/api/app.md)
* [auto-updater](../../docs/api/auto-updater.md)
* [browser-window](../../docs/api/browser-window.md)
* [content-tracing](../../docs/api/content-tracing.md)
* [app](api/app.md)
* [autoUpdater](api/auto-updater.md)
* [BrowserWindow](../../docs/api/browser-window.md)
* [contentTracing](../../docs/api/content-tracing.md)
* [dialog](../../docs/api/dialog.md)
* [global-shortcut](../../docs/api/global-shortcut.md)
* [ipc (main process)](../../docs/api/ipc-main-process.md)
* [menu](../../docs/api/menu.md)
* [menu-item](../../docs/api/menu-item.md)
* [power-monitor](../../docs/api/power-monitor.md)
* [power-save-blocker](../../docs/api/power-save-blocker.md)
* [globalShortcut](../../docs/api/global-shortcut.md)
* [ipcMain](../../docs/api/ipc-main-process.md)
* [Menu](../../docs/api/menu.md)
* [MenuItem](../../docs/api/menu-item.md)
* [powerMonitor](../../docs/api/power-monitor.md)
* [powerSaveBlocker](../../docs/api/power-save-blocker.md)
* [protocol](../../docs/api/protocol.md)
* [session](../../docs/api/session.md)
* [webContents](../../docs/api/web-contents.md)
* [tray](../../docs/api/tray.md)
* [Tray](../../docs/api/tray.md)
Módulos do renderizador (web page):
### Módulos para o Processo Renderizador:
* [ipc (renderer)](../../docs/api/ipc-renderer.md)
* [ipcRenderer](../../docs/api/ipc-renderer.md)
* [remote](../../docs/api/remote.md)
* [web-frame](../../docs/api/web-frame.md)
* [webFrame](../../docs/api/web-frame.md)
Módulos de ambos os processos:
### Módulos para ambos os processos:
* [clipboard](../../docs/api/clipboard.md)
* [crash-reporter](../../docs/api/crash-reporter.md)
* [native-image](../../docs/api/native-image.md)
* [crashReporter](../../docs/api/crash-reporter.md)
* [nativeImage](../../docs/api/native-image.md)
* [screen](../../docs/api/screen.md)
* [shell](api/shell.md)
## Desenvolvimento
* [Estilo de código](../../docs/development/coding-style.md)
* [Estrutura de diretórios padrão](../../docs/development/source-code-directory-structure.md)
* [Diferenças técnicas do NW.js (antigo node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md)
* [Visão geral do build](../../docs/development/build-system-overview.md)
* [Instrução de build (Mac)](../../docs/development/build-instructions-osx.md)
* [Instrução de build (Windows)](../../docs/development/build-instructions-windows.md)
* [Instrução de build (Linux)](../../docs/development/build-instructions-linux.md)
* [Configurando um symbol server no debugger](../../docs/development/setting-up-symbol-server.md)
* [Estilo de Código](development/coding-style.md)
* [Estrutura de Diretórios de Código Fonte](../../docs/development/source-code-directory-structure.md)
* [Diferenças Técnicas do NW.js (antigo node-webkit)](../../docs/development/atom-shell-vs-node-webkit.md)
* [Visão Geral do Build](../../docs/development/build-system-overview.md)
* [Instrução de Build (Mac)](../../docs/development/build-instructions-osx.md)
* [Instrução de Build (Windows)](../../docs/development/build-instructions-windows.md)
* [Instrução de Build (Linux)](../../docs/development/build-instructions-linux.md)
* [Configurando um Symbol Server no Debugger](../../docs/development/setting-up-symbol-server.md)

Просмотреть файл

@ -1,7 +1,7 @@
# Acelerador (teclas de atalhos)
Um acelerador é uma string que representa um atalho de tecla. Isso pode conter
multiplos modificadores e códigos chaves, combinado pelo caracter `+`.
Um acelerador é uma string que representa um atalho de tecla. Ele pode conter
múltiplos modificadores e códigos chaves, combinados pelo caractere `+`.
Exemplos:
@ -11,13 +11,13 @@ Exemplos:
## Aviso sobre plataformas
No Linux e no Windows a tecla `Command` não tem nenhum efeito,
então use `CommandOrControl` que representa a tecla `Command` existente no OSX e
então use `CommandOrControl` que representa a tecla `Command` existente no OS X e
`Control` no Linux e no Windows para definir aceleradores (atalhos).
A chave `Super` está mapeada para a tecla `Windows` para Windows e Linux,
e para a tecla `Cmd` para OSX.
e para a tecla `Cmd` para OS X.
## Modificadores disponiveis
## Modificadores disponíveis
* `Command` (ou `Cmd` abreviado)
* `Control` (ou `Ctrl` abreviado)
@ -26,21 +26,21 @@ e para a tecla `Cmd` para OSX.
* `Shift`
* `Super`
## Códigos chaves disponiveis
## Códigos chaves disponíveis
* `0` to `9`
* `A` to `Z`
* `F1` to `F24`
* Punctuations like `~`, `!`, `@`, `#`, `$`, etc.
* `0` até `9`
* `A` até `Z`
* `F1` até `F24`
* Pontuações como `~`, `!`, `@`, `#`, `$`, etc.
* `Plus`
* `Space`
* `Backspace`
* `Delete`
* `Insert`
* `Return` (or `Enter` as alias)
* `Up`, `Down`, `Left` and `Right`
* `Home` and `End`
* `PageUp` and `PageDown`
* `Escape` (or `Esc` for short)
* `VolumeUp`, `VolumeDown` and `VolumeMute`
* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause`
* `Return` (ou `Enter` como pseudônimo)
* `Up`, `Down`, `Left` e `Right`
* `Home` e `End`
* `PageUp` e `PageDown`
* `Escape` (ou `Esc` abreviado)
* `VolumeUp`, `VolumeDown` e `VolumeMute`
* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` e `MediaPlayPause`

Просмотреть файл

@ -0,0 +1,452 @@
# app
O módulo `app` é responsável por controlar o ciclo de vida do aplicativo.
O exemplo a seguir mostra como fechar o aplicativo quando a última janela é fechada:
```javascript
const app = require('electron').app;
app.on('window-all-closed', function() {
app.quit();
});
```
## Eventos
O objeto `app` emite os seguintes eventos:
### Evento: 'will-finish-launching'
Emitido quando o aplicativo finaliza a inicialização básica. No Windows e no Linux,
o evento `will-finish-launching` é o mesmo que o evento `ready`; No OS X,
esse evento representa a notificação `applicationWillFinishLaunching` do `NSApplication`.
Normalmente aqui seriam criados *listeners* para os eventos `open-file` e `open-url`, e inicializar o *crash reporter* e atualizador automático.
Na maioria dos casos, você deve fazer tudo no manipulador de eventos do `ready`.
### Evento: 'ready'
Emitido quando o Electron finaliza a inicialização.
### Evento: 'window-all-closed'
Emitido quando todas as janelas forem fechadas.
Este evento só é emitido quando o aplicativo não for fechar. Se o
usuário pressionou`Cmd + Q`, ou o desenvolvedor chamou `app.quit()`,
o Electron tentará primeiro fechar todas as janelas e então emitir o
evento `will-quit`, e neste caso o evento `window-all-closed` não
seria emitido.
### Evento: 'before-quit'
Retorna:
* `event` Event
Emitido antes que o aplicativo comece a fechar suas janelas.
Chamar `event.preventDefault()` irá impedir o comportamento padrão,
que é terminar o aplicativo.
### Evento: 'will-quit'
Retorna:
* `event` Event
Emitido quando todas as janelas foram fechadas e o aplicativo irá finalizar.
Chamar `event.preventDefault()` irá impedir o comportamento padrão,
que é terminar o aplicativo.
Veja a descrição do evento `window-all-closed` para as diferenças entre o
evento `will-quit` e `window-all-closed`.
### Evento: 'quit'
Emitido quando o aplicativo está finalizando.
### Evento: 'open-file' _OS X_
Retorna:
* `event` Event
* `path` String
Emitido quando o usuário deseja abrir um arquivo com o aplicativo. O evento
`open-file` normalmente é emitido quando o aplicativo já está aberto e o S.O.
quer reutilizar o aplicativo para abrir o arquivo. `open-file` também é emitido
quando um arquivo é jogado no *dock* e o aplicativo ainda não está rodando.
Certifique-se de utilizar um *listener* para o evento `open-file` cedo na
inicialização do seu aplicativo para cuidar deste caso (antes mesmo do evento
`ready` ser emitido).
Você deve chamar `event.preventDefault()` se quiser cuidar deste caso.
No Windows, você deve fazer o *parse* do `process.argv` para pegar o
endereço do arquivo.
### Evento: 'open-url' _OS X_
Retorna:
* `event` Event
* `url` String
Emitido quando o usuário deseja abrir uma URL com o aplicativo. O esquema deve
ser registrado para ser aberto pelo seu aplicativo.
Você deve chamar `event.preventDefault()` se quiser cuidar deste caso.
### Evento: 'activate' _OS X_
Retorna:
* `event` Event
* `hasVisibleWindows` Boolean
Emitido quando o aplicativo é ativado, que normalmente acontece quando o ícone
do aplicativo no *dock* é clicado.
### Evento: 'browser-window-blur'
Retorna:
* `event` Event
* `window` BrowserWindow
Emitido quando uma [browserWindow](../../../docs/api/browser-window.md) fica embaçada.
### Evento: 'browser-window-focus'
Retorna:
* `event` Event
* `window` BrowserWindow
Emitido quando uma [browserWindow](../../../docs/api/browser-window.md) é focada.
### Evento: 'browser-window-created'
Retorna:
* `event` Event
* `window` BrowserWindow
Emitido quando uma nova [browserWindow](../../../docs/api/browser-window.md) é criada.
### Evento: 'certificate-error'
Returns:
* `event` Event
* `webContents` [WebContents](../../../docs/api/web-contents.md)
* `url` URL
* `error` String - O código de erro
* `certificate` Object
* `data` Buffer - dados codificados PEM
* `issuerName` String
* `callback` Function
Emitido quando há uma falha na verificação do `certificate` para a `url`,
para confiar no certificado, você deve impedir o comportamento padrão com
`event.preventDefault()` e chamar `callback(true)`.
```javascript
session.on('certificate-error', function(event, webContents, url, error, certificate, callback) {
if (url == "https://github.com") {
// Lógica de verificação.
event.preventDefault();
callback(true);
} else {
callback(false);
}
});
```
### Evento: 'select-client-certificate'
Retorna:
* `event` Event
* `webContents` [WebContents](../../../docs/api/web-contents.md)
* `url` URL
* `certificateList` [Objects]
* `data` Buffer - dados codificados PEM
* `issuerName` String - Nome Comum do Emissor
* `callback` Function
Emitido quando um certificado de cliente é requisitado.
A `url` corresponde à entrada de navegação requisitando o certificado do
cliente e `callback` precisa ser chamada com uma entrada filtrada da lista.
Usar `event.preventDefault()` impede o aplicativo de usar o primeiro certificado
da memória.
```javascript
app.on('select-client-certificate', function(event, webContents, url, list, callback) {
event.preventDefault();
callback(list[0]);
})
```
### Evento: 'login'
Retorna:
* `event` Event
* `webContents` [WebContents](../../../docs/api/web-contents.md)
* `request` Object
* `method` String
* `url` URL
* `referrer` URL
* `authInfo` Object
* `isProxy` Boolean
* `scheme` String
* `host` String
* `port` Integer
* `realm` String
* `callback` Function
Emitido quando `webContents` deseja fazer autenticação básica.
O comportamento padrão é cancelar todas as autenticações, para sobrescrever
isto, você deve impedir esse comportamento com `event.preventDefault()` e
chamar `callback(username, password)` com as credenciais.
```javascript
app.on('login', function(event, webContents, request, authInfo, callback) {
event.preventDefault();
callback('username', 'secret');
})
```
### Evento: 'gpu-process-crashed'
Emitido quando o processo da gpu falha.
## Métodos
O objeto `app` possui os seguintes métodos:
**Nota:** Alguns métodos só estão disponíveis em sistemas operacionais específicos e estão rotulados como tal.
### `app.quit()`
Tente fechar todas as janelas. O evento `before-quit` será emitido primeiro. Se todas
as janelas fecharem com sucesso, o evento `will-quit` será emitido e por padrão o
aplicativo irá terminar.
Este método garante que todos os manipuladores de evento `beforeunload` e `unload`
sejam corretamente executados. É possível que uma janela cancele o processo de
encerramento ao retornar `false` no manipulador de evento `beforeunload`.
### `app.exit(exitCode)`
* `exitCode` Integer
Finaliza imediatamente com `exitCode`.
Todas as janelas serão fechadas imediatamente sem perguntar ao usuário, e os eventos
`before-quit` e `will-quit` não serão emitidos.
### `app.getAppPath()`
Retorna o atual diretório do aplicativo.
### `app.getPath(name)`
* `name` String
Retorna um endereço para um diretório especial ou arquivo associado com `nome`.
Numa falha um `Error` é lançado.
Você pode requisitar os seguintes endereços pelo nome:
* `home` Diretório *home* do usuário.
* `appData` Diretório de dados do aplicativo por usuário, que por padrão aponta para:
* `%APPDATA%` no Windows
* `$XDG_CONFIG_HOME` ou `~/.config` no Linux
* `~/Library/Application Support` no OS X
* `userData` O diretório para guardar os arquivos de configuração do seu aplicativo, que por padrão é o diretório `appData` concatenado com o nome do seu aplicativo.
* `temp` Diretório temporário.
* `exe` O arquivo executável atual.
* `module` A biblioteca `libchromiumcontent`.
* `desktop` O diretório *Desktop* do usuário atual.
* `documents` Diretório "Meus Documentos" do usuário.
* `downloads` Diretório dos downloads do usuário.
* `music` Diretório de músicas do usuário.
* `pictures` Diretório de imagens do usuário.
* `videos` Diretório de vídeos do usuário.
### `app.setPath(name, path)`
* `name` String
* `path` String
Sobrescreve o `path` para um diretório especial ou arquivo associado com `name`.
Se o endereço especifica um diretório não existente, o diretório será criado por
este método. Numa falha um `Error` é lançado.
Você pode sobrescrever apenas endereços com um `name` definido em `app.getPath`.
Por padrão, *cookies* e *caches* de páginas web serão guardadas no diretório `userData`. Se você quiser mudar esta localização, você deve sobrescrever o
endereço `userData` antes que o evento `ready` do módulo `app` seja emitido.
### `app.getVersion()`
Retorna a versão do aplicativo carregado. Se nenhuma versão for encontrada no
arquivo `package.json` do aplicativo, a versão do pacote ou executável atual é
retornada.
### `app.getName()`
Retorna o nome do aplicativo atual, que é o nome no arquivo `package.json` do
aplicativo.
Normalmente o campo `name` do `package.json` é um nome curto em letras minúsculas,
de acordo com as especificações de módulos npm. Normalmente você deve também
especificar um campo `productName`, que é o nome completo em letras maiúsculas do
seu aplicativo, e que será preferido ao `name` pelo Electron.
### `app.getLocale()`
Retorna a localidade atual do aplicativo.
### `app.addRecentDocument(path)` _OS X_ _Windows_
* `path` String
Adiciona `path` à lista de documentos recentes.
Esta lista é gerenciada pelo S.O.. No Windows você pode visitar a lista pela
barra de tarefas, e no OS X você pode visita-la pelo *dock*.
### `app.clearRecentDocuments()` _OS X_ _Windows_
Limpa a lista de documentos recentes.
### `app.setUserTasks(tasks)` _Windows_
* `tasks` Array - Vetor de objetos `Task`
Adiciona `tasks` à categoria [Tasks][tasks] do JumpList no Windows.
`tasks` é um vetor de objetos `Task` no seguinte formato:
`Task` Object
* `program` String - Endereço do programa a ser executado, normalmente você deve especificar `process.execPath` que abre o programa atual.
* `arguments` String - Os argumentos de linha de comando quando `program` é executado.
* `title` String - A string a ser exibida em uma JumpList.
* `description` String - Descrição desta *task*.
* `iconPath` String - O endereço absoluto para um ícone a ser exibido em uma JumpList, que pode ser um arquivo arbitrário que contém um ícone. Normalmente você pode especificar `process.execPath` para mostrar o ícone do programa.
* `iconIndex` Integer - O índice do ícone do arquivo do icone. Se um arquivo de ícone consiste de dois ou mais ícones, defina este valor para identificar o ícone. Se o arquivo de ícone consiste de um ícone apenas, este valor é 0.
### `app.allowNTLMCredentialsForAllDomains(allow)`
* `allow` Boolean
Define dinamicamente se sempre envia credenciais para HTTP NTLM ou autenticação *Negotiate* - normalmente, o Electron irá mandar apenas credenciais NTLM/Kerberos para URLs que se enquadram em sites "Intranet Local" (estão no mesmo domínio que você).
Entretanto, esta detecção frequentemente falha quando redes corporativas são mal configuradas, então isso permite optar por esse comportamento e habilitá-lo para todas as URLs.
### `app.makeSingleInstance(callback)`
* `callback` Function
Este método faz da sua aplicação uma Aplicação de Instância Única - invés de permitir múltiplas instâncias do seu aplicativo rodarem, isto irá assegurar que apenas uma única instância do seu aplicativo rodará, e outras instâncias sinalizam esta instância e finalizam.
`callback` será chamado com `callback(argv, workingDirectory)` quando uma segunda instância tenha sido executada. `argv` é um vetor de argumentos de linha de comando da segunda instância, e `workingDirectory` é o atual endereço de seu diretório.
Normalmente aplicativos respondem à isso não minimizando sua janela primária e dando foco à ela.
É garantida a execução do `callback` após o evento `ready` do `app` ser emitido.
Este método retorna `false` caso seu processo seja a instância primária do aplicativo e seu aplicativo deve continuar carregando. E retorna `true` caso seu processo tenha enviado seus parâmetros para outra instância, e você deve imediatamente finalizar.
No OS X o sistema enforça instância única automaticamente quando usuários tentam abrir uma segunda instância do seu aplicativo no *Finder*, e os eventos `open-file` e `open-url` serão emitidos para isso. Entretanto, quando usuários inicializam seu aplicativo na linha de comando, o mecanismo de instância única do sistema será ignorado e você terá de utilizar esse método para assegurar-se de ter uma instância única.
Um exemplo de ativação da janela de primeira instância quando uma segunda instância inicializa:
```js
var myWindow = null;
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
// Alguém tentou rodar uma segunda instância, devemos focar nossa janela
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore();
myWindow.focus();
}
return true;
});
if (shouldQuit) {
app.quit();
return;
}
// Cria myWindow, carrega o resto do aplicativo, etc...
app.on('ready', function() {
});
```
### `app.setAppUserModelId(id)` _Windows_
* `id` String
Muda o [Application User Model ID][app-user-model-id] para `id`.
### `app.commandLine.appendSwitch(switch[, value])`
Adiciona uma opção (com `value` opcional) à linha de comando do Chromium.
**Nota:** Isto não irá afetar `process.argv`, e é utilizado principalmente por desenvolvedores para controlar alguns comportamentos de baixo nível do Chromium.
### `app.commandLine.appendArgument(value)`
Adiciona um argumento à linha de comando do Chromium. O argumento será passado com aspas corretamente.
**Nota:** Isto não irá afetar `process.argv`.
### `app.dock.bounce([type])` _OS X_
* `type` String (opcional) - Pode ser `critical` ou `informational`. O padrão é
`informational`
Quando `critical` é passado, o ícone do *dock* irá pular até que o aplicativo se torne ativo ou a requisição seja cancelada.
Quando `informational` é passado, o ícone do *dock* irá pular por um segundo.
Entretanto, a requisição se mantém ativa até que o aplicativo se torne ativo ou a requisição seja cancelada.
Retorna um ID representando a requisição.
### `app.dock.cancelBounce(id)` _OS X_
* `id` Integer
Cancela o salto do `id`.
### `app.dock.setBadge(text)` _OS X_
* `text` String
Define a string a ser exibida na área de *badging* do *dock*.
### `app.dock.getBadge()` _OS X_
Retorna a string da *badge* do *dock*.
### `app.dock.hide()` _OS X_
Esconde o ícone do *dock*.
### `app.dock.show()` _OS X_
Exibe o ícone do *dock*.
### `app.dock.setMenu(menu)` _OS X_
* `menu` Menu
Define o [menu do dock][dock-menu] do aplicativo.
[dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103
[tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx

Просмотреть файл

@ -0,0 +1,85 @@
# autoUpdater
Este módulo oferece uma interface para o framework de atualização automática `Squirrel`.
## Avisos sobre Plataformas
Embora o `autoUpdater` ofereça uma API uniforme para diferentes plataformas, existem diferenças sutis em cada plataforma.
### OS X
No OS X, o módulo `autoUpdater` é construído sobre o [Squirrel.Mac][squirrel-mac], o que significa que você não precisa de nenhuma configuração especial para fazê-lo funcionar. Para requerimentos de servidor, você pode ler [Server Support][server-support].
### Windows
No Windows, você deve instalar seu aplicativo na máquina de um usuário antes que possa usar o auto-updater, então é recomendado utilizar o módulo [grunt-electron-installer][installer] para gerar um instalador do Windows.
O instalador gerado com Squirrel irá criar um ícone de atalho com um [Application User Model ID][app-user-model-id] no formato `com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`, por exemplo: `com.squirrel.slack.Slack` e `com.squirrel.code.Code`. Você precisa usar o mesmo ID para seu aplicativo a API `app.setAppUserModelId`, senão o Windows não conseguirá fixar seu aplicativo corretamente na barra de tarefas.
A configuração do servidor também é diferente do OS X. Você pode ler a documentação do [Squirrel.Windows][squirrel-windows] para mais detalhes.
### Linux
Não há suporte nativo do auto-updater para Linux, então é recomendado utilizar o gerenciador de pacotes da distribuição para atualizar seu aplicativo.
## Eventos
O objeto `autoUpdater` emite os seguintes eventos:
### Evento: 'error'
Retorna:
* `error` Error
Emitido quando há um erro durante a atualização.
### Evento: 'checking-for-update'
Emitido quando está verificando se uma atualização foi inicializada.
### Evento: 'update-available'
Emitido quando há uma atualização disponível. A autalização é baixada automaticamente.
### Evento: 'update-not-available'
Emitido quando não há uma atualização disponível.
### Evento: 'update-downloaded'
Retorna:
* `event` Event
* `releaseNotes` String
* `releaseName` String
* `releaseDate` Date
* `updateURL` String
Emitido quando uma atualização foi baixada.
No Windows apenas `releaseName` está disponível.
## Métodos
O objeto `autoUpdater` possui os seguintes métodos:
### `autoUpdater.setFeedURL(url)`
* `url` String
Define a `url` e inicializa o auto-updater. A `url` não pode ser alterada uma vez que foi definida.
### `autoUpdater.checkForUpdates()`
Pergunta ao servidor se há uma atualização. Você deve chamar `setFeedURL` antes de usar esta API.
### `autoUpdater.quitAndInstall()`
Reinicia o aplicativo e instala a atualização após esta ter sido baixada. Só deve ser chamado após o `update-downloaded` ter sido emitido.
[squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac
[server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support
[squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows
[installer]: https://github.com/atom/grunt-electron-installer
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx

Просмотреть файл

@ -1,22 +1,48 @@
# process
O objeto `process` no Electron tem as seguintes diferenças de um upstream node:
O objeto `process` no Electron tem as seguintes diferenças do objeto no upstream node:
* `process.type` String - Tipo de processo, pode ser `browser` (i.e. main process)
* `process.type` String - Tipo de processo, pode ser `browser` (processo principal)
ou `renderer`.
* `process.versions['electron']` String - Versão do Electron.
* `process.versions['chrome']` String - Versão do Chromium.
* `process.resourcesPath` String - Caminho para os códigos fontes JavaScript.
* `process.resourcesPath` String - Caminho para o código fonte JavaScript.
* `process.mas` Boolean - Para build da Mac App Store, este valor é `true`, para outros builds é `undefined`.
## Eventos
### Evento: 'loaded'
Emitido quando o Electron carregou seu script de inicialização interno e está começando a carregar a página web ou o script principal.
Pode ser utilizado pelo script pré-carregamento (preload.js abaixo) para adicionar símbolos globais do Node removidos para o escopo global quando a integração do node é desligada:
```js
// preload.js
var _setImmediate = setImmediate;
var _clearImmediate = clearImmediate;
process.once('loaded', function() {
global.setImmediate = _setImmediate;
global.clearImmediate = _clearImmediate;
});
```
## Propriedades
### `process.noAsar`
Definir isto para `true` pode desabilitar o suporte para arquivos `asar` nos módulos nativos do Node.
# Métodos
O objeto `process` tem os seguintes método:
O objeto `process` tem os seguintes métodos:
### `process.hang`
Afeta a thread principal do processo atual.
Faz com que o *thread* principal do processo congele.
## process.setFdLimit(MaxDescritores) _OS X_ _Linux_
### `process.setFdLimit(maxDescriptors)` _OS X_ _Linux_
* `maxDescriptors` Integer
Define o limite do arquivo descritor para `maxDescriptors` ou para o limite do OS,
o que for menor para o processo atual.
o que for menor para o processo atual.

Просмотреть файл

@ -1,11 +1,11 @@
# shell
O módulo `shell` fornece funções relacionadas intereções com o OS do usuário.
O módulo `shell` fornece funções relacionadas à integração com o desktop.
Um exemplo para abrir uma URL no browser padrão do usuário:
```javascript
var shell = require('shell');
const shell = require('shell');
shell.openExternal('https://github.com');
```
@ -17,26 +17,26 @@ O módulo `shell` tem os seguintes métodos:
* `fullPath` String
Exibe o arquivo no gerenciador de arquivos padrão do sistema. Se possivel, seleciona o arquivo automaticamente.
Exibe o arquivo num gerenciador de arquivos. Se possivel, seleciona o arquivo.
### `shell.openItem(fullPath)`
* `fullPath` String
Abre o arquivo em seu programa padrão.
Abre o arquivo de maneira padrão do desktop.
### `shell.openExternal(url)`
* `url` String
Abre o arquivo seguido de um protocol em seu programa padrão. (Por
exemplo, mailto:foo@bar.com.)
Abre a URL de protocolo externo de maneira padrão do desktop. (Por
exemplo, mailto: URLs no programa de email padrão do usuário)
### `shell.moveItemToTrash(fullPath)`
* `fullPath` String
Move o arquivo para a lixeira e retorna um boolean com o resultado da operação.
Move o arquivo para a lixeira e retorna um status boolean com o resultado da operação.
### `shell.beep()`

Просмотреть файл

@ -2,28 +2,25 @@
Estas são as diretrizes de estilo para codificar no Electron.
## C++ and Python
## C++ e Python
Para C ++ e Python, seguimos os padrões do projeto Chromium [Estilo de Codificação](http://www.chromium.org/developers/coding-style). Há também um
Para C++ e Python, seguimos o [Estilo de Codificação](http://www.chromium.org/developers/coding-style) do projeto Chromium. Há também um
script `script/cpplint.py` para verificar se todos os arquivos estão em conformidade.
A versão Python que estamos usando agora é a Python 2.7.
O código C ++ usa do Chromium's um monte de tipos e abstrações, por isso é recomendada para se familiarizar com eles. Um bom lugar para começar com a documentação do Chromium's [Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures). O documento menciona alguns tipos especiais, com escopo tipos (que automaticamente libera sua memória quando sai do escopo), registrando mecanismos etc.
O código C++ usa várias abstrações e tipos do Chromium, por isso é recomendado familiarizar-se com eles. Um bom lugar para começar é com a documentação do Chromium [Important Abstractions and Data Structures](https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures). O documento menciona alguns tipos especiais, *scoped types* (que automaticamente liberam sua memória ao sair do escopo), mecanismos de *log* etc.
## CoffeeScript
For CoffeeScript, we follow GitHub's [Style
Guide](https://github.com/styleguide/javascript) and the following rules:
Para CoffeeScript, seguimos o [Guia de Estilo] (https://github.com/styleguide/javascript) do GitHub com as seguintes regras:
Para CoffeeScript, seguimos o estilo do GitHub [Guia de Estilo] (https://github.com/styleguide/javascript) com as seguintes regras:
* Os arquivos **NÃO DEVEM** terminar com uma nova linha, porque queremos corresponder aos padrões de estilo Google.
* Os arquivos devem **NÃO DEVEM** com nova linha no final, porque queremos corresponder aos padrões de estilo Google.
* Os nomes dos arquivos devem ser concatenados com o `-` em vez de`_`, por exemplo, `file-name.coffee` em vez de`file_name.coffee`, porque no [github/atom](https://github.com/github/atom) os nomes dos módulos são geralmente em o formulário `module-name`. Esta regra só se aplica aos arquivos com extensão `.coffee`.
* Os nomes dos arquivos devem ser concatenados com `-` em vez de `_`, por exemplo, `file-name.coffee` em vez de `file_name.coffee`, porque no [github/atom](https://github.com/github/atom) os nomes dos módulos são geralmente da forma `module-name`. Esta regra só se aplica aos arquivos com extensão `.coffee`.
*
## API Names
## Nomes de APIs
Ao criar uma nova API, devemos preferencialmente utilizar métodos getters e setters em vez de
estilo de uma função do jQuery. Por exemplo, `.getText()` e `.setText(text)` utilize `.text([text])`. Existe uma
Ao criar uma nova API, devemos preferencialmente utilizar métodos getters e setters em vez do
estilo de uma função única do jQuery. Por exemplo, `.getText()` e `.setText(text)` são preferenciais a `.text([text])`. Existe uma
[discussão](https://github.com/atom/electron/issues/46) sobre este assunto.

Просмотреть файл

@ -4,7 +4,7 @@ Electron permite criar aplicações desktop com puro JavaScript através de
um runtime com APIs ricas e nativas. Você pode ver isso como uma variação do
runtime do io.js que é focado em aplicações desktop em vez de web servers.
Isso não significa que o Electron é uma ligação em JavaScript para blibliotécas
Isso não significa que o Electron é uma ligação em JavaScript para bibliotecas
de interface gráfica (GUI). Em vez disso, Electron usa páginas web como
interface gráfica, então você pode ver isso também como um navegador Chromium
mínimo, controlado por JavaScript.
@ -17,13 +17,13 @@ mostrar uma GUI criando páginas web.
### Processo Renderizador
Desde que o Electron usa o Chromium para mostrar as páginas web, a arquitetura
que o Electron usa o Chromium para mostrar as páginas web, a arquitetura
multi-processo do Chromium também é usada. Cada página web no Electron roda em
seu próprio processo, o que é chamado de __processo renderizador__.
Em navegadores comuns, as páginas web normalmente rodam em um ambiente em sandbox
e não tem permissão de acesso para recursos nativos. Usuários Electron, entretanto,
tem o poder de usar as APIs do io.js nas páginas web, permitindo interações de baixo
e não têm permissão de acesso para recursos nativos. Usuários Electron, entretanto,
têm o poder de usar as APIs do io.js nas páginas web, permitindo interações de baixo
nível no sistema operacional.
### Diferenças Entre o Processo Principal e o Processo Renderizador
@ -33,12 +33,12 @@ Cada instância de `BrowserWindow` roda a página web em seu próprio processo r
Quando uma instância de `BrowserWindow` é destruída, o processo renderizador
correspondente também é finalizado.
O processo principal gerência todas as páginas web de seus processos renderizadores
O processo principal gerencia todas as páginas web de seus processos renderizadores
correspondentes. Cada processo renderizador é isolado e toma conta de sua
respectiva página web.
Nas páginas web, chamar APIs nativas relacionadas à GUI não é permitido porque
gerênciar recursos de GUI em páginas web é muito perigoso e torna fácil o vazamento de
gerenciar recursos de GUI em páginas web é muito perigoso e torna fácil o vazamento de
recursos. Se você quer realizar operações com GUI em páginas web, o processo
renderizador da página web deve se comunicar com o processo principal para requisitar
que o processo principal realize estas operações.
@ -52,26 +52,26 @@ módulo [remoto](../../../docs/api/remote.md) para comunicação RPC.
Geralmente, um app Electron é estruturado assim:
```text
your-app/
seu-app/
├── package.json
├── main.js
└── index.html
```
O formato de `package.json` é exatamente o mesmo que os dos módulos do Node, e
O formato de `package.json` é exatamente o mesmo que o dos módulos do Node,
e o script especificado pelo campo `main` é o script de inicialização do seu app,
que irá executar o processo principal. Um exemplo do seu `package.json` deve parecer
com isso:
```json
{
"name" : "your-app",
"name" : "seu-app",
"version" : "0.1.0",
"main" : "main.js"
}
```
__Nota__: Se o campo `main` não estiver presente no `package.jso`, o Electron irá
__Nota__: Se o campo `main` não estiver presente no `package.json`, o Electron irá
tentar carregar um `index.js`
O `main.js` deve criar as janelas e os manipuladores de eventos do sistema, um típico
@ -140,8 +140,8 @@ Finalmente o `index.html` é a página web que você quer mostrar:
## Execute seu App
Uma vez que você criou seus arquivos `main.js`, `index.html, e `package.json` iniciais,
você provavelmente vai querer tentar executar seu app localmente para testa-lo a ter
Uma vez que você criou seus arquivos `main.js`, `index.html`, e `package.json` iniciais,
você provavelmente vai querer tentar executar seu app localmente para testa-lo e ter
certeza que funciona como você espera.
### electron-prebuilt
@ -167,19 +167,19 @@ executar seu app diretamente.
#### Windows
```bash
$ .\electron\electron.exe your-app\
$ .\electron\electron.exe seu-app\
```
#### Linux
```bash
$ ./electron/electron your-app/
$ ./electron/electron seu-app/
```
#### OS X
```bash
$ ./Electron.app/Contents/MacOS/Electron your-app/
$ ./Electron.app/Contents/MacOS/Electron seu-app/
```
`Electron.app` aqui é uma parte do pacote de lançamento do Electron, você pode baixa-lo
@ -188,5 +188,5 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/
### Executar como uma distribuição
Depois de terminar seu app, você pode criar uma distribuição seguindo o guia
[Application Distribution](./application-distribution.md) e então executar o app
[Distribuição de aplicações](./application-distribution.md) e então executar o app
empacotado.

Просмотреть файл

@ -0,0 +1,82 @@
Пожалуйста, убедитесь, что вы используете документацию, которые соответствует вашей версии Electron.
Номер версии должен быть частью адреса страницы. Если это не так, вы
возможно,используете документицию ветки разработки, которая может содержать изменения api,
которые не совместимы с вашей версией Electron. Если это так,
Вы можете переключиться на другую версию документации в списке
[доступные версии](http://electron.atom.io/docs/) на atom.io, или
если вы используете интерфейс GitHub, откройте список "переключение ветки/тега" и
выберите тег, который соответствует вашей версии.
## Руководства
* [Поддерживаемые платформы](tutorial/supported-platforms.md)
* [Application Distribution](tutorial/application-distribution.md)
* [Mac App Store Submission Guide](tutorial/mac-app-store-submission-guide.md)
* [Application Packaging](tutorial/application-packaging.md)
* [Using Native Node Modules](tutorial/using-native-node-modules.md)
* [Отладка главного процесса](tutorial/debugging-main-process.md)
* [Использование Selenium и WebDriver](tutorial/using-selenium-and-webdriver.md)
* [DevTools Extension](tutorial/devtools-extension.md)
* [Использование Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md)
## Учебники
* [Быстрый старт](tutorial/quick-start.md)
* [Desktop Environment Integration](tutorial/desktop-environment-integration.md)
* [Online/Offline Event Detection](tutorial/online-offline-events.md)
## API References
* [Краткий обзор](api/synopsis.md)
* [Process Object](api/process.md)
* [Поддерживаемые параметры командной строки Chrome](api/chrome-command-line-switches.md)
### Пользовательские элементы DOM:
* [`File` Object](api/file-object.md)
* [`<webview>` Tag](api/web-view-tag.md)
* [`window.open` Function](api/window-open.md)
### Modules for the Main Process:
* [app](api/app.md)
* [autoUpdater](api/auto-updater.md)
* [BrowserWindow](api/browser-window.md)
* [contentTracing](api/content-tracing.md)
* [dialog](api/dialog.md)
* [globalShortcut](api/global-shortcut.md)
* [ipcMain](api/ipc-main.md)
* [Menu](api/menu.md)
* [MenuItem](api/menu-item.md)
* [powerMonitor](api/power-monitor.md)
* [powerSaveBlocker](api/power-save-blocker.md)
* [protocol](api/protocol.md)
* [session](api/session.md)
* [webContents](api/web-contents.md)
* [Tray](api/tray.md)
### Модули для Renderer Process (Web Page):
* [ipcRenderer](api/ipc-renderer.md)
* [remote](api/remote.md)
* [webFrame](api/web-frame.md)
### Modules for Both Processes:
* [clipboard](api/clipboard.md)
* [crashReporter](api/crash-reporter.md)
* [nativeImage](api/native-image.md)
* [screen](api/screen.md)
* [shell](api/shell.md)
## Разработка
* [Стиль кодирования](development/coding-style.md)
* [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)
* [Обзор системы сборки](development/build-system-overview.md)
* [Инструкции по сборке (OS X)](development/build-instructions-osx.md)
* [Инструкции по сборке (Windows)](development/build-instructions-windows.md)
* [Инструкции по сборке (Linux)](development/build-instructions-linux.md)
* [Настройка сервера символов для отладчика](development/setting-up-symbol-server.md)

Просмотреть файл

@ -12,7 +12,7 @@ __1. 应用的入口__
在 Electron 中,入口是一个 JavaScript 脚本。不同于直接提供一个URL你需要手动创建一个浏览器窗口然后通过 API 加载 HTML 文件。你还可以监听窗口事件,决定何时让应用退出。
Electron 的工作方式更像 Node.js 运行时。 Electron 的 APIs 更加底层,因此你可以它替代 [PhantomJS](http://phantomjs.org/) 做浏览器测试。
Electron 的工作方式更像 Node.js 运行时。 Electron 的 APIs 更加底层,因此你可以它替代 [PhantomJS](http://phantomjs.org/) 做浏览器测试。
__2. 构建系统__

Просмотреть файл

@ -0,0 +1,141 @@
# 应用打包
为舒缓Windows下路径名过长的问题[issues](https://github.com/joyent/node/issues/6960), 也略对`require`加速以及简单隐匿你的源代码, 你可以通过极小的源代码改动将你的应用打包成[asar][asar].
## 生成`asar`包
[asar][asar]是一种将多个文件合并成一个文件的类tar风格的归档格式。 Electron可以无需解压即从其中读取任意文件内容。
参照如下步骤将你的应用打包成`asar`
### 1. 安装asar
```bash
$ npm install -g asar
```
### 2. 用`asar pack`打包
```bash
$ asar pack your-app app.asar
```
## 使用`asar`包
在Electron中有两类APIsNode.js提供的Node APIs和Chromium提供的Web APIs。这两种APIs都支持从`asar`包中读取文件。
### Node API
由于Electron中打了特别补丁 Node APIs中如`fs.readFile`或者`require`之类的方法可以将`asar`视之为虚拟文件夹,读取`asar`里面的文件就和从真实的文件系统中读取一样。
例如,假设我们在`/path/to`文件夹下有个`example.asar`包:
```bash
$ asar list /path/to/example.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js
```
从`asar`包读取一个文件:
```javascript
const fs = require('fs');
fs.readFileSync('/path/to/example.asar/file.txt');
```
列出`asar`包中根目录下的所有文件:
```javascript
const fs = require('fs');
fs.readdirSync('/path/to/example.asar');
```
使用`asar`包中的一个模块:
```javascript
require('/path/to/example.asar/dir/module.js');
```
你也可以使用`BrowserWindow`来显示一个`asar`包里的web页面
```javascript
const BrowserWindow = require('electron').BrowserWindow;
var win = new BrowserWindow({width: 800, height: 600});
win.loadURL('file:///path/to/example.asar/static/index.html');
```
### Web API
在Web页面里用`file:`协议可以获取`asar`包中文件。和Node API一样视`asar`包如虚拟文件夹。
例如,用`$.get`获取文件:
```html
<script>
var $ = require('./jquery.min.js');
$.get('file:///path/to/example.asar/file.txt', function(data) {
console.log(data);
});
</script>
```
### 像“文件”那样处理`asar`包
有些场景,如:核查`asar`包的校验和,我们需要像读取“文件”那样读取`asar`包的内容(而不是当成虚拟文件夹)。你可以使用内置的`original-fs`(提供和`fs`一样的APIs)模块来读取`asar`包的真实信息。
```javascript
var originalFs = require('original-fs');
originalFs.readFileSync('/path/to/example.asar');
```
## Node API缺陷
尽管我们已经尽了最大努力使得`asar`包在Node API下的应用尽可能的趋向于真实的目录结构但仍有一些底层Node API我们无法保证其正常工作。
### `asar`包是只读的
`asar`包中的内容不可更改所以Node APIs里那些可以用来修改文件的方法在对待`asar`包时都无法正常工作。
### Working Directory在`asar`包中无效
尽管`asar`包是虚拟文件夹但其实并没有真实的目录架构对应在文件系统里所以你不可能将working Directory设置成`asar`包里的一个文件夹。将`asar`中的文件夹以`cwd`形式作为参数传入一些API中也会报错。
### API中的额外“开箱”
大部分`fs`API可以无需解压即从`asar`包中读取文件或者文件的信息但是在处理一些依赖真实文件路径的底层系统方法时Electron会将所需文件解压到临时目录下然后将临时目录下的真实文件路径传给底层系统方法使其正常工作。 对于这类API耗费会略多一些。
以下是一些需要额外解压的APIs
* `child_process.execFile`
* `child_process.execFileSync`
* `fs.open`
* `fs.openSync`
* `process.dlopen` - `require`native模块时用到
### `fs.stat`获取的stat信息不可靠
对`asar`包中的文件取`fs.stat`,返回的`Stats`对象不是精确值,因为这些文件不是真实存在于文件系统里。所以除了文件大小和文件类型以外,你不应该依赖`Stats`对象的值。
### 执行`asar`包中的程序
Node中有一些可以执行程序的API如`child_process.exec``child_process.spawn`和`child_process.execFile`等,但只有`execFile`可以执行`asar`包中的程序。
因为`exec`和`spawn`允许`command`替代`file`作为输入,而`command`是需要在shell下执行的目前没有可靠的方法来判断`command`中是否在操作一个`asar`包中的文件,而且即便可以判断,我们依旧无法保证可以在无任何副作用的情况下替换`command`中的文件路径。
## 打包时排除文件
如上所述一些Node API会在调用时将文件解压到文件系统中除了效率问题外也有可能引起杀毒软件的注意
为解决这个问题,你可以在生成`asar`包时使用`--unpack`选项来排除一些文件,使其不打包到`asar`包中下面是如何排除一些用作共享用途的native模块的方法
```bash
$ asar pack app app.asar --unpack *.node
```
经过上述命令后,除了生成的`app.asar`包以外,还有一个包含了排除文件的`app.asar.unpacked`文件夹,你需要将这个文件夹一起拷贝,提供给用户。
[asar]: https://github.com/atom/asar

Просмотреть файл

@ -31,11 +31,18 @@ process.once('loaded', function() {
});
```
## Properties
### `process.noAsar`
Setting this to `true` can disable the support for `asar` archives in Node's
built-in modules.
## Methods
The `process` object has the following method:
### `process.hang`
### `process.hang()`
Causes the main thread of the current process hang.

Просмотреть файл

@ -187,12 +187,16 @@ when the tray icon is clicked. Defaults to true.
Displays a tray balloon.
### `Tray.popUpContextMenu([position])` _OS X_ _Windows_
### `Tray.popUpContextMenu([menu, position])` _OS X_ _Windows_
* `position` Object (optional)- The pop up position.
* `menu` Menu (optional)
* `position` Object (optional) - The pop up position.
* `x` Integer
* `y` Integer
Popups the context menu of tray icon. When `menu` is passed, the `menu` will
showed instead of the tray's context menu.
The `position` is only available on Windows, and it is (0, 0) by default.
### `Tray.setContextMenu(menu)`

Просмотреть файл

@ -452,15 +452,15 @@ Fired when a redirect was received while requesting a resource.
Fired when document in the given frame is loaded.
### Event: 'page-title-set'
### Event: 'page-title-updated'
Returns:
* `title` String
* `explicitSet` Boolean
Fired when page title is set during navigation. `explicitSet` is false when title is synthesised from file
url.
Fired when page title is set during navigation. `explicitSet` is false when
title is synthesised from file url.
### Event: 'page-favicon-updated'

Просмотреть файл

@ -103,6 +103,14 @@ var originalFs = require('original-fs');
originalFs.readFileSync('/path/to/example.asar');
```
You can also set `process.noAsar` to `true` to disable the support for `asar` in
the `fs` module:
```javascript
process.noAsar = true;
fs.readFileSync('/path/to/example.asar');
```
## Limitations on Node API
Even though we tried hard to make `asar` archives in the Node API work like

Просмотреть файл

@ -19,7 +19,7 @@ Like `--debug` but pauses the script on the first line.
## Use node-inspector for Debugging
__Note:__ Electron uses node v0.11.13, which currently doesn't work very well
__Note:__ Electron doesn't currently work very well
with node-inspector, and the main process will crash if you inspect the
`process` object under node-inspector's console.

Просмотреть файл

@ -4,6 +4,9 @@ Since v0.34.0, Electron allows submitting packaged apps to the Mac App Store
(MAS). This guide provides information on: how to submit your app and the
limitations of the MAS build.
__Note:__ Submitting an app to Mac App Store requires enrolling [Apple Developer
Program][developer-program], which costs money.
## How to Submit Your App
The following steps introduce a simple way to submit your app to Mac App Store.
@ -108,6 +111,7 @@ Also, due to the usage of app sandboxing, the resources which can be accessed by
the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for
more information.
[developer-program]: https://developer.apple.com/support/compare-memberships/
[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html
[nwjs-guide]: https://github.com/nwjs/nw.js/wiki/Mac-App-Store-%28MAS%29-Submission-Guideline#first-steps
[enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html

Просмотреть файл

@ -286,6 +286,8 @@
'atom/common/asar/scoped_temporary_file.h',
'atom/common/atom_command_line.cc',
'atom/common/atom_command_line.h',
'atom/common/atom_constants.cc',
'atom/common/atom_constants.h',
'atom/common/common_message_generator.cc',
'atom/common/common_message_generator.h',
'atom/common/crash_reporter/crash_reporter.cc',

Просмотреть файл

@ -81,6 +81,21 @@ describe 'protocol module', ->
error: (xhr, errorType, error) ->
done(error)
it 'sets Access-Control-Allow-Origin', (done) ->
handler = (request, callback) -> callback(text)
protocol.registerStringProtocol protocolName, handler, (error) ->
return done(error) if error
$.ajax
url: "#{protocolName}://fake-host"
success: (data, status, request) ->
assert.equal data, text
assert.equal(
request.getResponseHeader('Access-Control-Allow-Origin'),
'*')
done()
error: (xhr, errorType, error) ->
done(error)
it 'sends object as response', (done) ->
handler = (request, callback) -> callback(data: text, mimeType: 'text/html')
protocol.registerStringProtocol protocolName, handler, (error) ->
@ -120,6 +135,21 @@ describe 'protocol module', ->
error: (xhr, errorType, error) ->
done(error)
it 'sets Access-Control-Allow-Origin', (done) ->
handler = (request, callback) -> callback(buffer)
protocol.registerBufferProtocol protocolName, handler, (error) ->
return done(error) if error
$.ajax
url: "#{protocolName}://fake-host"
success: (data, status, request) ->
assert.equal data, text
assert.equal(
request.getResponseHeader('Access-Control-Allow-Origin'),
'*')
done()
error: (xhr, errorType, error) ->
done(error)
it 'sends object as response', (done) ->
handler = (request, callback) -> callback(data: buffer, mimeType: 'text/html')
protocol.registerBufferProtocol protocolName, handler, (error) ->
@ -163,6 +193,21 @@ describe 'protocol module', ->
error: (xhr, errorType, error) ->
done(error)
it 'sets Access-Control-Allow-Origin', (done) ->
handler = (request, callback) -> callback(filePath)
protocol.registerFileProtocol protocolName, handler, (error) ->
return done(error) if error
$.ajax
url: "#{protocolName}://fake-host"
success: (data, status, request) ->
assert.equal data, String(fileContent)
assert.equal(
request.getResponseHeader('Access-Control-Allow-Origin'),
'*')
done()
error: (xhr, errorType, error) ->
done(error)
it 'sends object as response', (done) ->
handler = (request, callback) -> callback(path: filePath)
protocol.registerFileProtocol protocolName, handler, (error) ->

Просмотреть файл

@ -423,6 +423,43 @@ describe 'asar package', ->
p = path.join fixtures, 'asar', 'unpack.asar', 'a.txt'
assert.equal internalModuleReadFile(p).toString().trim(), 'a'
describe 'process.noAsar', ->
errorName = if process.platform is 'win32' then 'ENOENT' else 'ENOTDIR'
beforeEach ->
process.noAsar = true
afterEach ->
process.noAsar = false
it 'disables asar support in sync API', ->
file = path.join fixtures, 'asar', 'a.asar', 'file1'
dir = path.join fixtures, 'asar', 'a.asar', 'dir1'
assert.throws (-> fs.readFileSync file), new RegExp(errorName)
assert.throws (-> fs.lstatSync file), new RegExp(errorName)
assert.throws (-> fs.realpathSync file), new RegExp(errorName)
assert.throws (-> fs.readdirSync dir), new RegExp(errorName)
it 'disables asar support in async API', (done) ->
file = path.join fixtures, 'asar', 'a.asar', 'file1'
dir = path.join fixtures, 'asar', 'a.asar', 'dir1'
fs.readFile file, (error) ->
assert.equal error.code, errorName
fs.lstat file, (error) ->
assert.equal error.code, errorName
fs.realpath file, (error) ->
assert.equal error.code, errorName
fs.readdir dir, (error) ->
assert.equal error.code, errorName
done()
it 'treats *.asar as normal file', ->
originalFs = require 'original-fs'
asar = path.join fixtures, 'asar', 'a.asar'
content1 = fs.readFileSync asar
content2 = originalFs.readFileSync asar
assert.equal content1.compare(content2), 0
assert.throws (-> fs.readdirSync asar), /ENOTDIR/
describe 'asar protocol', ->
url = require 'url'