From 0d3aaaf0af03eb090df190790143494ad6c86066 Mon Sep 17 00:00:00 2001 From: Ahmed Abdalla Date: Tue, 14 Apr 2015 23:04:19 -0400 Subject: [PATCH 001/155] edits quick-start "The renderer Process" segment --- docs/tutorial/quick-start.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index bbe35988f89f..ce7fda084b41 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -23,10 +23,10 @@ Since atom-shell uses Chromium for displaying web pages, Chromium's multi-processes architecture is also used. Each web page in atom-shell runs in its own process, which is called __the renderer process__. -In normal browsers web pages are usually running in sandboxed environment and -not allowed to access native resources. In atom-shell users are given the power -to use io.js APIs in web pages, so it would be possible to interactive with -low level operating system in web pages with JavaScript. +In normal browsers web pages usually run in a sandboxed environtment and are not +allowed access to native resources. In atom-shell users are given the power to +use io.js APIs in web pages and it is therefore possible to interact with low +level operating system features. ### Differences between main process and renderer process From 378e56e254386a7f1749c368fb9c365cb7188baa Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Tue, 14 Apr 2015 21:03:58 -0700 Subject: [PATCH 002/155] Updated documentation for power-monitor Added two undocumented events, added note that must be used after ready event. --- docs/api/power-monitor.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index 5ead769aa34c..9273e13d9a59 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -1,13 +1,19 @@ # power-monitor The `power-monitor` module is used to monitor the power state change. You can -only use it on the main process. +only use it on the main process. You should not use this module until the `ready` +event of `app` module gets emitted. An example is: ```javascript -require('power-monitor').on('suspend', function() { - console.log('The system is going to sleep'); +var app = require('app'); +var powerMonitor = require('power-monitor'); + +app.on('ready', function() { + powerMonitor.on('suspend', function() { + console.log('The system is going to sleep'); + }); }); ``` @@ -18,3 +24,11 @@ Emitted when the system is suspending. ## Event: resume Emitted when system is resuming. + +## Event: on-ac + +Emitted when the system changes to AC power. + +## Event: on-battery + +Emitted when system changes to battery power. From 2de9123cfdc7e420af60d4fcae3fc6679c0e0318 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Wed, 15 Apr 2015 08:17:10 -0700 Subject: [PATCH 003/155] Update power-monitor.md --- docs/api/power-monitor.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index 9273e13d9a59..4643110f35bb 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -8,10 +8,9 @@ An example is: ```javascript var app = require('app'); -var powerMonitor = require('power-monitor'); app.on('ready', function() { - powerMonitor.on('suspend', function() { + require('power-monitor').on('suspend', function() { console.log('The system is going to sleep'); }); }); From a179e48e3baaf52d9159ab93c409b2b99ed0d558 Mon Sep 17 00:00:00 2001 From: Ahmed Abdalla Date: Wed, 15 Apr 2015 13:58:30 -0400 Subject: [PATCH 004/155] fixes spelling typo --- docs/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ce7fda084b41..224e1328bd77 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -23,7 +23,7 @@ Since atom-shell uses Chromium for displaying web pages, Chromium's multi-processes architecture is also used. Each web page in atom-shell runs in its own process, which is called __the renderer process__. -In normal browsers web pages usually run in a sandboxed environtment and are not +In normal browsers web pages usually run in a sandboxed environment and are not allowed access to native resources. In atom-shell users are given the power to use io.js APIs in web pages and it is therefore possible to interact with low level operating system features. From 3a850b94f5fa48dec577d70f42d65f23c8b09c4e Mon Sep 17 00:00:00 2001 From: Ahmed Abdalla Date: Wed, 15 Apr 2015 14:01:09 -0400 Subject: [PATCH 005/155] removes use of passive voice --- docs/tutorial/quick-start.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 224e1328bd77..d77fd8f6ce8f 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -24,9 +24,9 @@ multi-processes architecture is also used. Each web page in atom-shell runs in its own process, which is called __the renderer process__. In normal browsers web pages usually run in a sandboxed environment and are not -allowed access to native resources. In atom-shell users are given the power to -use io.js APIs in web pages and it is therefore possible to interact with low -level operating system features. +allowed access to native resources. In atom-shell users have the power to use +io.js APIs in web pages and it is therefore possible to interact with low level +operating system features. ### Differences between main process and renderer process From 3971249868180511f2e69749d4ae3239875f7bb4 Mon Sep 17 00:00:00 2001 From: Max Ogden Date: Fri, 17 Apr 2015 11:25:06 -0700 Subject: [PATCH 006/155] Add electron-prebuilt npm instructions to README --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 7b582e6201cf..bbb4aa61e26d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,17 @@ editor](https://github.com/atom/atom). Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can be found on the [releases](https://github.com/atom/electron/releases) page. +You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron +binaries: + +``` +# Install the `electron` command globally in your $PATH +npm install electron-prebuilt -g + +# Install as a development dependency +npm install electron-prebuilt --save-dev +``` + ### Mirrors - [China](https://npm.taobao.org/mirrors/atom-shell) From 51cadc6e901ce5b5e016b4b56476a739f71ba88a Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 18 Apr 2015 01:29:57 +0530 Subject: [PATCH 007/155] nativemate: moved std::set converter --- atom/browser/api/atom_api_content_tracing.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/atom/browser/api/atom_api_content_tracing.cc b/atom/browser/api/atom_api_content_tracing.cc index 28a95aa71e6f..7ebca44f2cb2 100644 --- a/atom/browser/api/atom_api_content_tracing.cc +++ b/atom/browser/api/atom_api_content_tracing.cc @@ -17,20 +17,6 @@ using content::TracingController; namespace mate { -template -struct Converter > { - static v8::Handle ToV8(v8::Isolate* isolate, - const std::set& val) { - v8::Handle result = v8::Array::New( - isolate, static_cast(val.size())); - typename std::set::const_iterator it; - int i; - for (i = 0, it = val.begin(); it != val.end(); ++it, ++i) - result->Set(i, Converter::ToV8(isolate, *it)); - return result; - } -}; - template<> struct Converter { static bool FromV8(v8::Isolate* isolate, From 0d3cc8aaa789bce5da35736af9dc5ea9b37740e3 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Sat, 18 Apr 2015 19:08:22 +0700 Subject: [PATCH 008/155] Fix some draw issues in native mac os window Fix some non-transparent corners and lacking redraw while resizing non-frame window --- atom/browser/native_window_mac.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 668826624b4b..c1864d218395 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -348,6 +348,11 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, [window_ setHasShadow:NO]; [window_ setBackgroundColor:[NSColor clearColor]]; } + + // Fix some non-transparent corners and lacking redraw while resizing non-frame window + if (!has_frame_) { + [window_ setOpaque:NO]; + } // We will manage window's lifetime ourselves. [window_ setReleasedWhenClosed:NO]; From 45f022b9db04c4566dd1513e6d39aa2e126be347 Mon Sep 17 00:00:00 2001 From: SAKATA Sinji Date: Mon, 20 Apr 2015 00:46:00 +0900 Subject: [PATCH 009/155] docs: Atom Shell => Electron in quick-start.md --- docs/tutorial/quick-start.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 0e643d9422a7..fab7f2907bf6 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -2,29 +2,29 @@ ## Introduction -Generally, atom-shell enables you to create desktop applications with pure +Generally, Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native APIs. You could see it as a variant of the io.js runtime which is focused on desktop applications instead of web servers. -It doesn't mean atom-shell is a JavaScript binding to GUI libraries. Instead, -atom-shell uses web pages as its GUI, so you could also see it as a minimal +It doesn't mean Electron is a JavaScript binding to GUI libraries. Instead, +Electron uses web pages as its GUI, so you could also see it as a minimal Chromium browser, controlled by JavaScript. ### The main process -In atom-shell the process that runs `package.json`'s `main` script is called +In Electron the process that runs `package.json`'s `main` script is called __the main process__. The script runs in the main process can display GUI by creating web pages. ### The renderer process -Since atom-shell uses Chromium for displaying web pages, Chromium's -multi-processes architecture is also used. Each web page in atom-shell runs in +Since Electron uses Chromium for displaying web pages, Chromium's +multi-processes architecture is also used. Each web page in Electron runs in its own process, which is called __the renderer process__. In normal browsers web pages are usually running in sandboxed environment and -not allowed to access native resources. In atom-shell users are given the power +not allowed to access native resources. In Electron users are given the power to use io.js APIs in web pages, so it would be possible to interactive with low level operating system in web pages with JavaScript. @@ -44,13 +44,13 @@ native GUI resources in web pages is very dangerous and easy to leak resources. If you want to do GUI operations in web pages, you have to communicate with the main process to do it there. -In atom-shell, we have provided the [ipc](../api/ipc-renderer.md) module for +In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for communication between main process and renderer process. And there is also a [remote](../api/remote.md) module for RPC style communication. -## Write your first atom-shell app +## Write your first Electron app -Generally, an atom-shell app would be structured like this (see the +Generally, an Electron app would be structured like this (see the [hello-atom](https://github.com/dougnukem/hello-atom) repo for reference): ```text @@ -93,7 +93,7 @@ app.on('window-all-closed', function() { app.quit(); }); -// This method will be called when atom-shell has done everything +// This method will be called when Electron has done everything // initialization and ready for creating browser windows. app.on('ready', function() { // Create the browser window. @@ -123,7 +123,7 @@ Finally the `index.html` is the web page you want to show:

Hello World!

We are using node.js - and atom-shell . + and Electron . ``` @@ -133,18 +133,18 @@ Finally the `index.html` is the web page you want to show: After you're done writing your app, you can create a distribution by following the [Application distribution](./application-distribution.md) guide and then execute the packaged app. You can also just use the downloaded -atom-shell binary to execute your app directly. +Electron binary to execute your app directly. On Windows: ```cmd -$ .\atom-shell\atom.exe your-app\ +$ .\electron\atom.exe your-app\ ``` On Linux: ```bash -$ ./atom-shell/atom your-app/ +$ ./electron/atom your-app/ ``` On OS X: @@ -153,5 +153,5 @@ On OS X: $ ./Electron.app/Contents/MacOS/Atom your-app/ ``` -`Electron.app` here is part of the atom-shell's release package, you can download +`Electron.app` here is part of the Electron's release package, you can download it from [here](https://github.com/atom/electron/releases). From 9cf4156928c4f42551865648a16b721a03325de5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 14:05:47 +0800 Subject: [PATCH 010/155] Upgrade node for debugger flags --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index 9f7ab575d78f..2caa321f8b6b 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 9f7ab575d78fa4c50cc5529f15646c8a37eb3258 +Subproject commit 2caa321f8b6bb68838ee48a4c9efb820bf085337 From ee08d98d2e8cfc932a6e11babbe23c81e94c8a6b Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 14 Apr 2015 07:45:34 +0530 Subject: [PATCH 011/155] node: start debugger for node run during a forked process --- atom/app/node_main.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/app/node_main.cc b/atom/app/node_main.cc index 66cf9dcf12e7..dec2443525a8 100644 --- a/atom/app/node_main.cc +++ b/atom/app/node_main.cc @@ -28,6 +28,10 @@ int NodeMain(int argc, char *argv[]) { node::Environment* env = node::CreateEnvironment( gin_env.isolate(), gin_env.context(), argc, argv, exec_argc, exec_argv); + // Start debugger. + if (node::use_debug_agent) + node::StartDebug(env, node::debug_wait_connect); + bool more; do { more = uv_run(env->event_loop(), UV_RUN_ONCE); From 7a52a4cff11ed55387be81ace741d286874ca9b6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 14:10:15 +0800 Subject: [PATCH 012/155] Also enable the debugger --- atom/app/node_main.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/atom/app/node_main.cc b/atom/app/node_main.cc index dec2443525a8..deae0bab4068 100644 --- a/atom/app/node_main.cc +++ b/atom/app/node_main.cc @@ -26,12 +26,19 @@ int NodeMain(int argc, char *argv[]) { JavascriptEnvironment gin_env; node::Environment* env = node::CreateEnvironment( - gin_env.isolate(), gin_env.context(), argc, argv, exec_argc, exec_argv); + gin_env.isolate(), uv_default_loop(), gin_env.context(), argc, argv, + exec_argc, exec_argv); // Start debugger. if (node::use_debug_agent) node::StartDebug(env, node::debug_wait_connect); + node::LoadEnvironment(env); + + // Enable debugger. + if (node::use_debug_agent) + node::EnableDebug(env); + bool more; do { more = uv_run(env->event_loop(), UV_RUN_ONCE); From 88a1c7973c65bdb25894ba996ae92cb9f89d5136 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 14:32:41 +0800 Subject: [PATCH 013/155] Set node::node_isolate to fix crash --- atom/app/node_main.cc | 1 + vendor/node | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/app/node_main.cc b/atom/app/node_main.cc index deae0bab4068..7446a0a71106 100644 --- a/atom/app/node_main.cc +++ b/atom/app/node_main.cc @@ -30,6 +30,7 @@ int NodeMain(int argc, char *argv[]) { exec_argc, exec_argv); // Start debugger. + node::node_isolate = gin_env.isolate(); if (node::use_debug_agent) node::StartDebug(env, node::debug_wait_connect); diff --git a/vendor/node b/vendor/node index 2caa321f8b6b..a17c44028101 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 2caa321f8b6bb68838ee48a4c9efb820bf085337 +Subproject commit a17c44028101d80605556f047a844b3e7ab95677 From 1d148fe2fb0d7013d7d6633539de952e71d756f1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 14:35:57 +0800 Subject: [PATCH 014/155] Remove our own debugger implementation Previously it was used because Node doesn't provide one for latest V8. --- atom/browser/atom_browser_main_parts.cc | 8 - atom/browser/atom_browser_main_parts.h | 2 - atom/browser/node_debugger.cc | 202 ------------------------ atom/browser/node_debugger.h | 59 ------- atom/common/node_bindings.cc | 9 +- filenames.gypi | 2 - 6 files changed, 7 insertions(+), 275 deletions(-) delete mode 100644 atom/browser/node_debugger.cc delete mode 100644 atom/browser/node_debugger.h diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index bcf685e6e3ac..aaf68836d0c3 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -8,7 +8,6 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/browser.h" #include "atom/browser/javascript_environment.h" -#include "atom/browser/node_debugger.h" #include "atom/common/api/atom_bindings.h" #include "atom/common/node_bindings.h" #include "base/command_line.h" @@ -60,16 +59,9 @@ void AtomBrowserMainParts::PostEarlyInitialization() { node_bindings_->Initialize(); - // Support the "--debug" switch. - node_debugger_.reset(new NodeDebugger(js_env_->isolate())); - // Create the global environment. global_env = node_bindings_->CreateEnvironment(js_env_->context()); - // Make sure node can get correct environment when debugging. - if (node_debugger_->IsRunning()) - global_env->AssignToContext(v8::Debug::GetDebugContext()); - // Add atom-shell extended APIs. atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object()); diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index a825862ff9be..6ca0686655ba 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -14,7 +14,6 @@ class AtomBindings; class Browser; class JavascriptEnvironment; class NodeBindings; -class NodeDebugger; class AtomBrowserMainParts : public brightray::BrowserMainParts { public: @@ -46,7 +45,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { scoped_ptr js_env_; scoped_ptr node_bindings_; scoped_ptr atom_bindings_; - scoped_ptr node_debugger_; base::Timer gc_timer_; diff --git a/atom/browser/node_debugger.cc b/atom/browser/node_debugger.cc deleted file mode 100644 index 4e2302763c7e..000000000000 --- a/atom/browser/node_debugger.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/node_debugger.h" - -#include - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/browser/browser_thread.h" -#include "net/socket/tcp_listen_socket.h" - -#include "atom/common/node_includes.h" - -namespace atom { - -namespace { - -// NodeDebugger is stored in Isolate's data, slots 0, 1, 3 have already been -// taken by gin, blink and node, using 2 is a safe option for now. -const int kIsolateSlot = 2; - -const char* kContentLength = "Content-Length"; - -} // namespace - -NodeDebugger::NodeDebugger(v8::Isolate* isolate) - : isolate_(isolate), - thread_("NodeDebugger"), - content_length_(-1), - weak_factory_(this) { - bool use_debug_agent = false; - int port = 5858; - bool wait_for_connection = false; - - std::string port_str; - base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); - if (cmd->HasSwitch("debug")) { - use_debug_agent = true; - port_str = cmd->GetSwitchValueASCII("debug"); - } - if (cmd->HasSwitch("debug-brk")) { - use_debug_agent = true; - wait_for_connection = true; - port_str = cmd->GetSwitchValueASCII("debug-brk"); - } - - if (use_debug_agent) { - if (!port_str.empty()) - base::StringToInt(port_str, &port); - - isolate_->SetData(kIsolateSlot, this); - v8::Debug::SetMessageHandler(DebugMessageHandler); - - if (wait_for_connection) - v8::Debug::DebugBreak(isolate_); - - // Start a new IO thread. - base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; - if (!thread_.StartWithOptions(options)) { - LOG(ERROR) << "Unable to start debugger thread"; - return; - } - - // Start the server in new IO thread. - thread_.message_loop()->PostTask( - FROM_HERE, - base::Bind(&NodeDebugger::StartServer, weak_factory_.GetWeakPtr(), - port)); - } -} - -NodeDebugger::~NodeDebugger() { - thread_.Stop(); -} - -bool NodeDebugger::IsRunning() const { - return thread_.IsRunning(); -} - -void NodeDebugger::StartServer(int port) { - server_ = net::TCPListenSocket::CreateAndListen("127.0.0.1", port, this); - if (!server_) { - LOG(ERROR) << "Cannot start debugger server"; - return; - } -} - -void NodeDebugger::CloseSession() { - accepted_socket_.reset(); -} - -void NodeDebugger::OnMessage(const std::string& message) { - if (message.find("\"type\":\"request\",\"command\":\"disconnect\"}") != - std::string::npos) - CloseSession(); - - base::string16 message16 = base::UTF8ToUTF16(message); - v8::Debug::SendCommand( - isolate_, - reinterpret_cast(message16.data()), message16.size()); - - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::Bind(&v8::Debug::ProcessDebugMessages)); -} - -void NodeDebugger::SendMessage(const std::string& message) { - if (accepted_socket_) { - std::string header = base::StringPrintf( - "%s: %d\r\n\r\n", kContentLength, static_cast(message.size())); - accepted_socket_->Send(header); - accepted_socket_->Send(message); - } -} - -void NodeDebugger::SendConnectMessage() { - accepted_socket_->Send(base::StringPrintf( - "Type: connect\r\n" - "V8-Version: %s\r\n" - "Protocol-Version: 1\r\n" - "Embedding-Host: %s\r\n" - "%s: 0\r\n", - v8::V8::GetVersion(), ATOM_PRODUCT_NAME, kContentLength), true); -} - -// static -void NodeDebugger::DebugMessageHandler(const v8::Debug::Message& message) { - NodeDebugger* self = static_cast( - message.GetIsolate()->GetData(kIsolateSlot)); - - if (self) { - std::string message8(*v8::String::Utf8Value(message.GetJSON())); - self->thread_.message_loop()->PostTask( - FROM_HERE, - base::Bind(&NodeDebugger::SendMessage, self->weak_factory_.GetWeakPtr(), - message8)); - } -} - -void NodeDebugger::DidAccept(net::StreamListenSocket* server, - scoped_ptr socket) { - // Only accept one session. - if (accepted_socket_) { - socket->Send(std::string("Remote debugging session already active"), true); - return; - } - - accepted_socket_ = socket.Pass(); - SendConnectMessage(); -} - -void NodeDebugger::DidRead(net::StreamListenSocket* socket, - const char* data, - int len) { - buffer_.append(data, len); - - do { - if (buffer_.size() == 0) - return; - - // Read the "Content-Length" header. - if (content_length_ < 0) { - size_t pos = buffer_.find("\r\n\r\n"); - if (pos == std::string::npos) - return; - - // We can be sure that the header is "Content-Length: xxx\r\n". - std::string content_length = buffer_.substr(16, pos - 16); - if (!base::StringToInt(content_length, &content_length_)) { - DidClose(accepted_socket_.get()); - return; - } - - // Strip header from buffer. - buffer_ = buffer_.substr(pos + 4); - } - - // Read the message. - if (buffer_.size() >= static_cast(content_length_)) { - std::string message = buffer_.substr(0, content_length_); - buffer_ = buffer_.substr(content_length_); - - OnMessage(message); - - // Get ready for next message. - content_length_ = -1; - } - } while (true); -} - -void NodeDebugger::DidClose(net::StreamListenSocket* socket) { - // If we lost the connection, then simulate a disconnect msg: - OnMessage("{\"seq\":1,\"type\":\"request\",\"command\":\"disconnect\"}"); -} - -} // namespace atom diff --git a/atom/browser/node_debugger.h b/atom/browser/node_debugger.h deleted file mode 100644 index 6ee5b1e20688..000000000000 --- a/atom/browser/node_debugger.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_BROWSER_NODE_DEBUGGER_H_ -#define ATOM_BROWSER_NODE_DEBUGGER_H_ - -#include - -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread.h" -#include "net/socket/stream_listen_socket.h" -#include "v8/include/v8-debug.h" - -namespace atom { - -// Add support for node's "--debug" switch. -class NodeDebugger : public net::StreamListenSocket::Delegate { - public: - explicit NodeDebugger(v8::Isolate* isolate); - virtual ~NodeDebugger(); - - bool IsRunning() const; - - private: - void StartServer(int port); - void CloseSession(); - void OnMessage(const std::string& message); - void SendMessage(const std::string& message); - void SendConnectMessage(); - - static void DebugMessageHandler(const v8::Debug::Message& message); - - // net::StreamListenSocket::Delegate: - void DidAccept(net::StreamListenSocket* server, - scoped_ptr socket) override; - void DidRead(net::StreamListenSocket* socket, - const char* data, - int len) override; - void DidClose(net::StreamListenSocket* socket) override; - - v8::Isolate* isolate_; - - base::Thread thread_; - scoped_ptr server_; - scoped_ptr accepted_socket_; - - std::string buffer_; - int content_length_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(NodeDebugger); -}; - -} // namespace atom - -#endif // ATOM_BROWSER_NODE_DEBUGGER_H_ diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 01df48fdc66c..4a0292e2b51d 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -129,8 +129,7 @@ void NodeBindings::Initialize() { node::g_upstream_node_mode = false; // Init node. - // (we assume it would not node::Init would not modify the parameters under - // embedded mode). + // (we assume node::Init would not modify the parameters under embedded mode). node::Init(nullptr, nullptr, nullptr, nullptr); } @@ -166,7 +165,13 @@ node::Environment* NodeBindings::CreateEnvironment( } void NodeBindings::LoadEnvironment(node::Environment* env) { + if (node::use_debug_agent) + node::StartDebug(env, node::debug_wait_connect); + node::LoadEnvironment(env); + + if (node::use_debug_agent) + node::EnableDebug(env); } void NodeBindings::PrepareMessageLoop() { diff --git a/filenames.gypi b/filenames.gypi index d14c935ab728..586d67c17729 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -148,8 +148,6 @@ 'atom/browser/net/url_request_string_job.h', 'atom/browser/net/url_request_buffer_job.cc', 'atom/browser/net/url_request_buffer_job.h', - 'atom/browser/node_debugger.cc', - 'atom/browser/node_debugger.h', 'atom/browser/ui/accelerator_util.cc', 'atom/browser/ui/accelerator_util.h', 'atom/browser/ui/accelerator_util_mac.mm', From c1737e5c16cfc1a66a5ff354104e29647c7e867b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 15:12:46 +0800 Subject: [PATCH 015/155] Parse the debug args of Node --- atom/common/node_bindings.cc | 6 ++++++ vendor/node | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 4a0292e2b51d..10ab8f4929a4 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -128,6 +128,11 @@ void NodeBindings::Initialize() { node::g_standalone_mode = is_browser_; node::g_upstream_node_mode = false; + // Parse the debug args. + auto args = AtomCommandLine::argv(); + for (const std::string& arg : args) + node::ParseDebugOpt(arg.c_str()); + // Init node. // (we assume node::Init would not modify the parameters under embedded mode). node::Init(nullptr, nullptr, nullptr, nullptr); @@ -165,6 +170,7 @@ node::Environment* NodeBindings::CreateEnvironment( } void NodeBindings::LoadEnvironment(node::Environment* env) { + node::node_isolate = env->isolate(); if (node::use_debug_agent) node::StartDebug(env, node::debug_wait_connect); diff --git a/vendor/node b/vendor/node index a17c44028101..a7e75da3cae4 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit a17c44028101d80605556f047a844b3e7ab95677 +Subproject commit a7e75da3cae48cf6e55fa7c9f13d689f11021795 From 1f580cbb6756955ad9eecfb02b75b0774097987a Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 15 Apr 2015 16:50:25 +0530 Subject: [PATCH 016/155] pm: throw when initialising module before ready event --- atom/browser/api/atom_api_power_monitor.cc | 14 ++++++++++---- atom/browser/api/atom_api_power_monitor.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index 905f61f590ea..58496853f13f 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -4,6 +4,7 @@ #include "atom/browser/api/atom_api_power_monitor.h" +#include "atom/browser/browser.h" #include "base/power_monitor/power_monitor.h" #include "base/power_monitor/power_monitor_device_source.h" #include "native_mate/dictionary.h" @@ -38,8 +39,14 @@ void PowerMonitor::OnResume() { } // static -mate::Handle PowerMonitor::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new PowerMonitor); +v8::Handle PowerMonitor::Create(v8::Isolate* isolate) { + if (!Browser::Get()->is_ready()) { + node::ThrowError("Cannot initialize \"power-monitor\" module" + "before app is ready"); + return v8::Null(isolate); + } + + return CreateHandle(isolate, new PowerMonitor).ToV8(); } } // namespace api @@ -57,9 +64,8 @@ void Initialize(v8::Handle exports, v8::Handle unused, using atom::api::PowerMonitor; v8::Isolate* isolate = context->GetIsolate(); - mate::Handle power_monitor = PowerMonitor::Create(isolate); mate::Dictionary dict(isolate, exports); - dict.Set("powerMonitor", power_monitor); + dict.Set("powerMonitor", PowerMonitor::Create(isolate)); } } // namespace diff --git a/atom/browser/api/atom_api_power_monitor.h b/atom/browser/api/atom_api_power_monitor.h index 2fccc7fd311b..cdd14ff6e859 100644 --- a/atom/browser/api/atom_api_power_monitor.h +++ b/atom/browser/api/atom_api_power_monitor.h @@ -17,7 +17,7 @@ namespace api { class PowerMonitor : public mate::EventEmitter, public base::PowerObserver { public: - static mate::Handle Create(v8::Isolate* isolate); + static v8::Handle Create(v8::Isolate* isolate); protected: PowerMonitor(); From bcfe243b3cf8338e2205943c300ccc4f31b359bc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 19:48:07 +0800 Subject: [PATCH 017/155] Upgrade brightray for #1442 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index ec0a660b0b70..e2539f3550dd 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit ec0a660b0b70e6ea5a4ee760a753b8fac31a5de2 +Subproject commit e2539f3550ddc58f1f4e826b5ff9691485003d39 From 51b5e953f4a64a27efab0c0b6ec023642637716e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 20 Apr 2015 20:04:02 +0800 Subject: [PATCH 018/155] Align the " in #1426 --- atom/browser/api/atom_api_power_monitor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index 58496853f13f..8f87eec07280 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -42,7 +42,7 @@ void PowerMonitor::OnResume() { v8::Handle PowerMonitor::Create(v8::Isolate* isolate) { if (!Browser::Get()->is_ready()) { node::ThrowError("Cannot initialize \"power-monitor\" module" - "before app is ready"); + "before app is ready"); return v8::Null(isolate); } From 21f05fc36381f2ac168fcbae802f2da224061877 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 20 Apr 2015 09:34:32 -0700 Subject: [PATCH 019/155] Update discuss category to electron --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bbb4aa61e26d..a1d4b7382245 100644 --- a/README.md +++ b/README.md @@ -33,5 +33,5 @@ contains documents describing how to build and contribute to Electron. ## Community -There is an [`atom-shell` category on the Atom forums](http://discuss.atom.io/category/atom-shell) +There is an [`electron` category on the Atom forums](http://discuss.atom.io/category/electron) as well as an `#atom-shell` channel on Freenode. From 217e8f4078f74ad395b3f0fc95ff56fd51757f40 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 20 Apr 2015 11:22:50 -0700 Subject: [PATCH 020/155] Add mention of previous name --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a1d4b7382245..643de8cb0507 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Electron [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) +:zap: *formerly known as Atom Shell* :zap: + The Electron framework lets you write cross-platform desktop applications using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and [Chromium](http://www.chromium.org) and is used in the [Atom From 87809e65aac4f4c89cf5eabe79bd25477eacc6a4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 18:55:44 +0800 Subject: [PATCH 021/155] Fix refreshing specs --- spec/api-app-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-app-spec.coffee b/spec/api-app-spec.coffee index 1c88c0277b30..4e6bda2ac1fe 100644 --- a/spec/api-app-spec.coffee +++ b/spec/api-app-spec.coffee @@ -22,4 +22,4 @@ describe 'app module', -> assert.equal app.getName(), 'Electron Test' app.setName 'test-name' assert.equal app.getName(), 'test-name' - app.setName 'Electron Test App' + app.setName 'Electron Test' From 32f0ae5b50ed8541fd86586251716079e8275e86 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 18:56:00 +0800 Subject: [PATCH 022/155] Upgrade to Chrome 42 --- script/lib/config.py | 2 +- vendor/brightray | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script/lib/config.py b/script/lib/config.py index 7fb314ac9a27..f0ddbd61caf7 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -7,7 +7,7 @@ import sys BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'f1ad1412461ba3345a27cfe935ffc872dba0ac5b' +LIBCHROMIUMCONTENT_COMMIT = '9fe48b05eccb66436f5d37549ee8a35d3a3884af' PLATFORM = { 'cygwin': 'win32', diff --git a/vendor/brightray b/vendor/brightray index e2539f3550dd..10baaa887996 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit e2539f3550ddc58f1f4e826b5ff9691485003d39 +Subproject commit 10baaa8879962e9d2e50d1fbef73af22a51f30d0 From b37c73436b1562caf8198fdae10ebdedcb120b8e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 18:56:08 +0800 Subject: [PATCH 023/155] Fix API changes --- atom/browser/api/atom_api_content_tracing.cc | 10 +++++----- atom/browser/api/atom_api_web_contents.cc | 5 ++--- atom/browser/api/atom_api_web_contents.h | 3 +-- atom/browser/atom_browser_client.cc | 7 ++++--- atom/browser/atom_browser_client.h | 1 - atom/browser/native_window.cc | 3 +-- atom/browser/native_window.h | 2 +- atom/browser/web_view_manager.cc | 7 ++++--- atom/browser/web_view_manager.h | 20 +++++++++---------- .../printing/print_web_view_helper.cc | 9 ++++++--- .../printing/print_web_view_helper_linux.cc | 1 - .../printing/print_web_view_helper_mac.mm | 1 - .../printing/print_web_view_helper_pdf_win.cc | 1 - 13 files changed, 33 insertions(+), 37 deletions(-) diff --git a/atom/browser/api/atom_api_content_tracing.cc b/atom/browser/api/atom_api_content_tracing.cc index 28a95aa71e6f..b5d9cb6c738e 100644 --- a/atom/browser/api/atom_api_content_tracing.cc +++ b/atom/browser/api/atom_api_content_tracing.cc @@ -32,23 +32,23 @@ struct Converter > { }; template<> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, - base::debug::CategoryFilter* out) { + base::trace_event::CategoryFilter* out) { std::string filter; if (!ConvertFromV8(isolate, val, &filter)) return false; - *out = base::debug::CategoryFilter(filter); + *out = base::trace_event::CategoryFilter(filter); return true; } }; template<> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, - base::debug::TraceOptions* out) { + base::trace_event::TraceOptions* out) { std::string options; if (!ConvertFromV8(isolate, val, &options)) return false; diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index e0c433695e74..95e99cf5648b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -315,12 +315,11 @@ content::WebContents* WebContents::GetOwnerWebContents() const { return embedder_web_contents_; } -void WebContents::GuestSizeChanged(const gfx::Size& old_size, - const gfx::Size& new_size) { +void WebContents::GuestSizeChanged(const gfx::Size& new_size) { if (!auto_size_enabled_) return; + GuestSizeChangedDueToAutoSize(guest_size_, new_size); guest_size_ = new_size; - GuestSizeChangedDueToAutoSize(old_size, new_size); } void WebContents::RegisterDestructionCallback( diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 9b2a9cd4e3e4..2578c5c2a418 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -180,8 +180,7 @@ class WebContents : public mate::EventEmitter, void DidAttach(int guest_proxy_routing_id) final; void ElementSizeChanged(const gfx::Size& size) final; content::WebContents* GetOwnerWebContents() const final; - void GuestSizeChanged(const gfx::Size& old_size, - const gfx::Size& new_size) final; + void GuestSizeChanged(const gfx::Size& new_size) final; void RegisterDestructionCallback(const DestructionCallback& callback) final; void SetGuestSizer(content::GuestSizer* guest_sizer) final; void WillAttach(content::WebContents* embedder_web_contents, diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index ef76693b2c27..2a246f227647 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -79,7 +79,6 @@ void AtomBrowserClient::ResourceDispatcherHostCreated() { void AtomBrowserClient::OverrideWebkitPrefs( content::RenderViewHost* render_view_host, - const GURL& url, content::WebPreferences* prefs) { prefs->javascript_enabled = true; prefs->web_security_enabled = true; @@ -99,7 +98,9 @@ void AtomBrowserClient::OverrideWebkitPrefs( prefs->allow_running_insecure_content = false; // Turn off web security for devtools. - if (url.SchemeIs("chrome-devtools")) { + auto web_contents = content::WebContents::FromRenderViewHost( + render_view_host); + if (web_contents && web_contents->GetURL().SchemeIs("chrome-devtools")) { prefs->web_security_enabled = false; return; } @@ -115,7 +116,7 @@ void AtomBrowserClient::OverrideWebkitPrefs( NativeWindow* window = NativeWindow::FromRenderView( process->GetID(), render_view_host->GetRoutingID()); if (window) - window->OverrideWebkitPrefs(url, prefs); + window->OverrideWebkitPrefs(prefs); } bool AtomBrowserClient::ShouldSwapBrowsingInstancesForNavigation( diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index f35dddac1238..828b3f78f78a 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -26,7 +26,6 @@ class AtomBrowserClient : public brightray::BrowserClient { content::AccessTokenStore* CreateAccessTokenStore() override; void ResourceDispatcherHostCreated() override; void OverrideWebkitPrefs(content::RenderViewHost* render_view_host, - const GURL& url, content::WebPreferences* prefs) override; bool ShouldSwapBrowsingInstancesForNavigation( content::SiteInstance* site_instance, diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 739f1b3a2358..0576fec05761 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -435,8 +435,7 @@ void NativeWindow::AppendExtraCommandLineSwitches( } } -void NativeWindow::OverrideWebkitPrefs(const GURL& url, - content::WebPreferences* prefs) { +void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) { if (web_preferences_.IsEmpty()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d7661bf7487d..b300fce3d7b3 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -192,7 +192,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, // Called when renderer process is going to be started. void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id); - void OverrideWebkitPrefs(const GURL& url, content::WebPreferences* prefs); + void OverrideWebkitPrefs(content::WebPreferences* prefs); // Public API used by platform-dependent delegates and observers to send UI // related notifications. diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index 1fda008d0dc5..91124f911904 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -42,7 +42,8 @@ void WebViewManager::AddGuest(int guest_instance_id, webview_info_map_[guest_process_id] = info; // Map the element in embedder to guest. - ElementInstanceKey key(embedder, element_instance_id); + int owner_process_id = embedder->GetRenderProcessHost()->GetID(); + ElementInstanceKey key(owner_process_id, element_instance_id); element_instance_id_to_guest_map_[key] = guest_instance_id; } @@ -76,9 +77,9 @@ bool WebViewManager::GetInfo(int guest_process_id, WebViewInfo* webview_info) { } content::WebContents* WebViewManager::GetGuestByInstanceID( - content::WebContents* embedder, + int owner_process_id, int element_instance_id) { - ElementInstanceKey key(embedder, element_instance_id); + ElementInstanceKey key(owner_process_id, element_instance_id); if (!ContainsKey(element_instance_id_to_guest_map_, key)) return nullptr; diff --git a/atom/browser/web_view_manager.h b/atom/browser/web_view_manager.h index f87284c39e82..87f3c5699433 100644 --- a/atom/browser/web_view_manager.h +++ b/atom/browser/web_view_manager.h @@ -50,9 +50,8 @@ class WebViewManager : public content::BrowserPluginGuestManager { protected: // content::BrowserPluginGuestManager: - content::WebContents* GetGuestByInstanceID( - content::WebContents* embedder_web_contents, - int element_instance_id) override; + content::WebContents* GetGuestByInstanceID(int owner_process_id, + int element_instance_id) override; bool ForEachGuest(content::WebContents* embedder, const GuestCallback& callback) override; @@ -65,26 +64,25 @@ class WebViewManager : public content::BrowserPluginGuestManager { std::map web_contents_embdder_map_; struct ElementInstanceKey { - content::WebContents* owner_web_contents; + int embedder_process_id; int element_instance_id; - ElementInstanceKey(content::WebContents* owner_web_contents, - int element_instance_id) - : owner_web_contents(owner_web_contents), + ElementInstanceKey(int embedder_process_id, int element_instance_id) + : embedder_process_id(embedder_process_id), element_instance_id(element_instance_id) {} bool operator<(const ElementInstanceKey& other) const { - if (owner_web_contents != other.owner_web_contents) - return owner_web_contents < other.owner_web_contents; + if (embedder_process_id != other.embedder_process_id) + return embedder_process_id < other.embedder_process_id; return element_instance_id < other.element_instance_id; } bool operator==(const ElementInstanceKey& other) const { - return (owner_web_contents == other.owner_web_contents) && + return (embedder_process_id == other.embedder_process_id) && (element_instance_id == other.element_instance_id); } }; - // (web_contents, element_instance_id) => guest_instance_id + // (embedder_process_id, element_instance_id) => guest_instance_id std::map element_instance_id_to_guest_map_; typedef std::map WebViewInfoMap; diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc index 46718a0c546a..60158f6c1d4c 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc @@ -425,8 +425,10 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient, virtual void didStopLoading(); // blink::WebFrameClient override: - virtual blink::WebFrame* createChildFrame(blink::WebLocalFrame* parent, - const blink::WebString& name); + virtual blink::WebFrame* createChildFrame( + blink::WebLocalFrame* parent, + const blink::WebString& name, + blink::WebSandboxFlags sandboxFlags); virtual void frameDetached(blink::WebFrame* frame); private: @@ -571,7 +573,8 @@ void PrepareFrameAndViewForPrint::didStopLoading() { blink::WebFrame* PrepareFrameAndViewForPrint::createChildFrame( blink::WebLocalFrame* parent, - const blink::WebString& name) { + const blink::WebString& name, + blink::WebSandboxFlags sandboxFlags) { blink::WebFrame* frame = blink::WebLocalFrame::create(this); parent->appendChild(frame); return frame; diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc index 1fb3b260e0be..38bd9114d244 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc @@ -12,7 +12,6 @@ #include "printing/page_size_margins.h" #include "printing/pdf_metafile_skia.h" #include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm index e2ad3da5bc85..93fd06464b37 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm @@ -13,7 +13,6 @@ #include "printing/metafile_skia_wrapper.h" #include "printing/page_size_margins.h" #include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" #include "third_party/WebKit/public/platform/WebCanvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc index c4bd9648905b..f98ee5097cca 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc @@ -14,7 +14,6 @@ #include "printing/pdf_metafile_skia.h" #include "printing/units.h" #include "skia/ext/platform_device.h" -#include "skia/ext/vector_canvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" From 23833cf7f44604bb8d25b2bc1a59f4a0cd8bc32e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 19:01:29 +0800 Subject: [PATCH 024/155] Update user agent --- atom/common/chrome_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/chrome_version.h b/atom/common/chrome_version.h index 1971756871b9..6b2ea8d91a45 100644 --- a/atom/common/chrome_version.h +++ b/atom/common/chrome_version.h @@ -8,7 +8,7 @@ #ifndef ATOM_COMMON_CHROME_VERSION_H_ #define ATOM_COMMON_CHROME_VERSION_H_ -#define CHROME_VERSION_STRING "41.0.2272.76" +#define CHROME_VERSION_STRING "42.0.2311.107" #define CHROME_VERSION "v" CHROME_VERSION_STRING #endif // ATOM_COMMON_CHROME_VERSION_H_ From c910686b01c39de1ff8a618159b918a30b6902ba Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 19:06:28 +0800 Subject: [PATCH 025/155] mac: Update brightray to fix Release linking --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 10baaa887996..ede706c109a0 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 10baaa8879962e9d2e50d1fbef73af22a51f30d0 +Subproject commit ede706c109a0e5b8d9103b1502ade353872e7b9e From 5126f02184bdaed184df7fd204d38e0d096cfe65 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 20:01:07 +0800 Subject: [PATCH 026/155] Update the commit of libchromiumcontent to download --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index f0ddbd61caf7..ed050590ff9d 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -7,7 +7,7 @@ import sys BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '9fe48b05eccb66436f5d37549ee8a35d3a3884af' +LIBCHROMIUMCONTENT_COMMIT = '0529dc17ca2f950b671cf12f82260cc397b4cebb' PLATFORM = { 'cygwin': 'win32', From 38583ca721f61459efc08765a30dcda6e87fa87a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 21 Apr 2015 21:43:53 +0800 Subject: [PATCH 027/155] linux: Update brightray to fix crash --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index ede706c109a0..685435ae679a 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit ede706c109a0e5b8d9103b1502ade353872e7b9e +Subproject commit 685435ae679affcfcb095c546b3e884cbbc9f898 From a213a8639f6466e9c4f510ca910c5e90d2f7ed62 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 22 Apr 2015 10:04:30 +0800 Subject: [PATCH 028/155] win: OpenItemViaShell is removed --- atom/common/platform_util_win.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 78fb0ca00540..1998b8873189 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -128,7 +129,10 @@ void ShowItemInFolder(const base::FilePath& full_path) { } void OpenItem(const base::FilePath& full_path) { - ui::win::OpenItemViaShell(full_path); + if (base::DirectoryExists(full_path)) + ui::win::OpenFolderViaShell(full_path); + else + ui::win::OpenFileViaShell(full_path); } void OpenExternal(const GURL& url) { From 20c15302782872a7a70873df1a6f0dbef929e544 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 22 Apr 2015 10:12:16 +0800 Subject: [PATCH 029/155] win: Update referenced symbols on x64 --- common.gypi | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/common.gypi b/common.gypi index 4ae5e9e77c00..4109fb2e1b4f 100644 --- a/common.gypi +++ b/common.gypi @@ -128,15 +128,16 @@ ], }, { 'reference_symbols': [ - 'u_errorName_52', - 'ubidi_setPara_52', - 'ucsdet_getName_52', - 'uidna_openUTS46_52', - 'ulocdata_close_52', - 'uregex_matches_52', - 'uscript_getCode_52', - 'usearch_setPattern_52', - '?createInstance@Transliterator@icu_52@@SAPEAV12@AEBVUnicodeString@2@W4UTransDirection@@AEAW4UErrorCode@@@Z' + 'u_errorName_54', + 'ubidi_setPara_54', + 'ucsdet_getName_54', + 'uidna_openUTS46_54', + 'ulocdata_close_54', + 'unorm_normalize_54', + 'uregex_matches_54', + 'uscript_getCode_54', + 'usearch_setPattern_54', + '?createInstance@Transliterator@icu_54@@SAPEAV12@AEBVUnicodeString@2@W4UTransDirection@@AEAW4UErrorCode@@@Z', ], }], ], From b44c66b5c286a7d0cd648c0d3e84104ebb0d1adc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 22 Apr 2015 12:08:04 +0800 Subject: [PATCH 030/155] win: Update referenced symbols on ia32 --- common.gypi | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/common.gypi b/common.gypi index 4109fb2e1b4f..c6f3320c0a5b 100644 --- a/common.gypi +++ b/common.gypi @@ -115,16 +115,16 @@ 'conditions': [ ['target_arch=="ia32"', { 'reference_symbols': [ - '_u_errorName_52', - '_ubidi_setPara_52', - '_ucsdet_getName_52', - '_ulocdata_close_52', - '_uregex_matches_52', - '_uscript_getCode_52', - '_usearch_setPattern_52', - '?createInstance@Transliterator@icu_52@@SAPAV12@ABVUnicodeString@2@W4UTransDirection@@AAW4UErrorCode@@@Z', - '?nameToUnicodeUTF8@IDNA@icu_52@@UBEXABVStringPiece@2@AAVByteSink@2@AAVIDNAInfo@2@AAW4UErrorCode@@@Z', - '?kLineOffsetNotFound@Function@v8@@2HB', + '_u_errorName_54', + '_ubidi_setPara_54', + '_ucsdet_getName_54', + '_uidna_openUTS46_54', + '_ulocdata_close_54', + '_unorm_normalize_54', + '_uregex_matches_54', + '_uscript_getCode_54', + '_usearch_setPattern_54', + '?createInstance@Transliterator@icu_54@@SAPAV12@ABVUnicodeString@2@W4UTransDirection@@AAW4UErrorCode@@@Z', ], }, { 'reference_symbols': [ From e3109c9f1f54f7a9ae507acf7447b59415cc57a4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 22 Apr 2015 05:50:55 +0000 Subject: [PATCH 031/155] Bump v0.25.0 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- vendor/brightray | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/atom.gyp b/atom.gyp index 0e391a998f42..c6d39d544312 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.24.0', + 'version%': '0.25.0', 'atom_source_root': 'CFBundleIconFile atom.icns CFBundleVersion - 0.24.0 + 0.25.0 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 9004d559012d..2c672eeb731d 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,24,0,0 - PRODUCTVERSION 0,24,0,0 + FILEVERSION 0,25,0,0 + PRODUCTVERSION 0,25,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.24.0" + VALUE "FileVersion", "0.25.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.24.0" + VALUE "ProductVersion", "0.25.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 2223747054d8..6ccc153d9357 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,7 +6,7 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 24 +#define ATOM_MINOR_VERSION 25 #define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/vendor/brightray b/vendor/brightray index 685435ae679a..1ed1eb27098f 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 685435ae679affcfcb095c546b3e884cbbc9f898 +Subproject commit 1ed1eb27098f7148440e6d23fd491efb3ba12a49 From bc04e951cf2fdb7bcb5d6c8ae7ba108de72d585b Mon Sep 17 00:00:00 2001 From: Brennan Novak Date: Wed, 22 Apr 2015 16:22:08 +0200 Subject: [PATCH 032/155] updated bash path to ./Electron.app/Contents/MacOS/Electron it had the trailing /Atom which no longer exists --- docs/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index adbe0a912a3e..d664b7772156 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -149,7 +149,7 @@ $ ./electron/electron your-app/ On OS X: ```bash -$ ./Electron.app/Contents/MacOS/Atom your-app/ +$ ./Electron.app/Contents/MacOS/Electron your-app/ ``` `Electron.app` here is part of the Electron's release package, you can download From ec4d596189c172d9f17d0467b1806def2582b984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20H=C3=A4mmerle?= Date: Wed, 22 Apr 2015 22:14:50 +0200 Subject: [PATCH 033/155] Update quick-start.md --- docs/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index adbe0a912a3e..1118b61a5b31 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -121,7 +121,7 @@ Finally the `index.html` is the web page you want to show:

Hello World!

- We are using node.js + We are using io.js and Electron . From 4a6066c69ed8cf0f8c505fcc44b3ab860e3c141c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Apr 2015 10:22:09 +0800 Subject: [PATCH 034/155] Update native_mate --- vendor/native_mate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/native_mate b/vendor/native_mate index 40da835cbb7a..047a8de9342a 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 40da835cbb7a5f76aacebf9d3ee4b66a62cece71 +Subproject commit 047a8de9342a3217a8d8316f77b9276e8eb7a649 From 4983ef77bd3382c6c05e31a33b95621abbe5bc69 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 20 Apr 2015 15:27:51 +0530 Subject: [PATCH 035/155] module: remove system paths from search --- atom/browser/lib/init.coffee | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 9ef590dc6265..8bd264cf5f83 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -9,6 +9,25 @@ process.argv.splice 1, 1 # Add browser/api/lib to require's search paths, # which contains javascript part of Atom's built-in libraries. +homeDir = + if process.platform is 'win32' + process.env.USERPROFILE + else + process.env.HOME + +syspath = [] + +if homeDir + syspath.push(path.resolve(homeDir, '.node_modules')) + syspath.push(path.resolve(homeDir, '.node_libraries')) + +# Remove system paths from module lookups as it may contain modules not +# shipped with the app or compiled with wrong v8 headers. +syspath.map (path) -> + index = module.globalPaths.indexOf path + if index > -1 + module.globalPaths.splice(index,1) + globalPaths = module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') From fad977e27db424e1a48a96f51286562955586819 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Apr 2015 13:13:58 +0800 Subject: [PATCH 036/155] Simplify how we remove user-defined search paths --- atom/browser/lib/init.coffee | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 8bd264cf5f83..fec5a64ac07e 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -7,28 +7,21 @@ util = require 'util' # we need to restore it here. process.argv.splice 1, 1 -# Add browser/api/lib to require's search paths, -# which contains javascript part of Atom's built-in libraries. +# Global module search paths. +globalPaths = module.globalPaths + +# Don't lookup modules in user-defined search paths, see http://git.io/vf8sF. homeDir = if process.platform is 'win32' process.env.USERPROFILE else process.env.HOME +if homeDir # Node only add user-defined search paths when $HOME is defined. + userModulePath = path.resolve homeDir, '.node_modules' + globalPaths.splice globalPaths.indexOf(userModulePath), 2 -syspath = [] - -if homeDir - syspath.push(path.resolve(homeDir, '.node_modules')) - syspath.push(path.resolve(homeDir, '.node_libraries')) - -# Remove system paths from module lookups as it may contain modules not -# shipped with the app or compiled with wrong v8 headers. -syspath.map (path) -> - index = module.globalPaths.indexOf path - if index > -1 - module.globalPaths.splice(index,1) - -globalPaths = module.globalPaths +# Add browser/api/lib to module search paths, which contains javascript part of +# Electron's built-in libraries. globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') # Import common settings. From 500d15f53adc1979674160bd090525e9f0c0710e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Apr 2015 13:17:18 +0800 Subject: [PATCH 037/155] Also remove user-defined search paths in renderer --- atom/browser/lib/init.coffee | 18 +++--------------- atom/common/lib/init.coffee | 14 +++++++++++++- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index fec5a64ac07e..fcff0d890331 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -1,27 +1,15 @@ fs = require 'fs' path = require 'path' -module = require 'module' util = require 'util' +Module = require 'module' # We modified the original process.argv to let node.js load the atom.js, # we need to restore it here. process.argv.splice 1, 1 -# Global module search paths. -globalPaths = module.globalPaths - -# Don't lookup modules in user-defined search paths, see http://git.io/vf8sF. -homeDir = - if process.platform is 'win32' - process.env.USERPROFILE - else - process.env.HOME -if homeDir # Node only add user-defined search paths when $HOME is defined. - userModulePath = path.resolve homeDir, '.node_modules' - globalPaths.splice globalPaths.indexOf(userModulePath), 2 - # Add browser/api/lib to module search paths, which contains javascript part of # Electron's built-in libraries. +globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') # Import common settings. @@ -101,4 +89,4 @@ app.setPath 'userCache', path.join(app.getPath('cache'), app.getName()) require './chrome-extension' # Finally load app's main.js and transfer control to C++. -module._load path.join(packagePath, packageJson.main), module, true +Module._load path.join(packagePath, packageJson.main), Module, true diff --git a/atom/common/lib/init.coffee b/atom/common/lib/init.coffee index 4fd1f8289d55..88b32d8c0254 100644 --- a/atom/common/lib/init.coffee +++ b/atom/common/lib/init.coffee @@ -10,8 +10,20 @@ process.atomBinding = (name) -> catch e process.binding "atom_common_#{name}" if /No such module/.test e.message -# Add common/api/lib to module search paths. +# Global module search paths. globalPaths = Module.globalPaths + +# Don't lookup modules in user-defined search paths, see http://git.io/vf8sF. +homeDir = + if process.platform is 'win32' + process.env.USERPROFILE + else + process.env.HOME +if homeDir # Node only add user-defined search paths when $HOME is defined. + userModulePath = path.resolve homeDir, '.node_modules' + globalPaths.splice globalPaths.indexOf(userModulePath), 2 + +# Add common/api/lib to module search paths. globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') # setImmediate and process.nextTick makes use of uv_check and uv_prepare to From ba7e26539f9d5bc814d763727d2c34f5f9a7b15c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Apr 2015 13:27:11 +0800 Subject: [PATCH 038/155] Upgrade brightray for #1462 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 1ed1eb27098f..32ba91f830a1 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 1ed1eb27098f7148440e6d23fd491efb3ba12a49 +Subproject commit 32ba91f830a12f6f37017797b9b65d55037ad29d From fb78169396cb34fdc52b473142ef178cd1066cc9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Apr 2015 13:28:29 +0800 Subject: [PATCH 039/155] Don't add tag in bump-version.py It will be done by GitHub Releases. --- script/bump-version.py | 1 - 1 file changed, 1 deletion(-) diff --git a/script/bump-version.py b/script/bump-version.py index 59ff0a73306f..f910ae3ef95f 100755 --- a/script/bump-version.py +++ b/script/bump-version.py @@ -114,7 +114,6 @@ def update_info_plist(version): def tag_version(version): execute(['git', 'commit', '-a', '-m', 'Bump v{0}'.format(version)]) - execute(['git', 'tag', 'v{0}'.format(version)]) if __name__ == '__main__': From 67bc4afe884f765622dcc3069fb6977844fb5e04 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 23 Apr 2015 13:29:34 +0800 Subject: [PATCH 040/155] Bump v0.25.1 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index c6d39d544312..0da56c6d411d 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.25.0', + 'version%': '0.25.1', 'atom_source_root': 'CFBundleIconFile atom.icns CFBundleVersion - 0.25.0 + 0.25.1 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 2c672eeb731d..35713277625b 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,25,0,0 - PRODUCTVERSION 0,25,0,0 + FILEVERSION 0,25,1,0 + PRODUCTVERSION 0,25,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.25.0" + VALUE "FileVersion", "0.25.1" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.25.0" + VALUE "ProductVersion", "0.25.1" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 6ccc153d9357..229ab7e94b55 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 25 -#define ATOM_PATCH_VERSION 0 +#define ATOM_PATCH_VERSION 1 #define ATOM_VERSION_IS_RELEASE 1 From 20b4cae980cf45c336e235128aaac2032bf7953e Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 21 Apr 2015 19:05:36 +0530 Subject: [PATCH 041/155] window: supports HTML5 fullscreen api --- atom/browser/native_window.cc | 14 ++++++++++++++ atom/browser/native_window.h | 7 ++++++- atom/browser/native_window_mac.h | 2 +- atom/browser/native_window_mac.mm | 2 +- atom/browser/native_window_views.cc | 2 +- atom/browser/native_window_views.h | 2 +- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 0576fec05761..c2ed3b0fe79e 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -685,6 +685,20 @@ void NativeWindow::RendererResponsive(content::WebContents* source) { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive()); } +void NativeWindow::EnterFullscreenModeForTab(content::WebContents* source, + const GURL& origin) { + SetFullScreen(true); +} + +void NativeWindow::ExitFullscreenModeForTab(content::WebContents* source) { + SetFullScreen(false); +} + +bool NativeWindow::IsFullscreenForTabOrPending( + const content::WebContents* source) const { + return IsFullscreen(); +} + void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) { // Do nothing, we override this method just to avoid compilation error since // there are two virtual functions named BeforeUnloadFired. diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index b300fce3d7b3..b1f1a384b8bb 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -112,7 +112,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, virtual void Restore() = 0; virtual bool IsMinimized() = 0; virtual void SetFullScreen(bool fullscreen) = 0; - virtual bool IsFullscreen() = 0; + virtual bool IsFullscreen() const = 0; virtual void SetSize(const gfx::Size& size) = 0; virtual gfx::Size GetSize() = 0; virtual void SetContentSize(const gfx::Size& size) = 0; @@ -273,6 +273,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, const content::WebContents* source) const override; void RendererUnresponsive(content::WebContents* source) override; void RendererResponsive(content::WebContents* source) override; + void EnterFullscreenModeForTab(content::WebContents* source, + const GURL& origin) override; + void ExitFullscreenModeForTab(content::WebContents* source) override; + bool IsFullscreenForTabOrPending( + const content::WebContents* source) const override; // Implementations of content::WebContentsObserver. void RenderViewCreated(content::RenderViewHost* render_view_host) override; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index d21b207841e2..822594038a5a 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -44,7 +44,7 @@ class NativeWindowMac : public NativeWindow { void Restore() override; bool IsMinimized() override; void SetFullScreen(bool fullscreen) override; - bool IsFullscreen() override; + bool IsFullscreen() const override; void SetSize(const gfx::Size& size) override; gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 668826624b4b..ce4bc8775f4f 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -476,7 +476,7 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) { [window_ toggleFullScreen:nil]; } -bool NativeWindowMac::IsFullscreen() { +bool NativeWindowMac::IsFullscreen() const { return [window_ styleMask] & NSFullScreenWindowMask; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 9dc0709946de..1ef0a63680c9 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -369,7 +369,7 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) { #endif } -bool NativeWindowViews::IsFullscreen() { +bool NativeWindowViews::IsFullscreen() const { return window_->IsFullscreen(); } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 56d77afa2680..6ec3f2aef438 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -49,7 +49,7 @@ class NativeWindowViews : public NativeWindow, void Restore() override; bool IsMinimized() override; void SetFullScreen(bool fullscreen) override; - bool IsFullscreen() override; + bool IsFullscreen() const override; void SetSize(const gfx::Size& size) override; gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; From cdb1711fe17a85698dc77076541e534f9e884beb Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 22 Apr 2015 13:00:10 +0530 Subject: [PATCH 042/155] webview: add inspectElement method --- atom/browser/api/atom_api_web_contents.cc | 8 ++++++++ atom/browser/api/atom_api_web_contents.h | 1 + atom/renderer/lib/web-view/web-view.coffee | 1 + docs/api/web-view-tag.md | 7 +++++++ 4 files changed, 17 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 95e99cf5648b..f4a36a863128 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -470,6 +470,13 @@ bool WebContents::IsDevToolsOpened() { return storage_->IsDevToolsViewShowing(); } +void WebContents::InspectElement(int x, int y) { + OpenDevTools(); + scoped_refptr agent( + content::DevToolsAgentHost::GetOrCreateFor(storage_->GetWebContents())); + agent->InspectElement(x, y); +} + void WebContents::Undo() { web_contents()->Undo(); } @@ -591,6 +598,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("openDevTools", &WebContents::OpenDevTools) .SetMethod("closeDevTools", &WebContents::CloseDevTools) .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened) + .SetMethod("inspectElement", &WebContents::InspectElement) .SetMethod("undo", &WebContents::Undo) .SetMethod("redo", &WebContents::Redo) .SetMethod("cut", &WebContents::Cut) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 2578c5c2a418..990cbcdd59d0 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -67,6 +67,7 @@ class WebContents : public mate::EventEmitter, void OpenDevTools(); void CloseDevTools(); bool IsDevToolsOpened(); + void InspectElement(int x, int y); // Editing commands. void Undo(); diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index 3058863f7b52..bf163c0cfb5c 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -255,6 +255,7 @@ registerWebViewElement = -> "openDevTools" "closeDevTools" "isDevToolsOpened" + "inspectElement" "undo" "redo" "cut" diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index f8e5cf86f717..ec3bd984c8ba 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -219,6 +219,13 @@ Closes the devtools window of guest page. Returns whether guest page has a devtools window attached. +### ``.inspectElement(x, y) + +* `x` Integer +* `y` Integer + +Starts inspecting element at position (`x`, `y`) of guest page. + ### ``.undo() Executes editing command `undo` in page. From c0f0fcba7b5ddec754a806e2f936dc77df9ce5a4 Mon Sep 17 00:00:00 2001 From: "Machiste N. Quintana" Date: Thu, 23 Apr 2015 16:46:48 -0400 Subject: [PATCH 043/155] Add Electron logo to Readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 643de8cb0507..fae5dda03fc2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Electron [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) +[![Electron Logo](http://electron.atom.io/images/electron-logo-word-lg.png)](http://electron.atom.io/) + :zap: *formerly known as Atom Shell* :zap: The Electron framework lets you write cross-platform desktop applications From 1ae88f0f0f009614a3c03f1704ee1ae4fbb361db Mon Sep 17 00:00:00 2001 From: "Machiste N. Quintana" Date: Thu, 23 Apr 2015 16:50:43 -0400 Subject: [PATCH 044/155] :art: --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fae5dda03fc2..de803ba5f2e4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# Electron [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) - [![Electron Logo](http://electron.atom.io/images/electron-logo-word-lg.png)](http://electron.atom.io/) +[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) + :zap: *formerly known as Atom Shell* :zap: The Electron framework lets you write cross-platform desktop applications From 2157f898bbb94f9bc07eaa558aec86fcca0475ed Mon Sep 17 00:00:00 2001 From: "Machiste N. Quintana" Date: Thu, 23 Apr 2015 17:00:40 -0400 Subject: [PATCH 045/155] Add david-dm dependency status badge to Readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index de803ba5f2e4..256c21845b57 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Electron Logo](http://electron.atom.io/images/electron-logo-word-lg.png)](http://electron.atom.io/) [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) +[![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies) :zap: *formerly known as Atom Shell* :zap: From 00ef99826d3e3f4167018531cf4b49fd83de83e1 Mon Sep 17 00:00:00 2001 From: lazarus Date: Thu, 23 Apr 2015 16:32:41 -0700 Subject: [PATCH 046/155] fix minor text error --- docs/development/coding-style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md index cc697a219dbe..df7f42e4a74e 100644 --- a/docs/development/coding-style.md +++ b/docs/development/coding-style.md @@ -18,7 +18,7 @@ Guide](https://github.com/styleguide/javascript), and also following rules: * File names should be concatenated with `-` instead of `_`, e.g. `file-name.coffee` rather than `file_name.coffee`, because in [github/atom](https://github.com/github/atom) module names are usually in - the `module-name` form, this rule only apply to `.coffee` files. + the `module-name` form, this rule only applies to `.coffee` files. ## API Names From 0a995c3731a6a7fa52de918906f894697b545e52 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 23 Apr 2015 17:00:04 -0700 Subject: [PATCH 047/155] Mention new twitter account --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 256c21845b57..b143e742d699 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and [Chromium](http://www.chromium.org) and is used in the [Atom editor](https://github.com/atom/atom). +Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important +announcements. + ## Downloads Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can From 5c5fd377f7199e5296a58b9dd4577f87bed13589 Mon Sep 17 00:00:00 2001 From: Bhargav Patel Date: Thu, 23 Apr 2015 20:12:04 -0400 Subject: [PATCH 048/155] Minor grammatical fixes Fixed some run-on sentances and changed structor of some. --- docs/tutorial/quick-start.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index e4c5b3472046..d9f6504eb1fa 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -2,41 +2,35 @@ ## Introduction -Generally, Electron enables you to create desktop applications with pure -JavaScript by providing a runtime with rich native APIs. You could see it as -a variant of the io.js runtime which is focused on desktop applications -instead of web servers. +Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native APIs. You could see it as a variant of the io.js runtime which is focused on desktop applications instead of web servers. It doesn't mean Electron is a JavaScript binding to GUI libraries. Instead, Electron uses web pages as its GUI, so you could also see it as a minimal Chromium browser, controlled by JavaScript. -### The main process +### Main process -In Electron the process that runs `package.json`'s `main` script is called -__the main process__. The script runs in the main process can display GUI by +In Electron, the process that runs `package.json`'s `main` script is called +__the main process__. The script that runs in the main process, can display GUI by creating web pages. -### The renderer process +### Renderer process Since Electron uses Chromium for displaying web pages, Chromium's multi-processes architecture is also used. Each web page in Electron runs in its own process, which is called __the renderer process__. In normal browsers web pages usually run in a sandboxed environment and are not -allowed access to native resources. In Electron users have the power to use -io.js APIs in web pages and it is therefore possible to interact with low level -operating system features. +allowed access to native resources. Electron users however, have the power to use +io.js APIs in web pages allowing lower level operating system interactions. ### Differences between main process and renderer process -The main process creates web pages by creating `BrowserWindow` instances, and -each `BrowserWindow` instance runs the web page in its own renderer process, -when a `BrowserWindow` instance is destroyed, the corresponding renderer process +The main process creates web pages by creating `BrowserWindow` instances. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process would also be terminated. -So the main process manages all web pages and their corresponding renderer -processes, and each renderer process is separated from each other and only care +The main process manages all web pages and their corresponding renderer +processes, each renderer process is isolated and only cares about the web page running in it. In web pages, it is not allowed to call native GUI related APIs because managing From 7917748b21c657f7b9ea1e746ea96c54e2dd0d4a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 24 Apr 2015 13:06:49 +0800 Subject: [PATCH 049/155] :arrow_up: asar@0.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07e87364f978..80baded56c4a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "electron", "devDependencies": { - "asar": "0.2.2", + "asar": "0.5.0", "coffee-script": "~1.7.1", "coffeelint": "~1.3.0", "request": "*", From 80c8ab4c39641727f2c37195774de01a1cd16377 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 25 Apr 2015 10:35:28 +0800 Subject: [PATCH 050/155] Style fix --- atom/browser/native_window_mac.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index c1864d218395..1ac7f342a3f1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -348,11 +348,10 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, [window_ setHasShadow:NO]; [window_ setBackgroundColor:[NSColor clearColor]]; } - - // Fix some non-transparent corners and lacking redraw while resizing non-frame window - if (!has_frame_) { + + // Remove non-transparent corners, see http://git.io/vfonD. + if (!has_frame_) [window_ setOpaque:NO]; - } // We will manage window's lifetime ourselves. [window_ setReleasedWhenClosed:NO]; From 81783b255e371f59a12253937914223d9824724f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 25 Apr 2015 10:45:16 +0800 Subject: [PATCH 051/155] Increase timeout for some tests --- spec/api-browser-window-spec.coffee | 1 + spec/api-ipc-spec.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index c723246d94fc..fce7eeb79fa9 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -216,6 +216,7 @@ describe 'browser-window module', -> describe 'will-navigate event', -> it 'emits when user starts a navigation', (done) -> + @timeout 10000 w.webContents.on 'will-navigate', (event, url) -> event.preventDefault() assert.equal url, 'https://www.github.com/' diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index c63997af7e78..d7f77b14ce2e 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -66,6 +66,7 @@ describe 'ipc module', -> assert.equal msg, 'test' it 'does not crash when reply is not sent and browser is destroyed', (done) -> + @timeout 10000 w = new BrowserWindow(show: false) remote.require('ipc').once 'send-sync-message', (event) -> event.returnValue = null From c424d0e9f3224088e739d55498201e5c57da518d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 25 Apr 2015 10:45:28 +0800 Subject: [PATCH 052/155] Upgrade CoffeeScript to 1.9.2 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 80baded56c4a..1942bcbc9a04 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "electron", "devDependencies": { "asar": "0.5.0", - "coffee-script": "~1.7.1", - "coffeelint": "~1.3.0", + "coffee-script": "^1.9.2", + "coffeelint": "^1.9.4", "request": "*", "runas": "^2.0.0" }, From 9b585458c1283f8b78b298ee98662d492d84f559 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 18 Apr 2015 01:25:31 +0530 Subject: [PATCH 053/155] webview: will-navigate and page-favicon-set navigation events --- atom/browser/api/atom_api_web_contents.cc | 13 +++++++++++++ atom/browser/api/atom_api_web_contents.h | 5 +++++ atom/browser/lib/guest-view-manager.coffee | 1 + .../lib/web-view/guest-view-internal.coffee | 1 + .../lib/web-view/web-view-attributes.coffee | 15 ++++++++++++--- docs/api/browser-window.md | 7 +++++++ docs/api/web-view-tag.md | 13 +++++++++++++ spec/fixtures/pages/a.html | 2 ++ spec/webview-spec.coffee | 18 ++++++++++++++++++ 9 files changed, 72 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 95e99cf5648b..dd69a4ee6e16 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -256,6 +256,19 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry, Emit("page-title-set", entry->GetTitle(), explicit_set); } +void WebContents::DidUpdateFaviconURL( + const std::vector& urls) { + std::set unique_urls; + for (auto iter = urls.begin(); iter != urls.end(); ++iter) { + if (iter->icon_type != content::FaviconURL::FAVICON) + continue; + const GURL& url = iter->icon_url; + if (url.is_valid()) + unique_urls.insert(url); + } + Emit("page-favicon-set", unique_urls); +} + bool WebContents::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(WebContents, message) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 2578c5c2a418..384cf29ada92 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -6,10 +6,13 @@ #define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_ #include +#include +#include #include "atom/browser/api/event_emitter.h" #include "brightray/browser/default_web_contents_delegate.h" #include "content/public/browser/browser_plugin_guest_delegate.h" +#include "content/public/common/favicon_url.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "native_mate/handle.h" @@ -175,6 +178,8 @@ class WebContents : public mate::EventEmitter, void NavigationEntryCommitted( const content::LoadCommittedDetails& load_details) override; void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; + void DidUpdateFaviconURL( + const std::vector& urls) override; // content::BrowserPluginGuestDelegate: void DidAttach(int guest_proxy_routing_id) final; diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 51fb9424670f..a949617da49c 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -16,6 +16,7 @@ supportedWebViewEvents = [ 'crashed' 'destroyed' 'page-title-set' + 'page-favicon-set' ] nextInstanceId = 0 diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index 345491030147..19cca6a836fe 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -18,6 +18,7 @@ WEB_VIEW_EVENTS = 'crashed': [] 'destroyed': [] 'page-title-set': ['title', 'explicitSet'] + 'page-favicon-set': ['favicons'] dispatchEvent = (webView, event, args...) -> throw new Error("Unkown event #{event}") unless WEB_VIEW_EVENTS[event]? diff --git a/atom/renderer/lib/web-view/web-view-attributes.coffee b/atom/renderer/lib/web-view/web-view-attributes.coffee index e4b5dcb45bda..eb801eb9771a 100644 --- a/atom/renderer/lib/web-view/web-view-attributes.coffee +++ b/atom/renderer/lib/web-view/web-view-attributes.coffee @@ -154,6 +154,14 @@ class SrcAttribute extends WebViewAttribute not @.getValue() return + domEvent = new Event('will-navigate') + domEvent['url'] = @getValue() + domEvent.cancelable = true + self = @ + domEvent.preventDefault = () -> + self.setValueIgnoreMutation '' + @webViewImpl.webviewNode.dispatchEvent domEvent + unless @webViewImpl.guestInstanceId? if @webViewImpl.beforeFirstNavigation @webViewImpl.beforeFirstNavigation = false @@ -161,9 +169,10 @@ class SrcAttribute extends WebViewAttribute return # Navigate to |this.src|. - httpreferrer = @webViewImpl.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue() - urlOptions = if httpreferrer then {httpreferrer} else {} - remote.getGuestWebContents(@webViewImpl.guestInstanceId).loadUrl @getValue(), urlOptions + if @getValue() + httpreferrer = @webViewImpl.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue() + urlOptions = if httpreferrer then {httpreferrer} else {} + remote.getGuestWebContents(@webViewImpl.guestInstanceId).loadUrl @getValue(), urlOptions # Attribute specifies HTTP referrer. class HttpReferrerAttribute extends WebViewAttribute diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index cb6f9076c793..62eeb332ee66 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -662,6 +662,13 @@ Emitted when details regarding a requested resource is available. Emitted when a redirect was received while requesting a resource. +### Event: 'page-favicon-set' + +* `event` Event +* `favicons` [String] + +Emitted when page receives favicon urls. + ### Event: 'new-window' * `event` Event diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index f8e5cf86f717..b7572eefa8fe 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -275,6 +275,13 @@ examples. ## DOM events +### will-navigate + +* `url` String + +Fired when view is about to navigate , calling `event.preventDefault()` will +cancel the navigation. + ### did-finish-load Fired when the navigation is done, i.e. the spinner of the tab will stop @@ -330,6 +337,12 @@ Fired when a redirect was received while requesting a resource. Fired when page title is set during navigation. `explicitSet` is false when title is synthesised from file url. +### page-favicon-set + +* `favicons` [String] + +Fired when page receives favicon urls. + ### console-message * `level` Integer diff --git a/spec/fixtures/pages/a.html b/spec/fixtures/pages/a.html index a471ad292d87..568973aed1cf 100644 --- a/spec/fixtures/pages/a.html +++ b/spec/fixtures/pages/a.html @@ -1,4 +1,6 @@ + + + + + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 1936731f3541..ea50f632b31c 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -47,6 +47,19 @@ describe ' tag', -> webview.src = "file://#{fixtures}/pages/d.html" document.body.appendChild webview + it 'loads native modules when navigation happens', (done) -> + listener = (e) -> + webview.removeEventListener 'did-finish-load', listener + listener2 = (e) -> + assert.equal e.message, 'function' + done() + webview.addEventListener 'console-message', listener2 + webview.src = "file://#{fixtures}/pages/native-module.html" + webview.addEventListener 'did-finish-load', listener + webview.setAttribute 'nodeintegration', 'on' + webview.src = "file://#{fixtures}/pages/native-module.html" + document.body.appendChild webview + describe 'preload attribute', -> it 'loads the script before other scripts in window', (done) -> listener = (e) -> From 4c78f98da6ea95dc157cecc63d379b33ba1878f6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 17:26:00 +0800 Subject: [PATCH 066/155] Check if it is guest process before updating process ID --- atom/browser/atom_browser_client.cc | 4 ++-- atom/browser/web_view_manager.cc | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 8f1bb41d136d..0ee2c7f93170 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -159,8 +159,8 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( child_process_id = dying_process_id; } else { // It appears that the dying process doesn't belong to a BrowserWindow, - // then it must be a guest process, we should update its process ID in the - // WebViewManager here. + // then it might be a guest process, if it is we should update its + // process ID in the WebViewManager. auto child_process = content::RenderProcessHost::FromID(child_process_id); // Update the process ID in webview guests. WebViewManager::UpdateGuestProcessID(dying_render_process_, diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index 9de3088a0bf5..77a772da9adf 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -41,6 +41,8 @@ void WebViewManager::UpdateGuestProcessID( base::AutoLock auto_lock(manager->lock_); int old_id = old_process->GetID(); int new_id = new_process->GetID(); + if (!ContainsKey(manager->webview_info_map_, old_id)) + return; manager->webview_info_map_[new_id] = manager->webview_info_map_[old_id]; manager->webview_info_map_.erase(old_id); } From 2f1683445b8c7e089576114432575fe5e2ef2807 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 17:26:25 +0800 Subject: [PATCH 067/155] Only append command line params for renderer process --- atom/browser/atom_browser_client.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 0ee2c7f93170..c897d5d19af9 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -138,6 +138,10 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation( void AtomBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { + std::string process_type = command_line->GetSwitchValueASCII("type"); + if (process_type != "renderer") + return; + WindowList* list = WindowList::GetInstance(); NativeWindow* window = nullptr; From 0143a4548869c1e8201ef3c3b6c2e098d5dd5140 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 21:28:30 +0800 Subject: [PATCH 068/155] Implement our own NavigationController --- atom/browser/api/atom_api_web_contents.cc | 63 +-------------- atom/browser/api/atom_api_web_contents.h | 11 +-- .../api/lib/navigation-controller.coffee | 76 +++++++++++++++++++ atom/browser/api/lib/web-contents.coffee | 11 ++- filenames.gypi | 1 + 5 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 atom/browser/api/lib/navigation-controller.coffee diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5853b10d17c8..4e27e1e64e59 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -18,6 +18,7 @@ #include "atom/common/native_mate_converters/value_converter.h" #include "base/strings/utf_string_conversions.h" #include "brightray/browser/inspectable_web_contents.h" +#include "brightray/browser/media/media_stream_devices_controller.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" @@ -30,7 +31,6 @@ #include "content/public/browser/web_contents.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" -#include "vendor/brightray/browser/media/media_stream_devices_controller.h" #include "atom/common/node_includes.h" @@ -312,8 +312,7 @@ void WebContents::WebContentsDestroyed() { void WebContents::NavigationEntryCommitted( const content::LoadCommittedDetails& load_details) { - auto entry = web_contents()->GetController().GetLastCommittedEntry(); - entry->SetVirtualURL(load_details.entry->GetOriginalRequestURL()); + Emit("navigation-entry-commited", load_details.entry->GetURL()); } void WebContents::DidAttach(int guest_proxy_routing_id) { @@ -385,13 +384,6 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { web_contents()->GetController().LoadURLWithParams(params); } -GURL WebContents::GetURL() const { - auto entry = web_contents()->GetController().GetLastCommittedEntry(); - if (!entry) - return GURL::EmptyGURL(); - return entry->GetVirtualURL(); -} - base::string16 WebContents::GetTitle() const { return web_contents()->GetTitle(); } @@ -415,46 +407,8 @@ void WebContents::Stop() { web_contents()->Stop(); } -void WebContents::Reload(const mate::Dictionary& options) { - // Navigating to a URL would always restart the renderer process, we want this - // because normal reloading will break our node integration. - // This is done by AtomBrowserClient::ShouldSwapProcessesForNavigation. - LoadURL(GetURL(), options); -} - -void WebContents::ReloadIgnoringCache(const mate::Dictionary& options) { - // Hack to remove pending entries that ignores cache and treated as a fresh - // load. +void WebContents::ReloadIgnoringCache() { web_contents()->GetController().ReloadIgnoringCache(false); - Reload(options); -} - -bool WebContents::CanGoBack() const { - return web_contents()->GetController().CanGoBack(); -} - -bool WebContents::CanGoForward() const { - return web_contents()->GetController().CanGoForward(); -} - -bool WebContents::CanGoToOffset(int offset) const { - return web_contents()->GetController().CanGoToOffset(offset); -} - -void WebContents::GoBack() { - web_contents()->GetController().GoBack(); -} - -void WebContents::GoForward() { - web_contents()->GetController().GoForward(); -} - -void WebContents::GoToIndex(int index) { - web_contents()->GetController().GoToIndex(index); -} - -void WebContents::GoToOffset(int offset) { - web_contents()->GetController().GoToOffset(offset); } int WebContents::GetRoutingID() const { @@ -599,21 +553,12 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("destroy", &WebContents::Destroy) .SetMethod("isAlive", &WebContents::IsAlive) .SetMethod("_loadUrl", &WebContents::LoadURL) - .SetMethod("getUrl", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("getFavicon", &WebContents::GetFavicon) .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) - .SetMethod("stop", &WebContents::Stop) - .SetMethod("_reload", &WebContents::Reload) + .SetMethod("_stop", &WebContents::Stop) .SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache) - .SetMethod("canGoBack", &WebContents::CanGoBack) - .SetMethod("canGoForward", &WebContents::CanGoForward) - .SetMethod("canGoToOffset", &WebContents::CanGoToOffset) - .SetMethod("goBack", &WebContents::GoBack) - .SetMethod("goForward", &WebContents::GoForward) - .SetMethod("goToIndex", &WebContents::GoToIndex) - .SetMethod("goToOffset", &WebContents::GoToOffset) .SetMethod("getRoutingId", &WebContents::GetRoutingID) .SetMethod("getProcessId", &WebContents::GetProcessID) .SetMethod("isCrashed", &WebContents::IsCrashed) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 4ccf3d8caee3..371c338708cc 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -47,21 +47,12 @@ class WebContents : public mate::EventEmitter, void Destroy(); bool IsAlive() const; void LoadURL(const GURL& url, const mate::Dictionary& options); - GURL GetURL() const; base::string16 GetTitle() const; gfx::Image GetFavicon() const; bool IsLoading() const; bool IsWaitingForResponse() const; void Stop(); - void Reload(const mate::Dictionary& options); - void ReloadIgnoringCache(const mate::Dictionary& options); - bool CanGoBack() const; - bool CanGoForward() const; - bool CanGoToOffset(int offset) const; - void GoBack(); - void GoForward(); - void GoToIndex(int index); - void GoToOffset(int offset); + void ReloadIgnoringCache(); int GetRoutingID() const; int GetProcessID() const; bool IsCrashed() const; diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee new file mode 100644 index 000000000000..8f193de13e8a --- /dev/null +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -0,0 +1,76 @@ +# JavaScript implementation of Chromium's NavigationController. +# Instead of relying on Chromium for history control, we compeletely do history +# control on user land, and only rely on WebContents.loadUrl for navigation. +# This helps us avoid Chromium's various optimizations so we can ensure renderer +# process is restarted everytime. +class NavigationController + constructor: (@webContents) -> + @history = [] + @currentIndex = -1 + @pendingIndex = -1 + + @webContents.on 'navigation-entry-commited', (event, url) => + if @pendingIndex >= 0 # Go to index. + @currentIndex = @pendingIndex + @pendingIndex = -1 + @history[@currentIndex] = url + else # Normal navigation. + @history = @history.slice 0, @currentIndex + 1 # Clear history. + if @history[@currentIndex] isnt url + @currentIndex++ + @history.push url + + loadUrl: (url, options={}) -> + @pendingIndex = -1 + @webContents._loadUrl url, options + + getUrl: -> + if @currentIndex is -1 + '' + else + @history[@currentIndex] + + stop: -> + @pendingIndex = -1 + @webContents._stop() + + reload: -> + @pendingIndex = @currentIndex + @webContents._loadUrl @getUrl(), {} + + reloadIgnoringCache: -> + @webContents._reloadIgnoringCache() # Rely on WebContents to clear cache. + @reload() + + canGoBack: -> + @currentIndex > 0 + + canGoForward: -> + @currentIndex < @history.length + + canGoToIndex: (index) -> + index >=0 and index < @history.length + + canGoToOffset: (offset) -> + @canGoToIndex @currentIndex + offset + + goBack: -> + return unless @canGoBack() + @pendingIndex = @currentIndex - 1 + @webContents._loadUrl @history[@pendingIndex], {} + + goForward: -> + return unless @canGoForward() + @pendingIndex = @currentIndex + 1 + @webContents._loadUrl @history[@pendingIndex], {} + + goToIndex: (index) -> + return unless @canGoToIndex index + @pendingIndex = index + @webContents._loadUrl @history[@pendingIndex], {} + + goToOffset: (offset) -> + return unless @canGoToOffset offset + @goToIndex @currentIndex + offset + +module.exports = NavigationController diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index cb772fd8c27e..e249ccfb808d 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,4 +1,5 @@ EventEmitter = require('events').EventEmitter +NavigationController = require './navigation-controller' binding = process.atomBinding 'web_contents' ipc = require 'ipc' @@ -26,10 +27,12 @@ module.exports.wrap = (webContents) -> webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}" webContents.equal = (other) -> @getId() is other.getId() - # Provide a default parameter for |urlOptions|. - webContents.loadUrl = (url, urlOptions={}) -> @_loadUrl url, urlOptions - webContents.reload = (urlOptions={}) -> @_reload urlOptions - webContents.reloadIgnoringCache = (urlOptions={}) -> @_reloadIgnoringCache urlOptions + # The navigation controller. + controller = new NavigationController(webContents) + webContents.controller = controller + for name, method of NavigationController.prototype when method instanceof Function + do (name, method) -> + webContents[name] = -> method.apply controller, arguments # Translate |disposition| to string for 'new-window' event. webContents.on '-new-window', (args..., disposition) -> diff --git a/filenames.gypi b/filenames.gypi index 586d67c17729..093136805b24 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -18,6 +18,7 @@ 'atom/browser/api/lib/ipc.coffee', 'atom/browser/api/lib/menu.coffee', 'atom/browser/api/lib/menu-item.coffee', + 'atom/browser/api/lib/navigation-controller.coffee', 'atom/browser/api/lib/power-monitor.coffee', 'atom/browser/api/lib/protocol.coffee', 'atom/browser/api/lib/screen.coffee', From 16b2f08cd30064ff4bf1e3d6b931c9fb6ca4480b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 21:31:48 +0800 Subject: [PATCH 069/155] Don't use Chromium's history list --- atom/browser/api/atom_api_web_contents.cc | 2 ++ atom/browser/native_window.cc | 1 + 2 files changed, 3 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 4e27e1e64e59..0400e9457e37 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -140,6 +140,7 @@ content::WebContents* WebContents::OpenURLFromTab( load_url_params.is_renderer_initiated = params.is_renderer_initiated; load_url_params.transferred_global_request_id = params.transferred_global_request_id; + load_url_params.should_clear_history_list = true; web_contents()->GetController().LoadURLWithParams(load_url_params); return web_contents(); @@ -380,6 +381,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { blink::WebReferrerPolicyDefault); params.transition_type = ui::PAGE_TRANSITION_TYPED; + params.should_clear_history_list = true; params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; web_contents()->GetController().LoadURLWithParams(params); } diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c2ed3b0fe79e..0f757e8c619f 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -565,6 +565,7 @@ content::WebContents* NativeWindow::OpenURLFromTab( load_url_params.is_renderer_initiated = params.is_renderer_initiated; load_url_params.transferred_global_request_id = params.transferred_global_request_id; + load_url_params.should_clear_history_list = true; source->GetController().LoadURLWithParams(load_url_params); return source; From dde791d475dd1a4e2952709922b017a6fc08fba1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 22:29:51 +0800 Subject: [PATCH 070/155] Allow calling goBack for multiple times --- .../api/lib/navigation-controller.coffee | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 8f193de13e8a..75f9dd2097ca 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -10,15 +10,15 @@ class NavigationController @pendingIndex = -1 @webContents.on 'navigation-entry-commited', (event, url) => - if @pendingIndex >= 0 # Go to index. - @currentIndex = @pendingIndex - @pendingIndex = -1 - @history[@currentIndex] = url - else # Normal navigation. + if @pendingIndex is -1 # Normal navigation. @history = @history.slice 0, @currentIndex + 1 # Clear history. if @history[@currentIndex] isnt url @currentIndex++ @history.push url + else # Go to index. + @currentIndex = @pendingIndex + @pendingIndex = -1 + @history[@currentIndex] = url loadUrl: (url, options={}) -> @pendingIndex = -1 @@ -43,10 +43,10 @@ class NavigationController @reload() canGoBack: -> - @currentIndex > 0 + @getActiveIndex() > 0 canGoForward: -> - @currentIndex < @history.length + @getActiveIndex() < @history.length - 1 canGoToIndex: (index) -> index >=0 and index < @history.length @@ -56,12 +56,12 @@ class NavigationController goBack: -> return unless @canGoBack() - @pendingIndex = @currentIndex - 1 + @pendingIndex = @getActiveIndex() - 1 @webContents._loadUrl @history[@pendingIndex], {} goForward: -> return unless @canGoForward() - @pendingIndex = @currentIndex + 1 + @pendingIndex = @getActiveIndex() + 1 @webContents._loadUrl @history[@pendingIndex], {} goToIndex: (index) -> @@ -73,4 +73,7 @@ class NavigationController return unless @canGoToOffset offset @goToIndex @currentIndex + offset + getActiveIndex: -> + if @pendingIndex is -1 then @currentIndex else @pendingIndex + module.exports = NavigationController From b5aa2a31a10e13df15205c9fae4970feda570539 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 24 Apr 2015 13:27:19 -0700 Subject: [PATCH 071/155] Make full screen menu a toggler --- atom/browser/default_app/default_app.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index dffe03c628e1..7eeebf9188bc 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -112,11 +112,12 @@ app.on('ready', function() { click: function() { mainWindow.restart(); } }, { - label: 'Enter Fullscreen', - click: function() { mainWindow.setFullScreen(true); } + label: 'Toggle Full Screen', + accelerator: 'Ctrl+Command+F', + click: function() { mainWindow.setFullScreen(!mainWindow.isFullScreen()); } }, { - label: 'Toggle DevTools', + label: 'Toggle Developer Tools', accelerator: 'Alt+Command+I', click: function() { mainWindow.toggleDevTools(); } }, @@ -173,11 +174,12 @@ app.on('ready', function() { click: function() { mainWindow.restart(); } }, { - label: '&Enter Fullscreen', - click: function() { mainWindow.setFullScreen(true); } + label: 'Toggle &Full Screen', + accelerator: 'F11', + click: function() { mainWindow.setFullScreen(!mainWindow.isFullScreen()); } }, { - label: '&Toggle DevTools', + label: 'Toggle &Developer Tools', accelerator: 'Alt+Ctrl+I', click: function() { mainWindow.toggleDevTools(); } }, From e3c21424de55c36d7dd7851c8733fc8af863f436 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 24 Apr 2015 13:32:46 -0700 Subject: [PATCH 072/155] Add default help menu --- atom/browser/default_app/default_app.js | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 7eeebf9188bc..263f563ce52f 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -145,6 +145,23 @@ app.on('ready', function() { }, ] }, + { + label: 'Help', + submenu: [ + { + label: 'Documentation', + click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') } + }, + { + label: 'Community Discussions', + click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') } + }, + { + label: 'Search Issues', + click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') } + } + ] + } ]; menu = Menu.buildFromTemplate(template); @@ -185,6 +202,23 @@ app.on('ready', function() { }, ] }, + { + label: 'Help', + submenu: [ + { + label: 'Documentation', + click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') } + }, + { + label: 'Community Discussions', + click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') } + }, + { + label: 'Search Issues', + click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') } + } + ] + } ]; menu = Menu.buildFromTemplate(template); From f4a27f699a4a50268c8469b0d27198b4764c876b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 24 Apr 2015 13:37:34 -0700 Subject: [PATCH 073/155] Add help menu to electron site --- atom/browser/default_app/default_app.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 263f563ce52f..e471b23ae621 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -148,6 +148,10 @@ app.on('ready', function() { { label: 'Help', submenu: [ + { + label: 'Learn More', + click: function() { require('shell').openExternal('http://electron.atom.io') } + }, { label: 'Documentation', click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') } @@ -205,6 +209,10 @@ app.on('ready', function() { { label: 'Help', submenu: [ + { + label: 'Learn More', + click: function() { require('shell').openExternal('http://electron.atom.io') } + }, { label: 'Documentation', click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') } From da07e72f20df2862c3bdd7cc6c3db61be58a9f68 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 24 Apr 2015 14:02:49 -0700 Subject: [PATCH 074/155] Add -h/--help usage message --- atom/browser/default_app/main.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index bdb88a7cc29a..231e254bdc79 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -11,11 +11,14 @@ app.on('window-all-closed', function() { // Parse command line options. var argv = process.argv.slice(1); -var option = { file: null, version: null, webdriver: null }; +var option = { file: null, help: null, version: null, webdriver: null }; for (var i in argv) { if (argv[i] == '--version' || argv[i] == '-v') { option.version = true; break; + } else if (argv[i] == '--help' || argv[i] == '-h') { + option.help = true; + break; } else if (argv[i] == '--test-type=webdriver') { option.webdriver = true; } else if (argv[i][0] == '-') { @@ -58,7 +61,16 @@ if (option.file && !option.webdriver) { } } } else if (option.version) { - console.log('v' + process.versions['electron']); + console.log('v' + process.versions.electron); + process.exit(0); +} else if (option.help) { + var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n"; + helpMessage += "Usage: electron [options] [path]\n\n"; + helpMessage += "Specify a path to the Electron app to open\n\n"; + helpMessage += "Options:\n"; + helpMessage += " -h, --help Print this usage message.\n"; + helpMessage += " -v, --version Print the version."; + console.log(helpMessage); process.exit(0); } else { require('./default_app.js'); From fdfd8807a0787c5ed323253b7e4051f5cdba8da6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 24 Apr 2015 14:17:15 -0700 Subject: [PATCH 075/155] Tweak path docs --- atom/browser/default_app/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 231e254bdc79..5664fac4cd21 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -66,7 +66,8 @@ if (option.file && !option.webdriver) { } else if (option.help) { var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n"; helpMessage += "Usage: electron [options] [path]\n\n"; - helpMessage += "Specify a path to the Electron app to open\n\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 += "Options:\n"; helpMessage += " -h, --help Print this usage message.\n"; helpMessage += " -v, --version Print the version."; From 0e7970fec5c8667728d6b48e15c94722b1f2ea1d Mon Sep 17 00:00:00 2001 From: Ben Drucker Date: Sun, 26 Apr 2015 19:35:52 -0400 Subject: [PATCH 076/155] Fix grammar in NW.js comparison --- docs/development/atom-shell-vs-node-webkit.md | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/development/atom-shell-vs-node-webkit.md b/docs/development/atom-shell-vs-node-webkit.md index 6844df3556e9..ab8f6ab6dbdc 100644 --- a/docs/development/atom-shell-vs-node-webkit.md +++ b/docs/development/atom-shell-vs-node-webkit.md @@ -3,7 +3,7 @@ __Note: Electron was previously named Atom Shell.__ Like NW.js, Electron provides a platform to write desktop applications -with JavaScript and HTML, and has Node integration to grant access to low level +with JavaScript and HTML and has Node integration to grant access to low level system in web pages. But there are also fundamental differences between the two projects that make @@ -11,39 +11,38 @@ Electron a completely separate product from NW.js: __1. Entry of application__ -In NW.js, the main entry of an application is a web page, you specify a -main page in the `package.json` and it would be opened in a browser window as +In NW.js, the main entry of an application is a web page. You specify a +main page in the `package.json` and it is opened in a browser window as the application's main window. -While in Electron, the entry point is a JavaScript script, instead of -providing a URL directly, you need to manually create a browser window and load -html file in it with corresponding API. You also need to listen to window events +In Electron, the entry point is a JavaScript script. Instead of +providing a URL directly, you manually create a browser window and load +an HTML file using the API. You also need to listen to window events to decide when to quit the application. -So Electron works more like the Node.js runtime, and APIs are more low level, -you can also use Electron for web testing purpose like -[phantomjs](http://phantomjs.org/). +Electron works more like the Node.js runtime. Electron's APIs are lower level +so you can use it for browser testing in place of [PhantomJS](http://phantomjs.org/). __2. Build system__ In order to avoid the complexity of building the whole Chromium, Electron uses [libchromiumcontent](https://github.com/brightray/libchromiumcontent) to access -Chromium's Content API, libchromiumcontent is a single, shared library that -includes the Chromium Content module and all its dependencies. So users don't +Chromium's Content API. libchromiumcontent is a single, shared library that +includes the Chromium Content module and all its dependencies. Users don't need a powerful machine to build Electron. __3. Node integration__ In NW.js, the Node integration in web pages requires patching Chromium to -work, while in Electron we chose a different way to integrate libuv loop to -each platform's message loop to avoid hacking Chromium, see the +work, while in Electron we chose a different way to integrate libuv loop with +each platform's message loop to avoid hacking Chromium. See the [`node_bindings`](../../atom/common/) code for how that was done. __4. Multi-context__ If you are an experienced NW.js user, you should be familiar with the -concept of Node context and web context, these concepts were invented because -of how the NW.js was implemented. +concept of Node context and web context. These concepts were invented because +of how NW.js was implemented. By using the [multi-context](http://strongloop.com/strongblog/whats-new-node-js-v0-12-multiple-context-execution/) feature of Node, Electron doesn't introduce a new JavaScript context in web From 04a0aaa35f5b49e976fa975cacc31a07711576c5 Mon Sep 17 00:00:00 2001 From: "Machiste N. Quintana" Date: Tue, 28 Apr 2015 10:48:54 -0400 Subject: [PATCH 077/155] Logo png -> svg Fixes broken image in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b143e742d699..6afa9b804481 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Electron Logo](http://electron.atom.io/images/electron-logo-word-lg.png)](http://electron.atom.io/) +[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/) [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) [![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies) From fb6c80d12ecbb99a481e1018a0d1d56c3fc4dce3 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Tue, 28 Apr 2015 12:08:31 -0700 Subject: [PATCH 078/155] Create an explicit API for setting the App User Model ID --- atom/browser/api/atom_api_app.cc | 8 ++++++++ atom/browser/api/atom_api_app.h | 1 + 2 files changed, 9 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 37cfaf640395..78de29c1fac3 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -200,6 +200,13 @@ void App::SetDesktopName(const std::string& desktop_name) { #endif } +void App::SetAppUserModelId(const std::string& app_id) { +#if defined(OS_WIN) + base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id); + SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str()); +#endif +} + mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( v8::Isolate* isolate) { auto browser = base::Unretained(Browser::Get()); @@ -223,6 +230,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("getPath", &App::GetPath) .SetMethod("resolveProxy", &App::ResolveProxy) .SetMethod("setDesktopName", &App::SetDesktopName); + .SetMethod("setAppUserModelId", &App::SetAppUserModelId); } // static diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 062d2d083d2a..c2f9212b7ca7 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -61,6 +61,7 @@ class App : public mate::EventEmitter, void ResolveProxy(const GURL& url, ResolveProxyCallback callback); void SetDesktopName(const std::string& desktop_name); + void SetAppUserModelId(const std::string& app_id); DISALLOW_COPY_AND_ASSIGN(App); }; From 7c2b1468c8b65b8063dfcf16f39240bf1b4807ac Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Tue, 28 Apr 2015 15:49:16 -0700 Subject: [PATCH 079/155] Fix typo --- atom/browser/api/atom_api_app.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 78de29c1fac3..95fbbe38d854 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -229,7 +229,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("setPath", &App::SetPath) .SetMethod("getPath", &App::GetPath) .SetMethod("resolveProxy", &App::ResolveProxy) - .SetMethod("setDesktopName", &App::SetDesktopName); + .SetMethod("setDesktopName", &App::SetDesktopName) .SetMethod("setAppUserModelId", &App::SetAppUserModelId); } From 3a50c9e48c1e99bc867815d84bb381f190a3934d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 27 Apr 2015 11:47:26 +0800 Subject: [PATCH 080/155] Update to the new patch for acceptsFirstMouse --- atom/browser/native_window_mac.mm | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 946b2a41cdd4..12a147ebc2b3 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -54,10 +54,8 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; @interface AtomNSWindowDelegate : NSObject { @private atom::NativeWindowMac* shell_; - BOOL acceptsFirstMouse_; } - (id)initWithShell:(atom::NativeWindowMac*)shell; -- (void)setAcceptsFirstMouse:(BOOL)accept; @end @implementation AtomNSWindowDelegate @@ -65,15 +63,10 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; - (id)initWithShell:(atom::NativeWindowMac*)shell { if ((self = [super init])) { shell_ = shell; - acceptsFirstMouse_ = NO; } return self; } -- (void)setAcceptsFirstMouse:(BOOL)accept { - acceptsFirstMouse_ = accept; -} - - (void)windowDidBecomeMain:(NSNotification*)notification { content::WebContents* web_contents = shell_->GetWebContents(); if (!web_contents) @@ -151,10 +144,6 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; return NO; } -- (BOOL)acceptsFirstMouse:(NSEvent*)event { - return acceptsFirstMouse_; -} - @end @interface AtomNSWindow : EventProcessingWindow { @@ -162,6 +151,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; atom::NativeWindowMac* shell_; bool enable_larger_than_screen_; } +@property BOOL acceptsFirstMouse; - (void)setShell:(atom::NativeWindowMac*)shell; - (void)setEnableLargerThanScreen:(bool)enable; @end @@ -355,7 +345,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, // Enable the NSView to accept first mouse event. bool acceptsFirstMouse = false; options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse); - [window_delegate_ setAcceptsFirstMouse:acceptsFirstMouse]; + [window_ setAcceptsFirstMouse:acceptsFirstMouse]; // Disable fullscreen button when 'fullscreen' is specified to false. bool fullscreen; From c6cf91d11f6e570d513e592dfbceafe79a79ca77 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 27 Apr 2015 12:08:22 +0800 Subject: [PATCH 081/155] Add 'disable-auto-hide-cursor' option --- atom/browser/native_window_mac.mm | 6 ++++++ atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + 3 files changed, 10 insertions(+) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 12a147ebc2b3..b7eccd2a6c7c 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -152,6 +152,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; bool enable_larger_than_screen_; } @property BOOL acceptsFirstMouse; +@property BOOL disableAutoHideCursor; - (void)setShell:(atom::NativeWindowMac*)shell; - (void)setEnableLargerThanScreen:(bool)enable; @end @@ -347,6 +348,11 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse); [window_ setAcceptsFirstMouse:acceptsFirstMouse]; + // Disable auto-hiding cursor. + bool disableAutoHideCursor = false; + options.Get(switches::kDisableAutoHideCursor, &disableAutoHideCursor); + [window_ setDisableAutoHideCursor:disableAutoHideCursor]; + // Disable fullscreen button when 'fullscreen' is specified to false. bool fullscreen; if (!(options.Get(switches::kFullscreen, &fullscreen) && diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index f67a6456964c..c479b5004d07 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -75,6 +75,9 @@ const char kTransparent[] = "transparent"; // Window type hint. const char kType[] = "type"; +// Disable auto-hiding cursor. +const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor"; + // Web runtime features. const char kExperimentalFeatures[] = "experimental-features"; const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 967f62638733..546c6a04eb4d 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -41,6 +41,7 @@ extern const char kGuestInstanceID[]; extern const char kPreloadScript[]; extern const char kTransparent[]; extern const char kType[]; +extern const char kDisableAutoHideCursor[]; extern const char kExperimentalFeatures[]; extern const char kExperimentalCanvasFeatures[]; From 75b24c7d7671c12699ec1a4dc8c07e2edd172b29 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Apr 2015 10:28:42 +0800 Subject: [PATCH 082/155] docs: disable-auto-hide-cursor option --- docs/api/browser-window.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 8e6262e9275a..e4cec40f47cf 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -54,9 +54,10 @@ You can also create a window without chrome by using * `frame` Boolean - Specify `false` to create a [Frameless Window](frameless-window.md) * `node-integration` Boolean - Whether node integration is enabled, default - is `true` + is `true` * `accept-first-mouse` Boolean - Whether the web view accepts a single - mouse-down event that simultaneously activates the window + mouse-down event that simultaneously activates the window + * `disable-auto-hide-cursor` Boolean - Do not hide cursor when typing * `auto-hide-menu-bar` Boolean - Auto hide the menu bar unless the `Alt` key is pressed. * `enable-larger-than-screen` Boolean - Enable the window to be resized larger From d8be645d5ab26415d39a201c688b0f176ebd8925 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 29 Apr 2015 08:57:49 +0530 Subject: [PATCH 083/155] webContents: check for navigation entry before using --- atom/browser/api/atom_api_web_contents.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0400e9457e37..d6e0b170ce4d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -258,7 +258,9 @@ void WebContents::DidNavigateMainFrame( void WebContents::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { - Emit("page-title-set", entry->GetTitle(), explicit_set); + // Back/Forward navigation may have pruned entries. + if (entry) + Emit("page-title-set", entry->GetTitle(), explicit_set); } void WebContents::DidUpdateFaviconURL( From 8d3404d26c502a0d9107346d7455480cdb49279b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Apr 2015 15:13:46 +0800 Subject: [PATCH 084/155] win: Fix compilation error --- atom/browser/api/atom_api_app.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 95fbbe38d854..d3b04f043622 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -7,6 +7,10 @@ #include #include +#if defined(OS_WIN) +#include +#endif + #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/browser.h" @@ -25,6 +29,10 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" +#if defined(OS_WIN) +#include "base/strings/utf_string_conversions.h" +#endif + #include "atom/common/node_includes.h" using atom::Browser; From 129cdb768064ec0803f73da5d02aaad712ffe06f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Apr 2015 17:31:56 +0800 Subject: [PATCH 085/155] spec,win: Fix page-favicon-updated event spec --- spec/webview-spec.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index ea50f632b31c..51058ad695e9 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -169,7 +169,12 @@ describe ' tag', -> it 'emits when favicon urls are received', (done) -> webview.addEventListener 'page-favicon-updated', (e) -> assert.equal e.favicons.length, 2 - assert.equal e.favicons[0], 'file:///favicon.png' + url = + if process.platform is 'win32' + 'file:///C:/favicon.png' + else + 'file:///favicon.png' + assert.equal e.favicons[0], url done() webview.src = "file://#{fixtures}/pages/a.html" document.body.appendChild webview From 23afffa46d6cfdb0763f776ce04503e0be46abbf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 29 Apr 2015 17:57:16 +0800 Subject: [PATCH 086/155] Chaning src of webview should always do a load Previously changing src to the same value won't have any effect, which does not follow the behavior of browsers. --- atom/renderer/lib/web-view/web-view-attributes.coffee | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/atom/renderer/lib/web-view/web-view-attributes.coffee b/atom/renderer/lib/web-view/web-view-attributes.coffee index e4b5dcb45bda..05bd6141203f 100644 --- a/atom/renderer/lib/web-view/web-view-attributes.coffee +++ b/atom/renderer/lib/web-view/web-view-attributes.coffee @@ -138,10 +138,7 @@ class SrcAttribute extends WebViewAttribute setupMutationObserver: -> @observer = new MutationObserver (mutations) => for mutation in mutations - oldValue = mutation.oldValue - newValue = @getValue() - return if oldValue isnt newValue - @handleMutation oldValue, newValue + @handleMutation mutation.oldValue, @getValue() params = attributes: true, attributeOldValue: true, From 2b3ef714bd42df4d9e485489cb3e903226102d96 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 29 Apr 2015 13:56:31 -0400 Subject: [PATCH 087/155] Enable syntax highlighting in README Primarily to fade the comments in the code block --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6afa9b804481..44f37efdbefa 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ be found on the [releases](https://github.com/atom/electron/releases) page. You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron binaries: -``` +```sh # Install the `electron` command globally in your $PATH npm install electron-prebuilt -g From 8c5f171a93217210223cde1cf182d08044d35727 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 29 Apr 2015 19:19:31 +0530 Subject: [PATCH 088/155] webContents: providing dom-ready event --- atom/browser/api/atom_api_web_contents.cc | 6 ++++++ atom/browser/api/atom_api_web_contents.h | 2 ++ atom/browser/lib/guest-view-manager.coffee | 1 + .../lib/web-view/guest-view-internal.coffee | 1 + docs/api/browser-window.md | 6 ++++++ docs/api/web-view-tag.md | 4 ++++ spec/api-browser-window-spec.coffee | 21 +++++++++++++++++++ spec/fixtures/pages/f.html | 11 ++++++++++ 8 files changed, 52 insertions(+) create mode 100644 spec/fixtures/pages/f.html diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0400e9457e37..a25a00ae1747 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -196,6 +196,12 @@ void WebContents::RenderProcessGone(base::TerminationStatus status) { Emit("crashed"); } +void WebContents::DocumentLoadedInFrame( + content::RenderFrameHost* render_frame_host) { + if (!render_frame_host->GetParent()) + Emit("dom-ready"); +} + void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { bool is_main_frame = !render_frame_host->GetParent(); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 371c338708cc..0d146a694679 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -145,6 +145,8 @@ class WebContents : public mate::EventEmitter, // content::WebContentsObserver: void RenderViewDeleted(content::RenderViewHost*) override; void RenderProcessGone(base::TerminationStatus status) override; + void DocumentLoadedInFrame( + content::RenderFrameHost* render_frame_host) override; void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; void DidFailLoad(content::RenderFrameHost* render_frame_host, diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 6fc70131decb..43f4d7c98c5f 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -10,6 +10,7 @@ supportedWebViewEvents = [ 'did-stop-loading' 'did-get-response-details' 'did-get-redirect-request' + 'dom-ready' 'console-message' 'new-window' 'close' diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index 402bb5c7fa00..04aa5c5494f0 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -12,6 +12,7 @@ WEB_VIEW_EVENTS = 'did-get-response-details': ['status', 'newUrl', 'originalUrl', 'httpResponseCode', 'requestMethod', 'referrer'] 'did-get-redirect-request': ['oldUrl', 'newUrl', 'isMainFrame'] + 'dom-ready': [] 'console-message': ['level', 'message', 'line', 'sourceId'] 'new-window': ['url', 'frameName', 'disposition'] 'close': [] diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e4cec40f47cf..6852144bf56b 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -663,6 +663,12 @@ Emitted when details regarding a requested resource is available. Emitted when a redirect was received while requesting a resource. +### Event: 'dom-ready' + +* `event` Event + +Emitted when document in the given frame is loaded. + ### Event: 'page-favicon-updated' * `event` Event diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 3d2a7facd526..697860cfea67 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -333,6 +333,10 @@ Fired when details regarding a requested resource is available. Fired when a redirect was received while requesting a resource. +### dom-ready + +Fired when document in the given frame is loaded. + ### page-title-set * `title` String diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index fce7eeb79fa9..e2e03acd84dd 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -2,6 +2,8 @@ assert = require 'assert' fs = require 'fs' path = require 'path' remote = require 'remote' +http = require 'http' +url = require 'url' BrowserWindow = remote.require 'browser-window' @@ -222,3 +224,22 @@ describe 'browser-window module', -> assert.equal url, 'https://www.github.com/' done() w.loadUrl "file://#{fixtures}/pages/will-navigate.html" + + describe 'dom-ready event', -> + it 'emits when document is loaded', (done) -> + server = http.createServer (req, res) -> + action = url.parse(req.url, true).pathname + if action == '/logo.png' + img = fs.readFileSync(path.join(fixtures, 'assets', 'logo.png')) + res.writeHead(200, {'Content-Type': 'image/png'}) + setTimeout -> + res.end(img, 'binary') + , 2000 + server.close() + server.listen 62542, '127.0.0.1' + remote.require('ipc').on 'dom-ready', (e, state) -> + assert.equal state, 'interactive' + done() + w.webContents.on 'did-finish-load', -> + w.close() + w.loadUrl "file://#{fixtures}/pages/f.html" diff --git a/spec/fixtures/pages/f.html b/spec/fixtures/pages/f.html new file mode 100644 index 000000000000..e2003a3ab0d8 --- /dev/null +++ b/spec/fixtures/pages/f.html @@ -0,0 +1,11 @@ + + + + + + From ff87592722e6a508d55871cfc88ab2e7d08a2a10 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 30 Apr 2015 11:31:17 +0800 Subject: [PATCH 089/155] Make Print API work on Windows. --- atom/app/atom_main_delegate.cc | 8 + atom/app/atom_main_delegate.h | 2 + atom/utility/atom_content_utility_client.cc | 76 +++ atom/utility/atom_content_utility_client.h | 57 ++ .../browser/printing/pdf_to_emf_converter.cc | 495 ++++++++++++++++++ .../browser/printing/pdf_to_emf_converter.h | 48 ++ .../chrome/browser/printing/print_job.cc | 103 ++++ .../chrome/browser/printing/print_job.h | 18 + .../printing/print_view_manager_base.cc | 2 + .../chrome/common/chrome_utility_messages.h | 217 ++++++++ chromium_src/chrome/common/print_messages.h | 35 ++ .../chrome/utility/printing_handler.cc | 144 +++++ .../chrome/utility/printing_handler.h | 59 +++ .../chrome/utility/utility_message_handler.h | 22 + filenames.gypi | 8 + 15 files changed, 1294 insertions(+) create mode 100644 atom/utility/atom_content_utility_client.cc create mode 100644 atom/utility/atom_content_utility_client.h create mode 100644 chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc create mode 100644 chromium_src/chrome/browser/printing/pdf_to_emf_converter.h create mode 100644 chromium_src/chrome/common/chrome_utility_messages.h create mode 100644 chromium_src/chrome/utility/printing_handler.cc create mode 100644 chromium_src/chrome/utility/printing_handler.h create mode 100644 chromium_src/chrome/utility/utility_message_handler.h diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index c7ad0e11a0ca..7862e8ff6bda 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -14,6 +14,7 @@ #include "base/debug/stack_trace.h" #include "base/environment.h" #include "base/logging.h" +#include "chrome/utility/chrome_content_utility_client.h" #include "content/public/common/content_switches.h" #include "ui/base/resource/resource_bundle.h" @@ -94,6 +95,13 @@ content::ContentRendererClient* return renderer_client_.get(); } +content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() { +#if defined(OS_WIN) + utility_client_.reset(new AtomContentUtilityClient); + return utility_client_.get(); +#endif +} + scoped_ptr AtomMainDelegate::CreateContentClient() { return scoped_ptr(new AtomContentClient).Pass(); } diff --git a/atom/app/atom_main_delegate.h b/atom/app/atom_main_delegate.h index 8cd4a28ee1c0..7bcde8125c8e 100644 --- a/atom/app/atom_main_delegate.h +++ b/atom/app/atom_main_delegate.h @@ -21,6 +21,7 @@ class AtomMainDelegate : public brightray::MainDelegate { void PreSandboxStartup() override; content::ContentBrowserClient* CreateContentBrowserClient() override; content::ContentRendererClient* CreateContentRendererClient() override; + content::ContentUtilityClient* CreateContentUtilityClient() override; // brightray::MainDelegate: scoped_ptr CreateContentClient() override; @@ -35,6 +36,7 @@ class AtomMainDelegate : public brightray::MainDelegate { brightray::ContentClient content_client_; scoped_ptr browser_client_; scoped_ptr renderer_client_; + scoped_ptr utility_client_; DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate); }; diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc new file mode 100644 index 000000000000..41b1f851cb74 --- /dev/null +++ b/atom/utility/atom_content_utility_client.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/utility/atom_content_utility_client.h" + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/time/time.h" +#include "chrome/common/chrome_utility_messages.h" +#include "chrome/utility/utility_message_handler.h" +#include "content/public/common/content_switches.h" +#include "content/public/utility/utility_thread.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_message_macros.h" + + +#if defined(OS_WIN) +#include "chrome/utility/printing_handler.h" +#endif + + +namespace { + +bool Send(IPC::Message* message) { + return content::UtilityThread::Get()->Send(message); +} + +void ReleaseProcessIfNeeded() { + content::UtilityThread::Get()->ReleaseProcessIfNeeded(); +} + +} // namespace + +namespace atom { + +int64_t AtomContentUtilityClient::max_ipc_message_size_ = + IPC::Channel::kMaximumMessageSize; + +AtomContentUtilityClient::AtomContentUtilityClient() + : filter_messages_(false) { + handlers_.push_back(new PrintingHandler()); +} + +AtomContentUtilityClient::~AtomContentUtilityClient() { +} + +void AtomContentUtilityClient::UtilityThreadStarted() { +} + +bool AtomContentUtilityClient::OnMessageReceived( + const IPC::Message& message) { + if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) + return false; + + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(AtomContentUtilityClient, message) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + for (Handlers::iterator it = handlers_.begin(); + !handled && it != handlers_.end(); ++it) { + handled = (*it)->OnMessageReceived(message); + } + + return handled; +} + +void AtomContentUtilityClient::OnStartupPing() { + Send(new ChromeUtilityHostMsg_ProcessStarted); + // Don't release the process, we assume further messages are on the way. +} + +} // namespace atom diff --git a/atom/utility/atom_content_utility_client.h b/atom/utility/atom_content_utility_client.h new file mode 100644 index 000000000000..2c245b62f61e --- /dev/null +++ b/atom/utility/atom_content_utility_client.h @@ -0,0 +1,57 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_UTILITY_ATOM_CONTENT_UTILITY_CLIENT_H_ +#define ATOM_UTILITY_ATOM_CONTENT_UTILITY_CLIENT_H_ + +#include +#include +#include + +#include "base/compiler_specific.h" +#include "base/memory/scoped_vector.h" +#include "content/public/utility/content_utility_client.h" +#include "ipc/ipc_platform_file.h" + +namespace base { +class FilePath; +struct FileDescriptor; +} + +class UtilityMessageHandler; + +namespace atom { + +class AtomContentUtilityClient : public content::ContentUtilityClient { + public: + AtomContentUtilityClient(); + ~AtomContentUtilityClient() override; + + void UtilityThreadStarted() override; + bool OnMessageReceived(const IPC::Message& message) override; + + + static void set_max_ipc_message_size_for_test(int64_t max_message_size) { + max_ipc_message_size_ = max_message_size; + } + + private: + void OnStartupPing(); + + typedef ScopedVector Handlers; + Handlers handlers_; + + // Flag to enable whitelisting. + bool filter_messages_; + // A list of message_ids to filter. + std::set message_id_whitelist_; + // Maximum IPC msg size (default to kMaximumMessageSize; override for testing) + static int64_t max_ipc_message_size_; + + DISALLOW_COPY_AND_ASSIGN(AtomContentUtilityClient); +}; + +} // namespace atom + +#endif // ATOM_UTILITY_ATOM_CONTENT_UTILITY_CLIENT_H_ diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc new file mode 100644 index 000000000000..89bac3b68dca --- /dev/null +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc @@ -0,0 +1,495 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/printing/pdf_to_emf_converter.h" + +#include + +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/logging.h" +#include "chrome/common/chrome_utility_messages.h" +#include "chrome/common/print_messages.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_data.h" +#include "content/public/browser/utility_process_host.h" +#include "content/public/browser/utility_process_host_client.h" +#include "printing/emf_win.h" +#include "printing/pdf_render_settings.h" + +namespace printing { + +namespace { + +using content::BrowserThread; + +class PdfToEmfConverterImpl; + +// Allows to delete temporary directory after all temporary files created inside +// are closed. Windows cannot delete directory with opened files. Directory is +// used to store PDF and metafiles. PDF should be gone by the time utility +// process exits. Metafiles should be gone when all LazyEmf destroyed. +class RefCountedTempDir + : public base::RefCountedThreadSafe { + public: + RefCountedTempDir() { ignore_result(temp_dir_.CreateUniqueTempDir()); } + bool IsValid() const { return temp_dir_.IsValid(); } + const base::FilePath& GetPath() const { return temp_dir_.path(); } + + private: + friend struct BrowserThread::DeleteOnThread; + friend class base::DeleteHelper; + ~RefCountedTempDir() {} + + base::ScopedTempDir temp_dir_; + DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir); +}; + +typedef scoped_ptr + ScopedTempFile; + +// Wrapper for Emf to keep only file handle in memory, and load actual data only +// on playback. Emf::InitFromFile() can play metafile directly from disk, but it +// can't open file handles. We need file handles to reliably delete temporary +// files, and to efficiently interact with utility process. +class LazyEmf : public MetafilePlayer { + public: + LazyEmf(const scoped_refptr& temp_dir, ScopedTempFile file) + : temp_dir_(temp_dir), file_(file.Pass()) {} + virtual ~LazyEmf() { Close(); } + + virtual bool SafePlayback(HDC hdc) const override; + virtual bool SaveTo(base::File* file) const override; + + private: + void Close() const; + bool LoadEmf(Emf* emf) const; + + mutable scoped_refptr temp_dir_; + mutable ScopedTempFile file_; // Mutable because of consts in base class. + + DISALLOW_COPY_AND_ASSIGN(LazyEmf); +}; + +// Converts PDF into EMF. +// Class uses 3 threads: UI, IO and FILE. +// Internal workflow is following: +// 1. Create instance on the UI thread. (files_, settings_,) +// 2. Create pdf file on the FILE thread. +// 3. Start utility process and start conversion on the IO thread. +// 4. Utility process returns page count. +// 5. For each page: +// 1. Clients requests page with file handle to a temp file. +// 2. Utility converts the page, save it to the file and reply. +// +// All these steps work sequentially, so no data should be accessed +// simultaneously by several threads. +class PdfToEmfUtilityProcessHostClient + : public content::UtilityProcessHostClient { + public: + PdfToEmfUtilityProcessHostClient( + base::WeakPtr converter, + const PdfRenderSettings& settings); + + void Start(const scoped_refptr& data, + const PdfToEmfConverter::StartCallback& start_callback); + + void GetPage(int page_number, + const PdfToEmfConverter::GetPageCallback& get_page_callback); + + void Stop(); + + // UtilityProcessHostClient implementation. + virtual void OnProcessCrashed(int exit_code) override; + virtual void OnProcessLaunchFailed() override; + virtual bool OnMessageReceived(const IPC::Message& message) override; + + private: + class GetPageCallbackData { + MOVE_ONLY_TYPE_FOR_CPP_03(GetPageCallbackData, RValue); + + public: + GetPageCallbackData(int page_number, + PdfToEmfConverter::GetPageCallback callback) + : page_number_(page_number), callback_(callback) {} + + // Move constructor for STL. + GetPageCallbackData(RValue other) { this->operator=(other); } + + // Move assignment for STL. + GetPageCallbackData& operator=(RValue rhs) { + page_number_ = rhs.object->page_number_; + callback_ = rhs.object->callback_; + emf_ = rhs.object->emf_.Pass(); + return *this; + } + + int page_number() const { return page_number_; } + const PdfToEmfConverter::GetPageCallback& callback() const { + return callback_; + } + ScopedTempFile emf() { return emf_.Pass(); } + void set_emf(ScopedTempFile emf) { emf_ = emf.Pass(); } + + private: + int page_number_; + PdfToEmfConverter::GetPageCallback callback_; + ScopedTempFile emf_; + }; + + virtual ~PdfToEmfUtilityProcessHostClient(); + + bool Send(IPC::Message* msg); + + // Message handlers. + void OnProcessStarted(); + void OnPageCount(int page_count); + void OnPageDone(bool success, float scale_factor); + + void OnFailed(); + void OnTempPdfReady(ScopedTempFile pdf); + void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); + + scoped_refptr temp_dir_; + + // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. + base::WeakPtr converter_; + PdfRenderSettings settings_; + scoped_refptr data_; + + // Document loaded callback. + PdfToEmfConverter::StartCallback start_callback_; + + // Process host for IPC. + base::WeakPtr utility_process_host_; + + // Queue of callbacks for GetPage() requests. Utility process should reply + // with PageDone in the same order as requests were received. + // Use containers that keeps element pointers valid after push() and pop(). + typedef std::queue GetPageCallbacks; + GetPageCallbacks get_page_callbacks_; + + DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); +}; + +class PdfToEmfConverterImpl : public PdfToEmfConverter { + public: + PdfToEmfConverterImpl(); + + virtual ~PdfToEmfConverterImpl(); + + virtual void Start(const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback) override; + + virtual void GetPage(int page_number, + const GetPageCallback& get_page_callback) override; + + // Helps to cancel callbacks if this object is destroyed. + void RunCallback(const base::Closure& callback); + + private: + scoped_refptr utility_client_; + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); +}; + +ScopedTempFile CreateTempFile(scoped_refptr* temp_dir) { + if (!temp_dir->get()) + *temp_dir = new RefCountedTempDir(); + ScopedTempFile file; + if (!(*temp_dir)->IsValid()) + return file.Pass(); + base::FilePath path; + if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) + return file.Pass(); + file.reset(new base::File(path, + base::File::FLAG_CREATE_ALWAYS | + base::File::FLAG_WRITE | + base::File::FLAG_READ | + base::File::FLAG_DELETE_ON_CLOSE | + base::File::FLAG_TEMPORARY)); + if (!file->IsValid()) + file.reset(); + return file.Pass(); +} + +ScopedTempFile CreateTempPdfFile( + const scoped_refptr& data, + scoped_refptr* temp_dir) { + DCHECK_CURRENTLY_ON(BrowserThread::FILE); + + ScopedTempFile pdf_file = CreateTempFile(temp_dir); + if (!pdf_file || + static_cast(data->size()) != + pdf_file->WriteAtCurrentPos(data->front_as(), data->size())) { + pdf_file.reset(); + } + pdf_file->Seek(base::File::FROM_BEGIN, 0); + return pdf_file.Pass(); +} + +bool LazyEmf::SafePlayback(HDC hdc) const { + Emf emf; + bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); + // TODO(vitalybuka): Fix destruction of metafiles. For some reasons + // instances of Emf are not deleted. crbug.com/411683 + // It's known that the Emf going to be played just once to a printer. So just + // release file here. + Close(); + return result; +} + +bool LazyEmf::SaveTo(base::File* file) const { + Emf emf; + return LoadEmf(&emf) && emf.SaveTo(file); +} + +void LazyEmf::Close() const { + file_.reset(); + temp_dir_ = NULL; +} + +bool LazyEmf::LoadEmf(Emf* emf) const { + file_->Seek(base::File::FROM_BEGIN, 0); + int64 size = file_->GetLength(); + if (size <= 0) + return false; + std::vector data(size); + if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) + return false; + return emf->InitFromData(data.data(), data.size()); +} + +PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( + base::WeakPtr converter, + const PdfRenderSettings& settings) + : converter_(converter), settings_(settings) { +} + +PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { +} + +void PdfToEmfUtilityProcessHostClient::Start( + const scoped_refptr& data, + const PdfToEmfConverter::StartCallback& start_callback) { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask(BrowserThread::IO, + FROM_HERE, + base::Bind(&PdfToEmfUtilityProcessHostClient::Start, + this, + data, + start_callback)); + return; + } + data_ = data; + + // Store callback before any OnFailed() call to make it called on failure. + start_callback_ = start_callback; + + // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load + // gdiplus.dll, change how rendering happens, and not be able to correctly + // generate when sent to a metafile DC. + utility_process_host_ = + content::UtilityProcessHost::Create( + this, base::MessageLoop::current()->message_loop_proxy()) + ->AsWeakPtr(); + if (!utility_process_host_) + return OnFailed(); + // Should reply with OnProcessStarted(). + Send(new ChromeUtilityMsg_StartupPing); +} + +void PdfToEmfUtilityProcessHostClient::OnProcessStarted() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!utility_process_host_) + return OnFailed(); + + scoped_refptr data = data_; + data_ = NULL; + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&CreateTempPdfFile, data, &temp_dir_), + base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this)); +} + +void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!utility_process_host_) + return OnFailed(); + base::ProcessHandle process = utility_process_host_->GetData().handle; + // Should reply with OnPageCount(). + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( + IPC::GetFileHandleForProcess(pdf->GetPlatformFile(), process, false), + settings_)); +} + +void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (start_callback_.is_null()) + return OnFailed(); + BrowserThread::PostTask(BrowserThread::UI, + FROM_HERE, + base::Bind(&PdfToEmfConverterImpl::RunCallback, + converter_, + base::Bind(start_callback_, page_count))); + start_callback_.Reset(); +} + +void PdfToEmfUtilityProcessHostClient::GetPage( + int page_number, + const PdfToEmfConverter::GetPageCallback& get_page_callback) { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage, + this, + page_number, + get_page_callback)); + return; + } + + // Store callback before any OnFailed() call to make it called on failure. + get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback)); + + if (!utility_process_host_) + return OnFailed(); + + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&CreateTempFile, &temp_dir_), + base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady, + this, + &get_page_callbacks_.back())); +} + +void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( + GetPageCallbackData* callback_data, + ScopedTempFile emf) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!utility_process_host_) + return OnFailed(); + base::ProcessHandle process = utility_process_host_->GetData().handle; + IPC::PlatformFileForTransit transit = + IPC::GetFileHandleForProcess(emf->GetPlatformFile(), process, false); + callback_data->set_emf(emf.Pass()); + // Should reply with OnPageDone(). + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( + callback_data->page_number(), transit)); +} + +void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, + float scale_factor) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (get_page_callbacks_.empty()) + return OnFailed(); + scoped_ptr emf; + GetPageCallbackData& data = get_page_callbacks_.front(); + if (success) + emf.reset(new LazyEmf(temp_dir_, data.emf().Pass())); + BrowserThread::PostTask(BrowserThread::UI, + FROM_HERE, + base::Bind(&PdfToEmfConverterImpl::RunCallback, + converter_, + base::Bind(data.callback(), + data.page_number(), + scale_factor, + base::Passed(&emf)))); + get_page_callbacks_.pop(); +} + +void PdfToEmfUtilityProcessHostClient::Stop() { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); + return; + } + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); +} + +void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) { + OnFailed(); +} + +void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed() { + OnFailed(); +} + +bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( + const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted, OnProcessStarted) + IPC_MESSAGE_HANDLER( + ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount) + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, + OnPageDone) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { + if (utility_process_host_) + return utility_process_host_->Send(msg); + delete msg; + return false; +} + +void PdfToEmfUtilityProcessHostClient::OnFailed() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!start_callback_.is_null()) + OnPageCount(0); + while (!get_page_callbacks_.empty()) + OnPageDone(false, 0.0f); + utility_process_host_.reset(); +} + +PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { +} + +PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { + if (utility_client_.get()) + utility_client_->Stop(); +} + +void PdfToEmfConverterImpl::Start( + const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback) { + DCHECK(!utility_client_.get()); + utility_client_ = new PdfToEmfUtilityProcessHostClient( + weak_ptr_factory_.GetWeakPtr(), conversion_settings); + utility_client_->Start(data, start_callback); +} + +void PdfToEmfConverterImpl::GetPage(int page_number, + const GetPageCallback& get_page_callback) { + utility_client_->GetPage(page_number, get_page_callback); +} + +void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + callback.Run(); +} + +} // namespace + +PdfToEmfConverter::~PdfToEmfConverter() { +} + +// static +scoped_ptr PdfToEmfConverter::CreateDefault() { + return scoped_ptr(new PdfToEmfConverterImpl()); +} + +} // namespace printing diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h new file mode 100644 index 000000000000..60fdbc4b7e4e --- /dev/null +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h @@ -0,0 +1,48 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_ +#define CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_ + +#include "base/callback.h" +#include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_ptr.h" + +namespace base { +class FilePath; +} + +namespace printing { + +class MetafilePlayer; +class PdfRenderSettings; + +class PdfToEmfConverter { + public: + typedef base::Callback StartCallback; + typedef base::Callback emf)> GetPageCallback; + + virtual ~PdfToEmfConverter(); + + static scoped_ptr CreateDefault(); + + // Starts conversion of PDF provided as |data|. Calls |start_callback| + // with positive |page_count|. |page_count| is 0 if initialization failed. + virtual void Start(const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback) = 0; + + // Requests conversion of the page. |page_number| is 0-base page number in + // PDF provided in Start() call. + // Calls |get_page_callback| after conversion. |emf| of callback in not NULL + // if conversion succeeded. + virtual void GetPage(int page_number, + const GetPageCallback& get_page_callback) = 0; +}; + +} // namespace printing + +#endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_ diff --git a/chromium_src/chrome/browser/printing/print_job.cc b/chromium_src/chrome/browser/printing/print_job.cc index 25cf0ad79033..6bcc58322124 100644 --- a/chromium_src/chrome/browser/printing/print_job.cc +++ b/chromium_src/chrome/browser/printing/print_job.cc @@ -17,6 +17,12 @@ #include "printing/printed_document.h" #include "printing/printed_page.h" +#if defined(OS_WIN) +#include "chrome/browser/printing/pdf_to_emf_converter.h" +#include "printing/pdf_render_settings.h" +#endif + + using base::TimeDelta; namespace { @@ -272,6 +278,103 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { } } +#if defined(OS_WIN) + +class PrintJob::PdfToEmfState { + public: + PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area) + : page_count_(0), + current_page_(0), + pages_in_progress_(0), + page_size_(page_size), + content_area_(content_area), + converter_(PdfToEmfConverter::CreateDefault()) {} + + void Start(const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const PdfToEmfConverter::StartCallback& start_callback) { + converter_->Start(data, conversion_settings, start_callback); + } + + void GetMorePages( + const PdfToEmfConverter::GetPageCallback& get_page_callback) { + const int kMaxNumberOfTempFilesPerDocument = 3; + while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument && + current_page_ < page_count_) { + ++pages_in_progress_; + converter_->GetPage(current_page_++, get_page_callback); + } + } + + void OnPageProcessed( + const PdfToEmfConverter::GetPageCallback& get_page_callback) { + --pages_in_progress_; + GetMorePages(get_page_callback); + // Release converter if we don't need this any more. + if (!pages_in_progress_ && current_page_ >= page_count_) + converter_.reset(); + } + + void set_page_count(int page_count) { page_count_ = page_count; } + gfx::Size page_size() const { return page_size_; } + gfx::Rect content_area() const { return content_area_; } + + private: + int page_count_; + int current_page_; + int pages_in_progress_; + gfx::Size page_size_; + gfx::Rect content_area_; + scoped_ptr converter_; +}; + +void PrintJob::StartPdfToEmfConversion( + const scoped_refptr& bytes, + const gfx::Size& page_size, + const gfx::Rect& content_area) { + DCHECK(!ptd_to_emf_state_.get()); + ptd_to_emf_state_.reset(new PdfToEmfState(page_size, content_area)); + const int kPrinterDpi = settings().dpi(); + ptd_to_emf_state_->Start( + bytes, + printing::PdfRenderSettings(content_area, kPrinterDpi, true), + base::Bind(&PrintJob::OnPdfToEmfStarted, this)); +} + +void PrintJob::OnPdfToEmfStarted(int page_count) { + if (page_count <= 0) { + ptd_to_emf_state_.reset(); + Cancel(); + return; + } + ptd_to_emf_state_->set_page_count(page_count); + ptd_to_emf_state_->GetMorePages( + base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); +} + +void PrintJob::OnPdfToEmfPageConverted(int page_number, + float scale_factor, + scoped_ptr emf) { + DCHECK(ptd_to_emf_state_); + if (!document_.get() || !emf) { + ptd_to_emf_state_.reset(); + Cancel(); + return; + } + + // Update the rendered document. It will send notifications to the listener. + document_->SetPage(page_number, + emf.Pass(), + scale_factor, + ptd_to_emf_state_->page_size(), + ptd_to_emf_state_->content_area()); + + ptd_to_emf_state_->GetMorePages( + base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); +} + +#endif // OS_WIN + void PrintJob::OnDocumentDone() { // Be sure to live long enough. The instance could be destroyed by the // JOB_DONE broadcast. diff --git a/chromium_src/chrome/browser/printing/print_job.h b/chromium_src/chrome/browser/printing/print_job.h index a0f844a27c2d..48daaa6cb971 100644 --- a/chromium_src/chrome/browser/printing/print_job.h +++ b/chromium_src/chrome/browser/printing/print_job.h @@ -90,6 +90,19 @@ class PrintJob : public PrintJobWorkerOwner, // Access the current printed document. Warning: may be NULL. PrintedDocument* document() const; +#if defined(OS_WIN) + void StartPdfToEmfConversion( + const scoped_refptr& bytes, + const gfx::Size& page_size, + const gfx::Rect& content_area); + + void OnPdfToEmfStarted(int page_count); + void OnPdfToEmfPageConverted(int page_number, + float scale_factor, + scoped_ptr emf); + +#endif // OS_WIN + protected: virtual ~PrintJob(); @@ -137,6 +150,11 @@ class PrintJob : public PrintJobWorkerOwner, // the notified calls Cancel() again. bool is_canceling_; +#if defined(OS_WIN) + class PdfToEmfState; + scoped_ptr ptd_to_emf_state_; +#endif // OS_WIN + // Used at shutdown so that we can quit a nested message loop. base::WeakPtrFactory quit_factory_; diff --git a/chromium_src/chrome/browser/printing/print_view_manager_base.cc b/chromium_src/chrome/browser/printing/print_view_manager_base.cc index 3aec7a14d546..35c62fbc5327 100644 --- a/chromium_src/chrome/browser/printing/print_view_manager_base.cc +++ b/chromium_src/chrome/browser/printing/print_view_manager_base.cc @@ -156,6 +156,8 @@ void PrintViewManagerBase::OnDidPrintPage( params.data_size); document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf")); + print_job_->StartPdfToEmfConversion( + bytes, params.page_size, params.content_area); } #endif // !OS_WIN } diff --git a/chromium_src/chrome/common/chrome_utility_messages.h b/chromium_src/chrome/common/chrome_utility_messages.h new file mode 100644 index 000000000000..235c10333ee2 --- /dev/null +++ b/chromium_src/chrome/common/chrome_utility_messages.h @@ -0,0 +1,217 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Multiply-included message file, so no include guard. + +#if defined(OS_WIN) +#include +#endif // defined(OS_WIN) + +#include +#include + +#include "base/files/file_path.h" +#include "base/strings/string16.h" +#include "base/tuple.h" +#include "base/values.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_platform_file.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/ipc/gfx_param_traits.h" + +// Singly-included section for typedefs. +#ifndef CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_ +#define CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_ + +#if defined(OS_WIN) +// A vector of filters, each being a Tuple containing a display string (i.e. +// "Text Files") and a filter pattern (i.e. "*.txt"). +typedef std::vector> + GetOpenFileNameFilter; +#endif // OS_WIN + +#endif // CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_ + +#define IPC_MESSAGE_START ChromeUtilityMsgStart + +//#if defined(FULL_SAFE_BROWSING) +//IPC_STRUCT_TRAITS_BEGIN(safe_browsing::zip_analyzer::Results) + //IPC_STRUCT_TRAITS_MEMBER(success) + //IPC_STRUCT_TRAITS_MEMBER(has_executable) + //IPC_STRUCT_TRAITS_MEMBER(has_archive) +//IPC_STRUCT_TRAITS_END() +//#endif + +#if defined(OS_WIN) +IPC_STRUCT_BEGIN(ChromeUtilityMsg_GetSaveFileName_Params) + IPC_STRUCT_MEMBER(HWND, owner) + IPC_STRUCT_MEMBER(DWORD, flags) + IPC_STRUCT_MEMBER(GetOpenFileNameFilter, filters) + IPC_STRUCT_MEMBER(int, one_based_filter_index) + IPC_STRUCT_MEMBER(base::FilePath, suggested_filename) + IPC_STRUCT_MEMBER(base::FilePath, initial_directory) + IPC_STRUCT_MEMBER(base::string16, default_extension) +IPC_STRUCT_END() +#endif // OS_WIN + +//------------------------------------------------------------------------------ +// Utility process messages: +// These are messages from the browser to the utility process. + +// Tell the utility process to parse a JSON string into a Value object. +IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_ParseJSON, + std::string /* JSON to parse */) + +// Tell the utility process to decode the given image data. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_DecodeImage, + std::vector /* encoded image contents */, + bool /* shrink image if needed for IPC msg limit */) + +// Tell the utility process to decode the given JPEG image data with a robust +// libjpeg codec. +IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_RobustJPEGDecodeImage, + std::vector) // encoded image contents + +// Tell the utility process to patch the given |input_file| using |patch_file| +// and place the output in |output_file|. The patch should use the bsdiff +// algorithm (Courgette's version). +IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_PatchFileBsdiff, + base::FilePath /* input_file */, + base::FilePath /* patch_file */, + base::FilePath /* output_file */) + +// Tell the utility process to patch the given |input_file| using |patch_file| +// and place the output in |output_file|. The patch should use the Courgette +// algorithm. +IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_PatchFileCourgette, + base::FilePath /* input_file */, + base::FilePath /* patch_file */, + base::FilePath /* output_file */) + +#if defined(OS_CHROMEOS) +// Tell the utility process to create a zip file on the given list of files. +IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_CreateZipFile, + base::FilePath /* src_dir */, + std::vector /* src_relative_paths */, + base::FileDescriptor /* dest_fd */) +#endif // defined(OS_CHROMEOS) + +// Requests the utility process to respond with a +// ChromeUtilityHostMsg_ProcessStarted message once it has started. This may +// be used if the host process needs a handle to the running utility process. +IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_StartupPing) + +#if defined(FULL_SAFE_BROWSING) +// Tells the utility process to analyze a zip file for malicious download +// protection. +IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, + IPC::PlatformFileForTransit /* zip_file */) +#endif + +#if defined(OS_WIN) +// Invokes ui::base::win::OpenFileViaShell from the utility process. +IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_OpenFileViaShell, + base::FilePath /* full_path */) + +// Invokes ui::base::win::OpenFolderViaShell from the utility process. +IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_OpenFolderViaShell, + base::FilePath /* full_path */) + +// Instructs the utility process to invoke GetOpenFileName. |owner| is the +// parent of the modal dialog, |flags| are OFN_* flags. |filter| constrains the +// user's file choices. |initial_directory| and |filename| select the directory +// to be displayed and the file to be initially selected. +// +// Either ChromeUtilityHostMsg_GetOpenFileName_Failed or +// ChromeUtilityHostMsg_GetOpenFileName_Result will be returned when the +// operation completes whether due to error or user action. +IPC_MESSAGE_CONTROL5(ChromeUtilityMsg_GetOpenFileName, + HWND /* owner */, + DWORD /* flags */, + GetOpenFileNameFilter /* filter */, + base::FilePath /* initial_directory */, + base::FilePath /* filename */) +IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_GetSaveFileName, + ChromeUtilityMsg_GetSaveFileName_Params /* params */) +#endif // defined(OS_WIN) + +//#if defined(OS_ANDROID) +//// Instructs the utility process to detect support for seccomp-bpf, +//// and the result is reported through +//// ChromeUtilityHostMsg_DetectSeccompSupport_Result. +//IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_DetectSeccompSupport) +//#endif + +//------------------------------------------------------------------------------ +// Utility process host messages: +// These are messages from the utility process to the browser. + +// Reply when the utility process successfully parsed a JSON string. +// +// WARNING: The result can be of any Value subclass type, but we can't easily +// pass indeterminate value types by const object reference with our IPC macros, +// so we put the result Value into a ListValue. Handlers should examine the +// first (and only) element of the ListValue for the actual result. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_ParseJSON_Succeeded, + base::ListValue) + +// Reply when the utility process failed in parsing a JSON string. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_ParseJSON_Failed, + std::string /* error message, if any*/) + +// Reply when the utility process has failed while unpacking and parsing a +// web resource. |error_message| is a user-readable explanation of what +// went wrong. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnpackWebResource_Failed, + std::string /* error_message, if any */) + +// Reply when the utility process has succeeded in decoding the image. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DecodeImage_Succeeded, + SkBitmap) // decoded image + +// Reply when an error occurred decoding the image. +IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_DecodeImage_Failed) + +// Reply when a file has been patched. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_PatchFile_Finished, int /* result */) + +//#if defined(OS_CHROMEOS) +//// Reply when the utility process has succeeded in creating the zip file. +//IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_CreateZipFile_Succeeded) + +//// Reply when an error occured in creating the zip file. +//IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_CreateZipFile_Failed) +//#endif // defined(OS_CHROMEOS) + +// Reply when the utility process has started. +IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_ProcessStarted) + +//#if defined(FULL_SAFE_BROWSING) +//// Reply when a zip file has been analyzed for malicious download protection. +//IPC_MESSAGE_CONTROL1( + //ChromeUtilityHostMsg_AnalyzeZipFileForDownloadProtection_Finished, + //safe_browsing::zip_analyzer::Results) +//#endif + +#if defined(OS_WIN) +IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetOpenFileName_Failed) +IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetOpenFileName_Result, + base::FilePath /* directory */, + std::vector /* filenames */) +IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetSaveFileName_Failed) +IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetSaveFileName_Result, + base::FilePath /* path */, + int /* one_based_filter_index */) +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_BuildDirectWriteFontCache, + base::FilePath /* cache file path */) +#endif // defined(OS_WIN) + +//#if defined(OS_ANDROID) +//// Reply to ChromeUtilityMsg_DetectSeccompSupport to report the level +//// of kernel support for seccomp-bpf. +//IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl, + //bool [> seccomp prctl supported <]) +//IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall, + //bool [> seccomp syscall supported <]) +//#endif diff --git a/chromium_src/chrome/common/print_messages.h b/chromium_src/chrome/common/print_messages.h index 4ca8db82ae3d..4a54546b69d7 100644 --- a/chromium_src/chrome/common/print_messages.h +++ b/chromium_src/chrome/common/print_messages.h @@ -17,6 +17,13 @@ #include "ui/gfx/native_widget_types.h" #include "ui/gfx/geometry/rect.h" +#if defined(OS_WIN) +#include "ipc/ipc_platform_file.h" +#include "printing/backend/print_backend.h" +#include "printing/page_range.h" +#include "printing/pdf_render_settings.h" +#endif + #ifndef CHROME_COMMON_PRINT_MESSAGES_H_ #define CHROME_COMMON_PRINT_MESSAGES_H_ @@ -239,3 +246,31 @@ IPC_MESSAGE_ROUTED0(PrintHostMsg_ShowInvalidPrinterSettingsError) // Tell the browser printing failed. IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed, int /* document cookie */) + + +#if defined(OS_WIN) +// Tell the utility process to start rendering the given PDF into a metafile. +// Utility process would be alive until +// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles, + IPC::PlatformFileForTransit, /* input_file */ + printing::PdfRenderSettings /* settings */) + +// Requests conversion of the next page. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, + int /* page_number */, + IPC::PlatformFileForTransit /* output_file */) + +// Requests utility process to stop conversion and exit. +IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop) + +// Reply when the utility process loaded PDF. |page_count| is 0, if loading +// failed. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, + int /* page_count */) + +// Reply when the utility process rendered the PDF page. +IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, + bool /* success */, + float /* scale_factor */) +#endif diff --git a/chromium_src/chrome/utility/printing_handler.cc b/chromium_src/chrome/utility/printing_handler.cc new file mode 100644 index 000000000000..db6d9533cf51 --- /dev/null +++ b/chromium_src/chrome/utility/printing_handler.cc @@ -0,0 +1,144 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/utility/printing_handler.h" + +#include "base/files/file_util.h" +#include "base/lazy_instance.h" +#include "base/path_service.h" +#include "base/scoped_native_library.h" +#include "chrome/common/print_messages.h" +#include "content/public/utility/utility_thread.h" +#include "pdf/pdf.h" +#include "printing/page_range.h" +#include "printing/pdf_render_settings.h" + +#if defined(OS_WIN) +#include "printing/emf_win.h" +#include "ui/gfx/gdi_util.h" +#endif + + +namespace { + +bool Send(IPC::Message* message) { + return content::UtilityThread::Get()->Send(message); +} + +void ReleaseProcessIfNeeded() { + content::UtilityThread::Get()->ReleaseProcessIfNeeded(); +} + +} // namespace + +PrintingHandler::PrintingHandler() {} + +PrintingHandler::~PrintingHandler() {} + +bool PrintingHandler::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message) +#if defined(OS_WIN) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles, + OnRenderPDFPagesToMetafile) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, + OnRenderPDFPagesToMetafileGetPage) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop, + OnRenderPDFPagesToMetafileStop) +#endif // OS_WIN + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +#if defined(OS_WIN) +void PrintingHandler::OnRenderPDFPagesToMetafile( + IPC::PlatformFileForTransit pdf_transit, + const printing::PdfRenderSettings& settings) { + pdf_rendering_settings_ = settings; + base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); + int page_count = LoadPDF(pdf_file.Pass()); + //int page_count = 1; + Send( + new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count)); +} + +void PrintingHandler::OnRenderPDFPagesToMetafileGetPage( + int page_number, + IPC::PlatformFileForTransit output_file) { + base::File emf_file = IPC::PlatformFileForTransitToFile(output_file); + float scale_factor = 1.0f; + bool success = + RenderPdfPageToMetafile(page_number, emf_file.Pass(), &scale_factor); + Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone( + success, scale_factor)); +} + +void PrintingHandler::OnRenderPDFPagesToMetafileStop() { + ReleaseProcessIfNeeded(); +} + +int PrintingHandler::LoadPDF(base::File pdf_file) { + int64 length64 = pdf_file.GetLength(); + if (length64 <= 0 || length64 > std::numeric_limits::max()) + return 0; + int length = static_cast(length64); + + pdf_data_.resize(length); + if (length != pdf_file.Read(0, pdf_data_.data(), pdf_data_.size())) + return 0; + + int total_page_count = 0; + if (!chrome_pdf::GetPDFDocInfo( + &pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) { + return 0; + } + return total_page_count; +} + +bool PrintingHandler::RenderPdfPageToMetafile(int page_number, + base::File output_file, + float* scale_factor) { + printing::Emf metafile; + metafile.Init(); + + // We need to scale down DC to fit an entire page into DC available area. + // Current metafile is based on screen DC and have current screen size. + // Writing outside of those boundaries will result in the cut-off output. + // On metafiles (this is the case here), scaling down will still record + // original coordinates and we'll be able to print in full resolution. + // Before playback we'll need to counter the scaling up that will happen + // in the service (print_system_win.cc). + *scale_factor = + gfx::CalculatePageScale(metafile.context(), + pdf_rendering_settings_.area().right(), + pdf_rendering_settings_.area().bottom()); + gfx::ScaleDC(metafile.context(), *scale_factor); + + // The underlying metafile is of type Emf and ignores the arguments passed + // to StartPage. + metafile.StartPage(gfx::Size(), gfx::Rect(), 1); + if (!chrome_pdf::RenderPDFPageToDC( + &pdf_data_.front(), + pdf_data_.size(), + page_number, + metafile.context(), + pdf_rendering_settings_.dpi(), + pdf_rendering_settings_.area().x(), + pdf_rendering_settings_.area().y(), + pdf_rendering_settings_.area().width(), + pdf_rendering_settings_.area().height(), + true, + false, + true, + true, + pdf_rendering_settings_.autorotate())) { + return false; + } + metafile.FinishPage(); + metafile.FinishDocument(); + return metafile.SaveTo(&output_file); +} + +#endif // OS_WIN diff --git a/chromium_src/chrome/utility/printing_handler.h b/chromium_src/chrome/utility/printing_handler.h new file mode 100644 index 000000000000..b1f09acb9cc9 --- /dev/null +++ b/chromium_src/chrome/utility/printing_handler.h @@ -0,0 +1,59 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UTILITY_PRINTING_HANDLER_H_ +#define CHROME_UTILITY_PRINTING_HANDLER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "chrome/utility/utility_message_handler.h" +#include "ipc/ipc_platform_file.h" +#include "printing/pdf_render_settings.h" + +#if !defined(ENABLE_PRINT_PREVIEW) && !defined(OS_WIN) +#error "Windows or full printing must be enabled" +#endif + +namespace printing { +class PdfRenderSettings; +struct PwgRasterSettings; +struct PageRange; +} + +// Dispatches IPCs for printing. +class PrintingHandler : public UtilityMessageHandler { + public: + PrintingHandler(); + ~PrintingHandler() override; + + // IPC::Listener: + bool OnMessageReceived(const IPC::Message& message) override; + + private: + // IPC message handlers. +#if defined(OS_WIN) + void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit, + const printing::PdfRenderSettings& settings); + void OnRenderPDFPagesToMetafileGetPage( + int page_number, + IPC::PlatformFileForTransit output_file); + void OnRenderPDFPagesToMetafileStop(); +#endif // OS_WIN + +#if defined(OS_WIN) + int LoadPDF(base::File pdf_file); + bool RenderPdfPageToMetafile(int page_number, + base::File output_file, + float* scale_factor); +#endif // OS_WIN + +#if defined(OS_WIN) + std::vector pdf_data_; + printing::PdfRenderSettings pdf_rendering_settings_; +#endif + + DISALLOW_COPY_AND_ASSIGN(PrintingHandler); +}; + +#endif // CHROME_UTILITY_PRINTING_HANDLER_H_ diff --git a/chromium_src/chrome/utility/utility_message_handler.h b/chromium_src/chrome/utility/utility_message_handler.h new file mode 100644 index 000000000000..a86219188096 --- /dev/null +++ b/chromium_src/chrome/utility/utility_message_handler.h @@ -0,0 +1,22 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_ +#define CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_ + +namespace IPC { +class Message; +} + +class UtilityMessageHandler { + public: + virtual ~UtilityMessageHandler() {} + + // Called when a message is received. Returns true iff the message was + // handled. + virtual bool OnMessageReceived(const IPC::Message& message) = 0; +}; + +#endif // CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_ + diff --git a/filenames.gypi b/filenames.gypi index 586d67c17729..93e4da93e888 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -280,6 +280,8 @@ 'atom/renderer/atom_renderer_client.h', 'atom/renderer/guest_view_container.cc', 'atom/renderer/guest_view_container.h', + 'atom/utility/atom_content_utility_client.cc', + 'atom/utility/atom_content_utility_client.h', 'chromium_src/chrome/browser/browser_process.cc', 'chromium_src/chrome/browser/browser_process.h', 'chromium_src/chrome/browser/chrome_notification_types.h', @@ -291,6 +293,8 @@ 'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h', 'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc', 'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h', + 'chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc', + 'chromium_src/chrome/browser/printing/pdf_to_emf_converter.h', 'chromium_src/chrome/browser/printing/print_job.cc', 'chromium_src/chrome/browser/printing/print_job.h', 'chromium_src/chrome/browser/printing/print_job_manager.cc', @@ -324,6 +328,7 @@ 'chromium_src/chrome/browser/ui/views/color_chooser_aura.h', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h', + 'chromium_src/chrome/common/chrome_utility_messages.h', 'chromium_src/chrome/common/print_messages.cc', 'chromium_src/chrome/common/print_messages.h', 'chromium_src/chrome/common/tts_messages.h', @@ -338,6 +343,9 @@ 'chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h', 'chromium_src/chrome/renderer/tts_dispatcher.cc', 'chromium_src/chrome/renderer/tts_dispatcher.h', + 'chromium_src/chrome/utility/printing_handler.cc', + 'chromium_src/chrome/utility/printing_handler.h', + 'chromium_src/chrome/utility/utility_message_handler.h', 'chromium_src/library_loaders/libspeechd_loader.cc', 'chromium_src/library_loaders/libspeechd.h', '<@(native_mate_files)', From a8846e0432e7cd07ca39ee7c900fa0e354efde03 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Apr 2015 15:36:54 +0800 Subject: [PATCH 090/155] Also upload headers to iojs's locations --- script/upload-checksums.py | 3 +++ script/upload-node-headers.py | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/script/upload-checksums.py b/script/upload-checksums.py index 4c1cfe9e8779..c71425126363 100755 --- a/script/upload-checksums.py +++ b/script/upload-checksums.py @@ -39,8 +39,11 @@ def parse_args(): def get_files_list(version): return [ 'node-{0}.tar.gz'.format(version), + 'iojs-{0}.tar.gz'.format(version), 'node.lib', 'x64/node.lib', + 'win-x86/iojs.lib', + 'win-x64/iojs.lib', ] diff --git a/script/upload-node-headers.py b/script/upload-node-headers.py index 86335b2b63db..628f3c2ead97 100755 --- a/script/upload-node-headers.py +++ b/script/upload-node-headers.py @@ -38,10 +38,13 @@ def main(): safe_mkdir(DIST_DIR) args = parse_args() - dist_headers_dir = os.path.join(DIST_DIR, 'node-{0}'.format(args.version)) + node_headers_dir = os.path.join(DIST_DIR, 'node-{0}'.format(args.version)) + iojs_headers_dir = os.path.join(DIST_DIR, 'iojs-{0}'.format(args.version)) - copy_headers(dist_headers_dir) - create_header_tarball(dist_headers_dir) + copy_headers(node_headers_dir) + create_header_tarball(node_headers_dir) + copy_headers(iojs_headers_dir) + create_header_tarball(iojs_headers_dir) # Upload node's headers to S3. bucket, access_key, secret_key = s3_config() @@ -107,18 +110,26 @@ def upload_node(bucket, access_key, secret_key, version): if PLATFORM == 'win32': if get_target_arch() == 'ia32': node_lib = os.path.join(DIST_DIR, 'node.lib') + iojs_lib = os.path.join(DIST_DIR, 'win-x86', 'iojs.lib') else: node_lib = os.path.join(DIST_DIR, 'x64', 'node.lib') - safe_mkdir(os.path.dirname(node_lib)) + iojs_lib = os.path.join(DIST_DIR, 'win-x64', 'iojs.lib') + safe_mkdir(os.path.dirname(node_lib)) + safe_mkdir(os.path.dirname(iojs_lib)) - # Copy atom.lib to node.lib + # Copy atom.lib to node.lib and iojs.lib. atom_lib = os.path.join(OUT_DIR, 'node.dll.lib') shutil.copy2(atom_lib, node_lib) + shutil.copy2(atom_lib, iojs_lib) # Upload the node.lib. s3put(bucket, access_key, secret_key, DIST_DIR, 'atom-shell/dist/{0}'.format(version), [node_lib]) + # Upload the iojs.lib. + s3put(bucket, access_key, secret_key, DIST_DIR, + 'atom-shell/dist/{0}'.format(version), [iojs_lib]) + if __name__ == '__main__': sys.exit(main()) From dec7c40fd889f0dbecc9ddc6733fbb22bb22795c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Apr 2015 16:01:54 +0800 Subject: [PATCH 091/155] Also upload iojs-*-.tar.gz --- script/upload-node-headers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/upload-node-headers.py b/script/upload-node-headers.py index 628f3c2ead97..38cb2f7e16f5 100755 --- a/script/upload-node-headers.py +++ b/script/upload-node-headers.py @@ -106,6 +106,8 @@ def upload_node(bucket, access_key, secret_key, version): with scoped_cwd(DIST_DIR): s3put(bucket, access_key, secret_key, DIST_DIR, 'atom-shell/dist/{0}'.format(version), glob.glob('node-*.tar.gz')) + s3put(bucket, access_key, secret_key, DIST_DIR, + 'atom-shell/dist/{0}'.format(version), glob.glob('iojs-*.tar.gz')) if PLATFORM == 'win32': if get_target_arch() == 'ia32': From c54eca8dff3fb7a3be4b440434119efda7d40efb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 30 Apr 2015 17:07:20 +0800 Subject: [PATCH 092/155] Update node to fix #1472 --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index a7e75da3cae4..e5aaa1ad33b3 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit a7e75da3cae48cf6e55fa7c9f13d689f11021795 +Subproject commit e5aaa1ad33b3479dbb29df797beca5873e7490dc From 5fa7ae7d727e2e988fb0dc4c24c416a483783398 Mon Sep 17 00:00:00 2001 From: Lee McKinnon Date: Thu, 30 Apr 2015 15:40:30 -0400 Subject: [PATCH 093/155] Fixing typo in desktop-environment-integration.md Missing comma in the 'setUserTasks' as well as a typo in the description under "User tasks (Windows)" --- docs/tutorial/desktop-environment-integration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 716f5c42c312..ab4ef28b3366 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -118,8 +118,8 @@ app.setUserTasks([ arguments: '--new-window', iconPath: process.execPath, iconIndex: 0, - title: 'New Window' - description: 'Create a new winodw', + title: 'New Window', + description: 'Create a new window', } ]); ``` From 36d2512ff88cbb11ee02c4500eaafc072377307f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 May 2015 13:48:23 +0800 Subject: [PATCH 094/155] spec: Test beforeunload handler in webview --- spec/fixtures/pages/beforeunload-false.html | 13 +++++++++++++ spec/webview-spec.coffee | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 spec/fixtures/pages/beforeunload-false.html diff --git a/spec/fixtures/pages/beforeunload-false.html b/spec/fixtures/pages/beforeunload-false.html new file mode 100644 index 000000000000..7ae4edf4ce29 --- /dev/null +++ b/spec/fixtures/pages/beforeunload-false.html @@ -0,0 +1,13 @@ + + + + + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 51058ad695e9..92a77351ee68 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -178,3 +178,18 @@ describe ' tag', -> done() webview.src = "file://#{fixtures}/pages/a.html" document.body.appendChild webview + + describe '.reload()', -> + it 'should emit beforeunload handler', (done) -> + webview.addEventListener 'did-finish-load', (e) -> + webview.reload() + listener = (e) -> + assert.equal e.channel, 'onbeforeunload' + webview.removeEventListener 'ipc-message', listener + done() + webview.addEventListener 'console-message', (e) -> + console.log(e) + webview.addEventListener 'ipc-message', listener + webview.setAttribute 'nodeintegration', 'on' + webview.src = "file://#{fixtures}/pages/beforeunload-false.html" + document.body.appendChild webview From bfac7f7a174c7d204882c1e7b4f6c585b2a94f27 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 May 2015 13:48:39 +0800 Subject: [PATCH 095/155] Make beforeunload work in webview --- atom/browser/api/atom_api_web_contents.cc | 9 +++++++++ atom/browser/api/atom_api_web_contents.h | 4 ++++ atom/browser/atom_javascript_dialog_manager.cc | 1 - 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a6b10acd1e90..e6aa2f898679 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -7,6 +7,7 @@ #include #include "atom/browser/atom_browser_context.h" +#include "atom/browser/atom_javascript_dialog_manager.h" #include "atom/browser/native_window.h" #include "atom/browser/web_dialog_helper.h" #include "atom/browser/web_view_manager.h" @@ -146,6 +147,14 @@ content::WebContents* WebContents::OpenURLFromTab( return web_contents(); } +content::JavaScriptDialogManager* WebContents::GetJavaScriptDialogManager( + content::WebContents* source) { + if (!dialog_manager_) + dialog_manager_.reset(new AtomJavaScriptDialogManager); + + return dialog_manager_.get(); +} + void WebContents::RunFileChooser(content::WebContents* guest, const content::FileChooserParams& params) { if (!web_dialog_helper_) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 0d146a694679..e8010d560015 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -27,6 +27,7 @@ class Dictionary; namespace atom { +class AtomJavaScriptDialogManager; class WebDialogHelper; namespace api { @@ -126,6 +127,8 @@ class WebContents : public mate::EventEmitter, content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; + content::JavaScriptDialogManager* GetJavaScriptDialogManager( + content::WebContents* source) override; void RunFileChooser(content::WebContents* web_contents, const content::FileChooserParams& params) override; void EnumerateDirectory(content::WebContents* web_contents, @@ -201,6 +204,7 @@ class WebContents : public mate::EventEmitter, const gfx::Size& new_size); scoped_ptr web_dialog_helper_; + scoped_ptr dialog_manager_; // Unique ID for a guest WebContents. int guest_instance_id_; diff --git a/atom/browser/atom_javascript_dialog_manager.cc b/atom/browser/atom_javascript_dialog_manager.cc index 8d4e10853495..c21d1fb11816 100644 --- a/atom/browser/atom_javascript_dialog_manager.cc +++ b/atom/browser/atom_javascript_dialog_manager.cc @@ -27,7 +27,6 @@ void AtomJavaScriptDialogManager::RunBeforeUnloadDialog( const base::string16& message_text, bool is_reload, const DialogClosedCallback& callback) { - bool prevent_reload = message_text.empty() || message_text == base::ASCIIToUTF16("false"); callback.Run(!prevent_reload, message_text); From d76bd4a10394c77a2131f39fc952f981d7b75470 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 30 Apr 2015 18:45:19 +0530 Subject: [PATCH 096/155] webContents: adding serviceworker helper utilities --- atom/browser/api/atom_api_web_contents.cc | 43 +++++++++++++++++++++++ atom/browser/api/atom_api_web_contents.h | 2 ++ docs/api/browser-window.md | 15 ++++++++ 3 files changed, 60 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0400e9457e37..00a8d1a786f0 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -27,8 +27,11 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/resource_request_details.h" +#include "content/public/browser/service_worker_context.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" +#include "native_mate/callback.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" @@ -53,6 +56,22 @@ NativeWindow* GetWindowFromGuest(const content::WebContents* guest) { return nullptr; } +content::ServiceWorkerContext* GetServiceWorkerContext( + const content::WebContents* web_contents) { + auto context = web_contents->GetBrowserContext(); + auto site_instance = web_contents->GetSiteInstance(); + if (!context || !site_instance) + return nullptr; + + content::StoragePartition* storage_partition = + content::BrowserContext::GetStoragePartition( + context, site_instance); + + DCHECK(storage_partition); + + return storage_partition->GetServiceWorkerContext(); +} + } // namespace WebContents::WebContents(content::WebContents* web_contents) @@ -548,6 +567,27 @@ void WebContents::SetAllowTransparency(bool allow) { } } +void WebContents::HasServiceWorker( + const base::Callback& callback) { + auto context = GetServiceWorkerContext(web_contents()); + if (!context) + return; + + context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(), + GURL::EmptyGURL(), + callback); +} + +void WebContents::UnregisterServiceWorker( + const base::Callback& callback) { + auto context = GetServiceWorkerContext(web_contents()); + if (!context) + return; + + context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(), + callback); +} + mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( v8::Isolate* isolate) { if (template_.IsEmpty()) @@ -585,6 +625,9 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("setAutoSize", &WebContents::SetAutoSize) .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency) .SetMethod("isGuest", &WebContents::is_guest) + .SetMethod("hasServiceWorker", &WebContents::HasServiceWorker) + .SetMethod("unregisterServiceWorker", + &WebContents::UnregisterServiceWorker) .Build()); return mate::ObjectTemplateBuilder( diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 371c338708cc..d6c3e360ce72 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -63,6 +63,8 @@ class WebContents : public mate::EventEmitter, void CloseDevTools(); bool IsDevToolsOpened(); void InspectElement(int x, int y); + void HasServiceWorker(const base::Callback&); + void UnregisterServiceWorker(const base::Callback&); // Editing commands. void Undo(); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e4cec40f47cf..84985391871f 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -846,6 +846,21 @@ Executes editing command `replace` in page. Executes editing command `replaceMisspelling` in page. +### WebContents.hasServiceWorker(callback) + +* `callback` Function + +Checks if any serviceworker is registered and returns boolean as +response to `callback`. + +### WebContents.unregisterServiceWorker(callback) + +* `callback` Function + +Unregisters any serviceworker if present and returns boolean as +response to `callback` when the JS promise is fullfilled or false +when the JS promise is rejected. + ### WebContents.send(channel[, args...]) * `channel` String From 4608f5e9cd4508db48a5df51b23401f79b0d4147 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 May 2015 14:57:25 +0800 Subject: [PATCH 097/155] Bump v0.25.2 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index 0da56c6d411d..760937c87f2e 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.25.1', + 'version%': '0.25.2', 'atom_source_root': 'CFBundleIconFile atom.icns CFBundleVersion - 0.25.1 + 0.25.2 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 35713277625b..aa9d3a0726ff 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,25,1,0 - PRODUCTVERSION 0,25,1,0 + FILEVERSION 0,25,2,0 + PRODUCTVERSION 0,25,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.25.1" + VALUE "FileVersion", "0.25.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.25.1" + VALUE "ProductVersion", "0.25.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 229ab7e94b55..dc8f08b785d8 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 25 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 From ae6a1b409f3bb5bb2736a3b3ae138257adf79edb Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Fri, 1 May 2015 16:20:53 +0530 Subject: [PATCH 098/155] window: adding setBounds and getBounds api --- atom/browser/api/atom_api_window.cc | 11 +++++++++++ atom/browser/api/atom_api_window.h | 6 ++++++ atom/browser/native_window.h | 2 ++ atom/browser/native_window_mac.h | 2 ++ atom/browser/native_window_mac.mm | 9 +++++++++ atom/browser/native_window_views.cc | 8 ++++++++ atom/browser/native_window_views.h | 2 ++ docs/api/browser-window.md | 14 ++++++++++++++ 8 files changed, 54 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 22f40be27e30..b71499d3699c 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -15,6 +15,7 @@ #include "native_mate/callback.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" +#include "ui/gfx/geometry/rect.h" #include "atom/common/node_includes.h" @@ -222,6 +223,14 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } +void Window::SetBounds(const gfx::Rect& bounds) { + window_->SetBounds(bounds); +} + +gfx::Rect Window::GetBounds() { + return window_->GetBounds(); +} + void Window::SetSize(int width, int height) { window_->SetSize(gfx::Size(width, height)); } @@ -464,6 +473,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimized", &Window::IsMinimized) .SetMethod("setFullScreen", &Window::SetFullScreen) .SetMethod("isFullScreen", &Window::IsFullscreen) + .SetMethod("getBounds", &Window::GetBounds) + .SetMethod("setBounds", &Window::SetBounds) .SetMethod("getSize", &Window::GetSize) .SetMethod("setSize", &Window::SetSize) .SetMethod("getContentSize", &Window::GetContentSize) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 2894f0e50379..d5c3ceedd2eb 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -16,6 +16,10 @@ class GURL; +namespace gfx { +class Rect; +} + namespace mate { class Arguments; class Dictionary; @@ -85,6 +89,8 @@ class Window : public mate::EventEmitter, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); + void SetBounds(const gfx::Rect& bounds); + gfx::Rect GetBounds(); void SetSize(int width, int height); std::vector GetSize(); void SetContentSize(int width, int height); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index b1f1a384b8bb..d04769f171f8 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -113,6 +113,8 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, virtual bool IsMinimized() = 0; virtual void SetFullScreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; + virtual void SetBounds(const gfx::Rect& bounds) = 0; + virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size) = 0; virtual gfx::Size GetSize() = 0; virtual void SetContentSize(const gfx::Size& size) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 822594038a5a..24d52664a050 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -45,6 +45,8 @@ class NativeWindowMac : public NativeWindow { bool IsMinimized() override; void SetFullScreen(bool fullscreen) override; bool IsFullscreen() const override; + void SetBounds(const gfx::Rect& bounds) override; + gfx::Rect GetBounds() override; void SetSize(const gfx::Size& size) override; gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index b7eccd2a6c7c..d1cb82a2f4f1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -470,6 +470,15 @@ bool NativeWindowMac::IsFullscreen() const { return [window_ styleMask] & NSFullScreenWindowMask; } +void NativeWindowMac::SetBounds(const gfx::Rect& bounds) { + Move(bounds); +} + +gfx::Rect NativeWindowMac::GetBounds() { + return gfx::Rect(GetPosition(), + GetSize()); +} + void NativeWindowMac::SetSize(const gfx::Size& size) { NSRect frame = [window_ frame]; frame.origin.y -= size.height() - frame.size.height; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 1ef0a63680c9..d8eed64009c1 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -373,6 +373,14 @@ bool NativeWindowViews::IsFullscreen() const { return window_->IsFullscreen(); } +void NativeWindowViews::SetBounds(const gfx::Rect& bounds) { + window_->SetBoundsConstrained(bounds); +} + +gfx::Rect NativeWindowViews::GetBounds() { + return window_->GetRestoredBounds(); +} + void NativeWindowViews::SetSize(const gfx::Size& size) { #if defined(USE_X11) // On Linux the minimum and maximum size should be updated with window size diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 6ec3f2aef438..020e349332bf 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -50,6 +50,8 @@ class NativeWindowViews : public NativeWindow, bool IsMinimized() override; void SetFullScreen(bool fullscreen) override; bool IsFullscreen() const override; + void SetBounds(const gfx::Rect& bounds) override; + gfx::Rect GetBounds() override; void SetSize(const gfx::Size& size) override; gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index f16a629fccc6..44021cabe939 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -316,6 +316,20 @@ Sets whether the window should be in fullscreen mode. Returns whether the window is in fullscreen mode. +### BrowserWindow.setBounds(options) + +* `options` Object + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +Resizes and moves the window to `width`, `height`, `x`, `y`. + +### BrowserWindow.getBounds() + +Returns an object that contains window's width, height, x and y values. + ### BrowserWindow.setSize(width, height) * `width` Integer From 6d7d068e493f155ea735f2e9f0451a32640b24e1 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Fri, 1 May 2015 15:24:22 +0530 Subject: [PATCH 099/155] tray: send tray icon position as payload onclick OSX --- atom/browser/api/atom_api_tray.cc | 5 +++-- atom/browser/api/atom_api_tray.h | 2 +- atom/browser/ui/tray_icon.cc | 4 ++-- atom/browser/ui/tray_icon.h | 2 +- atom/browser/ui/tray_icon_cocoa.mm | 9 ++++++++- atom/browser/ui/tray_icon_observer.h | 6 +++++- atom/browser/ui/win/notify_icon.cc | 2 +- docs/api/tray.md | 5 +++++ 8 files changed, 26 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 94af89b81ecd..c7e0149b0114 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -9,6 +9,7 @@ #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/browser.h" #include "atom/browser/ui/tray_icon.h" +#include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "native_mate/constructor.h" @@ -39,8 +40,8 @@ mate::Wrappable* Tray::New(const gfx::Image& image) { return new Tray(image); } -void Tray::OnClicked() { - Emit("clicked"); +void Tray::OnClicked(const gfx::Point& pos) { + Emit("clicked", pos); } void Tray::OnDoubleClicked() { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 48828d2c9366..38fb044d9dab 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -41,7 +41,7 @@ class Tray : public mate::EventEmitter, virtual ~Tray(); // TrayIconObserver: - void OnClicked() override; + void OnClicked(const gfx::Point&) override; void OnDoubleClicked() override; void OnBalloonShow() override; void OnBalloonClicked() override; diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index 68770c1e5cfd..06c1f4be5967 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -26,8 +26,8 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon, const base::string16& contents) { } -void TrayIcon::NotifyClicked() { - FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked()); +void TrayIcon::NotifyClicked(const gfx::Point& pos) { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(pos)); } void TrayIcon::NotifyDoubleClicked() { diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index 6293b39002b6..26f31a12e072 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -50,7 +50,7 @@ class TrayIcon { void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); } void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); } - void NotifyClicked(); + void NotifyClicked(const gfx::Point&); void NotifyDoubleClicked(); void NotifyBalloonShow(); void NotifyBalloonClicked(); diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index db2508ecc6a4..a68dd1c48e60 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -7,6 +7,7 @@ #include "atom/browser/ui/cocoa/atom_menu_controller.h" #include "base/strings/sys_string_conversions.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/screen.h" @interface StatusItemController : NSObject { atom::TrayIconCocoa* trayIcon_; // weak @@ -25,7 +26,13 @@ } - (void)handleClick:(id)sender { - trayIcon_->NotifyClicked(); + // Get the position of the frame of the NSStatusItem. + NSPoint pos = [NSApp currentEvent].window.frame.origin; + // Flip coordinates to gfx (0,0 in top-left corner) using current screen. + NSScreen* screen = [NSScreen mainScreen]; + pos.y = NSMaxY([screen frame]) - pos.y; + + trayIcon_->NotifyClicked(gfx::Point(pos.x, pos.y)); } - (void)handleDoubleClick:(id)sender { diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index 293e5371c4cf..266654af21bf 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -5,11 +5,15 @@ #ifndef ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_ #define ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_ +namespace gfx { +class Point; +} + namespace atom { class TrayIconObserver { public: - virtual void OnClicked() {} + virtual void OnClicked(const gfx::Point&) {} virtual void OnDoubleClicked() {} virtual void OnBalloonShow() {} virtual void OnBalloonClicked() {} diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 99b7153631af..4c227c8044ae 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -49,7 +49,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, bool left_mouse_click) { // Pass to the observer if appropriate. if (left_mouse_click) { - NotifyClicked(); + NotifyClicked(cursor_pos); return; } diff --git a/docs/api/tray.md b/docs/api/tray.md index 6d16e3b50703..dd030385ad38 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -46,6 +46,11 @@ Creates a new tray icon associated with the `image`. ### Event: 'clicked' +* `event` +* `point` Object + * `x` Integer + * `y` Integer + Emitted when the tray icon is clicked. ### Event: 'double-clicked' From 9ae59e8ac7bc2f117066ca9c1637bd15fb78b8a9 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Fri, 1 May 2015 20:10:46 +0530 Subject: [PATCH 100/155] removed move utility and replaced with setbounds --- atom/browser/native_window.cc | 5 ++-- atom/browser/native_window.h | 1 - atom/browser/native_window_mac.h | 3 +- atom/browser/native_window_mac.mm | 43 ++++++++++++++--------------- atom/browser/native_window_views.cc | 29 +++++++++++-------- atom/browser/native_window_views.h | 1 - 6 files changed, 40 insertions(+), 42 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 0f757e8c619f..2920178058df 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -192,7 +192,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { int width = -1, height = -1; options.Get(switches::kWidth, &width); options.Get(switches::kHeight, &height); - Move(gfx::Rect(x, y, width, height)); + SetBounds(gfx::Rect(x, y, width, height)); } else if (options.Get(switches::kCenter, ¢er) && center) { Center(); } @@ -646,8 +646,7 @@ void NativeWindow::DeactivateContents(content::WebContents* contents) { void NativeWindow::MoveContents(content::WebContents* source, const gfx::Rect& pos) { - SetPosition(pos.origin()); - SetSize(pos.size()); + SetBounds(pos); } void NativeWindow::CloseContents(content::WebContents* source) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d04769f171f8..72056715837a 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -98,7 +98,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, virtual void Close() = 0; virtual void CloseImmediately() = 0; - virtual void Move(const gfx::Rect& pos) = 0; virtual void Focus(bool focus) = 0; virtual bool IsFocused() = 0; virtual void Show() = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 24d52664a050..0fa3fe9cce42 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -30,7 +30,6 @@ class NativeWindowMac : public NativeWindow { // NativeWindow implementation. void Close() override; void CloseImmediately() override; - void Move(const gfx::Rect& pos) override; void Focus(bool focus) override; bool IsFocused() override; void Show() override; @@ -46,7 +45,7 @@ class NativeWindowMac : public NativeWindow { void SetFullScreen(bool fullscreen) override; bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; - gfx::Rect GetBounds() override; + gfx::Rect GetBounds() override; void SetSize(const gfx::Size& size) override; gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index d1cb82a2f4f1..e2b58e96c7f7 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -382,18 +382,6 @@ void NativeWindowMac::CloseImmediately() { [window_ close]; } -void NativeWindowMac::Move(const gfx::Rect& pos) { - NSRect cocoa_bounds = NSMakeRect(pos.x(), 0, - pos.width(), - pos.height()); - // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; - cocoa_bounds.origin.y = - NSHeight([screen frame]) - pos.height() - pos.y(); - - [window_ setFrame:cocoa_bounds display:YES]; -} - void NativeWindowMac::Focus(bool focus) { if (!IsVisible()) return; @@ -471,12 +459,26 @@ bool NativeWindowMac::IsFullscreen() const { } void NativeWindowMac::SetBounds(const gfx::Rect& bounds) { - Move(bounds); + NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, + bounds.width(), + bounds.height()); + // Flip coordinates based on the primary screen. + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + cocoa_bounds.origin.y = + NSHeight([screen frame]) - bounds.height() - bounds.y(); + + [window_ setFrame:cocoa_bounds display:YES]; } gfx::Rect NativeWindowMac::GetBounds() { - return gfx::Rect(GetPosition(), - GetSize()); + NSRect frame = [window_ frame]; + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + + gfx::Point pos(frame.origin.x, + NSHeight([screen frame]) - frame.origin.y - frame.size.height); + gfx::Size size(frame.size.width, frame.size.height); + + return gfx::Rect(pos, size); } void NativeWindowMac::SetSize(const gfx::Size& size) { @@ -489,8 +491,7 @@ void NativeWindowMac::SetSize(const gfx::Size& size) { } gfx::Size NativeWindowMac::GetSize() { - NSRect frame = [window_ frame]; - return gfx::Size(frame.size.width, frame.size.height); + return GetBounds().size(); } void NativeWindowMac::SetContentSize(const gfx::Size& size) { @@ -564,15 +565,11 @@ void NativeWindowMac::Center() { } void NativeWindowMac::SetPosition(const gfx::Point& position) { - Move(gfx::Rect(position, GetSize())); + SetBounds(gfx::Rect(position, GetSize())); } gfx::Point NativeWindowMac::GetPosition() { - NSRect frame = [window_ frame]; - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; - - return gfx::Point(frame.origin.x, - NSHeight([screen frame]) - frame.origin.y - frame.size.height); + return GetBounds().origin(); } void NativeWindowMac::SetTitle(const std::string& title) { diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index d8eed64009c1..3b283ddbecf4 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -291,10 +291,6 @@ void NativeWindowViews::CloseImmediately() { window_->CloseNow(); } -void NativeWindowViews::Move(const gfx::Rect& bounds) { - window_->SetBounds(bounds); -} - void NativeWindowViews::Focus(bool focus) { if (focus) window_->Activate(); @@ -374,11 +370,25 @@ bool NativeWindowViews::IsFullscreen() const { } void NativeWindowViews::SetBounds(const gfx::Rect& bounds) { - window_->SetBoundsConstrained(bounds); +#if defined(USE_X11) + // On Linux the minimum and maximum size should be updated with window size + // when window is not resizable. + if (!resizable_) { + SetMaximumSize(bounds.size()); + SetMinimumSize(bounds.size()); + } +#endif + + window_->SetBounds(bounds); } gfx::Rect NativeWindowViews::GetBounds() { - return window_->GetRestoredBounds(); +#if defined(OS_WIN) + if (IsMinimized()) + return window_->GetRestoredBounds(); +#endif + + return window_->GetWindowBoundsInScreen(); } void NativeWindowViews::SetSize(const gfx::Size& size) { @@ -395,12 +405,7 @@ void NativeWindowViews::SetSize(const gfx::Size& size) { } gfx::Size NativeWindowViews::GetSize() { -#if defined(OS_WIN) - if (IsMinimized()) - return window_->GetRestoredBounds().size(); -#endif - - return window_->GetWindowBoundsInScreen().size(); + return GetBounds().size(); } void NativeWindowViews::SetContentSize(const gfx::Size& size) { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 020e349332bf..978aac826272 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -35,7 +35,6 @@ class NativeWindowViews : public NativeWindow, // NativeWindow: void Close() override; void CloseImmediately() override; - void Move(const gfx::Rect& pos) override; void Focus(bool focus) override; bool IsFocused() override; void Show() override; From d2ab8322b7bc36c3c5cc90140c98e7cb38115160 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Sat, 2 May 2015 01:28:17 +0700 Subject: [PATCH 101/155] update using-native-node-modules doc --- docs/tutorial/using-native-node-modules.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index b03fea134e39..628933856092 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -25,13 +25,13 @@ where to download headers and which version to use: ```bash $ cd /path-to-module/ -$ HOME=~/.electron-gyp node-gyp rebuild --target=0.16.0 --arch=ia32 --dist-url=https://atom.io/download/atom-shell +$ HOME=~/.electron-gyp node-gyp rebuild --target=0.25.0 --arch=ia64 --dist-url=https://atom.io/download/electron ``` The `HOME=~/.electron-gyp` changes where to find development headers. The -`--target=0.16.0` is version of Electron. The `--dist-url=...` specifies -where to download the headers. The `--arch=ia32` says the module is built for -32bit system. +`--target=0.25.0` is version of Electron. The `--dist-url=...` specifies +where to download the headers. The `--arch=ia64` says the module is built for +64bit system. ### The npm way @@ -39,8 +39,8 @@ You can also use `npm` to install modules, the steps are exactly the same with Node modules, except that you need to setup some environment variables: ```bash -export npm_config_disturl=https://atom.io/download/atom-shell -export npm_config_target=0.23.0 +export npm_config_disturl=https://atom.io/download/electron +export npm_config_target=0.25.0 export npm_config_arch=x64 HOME=~/.electron-gyp npm install module-name ``` From e2ec50173f6483eae7290b9e482409569da32bea Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 1 May 2015 16:10:45 -0700 Subject: [PATCH 102/155] Log errors in preload script instead of rethrowing At some point, unhandled errors in preload scripts stopped being logged to console, meaning that preload scripts were very difficult to debug. Instead, print the error to console (which is what we wanted to have happen anyways) --- atom/renderer/lib/init.coffee | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index 43d0fa9cfa06..1e0167d6e154 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -103,5 +103,8 @@ if preloadScript try require preloadScript catch error - throw error unless error.code is 'MODULE_NOT_FOUND' - console.error "Unable to load preload script #{preloadScript}" + if error.code is 'MODULE_NOT_FOUND' + console.error "Unable to load preload script #{preloadScript}" + else + console.error(error) + console.error(error.stack) From 4f674156071c8bf8aa2bd127ca47cd1490043db3 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 1 May 2015 16:40:21 -0700 Subject: [PATCH 103/155] Enable NPAPI by default, trump Chromium's default --- atom/browser/lib/init.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index fcff0d890331..cbee13655416 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -81,6 +81,9 @@ if packageJson.desktopName? else app.setDesktopName "#{app.getName()}.desktop" +# Chrome 42 disables NPAPI plugins by default, reenable them here +app.commandLine.appendSwitch 'enable-npapi' + # Set the user path according to application's name. app.setPath 'userData', path.join(app.getPath('appData'), app.getName()) app.setPath 'userCache', path.join(app.getPath('cache'), app.getName()) From abe63ebd84ce72de6d03b96a62629fd076e58e8c Mon Sep 17 00:00:00 2001 From: Sergey R Date: Mon, 4 May 2015 02:21:07 +0300 Subject: [PATCH 104/155] docs: fix typo --- docs/tutorial/desktop-environment-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index ab4ef28b3366..3f65df234dfe 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -165,7 +165,7 @@ To set the progress bar for a Window, you can use the ```javascript var window = new BrowserWindow({...}); -window.setProgresssBar(0.5); +window.setProgressBar(0.5); ``` ## Represented file of window (OS X) From 6842ac98c3ed010cf2547ae080bb38cae958fad9 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Mon, 4 May 2015 10:13:43 +0700 Subject: [PATCH 105/155] revert changes of dist url --- docs/tutorial/using-native-node-modules.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 628933856092..95192aee0a1b 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -25,7 +25,7 @@ where to download headers and which version to use: ```bash $ cd /path-to-module/ -$ HOME=~/.electron-gyp node-gyp rebuild --target=0.25.0 --arch=ia64 --dist-url=https://atom.io/download/electron +$ HOME=~/.electron-gyp node-gyp rebuild --target=0.25.0 --arch=ia64 --dist-url=https://atom.io/download/atom-shell ``` The `HOME=~/.electron-gyp` changes where to find development headers. The @@ -39,7 +39,7 @@ You can also use `npm` to install modules, the steps are exactly the same with Node modules, except that you need to setup some environment variables: ```bash -export npm_config_disturl=https://atom.io/download/electron +export npm_config_disturl=https://atom.io/download/atom-shell export npm_config_target=0.25.0 export npm_config_arch=x64 HOME=~/.electron-gyp npm install module-name From f64dbbea3e97280d9459b939ede0646e4f715f64 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 11:23:09 +0800 Subject: [PATCH 106/155] docs: Pass bounds in clicked event of tray --- docs/api/tray.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index dd030385ad38..0562a6180e46 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -47,12 +47,16 @@ Creates a new tray icon associated with the `image`. ### Event: 'clicked' * `event` -* `point` Object +* `bounds` Object - the bounds of tray icon * `x` Integer * `y` Integer + * `width` Integer + * `height` Integer Emitted when the tray icon is clicked. +__NOte:__ The `bounds` payload is only implemented on OS X. + ### Event: 'double-clicked' Emitted when the tray icon is double clicked. @@ -106,7 +110,7 @@ Sets the hover text for this tray icon. Sets the title displayed aside of the tray icon in the status bar. -This is only implemented on OS X. +__Note:__ This is only implemented on OS X. ### Tray.setHighlightMode(highlight) @@ -114,7 +118,7 @@ This is only implemented on OS X. Sets whether the tray icon is highlighted when it is clicked. -This is only implmented on OS X. +__Note:__ This is only implemented on OS X. ### Tray.displayBalloon(options) @@ -123,10 +127,14 @@ This is only implmented on OS X. * `title` String * `content` String +Displays a tray balloon. + +__Note:__ This is only implemented on Windows. + ### Tray.setContextMenu(menu) * `menu` Menu -Set the context menu for this icon. +Sets the context menu for this icon. [event-emitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter From a53b1f7edf8323b1ef2417f46cb9dabdc7accdf4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 11:37:23 +0800 Subject: [PATCH 107/155] win: Mouse position is not notify icon's position --- atom/browser/ui/win/notify_icon.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 4c227c8044ae..99b7153631af 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -49,7 +49,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos, bool left_mouse_click) { // Pass to the observer if appropriate. if (left_mouse_click) { - NotifyClicked(cursor_pos); + NotifyClicked(); return; } From f5cf3556b1f4fb2765d1b9793176104bf999e915 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 11:43:05 +0800 Subject: [PATCH 108/155] Pass bounds in clicked event of tray --- atom/browser/api/atom_api_tray.cc | 4 ++-- atom/browser/api/atom_api_tray.h | 2 +- atom/browser/ui/tray_icon.cc | 4 ++-- atom/browser/ui/tray_icon.h | 3 ++- atom/browser/ui/tray_icon_cocoa.mm | 9 +++++---- atom/browser/ui/tray_icon_observer.h | 4 ++-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index c7e0149b0114..b66d95cb0732 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -40,8 +40,8 @@ mate::Wrappable* Tray::New(const gfx::Image& image) { return new Tray(image); } -void Tray::OnClicked(const gfx::Point& pos) { - Emit("clicked", pos); +void Tray::OnClicked(const gfx::Rect& bounds) { + Emit("clicked", bounds); } void Tray::OnDoubleClicked() { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 38fb044d9dab..5ed29ecd74f1 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -41,7 +41,7 @@ class Tray : public mate::EventEmitter, virtual ~Tray(); // TrayIconObserver: - void OnClicked(const gfx::Point&) override; + void OnClicked(const gfx::Rect&) override; void OnDoubleClicked() override; void OnBalloonShow() override; void OnBalloonClicked() override; diff --git a/atom/browser/ui/tray_icon.cc b/atom/browser/ui/tray_icon.cc index 06c1f4be5967..a3878f718a62 100644 --- a/atom/browser/ui/tray_icon.cc +++ b/atom/browser/ui/tray_icon.cc @@ -26,8 +26,8 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon, const base::string16& contents) { } -void TrayIcon::NotifyClicked(const gfx::Point& pos) { - FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(pos)); +void TrayIcon::NotifyClicked(const gfx::Rect& bounds) { + FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(bounds)); } void TrayIcon::NotifyDoubleClicked() { diff --git a/atom/browser/ui/tray_icon.h b/atom/browser/ui/tray_icon.h index 26f31a12e072..7dc67da1bac4 100644 --- a/atom/browser/ui/tray_icon.h +++ b/atom/browser/ui/tray_icon.h @@ -10,6 +10,7 @@ #include "atom/browser/ui/tray_icon_observer.h" #include "base/observer_list.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/gfx/geometry/rect.h" namespace atom { @@ -50,7 +51,7 @@ class TrayIcon { void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); } void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); } - void NotifyClicked(const gfx::Point&); + void NotifyClicked(const gfx::Rect& = gfx::Rect()); void NotifyDoubleClicked(); void NotifyBalloonShow(); void NotifyBalloonClicked(); diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index a68dd1c48e60..1bcbaf79ac10 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -26,13 +26,14 @@ } - (void)handleClick:(id)sender { - // Get the position of the frame of the NSStatusItem. - NSPoint pos = [NSApp currentEvent].window.frame.origin; + // Get the frame of the NSStatusItem. + NSRect frame = [NSApp currentEvent].window.frame; + gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); // Flip coordinates to gfx (0,0 in top-left corner) using current screen. NSScreen* screen = [NSScreen mainScreen]; - pos.y = NSMaxY([screen frame]) - pos.y; + bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); - trayIcon_->NotifyClicked(gfx::Point(pos.x, pos.y)); + trayIcon_->NotifyClicked(bounds); } - (void)handleDoubleClick:(id)sender { diff --git a/atom/browser/ui/tray_icon_observer.h b/atom/browser/ui/tray_icon_observer.h index 266654af21bf..3a34888b5318 100644 --- a/atom/browser/ui/tray_icon_observer.h +++ b/atom/browser/ui/tray_icon_observer.h @@ -6,14 +6,14 @@ #define ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_ namespace gfx { -class Point; +class Rect; } namespace atom { class TrayIconObserver { public: - virtual void OnClicked(const gfx::Point&) {} + virtual void OnClicked(const gfx::Rect&) {} virtual void OnDoubleClicked() {} virtual void OnBalloonShow() {} virtual void OnBalloonClicked() {} From 7142cae04195137da5d9a293225be5a88b8bc927 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 12:06:03 +0800 Subject: [PATCH 109/155] mac: Also use [NSScreen mainScreen] in other places --- atom/browser/native_window_mac.mm | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index e2b58e96c7f7..53d0a48eac31 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -11,14 +11,14 @@ #include "atom/common/options_switches.h" #include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" +#include "brightray/browser/inspectable_web_contents.h" +#include "brightray/browser/inspectable_web_contents_view.h" #include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "native_mate/dictionary.h" -#include "vendor/brightray/browser/inspectable_web_contents.h" -#include "vendor/brightray/browser/inspectable_web_contents_view.h" static const CGFloat kAtomWindowCornerRadius = 4.0; @@ -303,7 +303,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, options.Get(switches::kWidth, &width); options.Get(switches::kHeight, &height); - NSRect main_screen_rect = [[[NSScreen screens] objectAtIndex:0] frame]; + NSRect main_screen_rect = [[NSScreen mainScreen] frame]; NSRect cocoa_bounds = NSMakeRect( round((NSWidth(main_screen_rect) - width) / 2) , round((NSHeight(main_screen_rect) - height) / 2), @@ -463,7 +463,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds) { bounds.width(), bounds.height()); // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [NSScreen mainScreen]; cocoa_bounds.origin.y = NSHeight([screen frame]) - bounds.height() - bounds.y(); @@ -472,13 +472,10 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds) { gfx::Rect NativeWindowMac::GetBounds() { NSRect frame = [window_ frame]; - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; - - gfx::Point pos(frame.origin.x, - NSHeight([screen frame]) - frame.origin.y - frame.size.height); - gfx::Size size(frame.size.width, frame.size.height); - - return gfx::Rect(pos, size); + gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); + NSScreen* screen = [NSScreen mainScreen]; + bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); + return bounds; } void NativeWindowMac::SetSize(const gfx::Size& size) { From 0d4d2080ca61c76350019db0770f5a9a2887c41b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 12:43:40 +0800 Subject: [PATCH 110/155] Implement size and position APIs with bounds API --- atom/browser/native_window.cc | 16 +++++++++++++ atom/browser/native_window.h | 8 +++---- atom/browser/native_window_mac.h | 4 ---- atom/browser/native_window_mac.mm | 21 ----------------- atom/browser/native_window_views.cc | 35 +++-------------------------- atom/browser/native_window_views.h | 4 ---- 6 files changed, 23 insertions(+), 65 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 2920178058df..5bef1acfb872 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -237,6 +237,22 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } +void NativeWindow::SetSize(const gfx::Size& size) { + SetBounds(gfx::Rect(GetPosition(), size)); +} + +gfx::Size NativeWindow::GetSize() { + return GetBounds().size(); +} + +void NativeWindow::SetPosition(const gfx::Point& position) { + SetBounds(gfx::Rect(position, GetSize())); +} + +gfx::Point NativeWindow::GetPosition() { + return GetBounds().origin(); +} + void NativeWindow::SetRepresentedFilename(const std::string& filename) { } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 72056715837a..32c3493cdbf8 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -114,8 +114,10 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, virtual bool IsFullscreen() const = 0; virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; - virtual void SetSize(const gfx::Size& size) = 0; - virtual gfx::Size GetSize() = 0; + virtual void SetSize(const gfx::Size& size); + virtual gfx::Size GetSize(); + virtual void SetPosition(const gfx::Point& position); + virtual gfx::Point GetPosition(); virtual void SetContentSize(const gfx::Size& size) = 0; virtual gfx::Size GetContentSize() = 0; virtual void SetMinimumSize(const gfx::Size& size) = 0; @@ -127,8 +129,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, virtual void SetAlwaysOnTop(bool top) = 0; virtual bool IsAlwaysOnTop() = 0; virtual void Center() = 0; - virtual void SetPosition(const gfx::Point& position) = 0; - virtual gfx::Point GetPosition() = 0; virtual void SetTitle(const std::string& title) = 0; virtual std::string GetTitle() = 0; virtual void FlashFrame(bool flash) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 0fa3fe9cce42..8a6d141c34bf 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -46,8 +46,6 @@ class NativeWindowMac : public NativeWindow { bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; - void SetSize(const gfx::Size& size) override; - gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; gfx::Size GetContentSize() override; void SetMinimumSize(const gfx::Size& size) override; @@ -59,8 +57,6 @@ class NativeWindowMac : public NativeWindow { void SetAlwaysOnTop(bool top) override; bool IsAlwaysOnTop() override; void Center() override; - void SetPosition(const gfx::Point& position) override; - gfx::Point GetPosition() override; void SetTitle(const std::string& title) override; std::string GetTitle() override; void FlashFrame(bool flash) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 53d0a48eac31..9071763e77f3 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -478,19 +478,6 @@ gfx::Rect NativeWindowMac::GetBounds() { return bounds; } -void NativeWindowMac::SetSize(const gfx::Size& size) { - NSRect frame = [window_ frame]; - frame.origin.y -= size.height() - frame.size.height; - frame.size.width = size.width(); - frame.size.height = size.height(); - - [window_ setFrame:frame display:YES]; -} - -gfx::Size NativeWindowMac::GetSize() { - return GetBounds().size(); -} - void NativeWindowMac::SetContentSize(const gfx::Size& size) { NSRect frame_nsrect = [window_ frame]; NSSize frame = frame_nsrect.size; @@ -561,14 +548,6 @@ void NativeWindowMac::Center() { [window_ center]; } -void NativeWindowMac::SetPosition(const gfx::Point& position) { - SetBounds(gfx::Rect(position, GetSize())); -} - -gfx::Point NativeWindowMac::GetPosition() { - return GetBounds().origin(); -} - void NativeWindowMac::SetTitle(const std::string& title) { // We don't want the title to show in transparent window. if (transparent_) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 3b283ddbecf4..4c99f88969ba 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -391,31 +391,15 @@ gfx::Rect NativeWindowViews::GetBounds() { return window_->GetWindowBoundsInScreen(); } -void NativeWindowViews::SetSize(const gfx::Size& size) { -#if defined(USE_X11) - // On Linux the minimum and maximum size should be updated with window size - // when window is not resizable. - if (!resizable_) { - SetMaximumSize(size); - SetMinimumSize(size); - } -#endif - - window_->SetSize(size); -} - -gfx::Size NativeWindowViews::GetSize() { - return GetBounds().size(); -} - void NativeWindowViews::SetContentSize(const gfx::Size& size) { if (!has_frame_) { - SetSize(size); + NativeWindow::SetSize(size); return; } gfx::Rect bounds = window_->GetWindowBoundsInScreen(); - SetSize(ContentBoundsToWindowBounds(gfx::Rect(bounds.origin(), size)).size()); + bounds.set_size(size); + SetBounds(ContentBoundsToWindowBounds(bounds)); } gfx::Size NativeWindowViews::GetContentSize() { @@ -505,19 +489,6 @@ void NativeWindowViews::Center() { window_->CenterWindow(GetSize()); } -void NativeWindowViews::SetPosition(const gfx::Point& position) { - window_->SetBounds(gfx::Rect(position, GetSize())); -} - -gfx::Point NativeWindowViews::GetPosition() { -#if defined(OS_WIN) - if (IsMinimized()) - return window_->GetRestoredBounds().origin(); -#endif - - return window_->GetWindowBoundsInScreen().origin(); -} - void NativeWindowViews::SetTitle(const std::string& title) { title_ = title; window_->UpdateWindowTitle(); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 978aac826272..15f073d8d8c1 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -51,8 +51,6 @@ class NativeWindowViews : public NativeWindow, bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; - void SetSize(const gfx::Size& size) override; - gfx::Size GetSize() override; void SetContentSize(const gfx::Size& size) override; gfx::Size GetContentSize() override; void SetMinimumSize(const gfx::Size& size) override; @@ -64,8 +62,6 @@ class NativeWindowViews : public NativeWindow, void SetAlwaysOnTop(bool top) override; bool IsAlwaysOnTop() override; void Center() override; - void SetPosition(const gfx::Point& position) override; - gfx::Point GetPosition() override; void SetTitle(const std::string& title) override; std::string GetTitle() override; void FlashFrame(bool flash) override; From a04222f398269e94221dc7c2b8f71ccb3c0c3b88 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 12:51:28 +0800 Subject: [PATCH 111/155] spec: Fix error when refreshing --- spec/api-browser-window-spec.coffee | 4 +++- spec/webview-spec.coffee | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index e2e03acd84dd..3e9315a20e61 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -227,6 +227,7 @@ describe 'browser-window module', -> describe 'dom-ready event', -> it 'emits when document is loaded', (done) -> + ipc = remote.require 'ipc' server = http.createServer (req, res) -> action = url.parse(req.url, true).pathname if action == '/logo.png' @@ -237,7 +238,8 @@ describe 'browser-window module', -> , 2000 server.close() server.listen 62542, '127.0.0.1' - remote.require('ipc').on 'dom-ready', (e, state) -> + ipc.on 'dom-ready', (e, state) -> + ipc.removeAllListeners 'dom-ready' assert.equal state, 'interactive' done() w.webContents.on 'did-finish-load', -> diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 92a77351ee68..54bc2e78817f 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -181,15 +181,15 @@ describe ' tag', -> describe '.reload()', -> it 'should emit beforeunload handler', (done) -> - webview.addEventListener 'did-finish-load', (e) -> - webview.reload() listener = (e) -> assert.equal e.channel, 'onbeforeunload' webview.removeEventListener 'ipc-message', listener done() - webview.addEventListener 'console-message', (e) -> - console.log(e) + listener2 = (e) -> + webview.reload() + webview.removeEventListener 'did-finish-load', listener2 webview.addEventListener 'ipc-message', listener + webview.addEventListener 'did-finish-load', listener2 webview.setAttribute 'nodeintegration', 'on' webview.src = "file://#{fixtures}/pages/beforeunload-false.html" document.body.appendChild webview From 22c50d0800b57289fd161b8fb3a0330ee6238862 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 4 May 2015 13:39:13 +0530 Subject: [PATCH 112/155] webContents: removing getFavicon api --- atom/browser/api/atom_api_web_contents.cc | 8 -------- atom/browser/api/atom_api_web_contents.h | 1 - atom/renderer/lib/web-view/web-view.coffee | 7 ------- docs/api/browser-window.md | 4 ---- docs/api/web-view-tag.md | 4 ---- 5 files changed, 24 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index f13127c84b35..c998deca5e30 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -426,13 +426,6 @@ base::string16 WebContents::GetTitle() const { return web_contents()->GetTitle(); } -gfx::Image WebContents::GetFavicon() const { - auto entry = web_contents()->GetController().GetLastCommittedEntry(); - if (!entry) - return gfx::Image(); - return entry->GetFavicon().image; -} - bool WebContents::IsLoading() const { return web_contents()->IsLoading(); } @@ -613,7 +606,6 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("isAlive", &WebContents::IsAlive) .SetMethod("_loadUrl", &WebContents::LoadURL) .SetMethod("getTitle", &WebContents::GetTitle) - .SetMethod("getFavicon", &WebContents::GetFavicon) .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("_stop", &WebContents::Stop) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 1925a96f6229..cc2fd30c832f 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -49,7 +49,6 @@ class WebContents : public mate::EventEmitter, bool IsAlive() const; void LoadURL(const GURL& url, const mate::Dictionary& options); base::string16 GetTitle() const; - gfx::Image GetFavicon() const; bool IsLoading() const; bool IsWaitingForResponse() const; void Stop(); diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index 8641151eac03..bf163c0cfb5c 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -277,13 +277,6 @@ registerWebViewElement = -> remote.getGuestWebContents(internal.guestInstanceId)[m] args... proto[m] = createHandler m for m in methods - # Return dataUrl instead of nativeImage. - proto.getFavicon = (args...) -> - internal = v8Util.getHiddenValue this, 'internal' - return unless internal - favicon = remote.getGuestWebContents(internal.guestInstanceId)['getFavicon'] args... - favicon.toDataUrl() - window.WebView = webFrame.registerEmbedderCustomElement 'webview', prototype: proto diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 44021cabe939..b1023db844e0 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -741,10 +741,6 @@ Returns URL of current web page. Returns the title of web page. -### WebContents.getFavicon() - -Returns the favicon of web page as [NativeImage](native-image.md). - ### WebContents.isLoading() Returns whether web page is still loading resources. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 697860cfea67..89ae678b3c46 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -130,10 +130,6 @@ Returns URL of guest page. Returns the title of guest page. -### ``.getFavicon() - -Returns the favicon of guest page as dataUrl. - ### ``.isLoading() Returns whether guest page is still loading resources. From 298d3a0144b740a40fc27af5fae931659c238845 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 4 May 2015 20:58:48 +0800 Subject: [PATCH 113/155] Fix compilation error on OS X. --- atom/app/atom_main_delegate.cc | 4 +--- atom/utility/atom_content_utility_client.cc | 6 ++---- filenames.gypi | 8 ++++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 7862e8ff6bda..c9cdc77e1173 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -10,11 +10,11 @@ #include "atom/browser/atom_browser_client.h" #include "atom/common/google_api_key.h" #include "atom/renderer/atom_renderer_client.h" +#include "atom/utility/atom_content_utility_client.h" #include "base/command_line.h" #include "base/debug/stack_trace.h" #include "base/environment.h" #include "base/logging.h" -#include "chrome/utility/chrome_content_utility_client.h" #include "content/public/common/content_switches.h" #include "ui/base/resource/resource_bundle.h" @@ -96,10 +96,8 @@ content::ContentRendererClient* } content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() { -#if defined(OS_WIN) utility_client_.reset(new AtomContentUtilityClient); return utility_client_.get(); -#endif } scoped_ptr AtomMainDelegate::CreateContentClient() { diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index 41b1f851cb74..cc739227aad8 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -27,10 +27,6 @@ bool Send(IPC::Message* message) { return content::UtilityThread::Get()->Send(message); } -void ReleaseProcessIfNeeded() { - content::UtilityThread::Get()->ReleaseProcessIfNeeded(); -} - } // namespace namespace atom { @@ -40,7 +36,9 @@ int64_t AtomContentUtilityClient::max_ipc_message_size_ = AtomContentUtilityClient::AtomContentUtilityClient() : filter_messages_(false) { +#if defined(OS_WIN) handlers_.push_back(new PrintingHandler()); +#endif } AtomContentUtilityClient::~AtomContentUtilityClient() { diff --git a/filenames.gypi b/filenames.gypi index 93e4da93e888..ef8396287ad3 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -293,8 +293,6 @@ 'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h', 'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc', 'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h', - 'chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc', - 'chromium_src/chrome/browser/printing/pdf_to_emf_converter.h', 'chromium_src/chrome/browser/printing/print_job.cc', 'chromium_src/chrome/browser/printing/print_job.h', 'chromium_src/chrome/browser/printing/print_job_manager.cc', @@ -343,8 +341,6 @@ 'chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h', 'chromium_src/chrome/renderer/tts_dispatcher.cc', 'chromium_src/chrome/renderer/tts_dispatcher.h', - 'chromium_src/chrome/utility/printing_handler.cc', - 'chromium_src/chrome/utility/printing_handler.h', 'chromium_src/chrome/utility/utility_message_handler.h', 'chromium_src/library_loaders/libspeechd_loader.cc', 'chromium_src/library_loaders/libspeechd.h', @@ -355,6 +351,10 @@ 'chromium_src/chrome/browser/ui/views/color_chooser_dialog.cc', 'chromium_src/chrome/browser/ui/views/color_chooser_dialog.h', 'chromium_src/chrome/browser/ui/views/color_chooser_win.cc', + 'chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc', + 'chromium_src/chrome/browser/printing/pdf_to_emf_converter.h', + 'chromium_src/chrome/utility/printing_handler.cc', + 'chromium_src/chrome/utility/printing_handler.h', ], 'framework_sources': [ 'atom/app/atom_library_main.h', From 2d190b9952a38de2ad69c1a576b5cb6fbc1e9352 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 4 May 2015 20:44:36 +0530 Subject: [PATCH 114/155] spec: add test for basic authentication --- spec/api-browser-window-spec.coffee | 24 ++++++++++++++++++++++++ spec/fixtures/pages/basic-auth.html | 17 +++++++++++++++++ spec/package.json | 1 + 3 files changed, 42 insertions(+) create mode 100644 spec/fixtures/pages/basic-auth.html diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 3e9315a20e61..958bd7295803 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -4,6 +4,7 @@ path = require 'path' remote = require 'remote' http = require 'http' url = require 'url' +auth = require 'basic-auth' BrowserWindow = remote.require 'browser-window' @@ -245,3 +246,26 @@ describe 'browser-window module', -> w.webContents.on 'did-finish-load', -> w.close() w.loadUrl "file://#{fixtures}/pages/f.html" + + describe 'basic auth', -> + it 'should authenticate with correct credentials', (done) -> + ipc = remote.require 'ipc' + server = http.createServer (req, res) -> + action = url.parse(req.url, true).pathname + if action == '/' + credentials = auth(req) + if credentials.name == 'test' and credentials.pass == 'test' + res.end('Authenticated') + server.close() + else if action == '/jquery.js' + js = fs.readFileSync(path.join(__dirname, 'static', 'jquery-2.0.3.min.js')) + res.writeHead(200, {'Content-Type': 'text/javascript'}) + res.end(js, 'utf-8') + server.listen 62342, '127.0.0.1' + ipc.on 'console-message', (e, message) -> + ipc.removeAllListeners 'console-message' + assert.equal message, 'Authenticated' + done() + w.webContents.on 'did-finish-load', -> + w.close() + w.loadUrl "file://#{fixtures}/pages/basic-auth.html" diff --git a/spec/fixtures/pages/basic-auth.html b/spec/fixtures/pages/basic-auth.html new file mode 100644 index 000000000000..81d5bd209cee --- /dev/null +++ b/spec/fixtures/pages/basic-auth.html @@ -0,0 +1,17 @@ + + + + + + diff --git a/spec/package.json b/spec/package.json index d91398382d9a..6e9489e601d8 100644 --- a/spec/package.json +++ b/spec/package.json @@ -4,6 +4,7 @@ "main": "static/main.js", "version": "0.1.0", "devDependencies": { + "basic-auth": "^1.0.0", "formidable": "1.0.16", "graceful-fs": "3.0.5", "mocha": "2.1.0", From 56afe4dd5d5c616e0b6a3d92f71ff93d20c19fa0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 4 May 2015 22:38:05 +0800 Subject: [PATCH 115/155] win: Remove unused build setting --- atom.gyp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 760937c87f2e..b1f473bd1544 100644 --- a/atom.gyp +++ b/atom.gyp @@ -114,15 +114,6 @@ ], }], # OS!="mac" ['OS=="win"', { - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalOptions': [ - # Force linking even though we have duplicate symbols between - # BoringSSL and OpenSSL. - '/FORCE:MULTIPLE', - ], - }, - }, 'copies': [ { 'variables': { From 904505bb2143f1af2dece0d2178ccbed7036b5fd Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 4 May 2015 22:39:55 -0700 Subject: [PATCH 116/155] Suggest electron-rebuild for building native modules --- docs/tutorial/using-native-node-modules.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 95192aee0a1b..643b4915b7ed 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -18,6 +18,19 @@ For old modules that only support Node v0.10.x, you should use the ## How to install native modules +### The Easy Way + +The most straightforward way to rebuild native modules is via the +[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) package, +which handles the manual steps of downloading headers and building native modules: + +```sh +npm install --save-dev electron-rebuild + +# Every time you run npm install, run this too +./node_modules/.bin/electron-rebuild +``` + ### The node-gyp way To build Node modules with headers of Electron, you need to tell `node-gyp` From a6ba0cd10751c3b051503f6eea4b312c89f07abd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 5 May 2015 16:07:47 +0800 Subject: [PATCH 117/155] Update libchromiumcontent which includes pdf and ppapi libs --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index d149446c1d72..af89a057d389 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -7,7 +7,7 @@ import sys BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '0fb4fbe55f5a967b960644f0fdc2013668d5a46a' +LIBCHROMIUMCONTENT_COMMIT = '07a73a610496e4a1b4f3abc3c2fb0516187ec460' PLATFORM = { 'cygwin': 'win32', From f2853a0b89b4d7a8e83fbbd9f6044cd646cd34ab Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 5 May 2015 21:56:58 +0800 Subject: [PATCH 118/155] Some cleanup. --- .../chrome/common/chrome_utility_messages.h | 48 ------------------- .../chrome/utility/utility_message_handler.h | 1 - 2 files changed, 49 deletions(-) diff --git a/chromium_src/chrome/common/chrome_utility_messages.h b/chromium_src/chrome/common/chrome_utility_messages.h index 235c10333ee2..1de0756c0d58 100644 --- a/chromium_src/chrome/common/chrome_utility_messages.h +++ b/chromium_src/chrome/common/chrome_utility_messages.h @@ -35,13 +35,6 @@ typedef std::vector> #define IPC_MESSAGE_START ChromeUtilityMsgStart -//#if defined(FULL_SAFE_BROWSING) -//IPC_STRUCT_TRAITS_BEGIN(safe_browsing::zip_analyzer::Results) - //IPC_STRUCT_TRAITS_MEMBER(success) - //IPC_STRUCT_TRAITS_MEMBER(has_executable) - //IPC_STRUCT_TRAITS_MEMBER(has_archive) -//IPC_STRUCT_TRAITS_END() -//#endif #if defined(OS_WIN) IPC_STRUCT_BEGIN(ChromeUtilityMsg_GetSaveFileName_Params) @@ -89,25 +82,12 @@ IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_PatchFileCourgette, base::FilePath /* patch_file */, base::FilePath /* output_file */) -#if defined(OS_CHROMEOS) -// Tell the utility process to create a zip file on the given list of files. -IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_CreateZipFile, - base::FilePath /* src_dir */, - std::vector /* src_relative_paths */, - base::FileDescriptor /* dest_fd */) -#endif // defined(OS_CHROMEOS) // Requests the utility process to respond with a // ChromeUtilityHostMsg_ProcessStarted message once it has started. This may // be used if the host process needs a handle to the running utility process. IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_StartupPing) -#if defined(FULL_SAFE_BROWSING) -// Tells the utility process to analyze a zip file for malicious download -// protection. -IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, - IPC::PlatformFileForTransit /* zip_file */) -#endif #if defined(OS_WIN) // Invokes ui::base::win::OpenFileViaShell from the utility process. @@ -136,12 +116,6 @@ IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_GetSaveFileName, ChromeUtilityMsg_GetSaveFileName_Params /* params */) #endif // defined(OS_WIN) -//#if defined(OS_ANDROID) -//// Instructs the utility process to detect support for seccomp-bpf, -//// and the result is reported through -//// ChromeUtilityHostMsg_DetectSeccompSupport_Result. -//IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_DetectSeccompSupport) -//#endif //------------------------------------------------------------------------------ // Utility process host messages: @@ -176,23 +150,10 @@ IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_DecodeImage_Failed) // Reply when a file has been patched. IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_PatchFile_Finished, int /* result */) -//#if defined(OS_CHROMEOS) -//// Reply when the utility process has succeeded in creating the zip file. -//IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_CreateZipFile_Succeeded) - -//// Reply when an error occured in creating the zip file. -//IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_CreateZipFile_Failed) -//#endif // defined(OS_CHROMEOS) // Reply when the utility process has started. IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_ProcessStarted) -//#if defined(FULL_SAFE_BROWSING) -//// Reply when a zip file has been analyzed for malicious download protection. -//IPC_MESSAGE_CONTROL1( - //ChromeUtilityHostMsg_AnalyzeZipFileForDownloadProtection_Finished, - //safe_browsing::zip_analyzer::Results) -//#endif #if defined(OS_WIN) IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetOpenFileName_Failed) @@ -206,12 +167,3 @@ IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetSaveFileName_Result, IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_BuildDirectWriteFontCache, base::FilePath /* cache file path */) #endif // defined(OS_WIN) - -//#if defined(OS_ANDROID) -//// Reply to ChromeUtilityMsg_DetectSeccompSupport to report the level -//// of kernel support for seccomp-bpf. -//IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl, - //bool [> seccomp prctl supported <]) -//IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall, - //bool [> seccomp syscall supported <]) -//#endif diff --git a/chromium_src/chrome/utility/utility_message_handler.h b/chromium_src/chrome/utility/utility_message_handler.h index a86219188096..3ccff1a0fbed 100644 --- a/chromium_src/chrome/utility/utility_message_handler.h +++ b/chromium_src/chrome/utility/utility_message_handler.h @@ -19,4 +19,3 @@ class UtilityMessageHandler { }; #endif // CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_ - From 0f67b1866a9f00b852370e721affa4efda623f3a Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 28 Apr 2015 13:28:18 +0800 Subject: [PATCH 119/155] Add `Super` key support in global-shortcut API. --- atom/browser/ui/accelerator_util.cc | 4 ++++ .../chrome/browser/extensions/global_shortcut_listener_win.cc | 4 ++++ .../chrome/browser/extensions/global_shortcut_listener_x11.cc | 3 +++ docs/api/accelerator.md | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index 4978b102c525..d210501ad8df 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -109,8 +109,12 @@ bool StringToAccelerator(const std::string& description, modifiers |= ui::EF_SHIFT_DOWN; } else if (tokens[i] == "ctrl" || tokens[i] == "control") { modifiers |= ui::EF_CONTROL_DOWN; + } else if (tokens[i] == "super") { + modifiers |= ui::EF_COMMAND_DOWN; +#if defined(OS_MACOSX) } else if (tokens[i] == "cmd" || tokens[i] == "command") { modifiers |= ui::EF_COMMAND_DOWN; +#endif } else if (tokens[i] == "commandorcontrol" || tokens[i] == "cmdorctrl") { #if defined(OS_MACOSX) modifiers |= ui::EF_COMMAND_DOWN; diff --git a/chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc b/chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc index 8f6f1912e36f..248ec6b890ef 100644 --- a/chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc +++ b/chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc @@ -58,6 +58,8 @@ void GlobalShortcutListenerWin::OnWndProc(HWND hwnd, modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0; modifiers |= (LOWORD(lparam) & MOD_ALT) ? ui::EF_ALT_DOWN : 0; modifiers |= (LOWORD(lparam) & MOD_CONTROL) ? ui::EF_CONTROL_DOWN : 0; + modifiers |= (LOWORD(lparam) & MOD_WIN) ? ui::EF_COMMAND_DOWN : 0; + ui::Accelerator accelerator( ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers); @@ -72,6 +74,8 @@ bool GlobalShortcutListenerWin::RegisterAcceleratorImpl( modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0; modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0; modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0; + modifiers |= accelerator.IsCmdDown() ? MOD_WIN : 0; + static int hotkey_id = 0; bool success = !!RegisterHotKey( gfx::SingletonHwnd::GetInstance()->hwnd(), diff --git a/chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.cc b/chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.cc index 5a3ad1a7a6ce..9a3cca69d538 100644 --- a/chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.cc +++ b/chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.cc @@ -35,6 +35,7 @@ int GetNativeModifiers(const ui::Accelerator& accelerator) { modifiers |= accelerator.IsShiftDown() ? ShiftMask : 0; modifiers |= accelerator.IsCtrlDown() ? ControlMask : 0; modifiers |= accelerator.IsAltDown() ? Mod1Mask : 0; + modifiers |= accelerator.IsCmdDown() ? Mod4Mask : 0; return modifiers; } @@ -148,6 +149,8 @@ void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) { modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0; modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0; modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0; + // For Windows key + modifiers |= (x_event->xkey.state & Mod4Mask) ? ui::EF_COMMAND_DOWN: 0; ui::Accelerator accelerator( ui::KeyboardCodeFromXKeyEvent(x_event), modifiers); diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md index 58c57d4590a1..a9755ed653b0 100644 --- a/docs/api/accelerator.md +++ b/docs/api/accelerator.md @@ -14,6 +14,9 @@ On Linux and Windows, the `Command` key would not have any effect, you can use `CommandOrControl` which represents `Command` on OS X and `Control` on Linux and Windows to define some accelerators. +The `Super` key is mapped to the `Windows` key on Windows and Linux and +`Cmd` on OS X. + ## Available modifiers * `Command` (or `Cmd` for short) @@ -21,6 +24,7 @@ Linux and Windows to define some accelerators. * `CommandOrControl` (or `CmdOrCtrl` for short) * `Alt` * `Shift` +* `Super` ## Available key codes From 102fb66461f6e5cecbe7ff824108ef23a3dd83a2 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 5 May 2015 20:53:26 -0400 Subject: [PATCH 120/155] Remove the textured background. --- atom/browser/native_window_mac.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9071763e77f3..c58c1d6ce38d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -313,8 +313,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, window_.reset([[AtomNSWindow alloc] initWithContentRect:cocoa_bounds styleMask:NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSResizableWindowMask | - NSTexturedBackgroundWindowMask + NSMiniaturizableWindowMask | NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES]); [window_ setShell:this]; From 1817ddc18ae6864b166289f6673113c1910b975b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 6 May 2015 09:17:40 +0800 Subject: [PATCH 121/155] Upload mksnapshot to releases --- script/create-dist.py | 26 +++++++++++++------------- script/upload.py | 7 ++++++- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/script/create-dist.py b/script/create-dist.py index 3703e960ae03..7a5b75b07b7b 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -79,7 +79,8 @@ def main(): force_build() create_symbols() copy_binaries() - copy_chromedriver() + copy_chrome_binary('chromedriver') + copy_chrome_binary('mksnapshot') copy_license() if PLATFORM == 'linux': @@ -88,7 +89,8 @@ def main(): create_version() create_dist_zip() - create_chromedriver_zip() + create_chrome_binary_zip('chromedriver', get_chromedriver_version()) + create_chrome_binary_zip('mksnapshot', ATOM_SHELL_VERSION) create_symbols_zip() @@ -107,13 +109,11 @@ def copy_binaries(): symlinks=True) -def copy_chromedriver(): +def copy_chrome_binary(binary): if PLATFORM == 'win32': - chromedriver = 'chromedriver.exe' - else: - chromedriver = 'chromedriver' - src = os.path.join(CHROMIUM_DIR, chromedriver) - dest = os.path.join(DIST_DIR, chromedriver) + binary += '.exe' + src = os.path.join(CHROMIUM_DIR, binary) + dest = os.path.join(DIST_DIR, binary) # Copy file and keep the executable bit. shutil.copyfile(src, dest) @@ -170,17 +170,17 @@ def create_dist_zip(): make_zip(zip_file, files, dirs) -def create_chromedriver_zip(): - dist_name = 'chromedriver-{0}-{1}-{2}.zip'.format(get_chromedriver_version(), - PLATFORM, get_target_arch()) +def create_chrome_binary_zip(binary, version): + dist_name = '{0}-{1}-{2}-{3}.zip'.format(binary, version, PLATFORM, + get_target_arch()) zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) with scoped_cwd(DIST_DIR): files = ['LICENSE'] if PLATFORM == 'win32': - files += ['chromedriver.exe'] + files += [binary + '.exe'] else: - files += ['chromedriver'] + files += [binary] make_zip(zip_file, files, []) diff --git a/script/upload.py b/script/upload.py index 040d1650110b..281300554ef3 100755 --- a/script/upload.py +++ b/script/upload.py @@ -34,6 +34,9 @@ SYMBOLS_NAME = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME, CHROMEDRIVER_NAME = 'chromedriver-{0}-{1}-{2}.zip'.format(CHROMEDRIVER_VERSION, PLATFORM, get_target_arch()) +MKSNAPSHOT_NAME = 'mksnapshot-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION, + PLATFORM, + get_target_arch()) def main(): @@ -74,10 +77,12 @@ def main(): upload_atom_shell(github, release_id, os.path.join(DIST_DIR, DIST_NAME)) upload_atom_shell(github, release_id, os.path.join(DIST_DIR, SYMBOLS_NAME)) - # Upload chromedriver for minor version update. + # Upload chromedriver and mksnapshot for minor version update. if parse_version(args.version)[2] == '0': upload_atom_shell(github, release_id, os.path.join(DIST_DIR, CHROMEDRIVER_NAME)) + upload_atom_shell(github, release_id, + os.path.join(DIST_DIR, MKSNAPSHOT_NAME)) if PLATFORM == 'win32': # Upload PDBs to Windows symbol server. From 5f357d39b23a4fb06bfa081d5c75d84e99a43b14 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 6 May 2015 10:08:24 -0400 Subject: [PATCH 122/155] If it's frameless then use the textured background. --- atom/browser/native_window_mac.mm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index c58c1d6ce38d..4dac6b75c9f6 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -310,10 +310,18 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, width, height); + bool useFrame = true; + options.Get(switches::kFrame, &useFrame); + + NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSResizableWindowMask; + if (!useFrame) { + styleMask |= NSTexturedBackgroundWindowMask; + } + window_.reset([[AtomNSWindow alloc] initWithContentRect:cocoa_bounds - styleMask:NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSResizableWindowMask + styleMask:styleMask backing:NSBackingStoreBuffered defer:YES]); [window_ setShell:this]; From 2b82e523bf1c522e5498b5abe7063299f495b334 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 7 May 2015 15:46:38 +0800 Subject: [PATCH 123/155] Fix a potential out-of-bound issue in Accelerator. --- atom/browser/ui/accelerator_util.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index d210501ad8df..87e56d063d7e 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -175,7 +175,7 @@ bool StringToAccelerator(const std::string& description, } else if (tokens[i].size() > 1 && tokens[i][0] == 'f') { // F1 - F24. int n; - if (base::StringToInt(tokens[i].c_str() + 1, &n)) { + if (base::StringToInt(tokens[i].c_str() + 1, &n) && n > 0 && n < 25) { key = static_cast(ui::VKEY_F1 + n - 1); } else { LOG(WARNING) << tokens[i] << "is not available on keyboard"; From ae8ac97f32873e2a468f707253c4f15102917ff6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 7 May 2015 19:44:06 +0800 Subject: [PATCH 124/155] Upgrade brightray, fixes #1318 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 32ba91f830a1..58df63ecb63e 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 32ba91f830a12f6f37017797b9b65d55037ad29d +Subproject commit 58df63ecb63e38d1951e38f392fb4354aed6de96 From dca872d98790f61369179bae70bbc75c77ca0189 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 8 May 2015 13:42:18 +0800 Subject: [PATCH 125/155] win: Download 64bit directx sdk when building for 64bit target --- script/update-external-binaries.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/script/update-external-binaries.py b/script/update-external-binaries.py index a95a30f4a549..0df5fcc03976 100755 --- a/script/update-external-binaries.py +++ b/script/update-external-binaries.py @@ -4,10 +4,11 @@ import errno import sys import os +from lib.config import get_target_arch from lib.util import safe_mkdir, rm_rf, extract_zip, tempdir, download -VERSION = 'v0.5.0' +VERSION = 'v0.6.0' SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) FRAMEWORKS_URL = 'http://github.com/atom/atom-shell-frameworks/releases' \ '/download/' + VERSION @@ -28,7 +29,7 @@ def main(): download_and_unzip('ReactiveCocoa') download_and_unzip('Squirrel') elif sys.platform in ['cygwin', 'win32']: - download_and_unzip('directxsdk') + download_and_unzip('directxsdk-' + get_target_arch()) with open(version_file, 'w') as f: f.write(VERSION) From 4d9470c24e2d2e168f30846ee07dca96205185d6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 8 May 2015 14:28:11 +0800 Subject: [PATCH 126/155] Bump v0.25.3 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index b1f473bd1544..5169fda640e9 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.25.2', + 'version%': '0.25.3', 'atom_source_root': 'CFBundleIconFile atom.icns CFBundleVersion - 0.25.2 + 0.25.3 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index aa9d3a0726ff..6891c1d4c991 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,25,2,0 - PRODUCTVERSION 0,25,2,0 + FILEVERSION 0,25,3,0 + PRODUCTVERSION 0,25,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.25.2" + VALUE "FileVersion", "0.25.3" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.25.2" + VALUE "ProductVersion", "0.25.3" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index dc8f08b785d8..4b7d98ea795b 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 25 -#define ATOM_PATCH_VERSION 2 +#define ATOM_PATCH_VERSION 3 #define ATOM_VERSION_IS_RELEASE 1 From 85119db81afb58729bfd66a282838e5780c73a15 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 8 May 2015 16:28:24 -0400 Subject: [PATCH 127/155] Use a new option to opt into the standard window. --- atom/browser/native_window_mac.mm | 6 +++--- atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 4dac6b75c9f6..70276c9a1cd1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -310,12 +310,12 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, width, height); - bool useFrame = true; - options.Get(switches::kFrame, &useFrame); + bool useStandardWindow = false; + options.Get(switches::kStandardWindow, &useStandardWindow); NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask; - if (!useFrame) { + if (!useStandardWindow) { styleMask |= NSTexturedBackgroundWindowMask; } diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index c479b5004d07..bfe34ee653ce 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -78,6 +78,9 @@ const char kType[] = "type"; // Disable auto-hiding cursor. const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor"; +// Use the OS X's standard window instead of the textured window. +const char kStandardWindow[] = "standard-window"; + // Web runtime features. const char kExperimentalFeatures[] = "experimental-features"; const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 546c6a04eb4d..118271b6e994 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -42,6 +42,7 @@ extern const char kPreloadScript[]; extern const char kTransparent[]; extern const char kType[]; extern const char kDisableAutoHideCursor[]; +extern const char kStandardWindow[]; extern const char kExperimentalFeatures[]; extern const char kExperimentalCanvasFeatures[]; From c8d0ef05a64b7e903b40b23f01bc623abe681579 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 8 May 2015 16:33:57 -0400 Subject: [PATCH 128/155] Docs. --- docs/api/browser-window.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 44021cabe939..d2854fc17014 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -72,6 +72,8 @@ You can also create a window without chrome by using * `type` String - Specifies the type of the window, possible types are `desktop`, `dock`, `toolbar`, `splash`, `notification`. This only works on Linux. + * `standard-window` Boolean - Use the OS X's standard window instead of the + textured window. Defaults to `false`. * `web-preferences` Object - Settings of web page's features * `javascript` Boolean * `web-security` Boolean From be06a3d562b2564838978e0c61999219a483c9c8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 10 May 2015 11:41:02 +0800 Subject: [PATCH 129/155] Upgrade brightray for #1532 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 58df63ecb63e..a929d7582927 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 58df63ecb63e38d1951e38f392fb4354aed6de96 +Subproject commit a929d75829270def615e342c79ea17634e8c5989 From 3fdc4543b8a99c17134c87e902ddc1528cce4d74 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 28 Apr 2015 21:15:58 +0530 Subject: [PATCH 130/155] ppapi flash plugin support --- atom/app/atom_content_client.cc | 69 ++++ atom/app/atom_content_client.h | 2 + atom/browser/atom_browser_client.cc | 10 + atom/browser/atom_browser_client.h | 1 + atom/common/options_switches.cc | 3 + atom/common/options_switches.h | 1 + atom/renderer/atom_renderer_client.cc | 6 + atom/renderer/atom_renderer_client.h | 1 + .../chrome_browser_pepper_host_factory.cc | 94 +++++ .../chrome_browser_pepper_host_factory.h | 38 ++ .../pepper/pepper_broker_message_filter.cc | 54 +++ .../pepper/pepper_broker_message_filter.h | 51 +++ .../pepper/pepper_flash_browser_host.cc | 114 ++++++ .../pepper/pepper_flash_browser_host.h | 60 +++ .../pepper_flash_clipboard_message_filter.cc | 376 ++++++++++++++++++ .../pepper_flash_clipboard_message_filter.h | 78 ++++ ...per_isolated_file_system_message_filter.cc | 110 +++++ ...pper_isolated_file_system_message_filter.h | 76 ++++ .../chrome_renderer_pepper_host_factory.cc | 87 ++++ .../chrome_renderer_pepper_host_factory.h | 35 ++ .../pepper/pepper_flash_drm_renderer_host.cc | 87 ++++ .../pepper/pepper_flash_drm_renderer_host.h | 51 +++ .../pepper/pepper_flash_font_file_host.cc | 74 ++++ .../pepper/pepper_flash_font_file_host.h | 52 +++ .../pepper/pepper_flash_fullscreen_host.cc | 43 ++ .../pepper/pepper_flash_fullscreen_host.h | 37 ++ .../renderer/pepper/pepper_flash_menu_host.cc | 202 ++++++++++ .../renderer/pepper/pepper_flash_menu_host.h | 69 ++++ .../pepper/pepper_flash_renderer_host.cc | 373 +++++++++++++++++ .../pepper/pepper_flash_renderer_host.h | 69 ++++ .../chrome/renderer/pepper/pepper_helper.cc | 26 ++ .../chrome/renderer/pepper/pepper_helper.h | 25 ++ .../pepper_shared_memory_message_filter.cc | 72 ++++ .../pepper_shared_memory_message_filter.h | 48 +++ filenames.gypi | 26 ++ 35 files changed, 2520 insertions(+) create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc create mode 100644 chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h create mode 100644 chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc create mode 100644 chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_helper.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_helper.h create mode 100644 chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc create mode 100644 chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index f4beeb5c4326..5d97fe5665f2 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -8,9 +8,65 @@ #include #include "atom/common/chrome_version.h" +#include "atom/common/options_switches.h" +#include "base/command_line.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "content/public/common/content_constants.h" +#include "content/public/common/pepper_plugin_info.h" +#include "ppapi/shared_impl/ppapi_permissions.h" namespace atom { +int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV | + ppapi::PERMISSION_PRIVATE | + ppapi::PERMISSION_BYPASS_USER_GESTURE | + ppapi::PERMISSION_FLASH; + +namespace { + + content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, + const std::string& version) { + content::PepperPluginInfo plugin; + + plugin.is_out_of_process = true; + plugin.name = content::kFlashPluginName; + plugin.path = path; + plugin.permissions = kPepperFlashPermissions; + + std::vector flash_version_numbers; + base::SplitString(version, '.', &flash_version_numbers); + if (flash_version_numbers.size() < 1) + flash_version_numbers.push_back("11"); + // |SplitString()| puts in an empty string given an empty string. :( + else if (flash_version_numbers[0].empty()) + flash_version_numbers[0] = "11"; + if (flash_version_numbers.size() < 2) + flash_version_numbers.push_back("2"); + if (flash_version_numbers.size() < 3) + flash_version_numbers.push_back("999"); + if (flash_version_numbers.size() < 4) + flash_version_numbers.push_back("999"); + // E.g., "Shockwave Flash 10.2 r154": + plugin.description = plugin.name + " " + flash_version_numbers[0] + "." + + flash_version_numbers[1] + " r" + flash_version_numbers[2]; + plugin.version = JoinString(flash_version_numbers, '.'); + content::WebPluginMimeType swf_mime_type( + content::kFlashPluginSwfMimeType, + content::kFlashPluginSwfExtension, + content::kFlashPluginSwfDescription); + plugin.mime_types.push_back(swf_mime_type); + content::WebPluginMimeType spl_mime_type( + content::kFlashPluginSplMimeType, + content::kFlashPluginSplExtension, + content::kFlashPluginSplDescription); + plugin.mime_types.push_back(spl_mime_type); + + return plugin; + } + +} // namespace + AtomContentClient::AtomContentClient() { } @@ -27,4 +83,17 @@ void AtomContentClient::AddAdditionalSchemes( standard_schemes->push_back("chrome-extension"); } +void AtomContentClient::AddPepperPlugins( + std::vector* plugins) { + const base::CommandLine::StringType flash_path = + base::CommandLine::ForCurrentProcess()->GetSwitchValueNative( + switches::kPpapiFlashPath); + if (flash_path.empty()) + return; + + std::string flash_version; + plugins->push_back( + CreatePepperFlashInfo(base::FilePath(flash_path), flash_version)); +} + } // namespace atom diff --git a/atom/app/atom_content_client.h b/atom/app/atom_content_client.h index 732ac3587800..279ec7179f49 100644 --- a/atom/app/atom_content_client.h +++ b/atom/app/atom_content_client.h @@ -23,6 +23,8 @@ class AtomContentClient : public brightray::ContentClient { void AddAdditionalSchemes( std::vector* standard_schemes, std::vector* savable_schemes) override; + void AddPepperPlugins( + std::vector* plugins) override; private: DISALLOW_COPY_AND_ASSIGN(AtomContentClient); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index c897d5d19af9..69ae0d3830cd 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -16,13 +16,16 @@ #include "base/command_line.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/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/common/web_preferences.h" +#include "ppapi/host/ppapi_host.h" #include "ui/base/l10n/l10n_util.h" namespace atom { @@ -197,6 +200,13 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( dying_render_process_ = nullptr; } +void AtomBrowserClient::DidCreatePpapiPlugin( + content::BrowserPpapiHost* browser_host) { + browser_host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr( + new chrome::ChromeBrowserPepperHostFactory(browser_host))); +} + brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( const content::MainFunctionParams&) { v8::V8::Initialize(); // Init V8 before creating main parts. diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 629ac9640ca2..cda0bd8e5cfb 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -35,6 +35,7 @@ class AtomBrowserClient : public brightray::BrowserClient { content::SiteInstance** new_instance); void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; + void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; private: brightray::BrowserMainParts* OverrideCreateBrowserMainParts( diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index c479b5004d07..37daa894c6d8 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -63,6 +63,9 @@ const char kDirectWrite[] = "direct-write"; // Enable plugins. const char kEnablePlugins[] = "enable-plugins"; +// Ppapi Flash path. +const char kPpapiFlashPath[] = "ppapi-flash-path"; + // Instancd ID of guest WebContents. const char kGuestInstanceID[] = "guest-instance-id"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 546c6a04eb4d..d6f8c072886c 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -37,6 +37,7 @@ extern const char kEnableLargerThanScreen[]; extern const char kDarkTheme[]; extern const char kDirectWrite[]; extern const char kEnablePlugins[]; +extern const char kPpapiFlashPath[]; extern const char kGuestInstanceID[]; extern const char kPreloadScript[]; extern const char kTransparent[]; diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index cc48bc0481d1..d90a90b9415f 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -11,6 +11,7 @@ #include "atom/common/options_switches.h" #include "atom/renderer/atom_render_view_observer.h" #include "atom/renderer/guest_view_container.h" +#include "chrome/renderer/pepper/pepper_helper.h" #include "chrome/renderer/printing/print_web_view_helper.h" #include "chrome/renderer/tts_dispatcher.h" #include "content/public/common/content_constants.h" @@ -79,6 +80,11 @@ void AtomRendererClient::RenderThreadStarted() { content::RenderThread::Get()->AddObserver(this); } +void AtomRendererClient::RenderFrameCreated( + content::RenderFrame* render_frame) { + new PepperHelper(render_frame); +} + void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { new printing::PrintWebViewHelper(render_view); new AtomRenderViewObserver(render_view, this); diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index 4aba42c5ad48..a7096125580c 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -34,6 +34,7 @@ class AtomRendererClient : public content::ContentRendererClient, // content::ContentRendererClient: void RenderThreadStarted() override; + void RenderFrameCreated(content::RenderFrame*) override; void RenderViewCreated(content::RenderView*) override; blink::WebSpeechSynthesizer* OverrideSpeechSynthesizer( blink::WebSpeechSynthesizerClient* client) override; diff --git a/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc new file mode 100644 index 000000000000..03d706fee045 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc @@ -0,0 +1,94 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" + +#include "build/build_config.h" +#include "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h" +#include "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h" +#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h" +#include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "ppapi/host/message_filter_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + +using ppapi::host::MessageFilterHost; +using ppapi::host::ResourceHost; +using ppapi::host::ResourceMessageFilter; + +namespace chrome { + +ChromeBrowserPepperHostFactory::ChromeBrowserPepperHostFactory( + content::BrowserPpapiHost* host) + : host_(host) {} + +ChromeBrowserPepperHostFactory::~ChromeBrowserPepperHostFactory() {} + +scoped_ptr ChromeBrowserPepperHostFactory::CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) { + DCHECK(host == host_->GetPpapiHost()); + + // Make sure the plugin is giving us a valid instance for this resource. + if (!host_->IsValidInstance(instance)) + return scoped_ptr(); + + // Private interfaces. + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_PRIVATE)) { + switch (message.type()) { + case PpapiHostMsg_Broker_Create::ID: { + scoped_refptr broker_filter( + new PepperBrokerMessageFilter(instance, host_)); + return scoped_ptr(new MessageFilterHost( + host_->GetPpapiHost(), instance, resource, broker_filter)); + } + } + } + + // Flash interfaces. + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_FLASH)) { + switch (message.type()) { + case PpapiHostMsg_Flash_Create::ID: + return scoped_ptr( + new PepperFlashBrowserHost(host_, instance, resource)); + case PpapiHostMsg_FlashClipboard_Create::ID: { + scoped_refptr clipboard_filter( + new PepperFlashClipboardMessageFilter); + return scoped_ptr(new MessageFilterHost( + host_->GetPpapiHost(), instance, resource, clipboard_filter)); + } +#if 0 + case PpapiHostMsg_FlashDRM_Create::ID: + return scoped_ptr( + new PepperFlashDRMHost(host_, instance, resource)); +#endif + } + } + + // Permissions for the following interfaces will be checked at the + // time of the corresponding instance's methods calls (because + // permission check can be performed only on the UI + // thread). Currently these interfaces are available only for + // whitelisted apps which may not have access to the other private + // interfaces. + if (message.type() == PpapiHostMsg_IsolatedFileSystem_Create::ID) { + PepperIsolatedFileSystemMessageFilter* isolated_fs_filter = + PepperIsolatedFileSystemMessageFilter::Create(instance, host_); + if (!isolated_fs_filter) + return scoped_ptr(); + return scoped_ptr( + new MessageFilterHost(host, instance, resource, isolated_fs_filter)); + } + + return scoped_ptr(); +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h new file mode 100644 index 000000000000..b817953b54dc --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_ + +#include "base/compiler_specific.h" +#include "ppapi/host/host_factory.h" + +namespace content { +class BrowserPpapiHost; +} // namespace content + +namespace chrome { + +class ChromeBrowserPepperHostFactory : public ppapi::host::HostFactory { + public: + // Non-owning pointer to the filter must outlive this class. + explicit ChromeBrowserPepperHostFactory(content::BrowserPpapiHost* host); + ~ChromeBrowserPepperHostFactory() override; + + scoped_ptr CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) override; + + private: + // Non-owning pointer. + content::BrowserPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(ChromeBrowserPepperHostFactory); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_ diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc new file mode 100644 index 000000000000..224b55d4cac5 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h" + +#include + +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "url/gurl.h" + +using content::BrowserPpapiHost; +using content::BrowserThread; +using content::RenderProcessHost; + +namespace chrome { + +PepperBrokerMessageFilter::PepperBrokerMessageFilter(PP_Instance instance, + BrowserPpapiHost* host) + : document_url_(host->GetDocumentURLForInstance(instance)) { + int unused; + host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); +} + +PepperBrokerMessageFilter::~PepperBrokerMessageFilter() {} + +scoped_refptr +PepperBrokerMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& message) { + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); +} + +int32_t PepperBrokerMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperBrokerMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Broker_IsAllowed, + OnIsAllowed) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperBrokerMessageFilter::OnIsAllowed( + ppapi::host::HostMessageContext* context) { + return PP_OK; +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h new file mode 100644 index 000000000000..44627c6a3556 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h @@ -0,0 +1,51 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_ + +#include "base/compiler_specific.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/host/resource_message_filter.h" +#include "url/gurl.h" + +namespace content { +class BrowserPpapiHost; +} + +namespace ppapi { +namespace host { +struct HostMessageContext; +} +} + +namespace chrome { + +// This filter handles messages for the PepperBrokerHost on the UI thread. +class PepperBrokerMessageFilter : public ppapi::host::ResourceMessageFilter { + public: + PepperBrokerMessageFilter(PP_Instance instance, + content::BrowserPpapiHost* host); + + private: + ~PepperBrokerMessageFilter() override; + + // ppapi::host::ResourceMessageFilter overrides. + scoped_refptr OverrideTaskRunnerForMessage( + const IPC::Message& message) override; + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + int32_t OnIsAllowed(ppapi::host::HostMessageContext* context); + + int render_process_id_; + GURL document_url_; + + DISALLOW_COPY_AND_ASSIGN(PepperBrokerMessageFilter); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_ diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc new file mode 100644 index 000000000000..43179c68d485 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc @@ -0,0 +1,114 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h" + +#include "base/time/time.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/shared_impl/time_conversion.h" +#include "url/gurl.h" + +#if defined(OS_WIN) +#include +#elif defined(OS_MACOSX) +#include +#endif + +using content::BrowserPpapiHost; +using content::BrowserThread; +using content::RenderProcessHost; + +namespace chrome { + +PepperFlashBrowserHost::PepperFlashBrowserHost(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host), + weak_factory_(this) { + int unused; + host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); +} + +PepperFlashBrowserHost::~PepperFlashBrowserHost() {} + +int32_t PepperFlashBrowserHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity, + OnUpdateActivity) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset, + OnGetLocalTimeZoneOffset) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( + PpapiHostMsg_Flash_GetLocalDataRestrictions, OnGetLocalDataRestrictions) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashBrowserHost::OnUpdateActivity( + ppapi::host::HostMessageContext* host_context) { +#if defined(OS_WIN) + // Reading then writing back the same value to the screensaver timeout system + // setting resets the countdown which prevents the screensaver from turning + // on "for a while". As long as the plugin pings us with this message faster + // than the screensaver timeout, it won't go on. + int value = 0; + if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0)) + SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0); +#elif defined(OS_MACOSX) +// UpdateSystemActivity(OverallAct); +#else +// TODO(brettw) implement this for other platforms. +#endif + return PP_OK; +} + +int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset( + ppapi::host::HostMessageContext* host_context, + const base::Time& t) { + // The reason for this processing being in the browser process is that on + // Linux, the localtime calls require filesystem access prohibited by the + // sandbox. + host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply( + ppapi::PPGetLocalTimeZoneOffset(t)); + return PP_OK; +} + +int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions( + ppapi::host::HostMessageContext* context) { + // Getting the Flash LSO settings requires using the CookieSettings which + // belong to the profile which lives on the UI thread. We lazily initialize + // |cookie_settings_| by grabbing the reference from the UI thread and then + // call |GetLocalDataRestrictions| with it. + GURL document_url = host_->GetDocumentURLForInstance(pp_instance()); + GURL plugin_url = host_->GetPluginURLForInstance(pp_instance()); + GetLocalDataRestrictions(context->MakeReplyMessageContext(), + document_url, + plugin_url); + return PP_OK_COMPLETIONPENDING; +} + +void PepperFlashBrowserHost::GetLocalDataRestrictions( + ppapi::host::ReplyMessageContext reply_context, + const GURL& document_url, + const GURL& plugin_url) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + PP_FlashLSORestrictions restrictions = PP_FLASHLSORESTRICTIONS_NONE; + SendReply(reply_context, + PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply( + static_cast(restrictions))); +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h new file mode 100644 index 000000000000..6fb4aced1819 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +namespace base { +class Time; +} + +namespace content { +class BrowserPpapiHost; +class ResourceContext; +} + +class GURL; + +namespace chrome { + +class PepperFlashBrowserHost : public ppapi::host::ResourceHost { + public: + PepperFlashBrowserHost(content::BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashBrowserHost() override; + + // ppapi::host::ResourceHost override. + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnUpdateActivity(ppapi::host::HostMessageContext* host_context); + int32_t OnGetLocalTimeZoneOffset( + ppapi::host::HostMessageContext* host_context, + const base::Time& t); + int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context); + + void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context, + const GURL& document_url, + const GURL& plugin_url); + + content::BrowserPpapiHost* host_; + int render_process_id_; + // For fetching the Flash LSO settings. + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHost); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc new file mode 100644 index 000000000000..4499b21aefe3 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc @@ -0,0 +1,376 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h" + +#include "base/pickle.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_thread.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash_clipboard.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ui/base/clipboard/scoped_clipboard_writer.h" + +using content::BrowserThread; + +namespace chrome { + +namespace { + +const size_t kMaxClipboardWriteSize = 1000000; + +ui::ClipboardType ConvertClipboardType(uint32_t type) { + switch (type) { + case PP_FLASH_CLIPBOARD_TYPE_STANDARD: + return ui::CLIPBOARD_TYPE_COPY_PASTE; + case PP_FLASH_CLIPBOARD_TYPE_SELECTION: + return ui::CLIPBOARD_TYPE_SELECTION; + } + NOTREACHED(); + return ui::CLIPBOARD_TYPE_COPY_PASTE; +} + +// Functions to pack/unpack custom data from a pickle. See the header file for +// more detail on custom formats in Pepper. +// TODO(raymes): Currently pepper custom formats are stored in their own +// native format type. However we should be able to store them in the same way +// as "Web Custom" formats are. This would allow clipboard data to be shared +// between pepper applications and web applications. However currently web apps +// assume all data that is placed on the clipboard is UTF16 and pepper allows +// arbitrary data so this change would require some reworking of the chrome +// clipboard interface for custom data. +bool JumpToFormatInPickle(const base::string16& format, PickleIterator* iter) { + size_t size = 0; + if (!iter->ReadSizeT(&size)) + return false; + for (size_t i = 0; i < size; ++i) { + base::string16 stored_format; + if (!iter->ReadString16(&stored_format)) + return false; + if (stored_format == format) + return true; + int skip_length; + if (!iter->ReadLength(&skip_length)) + return false; + if (!iter->SkipBytes(skip_length)) + return false; + } + return false; +} + +bool IsFormatAvailableInPickle(const base::string16& format, + const Pickle& pickle) { + PickleIterator iter(pickle); + return JumpToFormatInPickle(format, &iter); +} + +std::string ReadDataFromPickle(const base::string16& format, + const Pickle& pickle) { + std::string result; + PickleIterator iter(pickle); + if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result)) + return std::string(); + return result; +} + +bool WriteDataToPickle(const std::map& data, + Pickle* pickle) { + pickle->WriteSizeT(data.size()); + for (std::map::const_iterator it = data.begin(); + it != data.end(); + ++it) { + if (!pickle->WriteString16(it->first)) + return false; + if (!pickle->WriteString(it->second)) + return false; + } + return true; +} + +} // namespace + +PepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {} + +PepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {} + +scoped_refptr +PepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& msg) { + // Clipboard writes should always occur on the UI thread due to the + // restrictions of various platform APIs. In general, the clipboard is not + // thread-safe, so all clipboard calls should be serviced from the UI thread. + if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID) + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); + +// Windows needs clipboard reads to be serviced from the IO thread because +// these are sync IPCs which can result in deadlocks with plugins if serviced +// from the UI thread. Note that Windows clipboard calls ARE thread-safe so it +// is ok for reads and writes to be serviced from different threads. +#if !defined(OS_WIN) + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); +#else + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); +#endif +} + +int32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_FlashClipboard_RegisterCustomFormat, + OnMsgRegisterCustomFormat) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_FlashClipboard_IsFormatAvailable, OnMsgIsFormatAvailable) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_ReadData, + OnMsgReadData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_WriteData, + OnMsgWriteData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_FlashClipboard_GetSequenceNumber, OnMsgGetSequenceNumber) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat( + ppapi::host::HostMessageContext* host_context, + const std::string& format_name) { + uint32_t format = custom_formats_.RegisterFormat(format_name); + if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID) + return PP_ERROR_FAILED; + host_context->reply_msg = + PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format); + return PP_OK; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format) { + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + bool available = false; + switch (format) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { + bool plain = clipboard->IsFormatAvailable( + ui::Clipboard::GetPlainTextFormatType(), type); + bool plainw = clipboard->IsFormatAvailable( + ui::Clipboard::GetPlainTextWFormatType(), type); + available = plain || plainw; + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_HTML: + available = clipboard->IsFormatAvailable( + ui::Clipboard::GetHtmlFormatType(), type); + break; + case PP_FLASH_CLIPBOARD_FORMAT_RTF: + available = + clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type); + break; + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + break; + default: + if (custom_formats_.IsFormatRegistered(format)) { + std::string format_name = custom_formats_.GetFormatName(format); + std::string clipboard_data; + clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), + &clipboard_data); + Pickle pickle(clipboard_data.data(), clipboard_data.size()); + available = + IsFormatAvailableInPickle(base::UTF8ToUTF16(format_name), pickle); + } + break; + } + + return available ? PP_OK : PP_ERROR_FAILED; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgReadData( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format) { + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + std::string clipboard_string; + int32_t result = PP_ERROR_FAILED; + switch (format) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { + if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), + type)) { + base::string16 text; + clipboard->ReadText(type, &text); + if (!text.empty()) { + result = PP_OK; + clipboard_string = base::UTF16ToUTF8(text); + break; + } + } + // If the PlainTextW format isn't available or is empty, take the + // ASCII text format. + if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), + type)) { + result = PP_OK; + clipboard->ReadAsciiText(type, &clipboard_string); + } + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_HTML: { + if (!clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), + type)) { + break; + } + + base::string16 html; + std::string url; + uint32 fragment_start; + uint32 fragment_end; + clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end); + result = PP_OK; + clipboard_string = base::UTF16ToUTF8( + html.substr(fragment_start, fragment_end - fragment_start)); + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_RTF: { + if (!clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), + type)) { + break; + } + result = PP_OK; + clipboard->ReadRTF(type, &clipboard_string); + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + break; + default: { + if (custom_formats_.IsFormatRegistered(format)) { + base::string16 format_name = + base::UTF8ToUTF16(custom_formats_.GetFormatName(format)); + std::string clipboard_data; + clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), + &clipboard_data); + Pickle pickle(clipboard_data.data(), clipboard_data.size()); + if (IsFormatAvailableInPickle(format_name, pickle)) { + result = PP_OK; + clipboard_string = ReadDataFromPickle(format_name, pickle); + } + } + break; + } + } + + if (result == PP_OK) { + host_context->reply_msg = + PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string); + } + return result; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgWriteData( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + const std::vector& formats, + const std::vector& data) { + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + if (formats.size() != data.size()) + return PP_ERROR_FAILED; + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + // If no formats are passed in clear the clipboard. + if (formats.size() == 0) { + clipboard->Clear(type); + return PP_OK; + } + + ui::ScopedClipboardWriter scw(type); + std::map custom_data_map; + int32_t res = PP_OK; + for (uint32_t i = 0; i < formats.size(); ++i) { + if (data[i].length() > kMaxClipboardWriteSize) { + res = PP_ERROR_NOSPACE; + break; + } + + switch (formats[i]) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: + scw.WriteText(base::UTF8ToUTF16(data[i])); + break; + case PP_FLASH_CLIPBOARD_FORMAT_HTML: + scw.WriteHTML(base::UTF8ToUTF16(data[i]), std::string()); + break; + case PP_FLASH_CLIPBOARD_FORMAT_RTF: + scw.WriteRTF(data[i]); + break; + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + res = PP_ERROR_BADARGUMENT; + break; + default: + if (custom_formats_.IsFormatRegistered(formats[i])) { + std::string format_name = custom_formats_.GetFormatName(formats[i]); + custom_data_map[base::UTF8ToUTF16(format_name)] = data[i]; + } else { + // Invalid format. + res = PP_ERROR_BADARGUMENT; + break; + } + } + + if (res != PP_OK) + break; + } + + if (custom_data_map.size() > 0) { + Pickle pickle; + if (WriteDataToPickle(custom_data_map, &pickle)) { + scw.WritePickledData(pickle, + ui::Clipboard::GetPepperCustomDataFormatType()); + } else { + res = PP_ERROR_BADARGUMENT; + } + } + + if (res != PP_OK) { + // Need to clear the objects so nothing is written. + scw.Reset(); + } + + return res; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgGetSequenceNumber( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type) { + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + int64_t sequence_number = clipboard->GetSequenceNumber(type); + host_context->reply_msg = + PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply(sequence_number); + return PP_OK; +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h new file mode 100644 index 000000000000..ff07eb73750c --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h @@ -0,0 +1,78 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_ + +#include +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/host/resource_message_filter.h" +#include "ppapi/shared_impl/flash_clipboard_format_registry.h" + +namespace ppapi { +namespace host { +struct HostMessageContext; +} +} + +namespace ui { +class ScopedClipboardWriter; +} + +namespace chrome { + +// Resource message filter for accessing the clipboard in Pepper. Pepper +// supports reading/writing custom formats from the clipboard. Currently, all +// custom formats that are read/written from the clipboard through pepper are +// stored in a single real clipboard format (in the same way the "web custom" +// clipboard formats are). This is done so that we don't have to have use real +// clipboard types for each custom clipboard format which may be a limited +// resource on a particular platform. +class PepperFlashClipboardMessageFilter + : public ppapi::host::ResourceMessageFilter { + public: + PepperFlashClipboardMessageFilter(); + + protected: + // ppapi::host::ResourceMessageFilter overrides. + scoped_refptr OverrideTaskRunnerForMessage( + const IPC::Message& msg) override; + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + ~PepperFlashClipboardMessageFilter() override; + + int32_t OnMsgRegisterCustomFormat( + ppapi::host::HostMessageContext* host_context, + const std::string& format_name); + int32_t OnMsgIsFormatAvailable(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format); + int32_t OnMsgReadData(ppapi::host::HostMessageContext* host_context, + uint32_t clipoard_type, + uint32_t format); + int32_t OnMsgWriteData(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + const std::vector& formats, + const std::vector& data); + int32_t OnMsgGetSequenceNumber(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type); + + int32_t WriteClipboardDataItem(uint32_t format, + const std::string& data, + ui::ScopedClipboardWriter* scw); + + ppapi::FlashClipboardFormatRegistry custom_formats_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashClipboardMessageFilter); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_ diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc new file mode 100644 index 000000000000..10c07906af9b --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc @@ -0,0 +1,110 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h" + +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/render_view_host.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/file_system_util.h" +#include "storage/browser/fileapi/isolated_context.h" + +namespace chrome { + +// static +PepperIsolatedFileSystemMessageFilter* +PepperIsolatedFileSystemMessageFilter::Create(PP_Instance instance, + content::BrowserPpapiHost* host) { + int render_process_id; + int unused_render_frame_id; + if (!host->GetRenderFrameIDsForInstance( + instance, &render_process_id, &unused_render_frame_id)) { + return NULL; + } + return new PepperIsolatedFileSystemMessageFilter( + render_process_id, + host->GetProfileDataDirectory(), + host->GetDocumentURLForInstance(instance), + host->GetPpapiHost()); +} + +PepperIsolatedFileSystemMessageFilter::PepperIsolatedFileSystemMessageFilter( + int render_process_id, + const base::FilePath& profile_directory, + const GURL& document_url, + ppapi::host::PpapiHost* ppapi_host) + : render_process_id_(render_process_id), + profile_directory_(profile_directory), + document_url_(document_url), + ppapi_host_(ppapi_host) { +} + +PepperIsolatedFileSystemMessageFilter:: + ~PepperIsolatedFileSystemMessageFilter() {} + +scoped_refptr +PepperIsolatedFileSystemMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& msg) { + // In order to reach ExtensionSystem, we need to get ProfileManager first. + // ProfileManager lives in UI thread, so we need to do this in UI thread. + return content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::UI); +} + +int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperIsolatedFileSystemMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_IsolatedFileSystem_BrowserOpen, + OnOpenFileSystem) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem( + ppapi::host::HostMessageContext* context, + PP_IsolatedFileSystemType_Private type) { + switch (type) { + case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID: + case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: + break; + case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE: + return OpenPluginPrivateFileSystem(context); + } + NOTREACHED(); + context->reply_msg = + PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(std::string()); + return PP_ERROR_FAILED; +} + +int32_t PepperIsolatedFileSystemMessageFilter::OpenPluginPrivateFileSystem( + ppapi::host::HostMessageContext* context) { + DCHECK(ppapi_host_); + // Only plugins with private permission can open the filesystem. + if (!ppapi_host_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) + return PP_ERROR_NOACCESS; + + const std::string& root_name = ppapi::IsolatedFileSystemTypeToRootName( + PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE); + const std::string& fsid = + storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath( + storage::kFileSystemTypePluginPrivate, root_name, base::FilePath()); + + // Grant full access of isolated filesystem to renderer process. + content::ChildProcessSecurityPolicy* policy = + content::ChildProcessSecurityPolicy::GetInstance(); + policy->GrantCreateReadWriteFileSystem(render_process_id_, fsid); + + context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(fsid); + return PP_OK; +} + +} // namespace chrome diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h new file mode 100644 index 000000000000..6a24feadd150 --- /dev/null +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h @@ -0,0 +1,76 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_ +#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_ + +#include +#include + +#include "base/files/file_path.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/private/ppb_isolated_file_system_private.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/host/resource_message_filter.h" +#include "url/gurl.h" + +class Profile; + +namespace content { +class BrowserPpapiHost; +} + +namespace ppapi { +namespace host { +struct HostMessageContext; +} // namespace host +} // namespace ppapi + +namespace chrome { + +class PepperIsolatedFileSystemMessageFilter + : public ppapi::host::ResourceMessageFilter { + public: + static PepperIsolatedFileSystemMessageFilter* Create( + PP_Instance instance, + content::BrowserPpapiHost* host); + + // ppapi::host::ResourceMessageFilter implementation. + scoped_refptr OverrideTaskRunnerForMessage( + const IPC::Message& msg) override; + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + PepperIsolatedFileSystemMessageFilter(int render_process_id, + const base::FilePath& profile_directory, + const GURL& document_url, + ppapi::host::PpapiHost* ppapi_host_); + + ~PepperIsolatedFileSystemMessageFilter() override; + + // Returns filesystem id of isolated filesystem if valid, or empty string + // otherwise. This must run on the UI thread because ProfileManager only + // allows access on that thread. + + int32_t OnOpenFileSystem(ppapi::host::HostMessageContext* context, + PP_IsolatedFileSystemType_Private type); + int32_t OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext* context); + + const int render_process_id_; + // Keep a copy from original thread. + const base::FilePath profile_directory_; + const GURL document_url_; + + // Not owned by this object. + ppapi::host::PpapiHost* ppapi_host_; + + DISALLOW_COPY_AND_ASSIGN(PepperIsolatedFileSystemMessageFilter); +}; + +} // namespace chrome + +#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_ diff --git a/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc new file mode 100644 index 000000000000..db92669df19a --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc @@ -0,0 +1,87 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h" + +#include "base/logging.h" +#include "chrome/renderer/pepper/pepper_flash_drm_renderer_host.h" +#include "chrome/renderer/pepper/pepper_flash_font_file_host.h" +#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h" +#include "chrome/renderer/pepper/pepper_flash_menu_host.h" +#include "chrome/renderer/pepper/pepper_flash_renderer_host.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_message_utils.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + +using ppapi::host::ResourceHost; + +ChromeRendererPepperHostFactory::ChromeRendererPepperHostFactory( + content::RendererPpapiHost* host) + : host_(host) {} + +ChromeRendererPepperHostFactory::~ChromeRendererPepperHostFactory() {} + +scoped_ptr ChromeRendererPepperHostFactory::CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) { + DCHECK_EQ(host_->GetPpapiHost(), host); + + // Make sure the plugin is giving us a valid instance for this resource. + if (!host_->IsValidInstance(instance)) + return scoped_ptr(); + + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_FLASH)) { + switch (message.type()) { + case PpapiHostMsg_Flash_Create::ID: { + return scoped_ptr( + new PepperFlashRendererHost(host_, instance, resource)); + } + case PpapiHostMsg_FlashFullscreen_Create::ID: { + return scoped_ptr( + new PepperFlashFullscreenHost(host_, instance, resource)); + } + case PpapiHostMsg_FlashMenu_Create::ID: { + ppapi::proxy::SerializedFlashMenu serialized_menu; + if (ppapi::UnpackMessage( + message, &serialized_menu)) { + return scoped_ptr(new PepperFlashMenuHost( + host_, instance, resource, serialized_menu)); + } + break; + } + } + } + + // TODO(raymes): PDF also needs access to the FlashFontFileHost currently. + // We should either rename PPB_FlashFont_File to PPB_FontFile_Private or get + // rid of its use in PDF if possible. + if (host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_FLASH) || + host_->GetPpapiHost()->permissions().HasPermission( + ppapi::PERMISSION_PRIVATE)) { + switch (message.type()) { + case PpapiHostMsg_FlashFontFile_Create::ID: { + ppapi::proxy::SerializedFontDescription description; + PP_PrivateFontCharset charset; + if (ppapi::UnpackMessage( + message, &description, &charset)) { + return scoped_ptr(new PepperFlashFontFileHost( + host_, instance, resource, description, charset)); + } + break; + } + case PpapiHostMsg_FlashDRM_Create::ID: + return scoped_ptr( + new PepperFlashDRMRendererHost(host_, instance, resource)); + } + } + + return scoped_ptr(); +} diff --git a/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h new file mode 100644 index 000000000000..13ab2853a356 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h @@ -0,0 +1,35 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ +#define CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/host/host_factory.h" + +namespace content { +class RendererPpapiHost; +} + +class ChromeRendererPepperHostFactory : public ppapi::host::HostFactory { + public: + explicit ChromeRendererPepperHostFactory(content::RendererPpapiHost* host); + ~ChromeRendererPepperHostFactory() override; + + // HostFactory. + scoped_ptr CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) override; + + private: + // Not owned by this object. + content::RendererPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(ChromeRendererPepperHostFactory); +}; + +#endif // CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc new file mode 100644 index 000000000000..2e95d23dd41d --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc @@ -0,0 +1,87 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_flash_drm_renderer_host.h" + +#include "base/files/file_path.h" +#include "content/public/renderer/pepper_plugin_instance.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" + +// TODO(raymes): This is duplicated from pepper_flash_drm_host.cc but once +// FileRef is refactored to the browser, it won't need to be. +namespace { +const char kVoucherFilename[] = "plugin.vch"; +} // namespace + +PepperFlashDRMRendererHost::PepperFlashDRMRendererHost( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + renderer_ppapi_host_(host), + weak_factory_(this) {} + +PepperFlashDRMRendererHost::~PepperFlashDRMRendererHost() {} + +int32_t PepperFlashDRMRendererHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashDRMRendererHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetVoucherFile, + OnGetVoucherFile) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashDRMRendererHost::OnGetVoucherFile( + ppapi::host::HostMessageContext* context) { + content::PepperPluginInstance* plugin_instance = + renderer_ppapi_host_->GetPluginInstance(pp_instance()); + if (!plugin_instance) + return PP_ERROR_FAILED; + + base::FilePath plugin_dir = plugin_instance->GetModulePath().DirName(); + DCHECK(!plugin_dir.empty()); + base::FilePath voucher_file = plugin_dir.AppendASCII(kVoucherFilename); + + int renderer_pending_host_id = + plugin_instance->MakePendingFileRefRendererHost(voucher_file); + if (renderer_pending_host_id == 0) + return PP_ERROR_FAILED; + + std::vector create_msgs; + create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(voucher_file)); + + renderer_ppapi_host_->CreateBrowserResourceHosts( + pp_instance(), + create_msgs, + base::Bind(&PepperFlashDRMRendererHost::DidCreateFileRefHosts, + weak_factory_.GetWeakPtr(), + context->MakeReplyMessageContext(), + voucher_file, + renderer_pending_host_id)); + return PP_OK_COMPLETIONPENDING; +} + +void PepperFlashDRMRendererHost::DidCreateFileRefHosts( + const ppapi::host::ReplyMessageContext& reply_context, + const base::FilePath& external_path, + int renderer_pending_host_id, + const std::vector& browser_pending_host_ids) { + DCHECK_EQ(1U, browser_pending_host_ids.size()); + int browser_pending_host_id = browser_pending_host_ids[0]; + + ppapi::FileRefCreateInfo create_info = + ppapi::MakeExternalFileRefCreateInfo(external_path, + std::string(), + browser_pending_host_id, + renderer_pending_host_id); + host()->SendReply(reply_context, + PpapiPluginMsg_FlashDRM_GetVoucherFileReply(create_info)); +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h new file mode 100644 index 000000000000..cc06d382721f --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h @@ -0,0 +1,51 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_DRM_RENDERER_HOST_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_DRM_RENDERER_HOST_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/resource_host.h" + +namespace base { +class FilePath; +} + +namespace content { +class RendererPpapiHost; +} + +// TODO(raymes): This is only needed until we move FileRef resources to the +// browser. After that, get rid of this class altogether. +class PepperFlashDRMRendererHost : public ppapi::host::ResourceHost { + public: + PepperFlashDRMRendererHost(content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashDRMRendererHost() override; + + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnGetVoucherFile(ppapi::host::HostMessageContext* context); + + void DidCreateFileRefHosts( + const ppapi::host::ReplyMessageContext& reply_context, + const base::FilePath& external_path, + int renderer_pending_host_id, + const std::vector& browser_pending_host_ids); + + // Non-owning pointer. + content::RendererPpapiHost* renderer_ppapi_host_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashDRMRendererHost); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_DRM_RENDERER_HOST_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc new file mode 100644 index 000000000000..305b6ec56c07 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_flash_font_file_host.h" + +#include "build/build_config.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/serialized_structs.h" + +#if defined(OS_LINUX) || defined(OS_OPENBSD) +#include "content/public/common/child_process_sandbox_support_linux.h" +#endif + +PepperFlashFontFileHost::PepperFlashFontFileHost( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const ppapi::proxy::SerializedFontDescription& description, + PP_PrivateFontCharset charset) + : ResourceHost(host->GetPpapiHost(), instance, resource) { +#if defined(OS_LINUX) || defined(OS_OPENBSD) + fd_.reset(content::MatchFontWithFallback( + description.face.c_str(), + description.weight >= PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD, + description.italic, + charset, + PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT)); +#endif // defined(OS_LINUX) || defined(OS_OPENBSD) +} + +PepperFlashFontFileHost::~PepperFlashFontFileHost() {} + +int32_t PepperFlashFontFileHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFontFileHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFontFile_GetFontTable, + OnGetFontTable) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashFontFileHost::OnGetFontTable( + ppapi::host::HostMessageContext* context, + uint32_t table) { + std::string contents; + int32_t result = PP_ERROR_FAILED; +#if defined(OS_LINUX) || defined(OS_OPENBSD) + int fd = fd_.get(); + if (fd != -1) { + size_t length = 0; + if (content::GetFontTable(fd, table, 0 /* offset */, NULL, &length)) { + contents.resize(length); + uint8_t* contents_ptr = + reinterpret_cast(const_cast(contents.c_str())); + if (content::GetFontTable( + fd, table, 0 /* offset */, contents_ptr, &length)) { + result = PP_OK; + } else { + contents.clear(); + } + } + } +#endif // defined(OS_LINUX) || defined(OS_OPENBSD) + + context->reply_msg = PpapiPluginMsg_FlashFontFile_GetFontTableReply(contents); + return result; +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h new file mode 100644 index 000000000000..02bb30f315fd --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h @@ -0,0 +1,52 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/c/private/pp_private_font_charset.h" +#include "ppapi/host/resource_host.h" + +#if defined(OS_LINUX) || defined(OS_OPENBSD) +#include "base/files/scoped_file.h" +#endif + +namespace content { +class RendererPpapiHost; +} + +namespace ppapi { +namespace proxy { +struct SerializedFontDescription; +} +} + +class PepperFlashFontFileHost : public ppapi::host::ResourceHost { + public: + PepperFlashFontFileHost( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const ppapi::proxy::SerializedFontDescription& description, + PP_PrivateFontCharset charset); + ~PepperFlashFontFileHost() override; + + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnGetFontTable(ppapi::host::HostMessageContext* context, + uint32_t table); + +#if defined(OS_LINUX) || defined(OS_OPENBSD) + base::ScopedFD fd_; +#endif + + DISALLOW_COPY_AND_ASSIGN(PepperFlashFontFileHost); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc new file mode 100644 index 000000000000..d590cde3a4a5 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h" + +#include "content/public/renderer/pepper_plugin_instance.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" + +PepperFlashFullscreenHost::PepperFlashFullscreenHost( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + renderer_ppapi_host_(host) {} + +PepperFlashFullscreenHost::~PepperFlashFullscreenHost() {} + +int32_t PepperFlashFullscreenHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFullscreenHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_FlashFullscreen_SetFullscreen, + OnSetFullscreen) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashFullscreenHost::OnSetFullscreen( + ppapi::host::HostMessageContext* context, + bool fullscreen) { + content::PepperPluginInstance* plugin_instance = + renderer_ppapi_host_->GetPluginInstance(pp_instance()); + if (plugin_instance && plugin_instance->FlashSetFullscreen(fullscreen, true)) + return PP_OK; + return PP_ERROR_FAILED; +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h new file mode 100644 index 000000000000..3550ea136631 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/host/resource_host.h" + +namespace content { +class RendererPpapiHost; +} + +class PepperFlashFullscreenHost : public ppapi::host::ResourceHost { + public: + PepperFlashFullscreenHost(content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashFullscreenHost() override; + + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnSetFullscreen(ppapi::host::HostMessageContext* context, + bool fullscreen); + + // Non-owning pointer. + content::RendererPpapiHost* renderer_ppapi_host_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashFullscreenHost); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc new file mode 100644 index 000000000000..3b7a438f7220 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc @@ -0,0 +1,202 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_flash_menu_host.h" + +#include "base/strings/utf_string_conversions.h" +#include "content/public/common/context_menu_params.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ipc/ipc_message.h" +#include "ppapi/c/private/ppb_flash_menu.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/serialized_flash_menu.h" +#include "ui/gfx/geometry/point.h" + +namespace { + +// Maximum depth of submenus allowed (e.g., 1 indicates that submenus are +// allowed, but not sub-submenus). +const size_t kMaxMenuDepth = 2; + +// Maximum number of entries in any single menu (including separators). +const size_t kMaxMenuEntries = 50; + +// Maximum total number of entries in the |menu_id_map| (see below). +// (Limit to 500 real entries; reserve the 0 action as an invalid entry.) +const size_t kMaxMenuIdMapEntries = 501; + +// Converts menu data from one form to another. +// - |depth| is the current nested depth (call it starting with 0). +// - |menu_id_map| is such that |menu_id_map[output_item.action] == +// input_item.id| (where |action| is what a |MenuItem| has, |id| is what a +// |PP_Flash_MenuItem| has). +bool ConvertMenuData(const PP_Flash_Menu* in_menu, + size_t depth, + std::vector* out_menu, + std::vector* menu_id_map) { + if (depth > kMaxMenuDepth || !in_menu) + return false; + + // Clear the output, just in case. + out_menu->clear(); + + if (!in_menu->count) + return true; // Nothing else to do. + + if (!in_menu->items || in_menu->count > kMaxMenuEntries) + return false; + for (uint32_t i = 0; i < in_menu->count; i++) { + content::MenuItem item; + + PP_Flash_MenuItem_Type type = in_menu->items[i].type; + switch (type) { + case PP_FLASH_MENUITEM_TYPE_NORMAL: + item.type = content::MenuItem::OPTION; + break; + case PP_FLASH_MENUITEM_TYPE_CHECKBOX: + item.type = content::MenuItem::CHECKABLE_OPTION; + break; + case PP_FLASH_MENUITEM_TYPE_SEPARATOR: + item.type = content::MenuItem::SEPARATOR; + break; + case PP_FLASH_MENUITEM_TYPE_SUBMENU: + item.type = content::MenuItem::SUBMENU; + break; + default: + return false; + } + if (in_menu->items[i].name) + item.label = base::UTF8ToUTF16(in_menu->items[i].name); + if (menu_id_map->size() >= kMaxMenuIdMapEntries) + return false; + item.action = static_cast(menu_id_map->size()); + // This sets |(*menu_id_map)[item.action] = in_menu->items[i].id|. + menu_id_map->push_back(in_menu->items[i].id); + item.enabled = PP_ToBool(in_menu->items[i].enabled); + item.checked = PP_ToBool(in_menu->items[i].checked); + if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) { + if (!ConvertMenuData( + in_menu->items[i].submenu, depth + 1, &item.submenu, menu_id_map)) + return false; + } + + out_menu->push_back(item); + } + + return true; +} + +} // namespace + +PepperFlashMenuHost::PepperFlashMenuHost( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const ppapi::proxy::SerializedFlashMenu& serial_menu) + : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), + renderer_ppapi_host_(host), + showing_context_menu_(false), + context_menu_request_id_(0), + has_saved_context_menu_action_(false), + saved_context_menu_action_(0) { + menu_id_map_.push_back(0); // Reserve |menu_id_map_[0]|. + if (!ConvertMenuData(serial_menu.pp_menu(), 0, &menu_data_, &menu_id_map_)) { + menu_data_.clear(); + menu_id_map_.clear(); + } +} + +PepperFlashMenuHost::~PepperFlashMenuHost() { + if (showing_context_menu_) { + content::RenderFrame* render_frame = + renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance()); + if (render_frame) + render_frame->CancelContextMenu(context_menu_request_id_); + } +} + +int32_t PepperFlashMenuHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashMenuHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashMenu_Show, + OnHostMsgShow) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashMenuHost::OnHostMsgShow( + ppapi::host::HostMessageContext* context, + const PP_Point& location) { + // Note that all early returns must do a SendMenuReply. The sync result for + // this message isn't used, so to forward the error to the plugin, we need to + // additionally call SendMenuReply explicitly. + if (menu_data_.empty()) { + SendMenuReply(PP_ERROR_FAILED, -1); + return PP_ERROR_FAILED; + } + if (showing_context_menu_) { + SendMenuReply(PP_ERROR_INPROGRESS, -1); + return PP_ERROR_INPROGRESS; + } + + content::RenderFrame* render_frame = + renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance()); + + content::ContextMenuParams params; + params.x = location.x; + params.y = location.y; + params.custom_context.is_pepper_menu = true; + params.custom_context.render_widget_id = + renderer_ppapi_host_->GetRoutingIDForWidget(pp_instance()); + params.custom_items = menu_data_; + + // Transform the position to be in render frame's coordinates. + gfx::Point render_frame_pt = renderer_ppapi_host_->PluginPointToRenderFrame( + pp_instance(), gfx::Point(location.x, location.y)); + params.x = render_frame_pt.x(); + params.y = render_frame_pt.y(); + + showing_context_menu_ = true; + context_menu_request_id_ = render_frame->ShowContextMenu(this, params); + + // Note: the show message is sync so this OK is for the sync reply which we + // don't actually use (see the comment in the resource file for this). The + // async message containing the context menu action will be sent in the + // future. + return PP_OK; +} + +void PepperFlashMenuHost::OnMenuAction(int request_id, unsigned action) { + // Just save the action. + DCHECK(!has_saved_context_menu_action_); + has_saved_context_menu_action_ = true; + saved_context_menu_action_ = action; +} + +void PepperFlashMenuHost::OnMenuClosed(int request_id) { + if (has_saved_context_menu_action_ && + saved_context_menu_action_ < menu_id_map_.size()) { + SendMenuReply(PP_OK, menu_id_map_[saved_context_menu_action_]); + has_saved_context_menu_action_ = false; + saved_context_menu_action_ = 0; + } else { + SendMenuReply(PP_ERROR_USERCANCEL, -1); + } + + showing_context_menu_ = false; + context_menu_request_id_ = 0; +} + +void PepperFlashMenuHost::SendMenuReply(int32_t result, int action) { + ppapi::host::ReplyMessageContext reply_context( + ppapi::proxy::ResourceMessageReplyParams(pp_resource(), 0), + NULL, + MSG_ROUTING_NONE); + reply_context.params.set_result(result); + host()->SendReply(reply_context, PpapiPluginMsg_FlashMenu_ShowReply(action)); +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h new file mode 100644 index 000000000000..3aa730a6afc3 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h @@ -0,0 +1,69 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_ + +#include + +#include "base/compiler_specific.h" +#include "content/public/renderer/context_menu_client.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +namespace content { +class RendererPpapiHost; +struct MenuItem; +} + +namespace ppapi { +namespace proxy { +class SerializedFlashMenu; +} +} + +class PepperFlashMenuHost : public ppapi::host::ResourceHost, + public content::ContextMenuClient { + public: + PepperFlashMenuHost(content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const ppapi::proxy::SerializedFlashMenu& serial_menu); + ~PepperFlashMenuHost() override; + + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnHostMsgShow(ppapi::host::HostMessageContext* context, + const PP_Point& location); + + // ContextMenuClient implementation. + void OnMenuAction(int request_id, unsigned action) override; + void OnMenuClosed(int request_id) override; + + void SendMenuReply(int32_t result, int action); + + content::RendererPpapiHost* renderer_ppapi_host_; + + bool showing_context_menu_; + int context_menu_request_id_; + + std::vector menu_data_; + + // We send |MenuItem|s, which have an |unsigned| "action" field instead of + // an |int32_t| ID. (CONTENT also limits the range of valid values for + // actions.) This maps actions to IDs. + std::vector menu_id_map_; + + // Used to send a single context menu "completion" upon menu close. + bool has_saved_context_menu_action_; + unsigned saved_context_menu_action_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashMenuHost); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc new file mode 100644 index 000000000000..fe5e28ebbeb8 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc @@ -0,0 +1,373 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_flash_renderer_host.h" + +#include +#include + +#include "base/lazy_instance.h" +#include "base/metrics/histogram.h" +#include "base/strings/string_util.h" +#include "content/public/renderer/pepper_plugin_instance.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ipc/ipc_message_macros.h" +#include "net/http/http_util.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/trusted/ppb_browser_font_trusted.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/proxy/host_dispatcher.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/proxy/serialized_structs.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_image_data_api.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkTemplates.h" +#include "third_party/skia/include/core/SkTypeface.h" +#include "ui/gfx/geometry/rect.h" +#include "url/gurl.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_ImageData_API; + +namespace { + +// Some non-simple HTTP request headers that Flash may set. +// (Please see http://www.w3.org/TR/cors/#simple-header for the definition of +// simple headers.) +// +// The list and the enum defined below are used to collect data about request +// headers used in PPB_Flash.Navigate() calls, in order to understand the impact +// of rejecting PPB_Flash.Navigate() requests with non-simple headers. +// +// TODO(yzshen): We should be able to remove the histogram recording code once +// we get the answer. +const char* const kRejectedHttpRequestHeaders[] = { + "authorization", // + "cache-control", // + "content-encoding", // + "content-md5", // + "content-type", // If the media type is not one of those covered by the + // simple header definition. + "expires", // + "from", // + "if-match", // + "if-none-match", // + "if-range", // + "if-unmodified-since", // + "pragma", // + "referer" // +}; + +// Please note that new entries should be added right above +// FLASH_NAVIGATE_USAGE_ENUM_COUNT, and existing entries shouldn't be re-ordered +// or removed, since this ordering is used in a histogram. +enum FlashNavigateUsage { + // This section must be in the same order as kRejectedHttpRequestHeaders. + REJECT_AUTHORIZATION = 0, + REJECT_CACHE_CONTROL, + REJECT_CONTENT_ENCODING, + REJECT_CONTENT_MD5, + REJECT_CONTENT_TYPE, + REJECT_EXPIRES, + REJECT_FROM, + REJECT_IF_MATCH, + REJECT_IF_NONE_MATCH, + REJECT_IF_RANGE, + REJECT_IF_UNMODIFIED_SINCE, + REJECT_PRAGMA, + REJECT_REFERER, + + // The navigate request is rejected because of headers not listed above + // (e.g., custom headers). + REJECT_OTHER_HEADERS, + + // Total number of rejected navigate requests. + TOTAL_REJECTED_NAVIGATE_REQUESTS, + + // Total number of navigate requests. + TOTAL_NAVIGATE_REQUESTS, + FLASH_NAVIGATE_USAGE_ENUM_COUNT +}; + +static base::LazyInstance > + g_rejected_headers = LAZY_INSTANCE_INITIALIZER; + +bool IsSimpleHeader(const std::string& lower_case_header_name, + const std::string& header_value) { + if (lower_case_header_name == "accept" || + lower_case_header_name == "accept-language" || + lower_case_header_name == "content-language") { + return true; + } + + if (lower_case_header_name == "content-type") { + std::string lower_case_mime_type; + std::string lower_case_charset; + bool had_charset = false; + net::HttpUtil::ParseContentType(header_value, + &lower_case_mime_type, + &lower_case_charset, + &had_charset, + NULL); + return lower_case_mime_type == "application/x-www-form-urlencoded" || + lower_case_mime_type == "multipart/form-data" || + lower_case_mime_type == "text/plain"; + } + + return false; +} + +void RecordFlashNavigateUsage(FlashNavigateUsage usage) { + DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage); + UMA_HISTOGRAM_ENUMERATION( + "Plugin.FlashNavigateUsage", usage, FLASH_NAVIGATE_USAGE_ENUM_COUNT); +} + +} // namespace + +PepperFlashRendererHost::PepperFlashRendererHost( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host), + weak_factory_(this) {} + +PepperFlashRendererHost::~PepperFlashRendererHost() { + // This object may be destroyed in the middle of a sync message. If that is + // the case, make sure we respond to all the pending navigate calls. + std::vector::reverse_iterator it; + for (it = navigate_replies_.rbegin(); it != navigate_replies_.rend(); ++it) + SendReply(*it, IPC::Message()); +} + +int32_t PepperFlashRendererHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashRendererHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetProxyForURL, + OnGetProxyForURL) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_SetInstanceAlwaysOnTop, + OnSetInstanceAlwaysOnTop) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_DrawGlyphs, + OnDrawGlyphs) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_Navigate, OnNavigate) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_IsRectTopmost, + OnIsRectTopmost) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashRendererHost::OnGetProxyForURL( + ppapi::host::HostMessageContext* host_context, + const std::string& url) { + GURL gurl(url); + if (!gurl.is_valid()) + return PP_ERROR_FAILED; + std::string proxy; + bool result = content::RenderThread::Get()->ResolveProxy(gurl, &proxy); + if (!result) + return PP_ERROR_FAILED; + host_context->reply_msg = PpapiPluginMsg_Flash_GetProxyForURLReply(proxy); + return PP_OK; +} + +int32_t PepperFlashRendererHost::OnSetInstanceAlwaysOnTop( + ppapi::host::HostMessageContext* host_context, + bool on_top) { + content::PepperPluginInstance* plugin_instance = + host_->GetPluginInstance(pp_instance()); + if (plugin_instance) + plugin_instance->SetAlwaysOnTop(on_top); + // Since no reply is sent for this message, it doesn't make sense to return an + // error. + return PP_OK; +} + +int32_t PepperFlashRendererHost::OnDrawGlyphs( + ppapi::host::HostMessageContext* host_context, + ppapi::proxy::PPBFlash_DrawGlyphs_Params params) { + if (params.glyph_indices.size() != params.glyph_advances.size() || + params.glyph_indices.empty()) + return PP_ERROR_FAILED; + + // Set up the typeface. + int style = SkTypeface::kNormal; + if (static_cast(params.font_desc.weight) >= + PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD) + style |= SkTypeface::kBold; + if (params.font_desc.italic) + style |= SkTypeface::kItalic; + skia::RefPtr typeface = skia::AdoptRef(SkTypeface::CreateFromName( + params.font_desc.face.c_str(), static_cast(style))); + if (!typeface) + return PP_ERROR_FAILED; + + EnterResourceNoLock enter( + params.image_data.host_resource(), true); + if (enter.failed()) + return PP_ERROR_FAILED; + + // Set up the canvas. + PPB_ImageData_API* image = static_cast(enter.object()); + SkCanvas* canvas = image->GetCanvas(); + bool needs_unmapping = false; + if (!canvas) { + needs_unmapping = true; + image->Map(); + canvas = image->GetCanvas(); + if (!canvas) + return PP_ERROR_FAILED; // Failure mapping. + } + + SkAutoCanvasRestore acr(canvas, true); + + // Clip is applied in pixels before the transform. + SkRect clip_rect = { + SkIntToScalar(params.clip.point.x), SkIntToScalar(params.clip.point.y), + SkIntToScalar(params.clip.point.x + params.clip.size.width), + SkIntToScalar(params.clip.point.y + params.clip.size.height)}; + canvas->clipRect(clip_rect); + + // Convert & set the matrix. + SkMatrix matrix; + matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(params.transformation[0][0])); + matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(params.transformation[0][1])); + matrix.set(SkMatrix::kMTransX, SkFloatToScalar(params.transformation[0][2])); + matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(params.transformation[1][0])); + matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(params.transformation[1][1])); + matrix.set(SkMatrix::kMTransY, SkFloatToScalar(params.transformation[1][2])); + matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(params.transformation[2][0])); + matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(params.transformation[2][1])); + matrix.set(SkMatrix::kMPersp2, SkFloatToScalar(params.transformation[2][2])); + canvas->concat(matrix); + + SkPaint paint; + paint.setColor(params.color); + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + paint.setAntiAlias(true); + paint.setHinting(SkPaint::kFull_Hinting); + paint.setTextSize(SkIntToScalar(params.font_desc.size)); + paint.setTypeface(typeface.get()); // Takes a ref and manages lifetime. + if (params.allow_subpixel_aa) { + paint.setSubpixelText(true); + paint.setLCDRenderText(true); + } + + SkScalar x = SkIntToScalar(params.position.x); + SkScalar y = SkIntToScalar(params.position.y); + + // Build up the skia advances. + size_t glyph_count = params.glyph_indices.size(); + if (glyph_count) { + std::vector storage; + storage.resize(glyph_count); + SkPoint* sk_positions = &storage[0]; + for (uint32_t i = 0; i < glyph_count; i++) { + sk_positions[i].set(x, y); + x += SkFloatToScalar(params.glyph_advances[i].x); + y += SkFloatToScalar(params.glyph_advances[i].y); + } + + canvas->drawPosText( + ¶ms.glyph_indices[0], glyph_count * 2, sk_positions, paint); + } + + if (needs_unmapping) + image->Unmap(); + + return PP_OK; +} + +// CAUTION: This code is subtle because Navigate is a sync call which may +// cause re-entrancy or cause the instance to be destroyed. If the instance +// is destroyed we need to ensure that we respond to all outstanding sync +// messages so that the plugin process does not remain blocked. +int32_t PepperFlashRendererHost::OnNavigate( + ppapi::host::HostMessageContext* host_context, + const ppapi::URLRequestInfoData& data, + const std::string& target, + bool from_user_action) { + // If our PepperPluginInstance is already destroyed, just return a failure. + content::PepperPluginInstance* plugin_instance = + host_->GetPluginInstance(pp_instance()); + if (!plugin_instance) + return PP_ERROR_FAILED; + + std::map& rejected_headers = + g_rejected_headers.Get(); + if (rejected_headers.empty()) { + for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i) + rejected_headers[kRejectedHttpRequestHeaders[i]] = + static_cast(i); + } + + net::HttpUtil::HeadersIterator header_iter( + data.headers.begin(), data.headers.end(), "\n\r"); + bool rejected = false; + while (header_iter.GetNext()) { + std::string lower_case_header_name = + base::StringToLowerASCII(header_iter.name()); + if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) { + rejected = true; + + std::map::const_iterator iter = + rejected_headers.find(lower_case_header_name); + FlashNavigateUsage usage = + iter != rejected_headers.end() ? iter->second : REJECT_OTHER_HEADERS; + RecordFlashNavigateUsage(usage); + } + } + + RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS); + if (rejected) { + RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS); + return PP_ERROR_NOACCESS; + } + + // Navigate may call into Javascript (e.g. with a "javascript:" URL), + // or do things like navigate away from the page, either one of which will + // need to re-enter into the plugin. It is safe, because it is essentially + // equivalent to NPN_GetURL, where Flash would expect re-entrancy. + ppapi::proxy::HostDispatcher* host_dispatcher = + ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); + host_dispatcher->set_allow_plugin_reentrancy(); + + // Grab a weak pointer to ourselves on the stack so we can check if we are + // still alive. + base::WeakPtr weak_ptr = weak_factory_.GetWeakPtr(); + // Keep track of reply contexts in case we are destroyed during a Navigate + // call. Even if we are destroyed, we still need to send these replies to + // unblock the plugin process. + navigate_replies_.push_back(host_context->MakeReplyMessageContext()); + plugin_instance->Navigate(data, target.c_str(), from_user_action); + // This object might have been destroyed by this point. If it is destroyed + // the reply will be sent in the destructor. Otherwise send the reply here. + if (weak_ptr.get()) { + SendReply(navigate_replies_.back(), IPC::Message()); + navigate_replies_.pop_back(); + } + + // Return PP_OK_COMPLETIONPENDING so that no reply is automatically sent. + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFlashRendererHost::OnIsRectTopmost( + ppapi::host::HostMessageContext* host_context, + const PP_Rect& rect) { + content::PepperPluginInstance* plugin_instance = + host_->GetPluginInstance(pp_instance()); + if (plugin_instance && + plugin_instance->IsRectTopmost(gfx::Rect( + rect.point.x, rect.point.y, rect.size.width, rect.size.height))) + return PP_OK; + return PP_ERROR_FAILED; +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h new file mode 100644 index 000000000000..de22f46045a5 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h @@ -0,0 +1,69 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_ + +#include +#include + +#include "base/basictypes.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +struct PP_Rect; + +namespace ppapi { +struct URLRequestInfoData; +} + +namespace ppapi { +namespace proxy { +struct PPBFlash_DrawGlyphs_Params; +} +} + +namespace content { +class RendererPpapiHost; +} + +class PepperFlashRendererHost : public ppapi::host::ResourceHost { + public: + PepperFlashRendererHost(content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashRendererHost() override; + + // ppapi::host::ResourceHost override. + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + + private: + int32_t OnGetProxyForURL(ppapi::host::HostMessageContext* host_context, + const std::string& url); + int32_t OnSetInstanceAlwaysOnTop( + ppapi::host::HostMessageContext* host_context, + bool on_top); + int32_t OnDrawGlyphs(ppapi::host::HostMessageContext* host_context, + ppapi::proxy::PPBFlash_DrawGlyphs_Params params); + int32_t OnNavigate(ppapi::host::HostMessageContext* host_context, + const ppapi::URLRequestInfoData& data, + const std::string& target, + bool from_user_action); + int32_t OnIsRectTopmost(ppapi::host::HostMessageContext* host_context, + const PP_Rect& rect); + + // A stack of ReplyMessageContexts to track Navigate() calls which have not + // yet been replied to. + std::vector navigate_replies_; + + content::RendererPpapiHost* host_; + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashRendererHost); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_helper.cc b/chromium_src/chrome/renderer/pepper/pepper_helper.cc new file mode 100644 index 000000000000..a610a30dfff5 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_helper.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_helper.h" + +#include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h" +#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" + +PepperHelper::PepperHelper(content::RenderFrame* render_frame) + : RenderFrameObserver(render_frame) {} + +PepperHelper::~PepperHelper() {} + +void PepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) { + // TODO(brettw) figure out how to hook up the host factory. It needs some + // kind of filter-like system to allow dynamic additions. + host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr( + new ChromeRendererPepperHostFactory(host))); + host->GetPpapiHost()->AddInstanceMessageFilter( + scoped_ptr( + new PepperSharedMemoryMessageFilter(host))); +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_helper.h b/chromium_src/chrome/renderer/pepper/pepper_helper.h new file mode 100644 index 000000000000..b3e850b2481b --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_helper.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_ + +#include "base/compiler_specific.h" +#include "content/public/renderer/render_frame_observer.h" + +// This class listens for Pepper creation events from the RenderFrame and +// attaches the parts required for Chrome-specific plugin support. +class PepperHelper : public content::RenderFrameObserver { + public: + explicit PepperHelper(content::RenderFrame* render_frame); + ~PepperHelper() override; + + // RenderFrameObserver. + void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; + + private: + DISALLOW_COPY_AND_ASSIGN(PepperHelper); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_ diff --git a/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc new file mode 100644 index 000000000000..e01aea741fc8 --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h" + +#include "base/memory/scoped_ptr.h" +#include "base/memory/shared_memory.h" +#include "base/process/process_handle.h" +#include "content/public/common/content_client.h" +#include "content/public/renderer/pepper_plugin_instance.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/var_tracker.h" + +PepperSharedMemoryMessageFilter::PepperSharedMemoryMessageFilter( + content::RendererPpapiHost* host) + : InstanceMessageFilter(host->GetPpapiHost()), host_(host) {} + +PepperSharedMemoryMessageFilter::~PepperSharedMemoryMessageFilter() {} + +bool PepperSharedMemoryMessageFilter::OnInstanceMessageReceived( + const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PepperSharedMemoryMessageFilter, msg) + IPC_MESSAGE_HANDLER(PpapiHostMsg_SharedMemory_CreateSharedMemory, + OnHostMsgCreateSharedMemory) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +bool PepperSharedMemoryMessageFilter::Send(IPC::Message* msg) { + return host_->GetPpapiHost()->Send(msg); +} + +void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory( + PP_Instance instance, + uint32_t size, + int* host_handle_id, + ppapi::proxy::SerializedHandle* plugin_handle) { + plugin_handle->set_null_shmem(); + *host_handle_id = -1; + scoped_ptr shm(content::RenderThread::Get() + ->HostAllocateSharedMemoryBuffer(size) + .Pass()); + if (!shm.get()) + return; + + base::SharedMemoryHandle host_shm_handle; + shm->ShareToProcess(base::GetCurrentProcessHandle(), &host_shm_handle); + *host_handle_id = + content::PepperPluginInstance::Get(instance) + ->GetVarTracker() + ->TrackSharedMemoryHandle(instance, host_shm_handle, size); + + base::PlatformFile host_handle = +#if defined(OS_WIN) + host_shm_handle; +#elif defined(OS_POSIX) + host_shm_handle.fd; +#else +#error Not implemented. +#endif + // We set auto_close to false since we need our file descriptor to + // actually be duplicated on linux. The shared memory destructor will + // close the original handle for us. + plugin_handle->set_shmem(host_->ShareHandleWithRemote(host_handle, false), + size); +} diff --git a/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h new file mode 100644 index 000000000000..d7e0934cd6ec --- /dev/null +++ b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h @@ -0,0 +1,48 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ +#define CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/host/instance_message_filter.h" + +namespace content { +class RendererPpapiHost; +} + +namespace ppapi { +namespace proxy { +class SerializedHandle; +} +} + +// Implements the backend for shared memory messages from a plugin process. +class PepperSharedMemoryMessageFilter + : public ppapi::host::InstanceMessageFilter { + public: + explicit PepperSharedMemoryMessageFilter(content::RendererPpapiHost* host); + ~PepperSharedMemoryMessageFilter() override; + + // InstanceMessageFilter: + bool OnInstanceMessageReceived(const IPC::Message& msg) override; + + bool Send(IPC::Message* msg); + + private: + // Message handlers. + void OnHostMsgCreateSharedMemory( + PP_Instance instance, + uint32_t size, + int* host_shm_handle_id, + ppapi::proxy::SerializedHandle* plugin_shm_handle); + + content::RendererPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(PepperSharedMemoryMessageFilter); +}; + +#endif // CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ diff --git a/filenames.gypi b/filenames.gypi index bb1e7e54cf9b..c275af729eb4 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -311,6 +311,16 @@ 'chromium_src/chrome/browser/printing/printer_query.h', 'chromium_src/chrome/browser/printing/printing_message_filter.cc', 'chromium_src/chrome/browser/printing/printing_message_filter.h', + 'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc', + 'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc', + 'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h', 'chromium_src/chrome/browser/speech/tts_controller.h', 'chromium_src/chrome/browser/speech/tts_controller_impl.cc', 'chromium_src/chrome/browser/speech/tts_controller_impl.h', @@ -333,6 +343,22 @@ 'chromium_src/chrome/common/tts_messages.h', 'chromium_src/chrome/common/tts_utterance_request.cc', 'chromium_src/chrome/common/tts_utterance_request.h', + 'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc', + 'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h', + 'chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc', + 'chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h', + 'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc', + 'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h', + 'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc', + 'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h', + 'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc', + 'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h', + 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc', + 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h', + 'chromium_src/chrome/renderer/pepper/pepper_helper.cc', + 'chromium_src/chrome/renderer/pepper/pepper_helper.h', + 'chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc', + 'chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h', 'chromium_src/chrome/renderer/printing/print_web_view_helper.cc', 'chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc', 'chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm', From 1c190388e5bbeeef75e80b33a2a27dbb21a6d338 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 5 May 2015 14:24:22 +0530 Subject: [PATCH 131/155] flash_drm_host not required --- atom/app/atom_content_client.cc | 5 +- .../chrome_browser_pepper_host_factory.cc | 5 -- .../chrome_renderer_pepper_host_factory.cc | 4 - .../pepper/pepper_flash_drm_renderer_host.cc | 87 ------------------- .../pepper/pepper_flash_drm_renderer_host.h | 51 ----------- filenames.gypi | 4 +- 6 files changed, 2 insertions(+), 154 deletions(-) delete mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc delete mode 100644 chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index 5d97fe5665f2..ecc5c72155a4 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -18,10 +18,7 @@ namespace atom { -int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV | - ppapi::PERMISSION_PRIVATE | - ppapi::PERMISSION_BYPASS_USER_GESTURE | - ppapi::PERMISSION_FLASH; +int32 kPepperFlashPermissions = ppapi::PERMISSION_ALL_BITS; namespace { diff --git a/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc index 03d706fee045..c2992abcc11d 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc +++ b/chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc @@ -65,11 +65,6 @@ scoped_ptr ChromeBrowserPepperHostFactory::CreateResourceHost( return scoped_ptr(new MessageFilterHost( host_->GetPpapiHost(), instance, resource, clipboard_filter)); } -#if 0 - case PpapiHostMsg_FlashDRM_Create::ID: - return scoped_ptr( - new PepperFlashDRMHost(host_, instance, resource)); -#endif } } diff --git a/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc index db92669df19a..dd83b8191c06 100644 --- a/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc +++ b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc @@ -5,7 +5,6 @@ #include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h" #include "base/logging.h" -#include "chrome/renderer/pepper/pepper_flash_drm_renderer_host.h" #include "chrome/renderer/pepper/pepper_flash_font_file_host.h" #include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h" #include "chrome/renderer/pepper/pepper_flash_menu_host.h" @@ -77,9 +76,6 @@ scoped_ptr ChromeRendererPepperHostFactory::CreateResourceHost( } break; } - case PpapiHostMsg_FlashDRM_Create::ID: - return scoped_ptr( - new PepperFlashDRMRendererHost(host_, instance, resource)); } } diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc deleted file mode 100644 index 2e95d23dd41d..000000000000 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/renderer/pepper/pepper_flash_drm_renderer_host.h" - -#include "base/files/file_path.h" -#include "content/public/renderer/pepper_plugin_instance.h" -#include "content/public/renderer/renderer_ppapi_host.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/host/dispatch_host_message.h" -#include "ppapi/host/host_message_context.h" -#include "ppapi/host/ppapi_host.h" -#include "ppapi/proxy/ppapi_messages.h" - -// TODO(raymes): This is duplicated from pepper_flash_drm_host.cc but once -// FileRef is refactored to the browser, it won't need to be. -namespace { -const char kVoucherFilename[] = "plugin.vch"; -} // namespace - -PepperFlashDRMRendererHost::PepperFlashDRMRendererHost( - content::RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource) - : ResourceHost(host->GetPpapiHost(), instance, resource), - renderer_ppapi_host_(host), - weak_factory_(this) {} - -PepperFlashDRMRendererHost::~PepperFlashDRMRendererHost() {} - -int32_t PepperFlashDRMRendererHost::OnResourceMessageReceived( - const IPC::Message& msg, - ppapi::host::HostMessageContext* context) { - PPAPI_BEGIN_MESSAGE_MAP(PepperFlashDRMRendererHost, msg) - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetVoucherFile, - OnGetVoucherFile) - PPAPI_END_MESSAGE_MAP() - return PP_ERROR_FAILED; -} - -int32_t PepperFlashDRMRendererHost::OnGetVoucherFile( - ppapi::host::HostMessageContext* context) { - content::PepperPluginInstance* plugin_instance = - renderer_ppapi_host_->GetPluginInstance(pp_instance()); - if (!plugin_instance) - return PP_ERROR_FAILED; - - base::FilePath plugin_dir = plugin_instance->GetModulePath().DirName(); - DCHECK(!plugin_dir.empty()); - base::FilePath voucher_file = plugin_dir.AppendASCII(kVoucherFilename); - - int renderer_pending_host_id = - plugin_instance->MakePendingFileRefRendererHost(voucher_file); - if (renderer_pending_host_id == 0) - return PP_ERROR_FAILED; - - std::vector create_msgs; - create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(voucher_file)); - - renderer_ppapi_host_->CreateBrowserResourceHosts( - pp_instance(), - create_msgs, - base::Bind(&PepperFlashDRMRendererHost::DidCreateFileRefHosts, - weak_factory_.GetWeakPtr(), - context->MakeReplyMessageContext(), - voucher_file, - renderer_pending_host_id)); - return PP_OK_COMPLETIONPENDING; -} - -void PepperFlashDRMRendererHost::DidCreateFileRefHosts( - const ppapi::host::ReplyMessageContext& reply_context, - const base::FilePath& external_path, - int renderer_pending_host_id, - const std::vector& browser_pending_host_ids) { - DCHECK_EQ(1U, browser_pending_host_ids.size()); - int browser_pending_host_id = browser_pending_host_ids[0]; - - ppapi::FileRefCreateInfo create_info = - ppapi::MakeExternalFileRefCreateInfo(external_path, - std::string(), - browser_pending_host_id, - renderer_pending_host_id); - host()->SendReply(reply_context, - PpapiPluginMsg_FlashDRM_GetVoucherFileReply(create_info)); -} diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h deleted file mode 100644 index cc06d382721f..000000000000 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_DRM_RENDERER_HOST_H_ -#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_DRM_RENDERER_HOST_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/weak_ptr.h" -#include "ppapi/host/resource_host.h" - -namespace base { -class FilePath; -} - -namespace content { -class RendererPpapiHost; -} - -// TODO(raymes): This is only needed until we move FileRef resources to the -// browser. After that, get rid of this class altogether. -class PepperFlashDRMRendererHost : public ppapi::host::ResourceHost { - public: - PepperFlashDRMRendererHost(content::RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource); - ~PepperFlashDRMRendererHost() override; - - int32_t OnResourceMessageReceived( - const IPC::Message& msg, - ppapi::host::HostMessageContext* context) override; - - private: - int32_t OnGetVoucherFile(ppapi::host::HostMessageContext* context); - - void DidCreateFileRefHosts( - const ppapi::host::ReplyMessageContext& reply_context, - const base::FilePath& external_path, - int renderer_pending_host_id, - const std::vector& browser_pending_host_ids); - - // Non-owning pointer. - content::RendererPpapiHost* renderer_ppapi_host_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(PepperFlashDRMRendererHost); -}; - -#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_DRM_RENDERER_HOST_H_ diff --git a/filenames.gypi b/filenames.gypi index c275af729eb4..ebd1fb41aaf2 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -345,15 +345,13 @@ 'chromium_src/chrome/common/tts_utterance_request.h', 'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc', 'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h', - 'chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc', - 'chromium_src/chrome/renderer/pepper/pepper_flash_drm_renderer_host.h', 'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc', 'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h', 'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc', 'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h', 'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc', 'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h', - 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc', + 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc', 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h', 'chromium_src/chrome/renderer/pepper/pepper_helper.cc', 'chromium_src/chrome/renderer/pepper/pepper_helper.h', From 853ce0bbd7db0516147f2b1b2482fe557d0d18d4 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 6 May 2015 13:29:23 +0530 Subject: [PATCH 132/155] provide flag to set flash version --- atom/app/atom_content_client.cc | 28 +++++++--------------------- atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index ecc5c72155a4..c36a1e22c87d 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -30,24 +30,8 @@ namespace { plugin.name = content::kFlashPluginName; plugin.path = path; plugin.permissions = kPepperFlashPermissions; + plugin.version = version; - std::vector flash_version_numbers; - base::SplitString(version, '.', &flash_version_numbers); - if (flash_version_numbers.size() < 1) - flash_version_numbers.push_back("11"); - // |SplitString()| puts in an empty string given an empty string. :( - else if (flash_version_numbers[0].empty()) - flash_version_numbers[0] = "11"; - if (flash_version_numbers.size() < 2) - flash_version_numbers.push_back("2"); - if (flash_version_numbers.size() < 3) - flash_version_numbers.push_back("999"); - if (flash_version_numbers.size() < 4) - flash_version_numbers.push_back("999"); - // E.g., "Shockwave Flash 10.2 r154": - plugin.description = plugin.name + " " + flash_version_numbers[0] + "." + - flash_version_numbers[1] + " r" + flash_version_numbers[2]; - plugin.version = JoinString(flash_version_numbers, '.'); content::WebPluginMimeType swf_mime_type( content::kFlashPluginSwfMimeType, content::kFlashPluginSwfExtension, @@ -82,13 +66,15 @@ void AtomContentClient::AddAdditionalSchemes( void AtomContentClient::AddPepperPlugins( std::vector* plugins) { - const base::CommandLine::StringType flash_path = - base::CommandLine::ForCurrentProcess()->GetSwitchValueNative( - switches::kPpapiFlashPath); + auto command_line = base::CommandLine::ForCurrentProcess(); + auto flash_path = command_line->GetSwitchValueNative( + switches::kPpapiFlashPath); if (flash_path.empty()) return; - std::string flash_version; + auto flash_version = command_line->GetSwitchValueASCII( + switches::kPpapiFlashVersion); + plugins->push_back( CreatePepperFlashInfo(base::FilePath(flash_path), flash_version)); } diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 37daa894c6d8..13d1ad2571de 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -66,6 +66,9 @@ const char kEnablePlugins[] = "enable-plugins"; // Ppapi Flash path. const char kPpapiFlashPath[] = "ppapi-flash-path"; +// Ppapi Flash version. +const char kPpapiFlashVersion[] = "ppapi-flash-version"; + // Instancd ID of guest WebContents. const char kGuestInstanceID[] = "guest-instance-id"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index d6f8c072886c..8e7080ace45d 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -38,6 +38,7 @@ extern const char kDarkTheme[]; extern const char kDirectWrite[]; extern const char kEnablePlugins[]; extern const char kPpapiFlashPath[]; +extern const char kPpapiFlashVersion[]; extern const char kGuestInstanceID[]; extern const char kPreloadScript[]; extern const char kTransparent[]; From 15ae6b8d36982d0c6f69193dd23ae2eb011f5c35 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sun, 10 May 2015 10:25:19 +0530 Subject: [PATCH 133/155] fix lint errors and add documentation --- atom/app/atom_content_client.cc | 46 +++++++++++------------- atom/browser/atom_browser_client.cc | 8 +++-- docs/api/chrome-command-line-switches.md | 8 +++++ 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index c36a1e22c87d..c8a591a59cc4 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -10,41 +10,37 @@ #include "atom/common/chrome_version.h" #include "atom/common/options_switches.h" #include "base/command_line.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" #include "content/public/common/content_constants.h" #include "content/public/common/pepper_plugin_info.h" #include "ppapi/shared_impl/ppapi_permissions.h" namespace atom { -int32 kPepperFlashPermissions = ppapi::PERMISSION_ALL_BITS; - namespace { - content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, - const std::string& version) { - content::PepperPluginInfo plugin; +content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, + const std::string& version) { + content::PepperPluginInfo plugin; - plugin.is_out_of_process = true; - plugin.name = content::kFlashPluginName; - plugin.path = path; - plugin.permissions = kPepperFlashPermissions; - plugin.version = version; + plugin.is_out_of_process = true; + plugin.name = content::kFlashPluginName; + plugin.path = path; + plugin.permissions = ppapi::PERMISSION_ALL_BITS; + plugin.version = version; - content::WebPluginMimeType swf_mime_type( - content::kFlashPluginSwfMimeType, - content::kFlashPluginSwfExtension, - content::kFlashPluginSwfDescription); - plugin.mime_types.push_back(swf_mime_type); - content::WebPluginMimeType spl_mime_type( - content::kFlashPluginSplMimeType, - content::kFlashPluginSplExtension, - content::kFlashPluginSplDescription); - plugin.mime_types.push_back(spl_mime_type); + content::WebPluginMimeType swf_mime_type( + content::kFlashPluginSwfMimeType, + content::kFlashPluginSwfExtension, + content::kFlashPluginSwfDescription); + plugin.mime_types.push_back(swf_mime_type); + content::WebPluginMimeType spl_mime_type( + content::kFlashPluginSplMimeType, + content::kFlashPluginSplExtension, + content::kFlashPluginSplDescription); + plugin.mime_types.push_back(spl_mime_type); - return plugin; - } + return plugin; +} } // namespace @@ -65,7 +61,7 @@ void AtomContentClient::AddAdditionalSchemes( } void AtomContentClient::AddPepperPlugins( - std::vector* plugins) { + std::vector* plugins) { auto command_line = base::CommandLine::ForCurrentProcess(); auto flash_path = command_line->GetSwitchValueNative( switches::kPpapiFlashPath); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 69ae0d3830cd..1d00f6bdcf03 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -202,9 +202,11 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( void AtomBrowserClient::DidCreatePpapiPlugin( content::BrowserPpapiHost* browser_host) { - browser_host->GetPpapiHost()->AddHostFactoryFilter( - scoped_ptr( - new chrome::ChromeBrowserPepperHostFactory(browser_host))); + auto command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnablePlugins)) + browser_host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr( + new chrome::ChromeBrowserPepperHostFactory(browser_host))); } brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index de124ac8ceba..fe22bd2c08ab 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -62,6 +62,14 @@ Like `--host-rules` but these `rules` only apply to the host resolver. Ignore certificate related errors. +## --ppapi-flash-path + +Set path to pepper flash plugin for use. + +## --ppapi-flash-version + +Set the pepper flash version. + ## --v=`log_level` Gives the default maximal active V-logging level; 0 is the default. Normally From ed023a560eb12732f7372f396c18de97203bf908 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Sun, 10 May 2015 02:54:37 -0300 Subject: [PATCH 134/155] Fix wording in docs/api/remote.md --- docs/api/remote.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/remote.md b/docs/api/remote.md index 6145bc181b65..77e76ea57f01 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -49,7 +49,7 @@ Primary value types like strings and numbers, however, are sent by copy. ## Passing callbacks to the main process -Some APIs in the main process accept callbacks, and it would be attempting to +Some APIs in the main process accept callbacks, and it would be tempting to pass callbacks when calling a remote function. The `remote` module does support doing this, but you should also be extremely careful with this. From d9c90be1def608e9a39de8aea26802392de46e2b Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sun, 10 May 2015 16:15:12 +0800 Subject: [PATCH 135/155] Update China mirrors url fixes #1497 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44f37efdbefa..c3f7461c5e7e 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ npm install electron-prebuilt --save-dev ### Mirrors -- [China](https://npm.taobao.org/mirrors/atom-shell) +- [China](https://npm.taobao.org/mirrors/electron) ## Documentation From ce042d05240c06b15decd4a466b154ed26529525 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 10 May 2015 16:51:18 +0800 Subject: [PATCH 136/155] mac: Don't use [NSScreen mainScreen] --- atom/browser/native_window_mac.mm | 6 +++--- atom/browser/ui/tray_icon_cocoa.mm | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9071763e77f3..33e10ca9bffd 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -303,7 +303,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, options.Get(switches::kWidth, &width); options.Get(switches::kHeight, &height); - NSRect main_screen_rect = [[NSScreen mainScreen] frame]; + NSRect main_screen_rect = [[[NSScreen screens] objectAtIndex:0] frame]; NSRect cocoa_bounds = NSMakeRect( round((NSWidth(main_screen_rect) - width) / 2) , round((NSHeight(main_screen_rect) - height) / 2), @@ -463,7 +463,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds) { bounds.width(), bounds.height()); // Flip coordinates based on the primary screen. - NSScreen* screen = [NSScreen mainScreen]; + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; cocoa_bounds.origin.y = NSHeight([screen frame]) - bounds.height() - bounds.y(); @@ -473,7 +473,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds) { gfx::Rect NativeWindowMac::GetBounds() { NSRect frame = [window_ frame]; gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); - NSScreen* screen = [NSScreen mainScreen]; + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); return bounds; } diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 1bcbaf79ac10..f989b9b580e2 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -30,7 +30,7 @@ NSRect frame = [NSApp currentEvent].window.frame; gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); // Flip coordinates to gfx (0,0 in top-left corner) using current screen. - NSScreen* screen = [NSScreen mainScreen]; + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); trayIcon_->NotifyClicked(bounds); From 66ef52197a30b221d3afdeca4e729a493ad88241 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 10 May 2015 21:14:37 +0800 Subject: [PATCH 137/155] mac: Make "standard-window" option default to true --- atom/browser/native_window_mac.mm | 2 +- docs/api/browser-window.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 6b321d135419..8dd6bcbacbe1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -310,7 +310,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents, width, height); - bool useStandardWindow = false; + bool useStandardWindow = true; options.Get(switches::kStandardWindow, &useStandardWindow); NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index d2854fc17014..5d04ed2f3dd3 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -72,8 +72,8 @@ You can also create a window without chrome by using * `type` String - Specifies the type of the window, possible types are `desktop`, `dock`, `toolbar`, `splash`, `notification`. This only works on Linux. - * `standard-window` Boolean - Use the OS X's standard window instead of the - textured window. Defaults to `false`. + * `standard-window` Boolean - Uses the OS X's standard window instead of the + textured window. Defaults to `true`. * `web-preferences` Object - Settings of web page's features * `javascript` Boolean * `web-security` Boolean From f02cae1b0ab60824f76dfdfb13732edee5924eae Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 10 May 2015 22:14:32 +0800 Subject: [PATCH 138/155] docs: app.terminate is deprecated --- docs/api/app.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index 09ffb66c0b06..31fa1c616101 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -94,11 +94,6 @@ This method guarantees all `beforeunload` and `unload` handlers are correctly executed. It is possible that a window cancels the quitting by returning `false` in `beforeunload` handler. -## app.terminate() - -Quit the application directly, it will not try to close all windows so cleanup -code will not run. - ## app.getPath(name) * `name` String From f8e1dfbbc637e600c05fbb06bda0ec0cf41f4e02 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 10:47:07 +0800 Subject: [PATCH 139/155] Keep archive's file opened in the archive's whole life time --- atom/common/asar/archive.cc | 10 +++++----- atom/common/asar/archive.h | 2 ++ atom/common/asar/scoped_temporary_file.cc | 7 +++---- atom/common/asar/scoped_temporary_file.h | 6 +++++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index 4ad8c1817a90..e0d2373d9d97 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -104,6 +104,7 @@ bool FillFileInfoWithNode(Archive::FileInfo* info, Archive::Archive(const base::FilePath& path) : path_(path), + file_(path_, base::File::FLAG_OPEN | base::File::FLAG_READ), header_size_(0) { } @@ -111,15 +112,14 @@ Archive::~Archive() { } bool Archive::Init() { - base::File file(path_, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!file.IsValid()) + if (!file_.IsValid()) return false; std::vector buf; int len; buf.resize(8); - len = file.ReadAtCurrentPos(buf.data(), buf.size()); + len = file_.ReadAtCurrentPos(buf.data(), buf.size()); if (len != static_cast(buf.size())) { PLOG(ERROR) << "Failed to read header size from " << path_.value(); return false; @@ -132,7 +132,7 @@ bool Archive::Init() { } buf.resize(size); - len = file.ReadAtCurrentPos(buf.data(), buf.size()); + len = file_.ReadAtCurrentPos(buf.data(), buf.size()); if (len != static_cast(buf.size())) { PLOG(ERROR) << "Failed to read header from " << path_.value(); return false; @@ -250,7 +250,7 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { } scoped_ptr temp_file(new ScopedTemporaryFile); - if (!temp_file->InitFromFile(path_, info.offset, info.size)) + if (!temp_file->InitFromFile(file_, info.offset, info.size)) return false; *out = temp_file->path(); diff --git a/atom/common/asar/archive.h b/atom/common/asar/archive.h index 53adbfc13c41..e8bd7c5b063a 100644 --- a/atom/common/asar/archive.h +++ b/atom/common/asar/archive.h @@ -8,6 +8,7 @@ #include #include "base/containers/scoped_ptr_hash_map.h" +#include "base/files/file.h" #include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" @@ -64,6 +65,7 @@ class Archive { private: base::FilePath path_; + base::File file_; uint32 header_size_; scoped_ptr header_; diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index 574f178f6f34..de70a333279f 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -36,13 +36,12 @@ bool ScopedTemporaryFile::Init() { return base::CreateTemporaryFile(&path_); } -bool ScopedTemporaryFile::InitFromFile(const base::FilePath& path, +bool ScopedTemporaryFile::InitFromFile(base::File& src, uint64 offset, uint64 size) { - if (!Init()) + if (!src.IsValid()) return false; - base::File src(path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!src.IsValid()) + if (!Init()) return false; std::vector buf(size); diff --git a/atom/common/asar/scoped_temporary_file.h b/atom/common/asar/scoped_temporary_file.h index 62aafc8f07d6..8d822e99d60f 100644 --- a/atom/common/asar/scoped_temporary_file.h +++ b/atom/common/asar/scoped_temporary_file.h @@ -7,6 +7,10 @@ #include "base/files/file_path.h" +namespace base { +class File; +} + namespace asar { // An object representing a temporary file that should be cleaned up when this @@ -22,7 +26,7 @@ class ScopedTemporaryFile { bool Init(); // Init an temporary file and fill it with content of |path|. - bool InitFromFile(const base::FilePath& path, uint64 offset, uint64 size); + bool InitFromFile(base::File& src, uint64 offset, uint64 size); base::FilePath path() const { return path_; } From d8d7e5b9bb11e4959dd4fe04602ed83b6b022e1d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 11:02:17 +0800 Subject: [PATCH 140/155] Add Archive::GetFD --- atom/common/api/atom_api_asar.cc | 8 ++++++++ atom/common/asar/archive.cc | 20 +++++++++++++++++++- atom/common/asar/archive.h | 3 +++ atom/common/asar/scoped_temporary_file.cc | 6 +++--- atom/common/asar/scoped_temporary_file.h | 2 +- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index d035159380a4..3fd2ca6f86f7 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -88,6 +88,13 @@ class Archive : public mate::Wrappable { return mate::ConvertToV8(isolate, new_path); } + // Return the file descriptor. + int GetFD() const { + if (!archive_) + return -1; + return archive_->GetFD(); + } + // Free the resources used by archive. void Destroy() { archive_.reset(); @@ -102,6 +109,7 @@ class Archive : public mate::Wrappable { .SetMethod("readdir", &Archive::Readdir) .SetMethod("realpath", &Archive::Realpath) .SetMethod("copyFileOut", &Archive::CopyFileOut) + .SetMethod("getFd", &Archive::GetFD) .SetMethod("destroy", &Archive::Destroy); } diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index e0d2373d9d97..98e464650bac 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -4,6 +4,10 @@ #include "atom/common/asar/archive.h" +#if defined(OS_WIN) +#include +#endif + #include #include @@ -250,7 +254,7 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { } scoped_ptr temp_file(new ScopedTemporaryFile); - if (!temp_file->InitFromFile(file_, info.offset, info.size)) + if (!temp_file->InitFromFile(&file_, info.offset, info.size)) return false; *out = temp_file->path(); @@ -258,4 +262,18 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { return true; } +int Archive::GetFD() const { + if (!file_.IsValid()) + return -1; + +#if defined(OS_WIN) + return + _open_osfhandle(reinterpret_cast(file_.GetPlatformFile()), 0); +#elif defined(OS_POSIX) + return file_.GetPlatformFile(); +#else + return -1; +#endif +} + } // namespace asar diff --git a/atom/common/asar/archive.h b/atom/common/asar/archive.h index e8bd7c5b063a..2acd17fd7ab4 100644 --- a/atom/common/asar/archive.h +++ b/atom/common/asar/archive.h @@ -60,6 +60,9 @@ class Archive { // For unpacked file, this method will return its real path. bool CopyFileOut(const base::FilePath& path, base::FilePath* out); + // Returns the file's fd. + int GetFD() const; + base::FilePath path() const { return path_; } base::DictionaryValue* header() const { return header_.get(); } diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index de70a333279f..6fccc9434fdb 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -36,16 +36,16 @@ bool ScopedTemporaryFile::Init() { return base::CreateTemporaryFile(&path_); } -bool ScopedTemporaryFile::InitFromFile(base::File& src, +bool ScopedTemporaryFile::InitFromFile(base::File* src, uint64 offset, uint64 size) { - if (!src.IsValid()) + if (!src->IsValid()) return false; if (!Init()) return false; std::vector buf(size); - int len = src.Read(offset, buf.data(), buf.size()); + int len = src->Read(offset, buf.data(), buf.size()); if (len != static_cast(size)) return false; diff --git a/atom/common/asar/scoped_temporary_file.h b/atom/common/asar/scoped_temporary_file.h index 8d822e99d60f..ffaee22e514e 100644 --- a/atom/common/asar/scoped_temporary_file.h +++ b/atom/common/asar/scoped_temporary_file.h @@ -26,7 +26,7 @@ class ScopedTemporaryFile { bool Init(); // Init an temporary file and fill it with content of |path|. - bool InitFromFile(base::File& src, uint64 offset, uint64 size); + bool InitFromFile(base::File* src, uint64 offset, uint64 size); base::FilePath path() const { return path_; } From d9c769fa696d1ad2b19adf7ef4b2843f2f6990d3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 11:10:50 +0800 Subject: [PATCH 141/155] Reuse archive's fd in Node asar API --- atom/common/lib/asar.coffee | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/atom/common/lib/asar.coffee b/atom/common/lib/asar.coffee index f36a149a7cff..f70d2c456d78 100644 --- a/atom/common/lib/asar.coffee +++ b/atom/common/lib/asar.coffee @@ -236,21 +236,20 @@ exports.wrapFsWithAsar = (fs) -> return fs.readFile realPath, options, callback if not options - options = encoding: null, flag: 'r' + options = encoding: null else if util.isString options - options = encoding: options, flag: 'r' + options = encoding: options else if not util.isObject options throw new TypeError('Bad arguments') - flag = options.flag || 'r' encoding = options.encoding buffer = new Buffer(info.size) - open archive.path, flag, (error, fd) -> - return callback error if error - fs.read fd, buffer, 0, info.size, info.offset, (error) -> - fs.close fd, -> - callback error, if encoding then buffer.toString encoding else buffer + fd = archive.getFd() + return notFoundError asarPath, filePath, callback unless fd >= 0 + + fs.read fd, buffer, 0, info.size, info.offset, (error) -> + callback error, if encoding then buffer.toString encoding else buffer openSync = fs.openSync readFileSync = fs.readFileSync @@ -270,23 +269,19 @@ exports.wrapFsWithAsar = (fs) -> return fs.readFileSync realPath, options if not options - options = encoding: null, flag: 'r' + options = encoding: null else if util.isString options - options = encoding: options, flag: 'r' + options = encoding: options else if not util.isObject options throw new TypeError('Bad arguments') - flag = options.flag || 'r' encoding = options.encoding buffer = new Buffer(info.size) - fd = openSync archive.path, flag - try - fs.readSync fd, buffer, 0, info.size, info.offset - catch e - throw e - finally - fs.closeSync fd + fd = archive.getFd() + notFoundError asarPath, filePath unless fd >= 0 + + fs.readSync fd, buffer, 0, info.size, info.offset if encoding then buffer.toString encoding else buffer readdir = fs.readdir From 9ab53b0e4b49c2d2e8e6a67ed0d63d19825eaa6c Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 7 May 2015 13:12:35 +0530 Subject: [PATCH 142/155] protocol: adding error job to log error with custom protocols --- atom/browser/api/atom_api_protocol.cc | 8 ++++++++ atom/browser/api/lib/protocol.coffee | 4 ++++ atom/browser/net/adapter_request_job.cc | 2 +- docs/api/protocol.md | 22 +++++++++++++++++++++- spec/api-protocol-spec.coffee | 15 +++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index ecb9d416875a..617a098adbc3 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -105,6 +105,14 @@ class CustomProtocolRequestJob : public AdapterRequestJob { base::Bind(&AdapterRequestJob::CreateFileJobAndStart, GetWeakPtr(), path)); return; + } else if (name == "RequestErrorJob") { + int error; + dict.Get("error", &error); + + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&AdapterRequestJob::CreateErrorJobAndStart, + GetWeakPtr(), error)); + return; } } diff --git a/atom/browser/api/lib/protocol.coffee b/atom/browser/api/lib/protocol.coffee index 6eae01462b42..c2db7800c08d 100644 --- a/atom/browser/api/lib/protocol.coffee +++ b/atom/browser/api/lib/protocol.coffee @@ -30,4 +30,8 @@ protocol.RequestFileJob = class RequestFileJob constructor: (@path) -> +protocol.RequestErrorJob = +class RequestErrorJob + constructor: (@error) -> + module.exports = protocol diff --git a/atom/browser/net/adapter_request_job.cc b/atom/browser/net/adapter_request_job.cc index 86c82d7836ce..8b562bcbf248 100644 --- a/atom/browser/net/adapter_request_job.cc +++ b/atom/browser/net/adapter_request_job.cc @@ -5,10 +5,10 @@ #include "atom/browser/net/adapter_request_job.h" #include "base/threading/sequenced_worker_pool.h" +#include "atom/browser/net/url_request_buffer_job.h" #include "atom/browser/net/url_request_string_job.h" #include "atom/browser/net/asar/url_request_asar_job.h" #include "atom/common/asar/asar_util.h" -#include "atom/browser/net/url_request_buffer_job.h" #include "content/public/browser/browser_thread.h" #include "net/base/net_errors.h" #include "net/url_request/url_request_error_job.h" diff --git a/docs/api/protocol.md b/docs/api/protocol.md index e554dbf5ebaa..bcc3352751f5 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -82,4 +82,24 @@ Create a request job which sends a string as response. * `encoding` String - Default is `UTF-8` * `data` Buffer -Create a request job which accepts a buffer and sends a string as response. +Create a request job which sends a buffer as response. + +## Class: protocol.RequestErrorJob(code) + +* `code` Integer + +Create a request job which sets appropriate network error message to console. +Code should be in the following range. + +* Ranges: + * 0- 99 System related errors + * 100-199 Connection related errors + * 200-299 Certificate errors + * 300-399 HTTP errors + * 400-499 Cache errors + * 500-599 ? + * 600-699 FTP errors + * 700-799 Certificate manager errors + * 800-899 DNS resolver errors + +Check the [network error list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h) for code and message relations. diff --git a/spec/api-protocol-spec.coffee b/spec/api-protocol-spec.coffee index 0b6c62c02754..69506156089f 100644 --- a/spec/api-protocol-spec.coffee +++ b/spec/api-protocol-spec.coffee @@ -58,6 +58,21 @@ describe 'protocol module', -> assert false, 'Got error: ' + errorType + ' ' + error protocol.unregisterProtocol 'atom-string-job' + it 'returns RequestErrorJob should send error', (done) -> + data = 'valar morghulis' + job = new protocol.RequestErrorJob(-6) + handler = remote.createFunctionWithReturnValue job + protocol.registerProtocol 'atom-error-job', handler + + $.ajax + url: 'atom-error-job://fake-host' + success: (response) -> + assert false, 'should not reach here' + error: (xhr, errorType, error) -> + assert errorType, 'error' + protocol.unregisterProtocol 'atom-error-job' + done() + it 'returns RequestBufferJob should send buffer', (done) -> data = new Buffer("hello") job = new protocol.RequestBufferJob(data: data) From 24bcd3b21e71cbc8d5eb7507271297478af6b4b2 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 11 May 2015 10:24:44 +0530 Subject: [PATCH 143/155] provide default error message --- atom/browser/api/atom_api_protocol.cc | 3 ++- docs/api/protocol.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 617a098adbc3..8a7e0ae6840a 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -106,7 +106,8 @@ class CustomProtocolRequestJob : public AdapterRequestJob { GetWeakPtr(), path)); return; } else if (name == "RequestErrorJob") { - int error; + // Default value net::ERR_NOT_IMPLEMENTED + int error = -11; dict.Get("error", &error); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, diff --git a/docs/api/protocol.md b/docs/api/protocol.md index bcc3352751f5..65554e052105 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -89,7 +89,8 @@ Create a request job which sends a buffer as response. * `code` Integer Create a request job which sets appropriate network error message to console. -Code should be in the following range. +Default message is `net::ERR_NOT_IMPLEMENTED`. Code should be in the following +range. * Ranges: * 0- 99 System related errors From fc2bc20572815b3953680bbed672a1c83a883903 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 13:51:52 +0800 Subject: [PATCH 144/155] Determine wheter a navigation entry is in-page --- atom/browser/api/atom_api_web_contents.cc | 5 +++-- .../api/lib/navigation-controller.coffee | 21 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c998deca5e30..2fedd10cf4aa 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -348,8 +348,9 @@ void WebContents::WebContentsDestroyed() { } void WebContents::NavigationEntryCommitted( - const content::LoadCommittedDetails& load_details) { - Emit("navigation-entry-commited", load_details.entry->GetURL()); + const content::LoadCommittedDetails& details) { + Emit("navigation-entry-commited", details.entry->GetURL(), + details.is_in_page, details.did_replace_entry); } void WebContents::DidAttach(int guest_proxy_routing_id) { diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 75f9dd2097ca..28404b1214f2 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -9,16 +9,21 @@ class NavigationController @currentIndex = -1 @pendingIndex = -1 - @webContents.on 'navigation-entry-commited', (event, url) => + @webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) => + if replaceEntry + @history[@currentIndex] = {url, inPage} + return + if @pendingIndex is -1 # Normal navigation. @history = @history.slice 0, @currentIndex + 1 # Clear history. - if @history[@currentIndex] isnt url + currentEntry = @history[@currentIndex] + if currentEntry?.url isnt url or currentEntry?.inPage isnt inPage @currentIndex++ - @history.push url + @history.push {url, inPage} else # Go to index. @currentIndex = @pendingIndex @pendingIndex = -1 - @history[@currentIndex] = url + @history[@currentIndex] = {url, inPage} loadUrl: (url, options={}) -> @pendingIndex = -1 @@ -28,7 +33,7 @@ class NavigationController if @currentIndex is -1 '' else - @history[@currentIndex] + @history[@currentIndex].url stop: -> @pendingIndex = -1 @@ -57,17 +62,17 @@ class NavigationController goBack: -> return unless @canGoBack() @pendingIndex = @getActiveIndex() - 1 - @webContents._loadUrl @history[@pendingIndex], {} + @webContents._loadUrl @history[@pendingIndex].url, {} goForward: -> return unless @canGoForward() @pendingIndex = @getActiveIndex() + 1 - @webContents._loadUrl @history[@pendingIndex], {} + @webContents._loadUrl @history[@pendingIndex].url, {} goToIndex: (index) -> return unless @canGoToIndex index @pendingIndex = index - @webContents._loadUrl @history[@pendingIndex], {} + @webContents._loadUrl @history[@pendingIndex].url, {} goToOffset: (offset) -> return unless @canGoToOffset offset From 4c109256946e32ce21301ecfe8be7065bc270d90 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 14:05:20 +0800 Subject: [PATCH 145/155] Add remote.getCurrentWebContents API --- atom/browser/lib/rpc-server.coffee | 3 +++ atom/renderer/api/lib/remote.coffee | 9 ++++++++- docs/api/remote.md | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 1703f1e24751..48d00e9bd23b 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -107,6 +107,9 @@ ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, guestInstanceId) -> catch e event.returnValue = errorToMeta e +ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) -> + event.returnValue = valueToMeta event.sender, event.sender + ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) -> try args = unwrapArgs event.sender, args diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 673a01cb20b5..569678476587 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -110,13 +110,20 @@ exports.require = (module) -> meta = ipc.sendSync 'ATOM_BROWSER_REQUIRE', module moduleCache[module] = metaToValue meta -# Get current window object. +# Get current BrowserWindow object. windowCache = null exports.getCurrentWindow = -> return windowCache if windowCache? meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WINDOW', process.guestInstanceId windowCache = metaToValue meta +# Get current WebContents object. +webContentsCache = null +exports.getCurrentWebContents = -> + return webContentsCache if webContentsCache? + meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WEB_CONTENTS' + webContentsCache = metaToValue meta + # Get a global object in browser. exports.getGlobal = (name) -> meta = ipc.sendSync 'ATOM_BROWSER_GLOBAL', name diff --git a/docs/api/remote.md b/docs/api/remote.md index 77e76ea57f01..89bbc1f0606f 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -138,6 +138,10 @@ Returns the object returned by `require(module)` in the main process. Returns the [BrowserWindow](browser-window.md) object which this web page belongs to. +## remote.getCurrentWebContent() + +Returns the WebContents object of this web page. + ## remote.getGlobal(name) * `name` String From 4d1cd7e15f6f0ad780d04c4a5a0b34baa1a3df9a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 14:29:44 +0800 Subject: [PATCH 146/155] Redirect history operations in renderer to browser --- atom/renderer/lib/override.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index 6e02c2eb8222..3ac5177e809d 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -74,6 +74,12 @@ window.confirm = (message, title='') -> window.prompt = -> throw new Error('prompt() is and will not be supported.') +# Forward history operations to browser. +window.history.back = -> + remote.getCurrentWebContents().goBack() +window.history.forward = -> + remote.getCurrentWebContents().goForward() + window.opener = postMessage: (message, targetOrigin='*') -> ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', message, targetOrigin From 40631edb70abfe1803a8e912dfc0c27fcaed8ea4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 14:30:26 +0800 Subject: [PATCH 147/155] Use Chrome's navigation controller for in-page navigations --- atom/browser/api/atom_api_web_contents.cc | 10 +++++++ atom/browser/api/atom_api_web_contents.h | 3 ++ .../api/lib/navigation-controller.coffee | 28 ++++++++++++------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 2fedd10cf4aa..558b26b9d110 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -443,6 +443,14 @@ void WebContents::ReloadIgnoringCache() { web_contents()->GetController().ReloadIgnoringCache(false); } +void WebContents::GoBack() { + web_contents()->GetController().GoBack(); +} + +void WebContents::GoForward() { + web_contents()->GetController().GoForward(); +} + int WebContents::GetRoutingID() const { return web_contents()->GetRoutingID(); } @@ -611,6 +619,8 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("_stop", &WebContents::Stop) .SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache) + .SetMethod("_goBack", &WebContents::GoBack) + .SetMethod("_goForward", &WebContents::GoForward) .SetMethod("getRoutingId", &WebContents::GetRoutingID) .SetMethod("getProcessId", &WebContents::GetProcessID) .SetMethod("isCrashed", &WebContents::IsCrashed) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index cc2fd30c832f..aa0ee8d6f683 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -53,6 +53,9 @@ class WebContents : public mate::EventEmitter, bool IsWaitingForResponse() const; void Stop(); void ReloadIgnoringCache(); + void GoBack(); + void GoForward(); + void GoToIndex(); int GetRoutingID() const; int GetProcessID() const; bool IsCrashed() const; diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 28404b1214f2..675f34e85f85 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -10,20 +10,20 @@ class NavigationController @pendingIndex = -1 @webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) => - if replaceEntry - @history[@currentIndex] = {url, inPage} - return + console.log 'navigation-entry-commited', url, inPage, replaceEntry - if @pendingIndex is -1 # Normal navigation. + if @pendingIndex >= 0 # Go to index. + @currentIndex = @pendingIndex + @pendingIndex = -1 + @history[@currentIndex] = {url, inPage} + else if replaceEntry # Non-user initialized navigation. + @history[@currentIndex] = {url, inPage} + else # Normal navigation. @history = @history.slice 0, @currentIndex + 1 # Clear history. currentEntry = @history[@currentIndex] if currentEntry?.url isnt url or currentEntry?.inPage isnt inPage @currentIndex++ @history.push {url, inPage} - else # Go to index. - @currentIndex = @pendingIndex - @pendingIndex = -1 - @history[@currentIndex] = {url, inPage} loadUrl: (url, options={}) -> @pendingIndex = -1 @@ -62,12 +62,20 @@ class NavigationController goBack: -> return unless @canGoBack() @pendingIndex = @getActiveIndex() - 1 - @webContents._loadUrl @history[@pendingIndex].url, {} + pendingEntry = @history[@pendingIndex] + if pendingEntry.inPage + @webContents._goBack() + else + @webContents._loadUrl pendingEntry.url, {} goForward: -> return unless @canGoForward() @pendingIndex = @getActiveIndex() + 1 - @webContents._loadUrl @history[@pendingIndex].url, {} + pendingEntry = @history[@pendingIndex] + if pendingEntry.inPage + @webContents._goForward() + else + @webContents._loadUrl pendingEntry.url, {} goToIndex: (index) -> return unless @canGoToIndex index From d1545a64aeffcbd7ae4f207d72ea4fb29b3840f6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 14:40:40 +0800 Subject: [PATCH 148/155] Don't force restart renderer process for in-page navigation --- atom/browser/api/atom_api_web_contents.cc | 3 +++ atom/browser/atom_browser_client.cc | 13 +++++++++++++ atom/browser/atom_browser_client.h | 3 +++ 3 files changed, 19 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 558b26b9d110..ddb05cfdfeaa 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -6,6 +6,7 @@ #include +#include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_javascript_dialog_manager.h" #include "atom/browser/native_window.h" @@ -444,10 +445,12 @@ void WebContents::ReloadIgnoringCache() { } void WebContents::GoBack() { + atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce(); web_contents()->GetController().GoBack(); } void WebContents::GoForward() { + atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce(); web_contents()->GetController().GoForward(); } diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 1d00f6bdcf03..fbc09d9fe15f 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -32,6 +32,9 @@ namespace atom { namespace { +// Next navigation should not restart renderer process. +bool g_suppress_renderer_process_restart = false; + struct FindByProcessId { explicit FindByProcessId(int child_process_id) : child_process_id_(child_process_id) { @@ -51,6 +54,11 @@ struct FindByProcessId { } // namespace +// static +void AtomBrowserClient::SuppressRendererProcessRestartForOnce() { + g_suppress_renderer_process_restart = true; +} + AtomBrowserClient::AtomBrowserClient() : dying_render_process_(nullptr) { } @@ -131,6 +139,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation( content::SiteInstance* current_instance, const GURL& url, content::SiteInstance** new_instance) { + if (g_suppress_renderer_process_restart) { + g_suppress_renderer_process_restart = false; + return; + } + if (current_instance->HasProcess()) dying_render_process_ = current_instance->GetProcess(); diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index cda0bd8e5cfb..cc69a1e12de8 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -18,6 +18,9 @@ class AtomBrowserClient : public brightray::BrowserClient { AtomBrowserClient(); virtual ~AtomBrowserClient(); + // Don't force renderer process to restart for once. + static void SuppressRendererProcessRestartForOnce(); + protected: // content::ContentBrowserClient: void RenderProcessWillLaunch(content::RenderProcessHost* host) override; From 82ffa4d2b10d765e9fecb4030412f4ee051daf10 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 16:03:25 +0800 Subject: [PATCH 149/155] Send history operations as asynchronous messages Sending as sync message will cause weird results for NavigationController --- atom/browser/api/lib/navigation-controller.coffee | 6 ++++++ atom/browser/api/lib/web-contents.coffee | 1 - atom/renderer/lib/override.coffee | 13 +++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 675f34e85f85..9c3159ce407e 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -1,3 +1,9 @@ +ipc = require 'ipc' + +# The history operation in renderer is redirected to browser. +ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) -> + event.sender[method] args... + # JavaScript implementation of Chromium's NavigationController. # Instead of relying on Chromium for history control, we compeletely do history # control on user land, and only rely on WebContents.loadUrl for navigation. diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index e249ccfb808d..eb86c94500ce 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -29,7 +29,6 @@ module.exports.wrap = (webContents) -> # The navigation controller. controller = new NavigationController(webContents) - webContents.controller = controller for name, method of NavigationController.prototype when method instanceof Function do (name, method) -> webContents[name] = -> method.apply controller, arguments diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index 3ac5177e809d..1bc1e612c5c2 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -74,15 +74,16 @@ window.confirm = (message, title='') -> window.prompt = -> throw new Error('prompt() is and will not be supported.') -# Forward history operations to browser. -window.history.back = -> - remote.getCurrentWebContents().goBack() -window.history.forward = -> - remote.getCurrentWebContents().goForward() - +# Simple implementation of postMessage. window.opener = postMessage: (message, targetOrigin='*') -> ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', message, targetOrigin ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (message, targetOrigin) -> window.postMessage message, targetOrigin + +# Forward history operations to browser. +sendHistoryOperation = (args...) -> + ipc.send 'ATOM_SHELL_NAVIGATION_CONTROLLER', args... +window.history.back = -> sendHistoryOperation 'goBack' +window.history.forward = -> sendHistoryOperation 'goForward' From 2bb74973121a0933237bed60eb0c0037e465bff9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 16:37:53 +0800 Subject: [PATCH 150/155] Handle when in-page entries are cleared --- .../api/lib/navigation-controller.coffee | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 9c3159ce407e..82c4ab4da747 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -14,22 +14,28 @@ class NavigationController @history = [] @currentIndex = -1 @pendingIndex = -1 + @inPageIndex = -1 @webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) => - console.log 'navigation-entry-commited', url, inPage, replaceEntry + if @inPageIndex > -1 and not inPage + # Navigated to a new page, clear in-page mark. + @inPageIndex = -1 + else if @inPageIndex is -1 and inPage + # Started in-page navigations. + @inPageIndex = @currentIndex if @pendingIndex >= 0 # Go to index. @currentIndex = @pendingIndex @pendingIndex = -1 - @history[@currentIndex] = {url, inPage} + @history[@currentIndex] = url else if replaceEntry # Non-user initialized navigation. - @history[@currentIndex] = {url, inPage} + @history[@currentIndex] = url else # Normal navigation. @history = @history.slice 0, @currentIndex + 1 # Clear history. currentEntry = @history[@currentIndex] - if currentEntry?.url isnt url or currentEntry?.inPage isnt inPage + if currentEntry?.url isnt url @currentIndex++ - @history.push {url, inPage} + @history.push url loadUrl: (url, options={}) -> @pendingIndex = -1 @@ -39,7 +45,7 @@ class NavigationController if @currentIndex is -1 '' else - @history[@currentIndex].url + @history[@currentIndex] stop: -> @pendingIndex = -1 @@ -68,20 +74,18 @@ class NavigationController goBack: -> return unless @canGoBack() @pendingIndex = @getActiveIndex() - 1 - pendingEntry = @history[@pendingIndex] - if pendingEntry.inPage + if @inPageIndex > -1 and @pendingIndex >= @inPageIndex @webContents._goBack() else - @webContents._loadUrl pendingEntry.url, {} + @webContents._loadUrl @history[@pendingIndex], {} goForward: -> return unless @canGoForward() @pendingIndex = @getActiveIndex() + 1 - pendingEntry = @history[@pendingIndex] - if pendingEntry.inPage + if @inPageIndex > -1 and @pendingIndex >= @inPageIndex @webContents._goForward() else - @webContents._loadUrl pendingEntry.url, {} + @webContents._loadUrl @history[@pendingIndex], {} goToIndex: (index) -> return unless @canGoToIndex index From e817192df3db3b415bf277777625924e6d84d981 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 11 May 2015 16:44:01 +0800 Subject: [PATCH 151/155] Make history.go work --- atom/browser/api/atom_api_web_contents.cc | 6 ++++++ atom/browser/api/atom_api_web_contents.h | 2 +- atom/browser/api/lib/navigation-controller.coffee | 7 ++++++- atom/renderer/lib/override.coffee | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index ddb05cfdfeaa..e228a064f413 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -454,6 +454,11 @@ void WebContents::GoForward() { web_contents()->GetController().GoForward(); } +void WebContents::GoToOffset(int offset) { + atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce(); + web_contents()->GetController().GoToOffset(offset); +} + int WebContents::GetRoutingID() const { return web_contents()->GetRoutingID(); } @@ -624,6 +629,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache) .SetMethod("_goBack", &WebContents::GoBack) .SetMethod("_goForward", &WebContents::GoForward) + .SetMethod("_goToOffset", &WebContents::GoToOffset) .SetMethod("getRoutingId", &WebContents::GetRoutingID) .SetMethod("getProcessId", &WebContents::GetProcessID) .SetMethod("isCrashed", &WebContents::IsCrashed) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index aa0ee8d6f683..e75cfb0267f0 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -55,7 +55,7 @@ class WebContents : public mate::EventEmitter, void ReloadIgnoringCache(); void GoBack(); void GoForward(); - void GoToIndex(); + void GoToOffset(int offset); int GetRoutingID() const; int GetProcessID() const; bool IsCrashed() const; diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 82c4ab4da747..f7945e07bf40 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -94,7 +94,12 @@ class NavigationController goToOffset: (offset) -> return unless @canGoToOffset offset - @goToIndex @currentIndex + offset + pendingIndex = @currentIndex + offset + if @inPageIndex > -1 and pendingIndex >= @inPageIndex + @pendingIndex = pendingIndex + @webContents._goToOffset offset + else + @goToIndex pendingIndex getActiveIndex: -> if @pendingIndex is -1 then @currentIndex else @pendingIndex diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index 1bc1e612c5c2..1ca6e692ba21 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -87,3 +87,4 @@ sendHistoryOperation = (args...) -> ipc.send 'ATOM_SHELL_NAVIGATION_CONTROLLER', args... window.history.back = -> sendHistoryOperation 'goBack' window.history.forward = -> sendHistoryOperation 'goForward' +window.history.go = (offset) -> sendHistoryOperation 'goToOffset', offset From e5d30636c29cde0c4fa9e81f213b1fc008237229 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 12 May 2015 16:54:18 +0800 Subject: [PATCH 152/155] Update libchromiumcontent for linking with msvcrt dll --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index af89a057d389..eb17cc92c4fd 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -7,7 +7,7 @@ import sys BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '07a73a610496e4a1b4f3abc3c2fb0516187ec460' +LIBCHROMIUMCONTENT_COMMIT = '90a5b9c3792645067ad9517e60cf5eb99730e0f9' PLATFORM = { 'cygwin': 'win32', From 613a51f5fb79c33e6cc645088ec9c61613356044 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 12 May 2015 17:00:36 +0800 Subject: [PATCH 153/155] Upgrade brightray to link with msvcrt dll --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index a929d7582927..442d46faa757 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit a929d75829270def615e342c79ea17634e8c5989 +Subproject commit 442d46faa7579156da7501c7256ce232b87aa329 From 3bd54b792080ff7599a319f4ebe8932232d8f24f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 12 May 2015 17:08:27 +0800 Subject: [PATCH 154/155] Ship with vc++ redist files --- atom.gyp | 3 +++ script/create-dist.py | 3 +++ script/update-external-binaries.py | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/atom.gyp b/atom.gyp index 5169fda640e9..8e05a0d007d7 100644 --- a/atom.gyp +++ b/atom.gyp @@ -142,6 +142,9 @@ '<(libchromiumcontent_dir)/snapshot_blob.bin', 'external_binaries/d3dcompiler_47.dll', 'external_binaries/xinput1_3.dll', + 'external_binaries/msvcp120.dll', + 'external_binaries/msvcr120.dll', + 'external_binaries/vccorlib120.dll', ], }, { diff --git a/script/create-dist.py b/script/create-dist.py index 7a5b75b07b7b..6a6fa0d1a34b 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -35,12 +35,15 @@ TARGET_BINARIES = { 'icudtl.dat', 'libEGL.dll', 'libGLESv2.dll', + 'msvcp120.dll', + 'msvcr120.dll', 'node.dll', 'content_resources_200_percent.pak', 'ui_resources_200_percent.pak', 'xinput1_3.dll', 'natives_blob.bin', 'snapshot_blob.bin', + 'vccorlib120.dll', ], 'linux': [ PROJECT_NAME, # 'electron' diff --git a/script/update-external-binaries.py b/script/update-external-binaries.py index 0df5fcc03976..49e73435ab51 100755 --- a/script/update-external-binaries.py +++ b/script/update-external-binaries.py @@ -8,7 +8,7 @@ from lib.config import get_target_arch from lib.util import safe_mkdir, rm_rf, extract_zip, tempdir, download -VERSION = 'v0.6.0' +VERSION = 'v0.7.0' SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) FRAMEWORKS_URL = 'http://github.com/atom/atom-shell-frameworks/releases' \ '/download/' + VERSION @@ -30,6 +30,7 @@ def main(): download_and_unzip('Squirrel') elif sys.platform in ['cygwin', 'win32']: download_and_unzip('directxsdk-' + get_target_arch()) + download_and_unzip('vs2012-crt-' + get_target_arch()) with open(version_file, 'w') as f: f.write(VERSION) From 827741a9c602bc3b811bf56f61322a50ae9e882f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 12 May 2015 17:24:00 +0800 Subject: [PATCH 155/155] Bump v0.26.0 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 4 ++-- vendor/brightray | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 8e05a0d007d7..9ae9a90a122b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.25.3', + 'version%': '0.26.0', 'atom_source_root': 'CFBundleIconFile atom.icns CFBundleVersion - 0.25.3 + 0.26.0 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 6891c1d4c991..2de44863443c 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -50,8 +50,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,25,3,0 - PRODUCTVERSION 0,25,3,0 + FILEVERSION 0,26,0,0 + PRODUCTVERSION 0,26,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.25.3" + VALUE "FileVersion", "0.26.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.25.3" + VALUE "ProductVersion", "0.26.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 4b7d98ea795b..b14baf7ad702 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 25 -#define ATOM_PATCH_VERSION 3 +#define ATOM_MINOR_VERSION 26 +#define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/vendor/brightray b/vendor/brightray index 442d46faa757..a929d7582927 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 442d46faa7579156da7501c7256ce232b87aa329 +Subproject commit a929d75829270def615e342c79ea17634e8c5989