Commit 0fa0be50 authored by raymes's avatar raymes Committed by Commit bot

Implement find in page support for top level BrowserPlugins.

Right now BrowserPlugins don't handle find in page. This CL adds support for find in page in MIMEHandlerView BrowserPlugin instances.

Find in page is only handled for "full page" plugins, that is when the BrowserPlugin as loaded at the top level. The reason is because supporting find in embedded BrowserPlugins would require recursively searching which is far more complicated to implement and we (jam@, fsamuel@) have decided to defer implementing for the time being.

Detecting whether the BrowserPlugin is loaded at the top level requires detecting whether the main frame is a "plugin document" in blink, which needs to be sent to the browser from the renderer. It isn't sufficient to determine whether the BrowserPlugin is merely loaded in the main frame, because it may be <embed>ed inside a html document in the main frame. In that case we don't want find in page to search the document.

BUG=303491

Review URL: https://codereview.chromium.org/597753003

Cr-Commit-Position: refs/heads/master@{#299358}
parent 675a377e
......@@ -22,6 +22,7 @@
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "net/base/escape.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "ui/events/keycodes/keyboard_codes.h"
namespace content {
......@@ -162,6 +163,18 @@ bool BrowserPluginEmbedder::HandleKeyboardEvent(
return event_consumed;
}
bool BrowserPluginEmbedder::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options) {
return GetBrowserPluginGuestManager()->ForEachGuest(
GetWebContents(),
base::Bind(&BrowserPluginEmbedder::FindInGuest,
base::Unretained(this),
request_id,
search_text,
options));
}
bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(bool* mouse_unlocked,
WebContents* guest) {
*mouse_unlocked |= static_cast<WebContentsImpl*>(guest)
......@@ -173,4 +186,17 @@ bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(bool* mouse_unlocked,
return false;
}
bool BrowserPluginEmbedder::FindInGuest(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
WebContents* guest) {
if (static_cast<WebContentsImpl*>(guest)->GetBrowserPluginGuest()->Find(
request_id, search_text, options)) {
// There can only ever currently be one browser plugin that handles find so
// we can break the iteration at this point.
return true;
}
return false;
}
} // namespace content
......@@ -70,6 +70,12 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
// Used to handle special keyboard events.
bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event);
// Find the given |search_text| in the page. Returns true if the find request
// is handled by this browser plugin embedder.
bool Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options);
private:
explicit BrowserPluginEmbedder(WebContentsImpl* web_contents);
......@@ -79,10 +85,13 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
bool DidSendScreenRectsCallback(WebContents* guest_web_contents);
bool SetZoomLevelCallback(double level, WebContents* guest_web_contents);
bool UnlockMouseIfNecessaryCallback(bool* mouse_unlocked, WebContents* guest);
bool FindInGuest(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
WebContents* guest);
// Message handlers.
void OnAttach(int instance_id,
const BrowserPluginHostMsg_Attach_Params& params);
......
......@@ -81,6 +81,7 @@ BrowserPluginGuest::BrowserPluginGuest(bool has_render_view,
pending_lock_request_(false),
guest_visible_(false),
embedder_visible_(true),
is_full_page_plugin_(false),
copy_request_id_(0),
has_render_view_(has_render_view),
is_in_destruction_(false),
......@@ -202,6 +203,7 @@ void BrowserPluginGuest::Initialize(
browser_plugin_instance_id_ = browser_plugin_instance_id;
focused_ = params.focused;
guest_visible_ = params.visible;
is_full_page_plugin_ = params.is_full_page_plugin;
guest_window_rect_ = gfx::Rect(params.origin,
params.resize_guest_params.view_size);
......@@ -354,6 +356,13 @@ void BrowserPluginGuest::SetContentsOpaque(bool opaque) {
browser_plugin_instance_id(), opaque));
}
bool BrowserPluginGuest::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options) {
return delegate_->Find(request_id, search_text, options,
is_full_page_plugin_);
}
WebContentsImpl* BrowserPluginGuest::GetWebContents() const {
return static_cast<WebContentsImpl*>(web_contents());
}
......
......@@ -204,6 +204,12 @@ class CONTENT_EXPORT BrowserPluginGuest : public WebContentsObserver {
void SetContentsOpaque(bool opaque);
// Find the given |search_text| in the page. Returns true if the find request
// is handled by this browser plugin guest.
bool Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options);
private:
class EmbedderWebContentsObserver;
......@@ -339,6 +345,8 @@ class CONTENT_EXPORT BrowserPluginGuest : public WebContentsObserver {
bool pending_lock_request_;
bool guest_visible_;
bool embedder_visible_;
// Whether the browser plugin is inside a plugin document.
bool is_full_page_plugin_;
// Each copy-request is identified by a unique number. The unique number is
// used to keep track of the right callback.
......
......@@ -2401,6 +2401,11 @@ bool WebContentsImpl::IsSubframe() const {
void WebContentsImpl::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options) {
// See if a top level browser plugin handles the find request first.
if (browser_plugin_embedder_ &&
browser_plugin_embedder_->Find(request_id, search_text, options)) {
return;
}
Send(new ViewMsg_Find(GetRoutingID(), request_id, search_text, options));
}
......
......@@ -53,6 +53,8 @@ IPC_STRUCT_BEGIN(BrowserPluginHostMsg_Attach_Params)
IPC_STRUCT_MEMBER(BrowserPluginHostMsg_ResizeGuest_Params,
resize_guest_params)
IPC_STRUCT_MEMBER(gfx::Point, origin)
// Whether the browser plugin is a full page plugin document.
IPC_STRUCT_MEMBER(bool, is_full_page_plugin)
IPC_STRUCT_END()
// Browser plugin messages
......
......@@ -11,4 +11,11 @@ WebContents* BrowserPluginGuestDelegate::CreateNewGuestWindow(
return NULL;
}
bool BrowserPluginGuestDelegate::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
bool is_full_page_plugin) {
return false;
}
} // namespace content
......@@ -62,6 +62,13 @@ class CONTENT_EXPORT BrowserPluginGuestDelegate {
typedef base::Callback<void()> DestructionCallback;
virtual void RegisterDestructionCallback(
const DestructionCallback& callback) {}
// Find the given |search_text| in the page. Returns true if the find request
// is handled by this browser plugin guest delegate.
virtual bool Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
bool is_full_page_plugin);
};
} // namespace content
......
......@@ -22,8 +22,10 @@
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/sad_plugin.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/skia/include/core/SkCanvas.h"
......@@ -134,6 +136,12 @@ void BrowserPlugin::Attach() {
attach_params.focused = ShouldGuestBeFocused();
attach_params.visible = visible_;
attach_params.origin = plugin_rect().origin();
attach_params.is_full_page_plugin = false;
if (container()) {
blink::WebLocalFrame* frame = container()->element().document().frame();
attach_params.is_full_page_plugin =
frame->view()->mainFrame()->document().isPluginDocument();
}
gfx::Size view_size(width(), height());
if (!view_size.IsEmpty()) {
PopulateResizeGuestParameters(view_size,
......
......@@ -266,7 +266,7 @@ bool WebViewInternalFindFunction::RunAsyncSafe(WebViewGuest* guest) {
params->options->match_case ? *params->options->match_case : false;
}
guest->Find(search_text, options, this);
guest->StartFinding(search_text, options, this);
return true;
}
......
......@@ -131,6 +131,17 @@ void MimeHandlerViewGuest::DidInitialize() {
delegate_->AttachHelpers();
}
bool MimeHandlerViewGuest::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
bool is_full_page_plugin) {
if (is_full_page_plugin) {
web_contents()->Find(request_id, search_text, options);
return true;
}
return false;
}
void MimeHandlerViewGuest::ContentsZoomChange(bool zoom_in) {
if (delegate_)
delegate_->ChangeZoom(zoom_in);
......@@ -152,6 +163,23 @@ void MimeHandlerViewGuest::HandleKeyboardEvent(
event);
}
void MimeHandlerViewGuest::FindReply(content::WebContents* web_contents,
int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
if (!attached() || !embedder_web_contents()->GetDelegate())
return;
embedder_web_contents()->GetDelegate()->FindReply(embedder_web_contents(),
request_id,
number_of_matches,
selection_rect,
active_match_ordinal,
final_update);
}
bool MimeHandlerViewGuest::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewGuest, message)
......
......@@ -8,6 +8,10 @@
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/browser/guest_view/guest_view.h"
namespace content {
class WebContents;
} // namespace content
namespace extensions {
class MimeHandlerViewGuestDelegate;
......@@ -36,11 +40,23 @@ class MimeHandlerViewGuest : public GuestView<MimeHandlerViewGuest>,
virtual void DidAttachToEmbedder() override;
virtual void DidInitialize() override;
// content::BrowserPluginGuestDelegate implementation
virtual bool Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options,
bool is_full_page_plugin) override;
// WebContentsDelegate implementation.
virtual void ContentsZoomChange(bool zoom_in) override;
virtual void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
virtual void FindReply(content::WebContents* web_contents,
int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) override;
// content::WebContentsObserver implementation.
virtual bool OnMessageReceived(const IPC::Message& message) override;
......
......@@ -588,7 +588,7 @@ double WebViewGuest::GetZoom() {
return web_view_guest_delegate_->GetZoom();
}
void WebViewGuest::Find(
void WebViewGuest::StartFinding(
const base::string16& search_text,
const blink::WebFindOptions& options,
scoped_refptr<WebViewInternalFindFunction> find_function) {
......
......@@ -177,9 +177,9 @@ class WebViewGuest : public GuestView<WebViewGuest>,
double GetZoom();
// Begin or continue a find request.
void Find(const base::string16& search_text,
const blink::WebFindOptions& options,
scoped_refptr<WebViewInternalFindFunction> find_function);
void StartFinding(const base::string16& search_text,
const blink::WebFindOptions& options,
scoped_refptr<WebViewInternalFindFunction> find_function);
// Conclude a find request to clear highlighting.
void StopFinding(content::StopFindAction);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment