1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
|
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TextFinder_h
#define TextFinder_h
#include "core/editing/FindOptions.h"
#include "platform/geometry/FloatRect.h"
#include "platform/heap/Handle.h"
#include "public/platform/WebFloatPoint.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebRect.h"
#include "public/web/WebFindOptions.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
namespace blink {
class Range;
class WebLocalFrameImpl;
template <typename T> class WebVector;
class TextFinder final : public NoBaseWillBeGarbageCollectedFinalized<TextFinder> {
public:
static PassOwnPtrWillBeRawPtr<TextFinder> create(WebLocalFrameImpl& ownerFrame);
bool find(
int identifier, const WebString& searchText, const WebFindOptions&,
bool wrapWithinFrame, WebRect* selectionRect);
void stopFindingAndClearSelection();
void scopeStringMatches(
int identifier, const WebString& searchText, const WebFindOptions&,
bool reset);
void cancelPendingScopingEffort();
void increaseMatchCount(int identifier, int count);
void resetMatchCount();
int findMatchMarkersVersion() const { return m_findMatchMarkersVersion; }
WebFloatRect activeFindMatchRect();
void findMatchRects(WebVector<WebFloatRect>&);
int selectNearestFindMatch(const WebFloatPoint&, WebRect* selectionRect);
// Returns which frame has an active match. This function should only be
// called on the main frame, as it is the only frame keeping track. Returned
// value can be 0 if no frame has an active match.
WebLocalFrameImpl* activeMatchFrame() const { return m_currentActiveMatchFrame; }
// Returns the active match in the current frame. Could be a null range if
// the local frame has no active match.
Range* activeMatch() const { return m_activeMatch.get(); }
void flushCurrentScoping();
void resetActiveMatch() { m_activeMatch = nullptr; }
int totalMatchCount() const { return m_totalMatchCount; }
bool scopingInProgress() const { return m_scopingInProgress; }
void increaseMarkerVersion() { ++m_findMatchMarkersVersion; }
~TextFinder();
class FindMatch {
ALLOW_ONLY_INLINE_ALLOCATION();
public:
FindMatch(PassRefPtrWillBeRawPtr<Range>, int ordinal);
void trace(Visitor*);
RefPtrWillBeMember<Range> m_range;
// 1-based index within this frame.
int m_ordinal;
// In find-in-page coordinates.
// Lazily calculated by updateFindMatchRects.
FloatRect m_rect;
};
void trace(Visitor*);
private:
class DeferredScopeStringMatches;
friend class DeferredScopeStringMatches;
explicit TextFinder(WebLocalFrameImpl& ownerFrame);
// Notifies the delegate about a new selection rect.
void reportFindInPageSelection(
const WebRect& selectionRect, int activeMatchOrdinal, int identifier);
void reportFindInPageResultToAccessibility(int identifier);
// Clear the find-in-page matches cache forcing rects to be fully
// calculated again next time updateFindMatchRects is called.
void clearFindMatchesCache();
// Check if the activeMatchFrame still exists in the frame tree.
bool isActiveMatchFrameValid() const;
// Return the index in the find-in-page cache of the match closest to the
// provided point in find-in-page coordinates, or -1 in case of error.
// The squared distance to the closest match is returned in the distanceSquared parameter.
int nearestFindMatch(const FloatPoint&, float& distanceSquared);
// Select a find-in-page match marker in the current frame using a cache
// match index returned by nearestFindMatch. Returns the ordinal of the new
// selected match or -1 in case of error. Also provides the bounding box of
// the marker in window coordinates if selectionRect is not null.
int selectFindMatch(unsigned index, WebRect* selectionRect);
// Compute and cache the rects for FindMatches if required.
// Rects are automatically invalidated in case of content size changes,
// propagating the invalidation to child frames.
void updateFindMatchRects();
// Append the find-in-page match rects of the current frame to the provided vector.
void appendFindMatchRects(Vector<WebFloatRect>& frameRects);
// Add a WebKit TextMatch-highlight marker to nodes in a range.
void addMarker(Range*, bool activeMatch);
// Sets the markers within a range as active or inactive.
void setMarkerActive(Range*, bool active);
// Returns the ordinal of the first match in the frame specified. This
// function enumerates the frames, starting with the main frame and up to (but
// not including) the frame passed in as a parameter and counts how many
// matches have been found.
int ordinalOfFirstMatchForFrame(WebLocalFrameImpl*) const;
// Determines whether the scoping effort is required for a particular frame.
// It is not necessary if the frame is invisible, for example, or if this
// is a repeat search that already returned nothing last time the same prefix
// was searched.
bool shouldScopeMatches(const WTF::String& searchText);
// Removes the current frame from the global scoping effort and triggers any
// updates if appropriate. This method does not mark the scoping operation
// as finished.
void flushCurrentScopingEffort(int identifier);
// Finishes the current scoping effort and triggers any updates if appropriate.
void finishCurrentScopingEffort(int identifier);
// Queue up a deferred call to scopeStringMatches.
void scopeStringMatchesSoon(
int identifier, const WebString& searchText, const WebFindOptions&,
bool reset);
// Called by a DeferredScopeStringMatches instance.
void callScopeStringMatches(
DeferredScopeStringMatches*, int identifier, const WebString& searchText,
const WebFindOptions&, bool reset);
// Determines whether to invalidate the content area and scrollbar.
void invalidateIfNecessary();
// Sets the markers within a current match range as active or inactive.
void setMatchMarkerActive(bool);
void decrementFramesScopingCount(int identifier);
WebLocalFrameImpl& ownerFrame() const
{
ASSERT(m_ownerFrame);
return *m_ownerFrame;
}
// Returns the ordinal of the first match in the owner frame.
int ordinalOfFirstMatch() const;
RawPtrWillBeMember<WebLocalFrameImpl> m_ownerFrame;
// A way for the main frame to keep track of which frame has an active
// match. Should be 0 for all other frames.
RawPtrWillBeMember<WebLocalFrameImpl> m_currentActiveMatchFrame;
// The range of the active match for the current frame.
RefPtrWillBeMember<Range> m_activeMatch;
// The index of the active match for the current frame.
int m_activeMatchIndexInCurrentFrame;
// The scoping effort can time out and we need to keep track of where we
// ended our last search so we can continue from where we left of.
//
// This range is collapsed to the end position of the last successful
// search; the new search should start from this position.
RefPtrWillBeMember<Range> m_resumeScopingFromRange;
// Keeps track of the last string this frame searched for. This is used for
// short-circuiting searches in the following scenarios: When a frame has
// been searched and returned 0 results, we don't need to search that frame
// again if the user is just adding to the search (making it more specific).
WTF::String m_lastSearchString;
// Keeps track of how many matches this frame has found so far, so that we
// don't lose count between scoping efforts, and is also used (in conjunction
// with m_lastSearchString) to figure out if we need to search the frame again.
int m_lastMatchCount;
// This variable keeps a cumulative total of matches found so far for ALL the
// frames on the page, and is only incremented by calling IncreaseMatchCount
// (on the main frame only). It should be -1 for all other frames.
int m_totalMatchCount;
// This variable keeps a cumulative total of how many frames are currently
// scoping, and is incremented/decremented on the main frame only.
// It should be -1 for all other frames.
int m_framesScopingCount;
// Identifier of the latest find-in-page request. Required to be stored in
// the frame in order to reply if required in case the frame is detached.
int m_findRequestIdentifier;
// Keeps track of when the scoping effort should next invalidate the scrollbar
// and the frame area.
int m_nextInvalidateAfter;
// A list of all of the pending calls to scopeStringMatches.
WillBeHeapVector<OwnPtrWillBeMember<DeferredScopeStringMatches>> m_deferredScopingWork;
// Version number incremented on the main frame only whenever the document
// find-in-page match markers change. It should be 0 for all other frames.
int m_findMatchMarkersVersion;
// Local cache of the find match markers currently displayed for this frame.
WillBeHeapVector<FindMatch> m_findMatchesCache;
// Contents size when find-in-page match rects were last computed for this
// frame's cache.
IntSize m_contentsSizeForCurrentFindMatchRects;
// This flag is used by the scoping effort to determine if we need to figure
// out which rectangle is the active match. Once we find the active
// rectangle we clear this flag.
bool m_locatingActiveRect;
// Keeps track of whether there is an scoping effort ongoing in the frame.
bool m_scopingInProgress;
// Keeps track of whether the last find request completed its scoping effort
// without finding any matches in this frame.
bool m_lastFindRequestCompletedWithNoMatches;
// Determines if the rects in the find-in-page matches cache of this frame
// are invalid and should be recomputed.
bool m_findMatchRectsAreValid;
};
} // namespace blink
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::TextFinder::FindMatch);
#endif // TextFinder_h
|