Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1165)

Unified Diff: components/html_viewer/html_frame.cc

Issue 1371773003: mandoline: Add find in page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: General patch cleanup. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/html_viewer/html_frame.cc
diff --git a/components/html_viewer/html_frame.cc b/components/html_viewer/html_frame.cc
index edaed4f2c63cd875ffa769a50c1c4d5da377ba7f..73c1d87a8e8a421c86bf93b4472efbdd2b8bdb00 100644
--- a/components/html_viewer/html_frame.cc
+++ b/components/html_viewer/html_frame.cc
@@ -49,6 +49,7 @@
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
+#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -238,6 +239,14 @@ blink::WebView* HTMLFrame::web_view() {
: nullptr;
}
+blink::WebView* HTMLFrame::web_view() const {
+ blink::WebWidget* web_widget =
+ html_widget_ ? html_widget_->GetWidget() : nullptr;
+ return web_widget && web_widget->isWebView()
+ ? static_cast<blink::WebView*>(web_widget)
+ : nullptr;
+}
+
blink::WebWidget* HTMLFrame::GetWebWidget() {
return html_widget_ ? html_widget_->GetWidget() : nullptr;
}
@@ -466,6 +475,18 @@ void HTMLFrame::didReceiveTitle(blink::WebLocalFrame* frame,
server_->TitleChanged(formatted);
}
+void HTMLFrame::reportFindInPageMatchCount(int identifier,
+ int count,
+ bool finalUpdate) {
+ server_->ReportFindInPageMatchCount(identifier, count, finalUpdate);
+}
+
+void HTMLFrame::reportFindInPageSelection(int identifier,
+ int activeMatchOrdinal,
+ const blink::WebRect& selection) {
+ server_->ReportFindInPageSelection(identifier, activeMatchOrdinal);
+}
+
void HTMLFrame::Bind(
web_view::mojom::FramePtr frame,
mojo::InterfaceRequest<web_view::mojom::FrameClient> frame_client_request) {
@@ -617,6 +638,19 @@ void HTMLFrame::SwapDelegate(HTMLFrameDelegate* delegate) {
delegate->OnSwap(this, old_delegate);
}
+blink::WebElement HTMLFrame::GetFocusedElement() const {
+ if (!web_view())
+ return blink::WebElement();
+ blink::WebFrame* focused_frame = web_view()->focusedFrame();
+ if (focused_frame) {
+ blink::WebDocument doc = focused_frame->document();
+ if (!doc.isNull())
+ return doc.focusedElement();
+ }
+
+ return blink::WebElement();
+}
+
HTMLFrame* HTMLFrame::FindFrameWithWebFrame(blink::WebFrame* web_frame) {
if (web_frame_ == web_frame)
return this;
@@ -806,6 +840,129 @@ void HTMLFrame::OnDispatchFrameLoadEvent(uint32_t frame_id) {
frame->web_frame_->toWebRemoteFrame()->DispatchLoadEventForFrameOwner();
}
+void HTMLFrame::OnFind(int32 request_id, const mojo::String& search_text) {
Elliot Glaysher 2015/09/28 21:22:57 This and GetFocusedElement() were copied almost ve
+ blink::WebFrame* main_frame = web_view()->mainFrame();
+ blink::WebFrame* frame_after_main = main_frame->traverseNext(true);
+ blink::WebFrame* focused_frame = web_view()->focusedFrame();
+ blink::WebFrame* search_frame =
+ focused_frame; // start searching focused frame.
+
+ bool multi_frame = (frame_after_main != main_frame);
+
+ blink::WebFindOptions options;
+
+ // If we have multiple frames, we don't want to wrap the search within the
+ // frame, so we check here if we only have main_frame in the chain.
+ bool wrap_within_frame = !multi_frame;
+
+ blink::WebRect selection_rect;
+ bool result = false;
+
+ // If something is selected when we start searching it means we cannot just
+ // increment the current match ordinal; we need to re-generate it.
+ blink::WebRange current_selection = focused_frame->selectionRange();
+
+ do {
+ result = search_frame->find(request_id, search_text.To<blink::WebString>(),
+ options, wrap_within_frame, &selection_rect);
+
+ if (!result) {
+ // don't leave text selected as you move to the next frame.
+ search_frame->executeCommand(blink::WebString::fromUTF8("Unselect"),
+ GetFocusedElement());
+
+ // Find the next frame, but skip the invisible ones.
+ do {
+ // What is the next frame to search? (we might be going backwards). Note
+ // that we specify wrap=true so that search_frame never becomes NULL.
+ search_frame = options.forward ? search_frame->traverseNext(true)
+ : search_frame->traversePrevious(true);
+ } while (!search_frame->hasVisibleContent() &&
+ search_frame != focused_frame);
+
+ // Make sure selection doesn't affect the search operation in new frame.
+ search_frame->executeCommand(blink::WebString::fromUTF8("Unselect"),
+ GetFocusedElement());
+
+ // If we have multiple frames and we have wrapped back around to the
+ // focused frame, we need to search it once more allowing wrap within
+ // the frame, otherwise it will report 'no match' if the focused frame has
+ // reported matches, but no frames after the focused_frame contain a
+ // match for the search word(s).
+ if (multi_frame && search_frame == focused_frame) {
+ result =
+ search_frame->find(request_id, search_text.To<blink::WebString>(),
+ options, true, // Force wrapping.
+ &selection_rect);
+ }
+ }
+
+ web_view()->setFocusedFrame(search_frame);
+ } while (!result && search_frame != focused_frame);
+
+ if (options.findNext && current_selection.isNull()) {
+ // Force the main_frame to report the actual count.
+ main_frame->increaseMatchCount(0, request_id);
+ } else {
+ // If nothing is found, set result to "0 of 0", otherwise, set it to
+ // "-1 of 1" to indicate that we found at least one item, but we don't know
+ // yet what is active.
+ int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
+ int match_count = result ? 1 : 0; // 1 here means possibly more coming.
+
+ // If we find no matches then this will be our last status update.
+ // Otherwise the scoping effort will send more results.
+ bool final_status_update = !result;
+
+ server_->ReportFindInPageSelection(request_id, ordinal);
+ server_->ReportFindInPageMatchCount(request_id, match_count,
+ final_status_update);
+
+ // Scoping effort begins, starting with the mainframe.
+ search_frame = main_frame;
+
+ main_frame->resetMatchCount();
+
+ do {
+ // Cancel all old scoping requests before starting a new one.
+ search_frame->cancelPendingScopingEffort();
+
+ // We don't start another scoping effort unless at least one match has
+ // been found.
+ if (result) {
+ // Start new scoping request. If the scoping function determines that it
+ // needs to scope, it will defer until later.
+ search_frame->scopeStringMatches(
+ request_id, search_text.To<blink::WebString>(), options,
+ true); // reset the tickmarks
+ }
+
+ // Iterate to the next frame. The frame will not necessarily scope, for
+ // example if it is not visible.
+ search_frame = search_frame->traverseNext(true);
+ } while (search_frame != main_frame);
+ }
+}
+
+void HTMLFrame::OnStopFinding() {
+ blink::WebView* view = web_view();
+ if (!view)
+ return;
+
+ // TODO(erg): content has a whole concept about different actions that can be
+ // done during a stop find. We aren't handling these at all.
+ bool clear_selection = true;
+
+ view->focusedFrame()->executeCommand(blink::WebString::fromUTF8("Unselect"),
+ GetFocusedElement());
+
+ blink::WebFrame* frame = view->mainFrame();
+ while (frame) {
+ frame->stopFinding(clear_selection);
+ frame = frame->traverseNext(false);
+ }
+}
+
void HTMLFrame::frameDetached(blink::WebRemoteFrameClient::DetachType type) {
if (type == blink::WebRemoteFrameClient::DetachType::Swap) {
web_frame_->close();

Powered by Google App Engine
This is Rietveld 408576698