| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |