Merge branch 'master' of https://github.com/atom/atom-shell
This commit is contained in:
commit
90fb7bc52d
155 changed files with 4894 additions and 3819 deletions
25
README.md
25
README.md
|
@ -1,18 +1,37 @@
|
||||||
# Electron [](https://travis-ci.org/atom/electron)
|
[](http://electron.atom.io/)
|
||||||
|
|
||||||
|
[](https://travis-ci.org/atom/electron)
|
||||||
|
[](https://david-dm.org/atom/electron#info=devDependencies)
|
||||||
|
|
||||||
|
:zap: *formerly known as Atom Shell* :zap:
|
||||||
|
|
||||||
The Electron framework lets you write cross-platform desktop applications
|
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
|
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
|
[Chromium](http://www.chromium.org) and is used in the [Atom
|
||||||
editor](https://github.com/atom/atom).
|
editor](https://github.com/atom/atom).
|
||||||
|
|
||||||
|
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||||
|
announcements.
|
||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
|
|
||||||
Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can
|
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.
|
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
|
||||||
|
|
||||||
|
# Install as a development dependency
|
||||||
|
npm install electron-prebuilt --save-dev
|
||||||
|
```
|
||||||
|
|
||||||
### Mirrors
|
### Mirrors
|
||||||
|
|
||||||
- [China](https://npm.taobao.org/mirrors/atom-shell)
|
- [China](https://npm.taobao.org/mirrors/electron)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
@ -22,5 +41,5 @@ contains documents describing how to build and contribute to Electron.
|
||||||
|
|
||||||
## Community
|
## 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.
|
as well as an `#atom-shell` channel on Freenode.
|
||||||
|
|
14
atom.gyp
14
atom.gyp
|
@ -4,7 +4,7 @@
|
||||||
'product_name%': 'Electron',
|
'product_name%': 'Electron',
|
||||||
'company_name%': 'GitHub, Inc',
|
'company_name%': 'GitHub, Inc',
|
||||||
'company_abbr%': 'github',
|
'company_abbr%': 'github',
|
||||||
'version%': '0.24.0',
|
'version%': '0.26.0',
|
||||||
|
|
||||||
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
|
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
|
||||||
},
|
},
|
||||||
|
@ -114,15 +114,6 @@
|
||||||
],
|
],
|
||||||
}], # OS!="mac"
|
}], # OS!="mac"
|
||||||
['OS=="win"', {
|
['OS=="win"', {
|
||||||
'msvs_settings': {
|
|
||||||
'VCLinkerTool': {
|
|
||||||
'AdditionalOptions': [
|
|
||||||
# Force linking even though we have duplicate symbols between
|
|
||||||
# BoringSSL and OpenSSL.
|
|
||||||
'/FORCE:MULTIPLE',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'copies': [
|
'copies': [
|
||||||
{
|
{
|
||||||
'variables': {
|
'variables': {
|
||||||
|
@ -151,6 +142,9 @@
|
||||||
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
'<(libchromiumcontent_dir)/snapshot_blob.bin',
|
||||||
'external_binaries/d3dcompiler_47.dll',
|
'external_binaries/d3dcompiler_47.dll',
|
||||||
'external_binaries/xinput1_3.dll',
|
'external_binaries/xinput1_3.dll',
|
||||||
|
'external_binaries/msvcp120.dll',
|
||||||
|
'external_binaries/msvcr120.dll',
|
||||||
|
'external_binaries/vccorlib120.dll',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,9 +8,42 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/common/chrome_version.h"
|
#include "atom/common/chrome_version.h"
|
||||||
|
#include "atom/common/options_switches.h"
|
||||||
|
#include "base/command_line.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 {
|
namespace atom {
|
||||||
|
|
||||||
|
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 = 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);
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
AtomContentClient::AtomContentClient() {
|
AtomContentClient::AtomContentClient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,4 +60,19 @@ void AtomContentClient::AddAdditionalSchemes(
|
||||||
standard_schemes->push_back("chrome-extension");
|
standard_schemes->push_back("chrome-extension");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomContentClient::AddPepperPlugins(
|
||||||
|
std::vector<content::PepperPluginInfo>* plugins) {
|
||||||
|
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
auto flash_path = command_line->GetSwitchValueNative(
|
||||||
|
switches::kPpapiFlashPath);
|
||||||
|
if (flash_path.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto flash_version = command_line->GetSwitchValueASCII(
|
||||||
|
switches::kPpapiFlashVersion);
|
||||||
|
|
||||||
|
plugins->push_back(
|
||||||
|
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -23,6 +23,8 @@ class AtomContentClient : public brightray::ContentClient {
|
||||||
void AddAdditionalSchemes(
|
void AddAdditionalSchemes(
|
||||||
std::vector<std::string>* standard_schemes,
|
std::vector<std::string>* standard_schemes,
|
||||||
std::vector<std::string>* savable_schemes) override;
|
std::vector<std::string>* savable_schemes) override;
|
||||||
|
void AddPepperPlugins(
|
||||||
|
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "atom/browser/atom_browser_client.h"
|
#include "atom/browser/atom_browser_client.h"
|
||||||
#include "atom/common/google_api_key.h"
|
#include "atom/common/google_api_key.h"
|
||||||
#include "atom/renderer/atom_renderer_client.h"
|
#include "atom/renderer/atom_renderer_client.h"
|
||||||
|
#include "atom/utility/atom_content_utility_client.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/debug/stack_trace.h"
|
#include "base/debug/stack_trace.h"
|
||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
|
@ -94,6 +95,11 @@ content::ContentRendererClient*
|
||||||
return renderer_client_.get();
|
return renderer_client_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
|
||||||
|
utility_client_.reset(new AtomContentUtilityClient);
|
||||||
|
return utility_client_.get();
|
||||||
|
}
|
||||||
|
|
||||||
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
|
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
|
||||||
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
|
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||||
void PreSandboxStartup() override;
|
void PreSandboxStartup() override;
|
||||||
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
||||||
content::ContentRendererClient* CreateContentRendererClient() override;
|
content::ContentRendererClient* CreateContentRendererClient() override;
|
||||||
|
content::ContentUtilityClient* CreateContentUtilityClient() override;
|
||||||
|
|
||||||
// brightray::MainDelegate:
|
// brightray::MainDelegate:
|
||||||
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
|
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||||
|
@ -35,6 +36,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||||
brightray::ContentClient content_client_;
|
brightray::ContentClient content_client_;
|
||||||
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
||||||
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
||||||
|
scoped_ptr<content::ContentUtilityClient> utility_client_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,19 @@ int NodeMain(int argc, char *argv[]) {
|
||||||
|
|
||||||
JavascriptEnvironment gin_env;
|
JavascriptEnvironment gin_env;
|
||||||
node::Environment* env = node::CreateEnvironment(
|
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.
|
||||||
|
node::node_isolate = gin_env.isolate();
|
||||||
|
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;
|
bool more;
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include <shlobj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_menu.h"
|
#include "atom/browser/api/atom_api_menu.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/browser.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.h"
|
||||||
#include "net/url_request/url_request_context_getter.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"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
using atom::Browser;
|
using atom::Browser;
|
||||||
|
@ -200,6 +208,13 @@ void App::SetDesktopName(const std::string& desktop_name) {
|
||||||
#endif
|
#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(
|
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||||
v8::Isolate* isolate) {
|
v8::Isolate* isolate) {
|
||||||
auto browser = base::Unretained(Browser::Get());
|
auto browser = base::Unretained(Browser::Get());
|
||||||
|
@ -222,7 +237,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||||
.SetMethod("setPath", &App::SetPath)
|
.SetMethod("setPath", &App::SetPath)
|
||||||
.SetMethod("getPath", &App::GetPath)
|
.SetMethod("getPath", &App::GetPath)
|
||||||
.SetMethod("resolveProxy", &App::ResolveProxy)
|
.SetMethod("resolveProxy", &App::ResolveProxy)
|
||||||
.SetMethod("setDesktopName", &App::SetDesktopName);
|
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||||
|
.SetMethod("setAppUserModelId", &App::SetAppUserModelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -61,6 +61,7 @@ class App : public mate::EventEmitter,
|
||||||
|
|
||||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||||
void SetDesktopName(const std::string& desktop_name);
|
void SetDesktopName(const std::string& desktop_name);
|
||||||
|
void SetAppUserModelId(const std::string& app_id);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(App);
|
DISALLOW_COPY_AND_ASSIGN(App);
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,38 +17,24 @@ using content::TracingController;
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Converter<std::set<T> > {
|
|
||||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
|
||||||
const std::set<T>& val) {
|
|
||||||
v8::Handle<v8::Array> result = v8::Array::New(
|
|
||||||
isolate, static_cast<int>(val.size()));
|
|
||||||
typename std::set<T>::const_iterator it;
|
|
||||||
int i;
|
|
||||||
for (i = 0, it = val.begin(); it != val.end(); ++it, ++i)
|
|
||||||
result->Set(i, Converter<T>::ToV8(isolate, *it));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Converter<base::debug::CategoryFilter> {
|
struct Converter<base::trace_event::CategoryFilter> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> val,
|
v8::Handle<v8::Value> val,
|
||||||
base::debug::CategoryFilter* out) {
|
base::trace_event::CategoryFilter* out) {
|
||||||
std::string filter;
|
std::string filter;
|
||||||
if (!ConvertFromV8(isolate, val, &filter))
|
if (!ConvertFromV8(isolate, val, &filter))
|
||||||
return false;
|
return false;
|
||||||
*out = base::debug::CategoryFilter(filter);
|
*out = base::trace_event::CategoryFilter(filter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct Converter<base::debug::TraceOptions> {
|
struct Converter<base::trace_event::TraceOptions> {
|
||||||
static bool FromV8(v8::Isolate* isolate,
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
v8::Handle<v8::Value> val,
|
v8::Handle<v8::Value> val,
|
||||||
base::debug::TraceOptions* out) {
|
base::trace_event::TraceOptions* out) {
|
||||||
std::string options;
|
std::string options;
|
||||||
if (!ConvertFromV8(isolate, val, &options))
|
if (!ConvertFromV8(isolate, val, &options))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
#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.h"
|
||||||
#include "base/power_monitor/power_monitor_device_source.h"
|
#include "base/power_monitor/power_monitor_device_source.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
@ -38,8 +39,14 @@ void PowerMonitor::OnResume() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<PowerMonitor> PowerMonitor::Create(v8::Isolate* isolate) {
|
v8::Handle<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||||
return CreateHandle(isolate, new PowerMonitor);
|
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
|
} // namespace api
|
||||||
|
@ -57,9 +64,8 @@ void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
||||||
|
|
||||||
using atom::api::PowerMonitor;
|
using atom::api::PowerMonitor;
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Handle<PowerMonitor> power_monitor = PowerMonitor::Create(isolate);
|
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.Set("powerMonitor", power_monitor);
|
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace api {
|
||||||
class PowerMonitor : public mate::EventEmitter,
|
class PowerMonitor : public mate::EventEmitter,
|
||||||
public base::PowerObserver {
|
public base::PowerObserver {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<PowerMonitor> Create(v8::Isolate* isolate);
|
static v8::Handle<v8::Value> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PowerMonitor();
|
PowerMonitor();
|
||||||
|
|
|
@ -105,6 +105,15 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||||
base::Bind(&AdapterRequestJob::CreateFileJobAndStart,
|
base::Bind(&AdapterRequestJob::CreateFileJobAndStart,
|
||||||
GetWeakPtr(), path));
|
GetWeakPtr(), path));
|
||||||
return;
|
return;
|
||||||
|
} else if (name == "RequestErrorJob") {
|
||||||
|
// Default value net::ERR_NOT_IMPLEMENTED
|
||||||
|
int error = -11;
|
||||||
|
dict.Get("error", &error);
|
||||||
|
|
||||||
|
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&AdapterRequestJob::CreateErrorJobAndStart,
|
||||||
|
GetWeakPtr(), error));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "atom/browser/api/atom_api_menu.h"
|
#include "atom/browser/api/atom_api_menu.h"
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/ui/tray_icon.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/image_converter.h"
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
#include "native_mate/constructor.h"
|
#include "native_mate/constructor.h"
|
||||||
|
@ -39,8 +40,8 @@ mate::Wrappable* Tray::New(const gfx::Image& image) {
|
||||||
return new Tray(image);
|
return new Tray(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tray::OnClicked() {
|
void Tray::OnClicked(const gfx::Rect& bounds) {
|
||||||
Emit("clicked");
|
Emit("clicked", bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tray::OnDoubleClicked() {
|
void Tray::OnDoubleClicked() {
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Tray : public mate::EventEmitter,
|
||||||
virtual ~Tray();
|
virtual ~Tray();
|
||||||
|
|
||||||
// TrayIconObserver:
|
// TrayIconObserver:
|
||||||
void OnClicked() override;
|
void OnClicked(const gfx::Rect&) override;
|
||||||
void OnDoubleClicked() override;
|
void OnDoubleClicked() override;
|
||||||
void OnBalloonShow() override;
|
void OnBalloonShow() override;
|
||||||
void OnBalloonClicked() override;
|
void OnBalloonClicked() override;
|
||||||
|
|
|
@ -4,17 +4,24 @@
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "atom/browser/atom_browser_client.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
|
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||||
#include "atom/browser/native_window.h"
|
#include "atom/browser/native_window.h"
|
||||||
#include "atom/browser/web_dialog_helper.h"
|
#include "atom/browser/web_dialog_helper.h"
|
||||||
#include "atom/browser/web_view_manager.h"
|
#include "atom/browser/web_view_manager.h"
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/image_converter.h"
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "brightray/browser/inspectable_web_contents.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_details.h"
|
||||||
#include "content/public/browser/navigation_entry.h"
|
#include "content/public/browser/navigation_entry.h"
|
||||||
#include "content/public/browser/render_frame_host.h"
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
@ -22,11 +29,13 @@
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "content/public/browser/render_widget_host_view.h"
|
#include "content/public/browser/render_widget_host_view.h"
|
||||||
#include "content/public/browser/resource_request_details.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/site_instance.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "native_mate/callback.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "vendor/brightray/browser/media/media_stream_devices_controller.h"
|
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
@ -49,6 +58,22 @@ NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
|
||||||
return nullptr;
|
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
|
} // namespace
|
||||||
|
|
||||||
WebContents::WebContents(content::WebContents* web_contents)
|
WebContents::WebContents(content::WebContents* web_contents)
|
||||||
|
@ -136,11 +161,20 @@ content::WebContents* WebContents::OpenURLFromTab(
|
||||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||||
load_url_params.transferred_global_request_id =
|
load_url_params.transferred_global_request_id =
|
||||||
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);
|
web_contents()->GetController().LoadURLWithParams(load_url_params);
|
||||||
return web_contents();
|
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,
|
void WebContents::RunFileChooser(content::WebContents* guest,
|
||||||
const content::FileChooserParams& params) {
|
const content::FileChooserParams& params) {
|
||||||
if (!web_dialog_helper_)
|
if (!web_dialog_helper_)
|
||||||
|
@ -191,6 +225,12 @@ void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||||
Emit("crashed");
|
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,
|
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||||
const GURL& validated_url) {
|
const GURL& validated_url) {
|
||||||
bool is_main_frame = !render_frame_host->GetParent();
|
bool is_main_frame = !render_frame_host->GetParent();
|
||||||
|
@ -253,7 +293,22 @@ void WebContents::DidNavigateMainFrame(
|
||||||
|
|
||||||
void WebContents::TitleWasSet(content::NavigationEntry* entry,
|
void WebContents::TitleWasSet(content::NavigationEntry* entry,
|
||||||
bool explicit_set) {
|
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(
|
||||||
|
const std::vector<content::FaviconURL>& urls) {
|
||||||
|
std::set<GURL> 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-updated", unique_urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||||
|
@ -294,9 +349,9 @@ void WebContents::WebContentsDestroyed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::NavigationEntryCommitted(
|
void WebContents::NavigationEntryCommitted(
|
||||||
const content::LoadCommittedDetails& load_details) {
|
const content::LoadCommittedDetails& details) {
|
||||||
auto entry = web_contents()->GetController().GetLastCommittedEntry();
|
Emit("navigation-entry-commited", details.entry->GetURL(),
|
||||||
entry->SetVirtualURL(load_details.entry->GetOriginalRequestURL());
|
details.is_in_page, details.did_replace_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::DidAttach(int guest_proxy_routing_id) {
|
void WebContents::DidAttach(int guest_proxy_routing_id) {
|
||||||
|
@ -315,12 +370,11 @@ content::WebContents* WebContents::GetOwnerWebContents() const {
|
||||||
return embedder_web_contents_;
|
return embedder_web_contents_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::GuestSizeChanged(const gfx::Size& old_size,
|
void WebContents::GuestSizeChanged(const gfx::Size& new_size) {
|
||||||
const gfx::Size& new_size) {
|
|
||||||
if (!auto_size_enabled_)
|
if (!auto_size_enabled_)
|
||||||
return;
|
return;
|
||||||
|
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
|
||||||
guest_size_ = new_size;
|
guest_size_ = new_size;
|
||||||
GuestSizeChangedDueToAutoSize(old_size, new_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::RegisterDestructionCallback(
|
void WebContents::RegisterDestructionCallback(
|
||||||
|
@ -365,17 +419,11 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||||
blink::WebReferrerPolicyDefault);
|
blink::WebReferrerPolicyDefault);
|
||||||
|
|
||||||
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
||||||
|
params.should_clear_history_list = true;
|
||||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||||
web_contents()->GetController().LoadURLWithParams(params);
|
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 {
|
base::string16 WebContents::GetTitle() const {
|
||||||
return web_contents()->GetTitle();
|
return web_contents()->GetTitle();
|
||||||
}
|
}
|
||||||
|
@ -392,45 +440,22 @@ void WebContents::Stop() {
|
||||||
web_contents()->Stop();
|
web_contents()->Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::Reload(const mate::Dictionary& options) {
|
void WebContents::ReloadIgnoringCache() {
|
||||||
// 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.
|
|
||||||
web_contents()->GetController().ReloadIgnoringCache(false);
|
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() {
|
void WebContents::GoBack() {
|
||||||
|
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||||
web_contents()->GetController().GoBack();
|
web_contents()->GetController().GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::GoForward() {
|
void WebContents::GoForward() {
|
||||||
|
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||||
web_contents()->GetController().GoForward();
|
web_contents()->GetController().GoForward();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::GoToIndex(int index) {
|
|
||||||
web_contents()->GetController().GoToIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContents::GoToOffset(int offset) {
|
void WebContents::GoToOffset(int offset) {
|
||||||
|
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
||||||
web_contents()->GetController().GoToOffset(offset);
|
web_contents()->GetController().GoToOffset(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +496,13 @@ bool WebContents::IsDevToolsOpened() {
|
||||||
return storage_->IsDevToolsViewShowing();
|
return storage_->IsDevToolsViewShowing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::InspectElement(int x, int y) {
|
||||||
|
OpenDevTools();
|
||||||
|
scoped_refptr<content::DevToolsAgentHost> agent(
|
||||||
|
content::DevToolsAgentHost::GetOrCreateFor(storage_->GetWebContents()));
|
||||||
|
agent->InspectElement(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void WebContents::Undo() {
|
void WebContents::Undo() {
|
||||||
web_contents()->Undo();
|
web_contents()->Undo();
|
||||||
}
|
}
|
||||||
|
@ -562,6 +594,27 @@ void WebContents::SetAllowTransparency(bool allow) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::HasServiceWorker(
|
||||||
|
const base::Callback<void(bool)>& callback) {
|
||||||
|
auto context = GetServiceWorkerContext(web_contents());
|
||||||
|
if (!context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||||
|
GURL::EmptyGURL(),
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebContents::UnregisterServiceWorker(
|
||||||
|
const base::Callback<void(bool)>& callback) {
|
||||||
|
auto context = GetServiceWorkerContext(web_contents());
|
||||||
|
if (!context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
v8::Isolate* isolate) {
|
v8::Isolate* isolate) {
|
||||||
if (template_.IsEmpty())
|
if (template_.IsEmpty())
|
||||||
|
@ -569,20 +622,14 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
.SetMethod("destroy", &WebContents::Destroy)
|
.SetMethod("destroy", &WebContents::Destroy)
|
||||||
.SetMethod("isAlive", &WebContents::IsAlive)
|
.SetMethod("isAlive", &WebContents::IsAlive)
|
||||||
.SetMethod("_loadUrl", &WebContents::LoadURL)
|
.SetMethod("_loadUrl", &WebContents::LoadURL)
|
||||||
.SetMethod("getUrl", &WebContents::GetURL)
|
|
||||||
.SetMethod("getTitle", &WebContents::GetTitle)
|
.SetMethod("getTitle", &WebContents::GetTitle)
|
||||||
.SetMethod("isLoading", &WebContents::IsLoading)
|
.SetMethod("isLoading", &WebContents::IsLoading)
|
||||||
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
|
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
|
||||||
.SetMethod("stop", &WebContents::Stop)
|
.SetMethod("_stop", &WebContents::Stop)
|
||||||
.SetMethod("_reload", &WebContents::Reload)
|
|
||||||
.SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache)
|
.SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache)
|
||||||
.SetMethod("canGoBack", &WebContents::CanGoBack)
|
.SetMethod("_goBack", &WebContents::GoBack)
|
||||||
.SetMethod("canGoForward", &WebContents::CanGoForward)
|
.SetMethod("_goForward", &WebContents::GoForward)
|
||||||
.SetMethod("canGoToOffset", &WebContents::CanGoToOffset)
|
.SetMethod("_goToOffset", &WebContents::GoToOffset)
|
||||||
.SetMethod("goBack", &WebContents::GoBack)
|
|
||||||
.SetMethod("goForward", &WebContents::GoForward)
|
|
||||||
.SetMethod("goToIndex", &WebContents::GoToIndex)
|
|
||||||
.SetMethod("goToOffset", &WebContents::GoToOffset)
|
|
||||||
.SetMethod("getRoutingId", &WebContents::GetRoutingID)
|
.SetMethod("getRoutingId", &WebContents::GetRoutingID)
|
||||||
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
||||||
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
||||||
|
@ -592,6 +639,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||||
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
||||||
|
.SetMethod("inspectElement", &WebContents::InspectElement)
|
||||||
.SetMethod("undo", &WebContents::Undo)
|
.SetMethod("undo", &WebContents::Undo)
|
||||||
.SetMethod("redo", &WebContents::Redo)
|
.SetMethod("redo", &WebContents::Redo)
|
||||||
.SetMethod("cut", &WebContents::Cut)
|
.SetMethod("cut", &WebContents::Cut)
|
||||||
|
@ -606,6 +654,9 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
|
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
|
||||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||||
.SetMethod("isGuest", &WebContents::is_guest)
|
.SetMethod("isGuest", &WebContents::is_guest)
|
||||||
|
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||||
|
.SetMethod("unregisterServiceWorker",
|
||||||
|
&WebContents::UnregisterServiceWorker)
|
||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
return mate::ObjectTemplateBuilder(
|
return mate::ObjectTemplateBuilder(
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
#define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
#define ATOM_BROWSER_API_ATOM_API_WEB_CONTENTS_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/event_emitter.h"
|
||||||
#include "brightray/browser/default_web_contents_delegate.h"
|
#include "brightray/browser/default_web_contents_delegate.h"
|
||||||
#include "content/public/browser/browser_plugin_guest_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_delegate.h"
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
#include "ui/gfx/image/image.h"
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
class InspectableWebContents;
|
class InspectableWebContents;
|
||||||
|
@ -24,6 +27,7 @@ class Dictionary;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
class AtomJavaScriptDialogManager;
|
||||||
class WebDialogHelper;
|
class WebDialogHelper;
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
@ -44,19 +48,13 @@ class WebContents : public mate::EventEmitter,
|
||||||
void Destroy();
|
void Destroy();
|
||||||
bool IsAlive() const;
|
bool IsAlive() const;
|
||||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||||
GURL GetURL() const;
|
|
||||||
base::string16 GetTitle() const;
|
base::string16 GetTitle() const;
|
||||||
bool IsLoading() const;
|
bool IsLoading() const;
|
||||||
bool IsWaitingForResponse() const;
|
bool IsWaitingForResponse() const;
|
||||||
void Stop();
|
void Stop();
|
||||||
void Reload(const mate::Dictionary& options);
|
void ReloadIgnoringCache();
|
||||||
void ReloadIgnoringCache(const mate::Dictionary& options);
|
|
||||||
bool CanGoBack() const;
|
|
||||||
bool CanGoForward() const;
|
|
||||||
bool CanGoToOffset(int offset) const;
|
|
||||||
void GoBack();
|
void GoBack();
|
||||||
void GoForward();
|
void GoForward();
|
||||||
void GoToIndex(int index);
|
|
||||||
void GoToOffset(int offset);
|
void GoToOffset(int offset);
|
||||||
int GetRoutingID() const;
|
int GetRoutingID() const;
|
||||||
int GetProcessID() const;
|
int GetProcessID() const;
|
||||||
|
@ -67,6 +65,9 @@ class WebContents : public mate::EventEmitter,
|
||||||
void OpenDevTools();
|
void OpenDevTools();
|
||||||
void CloseDevTools();
|
void CloseDevTools();
|
||||||
bool IsDevToolsOpened();
|
bool IsDevToolsOpened();
|
||||||
|
void InspectElement(int x, int y);
|
||||||
|
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||||
|
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||||
|
|
||||||
// Editing commands.
|
// Editing commands.
|
||||||
void Undo();
|
void Undo();
|
||||||
|
@ -130,6 +131,8 @@ class WebContents : public mate::EventEmitter,
|
||||||
content::WebContents* OpenURLFromTab(
|
content::WebContents* OpenURLFromTab(
|
||||||
content::WebContents* source,
|
content::WebContents* source,
|
||||||
const content::OpenURLParams& params) override;
|
const content::OpenURLParams& params) override;
|
||||||
|
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||||
|
content::WebContents* source) override;
|
||||||
void RunFileChooser(content::WebContents* web_contents,
|
void RunFileChooser(content::WebContents* web_contents,
|
||||||
const content::FileChooserParams& params) override;
|
const content::FileChooserParams& params) override;
|
||||||
void EnumerateDirectory(content::WebContents* web_contents,
|
void EnumerateDirectory(content::WebContents* web_contents,
|
||||||
|
@ -149,6 +152,8 @@ class WebContents : public mate::EventEmitter,
|
||||||
// content::WebContentsObserver:
|
// content::WebContentsObserver:
|
||||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||||
void RenderProcessGone(base::TerminationStatus status) override;
|
void RenderProcessGone(base::TerminationStatus status) override;
|
||||||
|
void DocumentLoadedInFrame(
|
||||||
|
content::RenderFrameHost* render_frame_host) override;
|
||||||
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||||
const GURL& validated_url) override;
|
const GURL& validated_url) override;
|
||||||
void DidFailLoad(content::RenderFrameHost* render_frame_host,
|
void DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||||
|
@ -175,13 +180,14 @@ class WebContents : public mate::EventEmitter,
|
||||||
void NavigationEntryCommitted(
|
void NavigationEntryCommitted(
|
||||||
const content::LoadCommittedDetails& load_details) override;
|
const content::LoadCommittedDetails& load_details) override;
|
||||||
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
|
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
|
||||||
|
void DidUpdateFaviconURL(
|
||||||
|
const std::vector<content::FaviconURL>& urls) override;
|
||||||
|
|
||||||
// content::BrowserPluginGuestDelegate:
|
// content::BrowserPluginGuestDelegate:
|
||||||
void DidAttach(int guest_proxy_routing_id) final;
|
void DidAttach(int guest_proxy_routing_id) final;
|
||||||
void ElementSizeChanged(const gfx::Size& size) final;
|
void ElementSizeChanged(const gfx::Size& size) final;
|
||||||
content::WebContents* GetOwnerWebContents() const final;
|
content::WebContents* GetOwnerWebContents() const final;
|
||||||
void GuestSizeChanged(const gfx::Size& old_size,
|
void GuestSizeChanged(const gfx::Size& new_size) final;
|
||||||
const gfx::Size& new_size) final;
|
|
||||||
void RegisterDestructionCallback(const DestructionCallback& callback) final;
|
void RegisterDestructionCallback(const DestructionCallback& callback) final;
|
||||||
void SetGuestSizer(content::GuestSizer* guest_sizer) final;
|
void SetGuestSizer(content::GuestSizer* guest_sizer) final;
|
||||||
void WillAttach(content::WebContents* embedder_web_contents,
|
void WillAttach(content::WebContents* embedder_web_contents,
|
||||||
|
@ -202,6 +208,7 @@ class WebContents : public mate::EventEmitter,
|
||||||
const gfx::Size& new_size);
|
const gfx::Size& new_size);
|
||||||
|
|
||||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||||
|
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||||
|
|
||||||
// Unique ID for a guest WebContents.
|
// Unique ID for a guest WebContents.
|
||||||
int guest_instance_id_;
|
int guest_instance_id_;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "native_mate/callback.h"
|
#include "native_mate/callback.h"
|
||||||
#include "native_mate/constructor.h"
|
#include "native_mate/constructor.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "ui/gfx/geometry/rect.h"
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
@ -222,6 +223,14 @@ bool Window::IsFullscreen() {
|
||||||
return 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) {
|
void Window::SetSize(int width, int height) {
|
||||||
window_->SetSize(gfx::Size(width, height));
|
window_->SetSize(gfx::Size(width, height));
|
||||||
}
|
}
|
||||||
|
@ -464,6 +473,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("isMinimized", &Window::IsMinimized)
|
.SetMethod("isMinimized", &Window::IsMinimized)
|
||||||
.SetMethod("setFullScreen", &Window::SetFullScreen)
|
.SetMethod("setFullScreen", &Window::SetFullScreen)
|
||||||
.SetMethod("isFullScreen", &Window::IsFullscreen)
|
.SetMethod("isFullScreen", &Window::IsFullscreen)
|
||||||
|
.SetMethod("getBounds", &Window::GetBounds)
|
||||||
|
.SetMethod("setBounds", &Window::SetBounds)
|
||||||
.SetMethod("getSize", &Window::GetSize)
|
.SetMethod("getSize", &Window::GetSize)
|
||||||
.SetMethod("setSize", &Window::SetSize)
|
.SetMethod("setSize", &Window::SetSize)
|
||||||
.SetMethod("getContentSize", &Window::GetContentSize)
|
.SetMethod("getContentSize", &Window::GetContentSize)
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
class GURL;
|
class GURL;
|
||||||
|
|
||||||
|
namespace gfx {
|
||||||
|
class Rect;
|
||||||
|
}
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
class Arguments;
|
class Arguments;
|
||||||
class Dictionary;
|
class Dictionary;
|
||||||
|
@ -85,6 +89,8 @@ class Window : public mate::EventEmitter,
|
||||||
bool IsMinimized();
|
bool IsMinimized();
|
||||||
void SetFullScreen(bool fullscreen);
|
void SetFullScreen(bool fullscreen);
|
||||||
bool IsFullscreen();
|
bool IsFullscreen();
|
||||||
|
void SetBounds(const gfx::Rect& bounds);
|
||||||
|
gfx::Rect GetBounds();
|
||||||
void SetSize(int width, int height);
|
void SetSize(int width, int height);
|
||||||
std::vector<int> GetSize();
|
std::vector<int> GetSize();
|
||||||
void SetContentSize(int width, int height);
|
void SetContentSize(int width, int height);
|
||||||
|
|
107
atom/browser/api/lib/navigation-controller.coffee
Normal file
107
atom/browser/api/lib/navigation-controller.coffee
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
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.
|
||||||
|
# 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
|
||||||
|
@inPageIndex = -1
|
||||||
|
|
||||||
|
@webContents.on 'navigation-entry-commited', (event, 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
|
||||||
|
else if replaceEntry # Non-user initialized navigation.
|
||||||
|
@history[@currentIndex] = url
|
||||||
|
else # Normal navigation.
|
||||||
|
@history = @history.slice 0, @currentIndex + 1 # Clear history.
|
||||||
|
currentEntry = @history[@currentIndex]
|
||||||
|
if currentEntry?.url 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: ->
|
||||||
|
@getActiveIndex() > 0
|
||||||
|
|
||||||
|
canGoForward: ->
|
||||||
|
@getActiveIndex() < @history.length - 1
|
||||||
|
|
||||||
|
canGoToIndex: (index) ->
|
||||||
|
index >=0 and index < @history.length
|
||||||
|
|
||||||
|
canGoToOffset: (offset) ->
|
||||||
|
@canGoToIndex @currentIndex + offset
|
||||||
|
|
||||||
|
goBack: ->
|
||||||
|
return unless @canGoBack()
|
||||||
|
@pendingIndex = @getActiveIndex() - 1
|
||||||
|
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||||
|
@webContents._goBack()
|
||||||
|
else
|
||||||
|
@webContents._loadUrl @history[@pendingIndex], {}
|
||||||
|
|
||||||
|
goForward: ->
|
||||||
|
return unless @canGoForward()
|
||||||
|
@pendingIndex = @getActiveIndex() + 1
|
||||||
|
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
|
||||||
|
@webContents._goForward()
|
||||||
|
else
|
||||||
|
@webContents._loadUrl @history[@pendingIndex], {}
|
||||||
|
|
||||||
|
goToIndex: (index) ->
|
||||||
|
return unless @canGoToIndex index
|
||||||
|
@pendingIndex = index
|
||||||
|
@webContents._loadUrl @history[@pendingIndex].url, {}
|
||||||
|
|
||||||
|
goToOffset: (offset) ->
|
||||||
|
return unless @canGoToOffset 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
|
||||||
|
|
||||||
|
module.exports = NavigationController
|
|
@ -30,4 +30,8 @@ protocol.RequestFileJob =
|
||||||
class RequestFileJob
|
class RequestFileJob
|
||||||
constructor: (@path) ->
|
constructor: (@path) ->
|
||||||
|
|
||||||
|
protocol.RequestErrorJob =
|
||||||
|
class RequestErrorJob
|
||||||
|
constructor: (@error) ->
|
||||||
|
|
||||||
module.exports = protocol
|
module.exports = protocol
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
EventEmitter = require('events').EventEmitter
|
EventEmitter = require('events').EventEmitter
|
||||||
|
NavigationController = require './navigation-controller'
|
||||||
binding = process.atomBinding 'web_contents'
|
binding = process.atomBinding 'web_contents'
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc'
|
||||||
|
|
||||||
|
@ -26,10 +27,11 @@ module.exports.wrap = (webContents) ->
|
||||||
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
|
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
|
||||||
webContents.equal = (other) -> @getId() is other.getId()
|
webContents.equal = (other) -> @getId() is other.getId()
|
||||||
|
|
||||||
# Provide a default parameter for |urlOptions|.
|
# The navigation controller.
|
||||||
webContents.loadUrl = (url, urlOptions={}) -> @_loadUrl url, urlOptions
|
controller = new NavigationController(webContents)
|
||||||
webContents.reload = (urlOptions={}) -> @_reload urlOptions
|
for name, method of NavigationController.prototype when method instanceof Function
|
||||||
webContents.reloadIgnoringCache = (urlOptions={}) -> @_reloadIgnoringCache urlOptions
|
do (name, method) ->
|
||||||
|
webContents[name] = -> method.apply controller, arguments
|
||||||
|
|
||||||
# Translate |disposition| to string for 'new-window' event.
|
# Translate |disposition| to string for 'new-window' event.
|
||||||
webContents.on '-new-window', (args..., disposition) ->
|
webContents.on '-new-window', (args..., disposition) ->
|
||||||
|
|
|
@ -16,19 +16,25 @@
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "chrome/browser/printing/printing_message_filter.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 "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_process_host.h"
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "content/public/browser/resource_dispatcher_host.h"
|
#include "content/public/browser/resource_dispatcher_host.h"
|
||||||
#include "content/public/browser/site_instance.h"
|
#include "content/public/browser/site_instance.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "content/public/common/web_preferences.h"
|
#include "content/public/common/web_preferences.h"
|
||||||
|
#include "ppapi/host/ppapi_host.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Next navigation should not restart renderer process.
|
||||||
|
bool g_suppress_renderer_process_restart = false;
|
||||||
|
|
||||||
struct FindByProcessId {
|
struct FindByProcessId {
|
||||||
explicit FindByProcessId(int child_process_id)
|
explicit FindByProcessId(int child_process_id)
|
||||||
: child_process_id_(child_process_id) {
|
: child_process_id_(child_process_id) {
|
||||||
|
@ -48,8 +54,13 @@ struct FindByProcessId {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||||
|
g_suppress_renderer_process_restart = true;
|
||||||
|
}
|
||||||
|
|
||||||
AtomBrowserClient::AtomBrowserClient()
|
AtomBrowserClient::AtomBrowserClient()
|
||||||
: dying_render_process_(NULL) {
|
: dying_render_process_(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomBrowserClient::~AtomBrowserClient() {
|
AtomBrowserClient::~AtomBrowserClient() {
|
||||||
|
@ -79,7 +90,6 @@ void AtomBrowserClient::ResourceDispatcherHostCreated() {
|
||||||
|
|
||||||
void AtomBrowserClient::OverrideWebkitPrefs(
|
void AtomBrowserClient::OverrideWebkitPrefs(
|
||||||
content::RenderViewHost* render_view_host,
|
content::RenderViewHost* render_view_host,
|
||||||
const GURL& url,
|
|
||||||
content::WebPreferences* prefs) {
|
content::WebPreferences* prefs) {
|
||||||
prefs->javascript_enabled = true;
|
prefs->javascript_enabled = true;
|
||||||
prefs->web_security_enabled = true;
|
prefs->web_security_enabled = true;
|
||||||
|
@ -99,7 +109,9 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||||
prefs->allow_running_insecure_content = false;
|
prefs->allow_running_insecure_content = false;
|
||||||
|
|
||||||
// Turn off web security for devtools.
|
// 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;
|
prefs->web_security_enabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -115,30 +127,39 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||||
NativeWindow* window = NativeWindow::FromRenderView(
|
NativeWindow* window = NativeWindow::FromRenderView(
|
||||||
process->GetID(), render_view_host->GetRoutingID());
|
process->GetID(), render_view_host->GetRoutingID());
|
||||||
if (window)
|
if (window)
|
||||||
window->OverrideWebkitPrefs(url, prefs);
|
window->OverrideWebkitPrefs(prefs);
|
||||||
}
|
|
||||||
|
|
||||||
bool AtomBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
|
|
||||||
content::SiteInstance* site_instance,
|
|
||||||
const GURL& current_url,
|
|
||||||
const GURL& new_url) {
|
|
||||||
if (site_instance->HasProcess())
|
|
||||||
dying_render_process_ = site_instance->GetProcess();
|
|
||||||
|
|
||||||
// Restart renderer process for all navigations, this relies on a patch to
|
|
||||||
// Chromium: http://git.io/_PaNyg.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AtomBrowserClient::GetApplicationLocale() {
|
std::string AtomBrowserClient::GetApplicationLocale() {
|
||||||
return l10n_util::GetApplicationLocale("");
|
return l10n_util::GetApplicationLocale("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
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();
|
||||||
|
|
||||||
|
// Restart renderer process for all navigations.
|
||||||
|
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
|
||||||
|
}
|
||||||
|
|
||||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
base::CommandLine* command_line,
|
base::CommandLine* command_line,
|
||||||
int child_process_id) {
|
int child_process_id) {
|
||||||
|
std::string process_type = command_line->GetSwitchValueASCII("type");
|
||||||
|
if (process_type != "renderer")
|
||||||
|
return;
|
||||||
|
|
||||||
WindowList* list = WindowList::GetInstance();
|
WindowList* list = WindowList::GetInstance();
|
||||||
NativeWindow* window = NULL;
|
NativeWindow* window = nullptr;
|
||||||
|
|
||||||
// Find the owner of this child process.
|
// Find the owner of this child process.
|
||||||
WindowList::const_iterator iter = std::find_if(
|
WindowList::const_iterator iter = std::find_if(
|
||||||
|
@ -149,15 +170,25 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
// If the render process is a newly started one, which means the window still
|
// If the render process is a newly started one, which means the window still
|
||||||
// uses the old going-to-be-swapped render process, then we try to find the
|
// uses the old going-to-be-swapped render process, then we try to find the
|
||||||
// window from the swapped render process.
|
// window from the swapped render process.
|
||||||
if (window == NULL && dying_render_process_ != NULL) {
|
if (!window && dying_render_process_) {
|
||||||
child_process_id = dying_render_process_->GetID();
|
int dying_process_id = dying_render_process_->GetID();
|
||||||
WindowList::const_iterator iter = std::find_if(
|
WindowList::const_iterator iter = std::find_if(
|
||||||
list->begin(), list->end(), FindByProcessId(child_process_id));
|
list->begin(), list->end(), FindByProcessId(dying_process_id));
|
||||||
if (iter != list->end())
|
if (iter != list->end()) {
|
||||||
window = *iter;
|
window = *iter;
|
||||||
|
child_process_id = dying_process_id;
|
||||||
|
} else {
|
||||||
|
// It appears that the dying process doesn't belong to a BrowserWindow,
|
||||||
|
// 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_,
|
||||||
|
child_process);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window != NULL) {
|
if (window) {
|
||||||
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
|
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
|
||||||
} else {
|
} else {
|
||||||
// Append commnad line arguments for guest web view.
|
// Append commnad line arguments for guest web view.
|
||||||
|
@ -179,7 +210,16 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dying_render_process_ = NULL;
|
dying_render_process_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomBrowserClient::DidCreatePpapiPlugin(
|
||||||
|
content::BrowserPpapiHost* browser_host) {
|
||||||
|
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
if (command_line->HasSwitch(switches::kEnablePlugins))
|
||||||
|
browser_host->GetPpapiHost()->AddHostFactoryFilter(
|
||||||
|
scoped_ptr<ppapi::host::HostFactory>(
|
||||||
|
new chrome::ChromeBrowserPepperHostFactory(browser_host)));
|
||||||
}
|
}
|
||||||
|
|
||||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||||
|
|
|
@ -18,6 +18,9 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
||||||
AtomBrowserClient();
|
AtomBrowserClient();
|
||||||
virtual ~AtomBrowserClient();
|
virtual ~AtomBrowserClient();
|
||||||
|
|
||||||
|
// Don't force renderer process to restart for once.
|
||||||
|
static void SuppressRendererProcessRestartForOnce();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// content::ContentBrowserClient:
|
// content::ContentBrowserClient:
|
||||||
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
|
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
|
||||||
|
@ -26,15 +29,16 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
||||||
content::AccessTokenStore* CreateAccessTokenStore() override;
|
content::AccessTokenStore* CreateAccessTokenStore() override;
|
||||||
void ResourceDispatcherHostCreated() override;
|
void ResourceDispatcherHostCreated() override;
|
||||||
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||||
const GURL& url,
|
|
||||||
content::WebPreferences* prefs) override;
|
content::WebPreferences* prefs) override;
|
||||||
bool ShouldSwapBrowsingInstancesForNavigation(
|
|
||||||
content::SiteInstance* site_instance,
|
|
||||||
const GURL& current_url,
|
|
||||||
const GURL& new_url) override;
|
|
||||||
std::string GetApplicationLocale() override;
|
std::string GetApplicationLocale() override;
|
||||||
|
void OverrideSiteInstanceForNavigation(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
content::SiteInstance* current_instance,
|
||||||
|
const GURL& dest_url,
|
||||||
|
content::SiteInstance** new_instance);
|
||||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
||||||
int child_process_id) override;
|
int child_process_id) override;
|
||||||
|
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/javascript_environment.h"
|
#include "atom/browser/javascript_environment.h"
|
||||||
#include "atom/browser/node_debugger.h"
|
|
||||||
#include "atom/common/api/atom_bindings.h"
|
#include "atom/common/api/atom_bindings.h"
|
||||||
#include "atom/common/node_bindings.h"
|
#include "atom/common/node_bindings.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
@ -60,16 +59,9 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||||
|
|
||||||
node_bindings_->Initialize();
|
node_bindings_->Initialize();
|
||||||
|
|
||||||
// Support the "--debug" switch.
|
|
||||||
node_debugger_.reset(new NodeDebugger(js_env_->isolate()));
|
|
||||||
|
|
||||||
// Create the global environment.
|
// Create the global environment.
|
||||||
global_env = node_bindings_->CreateEnvironment(js_env_->context());
|
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.
|
// Add atom-shell extended APIs.
|
||||||
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
|
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ class AtomBindings;
|
||||||
class Browser;
|
class Browser;
|
||||||
class JavascriptEnvironment;
|
class JavascriptEnvironment;
|
||||||
class NodeBindings;
|
class NodeBindings;
|
||||||
class NodeDebugger;
|
|
||||||
|
|
||||||
class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
public:
|
public:
|
||||||
|
@ -46,7 +45,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
scoped_ptr<JavascriptEnvironment> js_env_;
|
scoped_ptr<JavascriptEnvironment> js_env_;
|
||||||
scoped_ptr<NodeBindings> node_bindings_;
|
scoped_ptr<NodeBindings> node_bindings_;
|
||||||
scoped_ptr<AtomBindings> atom_bindings_;
|
scoped_ptr<AtomBindings> atom_bindings_;
|
||||||
scoped_ptr<NodeDebugger> node_debugger_;
|
|
||||||
|
|
||||||
base::Timer gc_timer_;
|
base::Timer gc_timer_;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ void AtomJavaScriptDialogManager::RunBeforeUnloadDialog(
|
||||||
const base::string16& message_text,
|
const base::string16& message_text,
|
||||||
bool is_reload,
|
bool is_reload,
|
||||||
const DialogClosedCallback& callback) {
|
const DialogClosedCallback& callback) {
|
||||||
|
|
||||||
bool prevent_reload = message_text.empty() ||
|
bool prevent_reload = message_text.empty() ||
|
||||||
message_text == base::ASCIIToUTF16("false");
|
message_text == base::ASCIIToUTF16("false");
|
||||||
callback.Run(!prevent_reload, message_text);
|
callback.Run(!prevent_reload, message_text);
|
||||||
|
|
|
@ -112,11 +112,12 @@ app.on('ready', function() {
|
||||||
click: function() { mainWindow.restart(); }
|
click: function() { mainWindow.restart(); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Enter Fullscreen',
|
label: 'Toggle Full Screen',
|
||||||
click: function() { mainWindow.setFullScreen(true); }
|
accelerator: 'Ctrl+Command+F',
|
||||||
|
click: function() { mainWindow.setFullScreen(!mainWindow.isFullScreen()); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Toggle DevTools',
|
label: 'Toggle Developer Tools',
|
||||||
accelerator: 'Alt+Command+I',
|
accelerator: 'Alt+Command+I',
|
||||||
click: function() { mainWindow.toggleDevTools(); }
|
click: function() { mainWindow.toggleDevTools(); }
|
||||||
},
|
},
|
||||||
|
@ -144,6 +145,27 @@ 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') }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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);
|
menu = Menu.buildFromTemplate(template);
|
||||||
|
@ -173,16 +195,38 @@ app.on('ready', function() {
|
||||||
click: function() { mainWindow.restart(); }
|
click: function() { mainWindow.restart(); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '&Enter Fullscreen',
|
label: 'Toggle &Full Screen',
|
||||||
click: function() { mainWindow.setFullScreen(true); }
|
accelerator: 'F11',
|
||||||
|
click: function() { mainWindow.setFullScreen(!mainWindow.isFullScreen()); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '&Toggle DevTools',
|
label: 'Toggle &Developer Tools',
|
||||||
accelerator: 'Alt+Ctrl+I',
|
accelerator: 'Alt+Ctrl+I',
|
||||||
click: function() { mainWindow.toggleDevTools(); }
|
click: function() { mainWindow.toggleDevTools(); }
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
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') }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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);
|
menu = Menu.buildFromTemplate(template);
|
||||||
|
|
|
@ -11,11 +11,14 @@ app.on('window-all-closed', function() {
|
||||||
|
|
||||||
// Parse command line options.
|
// Parse command line options.
|
||||||
var argv = process.argv.slice(1);
|
var argv = process.argv.slice(1);
|
||||||
var option = { file: null, version: null, webdriver: null };
|
var option = { file: null, help: null, version: null, webdriver: null };
|
||||||
for (var i in argv) {
|
for (var i in argv) {
|
||||||
if (argv[i] == '--version' || argv[i] == '-v') {
|
if (argv[i] == '--version' || argv[i] == '-v') {
|
||||||
option.version = true;
|
option.version = true;
|
||||||
break;
|
break;
|
||||||
|
} else if (argv[i] == '--help' || argv[i] == '-h') {
|
||||||
|
option.help = true;
|
||||||
|
break;
|
||||||
} else if (argv[i] == '--test-type=webdriver') {
|
} else if (argv[i] == '--test-type=webdriver') {
|
||||||
option.webdriver = true;
|
option.webdriver = true;
|
||||||
} else if (argv[i][0] == '-') {
|
} else if (argv[i][0] == '-') {
|
||||||
|
@ -58,7 +61,17 @@ if (option.file && !option.webdriver) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (option.version) {
|
} 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 += "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.";
|
||||||
|
console.log(helpMessage);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} else {
|
} else {
|
||||||
require('./default_app.js');
|
require('./default_app.js');
|
||||||
|
|
|
@ -10,12 +10,14 @@ supportedWebViewEvents = [
|
||||||
'did-stop-loading'
|
'did-stop-loading'
|
||||||
'did-get-response-details'
|
'did-get-response-details'
|
||||||
'did-get-redirect-request'
|
'did-get-redirect-request'
|
||||||
|
'dom-ready'
|
||||||
'console-message'
|
'console-message'
|
||||||
'new-window'
|
'new-window'
|
||||||
'close'
|
'close'
|
||||||
'crashed'
|
'crashed'
|
||||||
'destroyed'
|
'destroyed'
|
||||||
'page-title-set'
|
'page-title-set'
|
||||||
|
'page-favicon-updated'
|
||||||
]
|
]
|
||||||
|
|
||||||
nextInstanceId = 0
|
nextInstanceId = 0
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
fs = require 'fs'
|
fs = require 'fs'
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
module = require 'module'
|
|
||||||
util = require 'util'
|
util = require 'util'
|
||||||
|
Module = require 'module'
|
||||||
|
|
||||||
# We modified the original process.argv to let node.js load the atom.js,
|
# We modified the original process.argv to let node.js load the atom.js,
|
||||||
# we need to restore it here.
|
# we need to restore it here.
|
||||||
process.argv.splice 1, 1
|
process.argv.splice 1, 1
|
||||||
|
|
||||||
# Add browser/api/lib to require's search paths,
|
# Add browser/api/lib to module search paths, which contains javascript part of
|
||||||
# which contains javascript part of Atom's built-in libraries.
|
# Electron's built-in libraries.
|
||||||
globalPaths = module.globalPaths
|
globalPaths = Module.globalPaths
|
||||||
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
|
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
|
||||||
|
|
||||||
# Import common settings.
|
# Import common settings.
|
||||||
|
@ -81,6 +81,9 @@ if packageJson.desktopName?
|
||||||
else
|
else
|
||||||
app.setDesktopName "#{app.getName()}.desktop"
|
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.
|
# Set the user path according to application's name.
|
||||||
app.setPath 'userData', path.join(app.getPath('appData'), app.getName())
|
app.setPath 'userData', path.join(app.getPath('appData'), app.getName())
|
||||||
app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
|
app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
|
||||||
|
@ -89,4 +92,4 @@ app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
|
||||||
require './chrome-extension'
|
require './chrome-extension'
|
||||||
|
|
||||||
# Finally load app's main.js and transfer control to C++.
|
# 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
|
||||||
|
|
|
@ -107,6 +107,9 @@ ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, guestInstanceId) ->
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta 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) ->
|
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
|
||||||
try
|
try
|
||||||
args = unwrapArgs event.sender, args
|
args = unwrapArgs event.sender, args
|
||||||
|
|
|
@ -18,6 +18,4 @@
|
||||||
// CrAppControlProtocol:
|
// CrAppControlProtocol:
|
||||||
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
|
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
|
||||||
|
|
||||||
- (IBAction)closeAllWindows:(id)sender;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -36,10 +36,6 @@
|
||||||
andEventID:kAEGetURL];
|
andEventID:kAEGetURL];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)closeAllWindows:(id)sender {
|
|
||||||
atom::Browser::Get()->Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
|
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
|
||||||
withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
|
withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
|
||||||
NSString* url = [
|
NSString* url = [
|
||||||
|
|
|
@ -192,7 +192,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||||
int width = -1, height = -1;
|
int width = -1, height = -1;
|
||||||
options.Get(switches::kWidth, &width);
|
options.Get(switches::kWidth, &width);
|
||||||
options.Get(switches::kHeight, &height);
|
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) {
|
} else if (options.Get(switches::kCenter, ¢er) && center) {
|
||||||
Center();
|
Center();
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,22 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||||
Show();
|
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) {
|
void NativeWindow::SetRepresentedFilename(const std::string& filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,8 +451,7 @@ void NativeWindow::AppendExtraCommandLineSwitches(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::OverrideWebkitPrefs(const GURL& url,
|
void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) {
|
||||||
content::WebPreferences* prefs) {
|
|
||||||
if (web_preferences_.IsEmpty())
|
if (web_preferences_.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -566,6 +581,7 @@ content::WebContents* NativeWindow::OpenURLFromTab(
|
||||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||||
load_url_params.transferred_global_request_id =
|
load_url_params.transferred_global_request_id =
|
||||||
params.transferred_global_request_id;
|
params.transferred_global_request_id;
|
||||||
|
load_url_params.should_clear_history_list = true;
|
||||||
|
|
||||||
source->GetController().LoadURLWithParams(load_url_params);
|
source->GetController().LoadURLWithParams(load_url_params);
|
||||||
return source;
|
return source;
|
||||||
|
@ -646,8 +662,7 @@ void NativeWindow::DeactivateContents(content::WebContents* contents) {
|
||||||
|
|
||||||
void NativeWindow::MoveContents(content::WebContents* source,
|
void NativeWindow::MoveContents(content::WebContents* source,
|
||||||
const gfx::Rect& pos) {
|
const gfx::Rect& pos) {
|
||||||
SetPosition(pos.origin());
|
SetBounds(pos);
|
||||||
SetSize(pos.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::CloseContents(content::WebContents* source) {
|
void NativeWindow::CloseContents(content::WebContents* source) {
|
||||||
|
@ -686,6 +701,20 @@ void NativeWindow::RendererResponsive(content::WebContents* source) {
|
||||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
|
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) {
|
void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
||||||
// Do nothing, we override this method just to avoid compilation error since
|
// Do nothing, we override this method just to avoid compilation error since
|
||||||
// there are two virtual functions named BeforeUnloadFired.
|
// there are two virtual functions named BeforeUnloadFired.
|
||||||
|
|
|
@ -98,7 +98,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||||
|
|
||||||
virtual void Close() = 0;
|
virtual void Close() = 0;
|
||||||
virtual void CloseImmediately() = 0;
|
virtual void CloseImmediately() = 0;
|
||||||
virtual void Move(const gfx::Rect& pos) = 0;
|
|
||||||
virtual void Focus(bool focus) = 0;
|
virtual void Focus(bool focus) = 0;
|
||||||
virtual bool IsFocused() = 0;
|
virtual bool IsFocused() = 0;
|
||||||
virtual void Show() = 0;
|
virtual void Show() = 0;
|
||||||
|
@ -112,9 +111,13 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||||
virtual void Restore() = 0;
|
virtual void Restore() = 0;
|
||||||
virtual bool IsMinimized() = 0;
|
virtual bool IsMinimized() = 0;
|
||||||
virtual void SetFullScreen(bool fullscreen) = 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 void SetBounds(const gfx::Rect& bounds) = 0;
|
||||||
virtual gfx::Size GetSize() = 0;
|
virtual gfx::Rect GetBounds() = 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 void SetContentSize(const gfx::Size& size) = 0;
|
||||||
virtual gfx::Size GetContentSize() = 0;
|
virtual gfx::Size GetContentSize() = 0;
|
||||||
virtual void SetMinimumSize(const gfx::Size& size) = 0;
|
virtual void SetMinimumSize(const gfx::Size& size) = 0;
|
||||||
|
@ -126,8 +129,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||||
virtual void SetAlwaysOnTop(bool top) = 0;
|
virtual void SetAlwaysOnTop(bool top) = 0;
|
||||||
virtual bool IsAlwaysOnTop() = 0;
|
virtual bool IsAlwaysOnTop() = 0;
|
||||||
virtual void Center() = 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 void SetTitle(const std::string& title) = 0;
|
||||||
virtual std::string GetTitle() = 0;
|
virtual std::string GetTitle() = 0;
|
||||||
virtual void FlashFrame(bool flash) = 0;
|
virtual void FlashFrame(bool flash) = 0;
|
||||||
|
@ -192,7 +193,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||||
// Called when renderer process is going to be started.
|
// Called when renderer process is going to be started.
|
||||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
||||||
int child_process_id);
|
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
|
// Public API used by platform-dependent delegates and observers to send UI
|
||||||
// related notifications.
|
// related notifications.
|
||||||
|
@ -273,6 +274,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||||
const content::WebContents* source) const override;
|
const content::WebContents* source) const override;
|
||||||
void RendererUnresponsive(content::WebContents* source) override;
|
void RendererUnresponsive(content::WebContents* source) override;
|
||||||
void RendererResponsive(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.
|
// Implementations of content::WebContentsObserver.
|
||||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||||
|
|
|
@ -30,7 +30,6 @@ class NativeWindowMac : public NativeWindow {
|
||||||
// NativeWindow implementation.
|
// NativeWindow implementation.
|
||||||
void Close() override;
|
void Close() override;
|
||||||
void CloseImmediately() override;
|
void CloseImmediately() override;
|
||||||
void Move(const gfx::Rect& pos) override;
|
|
||||||
void Focus(bool focus) override;
|
void Focus(bool focus) override;
|
||||||
bool IsFocused() override;
|
bool IsFocused() override;
|
||||||
void Show() override;
|
void Show() override;
|
||||||
|
@ -44,9 +43,9 @@ class NativeWindowMac : public NativeWindow {
|
||||||
void Restore() override;
|
void Restore() override;
|
||||||
bool IsMinimized() override;
|
bool IsMinimized() override;
|
||||||
void SetFullScreen(bool fullscreen) override;
|
void SetFullScreen(bool fullscreen) override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() const override;
|
||||||
void SetSize(const gfx::Size& size) override;
|
void SetBounds(const gfx::Rect& bounds) override;
|
||||||
gfx::Size GetSize() override;
|
gfx::Rect GetBounds() override;
|
||||||
void SetContentSize(const gfx::Size& size) override;
|
void SetContentSize(const gfx::Size& size) override;
|
||||||
gfx::Size GetContentSize() override;
|
gfx::Size GetContentSize() override;
|
||||||
void SetMinimumSize(const gfx::Size& size) override;
|
void SetMinimumSize(const gfx::Size& size) override;
|
||||||
|
@ -58,8 +57,6 @@ class NativeWindowMac : public NativeWindow {
|
||||||
void SetAlwaysOnTop(bool top) override;
|
void SetAlwaysOnTop(bool top) override;
|
||||||
bool IsAlwaysOnTop() override;
|
bool IsAlwaysOnTop() override;
|
||||||
void Center() override;
|
void Center() override;
|
||||||
void SetPosition(const gfx::Point& position) override;
|
|
||||||
gfx::Point GetPosition() override;
|
|
||||||
void SetTitle(const std::string& title) override;
|
void SetTitle(const std::string& title) override;
|
||||||
std::string GetTitle() override;
|
std::string GetTitle() override;
|
||||||
void FlashFrame(bool flash) override;
|
void FlashFrame(bool flash) override;
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
#include "base/strings/sys_string_conversions.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/browser_accessibility_state.h"
|
||||||
#include "content/public/browser/native_web_keyboard_event.h"
|
#include "content/public/browser/native_web_keyboard_event.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "content/public/browser/render_widget_host_view.h"
|
#include "content/public/browser/render_widget_host_view.h"
|
||||||
#include "native_mate/dictionary.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;
|
static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||||
|
|
||||||
|
@ -54,10 +54,8 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||||
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
|
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
|
||||||
@private
|
@private
|
||||||
atom::NativeWindowMac* shell_;
|
atom::NativeWindowMac* shell_;
|
||||||
BOOL acceptsFirstMouse_;
|
|
||||||
}
|
}
|
||||||
- (id)initWithShell:(atom::NativeWindowMac*)shell;
|
- (id)initWithShell:(atom::NativeWindowMac*)shell;
|
||||||
- (void)setAcceptsFirstMouse:(BOOL)accept;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation AtomNSWindowDelegate
|
@implementation AtomNSWindowDelegate
|
||||||
|
@ -65,15 +63,10 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||||
- (id)initWithShell:(atom::NativeWindowMac*)shell {
|
- (id)initWithShell:(atom::NativeWindowMac*)shell {
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
shell_ = shell;
|
shell_ = shell;
|
||||||
acceptsFirstMouse_ = NO;
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAcceptsFirstMouse:(BOOL)accept {
|
|
||||||
acceptsFirstMouse_ = accept;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)windowDidBecomeMain:(NSNotification*)notification {
|
- (void)windowDidBecomeMain:(NSNotification*)notification {
|
||||||
content::WebContents* web_contents = shell_->GetWebContents();
|
content::WebContents* web_contents = shell_->GetWebContents();
|
||||||
if (!web_contents)
|
if (!web_contents)
|
||||||
|
@ -151,10 +144,6 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)acceptsFirstMouse:(NSEvent*)event {
|
|
||||||
return acceptsFirstMouse_;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AtomNSWindow : EventProcessingWindow {
|
@interface AtomNSWindow : EventProcessingWindow {
|
||||||
|
@ -162,6 +151,8 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||||
atom::NativeWindowMac* shell_;
|
atom::NativeWindowMac* shell_;
|
||||||
bool enable_larger_than_screen_;
|
bool enable_larger_than_screen_;
|
||||||
}
|
}
|
||||||
|
@property BOOL acceptsFirstMouse;
|
||||||
|
@property BOOL disableAutoHideCursor;
|
||||||
- (void)setShell:(atom::NativeWindowMac*)shell;
|
- (void)setShell:(atom::NativeWindowMac*)shell;
|
||||||
- (void)setEnableLargerThanScreen:(bool)enable;
|
- (void)setEnableLargerThanScreen:(bool)enable;
|
||||||
@end
|
@end
|
||||||
|
@ -184,16 +175,6 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||||
return [super constrainFrameRect:frameRect toScreen:screen];
|
return [super constrainFrameRect:frameRect toScreen:screen];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)reload:(id)sender {
|
|
||||||
content::WebContents* web_contents = shell_->GetWebContents();
|
|
||||||
content::NavigationController::LoadURLParams params(web_contents->GetURL());
|
|
||||||
web_contents->GetController().LoadURLWithParams(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)showDevTools:(id)sender {
|
|
||||||
shell_->OpenDevTools(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)accessibilityAttributeValue:(NSString*)attribute {
|
- (id)accessibilityAttributeValue:(NSString*)attribute {
|
||||||
if (![attribute isEqualToString:@"AXChildren"])
|
if (![attribute isEqualToString:@"AXChildren"])
|
||||||
return [super accessibilityAttributeValue:attribute];
|
return [super accessibilityAttributeValue:attribute];
|
||||||
|
@ -329,11 +310,18 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
||||||
width,
|
width,
|
||||||
height);
|
height);
|
||||||
|
|
||||||
|
bool useStandardWindow = true;
|
||||||
|
options.Get(switches::kStandardWindow, &useStandardWindow);
|
||||||
|
|
||||||
|
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
|
||||||
|
NSMiniaturizableWindowMask | NSResizableWindowMask;
|
||||||
|
if (!useStandardWindow) {
|
||||||
|
styleMask |= NSTexturedBackgroundWindowMask;
|
||||||
|
}
|
||||||
|
|
||||||
window_.reset([[AtomNSWindow alloc]
|
window_.reset([[AtomNSWindow alloc]
|
||||||
initWithContentRect:cocoa_bounds
|
initWithContentRect:cocoa_bounds
|
||||||
styleMask:NSTitledWindowMask | NSClosableWindowMask |
|
styleMask:styleMask
|
||||||
NSMiniaturizableWindowMask | NSResizableWindowMask |
|
|
||||||
NSTexturedBackgroundWindowMask
|
|
||||||
backing:NSBackingStoreBuffered
|
backing:NSBackingStoreBuffered
|
||||||
defer:YES]);
|
defer:YES]);
|
||||||
[window_ setShell:this];
|
[window_ setShell:this];
|
||||||
|
@ -349,6 +337,10 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
||||||
[window_ setBackgroundColor:[NSColor clearColor]];
|
[window_ setBackgroundColor:[NSColor clearColor]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove non-transparent corners, see http://git.io/vfonD.
|
||||||
|
if (!has_frame_)
|
||||||
|
[window_ setOpaque:NO];
|
||||||
|
|
||||||
// We will manage window's lifetime ourselves.
|
// We will manage window's lifetime ourselves.
|
||||||
[window_ setReleasedWhenClosed:NO];
|
[window_ setReleasedWhenClosed:NO];
|
||||||
|
|
||||||
|
@ -361,7 +353,12 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
||||||
// Enable the NSView to accept first mouse event.
|
// Enable the NSView to accept first mouse event.
|
||||||
bool acceptsFirstMouse = false;
|
bool acceptsFirstMouse = false;
|
||||||
options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse);
|
options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse);
|
||||||
[window_delegate_ setAcceptsFirstMouse: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.
|
// Disable fullscreen button when 'fullscreen' is specified to false.
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
|
@ -392,18 +389,6 @@ void NativeWindowMac::CloseImmediately() {
|
||||||
[window_ close];
|
[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) {
|
void NativeWindowMac::Focus(bool focus) {
|
||||||
if (!IsVisible())
|
if (!IsVisible())
|
||||||
return;
|
return;
|
||||||
|
@ -476,22 +461,28 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) {
|
||||||
[window_ toggleFullScreen:nil];
|
[window_ toggleFullScreen:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::IsFullscreen() {
|
bool NativeWindowMac::IsFullscreen() const {
|
||||||
return [window_ styleMask] & NSFullScreenWindowMask;
|
return [window_ styleMask] & NSFullScreenWindowMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetSize(const gfx::Size& size) {
|
void NativeWindowMac::SetBounds(const gfx::Rect& bounds) {
|
||||||
NSRect frame = [window_ frame];
|
NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0,
|
||||||
frame.origin.y -= size.height() - frame.size.height;
|
bounds.width(),
|
||||||
frame.size.width = size.width();
|
bounds.height());
|
||||||
frame.size.height = size.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:frame display:YES];
|
[window_ setFrame:cocoa_bounds display:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Size NativeWindowMac::GetSize() {
|
gfx::Rect NativeWindowMac::GetBounds() {
|
||||||
NSRect frame = [window_ frame];
|
NSRect frame = [window_ frame];
|
||||||
return gfx::Size(frame.size.width, frame.size.height);
|
gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
|
||||||
|
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
||||||
|
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
|
||||||
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetContentSize(const gfx::Size& size) {
|
void NativeWindowMac::SetContentSize(const gfx::Size& size) {
|
||||||
|
@ -564,18 +555,6 @@ void NativeWindowMac::Center() {
|
||||||
[window_ center];
|
[window_ center];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetPosition(const gfx::Point& position) {
|
|
||||||
Move(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowMac::SetTitle(const std::string& title) {
|
void NativeWindowMac::SetTitle(const std::string& title) {
|
||||||
// We don't want the title to show in transparent window.
|
// We don't want the title to show in transparent window.
|
||||||
if (transparent_)
|
if (transparent_)
|
||||||
|
|
|
@ -291,10 +291,6 @@ void NativeWindowViews::CloseImmediately() {
|
||||||
window_->CloseNow();
|
window_->CloseNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::Move(const gfx::Rect& bounds) {
|
|
||||||
window_->SetBounds(bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowViews::Focus(bool focus) {
|
void NativeWindowViews::Focus(bool focus) {
|
||||||
if (focus)
|
if (focus)
|
||||||
window_->Activate();
|
window_->Activate();
|
||||||
|
@ -369,40 +365,41 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeWindowViews::IsFullscreen() {
|
bool NativeWindowViews::IsFullscreen() const {
|
||||||
return window_->IsFullscreen();
|
return window_->IsFullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::SetSize(const gfx::Size& size) {
|
void NativeWindowViews::SetBounds(const gfx::Rect& bounds) {
|
||||||
#if defined(USE_X11)
|
#if defined(USE_X11)
|
||||||
// On Linux the minimum and maximum size should be updated with window size
|
// On Linux the minimum and maximum size should be updated with window size
|
||||||
// when window is not resizable.
|
// when window is not resizable.
|
||||||
if (!resizable_) {
|
if (!resizable_) {
|
||||||
SetMaximumSize(size);
|
SetMaximumSize(bounds.size());
|
||||||
SetMinimumSize(size);
|
SetMinimumSize(bounds.size());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window_->SetSize(size);
|
window_->SetBounds(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Size NativeWindowViews::GetSize() {
|
gfx::Rect NativeWindowViews::GetBounds() {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
if (IsMinimized())
|
if (IsMinimized())
|
||||||
return window_->GetRestoredBounds().size();
|
return window_->GetRestoredBounds();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return window_->GetWindowBoundsInScreen().size();
|
return window_->GetWindowBoundsInScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
|
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
|
||||||
if (!has_frame_) {
|
if (!has_frame_) {
|
||||||
SetSize(size);
|
NativeWindow::SetSize(size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
|
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
|
||||||
SetSize(ContentBoundsToWindowBounds(gfx::Rect(bounds.origin(), size)).size());
|
bounds.set_size(size);
|
||||||
|
SetBounds(ContentBoundsToWindowBounds(bounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Size NativeWindowViews::GetContentSize() {
|
gfx::Size NativeWindowViews::GetContentSize() {
|
||||||
|
@ -492,19 +489,6 @@ void NativeWindowViews::Center() {
|
||||||
window_->CenterWindow(GetSize());
|
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) {
|
void NativeWindowViews::SetTitle(const std::string& title) {
|
||||||
title_ = title;
|
title_ = title;
|
||||||
window_->UpdateWindowTitle();
|
window_->UpdateWindowTitle();
|
||||||
|
|
|
@ -35,7 +35,6 @@ class NativeWindowViews : public NativeWindow,
|
||||||
// NativeWindow:
|
// NativeWindow:
|
||||||
void Close() override;
|
void Close() override;
|
||||||
void CloseImmediately() override;
|
void CloseImmediately() override;
|
||||||
void Move(const gfx::Rect& pos) override;
|
|
||||||
void Focus(bool focus) override;
|
void Focus(bool focus) override;
|
||||||
bool IsFocused() override;
|
bool IsFocused() override;
|
||||||
void Show() override;
|
void Show() override;
|
||||||
|
@ -49,9 +48,9 @@ class NativeWindowViews : public NativeWindow,
|
||||||
void Restore() override;
|
void Restore() override;
|
||||||
bool IsMinimized() override;
|
bool IsMinimized() override;
|
||||||
void SetFullScreen(bool fullscreen) override;
|
void SetFullScreen(bool fullscreen) override;
|
||||||
bool IsFullscreen() override;
|
bool IsFullscreen() const override;
|
||||||
void SetSize(const gfx::Size& size) override;
|
void SetBounds(const gfx::Rect& bounds) override;
|
||||||
gfx::Size GetSize() override;
|
gfx::Rect GetBounds() override;
|
||||||
void SetContentSize(const gfx::Size& size) override;
|
void SetContentSize(const gfx::Size& size) override;
|
||||||
gfx::Size GetContentSize() override;
|
gfx::Size GetContentSize() override;
|
||||||
void SetMinimumSize(const gfx::Size& size) override;
|
void SetMinimumSize(const gfx::Size& size) override;
|
||||||
|
@ -63,8 +62,6 @@ class NativeWindowViews : public NativeWindow,
|
||||||
void SetAlwaysOnTop(bool top) override;
|
void SetAlwaysOnTop(bool top) override;
|
||||||
bool IsAlwaysOnTop() override;
|
bool IsAlwaysOnTop() override;
|
||||||
void Center() override;
|
void Center() override;
|
||||||
void SetPosition(const gfx::Point& position) override;
|
|
||||||
gfx::Point GetPosition() override;
|
|
||||||
void SetTitle(const std::string& title) override;
|
void SetTitle(const std::string& title) override;
|
||||||
std::string GetTitle() override;
|
std::string GetTitle() override;
|
||||||
void FlashFrame(bool flash) override;
|
void FlashFrame(bool flash) override;
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
#include "atom/browser/net/adapter_request_job.h"
|
#include "atom/browser/net/adapter_request_job.h"
|
||||||
|
|
||||||
#include "base/threading/sequenced_worker_pool.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/url_request_string_job.h"
|
||||||
#include "atom/browser/net/asar/url_request_asar_job.h"
|
#include "atom/browser/net/asar/url_request_asar_job.h"
|
||||||
#include "atom/common/asar/asar_util.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 "content/public/browser/browser_thread.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
#include "net/url_request/url_request_error_job.h"
|
#include "net/url_request/url_request_error_job.h"
|
||||||
|
|
|
@ -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 <string>
|
|
||||||
|
|
||||||
#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<const uint16_t*>(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<int>(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<NodeDebugger*>(
|
|
||||||
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<net::StreamListenSocket> 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<size_t>(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
|
|
|
@ -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 <string>
|
|
||||||
|
|
||||||
#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<net::StreamListenSocket> 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<net::StreamListenSocket> server_;
|
|
||||||
scoped_ptr<net::StreamListenSocket> accepted_socket_;
|
|
||||||
|
|
||||||
std::string buffer_;
|
|
||||||
int content_length_;
|
|
||||||
|
|
||||||
base::WeakPtrFactory<NodeDebugger> weak_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(NodeDebugger);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace atom
|
|
||||||
|
|
||||||
#endif // ATOM_BROWSER_NODE_DEBUGGER_H_
|
|
|
@ -17,7 +17,7 @@
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>atom.icns</string>
|
<string>atom.icns</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.24.0</string>
|
<string>0.26.0</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>10.8.0</string>
|
<string>10.8.0</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
|
|
|
@ -50,8 +50,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,24,0,0
|
FILEVERSION 0,26,0,0
|
||||||
PRODUCTVERSION 0,24,0,0
|
PRODUCTVERSION 0,26,0,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -68,12 +68,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "GitHub, Inc."
|
VALUE "CompanyName", "GitHub, Inc."
|
||||||
VALUE "FileDescription", "Electron"
|
VALUE "FileDescription", "Electron"
|
||||||
VALUE "FileVersion", "0.24.0"
|
VALUE "FileVersion", "0.26.0"
|
||||||
VALUE "InternalName", "electron.exe"
|
VALUE "InternalName", "electron.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||||
VALUE "OriginalFilename", "electron.exe"
|
VALUE "OriginalFilename", "electron.exe"
|
||||||
VALUE "ProductName", "Electron"
|
VALUE "ProductName", "Electron"
|
||||||
VALUE "ProductVersion", "0.24.0"
|
VALUE "ProductVersion", "0.26.0"
|
||||||
VALUE "SquirrelAwareVersion", "1"
|
VALUE "SquirrelAwareVersion", "1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -109,8 +109,12 @@ bool StringToAccelerator(const std::string& description,
|
||||||
modifiers |= ui::EF_SHIFT_DOWN;
|
modifiers |= ui::EF_SHIFT_DOWN;
|
||||||
} else if (tokens[i] == "ctrl" || tokens[i] == "control") {
|
} else if (tokens[i] == "ctrl" || tokens[i] == "control") {
|
||||||
modifiers |= ui::EF_CONTROL_DOWN;
|
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") {
|
} else if (tokens[i] == "cmd" || tokens[i] == "command") {
|
||||||
modifiers |= ui::EF_COMMAND_DOWN;
|
modifiers |= ui::EF_COMMAND_DOWN;
|
||||||
|
#endif
|
||||||
} else if (tokens[i] == "commandorcontrol" || tokens[i] == "cmdorctrl") {
|
} else if (tokens[i] == "commandorcontrol" || tokens[i] == "cmdorctrl") {
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
modifiers |= ui::EF_COMMAND_DOWN;
|
modifiers |= ui::EF_COMMAND_DOWN;
|
||||||
|
@ -171,7 +175,7 @@ bool StringToAccelerator(const std::string& description,
|
||||||
} else if (tokens[i].size() > 1 && tokens[i][0] == 'f') {
|
} else if (tokens[i].size() > 1 && tokens[i][0] == 'f') {
|
||||||
// F1 - F24.
|
// F1 - F24.
|
||||||
int n;
|
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::KeyboardCode>(ui::VKEY_F1 + n - 1);
|
key = static_cast<ui::KeyboardCode>(ui::VKEY_F1 + n - 1);
|
||||||
} else {
|
} else {
|
||||||
LOG(WARNING) << tokens[i] << "is not available on keyboard";
|
LOG(WARNING) << tokens[i] << "is not available on keyboard";
|
||||||
|
|
|
@ -26,8 +26,8 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon,
|
||||||
const base::string16& contents) {
|
const base::string16& contents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::NotifyClicked() {
|
void TrayIcon::NotifyClicked(const gfx::Rect& bounds) {
|
||||||
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked());
|
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(bounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::NotifyDoubleClicked() {
|
void TrayIcon::NotifyDoubleClicked() {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "atom/browser/ui/tray_icon_observer.h"
|
#include "atom/browser/ui/tray_icon_observer.h"
|
||||||
#include "base/observer_list.h"
|
#include "base/observer_list.h"
|
||||||
#include "ui/base/models/simple_menu_model.h"
|
#include "ui/base/models/simple_menu_model.h"
|
||||||
|
#include "ui/gfx/geometry/rect.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ class TrayIcon {
|
||||||
|
|
||||||
void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); }
|
void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); }
|
||||||
void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); }
|
void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); }
|
||||||
void NotifyClicked();
|
void NotifyClicked(const gfx::Rect& = gfx::Rect());
|
||||||
void NotifyDoubleClicked();
|
void NotifyDoubleClicked();
|
||||||
void NotifyBalloonShow();
|
void NotifyBalloonShow();
|
||||||
void NotifyBalloonClicked();
|
void NotifyBalloonClicked();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "atom/browser/ui/cocoa/atom_menu_controller.h"
|
#include "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
|
#include "ui/gfx/screen.h"
|
||||||
|
|
||||||
@interface StatusItemController : NSObject {
|
@interface StatusItemController : NSObject {
|
||||||
atom::TrayIconCocoa* trayIcon_; // weak
|
atom::TrayIconCocoa* trayIcon_; // weak
|
||||||
|
@ -25,7 +26,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleClick:(id)sender {
|
- (void)handleClick:(id)sender {
|
||||||
trayIcon_->NotifyClicked();
|
// 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 screens] objectAtIndex:0];
|
||||||
|
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
|
||||||
|
|
||||||
|
trayIcon_->NotifyClicked(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleDoubleClick:(id)sender {
|
- (void)handleDoubleClick:(id)sender {
|
||||||
|
|
|
@ -5,11 +5,15 @@
|
||||||
#ifndef ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_
|
#ifndef ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_
|
||||||
#define ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_
|
#define ATOM_BROWSER_UI_TRAY_ICON_OBSERVER_H_
|
||||||
|
|
||||||
|
namespace gfx {
|
||||||
|
class Rect;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class TrayIconObserver {
|
class TrayIconObserver {
|
||||||
public:
|
public:
|
||||||
virtual void OnClicked() {}
|
virtual void OnClicked(const gfx::Rect&) {}
|
||||||
virtual void OnDoubleClicked() {}
|
virtual void OnDoubleClicked() {}
|
||||||
virtual void OnBalloonShow() {}
|
virtual void OnBalloonShow() {}
|
||||||
virtual void OnBalloonClicked() {}
|
virtual void OnBalloonClicked() {}
|
||||||
|
|
|
@ -10,18 +10,42 @@
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
WebViewManager* GetManagerFromProcess(content::RenderProcessHost* process) {
|
||||||
|
if (!process)
|
||||||
|
return nullptr;
|
||||||
|
auto context = process->GetBrowserContext();
|
||||||
|
if (!context)
|
||||||
|
return nullptr;
|
||||||
|
return static_cast<WebViewManager*>(context->GetGuestManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process,
|
bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process,
|
||||||
WebViewInfo* info) {
|
WebViewInfo* info) {
|
||||||
if (!process)
|
auto manager = GetManagerFromProcess(process);
|
||||||
return false;
|
|
||||||
auto context = process->GetBrowserContext();
|
|
||||||
if (!context)
|
|
||||||
return false;
|
|
||||||
auto manager = context->GetGuestManager();
|
|
||||||
if (!manager)
|
if (!manager)
|
||||||
return false;
|
return false;
|
||||||
return static_cast<WebViewManager*>(manager)->GetInfo(process->GetID(), info);
|
return manager->GetInfo(process->GetID(), info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void WebViewManager::UpdateGuestProcessID(
|
||||||
|
content::RenderProcessHost* old_process,
|
||||||
|
content::RenderProcessHost* new_process) {
|
||||||
|
auto manager = GetManagerFromProcess(old_process);
|
||||||
|
if (manager) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WebViewManager::WebViewManager(content::BrowserContext* context) {
|
WebViewManager::WebViewManager(content::BrowserContext* context) {
|
||||||
|
@ -42,7 +66,8 @@ void WebViewManager::AddGuest(int guest_instance_id,
|
||||||
webview_info_map_[guest_process_id] = info;
|
webview_info_map_[guest_process_id] = info;
|
||||||
|
|
||||||
// Map the element in embedder to guest.
|
// 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;
|
element_instance_id_to_guest_map_[key] = guest_instance_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,9 +101,9 @@ bool WebViewManager::GetInfo(int guest_process_id, WebViewInfo* webview_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
content::WebContents* WebViewManager::GetGuestByInstanceID(
|
content::WebContents* WebViewManager::GetGuestByInstanceID(
|
||||||
content::WebContents* embedder,
|
int owner_process_id,
|
||||||
int element_instance_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))
|
if (!ContainsKey(element_instance_id_to_guest_map_, key))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||||
static bool GetInfoForProcess(content::RenderProcessHost* process,
|
static bool GetInfoForProcess(content::RenderProcessHost* process,
|
||||||
WebViewInfo* info);
|
WebViewInfo* info);
|
||||||
|
|
||||||
|
// Updates the guest process ID.
|
||||||
|
static void UpdateGuestProcessID(content::RenderProcessHost* old_process,
|
||||||
|
content::RenderProcessHost* new_process);
|
||||||
|
|
||||||
explicit WebViewManager(content::BrowserContext* context);
|
explicit WebViewManager(content::BrowserContext* context);
|
||||||
virtual ~WebViewManager();
|
virtual ~WebViewManager();
|
||||||
|
|
||||||
|
@ -50,9 +54,8 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// content::BrowserPluginGuestManager:
|
// content::BrowserPluginGuestManager:
|
||||||
content::WebContents* GetGuestByInstanceID(
|
content::WebContents* GetGuestByInstanceID(int owner_process_id,
|
||||||
content::WebContents* embedder_web_contents,
|
int element_instance_id) override;
|
||||||
int element_instance_id) override;
|
|
||||||
bool ForEachGuest(content::WebContents* embedder,
|
bool ForEachGuest(content::WebContents* embedder,
|
||||||
const GuestCallback& callback) override;
|
const GuestCallback& callback) override;
|
||||||
|
|
||||||
|
@ -65,26 +68,25 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||||
std::map<int, WebContentsWithEmbedder> web_contents_embdder_map_;
|
std::map<int, WebContentsWithEmbedder> web_contents_embdder_map_;
|
||||||
|
|
||||||
struct ElementInstanceKey {
|
struct ElementInstanceKey {
|
||||||
content::WebContents* owner_web_contents;
|
int embedder_process_id;
|
||||||
int element_instance_id;
|
int element_instance_id;
|
||||||
|
|
||||||
ElementInstanceKey(content::WebContents* owner_web_contents,
|
ElementInstanceKey(int embedder_process_id, int element_instance_id)
|
||||||
int element_instance_id)
|
: embedder_process_id(embedder_process_id),
|
||||||
: owner_web_contents(owner_web_contents),
|
|
||||||
element_instance_id(element_instance_id) {}
|
element_instance_id(element_instance_id) {}
|
||||||
|
|
||||||
bool operator<(const ElementInstanceKey& other) const {
|
bool operator<(const ElementInstanceKey& other) const {
|
||||||
if (owner_web_contents != other.owner_web_contents)
|
if (embedder_process_id != other.embedder_process_id)
|
||||||
return owner_web_contents < other.owner_web_contents;
|
return embedder_process_id < other.embedder_process_id;
|
||||||
return element_instance_id < other.element_instance_id;
|
return element_instance_id < other.element_instance_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ElementInstanceKey& other) const {
|
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);
|
(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<ElementInstanceKey, int> element_instance_id_to_guest_map_;
|
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
|
||||||
|
|
||||||
typedef std::map<int, WebViewInfo> WebViewInfoMap;
|
typedef std::map<int, WebViewInfo> WebViewInfoMap;
|
||||||
|
|
|
@ -88,6 +88,13 @@ class Archive : public mate::Wrappable {
|
||||||
return mate::ConvertToV8(isolate, new_path);
|
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.
|
// Free the resources used by archive.
|
||||||
void Destroy() {
|
void Destroy() {
|
||||||
archive_.reset();
|
archive_.reset();
|
||||||
|
@ -102,6 +109,7 @@ class Archive : public mate::Wrappable {
|
||||||
.SetMethod("readdir", &Archive::Readdir)
|
.SetMethod("readdir", &Archive::Readdir)
|
||||||
.SetMethod("realpath", &Archive::Realpath)
|
.SetMethod("realpath", &Archive::Realpath)
|
||||||
.SetMethod("copyFileOut", &Archive::CopyFileOut)
|
.SetMethod("copyFileOut", &Archive::CopyFileOut)
|
||||||
|
.SetMethod("getFd", &Archive::GetFD)
|
||||||
.SetMethod("destroy", &Archive::Destroy);
|
.SetMethod("destroy", &Archive::Destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
#include "atom/common/asar/archive.h"
|
#include "atom/common/asar/archive.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -104,6 +108,7 @@ bool FillFileInfoWithNode(Archive::FileInfo* info,
|
||||||
|
|
||||||
Archive::Archive(const base::FilePath& path)
|
Archive::Archive(const base::FilePath& path)
|
||||||
: path_(path),
|
: path_(path),
|
||||||
|
file_(path_, base::File::FLAG_OPEN | base::File::FLAG_READ),
|
||||||
header_size_(0) {
|
header_size_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,15 +116,14 @@ Archive::~Archive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Archive::Init() {
|
bool Archive::Init() {
|
||||||
base::File file(path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
if (!file_.IsValid())
|
||||||
if (!file.IsValid())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<char> buf;
|
std::vector<char> buf;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
buf.resize(8);
|
buf.resize(8);
|
||||||
len = file.ReadAtCurrentPos(buf.data(), buf.size());
|
len = file_.ReadAtCurrentPos(buf.data(), buf.size());
|
||||||
if (len != static_cast<int>(buf.size())) {
|
if (len != static_cast<int>(buf.size())) {
|
||||||
PLOG(ERROR) << "Failed to read header size from " << path_.value();
|
PLOG(ERROR) << "Failed to read header size from " << path_.value();
|
||||||
return false;
|
return false;
|
||||||
|
@ -132,7 +136,7 @@ bool Archive::Init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.resize(size);
|
buf.resize(size);
|
||||||
len = file.ReadAtCurrentPos(buf.data(), buf.size());
|
len = file_.ReadAtCurrentPos(buf.data(), buf.size());
|
||||||
if (len != static_cast<int>(buf.size())) {
|
if (len != static_cast<int>(buf.size())) {
|
||||||
PLOG(ERROR) << "Failed to read header from " << path_.value();
|
PLOG(ERROR) << "Failed to read header from " << path_.value();
|
||||||
return false;
|
return false;
|
||||||
|
@ -250,7 +254,7 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_ptr<ScopedTemporaryFile> temp_file(new ScopedTemporaryFile);
|
scoped_ptr<ScopedTemporaryFile> temp_file(new ScopedTemporaryFile);
|
||||||
if (!temp_file->InitFromFile(path_, info.offset, info.size))
|
if (!temp_file->InitFromFile(&file_, info.offset, info.size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*out = temp_file->path();
|
*out = temp_file->path();
|
||||||
|
@ -258,4 +262,18 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Archive::GetFD() const {
|
||||||
|
if (!file_.IsValid())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
return
|
||||||
|
_open_osfhandle(reinterpret_cast<intptr_t>(file_.GetPlatformFile()), 0);
|
||||||
|
#elif defined(OS_POSIX)
|
||||||
|
return file_.GetPlatformFile();
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asar
|
} // namespace asar
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/containers/scoped_ptr_hash_map.h"
|
#include "base/containers/scoped_ptr_hash_map.h"
|
||||||
|
#include "base/files/file.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
|
||||||
|
@ -59,11 +60,15 @@ class Archive {
|
||||||
// For unpacked file, this method will return its real path.
|
// For unpacked file, this method will return its real path.
|
||||||
bool CopyFileOut(const base::FilePath& path, base::FilePath* out);
|
bool CopyFileOut(const base::FilePath& path, base::FilePath* out);
|
||||||
|
|
||||||
|
// Returns the file's fd.
|
||||||
|
int GetFD() const;
|
||||||
|
|
||||||
base::FilePath path() const { return path_; }
|
base::FilePath path() const { return path_; }
|
||||||
base::DictionaryValue* header() const { return header_.get(); }
|
base::DictionaryValue* header() const { return header_.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
base::FilePath path_;
|
base::FilePath path_;
|
||||||
|
base::File file_;
|
||||||
uint32 header_size_;
|
uint32 header_size_;
|
||||||
scoped_ptr<base::DictionaryValue> header_;
|
scoped_ptr<base::DictionaryValue> header_;
|
||||||
|
|
||||||
|
|
|
@ -36,17 +36,16 @@ bool ScopedTemporaryFile::Init() {
|
||||||
return base::CreateTemporaryFile(&path_);
|
return base::CreateTemporaryFile(&path_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScopedTemporaryFile::InitFromFile(const base::FilePath& path,
|
bool ScopedTemporaryFile::InitFromFile(base::File* src,
|
||||||
uint64 offset, uint64 size) {
|
uint64 offset, uint64 size) {
|
||||||
|
if (!src->IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!Init())
|
if (!Init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
base::File src(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
|
||||||
if (!src.IsValid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::vector<char> buf(size);
|
std::vector<char> buf(size);
|
||||||
int len = src.Read(offset, buf.data(), buf.size());
|
int len = src->Read(offset, buf.data(), buf.size());
|
||||||
if (len != static_cast<int>(size))
|
if (len != static_cast<int>(size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class File;
|
||||||
|
}
|
||||||
|
|
||||||
namespace asar {
|
namespace asar {
|
||||||
|
|
||||||
// An object representing a temporary file that should be cleaned up when this
|
// An object representing a temporary file that should be cleaned up when this
|
||||||
|
@ -22,7 +26,7 @@ class ScopedTemporaryFile {
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
// Init an temporary file and fill it with content of |path|.
|
// 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_; }
|
base::FilePath path() const { return path_; }
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#define ATOM_VERSION_H
|
#define ATOM_VERSION_H
|
||||||
|
|
||||||
#define ATOM_MAJOR_VERSION 0
|
#define ATOM_MAJOR_VERSION 0
|
||||||
#define ATOM_MINOR_VERSION 24
|
#define ATOM_MINOR_VERSION 26
|
||||||
#define ATOM_PATCH_VERSION 0
|
#define ATOM_PATCH_VERSION 0
|
||||||
|
|
||||||
#define ATOM_VERSION_IS_RELEASE 1
|
#define ATOM_VERSION_IS_RELEASE 1
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||||
#define 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
|
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||||
|
|
||||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||||
|
|
|
@ -53,11 +53,20 @@ asarStatsToFsStats = (stats) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a ENOENT error.
|
# Create a ENOENT error.
|
||||||
createNotFoundError = (asarPath, filePath) ->
|
notFoundError = (asarPath, filePath, callback) ->
|
||||||
error = new Error("ENOENT, #{filePath} not found in #{asarPath}")
|
error = new Error("ENOENT, #{filePath} not found in #{asarPath}")
|
||||||
error.code = "ENOENT"
|
error.code = "ENOENT"
|
||||||
error.errno = -2
|
error.errno = -2
|
||||||
error
|
unless typeof callback is 'function'
|
||||||
|
throw error
|
||||||
|
process.nextTick -> callback error
|
||||||
|
|
||||||
|
# Create invalid archive error.
|
||||||
|
invalidArchiveError = (asarPath, callback) ->
|
||||||
|
error = new Error("Invalid package #{asarPath}")
|
||||||
|
unless typeof callback is 'function'
|
||||||
|
throw error
|
||||||
|
process.nextTick -> callback error
|
||||||
|
|
||||||
# Override APIs that rely on passing file path instead of content to C++.
|
# Override APIs that rely on passing file path instead of content to C++.
|
||||||
overrideAPISync = (module, name, arg = 0) ->
|
overrideAPISync = (module, name, arg = 0) ->
|
||||||
|
@ -68,10 +77,10 @@ overrideAPISync = (module, name, arg = 0) ->
|
||||||
return old.apply this, arguments unless isAsar
|
return old.apply this, arguments unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
throw new Error("Invalid package #{asarPath}") unless archive
|
invalidArchiveError asarPath unless archive
|
||||||
|
|
||||||
newPath = archive.copyFileOut filePath
|
newPath = archive.copyFileOut filePath
|
||||||
throw createNotFoundError(asarPath, filePath) unless newPath
|
notFoundError asarPath, filePath unless newPath
|
||||||
|
|
||||||
arguments[arg] = newPath
|
arguments[arg] = newPath
|
||||||
old.apply this, arguments
|
old.apply this, arguments
|
||||||
|
@ -87,10 +96,10 @@ overrideAPI = (module, name, arg = 0) ->
|
||||||
return overrideAPISync module, name, arg unless typeof callback is 'function'
|
return overrideAPISync module, name, arg unless typeof callback is 'function'
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
return invalidArchiveError asarPath, callback unless archive
|
||||||
|
|
||||||
newPath = archive.copyFileOut filePath
|
newPath = archive.copyFileOut filePath
|
||||||
return callback createNotFoundError(asarPath, filePath) unless newPath
|
return notFoundError asarPath, filePath, callback unless newPath
|
||||||
|
|
||||||
arguments[arg] = newPath
|
arguments[arg] = newPath
|
||||||
old.apply this, arguments
|
old.apply this, arguments
|
||||||
|
@ -103,10 +112,10 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return lstatSync p unless isAsar
|
return lstatSync p unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
throw new Error("Invalid package #{asarPath}") unless archive
|
invalidArchiveError asarPath unless archive
|
||||||
|
|
||||||
stats = archive.stat filePath
|
stats = archive.stat filePath
|
||||||
throw createNotFoundError(asarPath, filePath) unless stats
|
notFoundError asarPath, filePath unless stats
|
||||||
|
|
||||||
asarStatsToFsStats stats
|
asarStatsToFsStats stats
|
||||||
|
|
||||||
|
@ -116,10 +125,10 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return lstat p, callback unless isAsar
|
return lstat p, callback unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
return invalidArchiveError asarPath, callback unless archive
|
||||||
|
|
||||||
stats = getOrCreateArchive(asarPath).stat filePath
|
stats = getOrCreateArchive(asarPath).stat filePath
|
||||||
return callback createNotFoundError(asarPath, filePath) unless stats
|
return notFoundError asarPath, filePath, callback unless stats
|
||||||
|
|
||||||
process.nextTick -> callback null, asarStatsToFsStats stats
|
process.nextTick -> callback null, asarStatsToFsStats stats
|
||||||
|
|
||||||
|
@ -156,10 +165,10 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return realpathSync.apply this, arguments unless isAsar
|
return realpathSync.apply this, arguments unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
throw new Error("Invalid package #{asarPath}") unless archive
|
invalidArchiveError asarPath unless archive
|
||||||
|
|
||||||
real = archive.realpath filePath
|
real = archive.realpath filePath
|
||||||
throw createNotFoundError(asarPath, filePath) if real is false
|
notFoundError asarPath, filePath if real is false
|
||||||
|
|
||||||
path.join realpathSync(asarPath), real
|
path.join realpathSync(asarPath), real
|
||||||
|
|
||||||
|
@ -173,10 +182,11 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
cache = undefined
|
cache = undefined
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
return invalidArchiveError asarPath, callback unless archive
|
||||||
|
|
||||||
real = archive.realpath filePath
|
real = archive.realpath filePath
|
||||||
return callback createNotFoundError(asarPath, filePath) if real is false
|
if real is false
|
||||||
|
return notFoundError asarPath, filePath, callback
|
||||||
|
|
||||||
realpath asarPath, (err, p) ->
|
realpath asarPath, (err, p) ->
|
||||||
return callback err if err
|
return callback err if err
|
||||||
|
@ -188,7 +198,7 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return exists p, callback unless isAsar
|
return exists p, callback unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
return invalidArchiveError asarPath, callback unless archive
|
||||||
|
|
||||||
process.nextTick -> callback archive.stat(filePath) isnt false
|
process.nextTick -> callback archive.stat(filePath) isnt false
|
||||||
|
|
||||||
|
@ -213,32 +223,33 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
options = undefined
|
options = undefined
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
return invalidArchiveError asarPath, callback unless archive
|
||||||
|
|
||||||
info = archive.getFileInfo filePath
|
info = archive.getFileInfo filePath
|
||||||
return callback createNotFoundError(asarPath, filePath) unless info
|
return notFoundError asarPath, filePath, callback unless info
|
||||||
return callback null, new Buffer(0) if info.size is 0
|
|
||||||
|
if info.size is 0
|
||||||
|
return process.nextTick -> callback null, new Buffer(0)
|
||||||
|
|
||||||
if info.unpacked
|
if info.unpacked
|
||||||
realPath = archive.copyFileOut filePath
|
realPath = archive.copyFileOut filePath
|
||||||
return fs.readFile realPath, options, callback
|
return fs.readFile realPath, options, callback
|
||||||
|
|
||||||
if not options
|
if not options
|
||||||
options = encoding: null, flag: 'r'
|
options = encoding: null
|
||||||
else if util.isString options
|
else if util.isString options
|
||||||
options = encoding: options, flag: 'r'
|
options = encoding: options
|
||||||
else if not util.isObject options
|
else if not util.isObject options
|
||||||
throw new TypeError('Bad arguments')
|
throw new TypeError('Bad arguments')
|
||||||
|
|
||||||
flag = options.flag || 'r'
|
|
||||||
encoding = options.encoding
|
encoding = options.encoding
|
||||||
|
|
||||||
buffer = new Buffer(info.size)
|
buffer = new Buffer(info.size)
|
||||||
open archive.path, flag, (error, fd) ->
|
fd = archive.getFd()
|
||||||
return callback error if error
|
return notFoundError asarPath, filePath, callback unless fd >= 0
|
||||||
fs.read fd, buffer, 0, info.size, info.offset, (error) ->
|
|
||||||
fs.close fd, ->
|
fs.read fd, buffer, 0, info.size, info.offset, (error) ->
|
||||||
callback error, if encoding then buffer.toString encoding else buffer
|
callback error, if encoding then buffer.toString encoding else buffer
|
||||||
|
|
||||||
openSync = fs.openSync
|
openSync = fs.openSync
|
||||||
readFileSync = fs.readFileSync
|
readFileSync = fs.readFileSync
|
||||||
|
@ -247,10 +258,10 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return readFileSync.apply this, arguments unless isAsar
|
return readFileSync.apply this, arguments unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
throw new Error("Invalid package #{asarPath}") unless archive
|
invalidArchiveError asarPath unless archive
|
||||||
|
|
||||||
info = archive.getFileInfo filePath
|
info = archive.getFileInfo filePath
|
||||||
throw createNotFoundError(asarPath, filePath) unless info
|
notFoundError asarPath, filePath unless info
|
||||||
return new Buffer(0) if info.size is 0
|
return new Buffer(0) if info.size is 0
|
||||||
|
|
||||||
if info.unpacked
|
if info.unpacked
|
||||||
|
@ -258,23 +269,19 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return fs.readFileSync realPath, options
|
return fs.readFileSync realPath, options
|
||||||
|
|
||||||
if not options
|
if not options
|
||||||
options = encoding: null, flag: 'r'
|
options = encoding: null
|
||||||
else if util.isString options
|
else if util.isString options
|
||||||
options = encoding: options, flag: 'r'
|
options = encoding: options
|
||||||
else if not util.isObject options
|
else if not util.isObject options
|
||||||
throw new TypeError('Bad arguments')
|
throw new TypeError('Bad arguments')
|
||||||
|
|
||||||
flag = options.flag || 'r'
|
|
||||||
encoding = options.encoding
|
encoding = options.encoding
|
||||||
|
|
||||||
buffer = new Buffer(info.size)
|
buffer = new Buffer(info.size)
|
||||||
fd = openSync archive.path, flag
|
fd = archive.getFd()
|
||||||
try
|
notFoundError asarPath, filePath unless fd >= 0
|
||||||
fs.readSync fd, buffer, 0, info.size, info.offset
|
|
||||||
catch e
|
fs.readSync fd, buffer, 0, info.size, info.offset
|
||||||
throw e
|
|
||||||
finally
|
|
||||||
fs.closeSync fd
|
|
||||||
if encoding then buffer.toString encoding else buffer
|
if encoding then buffer.toString encoding else buffer
|
||||||
|
|
||||||
readdir = fs.readdir
|
readdir = fs.readdir
|
||||||
|
@ -283,10 +290,10 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return readdir.apply this, arguments unless isAsar
|
return readdir.apply this, arguments unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
return invalidArchiveError asarPath, callback unless archive
|
||||||
|
|
||||||
files = archive.readdir filePath
|
files = archive.readdir filePath
|
||||||
return callback createNotFoundError(asarPath, filePath) unless files
|
return notFoundError asarPath, filePath, callback unless files
|
||||||
|
|
||||||
process.nextTick -> callback null, files
|
process.nextTick -> callback null, files
|
||||||
|
|
||||||
|
@ -296,10 +303,10 @@ exports.wrapFsWithAsar = (fs) ->
|
||||||
return readdirSync.apply this, arguments unless isAsar
|
return readdirSync.apply this, arguments unless isAsar
|
||||||
|
|
||||||
archive = getOrCreateArchive asarPath
|
archive = getOrCreateArchive asarPath
|
||||||
throw new Error("Invalid package #{asarPath}") unless archive
|
invalidArchiveError asarPath unless archive
|
||||||
|
|
||||||
files = archive.readdir filePath
|
files = archive.readdir filePath
|
||||||
throw createNotFoundError(asarPath, filePath) unless files
|
notFoundError asarPath, filePath unless files
|
||||||
|
|
||||||
files
|
files
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,20 @@ process.atomBinding = (name) ->
|
||||||
catch e
|
catch e
|
||||||
process.binding "atom_common_#{name}" if /No such module/.test e.message
|
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
|
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')
|
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
|
||||||
|
|
||||||
# setImmediate and process.nextTick makes use of uv_check and uv_prepare to
|
# setImmediate and process.nextTick makes use of uv_check and uv_prepare to
|
||||||
|
|
|
@ -128,9 +128,13 @@ void NodeBindings::Initialize() {
|
||||||
node::g_standalone_mode = is_browser_;
|
node::g_standalone_mode = is_browser_;
|
||||||
node::g_upstream_node_mode = false;
|
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.
|
// Init node.
|
||||||
// (we assume it would not node::Init would not modify the parameters under
|
// (we assume node::Init would not modify the parameters under embedded mode).
|
||||||
// embedded mode).
|
|
||||||
node::Init(nullptr, nullptr, nullptr, nullptr);
|
node::Init(nullptr, nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +170,14 @@ node::Environment* NodeBindings::CreateEnvironment(
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeBindings::LoadEnvironment(node::Environment* env) {
|
void NodeBindings::LoadEnvironment(node::Environment* env) {
|
||||||
|
node::node_isolate = env->isolate();
|
||||||
|
if (node::use_debug_agent)
|
||||||
|
node::StartDebug(env, node::debug_wait_connect);
|
||||||
|
|
||||||
node::LoadEnvironment(env);
|
node::LoadEnvironment(env);
|
||||||
|
|
||||||
|
if (node::use_debug_agent)
|
||||||
|
node::EnableDebug(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeBindings::PrepareMessageLoop() {
|
void NodeBindings::PrepareMessageLoop() {
|
||||||
|
|
|
@ -63,6 +63,12 @@ const char kDirectWrite[] = "direct-write";
|
||||||
// Enable plugins.
|
// Enable plugins.
|
||||||
const char kEnablePlugins[] = "enable-plugins";
|
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.
|
// Instancd ID of guest WebContents.
|
||||||
const char kGuestInstanceID[] = "guest-instance-id";
|
const char kGuestInstanceID[] = "guest-instance-id";
|
||||||
|
|
||||||
|
@ -75,6 +81,12 @@ const char kTransparent[] = "transparent";
|
||||||
// Window type hint.
|
// Window type hint.
|
||||||
const char kType[] = "type";
|
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.
|
// Web runtime features.
|
||||||
const char kExperimentalFeatures[] = "experimental-features";
|
const char kExperimentalFeatures[] = "experimental-features";
|
||||||
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
||||||
|
|
|
@ -37,10 +37,14 @@ extern const char kEnableLargerThanScreen[];
|
||||||
extern const char kDarkTheme[];
|
extern const char kDarkTheme[];
|
||||||
extern const char kDirectWrite[];
|
extern const char kDirectWrite[];
|
||||||
extern const char kEnablePlugins[];
|
extern const char kEnablePlugins[];
|
||||||
|
extern const char kPpapiFlashPath[];
|
||||||
|
extern const char kPpapiFlashVersion[];
|
||||||
extern const char kGuestInstanceID[];
|
extern const char kGuestInstanceID[];
|
||||||
extern const char kPreloadScript[];
|
extern const char kPreloadScript[];
|
||||||
extern const char kTransparent[];
|
extern const char kTransparent[];
|
||||||
extern const char kType[];
|
extern const char kType[];
|
||||||
|
extern const char kDisableAutoHideCursor[];
|
||||||
|
extern const char kStandardWindow[];
|
||||||
|
|
||||||
extern const char kExperimentalFeatures[];
|
extern const char kExperimentalFeatures[];
|
||||||
extern const char kExperimentalCanvasFeatures[];
|
extern const char kExperimentalCanvasFeatures[];
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/bind_helpers.h"
|
#include "base/bind_helpers.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/files/file_util.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
#include "base/strings/utf_string_conversions.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) {
|
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) {
|
void OpenExternal(const GURL& url) {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -110,13 +110,20 @@ exports.require = (module) ->
|
||||||
meta = ipc.sendSync 'ATOM_BROWSER_REQUIRE', module
|
meta = ipc.sendSync 'ATOM_BROWSER_REQUIRE', module
|
||||||
moduleCache[module] = metaToValue meta
|
moduleCache[module] = metaToValue meta
|
||||||
|
|
||||||
# Get current window object.
|
# Get current BrowserWindow object.
|
||||||
windowCache = null
|
windowCache = null
|
||||||
exports.getCurrentWindow = ->
|
exports.getCurrentWindow = ->
|
||||||
return windowCache if windowCache?
|
return windowCache if windowCache?
|
||||||
meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WINDOW', process.guestInstanceId
|
meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WINDOW', process.guestInstanceId
|
||||||
windowCache = metaToValue meta
|
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.
|
# Get a global object in browser.
|
||||||
exports.getGlobal = (name) ->
|
exports.getGlobal = (name) ->
|
||||||
meta = ipc.sendSync 'ATOM_BROWSER_GLOBAL', name
|
meta = ipc.sendSync 'ATOM_BROWSER_GLOBAL', name
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "atom/renderer/atom_render_view_observer.h"
|
#include "atom/renderer/atom_render_view_observer.h"
|
||||||
#include "atom/renderer/guest_view_container.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/printing/print_web_view_helper.h"
|
||||||
#include "chrome/renderer/tts_dispatcher.h"
|
#include "chrome/renderer/tts_dispatcher.h"
|
||||||
#include "content/public/common/content_constants.h"
|
#include "content/public/common/content_constants.h"
|
||||||
|
@ -79,6 +80,11 @@ void AtomRendererClient::RenderThreadStarted() {
|
||||||
content::RenderThread::Get()->AddObserver(this);
|
content::RenderThread::Get()->AddObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomRendererClient::RenderFrameCreated(
|
||||||
|
content::RenderFrame* render_frame) {
|
||||||
|
new PepperHelper(render_frame);
|
||||||
|
}
|
||||||
|
|
||||||
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
||||||
new printing::PrintWebViewHelper(render_view);
|
new printing::PrintWebViewHelper(render_view);
|
||||||
new AtomRenderViewObserver(render_view, this);
|
new AtomRenderViewObserver(render_view, this);
|
||||||
|
|
|
@ -34,6 +34,7 @@ class AtomRendererClient : public content::ContentRendererClient,
|
||||||
|
|
||||||
// content::ContentRendererClient:
|
// content::ContentRendererClient:
|
||||||
void RenderThreadStarted() override;
|
void RenderThreadStarted() override;
|
||||||
|
void RenderFrameCreated(content::RenderFrame*) override;
|
||||||
void RenderViewCreated(content::RenderView*) override;
|
void RenderViewCreated(content::RenderView*) override;
|
||||||
blink::WebSpeechSynthesizer* OverrideSpeechSynthesizer(
|
blink::WebSpeechSynthesizer* OverrideSpeechSynthesizer(
|
||||||
blink::WebSpeechSynthesizerClient* client) override;
|
blink::WebSpeechSynthesizerClient* client) override;
|
||||||
|
|
|
@ -103,5 +103,8 @@ if preloadScript
|
||||||
try
|
try
|
||||||
require preloadScript
|
require preloadScript
|
||||||
catch error
|
catch error
|
||||||
throw error unless error.code is 'MODULE_NOT_FOUND'
|
if error.code is 'MODULE_NOT_FOUND'
|
||||||
console.error "Unable to load preload script #{preloadScript}"
|
console.error "Unable to load preload script #{preloadScript}"
|
||||||
|
else
|
||||||
|
console.error(error)
|
||||||
|
console.error(error.stack)
|
||||||
|
|
|
@ -74,9 +74,17 @@ window.confirm = (message, title='') ->
|
||||||
window.prompt = ->
|
window.prompt = ->
|
||||||
throw new Error('prompt() is and will not be supported.')
|
throw new Error('prompt() is and will not be supported.')
|
||||||
|
|
||||||
|
# Simple implementation of postMessage.
|
||||||
window.opener =
|
window.opener =
|
||||||
postMessage: (message, targetOrigin='*') ->
|
postMessage: (message, targetOrigin='*') ->
|
||||||
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_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) ->
|
ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (message, targetOrigin) ->
|
||||||
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'
|
||||||
|
window.history.go = (offset) -> sendHistoryOperation 'goToOffset', offset
|
||||||
|
|
|
@ -12,12 +12,14 @@ WEB_VIEW_EVENTS =
|
||||||
'did-get-response-details': ['status', 'newUrl', 'originalUrl',
|
'did-get-response-details': ['status', 'newUrl', 'originalUrl',
|
||||||
'httpResponseCode', 'requestMethod', 'referrer']
|
'httpResponseCode', 'requestMethod', 'referrer']
|
||||||
'did-get-redirect-request': ['oldUrl', 'newUrl', 'isMainFrame']
|
'did-get-redirect-request': ['oldUrl', 'newUrl', 'isMainFrame']
|
||||||
|
'dom-ready': []
|
||||||
'console-message': ['level', 'message', 'line', 'sourceId']
|
'console-message': ['level', 'message', 'line', 'sourceId']
|
||||||
'new-window': ['url', 'frameName', 'disposition']
|
'new-window': ['url', 'frameName', 'disposition']
|
||||||
'close': []
|
'close': []
|
||||||
'crashed': []
|
'crashed': []
|
||||||
'destroyed': []
|
'destroyed': []
|
||||||
'page-title-set': ['title', 'explicitSet']
|
'page-title-set': ['title', 'explicitSet']
|
||||||
|
'page-favicon-updated': ['favicons']
|
||||||
|
|
||||||
dispatchEvent = (webView, event, args...) ->
|
dispatchEvent = (webView, event, args...) ->
|
||||||
throw new Error("Unkown event #{event}") unless WEB_VIEW_EVENTS[event]?
|
throw new Error("Unkown event #{event}") unless WEB_VIEW_EVENTS[event]?
|
||||||
|
|
|
@ -138,10 +138,7 @@ class SrcAttribute extends WebViewAttribute
|
||||||
setupMutationObserver: ->
|
setupMutationObserver: ->
|
||||||
@observer = new MutationObserver (mutations) =>
|
@observer = new MutationObserver (mutations) =>
|
||||||
for mutation in mutations
|
for mutation in mutations
|
||||||
oldValue = mutation.oldValue
|
@handleMutation mutation.oldValue, @getValue()
|
||||||
newValue = @getValue()
|
|
||||||
return if oldValue isnt newValue
|
|
||||||
@handleMutation oldValue, newValue
|
|
||||||
params =
|
params =
|
||||||
attributes: true,
|
attributes: true,
|
||||||
attributeOldValue: true,
|
attributeOldValue: true,
|
||||||
|
|
|
@ -255,6 +255,7 @@ registerWebViewElement = ->
|
||||||
"openDevTools"
|
"openDevTools"
|
||||||
"closeDevTools"
|
"closeDevTools"
|
||||||
"isDevToolsOpened"
|
"isDevToolsOpened"
|
||||||
|
"inspectElement"
|
||||||
"undo"
|
"undo"
|
||||||
"redo"
|
"redo"
|
||||||
"cut"
|
"cut"
|
||||||
|
|
74
atom/utility/atom_content_utility_client.cc
Normal file
74
atom/utility/atom_content_utility_client.cc
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
int64_t AtomContentUtilityClient::max_ipc_message_size_ =
|
||||||
|
IPC::Channel::kMaximumMessageSize;
|
||||||
|
|
||||||
|
AtomContentUtilityClient::AtomContentUtilityClient()
|
||||||
|
: filter_messages_(false) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
handlers_.push_back(new PrintingHandler());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
57
atom/utility/atom_content_utility_client.h
Normal file
57
atom/utility/atom_content_utility_client.h
Normal file
|
@ -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 <set>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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<UtilityMessageHandler> Handlers;
|
||||||
|
Handlers handlers_;
|
||||||
|
|
||||||
|
// Flag to enable whitelisting.
|
||||||
|
bool filter_messages_;
|
||||||
|
// A list of message_ids to filter.
|
||||||
|
std::set<int> 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_
|
|
@ -58,6 +58,8 @@ void GlobalShortcutListenerWin::OnWndProc(HWND hwnd,
|
||||||
modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0;
|
modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0;
|
||||||
modifiers |= (LOWORD(lparam) & MOD_ALT) ? ui::EF_ALT_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_CONTROL) ? ui::EF_CONTROL_DOWN : 0;
|
||||||
|
modifiers |= (LOWORD(lparam) & MOD_WIN) ? ui::EF_COMMAND_DOWN : 0;
|
||||||
|
|
||||||
ui::Accelerator accelerator(
|
ui::Accelerator accelerator(
|
||||||
ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers);
|
ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers);
|
||||||
|
|
||||||
|
@ -72,6 +74,8 @@ bool GlobalShortcutListenerWin::RegisterAcceleratorImpl(
|
||||||
modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0;
|
modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0;
|
||||||
modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0;
|
modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0;
|
||||||
modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0;
|
modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0;
|
||||||
|
modifiers |= accelerator.IsCmdDown() ? MOD_WIN : 0;
|
||||||
|
|
||||||
static int hotkey_id = 0;
|
static int hotkey_id = 0;
|
||||||
bool success = !!RegisterHotKey(
|
bool success = !!RegisterHotKey(
|
||||||
gfx::SingletonHwnd::GetInstance()->hwnd(),
|
gfx::SingletonHwnd::GetInstance()->hwnd(),
|
||||||
|
|
|
@ -35,6 +35,7 @@ int GetNativeModifiers(const ui::Accelerator& accelerator) {
|
||||||
modifiers |= accelerator.IsShiftDown() ? ShiftMask : 0;
|
modifiers |= accelerator.IsShiftDown() ? ShiftMask : 0;
|
||||||
modifiers |= accelerator.IsCtrlDown() ? ControlMask : 0;
|
modifiers |= accelerator.IsCtrlDown() ? ControlMask : 0;
|
||||||
modifiers |= accelerator.IsAltDown() ? Mod1Mask : 0;
|
modifiers |= accelerator.IsAltDown() ? Mod1Mask : 0;
|
||||||
|
modifiers |= accelerator.IsCmdDown() ? Mod4Mask : 0;
|
||||||
|
|
||||||
return modifiers;
|
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 & ShiftMask) ? ui::EF_SHIFT_DOWN : 0;
|
||||||
modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0;
|
modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0;
|
||||||
modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_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::Accelerator accelerator(
|
||||||
ui::KeyboardCodeFromXKeyEvent(x_event), modifiers);
|
ui::KeyboardCodeFromXKeyEvent(x_event), modifiers);
|
||||||
|
|
495
chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc
Normal file
495
chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc
Normal file
|
@ -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 <queue>
|
||||||
|
|
||||||
|
#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<RefCountedTempDir,
|
||||||
|
BrowserThread::DeleteOnFileThread> {
|
||||||
|
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<BrowserThread::FILE>;
|
||||||
|
friend class base::DeleteHelper<RefCountedTempDir>;
|
||||||
|
~RefCountedTempDir() {}
|
||||||
|
|
||||||
|
base::ScopedTempDir temp_dir_;
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef scoped_ptr<base::File, BrowserThread::DeleteOnFileThread>
|
||||||
|
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<RefCountedTempDir>& 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<RefCountedTempDir> 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<PdfToEmfConverterImpl> converter,
|
||||||
|
const PdfRenderSettings& settings);
|
||||||
|
|
||||||
|
void Start(const scoped_refptr<base::RefCountedMemory>& 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<RefCountedTempDir> temp_dir_;
|
||||||
|
|
||||||
|
// Used to suppress callbacks after PdfToEmfConverterImpl is deleted.
|
||||||
|
base::WeakPtr<PdfToEmfConverterImpl> converter_;
|
||||||
|
PdfRenderSettings settings_;
|
||||||
|
scoped_refptr<base::RefCountedMemory> data_;
|
||||||
|
|
||||||
|
// Document loaded callback.
|
||||||
|
PdfToEmfConverter::StartCallback start_callback_;
|
||||||
|
|
||||||
|
// Process host for IPC.
|
||||||
|
base::WeakPtr<content::UtilityProcessHost> 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<GetPageCallbackData> GetPageCallbacks;
|
||||||
|
GetPageCallbacks get_page_callbacks_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PdfToEmfConverterImpl : public PdfToEmfConverter {
|
||||||
|
public:
|
||||||
|
PdfToEmfConverterImpl();
|
||||||
|
|
||||||
|
virtual ~PdfToEmfConverterImpl();
|
||||||
|
|
||||||
|
virtual void Start(const scoped_refptr<base::RefCountedMemory>& 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<PdfToEmfUtilityProcessHostClient> utility_client_;
|
||||||
|
base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* 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<base::RefCountedMemory>& data,
|
||||||
|
scoped_refptr<RefCountedTempDir>* temp_dir) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
||||||
|
|
||||||
|
ScopedTempFile pdf_file = CreateTempFile(temp_dir);
|
||||||
|
if (!pdf_file ||
|
||||||
|
static_cast<int>(data->size()) !=
|
||||||
|
pdf_file->WriteAtCurrentPos(data->front_as<char>(), 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<char> data(size);
|
||||||
|
if (file_->ReadAtCurrentPos(data.data(), data.size()) != size)
|
||||||
|
return false;
|
||||||
|
return emf->InitFromData(data.data(), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient(
|
||||||
|
base::WeakPtr<PdfToEmfConverterImpl> converter,
|
||||||
|
const PdfRenderSettings& settings)
|
||||||
|
: converter_(converter), settings_(settings) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdfToEmfUtilityProcessHostClient::Start(
|
||||||
|
const scoped_refptr<base::RefCountedMemory>& 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<base::RefCountedMemory> 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<MetafilePlayer> 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<base::RefCountedMemory>& 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> PdfToEmfConverter::CreateDefault() {
|
||||||
|
return scoped_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace printing
|
48
chromium_src/chrome/browser/printing/pdf_to_emf_converter.h
Normal file
48
chromium_src/chrome/browser/printing/pdf_to_emf_converter.h
Normal file
|
@ -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<void(int page_count)> StartCallback;
|
||||||
|
typedef base::Callback<void(int page_number,
|
||||||
|
float scale_factor,
|
||||||
|
scoped_ptr<MetafilePlayer> emf)> GetPageCallback;
|
||||||
|
|
||||||
|
virtual ~PdfToEmfConverter();
|
||||||
|
|
||||||
|
static scoped_ptr<PdfToEmfConverter> 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<base::RefCountedMemory>& 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_
|
|
@ -17,6 +17,12 @@
|
||||||
#include "printing/printed_document.h"
|
#include "printing/printed_document.h"
|
||||||
#include "printing/printed_page.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;
|
using base::TimeDelta;
|
||||||
|
|
||||||
namespace {
|
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<base::RefCountedMemory>& 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<PdfToEmfConverter> converter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PrintJob::StartPdfToEmfConversion(
|
||||||
|
const scoped_refptr<base::RefCountedMemory>& 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<MetafilePlayer> 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() {
|
void PrintJob::OnDocumentDone() {
|
||||||
// Be sure to live long enough. The instance could be destroyed by the
|
// Be sure to live long enough. The instance could be destroyed by the
|
||||||
// JOB_DONE broadcast.
|
// JOB_DONE broadcast.
|
||||||
|
|
|
@ -90,6 +90,19 @@ class PrintJob : public PrintJobWorkerOwner,
|
||||||
// Access the current printed document. Warning: may be NULL.
|
// Access the current printed document. Warning: may be NULL.
|
||||||
PrintedDocument* document() const;
|
PrintedDocument* document() const;
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void StartPdfToEmfConversion(
|
||||||
|
const scoped_refptr<base::RefCountedMemory>& 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<MetafilePlayer> emf);
|
||||||
|
|
||||||
|
#endif // OS_WIN
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~PrintJob();
|
virtual ~PrintJob();
|
||||||
|
|
||||||
|
@ -137,6 +150,11 @@ class PrintJob : public PrintJobWorkerOwner,
|
||||||
// the notified calls Cancel() again.
|
// the notified calls Cancel() again.
|
||||||
bool is_canceling_;
|
bool is_canceling_;
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
class PdfToEmfState;
|
||||||
|
scoped_ptr<PdfToEmfState> ptd_to_emf_state_;
|
||||||
|
#endif // OS_WIN
|
||||||
|
|
||||||
// Used at shutdown so that we can quit a nested message loop.
|
// Used at shutdown so that we can quit a nested message loop.
|
||||||
base::WeakPtrFactory<PrintJob> quit_factory_;
|
base::WeakPtrFactory<PrintJob> quit_factory_;
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,8 @@ void PrintViewManagerBase::OnDidPrintPage(
|
||||||
params.data_size);
|
params.data_size);
|
||||||
|
|
||||||
document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
|
document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
|
||||||
|
print_job_->StartPdfToEmfConversion(
|
||||||
|
bytes, params.page_size, params.content_area);
|
||||||
}
|
}
|
||||||
#endif // !OS_WIN
|
#endif // !OS_WIN
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
// 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<ResourceHost> 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<ResourceHost>();
|
||||||
|
|
||||||
|
// Private interfaces.
|
||||||
|
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||||
|
ppapi::PERMISSION_PRIVATE)) {
|
||||||
|
switch (message.type()) {
|
||||||
|
case PpapiHostMsg_Broker_Create::ID: {
|
||||||
|
scoped_refptr<ResourceMessageFilter> broker_filter(
|
||||||
|
new PepperBrokerMessageFilter(instance, host_));
|
||||||
|
return scoped_ptr<ResourceHost>(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<ResourceHost>(
|
||||||
|
new PepperFlashBrowserHost(host_, instance, resource));
|
||||||
|
case PpapiHostMsg_FlashClipboard_Create::ID: {
|
||||||
|
scoped_refptr<ResourceMessageFilter> clipboard_filter(
|
||||||
|
new PepperFlashClipboardMessageFilter);
|
||||||
|
return scoped_ptr<ResourceHost>(new MessageFilterHost(
|
||||||
|
host_->GetPpapiHost(), instance, resource, clipboard_filter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<ResourceHost>();
|
||||||
|
return scoped_ptr<ResourceHost>(
|
||||||
|
new MessageFilterHost(host, instance, resource, isolated_fs_filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
return scoped_ptr<ResourceHost>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace chrome
|
|
@ -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<ppapi::host::ResourceHost> 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_
|
|
@ -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 <string>
|
||||||
|
|
||||||
|
#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<base::TaskRunner>
|
||||||
|
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
|
|
@ -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<base::TaskRunner> 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_
|
|
@ -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 <windows.h>
|
||||||
|
#elif defined(OS_MACOSX)
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
#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<int32_t>(restrictions)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace chrome
|
|
@ -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<PepperFlashBrowserHost> weak_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHost);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace chrome
|
||||||
|
|
||||||
|
#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_
|
|
@ -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<base::string16, std::string>& data,
|
||||||
|
Pickle* pickle) {
|
||||||
|
pickle->WriteSizeT(data.size());
|
||||||
|
for (std::map<base::string16, std::string>::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<base::TaskRunner>
|
||||||
|
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<uint32_t>& formats,
|
||||||
|
const std::vector<std::string>& 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<base::string16, std::string> 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
|
|
@ -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 <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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<base::TaskRunner> 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<uint32_t>& formats,
|
||||||
|
const std::vector<std::string>& 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_
|
|
@ -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<base::TaskRunner>
|
||||||
|
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
|
|
@ -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 <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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<base::TaskRunner> 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_
|
169
chromium_src/chrome/common/chrome_utility_messages.h
Normal file
169
chromium_src/chrome/common/chrome_utility_messages.h
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
// 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 <Windows.h>
|
||||||
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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<Tuple<base::string16, base::string16>>
|
||||||
|
GetOpenFileNameFilter;
|
||||||
|
#endif // OS_WIN
|
||||||
|
|
||||||
|
#endif // CHROME_COMMON_CHROME_UTILITY_MESSAGES_H_
|
||||||
|
|
||||||
|
#define IPC_MESSAGE_START ChromeUtilityMsgStart
|
||||||
|
|
||||||
|
|
||||||
|
#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<unsigned char> /* 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<unsigned char>) // 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 */)
|
||||||
|
|
||||||
|
|
||||||
|
// 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(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)
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// 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 */)
|
||||||
|
|
||||||
|
|
||||||
|
// Reply when the utility process has started.
|
||||||
|
IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_ProcessStarted)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
IPC_MESSAGE_CONTROL0(ChromeUtilityHostMsg_GetOpenFileName_Failed)
|
||||||
|
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_GetOpenFileName_Result,
|
||||||
|
base::FilePath /* directory */,
|
||||||
|
std::vector<base::FilePath> /* 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)
|
|
@ -17,6 +17,13 @@
|
||||||
#include "ui/gfx/native_widget_types.h"
|
#include "ui/gfx/native_widget_types.h"
|
||||||
#include "ui/gfx/geometry/rect.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_
|
#ifndef CHROME_COMMON_PRINT_MESSAGES_H_
|
||||||
#define 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.
|
// Tell the browser printing failed.
|
||||||
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed,
|
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed,
|
||||||
int /* document cookie */)
|
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
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
// 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_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<ResourceHost> 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<ResourceHost>();
|
||||||
|
|
||||||
|
if (host_->GetPpapiHost()->permissions().HasPermission(
|
||||||
|
ppapi::PERMISSION_FLASH)) {
|
||||||
|
switch (message.type()) {
|
||||||
|
case PpapiHostMsg_Flash_Create::ID: {
|
||||||
|
return scoped_ptr<ResourceHost>(
|
||||||
|
new PepperFlashRendererHost(host_, instance, resource));
|
||||||
|
}
|
||||||
|
case PpapiHostMsg_FlashFullscreen_Create::ID: {
|
||||||
|
return scoped_ptr<ResourceHost>(
|
||||||
|
new PepperFlashFullscreenHost(host_, instance, resource));
|
||||||
|
}
|
||||||
|
case PpapiHostMsg_FlashMenu_Create::ID: {
|
||||||
|
ppapi::proxy::SerializedFlashMenu serialized_menu;
|
||||||
|
if (ppapi::UnpackMessage<PpapiHostMsg_FlashMenu_Create>(
|
||||||
|
message, &serialized_menu)) {
|
||||||
|
return scoped_ptr<ResourceHost>(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<PpapiHostMsg_FlashFontFile_Create>(
|
||||||
|
message, &description, &charset)) {
|
||||||
|
return scoped_ptr<ResourceHost>(new PepperFlashFontFileHost(
|
||||||
|
host_, instance, resource, description, charset));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return scoped_ptr<ResourceHost>();
|
||||||
|
}
|
|
@ -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<ppapi::host::ResourceHost> 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_
|
|
@ -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<uint8_t*>(const_cast<char*>(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;
|
||||||
|
}
|
|
@ -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_
|
|
@ -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;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue