Implement GuestViewInternal.createGuest and destroyGuest

This commit is contained in:
Cheng Zhao 2014-10-23 17:54:52 +08:00
parent d34cff2eef
commit a22a5c67bd
8 changed files with 124 additions and 16 deletions

View file

@ -29,6 +29,7 @@
'atom/browser/api/lib/tray.coffee', 'atom/browser/api/lib/tray.coffee',
'atom/browser/api/lib/web-contents.coffee', 'atom/browser/api/lib/web-contents.coffee',
'atom/browser/lib/chrome-extension.coffee', 'atom/browser/lib/chrome-extension.coffee',
'atom/browser/lib/guest-view-manager.coffee',
'atom/browser/lib/init.coffee', 'atom/browser/lib/init.coffee',
'atom/browser/lib/objects-registry.coffee', 'atom/browser/lib/objects-registry.coffee',
'atom/browser/lib/rpc-server.coffee', 'atom/browser/lib/rpc-server.coffee',
@ -41,6 +42,7 @@
'atom/common/lib/init.coffee', 'atom/common/lib/init.coffee',
'atom/common/lib/asar.coffee', 'atom/common/lib/asar.coffee',
'atom/renderer/lib/chrome-api.coffee', 'atom/renderer/lib/chrome-api.coffee',
'atom/renderer/lib/guest-view-internal.coffee',
'atom/renderer/lib/init.coffee', 'atom/renderer/lib/init.coffee',
'atom/renderer/lib/inspector.coffee', 'atom/renderer/lib/inspector.coffee',
'atom/renderer/lib/override.coffee', 'atom/renderer/lib/override.coffee',

View file

@ -30,10 +30,14 @@ v8::Persistent<v8::ObjectTemplate> template_;
} // namespace } // namespace
WebContents::WebContents(content::WebContents* web_contents) WebContents::WebContents(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents) { : content::WebContentsObserver(web_contents),
guest_instance_id_(-1) {
} }
WebContents::WebContents(const mate::Dictionary& options) { WebContents::WebContents(const mate::Dictionary& options)
: guest_instance_id_(-1) {
options.Get("guestInstances", &guest_instance_id_);
content::WebContents::CreateParams params(AtomBrowserContext::Get()); content::WebContents::CreateParams params(AtomBrowserContext::Get());
bool is_guest; bool is_guest;
if (options.Get("isGuest", &is_guest) && is_guest) if (options.Get("isGuest", &is_guest) && is_guest)
@ -44,6 +48,7 @@ WebContents::WebContents(const mate::Dictionary& options) {
} }
WebContents::~WebContents() { WebContents::~WebContents() {
Destroy();
} }
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) { void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
@ -95,8 +100,47 @@ void WebContents::WebContentsDestroyed() {
Emit("destroyed"); Emit("destroyed");
} }
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
const base::DictionaryValue& extra_params) {
LOG(ERROR) << "WillAttach";
}
void WebContents::DidAttach() {
LOG(ERROR) << "DidAttach";
}
int WebContents::GetGuestInstanceID() const {
return guest_instance_id_;
}
void WebContents::ElementSizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) {
LOG(ERROR) << "ElementSizeChanged";
}
void WebContents::GuestSizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) {
LOG(ERROR) << "GuestSizeChanged";
}
void WebContents::RequestPointerLockPermission(
bool user_gesture,
bool last_unlocked_by_target,
const base::Callback<void(bool)>& callback) {
callback.Run(true);
}
void WebContents::RegisterDestructionCallback(
const DestructionCallback& callback) {
LOG(ERROR) << "RegisterDestructionCallback";
destruction_callback_ = callback;
}
void WebContents::Destroy() { void WebContents::Destroy() {
if (storage_) { if (storage_) {
if (!destruction_callback_.is_null())
destruction_callback_.Run();
Observe(nullptr); Observe(nullptr);
storage_.reset(); storage_.reset();
} }

View file

@ -59,11 +59,11 @@ class WebContents : public mate::EventEmitter,
explicit WebContents(const mate::Dictionary& options); explicit WebContents(const mate::Dictionary& options);
~WebContents(); ~WebContents();
// mate::Wrappable implementations: // mate::Wrappable:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE; v8::Isolate* isolate) OVERRIDE;
// content::WebContentsObserver implementations: // content::WebContentsObserver:
virtual void RenderViewDeleted(content::RenderViewHost*) OVERRIDE; virtual void RenderViewDeleted(content::RenderViewHost*) OVERRIDE;
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host, virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
@ -75,6 +75,22 @@ class WebContents : public mate::EventEmitter,
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void WebContentsDestroyed() OVERRIDE; virtual void WebContentsDestroyed() OVERRIDE;
// content::BrowserPluginGuestDelegate:
virtual void WillAttach(content::WebContents* embedder_web_contents,
const base::DictionaryValue& extra_params) final;
virtual void DidAttach() final;
virtual int GetGuestInstanceID() const final;
virtual void ElementSizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) final;
virtual void GuestSizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) final;
virtual void RequestPointerLockPermission(
bool user_gesture,
bool last_unlocked_by_target,
const base::Callback<void(bool)>& callback) final;
virtual void RegisterDestructionCallback(
const DestructionCallback& callback) final;
private: private:
// Called when received a message from renderer. // Called when received a message from renderer.
void OnRendererMessage(const base::string16& channel, void OnRendererMessage(const base::string16& channel,
@ -85,6 +101,11 @@ class WebContents : public mate::EventEmitter,
const base::ListValue& args, const base::ListValue& args,
IPC::Message* message); IPC::Message* message);
// Unique ID for a guest WebContents.
int guest_instance_id_;
DestructionCallback destruction_callback_;
// 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_;

View file

@ -56,7 +56,7 @@
</style> </style>
</head> </head>
<body> <body>
<browser-plugin type="application/browser-plugin"></browser-plugin> <webview id="foo" 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;

View file

@ -0,0 +1,26 @@
ipc = require 'ipc'
webContents = require 'web-contents'
nextInstanceId = 0
guestInstances = {}
# Generate guestInstanceId.
getNextInstanceId = (webContents) ->
++nextInstanceId
# Create a new guest instance.
createGuest = (embedder, params) ->
id = getNextInstanceId embedder
guestInstances[id] = webContents.create isGuest: true, guestInstanceId: id
id
# Destroy an existing guest instance.
destroyGuest = (id) ->
guestInstances[id].destroy()
delete guestInstances[id]
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) ->
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender)
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, guestInstanceId) ->
destroyGuest guestInstanceId

View file

@ -61,6 +61,9 @@ setImmediate ->
# Load the RPC server. # Load the RPC server.
require './rpc-server.js' require './rpc-server.js'
# Load the guest view manager.
require './guest-view-manager.js'
# Now we try to load app's package.json. # Now we try to load app's package.json.
packageJson = null packageJson = null

View file

@ -0,0 +1,12 @@
ipc = require 'ipc'
requestId = 0
module.exports =
createGuest: (type, params, callback) ->
requestId++
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', type, params, requestId
ipc.on "ATOM_SHELL_RESPONSE_#{requestId}", callback
destroyGuest: (guestInstanceId) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId

View file

@ -1,4 +1,5 @@
v8Util = process.atomBinding 'v8_util' v8Util = process.atomBinding 'v8_util'
guestViewInternal = require './guest-view-internal'
webView = require 'web-view' webView = require 'web-view'
# ID generator. # ID generator.
@ -114,8 +115,7 @@ class WebView
# heard back from createGuest yet. We will not reset the flag in this case so # heard back from createGuest yet. We will not reset the flag in this case so
# that we don't end up allocating a second guest. # that we don't end up allocating a second guest.
if @guestInstanceId if @guestInstanceId
# FIXME guestViewInternal.destroyGuest @guestInstanceId
# GuestViewInternal.destroyGuest @guestInstanceId
@guestInstanceId = undefined @guestInstanceId = undefined
@beforeFirstNavigation = true @beforeFirstNavigation = true
@validPartitionId = true @validPartitionId = true
@ -287,6 +287,7 @@ class WebView
@browserPluginNode.removeAttribute 'internalinstanceid' @browserPluginNode.removeAttribute 'internalinstanceid'
@internalInstanceId = parseInt newValue @internalInstanceId = parseInt newValue
console.log 'internalinstanceid', @internalInstanceId
if !!@guestInstanceId and @guestInstanceId != 0 if !!@guestInstanceId and @guestInstanceId != 0
isNewWindow = if @deferredAttachState then @deferredAttachState.isNewWindow else false isNewWindow = if @deferredAttachState then @deferredAttachState.isNewWindow else false
params = @buildAttachParams isNewWindow params = @buildAttachParams isNewWindow
@ -378,18 +379,17 @@ class WebView
@parseSrcAttribute result @parseSrcAttribute result
createGuest: -> createGuest: ->
return if @pendingGuestCreation? return if @pendingGuestCreation
storagePartitionId = storagePartitionId =
@webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) or @webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) or
@webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION] @webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]
params = storagePartitionId: storagePartitionId params = storagePartitionId: storagePartitionId
# FIXME guestViewInternal.createGuest 'webview', params, (guestInstanceId) =>
# GuestViewInternal.createGuest 'webview', params, (guestInstanceId) => @pendingGuestCreation = false
# @pendingGuestCreation = false unless @elementAttached
# unless @elementAttached guestViewInternal.destroyGuest guestInstanceId
# GuestViewInternal.destroyGuest guestInstanceId return
# return @attachWindow guestInstanceId, false
# @attachWindow guestInstanceId, false
@pendingGuestCreation = true @pendingGuestCreation = true
onFrameNameChanged: (name) -> onFrameNameChanged: (name) ->