Merge branch 'master' of https://github.com/atom/electron
This commit is contained in:
commit
d367af3fa4
40 changed files with 283 additions and 171 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 window’s 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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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'}
|
||||
]
|
||||
```
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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:__
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
2
vendor/brightray
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 1cba3a459e9629916655c98716b32ccd1869ef56
|
||||
Subproject commit 7c6c530608e17ee569edea3dc2607736f3cdb376
|
2
vendor/node
vendored
2
vendor/node
vendored
|
@ -1 +1 @@
|
|||
Subproject commit b772c19a8f9db65673184822fb294235eff9c364
|
||||
Subproject commit ab1b3ba0b0076d7aa72e80caf8045fb6f7a68be0
|
Loading…
Reference in a new issue