This commit is contained in:
eaton11 2015-06-10 19:28:14 -06:00
commit d367af3fa4
40 changed files with 283 additions and 171 deletions

View file

@ -41,8 +41,9 @@ void PowerMonitor::OnResume() {
// static
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot initialize \"power-monitor\" module"
"before app is ready");
node::ThrowError(
isolate,
"Cannot initialize \"power-monitor\" module before app is ready");
return v8::Null(isolate);
}

View file

@ -192,28 +192,19 @@ Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("registerProtocol",
base::Bind(&Protocol::RegisterProtocol,
base::Unretained(this)))
.SetMethod("unregisterProtocol",
base::Bind(&Protocol::UnregisterProtocol,
base::Unretained(this)))
.SetMethod("isHandledProtocol",
base::Bind(&Protocol::IsHandledProtocol,
base::Unretained(this)))
.SetMethod("interceptProtocol",
base::Bind(&Protocol::InterceptProtocol,
base::Unretained(this)))
.SetMethod("uninterceptProtocol",
base::Bind(&Protocol::UninterceptProtocol,
base::Unretained(this)));
.SetMethod("registerProtocol", &Protocol::RegisterProtocol)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("isHandledProtocol", &Protocol::IsHandledProtocol)
.SetMethod("interceptProtocol", &Protocol::InterceptProtocol)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
}
void Protocol::RegisterProtocol(const std::string& scheme,
void Protocol::RegisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback) {
if (ContainsKey(protocol_handlers_, scheme) ||
job_factory_->IsHandledProtocol(scheme))
return node::ThrowError("The scheme is already registered");
return node::ThrowError(isolate, "The scheme is already registered");
protocol_handlers_[scheme] = callback;
BrowserThread::PostTask(BrowserThread::IO,
@ -222,10 +213,11 @@ void Protocol::RegisterProtocol(const std::string& scheme,
base::Unretained(this), scheme));
}
void Protocol::UnregisterProtocol(const std::string& scheme) {
void Protocol::UnregisterProtocol(v8::Isolate* isolate,
const std::string& scheme) {
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return node::ThrowError("The scheme has not been registered");
return node::ThrowError(isolate, "The scheme has not been registered");
protocol_handlers_.erase(it);
BrowserThread::PostTask(BrowserThread::IO,
@ -238,13 +230,14 @@ bool Protocol::IsHandledProtocol(const std::string& scheme) {
return job_factory_->IsHandledProtocol(scheme);
}
void Protocol::InterceptProtocol(const std::string& scheme,
void Protocol::InterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback) {
if (!job_factory_->HasProtocolHandler(scheme))
return node::ThrowError("Scheme does not exist.");
return node::ThrowError(isolate, "Scheme does not exist.");
if (ContainsKey(protocol_handlers_, scheme))
return node::ThrowError("Cannot intercept custom procotols");
return node::ThrowError(isolate, "Cannot intercept custom procotols");
protocol_handlers_[scheme] = callback;
BrowserThread::PostTask(BrowserThread::IO,
@ -253,10 +246,11 @@ void Protocol::InterceptProtocol(const std::string& scheme,
base::Unretained(this), scheme));
}
void Protocol::UninterceptProtocol(const std::string& scheme) {
void Protocol::UninterceptProtocol(v8::Isolate* isolate,
const std::string& scheme) {
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
if (it == protocol_handlers_.end())
return node::ThrowError("The scheme has not been registered");
return node::ThrowError(isolate, "The scheme has not been registered");
protocol_handlers_.erase(it);
BrowserThread::PostTask(BrowserThread::IO,

View file

@ -43,9 +43,10 @@ class Protocol : public mate::EventEmitter {
// Register/unregister an networking |scheme| which would be handled by
// |callback|.
void RegisterProtocol(const std::string& scheme,
void RegisterProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback);
void UnregisterProtocol(const std::string& scheme);
void UnregisterProtocol(v8::Isolate* isolate, const std::string& scheme);
// Returns whether a scheme has been registered.
// FIXME Should accept a callback and be asynchronous so we do not have to use
@ -53,9 +54,10 @@ class Protocol : public mate::EventEmitter {
bool IsHandledProtocol(const std::string& scheme);
// Intercept/unintercept an existing protocol handler.
void InterceptProtocol(const std::string& scheme,
void InterceptProtocol(v8::Isolate* isolate,
const std::string& scheme,
const JsProtocolHandler& callback);
void UninterceptProtocol(const std::string& scheme);
void UninterceptProtocol(v8::Isolate* isolate, const std::string& scheme);
// The networking related operations have to be done in IO thread.
void RegisterProtocolInIO(const std::string& scheme);

View file

@ -113,13 +113,14 @@ mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
// static
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot initialize \"screen\" module before app is ready");
node::ThrowError(isolate,
"Cannot initialize \"screen\" module before app is ready");
return v8::Null(isolate);
}
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
if (!screen) {
node::ThrowError("Failed to get screen information");
node::ThrowError(isolate, "Failed to get screen information");
return v8::Null(isolate);
}

View file

@ -32,9 +32,9 @@ Tray::~Tray() {
}
// static
mate::Wrappable* Tray::New(const gfx::Image& image) {
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot create Tray before app is ready");
node::ThrowError(isolate, "Cannot create Tray before app is ready");
return nullptr;
}
return new Tray(image);

View file

@ -31,7 +31,7 @@ class Menu;
class Tray : public mate::EventEmitter,
public TrayIconObserver {
public:
static mate::Wrappable* New(const gfx::Image& image);
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);

View file

@ -189,7 +189,8 @@ void Window::OnDevToolsClosed() {
mate::Wrappable* Window::New(v8::Isolate* isolate,
const mate::Dictionary& options) {
if (!Browser::Get()->is_ready()) {
node::ThrowError("Cannot create BrowserWindow before app is ready");
node::ThrowError(isolate,
"Cannot create BrowserWindow before app is ready");
return nullptr;
}
return new Window(options);

View file

@ -14,16 +14,20 @@
#include "atom/browser/window_list.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/printing/printing_message_filter.h"
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
#include "chrome/browser/speech/tts_message_filter.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/web_preferences.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
#include "ui/base/l10n/l10n_util.h"
@ -67,6 +71,23 @@ ProcessOwner GetProcessOwner(int process_id,
return OWNER_NONE;
}
scoped_refptr<net::X509Certificate> ImportCertFromFile(
const base::FilePath& path) {
std::string cert_data;
if (!base::ReadFileToString(path, &cert_data))
return nullptr;
net::CertificateList certs =
net::X509Certificate::CreateCertificateListFromBytes(
cert_data.data(), cert_data.size(),
net::X509Certificate::FORMAT_AUTO);
if (certs.empty())
return nullptr;
return certs[0];
}
} // namespace
// static
@ -189,6 +210,29 @@ content::QuotaPermissionContext*
return new AtomQuotaPermissionContext;
}
void AtomBrowserClient::SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) {
auto command_line = base::CommandLine::ForCurrentProcess();
auto cert_path = command_line->GetSwitchValueNative(
switches::kClientCertificate);
// TODO(zcbenz): allow users to select certificate from
// client_cert list. Right now defaults to first certificate
// in the list.
scoped_refptr<net::X509Certificate> certificate;
if (cert_path.empty()) {
if (!cert_request_info->client_certs.empty())
certificate = cert_request_info->client_certs[0];
} else {
certificate = ImportCertFromFile(base::FilePath(cert_path));
}
if (certificate.get())
delegate->ContinueWithCertificate(certificate.get());
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) {
v8::V8::Initialize(); // Init V8 before creating main parts.

View file

@ -11,6 +11,11 @@
namespace content {
class QuotaPermissionContext;
class ClientCertificateDelegate;
}
namespace net {
class SSLCertRequestInfo;
}
namespace atom {
@ -41,6 +46,10 @@ class AtomBrowserClient : public brightray::BrowserClient {
int child_process_id) override;
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
void SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
private:
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(

View file

@ -7,6 +7,7 @@ v8Util = process.atomBinding 'v8_util'
valueToMeta = (sender, value) ->
meta = type: typeof value
meta.type = 'buffer' if Buffer.isBuffer value
meta.type = 'value' if value is null
meta.type = 'array' if Array.isArray value
@ -26,6 +27,8 @@ valueToMeta = (sender, value) ->
meta.members = []
meta.members.push {name: prop, type: typeof field} for prop, field of value
else if meta.type is 'buffer'
meta.value = Array::slice.call value, 0
else
meta.type = 'value'
meta.value = value
@ -43,6 +46,7 @@ unwrapArgs = (sender, args) ->
when 'value' then meta.value
when 'remote-object' then objectsRegistry.get meta.id
when 'array' then unwrapArgs sender, meta.value
when 'buffer' then new Buffer(meta.value)
when 'object'
ret = v8Util.createObjectWithName meta.name
for member in meta.members

View file

@ -7,6 +7,7 @@
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
@ -15,44 +16,32 @@
#include "atom/common/node_includes.h"
namespace mate {
template<>
struct Converter<ui::ClipboardType> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
ui::ClipboardType* out) {
std::string type;
if (!Converter<std::string>::FromV8(isolate, val, &type))
return false;
if (type == "selection")
*out = ui::CLIPBOARD_TYPE_SELECTION;
else
*out = ui::CLIPBOARD_TYPE_COPY_PASTE;
return true;
}
};
} // namespace mate
namespace {
std::vector<base::string16> AvailableFormats(ui::ClipboardType type) {
ui::ClipboardType GetClipboardType(mate::Arguments* args) {
std::string type;
if (args->GetNext(&type) && type == "selection")
return ui::CLIPBOARD_TYPE_SELECTION;
else
return ui::CLIPBOARD_TYPE_COPY_PASTE;
}
std::vector<base::string16> AvailableFormats(mate::Arguments* args) {
std::vector<base::string16> format_types;
bool ignore;
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
clipboard->ReadAvailableTypes(type, &format_types, &ignore);
clipboard->ReadAvailableTypes(GetClipboardType(args), &format_types, &ignore);
return format_types;
}
bool Has(const std::string& format_string, ui::ClipboardType type) {
bool Has(const std::string& format_string, mate::Arguments* args) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));
return clipboard->IsFormatAvailable(format, type);
return clipboard->IsFormatAvailable(format, GetClipboardType(args));
}
std::string Read(const std::string& format_string,
ui::ClipboardType type) {
mate::Arguments* args) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));
@ -61,62 +50,62 @@ std::string Read(const std::string& format_string,
return data;
}
base::string16 ReadText(ui::ClipboardType type) {
base::string16 ReadText(mate::Arguments* args) {
base::string16 data;
ui::Clipboard::GetForCurrentThread()->ReadText(type, &data);
ui::Clipboard::GetForCurrentThread()->ReadText(GetClipboardType(args), &data);
return data;
}
void WriteText(const base::string16& text, ui::ClipboardType type) {
ui::ScopedClipboardWriter writer(type);
void WriteText(const base::string16& text, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteText(text);
}
base::string16 ReadHtml(ui::ClipboardType type) {
base::string16 ReadHtml(mate::Arguments* args) {
base::string16 data;
base::string16 html;
std::string url;
uint32 start;
uint32 end;
ui::Clipboard::GetForCurrentThread()->ReadHTML(type, &html, &url,
&start, &end);
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
clipboard->ReadHTML(GetClipboardType(args), &html, &url, &start, &end);
data = html.substr(start, end - start);
return data;
}
void WriteHtml(const base::string16& html,
ui::ClipboardType type) {
ui::ScopedClipboardWriter writer(type);
void WriteHtml(const base::string16& html, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteHTML(html, std::string());
}
gfx::Image ReadImage(ui::ClipboardType type) {
SkBitmap bitmap = ui::Clipboard::GetForCurrentThread()->ReadImage(type);
gfx::Image ReadImage(mate::Arguments* args) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
SkBitmap bitmap = clipboard->ReadImage(GetClipboardType(args));
return gfx::Image::CreateFrom1xBitmap(bitmap);
}
void WriteImage(const gfx::Image& image, ui::ClipboardType type) {
ui::ScopedClipboardWriter writer(type);
void WriteImage(const gfx::Image& image, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteImage(image.AsBitmap());
}
void Clear(ui::ClipboardType type) {
ui::Clipboard::GetForCurrentThread()->Clear(type);
void Clear(mate::Arguments* args) {
ui::Clipboard::GetForCurrentThread()->Clear(GetClipboardType(args));
}
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("_availableFormats", &AvailableFormats);
dict.SetMethod("_has", &Has);
dict.SetMethod("_read", &Read);
dict.SetMethod("_readText", &ReadText);
dict.SetMethod("_writeText", &WriteText);
dict.SetMethod("_readHtml", &ReadHtml);
dict.SetMethod("_writeHtml", &WriteHtml);
dict.SetMethod("_readImage", &ReadImage);
dict.SetMethod("_writeImage", &WriteImage);
dict.SetMethod("_clear", &Clear);
dict.SetMethod("availableFormats", &AvailableFormats);
dict.SetMethod("has", &Has);
dict.SetMethod("read", &Read);
dict.SetMethod("readText", &ReadText);
dict.SetMethod("writeText", &WriteText);
dict.SetMethod("readHtml", &ReadHtml);
dict.SetMethod("writeHtml", &WriteHtml);
dict.SetMethod("readImage", &ReadImage);
dict.SetMethod("writeImage", &WriteImage);
dict.SetMethod("clear", &Clear);
}
} // namespace

View file

@ -35,7 +35,7 @@ int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Local<v8::Object> object) {
v8::Local<v8::Value> IDWeakMap::Get(v8::Isolate* isolate, int32_t key) {
if (!Has(key)) {
node::ThrowError("Invalid key");
node::ThrowError(isolate, "Invalid key");
return v8::Undefined(isolate);
}

View file

@ -1,12 +1,5 @@
binding = process.atomBinding 'clipboard'
module.exports =
availableFormats: (type='standard') -> binding._availableFormats type
has: (format, type='standard') -> binding._has format, type
read: (format, type='standard') -> binding._read format, type
readText: (type='standard') -> binding._readText type
writeText: (text, type='standard') -> binding._writeText text, type
readHtml: (type='standard') -> binding._readHtml type
writeHtml: (markup, type='standard') -> binding._writeHtml markup, type
readImage: (type='standard') -> binding._readImage type
writeImage: (image, type='standard') -> binding._writeImage image, type
clear: (type='standard') -> binding._clear type
if process.platform is 'linux' and process.type is 'renderer'
# On Linux we could not access clipboard in renderer process.
module.exports = require('remote').require 'clipboard'
else
module.exports = process.atomBinding 'clipboard'

View file

@ -46,7 +46,8 @@ std::vector<CrashReporter::UploadReportResult>
CrashReporter::GetUploadedReports(const std::string& path) {
std::string file_content;
std::vector<CrashReporter::UploadReportResult> result;
if (base::ReadFileToString(base::FilePath(path), &file_content)) {
if (base::ReadFileToString(base::FilePath::FromUTF8Unsafe(path),
&file_content)) {
std::vector<std::string> reports;
base::SplitString(file_content, '\n', &reports);
for (const std::string& report : reports) {

View file

@ -310,6 +310,38 @@ exports.wrapFsWithAsar = (fs) ->
files
internalModuleReadFile = process.binding('fs').internalModuleReadFile
process.binding('fs').internalModuleReadFile = (p) ->
[isAsar, asarPath, filePath] = splitPath p
return internalModuleReadFile p unless isAsar
archive = getOrCreateArchive asarPath
return undefined unless archive
info = archive.getFileInfo filePath
return undefined unless info
return '' if info.size is 0
buffer = new Buffer(info.size)
fd = archive.getFd()
retrun undefined unless fd >= 0
fs.readSync fd, buffer, 0, info.size, info.offset
buffer.toString 'utf8'
internalModuleStat = process.binding('fs').internalModuleStat
process.binding('fs').internalModuleStat = (p) ->
[isAsar, asarPath, filePath] = splitPath p
return internalModuleStat p unless isAsar
archive = getOrCreateArchive asarPath
return -34 unless archive # -ENOENT
stats = archive.stat filePath
return -34 unless stats # -ENOENT
if stats.isDirectory then return 1 else return 0
overrideAPI fs, 'open'
overrideAPI child_process, 'execFile'
overrideAPISync process, 'dlopen', 1

View file

@ -87,6 +87,9 @@ const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor";
// Use the OS X's standard window instead of the textured window.
const char kStandardWindow[] = "standard-window";
// Path to client certificate.
const char kClientCertificate[] = "client-certificate";
// Web runtime features.
const char kExperimentalFeatures[] = "experimental-features";
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";

View file

@ -45,6 +45,7 @@ extern const char kTransparent[];
extern const char kType[];
extern const char kDisableAutoHideCursor[];
extern const char kStandardWindow[];
extern const char kClientCertificate[];
extern const char kExperimentalFeatures[];
extern const char kExperimentalCanvasFeatures[];

View file

@ -30,7 +30,9 @@ RenderView* GetCurrentRenderView() {
return RenderView::FromWebView(view);
}
void Send(const base::string16& channel, const base::ListValue& arguments) {
void Send(v8::Isolate* isolate,
const base::string16& channel,
const base::ListValue& arguments) {
RenderView* render_view = GetCurrentRenderView();
if (render_view == NULL)
return;
@ -39,10 +41,11 @@ void Send(const base::string16& channel, const base::ListValue& arguments) {
render_view->GetRoutingID(), channel, arguments));
if (!success)
node::ThrowError("Unable to send AtomViewHostMsg_Message");
node::ThrowError(isolate, "Unable to send AtomViewHostMsg_Message");
}
base::string16 SendSync(const base::string16& channel,
base::string16 SendSync(v8::Isolate* isolate,
const base::string16& channel,
const base::ListValue& arguments) {
base::string16 json;
@ -57,7 +60,7 @@ base::string16 SendSync(const base::string16& channel,
bool success = render_view->Send(message);
if (!success)
node::ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
node::ThrowError(isolate, "Unable to send AtomViewHostMsg_Message_Sync");
return json;
}

View file

@ -10,6 +10,8 @@ wrapArgs = (args) ->
valueToMeta = (value) ->
if Array.isArray value
type: 'array', value: wrapArgs(value)
else if Buffer.isBuffer value
type: 'buffer', value: Array::slice.call(value, 0)
else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId'
type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId'
else if value? and typeof value is 'object'
@ -30,6 +32,7 @@ metaToValue = (meta) ->
switch meta.type
when 'value' then meta.value
when 'array' then (metaToValue(el) for el in meta.members)
when 'buffer' then new Buffer(meta.value)
when 'error'
throw new Error("#{meta.message}\n#{meta.stack}")
else

View file

@ -173,7 +173,7 @@ class WebViewImpl
params =
instanceId: @viewInstanceId
userAgentOverride: @userAgentOverride
for attributeName, attribute of @attributes
for own attributeName, attribute of @attributes
params[attributeName] = attribute.getValue()
# When the WebView is not participating in layout (display:none)
# then getBoundingClientRect() would report a width and height of 0.

View file

@ -9,6 +9,7 @@
'component%': 'static_library',
'python': 'python',
'openssl_no_asm': 1,
'node_target_type': 'shared_library',
'node_install_npm': 'false',
'node_prefix': '',
'node_shared_cares': 'false',
@ -26,6 +27,7 @@
'uv_library': 'static_library',
'uv_parent_path': 'vendor/node/deps/uv',
'uv_use_dtrace': 'false',
'V8_BASE': '',
'v8_postmortem_support': 'false',
'v8_enable_i18n_support': 'false',
# Required by Linux (empty for now, should support it in future).
@ -99,7 +101,10 @@
],
}],
['_target_name=="node"', {
'include_dirs': [ '<(libchromiumcontent_src_dir)/v8/include' ],
'include_dirs': [
'<(libchromiumcontent_src_dir)/v8',
'<(libchromiumcontent_src_dir)/v8/include',
],
'conditions': [
['OS=="mac" and libchromiumcontent_component==0', {
# -all_load is the "whole-archive" on OS X.

View file

@ -43,7 +43,7 @@ You can also create a window without chrome by using
other windows
* `fullscreen` Boolean - Whether the window should show in fullscreen, when
set to `false` the fullscreen button would also be hidden on OS X
* `skip-taskbar` Boolean - Do not show window in Taskbar
* `skip-taskbar` Boolean - Do not show window in taskbar
* `zoom-factor` Number - The default zoom factor of the page, zoom factor is
zoom percent / 100, so `3.0` represents `300%`
* `kiosk` Boolean - The kiosk mode
@ -131,9 +131,9 @@ window.onbeforeunload = function(e) {
console.log('I do not want to be closed');
// Unlike usual browsers, in which a string should be returned and the user is
// prompted to confirm the page unload. Electron gives the power completely
// to the developers, return empty string or false would prevent the unloading
// now. You can also use the dialog API to let user confirm it.
// prompted to confirm the page unload, Electron gives developers more options.
// Returning empty string or false would prevent the unloading now.
// You can also use the dialog API to let the user confirm closing the application.
return false;
};
```
@ -464,7 +464,7 @@ Starts or stops flashing the window to attract user's attention.
* `skip` Boolean
Makes the window do not show in Taskbar.
Makes the window not show in the taskbar.
### BrowserWindow.setKiosk(flag)
@ -483,13 +483,13 @@ Returns whether the window is in kiosk mode.
Sets the pathname of the file the window represents, and the icon of the file
will show in window's title bar.
__Note__: This API is available only on OS X.
__Note__: This API is only available on OS X.
### BrowserWindow.getRepresentedFilename()
Returns the pathname of the file the window represents.
__Note__: This API is available only on OS X.
__Note__: This API is only available on OS X.
### BrowserWindow.setDocumentEdited(edited)
@ -498,13 +498,13 @@ __Note__: This API is available only on OS X.
Specifies whether the windows document has been edited, and the icon in title
bar will become grey when set to `true`.
__Note__: This API is available only on OS X.
__Note__: This API is only available on OS X.
### BrowserWindow.IsDocumentEdited()
Whether the window's document has been edited.
__Note__: This API is available only on OS X.
__Note__: This API is only available on OS X.
### BrowserWindow.openDevTools([options])
@ -604,20 +604,20 @@ it will assume `app.getName().desktop`.
### BrowserWindow.setOverlayIcon(overlay, description)
* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom
right corner of the Taskbar icon. If this parameter is `null`, the overlay is
right corner of the taskbar icon. If this parameter is `null`, the overlay is
cleared
* `description` String - a description that will be provided to Accessibility
screen readers
Sets a 16px overlay onto the current Taskbar icon, usually used to convey some sort of application status or to passively notify the user.
Sets a 16px overlay onto the current taskbar icon, usually used to convey some sort of application status or to passively notify the user.
__Note:__ This API is only available on Windows, Win7 or above
__Note:__ This API is only available on Windows (Windows 7 and above)
### BrowserWindow.showDefinitionForSelection()
Shows pop-up dictionary that searches the selected word on the page.
__Note__: This API is available only on OS X.
__Note__: This API is only available on OS X.
### BrowserWindow.setAutoHideMenuBar(hide)
@ -753,7 +753,7 @@ Calling `event.preventDefault()` can prevent creating new windows.
Emitted when user or the page wants to start an navigation, it can happen when
`window.location` object is changed or user clicks a link in the page.
This event will not emit when the navigation is started programmely with APIs
This event will not emit when the navigation is started programmatically with APIs
like `WebContents.loadUrl` and `WebContents.back`.
Calling `event.preventDefault()` can prevent the navigation.

View file

@ -1,6 +1,6 @@
# Supported Chrome command line switches
Following command lines switches in Chrome browser are also Supported in
The following command lines switches in Chrome browser are also supported in
Electron, you can use [app.commandLine.appendSwitch][append-switch] to append
them in your app's main script before the [ready][ready] event of [app][app]
module is emitted:
@ -11,9 +11,14 @@ app.commandLine.appendSwitch('remote-debugging-port', '8315');
app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1');
app.on('ready', function() {
// Your code here
});
```
## --client-certificate=`path`
Sets `path` of client certificate file.
## --disable-http-cache
Disables the disk cache for HTTP requests.

View file

@ -36,8 +36,8 @@ selected, an example is:
filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },
{ name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] },
{ name: 'Custom File Type', extensions: ['as'] },
],
{ name: 'Custom File Type', extensions: ['as'] }
]
}
```

View file

@ -28,7 +28,7 @@ var win = new BrowserWindow({ transparent: true, frame: false });
API to set window shape to solve this, but currently blocked at an
[upstream bug](https://code.google.com/p/chromium/issues/detail?id=387234).
* Transparent window is not resizable, setting `resizable` to `true` may make
transprent window stop working on some platforms.
transparent window stop working on some platforms.
* The `blur` filter only applies to the web page, so there is no way to apply
blur effect to the content below the window.
* On Windows transparent window will not work when DWM is disabled.

View file

@ -9,8 +9,10 @@ var globalShortcut = require('global-shortcut');
// Register a 'ctrl+x' shortcut listener.
var ret = globalShortcut.register('ctrl+x', function() { console.log('ctrl+x is pressed'); })
if (!ret)
console.log('registerion fails');
if (!ret) {
console.log('registration failed');
}
// Check whether a shortcut is registered.
console.log(globalShortcut.isRegistered('ctrl+x'));

View file

@ -29,8 +29,11 @@ window.addEventListener('contextmenu', function (e) {
Another example of creating the application menu with the simple template API:
```javascript
// main.js
```html
<!-- index.html -->
<script>
var remote = require('remote');
var Menu = remote.require('menu');
var template = [
{
label: 'Electron',
@ -69,7 +72,7 @@ var template = [
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
selector: 'terminate:'
},
]
},
@ -108,7 +111,7 @@ var template = [
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:'
},
}
]
},
{
@ -117,12 +120,12 @@ var template = [
{
label: 'Reload',
accelerator: 'Command+R',
click: function() { BrowserWindow.getFocusedWindow().reloadIgnoringCache(); }
click: function() { remote.getCurrentWindow().reload(); }
},
{
label: 'Toggle DevTools',
accelerator: 'Alt+Command+I',
click: function() { BrowserWindow.getFocusedWindow().toggleDevTools(); }
click: function() { remote.getCurrentWindow().toggleDevTools(); }
},
]
},
@ -145,18 +148,19 @@ var template = [
{
label: 'Bring All to Front',
selector: 'arrangeInFront:'
},
}
]
},
{
label: 'Help',
submenu: []
},
}
];
menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu); // Must be called within app.on('ready', function(){ ... });
Menu.setApplicationMenu(menu);
</script>
```
## Class: Menu
@ -281,10 +285,10 @@ Template:
```javascript
[
{label: '4', id: '4'}
{label: '5', id: '5'}
{label: '1', id: '1', position: 'before=4'}
{label: '2', id: '2'}
{label: '4', id: '4'},
{label: '5', id: '5'},
{label: '1', id: '1', position: 'before=4'},
{label: '2', id: '2'},
{label: '3', id: '3'}
]
```
@ -303,11 +307,11 @@ Template:
```javascript
[
{label: 'a', position: 'endof=letters'}
{label: '1', position: 'endof=numbers'}
{label: 'b', position: 'endof=letters'}
{label: '2', position: 'endof=numbers'}
{label: 'c', position: 'endof=letters'}
{label: 'a', position: 'endof=letters'},
{label: '1', position: 'endof=numbers'},
{label: 'b', position: 'endof=letters'},
{label: '2', position: 'endof=numbers'},
{label: 'c', position: 'endof=letters'},
{label: '3', position: 'endof=numbers'}
]
```

View file

@ -7,8 +7,8 @@ An example of implementing a protocol that has the same effect with the
`file://` protocol:
```javascript
var app = require('app'),
path = require('path');
var app = require('app');
var path = require('path');
app.on('ready', function() {
var protocol = require('protocol');

View file

@ -15,7 +15,7 @@ app.on('ready', function(){
{ label: 'Item1', type: 'radio' },
{ label: 'Item2', type: 'radio' },
{ label: 'Item3', type: 'radio', checked: true },
{ label: 'Item4', type: 'radio' },
{ label: 'Item4', type: 'radio' }
]);
appIcon.setToolTip('This is my application.');
appIcon.setContextMenu(contextMenu);

View file

@ -18,7 +18,7 @@ form, the `webview` tag includes the `src` of the web page and css styles that
control the appearance of the `webview` container:
```html
<webview id="foo" src="https://www.github.com/" style="width:640px; height:480px"></webview>
<webview id="foo" src="https://www.github.com/" style="display:inline-block; width:640px; height:480px"></webview>
```
If you want to control the guest content in any way, you can write JavaScript
@ -398,7 +398,7 @@ without regard for log level or other properties.
```javascript
webview.addEventListener('console-message', function(e) {
console.log('Guest page logged a message: ', e.message);
console.log('Guest page logged a message:', e.message);
});
```
@ -456,7 +456,7 @@ webview.send('ping');
var ipc = require('ipc');
ipc.on('ping', function() {
ipc.sendToHost('pong');
})
});
```
### crashed

View file

@ -35,7 +35,7 @@ exposing your app's source code to users.
To use an `asar` archive to replace the `app` folder, you need to rename the
archive to `app.asar`, and put it under Electron's resources directory like
bellow, and Electron will then try read the archive and start from it.
below, and Electron will then try read the archive and start from it.
On OS X:

View file

@ -70,9 +70,9 @@ var dockMenu = Menu.buildFromTemplate([
{ label: 'New Window', click: function() { console.log('New Window'); } },
{ label: 'New Window with Settings', submenu: [
{ label: 'Basic' },
{ label: 'Pro'},
{ label: 'Pro'}
]},
{ label: 'New Command...'},
{ label: 'New Command...'}
]);
app.dock.setMenu(dockMenu);
```
@ -119,7 +119,7 @@ app.setUserTasks([
iconPath: process.execPath,
iconIndex: 0,
title: 'New Window',
description: 'Create a new window',
description: 'Create a new window'
}
]);
```
@ -149,8 +149,8 @@ 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 that user having to
switch to the window itself.
The Unity DE also has a simililar feature that allows you to specify progress
bar in the lancher.
The Unity DE also has a similar feature that allows you to specify the progress
bar in the launcher.
__Progress bar in taskbar button:__

View file

@ -20,14 +20,14 @@ Then you can load the extension in Electron by opening devtools in any window,
and then running the following code in the devtools console:
```javascript
require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools')
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:
```javascript
require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools')
require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools');
```
## Format of devtools extension

View file

@ -82,8 +82,9 @@ var mainWindow = null;
// Quit when all windows are closed.
app.on('window-all-closed', function() {
if (process.platform != 'darwin')
if (process.platform != 'darwin') {
app.quit();
}
});
// This method will be called when Electron has done everything

View file

@ -23,8 +23,9 @@ var mainWindow = null;
// Quit when all windows are closed.
app.on('window-all-closed', function() {
if (process.platform != 'darwin')
if (process.platform != 'darwin') {
app.quit();
}
});
// Specify flash path.

View file

@ -49,14 +49,14 @@ and where to find Electron's binary:
```javascript
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
// The "9515" is the port opened by chrome driver.
usingServer('http://localhost:9515').
withCapabilities({chromeOptions: {
// Here is the path to your Electron binary.
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}}).
forBrowser('electron').
build();
var driver = new webdriver.Builder()
// The "9515" is the port opened by chrome driver.
.usingServer('http://localhost:9515')
.withCapabilities({chromeOptions: {
// Here is the path to your Electron binary.
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}})
.forBrowser('electron')
.build();
driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python
import os
import platform
import subprocess
import sys
@ -43,10 +44,19 @@ def run_gyp(target_arch, component):
defines = [
'-Dlibchromiumcontent_component={0}'.format(component),
'-Dtarget_arch={0}'.format(target_arch),
'-Dhost_arch={0}'.format(target_arch),
'-Dlibrary=static_library',
]
return subprocess.call([python, gyp, '-f', 'ninja', '--depth', '.',
'atom.gyp', '-Icommon.gypi'] + defines)
def get_host_arch():
if platform.architecture()[0] == '32bit':
return 'ia32'
else:
return 'x64'
if __name__ == '__main__':
sys.exit(main())

View file

@ -188,6 +188,7 @@ describe 'browser-window module', ->
w.loadUrl 'file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html')
describe 'new-window event', ->
return if isCI and process.platform is 'darwin'
it 'emits when window.open is called', (done) ->
w.webContents.once 'new-window', (e, url, frameName) ->
e.preventDefault()
@ -230,6 +231,7 @@ describe 'browser-window module', ->
w.minimize()
describe 'will-navigate event', ->
return if isCI and process.platform is 'darwin'
it 'emits when user starts a navigation', (done) ->
@timeout 10000
w.webContents.on 'will-navigate', (event, url) ->
@ -239,6 +241,7 @@ describe 'browser-window module', ->
w.loadUrl "file://#{fixtures}/pages/will-navigate.html"
describe 'dom-ready event', ->
return if isCI and process.platform is 'darwin'
it 'emits when document is loaded', (done) ->
ipc = remote.require 'ipc'
server = http.createServer (req, res) ->

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit 1cba3a459e9629916655c98716b32ccd1869ef56
Subproject commit 7c6c530608e17ee569edea3dc2607736f3cdb376

2
vendor/node vendored

@ -1 +1 @@
Subproject commit b772c19a8f9db65673184822fb294235eff9c364
Subproject commit ab1b3ba0b0076d7aa72e80caf8045fb6f7a68be0