| 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 |