diff options
-rw-r--r-- | chrome/renderer/render_view.cc | 123 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 10 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.cc | 48 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.h | 15 | ||||
-rw-r--r-- | third_party/npapi/bindings/npapi_extensions.h | 79 | ||||
-rw-r--r-- | webkit/glue/plugins/npapi_extension_thunk.cc | 22 | ||||
-rw-r--r-- | webkit/glue/webplugin_delegate.h | 10 |
7 files changed, 243 insertions, 64 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index fb2e70e..f9f875d 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -87,6 +87,8 @@ #include "third_party/WebKit/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/WebKit/chromium/public/WebNodeList.h" #include "third_party/WebKit/WebKit/chromium/public/WebPageSerializer.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPluginDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" #include "third_party/WebKit/WebKit/chromium/public/WebRange.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" @@ -117,6 +119,7 @@ #include "webkit/glue/webdropdata.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/webmediaplayer_impl.h" +#include "webkit/glue/webplugin_delegate.h" #include "webkit/glue/webplugin_impl.h" #if defined(OS_WIN) @@ -168,6 +171,7 @@ using WebKit::WebPageSerializer; using WebKit::WebPageSerializerClient; using WebKit::WebPlugin; using WebKit::WebPluginParams; +using WebKit::WebPluginDocument; using WebKit::WebPoint; using WebKit::WebPopupMenuInfo; using WebKit::WebRange; @@ -507,7 +511,6 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop) IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame) IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText) - IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding) IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo) IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo) IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut) @@ -526,6 +529,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt) IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand) IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind) + IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding) + IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck) IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom) IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingHost, OnSetContentSettingsForLoadingHost) @@ -552,7 +557,6 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded, OnDragSourceSystemDragEnded) IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus) - IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck) IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck) IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences) IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL) @@ -992,44 +996,6 @@ void RenderView::OnSetupDevToolsClient() { devtools_client_.reset(new DevToolsClient(this)); } -void RenderView::OnStopFinding(const ViewMsg_StopFinding_Params& params) { - WebView* view = webview(); - if (!view) - return; - - bool clear_selection = - params.action == ViewMsg_StopFinding_Params::kClearSelection; - if (clear_selection) - view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect")); - - WebFrame* frame = view->mainFrame(); - while (frame) { - frame->stopFinding(clear_selection); - frame = frame->traverseNext(false); - } - - if (params.action == ViewMsg_StopFinding_Params::kActivateSelection) { - WebFrame* focused_frame = view->focusedFrame(); - if (focused_frame) { - WebDocument doc = focused_frame->document(); - if (!doc.isNull()) { - WebNode node = doc.focusedNode(); - if (!node.isNull()) - node.simulateClick(); - } - } - } -} - -void RenderView::OnFindReplyAck() { - // Check if there is any queued up request waiting to be sent. - if (queued_find_reply_message_.get()) { - // Send the search result over to the browser process. - Send(queued_find_reply_message_.get()); - queued_find_reply_message_.release(); - } -} - void RenderView::OnUpdateTargetURLAck() { // Check if there is a targeturl waiting to be sent. if (target_url_status_ == TARGET_PENDING) { @@ -2986,6 +2952,15 @@ void RenderView::reportFindInPageSelection(int request_id, false)); } +void RenderView::ReportNoFindInPageResults(int request_id) { + Send(new ViewHostMsg_Find_Reply(routing_id_, + request_id, + 0, + gfx::Rect(), + 0, + true)); +} + // webkit_glue::WebPluginPageDelegate ----------------------------------------- webkit_glue::WebPluginDelegate* RenderView::CreatePluginDelegate( @@ -3252,9 +3227,33 @@ GURL RenderView::GetAlternateErrorPageURL(const GURL& failed_url, return url; } +webkit_glue::WebPluginDelegate* RenderView::GetDelegateForPluginDocument() { + WebPlugin* plugin = webview()->mainFrame()->document(). + toElement<WebPluginDocument>().plugin(); + return static_cast<webkit_glue::WebPluginImpl*>(plugin)->delegate(); +} + void RenderView::OnFind(int request_id, const string16& search_text, const WebFindOptions& options) { WebFrame* main_frame = webview()->mainFrame(); + + if (main_frame->document().isPluginDocument()) { + webkit_glue::WebPluginDelegate* delegate = GetDelegateForPluginDocument(); + if (options.findNext) { + // Just navigate back/forward. + delegate->SelectFindResult(options.forward); + } else { + if (delegate->SupportsFind()) { + delegate->StartFind(UTF16ToUTF8(search_text), + options.matchCase, + request_id); + } else { + ReportNoFindInPageResults(request_id); + } + } + return; + } + WebFrame* frame_after_main = main_frame->traverseNext(true); WebFrame* focused_frame = webview()->focusedFrame(); WebFrame* search_frame = focused_frame; // start searching focused frame. @@ -3357,6 +3356,50 @@ void RenderView::OnFind(int request_id, const string16& search_text, } } +void RenderView::OnStopFinding(const ViewMsg_StopFinding_Params& params) { + WebView* view = webview(); + if (!view) + return; + + WebDocument doc = view->mainFrame()->document(); + if (doc.isPluginDocument()) { + GetDelegateForPluginDocument()->StopFind(); + return; + } + + bool clear_selection = + params.action == ViewMsg_StopFinding_Params::kClearSelection; + if (clear_selection) + view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect")); + + WebFrame* frame = view->mainFrame(); + while (frame) { + frame->stopFinding(clear_selection); + frame = frame->traverseNext(false); + } + + if (params.action == ViewMsg_StopFinding_Params::kActivateSelection) { + WebFrame* focused_frame = view->focusedFrame(); + if (focused_frame) { + WebDocument doc = focused_frame->document(); + if (!doc.isNull()) { + WebNode node = doc.focusedNode(); + if (!node.isNull()) + node.simulateClick(); + } + } + } +} + +void RenderView::OnFindReplyAck() { + // Check if there is any queued up request waiting to be sent. + if (queued_find_reply_message_.get()) { + // Send the search result over to the browser process. + Send(queued_find_reply_message_.get()); + queued_find_reply_message_.release(); + } +} + // static std::string RenderView::DetermineTextLanguage(const std::wstring& text) { // Text with less than 100 bytes will probably not provide good results. diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index b2d692b..43605ef 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -423,6 +423,9 @@ class RenderView : public RenderWidget, // Called when a plugin has crashed. void PluginCrashed(const FilePath& plugin_path); + // Called to indicate that there are no matching search results. + void ReportNoFindInPageResults(int request_id); + #if defined(OS_MACOSX) void RegisterPluginDelegate(WebPluginDelegateProxy* delegate); void UnregisterPluginDelegate(WebPluginDelegateProxy* delegate); @@ -619,8 +622,6 @@ class RenderView : public RenderWidget, bool new_navigation, const GURL& display_url, const std::string& security_info); - void OnStopFinding(const ViewMsg_StopFinding_Params& params); - void OnFindReplyAck(); void OnUpdateTargetURLAck(); void OnUndo(); void OnRedo(); @@ -642,6 +643,8 @@ class RenderView : public RenderWidget, void OnSetupDevToolsClient(); void OnCancelDownload(int32 download_id); void OnFind(int request_id, const string16&, const WebKit::WebFindOptions&); + void OnStopFinding(const ViewMsg_StopFinding_Params& params); + void OnFindReplyAck(); void OnDeterminePageLanguage(); void OnSetContentSettingsForLoadingHost( std::string host, const ContentSettings& content_settings); @@ -890,6 +893,9 @@ class RenderView : public RenderWidget, // Resets the |content_blocked_| array. void ClearBlockedContentSettings(); + // Should only be called if this object wraps a PluginDocument. + webkit_glue::WebPluginDelegate* GetDelegateForPluginDocument(); + // Bitwise-ORed set of extra bindings that have been enabled. See // BindingsPolicy for details. int enabled_bindings_; diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc index 33ad51a..70ce34e 100644 --- a/chrome/renderer/webplugin_delegate_pepper.cc +++ b/chrome/renderer/webplugin_delegate_pepper.cc @@ -321,6 +321,40 @@ WebPluginResourceClient* WebPluginDelegatePepper::CreateSeekableResourceClient( return instance()->GetRangeRequest(range_request_id); } +void WebPluginDelegatePepper::StartFind(const std::string& search_text, + bool case_sensitive, + int identifier) { + find_identifier_ = identifier; + GetFindExtensions()->startFind( + instance()->npp(), search_text.c_str(), case_sensitive); +} + +void WebPluginDelegatePepper::SelectFindResult(bool forward) { + GetFindExtensions()->selectFindResult(instance()->npp(), forward); +} + +void WebPluginDelegatePepper::StopFind() { + find_identifier_ = -1; + GetFindExtensions()->stopFind(instance()->npp()); +} + +void WebPluginDelegatePepper::NumberOfFindResultsChanged(int total, + bool final_result) { + DCHECK(find_identifier_ != -1); + + if (total == 0) { + render_view_->ReportNoFindInPageResults(find_identifier_); + } else { + render_view_->reportFindInPageMatchCount( + find_identifier_, total, final_result); + } +} + +void WebPluginDelegatePepper::SelectedFindResultChanged(int index) { + render_view_->reportFindInPageSelection( + find_identifier_, index + 1, WebKit::WebRect()); +} + NPError WebPluginDelegatePepper::Device2DQueryCapability(int32 capability, int32* value) { return NPERR_GENERIC_ERROR; @@ -982,6 +1016,10 @@ void WebPluginDelegatePepper::PrintEnd() { current_printable_area_ = gfx::Rect(); } +bool WebPluginDelegatePepper::SupportsFind() { + return GetFindExtensions() != NULL; +} + WebPluginDelegatePepper::WebPluginDelegatePepper( const base::WeakPtr<RenderView>& render_view, @@ -993,6 +1031,7 @@ WebPluginDelegatePepper::WebPluginDelegatePepper( #if defined(ENABLE_GPU) command_buffer_(NULL), #endif + find_identifier_(-1), method_factory3d_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { // For now we keep a window struct, although it isn't used. memset(&window_, 0, sizeof(window_)); @@ -1263,6 +1302,15 @@ NPPPrintExtensions* WebPluginDelegatePepper::GetPrintExtensions() { return ret; } +NPPFindExtensions* WebPluginDelegatePepper::GetFindExtensions() { + NPPFindExtensions* ret = NULL; + NPPExtensions* extensions = NULL; + instance()->NPP_GetValue(NPPVPepperExtensions, &extensions); + if (extensions && extensions->getFindExtensions) + ret = extensions->getFindExtensions(instance()->npp()); + return ret; +} + #if defined(OS_WIN) bool WebPluginDelegatePepper::DrawJPEGToPlatformDC( const SkBitmap& bitmap, diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h index 4f34631..13c1f47 100644 --- a/chrome/renderer/webplugin_delegate_pepper.h +++ b/chrome/renderer/webplugin_delegate_pepper.h @@ -74,6 +74,14 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { unsigned long resource_id, const GURL& url, int notify_id); virtual webkit_glue::WebPluginResourceClient* CreateSeekableResourceClient( unsigned long resource_id, int range_request_id); + virtual bool SupportsFind(); + virtual void StartFind(const std::string& search_text, + bool case_sensitive, + int identifier); + virtual void SelectFindResult(bool forward); + virtual void StopFind(); + virtual void NumberOfFindResultsChanged(int total, bool final_result); + virtual void SelectedFindResultChanged(int index); // WebPlugin2DDeviceDelegate implementation. virtual NPError Device2DQueryCapability(int32 capability, int32* value); @@ -149,8 +157,6 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { virtual bool PrintPage(int page_number, WebKit::WebCanvas* canvas); virtual void PrintEnd(); - // End of WebPluginDelegate implementation. - gfx::Rect GetRect() const { return window_rect_; } gfx::Rect GetClipRect() const { return clip_rect_; } @@ -188,6 +194,8 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { gfx::Size* page_dimensions); NPPPrintExtensions* GetPrintExtensions(); + NPPFindExtensions* GetFindExtensions(); + #if defined(OS_WIN) // Compresses the given bitmap as JPEG and draws it into the backing platform // DC (Windows-only). @@ -246,6 +254,9 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { CommandBufferProxy* command_buffer_; #endif + // The id of the current find operation, or -1 if none is in process. + int find_identifier_; + // Tells the browser out-of-band where the nested delegate lives on // the page. void SendNestedDelegateGeometryToBrowser(const gfx::Rect& window_rect, diff --git a/third_party/npapi/bindings/npapi_extensions.h b/third_party/npapi/bindings/npapi_extensions.h index 2cfc717..38bc886 100644 --- a/third_party/npapi/bindings/npapi_extensions.h +++ b/third_party/npapi/bindings/npapi_extensions.h @@ -12,14 +12,12 @@ /* * A fake "enum" value for getting browser-implemented Pepper extensions. - * The variable returns a pointer to an NPPepperExtensions structure - */ + * The variable returns a pointer to an NPNExtensions structure. */ #define NPNVPepperExtensions ((NPNVariable) 4000) /* * A fake "enum" value for getting plugin-implemented Pepper extensions. - * The variable returns a pointer to an NPPPepperExtensions structure - */ + * The variable returns a pointer to an NPPExtensions structure. */ #define NPPVPepperExtensions ((NPPVariable) 4001) typedef void NPDeviceConfig; @@ -153,7 +151,11 @@ typedef NPError (*NPDeviceThemePaint)( /* forward decl typdef structs */ typedef struct NPDevice NPDevice; -typedef struct NPExtensions NPExtensions; +typedef struct NPNExtensions NPNExtensions; + +// DEPRECATED: this typedef is just for the NaCl code until they switch to NPNExtensions. +// PLEASE REMOVE THIS WHEN THE NACL CODE IS UPDATED. +typedef struct NPNExtensions NPExtensions; /* generic device interface */ struct NPDevice { @@ -181,12 +183,29 @@ typedef void (*NPCopyTextToClipboardPtr)( NPP instance, const char* content); +/* Updates the number of find results for the current search term. If + * there are no matches 0 should be passed in. Only when the plugin has + * finished searching should it pass in the final count with finalResult set to + * true. */ +typedef void (*NPNumberOfFindResultsChangedPtr)( + NPP instance, + int total, + bool finalResult); + + /* Updates the index of the currently selected search item. */ +typedef void (*NPSelectedFindResultChangedPtr)( + NPP instance, + int index); + /* Pepper extensions */ -struct NPExtensions { +struct NPNExtensions { /* Device interface acquisition */ NPAcquireDevicePtr acquireDevice; /* Clipboard functionality */ NPCopyTextToClipboardPtr copyTextToClipboard; + /* Find */ + NPNumberOfFindResultsChangedPtr numberOfFindResultsChanged; + NPSelectedFindResultChangedPtr selectedFindResultChanged; }; /* Events -------------------------------------------------------------------*/ @@ -298,8 +317,7 @@ typedef struct _NPDeviceContext2DConfig { typedef struct _NPDeviceContext2D { - /* Internal value used by the browser to identify this device. - */ + /* Internal value used by the browser to identify this device. */ void* reserved; /* A pointer to the pixel data. This data is 8-bit values in BGRA order in @@ -308,20 +326,17 @@ typedef struct _NPDeviceContext2D * THIS DATA USES PREMULTIPLIED ALPHA. This means that each color channel has * been multiplied with the corresponding alpha, which makes compositing * easier. If any color channels have a value greater than the alpha value, - * you'll likely get crazy colors and weird artifacts. - */ + * you'll likely get crazy colors and weird artifacts. */ void* region; /* Length of each row of pixels in bytes. This may be larger than width * 4 - * if there is padding at the end of each row to help with alignment. - */ + * if there is padding at the end of each row to help with alignment. */ int32 stride; /* The dirty region that the plugin has painted into the buffer. This * will be initialized to the size of the plugin image in * initializeContextPtr. The plugin can change the values to only - * update portions of the image. - */ + * update portions of the image. */ struct { int32 left; int32 top; @@ -494,7 +509,7 @@ struct _NPDeviceContextAudio { * given printableArea size and DPI. printableArea is in points (a point is 1/72 * of an inch). The plugin is expected to remember the values of printableArea * and printerDPI for use in subsequent print interface calls. These values - * should be cleared in printEnd*/ + * should be cleared in printEnd. */ typedef NPError (*NPPPrintBeginPtr) ( NPP instance, NPRect* printableArea, @@ -516,8 +531,7 @@ typedef NPError (*NPPPrintEndPtr) (NPP instance); /* TODO(sanjeevr) : Provide a vector interface for printing. We need to decide * on a vector format that can support embedded fonts. A vector format will - * greatly reduce the size of the required output buffer -*/ + * greatly reduce the size of the required output buffer. */ typedef struct _NPPPrintExtensions { NPPPrintBeginPtr printBegin; @@ -529,8 +543,39 @@ typedef struct _NPPPrintExtensions { /* Returns NULL if the plugin does not support print extensions */ typedef NPPPrintExtensions* (*NPPGetPrintExtensionsPtr)(NPP instance); +/* Find ---------------------------------------------------------------------*/ + +/* Finds the given UTF-8 text starting at the current selection. The number of + * results will be updated asynchronously via numberOfFindResultsChanged. Note + * that multiple StartFind calls can happen before StopFind is called in the + * case of the search term changing. */ +typedef NPError (*NPPStartFindPtr) ( + NPP instance, + const char* text, + bool caseSensitive); + +/* Go to the next/previous result. */ +typedef NPError (*NPPSelectFindResultPtr) ( + NPP instance, + bool forward); + +/* Tells the plugin that the find operation has stopped, so it should clear + * any highlighting. */ +typedef NPError (*NPPStopFindPtr) ( + NPP instance); + +typedef struct _NPPFindExtensions { + NPPStartFindPtr startFind; + NPPSelectFindResultPtr selectFindResult; + NPPStopFindPtr stopFind; +} NPPFindExtensions; + +/* Returns NULL if the plugin does not support find extensions. */ +typedef NPPFindExtensions* (*NPPGetFindExtensionsPtr)(NPP instance); + typedef struct _NPPExtensions { NPPGetPrintExtensionsPtr getPrintExtensions; + NPPGetFindExtensionsPtr getFindExtensions; } NPPExtensions; #endif /* _NP_EXTENSIONS_H_ */ diff --git a/webkit/glue/plugins/npapi_extension_thunk.cc b/webkit/glue/plugins/npapi_extension_thunk.cc index 1ffecfc..d653b35 100644 --- a/webkit/glue/plugins/npapi_extension_thunk.cc +++ b/webkit/glue/plugins/npapi_extension_thunk.cc @@ -414,17 +414,33 @@ static void CopyTextToClipboard(NPP id, const char* content) { scw.WriteText(UTF8ToUTF16(content)); } +static void NumberOfFindResultsChanged(NPP id, int total, bool final_result) { + scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + if (plugin) { + plugin->webplugin()->delegate()->NumberOfFindResultsChanged( + total, final_result); + } +} + +static void SelectedFindResultChanged(NPP id, int index) { + scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + if (plugin) + plugin->webplugin()->delegate()->SelectedFindResultChanged(index); +} + namespace NPAPI { NPError GetPepperExtensionsFunctions(void* value) { - static const NPExtensions kExtensions = { + static const NPNExtensions kExtensions = { &AcquireDevice, &CopyTextToClipboard, + &NumberOfFindResultsChanged, + &SelectedFindResultChanged, }; // Return a pointer to the canonical function table. - NPExtensions* extensions = const_cast<NPExtensions*>(&kExtensions); - NPExtensions** exts = reinterpret_cast<NPExtensions**>(value); + NPNExtensions* extensions = const_cast<NPNExtensions*>(&kExtensions); + NPNExtensions** exts = reinterpret_cast<NPNExtensions**>(value); *exts = extensions; return NPERR_NO_ERROR; } diff --git a/webkit/glue/webplugin_delegate.h b/webkit/glue/webplugin_delegate.h index 343f486..19eee7a 100644 --- a/webkit/glue/webplugin_delegate.h +++ b/webkit/glue/webplugin_delegate.h @@ -138,6 +138,16 @@ class WebPluginDelegate : public WebPlugin2DDeviceDelegate, // has become seekable. virtual WebPluginResourceClient* CreateSeekableResourceClient( unsigned long resource_id, int range_request_id) = 0; + + // See WebPluginContainerImpl's description of the interface. + virtual bool SupportsFind() { return false; } + virtual void StartFind(const std::string& search_text, + bool case_sensitive, + int identifier) {} + virtual void SelectFindResult(bool forward) {} + virtual void StopFind() {} + virtual void NumberOfFindResultsChanged(int total, bool final_result) {} + virtual void SelectedFindResultChanged(int index) {} }; } // namespace webkit_glue |