Attach <webview> with guest WebContents
This commit is contained in:
parent
2d8fe489a7
commit
39e75574f4
8 changed files with 126 additions and 28 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
|
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
|
@ -31,11 +32,13 @@ v8::Persistent<v8::ObjectTemplate> template_;
|
||||||
|
|
||||||
WebContents::WebContents(content::WebContents* web_contents)
|
WebContents::WebContents(content::WebContents* web_contents)
|
||||||
: content::WebContentsObserver(web_contents),
|
: content::WebContentsObserver(web_contents),
|
||||||
guest_instance_id_(-1) {
|
guest_instance_id_(-1),
|
||||||
|
auto_size_enabled_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
WebContents::WebContents(const mate::Dictionary& options)
|
WebContents::WebContents(const mate::Dictionary& options)
|
||||||
: guest_instance_id_(-1) {
|
: guest_instance_id_(-1),
|
||||||
|
auto_size_enabled_(false) {
|
||||||
options.Get("guestInstances", &guest_instance_id_);
|
options.Get("guestInstances", &guest_instance_id_);
|
||||||
|
|
||||||
content::WebContents::CreateParams params(AtomBrowserContext::Get());
|
content::WebContents::CreateParams params(AtomBrowserContext::Get());
|
||||||
|
@ -106,17 +109,19 @@ void WebContents::WebContentsDestroyed() {
|
||||||
|
|
||||||
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
|
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
|
||||||
const base::DictionaryValue& extra_params) {
|
const base::DictionaryValue& extra_params) {
|
||||||
LOG(ERROR) << "WillAttach";
|
embedder_web_contents_ = embedder_web_contents;
|
||||||
|
extra_params_.reset(extra_params.DeepCopy());
|
||||||
}
|
}
|
||||||
|
|
||||||
content::WebContents* WebContents::CreateNewGuestWindow(
|
content::WebContents* WebContents::CreateNewGuestWindow(
|
||||||
const content::WebContents::CreateParams& create_params) {
|
const content::WebContents::CreateParams& create_params) {
|
||||||
LOG(ERROR) << "CreateNewGuestWindow";
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::DidAttach() {
|
void WebContents::DidAttach() {
|
||||||
LOG(ERROR) << "DidAttach";
|
base::ListValue args;
|
||||||
|
args.Append(extra_params_.release());
|
||||||
|
Emit("internal-did-attach", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebContents::GetGuestInstanceID() const {
|
int WebContents::GetGuestInstanceID() const {
|
||||||
|
@ -125,29 +130,30 @@ int WebContents::GetGuestInstanceID() const {
|
||||||
|
|
||||||
void WebContents::ElementSizeChanged(const gfx::Size& old_size,
|
void WebContents::ElementSizeChanged(const gfx::Size& old_size,
|
||||||
const gfx::Size& new_size) {
|
const gfx::Size& new_size) {
|
||||||
LOG(ERROR) << "ElementSizeChanged";
|
element_size_ = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::GuestSizeChanged(const gfx::Size& old_size,
|
void WebContents::GuestSizeChanged(const gfx::Size& old_size,
|
||||||
const gfx::Size& new_size) {
|
const gfx::Size& new_size) {
|
||||||
LOG(ERROR) << "GuestSizeChanged";
|
if (!auto_size_enabled_)
|
||||||
|
return;
|
||||||
|
guest_size_ = new_size;
|
||||||
|
GuestSizeChangedDueToAutoSize(old_size, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::RequestPointerLockPermission(
|
void WebContents::RequestPointerLockPermission(
|
||||||
bool user_gesture,
|
bool user_gesture,
|
||||||
bool last_unlocked_by_target,
|
bool last_unlocked_by_target,
|
||||||
const base::Callback<void(bool)>& callback) {
|
const base::Callback<void(bool enabled)>& callback) {
|
||||||
callback.Run(true);
|
callback.Run(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::RegisterDestructionCallback(
|
void WebContents::RegisterDestructionCallback(
|
||||||
const DestructionCallback& callback) {
|
const DestructionCallback& callback) {
|
||||||
LOG(ERROR) << "RegisterDestructionCallback";
|
|
||||||
destruction_callback_ = callback;
|
destruction_callback_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::Destroy() {
|
void WebContents::Destroy() {
|
||||||
LOG(ERROR) << "Destroy";
|
|
||||||
if (storage_) {
|
if (storage_) {
|
||||||
if (!destruction_callback_.is_null())
|
if (!destruction_callback_.is_null())
|
||||||
destruction_callback_.Run();
|
destruction_callback_.Run();
|
||||||
|
@ -248,6 +254,33 @@ bool WebContents::SendIPCMessage(const base::string16& channel,
|
||||||
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
|
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::SetAutoSize(bool enabled,
|
||||||
|
const gfx::Size& min_size,
|
||||||
|
const gfx::Size& max_size) {
|
||||||
|
min_auto_size_ = min_size;
|
||||||
|
min_auto_size_.SetToMin(max_size);
|
||||||
|
max_auto_size_ = max_size;
|
||||||
|
max_auto_size_.SetToMax(min_size);
|
||||||
|
|
||||||
|
enabled &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
|
||||||
|
if (!enabled && !auto_size_enabled_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto_size_enabled_ = enabled;
|
||||||
|
|
||||||
|
if (!attached())
|
||||||
|
return;
|
||||||
|
|
||||||
|
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
|
||||||
|
if (auto_size_enabled_) {
|
||||||
|
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
|
||||||
|
} else {
|
||||||
|
rvh->DisableAutoResize(element_size_);
|
||||||
|
guest_size_ = element_size_;
|
||||||
|
GuestSizeChangedDueToAutoSize(guest_size_, element_size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
v8::Isolate* isolate) {
|
v8::Isolate* isolate) {
|
||||||
if (template_.IsEmpty())
|
if (template_.IsEmpty())
|
||||||
|
@ -274,6 +307,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
||||||
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||||
|
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
|
||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
return mate::ObjectTemplateBuilder(
|
return mate::ObjectTemplateBuilder(
|
||||||
|
@ -283,7 +317,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
void WebContents::OnRendererMessage(const base::string16& channel,
|
void WebContents::OnRendererMessage(const base::string16& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
// webContents.emit(channel, new Event(), args...);
|
// webContents.emit(channel, new Event(), args...);
|
||||||
Emit(base::UTF16ToUTF8(channel), args, web_contents(), NULL);
|
Emit(base::UTF16ToUTF8(channel), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::OnRendererMessageSync(const base::string16& channel,
|
void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||||
|
@ -293,6 +327,16 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||||
Emit(base::UTF16ToUTF8(channel), args, web_contents(), message);
|
Emit(base::UTF16ToUTF8(channel), args, web_contents(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||||
|
const gfx::Size& new_size) {
|
||||||
|
base::ListValue args;
|
||||||
|
args.AppendInteger(old_size.width());
|
||||||
|
args.AppendInteger(old_size.height());
|
||||||
|
args.AppendInteger(new_size.width());
|
||||||
|
args.AppendInteger(new_size.height());
|
||||||
|
Emit("size-changed", args);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||||
|
|
|
@ -56,6 +56,14 @@ class WebContents : public mate::EventEmitter,
|
||||||
bool SendIPCMessage(const base::string16& channel,
|
bool SendIPCMessage(const base::string16& channel,
|
||||||
const base::ListValue& args);
|
const base::ListValue& args);
|
||||||
|
|
||||||
|
// Toggles autosize mode for corresponding <webview>.
|
||||||
|
void SetAutoSize(bool enabled,
|
||||||
|
const gfx::Size& min_size,
|
||||||
|
const gfx::Size& max_size);
|
||||||
|
|
||||||
|
// Returns whether this guest has an associated embedder.
|
||||||
|
bool attached() const { return !!embedder_web_contents_; }
|
||||||
|
|
||||||
content::WebContents* web_contents() const {
|
content::WebContents* web_contents() const {
|
||||||
return content::WebContentsObserver::web_contents();
|
return content::WebContentsObserver::web_contents();
|
||||||
}
|
}
|
||||||
|
@ -96,7 +104,7 @@ class WebContents : public mate::EventEmitter,
|
||||||
virtual void RequestPointerLockPermission(
|
virtual void RequestPointerLockPermission(
|
||||||
bool user_gesture,
|
bool user_gesture,
|
||||||
bool last_unlocked_by_target,
|
bool last_unlocked_by_target,
|
||||||
const base::Callback<void(bool)>& callback) override;
|
const base::Callback<void(bool enabled)>& callback) override;
|
||||||
virtual void RegisterDestructionCallback(
|
virtual void RegisterDestructionCallback(
|
||||||
const DestructionCallback& callback) override;
|
const DestructionCallback& callback) override;
|
||||||
|
|
||||||
|
@ -110,14 +118,42 @@ class WebContents : public mate::EventEmitter,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
IPC::Message* message);
|
IPC::Message* message);
|
||||||
|
|
||||||
|
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||||
|
const gfx::Size& new_size);
|
||||||
|
|
||||||
// Unique ID for a guest WebContents.
|
// Unique ID for a guest WebContents.
|
||||||
int guest_instance_id_;
|
int guest_instance_id_;
|
||||||
|
|
||||||
DestructionCallback destruction_callback_;
|
DestructionCallback destruction_callback_;
|
||||||
|
|
||||||
|
// The extra parameters associated with this guest view passed
|
||||||
|
// in from JavaScript. This will typically be the view instance ID,
|
||||||
|
// the API to use, and view-specific parameters. These parameters
|
||||||
|
// are passed along to new guests that are created from this guest.
|
||||||
|
scoped_ptr<base::DictionaryValue> extra_params_;
|
||||||
|
|
||||||
// Stores the WebContents that managed by this class.
|
// Stores the WebContents that managed by this class.
|
||||||
scoped_ptr<content::WebContents> storage_;
|
scoped_ptr<content::WebContents> storage_;
|
||||||
|
|
||||||
|
// The WebContents that attaches this guest view.
|
||||||
|
content::WebContents* embedder_web_contents_;
|
||||||
|
|
||||||
|
// The size of the container element.
|
||||||
|
gfx::Size element_size_;
|
||||||
|
|
||||||
|
// The size of the guest content. Note: In autosize mode, the container
|
||||||
|
// element may not match the size of the guest.
|
||||||
|
gfx::Size guest_size_;
|
||||||
|
|
||||||
|
// Indicates whether autosize mode is enabled or not.
|
||||||
|
bool auto_size_enabled_;
|
||||||
|
|
||||||
|
// The maximum size constraints of the container element in autosize mode.
|
||||||
|
gfx::Size max_auto_size_;
|
||||||
|
|
||||||
|
// The minimum size constraints of the container element in autosize mode.
|
||||||
|
gfx::Size min_auto_size_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,14 @@ module.exports.wrap = (webContents) ->
|
||||||
else
|
else
|
||||||
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code)
|
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code)
|
||||||
|
|
||||||
|
# Init guest web view.
|
||||||
|
webContents.on 'internal-did-attach', (event, params) ->
|
||||||
|
min = width: params.minwidth, height: params.minheight
|
||||||
|
max = width: params.maxwidth, height: params.maxheight
|
||||||
|
@setAutoSize params.autosize, min, max
|
||||||
|
if params.src
|
||||||
|
@loadUrl params.src
|
||||||
|
|
||||||
# The processId and routingId and identify a webContents.
|
# The processId and routingId and identify a webContents.
|
||||||
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
|
webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}"
|
||||||
webContents.equal = (other) -> @getId() is other.getId()
|
webContents.equal = (other) -> @getId() is other.getId()
|
||||||
|
@ -32,10 +40,10 @@ module.exports.wrap = (webContents) ->
|
||||||
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
|
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
|
||||||
|
|
||||||
# Dispatch IPC messages to the ipc module.
|
# Dispatch IPC messages to the ipc module.
|
||||||
webContents.on 'ipc-message', (event, channel, args...) =>
|
webContents.on 'ipc-message', (event, channel, args...) ->
|
||||||
Object.defineProperty event, 'sender', value: webContents
|
Object.defineProperty event, 'sender', value: webContents
|
||||||
ipc.emit channel, event, args...
|
ipc.emit channel, event, args...
|
||||||
webContents.on 'ipc-message-sync', (event, channel, args...) =>
|
webContents.on 'ipc-message-sync', (event, channel, args...) ->
|
||||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||||
Object.defineProperty event, 'sender', value: webContents
|
Object.defineProperty event, 'sender', value: webContents
|
||||||
ipc.emit channel, event, args...
|
ipc.emit channel, event, args...
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<webview id="foo" src="http://www.baidu.com/" style="display:block; width:640px; height:100px"></webview>
|
<webview id="foo" autosize src="http://www.baidu.com/" style="display:block; width:640px; height:100px"></webview>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var execPath = require('remote').process.execPath;
|
var execPath = require('remote').process.execPath;
|
||||||
|
|
|
@ -32,3 +32,6 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, reque
|
||||||
|
|
||||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, guestInstanceId) ->
|
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, guestInstanceId) ->
|
||||||
destroyGuest guestInstanceId
|
destroyGuest guestInstanceId
|
||||||
|
|
||||||
|
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, guestInstanceId, params) ->
|
||||||
|
guestInstances[id]?.setAutoSize params.enableAutoSize, params.min, params.max
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
// Use of this source code is governed by the MIT license that can be
|
// Use of this source code is governed by the MIT license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
||||||
|
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
||||||
|
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "ui/gfx/point.h"
|
#include "ui/gfx/point.h"
|
||||||
#include "ui/gfx/rect.h"
|
#include "ui/gfx/rect.h"
|
||||||
|
@ -94,3 +97,5 @@ struct Converter<gfx::Display> {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
||||||
|
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
||||||
|
|
|
@ -10,3 +10,6 @@ module.exports =
|
||||||
|
|
||||||
destroyGuest: (guestInstanceId) ->
|
destroyGuest: (guestInstanceId) ->
|
||||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId
|
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId
|
||||||
|
|
||||||
|
setAutoSize: (guestInstanceId, params) ->
|
||||||
|
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', guestInstanceId, params
|
||||||
|
|
|
@ -3,8 +3,8 @@ guestViewInternal = require './guest-view-internal'
|
||||||
webView = require 'web-view'
|
webView = require 'web-view'
|
||||||
|
|
||||||
# ID generator.
|
# ID generator.
|
||||||
nextId = 1
|
nextId = 0
|
||||||
getNextId = -> nextId++
|
getNextId = -> ++nextId
|
||||||
|
|
||||||
# FIXME
|
# FIXME
|
||||||
# Discarded after Chrome 39
|
# Discarded after Chrome 39
|
||||||
|
@ -45,7 +45,7 @@ class Partition
|
||||||
|
|
||||||
toAttribute: ->
|
toAttribute: ->
|
||||||
return '' unless @validPartitionId
|
return '' unless @validPartitionId
|
||||||
(@persistStorage ? 'persist:' : '') + @storagePartitionId
|
(if @persistStorage then 'persist:' else '') + @storagePartitionId
|
||||||
|
|
||||||
fromAttribute: (value, hasNavigated) ->
|
fromAttribute: (value, hasNavigated) ->
|
||||||
result = {}
|
result = {}
|
||||||
|
@ -223,15 +223,14 @@ class WebView
|
||||||
return unless @guestInstanceId
|
return unless @guestInstanceId
|
||||||
# Convert autosize attribute to boolean.
|
# Convert autosize attribute to boolean.
|
||||||
autosize = @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_AUTOSIZE
|
autosize = @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_AUTOSIZE
|
||||||
# FIXME
|
guestViewInternal.setAutoSize @guestInstanceId,
|
||||||
# GuestViewInternal.setAutoSize @guestInstanceId,
|
enableAutoSize: autosize,
|
||||||
# enableAutoSize: autosize,
|
min:
|
||||||
# min:
|
width: parseInt @minwidth || 0
|
||||||
# width: parseInt @minwidth ? 0
|
height: parseInt @minheight || 0
|
||||||
# height: parseInt @minheight ? 0
|
max:
|
||||||
# max:
|
width: parseInt @maxwidth || 0
|
||||||
# width: parseInt @maxwidth ? 0
|
height: parseInt @maxheight || 0
|
||||||
# height: parseInt @maxheight ? 0
|
|
||||||
else if name is WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY
|
else if name is WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY
|
||||||
# We treat null attribute (attribute removed) and the empty string as
|
# We treat null attribute (attribute removed) and the empty string as
|
||||||
# one case.
|
# one case.
|
||||||
|
@ -450,7 +449,7 @@ class WebView
|
||||||
minwidth: parseInt @minwidth || 0
|
minwidth: parseInt @minwidth || 0
|
||||||
name: @name
|
name: @name
|
||||||
# We don't need to navigate new window from here.
|
# We don't need to navigate new window from here.
|
||||||
src: isNewWindow ? undefined : @src
|
src: if isNewWindow then undefined else @src
|
||||||
# If we have a partition from the opener, that will also be already
|
# If we have a partition from the opener, that will also be already
|
||||||
# set via this.onAttach().
|
# set via this.onAttach().
|
||||||
storagePartitionId: @partition.toAttribute()
|
storagePartitionId: @partition.toAttribute()
|
||||||
|
|
Loading…
Reference in a new issue