From d162180196a87f0029aa0420d1e15f4157c62d3c Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 18 Dec 2015 04:40:42 +0530 Subject: [PATCH] add api to webview --- atom/browser/api/atom_api_web_contents.cc | 23 ++++---- atom/browser/api/atom_api_web_contents.h | 9 +++- atom/browser/lib/guest-view-manager.coffee | 7 +-- .../native_mate_converters/blink_converter.cc | 1 + .../native_mate_converters/blink_converter.h | 2 +- .../content_converter.cc | 4 +- .../lib/web-view/guest-view-internal.coffee | 1 + atom/renderer/lib/web-view/web-view.coffee | 2 + docs/api/web-contents.md | 44 +++++++++------- docs/api/web-view-tag.md | 52 +++++++++++++++++++ spec/fixtures/pages/content.html | 16 ++++++ spec/webview-spec.coffee | 16 ++++++ 12 files changed, 138 insertions(+), 39 deletions(-) create mode 100644 spec/fixtures/pages/content.html diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 8c24ea1a8..995774376 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -225,7 +225,8 @@ WebContents::WebContents(content::WebContents* web_contents) } WebContents::WebContents(v8::Isolate* isolate, - const mate::Dictionary& options) { + const mate::Dictionary& options) + : request_id_(0) { // Whether it is a guest WebContents. bool is_guest = false; options.Get("isGuest", &is_guest); @@ -441,12 +442,12 @@ void WebContents::FindReply(content::WebContents* web_contents, result.Set("requestId", request_id); result.Set("selectionArea", selection_rect); result.Set("finalUpdate", final_update); - Emit("find-in-page-response", result); + Emit("found-in-page", result); } else if (final_update) { result.Set("requestId", request_id); result.Set("matches", number_of_matches); result.Set("finalUpdate", final_update); - Emit("find-in-page-response", result); + Emit("found-in-page", result); } } @@ -926,25 +927,19 @@ void WebContents::ReplaceMisspelling(const base::string16& word) { web_contents()->ReplaceMisspelling(word); } -void WebContents::FindInPage(mate::Arguments* args) { - int request_id; +uint32 WebContents::FindInPage(mate::Arguments* args) { + uint32 request_id = GetNextRequestId(); base::string16 search_text; blink::WebFindOptions options; - if (!args->GetNext(&request_id)) { - args->ThrowError("Must provide a request id"); - return; - } - - if (!args->GetNext(&search_text)) { + if (!args->GetNext(&search_text) || search_text.empty()) { args->ThrowError("Must provide a non-empty search content"); - return; + return 0; } args->GetNext(&options); web_contents()->Find(request_id, search_text, options); - web_contents()->GetMainFrame() - ->ActivateFindInPageResultForAccessibility(request_id); + return request_id; } void WebContents::StopFindInPage(content::StopFindAction action) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index d78455608..0c7f129bd 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -110,7 +110,7 @@ class WebContents : public mate::TrackableObject, void Unselect(); void Replace(const base::string16& word); void ReplaceMisspelling(const base::string16& word); - void FindInPage(mate::Arguments* args); + uint32 FindInPage(mate::Arguments* args); void StopFindInPage(content::StopFindAction action); // Focus. @@ -250,6 +250,10 @@ class WebContents : public mate::TrackableObject, AtomBrowserContext* GetBrowserContext() const; + uint32 GetNextRequestId() { + return ++request_id_; + } + // Called when received a message from renderer. void OnRendererMessage(const base::string16& channel, const base::ListValue& args); @@ -271,6 +275,9 @@ class WebContents : public mate::TrackableObject, // The type of current WebContents. Type type_; + // Request id used for findInPage request. + uint32 request_id_; + DISALLOW_COPY_AND_ASSIGN(WebContents); }; diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 335d6516f..17308f4ce 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -22,9 +22,10 @@ supportedWebViewEvents = [ 'page-title-updated' 'page-favicon-updated' 'enter-html-full-screen' - 'leave-html-full-screen', - 'media-started-playing', - 'media-paused', + 'leave-html-full-screen' + 'media-started-playing' + 'media-paused' + 'found-in-page' ] nextInstanceId = 0 diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 71a2ac977..095490ab8 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -13,6 +13,7 @@ #include "content/public/browser/native_web_keyboard_event.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" +#include "third_party/WebKit/public/web/WebFindOptions.h" #include "third_party/WebKit/public/web/WebInputEvent.h" namespace { diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index 9f58659a3..5e715c631 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -6,7 +6,6 @@ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ #include "native_mate/converter.h" -#include "third_party/WebKit/public/web/WebFindOptions.h" namespace blink { class WebInputEvent; @@ -14,6 +13,7 @@ class WebMouseEvent; class WebMouseWheelEvent; class WebKeyboardEvent; struct WebDeviceEmulationParams; +struct WebFindOptions; struct WebFloatPoint; struct WebPoint; struct WebSize; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 41d19e396..d79094f79 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -111,8 +111,10 @@ bool Converter::FromV8( *out = content::STOP_FIND_ACTION_CLEAR_SELECTION; else if (action == "keepSelection") *out = content::STOP_FIND_ACTION_KEEP_SELECTION; - else + else if (action == "activateSelection") *out = content::STOP_FIND_ACTION_ACTIVATE_SELECTION; + else + return false; return true; } diff --git a/atom/renderer/lib/web-view/guest-view-internal.coffee b/atom/renderer/lib/web-view/guest-view-internal.coffee index 04fa707da..9178b3273 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.coffee +++ b/atom/renderer/lib/web-view/guest-view-internal.coffee @@ -27,6 +27,7 @@ WEB_VIEW_EVENTS = 'page-favicon-updated': ['favicons'] 'enter-html-full-screen': [] 'leave-html-full-screen': [] + 'found-in-page': ['result'] DEPRECATED_EVENTS = 'page-title-updated': 'page-title-set' diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index da36886f6..2d81bd6aa 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -287,6 +287,8 @@ registerWebViewElement = -> 'unselect' 'replace' 'replaceMisspelling' + 'findInPage' + 'stopFindInPage' 'getId' 'downloadURL' 'inspectServiceWorker' diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 4d7907c0f..3d903a841 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -229,16 +229,16 @@ Emitted when media starts playing. Emitted when media is paused or done playing. -### Event: 'find-in-page-response' +### Event: 'found-in-page' Returns: * `event` Event * `result` Object * `requestId` Integer - * `matches` Integer __Optional__ - Number of Matches. - * `selectionArea` Object __Optional__ - Coordinates of first match region. * `finalUpdate` Boolean - Indicates if more responses are to follow. + * `matches` Integer (Optional) - Number of Matches. + * `selectionArea` Object (Optional) - Coordinates of first match region. Emitted when a result is available for [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) request. @@ -434,38 +434,44 @@ Executes the editing command `replace` in web page. Executes the editing command `replaceMisspelling` in web page. -### `webContents.findInPage(id, text[, options])` +### `webContents.findInPage(text[, options])` -* `id` Integer * `text` String - Content to be searched, must not be empty. -* `options` Object __Optional__ - * `forward` Boolean - Whether to search forward or backward. - * `findNext` Boolean - Whether the operation is first request or a follow up. - * `matchCase` Boolean - Whether search should be case-sensitive. +* `options` Object (Optional) + * `forward` Boolean - Whether to search forward or backward, defaults to `true`. + * `findNext` Boolean - Whether the operation is first request or a follow up, + defaults to `false`. + * `matchCase` Boolean - Whether search should be case-sensitive, + defaults to `false`. * `wordStart` Boolean - Whether to look only at the start of words. - * ` medialCapitalAsWordStart` Boolean - When combined with `wordStart`, + defaults to `false`. + * `medialCapitalAsWordStart` Boolean - When combined with `wordStart`, accepts a match in the middle of a word if the match begins with an uppercase letter followed by a lowercase or non-letter. - Accepts several other intra-word matches + Accepts several other intra-word matches, defaults to `false`. -Finds all matches for the `text` in the web page. +Starts a request to find all matches for the `text` in the web page and returns an `Integer` +representing the request id used for the request. The result of the request can be +obtained by subscribing to [`found-in-page`](web-contents.md#event-found-in-page) event. ### `webContents.stopFindInPage(action)` -* `action` String - Should be called with either `clearSelection` or `keepSelection`. - By default it keeps the last selection. +* `action` String - Specifies the action to take place when ending + [`webContents.findInPage `](web-contents.md#webcontentfindinpage) request. + * `clearSelection` - Translate the selection into a normal selection. + * `keepSelection` - Clear the selection. + * `activateSelection` - Focus and click the selection node. -Stops any `findInPage` request for the `webContents` -with the provided `action`. +Stops any `findInPage` request for the `webContents` with the provided `action`. ```javascript -webContents.on('find-in-page-response', function(event, result) { +webContents.on('found-in-page', function(event, result) { if (result.finalUpdate) webContents.stopFindInPage("clearSelection"); }); -webContents.findInPage(1, "api"); -```. +const requestId = webContents.findInPage("api"); +``` ### `webContents.hasServiceWorker(callback)` diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index e317ef8ea..a65bc6063 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -348,6 +348,36 @@ Executes editing command `replace` in page. Executes editing command `replaceMisspelling` in page. +### `.findInPage(text[, options])` + +* `text` String - Content to be searched, must not be empty. +* `options` Object (Optional) + * `forward` Boolean - Whether to search forward or backward, defaults to `true`. + * `findNext` Boolean - Whether the operation is first request or a follow up, + defaults to `false`. + * `matchCase` Boolean - Whether search should be case-sensitive, + defaults to `false`. + * `wordStart` Boolean - Whether to look only at the start of words. + defaults to `false`. + * `medialCapitalAsWordStart` Boolean - When combined with `wordStart`, + accepts a match in the middle of a word if the match begins with an + uppercase letter followed by a lowercase or non-letter. + Accepts several other intra-word matches, defaults to `false`. + +Starts a request to find all matches for the `text` in the web page and returns an `Integer` +representing the request id used for the request. The result of the request can be +obtained by subscribing to [`found-in-page`](web-view-tag.md#event-found-in-page) event. + +### `.stopFindInPage(action)` + +* `action` String - Specifies the action to take place when ending + [`.findInPage `](web-view-tag.md#webviewtagfindinpage) request. + * `clearSelection` - Translate the selection into a normal selection. + * `keepSelection` - Clear the selection. + * `activateSelection` - Focus and click the selection node. + +Stops any `findInPage` request for the `webview` with the provided `action`. + ### `.print([options])` Prints `webview`'s web page. Same with `webContents.print([options])`. @@ -499,6 +529,28 @@ webview.addEventListener('console-message', function(e) { }); ``` +### Event: 'found-in-page' + +Returns: + +* `result` Object + * `requestId` Integer + * `finalUpdate` Boolean - Indicates if more responses are to follow. + * `matches` Integer (Optional) - Number of Matches. + * `selectionArea` Object (Optional) - Coordinates of first match region. + +Fired when a result is available for +[`webview.findInPage`](web-view-tag.md#webviewtagfindinpage) request. + +```javascript +webview.addEventListener('found-in-page', function(e) { + if (e.result.finalUpdate) + webview.stopFindInPage("keepSelection"); +}); + +const rquestId = webview.findInPage("test"); +``` + ### Event: 'new-window' Returns: diff --git a/spec/fixtures/pages/content.html b/spec/fixtures/pages/content.html new file mode 100644 index 000000000..e37ba34c1 --- /dev/null +++ b/spec/fixtures/pages/content.html @@ -0,0 +1,16 @@ +

+ Virtual member functions are key to the object-oriented paradigm, + such as making it easy for old code to call new code. + A virtual function allows derived classes to replace the implementation + provided by the base class. The compiler makes sure the replacement is + always called whenever the object in question is actually of the derived class, + even if the object is accessed by a base pointer rather than a derived pointer. + This allows algorithms in the base class to be replaced in the derived class, + even if users dont know about the derived class. + + class A { + public: + virtual void foo() {} + } + +

diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 28b25a226..c0578d050 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -390,3 +390,19 @@ describe ' tag', -> done() webview.src = "file://#{fixtures}/pages/audio.html" document.body.appendChild webview + + describe 'found-in-page event', -> + it 'emits when a request is made', (done) -> + requestId = null + listener = (e) -> + assert.equal e.result.requestId, requestId + if e.result.finalUpdate + assert.equal e.result.matches, 3 + webview.stopFindInPage "clearSelection" + done() + listener2 = (e) -> + requestId = webview.findInPage "virtual" + webview.addEventListener 'found-in-page', listener + webview.addEventListener 'did-finish-load', listener2 + webview.src = "file://#{fixtures}/pages/content.html" + document.body.appendChild webview -- 2.34.1