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

Side by Side Diff: webkit/glue/webframe_impl.cc

Issue 66016: Let WebKit draw the active highlight for FindInPage (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/webframe_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 const WebFindOptions& options, 963 const WebFindOptions& options,
964 bool wrap_within_frame, 964 bool wrap_within_frame,
965 WebRect* selection_rect) { 965 WebRect* selection_rect) {
966 WebCore::String webcore_string = webkit_glue::String16ToString(search_text); 966 WebCore::String webcore_string = webkit_glue::String16ToString(search_text);
967 967
968 WebFrameImpl* const main_frame_impl = 968 WebFrameImpl* const main_frame_impl =
969 static_cast<WebFrameImpl*>(GetView()->GetMainFrame()); 969 static_cast<WebFrameImpl*>(GetView()->GetMainFrame());
970 970
971 if (!options.findNext) 971 if (!options.findNext)
972 frame()->page()->unmarkAllTextMatches(); 972 frame()->page()->unmarkAllTextMatches();
973 else
974 SetMarkerActive(active_match_.get(), false); // Active match is changing.
973 975
974 // Starts the search from the current selection. 976 // Starts the search from the current selection.
975 bool start_in_selection = true; 977 bool start_in_selection = true;
976 978
979 // If the user has selected something since the last Find operation we want
980 // to start from there. Otherwise, we start searching from where the last Find
981 // operation left off (either a Find or a FindNext operation).
982 VisibleSelection selection(frame()->selection()->selection());
983 if (selection.isNone() && active_match_) {
984 selection = VisibleSelection(active_match_.get());
985 frame()->selection()->setSelection(selection);
986 }
987
977 DCHECK(frame() && frame()->view()); 988 DCHECK(frame() && frame()->view());
978 bool found = frame()->findString(webcore_string, options.forward, 989 bool found = frame()->findString(webcore_string, options.forward,
979 options.matchCase, wrap_within_frame, 990 options.matchCase, wrap_within_frame,
980 start_in_selection); 991 start_in_selection);
981 if (found) { 992 if (found) {
982 #if defined(OS_WIN)
983 WebCore::RenderThemeChromiumWin::setFindInPageMode(true);
984 #endif
985 // Store which frame was active. This will come in handy later when we 993 // Store which frame was active. This will come in handy later when we
986 // change the active match ordinal below. 994 // change the active match ordinal below.
987 WebFrameImpl* old_active_frame = main_frame_impl->active_match_frame_; 995 WebFrameImpl* old_active_frame = main_frame_impl->active_match_frame_;
988 // Set this frame as the active frame (the one with the active highlight). 996 // Set this frame as the active frame (the one with the active highlight).
989 main_frame_impl->active_match_frame_ = this; 997 main_frame_impl->active_match_frame_ = this;
990 998
991 // We found something, so we can now query the selection for its position. 999 // We found something, so we can now query the selection for its position.
992 VisibleSelection new_selection(frame()->selection()->selection()); 1000 VisibleSelection new_selection(frame()->selection()->selection());
993 IntRect curr_selection_rect; 1001 IntRect curr_selection_rect;
994 1002
995 // If we thought we found something, but it couldn't be selected (perhaps 1003 // If we thought we found something, but it couldn't be selected (perhaps
996 // because it was marked -webkit-user-select: none), we can't set it to 1004 // because it was marked -webkit-user-select: none), we can't set it to
997 // be active but we still continue searching. This matches Safari's 1005 // be active but we still continue searching. This matches Safari's
998 // behavior, including some oddities when selectable and un-selectable text 1006 // behavior, including some oddities when selectable and un-selectable text
999 // are mixed on a page: see https://bugs.webkit.org/show_bug.cgi?id=19127. 1007 // are mixed on a page: see https://bugs.webkit.org/show_bug.cgi?id=19127.
1000 if (new_selection.isNone() || 1008 if (new_selection.isNone() ||
1001 (new_selection.start() == new_selection.end())) { 1009 (new_selection.start() == new_selection.end())) {
1002 active_match_ = NULL; 1010 active_match_ = NULL;
1003 } else { 1011 } else {
1004 active_match_ = new_selection.toNormalizedRange(); 1012 active_match_ = new_selection.toNormalizedRange();
1005 curr_selection_rect = active_match_->boundingBox(); 1013 curr_selection_rect = active_match_->boundingBox();
1014 SetMarkerActive(active_match_.get(), true); // Active.
1015 ClearSelection(); // WebKit draws the highlighting for all matches.
1006 } 1016 }
1007 1017
1008 if (!options.findNext) { 1018 if (!options.findNext) {
1009 // This is a Find operation, so we set the flag to ask the scoping effort 1019 // This is a Find operation, so we set the flag to ask the scoping effort
1010 // to find the active rect for us so we can update the ordinal (n of m). 1020 // to find the active rect for us so we can update the ordinal (n of m).
1011 locating_active_rect_ = true; 1021 locating_active_rect_ = true;
1012 } else { 1022 } else {
1013 if (old_active_frame != this) { 1023 if (old_active_frame != this) {
1014 // If the active frame has changed it means that we have a multi-frame 1024 // If the active frame has changed it means that we have a multi-frame
1015 // page and we just switch to searching in a new frame. Then we just 1025 // page and we just switch to searching in a new frame. Then we just
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 // 1125, 1688, 2K, 3K). 1116 // 1125, 1688, 2K, 3K).
1107 static const int start_slowing_down_after = 500; 1117 static const int start_slowing_down_after = 500;
1108 static const int slowdown = 750; 1118 static const int slowdown = 750;
1109 int i = (last_match_count_ / start_slowing_down_after); 1119 int i = (last_match_count_ / start_slowing_down_after);
1110 next_invalidate_after_ += i * slowdown; 1120 next_invalidate_after_ += i * slowdown;
1111 1121
1112 InvalidateArea(INVALIDATE_SCROLLBAR); 1122 InvalidateArea(INVALIDATE_SCROLLBAR);
1113 } 1123 }
1114 } 1124 }
1115 1125
1116 void WebFrameImpl::AddMarker(WebCore::Range* range) { 1126 void WebFrameImpl::AddMarker(WebCore::Range* range, bool active_match) {
1117 // Use a TextIterator to visit the potentially multiple nodes the range 1127 // Use a TextIterator to visit the potentially multiple nodes the range
1118 // covers. 1128 // covers.
1119 TextIterator markedText(range); 1129 TextIterator markedText(range);
1120 for (; !markedText.atEnd(); markedText.advance()) { 1130 for (; !markedText.atEnd(); markedText.advance()) {
1121 RefPtr<Range> textPiece = markedText.range(); 1131 RefPtr<Range> textPiece = markedText.range();
1122 int exception = 0; 1132 int exception = 0;
1123 1133
1124 WebCore::DocumentMarker marker = { 1134 WebCore::DocumentMarker marker = {
1125 WebCore::DocumentMarker::TextMatch, 1135 WebCore::DocumentMarker::TextMatch,
1126 textPiece->startOffset(exception), 1136 textPiece->startOffset(exception),
1127 textPiece->endOffset(exception), 1137 textPiece->endOffset(exception),
1128 "" }; 1138 "",
1139 active_match };
1129 1140
1130 if (marker.endOffset > marker.startOffset) { 1141 if (marker.endOffset > marker.startOffset) {
1131 // Find the node to add a marker to and add it. 1142 // Find the node to add a marker to and add it.
1132 Node* node = textPiece->startContainer(exception); 1143 Node* node = textPiece->startContainer(exception);
1133 frame()->document()->addMarker(node, marker); 1144 frame()->document()->addMarker(node, marker);
1134 1145
1135 // Rendered rects for markers in WebKit are not populated until each time 1146 // Rendered rects for markers in WebKit are not populated until each time
1136 // the markers are painted. However, we need it to happen sooner, because 1147 // the markers are painted. However, we need it to happen sooner, because
1137 // the whole purpose of tickmarks on the scrollbar is to show where 1148 // the whole purpose of tickmarks on the scrollbar is to show where
1138 // matches off-screen are (that haven't been painted yet). 1149 // matches off-screen are (that haven't been painted yet).
1139 Vector<WebCore::DocumentMarker> markers = 1150 Vector<WebCore::DocumentMarker> markers =
1140 frame()->document()->markersForNode(node); 1151 frame()->document()->markersForNode(node);
1141 frame()->document()->setRenderedRectForMarker( 1152 frame()->document()->setRenderedRectForMarker(
1142 textPiece->startContainer(exception), 1153 textPiece->startContainer(exception),
1143 markers[markers.size() - 1], 1154 markers[markers.size() - 1],
1144 range->boundingBox()); 1155 range->boundingBox());
1145 } 1156 }
1146 } 1157 }
1147 } 1158 }
1148 1159
1160 void WebFrameImpl::SetMarkerActive(WebCore::Range* range, bool active) {
1161 if (!range)
1162 return;
1163
1164 frame()->document()->setMarkersActive(range, active);
1165 }
1166
1149 void WebFrameImpl::ScopeStringMatches(int request_id, 1167 void WebFrameImpl::ScopeStringMatches(int request_id,
1150 const string16& search_text, 1168 const string16& search_text,
1151 const WebFindOptions& options, 1169 const WebFindOptions& options,
1152 bool reset) { 1170 bool reset) {
1153 if (!ShouldScopeMatches(search_text)) 1171 if (!ShouldScopeMatches(search_text))
1154 return; 1172 return;
1155 1173
1156 WebFrameImpl* main_frame_impl = 1174 WebFrameImpl* main_frame_impl =
1157 static_cast<WebFrameImpl*>(GetView()->GetMainFrame()); 1175 static_cast<WebFrameImpl*>(GetView()->GetMainFrame());
1158 1176
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 VisiblePosition new_start = endVisiblePosition(result_range.get(), 1253 VisiblePosition new_start = endVisiblePosition(result_range.get(),
1236 WebCore::DOWNSTREAM); 1254 WebCore::DOWNSTREAM);
1237 if (new_start == startVisiblePosition(search_range.get(), 1255 if (new_start == startVisiblePosition(search_range.get(),
1238 WebCore::DOWNSTREAM)) 1256 WebCore::DOWNSTREAM))
1239 break; 1257 break;
1240 1258
1241 // Only treat the result as a match if it is visible 1259 // Only treat the result as a match if it is visible
1242 if (frame()->editor()->insideVisibleArea(result_range.get())) { 1260 if (frame()->editor()->insideVisibleArea(result_range.get())) {
1243 ++match_count; 1261 ++match_count;
1244 1262
1245 AddMarker(result_range.get());
1246
1247 setStart(search_range.get(), new_start); 1263 setStart(search_range.get(), new_start);
1248 Node* shadow_tree_root = search_range->shadowTreeRootNode(); 1264 Node* shadow_tree_root = search_range->shadowTreeRootNode();
1249 if (search_range->collapsed(ec) && shadow_tree_root) 1265 if (search_range->collapsed(ec) && shadow_tree_root)
1250 search_range->setEnd(shadow_tree_root, 1266 search_range->setEnd(shadow_tree_root,
1251 shadow_tree_root->childNodeCount(), ec); 1267 shadow_tree_root->childNodeCount(), ec);
1252 1268
1253 // Catch a special case where Find found something but doesn't know what 1269 // Catch a special case where Find found something but doesn't know what
1254 // the bounding box for it is. In this case we set the first match we find 1270 // the bounding box for it is. In this case we set the first match we find
1255 // as the active rect. 1271 // as the active rect.
1256 IntRect result_bounds = result_range->boundingBox(); 1272 IntRect result_bounds = result_range->boundingBox();
1257 IntRect active_selection_rect; 1273 IntRect active_selection_rect;
1258 if (locating_active_rect_) { 1274 if (locating_active_rect_) {
1259 active_selection_rect = active_match_.get() ? 1275 active_selection_rect = active_match_.get() ?
1260 active_match_->boundingBox() : result_bounds; 1276 active_match_->boundingBox() : result_bounds;
1261 } 1277 }
1262 1278
1263 // If the Find function found a match it will have stored where the 1279 // If the Find function found a match it will have stored where the
1264 // match was found in active_selection_rect_ on the current frame. If we 1280 // match was found in active_selection_rect_ on the current frame. If we
1265 // find this rect during scoping it means we have found the active 1281 // find this rect during scoping it means we have found the active
1266 // tickmark. 1282 // tickmark.
1283 bool found_active_match = false;
1267 if (locating_active_rect_ && (active_selection_rect == result_bounds)) { 1284 if (locating_active_rect_ && (active_selection_rect == result_bounds)) {
1268 // We have found the active tickmark frame. 1285 // We have found the active tickmark frame.
1269 main_frame_impl->active_match_frame_ = this; 1286 main_frame_impl->active_match_frame_ = this;
1287 found_active_match = true;
1270 // We also know which tickmark is active now. 1288 // We also know which tickmark is active now.
1271 active_match_index_ = match_count - 1; 1289 active_match_index_ = match_count - 1;
1272 // To stop looking for the active tickmark, we set this flag. 1290 // To stop looking for the active tickmark, we set this flag.
1273 locating_active_rect_ = false; 1291 locating_active_rect_ = false;
1274 1292
1275 #if defined(OS_WIN) 1293 #if defined(OS_WIN)
1276 // TODO(pinkerton): Fix Mac invalidation to be more like Win ScrollView 1294 // TODO(pinkerton): Fix Mac invalidation to be more like Win ScrollView
1277 // Notify browser of new location for the selected rectangle. 1295 // Notify browser of new location for the selected rectangle.
1278 result_bounds.move(-frameview()->scrollOffset().width(), 1296 result_bounds.move(-frameview()->scrollOffset().width(),
1279 -frameview()->scrollOffset().height()); 1297 -frameview()->scrollOffset().height());
1280 ReportFindInPageSelection( 1298 ReportFindInPageSelection(
1281 webkit_glue::IntRectToWebRect( 1299 webkit_glue::IntRectToWebRect(
1282 frame()->view()->convertToContainingWindow(result_bounds)), 1300 frame()->view()->convertToContainingWindow(result_bounds)),
1283 active_match_index_ + 1, 1301 active_match_index_ + 1,
1284 request_id); 1302 request_id);
1285 #endif 1303 #endif
1286 } 1304 }
1305
1306 AddMarker(result_range.get(), found_active_match);
1287 } 1307 }
1288 1308
1289 resume_scoping_from_range_ = result_range; 1309 resume_scoping_from_range_ = result_range;
1290 timeout = (Time::Now() - start_time).InMilliseconds() >= kTimeout; 1310 timeout = (Time::Now() - start_time).InMilliseconds() >= kTimeout;
1291 } while (!timeout); 1311 } while (!timeout);
1292 1312
1293 // Remember what we search for last time, so we can skip searching if more 1313 // Remember what we search for last time, so we can skip searching if more
1294 // letters are added to the search string (and last outcome was 0). 1314 // letters are added to the search string (and last outcome was 0).
1295 last_search_string_ = search_text; 1315 last_search_string_ = search_text;
1296 1316
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 } 1402 }
1383 } 1403 }
1384 } 1404 }
1385 } 1405 }
1386 1406
1387 void WebFrameImpl::StopFinding(bool clear_selection) { 1407 void WebFrameImpl::StopFinding(bool clear_selection) {
1388 if (!clear_selection) 1408 if (!clear_selection)
1389 SetFindEndstateFocusAndSelection(); 1409 SetFindEndstateFocusAndSelection();
1390 CancelPendingScopingEffort(); 1410 CancelPendingScopingEffort();
1391 1411
1392 #if defined(OS_WIN)
1393 WebCore::RenderThemeChromiumWin::setFindInPageMode(false);
1394 #endif
1395
1396 // Remove all markers for matches found and turn off the highlighting. 1412 // Remove all markers for matches found and turn off the highlighting.
1397 if (this == static_cast<WebFrameImpl*>(GetView()->GetMainFrame())) 1413 if (this == static_cast<WebFrameImpl*>(GetView()->GetMainFrame()))
1398 frame()->document()->removeMarkers(WebCore::DocumentMarker::TextMatch); 1414 frame()->document()->removeMarkers(WebCore::DocumentMarker::TextMatch);
1399 frame()->setMarkedTextMatchesAreHighlighted(false); 1415 frame()->setMarkedTextMatchesAreHighlighted(false);
1400 1416
1401 // Let the frame know that we don't want tickmarks or highlighting anymore. 1417 // Let the frame know that we don't want tickmarks or highlighting anymore.
1402 InvalidateArea(INVALIDATE_ALL); 1418 InvalidateArea(INVALIDATE_ALL);
1403 } 1419 }
1404 1420
1405 void WebFrameImpl::SelectAll() { 1421 void WebFrameImpl::SelectAll() {
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 return password_listeners_.get(input_element); 1992 return password_listeners_.get(input_element);
1977 } 1993 }
1978 1994
1979 void WebFrameImpl::ClearPasswordListeners() { 1995 void WebFrameImpl::ClearPasswordListeners() {
1980 for (PasswordListenerMap::iterator iter = password_listeners_.begin(); 1996 for (PasswordListenerMap::iterator iter = password_listeners_.begin();
1981 iter != password_listeners_.end(); ++iter) { 1997 iter != password_listeners_.end(); ++iter) {
1982 delete iter->second; 1998 delete iter->second;
1983 } 1999 }
1984 password_listeners_.clear(); 2000 password_listeners_.clear();
1985 } 2001 }
OLDNEW
« no previous file with comments | « webkit/glue/webframe_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698