Merge branch 'master' into chrome52

This commit is contained in:
Cheng Zhao 2016-07-21 05:34:36 -06:00
commit b57665330c
203 changed files with 2352 additions and 1220 deletions

View file

@ -32,6 +32,7 @@
#include "base/strings/string_util.h"
#include "brightray/browser/brightray_paths.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/render_frame_host.h"
@ -71,6 +72,30 @@ struct Converter<Browser::UserTask> {
};
#endif
template<>
struct Converter<Browser::LoginItemSettings> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
Browser::LoginItemSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("openAtLogin", &(out->open_at_login));
dict.Get("openAsHidden", &(out->open_as_hidden));
return true;
}
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
Browser::LoginItemSettings val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.Set("openAtLogin", val.open_at_login);
dict.Set("openAsHidden", val.open_as_hidden);
dict.Set("restoreState", val.restore_state);
dict.Set("wasOpenedAtLogin", val.opened_at_login);
dict.Set("wasOpenedAsHidden", val.opened_as_hidden);
return dict.GetHandle();
}
};
} // namespace mate
@ -254,6 +279,10 @@ void App::OnFinishLaunching() {
Emit("ready");
}
void App::OnAccessibilitySupportChanged() {
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
}
#if defined(OS_MACOSX)
void App::OnContinueUserActivity(
bool* prevent_default,
@ -459,11 +488,16 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) {
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
}
bool App::IsAccessibilitySupportEnabled() {
auto ax_state = content::BrowserAccessibilityState::GetInstance();
return ax_state->IsAccessibleBrowser();
}
#if defined(USE_NSS_CERTS)
void App::ImportCertificate(
const base::DictionaryValue& options,
const net::CompletionCallback& callback) {
auto browser_context = brightray::BrowserContext::From("", false);
auto browser_context = AtomBrowserContext::From("", false);
if (!certificate_manager_model_) {
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
CertificateManagerModel::Create(
@ -522,6 +556,10 @@ void App::BuildPrototype(
base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser))
.SetMethod("setBadgeCount", base::Bind(&Browser::SetBadgeCount, browser))
.SetMethod("getBadgeCount", base::Bind(&Browser::GetBadgeCount, browser))
.SetMethod("getLoginItemSettings",
base::Bind(&Browser::GetLoginItemSettings, browser))
.SetMethod("setLoginItemSettings",
base::Bind(&Browser::SetLoginItemSettings, browser))
#if defined(OS_MACOSX)
.SetMethod("hide", base::Bind(&Browser::Hide, browser))
.SetMethod("show", base::Bind(&Browser::Show, browser))
@ -547,6 +585,8 @@ void App::BuildPrototype(
.SetMethod("makeSingleInstance", &App::MakeSingleInstance)
.SetMethod("releaseSingleInstance", &App::ReleaseSingleInstance)
.SetMethod("relaunch", &App::Relaunch)
.SetMethod("isAccessibilitySupportEnabled",
&App::IsAccessibilitySupportEnabled)
.SetMethod("disableHardwareAcceleration",
&App::DisableHardwareAcceleration);
}

View file

@ -72,6 +72,7 @@ class App : public AtomBrowserClient::Delegate,
void OnFinishLaunching() override;
void OnLogin(LoginHandler* login_handler,
const base::DictionaryValue& request_details) override;
void OnAccessibilitySupportChanged() override;
#if defined(OS_MACOSX)
void OnContinueUserActivity(
bool* prevent_default,
@ -113,6 +114,7 @@ class App : public AtomBrowserClient::Delegate,
void ReleaseSingleInstance();
bool Relaunch(mate::Arguments* args);
void DisableHardwareAcceleration(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
#if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback);

View file

@ -109,6 +109,7 @@ void AutoUpdater::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("getFeedURL", &auto_updater::AutoUpdater::GetFeedURL)
.SetMethod("setFeedURL", &AutoUpdater::SetFeedURL)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
}

View file

@ -44,6 +44,7 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
void OnWindowAllClosed() override;
private:
std::string GetFeedURL();
void SetFeedURL(const std::string& url, mate::Arguments* args);
void QuitAndInstall();

View file

@ -21,7 +21,7 @@ namespace api {
Menu::Menu(v8::Isolate* isolate)
: model_(new AtomMenuModel(this)),
parent_(NULL) {
parent_(nullptr) {
}
Menu::~Menu() {
@ -53,11 +53,14 @@ bool Menu::IsCommandIdVisible(int command_id) const {
return is_visible_.Run(command_id);
}
bool Menu::GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) {
bool Menu::GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Value> val = get_accelerator_.Run(command_id);
v8::Local<v8::Value> val = get_accelerator_.Run(
command_id, use_default_accelerator);
return mate::ConvertFromV8(isolate(), val, accelerator);
}

View file

@ -46,8 +46,10 @@ class Menu : public mate::TrackableObject<Menu>,
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) override;
bool GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
@ -89,7 +91,7 @@ class Menu : public mate::TrackableObject<Menu>,
base::Callback<bool(int)> is_checked_;
base::Callback<bool(int)> is_enabled_;
base::Callback<bool(int)> is_visible_;
base::Callback<v8::Local<v8::Value>(int)> get_accelerator_;
base::Callback<v8::Local<v8::Value>(int, bool)> get_accelerator_;
base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
base::Callback<void()> menu_will_show_;

View file

@ -5,6 +5,7 @@
#import "atom/browser/api/atom_api_menu_mac.h"
#include "atom/browser/native_window.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
@ -30,7 +31,8 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
return;
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:model_.get()]);
[[AtomMenuController alloc] initWithModel:model_.get()
useDefaultAccelerator:NO]);
NSMenu* menu = [menu_controller menu];
NSView* view = web_contents->GetView()->GetNativeView();
@ -66,6 +68,9 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
}
@ -74,7 +79,8 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
void Menu::SetApplicationMenu(Menu* base_menu) {
MenuMac* menu = static_cast<MenuMac*>(base_menu);
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:menu->model_.get()]);
[[AtomMenuController alloc] initWithModel:menu->model_.get()
useDefaultAccelerator:YES]);
[NSApp setMainMenu:[menu_controller menu]];
// Ensure the menu_controller_ is destroyed after main menu is set.

View file

@ -5,6 +5,7 @@
#include "atom/browser/api/atom_api_menu_views.h"
#include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/display/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
@ -36,6 +37,9 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
location = gfx::Point(origin.x() + x, origin.y() + y);
}
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
views::MenuRunner menu_runner(
model(),

View file

@ -6,6 +6,7 @@
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h"
#include "atom/browser/net/url_request_async_asar_job.h"
#include "atom/browser/net/url_request_buffer_job.h"
#include "atom/browser/net/url_request_fetch_job.h"
@ -26,12 +27,30 @@ namespace atom {
namespace api {
namespace {
// Clear protocol handlers in IO thread.
void ClearJobFactoryInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
job_factory->Clear();
}
} // namespace
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()),
weak_factory_(this) {
Init(isolate);
}
Protocol::~Protocol() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(ClearJobFactoryInIO, request_context_getter_));
}
void Protocol::RegisterServiceWorkerSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
@ -173,7 +192,13 @@ void Protocol::BuildPrototype(
namespace {
void RegisterStandardSchemes(
const std::vector<std::string>& schemes) {
const std::vector<std::string>& schemes, mate::Arguments* args) {
if (atom::Browser::Get()->is_ready()) {
args->ThrowError("protocol.registerStandardSchemes should be called before "
"app is ready");
return;
}
auto policy = content::ChildProcessSecurityPolicy::GetInstance();
for (const auto& scheme : schemes) {
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);

View file

@ -43,6 +43,7 @@ class Protocol : public mate::TrackableObject<Protocol> {
protected:
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Protocol();
private:
// Possible errors.

View file

@ -11,6 +11,7 @@
#include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/api/atom_api_web_request.h"
#include "atom/browser/browser.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_permission_manager.h"
@ -20,6 +21,7 @@
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "base/files/file_path.h"
#include "base/guid.h"
@ -163,6 +165,8 @@ namespace api {
namespace {
const char kPersistPrefix[] = "persist:";
// The wrapSession funtion which is implemented in JavaScript
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapSessionCallback g_wrap_session;
@ -241,10 +245,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
} else if (action == Session::CacheAction::STATS) {
base::StringPairs stats;
(*backend_ptr)->GetStats(&stats);
for (size_t i = 0; i < stats.size(); ++i) {
if (stats[i].first == "Current size") {
for (const auto& stat : stats) {
if (stat.first == "Current size") {
int current_size;
base::StringToInt(stats[i].second, &current_size);
base::StringToInt(stat.second, &current_size);
RunCallbackInUI(callback, current_size);
break;
}
@ -266,7 +270,7 @@ void DoCacheActionInIO(
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*;
BackendPtr* backend_ptr = new BackendPtr(nullptr);
auto* backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
@ -285,6 +289,14 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
RunCallbackInUI(callback);
}
void SetCertVerifyProcInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const AtomCertVerifier::VerifyProc& proc) {
auto request_context = context_getter->GetURLRequestContext();
static_cast<AtomCertVerifier*>(request_context->cert_verifier())->
SetVerifyProc(proc);
}
void ClearHostResolverCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const base::Closure& callback) {
@ -311,6 +323,11 @@ void AllowNTLMCredentialsForDomainsInIO(
}
}
void OnClearStorageDataDone(const base::Closure& callback) {
if (!callback.is_null())
callback.Run();
}
} // namespace
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
@ -360,21 +377,19 @@ void Session::DoCacheAction(const net::CompletionCallback& callback) {
}
void Session::ClearStorageData(mate::Arguments* args) {
// clearStorageData([options, ]callback)
// clearStorageData([options, callback])
ClearStorageDataOptions options;
args->GetNext(&options);
base::Closure callback;
if (!args->GetNext(&callback)) {
args->ThrowError();
return;
}
args->GetNext(&options);
args->GetNext(&callback);
auto storage_partition =
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
storage_partition->ClearData(
options.storage_types, options.quota_types, options.origin,
content::StoragePartition::OriginMatcherFunction(),
base::Time(), base::Time::Max(), callback);
base::Time(), base::Time::Max(),
base::Bind(&OnClearStorageDataDone, callback));
}
void Session::FlushStorageData() {
@ -434,7 +449,10 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
return;
}
browser_context_->cert_verifier()->SetVerifyProc(proc);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&SetCertVerifyProcInIO,
make_scoped_refptr(browser_context_->GetRequestContext()),
proc));
}
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
@ -522,10 +540,19 @@ mate::Handle<Session> Session::CreateFrom(
// static
mate::Handle<Session> Session::FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory) {
auto browser_context = brightray::BrowserContext::From(partition, in_memory);
return CreateFrom(isolate,
static_cast<AtomBrowserContext*>(browser_context.get()));
v8::Isolate* isolate, const std::string& partition,
const base::DictionaryValue& options) {
scoped_refptr<AtomBrowserContext> browser_context;
if (partition.empty()) {
browser_context = AtomBrowserContext::From("", false, options);
} else if (base::StartsWith(partition, kPersistPrefix,
base::CompareCase::SENSITIVE)) {
std::string name = partition.substr(8);
browser_context = AtomBrowserContext::From(name, false, options);
} else {
browser_context = AtomBrowserContext::From(partition, true, options);
}
return CreateFrom(isolate, browser_context.get());
}
// static
@ -565,11 +592,23 @@ void SetWrapSession(const WrapSessionCallback& callback) {
namespace {
v8::Local<v8::Value> FromPartition(
const std::string& partition, mate::Arguments* args) {
if (!atom::Browser::Get()->is_ready()) {
args->ThrowError("Session can only be received when app is ready");
return v8::Null(args->isolate());
}
base::DictionaryValue options;
args->GetNext(&options);
return atom::api::Session::FromPartition(
args->isolate(), partition, options).ToV8();
}
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
dict.SetMethod("fromPartition", &FromPartition);
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
}

View file

@ -8,6 +8,7 @@
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "base/values.h"
#include "content/public/browser/download_manager.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
@ -47,9 +48,10 @@ class Session: public mate::TrackableObject<Session>,
static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
// Gets the Session of |partition| and |in_memory|.
// Gets the Session of |partition|.
static mate::Handle<Session> FromPartition(
v8::Isolate* isolate, const std::string& partition, bool in_memory);
v8::Isolate* isolate, const std::string& partition,
const base::DictionaryValue& options = base::DictionaryValue());
AtomBrowserContext* browser_context() const { return browser_context_.get(); }

View file

@ -29,6 +29,8 @@ Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
}
Tray::~Tray() {
// Destroy the native tray in next tick.
base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
}
// static
@ -74,6 +76,10 @@ void Tray::OnDropFiles(const std::vector<std::string>& files) {
Emit("drop-files", files);
}
void Tray::OnDropText(const std::string& text) {
Emit("drop-text", text);
}
void Tray::OnDragEntered() {
Emit("drag-enter");
}

View file

@ -53,6 +53,7 @@ class Tray : public mate::TrackableObject<Tray>,
void OnBalloonClosed() override;
void OnDrop() override;
void OnDropFiles(const std::vector<std::string>& files) override;
void OnDropText(const std::string& text) override;
void OnDragEntered() override;
void OnDragExited() override;
void OnDragEnded() override;

View file

@ -47,6 +47,7 @@
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@ -65,6 +66,7 @@
#include "net/url_request/url_request_context.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "ui/gfx/screen.h"
#include "atom/common/node_includes.h"
@ -238,6 +240,13 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
return storage_partition->GetServiceWorkerContext();
}
// Called when CapturePage is done.
void OnCapturePageDone(base::Callback<void(const gfx::Image&)> callback,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
} // namespace
WebContents::WebContents(v8::Isolate* isolate,
@ -277,16 +286,11 @@ WebContents::WebContents(v8::Isolate* isolate,
std::string partition;
mate::Handle<api::Session> session;
if (options.Get("session", &session)) {
} else if (options.Get("partition", &partition) && !partition.empty()) {
bool in_memory = true;
if (base::StartsWith(partition, "persist:", base::CompareCase::SENSITIVE)) {
in_memory = false;
partition = partition.substr(8);
}
session = Session::FromPartition(isolate, partition, in_memory);
} else if (options.Get("partition", &partition)) {
session = Session::FromPartition(isolate, partition);
} else {
// Use the default session if not specified.
session = Session::FromPartition(isolate, "", false);
session = Session::FromPartition(isolate, "");
}
session_.Reset(isolate, session.ToV8());
@ -600,20 +604,6 @@ void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
Emit("did-finish-load");
}
void WebContents::DidFailProvisionalLoad(
content::RenderFrameHost* render_frame_host,
const GURL& url,
int code,
const base::string16& description,
bool was_ignored_by_handler) {
bool is_main_frame = !render_frame_host->GetParent();
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
// Do not emit "did-fail-load" for canceled requests.
if (code != net::ERR_ABORTED)
Emit("did-fail-load", code, description, url, is_main_frame);
}
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& url,
int error_code,
@ -657,13 +647,27 @@ void WebContents::DidGetRedirectForResourceRequest(
details.headers.get());
}
void WebContents::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
if (details.is_navigation_to_different_page())
Emit("did-navigate", params.url);
else if (details.is_in_page)
Emit("did-navigate-in-page", params.url);
void WebContents::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
bool is_main_frame = navigation_handle->IsInMainFrame();
if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
auto url = navigation_handle->GetURL();
bool is_in_page = navigation_handle->IsSamePage();
if (is_main_frame && !is_in_page) {
Emit("did-navigate", url);
} else if (is_in_page) {
Emit("did-navigate-in-page", url);
}
} else {
auto url = navigation_handle->GetURL();
int code = navigation_handle->GetNetErrorCode();
auto description = net::ErrorToShortString(code);
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
// Do not emit "did-fail-load" for canceled requests.
if (code != net::ERR_ABORTED)
Emit("did-fail-load", code, description, url, is_main_frame);
}
}
void WebContents::TitleWasSet(content::NavigationEntry* entry,
@ -677,10 +681,10 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry,
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)
for (const auto& iter : urls) {
if (iter.icon_type != content::FaviconURL::FAVICON)
continue;
const GURL& url = iter->icon_url;
const GURL& url = iter.icon_url;
if (url.is_valid())
unique_urls.insert(url);
}
@ -781,6 +785,13 @@ WebContents::Type WebContents::GetType() const {
return type_;
}
#if !defined(OS_MACOSX)
bool WebContents::IsFocused() const {
auto view = web_contents()->GetRenderWidgetHostView();
return view && view->HasFocus();
}
#endif
bool WebContents::Equal(const WebContents* web_contents) const {
return GetID() == web_contents->GetID();
}
@ -1235,6 +1246,45 @@ void WebContents::StartDrag(const mate::Dictionary& item,
}
}
void WebContents::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(const gfx::Image&)> callback;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)
&& args->GetNext(&callback))) {
args->ThrowError();
return;
}
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(gfx::Image());
return;
}
// Capture full page if user doesn't specify a |rect|.
const gfx::Size view_size = rect.IsEmpty() ? view->GetViewBounds().size() :
rect.size();
// By default, the requested bitmap size is the view size in screen
// coordinates. However, if there's more pixel detail available on the
// current system, increase the requested bitmap size to capture it all.
gfx::Size bitmap_size = view_size;
const gfx::NativeView native_view = view->GetNativeView();
const float scale =
gfx::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
.device_scale_factor();
if (scale > 1.0f)
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
host->CopyFromBackingStore(gfx::Rect(rect.origin(), view_size),
bitmap_size,
base::Bind(&OnCapturePageDone, callback),
kBGRA_8888_SkColorType);
}
void WebContents::OnCursorChange(const content::WebCursor& cursor) {
content::WebCursor::CursorInfo info;
cursor.GetCursorInfo(&info);
@ -1370,6 +1420,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
.SetMethod("showDefinitionForSelection",
&WebContents::ShowDefinitionForSelection)
.SetMethod("capturePage", &WebContents::CapturePage)
.SetMethod("isFocused", &WebContents::IsFocused)
.SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents)

View file

@ -67,6 +67,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
int GetID() const;
Type GetType() const;
bool IsFocused() const;
bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options);
void DownloadURL(const GURL& url);
@ -145,6 +146,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Dragging native items.
void StartDrag(const mate::Dictionary& item, mate::Arguments* args);
// Captures the page with |rect|, |callback| would be called when capturing is
// done.
void CapturePage(mate::Arguments* args);
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
bool IsGuest() const;
@ -240,11 +245,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidStartLoading() override;
void DidStopLoading() override;
void DidGetResourceResponseStart(
@ -252,9 +252,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DidGetRedirectForResourceRequest(
content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) override;
void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
bool OnMessageReceived(const IPC::Message& message) override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(

View file

@ -0,0 +1,30 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
@interface NSWindow
- (BOOL)isKeyWindow;
@end
namespace atom {
namespace api {
bool WebContents::IsFocused() const {
if (GetType() != BACKGROUND_PAGE) {
auto window = web_contents()->GetTopLevelNativeWindow();
// On Mac the render widget host view does not lose focus when the window
// loses focus so check if the top level window is the key window.
if (window && ![window isKeyWindow])
return false;
}
auto view = web_contents()->GetRenderWidgetHostView();
return view && view->HasFocus();
}
} // namespace api
} // namespace atom

View file

@ -55,15 +55,6 @@ namespace api {
namespace {
void OnCapturePageDone(
v8::Isolate* isolate,
const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
// Converts binary data to Buffer.
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
@ -581,21 +572,6 @@ void Window::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
}
void Window::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(const gfx::Image&)> callback;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)
&& args->GetNext(&callback))) {
args->ThrowError();
return;
}
window_->CapturePage(
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
}
void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress);
}
@ -673,6 +649,12 @@ bool Window::IsWindowMessageHooked(UINT message) {
void Window::UnhookAllWindowMessages() {
messages_callback_map_.clear();
}
bool Window::SetThumbnailClip(const gfx::Rect& region) {
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailClip(
window_->GetAcceleratedWidget(), region);
}
#endif
#if defined(TOOLKIT_VIEWS)
@ -843,7 +825,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
@ -861,6 +842,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
.SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
#endif
#if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &Window::SetIcon)

View file

@ -155,7 +155,6 @@ class Window : public mate::TrackableObject<Window>,
void SetIgnoreMouseEvents(bool ignore);
void SetContentProtection(bool enable);
void SetFocusable(bool focusable);
void CapturePage(mate::Arguments* args);
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description);
@ -180,6 +179,7 @@ class Window : public mate::TrackableObject<Window>,
bool IsWindowMessageHooked(UINT message);
void UnhookWindowMessage(UINT message);
void UnhookAllWindowMessages();
bool SetThumbnailClip(const gfx::Rect& region);
#endif
#if defined(TOOLKIT_VIEWS)

View file

@ -12,8 +12,8 @@
namespace mate {
Event::Event(v8::Isolate* isolate)
: sender_(NULL),
message_(NULL) {
: sender_(nullptr),
message_(nullptr) {
Init(isolate);
}
@ -31,8 +31,8 @@ void Event::SetSenderAndMessage(content::WebContents* sender,
}
void Event::WebContentsDestroyed() {
sender_ = NULL;
message_ = NULL;
sender_ = nullptr;
message_ = nullptr;
}
void Event::PreventDefault(v8::Isolate* isolate) {
@ -41,13 +41,13 @@ void Event::PreventDefault(v8::Isolate* isolate) {
}
bool Event::SendReply(const base::string16& json) {
if (message_ == NULL || sender_ == NULL)
if (message_ == nullptr || sender_ == nullptr)
return false;
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
bool success = sender_->Send(message_);
message_ = NULL;
sender_ = NULL;
message_ = nullptr;
sender_ = nullptr;
return success;
}