Use element instant id for GetGuestByInstanceID

This commit is contained in:
Cheng Zhao 2014-12-09 14:38:43 -08:00
parent 9fcb6b2cd1
commit 68381e1b76
6 changed files with 119 additions and 46 deletions

View file

@ -12,6 +12,7 @@
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@ -190,6 +191,13 @@ void WebContents::DidGetRedirectForResourceRequest(
Emit("did-get-redirect-request", args);
}
void WebContents::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
if (details.is_navigation_to_different_page())
Emit("did-navigate-to-different-page");
}
bool WebContents::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(WebContents, message)

View file

@ -118,24 +118,25 @@ class WebContents : public mate::EventEmitter,
const content::NativeWebKeyboardEvent& event) override;
// content::WebContentsObserver:
virtual void RenderViewDeleted(content::RenderViewHost*) override;
virtual void RenderProcessGone(base::TerminationStatus status) override;
virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override;
virtual void DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) override;
virtual void DidStartLoading(
content::RenderViewHost* render_view_host) override;
virtual void DidStopLoading(
content::RenderViewHost* render_view_host) override;
virtual void DidGetRedirectForResourceRequest(
void RenderViewDeleted(content::RenderViewHost*) override;
void RenderProcessGone(base::TerminationStatus status) override;
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override;
void DidFailLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description) override;
void DidStartLoading(content::RenderViewHost* render_view_host) override;
void DidStopLoading(content::RenderViewHost* render_view_host) override;
void DidGetRedirectForResourceRequest(
content::RenderViewHost* render_view_host,
const content::ResourceRedirectDetails& details) override;
virtual bool OnMessageReceived(const IPC::Message& message) override;
virtual void RenderViewReady() override;
virtual void WebContentsDestroyed() override;
void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override;
void RenderViewReady() override;
void WebContentsDestroyed() override;
// content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final;

View file

@ -35,12 +35,13 @@ createGuest = (embedder, params) ->
guestInstanceId: id
storagePartitionId: params.storagePartitionId
guestInstances[id] = {guest, embedder}
preload = params.preload ? ''
webViewManager.addGuest id, embedder, guest, params.nodeIntegration, params.plugins, preload
# Destroy guest when the embedder is gone.
embedder.once 'render-view-deleted', ->
# Destroy guest when the embedder is gone or navigated.
destroyEvents = ['destroyed', 'crashed', 'did-navigate-to-different-page']
destroy = ->
destroyGuest id if guestInstances[id]?
embedder.removeListener event, destroy for event in destroyEvents
embedder.once event, destroy for event in destroyEvents
# Init guest web view after attached.
guest.once 'did-attach', ->
@ -85,6 +86,11 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
return unless guestInstances[oldGuestInstanceId]?
destroyGuest oldGuestInstanceId
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest,
nodeIntegration: params.nodeIntegration
plugins: params.plugins
preloadUrl: params.preload ? ''
guest.attachParams = params
embedderElementsMap[key] = guestInstanceId
reverseEmbedderElementsMap[guestInstanceId] = key

View file

@ -32,6 +32,19 @@ struct Converter<content::WebContents*> {
}
};
template<>
struct Converter<atom::WebViewManager::WebViewOptions> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
atom::WebViewManager::WebViewOptions* out) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
return options.Get("nodeIntegration", &(out->node_integration)) &&
options.Get("plugins", &(out->plugins)) &&
options.Get("preloadUrl", &(out->preload_url));
}
};
} // namespace mate
namespace atom {
@ -43,17 +56,16 @@ WebViewManager::~WebViewManager() {
}
void WebViewManager::AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
bool node_integration,
bool plugins,
const GURL& preload_url) {
const WebViewOptions& options) {
web_contents_map_[guest_instance_id] = { web_contents, embedder };
WebViewRendererState::WebViewInfo web_view_info = {
guest_instance_id, node_integration, plugins
guest_instance_id, options.node_integration, options.plugins
};
net::FileURLToFilePath(preload_url, &web_view_info.preload_script);
net::FileURLToFilePath(options.preload_url, &web_view_info.preload_script);
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
@ -61,6 +73,10 @@ void WebViewManager::AddGuest(int guest_instance_id,
base::Unretained(WebViewRendererState::GetInstance()),
web_contents->GetRenderProcessHost()->GetID(),
web_view_info));
// Map the element in embedder to guest.
ElementInstanceKey key(embedder, element_instance_id);
element_instance_id_to_guest_map_[key] = guest_instance_id;
}
void WebViewManager::RemoveGuest(int guest_instance_id) {
@ -71,13 +87,24 @@ void WebViewManager::RemoveGuest(int guest_instance_id) {
&WebViewRendererState::RemoveGuest,
base::Unretained(WebViewRendererState::GetInstance()),
web_contents->GetRenderProcessHost()->GetID()));
web_contents_map_.erase(guest_instance_id);
// Remove the record of element in embedder too.
for (const auto& element : element_instance_id_to_guest_map_)
if (element.second == guest_instance_id) {
element_instance_id_to_guest_map_.erase(element.first);
break;
}
}
content::WebContents* WebViewManager::GetGuestByInstanceID(
content::WebContents* embedder_web_contents,
int guest_instance_id) {
content::WebContents* embedder,
int element_instance_id) {
ElementInstanceKey key(embedder, element_instance_id);
if (!ContainsKey(element_instance_id_to_guest_map_, key))
return nullptr;
int guest_instance_id = element_instance_id_to_guest_map_[key];
if (ContainsKey(web_contents_map_, guest_instance_id))
return web_contents_map_[guest_instance_id].web_contents;
else

View file

@ -21,20 +21,25 @@ class WebViewManager : public content::BrowserPluginGuestManager {
explicit WebViewManager(content::BrowserContext* context);
virtual ~WebViewManager();
struct WebViewOptions {
bool node_integration;
bool plugins;
GURL preload_url;
};
void AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* web_contents,
bool node_integration,
bool plugins,
const GURL& preload_url);
const WebViewOptions& options);
void RemoveGuest(int guest_instance_id);
protected:
// content::BrowserPluginGuestManager:
content::WebContents* GetGuestByInstanceID(
content::WebContents* embedder_web_contents,
int browser_plugin_instance_id) override;
bool ForEachGuest(content::WebContents* embedder_web_contents,
int element_instance_id) override;
bool ForEachGuest(content::WebContents* embedder,
const GuestCallback& callback) override;
private:
@ -44,6 +49,32 @@ class WebViewManager : public content::BrowserPluginGuestManager {
};
std::map<int, WebContentsWithEmbedder> web_contents_map_;
struct ElementInstanceKey {
content::WebContents* owner_web_contents;
int element_instance_id;
ElementInstanceKey()
: owner_web_contents(nullptr),
element_instance_id(0) {}
ElementInstanceKey(content::WebContents* owner_web_contents,
int element_instance_id)
: owner_web_contents(owner_web_contents),
element_instance_id(element_instance_id) {}
bool operator<(const ElementInstanceKey& other) const {
if (owner_web_contents != other.owner_web_contents)
return owner_web_contents < other.owner_web_contents;
return element_instance_id < other.element_instance_id;
}
bool operator==(const ElementInstanceKey& other) const {
return (owner_web_contents == other.owner_web_contents) &&
(element_instance_id == other.element_instance_id);
}
};
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
DISALLOW_COPY_AND_ASSIGN(WebViewManager);
};

View file

@ -138,19 +138,6 @@ class WebViewImpl
return if @pendingGuestCreation
params =
storagePartitionId: @attributes[webViewConstants.ATTRIBUTE_PARTITION].getValue()
nodeIntegration: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_NODEINTEGRATION
plugins: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_PLUGINS
if @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_PRELOAD
preload = @webviewNode.getAttribute webViewConstants.ATTRIBUTE_PRELOAD
# Get the full path.
a = document.createElement 'a'
a.href = preload
params.preload = a.href
# Only support file: or asar: protocol.
protocol = params.preload.substr 0, 5
unless protocol in ['file:', 'asar:']
delete params.preload
console.error webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE
guestViewInternal.createGuest 'webview', params, (guestInstanceId) =>
@pendingGuestCreation = false
unless @elementAttached
@ -193,8 +180,21 @@ class WebViewImpl
params =
instanceId: @viewInstanceId
userAgentOverride: @userAgentOverride
nodeIntegration: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_NODEINTEGRATION
plugins: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_PLUGINS
for attributeName, attribute of @attributes
params[attributeName] = attribute.getValue()
if @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_PRELOAD
preload = @webviewNode.getAttribute webViewConstants.ATTRIBUTE_PRELOAD
# Get the full path.
a = document.createElement 'a'
a.href = preload
params.preload = a.href
# Only support file: or asar: protocol.
protocol = params.preload.substr 0, 5
unless protocol in ['file:', 'asar:']
delete params.preload
console.error webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE
params
attachWindow: (guestInstanceId) ->