OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * 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 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 (options.forward ? 0 : Backwards) | | 141 (options.forward ? 0 : Backwards) | |
142 (options.matchCase ? 0 : CaseInsensitive) | | 142 (options.matchCase ? 0 : CaseInsensitive) | |
143 (wrapWithinFrame ? WrapAround : 0) | | 143 (wrapWithinFrame ? WrapAround : 0) | |
144 (options.wordStart ? AtWordStarts : 0) | | 144 (options.wordStart ? AtWordStarts : 0) | |
145 (options.medialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) | | 145 (options.medialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) | |
146 (options.findNext ? 0 : StartInSelection); | 146 (options.findNext ? 0 : StartInSelection); |
147 m_activeMatch = ownerFrame().frame()->editor().findStringAndScrollToVisible( | 147 m_activeMatch = ownerFrame().frame()->editor().findStringAndScrollToVisible( |
148 searchText, m_activeMatch.get(), findOptions); | 148 searchText, m_activeMatch.get(), findOptions); |
149 | 149 |
150 if (!m_activeMatch) { | 150 if (!m_activeMatch) { |
151 // If we're finding next the next active match might not be in the current f
rame. | 151 // If we're finding next the next active match might not be in the current |
152 // In this case we don't want to clear the matches cache. | 152 // frame. In this case we don't want to clear the matches cache. |
153 if (!options.findNext) | 153 if (!options.findNext) |
154 clearFindMatchesCache(); | 154 clearFindMatchesCache(); |
155 | 155 |
156 ownerFrame().frameView()->invalidatePaintForTickmarks(); | 156 ownerFrame().frameView()->invalidatePaintForTickmarks(); |
157 return false; | 157 return false; |
158 } | 158 } |
159 | 159 |
160 // If the user is browsing a page with autosizing, adjust the zoom to the | 160 // If the user is browsing a page with autosizing, adjust the zoom to the |
161 // column where the next hit has been found. Doing this when autosizing is | 161 // column where the next hit has been found. Doing this when autosizing is |
162 // not set will result in a zoom reset on small devices. | 162 // not set will result in a zoom reset on small devices. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 identifier, m_activeMatchIndex + 1, WebAXObject(startObject), | 263 identifier, m_activeMatchIndex + 1, WebAXObject(startObject), |
264 m_activeMatch->startOffset(), WebAXObject(endObject), | 264 m_activeMatch->startOffset(), WebAXObject(endObject), |
265 m_activeMatch->endOffset()); | 265 m_activeMatch->endOffset()); |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 void TextFinder::scopeStringMatches(int identifier, | 269 void TextFinder::scopeStringMatches(int identifier, |
270 const WebString& searchText, | 270 const WebString& searchText, |
271 const WebFindOptions& options, | 271 const WebFindOptions& options, |
272 bool reset) { | 272 bool reset) { |
273 // TODO(dglazkov): The reset/continue cases need to be untangled into two sepa
rate functions. This collation of logic | 273 // TODO(dglazkov): The reset/continue cases need to be untangled into two |
274 // is unnecessary and adds to overall complexity of the code. | 274 // separate functions. This collation of logic is unnecessary and adds to |
| 275 // overall complexity of the code. |
275 if (reset) { | 276 if (reset) { |
276 // This is a brand new search, so we need to reset everything. | 277 // This is a brand new search, so we need to reset everything. |
277 // Scoping is just about to begin. | 278 // Scoping is just about to begin. |
278 m_scopingInProgress = true; | 279 m_scopingInProgress = true; |
279 | 280 |
280 // Need to keep the current identifier locally in order to finish the | 281 // Need to keep the current identifier locally in order to finish the |
281 // request in case the frame is detached during the process. | 282 // request in case the frame is detached during the process. |
282 m_findRequestIdentifier = identifier; | 283 m_findRequestIdentifier = identifier; |
283 | 284 |
284 // Clear highlighting for this frame. | 285 // Clear highlighting for this frame. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 if (m_resumeScopingFromRange) { | 319 if (m_resumeScopingFromRange) { |
319 // This is a continuation of a scoping operation that timed out and didn't | 320 // This is a continuation of a scoping operation that timed out and didn't |
320 // complete last time around, so we should start from where we left off. | 321 // complete last time around, so we should start from where we left off. |
321 DCHECK(m_resumeScopingFromRange->collapsed()); | 322 DCHECK(m_resumeScopingFromRange->collapsed()); |
322 searchStart = fromPositionInDOMTree<EditingInFlatTreeStrategy>( | 323 searchStart = fromPositionInDOMTree<EditingInFlatTreeStrategy>( |
323 m_resumeScopingFromRange->endPosition()); | 324 m_resumeScopingFromRange->endPosition()); |
324 if (searchStart.document() != searchEnd.document()) | 325 if (searchStart.document() != searchEnd.document()) |
325 return; | 326 return; |
326 } | 327 } |
327 | 328 |
328 // TODO(dglazkov): The use of updateStyleAndLayoutIgnorePendingStylesheets nee
ds to be audited. | 329 // TODO(dglazkov): The use of updateStyleAndLayoutIgnorePendingStylesheets |
329 // see http://crbug.com/590369 for more details. | 330 // needs to be audited. see http://crbug.com/590369 for more details. |
330 searchStart.document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 331 searchStart.document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
331 | 332 |
332 // This timeout controls how long we scope before releasing control. This | 333 // This timeout controls how long we scope before releasing control. This |
333 // value does not prevent us from running for longer than this, but it is | 334 // value does not prevent us from running for longer than this, but it is |
334 // periodically checked to see if we have exceeded our allocated time. | 335 // periodically checked to see if we have exceeded our allocated time. |
335 const double maxScopingDuration = 0.1; // seconds | 336 const double maxScopingDuration = 0.1; // seconds |
336 | 337 |
337 int matchCount = 0; | 338 int matchCount = 0; |
338 bool timedOut = false; | 339 bool timedOut = false; |
339 double startTime = currentTime(); | 340 double startTime = currentTime(); |
340 do { | 341 do { |
341 // Find next occurrence of the search string. | 342 // Find next occurrence of the search string. |
342 // FIXME: (http://crbug.com/6818) This WebKit operation may run for longer | 343 // FIXME: (http://crbug.com/6818) This WebKit operation may run for longer |
343 // than the timeout value, and is not interruptible as it is currently | 344 // than the timeout value, and is not interruptible as it is currently |
344 // written. We may need to rewrite it with interruptibility in mind, or | 345 // written. We may need to rewrite it with interruptibility in mind, or |
345 // find an alternative. | 346 // find an alternative. |
346 const EphemeralRangeInFlatTree result = | 347 const EphemeralRangeInFlatTree result = |
347 findPlainText(EphemeralRangeInFlatTree(searchStart, searchEnd), | 348 findPlainText(EphemeralRangeInFlatTree(searchStart, searchEnd), |
348 searchText, options.matchCase ? 0 : CaseInsensitive); | 349 searchText, options.matchCase ? 0 : CaseInsensitive); |
349 if (result.isCollapsed()) { | 350 if (result.isCollapsed()) { |
350 // Not found. | 351 // Not found. |
351 break; | 352 break; |
352 } | 353 } |
353 Range* resultRange = Range::create( | 354 Range* resultRange = Range::create( |
354 result.document(), toPositionInDOMTree(result.startPosition()), | 355 result.document(), toPositionInDOMTree(result.startPosition()), |
355 toPositionInDOMTree(result.endPosition())); | 356 toPositionInDOMTree(result.endPosition())); |
356 if (resultRange->collapsed()) { | 357 if (resultRange->collapsed()) { |
357 // resultRange will be collapsed if the matched text spans over multiple T
reeScopes. | 358 // resultRange will be collapsed if the matched text spans over multiple |
358 // FIXME: Show such matches to users. | 359 // TreeScopes. FIXME: Show such matches to users. |
359 searchStart = result.endPosition(); | 360 searchStart = result.endPosition(); |
360 continue; | 361 continue; |
361 } | 362 } |
362 | 363 |
363 ++matchCount; | 364 ++matchCount; |
364 | 365 |
365 // Catch a special case where Find found something but doesn't know what | 366 // Catch a special case where Find found something but doesn't know what |
366 // the bounding box for it is. In this case we set the first match we find | 367 // the bounding box for it is. In this case we set the first match we find |
367 // as the active rect. | 368 // as the active rect. |
368 IntRect resultBounds = resultRange->boundingBox(); | 369 IntRect resultBounds = resultRange->boundingBox(); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 filteredMatches.reserveCapacity(m_findMatchesCache.size() - deadMatches); | 538 filteredMatches.reserveCapacity(m_findMatchesCache.size() - deadMatches); |
538 | 539 |
539 for (const FindMatch& match : m_findMatchesCache) { | 540 for (const FindMatch& match : m_findMatchesCache) { |
540 if (!match.m_rect.isEmpty()) | 541 if (!match.m_rect.isEmpty()) |
541 filteredMatches.append(match); | 542 filteredMatches.append(match); |
542 } | 543 } |
543 | 544 |
544 m_findMatchesCache.swap(filteredMatches); | 545 m_findMatchesCache.swap(filteredMatches); |
545 } | 546 } |
546 | 547 |
547 // Invalidate the rects in child frames. Will be updated later during traversa
l. | 548 // Invalidate the rects in child frames. Will be updated later during |
| 549 // traversal. |
548 if (!m_findMatchRectsAreValid) | 550 if (!m_findMatchRectsAreValid) |
549 for (WebFrame* child = ownerFrame().firstChild(); child; | 551 for (WebFrame* child = ownerFrame().firstChild(); child; |
550 child = child->nextSibling()) | 552 child = child->nextSibling()) |
551 toWebLocalFrameImpl(child)->ensureTextFinder().m_findMatchRectsAreValid = | 553 toWebLocalFrameImpl(child)->ensureTextFinder().m_findMatchRectsAreValid = |
552 false; | 554 false; |
553 | 555 |
554 m_findMatchRectsAreValid = true; | 556 m_findMatchRectsAreValid = true; |
555 } | 557 } |
556 | 558 |
557 WebFloatRect TextFinder::activeFindMatchRect() { | 559 WebFloatRect TextFinder::activeFindMatchRect() { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 | 623 |
622 // Set this frame as the active frame (the one with the active highlight). | 624 // Set this frame as the active frame (the one with the active highlight). |
623 m_currentActiveMatchFrame = true; | 625 m_currentActiveMatchFrame = true; |
624 ownerFrame().viewImpl()->setFocusedFrame(&ownerFrame()); | 626 ownerFrame().viewImpl()->setFocusedFrame(&ownerFrame()); |
625 | 627 |
626 if (m_activeMatch) | 628 if (m_activeMatch) |
627 setMarkerActive(m_activeMatch.get(), false); | 629 setMarkerActive(m_activeMatch.get(), false); |
628 m_activeMatch = range; | 630 m_activeMatch = range; |
629 setMarkerActive(m_activeMatch.get(), true); | 631 setMarkerActive(m_activeMatch.get(), true); |
630 | 632 |
631 // Clear any user selection, to make sure Find Next continues on from the ma
tch we just activated. | 633 // Clear any user selection, to make sure Find Next continues on from the |
| 634 // match we just activated. |
632 ownerFrame().frame()->selection().clear(); | 635 ownerFrame().frame()->selection().clear(); |
633 | 636 |
634 // Make sure no node is focused. See http://crbug.com/38700. | 637 // Make sure no node is focused. See http://crbug.com/38700. |
635 ownerFrame().frame()->document()->clearFocusedElement(); | 638 ownerFrame().frame()->document()->clearFocusedElement(); |
636 } | 639 } |
637 | 640 |
638 IntRect activeMatchRect; | 641 IntRect activeMatchRect; |
639 IntRect activeMatchBoundingBox = enclosingIntRect( | 642 IntRect activeMatchBoundingBox = enclosingIntRect( |
640 LayoutObject::absoluteBoundingBoxRectForRange(m_activeMatch.get())); | 643 LayoutObject::absoluteBoundingBoxRectForRange(m_activeMatch.get())); |
641 | 644 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 | 776 |
774 DEFINE_TRACE(TextFinder) { | 777 DEFINE_TRACE(TextFinder) { |
775 visitor->trace(m_ownerFrame); | 778 visitor->trace(m_ownerFrame); |
776 visitor->trace(m_activeMatch); | 779 visitor->trace(m_activeMatch); |
777 visitor->trace(m_resumeScopingFromRange); | 780 visitor->trace(m_resumeScopingFromRange); |
778 visitor->trace(m_deferredScopingWork); | 781 visitor->trace(m_deferredScopingWork); |
779 visitor->trace(m_findMatchesCache); | 782 visitor->trace(m_findMatchesCache); |
780 } | 783 } |
781 | 784 |
782 } // namespace blink | 785 } // namespace blink |
OLD | NEW |