Merge remote-tracking branch 'atom/master'

This commit is contained in:
Plusb Preco 2015-09-30 11:01:08 +09:00
commit 79112288b8
13 changed files with 197 additions and 53 deletions

View file

@ -19,6 +19,8 @@
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h" #include "base/thread_task_runner_handle.h"
#include "brightray/browser/net/devtools_network_conditions.h"
#include "brightray/browser/net/devtools_network_controller.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
@ -294,6 +296,43 @@ void Session::SetDownloadPath(const base::FilePath& path) {
prefs::kDownloadDefaultDirectory, path); prefs::kDownloadDefaultDirectory, path);
} }
void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
scoped_ptr<brightray::DevToolsNetworkConditions> conditions;
bool offline = false;
double latency, download_throughput, upload_throughput;
if (options.Get("offline", &offline) && offline) {
conditions.reset(new brightray::DevToolsNetworkConditions(offline));
} else {
options.Get("latency", &latency);
options.Get("downloadThroughput", &download_throughput);
options.Get("uploadThroughput", &upload_throughput);
conditions.reset(
new brightray::DevToolsNetworkConditions(false,
latency,
download_throughput,
upload_throughput));
}
auto controller = browser_context_->GetDevToolsNetworkController();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
base::Unretained(controller),
std::string(),
base::Passed(&conditions)));
}
void Session::DisableNetworkEmulation() {
scoped_ptr<brightray::DevToolsNetworkConditions> conditions(
new brightray::DevToolsNetworkConditions(false));
auto controller = browser_context_->GetDevToolsNetworkController();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
base::Unretained(controller),
std::string(),
base::Passed(&conditions)));
}
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) { v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
if (cookies_.IsEmpty()) { if (cookies_.IsEmpty()) {
auto handle = atom::api::Cookies::Create(isolate, browser_context()); auto handle = atom::api::Cookies::Create(isolate, browser_context());
@ -310,6 +349,8 @@ mate::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
.SetMethod("clearStorageData", &Session::ClearStorageData) .SetMethod("clearStorageData", &Session::ClearStorageData)
.SetMethod("setProxy", &Session::SetProxy) .SetMethod("setProxy", &Session::SetProxy)
.SetMethod("setDownloadPath", &Session::SetDownloadPath) .SetMethod("setDownloadPath", &Session::SetDownloadPath)
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
.SetProperty("cookies", &Session::Cookies); .SetProperty("cookies", &Session::Cookies);
} }

View file

@ -20,6 +20,7 @@ class FilePath;
namespace mate { namespace mate {
class Arguments; class Arguments;
class Dictionary;
} }
namespace atom { namespace atom {
@ -65,6 +66,8 @@ class Session: public mate::TrackableObject<Session>,
void ClearStorageData(mate::Arguments* args); void ClearStorageData(mate::Arguments* args);
void SetProxy(const std::string& proxy, const base::Closure& callback); void SetProxy(const std::string& proxy, const base::Closure& callback);
void SetDownloadPath(const base::FilePath& path); void SetDownloadPath(const base::FilePath& path);
void EnableNetworkEmulation(const mate::Dictionary& options);
void DisableNetworkEmulation();
v8::Local<v8::Value> Cookies(v8::Isolate* isolate); v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
// Cached object for cookies API. // Cached object for cookies API.

View file

@ -13,8 +13,8 @@ app.on('window-all-closed', function() {
// Parse command line options. // Parse command line options.
var argv = process.argv.slice(1); var argv = process.argv.slice(1);
var option = { file: null, help: null, version: null, webdriver: null }; var option = { file: null, help: null, version: null, webdriver: null, modules: [] };
for (var i in argv) { for (var i = 0; i < argv.length; i++) {
if (argv[i] == '--version' || argv[i] == '-v') { if (argv[i] == '--version' || argv[i] == '-v') {
option.version = true; option.version = true;
break; break;
@ -23,6 +23,9 @@ for (var i in argv) {
break; break;
} else if (argv[i] == '--test-type=webdriver') { } else if (argv[i] == '--test-type=webdriver') {
option.webdriver = true; option.webdriver = true;
} else if (argv[i] == '--require' || argv[i] == '-r') {
option.modules.push(argv[++i]);
continue;
} else if (argv[i][0] == '-') { } else if (argv[i][0] == '-') {
continue; continue;
} else { } else {
@ -212,6 +215,10 @@ app.once('ready', function() {
Menu.setApplicationMenu(menu); Menu.setApplicationMenu(menu);
}); });
if (option.modules.length > 0) {
require('module')._preloadModules(option.modules);
}
// Start the specified app if there is one specified in command line, otherwise // Start the specified app if there is one specified in command line, otherwise
// start the default app. // start the default app.
if (option.file && !option.webdriver) { if (option.file && !option.webdriver) {
@ -253,6 +260,7 @@ if (option.file && !option.webdriver) {
helpMessage += "A path to an Electron application may be specified. The path must be to \n"; helpMessage += "A path to an Electron application may be specified. The path must be to \n";
helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n"; helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
helpMessage += "Options:\n"; helpMessage += "Options:\n";
helpMessage += " -r, --require Module to preload (option can be repeated)";
helpMessage += " -h, --help Print this usage message.\n"; helpMessage += " -h, --help Print this usage message.\n";
helpMessage += " -v, --version Print the version."; helpMessage += " -v, --version Print the version.";
console.log(helpMessage); console.log(helpMessage);

View file

@ -169,9 +169,6 @@ NativeWindowViews::NativeWindowViews(
menu_bar_autohide_(false), menu_bar_autohide_(false),
menu_bar_visible_(false), menu_bar_visible_(false),
menu_bar_alt_pressed_(false), menu_bar_alt_pressed_(false),
#if defined(OS_WIN)
is_minimized_(false),
#endif
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
use_content_size_(false), use_content_size_(false),
resizable_(true) { resizable_(true) {
@ -228,6 +225,9 @@ NativeWindowViews::NativeWindowViews(
window_->Init(params); window_->Init(params);
bool fullscreen = false;
options.Get(switches::kFullscreen, &fullscreen);
#if defined(USE_X11) #if defined(USE_X11)
// Start monitoring window states. // Start monitoring window states.
window_state_watcher_.reset(new WindowStateWatcher(this)); window_state_watcher_.reset(new WindowStateWatcher(this));
@ -253,8 +253,7 @@ NativeWindowViews::NativeWindowViews(
} }
// Before the window is mapped, there is no SHOW_FULLSCREEN_STATE. // Before the window is mapped, there is no SHOW_FULLSCREEN_STATE.
bool fullscreen = false; if (fullscreen) {
if (options.Get(switches::kFullscreen, & fullscreen) && fullscreen) {
state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN")); state_atom_list.push_back(GetAtom("_NET_WM_STATE_FULLSCREEN"));
} }
@ -278,6 +277,12 @@ NativeWindowViews::NativeWindowViews(
bounds = ContentBoundsToWindowBounds(bounds); bounds = ContentBoundsToWindowBounds(bounds);
#if defined(OS_WIN) #if defined(OS_WIN)
// Save initial window state.
if (fullscreen)
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
else
last_window_state_ = ui::SHOW_STATE_NORMAL;
if (!has_frame()) { if (!has_frame()) {
// Set Window style so that we get a minimize and maximize animation when // Set Window style so that we get a minimize and maximize animation when
// frameless. // frameless.
@ -391,11 +396,16 @@ bool NativeWindowViews::IsMinimized() {
void NativeWindowViews::SetFullScreen(bool fullscreen) { void NativeWindowViews::SetFullScreen(bool fullscreen) {
#if defined(OS_WIN) #if defined(OS_WIN)
// There is no native fullscreen state on Windows. // There is no native fullscreen state on Windows.
window_->SetFullscreen(fullscreen); if (fullscreen) {
if (fullscreen) last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
NotifyWindowEnterFullScreen(); NotifyWindowEnterFullScreen();
else } else {
last_window_state_ = ui::SHOW_STATE_NORMAL;
NotifyWindowLeaveFullScreen(); NotifyWindowLeaveFullScreen();
}
// We set the new value after notifying, so we can handle the size event
// correctly.
window_->SetFullscreen(fullscreen);
#else #else
if (IsVisible()) if (IsVisible())
window_->SetFullscreen(fullscreen); window_->SetFullscreen(fullscreen);
@ -807,24 +817,8 @@ void NativeWindowViews::OnWidgetMove() {
#if defined(OS_WIN) #if defined(OS_WIN)
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) { bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
// Windows uses the 4 lower order bits of |command_id| for type-specific std::string command = AppCommandToString(command_id);
// information so we must exclude this when comparing. NotifyWindowExecuteWindowsCommand(command);
static const int sc_mask = 0xFFF0;
if ((command_id & sc_mask) == SC_MINIMIZE) {
NotifyWindowMinimize();
is_minimized_ = true;
} else if ((command_id & sc_mask) == SC_RESTORE) {
if (is_minimized_)
NotifyWindowRestore();
else
NotifyWindowUnmaximize();
is_minimized_ = false;
} else if ((command_id & sc_mask) == SC_MAXIMIZE) {
NotifyWindowMaximize();
} else {
std::string command = AppCommandToString(command_id);
NotifyWindowExecuteWindowsCommand(command);
}
return false; return false;
} }
#endif #endif
@ -844,11 +838,54 @@ void NativeWindowViews::GetDevToolsWindowWMClass(
#if defined(OS_WIN) #if defined(OS_WIN)
bool NativeWindowViews::PreHandleMSG( bool NativeWindowViews::PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) {
// Handle thumbar button click message. switch (message) {
if (message == WM_COMMAND && HIWORD(w_param) == THBN_CLICKED) case WM_COMMAND:
return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param)); // Handle thumbar button click message.
else if (HIWORD(w_param) == THBN_CLICKED)
return false; return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param));
return false;
case WM_SIZE:
// Handle window state change.
HandleSizeEvent(w_param, l_param);
return false;
default:
return false;
}
}
void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
// Here we handle the WM_SIZE event in order to figure out what is the current
// window state and notify the user accordingly.
switch (w_param) {
case SIZE_MAXIMIZED:
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
NotifyWindowMaximize();
break;
case SIZE_MINIMIZED:
last_window_state_ = ui::SHOW_STATE_MINIMIZED;
NotifyWindowMinimize();
break;
case SIZE_RESTORED:
if (last_window_state_ == ui::SHOW_STATE_NORMAL)
return;
switch (last_window_state_) {
case ui::SHOW_STATE_MAXIMIZED:
last_window_state_ = ui::SHOW_STATE_NORMAL;
NotifyWindowUnmaximize();
break;
case ui::SHOW_STATE_MINIMIZED:
if (IsFullscreen()) {
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
NotifyWindowEnterFullScreen();
} else {
last_window_state_ = ui::SHOW_STATE_NORMAL;
NotifyWindowRestore();
}
break;
}
break;
}
} }
#endif #endif

View file

@ -142,6 +142,8 @@ class NativeWindowViews : public NativeWindow,
// MessageHandlerDelegate: // MessageHandlerDelegate:
bool PreHandleMSG( bool PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
void HandleSizeEvent(WPARAM w_param, LPARAM l_param);
#endif #endif
// NativeWindow: // NativeWindow:
@ -178,9 +180,9 @@ class NativeWindowViews : public NativeWindow,
#elif defined(OS_WIN) #elif defined(OS_WIN)
// Weak ref. // Weak ref.
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_; AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
// Records window was whether restored from minimized state or maximized
// state. ui::WindowShowState last_window_state_;
bool is_minimized_;
// In charge of running taskbar related APIs. // In charge of running taskbar related APIs.
TaskbarHost taskbar_host_; TaskbarHost taskbar_host_;
#endif #endif

View file

@ -79,6 +79,9 @@ class FileDialog {
if (!title.empty()) if (!title.empty())
GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str()); GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str());
if (!filterspec.empty())
GetPtr()->SetDefaultExtension(filterspec.front().pszSpec);
SetDefaultFolder(default_path); SetDefaultFolder(default_path);
} }

View file

@ -9,6 +9,7 @@
#include "atom/common/keyboad_util.h" #include "atom/common/keyboad_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/native_web_keyboard_event.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
@ -29,10 +30,10 @@ int VectorToBitArray(const std::vector<T>& vec) {
namespace mate { namespace mate {
template<> template<>
struct Converter<char> { struct Converter<base::char16> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
char* out) { base::char16* out) {
std::string code = base::StringToLowerASCII(V8ToString(val)); base::string16 code = base::UTF8ToUTF16(V8ToString(val));
if (code.length() != 1) if (code.length() != 1)
return false; return false;
*out = code[0]; *out = code[0];
@ -77,6 +78,21 @@ struct Converter<blink::WebInputEvent::Type> {
} }
}; };
template<>
struct Converter<blink::WebMouseEvent::Button> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
blink::WebMouseEvent::Button* out) {
std::string button = base::StringToLowerASCII(V8ToString(val));
if (button == "left")
*out = blink::WebMouseEvent::Button::ButtonLeft;
else if (button == "middle")
*out = blink::WebMouseEvent::Button::ButtonMiddle;
else if (button == "right")
*out = blink::WebMouseEvent::Button::ButtonRight;
return true;
}
};
template<> template<>
struct Converter<blink::WebInputEvent::Modifiers> { struct Converter<blink::WebInputEvent::Modifiers> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
@ -142,16 +158,19 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(
return false; return false;
if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out))) if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out)))
return false; return false;
char code; base::char16 code;
if (!dict.Get("keyCode", &code)) if (!dict.Get("keyCode", &code))
return false; return false;
bool shifted = false; bool shifted = false;
out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted); out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted);
if (out->windowsKeyCode == ui::VKEY_UNKNOWN)
return false;
if (shifted) if (shifted)
out->modifiers |= blink::WebInputEvent::ShiftKey; out->modifiers |= blink::WebInputEvent::ShiftKey;
out->setKeyIdentifierFromWindowsKeyCode(); out->setKeyIdentifierFromWindowsKeyCode();
if (out->type == blink::WebInputEvent::Char ||
out->type == blink::WebInputEvent::RawKeyDown) {
out->text[0] = code;
out->unmodifiedText[0] = code;
}
return true; return true;
} }
@ -176,6 +195,7 @@ bool Converter<blink::WebMouseEvent>::FromV8(
return false; return false;
if (!dict.Get("x", &out->x) || !dict.Get("y", &out->y)) if (!dict.Get("x", &out->x) || !dict.Get("y", &out->y))
return false; return false;
dict.Get("button", &out->button);
dict.Get("globalX", &out->globalX); dict.Get("globalX", &out->globalX);
dict.Get("globalY", &out->globalY); dict.Get("globalY", &out->globalY);
dict.Get("movementX", &out->movementX); dict.Get("movementX", &out->movementX);

View file

@ -191,3 +191,30 @@ proxy-uri = [<proxy-scheme>"://"]<proxy-host>[":"<proxy-port>]
Sets download saving directory. By default, the download directory will be the Sets download saving directory. By default, the download directory will be the
`Downloads` under the respective app folder. `Downloads` under the respective app folder.
### `session.enableNetworkEmulation(options)`
* `options` Object
* `offline` Boolean - Whether to emulate network outage.
* `latency` Double - RTT in ms
* `downloadThroughput` Double - Download rate in Bps
* `uploadThroughput` Double - Upload rate in Bps
Emulates network with the given configuration for the `session`.
```javascript
// To emulate a GPRS connection with 50kbps throughput and 500 ms latency.
window.webContents.session.enableNetworkEmulation({
latency: 500,
downloadThroughput: 6400,
uploadThroughput: 6400
});
// To emulate a network outage.
window.webContents.session.enableNetworkEmulation({offline: true});
```
### `session.disableNetworkEmulation`
Disables any network emulation already active for the `session`. Resets to
the original network configuration.

View file

@ -534,13 +534,13 @@ Sends an input `event` to the page.
For keyboard events, the `event` object also have following properties: For keyboard events, the `event` object also have following properties:
* `keyCode` String (**required**) - A single character that will be sent as * `keyCode` String (**required**) - A single character that will be sent as
keyboard event. Can be any ASCII character on the keyboard, like `a`, `1` keyboard event. Can be any UTF-8 character.
and `=`.
For mouse events, the `event` object also have following properties: For mouse events, the `event` object also have following properties:
* `x` Integer (**required**) * `x` Integer (**required**)
* `y` Integer (**required**) * `y` Integer (**required**)
* `button` String - The button pressed, can be `left`, `middle`, `right`
* `globalX` Integer * `globalX` Integer
* `globalY` Integer * `globalY` Integer
* `movementX` Integer * `movementX` Integer
@ -565,8 +565,11 @@ For the `mouseWheel` event, the `event` object also have following properties:
Begin subscribing for presentation events and captured frames, the `callback` Begin subscribing for presentation events and captured frames, the `callback`
will be called with `callback(frameBuffer)` when there is a presentation event. will be called with `callback(frameBuffer)` when there is a presentation event.
The `frameBuffer` is a `Buffer` that contains raw pixel data, in the format of The `frameBuffer` is a `Buffer` that contains raw pixel data. On most machines,
32bit ARGB. the pixel data is effectively stored in 32bit BGRA format, but the actual
representation depends on the endianness of the processor (most modern
processors are little-endian, on machines with big-endian processors the data
is in 32bit ARGB format).
### `webContents.endFrameSubscription()` ### `webContents.endFrameSubscription()`

View file

@ -143,8 +143,8 @@ working as expected.
### electron-prebuilt ### electron-prebuilt
If you've installed `electron-prebuilt` globally with `npm`, then you need only If you've installed `electron-prebuilt` globally with `npm`, then you will only need
run the following in your app's source directory: to run the following in your app's source directory:
```bash ```bash
electron . electron .
@ -158,7 +158,7 @@ If you've installed it locally, then run:
### Manually Downloaded Electron Binary ### Manually Downloaded Electron Binary
If you downloaded Electron manually, you can also just use the included If you downloaded Electron manually, you can also use the included
binary to execute your app directly. binary to execute your app directly.
#### Windows #### Windows

View file

@ -1,11 +1,11 @@
{ {
"name": "electron", "name": "electron",
"devDependencies": { "devDependencies": {
"asar": "0.8.x", "asar": "^0.8.0",
"coffee-script": "^1.9.2", "coffee-script": "^1.9.2",
"coffeelint": "^1.9.4", "coffeelint": "^1.9.4",
"request": "*", "request": "*",
"runas": "3.x" "runas": "^3.0.0"
}, },
"private": true, "private": true,
"scripts": { "scripts": {

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit 8e443520e695674fd26585cfa24a0ec0b6140c27 Subproject commit 75f7d3fd88ae60026a0717b93e3bf7182f827dc3

2
vendor/node vendored

@ -1 +1 @@
Subproject commit ac25693ad1d4c248e69a89147fd3995c3bf6c946 Subproject commit f4243f5c84a371632d8d72a1a2210a0e994afdcc