Use element instant id for GetGuestByInstanceID
This commit is contained in:
parent
9fcb6b2cd1
commit
68381e1b76
6 changed files with 119 additions and 46 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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) ->
|
||||
|
|
Loading…
Reference in a new issue