2014-10-31 18:17:05 +00:00
|
|
|
// Copyright (c) 2014 GitHub, Inc.
|
2014-04-25 09:49:37 +00:00
|
|
|
// Use of this source code is governed by the MIT license that can be
|
2014-04-24 08:45:25 +00:00
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "atom/browser/api/atom_api_web_contents.h"
|
|
|
|
|
2015-04-25 04:43:52 +00:00
|
|
|
#include <set>
|
2015-12-11 15:54:32 +00:00
|
|
|
#include <string>
|
2015-04-25 04:43:52 +00:00
|
|
|
|
2016-01-21 18:22:23 +00:00
|
|
|
#include "atom/browser/api/atom_api_debugger.h"
|
2015-06-16 09:23:29 +00:00
|
|
|
#include "atom/browser/api/atom_api_session.h"
|
2015-10-01 05:45:59 +00:00
|
|
|
#include "atom/browser/api/atom_api_window.h"
|
2015-05-11 06:40:40 +00:00
|
|
|
#include "atom/browser/atom_browser_client.h"
|
2014-10-23 06:04:13 +00:00
|
|
|
#include "atom/browser/atom_browser_context.h"
|
2015-06-18 09:01:23 +00:00
|
|
|
#include "atom/browser/atom_browser_main_parts.h"
|
2016-06-01 05:54:41 +00:00
|
|
|
#include "atom/browser/lib/bluetooth_chooser.h"
|
2014-12-18 20:58:17 +00:00
|
|
|
#include "atom/browser/native_window.h"
|
2016-04-08 18:19:36 +00:00
|
|
|
#include "atom/browser/net/atom_network_delegate.h"
|
2016-08-03 03:29:55 +00:00
|
|
|
#include "atom/browser/osr/osr_output_device.h"
|
2016-08-03 02:01:35 +00:00
|
|
|
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
2016-08-26 22:30:02 +00:00
|
|
|
#include "atom/browser/osr/osr_web_contents_view.h"
|
2016-07-03 03:26:43 +00:00
|
|
|
#include "atom/browser/ui/drag_util.h"
|
2016-01-23 13:29:47 +00:00
|
|
|
#include "atom/browser/web_contents_permission_helper.h"
|
2015-09-04 16:44:22 +00:00
|
|
|
#include "atom/browser/web_contents_preferences.h"
|
2017-01-30 11:18:40 +00:00
|
|
|
#include "atom/browser/web_contents_zoom_controller.h"
|
2015-06-25 06:28:13 +00:00
|
|
|
#include "atom/browser/web_view_guest_delegate.h"
|
2014-04-25 05:10:16 +00:00
|
|
|
#include "atom/common/api/api_messages.h"
|
2015-08-07 11:34:00 +00:00
|
|
|
#include "atom/common/api/event_emitter_caller.h"
|
2016-04-14 12:52:17 +00:00
|
|
|
#include "atom/common/color_util.h"
|
2016-04-08 06:54:33 +00:00
|
|
|
#include "atom/common/mouse_util.h"
|
2015-09-18 03:06:38 +00:00
|
|
|
#include "atom/common/native_mate_converters/blink_converter.h"
|
2015-08-07 10:10:19 +00:00
|
|
|
#include "atom/common/native_mate_converters/callback.h"
|
2015-10-31 13:39:07 +00:00
|
|
|
#include "atom/common/native_mate_converters/content_converter.h"
|
2015-07-24 09:39:11 +00:00
|
|
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
2014-10-24 06:37:14 +00:00
|
|
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
2014-04-24 09:00:41 +00:00
|
|
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
2015-04-20 06:50:04 +00:00
|
|
|
#include "atom/common/native_mate_converters/image_converter.h"
|
2016-10-13 15:14:23 +00:00
|
|
|
#include "atom/common/native_mate_converters/net_converter.h"
|
2014-04-24 09:00:41 +00:00
|
|
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
2014-04-25 05:10:16 +00:00
|
|
|
#include "atom/common/native_mate_converters/value_converter.h"
|
2016-04-08 06:54:33 +00:00
|
|
|
#include "atom/common/options_switches.h"
|
2017-04-18 11:44:31 +00:00
|
|
|
#include "base/process/process_handle.h"
|
2014-04-25 08:13:16 +00:00
|
|
|
#include "base/strings/utf_string_conversions.h"
|
2016-11-30 07:30:03 +00:00
|
|
|
#include "base/threading/thread_task_runner_handle.h"
|
2014-11-03 14:12:56 +00:00
|
|
|
#include "brightray/browser/inspectable_web_contents.h"
|
2015-10-01 03:14:19 +00:00
|
|
|
#include "brightray/browser/inspectable_web_contents_view.h"
|
2015-06-09 05:07:40 +00:00
|
|
|
#include "chrome/browser/printing/print_preview_message_handler.h"
|
2016-08-26 22:30:02 +00:00
|
|
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
2017-01-24 01:51:11 +00:00
|
|
|
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
2017-02-19 20:43:17 +00:00
|
|
|
#include "content/browser/frame_host/navigation_entry_impl.h"
|
2016-04-08 06:54:33 +00:00
|
|
|
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
2016-08-03 02:01:35 +00:00
|
|
|
#include "content/browser/web_contents/web_contents_impl.h"
|
2015-08-31 09:19:19 +00:00
|
|
|
#include "content/common/view_messages.h"
|
2015-04-20 06:50:04 +00:00
|
|
|
#include "content/public/browser/favicon_status.h"
|
2015-09-18 06:20:31 +00:00
|
|
|
#include "content/public/browser/native_web_keyboard_event.h"
|
2014-12-09 22:38:43 +00:00
|
|
|
#include "content/public/browser/navigation_details.h"
|
2015-03-05 14:39:27 +00:00
|
|
|
#include "content/public/browser/navigation_entry.h"
|
2016-07-14 00:19:28 +00:00
|
|
|
#include "content/public/browser/navigation_handle.h"
|
2017-02-19 20:43:17 +00:00
|
|
|
#include "content/public/browser/notification_details.h"
|
|
|
|
#include "content/public/browser/notification_source.h"
|
|
|
|
#include "content/public/browser/notification_types.h"
|
2015-05-12 19:35:56 +00:00
|
|
|
#include "content/public/browser/plugin_service.h"
|
2014-07-28 07:29:51 +00:00
|
|
|
#include "content/public/browser/render_frame_host.h"
|
2014-04-24 09:00:41 +00:00
|
|
|
#include "content/public/browser/render_process_host.h"
|
2014-04-25 02:34:40 +00:00
|
|
|
#include "content/public/browser/render_view_host.h"
|
2016-03-08 14:28:53 +00:00
|
|
|
#include "content/public/browser/render_widget_host.h"
|
2015-09-18 06:20:31 +00:00
|
|
|
#include "content/public/browser/render_widget_host_view.h"
|
2014-10-24 15:05:25 +00:00
|
|
|
#include "content/public/browser/resource_request_details.h"
|
2015-04-30 13:15:19 +00:00
|
|
|
#include "content/public/browser/service_worker_context.h"
|
2014-10-24 12:20:56 +00:00
|
|
|
#include "content/public/browser/site_instance.h"
|
2016-08-26 22:30:02 +00:00
|
|
|
#include "content/public/browser/storage_partition.h"
|
2014-04-24 08:45:25 +00:00
|
|
|
#include "content/public/browser/web_contents.h"
|
2015-11-02 15:28:45 +00:00
|
|
|
#include "content/public/common/context_menu_params.h"
|
2014-10-23 06:04:13 +00:00
|
|
|
#include "native_mate/dictionary.h"
|
2014-04-24 08:45:25 +00:00
|
|
|
#include "native_mate/object_template_builder.h"
|
2015-05-20 10:44:57 +00:00
|
|
|
#include "net/url_request/url_request_context.h"
|
2017-01-24 05:48:55 +00:00
|
|
|
#include "third_party/WebKit/public/platform/WebInputEvent.h"
|
2017-01-26 07:21:26 +00:00
|
|
|
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
2016-07-21 12:03:38 +00:00
|
|
|
#include "ui/display/screen.h"
|
2014-04-24 08:45:25 +00:00
|
|
|
|
2016-08-15 21:13:24 +00:00
|
|
|
#if !defined(OS_MACOSX)
|
|
|
|
#include "ui/aura/window.h"
|
|
|
|
#endif
|
2014-10-23 06:04:13 +00:00
|
|
|
|
2016-09-06 08:24:37 +00:00
|
|
|
#include "atom/common/node_includes.h"
|
|
|
|
|
2015-06-13 13:23:45 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
struct PrintSettings {
|
|
|
|
bool silent;
|
|
|
|
bool print_background;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2015-05-29 03:12:55 +00:00
|
|
|
namespace mate {
|
|
|
|
|
|
|
|
template<>
|
2015-06-25 06:28:13 +00:00
|
|
|
struct Converter<atom::SetSizeParams> {
|
2015-05-29 03:12:55 +00:00
|
|
|
static bool FromV8(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::Value> val,
|
2015-06-25 06:28:13 +00:00
|
|
|
atom::SetSizeParams* out) {
|
2015-05-29 03:12:55 +00:00
|
|
|
mate::Dictionary params;
|
|
|
|
if (!ConvertFromV8(isolate, val, ¶ms))
|
|
|
|
return false;
|
|
|
|
bool autosize;
|
|
|
|
if (params.Get("enableAutoSize", &autosize))
|
|
|
|
out->enable_auto_size.reset(new bool(true));
|
|
|
|
gfx::Size size;
|
|
|
|
if (params.Get("min", &size))
|
|
|
|
out->min_size.reset(new gfx::Size(size));
|
|
|
|
if (params.Get("max", &size))
|
|
|
|
out->max_size.reset(new gfx::Size(size));
|
2015-05-29 05:47:09 +00:00
|
|
|
if (params.Get("normal", &size))
|
2015-05-29 03:44:49 +00:00
|
|
|
out->normal_size.reset(new gfx::Size(size));
|
2015-05-29 03:12:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-06-13 13:23:45 +00:00
|
|
|
template<>
|
|
|
|
struct Converter<PrintSettings> {
|
|
|
|
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
|
|
|
PrintSettings* out) {
|
|
|
|
mate::Dictionary dict;
|
|
|
|
if (!ConvertFromV8(isolate, val, &dict))
|
|
|
|
return false;
|
|
|
|
dict.Get("silent", &(out->silent));
|
|
|
|
dict.Get("printBackground", &(out->print_background));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-06-23 08:34:22 +00:00
|
|
|
template<>
|
|
|
|
struct Converter<WindowOpenDisposition> {
|
|
|
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
|
|
|
WindowOpenDisposition val) {
|
|
|
|
std::string disposition = "other";
|
|
|
|
switch (val) {
|
2017-01-24 07:50:02 +00:00
|
|
|
case WindowOpenDisposition::CURRENT_TAB:
|
|
|
|
disposition = "default";
|
|
|
|
break;
|
|
|
|
case WindowOpenDisposition::NEW_FOREGROUND_TAB:
|
|
|
|
disposition = "foreground-tab";
|
|
|
|
break;
|
|
|
|
case WindowOpenDisposition::NEW_BACKGROUND_TAB:
|
|
|
|
disposition = "background-tab";
|
|
|
|
break;
|
|
|
|
case WindowOpenDisposition::NEW_POPUP:
|
|
|
|
case WindowOpenDisposition::NEW_WINDOW:
|
|
|
|
disposition = "new-window";
|
|
|
|
break;
|
|
|
|
case WindowOpenDisposition::SAVE_TO_DISK:
|
|
|
|
disposition = "save-to-disk";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2015-06-23 08:34:22 +00:00
|
|
|
}
|
|
|
|
return mate::ConvertToV8(isolate, disposition);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-10-14 04:41:31 +00:00
|
|
|
template<>
|
|
|
|
struct Converter<content::SavePageType> {
|
|
|
|
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
|
|
|
content::SavePageType* out) {
|
|
|
|
std::string save_type;
|
|
|
|
if (!ConvertFromV8(isolate, val, &save_type))
|
|
|
|
return false;
|
2015-12-07 11:56:23 +00:00
|
|
|
save_type = base::ToLowerASCII(save_type);
|
2015-11-02 13:19:00 +00:00
|
|
|
if (save_type == "htmlonly") {
|
2015-10-14 04:41:31 +00:00
|
|
|
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
2015-11-02 13:19:00 +00:00
|
|
|
} else if (save_type == "htmlcomplete") {
|
2015-10-14 04:41:31 +00:00
|
|
|
*out = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML;
|
2015-11-02 13:19:00 +00:00
|
|
|
} else if (save_type == "mhtml") {
|
2015-10-14 04:41:31 +00:00
|
|
|
*out = content::SAVE_PAGE_TYPE_AS_MHTML;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-06-14 16:09:54 +00:00
|
|
|
template<>
|
|
|
|
struct Converter<atom::api::WebContents::Type> {
|
|
|
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
|
|
|
atom::api::WebContents::Type val) {
|
2016-06-14 17:05:25 +00:00
|
|
|
using Type = atom::api::WebContents::Type;
|
2016-06-14 16:09:54 +00:00
|
|
|
std::string type = "";
|
|
|
|
switch (val) {
|
2016-06-14 17:05:25 +00:00
|
|
|
case Type::BACKGROUND_PAGE: type = "backgroundPage"; break;
|
|
|
|
case Type::BROWSER_WINDOW: type = "window"; break;
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
case Type::BROWSER_VIEW: type = "browserView"; break;
|
2016-06-14 17:05:25 +00:00
|
|
|
case Type::REMOTE: type = "remote"; break;
|
|
|
|
case Type::WEB_VIEW: type = "webview"; break;
|
2016-07-28 10:10:56 +00:00
|
|
|
case Type::OFF_SCREEN: type = "offscreen"; break;
|
2016-06-14 17:05:25 +00:00
|
|
|
default: break;
|
2016-06-14 16:09:54 +00:00
|
|
|
}
|
|
|
|
return mate::ConvertToV8(isolate, type);
|
|
|
|
}
|
|
|
|
|
2016-06-14 16:23:03 +00:00
|
|
|
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
|
|
|
atom::api::WebContents::Type* out) {
|
2016-06-14 17:05:25 +00:00
|
|
|
using Type = atom::api::WebContents::Type;
|
2016-06-14 16:23:03 +00:00
|
|
|
std::string type;
|
|
|
|
if (!ConvertFromV8(isolate, val, &type))
|
|
|
|
return false;
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
if (type == "backgroundPage") {
|
2016-06-14 17:05:25 +00:00
|
|
|
*out = Type::BACKGROUND_PAGE;
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
} else if (type == "browserView") {
|
|
|
|
*out = Type::BROWSER_VIEW;
|
|
|
|
} else if (type == "webview") {
|
|
|
|
*out = Type::WEB_VIEW;
|
2016-07-28 10:10:56 +00:00
|
|
|
} else if (type == "offscreen") {
|
|
|
|
*out = Type::OFF_SCREEN;
|
2016-06-14 16:23:03 +00:00
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
2016-06-14 16:09:54 +00:00
|
|
|
|
2015-05-29 03:12:55 +00:00
|
|
|
} // namespace mate
|
|
|
|
|
|
|
|
|
2014-04-24 08:45:25 +00:00
|
|
|
namespace atom {
|
|
|
|
|
|
|
|
namespace api {
|
|
|
|
|
2014-10-23 05:31:10 +00:00
|
|
|
namespace {
|
|
|
|
|
2015-04-30 13:15:19 +00:00
|
|
|
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;
|
|
|
|
|
2015-06-05 07:41:03 +00:00
|
|
|
auto storage_partition =
|
|
|
|
content::BrowserContext::GetStoragePartition(context, site_instance);
|
|
|
|
if (!storage_partition)
|
|
|
|
return nullptr;
|
2015-04-30 13:15:19 +00:00
|
|
|
|
|
|
|
return storage_partition->GetServiceWorkerContext();
|
|
|
|
}
|
|
|
|
|
2016-07-06 16:32:58 +00:00
|
|
|
// Called when CapturePage is done.
|
2017-03-29 19:29:52 +00:00
|
|
|
void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
|
2016-07-06 16:32:58 +00:00
|
|
|
const SkBitmap& bitmap,
|
|
|
|
content::ReadbackResponse response) {
|
|
|
|
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
|
|
|
}
|
|
|
|
|
2017-02-19 20:43:17 +00:00
|
|
|
// Set the background color of RenderWidgetHostView.
|
|
|
|
void SetBackgroundColor(content::WebContents* web_contents) {
|
|
|
|
const auto view = web_contents->GetRenderWidgetHostView();
|
|
|
|
if (view) {
|
|
|
|
WebContentsPreferences* web_preferences =
|
|
|
|
WebContentsPreferences::FromWebContents(web_contents);
|
|
|
|
std::string color_name;
|
|
|
|
if (web_preferences->web_preferences()->GetString(options::kBackgroundColor,
|
|
|
|
&color_name)) {
|
|
|
|
view->SetBackgroundColor(ParseHexColor(color_name));
|
|
|
|
} else {
|
|
|
|
view->SetBackgroundColor(SK_ColorTRANSPARENT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-23 05:31:10 +00:00
|
|
|
} // namespace
|
|
|
|
|
2016-04-25 01:17:54 +00:00
|
|
|
WebContents::WebContents(v8::Isolate* isolate,
|
2016-08-17 00:15:10 +00:00
|
|
|
content::WebContents* web_contents,
|
|
|
|
Type type)
|
2015-06-24 14:23:38 +00:00
|
|
|
: content::WebContentsObserver(web_contents),
|
2016-04-18 05:52:03 +00:00
|
|
|
embedder_(nullptr),
|
2017-01-31 09:25:48 +00:00
|
|
|
zoom_controller_(nullptr),
|
2016-08-17 00:15:10 +00:00
|
|
|
type_(type),
|
2016-04-08 06:54:33 +00:00
|
|
|
request_id_(0),
|
2016-09-06 03:08:50 +00:00
|
|
|
background_throttling_(true),
|
2017-01-30 11:18:40 +00:00
|
|
|
enable_devtools_(true) {
|
2016-08-17 00:15:10 +00:00
|
|
|
if (type == REMOTE) {
|
|
|
|
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
|
|
|
Init(isolate);
|
|
|
|
AttachAsUserData(web_contents);
|
|
|
|
} else {
|
|
|
|
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
|
|
|
|
auto session = Session::CreateFrom(isolate, GetBrowserContext());
|
|
|
|
session_.Reset(isolate, session.ToV8());
|
|
|
|
InitWithSessionAndOptions(isolate, web_contents, session, options);
|
|
|
|
}
|
2014-10-23 06:04:13 +00:00
|
|
|
}
|
|
|
|
|
2017-01-30 11:18:40 +00:00
|
|
|
WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
2017-01-31 09:25:48 +00:00
|
|
|
: embedder_(nullptr),
|
|
|
|
zoom_controller_(nullptr),
|
2016-06-16 01:54:28 +00:00
|
|
|
type_(BROWSER_WINDOW),
|
2016-04-08 06:54:33 +00:00
|
|
|
request_id_(0),
|
2016-09-06 03:08:50 +00:00
|
|
|
background_throttling_(true),
|
2017-01-30 11:18:40 +00:00
|
|
|
enable_devtools_(true) {
|
2016-04-08 06:54:33 +00:00
|
|
|
// Read options.
|
|
|
|
options.Get("backgroundThrottling", &background_throttling_);
|
|
|
|
|
2016-06-16 01:54:28 +00:00
|
|
|
// FIXME(zcbenz): We should read "type" parameter for better design, but
|
|
|
|
// on Windows we have encountered a compiler bug that if we read "type"
|
|
|
|
// from |options| and then set |type_|, a memory corruption will happen
|
|
|
|
// and Electron will soon crash.
|
|
|
|
// Remvoe this after we upgraded to use VS 2015 Update 3.
|
|
|
|
bool b = false;
|
|
|
|
if (options.Get("isGuest", &b) && b)
|
|
|
|
type_ = WEB_VIEW;
|
|
|
|
else if (options.Get("isBackgroundPage", &b) && b)
|
|
|
|
type_ = BACKGROUND_PAGE;
|
Implement initial, experimental BrowserView API
Right now, `<webview>` is the only way to embed additional content in a
`BrowserWindow`. Unfortunately `<webview>` suffers from a [number of
problems](https://github.com/electron/electron/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Awebview%20).
To make matters worse, many of these are upstream Chromium bugs instead
of Electron-specific bugs.
For us at [Figma](https://www.figma.com), the main issue is very slow
performance.
Despite the upstream improvements to `<webview>` through the OOPIF work, it is
probable that there will continue to be `<webview>`-specific bugs in the
future.
Therefore, this introduces a `<webview>` alternative to called `BrowserView`,
which...
- is a thin wrapper around `api::WebContents` (so bugs in `BrowserView` will
likely also be bugs in `BrowserWindow` web contents)
- is instantiated in the main process like `BrowserWindow` (and unlike
`<webview>`, which lives in the DOM of a `BrowserWindow` web contents)
- needs to be added to a `BrowserWindow` to display something on the screen
This implements the most basic API. The API is expected to evolve and change in
the near future and has consequently been marked as experimental. Please do not
use this API in production unless you are prepared to deal with breaking
changes.
In the future, we will want to change the API to support multiple
`BrowserView`s per window. We will also want to consider z-ordering
auto-resizing, and possibly even nested views.
2017-04-11 17:47:30 +00:00
|
|
|
else if (options.Get("isBrowserView", &b) && b)
|
|
|
|
type_ = BROWSER_VIEW;
|
2016-07-28 10:10:56 +00:00
|
|
|
else if (options.Get("offscreen", &b) && b)
|
2016-07-29 12:50:27 +00:00
|
|
|
type_ = OFF_SCREEN;
|
2015-06-24 15:29:32 +00:00
|
|
|
|
2016-09-07 02:16:52 +00:00
|
|
|
// Whether to enable DevTools.
|
|
|
|
options.Get("devTools", &enable_devtools_);
|
2016-09-05 08:27:56 +00:00
|
|
|
|
2015-09-05 14:39:48 +00:00
|
|
|
// Obtain the session.
|
|
|
|
std::string partition;
|
|
|
|
mate::Handle<api::Session> session;
|
|
|
|
if (options.Get("session", &session)) {
|
2016-07-12 12:01:49 +00:00
|
|
|
} else if (options.Get("partition", &partition)) {
|
|
|
|
session = Session::FromPartition(isolate, partition);
|
2015-09-05 14:39:48 +00:00
|
|
|
} else {
|
|
|
|
// Use the default session if not specified.
|
2016-07-12 12:01:49 +00:00
|
|
|
session = Session::FromPartition(isolate, "");
|
2015-09-05 14:39:48 +00:00
|
|
|
}
|
|
|
|
session_.Reset(isolate, session.ToV8());
|
|
|
|
|
2015-06-24 15:29:32 +00:00
|
|
|
content::WebContents* web_contents;
|
2016-06-14 16:23:03 +00:00
|
|
|
if (IsGuest()) {
|
2016-05-23 03:28:59 +00:00
|
|
|
scoped_refptr<content::SiteInstance> site_instance =
|
|
|
|
content::SiteInstance::CreateForURL(
|
|
|
|
session->browser_context(), GURL("chrome-guest://fake-host"));
|
2015-09-05 14:39:48 +00:00
|
|
|
content::WebContents::CreateParams params(
|
|
|
|
session->browser_context(), site_instance);
|
2015-06-25 06:28:13 +00:00
|
|
|
guest_delegate_.reset(new WebViewGuestDelegate);
|
|
|
|
params.guest_delegate = guest_delegate_.get();
|
2015-06-24 15:29:32 +00:00
|
|
|
web_contents = content::WebContents::Create(params);
|
2016-07-31 10:19:56 +00:00
|
|
|
} else if (IsOffScreen()) {
|
2016-08-01 11:27:39 +00:00
|
|
|
bool transparent = false;
|
|
|
|
options.Get("transparent", &transparent);
|
|
|
|
|
2016-07-29 12:50:27 +00:00
|
|
|
content::WebContents::CreateParams params(session->browser_context());
|
2016-08-04 04:03:24 +00:00
|
|
|
auto* view = new OffScreenWebContentsView(
|
|
|
|
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
2016-08-03 04:04:36 +00:00
|
|
|
params.view = view;
|
|
|
|
params.delegate_view = view;
|
2016-07-25 13:55:00 +00:00
|
|
|
|
2015-06-24 15:29:32 +00:00
|
|
|
web_contents = content::WebContents::Create(params);
|
2016-07-29 12:50:27 +00:00
|
|
|
view->SetWebContents(web_contents);
|
|
|
|
} else {
|
|
|
|
content::WebContents::CreateParams params(session->browser_context());
|
2016-07-27 23:58:23 +00:00
|
|
|
web_contents = content::WebContents::Create(params);
|
2015-06-24 14:14:46 +00:00
|
|
|
}
|
2015-06-09 07:50:20 +00:00
|
|
|
|
2016-08-17 00:15:10 +00:00
|
|
|
InitWithSessionAndOptions(isolate, web_contents, session, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate,
|
|
|
|
content::WebContents *web_contents,
|
|
|
|
mate::Handle<api::Session> session,
|
|
|
|
const mate::Dictionary& options) {
|
2017-02-19 20:43:17 +00:00
|
|
|
content::WebContentsObserver::Observe(web_contents);
|
2016-05-17 12:49:05 +00:00
|
|
|
InitWithWebContents(web_contents, session->browser_context());
|
2015-06-05 07:01:51 +00:00
|
|
|
|
2015-10-01 03:14:19 +00:00
|
|
|
managed_web_contents()->GetView()->SetDelegate(this);
|
|
|
|
|
2015-09-22 13:56:56 +00:00
|
|
|
// Save the preferences in C++.
|
2015-11-11 02:32:25 +00:00
|
|
|
new WebContentsPreferences(web_contents, options);
|
2015-09-04 16:44:22 +00:00
|
|
|
|
2017-01-30 11:18:40 +00:00
|
|
|
// Initialize permission helper.
|
2016-01-30 11:19:18 +00:00
|
|
|
WebContentsPermissionHelper::CreateForWebContents(web_contents);
|
2017-01-30 11:18:40 +00:00
|
|
|
// Initialize security state client.
|
2017-01-24 01:51:11 +00:00
|
|
|
SecurityStateTabHelper::CreateForWebContents(web_contents);
|
2017-01-30 11:18:40 +00:00
|
|
|
// Initialize zoom controller.
|
|
|
|
WebContentsZoomController::CreateForWebContents(web_contents);
|
|
|
|
zoom_controller_ = WebContentsZoomController::FromWebContents(web_contents);
|
|
|
|
double zoom_factor;
|
2017-01-31 09:25:48 +00:00
|
|
|
if (options.Get(options::kZoomFactor, &zoom_factor))
|
2017-01-30 11:18:40 +00:00
|
|
|
zoom_controller_->SetDefaultZoomFactor(zoom_factor);
|
2016-01-23 13:29:47 +00:00
|
|
|
|
2015-07-14 19:13:25 +00:00
|
|
|
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
|
|
|
|
2016-06-14 16:23:03 +00:00
|
|
|
if (IsGuest()) {
|
2015-06-25 06:28:13 +00:00
|
|
|
guest_delegate_->Initialize(this);
|
|
|
|
|
2015-06-24 15:29:32 +00:00
|
|
|
NativeWindow* owner_window = nullptr;
|
2016-02-17 08:52:19 +00:00
|
|
|
if (options.Get("embedder", &embedder_) && embedder_) {
|
2015-06-24 15:29:32 +00:00
|
|
|
// New WebContents's owner_window is the embedder's owner_window.
|
2016-02-17 08:52:19 +00:00
|
|
|
auto relay =
|
|
|
|
NativeWindowRelay::FromWebContents(embedder_->web_contents());
|
2015-06-24 15:29:32 +00:00
|
|
|
if (relay)
|
|
|
|
owner_window = relay->window.get();
|
|
|
|
}
|
|
|
|
if (owner_window)
|
|
|
|
SetOwnerWindow(owner_window);
|
|
|
|
}
|
2016-04-25 01:17:54 +00:00
|
|
|
|
2017-02-19 20:43:17 +00:00
|
|
|
const content::NavigationController* controller =
|
|
|
|
&web_contents->GetController();
|
|
|
|
registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
|
|
|
|
content::Source<content::NavigationController>(controller));
|
|
|
|
|
2016-04-25 01:17:54 +00:00
|
|
|
Init(isolate);
|
|
|
|
AttachAsUserData(web_contents);
|
2014-10-23 06:04:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
WebContents::~WebContents() {
|
2016-01-13 09:59:59 +00:00
|
|
|
// The destroy() is called.
|
|
|
|
if (managed_web_contents()) {
|
|
|
|
// For webview we need to tell content module to do some cleanup work before
|
|
|
|
// destroying it.
|
|
|
|
if (type_ == WEB_VIEW)
|
|
|
|
guest_delegate_->Destroy();
|
|
|
|
|
2016-02-22 07:20:23 +00:00
|
|
|
RenderViewDeleted(web_contents()->GetRenderViewHost());
|
2017-03-18 19:40:30 +00:00
|
|
|
DestroyWebContents();
|
2016-01-13 09:59:59 +00:00
|
|
|
}
|
2014-04-24 08:45:25 +00:00
|
|
|
}
|
|
|
|
|
2017-03-18 19:40:30 +00:00
|
|
|
void WebContents::DestroyWebContents() {
|
|
|
|
// This event is only for internal use, which is emitted when WebContents is
|
|
|
|
// being destroyed.
|
|
|
|
Emit("will-destroy");
|
2017-03-22 02:00:36 +00:00
|
|
|
ResetManagedWebContents();
|
2017-03-18 19:40:30 +00:00
|
|
|
}
|
|
|
|
|
2017-01-23 09:59:40 +00:00
|
|
|
bool WebContents::DidAddMessageToConsole(content::WebContents* source,
|
|
|
|
int32_t level,
|
|
|
|
const base::string16& message,
|
|
|
|
int32_t line_no,
|
|
|
|
const base::string16& source_id) {
|
2016-08-03 03:29:55 +00:00
|
|
|
if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) {
|
2015-06-25 03:07:23 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
Emit("console-message", level, message, line_no, source_id);
|
|
|
|
return true;
|
|
|
|
}
|
2014-10-25 02:01:19 +00:00
|
|
|
}
|
|
|
|
|
2016-10-09 23:30:38 +00:00
|
|
|
void WebContents::OnCreateWindow(
|
|
|
|
const GURL& target_url,
|
|
|
|
const std::string& frame_name,
|
|
|
|
WindowOpenDisposition disposition,
|
2017-01-23 08:44:42 +00:00
|
|
|
const std::vector<std::string>& features,
|
2016-10-09 23:30:38 +00:00
|
|
|
const scoped_refptr<content::ResourceRequestBodyImpl>& body) {
|
2016-08-03 03:29:55 +00:00
|
|
|
if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
|
2016-10-09 23:30:38 +00:00
|
|
|
Emit("-new-window", target_url, frame_name, disposition, features, body);
|
2015-06-25 03:07:23 +00:00
|
|
|
else
|
2016-09-15 13:37:35 +00:00
|
|
|
Emit("new-window", target_url, frame_name, disposition, features);
|
2014-10-25 05:21:09 +00:00
|
|
|
}
|
|
|
|
|
2016-08-16 00:13:18 +00:00
|
|
|
void WebContents::WebContentsCreated(content::WebContents* source_contents,
|
2017-01-23 09:59:40 +00:00
|
|
|
int opener_render_process_id,
|
2016-08-16 00:13:18 +00:00
|
|
|
int opener_render_frame_id,
|
|
|
|
const std::string& frame_name,
|
|
|
|
const GURL& target_url,
|
|
|
|
content::WebContents* new_contents) {
|
|
|
|
v8::Locker locker(isolate());
|
|
|
|
v8::HandleScope handle_scope(isolate());
|
|
|
|
auto api_web_contents = CreateFrom(isolate(), new_contents, BROWSER_WINDOW);
|
|
|
|
Emit("-web-contents-created", api_web_contents, target_url, frame_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::AddNewContents(content::WebContents* source,
|
|
|
|
content::WebContents* new_contents,
|
|
|
|
WindowOpenDisposition disposition,
|
|
|
|
const gfx::Rect& initial_rect,
|
|
|
|
bool user_gesture,
|
|
|
|
bool* was_blocked) {
|
|
|
|
v8::Locker locker(isolate());
|
|
|
|
v8::HandleScope handle_scope(isolate());
|
|
|
|
auto api_web_contents = CreateFrom(isolate(), new_contents);
|
2017-01-10 23:40:07 +00:00
|
|
|
if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture,
|
2016-08-16 00:13:18 +00:00
|
|
|
initial_rect.x(), initial_rect.y(), initial_rect.width(),
|
2017-01-10 23:40:07 +00:00
|
|
|
initial_rect.height())) {
|
|
|
|
api_web_contents->DestroyWebContents();
|
|
|
|
}
|
2016-08-16 00:13:18 +00:00
|
|
|
}
|
|
|
|
|
2014-10-24 10:06:32 +00:00
|
|
|
content::WebContents* WebContents::OpenURLFromTab(
|
|
|
|
content::WebContents* source,
|
|
|
|
const content::OpenURLParams& params) {
|
2017-01-24 07:50:02 +00:00
|
|
|
if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
|
2016-08-03 03:29:55 +00:00
|
|
|
if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
|
2015-06-25 03:07:23 +00:00
|
|
|
Emit("-new-window", params.url, "", params.disposition);
|
|
|
|
else
|
|
|
|
Emit("new-window", params.url, "", params.disposition);
|
2014-12-17 22:55:22 +00:00
|
|
|
return nullptr;
|
2014-11-04 09:59:15 +00:00
|
|
|
}
|
2014-10-24 10:06:32 +00:00
|
|
|
|
2014-12-17 22:55:22 +00:00
|
|
|
// Give user a chance to cancel navigation.
|
2015-01-15 01:51:54 +00:00
|
|
|
if (Emit("will-navigate", params.url))
|
2014-12-17 22:55:22 +00:00
|
|
|
return nullptr;
|
|
|
|
|
2016-12-21 00:51:03 +00:00
|
|
|
// Don't load the URL if the web contents was marked as destroyed from a
|
|
|
|
// will-navigate event listener
|
|
|
|
if (IsDestroyed())
|
|
|
|
return nullptr;
|
|
|
|
|
2015-06-05 09:45:17 +00:00
|
|
|
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
|
2014-10-24 10:06:32 +00:00
|
|
|
}
|
|
|
|
|
2015-06-25 03:07:23 +00:00
|
|
|
void WebContents::BeforeUnloadFired(content::WebContents* tab,
|
|
|
|
bool proceed,
|
|
|
|
bool* proceed_to_fire_unload) {
|
2016-08-03 03:29:55 +00:00
|
|
|
if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
|
2015-06-25 03:07:23 +00:00
|
|
|
*proceed_to_fire_unload = proceed;
|
|
|
|
else
|
|
|
|
*proceed_to_fire_unload = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::MoveContents(content::WebContents* source,
|
|
|
|
const gfx::Rect& pos) {
|
|
|
|
Emit("move", pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::CloseContents(content::WebContents* source) {
|
2015-07-10 02:38:15 +00:00
|
|
|
Emit("close");
|
2016-07-30 13:40:16 +00:00
|
|
|
|
2016-07-28 10:10:56 +00:00
|
|
|
if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window())
|
2015-06-25 03:07:23 +00:00
|
|
|
owner_window()->CloseContents(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::ActivateContents(content::WebContents* source) {
|
2015-06-25 05:18:36 +00:00
|
|
|
Emit("activate");
|
2015-06-25 03:07:23 +00:00
|
|
|
}
|
|
|
|
|
2016-06-07 06:56:19 +00:00
|
|
|
void WebContents::UpdateTargetURL(content::WebContents* source,
|
|
|
|
const GURL& url) {
|
|
|
|
Emit("update-target-url", url);
|
|
|
|
}
|
|
|
|
|
2015-06-24 14:23:38 +00:00
|
|
|
bool WebContents::IsPopupOrPanel(const content::WebContents* source) const {
|
|
|
|
return type_ == BROWSER_WINDOW;
|
|
|
|
}
|
|
|
|
|
2014-10-24 13:46:47 +00:00
|
|
|
void WebContents::HandleKeyboardEvent(
|
|
|
|
content::WebContents* source,
|
|
|
|
const content::NativeWebKeyboardEvent& event) {
|
2016-05-18 04:47:50 +00:00
|
|
|
if (type_ == WEB_VIEW && embedder_) {
|
2015-06-25 03:07:23 +00:00
|
|
|
// Send the unhandled keyboard events back to the embedder.
|
2016-05-18 04:29:21 +00:00
|
|
|
embedder_->HandleKeyboardEvent(source, event);
|
2016-05-18 04:47:50 +00:00
|
|
|
} else {
|
|
|
|
// Go to the default keyboard handling.
|
|
|
|
CommonWebContentsDelegate::HandleKeyboardEvent(source, event);
|
2015-06-25 03:07:23 +00:00
|
|
|
}
|
2014-10-24 13:46:47 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 22:41:18 +00:00
|
|
|
bool WebContents::PreHandleKeyboardEvent(
|
|
|
|
content::WebContents* source,
|
|
|
|
const content::NativeWebKeyboardEvent& event,
|
|
|
|
bool* is_keyboard_shortcut) {
|
2016-12-13 23:52:37 +00:00
|
|
|
if (event.type == blink::WebInputEvent::Type::RawKeyDown
|
|
|
|
|| event.type == blink::WebInputEvent::Type::KeyUp)
|
|
|
|
return Emit("before-input-event", event);
|
|
|
|
else
|
2016-12-06 22:41:18 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-09 12:17:40 +00:00
|
|
|
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
|
2015-05-08 06:18:15 +00:00
|
|
|
const GURL& origin) {
|
2016-02-01 10:03:38 +00:00
|
|
|
auto permission_helper =
|
|
|
|
WebContentsPermissionHelper::FromWebContents(source);
|
|
|
|
auto callback = base::Bind(&WebContents::OnEnterFullscreenModeForTab,
|
|
|
|
base::Unretained(this), source, origin);
|
|
|
|
permission_helper->RequestFullscreenPermission(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::OnEnterFullscreenModeForTab(content::WebContents* source,
|
|
|
|
const GURL& origin,
|
|
|
|
bool allowed) {
|
|
|
|
if (!allowed)
|
|
|
|
return;
|
2015-06-05 09:27:24 +00:00
|
|
|
CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin);
|
|
|
|
Emit("enter-html-full-screen");
|
2015-05-08 06:18:15 +00:00
|
|
|
}
|
|
|
|
|
2015-05-09 12:17:40 +00:00
|
|
|
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
|
2015-06-05 09:27:24 +00:00
|
|
|
CommonWebContentsDelegate::ExitFullscreenModeForTab(source);
|
|
|
|
Emit("leave-html-full-screen");
|
2015-05-08 06:18:15 +00:00
|
|
|
}
|
|
|
|
|
2017-01-23 09:59:40 +00:00
|
|
|
void WebContents::RendererUnresponsive(
|
|
|
|
content::WebContents* source,
|
|
|
|
const content::WebContentsUnresponsiveState& unresponsive_state) {
|
2015-06-25 03:07:23 +00:00
|
|
|
Emit("unresponsive");
|
2016-07-28 10:10:56 +00:00
|
|
|
if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window())
|
2015-06-25 03:07:23 +00:00
|
|
|
owner_window()->RendererUnresponsive(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::RendererResponsive(content::WebContents* source) {
|
|
|
|
Emit("responsive");
|
2016-07-28 10:10:56 +00:00
|
|
|
if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window())
|
2015-06-25 03:07:23 +00:00
|
|
|
owner_window()->RendererResponsive(source);
|
|
|
|
}
|
|
|
|
|
2015-10-31 13:39:07 +00:00
|
|
|
bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) {
|
2016-05-03 00:02:33 +00:00
|
|
|
if (params.custom_context.is_pepper_menu) {
|
|
|
|
Emit("pepper-context-menu", std::make_pair(params, web_contents()));
|
|
|
|
web_contents()->NotifyContextMenuClosed(params.custom_context);
|
|
|
|
} else {
|
|
|
|
Emit("context-menu", std::make_pair(params, web_contents()));
|
|
|
|
}
|
2015-11-02 15:28:45 +00:00
|
|
|
|
2015-10-31 13:39:07 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-19 19:53:47 +00:00
|
|
|
bool WebContents::OnGoToEntryOffset(int offset) {
|
|
|
|
GoToOffset(offset);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-17 17:27:56 +00:00
|
|
|
void WebContents::FindReply(content::WebContents* web_contents,
|
|
|
|
int request_id,
|
|
|
|
int number_of_matches,
|
|
|
|
const gfx::Rect& selection_rect,
|
|
|
|
int active_match_ordinal,
|
|
|
|
bool final_update) {
|
2016-09-09 10:50:43 +00:00
|
|
|
if (!final_update)
|
|
|
|
return;
|
|
|
|
|
2015-12-17 17:27:56 +00:00
|
|
|
v8::Locker locker(isolate());
|
|
|
|
v8::HandleScope handle_scope(isolate());
|
|
|
|
mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate());
|
2016-09-08 05:27:10 +00:00
|
|
|
result.Set("requestId", request_id);
|
|
|
|
result.Set("matches", number_of_matches);
|
|
|
|
result.Set("selectionArea", selection_rect);
|
|
|
|
result.Set("activeMatchOrdinal", active_match_ordinal);
|
2016-09-09 10:50:43 +00:00
|
|
|
result.Set("finalUpdate", final_update); // Deprecate after 2.0
|
2016-09-08 05:27:10 +00:00
|
|
|
Emit("found-in-page", result);
|
2015-12-17 17:27:56 +00:00
|
|
|
}
|
|
|
|
|
2016-02-26 10:17:28 +00:00
|
|
|
bool WebContents::CheckMediaAccessPermission(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
const GURL& security_origin,
|
|
|
|
content::MediaStreamType type) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-23 13:29:47 +00:00
|
|
|
void WebContents::RequestMediaAccessPermission(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
const content::MediaStreamRequest& request,
|
|
|
|
const content::MediaResponseCallback& callback) {
|
|
|
|
auto permission_helper =
|
|
|
|
WebContentsPermissionHelper::FromWebContents(web_contents);
|
|
|
|
permission_helper->RequestMediaAccessPermission(request, callback);
|
|
|
|
}
|
|
|
|
|
2016-02-01 09:43:49 +00:00
|
|
|
void WebContents::RequestToLockMouse(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
bool user_gesture,
|
|
|
|
bool last_unlocked_by_target) {
|
|
|
|
auto permission_helper =
|
|
|
|
WebContentsPermissionHelper::FromWebContents(web_contents);
|
|
|
|
permission_helper->RequestPointerLockPermission(user_gesture);
|
|
|
|
}
|
|
|
|
|
2016-05-30 12:38:09 +00:00
|
|
|
std::unique_ptr<content::BluetoothChooser> WebContents::RunBluetoothChooser(
|
|
|
|
content::RenderFrameHost* frame,
|
|
|
|
const content::BluetoothChooser::EventHandler& event_handler) {
|
|
|
|
std::unique_ptr<BluetoothChooser> bluetooth_chooser(
|
|
|
|
new BluetoothChooser(this, event_handler));
|
|
|
|
return std::move(bluetooth_chooser);
|
|
|
|
}
|
|
|
|
|
2015-06-25 03:07:23 +00:00
|
|
|
void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
|
|
|
// Do nothing, we override this method just to avoid compilation error since
|
|
|
|
// there are two virtual functions named BeforeUnloadFired.
|
|
|
|
}
|
|
|
|
|
2016-12-28 23:44:44 +00:00
|
|
|
void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
|
|
|
|
const auto impl = content::RenderWidgetHostImpl::FromID(
|
|
|
|
render_view_host->GetProcess()->GetID(),
|
|
|
|
render_view_host->GetRoutingID());
|
|
|
|
if (impl)
|
|
|
|
impl->disable_hidden_ = !background_throttling_;
|
|
|
|
}
|
|
|
|
|
2014-04-25 04:40:04 +00:00
|
|
|
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
2016-02-22 06:54:55 +00:00
|
|
|
Emit("render-view-deleted", render_view_host->GetProcess()->GetID());
|
2014-04-25 03:51:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
2016-09-18 00:00:45 +00:00
|
|
|
Emit("crashed", status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
2014-04-25 03:51:05 +00:00
|
|
|
}
|
|
|
|
|
2015-05-12 19:35:56 +00:00
|
|
|
void WebContents::PluginCrashed(const base::FilePath& plugin_path,
|
|
|
|
base::ProcessId plugin_pid) {
|
|
|
|
content::WebPluginInfo info;
|
|
|
|
auto plugin_service = content::PluginService::GetInstance();
|
|
|
|
plugin_service->GetPluginInfoByPath(plugin_path, &info);
|
|
|
|
Emit("plugin-crashed", info.name, info.version);
|
|
|
|
}
|
|
|
|
|
2017-01-23 09:59:40 +00:00
|
|
|
void WebContents::MediaStartedPlaying(const MediaPlayerInfo& video_type,
|
|
|
|
const MediaPlayerId& id) {
|
2015-12-20 03:16:22 +00:00
|
|
|
Emit("media-started-playing");
|
|
|
|
}
|
|
|
|
|
2017-01-23 09:59:40 +00:00
|
|
|
void WebContents::MediaStoppedPlaying(const MediaPlayerInfo& video_type,
|
|
|
|
const MediaPlayerId& id) {
|
2015-12-20 03:16:22 +00:00
|
|
|
Emit("media-paused");
|
|
|
|
}
|
|
|
|
|
2015-12-22 22:16:00 +00:00
|
|
|
void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
2016-10-10 21:27:16 +00:00
|
|
|
Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
|
2015-12-22 22:16:00 +00:00
|
|
|
}
|
|
|
|
|
2015-04-29 13:49:31 +00:00
|
|
|
void WebContents::DocumentLoadedInFrame(
|
|
|
|
content::RenderFrameHost* render_frame_host) {
|
2016-08-04 04:03:24 +00:00
|
|
|
if (!render_frame_host->GetParent())
|
2015-04-29 13:49:31 +00:00
|
|
|
Emit("dom-ready");
|
|
|
|
}
|
|
|
|
|
2014-10-11 11:11:34 +00:00
|
|
|
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
|
|
|
const GURL& validated_url) {
|
|
|
|
bool is_main_frame = !render_frame_host->GetParent();
|
2015-01-15 01:51:54 +00:00
|
|
|
Emit("did-frame-finish-load", is_main_frame);
|
2014-06-09 04:03:19 +00:00
|
|
|
|
|
|
|
if (is_main_frame)
|
|
|
|
Emit("did-finish-load");
|
2014-04-25 04:22:16 +00:00
|
|
|
}
|
|
|
|
|
2014-10-24 15:05:25 +00:00
|
|
|
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
|
2016-04-13 10:33:59 +00:00
|
|
|
const GURL& url,
|
2014-10-24 15:05:25 +00:00
|
|
|
int error_code,
|
2015-09-02 07:16:49 +00:00
|
|
|
const base::string16& error_description,
|
|
|
|
bool was_ignored_by_handler) {
|
2016-04-05 02:24:58 +00:00
|
|
|
bool is_main_frame = !render_frame_host->GetParent();
|
2016-04-13 10:33:59 +00:00
|
|
|
Emit("did-fail-load", error_code, error_description, url, is_main_frame);
|
2014-10-24 15:05:25 +00:00
|
|
|
}
|
|
|
|
|
2015-05-22 07:24:34 +00:00
|
|
|
void WebContents::DidStartLoading() {
|
2014-04-25 04:22:16 +00:00
|
|
|
Emit("did-start-loading");
|
|
|
|
}
|
|
|
|
|
2015-05-22 07:24:34 +00:00
|
|
|
void WebContents::DidStopLoading() {
|
2014-04-25 04:22:16 +00:00
|
|
|
Emit("did-stop-loading");
|
|
|
|
}
|
|
|
|
|
2015-04-08 13:44:47 +00:00
|
|
|
void WebContents::DidGetResourceResponseStart(
|
|
|
|
const content::ResourceRequestDetails& details) {
|
|
|
|
Emit("did-get-response-details",
|
|
|
|
details.socket_address.IsEmpty(),
|
|
|
|
details.url,
|
|
|
|
details.original_url,
|
|
|
|
details.http_response_code,
|
|
|
|
details.method,
|
2015-05-20 15:54:59 +00:00
|
|
|
details.referrer,
|
2016-10-25 10:41:01 +00:00
|
|
|
details.headers.get(),
|
2016-04-08 18:19:36 +00:00
|
|
|
ResourceTypeToString(details.resource_type));
|
2015-04-08 13:44:47 +00:00
|
|
|
}
|
|
|
|
|
2014-10-24 15:05:25 +00:00
|
|
|
void WebContents::DidGetRedirectForResourceRequest(
|
|
|
|
const content::ResourceRedirectDetails& details) {
|
2015-01-15 01:51:54 +00:00
|
|
|
Emit("did-get-redirect-request",
|
|
|
|
details.url,
|
|
|
|
details.new_url,
|
2015-09-18 10:01:31 +00:00
|
|
|
(details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME),
|
|
|
|
details.http_response_code,
|
|
|
|
details.method,
|
|
|
|
details.referrer,
|
2016-10-25 10:41:01 +00:00
|
|
|
details.headers.get());
|
2014-10-24 15:05:25 +00:00
|
|
|
}
|
|
|
|
|
2017-02-19 20:43:17 +00:00
|
|
|
void WebContents::DidStartNavigation(
|
|
|
|
content::NavigationHandle* navigation_handle) {
|
|
|
|
if (!navigation_handle->IsInMainFrame() || navigation_handle->IsSamePage())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (deferred_load_url_.id) {
|
|
|
|
auto web_contents = navigation_handle->GetWebContents();
|
|
|
|
auto& controller = web_contents->GetController();
|
|
|
|
int id = controller.GetPendingEntry()->GetUniqueID();
|
|
|
|
if (id == deferred_load_url_.id) {
|
|
|
|
if (!deferred_load_url_.params.url.is_empty()) {
|
|
|
|
auto params = deferred_load_url_.params;
|
|
|
|
deferred_load_url_.id = 0;
|
|
|
|
deferred_load_url_.params =
|
|
|
|
content::NavigationController::LoadURLParams(GURL());
|
|
|
|
controller.LoadURLWithParams(params);
|
|
|
|
SetBackgroundColor(web_contents);
|
|
|
|
} else {
|
|
|
|
deferred_load_url_.id = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-14 00:19:28 +00:00
|
|
|
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) {
|
2016-08-11 15:27:50 +00:00
|
|
|
Emit("did-navigate-in-page", url, is_main_frame);
|
2016-07-14 00:19:28 +00:00
|
|
|
}
|
|
|
|
} 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);
|
|
|
|
}
|
2014-12-09 22:38:43 +00:00
|
|
|
}
|
|
|
|
|
2015-04-05 09:20:42 +00:00
|
|
|
void WebContents::TitleWasSet(content::NavigationEntry* entry,
|
|
|
|
bool explicit_set) {
|
2015-04-29 03:27:49 +00:00
|
|
|
if (entry)
|
2015-12-01 10:50:56 +00:00
|
|
|
Emit("-page-title-updated", entry->GetTitle(), explicit_set);
|
2015-12-01 09:52:13 +00:00
|
|
|
else
|
2015-12-01 10:50:56 +00:00
|
|
|
Emit("-page-title-updated", "", explicit_set);
|
2015-04-05 09:20:42 +00:00
|
|
|
}
|
|
|
|
|
2015-04-17 19:55:31 +00:00
|
|
|
void WebContents::DidUpdateFaviconURL(
|
|
|
|
const std::vector<content::FaviconURL>& urls) {
|
|
|
|
std::set<GURL> unique_urls;
|
2016-07-10 11:32:40 +00:00
|
|
|
for (const auto& iter : urls) {
|
|
|
|
if (iter.icon_type != content::FaviconURL::FAVICON)
|
2015-04-17 19:55:31 +00:00
|
|
|
continue;
|
2016-07-10 11:32:40 +00:00
|
|
|
const GURL& url = iter.icon_url;
|
2015-04-17 19:55:31 +00:00
|
|
|
if (url.is_valid())
|
|
|
|
unique_urls.insert(url);
|
|
|
|
}
|
2015-04-20 06:50:04 +00:00
|
|
|
Emit("page-favicon-updated", unique_urls);
|
2015-04-17 19:55:31 +00:00
|
|
|
}
|
|
|
|
|
2017-02-19 20:43:17 +00:00
|
|
|
void WebContents::Observe(int type,
|
|
|
|
const content::NotificationSource& source,
|
|
|
|
const content::NotificationDetails& details) {
|
|
|
|
switch (type) {
|
|
|
|
case content::NOTIFICATION_NAV_ENTRY_PENDING: {
|
|
|
|
content::NavigationEntry* entry =
|
|
|
|
content::Details<content::NavigationEntry>(details).ptr();
|
|
|
|
content::NavigationEntryImpl* entry_impl =
|
|
|
|
static_cast<content::NavigationEntryImpl*>(entry);
|
|
|
|
// In NavigatorImpl::DidStartMainFrameNavigation when there is no
|
|
|
|
// browser side pending entry available it creates a new one based
|
|
|
|
// on existing pending entry, hence we track the unique id here
|
|
|
|
// instead in WebContents::LoadURL with controller.GetPendingEntry()
|
|
|
|
// TODO(deepak1556): Remove once we have
|
|
|
|
// https://codereview.chromium.org/2661743002.
|
2017-03-05 18:51:52 +00:00
|
|
|
if (entry_impl->frame_tree_node_id() == -1) {
|
2017-02-19 20:43:17 +00:00
|
|
|
deferred_load_url_.id = entry->GetUniqueID();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
NOTREACHED();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-12 07:36:12 +00:00
|
|
|
void WebContents::DevToolsReloadPage() {
|
|
|
|
Emit("devtools-reload-page");
|
|
|
|
}
|
|
|
|
|
2015-10-01 03:14:19 +00:00
|
|
|
void WebContents::DevToolsFocused() {
|
|
|
|
Emit("devtools-focused");
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::DevToolsOpened() {
|
|
|
|
v8::Locker locker(isolate());
|
|
|
|
v8::HandleScope handle_scope(isolate());
|
|
|
|
auto handle = WebContents::CreateFrom(
|
|
|
|
isolate(), managed_web_contents()->GetDevToolsWebContents());
|
|
|
|
devtools_web_contents_.Reset(isolate(), handle.ToV8());
|
|
|
|
|
2016-05-26 10:29:39 +00:00
|
|
|
// Set inspected tabID.
|
|
|
|
base::FundamentalValue tab_id(ID());
|
|
|
|
managed_web_contents()->CallClientFunction(
|
|
|
|
"DevToolsAPI.setInspectedTabId", &tab_id, nullptr, nullptr);
|
|
|
|
|
2015-10-01 06:41:01 +00:00
|
|
|
// Inherit owner window in devtools.
|
|
|
|
if (owner_window())
|
|
|
|
handle->SetOwnerWindow(managed_web_contents()->GetDevToolsWebContents(),
|
|
|
|
owner_window());
|
|
|
|
|
2015-10-01 03:14:19 +00:00
|
|
|
Emit("devtools-opened");
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::DevToolsClosed() {
|
|
|
|
v8::Locker locker(isolate());
|
|
|
|
v8::HandleScope handle_scope(isolate());
|
|
|
|
devtools_web_contents_.Reset();
|
|
|
|
|
|
|
|
Emit("devtools-closed");
|
|
|
|
}
|
|
|
|
|
2014-04-25 08:13:16 +00:00
|
|
|
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
|
|
|
bool handled = true;
|
|
|
|
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
|
|
|
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
|
|
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
|
|
|
OnRendererMessageSync)
|
2017-01-30 17:06:50 +00:00
|
|
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_SetTemporaryZoomLevel,
|
|
|
|
OnSetTemporaryZoomLevel)
|
|
|
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel,
|
|
|
|
OnGetZoomLevel)
|
2016-01-30 05:33:55 +00:00
|
|
|
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
|
|
|
|
handled = false)
|
2014-04-25 08:13:16 +00:00
|
|
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
|
|
|
IPC_END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
return handled;
|
|
|
|
}
|
|
|
|
|
2016-01-13 09:59:59 +00:00
|
|
|
// There are three ways of destroying a webContents:
|
2016-07-28 22:48:01 +00:00
|
|
|
// 1. call webContents.destroy();
|
2016-01-13 09:59:59 +00:00
|
|
|
// 2. garbage collection;
|
|
|
|
// 3. user closes the window of webContents;
|
|
|
|
// For webview only #1 will happen, for BrowserWindow both #1 and #3 may
|
|
|
|
// happen. The #2 should never happen for webContents, because webview is
|
|
|
|
// managed by GuestViewManager, and BrowserWindow's webContents is managed
|
|
|
|
// by api::Window.
|
|
|
|
// For #1, the destructor will do the cleanup work and we only need to make
|
|
|
|
// sure "destroyed" event is emitted. For #3, the content::WebContents will
|
|
|
|
// be destroyed on close, and WebContentsDestroyed would be called for it, so
|
|
|
|
// we need to make sure the api::WebContents is also deleted.
|
2014-07-28 07:29:51 +00:00
|
|
|
void WebContents::WebContentsDestroyed() {
|
2016-01-13 06:47:39 +00:00
|
|
|
// Cleanup relationships with other parts.
|
2015-06-24 09:58:12 +00:00
|
|
|
RemoveFromWeakMap();
|
2016-01-12 13:10:24 +00:00
|
|
|
|
|
|
|
// We can not call Destroy here because we need to call Emit first, but we
|
|
|
|
// also do not want any method to be used, so just mark as destroyed here.
|
|
|
|
MarkDestroyed();
|
|
|
|
|
|
|
|
Emit("destroyed");
|
|
|
|
|
|
|
|
// Destroy the native class in next tick.
|
2016-11-30 07:30:03 +00:00
|
|
|
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
|
|
|
FROM_HERE, GetDestroyClosure());
|
2014-04-25 03:22:51 +00:00
|
|
|
}
|
|
|
|
|
2015-03-05 14:39:27 +00:00
|
|
|
void WebContents::NavigationEntryCommitted(
|
2015-05-11 05:51:52 +00:00
|
|
|
const content::LoadCommittedDetails& details) {
|
|
|
|
Emit("navigation-entry-commited", details.entry->GetURL(),
|
|
|
|
details.is_in_page, details.did_replace_entry);
|
2015-03-05 14:39:27 +00:00
|
|
|
}
|
|
|
|
|
2016-09-06 01:28:40 +00:00
|
|
|
int64_t WebContents::GetID() const {
|
|
|
|
int64_t process_id = web_contents()->GetRenderProcessHost()->GetID();
|
|
|
|
int64_t routing_id = web_contents()->GetRoutingID();
|
|
|
|
int64_t rv = (process_id << 32) + routing_id;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WebContents::GetProcessID() const {
|
2015-06-23 08:16:10 +00:00
|
|
|
return web_contents()->GetRenderProcessHost()->GetID();
|
|
|
|
}
|
|
|
|
|
2017-04-18 10:31:20 +00:00
|
|
|
int WebContents::GetOSProcessID() const {
|
|
|
|
auto process_handle = web_contents()->GetRenderProcessHost()->GetHandle();
|
|
|
|
return base::GetProcId(process_handle);
|
|
|
|
}
|
|
|
|
|
2016-06-14 16:09:54 +00:00
|
|
|
WebContents::Type WebContents::GetType() const {
|
|
|
|
return type_;
|
2016-06-08 18:41:14 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 08:16:10 +00:00
|
|
|
bool WebContents::Equal(const WebContents* web_contents) const {
|
|
|
|
return GetID() == web_contents->GetID();
|
|
|
|
}
|
|
|
|
|
2014-11-06 19:29:41 +00:00
|
|
|
void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
2017-01-21 09:29:20 +00:00
|
|
|
if (!url.is_valid() || url.spec().size() > url::kMaxURLChars) {
|
2016-02-11 02:54:50 +00:00
|
|
|
Emit("did-fail-load",
|
|
|
|
static_cast<int>(net::ERR_INVALID_URL),
|
|
|
|
net::ErrorToShortString(net::ERR_INVALID_URL),
|
2016-04-05 02:24:58 +00:00
|
|
|
url.possibly_invalid_spec(),
|
|
|
|
true);
|
2016-02-11 02:54:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-25 04:52:30 +00:00
|
|
|
content::NavigationController::LoadURLParams params(url);
|
2014-11-06 19:29:41 +00:00
|
|
|
|
2014-11-12 02:28:50 +00:00
|
|
|
GURL http_referrer;
|
2015-06-09 01:27:57 +00:00
|
|
|
if (options.Get("httpReferrer", &http_referrer))
|
2014-11-12 02:28:50 +00:00
|
|
|
params.referrer = content::Referrer(http_referrer.GetAsReferrer(),
|
|
|
|
blink::WebReferrerPolicyDefault);
|
2014-11-06 19:29:41 +00:00
|
|
|
|
2015-05-06 04:01:41 +00:00
|
|
|
std::string user_agent;
|
2015-06-09 01:27:57 +00:00
|
|
|
if (options.Get("userAgent", &user_agent))
|
2016-06-22 06:57:51 +00:00
|
|
|
web_contents()->SetUserAgentOverride(user_agent);
|
2015-05-06 04:01:41 +00:00
|
|
|
|
2015-10-26 21:18:16 +00:00
|
|
|
std::string extra_headers;
|
|
|
|
if (options.Get("extraHeaders", &extra_headers))
|
|
|
|
params.extra_headers = extra_headers;
|
|
|
|
|
2016-10-09 23:30:38 +00:00
|
|
|
scoped_refptr<content::ResourceRequestBodyImpl> body;
|
|
|
|
if (options.Get("postData", &body)) {
|
|
|
|
params.post_data = body;
|
|
|
|
params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST;
|
|
|
|
}
|
|
|
|
|
2017-03-01 00:49:03 +00:00
|
|
|
GURL base_url_for_data_url;
|
|
|
|
if (options.Get("baseURLForDataURL", &base_url_for_data_url)) {
|
|
|
|
params.base_url_for_data_url = base_url_for_data_url;
|
|
|
|
params.load_type = content::NavigationController::LOAD_TYPE_DATA;
|
|
|
|
}
|
2017-03-02 18:50:48 +00:00
|
|
|
|
2014-12-07 15:43:26 +00:00
|
|
|
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
2015-04-26 13:31:48 +00:00
|
|
|
params.should_clear_history_list = true;
|
2014-04-25 04:52:30 +00:00
|
|
|
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
2016-04-03 01:37:48 +00:00
|
|
|
|
2017-02-19 20:43:17 +00:00
|
|
|
if (deferred_load_url_.id) {
|
|
|
|
deferred_load_url_.params = params;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
web_contents()->GetController().LoadURLWithParams(params);
|
2016-04-03 01:37:48 +00:00
|
|
|
// We have to call it right after LoadURL because the RenderViewHost is only
|
|
|
|
// created after loading a page.
|
2017-02-19 20:43:17 +00:00
|
|
|
SetBackgroundColor(web_contents());
|
2014-04-25 04:52:30 +00:00
|
|
|
}
|
|
|
|
|
2015-12-02 21:49:30 +00:00
|
|
|
void WebContents::DownloadURL(const GURL& url) {
|
|
|
|
auto browser_context = web_contents()->GetBrowserContext();
|
|
|
|
auto download_manager =
|
|
|
|
content::BrowserContext::GetDownloadManager(browser_context);
|
|
|
|
|
|
|
|
download_manager->DownloadUrl(
|
2016-09-06 08:24:37 +00:00
|
|
|
content::DownloadUrlParameters::CreateForWebContentsMainFrame(
|
|
|
|
web_contents(), url));
|
2015-12-02 21:49:30 +00:00
|
|
|
}
|
|
|
|
|
2015-09-15 01:17:45 +00:00
|
|
|
GURL WebContents::GetURL() const {
|
|
|
|
return web_contents()->GetURL();
|
|
|
|
}
|
|
|
|
|
2014-06-28 11:36:57 +00:00
|
|
|
base::string16 WebContents::GetTitle() const {
|
2014-04-25 05:10:16 +00:00
|
|
|
return web_contents()->GetTitle();
|
2014-04-24 09:00:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool WebContents::IsLoading() const {
|
2014-04-25 05:10:16 +00:00
|
|
|
return web_contents()->IsLoading();
|
2014-04-24 09:00:41 +00:00
|
|
|
}
|
|
|
|
|
2016-04-18 17:37:08 +00:00
|
|
|
bool WebContents::IsLoadingMainFrame() const {
|
2016-04-20 05:05:09 +00:00
|
|
|
// Comparing site instances works because Electron always creates a new site
|
|
|
|
// instance when navigating, regardless of origin. See AtomBrowserClient.
|
|
|
|
return (web_contents()->GetLastCommittedURL().is_empty() ||
|
|
|
|
web_contents()->GetSiteInstance() !=
|
|
|
|
web_contents()->GetPendingSiteInstance()) && IsLoading();
|
2016-04-18 17:37:08 +00:00
|
|
|
}
|
2014-04-24 09:00:41 +00:00
|
|
|
|
|
|
|
bool WebContents::IsWaitingForResponse() const {
|
2014-04-25 05:10:16 +00:00
|
|
|
return web_contents()->IsWaitingForResponse();
|
2014-04-24 09:00:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Stop() {
|
2014-04-25 05:10:16 +00:00
|
|
|
web_contents()->Stop();
|
2014-04-24 09:00:41 +00:00
|
|
|
}
|
|
|
|
|
2015-05-11 06:30:26 +00:00
|
|
|
void WebContents::GoBack() {
|
2015-05-11 06:40:40 +00:00
|
|
|
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
2015-05-11 06:30:26 +00:00
|
|
|
web_contents()->GetController().GoBack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::GoForward() {
|
2015-05-11 06:40:40 +00:00
|
|
|
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
2015-05-11 06:30:26 +00:00
|
|
|
web_contents()->GetController().GoForward();
|
|
|
|
}
|
|
|
|
|
2015-05-11 08:44:01 +00:00
|
|
|
void WebContents::GoToOffset(int offset) {
|
|
|
|
atom::AtomBrowserClient::SuppressRendererProcessRestartForOnce();
|
|
|
|
web_contents()->GetController().GoToOffset(offset);
|
|
|
|
}
|
|
|
|
|
2017-03-09 03:06:26 +00:00
|
|
|
const std::string WebContents::GetWebRTCIPHandlingPolicy() const {
|
2017-03-08 14:55:59 +00:00
|
|
|
return web_contents()->
|
|
|
|
GetMutableRendererPrefs()->webrtc_ip_handling_policy;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::SetWebRTCIPHandlingPolicy(
|
2017-03-09 03:06:26 +00:00
|
|
|
const std::string& webrtc_ip_handling_policy) {
|
2017-03-08 14:55:59 +00:00
|
|
|
if (GetWebRTCIPHandlingPolicy() == webrtc_ip_handling_policy)
|
|
|
|
return;
|
|
|
|
web_contents()->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
|
|
|
|
webrtc_ip_handling_policy;
|
|
|
|
|
|
|
|
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
|
|
|
|
if (host)
|
|
|
|
host->SyncRendererPrefs();
|
|
|
|
}
|
|
|
|
|
2014-04-24 09:00:41 +00:00
|
|
|
bool WebContents::IsCrashed() const {
|
2014-04-25 05:10:16 +00:00
|
|
|
return web_contents()->IsCrashed();
|
2014-04-24 09:00:41 +00:00
|
|
|
}
|
|
|
|
|
2016-06-22 06:57:51 +00:00
|
|
|
void WebContents::SetUserAgent(const std::string& user_agent,
|
|
|
|
mate::Arguments* args) {
|
2014-10-24 12:57:44 +00:00
|
|
|
web_contents()->SetUserAgentOverride(user_agent);
|
|
|
|
}
|
|
|
|
|
2015-07-22 04:25:10 +00:00
|
|
|
std::string WebContents::GetUserAgent() {
|
|
|
|
return web_contents()->GetUserAgentOverride();
|
|
|
|
}
|
|
|
|
|
2015-10-14 04:41:31 +00:00
|
|
|
bool WebContents::SavePage(const base::FilePath& full_file_path,
|
|
|
|
const content::SavePageType& save_type,
|
|
|
|
const SavePageHandler::SavePageCallback& callback) {
|
|
|
|
auto handler = new SavePageHandler(web_contents(), callback);
|
|
|
|
return handler->Handle(full_file_path, save_type);
|
|
|
|
}
|
|
|
|
|
2015-06-05 09:01:17 +00:00
|
|
|
void WebContents::OpenDevTools(mate::Arguments* args) {
|
2015-06-24 14:23:38 +00:00
|
|
|
if (type_ == REMOTE)
|
2015-06-05 07:41:03 +00:00
|
|
|
return;
|
2015-06-24 14:23:38 +00:00
|
|
|
|
2016-09-07 02:16:52 +00:00
|
|
|
if (!enable_devtools_)
|
2016-09-05 08:27:56 +00:00
|
|
|
return;
|
|
|
|
|
2016-04-19 12:42:05 +00:00
|
|
|
std::string state;
|
2016-05-17 13:39:18 +00:00
|
|
|
if (type_ == WEB_VIEW || !owner_window()) {
|
2016-04-19 12:42:05 +00:00
|
|
|
state = "detach";
|
2015-06-05 09:01:17 +00:00
|
|
|
} else if (args && args->Length() == 1) {
|
2016-04-19 12:42:05 +00:00
|
|
|
bool detach = false;
|
2015-06-05 09:01:17 +00:00
|
|
|
mate::Dictionary options;
|
2016-04-19 12:42:05 +00:00
|
|
|
if (args->GetNext(&options)) {
|
|
|
|
options.Get("mode", &state);
|
2016-09-07 18:21:13 +00:00
|
|
|
|
|
|
|
// TODO(kevinsawicki) Remove in 2.0
|
2016-04-19 12:42:05 +00:00
|
|
|
options.Get("detach", &detach);
|
|
|
|
if (state.empty() && detach)
|
|
|
|
state = "detach";
|
|
|
|
}
|
2015-06-05 09:01:17 +00:00
|
|
|
}
|
2016-04-19 12:42:05 +00:00
|
|
|
managed_web_contents()->SetDockState(state);
|
2015-06-25 06:32:38 +00:00
|
|
|
managed_web_contents()->ShowDevTools();
|
2014-11-02 14:34:22 +00:00
|
|
|
}
|
|
|
|
|
2014-11-03 14:12:56 +00:00
|
|
|
void WebContents::CloseDevTools() {
|
2015-06-24 14:23:38 +00:00
|
|
|
if (type_ == REMOTE)
|
2015-06-05 07:41:03 +00:00
|
|
|
return;
|
2015-06-24 14:23:38 +00:00
|
|
|
|
2015-06-25 06:32:38 +00:00
|
|
|
managed_web_contents()->CloseDevTools();
|
2014-11-03 14:12:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool WebContents::IsDevToolsOpened() {
|
2015-06-24 14:23:38 +00:00
|
|
|
if (type_ == REMOTE)
|
2015-06-05 07:41:03 +00:00
|
|
|
return false;
|
2015-06-25 06:32:38 +00:00
|
|
|
|
|
|
|
return managed_web_contents()->IsDevToolsViewShowing();
|
2014-11-03 14:12:56 +00:00
|
|
|
}
|
|
|
|
|
2016-01-01 05:11:21 +00:00
|
|
|
bool WebContents::IsDevToolsFocused() {
|
|
|
|
if (type_ == REMOTE)
|
|
|
|
return false;
|
2016-01-01 09:45:03 +00:00
|
|
|
|
2016-01-01 05:11:21 +00:00
|
|
|
return managed_web_contents()->GetView()->IsDevToolsViewFocused();
|
|
|
|
}
|
|
|
|
|
2015-09-18 03:06:38 +00:00
|
|
|
void WebContents::EnableDeviceEmulation(
|
|
|
|
const blink::WebDeviceEmulationParams& params) {
|
2015-08-31 09:19:19 +00:00
|
|
|
if (type_ == REMOTE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Send(new ViewMsg_EnableDeviceEmulation(routing_id(), params));
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::DisableDeviceEmulation() {
|
|
|
|
if (type_ == REMOTE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Send(new ViewMsg_DisableDeviceEmulation(routing_id()));
|
|
|
|
}
|
|
|
|
|
2015-06-05 09:01:17 +00:00
|
|
|
void WebContents::ToggleDevTools() {
|
|
|
|
if (IsDevToolsOpened())
|
|
|
|
CloseDevTools();
|
|
|
|
else
|
|
|
|
OpenDevTools(nullptr);
|
|
|
|
}
|
|
|
|
|
2015-04-22 07:30:10 +00:00
|
|
|
void WebContents::InspectElement(int x, int y) {
|
2015-06-24 14:23:38 +00:00
|
|
|
if (type_ == REMOTE)
|
2015-06-05 07:41:03 +00:00
|
|
|
return;
|
2015-06-24 14:23:38 +00:00
|
|
|
|
2016-09-07 02:16:52 +00:00
|
|
|
if (!enable_devtools_)
|
2016-09-06 09:53:42 +00:00
|
|
|
return;
|
|
|
|
|
2016-08-23 22:26:13 +00:00
|
|
|
if (!managed_web_contents()->GetDevToolsWebContents())
|
|
|
|
OpenDevTools(nullptr);
|
2016-12-20 00:25:32 +00:00
|
|
|
managed_web_contents()->InspectElement(x, y);
|
2015-04-22 07:30:10 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 07:41:03 +00:00
|
|
|
void WebContents::InspectServiceWorker() {
|
2015-06-24 14:23:38 +00:00
|
|
|
if (type_ == REMOTE)
|
2015-06-05 07:41:03 +00:00
|
|
|
return;
|
2015-06-24 14:23:38 +00:00
|
|
|
|
2016-09-07 02:16:52 +00:00
|
|
|
if (!enable_devtools_)
|
2016-09-06 09:53:42 +00:00
|
|
|
return;
|
|
|
|
|
2015-06-05 07:41:03 +00:00
|
|
|
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
|
|
|
if (agent_host->GetType() ==
|
2017-01-24 07:50:02 +00:00
|
|
|
content::DevToolsAgentHost::kTypeServiceWorker) {
|
2015-06-05 09:01:17 +00:00
|
|
|
OpenDevTools(nullptr);
|
2015-06-25 06:32:38 +00:00
|
|
|
managed_web_contents()->AttachTo(agent_host);
|
2015-06-05 07:41:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-06-15 13:40:49 +00:00
|
|
|
void WebContents::SetAudioMuted(bool muted) {
|
|
|
|
web_contents()->SetAudioMuted(muted);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WebContents::IsAudioMuted() {
|
|
|
|
return web_contents()->IsAudioMuted();
|
|
|
|
}
|
|
|
|
|
2015-06-13 13:23:45 +00:00
|
|
|
void WebContents::Print(mate::Arguments* args) {
|
|
|
|
PrintSettings settings = { false, false };
|
|
|
|
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
|
|
|
args->ThrowError();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
printing::PrintViewManagerBasic::FromWebContents(web_contents())->
|
2017-01-31 05:22:18 +00:00
|
|
|
PrintNow(web_contents()->GetMainFrame(),
|
|
|
|
settings.silent,
|
|
|
|
settings.print_background);
|
2015-06-13 13:23:45 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 03:34:16 +00:00
|
|
|
void WebContents::PrintToPDF(const base::DictionaryValue& setting,
|
2015-06-13 08:02:16 +00:00
|
|
|
const PrintToPDFCallback& callback) {
|
2015-06-09 05:07:40 +00:00
|
|
|
printing::PrintPreviewMessageHandler::FromWebContents(web_contents())->
|
2015-06-10 03:34:16 +00:00
|
|
|
PrintToPDF(setting, callback);
|
2015-06-09 05:07:40 +00:00
|
|
|
}
|
|
|
|
|
2015-09-07 08:12:31 +00:00
|
|
|
void WebContents::AddWorkSpace(mate::Arguments* args,
|
|
|
|
const base::FilePath& path) {
|
2015-07-24 09:39:11 +00:00
|
|
|
if (path.empty()) {
|
2015-09-07 08:12:31 +00:00
|
|
|
args->ThrowError("path cannot be empty");
|
2015-07-24 09:39:11 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
DevToolsAddFileSystem(path);
|
|
|
|
}
|
|
|
|
|
2015-09-07 08:12:31 +00:00
|
|
|
void WebContents::RemoveWorkSpace(mate::Arguments* args,
|
|
|
|
const base::FilePath& path) {
|
2015-07-24 09:39:11 +00:00
|
|
|
if (path.empty()) {
|
2015-09-07 08:12:31 +00:00
|
|
|
args->ThrowError("path cannot be empty");
|
2015-07-24 09:39:11 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
DevToolsRemoveFileSystem(path);
|
|
|
|
}
|
|
|
|
|
2015-01-19 20:09:47 +00:00
|
|
|
void WebContents::Undo() {
|
|
|
|
web_contents()->Undo();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Redo() {
|
|
|
|
web_contents()->Redo();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Cut() {
|
|
|
|
web_contents()->Cut();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Copy() {
|
|
|
|
web_contents()->Copy();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Paste() {
|
|
|
|
web_contents()->Paste();
|
|
|
|
}
|
|
|
|
|
2015-05-15 07:15:19 +00:00
|
|
|
void WebContents::PasteAndMatchStyle() {
|
|
|
|
web_contents()->PasteAndMatchStyle();
|
|
|
|
}
|
|
|
|
|
2015-01-19 20:09:47 +00:00
|
|
|
void WebContents::Delete() {
|
|
|
|
web_contents()->Delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::SelectAll() {
|
|
|
|
web_contents()->SelectAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Unselect() {
|
|
|
|
web_contents()->Unselect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::Replace(const base::string16& word) {
|
|
|
|
web_contents()->Replace(word);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::ReplaceMisspelling(const base::string16& word) {
|
|
|
|
web_contents()->ReplaceMisspelling(word);
|
|
|
|
}
|
|
|
|
|
2016-03-08 04:40:10 +00:00
|
|
|
uint32_t WebContents::FindInPage(mate::Arguments* args) {
|
|
|
|
uint32_t request_id = GetNextRequestId();
|
2015-12-17 17:27:56 +00:00
|
|
|
base::string16 search_text;
|
|
|
|
blink::WebFindOptions options;
|
2015-12-17 23:10:42 +00:00
|
|
|
if (!args->GetNext(&search_text) || search_text.empty()) {
|
2015-12-17 17:27:56 +00:00
|
|
|
args->ThrowError("Must provide a non-empty search content");
|
2015-12-17 23:10:42 +00:00
|
|
|
return 0;
|
2015-12-17 17:27:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
args->GetNext(&options);
|
|
|
|
|
|
|
|
web_contents()->Find(request_id, search_text, options);
|
2015-12-17 23:10:42 +00:00
|
|
|
return request_id;
|
2015-12-17 17:27:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::StopFindInPage(content::StopFindAction action) {
|
|
|
|
web_contents()->StopFinding(action);
|
|
|
|
}
|
|
|
|
|
2016-06-02 17:12:38 +00:00
|
|
|
void WebContents::ShowDefinitionForSelection() {
|
2016-06-07 20:20:06 +00:00
|
|
|
#if defined(OS_MACOSX)
|
2016-06-02 17:12:38 +00:00
|
|
|
const auto view = web_contents()->GetRenderWidgetHostView();
|
|
|
|
if (view)
|
|
|
|
view->ShowDefinitionForSelection();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-07-26 19:06:11 +00:00
|
|
|
void WebContents::CopyImageAt(int x, int y) {
|
2016-09-06 08:24:37 +00:00
|
|
|
const auto host = web_contents()->GetMainFrame();
|
2016-07-26 19:06:11 +00:00
|
|
|
if (host)
|
|
|
|
host->CopyImageAt(x, y);
|
|
|
|
}
|
|
|
|
|
2015-07-24 04:58:28 +00:00
|
|
|
void WebContents::Focus() {
|
|
|
|
web_contents()->Focus();
|
|
|
|
}
|
|
|
|
|
2016-08-03 03:29:55 +00:00
|
|
|
#if !defined(OS_MACOSX)
|
|
|
|
bool WebContents::IsFocused() const {
|
|
|
|
auto view = web_contents()->GetRenderWidgetHostView();
|
2016-08-15 21:13:24 +00:00
|
|
|
if (!view) return false;
|
|
|
|
|
|
|
|
if (GetType() != BACKGROUND_PAGE) {
|
2016-08-23 17:12:55 +00:00
|
|
|
auto window = web_contents()->GetNativeView()->GetToplevelWindow();
|
2016-08-15 21:13:24 +00:00
|
|
|
if (window && !window->IsVisible())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return view->HasFocus();
|
2016-08-03 03:29:55 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-07-24 04:58:28 +00:00
|
|
|
void WebContents::TabTraverse(bool reverse) {
|
|
|
|
web_contents()->FocusThroughTabTraversal(reverse);
|
|
|
|
}
|
|
|
|
|
2016-05-29 03:10:32 +00:00
|
|
|
bool WebContents::SendIPCMessage(bool all_frames,
|
|
|
|
const base::string16& channel,
|
2014-04-25 05:10:16 +00:00
|
|
|
const base::ListValue& args) {
|
2016-05-29 03:10:32 +00:00
|
|
|
return Send(new AtomViewMsg_Message(routing_id(), all_frames, channel, args));
|
2014-04-25 05:10:16 +00:00
|
|
|
}
|
|
|
|
|
2015-09-18 06:20:31 +00:00
|
|
|
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
|
|
|
v8::Local<v8::Value> input_event) {
|
|
|
|
const auto view = web_contents()->GetRenderWidgetHostView();
|
|
|
|
if (!view)
|
|
|
|
return;
|
|
|
|
const auto host = view->GetRenderWidgetHost();
|
|
|
|
if (!host)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int type = mate::GetWebInputEventType(isolate, input_event);
|
|
|
|
if (blink::WebInputEvent::isMouseEventType(type)) {
|
|
|
|
blink::WebMouseEvent mouse_event;
|
|
|
|
if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
|
|
|
|
host->ForwardMouseEvent(mouse_event);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (blink::WebInputEvent::isKeyboardEventType(type)) {
|
2016-01-11 00:11:40 +00:00
|
|
|
content::NativeWebKeyboardEvent keyboard_event;
|
2015-09-18 06:20:31 +00:00
|
|
|
if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
|
|
|
|
host->ForwardKeyboardEvent(keyboard_event);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (type == blink::WebInputEvent::MouseWheel) {
|
|
|
|
blink::WebMouseWheelEvent mouse_wheel_event;
|
|
|
|
if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
|
|
|
|
host->ForwardWheelEvent(mouse_wheel_event);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
2015-09-18 10:21:51 +00:00
|
|
|
isolate, "Invalid event object")));
|
2015-09-18 06:20:31 +00:00
|
|
|
}
|
|
|
|
|
2016-06-26 02:46:40 +00:00
|
|
|
void WebContents::BeginFrameSubscription(mate::Arguments* args) {
|
2016-06-25 16:23:40 +00:00
|
|
|
bool only_dirty = false;
|
2016-06-26 02:46:40 +00:00
|
|
|
FrameSubscriber::FrameCaptureCallback callback;
|
2016-06-21 00:15:39 +00:00
|
|
|
|
2016-06-26 02:46:40 +00:00
|
|
|
args->GetNext(&only_dirty);
|
2016-06-25 16:23:40 +00:00
|
|
|
if (!args->GetNext(&callback)) {
|
2016-06-26 02:46:40 +00:00
|
|
|
args->ThrowError();
|
|
|
|
return;
|
2016-06-25 16:23:40 +00:00
|
|
|
}
|
2016-06-21 00:15:39 +00:00
|
|
|
|
2015-09-18 07:57:43 +00:00
|
|
|
const auto view = web_contents()->GetRenderWidgetHostView();
|
|
|
|
if (view) {
|
2016-07-29 12:50:27 +00:00
|
|
|
std::unique_ptr<FrameSubscriber> frame_subscriber(new FrameSubscriber(
|
|
|
|
isolate(), view, callback, only_dirty));
|
|
|
|
view->BeginFrameSubscription(std::move(frame_subscriber));
|
2015-09-18 07:57:43 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-18 06:20:31 +00:00
|
|
|
|
2015-09-18 07:57:43 +00:00
|
|
|
void WebContents::EndFrameSubscription() {
|
|
|
|
const auto view = web_contents()->GetRenderWidgetHostView();
|
|
|
|
if (view)
|
|
|
|
view->EndFrameSubscription();
|
|
|
|
}
|
2015-09-18 06:20:31 +00:00
|
|
|
|
2016-07-03 04:58:31 +00:00
|
|
|
void WebContents::StartDrag(const mate::Dictionary& item,
|
|
|
|
mate::Arguments* args) {
|
|
|
|
base::FilePath file;
|
|
|
|
std::vector<base::FilePath> files;
|
|
|
|
if (!item.Get("files", &files) && item.Get("file", &file)) {
|
|
|
|
files.push_back(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
mate::Handle<NativeImage> icon;
|
|
|
|
if (!item.Get("icon", &icon) && !file.empty()) {
|
|
|
|
// TODO(zcbenz): Set default icon from file.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error checking.
|
|
|
|
if (icon.IsEmpty()) {
|
2017-01-26 18:38:13 +00:00
|
|
|
args->ThrowError("Must specify 'icon' option");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(OS_MACOSX)
|
|
|
|
// NSWindow.dragImage requires a non-empty NSImage
|
|
|
|
if (icon->image().IsEmpty()) {
|
2017-01-26 18:34:27 +00:00
|
|
|
args->ThrowError("Must specify non-empty 'icon' option");
|
2016-07-03 04:58:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-26 18:38:13 +00:00
|
|
|
#endif
|
2016-07-03 04:58:31 +00:00
|
|
|
|
|
|
|
// Start dragging.
|
|
|
|
if (!files.empty()) {
|
2016-07-03 06:30:27 +00:00
|
|
|
base::MessageLoop::ScopedNestableTaskAllower allow(
|
|
|
|
base::MessageLoop::current());
|
2016-07-03 04:58:31 +00:00
|
|
|
DragFileItems(files, icon->image(), web_contents()->GetNativeView());
|
|
|
|
} else {
|
2017-01-26 18:34:27 +00:00
|
|
|
args->ThrowError("Must specify either 'file' or 'files' option");
|
2016-07-03 04:58:31 +00:00
|
|
|
}
|
2016-07-03 03:26:43 +00:00
|
|
|
}
|
|
|
|
|
2016-07-05 22:43:57 +00:00
|
|
|
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 =
|
2016-07-21 12:03:38 +00:00
|
|
|
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
2016-07-05 22:43:57 +00:00
|
|
|
.device_scale_factor();
|
|
|
|
if (scale > 1.0f)
|
|
|
|
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
|
|
|
|
2016-07-06 16:42:43 +00:00
|
|
|
host->CopyFromBackingStore(gfx::Rect(rect.origin(), view_size),
|
|
|
|
bitmap_size,
|
|
|
|
base::Bind(&OnCapturePageDone, callback),
|
|
|
|
kBGRA_8888_SkColorType);
|
2016-07-05 22:43:57 +00:00
|
|
|
}
|
|
|
|
|
2016-01-30 05:33:55 +00:00
|
|
|
void WebContents::OnCursorChange(const content::WebCursor& cursor) {
|
2016-02-01 06:17:58 +00:00
|
|
|
content::WebCursor::CursorInfo info;
|
|
|
|
cursor.GetCursorInfo(&info);
|
2016-01-31 16:00:14 +00:00
|
|
|
|
|
|
|
if (cursor.IsCustom()) {
|
|
|
|
Emit("cursor-changed", CursorTypeToString(info),
|
2016-02-01 06:17:58 +00:00
|
|
|
gfx::Image::CreateFrom1xBitmap(info.custom_image),
|
2016-08-01 00:13:31 +00:00
|
|
|
info.image_scale_factor,
|
|
|
|
gfx::Size(info.custom_image.width(), info.custom_image.height()),
|
|
|
|
info.hotspot);
|
2016-01-31 16:00:14 +00:00
|
|
|
} else {
|
|
|
|
Emit("cursor-changed", CursorTypeToString(info));
|
|
|
|
}
|
2016-01-30 05:33:55 +00:00
|
|
|
}
|
2016-07-18 06:54:52 +00:00
|
|
|
|
2015-05-29 03:12:55 +00:00
|
|
|
void WebContents::SetSize(const SetSizeParams& params) {
|
2015-06-25 06:28:13 +00:00
|
|
|
if (guest_delegate_)
|
|
|
|
guest_delegate_->SetSize(params);
|
2014-10-24 06:37:14 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 07:18:15 +00:00
|
|
|
bool WebContents::IsGuest() const {
|
2015-06-24 14:23:38 +00:00
|
|
|
return type_ == WEB_VIEW;
|
2015-06-05 07:18:15 +00:00
|
|
|
}
|
|
|
|
|
2016-07-28 10:10:56 +00:00
|
|
|
bool WebContents::IsOffScreen() const {
|
|
|
|
return type_ == OFF_SCREEN;
|
|
|
|
}
|
|
|
|
|
2016-08-04 04:47:52 +00:00
|
|
|
void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {
|
|
|
|
mate::Handle<NativeImage> image =
|
|
|
|
NativeImage::Create(isolate(), gfx::Image::CreateFrom1xBitmap(bitmap));
|
|
|
|
Emit("paint", dirty_rect, image);
|
2016-08-03 03:29:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::StartPainting() {
|
|
|
|
if (!IsOffScreen())
|
|
|
|
return;
|
|
|
|
|
2016-08-03 04:04:36 +00:00
|
|
|
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
2016-08-03 03:29:55 +00:00
|
|
|
web_contents()->GetRenderWidgetHostView());
|
2016-08-05 02:35:04 +00:00
|
|
|
if (osr_rwhv)
|
2016-08-04 03:18:27 +00:00
|
|
|
osr_rwhv->SetPainting(true);
|
2016-08-03 03:29:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::StopPainting() {
|
|
|
|
if (!IsOffScreen())
|
|
|
|
return;
|
|
|
|
|
2016-08-03 04:04:36 +00:00
|
|
|
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
2016-08-03 03:29:55 +00:00
|
|
|
web_contents()->GetRenderWidgetHostView());
|
2016-08-05 02:35:04 +00:00
|
|
|
if (osr_rwhv)
|
2016-08-03 03:29:55 +00:00
|
|
|
osr_rwhv->SetPainting(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WebContents::IsPainting() const {
|
|
|
|
if (!IsOffScreen())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
|
|
|
web_contents()->GetRenderWidgetHostView());
|
|
|
|
return osr_rwhv && osr_rwhv->IsPainting();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::SetFrameRate(int frame_rate) {
|
|
|
|
if (!IsOffScreen())
|
|
|
|
return;
|
|
|
|
|
2016-08-03 04:04:36 +00:00
|
|
|
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
2016-08-03 03:29:55 +00:00
|
|
|
web_contents()->GetRenderWidgetHostView());
|
|
|
|
if (osr_rwhv)
|
|
|
|
osr_rwhv->SetFrameRate(frame_rate);
|
|
|
|
}
|
|
|
|
|
|
|
|
int WebContents::GetFrameRate() const {
|
|
|
|
if (!IsOffScreen())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
|
|
|
web_contents()->GetRenderWidgetHostView());
|
|
|
|
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
|
|
|
|
}
|
|
|
|
|
2016-09-01 17:25:12 +00:00
|
|
|
void WebContents::Invalidate() {
|
2017-02-08 07:08:03 +00:00
|
|
|
if (IsOffScreen()) {
|
|
|
|
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
2016-09-01 17:25:12 +00:00
|
|
|
web_contents()->GetRenderWidgetHostView());
|
2017-02-08 07:08:03 +00:00
|
|
|
if (osr_rwhv)
|
|
|
|
osr_rwhv->Invalidate();
|
2017-02-08 08:05:16 +00:00
|
|
|
} else {
|
2017-02-14 20:30:23 +00:00
|
|
|
const auto window = owner_window();
|
|
|
|
if (window)
|
|
|
|
window->Invalidate();
|
2017-02-08 07:08:03 +00:00
|
|
|
}
|
2016-09-01 17:25:12 +00:00
|
|
|
}
|
2016-08-03 03:29:55 +00:00
|
|
|
|
2017-01-29 14:13:20 +00:00
|
|
|
void WebContents::SetZoomLevel(double level) {
|
2017-01-30 11:18:40 +00:00
|
|
|
zoom_controller_->SetZoomLevel(level);
|
2017-01-29 14:13:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double WebContents::GetZoomLevel() {
|
2017-01-30 11:18:40 +00:00
|
|
|
return zoom_controller_->GetZoomLevel();
|
2017-01-29 14:13:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::SetZoomFactor(double factor) {
|
|
|
|
auto level = content::ZoomFactorToZoomLevel(factor);
|
|
|
|
SetZoomLevel(level);
|
|
|
|
}
|
|
|
|
|
|
|
|
double WebContents::GetZoomFactor() {
|
|
|
|
auto level = GetZoomLevel();
|
|
|
|
return content::ZoomLevelToZoomFactor(level);
|
|
|
|
}
|
|
|
|
|
2017-01-30 17:06:50 +00:00
|
|
|
void WebContents::OnSetTemporaryZoomLevel(double level,
|
|
|
|
IPC::Message* reply_msg) {
|
|
|
|
zoom_controller_->SetTemporaryZoomLevel(level);
|
2017-01-31 09:15:45 +00:00
|
|
|
double new_level = zoom_controller_->GetZoomLevel();
|
2017-01-30 17:06:50 +00:00
|
|
|
AtomViewHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg, new_level);
|
|
|
|
Send(reply_msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebContents::OnGetZoomLevel(IPC::Message* reply_msg) {
|
|
|
|
AtomViewHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
|
|
|
|
Send(reply_msg);
|
|
|
|
}
|
|
|
|
|
2015-09-22 13:56:56 +00:00
|
|
|
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
|
|
|
WebContentsPreferences* web_preferences =
|
|
|
|
WebContentsPreferences::FromWebContents(web_contents());
|
|
|
|
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
|
|
|
|
}
|
|
|
|
|
2015-10-01 05:45:59 +00:00
|
|
|
v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
|
|
|
|
if (owner_window())
|
|
|
|
return Window::From(isolate(), owner_window());
|
|
|
|
else
|
|
|
|
return v8::Null(isolate());
|
|
|
|
}
|
|
|
|
|
2016-05-17 12:56:47 +00:00
|
|
|
int32_t WebContents::ID() const {
|
|
|
|
return weak_map_id();
|
|
|
|
}
|
|
|
|
|
2015-10-01 03:14:19 +00:00
|
|
|
v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
|
|
|
|
return v8::Local<v8::Value>::New(isolate, session_);
|
|
|
|
}
|
|
|
|
|
2016-02-17 08:52:19 +00:00
|
|
|
content::WebContents* WebContents::HostWebContents() {
|
|
|
|
if (!embedder_)
|
|
|
|
return nullptr;
|
|
|
|
return embedder_->web_contents();
|
|
|
|
}
|
|
|
|
|
2016-09-08 17:01:01 +00:00
|
|
|
void WebContents::SetEmbedder(const WebContents* embedder) {
|
|
|
|
if (embedder) {
|
|
|
|
NativeWindow* owner_window = nullptr;
|
|
|
|
auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents());
|
|
|
|
if (relay) {
|
|
|
|
owner_window = relay->window.get();
|
|
|
|
}
|
|
|
|
if (owner_window)
|
|
|
|
SetOwnerWindow(owner_window);
|
|
|
|
|
|
|
|
content::RenderWidgetHostView* rwhv =
|
|
|
|
web_contents()->GetRenderWidgetHostView();
|
|
|
|
if (rwhv) {
|
|
|
|
rwhv->Hide();
|
|
|
|
rwhv->Show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-01 03:14:19 +00:00
|
|
|
v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
|
|
|
|
if (devtools_web_contents_.IsEmpty())
|
|
|
|
return v8::Null(isolate);
|
|
|
|
else
|
|
|
|
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
|
|
|
|
}
|
|
|
|
|
2016-01-21 18:22:23 +00:00
|
|
|
v8::Local<v8::Value> WebContents::Debugger(v8::Isolate* isolate) {
|
|
|
|
if (debugger_.IsEmpty()) {
|
|
|
|
auto handle = atom::api::Debugger::Create(isolate, web_contents());
|
|
|
|
debugger_.Reset(isolate, handle.ToV8());
|
|
|
|
}
|
|
|
|
return v8::Local<v8::Value>::New(isolate, debugger_);
|
|
|
|
}
|
|
|
|
|
2015-12-03 08:04:46 +00:00
|
|
|
// static
|
|
|
|
void WebContents::BuildPrototype(v8::Isolate* isolate,
|
2016-08-02 09:08:12 +00:00
|
|
|
v8::Local<v8::FunctionTemplate> prototype) {
|
2016-08-02 10:28:12 +00:00
|
|
|
prototype->SetClassName(mate::StringToV8(isolate, "WebContents"));
|
2016-08-02 09:08:12 +00:00
|
|
|
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
2015-12-03 08:04:46 +00:00
|
|
|
.MakeDestroyable()
|
|
|
|
.SetMethod("getId", &WebContents::GetID)
|
2016-09-06 01:28:40 +00:00
|
|
|
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
2017-04-18 10:31:20 +00:00
|
|
|
.SetMethod("getOSProcessId", &WebContents::GetOSProcessID)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("equal", &WebContents::Equal)
|
|
|
|
.SetMethod("_loadURL", &WebContents::LoadURL)
|
2015-12-03 18:31:51 +00:00
|
|
|
.SetMethod("downloadURL", &WebContents::DownloadURL)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("_getURL", &WebContents::GetURL)
|
|
|
|
.SetMethod("getTitle", &WebContents::GetTitle)
|
|
|
|
.SetMethod("isLoading", &WebContents::IsLoading)
|
2016-04-18 17:37:08 +00:00
|
|
|
.SetMethod("isLoadingMainFrame", &WebContents::IsLoadingMainFrame)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
|
|
|
|
.SetMethod("_stop", &WebContents::Stop)
|
|
|
|
.SetMethod("_goBack", &WebContents::GoBack)
|
|
|
|
.SetMethod("_goForward", &WebContents::GoForward)
|
|
|
|
.SetMethod("_goToOffset", &WebContents::GoToOffset)
|
|
|
|
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
|
|
|
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
|
|
|
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
|
|
|
|
.SetMethod("savePage", &WebContents::SavePage)
|
|
|
|
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
|
|
|
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
|
|
|
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
2016-01-01 05:11:21 +00:00
|
|
|
.SetMethod("isDevToolsFocused", &WebContents::IsDevToolsFocused)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("enableDeviceEmulation",
|
|
|
|
&WebContents::EnableDeviceEmulation)
|
|
|
|
.SetMethod("disableDeviceEmulation",
|
|
|
|
&WebContents::DisableDeviceEmulation)
|
|
|
|
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
|
|
|
|
.SetMethod("inspectElement", &WebContents::InspectElement)
|
|
|
|
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
|
|
|
|
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
|
|
|
|
.SetMethod("undo", &WebContents::Undo)
|
|
|
|
.SetMethod("redo", &WebContents::Redo)
|
|
|
|
.SetMethod("cut", &WebContents::Cut)
|
|
|
|
.SetMethod("copy", &WebContents::Copy)
|
|
|
|
.SetMethod("paste", &WebContents::Paste)
|
|
|
|
.SetMethod("pasteAndMatchStyle", &WebContents::PasteAndMatchStyle)
|
|
|
|
.SetMethod("delete", &WebContents::Delete)
|
|
|
|
.SetMethod("selectAll", &WebContents::SelectAll)
|
|
|
|
.SetMethod("unselect", &WebContents::Unselect)
|
|
|
|
.SetMethod("replace", &WebContents::Replace)
|
|
|
|
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
|
2015-12-17 17:27:56 +00:00
|
|
|
.SetMethod("findInPage", &WebContents::FindInPage)
|
|
|
|
.SetMethod("stopFindInPage", &WebContents::StopFindInPage)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("focus", &WebContents::Focus)
|
2016-08-03 03:29:55 +00:00
|
|
|
.SetMethod("isFocused", &WebContents::IsFocused)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("tabTraverse", &WebContents::TabTraverse)
|
|
|
|
.SetMethod("_send", &WebContents::SendIPCMessage)
|
|
|
|
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
|
|
|
|
.SetMethod("beginFrameSubscription",
|
|
|
|
&WebContents::BeginFrameSubscription)
|
|
|
|
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
2016-07-03 03:26:43 +00:00
|
|
|
.SetMethod("startDrag", &WebContents::StartDrag)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("setSize", &WebContents::SetSize)
|
|
|
|
.SetMethod("isGuest", &WebContents::IsGuest)
|
2016-08-03 03:29:55 +00:00
|
|
|
.SetMethod("isOffscreen", &WebContents::IsOffScreen)
|
|
|
|
.SetMethod("startPainting", &WebContents::StartPainting)
|
|
|
|
.SetMethod("stopPainting", &WebContents::StopPainting)
|
|
|
|
.SetMethod("isPainting", &WebContents::IsPainting)
|
|
|
|
.SetMethod("setFrameRate", &WebContents::SetFrameRate)
|
|
|
|
.SetMethod("getFrameRate", &WebContents::GetFrameRate)
|
2016-09-01 17:25:12 +00:00
|
|
|
.SetMethod("invalidate", &WebContents::Invalidate)
|
2017-01-29 14:13:20 +00:00
|
|
|
.SetMethod("setZoomLevel", &WebContents::SetZoomLevel)
|
2017-02-15 22:14:24 +00:00
|
|
|
.SetMethod("_getZoomLevel", &WebContents::GetZoomLevel)
|
2017-01-29 14:13:20 +00:00
|
|
|
.SetMethod("setZoomFactor", &WebContents::SetZoomFactor)
|
2017-02-15 22:14:24 +00:00
|
|
|
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
|
2016-06-08 18:41:14 +00:00
|
|
|
.SetMethod("getType", &WebContents::GetType)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
|
|
|
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
|
|
|
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
|
|
|
.SetMethod("unregisterServiceWorker",
|
|
|
|
&WebContents::UnregisterServiceWorker)
|
|
|
|
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
|
|
|
|
.SetMethod("print", &WebContents::Print)
|
|
|
|
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
|
|
|
|
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
|
|
|
|
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
|
2016-06-07 20:13:49 +00:00
|
|
|
.SetMethod("showDefinitionForSelection",
|
|
|
|
&WebContents::ShowDefinitionForSelection)
|
2016-07-26 19:06:11 +00:00
|
|
|
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
|
2016-07-05 22:43:57 +00:00
|
|
|
.SetMethod("capturePage", &WebContents::CapturePage)
|
2016-09-08 17:01:01 +00:00
|
|
|
.SetMethod("setEmbedder", &WebContents::SetEmbedder)
|
2017-03-08 14:55:59 +00:00
|
|
|
.SetMethod("setWebRTCIPHandlingPolicy",
|
|
|
|
&WebContents::SetWebRTCIPHandlingPolicy)
|
|
|
|
.SetMethod("getWebRTCIPHandlingPolicy",
|
|
|
|
&WebContents::GetWebRTCIPHandlingPolicy)
|
2016-05-17 12:56:47 +00:00
|
|
|
.SetProperty("id", &WebContents::ID)
|
2015-12-03 08:04:46 +00:00
|
|
|
.SetProperty("session", &WebContents::Session)
|
2016-02-17 08:52:19 +00:00
|
|
|
.SetProperty("hostWebContents", &WebContents::HostWebContents)
|
2016-01-21 18:22:23 +00:00
|
|
|
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
|
|
|
|
.SetProperty("debugger", &WebContents::Debugger);
|
2015-07-06 10:21:04 +00:00
|
|
|
}
|
|
|
|
|
2015-07-14 19:13:25 +00:00
|
|
|
AtomBrowserContext* WebContents::GetBrowserContext() const {
|
|
|
|
return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
|
|
|
|
}
|
|
|
|
|
2014-06-28 11:36:57 +00:00
|
|
|
void WebContents::OnRendererMessage(const base::string16& channel,
|
2014-04-25 08:13:16 +00:00
|
|
|
const base::ListValue& args) {
|
|
|
|
// webContents.emit(channel, new Event(), args...);
|
2014-10-24 06:37:14 +00:00
|
|
|
Emit(base::UTF16ToUTF8(channel), args);
|
2014-04-25 08:13:16 +00:00
|
|
|
}
|
|
|
|
|
2014-06-28 11:36:57 +00:00
|
|
|
void WebContents::OnRendererMessageSync(const base::string16& channel,
|
2014-04-25 08:13:16 +00:00
|
|
|
const base::ListValue& args,
|
|
|
|
IPC::Message* message) {
|
|
|
|
// webContents.emit(channel, new Event(sender, message), args...);
|
2015-01-15 01:51:54 +00:00
|
|
|
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
2014-04-24 08:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
2014-10-23 06:04:13 +00:00
|
|
|
mate::Handle<WebContents> WebContents::CreateFrom(
|
2014-04-24 08:45:25 +00:00
|
|
|
v8::Isolate* isolate, content::WebContents* web_contents) {
|
2015-06-24 07:09:50 +00:00
|
|
|
// We have an existing WebContents object in JS.
|
|
|
|
auto existing = TrackableObject::FromWrappedClass(isolate, web_contents);
|
|
|
|
if (existing)
|
|
|
|
return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
|
|
|
|
|
|
|
|
// Otherwise create a new WebContents wrapper object.
|
2016-08-17 00:15:10 +00:00
|
|
|
return mate::CreateHandle(isolate, new WebContents(isolate, web_contents,
|
|
|
|
REMOTE));
|
|
|
|
}
|
|
|
|
|
|
|
|
mate::Handle<WebContents> WebContents::CreateFrom(
|
|
|
|
v8::Isolate* isolate, content::WebContents* web_contents, Type type) {
|
|
|
|
// Otherwise create a new WebContents wrapper object.
|
|
|
|
return mate::CreateHandle(isolate, new WebContents(isolate, web_contents,
|
|
|
|
type));
|
2014-04-24 08:45:25 +00:00
|
|
|
}
|
|
|
|
|
2014-10-23 06:04:13 +00:00
|
|
|
// static
|
|
|
|
mate::Handle<WebContents> WebContents::Create(
|
|
|
|
v8::Isolate* isolate, const mate::Dictionary& options) {
|
2016-08-02 11:38:35 +00:00
|
|
|
return mate::CreateHandle(isolate, new WebContents(isolate, options));
|
2014-10-23 06:04:13 +00:00
|
|
|
}
|
|
|
|
|
2014-04-24 08:45:25 +00:00
|
|
|
} // namespace api
|
|
|
|
|
|
|
|
} // namespace atom
|
2014-10-23 06:04:13 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2016-08-02 11:38:35 +00:00
|
|
|
using atom::api::WebContents;
|
|
|
|
|
2015-05-22 11:11:22 +00:00
|
|
|
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
|
|
|
v8::Local<v8::Context> context, void* priv) {
|
2014-10-23 06:04:13 +00:00
|
|
|
v8::Isolate* isolate = context->GetIsolate();
|
|
|
|
mate::Dictionary dict(isolate, exports);
|
2016-08-02 11:38:35 +00:00
|
|
|
dict.Set("WebContents", WebContents::GetConstructor(isolate)->GetFunction());
|
|
|
|
dict.SetMethod("create", &WebContents::Create);
|
|
|
|
dict.SetMethod("fromId", &mate::TrackableObject<WebContents>::FromWeakMapID);
|
2016-06-07 17:52:03 +00:00
|
|
|
dict.SetMethod("getAllWebContents",
|
2016-08-02 11:38:35 +00:00
|
|
|
&mate::TrackableObject<WebContents>::GetAll);
|
2014-10-23 06:04:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_contents, Initialize)
|