Changeset 72887 in webkit
- Timestamp:
- Nov 29, 2010 10:39:39 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 44 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r72885 r72887 1 2010-11-29 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 WTF support for <rdar://problem/8650085> adding word-prefix search options to the text search API. 6 https://bugs.webkit.org/show_bug.cgi?id=50038 7 8 * wtf/unicode/UnicodeMacrosFromICU.h: Copied additional macros from icu/unicode/utf16.h. 9 1 10 2010-11-29 Steve Falkenburg <sfalken@apple.com> 2 11 -
trunk/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h
r67475 r72887 1 1 /* 2 * Copyright (C) 1999-2004, International Business Machines Corporation and others. All Rights Reserved. 2 3 * Copyright (C) 2006 George Staikos <staikos@kde.org> 3 4 * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> … … 44 45 #define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) 45 46 47 #define U16_GET(s, start, i, length, c) { \ 48 (c)=(s)[i]; \ 49 if(U16_IS_SURROGATE(c)) { \ 50 uint16_t __c2; \ 51 if(U16_IS_SURROGATE_LEAD(c)) { \ 52 if((i)+1<(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \ 53 (c)=U16_GET_SUPPLEMENTARY((c), __c2); \ 54 } \ 55 } else { \ 56 if((i)-1>=(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ 57 (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ 58 } \ 59 } \ 60 } \ 61 } 62 46 63 #define U16_PREV(s, start, i, c) { \ 47 64 (c)=(s)[--(i)]; \ … … 52 69 (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ 53 70 } \ 71 } \ 72 } 73 74 #define U16_BACK_1(s, start, i) { \ 75 if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \ 76 --(i); \ 54 77 } \ 55 78 } … … 66 89 } 67 90 91 #define U16_FWD_1(s, i, length) { \ 92 if(U16_IS_LEAD((s)[(i)++]) && (i)<(length) && U16_IS_TRAIL((s)[i])) { \ 93 ++(i); \ 94 } \ 95 } 96 68 97 #define U_MASK(x) ((uint32_t)1<<(x)) 69 98 70 99 #endif 71 -
trunk/LayoutTests/ChangeLog
r72886 r72887 1 2010-11-29 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 Added text search tests, in particular testing word-prefix search. 6 https://bugs.webkit.org/show_bug.cgi?id=50038 7 8 * editing/text-iterator/findString-expected.txt: Added. 9 * editing/text-iterator/findString.html: Added. 10 1 11 2010-11-29 Ojan Vafai <ojan@chromium.org> 2 12 -
trunk/WebCore/ChangeLog
r72884 r72887 1 2010-11-29 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 WebCore part of <rdar://problem/8650085> adding word-prefix search options to the text search API. 6 https://bugs.webkit.org/show_bug.cgi?id=50038 7 8 Test: editing/text-iterator/findString.html 9 10 * GNUmakefile.am: Added FindOptions.h. 11 * WebCore.exp.in: Export the new methods that take FindOptions. 12 * WebCore.gypi: Added FindOptions.h. 13 * WebCore.pro: Added FindOptions.h and TextBoundaries.{cpp,h}. 14 * WebCore.vcproj/WebCore.vcproj: Added FindOptions.h. 15 * WebCore.xcodeproj/project.pbxproj: Added FindOptions.h and TextBoundaries.cpp. 16 * editing/Editor.cpp: 17 (WebCore::Editor::firstVisibleRange): Changed to use FindOptions. 18 (WebCore::Editor::lastVisibleRange): Ditto. 19 (WebCore::Editor::nextVisibleRange): Ditto. 20 (WebCore::Editor::findString): Ditto. 21 (WebCore::Editor::countMatchesForText): Ditto. 22 * editing/Editor.h: Added a version of findString() that takes FindOptions. Changed 23 countMatchesForText() to take FindOptions. Made nextVisibleRange() private and changed it 24 and firstVisibleRange() and lastVisibleRange() to take FindOptions. 25 * editing/FindOptions.h: Added. 26 * editing/TextIterator.cpp: 27 Augmented SearchBuffer with an optional prefix, which is not searched, but provides context 28 for determining word boundaries. 29 (WebCore::isSeparator): Added. Identifies a class of characters used to determine where 30 “words” are embedded in a word. 31 (WebCore::SearchBuffer::SearchBuffer): Changed to take FindOptions. Added initialization of 32 m_options, m_prefixLength and m_needsMoreContext. 33 (WebCore::SearchBuffer::append): Adjust m_prefixLength as part of the prefix gets pushed out 34 of the buffer. 35 (WebCore::SearchBuffer::needsMoreContext): Added. 36 (WebCore::SearchBuffer::prependContext): Added. 37 (WebCore::SearchBuffer::isWordStartMatch): Added. 38 (WebCore::SearchBuffer::search): Changed to account for the context prefix. When searching 39 only for word prefix matches, maintains enough context before a tentative match when moving 40 it to the beginning of the buffer. Reject matches that are not at word starts if requested. 41 Adjust m_prefixLength when pushing characters out of the buffer. 42 (WebCore::findPlainText): Changed to work with FindOptions. Feed the search buffer with context 43 if and as long as it requires more of it. 44 * editing/TextIterator.h: Added a version of findPlainText() that takes FindOptions. 45 * editing/visible_units.cpp: Moved {end,start}Of{First,Last}WordBoundary to TextBoundaries.cpp. 46 * page/Page.cpp: 47 (WebCore::Page::findString): Changed to work with FindOptions. 48 (WebCore::Page::markAllMatchesForText): Ditto. 49 * page/Page.h: Added FindOptions-based findString() and markAllMatchesForText(). 50 * platform/text/TextBoundaries.cpp: 51 (WebCore::endOfFirstWordBoundaryContext): Moved here from visible_units.cpp. 52 (WebCore::startOfLastWordBoundaryContext): Ditto. 53 * platform/text/TextBoundaries.h: 54 1 55 2010-11-29 Dai Mikurube <dmikurube@google.com> 2 56 -
trunk/WebCore/GNUmakefile.am
r72834 r72887 1333 1333 WebCore/editing/Editor.h \ 1334 1334 WebCore/editing/EditorInsertAction.h \ 1335 WebCore/editing/FindOptions.h \ 1335 1336 WebCore/editing/FormatBlockCommand.cpp \ 1336 1337 WebCore/editing/FormatBlockCommand.h \ -
trunk/WebCore/WebCore.exp.in
r72777 r72887 600 600 __ZN7WebCore4Node18startIgnoringLeaksEv 601 601 __ZN7WebCore4Node19setNeedsStyleRecalcENS_15StyleChangeTypeE 602 __ZN7WebCore4Page10findStringERKN3WTF6StringE NS1_19TextCaseSensitivityENS_13FindDirectionEb602 __ZN7WebCore4Page10findStringERKN3WTF6StringEj 603 603 __ZN7WebCore4Page11PageClientsC1Ev 604 604 __ZN7WebCore4Page11PageClientsD1Ev … … 615 615 __ZN7WebCore4Page19visitedStateChangedEPNS_9PageGroupEy 616 616 __ZN7WebCore4Page20unmarkAllTextMatchesEv 617 __ZN7WebCore4Page21markAllMatchesForTextERKN3WTF6StringE NS1_19TextCaseSensitivityEbj617 __ZN7WebCore4Page21markAllMatchesForTextERKN3WTF6StringEjbj 618 618 __ZN7WebCore4Page22allVisitedStateChangedEPNS_9PageGroupE 619 619 __ZN7WebCore4Page23clearUndoRedoOperationsEv … … 662 662 __ZN7WebCore6CursoraSERKS0_ 663 663 __ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE 664 __ZN7WebCore6Editor10findStringERKN3WTF6StringE bbbb664 __ZN7WebCore6Editor10findStringERKN3WTF6StringEj 665 665 __ZN7WebCore6Editor10insertTextERKN3WTF6StringEPNS_5EventE 666 666 __ZN7WebCore6Editor13canDHTMLPasteEv … … 674 674 __ZN7WebCore6Editor18confirmCompositionERKN3WTF6StringE 675 675 __ZN7WebCore6Editor18confirmCompositionEv 676 __ZN7WebCore6Editor19countMatchesForTextERKN3WTF6StringE bjb676 __ZN7WebCore6Editor19countMatchesForTextERKN3WTF6StringEjjb 677 677 __ZN7WebCore6Editor19deleteWithDirectionENS_19SelectionController10EDirectionENS_15TextGranularityEbb 678 678 __ZN7WebCore6Editor19insertUnorderedListEv -
trunk/WebCore/WebCore.gypi
r72777 r72887 1400 1400 'editing/EditorDeleteAction.h', 1401 1401 'editing/EditorInsertAction.h', 1402 'editing/FindOptions.h', 1402 1403 'editing/FormatBlockCommand.cpp', 1403 1404 'editing/FormatBlockCommand.h', -
trunk/WebCore/WebCore.pro
r72777 r72887 1232 1232 platform/SharedBuffer.cpp \ 1233 1233 platform/text/String.cpp \ 1234 platform/text/TextBoundaries.cpp \ 1234 1235 platform/text/TextCodec.cpp \ 1235 1236 platform/text/TextCodecLatin1.cpp \ … … 1713 1714 editing/EditingBoundary.h \ 1714 1715 editing/Editor.h \ 1716 editing/FindOptions.h \ 1715 1717 editing/FormatBlockCommand.h \ 1716 1718 editing/htmlediting.h \ … … 2178 2180 platform/text/RegularExpression.h \ 2179 2181 platform/text/SegmentedString.h \ 2182 platform/text/TextBoundaries.h \ 2180 2183 platform/text/TextCodec.h \ 2181 2184 platform/text/TextCodecLatin1.h \ -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r72795 r72887 46584 46584 </File> 46585 46585 <File 46586 RelativePath="..\editing\FindOptions.h" 46587 > 46588 </File> 46589 <File 46586 46590 RelativePath="..\editing\FormatBlockCommand.cpp" 46587 46591 > -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r72777 r72887 872 872 371F53EA0D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 371F53E80D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp */; }; 873 873 37202199106213C600F25C4B /* FontSmoothingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 37202198106213C600F25C4B /* FontSmoothingMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 874 372C00C4129611F1005C9575 /* TextBoundaries.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 372C00C3129611F1005C9575 /* TextBoundaries.cpp */; }; 875 372C00D9129619F8005C9575 /* FindOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 372C00D8129619F8005C9575 /* FindOptions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 874 876 3744570F0DB05FA500AE0992 /* SVGGlyphMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 3744570E0DB05FA500AE0992 /* SVGGlyphMap.h */; }; 875 877 375CD232119D43C800A2A859 /* Hyphenation.h in Headers */ = {isa = PBXBuildFile; fileRef = 375CD231119D43C800A2A859 /* Hyphenation.h */; }; … … 6979 6981 371F53E80D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSUnicodeRangeValue.cpp; sourceTree = "<group>"; }; 6980 6982 37202198106213C600F25C4B /* FontSmoothingMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSmoothingMode.h; sourceTree = "<group>"; }; 6983 372C00C3129611F1005C9575 /* TextBoundaries.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextBoundaries.cpp; sourceTree = "<group>"; }; 6984 372C00D8129619F8005C9575 /* FindOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindOptions.h; sourceTree = "<group>"; }; 6981 6985 3744570E0DB05FA500AE0992 /* SVGGlyphMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGGlyphMap.h; sourceTree = "<group>"; }; 6982 6986 375CD231119D43C800A2A859 /* Hyphenation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hyphenation.h; sourceTree = "<group>"; }; … … 14611 14615 4BAE95B00B2FA9CE00AED8A0 /* EditorDeleteAction.h */, 14612 14616 93FDAFC90B11307400E2746F /* EditorInsertAction.h */, 14617 372C00D8129619F8005C9575 /* FindOptions.h */, 14613 14618 D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */, 14614 14619 D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */, … … 16850 16855 B2C3DA000D006C1D00EF6F26 /* String.cpp */, 16851 16856 97C0784F1165D5BE003A32EF /* SuffixTree.h */, 16857 372C00C3129611F1005C9575 /* TextBoundaries.cpp */, 16852 16858 B2C3DA040D006C1D00EF6F26 /* TextBoundaries.h */, 16853 16859 B2C3DA060D006C1D00EF6F26 /* TextBreakIterator.h */, … … 19691 19697 845E72F80FD261EE00A87D79 /* Filter.h in Headers */, 19692 19698 08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */, 19699 372C00D9129619F8005C9575 /* FindOptions.h in Headers */, 19693 19700 A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */, 19694 19701 89878566122CA064003AABDA /* Flags.h in Headers */, … … 23788 23795 498770EE1242C535002226BA /* TexShader.cpp in Sources */, 23789 23796 6550B6A5099DF0270090D781 /* Text.cpp in Sources */, 23797 372C00C4129611F1005C9575 /* TextBoundaries.cpp in Sources */, 23790 23798 B2AFFC970D00A5DF0030074D /* TextBoundaries.mm in Sources */, 23791 23799 B2C3DA370D006C1D00EF6F26 /* TextBreakIteratorICU.cpp in Sources */, -
trunk/WebCore/editing/Editor.cpp
r72573 r72887 2835 2835 } 2836 2836 2837 PassRefPtr<Range> Editor::firstVisibleRange(const String& target, bool caseFlag)2837 PassRefPtr<Range> Editor::firstVisibleRange(const String& target, FindOptions options) 2838 2838 { 2839 2839 RefPtr<Range> searchRange(rangeOfContents(m_frame->document())); 2840 RefPtr<Range> resultRange = findPlainText(searchRange.get(), target, true, caseFlag);2840 RefPtr<Range> resultRange = findPlainText(searchRange.get(), target, options & ~Backwards); 2841 2841 ExceptionCode ec = 0; 2842 2842 … … 2845 2845 if (searchRange->startContainer() == searchRange->endContainer()) 2846 2846 return Range::create(m_frame->document()); 2847 resultRange = findPlainText(searchRange.get(), target, true, caseFlag);2847 resultRange = findPlainText(searchRange.get(), target, options & ~Backwards); 2848 2848 } 2849 2849 … … 2851 2851 } 2852 2852 2853 PassRefPtr<Range> Editor::lastVisibleRange(const String& target, bool caseFlag)2853 PassRefPtr<Range> Editor::lastVisibleRange(const String& target, FindOptions options) 2854 2854 { 2855 2855 RefPtr<Range> searchRange(rangeOfContents(m_frame->document())); 2856 RefPtr<Range> resultRange = findPlainText(searchRange.get(), target, false, caseFlag);2856 RefPtr<Range> resultRange = findPlainText(searchRange.get(), target, options | Backwards); 2857 2857 ExceptionCode ec = 0; 2858 2858 … … 2861 2861 if (searchRange->startContainer() == searchRange->endContainer()) 2862 2862 return Range::create(m_frame->document()); 2863 resultRange = findPlainText(searchRange.get(), target, false, caseFlag);2863 resultRange = findPlainText(searchRange.get(), target, options | Backwards); 2864 2864 } 2865 2865 … … 2867 2867 } 2868 2868 2869 PassRefPtr<Range> Editor::nextVisibleRange(Range* currentRange, const String& target, bool forward, bool caseFlag, bool wrapFlag)2869 PassRefPtr<Range> Editor::nextVisibleRange(Range* currentRange, const String& target, FindOptions options) 2870 2870 { 2871 2871 if (m_frame->excludeFromTextSearch()) … … 2875 2875 RefPtr<Range> searchRange(rangeOfContents(m_frame->document())); 2876 2876 ExceptionCode ec = 0; 2877 2878 for ( ; !insideVisibleArea(resultRange.get()); resultRange = findPlainText(searchRange.get(), target, forward, caseFlag)) {2877 bool forward = !(options & Backwards); 2878 for ( ; !insideVisibleArea(resultRange.get()); resultRange = findPlainText(searchRange.get(), target, options)) { 2879 2879 if (resultRange->collapsed(ec)) { 2880 2880 if (!resultRange->startContainer()->isInShadowTree()) … … 2908 2908 return resultRange; 2909 2909 2910 if (! wrapFlag)2910 if (!(options & WrapAround)) 2911 2911 return Range::create(m_frame->document()); 2912 2912 2913 if ( forward)2914 return firstVisibleRange(target, caseFlag);2915 2916 return lastVisibleRange(target, caseFlag);2913 if (options & Backwards) 2914 return lastVisibleRange(target, options); 2915 2916 return firstVisibleRange(target, options); 2917 2917 } 2918 2918 … … 3186 3186 bool Editor::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection) 3187 3187 { 3188 FindOptions options = (forward ? 0 : Backwards) | (caseFlag ? 0 : CaseInsensitive) | (wrapFlag ? WrapAround : 0) | (startInSelection ? StartInSelection : 0); 3189 return findString(target, options); 3190 } 3191 3192 bool Editor::findString(const String& target, FindOptions options) 3193 { 3188 3194 if (target.isEmpty()) 3189 3195 return false; … … 3197 3203 VisibleSelection selection = m_frame->selection()->selection(); 3198 3204 3205 bool forward = !(options & Backwards); 3206 bool startInSelection = options & StartInSelection; 3199 3207 if (forward) 3200 3208 setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd()); … … 3211 3219 } 3212 3220 3213 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));3221 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options)); 3214 3222 // If we started in the selection and the found range exactly matches the existing selection, find again. 3215 3223 // Build a selection with the found range to remove collapsed whitespace. … … 3230 3238 } 3231 3239 3232 resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);3240 resultRange = findPlainText(searchRange.get(), target, options); 3233 3241 } 3234 3242 … … 3243 3251 searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception); 3244 3252 3245 resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);3253 resultRange = findPlainText(searchRange.get(), target, options); 3246 3254 } 3247 3255 3248 3256 if (!insideVisibleArea(resultRange.get())) { 3249 resultRange = nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);3257 resultRange = nextVisibleRange(resultRange.get(), target, options); 3250 3258 if (!resultRange) 3251 3259 return false; … … 3254 3262 // If we didn't find anything and we're wrapping, search again in the entire document (this will 3255 3263 // redundantly re-search the area already searched in some cases). 3256 if (resultRange->collapsed(exception) && wrapFlag) {3264 if (resultRange->collapsed(exception) && options & WrapAround) { 3257 3265 searchRange = rangeOfContents(m_frame->document()); 3258 resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);3266 resultRange = findPlainText(searchRange.get(), target, options); 3259 3267 // We used to return false here if we ended up with the same range that we started with 3260 3268 // (e.g., the selection was already the only instance of this text). But we decided that … … 3270 3278 } 3271 3279 3272 unsigned Editor::countMatchesForText(const String& target, bool caseFlag, unsigned limit, bool markMatches)3280 unsigned Editor::countMatchesForText(const String& target, FindOptions options, unsigned limit, bool markMatches) 3273 3281 { 3274 3282 if (target.isEmpty()) … … 3280 3288 unsigned matchCount = 0; 3281 3289 do { 3282 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));3290 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options & ~Backwards)); 3283 3291 if (resultRange->collapsed(exception)) { 3284 3292 if (!resultRange->startContainer()->isInShadowTree()) -
trunk/WebCore/editing/Editor.h
r72573 r72887 34 34 #include "EditorDeleteAction.h" 35 35 #include "EditorInsertAction.h" 36 #include "FindOptions.h" 36 37 #include "SelectionController.h" 37 38 … … 308 309 bool insideVisibleArea(const IntPoint&) const; 309 310 bool insideVisibleArea(Range*) const; 310 PassRefPtr<Range> nextVisibleRange(Range*, const String&, bool forward, bool caseFlag, bool wrapFlag);311 311 312 312 void addToKillRing(Range*, bool prepend); … … 329 329 330 330 String selectedText() const; 331 bool findString(const String&, FindOptions); 332 // FIXME: Switch callers over to the FindOptions version and retire this one. 331 333 bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection); 332 334 … … 345 347 RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const; 346 348 347 unsigned countMatchesForText(const String&, bool caseFlag, unsigned limit, bool markMatches);349 unsigned countMatchesForText(const String&, FindOptions, unsigned limit, bool markMatches); 348 350 bool markedTextMatchesAreHighlighted() const; 349 351 void setMarkedTextMatchesAreHighlighted(bool); … … 399 401 void setIgnoreCompositionSelectionChange(bool ignore); 400 402 401 PassRefPtr<Range> firstVisibleRange(const String&, bool caseFlag); 402 PassRefPtr<Range> lastVisibleRange(const String&, bool caseFlag); 403 PassRefPtr<Range> firstVisibleRange(const String&, FindOptions); 404 PassRefPtr<Range> lastVisibleRange(const String&, FindOptions); 405 PassRefPtr<Range> nextVisibleRange(Range*, const String&, FindOptions); 403 406 404 407 void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle); -
trunk/WebCore/editing/TextIterator.cpp
r72748 r72887 39 39 #include "RenderTextControl.h" 40 40 #include "RenderTextFragment.h" 41 #include "TextBoundaries.h" 42 #include "TextBreakIterator.h" 41 43 #include "VisiblePosition.h" 42 44 #include "visible_units.h" … … 57 59 // Keeps enough of the previous text to be able to search in the future, but no more. 58 60 // Non-breaking spaces are always equal to normal spaces. 59 // Case folding is also done if <isCaseSensitive> is false. 61 // Case folding is also done if the CaseInsensitive option is specified. 62 // Matches are further filtered if the AtWordStarts option is specified, although some 63 // matches inside a word are permitted if TreatMedialCapitalAsWordStart is specified as well. 60 64 class SearchBuffer : public Noncopyable { 61 65 public: 62 SearchBuffer(const String& target, bool isCaseSensitive);66 SearchBuffer(const String& target, FindOptions); 63 67 ~SearchBuffer(); 64 68 65 69 // Returns number of characters appended; guaranteed to be in the range [1, length]. 66 70 size_t append(const UChar*, size_t length); 71 bool needsMoreContext() const; 72 void prependContext(const UChar*, size_t length); 67 73 void reachedBreak(); 68 74 … … 76 82 private: 77 83 bool isBadMatch(const UChar*, size_t length) const; 84 bool isWordStartMatch(size_t start, size_t length) const; 78 85 79 86 String m_target; 87 FindOptions m_options; 88 80 89 Vector<UChar> m_buffer; 81 90 size_t m_overlap; 91 size_t m_prefixLength; 82 92 bool m_atBreak; 93 bool m_needsMoreContext; 83 94 84 95 bool m_targetRequiresKanaWorkaround; … … 93 104 94 105 String m_target; 95 bool m_isCaseSensitive;106 FindOptions m_options; 96 107 97 108 Vector<UChar> m_buffer; … … 1829 1840 } 1830 1841 1831 inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive) 1842 static bool isNonLatin1Separator(UChar32 character) 1843 { 1844 ASSERT_ARG(character, character >= 256); 1845 1846 return U_GET_GC_MASK(character) & (U_GC_S_MASK | U_GC_P_MASK | U_GC_Z_MASK | U_GC_CF_MASK); 1847 } 1848 1849 static inline bool isSeparator(UChar32 character) 1850 { 1851 static const bool latin1SeparatorTable[256] = { 1852 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1853 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1854 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // space ! " # $ % & ' ( ) * + , - . / 1855 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, // : ; < = > ? 1856 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // @ 1857 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, // [ \ ] ^ _ 1858 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ` 1859 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // { | } ~ 1860 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1861 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1862 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1863 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1864 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1865 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1866 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1867 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 1868 }; 1869 1870 if (character < 256) 1871 return latin1SeparatorTable[character]; 1872 1873 return isNonLatin1Separator(character); 1874 } 1875 1876 inline SearchBuffer::SearchBuffer(const String& target, FindOptions options) 1832 1877 : m_target(target) 1878 , m_options(options) 1879 , m_prefixLength(0) 1833 1880 , m_atBreak(true) 1881 , m_needsMoreContext(options & AtWordStarts) 1834 1882 , m_targetRequiresKanaWorkaround(containsKanaLetters(m_target)) 1835 1883 { … … 1853 1901 UCollator* collator = usearch_getCollator(searcher); 1854 1902 1855 UCollationStrength strength = isCaseSensitive ? UCOL_TERTIARY : UCOL_PRIMARY;1903 UCollationStrength strength = m_options & CaseInsensitive ? UCOL_PRIMARY : UCOL_TERTIARY; 1856 1904 if (ucol_getStrength(collator) != strength) { 1857 1905 ucol_setStrength(collator, strength); … … 1879 1927 if (m_atBreak) { 1880 1928 m_buffer.shrink(0); 1929 m_prefixLength = 0; 1881 1930 m_atBreak = false; 1882 1931 } else if (m_buffer.size() == m_buffer.capacity()) { 1883 1932 memcpy(m_buffer.data(), m_buffer.data() + m_buffer.size() - m_overlap, m_overlap * sizeof(UChar)); 1933 m_prefixLength -= min(m_prefixLength, m_buffer.size() - m_overlap); 1884 1934 m_buffer.shrink(m_overlap); 1885 1935 } … … 1891 1941 foldQuoteMarksAndSoftHyphens(m_buffer.data() + oldLength, usableLength); 1892 1942 return usableLength; 1943 } 1944 1945 inline bool SearchBuffer::needsMoreContext() const 1946 { 1947 return m_needsMoreContext; 1948 } 1949 1950 inline void SearchBuffer::prependContext(const UChar* characters, size_t length) 1951 { 1952 ASSERT(m_needsMoreContext); 1953 ASSERT(m_prefixLength == m_buffer.size()); 1954 1955 if (!length) 1956 return; 1957 1958 m_atBreak = false; 1959 1960 size_t wordBoundaryContextStart = length; 1961 if (wordBoundaryContextStart) { 1962 U16_BACK_1(characters, 0, wordBoundaryContextStart); 1963 wordBoundaryContextStart = startOfLastWordBoundaryContext(characters, wordBoundaryContextStart); 1964 } 1965 1966 size_t usableLength = min(m_buffer.capacity() - m_prefixLength, length - wordBoundaryContextStart); 1967 m_buffer.prepend(characters + length - usableLength, usableLength); 1968 m_prefixLength += usableLength; 1969 1970 if (wordBoundaryContextStart || m_prefixLength == m_buffer.capacity()) 1971 m_needsMoreContext = false; 1893 1972 } 1894 1973 … … 1963 2042 } 1964 2043 2044 inline bool SearchBuffer::isWordStartMatch(size_t start, size_t length) const 2045 { 2046 ASSERT(m_options & AtWordStarts); 2047 2048 if (!start) 2049 return true; 2050 2051 if (m_options & TreatMedialCapitalAsWordStart) { 2052 int size = m_buffer.size(); 2053 int offset = start; 2054 UChar32 firstCharacter; 2055 U16_GET(m_buffer.data(), 0, offset, size, firstCharacter); 2056 UChar32 previousCharacter; 2057 U16_PREV(m_buffer.data(), 0, offset, previousCharacter); 2058 2059 if (isSeparator(firstCharacter)) { 2060 // The start of a separator run is a word start (".org" in "webkit.org"). 2061 if (!isSeparator(previousCharacter)) 2062 return true; 2063 } else if (isASCIIUpper(firstCharacter)) { 2064 // The start of an uppercase run is a word start ("Kit" in "WebKit"). 2065 if (!isASCIIUpper(previousCharacter)) 2066 return true; 2067 // The last character of an uppercase run followed by a non-separator, non-digit 2068 // is a word start ("Request" in "XMLHTTPRequest"). 2069 offset = start; 2070 U16_FWD_1(m_buffer.data(), offset, size); 2071 UChar32 nextCharacter = 0; 2072 if (offset < size) 2073 U16_GET(m_buffer.data(), 0, offset, size, nextCharacter); 2074 if (!isASCIIUpper(nextCharacter) && !isASCIIDigit(nextCharacter) && !isSeparator(nextCharacter)) 2075 return true; 2076 } else if (isASCIIDigit(firstCharacter)) { 2077 // The start of a digit run is a word start ("2" in "WebKit2"). 2078 if (!isASCIIDigit(previousCharacter)) 2079 return true; 2080 } else if (isSeparator(previousCharacter) || isASCIIDigit(previousCharacter)) { 2081 // The start of a non-separator, non-uppercase, non-digit run is a word start, 2082 // except after an uppercase. ("org" in "webkit.org", but not "ore" in "WebCore"). 2083 return true; 2084 } 2085 } 2086 2087 size_t wordBreakSearchStart = start + length; 2088 while (wordBreakSearchStart > start) 2089 wordBreakSearchStart = findNextWordFromIndex(m_buffer.data(), m_buffer.size(), wordBreakSearchStart, false /* backwards */); 2090 return wordBreakSearchStart == start; 2091 } 2092 1965 2093 inline size_t SearchBuffer::search(size_t& start) 1966 2094 { … … 1980 2108 ASSERT(status == U_ZERO_ERROR); 1981 2109 1982 int matchStart = usearch_first(searcher, &status); 2110 usearch_setOffset(searcher, m_prefixLength, &status); 2111 ASSERT(status == U_ZERO_ERROR); 2112 2113 int matchStart = usearch_next(searcher, &status); 1983 2114 ASSERT(status == U_ZERO_ERROR); 1984 2115 … … 1993 2124 // possibly including a combining character that's not yet in the buffer. 1994 2125 if (!m_atBreak && static_cast<size_t>(matchStart) >= size - m_overlap) { 1995 memcpy(m_buffer.data(), m_buffer.data() + size - m_overlap, m_overlap * sizeof(UChar)); 1996 m_buffer.shrink(m_overlap); 2126 size_t overlap = m_overlap; 2127 if (m_options & AtWordStarts) { 2128 // Ensure that there is sufficient context before matchStart the next time around for 2129 // determining if it is at a word boundary. 2130 int wordBoundaryContextStart = matchStart; 2131 U16_BACK_1(m_buffer.data(), 0, wordBoundaryContextStart); 2132 wordBoundaryContextStart = startOfLastWordBoundaryContext(m_buffer.data(), wordBoundaryContextStart); 2133 overlap = min(size - 1, max(overlap, size - wordBoundaryContextStart)); 2134 } 2135 memcpy(m_buffer.data(), m_buffer.data() + size - overlap, overlap * sizeof(UChar)); 2136 m_prefixLength -= min(m_prefixLength, size - overlap); 2137 m_buffer.shrink(overlap); 1997 2138 return 0; 1998 2139 } … … 2002 2143 2003 2144 // If this match is "bad", move on to the next match. 2004 if (isBadMatch(m_buffer.data() + matchStart, matchedLength) ) {2145 if (isBadMatch(m_buffer.data() + matchStart, matchedLength) || m_options & AtWordStarts && !isWordStartMatch(matchStart, matchedLength)) { 2005 2146 matchStart = usearch_next(searcher, &status); 2006 2147 ASSERT(status == U_ZERO_ERROR); … … 2010 2151 size_t newSize = size - (matchStart + 1); 2011 2152 memmove(m_buffer.data(), m_buffer.data() + matchStart + 1, newSize * sizeof(UChar)); 2153 m_prefixLength -= min<size_t>(m_prefixLength, matchStart + 1); 2012 2154 m_buffer.shrink(newSize); 2013 2155 … … 2018 2160 #else // !ICU_UNICODE 2019 2161 2020 inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive)2021 : m_target( isCaseSensitive ? target : target.foldCase())2022 , m_ isCaseSensitive(isCaseSensitive)2162 inline SearchBuffer::SearchBuffer(const String& target, FindOptions options) 2163 : m_target(options & CaseInsensitive ? target.foldCase() : target) 2164 , m_options(options) 2023 2165 , m_buffer(m_target.length()) 2024 2166 , m_isCharacterStartBuffer(m_target.length()) … … 2059 2201 { 2060 2202 ASSERT(length); 2061 if ( m_isCaseSensitive) {2203 if (!(m_options & CaseInsensitive)) { 2062 2204 append(characters[0], true); 2063 2205 return 1; … … 2077 2219 } 2078 2220 return 1; 2221 } 2222 2223 inline bool SearchBuffer::needsMoreContext() const 2224 { 2225 return false; 2226 } 2227 2228 void prependContext(const UChar*, size_t) 2229 { 2230 ASSERT_NOT_REACHED(); 2079 2231 } 2080 2232 … … 2333 2485 } 2334 2486 2335 static size_t findPlainText(CharacterIterator& it, const String& target, bool forward, bool caseSensitive, size_t& matchStart)2487 static size_t findPlainText(CharacterIterator& it, const String& target, FindOptions options, size_t& matchStart) 2336 2488 { 2337 2489 matchStart = 0; 2338 2490 size_t matchLength = 0; 2339 2491 2340 SearchBuffer buffer(target, caseSensitive); 2492 SearchBuffer buffer(target, options); 2493 2494 if (buffer.needsMoreContext()) { 2495 RefPtr<Range> startRange = it.range(); 2496 RefPtr<Range> beforeStartRange = startRange->ownerDocument()->createRange(); 2497 ExceptionCode ec = 0; 2498 beforeStartRange->setEnd(startRange->startContainer(), startRange->startOffset(), ec); 2499 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { 2500 buffer.prependContext(backwardsIterator.characters(), backwardsIterator.length()); 2501 if (!buffer.needsMoreContext()) 2502 break; 2503 } 2504 } 2341 2505 2342 2506 while (!it.atEnd()) { … … 2352 2516 // If searching forward, stop on the first match. 2353 2517 // If searching backward, don't stop, so we end up with the last match. 2354 if ( forward)2518 if (!(options & Backwards)) 2355 2519 break; 2356 2520 goto tryAgain; … … 2366 2530 2367 2531 PassRefPtr<Range> findPlainText(const Range* range, const String& target, bool forward, bool caseSensitive) 2532 { 2533 return findPlainText(range, target, (forward ? 0 : Backwards) | (caseSensitive ? 0 : CaseInsensitive)); 2534 } 2535 2536 PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOptions options) 2368 2537 { 2369 2538 // First, find the text. … … 2372 2541 { 2373 2542 CharacterIterator findIterator(range, TextIteratorEntersTextControls); 2374 matchLength = findPlainText(findIterator, target, forward, caseSensitive, matchStart);2543 matchLength = findPlainText(findIterator, target, options, matchStart); 2375 2544 if (!matchLength) 2376 return collapsedToBoundary(range, forward);2545 return collapsedToBoundary(range, !(options & Backwards)); 2377 2546 } 2378 2547 -
trunk/WebCore/editing/TextIterator.h
r69437 r72887 27 27 #define TextIterator_h 28 28 29 #include "FindOptions.h" 29 30 #include "InlineTextBox.h" 30 31 #include "Range.h" … … 59 60 60 61 String plainText(const Range*, TextIteratorBehavior defaultBehavior = TextIteratorDefaultBehavior); 61 UChar* plainTextToMallocAllocatedBuffer(const Range*, unsigned& bufferLength, bool isDisplayString, TextIteratorBehavior defaultBehavior = TextIteratorDefaultBehavior); 62 UChar* plainTextToMallocAllocatedBuffer(const Range*, unsigned& bufferLength, bool isDisplayString, TextIteratorBehavior = TextIteratorDefaultBehavior); 63 PassRefPtr<Range> findPlainText(const Range*, const String&, FindOptions); 64 // FIXME: Switch callers over to the FindOptions version and retire this one. 62 65 PassRefPtr<Range> findPlainText(const Range*, const String&, bool forward, bool caseSensitive); 63 66 -
trunk/WebCore/editing/visible_units.cpp
r72861 r72887 46 46 using namespace WTF::Unicode; 47 47 48 static int endOfFirstWordBoundaryContext(const UChar* characters, int length)49 {50 for (int i = 0; i < length; ) {51 int first = i;52 UChar32 ch;53 U16_NEXT(characters, i, length, ch);54 if (!requiresContextForWordBoundary(ch))55 return first;56 }57 return length;58 }59 60 static int startOfLastWordBoundaryContext(const UChar* characters, int length)61 {62 for (int i = length; i > 0; ) {63 int last = i;64 UChar32 ch;65 U16_PREV(characters, 0, i, ch);66 if (!requiresContextForWordBoundary(ch))67 return last;68 }69 return 0;70 }71 72 48 enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext }; 73 49 -
trunk/WebCore/page/Page.cpp
r71903 r72887 508 508 bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity, FindDirection direction, bool shouldWrap) 509 509 { 510 return findString(target, (caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0) | (direction == FindDirectionBackward ? Backwards : 0) | (shouldWrap ? WrapAround : 0)); 511 } 512 513 bool Page::findString(const String& target, FindOptions options) 514 { 510 515 if (target.isEmpty() || !mainFrame()) 511 516 return false; 512 517 518 bool shouldWrap = options & WrapAround; 513 519 Frame* frame = focusController()->focusedOrMainFrame(); 514 520 Frame* startFrame = frame; 515 521 do { 516 if (frame->editor()->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, false, true)) {522 if (frame->editor()->findString(target, (options & ~WrapAround) | StartInSelection)) { 517 523 if (frame != startFrame) 518 524 startFrame->selection()->clear(); … … 520 526 return true; 521 527 } 522 frame = incrementFrame(frame, direction == FindDirectionForward, shouldWrap);528 frame = incrementFrame(frame, !(options & Backwards), shouldWrap); 523 529 } while (frame && frame != startFrame); 524 530 … … 526 532 // We cheat a bit and just research with wrap on 527 533 if (shouldWrap && !startFrame->selection()->isNone()) { 528 bool found = startFrame->editor()->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, true, true);534 bool found = startFrame->editor()->findString(target, options | WrapAround | StartInSelection); 529 535 focusController()->setFocusedFrame(frame); 530 536 return found; … … 535 541 536 542 unsigned int Page::markAllMatchesForText(const String& target, TextCaseSensitivity caseSensitivity, bool shouldHighlight, unsigned limit) 543 { 544 return markAllMatchesForText(target, caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0, shouldHighlight, limit); 545 } 546 547 unsigned int Page::markAllMatchesForText(const String& target, FindOptions options, bool shouldHighlight, unsigned limit) 537 548 { 538 549 if (target.isEmpty() || !mainFrame()) … … 544 555 do { 545 556 frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight); 546 matches += frame->editor()->countMatchesForText(target, caseSensitivity == TextCaseSensitive, limit ? (limit - matches) : 0, true);557 matches += frame->editor()->countMatchesForText(target, options, limit ? (limit - matches) : 0, true); 547 558 frame = incrementFrame(frame, true, false); 548 559 } while (frame); -
trunk/WebCore/page/Page.h
r71903 r72887 23 23 24 24 #include "FrameLoaderTypes.h" 25 #include "FindOptions.h" 25 26 #include "PlatformString.h" 26 27 #include "ViewportArguments.h" … … 199 200 bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; } 200 201 202 bool findString(const String&, FindOptions); 203 // FIXME: Switch callers over to the FindOptions version and retire this one. 201 204 bool findString(const String&, TextCaseSensitivity, FindDirection, bool shouldWrap); 202 unsigned int markAllMatchesForText(const String&, TextCaseSensitivity, bool shouldHighlight, unsigned); 205 unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned); 206 // FIXME: Switch callers over to the FindOptions version and retire this one. 207 unsigned markAllMatchesForText(const String&, TextCaseSensitivity, bool shouldHighlight, unsigned); 203 208 void unmarkAllTextMatches(); 204 209 -
trunk/WebCore/platform/text/TextBoundaries.cpp
r65084 r72887 36 36 37 37 namespace WebCore { 38 39 int endOfFirstWordBoundaryContext(const UChar* characters, int length) 40 { 41 for (int i = 0; i < length; ) { 42 int first = i; 43 UChar32 ch; 44 U16_NEXT(characters, i, length, ch); 45 if (!requiresContextForWordBoundary(ch)) 46 return first; 47 } 48 return length; 49 } 50 51 int startOfLastWordBoundaryContext(const UChar* characters, int length) 52 { 53 for (int i = length; i > 0; ) { 54 int last = i; 55 UChar32 ch; 56 U16_PREV(characters, 0, i, ch); 57 if (!requiresContextForWordBoundary(ch)) 58 return last; 59 } 60 return 0; 61 } 62 63 #if !PLATFORM(BREWMP) && !PLATFORM(MAC) && !PLATFORM(QT) 38 64 39 65 int findNextWordFromIndex(const UChar* chars, int len, int position, bool forward) … … 77 103 } 78 104 105 #endif // !PLATFORM(BREWMP) && !PLATFORM(MAC) && !PLATFORM(QT) 106 79 107 } // namespace WebCore -
trunk/WebCore/platform/text/TextBoundaries.h
r44102 r72887 36 36 } 37 37 38 int endOfFirstWordBoundaryContext(const UChar* characters, int length); 39 int startOfLastWordBoundaryContext(const UChar* characters, int length); 40 38 41 void findWordBoundary(const UChar*, int len, int position, int* start, int* end); 39 42 int findNextWordFromIndex(const UChar*, int len, int position, bool forward); -
trunk/WebKit/mac/ChangeLog
r72852 r72887 1 2010-11-29 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 WebKit Mac part of <rdar://problem/8650085> adding word-prefix search options to the text search API. 6 https://bugs.webkit.org/show_bug.cgi?id=50038 7 Based on a patch from Darin Adler. 8 9 * WebView/WebDocumentInternal.h: Removed -markAllMatchesForText:caseSensitive:limit: and 10 replaced -countMatchesForText:caseSensitive:limit:markMatches: with a WebFindOptions-based 11 method. Declared a WebDocumentOptionsSearching protocol with a new -findString:options: 12 method. Made WebHTMLView conform to the new protocol. 13 * WebView/WebHTMLView.mm: 14 (coreOptions): Added. Converts WebFindOptions to WebCore FindOptions. 15 (-[WebHTMLView searchFor:direction:caseSensitive:wrap:startInSelection:]): Changed to use 16 -findString:options:. 17 (-[WebHTMLView countMatchesForText:options:limit:markMatches:]): Changed to use WebFindOptions. 18 (-[WebHTMLView findString:options:]): Added. Calls through to WebCore::Editor::findString(). 19 * WebView/WebPDFView.mm: 20 (-[WebPDFView countMatchesForText:options:limit:markMatches:]): Changed to use WebFindOptions. 21 * WebView/WebView.mm: 22 (-[WebView markAllMatchesForText:caseSensitive:highlight:limit:]): Now calls through to 23 -countMatchesForText:options:highlight:limit:markMatches. 24 (-[WebView countMatchesForText:caseSensitive:highlight:limit:markMatches:]): Ditto. 25 (-[WebView searchFor:direction:caseSensitive:wrap:startInSelection:]): Now calls through to 26 -findString:options:. 27 (incrementFrame): Changed to use WebFindOptions. 28 (findString): Added this helper method that performs the search using the best supported 29 method for the document view. 30 (-[WebView findString:options:]): Changed -searchFor::::: into this. 31 (-[WebView canMarkAllTextMatches]): 32 (-[WebView countMatchesForText:options:highlight:limit:markMatches:]): Updated to use 33 WebFindOptions. 34 (-[WebView unmarkAllTextMatches]): Updated for change to incrementFrame. 35 (-[WebView rectsForTextMatches]): Ditto. 36 * WebView/WebViewPrivate.h: Added WebFindOptions, -findString:options:, and WebFindOptions version 37 of countMatchesForText:. 38 1 39 2010-11-29 Jeremy Moskovich <jeremy@chromium.org> 2 40 -
trunk/WebKit/mac/WebView/WebDocumentInternal.h
r66544 r72887 29 29 #import <WebKit/WebDocumentPrivate.h> 30 30 #import <WebKit/WebHTMLView.h> 31 #import <WebKit/WebViewPrivate.h> 31 32 32 33 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 … … 62 63 - (void)setMarkedTextMatchesAreHighlighted:(BOOL)newValue; 63 64 - (BOOL)markedTextMatchesAreHighlighted; 64 - (WebNSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(WebNSUInteger)limit; 65 - (WebNSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(WebNSUInteger)limit markMatches:(BOOL)markMatches; 65 - (WebNSUInteger)countMatchesForText:(NSString *)string options:(WebFindOptions)options limit:(WebNSUInteger)limit markMatches:(BOOL)markMatches; 66 66 - (void)unmarkAllTextMatches; 67 67 - (NSArray *)rectsForTextMatches; 68 68 @end 69 69 70 @protocol WebDocumentOptionsSearching <NSObject> 71 - (BOOL)findString:(NSString *)string options:(WebFindOptions)options; 72 @end 70 73 71 74 /* Used to save and restore state in the view, typically when going back/forward */ … … 77 80 @end 78 81 79 @interface WebHTMLView (WebDocumentInternalProtocols) <WebDocumentElement, WebMultipleTextMatches >82 @interface WebHTMLView (WebDocumentInternalProtocols) <WebDocumentElement, WebMultipleTextMatches, WebDocumentOptionsSearching> 80 83 @end 81 84 -
trunk/WebKit/mac/WebView/WebHTMLView.mm
r72852 r72887 524 524 ASSERT_NOT_REACHED(); 525 525 return NSOffState; 526 } 527 528 static FindOptions coreOptions(WebFindOptions options) 529 { 530 return (options & WebFindOptionsCaseInsensitive ? CaseInsensitive : 0) 531 | (options & WebFindOptionsAtWordStarts ? AtWordStarts : 0) 532 | (options & WebFindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) 533 | (options & WebFindOptionsBackwards ? Backwards : 0) 534 | (options & WebFindOptionsWrapAround ? WrapAround : 0) 535 | (options & WebFindOptionsStartInSelection ? StartInSelection : 0); 526 536 } 527 537 … … 6199 6209 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection 6200 6210 { 6201 if (![string length]) 6202 return NO; 6203 Frame* coreFrame = core([self _frame]); 6204 return coreFrame && coreFrame->editor()->findString(string, forward, caseFlag, wrapFlag, startInSelection); 6211 return [self findString:string options:(forward ? 0 : WebFindOptionsBackwards) | (caseFlag ? 0 : WebFindOptionsCaseInsensitive) | (startInSelection ? WebFindOptionsStartInSelection : 0)]; 6205 6212 } 6206 6213 … … 6222 6229 } 6223 6230 6224 - (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(NSUInteger)limit 6225 { 6226 return [self countMatchesForText:string caseSensitive:caseFlag limit:limit markMatches:YES]; 6227 } 6228 6229 - (NSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(NSUInteger)limit markMatches:(BOOL)markMatches 6231 - (NSUInteger)countMatchesForText:(NSString *)string options:(WebFindOptions)options limit:(NSUInteger)limit markMatches:(BOOL)markMatches 6230 6232 { 6231 6233 Frame* coreFrame = core([self _frame]); 6232 6234 if (!coreFrame) 6233 6235 return 0; 6234 return coreFrame->editor()->countMatchesForText(string, c aseFlag, limit, markMatches);6236 return coreFrame->editor()->countMatchesForText(string, coreOptions(options), limit, markMatches); 6235 6237 } 6236 6238 … … 6277 6279 } 6278 6280 6281 - (BOOL)findString:(NSString *)string options:(WebFindOptions)options 6282 { 6283 if (![string length]) 6284 return NO; 6285 Frame* coreFrame = core([self _frame]); 6286 return coreFrame && coreFrame->editor()->findString(string, coreOptions(options)); 6287 } 6288 6279 6289 @end 6280 6290 -
trunk/WebKit/mac/WebView/WebPDFView.mm
r66544 r72887 627 627 } 628 628 629 - (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(NSUInteger)limit 630 { 631 return [self countMatchesForText:string caseSensitive:caseFlag limit:limit markMatches:YES]; 632 } 633 634 - (NSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag limit:(NSUInteger)limit markMatches:(BOOL)markMatches 629 - (NSUInteger)countMatchesForText:(NSString *)string options:(WebFindOptions)options limit:(NSUInteger)limit markMatches:(BOOL)markMatches 635 630 { 636 631 PDFSelection *previousMatch = nil; 637 PDFSelection *nextMatch = nil;638 632 NSMutableArray *matches = [[NSMutableArray alloc] initWithCapacity:limit]; 639 633 640 634 for (;;) { 641 nextMatch = [self _nextMatchFor:string direction:YES caseSensitive:caseFlagwrap:NO fromSelection:previousMatch startInSelection:NO];635 PDFSelection *nextMatch = [self _nextMatchFor:string direction:YES caseSensitive:!(options & WebFindOptionsCaseInsensitive) wrap:NO fromSelection:previousMatch startInSelection:NO]; 642 636 if (!nextMatch) 643 637 break; -
trunk/WebKit/mac/WebView/WebView.mm
r71903 r72887 2646 2646 } 2647 2647 2648 - (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit 2649 { 2650 return [self countMatchesForText:string options:(caseFlag ? 0 : WebFindOptionsCaseInsensitive) highlight:highlight limit:limit markMatches:YES]; 2651 } 2652 2653 - (NSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit markMatches:(BOOL)markMatches 2654 { 2655 return [self countMatchesForText:string options:(caseFlag ? 0 : WebFindOptionsCaseInsensitive) highlight:highlight limit:limit markMatches:markMatches]; 2656 } 2657 2658 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection 2659 { 2660 return [self findString:string options:((forward ? 0 : WebFindOptionsBackwards) | (caseFlag ? 0 : WebFindOptionsCaseInsensitive) | (wrapFlag ? WebFindOptionsWrapAround : 0) | (startInSelection ? WebFindOptionsStartInSelection : 0))]; 2661 } 2662 2648 2663 @end 2649 2664 … … 3825 3840 } 3826 3841 3827 static WebFrame *incrementFrame(WebFrame *frame, BOOL forward, BOOL wrapFlag)3842 static WebFrame *incrementFrame(WebFrame *frame, WebFindOptions options = 0) 3828 3843 { 3829 3844 Frame* coreFrame = core(frame); 3830 return kit( forward3831 ? coreFrame->tree()->traverse NextWithWrap(wrapFlag)3832 : coreFrame->tree()->traverse PreviousWithWrap(wrapFlag));3845 return kit((options & WebFindOptionsBackwards) 3846 ? coreFrame->tree()->traversePreviousWithWrap(options & WebFindOptionsWrapAround) 3847 : coreFrame->tree()->traverseNextWithWrap(options & WebFindOptionsWrapAround)); 3833 3848 } 3834 3849 … … 4256 4271 } 4257 4272 4258 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection 4273 static BOOL findString(NSView <WebDocumentSearching> *searchView, NSString *string, WebFindOptions options) 4274 { 4275 if ([searchView conformsToProtocol:@protocol(WebDocumentOptionsSearching)]) 4276 return [(NSView <WebDocumentOptionsSearching> *)searchView findString:string options:options]; 4277 if ([searchView conformsToProtocol:@protocol(WebDocumentIncrementalSearching)]) 4278 return [(NSView <WebDocumentIncrementalSearching> *)searchView searchFor:string direction:!(options & WebFindOptionsBackwards) caseSensitive:!(options & WebFindOptionsCaseInsensitive) wrap:!!(options & WebFindOptionsWrapAround) startInSelection:!!(options & WebFindOptionsStartInSelection)]; 4279 return [searchView searchFor:string direction:!(options & WebFindOptionsBackwards) caseSensitive:!(options & WebFindOptionsCaseInsensitive) wrap:!!(options & WebFindOptionsWrapAround)]; 4280 } 4281 4282 - (BOOL)findString:(NSString *)string options:(WebFindOptions)options 4259 4283 { 4260 4284 if (_private->closed) … … 4268 4292 WebFrame *frame = startFrame; 4269 4293 do { 4270 WebFrame *nextFrame = incrementFrame(frame, forward, wrapFlag);4294 WebFrame *nextFrame = incrementFrame(frame, options); 4271 4295 4272 4296 BOOL onlyOneFrame = (frame == nextFrame); … … 4280 4304 startSearchView = searchView; 4281 4305 4282 BOOL foundString;4283 4306 // In some cases we have to search some content twice; see comment later in this method. 4284 // We can avoid ever doing this in the common one-frame case by passing YES for wrapFlag4307 // We can avoid ever doing this in the common one-frame case by passing the wrap option through 4285 4308 // here, and then bailing out before we get to the code that would search again in the 4286 4309 // same content. 4287 BOOL wrapOnThisPass = wrapFlag && onlyOneFrame; 4288 if ([searchView conformsToProtocol:@protocol(WebDocumentIncrementalSearching)]) 4289 foundString = [(NSView <WebDocumentIncrementalSearching> *)searchView searchFor:string direction:forward caseSensitive:caseFlag wrap:wrapOnThisPass startInSelection:startInSelection]; 4290 else 4291 foundString = [searchView searchFor:string direction:forward caseSensitive:caseFlag wrap:wrapOnThisPass]; 4292 4293 if (foundString) { 4310 WebFindOptions optionsForThisPass = onlyOneFrame ? options : (options & ~WebFindOptionsWrapAround); 4311 4312 if (findString(searchView, string, optionsForThisPass)) { 4294 4313 if (frame != startFrame) 4295 4314 [startFrame _clearSelection]; … … 4304 4323 } while (frame && frame != startFrame); 4305 4324 4306 // If there are multiple frames and wrapFlag is trueand we've visited each one without finding a result, we still need to search in the4325 // If there are multiple frames and WebFindOptionsWrapAround is set and we've visited each one without finding a result, we still need to search in the 4307 4326 // first-searched frame up to the selection. However, the API doesn't provide a way to search only up to a particular point. The only 4308 // way to make sure the entire frame is searched is to pass YES for the wrapFlag. When there are no matches, this will search again4327 // way to make sure the entire frame is searched is to pass WebFindOptionsWrapAround. When there are no matches, this will search 4309 4328 // some content that we already searched on the first pass. In the worst case, we could search the entire contents of this frame twice. 4310 4329 // To fix this, we'd need to add a mechanism to specify a range in which to search. 4311 if (wrapFlag && startSearchView) { 4312 BOOL foundString; 4313 if ([startSearchView conformsToProtocol:@protocol(WebDocumentIncrementalSearching)]) 4314 foundString = [(NSView <WebDocumentIncrementalSearching> *)startSearchView searchFor:string direction:forward caseSensitive:caseFlag wrap:YES startInSelection:startInSelection]; 4315 else 4316 foundString = [startSearchView searchFor:string direction:forward caseSensitive:caseFlag wrap:YES]; 4317 if (foundString) { 4330 if ((options & WebFindOptionsWrapAround) && startSearchView) { 4331 if (findString(startSearchView, string, options)) { 4318 4332 [[self window] makeFirstResponder:startSearchView]; 4319 4333 return YES; … … 4497 4511 return NO; 4498 4512 4499 frame = incrementFrame(frame , YES, NO);4513 frame = incrementFrame(frame); 4500 4514 } while (frame); 4501 4515 … … 4503 4517 } 4504 4518 4505 - (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit 4506 { 4507 if (_private->closed) 4508 return 0; 4509 4510 return [self countMatchesForText:string caseSensitive:caseFlag highlight:highlight limit:limit markMatches:YES]; 4511 } 4512 4513 - (NSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit markMatches:(BOOL)markMatches 4519 - (NSUInteger)countMatchesForText:(NSString *)string options:(WebFindOptions)options highlight:(BOOL)highlight limit:(NSUInteger)limit markMatches:(BOOL)markMatches 4514 4520 { 4515 4521 if (_private->closed) … … 4525 4531 4526 4532 ASSERT(limit == 0 || matchCount < limit); 4527 matchCount += [(NSView <WebMultipleTextMatches>*)view countMatchesForText:string caseSensitive:caseFlag limit:limit == 0 ? 0 : limit - matchCountmarkMatches:markMatches];4533 matchCount += [(NSView <WebMultipleTextMatches>*)view countMatchesForText:string options:options limit:(limit == 0 ? 0 : limit - matchCount) markMatches:markMatches]; 4528 4534 4529 4535 // Stop looking if we've reached the limit. A limit of 0 means no limit. … … 4532 4538 } 4533 4539 4534 frame = incrementFrame(frame , YES, NO);4540 frame = incrementFrame(frame); 4535 4541 } while (frame); 4536 4542 … … 4549 4555 [(NSView <WebMultipleTextMatches>*)view unmarkAllTextMatches]; 4550 4556 4551 frame = incrementFrame(frame , YES, NO);4557 frame = incrementFrame(frame); 4552 4558 } while (frame); 4553 4559 } … … 4587 4593 } 4588 4594 4589 frame = incrementFrame(frame , YES, NO);4595 frame = incrementFrame(frame); 4590 4596 } while (frame); 4591 4597 -
trunk/WebKit/mac/WebView/WebViewPrivate.h
r71790 r72887 71 71 72 72 // other WebElementDictionary keys 73 extern NSString *WebElementLinkIsLiveKey; // NSNumber of BOOL indic tating whether the link is live or not73 extern NSString *WebElementLinkIsLiveKey; // NSNumber of BOOL indicating whether the link is live or not 74 74 extern NSString *WebElementIsInScrollBarKey; 75 75 … … 97 97 } WebUserContentInjectedFrames; 98 98 99 enum { 100 WebFindOptionsCaseInsensitive = 1 << 0, 101 WebFindOptionsAtWordStarts = 1 << 1, 102 WebFindOptionsTreatMedialCapitalAsWordStart = 1 << 2, 103 WebFindOptionsBackwards = 1 << 3, 104 WebFindOptionsWrapAround = 1 << 4, 105 WebFindOptionsStartInSelection = 1 << 5 106 }; 107 typedef NSUInteger WebFindOptions; 108 99 109 @interface WebController : NSTreeController { 100 110 IBOutlet WebView *webView; … … 115 125 - (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode; 116 126 117 /*! 118 @method searchFor:direction:caseSensitive:wrap:startInSelection: 119 @abstract Searches a document view for a string and highlights the string if it is found. 120 Starts the search from the current selection. Will search across all frames. 121 @param string The string to search for. 122 @param forward YES to search forward, NO to seach backwards. 123 @param caseFlag YES to for case-sensitive search, NO for case-insensitive search. 124 @param wrapFlag YES to wrap around, NO to avoid wrapping. 125 @param startInSelection YES to begin search in the selected text (useful for incremental searching), NO to begin search after the selected text. 126 @result YES if found, NO if not found. 127 */ 128 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection; 127 - (BOOL)findString:(NSString *)string options:(WebFindOptions)options; 129 128 130 129 - (void)setMainFrameDocumentReady:(BOOL)mainFrameDocumentReady; … … 183 182 // These methods are still in flux; don't rely on them yet. 184 183 - (BOOL)canMarkAllTextMatches; 185 - (WebNSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(WebNSUInteger)limit; 186 - (WebNSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(WebNSUInteger)limit markMatches:(BOOL)markMatches; 184 - (WebNSUInteger)countMatchesForText:(NSString *)string options:(WebFindOptions)options highlight:(BOOL)highlight limit:(WebNSUInteger)limit markMatches:(BOOL)markMatches; 187 185 - (void)unmarkAllTextMatches; 188 186 - (NSArray *)rectsForTextMatches; … … 545 543 - (void)_scaleWebView:(float)scale atOrigin:(NSPoint)origin; 546 544 - (float)_viewScaleFactor; 545 546 // Deprecated. Use the methods in pending public above instead. 547 - (WebNSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(WebNSUInteger)limit; 548 - (WebNSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(WebNSUInteger)limit markMatches:(BOOL)markMatches; 549 550 /*! 551 @method searchFor:direction:caseSensitive:wrap:startInSelection: 552 @abstract Searches a document view for a string and highlights the string if it is found. 553 Starts the search from the current selection. Will search across all frames. 554 @param string The string to search for. 555 @param forward YES to search forward, NO to seach backwards. 556 @param caseFlag YES to for case-sensitive search, NO for case-insensitive search. 557 @param wrapFlag YES to wrap around, NO to avoid wrapping. 558 @param startInSelection YES to begin search in the selected text (useful for incremental searching), NO to begin search after the selected text. 559 @result YES if found, NO if not found. 560 */ 561 // Deprecated. Use findString. 562 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection; 547 563 548 564 @end -
trunk/WebKit2/ChangeLog
r72857 r72887 1 2010-11-29 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 WebKit2 part of <rdar://problem/8650085> adding word-prefix search options to the text search API. 6 https://bugs.webkit.org/show_bug.cgi?id=50038 7 Based on a patch from Darin Adler. 8 9 * Shared/WebFindOptions.h: Renamed FindOptions.h to this to account for WebCore’s new private 10 FindOptions.h. Added and reordered FindOptions and rolled FindDirection into FindOptions. 11 * UIProcess/API/C/WKAPICast.h: Removed toFindDirection(). 12 (WebKit::toFindOptions): Updated for new values. 13 * UIProcess/API/C/WKPage.cpp: 14 (WKPageFindString): Removed separate WKFindDirection. 15 (WKPageCountStringMatches): Replaces caseInsensitive boolean with WKFindOptions. 16 * UIProcess/API/C/WKPage.h: Removed WKFindDirection and updated WKFindOptions. 17 * UIProcess/WebPageProxy.cpp: 18 (WebKit::WebPageProxy::findString): Removed separate FindDirection. 19 (WebKit::WebPageProxy::countStringMatches): Replaced caseInsensitive boolean with FindOptions. 20 * UIProcess/WebPageProxy.h: 21 * WebKit2.xcodeproj/project.pbxproj: Updated for the header rename. 22 * WebProcess/WebPage/FindController.cpp: 23 (WebKit::core): Added. Converts WebKit2 FindOptions to WebCore FindOptions. 24 (WebKit::FindController::countStringMatches): Changed to use FindOptions. 25 (WebKit::FindController::findString): Ditto. 26 * WebProcess/WebPage/FindController.h: 27 * WebProcess/WebPage/WebPage.cpp: 28 (WebKit::WebPage::findString): Ditto. 29 (WebKit::WebPage::countStringMatches): Ditto. 30 * WebProcess/WebPage/WebPage.h: 31 * WebProcess/WebPage/WebPage.messages.in: Ditto. 32 1 33 2010-11-29 Brent Fulgham <bfulgham@webkit.org> 2 34 -
trunk/WebKit2/Shared/WebFindOptions.h
r72886 r72887 24 24 */ 25 25 26 #ifndef FindOptions_h27 #define FindOptions_h26 #ifndef WebFindOptions_h 27 #define WebFindOptions_h 28 28 29 29 namespace WebKit { 30 30 31 enum FindDirection {32 FindDirectionForward,33 FindDirectionBackward34 };35 36 31 enum FindOptions { 37 32 FindOptionsCaseInsensitive = 1 << 0, 38 FindOptionsWrapAround = 1 << 1, 39 FindOptionsShowOverlay = 1 << 2, 40 FindOptionsShowFindIndicator = 1 << 3, 33 FindOptionsAtWordStarts = 1 << 1, 34 FindOptionsTreatMedialCapitalAsWordStart = 1 << 2, 35 FindOptionsBackwards = 1 << 3, 36 FindOptionsWrapAround = 1 << 4, 37 FindOptionsShowOverlay = 1 << 5, 38 FindOptionsShowFindIndicator = 1 << 6 41 39 }; 42 40 43 41 } // namespace WebKit 44 42 45 #endif // FindOptions_h43 #endif // WebFindOptions_h -
trunk/WebKit2/UIProcess/API/C/WKAPICast.h
r72666 r72887 28 28 29 29 #include "CacheModel.h" 30 #include "FindOptions.h"31 30 #include "FontSmoothingLevel.h" 32 31 #include "WKContext.h" … … 34 33 #include "WKPreferencesPrivate.h" 35 34 #include "WKSharedAPICast.h" 35 #include "WebFindOptions.h" 36 36 #include <WebCore/FrameLoaderTypes.h> 37 37 … … 125 125 } 126 126 127 inline FindDirection toFindDirection(WKFindDirection wkFindDirection)128 {129 switch (wkFindDirection) {130 case kWKFindDirectionForward:131 return FindDirectionForward;132 case kWKFindDirectionBackward:133 return FindDirectionBackward;134 }135 136 ASSERT_NOT_REACHED();137 return FindDirectionForward;138 }139 140 127 inline FindOptions toFindOptions(WKFindOptions wkFindOptions) 141 128 { … … 144 131 if (wkFindOptions & kWKFindOptionsCaseInsensitive) 145 132 findOptions |= FindOptionsCaseInsensitive; 133 if (wkFindOptions & kWKFindOptionsAtWordStarts) 134 findOptions |= FindOptionsAtWordStarts; 135 if (wkFindOptions & kWKFindOptionsTreatMedialCapitalAsWordStart) 136 findOptions |= FindOptionsTreatMedialCapitalAsWordStart; 137 if (wkFindOptions & kWKFindOptionsBackwards) 138 findOptions |= FindOptionsBackwards; 146 139 if (wkFindOptions & kWKFindOptionsWrapAround) 147 140 findOptions |= FindOptionsWrapAround; -
trunk/WebKit2/UIProcess/API/C/WKPage.cpp
r72666 r72887 231 231 } 232 232 233 void WKPageFindString(WKPageRef pageRef, WKStringRef string, WKFind Direction findDirection, WKFindOptions findOptions, unsigned maxMatchCount)234 { 235 toImpl(pageRef)->findString(toImpl(string)->string(), toFind Direction(findDirection), toFindOptions(findOptions), maxMatchCount);233 void WKPageFindString(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount) 234 { 235 toImpl(pageRef)->findString(toImpl(string)->string(), toFindOptions(options), maxMatchCount); 236 236 } 237 237 … … 241 241 } 242 242 243 void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, bool caseInsensitive, unsigned maxMatchCount)244 { 245 toImpl(pageRef)->countStringMatches(toImpl(string)->string(), caseInsensitive, maxMatchCount);243 void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount) 244 { 245 toImpl(pageRef)->countStringMatches(toImpl(string)->string(), toFindOptions(options), maxMatchCount); 246 246 } 247 247 -
trunk/WebKit2/UIProcess/API/C/WKPage.h
r72707 r72887 275 275 // Find. 276 276 enum { 277 kWKFindDirectionForward,278 kWKFindDirectionBackward279 };280 typedef uint32_t WKFindDirection;281 282 enum {283 277 kWKFindOptionsCaseInsensitive = 1 << 0, 284 kWKFindOptionsWrapAround = 1 << 1, 285 kWKFindOptionsShowOverlay = 1 << 2, 286 kWKFindOptionsShowFindIndicator = 1 << 3 278 kWKFindOptionsAtWordStarts = 1 << 1, 279 kWKFindOptionsTreatMedialCapitalAsWordStart = 1 << 2, 280 kWKFindOptionsBackwards = 1 << 3, 281 kWKFindOptionsWrapAround = 1 << 4, 282 kWKFindOptionsShowOverlay = 1 << 5, 283 kWKFindOptionsShowFindIndicator = 1 << 6 287 284 }; 288 285 typedef uint32_t WKFindOptions; 289 286 290 WK_EXPORT void WKPageFindString(WKPageRef page, WKStringRef string, WKFind Direction findDirection, WKFindOptions findOptions, unsigned maxMatchCount);287 WK_EXPORT void WKPageFindString(WKPageRef page, WKStringRef string, WKFindOptions findOptions, unsigned maxMatchCount); 291 288 WK_EXPORT void WKPageHideFindUI(WKPageRef page); 292 WK_EXPORT void WKPageCountStringMatches(WKPageRef page, WKStringRef string, bool caseInsensitive, unsigned maxMatchCount);289 WK_EXPORT void WKPageCountStringMatches(WKPageRef page, WKStringRef string, WKFindOptions findOptions, unsigned maxMatchCount); 293 290 294 291 WK_EXPORT void WKPageSetPageContextMenuClient(WKPageRef page, const WKPageContextMenuClient* client); -
trunk/WebKit2/UIProcess/WebPageProxy.cpp
r72707 r72887 608 608 } 609 609 610 void WebPageProxy::findString(const String& string, Find Direction findDirection, FindOptions findOptions, unsigned maxMatchCount)611 { 612 process()->send(Messages::WebPage::FindString(string, findDirection, findOptions, maxMatchCount), m_pageID);610 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount) 611 { 612 process()->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID); 613 613 } 614 614 … … 618 618 } 619 619 620 void WebPageProxy::countStringMatches(const String& string, bool caseInsensitive, unsigned maxMatchCount)621 { 622 process()->send(Messages::WebPage::CountStringMatches(string, caseInsensitive, maxMatchCount), m_pageID);620 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) 621 { 622 process()->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID); 623 623 } 624 624 -
trunk/WebKit2/UIProcess/WebPageProxy.h
r72666 r72887 29 29 #include "APIObject.h" 30 30 #include "DrawingAreaProxy.h" 31 #include "FindOptions.h"32 31 #include "GenericCallback.h" 33 32 #include "SharedMemory.h" … … 37 36 #include "WebEvent.h" 38 37 #include "WebFindClient.h" 38 #include "WebFindOptions.h" 39 39 #include "WebFormClient.h" 40 40 #include "WebFrameProxy.h" … … 209 209 210 210 // Find. 211 void findString(const String&, Find Direction, FindOptions, unsigned maxMatchCount);211 void findString(const String&, FindOptions, unsigned maxMatchCount); 212 212 void hideFindUI(); 213 void countStringMatches(const String&, bool caseInsensitive, unsigned maxMatchCount);213 void countStringMatches(const String&, FindOptions, unsigned maxMatchCount); 214 214 215 215 void runJavaScriptInMainFrame(const String&, PassRefPtr<ScriptReturnValueCallback>); -
trunk/WebKit2/WebKit2.pro
r72792 r72887 246 246 Shared/WebEvent.h \ 247 247 Shared/WebEventConversion.h \ 248 Shared/WebFindOptions.h \ 248 249 Shared/WebNavigationDataStore.h \ 249 250 Shared/WebNumber.h \ -
trunk/WebKit2/WebKit2.xcodeproj/project.pbxproj
r72422 r72887 141 141 1A8EFDFA1253CAA200F7067F /* DataReference.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8EFDF91253CAA200F7067F /* DataReference.h */; }; 142 142 1A8EFDFE1253CB6E00F7067F /* DataReference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8EFDFD1253CB6E00F7067F /* DataReference.cpp */; }; 143 1A90C1EE1264FD50003E44D4 /* FindOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A90C1ED1264FD50003E44D4 /*FindOptions.h */; };143 1A90C1EE1264FD50003E44D4 /* WebFindOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A90C1ED1264FD50003E44D4 /* WebFindOptions.h */; }; 144 144 1A90C1F41264FD71003E44D4 /* FindController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A90C1F21264FD71003E44D4 /* FindController.h */; }; 145 145 1A90C1F51264FD71003E44D4 /* FindController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A90C1F31264FD71003E44D4 /* FindController.cpp */; }; … … 701 701 1A8EFDF91253CAA200F7067F /* DataReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataReference.h; sourceTree = "<group>"; }; 702 702 1A8EFDFD1253CB6E00F7067F /* DataReference.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataReference.cpp; sourceTree = "<group>"; }; 703 1A90C1ED1264FD50003E44D4 /* FindOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =FindOptions.h; sourceTree = "<group>"; };703 1A90C1ED1264FD50003E44D4 /* WebFindOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFindOptions.h; sourceTree = "<group>"; }; 704 704 1A90C1F21264FD71003E44D4 /* FindController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindController.h; sourceTree = "<group>"; }; 705 705 1A90C1F31264FD71003E44D4 /* FindController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FindController.cpp; sourceTree = "<group>"; }; … … 1386 1386 1A6F9F8E11E13EFC00DB1371 /* CommandLine.h */, 1387 1387 0FB659221208B4DB0044816C /* DrawingAreaBase.h */, 1388 1A90C1ED1264FD50003E44D4 /* FindOptions.h */,1389 1388 762B7481120BBA0100819339 /* FontSmoothingLevel.h */, 1390 1389 BC64696D11DBE603006455B0 /* ImmutableArray.cpp */, … … 1418 1417 BC032DB010F4380F0058C15A /* WebEventConversion.cpp */, 1419 1418 BC032DB110F4380F0058C15A /* WebEventConversion.h */, 1419 1A90C1ED1264FD50003E44D4 /* WebFindOptions.h */, 1420 1420 C0337DD2127A2A0E008FF4F4 /* WebKeyboardEvent.cpp */, 1421 1421 C0337DAF127A28D0008FF4F4 /* WebMouseEvent.cpp */, … … 2379 2379 BC57450C1263B155006F0F12 /* WKBundleNodeHandlePrivate.h in Headers */, 2380 2380 1AC41AC71263C88300054E94 /* BinarySemaphore.h in Headers */, 2381 1A90C1EE1264FD50003E44D4 /* FindOptions.h in Headers */,2381 1A90C1EE1264FD50003E44D4 /* WebFindOptions.h in Headers */, 2382 2382 1A90C1F41264FD71003E44D4 /* FindController.h in Headers */, 2383 2383 1A90C23712650717003E44D4 /* PageOverlay.h in Headers */, -
trunk/WebKit2/WebProcess/WebPage/FindController.cpp
r71935 r72887 41 41 namespace WebKit { 42 42 43 static WebCore::FindOptions core(FindOptions options) 44 { 45 return (options & FindOptionsCaseInsensitive ? CaseInsensitive : 0) 46 | (options & FindOptionsAtWordStarts ? AtWordStarts : 0) 47 | (options & FindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) 48 | (options & FindOptionsBackwards ? Backwards : 0) 49 | (options & FindOptionsWrapAround ? WrapAround : 0); 50 } 51 43 52 FindController::FindController(WebPage* webPage) 44 53 : m_webPage(webPage) … … 52 61 } 53 62 54 void FindController::countStringMatches(const String& string, bool caseInsensitive, unsigned maxMatchCount)55 { 56 unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, c aseInsensitive ? TextCaseInsensitive : TextCaseSensitive, false, maxMatchCount);63 void FindController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) 64 { 65 unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount); 57 66 m_webPage->corePage()->unmarkAllTextMatches(); 58 67 … … 70 79 } 71 80 72 void FindController::findString(const String& string, Find Direction findDirection, FindOptions findOptions, unsigned maxMatchCount)81 void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount) 73 82 { 74 83 m_webPage->corePage()->unmarkAllTextMatches(); 75 84 76 TextCaseSensitivity caseSensitivity = findOptions & FindOptionsCaseInsensitive ? TextCaseInsensitive : TextCaseSensitive; 77 bool found = m_webPage->corePage()->findString(string, caseSensitivity, 78 findDirection == FindDirectionForward ? WebCore::FindDirectionForward : WebCore::FindDirectionBackward, 79 findOptions & FindOptionsWrapAround); 85 bool found = m_webPage->corePage()->findString(string, core(options)); 80 86 81 87 Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); … … 92 98 m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string)); 93 99 } else { 94 shouldShowOverlay = findOptions & FindOptionsShowOverlay;100 shouldShowOverlay = options & FindOptionsShowOverlay; 95 101 96 102 if (shouldShowOverlay) { 97 unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, c aseSensitivity, false, maxMatchCount + 1);103 unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1); 98 104 99 105 // Check if we have more matches than allowed. … … 106 112 } 107 113 108 if (!( findOptions & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) {114 if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) { 109 115 // Either we shouldn't show the find indicator, or we couldn't update it. 110 116 hideFindIndicator(); -
trunk/WebKit2/WebProcess/WebPage/FindController.h
r71685 r72887 27 27 #define FindController_h 28 28 29 #include "FindOptions.h"30 29 #include "PageOverlay.h" 30 #include "WebFindOptions.h" 31 31 #include <wtf/Forward.h> 32 32 #include <wtf/Noncopyable.h> … … 49 49 virtual ~FindController(); 50 50 51 void findString(const String&, Find Direction, FindOptions, unsigned maxMatchCount);51 void findString(const String&, FindOptions, unsigned maxMatchCount); 52 52 void hideFindUI(); 53 void countStringMatches(const String&, bool caseInsensitive, unsigned maxMatchCount);53 void countStringMatches(const String&, FindOptions, unsigned maxMatchCount); 54 54 55 55 void hideFindIndicator(); -
trunk/WebKit2/WebProcess/WebPage/WebPage.cpp
r72666 r72887 999 999 } 1000 1000 1001 void WebPage::findString(const String& string, uint32_t findDirection, uint32_t findOptions, uint32_t maxMatchCount)1002 { 1003 m_findController.findString(string, static_cast<Find Direction>(findDirection), static_cast<FindOptions>(findOptions), maxMatchCount);1001 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount) 1002 { 1003 m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount); 1004 1004 } 1005 1005 … … 1009 1009 } 1010 1010 1011 void WebPage::countStringMatches(const String& string, bool caseInsensitive, uint32_t maxMatchCount)1012 { 1013 m_findController.countStringMatches(string, caseInsensitive, maxMatchCount);1011 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount) 1012 { 1013 m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount); 1014 1014 } 1015 1015 -
trunk/WebKit2/WebProcess/WebPage/WebPage.h
r72666 r72887 291 291 void didRemoveEditCommand(uint64_t commandID); 292 292 293 void findString(const String&, uint32_t find Direction, uint32_t findOptions, uint32_t maxMatchCount);293 void findString(const String&, uint32_t findOptions, uint32_t maxMatchCount); 294 294 void hideFindUI(); 295 void countStringMatches(const String&, bool caseInsensitive, uint32_t maxMatchCount);295 void countStringMatches(const String&, uint32_t findOptions, uint32_t maxMatchCount); 296 296 297 297 #if PLATFORM(QT) -
trunk/WebKit2/WebProcess/WebPage/WebPage.messages.in
r72438 r72887 79 79 80 80 # Find. 81 FindString(WTF::String string, uint32_t find Direction, uint32_t findOptions, unsigned maxMatchCount)81 FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) 82 82 HideFindUI() 83 CountStringMatches(WTF::String string, bool caseInsensitive, unsigned maxMatchCount)83 CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) 84 84 85 85 # Popup menu. -
trunk/WebKit2/win/WebKit2.vcproj
r72857 r72887 553 553 </File> 554 554 <File 555 RelativePath="..\Shared\WebFindOptions.h" 556 > 557 </File> 558 <File 555 559 RelativePath="..\Shared\WebKeyboardEvent.cpp" 556 560 > -
trunk/WebKitTools/ChangeLog
r72868 r72887 1 2010-11-29 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 DumpRenderTree changes for testing the text search API. 6 https://bugs.webkit.org/show_bug.cgi?id=50038 7 8 * DumpRenderTree/LayoutTestController.cpp: 9 (findStringCallback): 10 (LayoutTestController::staticFunctions): 11 * DumpRenderTree/LayoutTestController.h: 12 * DumpRenderTree/mac/LayoutTestControllerMac.mm: 13 (LayoutTestController::findString): 14 * MiniBrowser/mac/BrowserWindowController.m: 15 (-[BrowserWindowController find:]): 16 1 17 2010-11-29 Johnny Ding <jnd@chromium.org> 2 18 -
trunk/WebKitTools/DumpRenderTree/LayoutTestController.cpp
r72591 r72887 443 443 } 444 444 445 static JSValueRef findStringCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 446 { 447 // Has Mac implementation. 448 if (argumentCount < 2) 449 return JSValueMakeUndefined(context); 450 451 JSRetainPtr<JSStringRef> target(Adopt, JSValueToStringCopy(context, arguments[0], exception)); 452 ASSERT(!*exception); 453 454 JSObjectRef options = JSValueToObject(context, arguments[1], exception); 455 ASSERT(!*exception); 456 457 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); 458 return JSValueMakeBoolean(context, controller->findString(context, target.get(), options)); 459 } 460 445 461 static JSValueRef counterValueForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 446 462 { … … 1917 1933 { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1918 1934 { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1935 { "findString", findStringCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1919 1936 { "counterValueForElementById", counterValueForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1920 1937 { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, -
trunk/WebKitTools/DumpRenderTree/LayoutTestController.h
r72591 r72887 53 53 JSStringRef copyDecodedHostName(JSStringRef name); 54 54 JSStringRef copyEncodedHostName(JSStringRef name); 55 JSRetainPtr<JSStringRef> counterValueForElementById(JSStringRef id); 55 56 void disableImageLoading(); 56 57 void dispatchPendingLoadRequests(); 57 58 void display(); 58 59 void execCommand(JSStringRef name, JSStringRef value); 59 JSRetainPtr<JSStringRef> counterValueForElementById(JSStringRef id);60 bool findString(JSContextRef, JSStringRef, JSObjectRef optionsArray); 60 61 bool isCommandEnabled(JSStringRef name); 61 62 void keepWebHistory(); -
trunk/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
r72591 r72887 584 584 } 585 585 586 bool LayoutTestController::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray) 587 { 588 WebFindOptions options = 0; 589 590 JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); 591 JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); 592 if (!JSValueIsNumber(context, lengthValue)) 593 return false; 594 595 RetainPtr<CFStringRef> targetCFString(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, target)); 596 597 size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); 598 for (size_t i = 0; i < length; ++i) { 599 JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); 600 if (!JSValueIsString(context, value)) 601 continue; 602 603 JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0)); 604 605 if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive")) 606 options |= WebFindOptionsCaseInsensitive; 607 else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts")) 608 options |= WebFindOptionsAtWordStarts; 609 else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart")) 610 options |= WebFindOptionsTreatMedialCapitalAsWordStart; 611 else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards")) 612 options |= WebFindOptionsBackwards; 613 else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround")) 614 options |= WebFindOptionsWrapAround; 615 else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) 616 options |= WebFindOptionsStartInSelection; 617 } 618 619 return [[mainFrame webView] findString:(NSString *)targetCFString.get() options:options]; 620 } 621 586 622 void LayoutTestController::setCacheModel(int cacheModel) 587 623 { -
trunk/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
r70790 r72887 691 691 WKStringRef string = WKStringCreateWithCFString((CFStringRef)[sender stringValue]); 692 692 693 WKPageFindString(_webView.pageRef, string, kWKFindDirectionForward, 694 kWKFindOptionsCaseInsensitive | kWKFindOptionsWrapAround | kWKFindOptionsShowFindIndicator | kWKFindOptionsShowOverlay, 100); 693 WKPageFindString(_webView.pageRef, string, kWKFindOptionsCaseInsensitive | kWKFindOptionsWrapAround | kWKFindOptionsShowFindIndicator | kWKFindOptionsShowOverlay, 100); 695 694 } 696 695
Note: See TracChangeset
for help on using the changeset viewer.