Chromium Code Reviews| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 : m_range(range) | 58 : m_range(range) |
| 59 , m_ordinal(ordinal) | 59 , m_ordinal(ordinal) |
| 60 { | 60 { |
| 61 } | 61 } |
| 62 | 62 |
| 63 void TextFinder::FindMatch::trace(Visitor* visitor) | 63 void TextFinder::FindMatch::trace(Visitor* visitor) |
| 64 { | 64 { |
| 65 visitor->trace(m_range); | 65 visitor->trace(m_range); |
| 66 } | 66 } |
| 67 | 67 |
| 68 class TextFinder::DeferredScopeStringMatches { | 68 class TextFinder::DeferredScopeStringMatches : public NoBaseWillBeGarbageCollect edFinalized<TextFinder::DeferredScopeStringMatches> { |
| 69 public: | 69 public: |
| 70 static PassOwnPtrWillBeRawPtr<DeferredScopeStringMatches> create(TextFinder* textFinder, int identifier, const WebString& searchText, const WebFindOptions& options, bool reset) | |
| 71 { | |
| 72 return adoptPtrWillBeNoop(new DeferredScopeStringMatches(textFinder, ide ntifier, searchText, options, reset)); | |
| 73 } | |
| 74 | |
| 75 void trace(Visitor* visitor) | |
| 76 { | |
| 77 visitor->trace(m_textFinder); | |
| 78 } | |
| 79 | |
| 80 void dispose() | |
|
haraken
2014/10/24 01:18:21
Actually this dispose() method wouldn't be needed.
sof
2014/10/24 05:32:00
Yes, that will happen as expectefd. And is now don
| |
| 81 { | |
| 82 if (m_timer.isActive()) | |
| 83 m_timer.stop(); | |
| 84 } | |
| 85 | |
| 86 private: | |
| 70 DeferredScopeStringMatches(TextFinder* textFinder, int identifier, const Web String& searchText, const WebFindOptions& options, bool reset) | 87 DeferredScopeStringMatches(TextFinder* textFinder, int identifier, const Web String& searchText, const WebFindOptions& options, bool reset) |
| 71 : m_timer(this, &DeferredScopeStringMatches::doTimeout) | 88 : m_timer(this, &DeferredScopeStringMatches::doTimeout) |
| 72 , m_textFinder(textFinder) | 89 , m_textFinder(textFinder) |
| 73 , m_identifier(identifier) | 90 , m_identifier(identifier) |
| 74 , m_searchText(searchText) | 91 , m_searchText(searchText) |
| 75 , m_options(options) | 92 , m_options(options) |
| 76 , m_reset(reset) | 93 , m_reset(reset) |
| 77 { | 94 { |
| 78 m_timer.startOneShot(0.0, FROM_HERE); | 95 m_timer.startOneShot(0.0, FROM_HERE); |
| 79 } | 96 } |
| 80 | 97 |
| 81 private: | |
| 82 void doTimeout(Timer<DeferredScopeStringMatches>*) | 98 void doTimeout(Timer<DeferredScopeStringMatches>*) |
| 83 { | 99 { |
| 84 m_textFinder->callScopeStringMatches(this, m_identifier, m_searchText, m _options, m_reset); | 100 m_textFinder->callScopeStringMatches(this, m_identifier, m_searchText, m _options, m_reset); |
| 85 } | 101 } |
| 86 | 102 |
| 87 Timer<DeferredScopeStringMatches> m_timer; | 103 Timer<DeferredScopeStringMatches> m_timer; |
| 88 TextFinder* m_textFinder; | 104 RawPtrWillBeMember<TextFinder> m_textFinder; |
| 89 const int m_identifier; | 105 const int m_identifier; |
| 90 const WebString m_searchText; | 106 const WebString m_searchText; |
| 91 const WebFindOptions m_options; | 107 const WebFindOptions m_options; |
| 92 const bool m_reset; | 108 const bool m_reset; |
| 93 }; | 109 }; |
| 94 | 110 |
| 95 bool TextFinder::find(int identifier, const WebString& searchText, const WebFind Options& options, bool wrapWithinFrame, WebRect* selectionRect) | 111 bool TextFinder::find(int identifier, const WebString& searchText, const WebFind Options& options, bool wrapWithinFrame, WebRect* selectionRect) |
| 96 { | 112 { |
| 97 if (!m_ownerFrame.frame() || !m_ownerFrame.frame()->page()) | 113 if (!ownerFrame().frame() || !ownerFrame().frame()->page()) |
| 98 return false; | 114 return false; |
| 99 | 115 |
| 100 WebLocalFrameImpl* mainFrameImpl = m_ownerFrame.viewImpl()->mainFrameImpl(); | 116 WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl(); |
| 101 | 117 |
| 102 if (!options.findNext) | 118 if (!options.findNext) |
| 103 m_ownerFrame.frame()->page()->unmarkAllTextMatches(); | 119 ownerFrame().frame()->page()->unmarkAllTextMatches(); |
| 104 else | 120 else |
| 105 setMarkerActive(m_activeMatch.get(), false); | 121 setMarkerActive(m_activeMatch.get(), false); |
| 106 | 122 |
| 107 if (m_activeMatch && &m_activeMatch->ownerDocument() != m_ownerFrame.frame() ->document()) | 123 if (m_activeMatch && &m_activeMatch->ownerDocument() != ownerFrame().frame() ->document()) |
| 108 m_activeMatch = nullptr; | 124 m_activeMatch = nullptr; |
| 109 | 125 |
| 110 // If the user has selected something since the last Find operation we want | 126 // If the user has selected something since the last Find operation we want |
| 111 // to start from there. Otherwise, we start searching from where the last Fi nd | 127 // to start from there. Otherwise, we start searching from where the last Fi nd |
| 112 // operation left off (either a Find or a FindNext operation). | 128 // operation left off (either a Find or a FindNext operation). |
| 113 VisibleSelection selection(m_ownerFrame.frame()->selection().selection()); | 129 VisibleSelection selection(ownerFrame().frame()->selection().selection()); |
| 114 bool activeSelection = !selection.isNone(); | 130 bool activeSelection = !selection.isNone(); |
| 115 if (activeSelection) { | 131 if (activeSelection) { |
| 116 m_activeMatch = selection.firstRange().get(); | 132 m_activeMatch = selection.firstRange().get(); |
| 117 m_ownerFrame.frame()->selection().clear(); | 133 ownerFrame().frame()->selection().clear(); |
| 118 } | 134 } |
| 119 | 135 |
| 120 ASSERT(m_ownerFrame.frame() && m_ownerFrame.frame()->view()); | 136 ASSERT(ownerFrame().frame() && ownerFrame().frame()->view()); |
| 121 const FindOptions findOptions = (options.forward ? 0 : Backwards) | 137 const FindOptions findOptions = (options.forward ? 0 : Backwards) |
| 122 | (options.matchCase ? 0 : CaseInsensitive) | 138 | (options.matchCase ? 0 : CaseInsensitive) |
| 123 | (wrapWithinFrame ? WrapAround : 0) | 139 | (wrapWithinFrame ? WrapAround : 0) |
| 124 | (options.wordStart ? AtWordStarts : 0) | 140 | (options.wordStart ? AtWordStarts : 0) |
| 125 | (options.medialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) | 141 | (options.medialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) |
| 126 | (options.findNext ? 0 : StartInSelection); | 142 | (options.findNext ? 0 : StartInSelection); |
| 127 m_activeMatch = m_ownerFrame.frame()->editor().findStringAndScrollToVisible( searchText, m_activeMatch.get(), findOptions); | 143 m_activeMatch = ownerFrame().frame()->editor().findStringAndScrollToVisible( searchText, m_activeMatch.get(), findOptions); |
| 128 | 144 |
| 129 if (!m_activeMatch) { | 145 if (!m_activeMatch) { |
| 130 // If we're finding next the next active match might not be in the curre nt frame. | 146 // If we're finding next the next active match might not be in the curre nt frame. |
| 131 // In this case we don't want to clear the matches cache. | 147 // In this case we don't want to clear the matches cache. |
| 132 if (!options.findNext) | 148 if (!options.findNext) |
| 133 clearFindMatchesCache(); | 149 clearFindMatchesCache(); |
| 134 | 150 |
| 135 m_ownerFrame.invalidateAll(); | 151 ownerFrame().invalidateAll(); |
| 136 return false; | 152 return false; |
| 137 } | 153 } |
| 138 | 154 |
| 139 #if OS(ANDROID) | 155 #if OS(ANDROID) |
| 140 m_ownerFrame.viewImpl()->zoomToFindInPageRect(m_ownerFrame.frameView()->cont entsToWindow(enclosingIntRect(RenderObject::absoluteBoundingBoxRectForRange(m_ac tiveMatch.get())))); | 156 ownerFrame().viewImpl()->zoomToFindInPageRect(ownerFrame().frameView()->cont entsToWindow(enclosingIntRect(RenderObject::absoluteBoundingBoxRectForRange(m_ac tiveMatch.get())))); |
| 141 #endif | 157 #endif |
| 142 | 158 |
| 143 setMarkerActive(m_activeMatch.get(), true); | 159 setMarkerActive(m_activeMatch.get(), true); |
| 144 WebLocalFrameImpl* oldActiveFrame = mainFrameImpl->ensureTextFinder().m_curr entActiveMatchFrame; | 160 WebLocalFrameImpl* oldActiveFrame = mainFrameImpl->ensureTextFinder().m_curr entActiveMatchFrame; |
| 145 mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &m_ownerFrame; | 161 mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &ownerFrame(); |
| 146 | 162 |
| 147 // Make sure no node is focused. See http://crbug.com/38700. | 163 // Make sure no node is focused. See http://crbug.com/38700. |
| 148 m_ownerFrame.frame()->document()->setFocusedElement(nullptr); | 164 ownerFrame().frame()->document()->setFocusedElement(nullptr); |
| 149 | 165 |
| 150 if (!options.findNext || activeSelection) { | 166 if (!options.findNext || activeSelection) { |
| 151 // This is either a Find operation or a Find-next from a new start point | 167 // This is either a Find operation or a Find-next from a new start point |
| 152 // due to a selection, so we set the flag to ask the scoping effort | 168 // due to a selection, so we set the flag to ask the scoping effort |
| 153 // to find the active rect for us and report it back to the UI. | 169 // to find the active rect for us and report it back to the UI. |
| 154 m_locatingActiveRect = true; | 170 m_locatingActiveRect = true; |
| 155 } else { | 171 } else { |
| 156 if (oldActiveFrame != &m_ownerFrame) { | 172 if (oldActiveFrame != &ownerFrame()) { |
| 157 if (options.forward) | 173 if (options.forward) |
| 158 m_activeMatchIndexInCurrentFrame = 0; | 174 m_activeMatchIndexInCurrentFrame = 0; |
| 159 else | 175 else |
| 160 m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1; | 176 m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1; |
| 161 } else { | 177 } else { |
| 162 if (options.forward) | 178 if (options.forward) |
| 163 ++m_activeMatchIndexInCurrentFrame; | 179 ++m_activeMatchIndexInCurrentFrame; |
| 164 else | 180 else |
| 165 --m_activeMatchIndexInCurrentFrame; | 181 --m_activeMatchIndexInCurrentFrame; |
| 166 | 182 |
| 167 if (m_activeMatchIndexInCurrentFrame + 1 > m_lastMatchCount) | 183 if (m_activeMatchIndexInCurrentFrame + 1 > m_lastMatchCount) |
| 168 m_activeMatchIndexInCurrentFrame = 0; | 184 m_activeMatchIndexInCurrentFrame = 0; |
| 169 if (m_activeMatchIndexInCurrentFrame == -1) | 185 if (m_activeMatchIndexInCurrentFrame == -1) |
| 170 m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1; | 186 m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1; |
| 171 } | 187 } |
| 172 if (selectionRect) { | 188 if (selectionRect) { |
| 173 *selectionRect = m_ownerFrame.frameView()->contentsToWindow(m_active Match->boundingBox()); | 189 *selectionRect = ownerFrame().frameView()->contentsToWindow(m_active Match->boundingBox()); |
| 174 reportFindInPageSelection(*selectionRect, m_activeMatchIndexInCurren tFrame + 1, identifier); | 190 reportFindInPageSelection(*selectionRect, m_activeMatchIndexInCurren tFrame + 1, identifier); |
| 175 } | 191 } |
| 176 } | 192 } |
| 177 | 193 |
| 178 return true; | 194 return true; |
| 179 } | 195 } |
| 180 | 196 |
| 181 void TextFinder::stopFindingAndClearSelection() | 197 void TextFinder::stopFindingAndClearSelection() |
| 182 { | 198 { |
| 183 cancelPendingScopingEffort(); | 199 cancelPendingScopingEffort(); |
| 184 | 200 |
| 185 // Remove all markers for matches found and turn off the highlighting. | 201 // Remove all markers for matches found and turn off the highlighting. |
| 186 m_ownerFrame.frame()->document()->markers().removeMarkers(DocumentMarker::Te xtMatch); | 202 ownerFrame().frame()->document()->markers().removeMarkers(DocumentMarker::Te xtMatch); |
| 187 m_ownerFrame.frame()->editor().setMarkedTextMatchesAreHighlighted(false); | 203 ownerFrame().frame()->editor().setMarkedTextMatchesAreHighlighted(false); |
| 188 clearFindMatchesCache(); | 204 clearFindMatchesCache(); |
| 189 | 205 |
| 190 // Let the frame know that we don't want tickmarks or highlighting anymore. | 206 // Let the frame know that we don't want tickmarks or highlighting anymore. |
| 191 m_ownerFrame.invalidateAll(); | 207 ownerFrame().invalidateAll(); |
| 192 } | 208 } |
| 193 | 209 |
| 194 void TextFinder::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset) | 210 void TextFinder::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset) |
| 195 { | 211 { |
| 196 if (reset) { | 212 if (reset) { |
| 197 // This is a brand new search, so we need to reset everything. | 213 // This is a brand new search, so we need to reset everything. |
| 198 // Scoping is just about to begin. | 214 // Scoping is just about to begin. |
| 199 m_scopingInProgress = true; | 215 m_scopingInProgress = true; |
| 200 | 216 |
| 201 // Need to keep the current identifier locally in order to finish the | 217 // Need to keep the current identifier locally in order to finish the |
| 202 // request in case the frame is detached during the process. | 218 // request in case the frame is detached during the process. |
| 203 m_findRequestIdentifier = identifier; | 219 m_findRequestIdentifier = identifier; |
| 204 | 220 |
| 205 // Clear highlighting for this frame. | 221 // Clear highlighting for this frame. |
| 206 LocalFrame* frame = m_ownerFrame.frame(); | 222 LocalFrame* frame = ownerFrame().frame(); |
| 207 if (frame && frame->page() && frame->editor().markedTextMatchesAreHighli ghted()) | 223 if (frame && frame->page() && frame->editor().markedTextMatchesAreHighli ghted()) |
| 208 frame->page()->unmarkAllTextMatches(); | 224 frame->page()->unmarkAllTextMatches(); |
| 209 | 225 |
| 210 // Clear the tickmarks and results cache. | 226 // Clear the tickmarks and results cache. |
| 211 clearFindMatchesCache(); | 227 clearFindMatchesCache(); |
| 212 | 228 |
| 213 // Clear the counters from last operation. | 229 // Clear the counters from last operation. |
| 214 m_lastMatchCount = 0; | 230 m_lastMatchCount = 0; |
| 215 m_nextInvalidateAfter = 0; | 231 m_nextInvalidateAfter = 0; |
| 216 m_resumeScopingFromRange = nullptr; | 232 m_resumeScopingFromRange = nullptr; |
| 217 | 233 |
| 218 // The view might be null on detached frames. | 234 // The view might be null on detached frames. |
| 219 if (frame && frame->page()) | 235 if (frame && frame->page()) |
| 220 m_ownerFrame.viewImpl()->mainFrameImpl()->ensureTextFinder().m_frame sScopingCount++; | 236 ownerFrame().viewImpl()->mainFrameImpl()->ensureTextFinder().m_frame sScopingCount++; |
| 221 | 237 |
| 222 // Now, defer scoping until later to allow find operation to finish quic kly. | 238 // Now, defer scoping until later to allow find operation to finish quic kly. |
| 223 scopeStringMatchesSoon(identifier, searchText, options, false); // false means just reset, so don't do it again. | 239 scopeStringMatchesSoon(identifier, searchText, options, false); // false means just reset, so don't do it again. |
| 224 return; | 240 return; |
| 225 } | 241 } |
| 226 | 242 |
| 227 if (!shouldScopeMatches(searchText)) { | 243 if (!shouldScopeMatches(searchText)) { |
| 228 // Note that we want to defer the final update when resetting even if sh ouldScopeMatches returns false. | 244 // Note that we want to defer the final update when resetting even if sh ouldScopeMatches returns false. |
| 229 // This is done in order to prevent sending a final message based only o n the results of the first frame | 245 // This is done in order to prevent sending a final message based only o n the results of the first frame |
| 230 // since m_framesScopingCount would be 0 as other frames have yet to res et. | 246 // since m_framesScopingCount would be 0 as other frames have yet to res et. |
| 231 finishCurrentScopingEffort(identifier); | 247 finishCurrentScopingEffort(identifier); |
| 232 return; | 248 return; |
| 233 } | 249 } |
| 234 | 250 |
| 235 WebLocalFrameImpl* mainFrameImpl = m_ownerFrame.viewImpl()->mainFrameImpl(); | 251 WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl(); |
| 236 Position searchStart = firstPositionInNode(m_ownerFrame.frame()->document()) ; | 252 Position searchStart = firstPositionInNode(ownerFrame().frame()->document()) ; |
| 237 Position searchEnd = lastPositionInNode(m_ownerFrame.frame()->document()); | 253 Position searchEnd = lastPositionInNode(ownerFrame().frame()->document()); |
| 238 ASSERT(searchStart.document() == searchEnd.document()); | 254 ASSERT(searchStart.document() == searchEnd.document()); |
| 239 | 255 |
| 240 if (m_resumeScopingFromRange) { | 256 if (m_resumeScopingFromRange) { |
| 241 // This is a continuation of a scoping operation that timed out and didn 't | 257 // This is a continuation of a scoping operation that timed out and didn 't |
| 242 // complete last time around, so we should start from where we left off. | 258 // complete last time around, so we should start from where we left off. |
| 243 ASSERT(m_resumeScopingFromRange->collapsed()); | 259 ASSERT(m_resumeScopingFromRange->collapsed()); |
| 244 searchStart = m_resumeScopingFromRange->endPosition(); | 260 searchStart = m_resumeScopingFromRange->endPosition(); |
| 245 if (searchStart.document() != searchEnd.document()) | 261 if (searchStart.document() != searchEnd.document()) |
| 246 return; | 262 return; |
| 247 } | 263 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 m_activeMatch->boundingBox() : resultBounds; | 304 m_activeMatch->boundingBox() : resultBounds; |
| 289 } | 305 } |
| 290 | 306 |
| 291 // If the Find function found a match it will have stored where the | 307 // If the Find function found a match it will have stored where the |
| 292 // match was found in m_activeSelectionRect on the current frame. If we | 308 // match was found in m_activeSelectionRect on the current frame. If we |
| 293 // find this rect during scoping it means we have found the active | 309 // find this rect during scoping it means we have found the active |
| 294 // tickmark. | 310 // tickmark. |
| 295 bool foundActiveMatch = false; | 311 bool foundActiveMatch = false; |
| 296 if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) { | 312 if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) { |
| 297 // We have found the active tickmark frame. | 313 // We have found the active tickmark frame. |
| 298 mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &m_own erFrame; | 314 mainFrameImpl->ensureTextFinder().m_currentActiveMatchFrame = &owner Frame(); |
| 299 foundActiveMatch = true; | 315 foundActiveMatch = true; |
| 300 // We also know which tickmark is active now. | 316 // We also know which tickmark is active now. |
| 301 m_activeMatchIndexInCurrentFrame = matchCount - 1; | 317 m_activeMatchIndexInCurrentFrame = matchCount - 1; |
| 302 // To stop looking for the active tickmark, we set this flag. | 318 // To stop looking for the active tickmark, we set this flag. |
| 303 m_locatingActiveRect = false; | 319 m_locatingActiveRect = false; |
| 304 | 320 |
| 305 // Notify browser of new location for the selected rectangle. | 321 // Notify browser of new location for the selected rectangle. |
| 306 reportFindInPageSelection( | 322 reportFindInPageSelection( |
| 307 m_ownerFrame.frameView()->contentsToWindow(resultBounds), | 323 ownerFrame().frameView()->contentsToWindow(resultBounds), |
| 308 m_activeMatchIndexInCurrentFrame + 1, | 324 m_activeMatchIndexInCurrentFrame + 1, |
| 309 identifier); | 325 identifier); |
| 310 } | 326 } |
| 311 | 327 |
| 312 addMarker(resultRange.get(), foundActiveMatch); | 328 addMarker(resultRange.get(), foundActiveMatch); |
| 313 | 329 |
| 314 m_findMatchesCache.append(FindMatch(resultRange.get(), m_lastMatchCount + matchCount)); | 330 m_findMatchesCache.append(FindMatch(resultRange.get(), m_lastMatchCount + matchCount)); |
| 315 | 331 |
| 316 // Set the new start for the search range to be the end of the previous | 332 // Set the new start for the search range to be the end of the previous |
| 317 // result range. There is no need to use a VisiblePosition here, | 333 // result range. There is no need to use a VisiblePosition here, |
| 318 // since findPlainText will use a TextIterator to go over the visible | 334 // since findPlainText will use a TextIterator to go over the visible |
| 319 // text nodes. | 335 // text nodes. |
| 320 searchStart = resultEnd; | 336 searchStart = resultEnd; |
| 321 | 337 |
| 322 m_resumeScopingFromRange = Range::create(*resultStart.document(), result End, resultEnd); | 338 m_resumeScopingFromRange = Range::create(*resultStart.document(), result End, resultEnd); |
| 323 timedOut = (currentTime() - startTime) >= maxScopingDuration; | 339 timedOut = (currentTime() - startTime) >= maxScopingDuration; |
| 324 } while (!timedOut); | 340 } while (!timedOut); |
| 325 | 341 |
| 326 // Remember what we search for last time, so we can skip searching if more | 342 // Remember what we search for last time, so we can skip searching if more |
| 327 // letters are added to the search string (and last outcome was 0). | 343 // letters are added to the search string (and last outcome was 0). |
| 328 m_lastSearchString = searchText; | 344 m_lastSearchString = searchText; |
| 329 | 345 |
| 330 if (matchCount > 0) { | 346 if (matchCount > 0) { |
| 331 m_ownerFrame.frame()->editor().setMarkedTextMatchesAreHighlighted(true); | 347 ownerFrame().frame()->editor().setMarkedTextMatchesAreHighlighted(true); |
| 332 | 348 |
| 333 m_lastMatchCount += matchCount; | 349 m_lastMatchCount += matchCount; |
| 334 | 350 |
| 335 // Let the mainframe know how much we found during this pass. | 351 // Let the mainframe know how much we found during this pass. |
| 336 mainFrameImpl->increaseMatchCount(matchCount, identifier); | 352 mainFrameImpl->increaseMatchCount(matchCount, identifier); |
| 337 } | 353 } |
| 338 | 354 |
| 339 if (timedOut) { | 355 if (timedOut) { |
| 340 // If we found anything during this pass, we should redraw. However, we | 356 // If we found anything during this pass, we should redraw. However, we |
| 341 // don't want to spam too much if the page is extremely long, so if we | 357 // don't want to spam too much if the page is extremely long, so if we |
| 342 // reach a certain point we start throttling the redraw requests. | 358 // reach a certain point we start throttling the redraw requests. |
| 343 if (matchCount > 0) | 359 if (matchCount > 0) |
| 344 invalidateIfNecessary(); | 360 invalidateIfNecessary(); |
| 345 | 361 |
| 346 // Scoping effort ran out of time, lets ask for another time-slice. | 362 // Scoping effort ran out of time, lets ask for another time-slice. |
| 347 scopeStringMatchesSoon( | 363 scopeStringMatchesSoon( |
| 348 identifier, | 364 identifier, |
| 349 searchText, | 365 searchText, |
| 350 options, | 366 options, |
| 351 false); // don't reset. | 367 false); // don't reset. |
| 352 return; // Done for now, resume work later. | 368 return; // Done for now, resume work later. |
| 353 } | 369 } |
| 354 | 370 |
| 355 finishCurrentScopingEffort(identifier); | 371 finishCurrentScopingEffort(identifier); |
| 356 } | 372 } |
| 357 | 373 |
| 358 void TextFinder::flushCurrentScopingEffort(int identifier) | 374 void TextFinder::flushCurrentScopingEffort(int identifier) |
| 359 { | 375 { |
| 360 if (!m_ownerFrame.frame() || !m_ownerFrame.frame()->page()) | 376 if (!ownerFrame().frame() || !ownerFrame().frame()->page()) |
| 361 return; | 377 return; |
| 362 | 378 |
| 363 WebLocalFrameImpl* mainFrameImpl = m_ownerFrame.viewImpl()->mainFrameImpl(); | 379 WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl(); |
| 364 mainFrameImpl->ensureTextFinder().decrementFramesScopingCount(identifier); | 380 mainFrameImpl->ensureTextFinder().decrementFramesScopingCount(identifier); |
| 365 } | 381 } |
| 366 | 382 |
| 367 void TextFinder::finishCurrentScopingEffort(int identifier) | 383 void TextFinder::finishCurrentScopingEffort(int identifier) |
| 368 { | 384 { |
| 369 flushCurrentScopingEffort(identifier); | 385 flushCurrentScopingEffort(identifier); |
| 370 | 386 |
| 371 m_scopingInProgress = false; | 387 m_scopingInProgress = false; |
| 372 m_lastFindRequestCompletedWithNoMatches = !m_lastMatchCount; | 388 m_lastFindRequestCompletedWithNoMatches = !m_lastMatchCount; |
| 373 | 389 |
| 374 // This frame is done, so show any scrollbar tickmarks we haven't drawn yet. | 390 // This frame is done, so show any scrollbar tickmarks we haven't drawn yet. |
| 375 m_ownerFrame.invalidateScrollbar(); | 391 ownerFrame().invalidateScrollbar(); |
| 376 } | 392 } |
| 377 | 393 |
| 378 void TextFinder::cancelPendingScopingEffort() | 394 void TextFinder::cancelPendingScopingEffort() |
| 379 { | 395 { |
| 380 deleteAllValues(m_deferredScopingWork); | 396 #if ENABLE(OILPAN) |
| 397 for (DeferredScopeStringMatches* deferredWork : m_deferredScopingWork) | |
| 398 deferredWork->dispose(); | |
| 399 #endif | |
| 381 m_deferredScopingWork.clear(); | 400 m_deferredScopingWork.clear(); |
| 382 | 401 |
| 383 m_activeMatchIndexInCurrentFrame = -1; | 402 m_activeMatchIndexInCurrentFrame = -1; |
| 384 | 403 |
| 385 // Last request didn't complete. | 404 // Last request didn't complete. |
| 386 if (m_scopingInProgress) | 405 if (m_scopingInProgress) |
| 387 m_lastFindRequestCompletedWithNoMatches = false; | 406 m_lastFindRequestCompletedWithNoMatches = false; |
| 388 | 407 |
| 389 m_scopingInProgress = false; | 408 m_scopingInProgress = false; |
| 390 } | 409 } |
| 391 | 410 |
| 392 void TextFinder::increaseMatchCount(int identifier, int count) | 411 void TextFinder::increaseMatchCount(int identifier, int count) |
| 393 { | 412 { |
| 394 if (count) | 413 if (count) |
| 395 ++m_findMatchMarkersVersion; | 414 ++m_findMatchMarkersVersion; |
| 396 | 415 |
| 397 m_totalMatchCount += count; | 416 m_totalMatchCount += count; |
| 398 | 417 |
| 399 // Update the UI with the latest findings. | 418 // Update the UI with the latest findings. |
| 400 if (m_ownerFrame.client()) | 419 if (ownerFrame().client()) |
| 401 m_ownerFrame.client()->reportFindInPageMatchCount(identifier, m_totalMat chCount, !m_framesScopingCount); | 420 ownerFrame().client()->reportFindInPageMatchCount(identifier, m_totalMat chCount, !m_framesScopingCount); |
| 402 } | 421 } |
| 403 | 422 |
| 404 void TextFinder::reportFindInPageSelection(const WebRect& selectionRect, int act iveMatchOrdinal, int identifier) | 423 void TextFinder::reportFindInPageSelection(const WebRect& selectionRect, int act iveMatchOrdinal, int identifier) |
| 405 { | 424 { |
| 406 // Update the UI with the latest selection rect. | 425 // Update the UI with the latest selection rect. |
| 407 if (m_ownerFrame.client()) | 426 if (ownerFrame().client()) |
| 408 m_ownerFrame.client()->reportFindInPageSelection(identifier, ordinalOfFi rstMatch() + activeMatchOrdinal, selectionRect); | 427 ownerFrame().client()->reportFindInPageSelection(identifier, ordinalOfFi rstMatch() + activeMatchOrdinal, selectionRect); |
| 409 } | 428 } |
| 410 | 429 |
| 411 void TextFinder::resetMatchCount() | 430 void TextFinder::resetMatchCount() |
| 412 { | 431 { |
| 413 if (m_totalMatchCount > 0) | 432 if (m_totalMatchCount > 0) |
| 414 ++m_findMatchMarkersVersion; | 433 ++m_findMatchMarkersVersion; |
| 415 | 434 |
| 416 m_totalMatchCount = 0; | 435 m_totalMatchCount = 0; |
| 417 m_framesScopingCount = 0; | 436 m_framesScopingCount = 0; |
| 418 } | 437 } |
| 419 | 438 |
| 420 void TextFinder::clearFindMatchesCache() | 439 void TextFinder::clearFindMatchesCache() |
| 421 { | 440 { |
| 422 if (!m_findMatchesCache.isEmpty()) | 441 if (!m_findMatchesCache.isEmpty()) |
| 423 m_ownerFrame.viewImpl()->mainFrameImpl()->ensureTextFinder().m_findMatch MarkersVersion++; | 442 ownerFrame().viewImpl()->mainFrameImpl()->ensureTextFinder().m_findMatch MarkersVersion++; |
| 424 | 443 |
| 425 m_findMatchesCache.clear(); | 444 m_findMatchesCache.clear(); |
| 426 m_findMatchRectsAreValid = false; | 445 m_findMatchRectsAreValid = false; |
| 427 } | 446 } |
| 428 | 447 |
| 429 bool TextFinder::isActiveMatchFrameValid() const | 448 bool TextFinder::isActiveMatchFrameValid() const |
| 430 { | 449 { |
| 431 WebLocalFrameImpl* mainFrameImpl = m_ownerFrame.viewImpl()->mainFrameImpl(); | 450 WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl(); |
| 432 WebLocalFrameImpl* activeMatchFrame = mainFrameImpl->activeMatchFrame(); | 451 WebLocalFrameImpl* activeMatchFrame = mainFrameImpl->activeMatchFrame(); |
| 433 return activeMatchFrame && activeMatchFrame->activeMatch() && activeMatchFra me->frame()->tree().isDescendantOf(mainFrameImpl->frame()); | 452 return activeMatchFrame && activeMatchFrame->activeMatch() && activeMatchFra me->frame()->tree().isDescendantOf(mainFrameImpl->frame()); |
| 434 } | 453 } |
| 435 | 454 |
| 436 void TextFinder::updateFindMatchRects() | 455 void TextFinder::updateFindMatchRects() |
| 437 { | 456 { |
| 438 IntSize currentContentsSize = m_ownerFrame.contentsSize(); | 457 IntSize currentContentsSize = ownerFrame().contentsSize(); |
| 439 if (m_contentsSizeForCurrentFindMatchRects != currentContentsSize) { | 458 if (m_contentsSizeForCurrentFindMatchRects != currentContentsSize) { |
| 440 m_contentsSizeForCurrentFindMatchRects = currentContentsSize; | 459 m_contentsSizeForCurrentFindMatchRects = currentContentsSize; |
| 441 m_findMatchRectsAreValid = false; | 460 m_findMatchRectsAreValid = false; |
| 442 } | 461 } |
| 443 | 462 |
| 444 size_t deadMatches = 0; | 463 size_t deadMatches = 0; |
| 445 for (FindMatch& match : m_findMatchesCache) { | 464 for (FindMatch& match : m_findMatchesCache) { |
| 446 if (!match.m_range->boundaryPointsValid() || !match.m_range->startContai ner()->inDocument()) | 465 if (!match.m_range->boundaryPointsValid() || !match.m_range->startContai ner()->inDocument()) |
| 447 match.m_rect = FloatRect(); | 466 match.m_rect = FloatRect(); |
| 448 else if (!m_findMatchRectsAreValid) | 467 else if (!m_findMatchRectsAreValid) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 460 for (const FindMatch& match : m_findMatchesCache) { | 479 for (const FindMatch& match : m_findMatchesCache) { |
| 461 if (!match.m_rect.isEmpty()) | 480 if (!match.m_rect.isEmpty()) |
| 462 filteredMatches.append(match); | 481 filteredMatches.append(match); |
| 463 } | 482 } |
| 464 | 483 |
| 465 m_findMatchesCache.swap(filteredMatches); | 484 m_findMatchesCache.swap(filteredMatches); |
| 466 } | 485 } |
| 467 | 486 |
| 468 // Invalidate the rects in child frames. Will be updated later during traver sal. | 487 // Invalidate the rects in child frames. Will be updated later during traver sal. |
| 469 if (!m_findMatchRectsAreValid) | 488 if (!m_findMatchRectsAreValid) |
| 470 for (WebFrame* child = m_ownerFrame.firstChild(); child; child = child-> nextSibling()) | 489 for (WebFrame* child = ownerFrame().firstChild(); child; child = child-> nextSibling()) |
| 471 toWebLocalFrameImpl(child)->ensureTextFinder().m_findMatchRectsAreVa lid = false; | 490 toWebLocalFrameImpl(child)->ensureTextFinder().m_findMatchRectsAreVa lid = false; |
| 472 | 491 |
| 473 m_findMatchRectsAreValid = true; | 492 m_findMatchRectsAreValid = true; |
| 474 } | 493 } |
| 475 | 494 |
| 476 WebFloatRect TextFinder::activeFindMatchRect() | 495 WebFloatRect TextFinder::activeFindMatchRect() |
| 477 { | 496 { |
| 478 if (!isActiveMatchFrameValid()) | 497 if (!isActiveMatchFrameValid()) |
| 479 return WebFloatRect(); | 498 return WebFloatRect(); |
| 480 | 499 |
| 481 return WebFloatRect(findInPageRectFromRange(m_currentActiveMatchFrame->activ eMatch())); | 500 return WebFloatRect(findInPageRectFromRange(m_currentActiveMatchFrame->activ eMatch())); |
| 482 } | 501 } |
| 483 | 502 |
| 484 void TextFinder::findMatchRects(WebVector<WebFloatRect>& outputRects) | 503 void TextFinder::findMatchRects(WebVector<WebFloatRect>& outputRects) |
| 485 { | 504 { |
| 486 Vector<WebFloatRect> matchRects; | 505 Vector<WebFloatRect> matchRects; |
| 487 for (WebLocalFrameImpl* frame = &m_ownerFrame; frame; frame = toWebLocalFram eImpl(frame->traverseNext(false))) | 506 for (WebLocalFrameImpl* frame = &ownerFrame(); frame; frame = toWebLocalFram eImpl(frame->traverseNext(false))) |
| 488 frame->ensureTextFinder().appendFindMatchRects(matchRects); | 507 frame->ensureTextFinder().appendFindMatchRects(matchRects); |
| 489 | 508 |
| 490 outputRects = matchRects; | 509 outputRects = matchRects; |
| 491 } | 510 } |
| 492 | 511 |
| 493 void TextFinder::appendFindMatchRects(Vector<WebFloatRect>& frameRects) | 512 void TextFinder::appendFindMatchRects(Vector<WebFloatRect>& frameRects) |
| 494 { | 513 { |
| 495 updateFindMatchRects(); | 514 updateFindMatchRects(); |
| 496 frameRects.reserveCapacity(frameRects.size() + m_findMatchesCache.size()); | 515 frameRects.reserveCapacity(frameRects.size() + m_findMatchesCache.size()); |
| 497 for (const FindMatch& match : m_findMatchesCache) { | 516 for (const FindMatch& match : m_findMatchesCache) { |
| 498 ASSERT(!match.m_rect.isEmpty()); | 517 ASSERT(!match.m_rect.isEmpty()); |
| 499 frameRects.append(match.m_rect); | 518 frameRects.append(match.m_rect); |
| 500 } | 519 } |
| 501 } | 520 } |
| 502 | 521 |
| 503 int TextFinder::selectNearestFindMatch(const WebFloatPoint& point, WebRect* sele ctionRect) | 522 int TextFinder::selectNearestFindMatch(const WebFloatPoint& point, WebRect* sele ctionRect) |
| 504 { | 523 { |
| 505 TextFinder* bestFinder = nullptr; | 524 TextFinder* bestFinder = nullptr; |
| 506 int indexInBestFrame = -1; | 525 int indexInBestFrame = -1; |
| 507 float distanceInBestFrame = FLT_MAX; | 526 float distanceInBestFrame = FLT_MAX; |
| 508 | 527 |
| 509 for (WebLocalFrameImpl* frame = &m_ownerFrame; frame; frame = toWebLocalFram eImpl(frame->traverseNext(false))) { | 528 for (WebLocalFrameImpl* frame = &ownerFrame(); frame; frame = toWebLocalFram eImpl(frame->traverseNext(false))) { |
| 510 float distanceInFrame; | 529 float distanceInFrame; |
| 511 TextFinder& finder = frame->ensureTextFinder(); | 530 TextFinder& finder = frame->ensureTextFinder(); |
| 512 int indexInFrame = finder.nearestFindMatch(point, distanceInFrame); | 531 int indexInFrame = finder.nearestFindMatch(point, distanceInFrame); |
| 513 if (distanceInFrame < distanceInBestFrame) { | 532 if (distanceInFrame < distanceInBestFrame) { |
| 514 bestFinder = &finder; | 533 bestFinder = &finder; |
| 515 indexInBestFrame = indexInFrame; | 534 indexInBestFrame = indexInFrame; |
| 516 distanceInBestFrame = distanceInFrame; | 535 distanceInBestFrame = distanceInFrame; |
| 517 } | 536 } |
| 518 } | 537 } |
| 519 | 538 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 545 | 564 |
| 546 int TextFinder::selectFindMatch(unsigned index, WebRect* selectionRect) | 565 int TextFinder::selectFindMatch(unsigned index, WebRect* selectionRect) |
| 547 { | 566 { |
| 548 ASSERT_WITH_SECURITY_IMPLICATION(index < m_findMatchesCache.size()); | 567 ASSERT_WITH_SECURITY_IMPLICATION(index < m_findMatchesCache.size()); |
| 549 | 568 |
| 550 RefPtrWillBeRawPtr<Range> range = m_findMatchesCache[index].m_range; | 569 RefPtrWillBeRawPtr<Range> range = m_findMatchesCache[index].m_range; |
| 551 if (!range->boundaryPointsValid() || !range->startContainer()->inDocument()) | 570 if (!range->boundaryPointsValid() || !range->startContainer()->inDocument()) |
| 552 return -1; | 571 return -1; |
| 553 | 572 |
| 554 // Check if the match is already selected. | 573 // Check if the match is already selected. |
| 555 TextFinder& mainFrameTextFinder = m_ownerFrame.viewImpl()->mainFrameImpl()-> ensureTextFinder(); | 574 TextFinder& mainFrameTextFinder = ownerFrame().viewImpl()->mainFrameImpl()-> ensureTextFinder(); |
| 556 WebLocalFrameImpl* activeMatchFrame = mainFrameTextFinder.m_currentActiveMat chFrame; | 575 WebLocalFrameImpl* activeMatchFrame = mainFrameTextFinder.m_currentActiveMat chFrame; |
| 557 if (&m_ownerFrame != activeMatchFrame || !m_activeMatch || !areRangesEqual(m _activeMatch.get(), range.get())) { | 576 if (&ownerFrame() != activeMatchFrame || !m_activeMatch || !areRangesEqual(m _activeMatch.get(), range.get())) { |
| 558 if (isActiveMatchFrameValid()) | 577 if (isActiveMatchFrameValid()) |
| 559 activeMatchFrame->ensureTextFinder().setMatchMarkerActive(false); | 578 activeMatchFrame->ensureTextFinder().setMatchMarkerActive(false); |
| 560 | 579 |
| 561 m_activeMatchIndexInCurrentFrame = m_findMatchesCache[index].m_ordinal - 1; | 580 m_activeMatchIndexInCurrentFrame = m_findMatchesCache[index].m_ordinal - 1; |
| 562 | 581 |
| 563 // Set this frame as the active frame (the one with the active highlight ). | 582 // Set this frame as the active frame (the one with the active highlight ). |
| 564 mainFrameTextFinder.m_currentActiveMatchFrame = &m_ownerFrame; | 583 mainFrameTextFinder.m_currentActiveMatchFrame = &ownerFrame(); |
| 565 m_ownerFrame.viewImpl()->setFocusedFrame(&m_ownerFrame); | 584 ownerFrame().viewImpl()->setFocusedFrame(&ownerFrame()); |
| 566 | 585 |
| 567 m_activeMatch = range.release(); | 586 m_activeMatch = range.release(); |
| 568 setMarkerActive(m_activeMatch.get(), true); | 587 setMarkerActive(m_activeMatch.get(), true); |
| 569 | 588 |
| 570 // Clear any user selection, to make sure Find Next continues on from th e match we just activated. | 589 // Clear any user selection, to make sure Find Next continues on from th e match we just activated. |
| 571 m_ownerFrame.frame()->selection().clear(); | 590 ownerFrame().frame()->selection().clear(); |
| 572 | 591 |
| 573 // Make sure no node is focused. See http://crbug.com/38700. | 592 // Make sure no node is focused. See http://crbug.com/38700. |
| 574 m_ownerFrame.frame()->document()->setFocusedElement(nullptr); | 593 ownerFrame().frame()->document()->setFocusedElement(nullptr); |
| 575 } | 594 } |
| 576 | 595 |
| 577 IntRect activeMatchRect; | 596 IntRect activeMatchRect; |
| 578 IntRect activeMatchBoundingBox = enclosingIntRect(RenderObject::absoluteBoun dingBoxRectForRange(m_activeMatch.get())); | 597 IntRect activeMatchBoundingBox = enclosingIntRect(RenderObject::absoluteBoun dingBoxRectForRange(m_activeMatch.get())); |
| 579 | 598 |
| 580 if (!activeMatchBoundingBox.isEmpty()) { | 599 if (!activeMatchBoundingBox.isEmpty()) { |
| 581 if (m_activeMatch->firstNode() && m_activeMatch->firstNode()->renderer() ) { | 600 if (m_activeMatch->firstNode() && m_activeMatch->firstNode()->renderer() ) { |
| 582 m_activeMatch->firstNode()->renderer()->scrollRectToVisible( | 601 m_activeMatch->firstNode()->renderer()->scrollRectToVisible( |
| 583 activeMatchBoundingBox, ScrollAlignment::alignCenterIfNeeded, Sc rollAlignment::alignCenterIfNeeded); | 602 activeMatchBoundingBox, ScrollAlignment::alignCenterIfNeeded, Sc rollAlignment::alignCenterIfNeeded); |
| 584 } | 603 } |
| 585 | 604 |
| 586 // Zoom to the active match. | 605 // Zoom to the active match. |
| 587 activeMatchRect = m_ownerFrame.frameView()->contentsToWindow(activeMatch BoundingBox); | 606 activeMatchRect = ownerFrame().frameView()->contentsToWindow(activeMatch BoundingBox); |
| 588 m_ownerFrame.viewImpl()->zoomToFindInPageRect(activeMatchRect); | 607 ownerFrame().viewImpl()->zoomToFindInPageRect(activeMatchRect); |
| 589 } | 608 } |
| 590 | 609 |
| 591 if (selectionRect) | 610 if (selectionRect) |
| 592 *selectionRect = activeMatchRect; | 611 *selectionRect = activeMatchRect; |
| 593 | 612 |
| 594 return ordinalOfFirstMatch() + m_activeMatchIndexInCurrentFrame + 1; | 613 return ordinalOfFirstMatch() + m_activeMatchIndexInCurrentFrame + 1; |
| 595 } | 614 } |
| 596 | 615 |
| 597 PassOwnPtr<TextFinder> TextFinder::create(WebLocalFrameImpl& ownerFrame) | 616 PassOwnPtrWillBeRawPtr<TextFinder> TextFinder::create(WebLocalFrameImpl& ownerFr ame) |
| 598 { | 617 { |
| 599 return adoptPtr(new TextFinder(ownerFrame)); | 618 return adoptPtrWillBeNoop(new TextFinder(ownerFrame)); |
| 600 } | 619 } |
| 601 | 620 |
| 602 TextFinder::TextFinder(WebLocalFrameImpl& ownerFrame) | 621 TextFinder::TextFinder(WebLocalFrameImpl& ownerFrame) |
| 603 : m_ownerFrame(ownerFrame) | 622 : m_ownerFrame(&ownerFrame) |
| 604 , m_currentActiveMatchFrame(nullptr) | 623 , m_currentActiveMatchFrame(nullptr) |
| 605 , m_activeMatchIndexInCurrentFrame(-1) | 624 , m_activeMatchIndexInCurrentFrame(-1) |
| 606 , m_resumeScopingFromRange(nullptr) | 625 , m_resumeScopingFromRange(nullptr) |
| 607 , m_lastMatchCount(-1) | 626 , m_lastMatchCount(-1) |
| 608 , m_totalMatchCount(-1) | 627 , m_totalMatchCount(-1) |
| 609 , m_framesScopingCount(-1) | 628 , m_framesScopingCount(-1) |
| 610 , m_findRequestIdentifier(-1) | 629 , m_findRequestIdentifier(-1) |
| 611 , m_nextInvalidateAfter(0) | 630 , m_nextInvalidateAfter(0) |
| 612 , m_findMatchMarkersVersion(0) | 631 , m_findMatchMarkersVersion(0) |
| 613 , m_locatingActiveRect(false) | 632 , m_locatingActiveRect(false) |
| 614 , m_scopingInProgress(false) | 633 , m_scopingInProgress(false) |
| 615 , m_lastFindRequestCompletedWithNoMatches(false) | 634 , m_lastFindRequestCompletedWithNoMatches(false) |
| 616 , m_findMatchRectsAreValid(false) | 635 , m_findMatchRectsAreValid(false) |
| 617 { | 636 { |
| 618 } | 637 } |
| 619 | 638 |
| 620 TextFinder::~TextFinder() | 639 TextFinder::~TextFinder() |
| 621 { | 640 { |
| 641 #if !ENABLE(OILPAN) | |
| 622 cancelPendingScopingEffort(); | 642 cancelPendingScopingEffort(); |
| 643 #endif | |
| 623 } | 644 } |
| 624 | 645 |
| 625 void TextFinder::addMarker(Range* range, bool activeMatch) | 646 void TextFinder::addMarker(Range* range, bool activeMatch) |
| 626 { | 647 { |
| 627 m_ownerFrame.frame()->document()->markers().addTextMatchMarker(range, active Match); | 648 ownerFrame().frame()->document()->markers().addTextMatchMarker(range, active Match); |
| 628 } | 649 } |
| 629 | 650 |
| 630 void TextFinder::setMarkerActive(Range* range, bool active) | 651 void TextFinder::setMarkerActive(Range* range, bool active) |
| 631 { | 652 { |
| 632 if (!range || range->collapsed()) | 653 if (!range || range->collapsed()) |
| 633 return; | 654 return; |
| 634 m_ownerFrame.frame()->document()->markers().setMarkersActive(range, active); | 655 ownerFrame().frame()->document()->markers().setMarkersActive(range, active); |
| 635 } | 656 } |
| 636 | 657 |
| 637 int TextFinder::ordinalOfFirstMatchForFrame(WebLocalFrameImpl* frame) const | 658 int TextFinder::ordinalOfFirstMatchForFrame(WebLocalFrameImpl* frame) const |
| 638 { | 659 { |
| 639 int ordinal = 0; | 660 int ordinal = 0; |
| 640 WebLocalFrameImpl* mainFrameImpl = m_ownerFrame.viewImpl()->mainFrameImpl(); | 661 WebLocalFrameImpl* mainFrameImpl = ownerFrame().viewImpl()->mainFrameImpl(); |
| 641 // Iterate from the main frame up to (but not including) |frame| and | 662 // Iterate from the main frame up to (but not including) |frame| and |
| 642 // add up the number of matches found so far. | 663 // add up the number of matches found so far. |
| 643 for (WebLocalFrameImpl* it = mainFrameImpl; it != frame; it = toWebLocalFram eImpl(it->traverseNext(true))) { | 664 for (WebLocalFrameImpl* it = mainFrameImpl; it != frame; it = toWebLocalFram eImpl(it->traverseNext(true))) { |
| 644 TextFinder& finder = it->ensureTextFinder(); | 665 TextFinder& finder = it->ensureTextFinder(); |
| 645 if (finder.m_lastMatchCount > 0) | 666 if (finder.m_lastMatchCount > 0) |
| 646 ordinal += finder.m_lastMatchCount; | 667 ordinal += finder.m_lastMatchCount; |
| 647 } | 668 } |
| 648 return ordinal; | 669 return ordinal; |
| 649 } | 670 } |
| 650 | 671 |
| 651 bool TextFinder::shouldScopeMatches(const String& searchText) | 672 bool TextFinder::shouldScopeMatches(const String& searchText) |
| 652 { | 673 { |
| 653 // Don't scope if we can't find a frame or a view. | 674 // Don't scope if we can't find a frame or a view. |
| 654 // The user may have closed the tab/application, so abort. | 675 // The user may have closed the tab/application, so abort. |
| 655 // Also ignore detached frames, as many find operations report to the main f rame. | 676 // Also ignore detached frames, as many find operations report to the main f rame. |
| 656 LocalFrame* frame = m_ownerFrame.frame(); | 677 LocalFrame* frame = ownerFrame().frame(); |
| 657 if (!frame || !frame->view() || !frame->page() || !m_ownerFrame.hasVisibleCo ntent()) | 678 if (!frame || !frame->view() || !frame->page() || !ownerFrame().hasVisibleCo ntent()) |
| 658 return false; | 679 return false; |
| 659 | 680 |
| 660 ASSERT(frame->document() && frame->view()); | 681 ASSERT(frame->document() && frame->view()); |
| 661 | 682 |
| 662 // If the frame completed the scoping operation and found 0 matches the last | 683 // If the frame completed the scoping operation and found 0 matches the last |
| 663 // time it was searched, then we don't have to search it again if the user i s | 684 // time it was searched, then we don't have to search it again if the user i s |
| 664 // just adding to the search string or sending the same search string again. | 685 // just adding to the search string or sending the same search string again. |
| 665 if (m_lastFindRequestCompletedWithNoMatches && !m_lastSearchString.isEmpty() ) { | 686 if (m_lastFindRequestCompletedWithNoMatches && !m_lastSearchString.isEmpty() ) { |
| 666 // Check to see if the search string prefixes match. | 687 // Check to see if the search string prefixes match. |
| 667 String previousSearchPrefix = | 688 String previousSearchPrefix = |
| 668 searchText.substring(0, m_lastSearchString.length()); | 689 searchText.substring(0, m_lastSearchString.length()); |
| 669 | 690 |
| 670 if (previousSearchPrefix == m_lastSearchString) | 691 if (previousSearchPrefix == m_lastSearchString) |
| 671 return false; // Don't search this frame, it will be fruitless. | 692 return false; // Don't search this frame, it will be fruitless. |
| 672 } | 693 } |
| 673 | 694 |
| 674 return true; | 695 return true; |
| 675 } | 696 } |
| 676 | 697 |
| 677 void TextFinder::scopeStringMatchesSoon(int identifier, const WebString& searchT ext, const WebFindOptions& options, bool reset) | 698 void TextFinder::scopeStringMatchesSoon(int identifier, const WebString& searchT ext, const WebFindOptions& options, bool reset) |
| 678 { | 699 { |
| 679 m_deferredScopingWork.append(new DeferredScopeStringMatches(this, identifier , searchText, options, reset)); | 700 m_deferredScopingWork.append(DeferredScopeStringMatches::create(this, identi fier, searchText, options, reset)); |
| 680 } | 701 } |
| 681 | 702 |
| 682 void TextFinder::callScopeStringMatches(DeferredScopeStringMatches* caller, int identifier, const WebString& searchText, const WebFindOptions& options, bool res et) | 703 void TextFinder::callScopeStringMatches(DeferredScopeStringMatches* caller, int identifier, const WebString& searchText, const WebFindOptions& options, bool res et) |
| 683 { | 704 { |
| 684 m_deferredScopingWork.remove(m_deferredScopingWork.find(caller)); | 705 size_t index = m_deferredScopingWork.find(caller); |
| 706 #if !ENABLE(OILPAN) | |
| 707 // Finalization needs to be delayed as (m_)searchText is passed by reference . | |
| 708 OwnPtr<DeferredScopeStringMatches> item = index != kNotFound ? m_deferredSco pingWork[index].release() : nullptr; | |
| 709 #endif | |
| 710 m_deferredScopingWork.remove(index); | |
| 711 | |
| 685 scopeStringMatches(identifier, searchText, options, reset); | 712 scopeStringMatches(identifier, searchText, options, reset); |
| 686 | |
| 687 // This needs to happen last since searchText is passed by reference. | |
| 688 delete caller; | |
| 689 } | 713 } |
| 690 | 714 |
| 691 void TextFinder::invalidateIfNecessary() | 715 void TextFinder::invalidateIfNecessary() |
| 692 { | 716 { |
| 693 if (m_lastMatchCount <= m_nextInvalidateAfter) | 717 if (m_lastMatchCount <= m_nextInvalidateAfter) |
| 694 return; | 718 return; |
| 695 | 719 |
| 696 // FIXME: (http://b/1088165) Optimize the drawing of the tickmarks and | 720 // FIXME: (http://b/1088165) Optimize the drawing of the tickmarks and |
| 697 // remove this. This calculation sets a milestone for when next to | 721 // remove this. This calculation sets a milestone for when next to |
| 698 // invalidate the scrollbar and the content area. We do this so that we | 722 // invalidate the scrollbar and the content area. We do this so that we |
| 699 // don't spend too much time drawing the scrollbar over and over again. | 723 // don't spend too much time drawing the scrollbar over and over again. |
| 700 // Basically, up until the first 500 matches there is no throttle. | 724 // Basically, up until the first 500 matches there is no throttle. |
| 701 // After the first 500 matches, we set set the milestone further and | 725 // After the first 500 matches, we set set the milestone further and |
| 702 // further out (750, 1125, 1688, 2K, 3K). | 726 // further out (750, 1125, 1688, 2K, 3K). |
| 703 static const int startSlowingDownAfter = 500; | 727 static const int startSlowingDownAfter = 500; |
| 704 static const int slowdown = 750; | 728 static const int slowdown = 750; |
| 705 | 729 |
| 706 int i = m_lastMatchCount / startSlowingDownAfter; | 730 int i = m_lastMatchCount / startSlowingDownAfter; |
| 707 m_nextInvalidateAfter += i * slowdown; | 731 m_nextInvalidateAfter += i * slowdown; |
| 708 m_ownerFrame.invalidateScrollbar(); | 732 ownerFrame().invalidateScrollbar(); |
| 709 } | 733 } |
| 710 | 734 |
| 711 void TextFinder::flushCurrentScoping() | 735 void TextFinder::flushCurrentScoping() |
| 712 { | 736 { |
| 713 flushCurrentScopingEffort(m_findRequestIdentifier); | 737 flushCurrentScopingEffort(m_findRequestIdentifier); |
| 714 } | 738 } |
| 715 | 739 |
| 716 void TextFinder::setMatchMarkerActive(bool active) | 740 void TextFinder::setMatchMarkerActive(bool active) |
| 717 { | 741 { |
| 718 setMarkerActive(m_activeMatch.get(), active); | 742 setMarkerActive(m_activeMatch.get(), active); |
| 719 } | 743 } |
| 720 | 744 |
| 721 void TextFinder::decrementFramesScopingCount(int identifier) | 745 void TextFinder::decrementFramesScopingCount(int identifier) |
| 722 { | 746 { |
| 723 // This frame has no further scoping left, so it is done. Other frames might , | 747 // This frame has no further scoping left, so it is done. Other frames might , |
| 724 // of course, continue to scope matches. | 748 // of course, continue to scope matches. |
| 725 --m_framesScopingCount; | 749 --m_framesScopingCount; |
| 726 | 750 |
| 727 // If this is the last frame to finish scoping we need to trigger the final | 751 // If this is the last frame to finish scoping we need to trigger the final |
| 728 // update to be sent. | 752 // update to be sent. |
| 729 if (!m_framesScopingCount) | 753 if (!m_framesScopingCount) |
| 730 m_ownerFrame.increaseMatchCount(0, identifier); | 754 ownerFrame().increaseMatchCount(0, identifier); |
| 731 } | 755 } |
| 732 | 756 |
| 733 int TextFinder::ordinalOfFirstMatch() const | 757 int TextFinder::ordinalOfFirstMatch() const |
| 734 { | 758 { |
| 735 return ordinalOfFirstMatchForFrame(&m_ownerFrame); | 759 return ordinalOfFirstMatchForFrame(m_ownerFrame.get()); |
| 760 } | |
| 761 | |
| 762 void TextFinder::trace(Visitor* visitor) | |
| 763 { | |
| 764 visitor->trace(m_ownerFrame); | |
| 765 visitor->trace(m_currentActiveMatchFrame); | |
| 766 visitor->trace(m_activeMatch); | |
| 767 visitor->trace(m_resumeScopingFromRange); | |
| 768 visitor->trace(m_deferredScopingWork); | |
| 769 visitor->trace(m_findMatchesCache); | |
| 736 } | 770 } |
| 737 | 771 |
| 738 } // namespace blink | 772 } // namespace blink |
| OLD | NEW |