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 |