Changeset 72887 in webkit


Ignore:
Timestamp:
Nov 29, 2010 10:39:39 PM (13 years ago)
Author:
mitz@apple.com
Message:

JavaScriptCore: WTF support for <rdar://problem/8650085> adding word-prefix search options to the text search API.
https://bugs.webkit.org/show_bug.cgi?id=50038

Reviewed by Darin Adler.

  • wtf/unicode/UnicodeMacrosFromICU.h: Copied additional macros from icu/unicode/utf16.h.

WebCore: WebCore part of <rdar://problem/8650085> adding word-prefix search options to the text search API.
https://bugs.webkit.org/show_bug.cgi?id=50038

Reviewed by Darin Adler.

Test: editing/text-iterator/findString.html

  • GNUmakefile.am: Added FindOptions.h.
  • WebCore.exp.in: Export the new methods that take FindOptions.
  • WebCore.gypi: Added FindOptions.h.
  • WebCore.pro: Added FindOptions.h and TextBoundaries.{cpp,h}.
  • WebCore.vcproj/WebCore.vcproj: Added FindOptions.h.
  • WebCore.xcodeproj/project.pbxproj: Added FindOptions.h and TextBoundaries.cpp.
  • editing/Editor.cpp:

(WebCore::Editor::firstVisibleRange): Changed to use FindOptions.
(WebCore::Editor::lastVisibleRange): Ditto.
(WebCore::Editor::nextVisibleRange): Ditto.
(WebCore::Editor::findString): Ditto.
(WebCore::Editor::countMatchesForText): Ditto.

  • editing/Editor.h: Added a version of findString() that takes FindOptions. Changed

countMatchesForText() to take FindOptions. Made nextVisibleRange() private and changed it
and firstVisibleRange() and lastVisibleRange() to take FindOptions.

  • editing/FindOptions.h: Added.
  • editing/TextIterator.cpp:

Augmented SearchBuffer with an optional prefix, which is not searched, but provides context
for determining word boundaries.
(WebCore::isSeparator): Added. Identifies a class of characters used to determine where
“words” are embedded in a word.
(WebCore::SearchBuffer::SearchBuffer): Changed to take FindOptions. Added initialization of
m_options, m_prefixLength and m_needsMoreContext.
(WebCore::SearchBuffer::append): Adjust m_prefixLength as part of the prefix gets pushed out
of the buffer.
(WebCore::SearchBuffer::needsMoreContext): Added.
(WebCore::SearchBuffer::prependContext): Added.
(WebCore::SearchBuffer::isWordStartMatch): Added.
(WebCore::SearchBuffer::search): Changed to account for the context prefix. When searching
only for word prefix matches, maintains enough context before a tentative match when moving
it to the beginning of the buffer. Reject matches that are not at word starts if requested.
Adjust m_prefixLength when pushing characters out of the buffer.
(WebCore::findPlainText): Changed to work with FindOptions. Feed the search buffer with context
if and as long as it requires more of it.

  • editing/TextIterator.h: Added a version of findPlainText() that takes FindOptions.
  • editing/visible_units.cpp: Moved {end,start}Of{First,Last}WordBoundary to TextBoundaries.cpp.
  • page/Page.cpp:

(WebCore::Page::findString): Changed to work with FindOptions.
(WebCore::Page::markAllMatchesForText): Ditto.

  • page/Page.h: Added FindOptions-based findString() and markAllMatchesForText().
  • platform/text/TextBoundaries.cpp:

(WebCore::endOfFirstWordBoundaryContext): Moved here from visible_units.cpp.
(WebCore::startOfLastWordBoundaryContext): Ditto.

  • platform/text/TextBoundaries.h:

WebKit/mac: WebKit Mac part of <rdar://problem/8650085> adding word-prefix search options to the text search API.
https://bugs.webkit.org/show_bug.cgi?id=50038
Based on a patch from Darin Adler.

Reviewed by Darin Adler.

  • WebView/WebDocumentInternal.h: Removed -markAllMatchesForText:caseSensitive:limit: and

replaced -countMatchesForText:caseSensitive:limit:markMatches: with a WebFindOptions-based
method. Declared a WebDocumentOptionsSearching protocol with a new -findString:options:
method. Made WebHTMLView conform to the new protocol.

  • WebView/WebHTMLView.mm:

(coreOptions): Added. Converts WebFindOptions to WebCore FindOptions.
(-[WebHTMLView searchFor:direction:caseSensitive:wrap:startInSelection:]): Changed to use
-findString:options:.
(-[WebHTMLView countMatchesForText:options:limit:markMatches:]): Changed to use WebFindOptions.
(-[WebHTMLView findString:options:]): Added. Calls through to WebCore::Editor::findString().

  • WebView/WebPDFView.mm:

(-[WebPDFView countMatchesForText:options:limit:markMatches:]): Changed to use WebFindOptions.

  • WebView/WebView.mm:

(-[WebView markAllMatchesForText:caseSensitive:highlight:limit:]): Now calls through to
-countMatchesForText:options:highlight:limit:markMatches.
(-[WebView countMatchesForText:caseSensitive:highlight:limit:markMatches:]): Ditto.
(-[WebView searchFor:direction:caseSensitive:wrap:startInSelection:]): Now calls through to
-findString:options:.
(incrementFrame): Changed to use WebFindOptions.
(findString): Added this helper method that performs the search using the best supported
method for the document view.
(-[WebView findString:options:]): Changed -searchFor::::: into this.
(-[WebView canMarkAllTextMatches]):
(-[WebView countMatchesForText:options:highlight:limit:markMatches:]): Updated to use
WebFindOptions.
(-[WebView unmarkAllTextMatches]): Updated for change to incrementFrame.
(-[WebView rectsForTextMatches]): Ditto.

  • WebView/WebViewPrivate.h: Added WebFindOptions, -findString:options:, and WebFindOptions version

of countMatchesForText:.

WebKit2: WebKit2 part of <rdar://problem/8650085> adding word-prefix search options to the text search API.
https://bugs.webkit.org/show_bug.cgi?id=50038
Based on a patch from Darin Adler.

Reviewed by Darin Adler.

  • Shared/WebFindOptions.h: Renamed FindOptions.h to this to account for WebCore’s new private

FindOptions.h. Added and reordered FindOptions and rolled FindDirection into FindOptions.

  • UIProcess/API/C/WKAPICast.h: Removed toFindDirection().

(WebKit::toFindOptions): Updated for new values.

  • UIProcess/API/C/WKPage.cpp:

(WKPageFindString): Removed separate WKFindDirection.
(WKPageCountStringMatches): Replaces caseInsensitive boolean with WKFindOptions.

  • UIProcess/API/C/WKPage.h: Removed WKFindDirection and updated WKFindOptions.
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::findString): Removed separate FindDirection.
(WebKit::WebPageProxy::countStringMatches): Replaced caseInsensitive boolean with FindOptions.

  • UIProcess/WebPageProxy.h:
  • WebKit2.xcodeproj/project.pbxproj: Updated for the header rename.
  • WebProcess/WebPage/FindController.cpp:

(WebKit::core): Added. Converts WebKit2 FindOptions to WebCore FindOptions.
(WebKit::FindController::countStringMatches): Changed to use FindOptions.
(WebKit::FindController::findString): Ditto.

  • WebProcess/WebPage/FindController.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::findString): Ditto.
(WebKit::WebPage::countStringMatches): Ditto.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in: Ditto.

WebKitTools: DumpRenderTree changes for testing the text search API.
https://bugs.webkit.org/show_bug.cgi?id=50038

Reviewed by Darin Adler.

  • DumpRenderTree/LayoutTestController.cpp:

(findStringCallback):
(LayoutTestController::staticFunctions):

  • DumpRenderTree/LayoutTestController.h:
  • DumpRenderTree/mac/LayoutTestControllerMac.mm:

(LayoutTestController::findString):

  • MiniBrowser/mac/BrowserWindowController.m:

(-[BrowserWindowController find:]):

LayoutTests: Added text search tests, in particular testing word-prefix search.
https://bugs.webkit.org/show_bug.cgi?id=50038

Reviewed by Darin Adler.

  • editing/text-iterator/findString-expected.txt: Added.
  • editing/text-iterator/findString.html: Added.
Location:
trunk
Files:
3 added
44 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r72885 r72887  
     12010-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
    1102010-11-29  Steve Falkenburg  <sfalken@apple.com>
    211
  • trunk/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h

    r67475 r72887  
    11/*
     2 *  Copyright (C) 1999-2004, International Business Machines Corporation and others.  All Rights Reserved.
    23 *  Copyright (C) 2006 George Staikos <staikos@kde.org>
    34 *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
     
    4445#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
    4546
     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
    4663#define U16_PREV(s, start, i, c) { \
    4764    (c)=(s)[--(i)]; \
     
    5269            (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
    5370        } \
     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); \
    5477    } \
    5578}
     
    6689}
    6790
     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
    6897#define U_MASK(x) ((uint32_t)1<<(x))
    6998
    7099#endif
    71 
  • trunk/LayoutTests/ChangeLog

    r72886 r72887  
     12010-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
    1112010-11-29  Ojan Vafai  <ojan@chromium.org>
    212
  • trunk/WebCore/ChangeLog

    r72884 r72887  
     12010-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
    1552010-11-29  Dai Mikurube  <dmikurube@google.com>
    256
  • trunk/WebCore/GNUmakefile.am

    r72834 r72887  
    13331333        WebCore/editing/Editor.h \
    13341334        WebCore/editing/EditorInsertAction.h \
     1335        WebCore/editing/FindOptions.h \
    13351336        WebCore/editing/FormatBlockCommand.cpp \
    13361337        WebCore/editing/FormatBlockCommand.h \
  • trunk/WebCore/WebCore.exp.in

    r72777 r72887  
    600600__ZN7WebCore4Node18startIgnoringLeaksEv
    601601__ZN7WebCore4Node19setNeedsStyleRecalcENS_15StyleChangeTypeE
    602 __ZN7WebCore4Page10findStringERKN3WTF6StringENS1_19TextCaseSensitivityENS_13FindDirectionEb
     602__ZN7WebCore4Page10findStringERKN3WTF6StringEj
    603603__ZN7WebCore4Page11PageClientsC1Ev
    604604__ZN7WebCore4Page11PageClientsD1Ev
     
    615615__ZN7WebCore4Page19visitedStateChangedEPNS_9PageGroupEy
    616616__ZN7WebCore4Page20unmarkAllTextMatchesEv
    617 __ZN7WebCore4Page21markAllMatchesForTextERKN3WTF6StringENS1_19TextCaseSensitivityEbj
     617__ZN7WebCore4Page21markAllMatchesForTextERKN3WTF6StringEjbj
    618618__ZN7WebCore4Page22allVisitedStateChangedEPNS_9PageGroupE
    619619__ZN7WebCore4Page23clearUndoRedoOperationsEv
     
    662662__ZN7WebCore6CursoraSERKS0_
    663663__ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
    664 __ZN7WebCore6Editor10findStringERKN3WTF6StringEbbbb
     664__ZN7WebCore6Editor10findStringERKN3WTF6StringEj
    665665__ZN7WebCore6Editor10insertTextERKN3WTF6StringEPNS_5EventE
    666666__ZN7WebCore6Editor13canDHTMLPasteEv
     
    674674__ZN7WebCore6Editor18confirmCompositionERKN3WTF6StringE
    675675__ZN7WebCore6Editor18confirmCompositionEv
    676 __ZN7WebCore6Editor19countMatchesForTextERKN3WTF6StringEbjb
     676__ZN7WebCore6Editor19countMatchesForTextERKN3WTF6StringEjjb
    677677__ZN7WebCore6Editor19deleteWithDirectionENS_19SelectionController10EDirectionENS_15TextGranularityEbb
    678678__ZN7WebCore6Editor19insertUnorderedListEv
  • trunk/WebCore/WebCore.gypi

    r72777 r72887  
    14001400            'editing/EditorDeleteAction.h',
    14011401            'editing/EditorInsertAction.h',
     1402            'editing/FindOptions.h',
    14021403            'editing/FormatBlockCommand.cpp',
    14031404            'editing/FormatBlockCommand.h',
  • trunk/WebCore/WebCore.pro

    r72777 r72887  
    12321232    platform/SharedBuffer.cpp \
    12331233    platform/text/String.cpp \
     1234    platform/text/TextBoundaries.cpp \
    12341235    platform/text/TextCodec.cpp \
    12351236    platform/text/TextCodecLatin1.cpp \
     
    17131714    editing/EditingBoundary.h \
    17141715    editing/Editor.h \
     1716    editing/FindOptions.h \
    17151717    editing/FormatBlockCommand.h \
    17161718    editing/htmlediting.h \
     
    21782180    platform/text/RegularExpression.h \
    21792181    platform/text/SegmentedString.h \
     2182    platform/text/TextBoundaries.h \
    21802183    platform/text/TextCodec.h \
    21812184    platform/text/TextCodecLatin1.h \
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r72795 r72887  
    4658446584                        </File>
    4658546585                        <File
     46586                                RelativePath="..\editing\FindOptions.h"
     46587                                >
     46588                        </File>
     46589                        <File
    4658646590                                RelativePath="..\editing\FormatBlockCommand.cpp"
    4658746591                                >
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r72777 r72887  
    872872                371F53EA0D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 371F53E80D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp */; };
    873873                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, ); }; };
    874876                3744570F0DB05FA500AE0992 /* SVGGlyphMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 3744570E0DB05FA500AE0992 /* SVGGlyphMap.h */; };
    875877                375CD232119D43C800A2A859 /* Hyphenation.h in Headers */ = {isa = PBXBuildFile; fileRef = 375CD231119D43C800A2A859 /* Hyphenation.h */; };
     
    69796981                371F53E80D2704F900ECE0D5 /* CSSUnicodeRangeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSUnicodeRangeValue.cpp; sourceTree = "<group>"; };
    69806982                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>"; };
    69816985                3744570E0DB05FA500AE0992 /* SVGGlyphMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGGlyphMap.h; sourceTree = "<group>"; };
    69826986                375CD231119D43C800A2A859 /* Hyphenation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hyphenation.h; sourceTree = "<group>"; };
     
    1461114615                                4BAE95B00B2FA9CE00AED8A0 /* EditorDeleteAction.h */,
    1461214616                                93FDAFC90B11307400E2746F /* EditorInsertAction.h */,
     14617                                372C00D8129619F8005C9575 /* FindOptions.h */,
    1461314618                                D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */,
    1461414619                                D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */,
     
    1685016855                                B2C3DA000D006C1D00EF6F26 /* String.cpp */,
    1685116856                                97C0784F1165D5BE003A32EF /* SuffixTree.h */,
     16857                                372C00C3129611F1005C9575 /* TextBoundaries.cpp */,
    1685216858                                B2C3DA040D006C1D00EF6F26 /* TextBoundaries.h */,
    1685316859                                B2C3DA060D006C1D00EF6F26 /* TextBreakIterator.h */,
     
    1969119697                                845E72F80FD261EE00A87D79 /* Filter.h in Headers */,
    1969219698                                08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */,
     19699                                372C00D9129619F8005C9575 /* FindOptions.h in Headers */,
    1969319700                                A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */,
    1969419701                                89878566122CA064003AABDA /* Flags.h in Headers */,
     
    2378823795                                498770EE1242C535002226BA /* TexShader.cpp in Sources */,
    2378923796                                6550B6A5099DF0270090D781 /* Text.cpp in Sources */,
     23797                                372C00C4129611F1005C9575 /* TextBoundaries.cpp in Sources */,
    2379023798                                B2AFFC970D00A5DF0030074D /* TextBoundaries.mm in Sources */,
    2379123799                                B2C3DA370D006C1D00EF6F26 /* TextBreakIteratorICU.cpp in Sources */,
  • trunk/WebCore/editing/Editor.cpp

    r72573 r72887  
    28352835}
    28362836
    2837 PassRefPtr<Range> Editor::firstVisibleRange(const String& target, bool caseFlag)
     2837PassRefPtr<Range> Editor::firstVisibleRange(const String& target, FindOptions options)
    28382838{
    28392839    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);
    28412841    ExceptionCode ec = 0;
    28422842
     
    28452845        if (searchRange->startContainer() == searchRange->endContainer())
    28462846            return Range::create(m_frame->document());
    2847         resultRange = findPlainText(searchRange.get(), target, true, caseFlag);
     2847        resultRange = findPlainText(searchRange.get(), target, options & ~Backwards);
    28482848    }
    28492849   
     
    28512851}
    28522852
    2853 PassRefPtr<Range> Editor::lastVisibleRange(const String& target, bool caseFlag)
     2853PassRefPtr<Range> Editor::lastVisibleRange(const String& target, FindOptions options)
    28542854{
    28552855    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);
    28572857    ExceptionCode ec = 0;
    28582858
     
    28612861        if (searchRange->startContainer() == searchRange->endContainer())
    28622862            return Range::create(m_frame->document());
    2863         resultRange = findPlainText(searchRange.get(), target, false, caseFlag);
     2863        resultRange = findPlainText(searchRange.get(), target, options | Backwards);
    28642864    }
    28652865   
     
    28672867}
    28682868
    2869 PassRefPtr<Range> Editor::nextVisibleRange(Range* currentRange, const String& target, bool forward, bool caseFlag, bool wrapFlag)
     2869PassRefPtr<Range> Editor::nextVisibleRange(Range* currentRange, const String& target, FindOptions options)
    28702870{
    28712871    if (m_frame->excludeFromTextSearch())
     
    28752875    RefPtr<Range> searchRange(rangeOfContents(m_frame->document()));
    28762876    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)) {
    28792879        if (resultRange->collapsed(ec)) {
    28802880            if (!resultRange->startContainer()->isInShadowTree())
     
    29082908        return resultRange;
    29092909   
    2910     if (!wrapFlag)
     2910    if (!(options & WrapAround))
    29112911        return Range::create(m_frame->document());
    29122912
    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);
    29172917}
    29182918
     
    31863186bool Editor::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
    31873187{
     3188    FindOptions options = (forward ? 0 : Backwards) | (caseFlag ? 0 : CaseInsensitive) | (wrapFlag ? WrapAround : 0) | (startInSelection ? StartInSelection : 0);
     3189    return findString(target, options);
     3190}
     3191
     3192bool Editor::findString(const String& target, FindOptions options)
     3193{
    31883194    if (target.isEmpty())
    31893195        return false;
     
    31973203    VisibleSelection selection = m_frame->selection()->selection();
    31983204
     3205    bool forward = !(options & Backwards);
     3206    bool startInSelection = options & StartInSelection;
    31993207    if (forward)
    32003208        setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
     
    32113219    }
    32123220
    3213     RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
     3221    RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options));
    32143222    // If we started in the selection and the found range exactly matches the existing selection, find again.
    32153223    // Build a selection with the found range to remove collapsed whitespace.
     
    32303238        }
    32313239
    3232         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
     3240        resultRange = findPlainText(searchRange.get(), target, options);
    32333241    }
    32343242
     
    32433251            searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
    32443252
    3245         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
     3253        resultRange = findPlainText(searchRange.get(), target, options);
    32463254    }
    32473255
    32483256    if (!insideVisibleArea(resultRange.get())) {
    3249         resultRange = nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
     3257        resultRange = nextVisibleRange(resultRange.get(), target, options);
    32503258        if (!resultRange)
    32513259            return false;
     
    32543262    // If we didn't find anything and we're wrapping, search again in the entire document (this will
    32553263    // redundantly re-search the area already searched in some cases).
    3256     if (resultRange->collapsed(exception) && wrapFlag) {
     3264    if (resultRange->collapsed(exception) && options & WrapAround) {
    32573265        searchRange = rangeOfContents(m_frame->document());
    3258         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
     3266        resultRange = findPlainText(searchRange.get(), target, options);
    32593267        // We used to return false here if we ended up with the same range that we started with
    32603268        // (e.g., the selection was already the only instance of this text). But we decided that
     
    32703278}
    32713279
    3272 unsigned Editor::countMatchesForText(const String& target, bool caseFlag, unsigned limit, bool markMatches)
     3280unsigned Editor::countMatchesForText(const String& target, FindOptions options, unsigned limit, bool markMatches)
    32733281{
    32743282    if (target.isEmpty())
     
    32803288    unsigned matchCount = 0;
    32813289    do {
    3282         RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
     3290        RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options & ~Backwards));
    32833291        if (resultRange->collapsed(exception)) {
    32843292            if (!resultRange->startContainer()->isInShadowTree())
  • trunk/WebCore/editing/Editor.h

    r72573 r72887  
    3434#include "EditorDeleteAction.h"
    3535#include "EditorInsertAction.h"
     36#include "FindOptions.h"
    3637#include "SelectionController.h"
    3738
     
    308309    bool insideVisibleArea(const IntPoint&) const;
    309310    bool insideVisibleArea(Range*) const;
    310     PassRefPtr<Range> nextVisibleRange(Range*, const String&, bool forward, bool caseFlag, bool wrapFlag);
    311311
    312312    void addToKillRing(Range*, bool prepend);
     
    329329
    330330    String selectedText() const;
     331    bool findString(const String&, FindOptions);
     332    // FIXME: Switch callers over to the FindOptions version and retire this one.
    331333    bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
    332334
     
    345347    RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
    346348
    347     unsigned countMatchesForText(const String&, bool caseFlag, unsigned limit, bool markMatches);
     349    unsigned countMatchesForText(const String&, FindOptions, unsigned limit, bool markMatches);
    348350    bool markedTextMatchesAreHighlighted() const;
    349351    void setMarkedTextMatchesAreHighlighted(bool);
     
    399401    void setIgnoreCompositionSelectionChange(bool ignore);
    400402
    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);
    403406
    404407    void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
  • trunk/WebCore/editing/TextIterator.cpp

    r72748 r72887  
    3939#include "RenderTextControl.h"
    4040#include "RenderTextFragment.h"
     41#include "TextBoundaries.h"
     42#include "TextBreakIterator.h"
    4143#include "VisiblePosition.h"
    4244#include "visible_units.h"
     
    5759// Keeps enough of the previous text to be able to search in the future, but no more.
    5860// 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.
    6064class SearchBuffer : public Noncopyable {
    6165public:
    62     SearchBuffer(const String& target, bool isCaseSensitive);
     66    SearchBuffer(const String& target, FindOptions);
    6367    ~SearchBuffer();
    6468
    6569    // Returns number of characters appended; guaranteed to be in the range [1, length].
    6670    size_t append(const UChar*, size_t length);
     71    bool needsMoreContext() const;
     72    void prependContext(const UChar*, size_t length);
    6773    void reachedBreak();
    6874
     
    7682private:
    7783    bool isBadMatch(const UChar*, size_t length) const;
     84    bool isWordStartMatch(size_t start, size_t length) const;
    7885
    7986    String m_target;
     87    FindOptions m_options;
     88
    8089    Vector<UChar> m_buffer;
    8190    size_t m_overlap;
     91    size_t m_prefixLength;
    8292    bool m_atBreak;
     93    bool m_needsMoreContext;
    8394
    8495    bool m_targetRequiresKanaWorkaround;
     
    93104
    94105    String m_target;
    95     bool m_isCaseSensitive;
     106    FindOptions m_options;
    96107
    97108    Vector<UChar> m_buffer;
     
    18291840}
    18301841
    1831 inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive)
     1842static 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
     1849static 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
     1876inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
    18321877    : m_target(target)
     1878    , m_options(options)
     1879    , m_prefixLength(0)
    18331880    , m_atBreak(true)
     1881    , m_needsMoreContext(options & AtWordStarts)
    18341882    , m_targetRequiresKanaWorkaround(containsKanaLetters(m_target))
    18351883{
     
    18531901    UCollator* collator = usearch_getCollator(searcher);
    18541902
    1855     UCollationStrength strength = isCaseSensitive ? UCOL_TERTIARY : UCOL_PRIMARY;
     1903    UCollationStrength strength = m_options & CaseInsensitive ? UCOL_PRIMARY : UCOL_TERTIARY;
    18561904    if (ucol_getStrength(collator) != strength) {
    18571905        ucol_setStrength(collator, strength);
     
    18791927    if (m_atBreak) {
    18801928        m_buffer.shrink(0);
     1929        m_prefixLength = 0;
    18811930        m_atBreak = false;
    18821931    } else if (m_buffer.size() == m_buffer.capacity()) {
    18831932        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);
    18841934        m_buffer.shrink(m_overlap);
    18851935    }
     
    18911941    foldQuoteMarksAndSoftHyphens(m_buffer.data() + oldLength, usableLength);
    18921942    return usableLength;
     1943}
     1944
     1945inline bool SearchBuffer::needsMoreContext() const
     1946{
     1947    return m_needsMoreContext;
     1948}
     1949
     1950inline 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;
    18931972}
    18941973
     
    19632042}
    19642043
     2044inline 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
    19652093inline size_t SearchBuffer::search(size_t& start)
    19662094{
     
    19802108    ASSERT(status == U_ZERO_ERROR);
    19812109
    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);
    19832114    ASSERT(status == U_ZERO_ERROR);
    19842115
     
    19932124    // possibly including a combining character that's not yet in the buffer.
    19942125    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);
    19972138        return 0;
    19982139    }
     
    20022143
    20032144    // 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)) {
    20052146        matchStart = usearch_next(searcher, &status);
    20062147        ASSERT(status == U_ZERO_ERROR);
     
    20102151    size_t newSize = size - (matchStart + 1);
    20112152    memmove(m_buffer.data(), m_buffer.data() + matchStart + 1, newSize * sizeof(UChar));
     2153    m_prefixLength -= min<size_t>(m_prefixLength, matchStart + 1);
    20122154    m_buffer.shrink(newSize);
    20132155
     
    20182160#else // !ICU_UNICODE
    20192161
    2020 inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive)
    2021     : m_target(isCaseSensitive ? target : target.foldCase())
    2022     , m_isCaseSensitive(isCaseSensitive)
     2162inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
     2163    : m_target(options & CaseInsensitive ? target.foldCase() : target)
     2164    , m_options(options)
    20232165    , m_buffer(m_target.length())
    20242166    , m_isCharacterStartBuffer(m_target.length())
     
    20592201{
    20602202    ASSERT(length);
    2061     if (m_isCaseSensitive) {
     2203    if (!(m_options & CaseInsensitive)) {
    20622204        append(characters[0], true);
    20632205        return 1;
     
    20772219    }
    20782220    return 1;
     2221}
     2222
     2223inline bool SearchBuffer::needsMoreContext() const
     2224{
     2225    return false;
     2226}
     2227
     2228void prependContext(const UChar*, size_t)
     2229{
     2230    ASSERT_NOT_REACHED();
    20792231}
    20802232
     
    23332485}
    23342486
    2335 static size_t findPlainText(CharacterIterator& it, const String& target, bool forward, bool caseSensitive, size_t& matchStart)
     2487static size_t findPlainText(CharacterIterator& it, const String& target, FindOptions options, size_t& matchStart)
    23362488{
    23372489    matchStart = 0;
    23382490    size_t matchLength = 0;
    23392491
    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    }
    23412505
    23422506    while (!it.atEnd()) {
     
    23522516            // If searching forward, stop on the first match.
    23532517            // If searching backward, don't stop, so we end up with the last match.
    2354             if (forward)
     2518            if (!(options & Backwards))
    23552519                break;
    23562520            goto tryAgain;
     
    23662530
    23672531PassRefPtr<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
     2536PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOptions options)
    23682537{
    23692538    // First, find the text.
     
    23722541    {
    23732542        CharacterIterator findIterator(range, TextIteratorEntersTextControls);
    2374         matchLength = findPlainText(findIterator, target, forward, caseSensitive, matchStart);
     2543        matchLength = findPlainText(findIterator, target, options, matchStart);
    23752544        if (!matchLength)
    2376             return collapsedToBoundary(range, forward);
     2545            return collapsedToBoundary(range, !(options & Backwards));
    23772546    }
    23782547
  • trunk/WebCore/editing/TextIterator.h

    r69437 r72887  
    2727#define TextIterator_h
    2828
     29#include "FindOptions.h"
    2930#include "InlineTextBox.h"
    3031#include "Range.h"
     
    5960
    6061String plainText(const Range*, TextIteratorBehavior defaultBehavior = TextIteratorDefaultBehavior);
    61 UChar* plainTextToMallocAllocatedBuffer(const Range*, unsigned& bufferLength, bool isDisplayString, TextIteratorBehavior defaultBehavior = TextIteratorDefaultBehavior);
     62UChar* plainTextToMallocAllocatedBuffer(const Range*, unsigned& bufferLength, bool isDisplayString, TextIteratorBehavior = TextIteratorDefaultBehavior);
     63PassRefPtr<Range> findPlainText(const Range*, const String&, FindOptions);
     64// FIXME: Switch callers over to the FindOptions version and retire this one.
    6265PassRefPtr<Range> findPlainText(const Range*, const String&, bool forward, bool caseSensitive);
    6366
  • trunk/WebCore/editing/visible_units.cpp

    r72861 r72887  
    4646using namespace WTF::Unicode;
    4747
    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 
    7248enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext };
    7349
  • trunk/WebCore/page/Page.cpp

    r71903 r72887  
    508508bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity, FindDirection direction, bool shouldWrap)
    509509{
     510    return findString(target, (caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0) | (direction == FindDirectionBackward ? Backwards : 0) | (shouldWrap ? WrapAround : 0));
     511}
     512
     513bool Page::findString(const String& target, FindOptions options)
     514{
    510515    if (target.isEmpty() || !mainFrame())
    511516        return false;
    512517
     518    bool shouldWrap = options & WrapAround;
    513519    Frame* frame = focusController()->focusedOrMainFrame();
    514520    Frame* startFrame = frame;
    515521    do {
    516         if (frame->editor()->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, false, true)) {
     522        if (frame->editor()->findString(target, (options & ~WrapAround) | StartInSelection)) {
    517523            if (frame != startFrame)
    518524                startFrame->selection()->clear();
     
    520526            return true;
    521527        }
    522         frame = incrementFrame(frame, direction == FindDirectionForward, shouldWrap);
     528        frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
    523529    } while (frame && frame != startFrame);
    524530
     
    526532    // We cheat a bit and just research with wrap on
    527533    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);
    529535        focusController()->setFocusedFrame(frame);
    530536        return found;
     
    535541
    536542unsigned 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
     547unsigned int Page::markAllMatchesForText(const String& target, FindOptions options, bool shouldHighlight, unsigned limit)
    537548{
    538549    if (target.isEmpty() || !mainFrame())
     
    544555    do {
    545556        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);
    547558        frame = incrementFrame(frame, true, false);
    548559    } while (frame);
  • trunk/WebCore/page/Page.h

    r71903 r72887  
    2323
    2424#include "FrameLoaderTypes.h"
     25#include "FindOptions.h"
    2526#include "PlatformString.h"
    2627#include "ViewportArguments.h"
     
    199200        bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; }
    200201
     202        bool findString(const String&, FindOptions);
     203        // FIXME: Switch callers over to the FindOptions version and retire this one.
    201204        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);
    203208        void unmarkAllTextMatches();
    204209
  • trunk/WebCore/platform/text/TextBoundaries.cpp

    r65084 r72887  
    3636
    3737namespace WebCore {
     38
     39int 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
     51int 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)
    3864
    3965int findNextWordFromIndex(const UChar* chars, int len, int position, bool forward)
     
    77103}
    78104
     105#endif // !PLATFORM(BREWMP) && !PLATFORM(MAC) && !PLATFORM(QT)
     106
    79107} // namespace WebCore
  • trunk/WebCore/platform/text/TextBoundaries.h

    r44102 r72887  
    3636    }
    3737
     38    int endOfFirstWordBoundaryContext(const UChar* characters, int length);
     39    int startOfLastWordBoundaryContext(const UChar* characters, int length);
     40
    3841    void findWordBoundary(const UChar*, int len, int position, int* start, int* end);
    3942    int findNextWordFromIndex(const UChar*, int len, int position, bool forward);
  • trunk/WebKit/mac/ChangeLog

    r72852 r72887  
     12010-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
    1392010-11-29  Jeremy Moskovich  <jeremy@chromium.org>
    240
  • trunk/WebKit/mac/WebView/WebDocumentInternal.h

    r66544 r72887  
    2929#import <WebKit/WebDocumentPrivate.h>
    3030#import <WebKit/WebHTMLView.h>
     31#import <WebKit/WebViewPrivate.h>
    3132
    3233#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
     
    6263- (void)setMarkedTextMatchesAreHighlighted:(BOOL)newValue;
    6364- (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;
    6666- (void)unmarkAllTextMatches;
    6767- (NSArray *)rectsForTextMatches;
    6868@end
    6969
     70@protocol WebDocumentOptionsSearching <NSObject>
     71- (BOOL)findString:(NSString *)string options:(WebFindOptions)options;
     72@end
    7073
    7174/* Used to save and restore state in the view, typically when going back/forward */
     
    7780@end
    7881
    79 @interface WebHTMLView (WebDocumentInternalProtocols) <WebDocumentElement, WebMultipleTextMatches>
     82@interface WebHTMLView (WebDocumentInternalProtocols) <WebDocumentElement, WebMultipleTextMatches, WebDocumentOptionsSearching>
    8083@end
    8184
  • trunk/WebKit/mac/WebView/WebHTMLView.mm

    r72852 r72887  
    524524    ASSERT_NOT_REACHED();
    525525    return NSOffState;
     526}
     527
     528static 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);
    526536}
    527537
     
    61996209- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection
    62006210{
    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)];
    62056212}
    62066213
     
    62226229}
    62236230
    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
    62306232{
    62316233    Frame* coreFrame = core([self _frame]);
    62326234    if (!coreFrame)
    62336235        return 0;
    6234     return coreFrame->editor()->countMatchesForText(string, caseFlag, limit, markMatches);
     6236    return coreFrame->editor()->countMatchesForText(string, coreOptions(options), limit, markMatches);
    62356237}
    62366238
     
    62776279}
    62786280
     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
    62796289@end
    62806290
  • trunk/WebKit/mac/WebView/WebPDFView.mm

    r66544 r72887  
    627627}
    628628
    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
    635630{
    636631    PDFSelection *previousMatch = nil;
    637     PDFSelection *nextMatch = nil;
    638632    NSMutableArray *matches = [[NSMutableArray alloc] initWithCapacity:limit];
    639633   
    640634    for (;;) {
    641         nextMatch = [self _nextMatchFor:string direction:YES caseSensitive:caseFlag wrap:NO fromSelection:previousMatch startInSelection:NO];
     635        PDFSelection *nextMatch = [self _nextMatchFor:string direction:YES caseSensitive:!(options & WebFindOptionsCaseInsensitive) wrap:NO fromSelection:previousMatch startInSelection:NO];
    642636        if (!nextMatch)
    643637            break;
  • trunk/WebKit/mac/WebView/WebView.mm

    r71903 r72887  
    26462646}
    26472647
     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
    26482663@end
    26492664
     
    38253840}
    38263841
    3827 static WebFrame *incrementFrame(WebFrame *frame, BOOL forward, BOOL wrapFlag)
     3842static WebFrame *incrementFrame(WebFrame *frame, WebFindOptions options = 0)
    38283843{
    38293844    Frame* coreFrame = core(frame);
    3830     return kit(forward
    3831         ? coreFrame->tree()->traverseNextWithWrap(wrapFlag)
    3832         : coreFrame->tree()->traversePreviousWithWrap(wrapFlag));
     3845    return kit((options & WebFindOptionsBackwards)
     3846        ? coreFrame->tree()->traversePreviousWithWrap(options & WebFindOptionsWrapAround)
     3847        : coreFrame->tree()->traverseNextWithWrap(options & WebFindOptionsWrapAround));
    38333848}
    38343849
     
    42564271}
    42574272
    4258 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection
     4273static 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
    42594283{
    42604284    if (_private->closed)
     
    42684292    WebFrame *frame = startFrame;
    42694293    do {
    4270         WebFrame *nextFrame = incrementFrame(frame, forward, wrapFlag);
     4294        WebFrame *nextFrame = incrementFrame(frame, options);
    42714295       
    42724296        BOOL onlyOneFrame = (frame == nextFrame);
     
    42804304                startSearchView = searchView;
    42814305           
    4282             BOOL foundString;
    42834306            // 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 wrapFlag
     4307            // We can avoid ever doing this in the common one-frame case by passing the wrap option through
    42854308            // here, and then bailing out before we get to the code that would search again in the
    42864309            // 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)) {
    42944313                if (frame != startFrame)
    42954314                    [startFrame _clearSelection];
     
    43044323    } while (frame && frame != startFrame);
    43054324   
    4306     // If there are multiple frames and wrapFlag is true and we've visited each one without finding a result, we still need to search in the
     4325    // 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
    43074326    // 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 again
     4327    // way to make sure the entire frame is searched is to pass WebFindOptionsWrapAround. When there are no matches, this will search
    43094328    // some content that we already searched on the first pass. In the worst case, we could search the entire contents of this frame twice.
    43104329    // 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)) {
    43184332            [[self window] makeFirstResponder:startSearchView];
    43194333            return YES;
     
    44974511            return NO;
    44984512       
    4499         frame = incrementFrame(frame, YES, NO);
     4513        frame = incrementFrame(frame);
    45004514    } while (frame);
    45014515   
     
    45034517}
    45044518
    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
    45144520{
    45154521    if (_private->closed)
     
    45254531       
    45264532            ASSERT(limit == 0 || matchCount < limit);
    4527             matchCount += [(NSView <WebMultipleTextMatches>*)view countMatchesForText:string caseSensitive:caseFlag limit:limit == 0 ? 0 : limit - matchCount markMatches:markMatches];
     4533            matchCount += [(NSView <WebMultipleTextMatches>*)view countMatchesForText:string options:options limit:(limit == 0 ? 0 : limit - matchCount) markMatches:markMatches];
    45284534
    45294535            // Stop looking if we've reached the limit. A limit of 0 means no limit.
     
    45324538        }
    45334539       
    4534         frame = incrementFrame(frame, YES, NO);
     4540        frame = incrementFrame(frame);
    45354541    } while (frame);
    45364542   
     
    45494555            [(NSView <WebMultipleTextMatches>*)view unmarkAllTextMatches];
    45504556       
    4551         frame = incrementFrame(frame, YES, NO);
     4557        frame = incrementFrame(frame);
    45524558    } while (frame);
    45534559}
     
    45874593        }
    45884594       
    4589         frame = incrementFrame(frame, YES, NO);
     4595        frame = incrementFrame(frame);
    45904596    } while (frame);
    45914597   
  • trunk/WebKit/mac/WebView/WebViewPrivate.h

    r71790 r72887  
    7171
    7272// other WebElementDictionary keys
    73 extern NSString *WebElementLinkIsLiveKey;        // NSNumber of BOOL indictating whether the link is live or not
     73extern NSString *WebElementLinkIsLiveKey;        // NSNumber of BOOL indicating whether the link is live or not
    7474extern NSString *WebElementIsInScrollBarKey;
    7575
     
    9797} WebUserContentInjectedFrames;
    9898
     99enum {
     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};
     107typedef NSUInteger WebFindOptions;
     108
    99109@interface WebController : NSTreeController {
    100110    IBOutlet WebView *webView;
     
    115125- (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode;
    116126
    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;
    129128
    130129- (void)setMainFrameDocumentReady:(BOOL)mainFrameDocumentReady;
     
    183182// These methods are still in flux; don't rely on them yet.
    184183- (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;
    187185- (void)unmarkAllTextMatches;
    188186- (NSArray *)rectsForTextMatches;
     
    545543- (void)_scaleWebView:(float)scale atOrigin:(NSPoint)origin;
    546544- (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;
    547563
    548564@end
  • trunk/WebKit2/ChangeLog

    r72857 r72887  
     12010-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
    1332010-11-29  Brent Fulgham  <bfulgham@webkit.org>
    234
  • trunk/WebKit2/Shared/WebFindOptions.h

    r72886 r72887  
    2424 */
    2525
    26 #ifndef FindOptions_h
    27 #define FindOptions_h
     26#ifndef WebFindOptions_h
     27#define WebFindOptions_h
    2828
    2929namespace WebKit {
    3030
    31 enum FindDirection {
    32     FindDirectionForward,
    33     FindDirectionBackward
    34 };
    35 
    3631enum FindOptions {
    3732    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
    4139};
    4240
    4341} // namespace WebKit
    4442
    45 #endif // FindOptions_h
     43#endif // WebFindOptions_h
  • trunk/WebKit2/UIProcess/API/C/WKAPICast.h

    r72666 r72887  
    2828
    2929#include "CacheModel.h"
    30 #include "FindOptions.h"
    3130#include "FontSmoothingLevel.h"
    3231#include "WKContext.h"
     
    3433#include "WKPreferencesPrivate.h"
    3534#include "WKSharedAPICast.h"
     35#include "WebFindOptions.h"
    3636#include <WebCore/FrameLoaderTypes.h>
    3737
     
    125125}
    126126
    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 
    140127inline FindOptions toFindOptions(WKFindOptions wkFindOptions)
    141128{
     
    144131    if (wkFindOptions & kWKFindOptionsCaseInsensitive)
    145132        findOptions |= FindOptionsCaseInsensitive;
     133    if (wkFindOptions & kWKFindOptionsAtWordStarts)
     134        findOptions |= FindOptionsAtWordStarts;
     135    if (wkFindOptions & kWKFindOptionsTreatMedialCapitalAsWordStart)
     136        findOptions |= FindOptionsTreatMedialCapitalAsWordStart;
     137    if (wkFindOptions & kWKFindOptionsBackwards)
     138        findOptions |= FindOptionsBackwards;
    146139    if (wkFindOptions & kWKFindOptionsWrapAround)
    147140        findOptions |= FindOptionsWrapAround;
  • trunk/WebKit2/UIProcess/API/C/WKPage.cpp

    r72666 r72887  
    231231}
    232232
    233 void WKPageFindString(WKPageRef pageRef, WKStringRef string, WKFindDirection findDirection, WKFindOptions findOptions, unsigned maxMatchCount)
    234 {
    235     toImpl(pageRef)->findString(toImpl(string)->string(), toFindDirection(findDirection), toFindOptions(findOptions), maxMatchCount);
     233void WKPageFindString(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
     234{
     235    toImpl(pageRef)->findString(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
    236236}
    237237
     
    241241}
    242242
    243 void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, bool caseInsensitive, unsigned maxMatchCount)
    244 {
    245     toImpl(pageRef)->countStringMatches(toImpl(string)->string(), caseInsensitive, maxMatchCount);
     243void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptions options, unsigned maxMatchCount)
     244{
     245    toImpl(pageRef)->countStringMatches(toImpl(string)->string(), toFindOptions(options), maxMatchCount);
    246246}
    247247
  • trunk/WebKit2/UIProcess/API/C/WKPage.h

    r72707 r72887  
    275275// Find.
    276276enum {
    277     kWKFindDirectionForward,
    278     kWKFindDirectionBackward
    279 };
    280 typedef uint32_t WKFindDirection;
    281 
    282 enum {
    283277    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
    287284};
    288285typedef uint32_t WKFindOptions;
    289286
    290 WK_EXPORT void WKPageFindString(WKPageRef page, WKStringRef string, WKFindDirection findDirection, WKFindOptions findOptions, unsigned maxMatchCount);
     287WK_EXPORT void WKPageFindString(WKPageRef page, WKStringRef string, WKFindOptions findOptions, unsigned maxMatchCount);
    291288WK_EXPORT void WKPageHideFindUI(WKPageRef page);
    292 WK_EXPORT void WKPageCountStringMatches(WKPageRef page, WKStringRef string, bool caseInsensitive, unsigned maxMatchCount);
     289WK_EXPORT void WKPageCountStringMatches(WKPageRef page, WKStringRef string, WKFindOptions findOptions, unsigned maxMatchCount);
    293290
    294291WK_EXPORT void WKPageSetPageContextMenuClient(WKPageRef page, const WKPageContextMenuClient* client);
  • trunk/WebKit2/UIProcess/WebPageProxy.cpp

    r72707 r72887  
    608608}
    609609
    610 void WebPageProxy::findString(const String& string, FindDirection findDirection, FindOptions findOptions, unsigned maxMatchCount)
    611 {
    612     process()->send(Messages::WebPage::FindString(string, findDirection, findOptions, maxMatchCount), m_pageID);
     610void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
     611{
     612    process()->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
    613613}
    614614
     
    618618}
    619619
    620 void WebPageProxy::countStringMatches(const String& string, bool caseInsensitive, unsigned maxMatchCount)
    621 {
    622     process()->send(Messages::WebPage::CountStringMatches(string, caseInsensitive, maxMatchCount), m_pageID);
     620void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
     621{
     622    process()->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
    623623}
    624624   
  • trunk/WebKit2/UIProcess/WebPageProxy.h

    r72666 r72887  
    2929#include "APIObject.h"
    3030#include "DrawingAreaProxy.h"
    31 #include "FindOptions.h"
    3231#include "GenericCallback.h"
    3332#include "SharedMemory.h"
     
    3736#include "WebEvent.h"
    3837#include "WebFindClient.h"
     38#include "WebFindOptions.h"
    3939#include "WebFormClient.h"
    4040#include "WebFrameProxy.h"
     
    209209
    210210    // Find.
    211     void findString(const String&, FindDirection, FindOptions, unsigned maxMatchCount);
     211    void findString(const String&, FindOptions, unsigned maxMatchCount);
    212212    void hideFindUI();
    213     void countStringMatches(const String&, bool caseInsensitive, unsigned maxMatchCount);
     213    void countStringMatches(const String&, FindOptions, unsigned maxMatchCount);
    214214
    215215    void runJavaScriptInMainFrame(const String&, PassRefPtr<ScriptReturnValueCallback>);
  • trunk/WebKit2/WebKit2.pro

    r72792 r72887  
    246246    Shared/WebEvent.h \
    247247    Shared/WebEventConversion.h \
     248    Shared/WebFindOptions.h \
    248249    Shared/WebNavigationDataStore.h \
    249250    Shared/WebNumber.h \
  • trunk/WebKit2/WebKit2.xcodeproj/project.pbxproj

    r72422 r72887  
    141141                1A8EFDFA1253CAA200F7067F /* DataReference.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8EFDF91253CAA200F7067F /* DataReference.h */; };
    142142                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 */; };
    144144                1A90C1F41264FD71003E44D4 /* FindController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A90C1F21264FD71003E44D4 /* FindController.h */; };
    145145                1A90C1F51264FD71003E44D4 /* FindController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A90C1F31264FD71003E44D4 /* FindController.cpp */; };
     
    701701                1A8EFDF91253CAA200F7067F /* DataReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataReference.h; sourceTree = "<group>"; };
    702702                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>"; };
    704704                1A90C1F21264FD71003E44D4 /* FindController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindController.h; sourceTree = "<group>"; };
    705705                1A90C1F31264FD71003E44D4 /* FindController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FindController.cpp; sourceTree = "<group>"; };
     
    13861386                                1A6F9F8E11E13EFC00DB1371 /* CommandLine.h */,
    13871387                                0FB659221208B4DB0044816C /* DrawingAreaBase.h */,
    1388                                 1A90C1ED1264FD50003E44D4 /* FindOptions.h */,
    13891388                                762B7481120BBA0100819339 /* FontSmoothingLevel.h */,
    13901389                                BC64696D11DBE603006455B0 /* ImmutableArray.cpp */,
     
    14181417                                BC032DB010F4380F0058C15A /* WebEventConversion.cpp */,
    14191418                                BC032DB110F4380F0058C15A /* WebEventConversion.h */,
     1419                                1A90C1ED1264FD50003E44D4 /* WebFindOptions.h */,
    14201420                                C0337DD2127A2A0E008FF4F4 /* WebKeyboardEvent.cpp */,
    14211421                                C0337DAF127A28D0008FF4F4 /* WebMouseEvent.cpp */,
     
    23792379                                BC57450C1263B155006F0F12 /* WKBundleNodeHandlePrivate.h in Headers */,
    23802380                                1AC41AC71263C88300054E94 /* BinarySemaphore.h in Headers */,
    2381                                 1A90C1EE1264FD50003E44D4 /* FindOptions.h in Headers */,
     2381                                1A90C1EE1264FD50003E44D4 /* WebFindOptions.h in Headers */,
    23822382                                1A90C1F41264FD71003E44D4 /* FindController.h in Headers */,
    23832383                                1A90C23712650717003E44D4 /* PageOverlay.h in Headers */,
  • trunk/WebKit2/WebProcess/WebPage/FindController.cpp

    r71935 r72887  
    4141namespace WebKit {
    4242
     43static 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
    4352FindController::FindController(WebPage* webPage)
    4453    : m_webPage(webPage)
     
    5261}
    5362
    54 void FindController::countStringMatches(const String& string, bool caseInsensitive, unsigned maxMatchCount)
    55 {
    56     unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, caseInsensitive ? TextCaseInsensitive : TextCaseSensitive, false, maxMatchCount);
     63void FindController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
     64{
     65    unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount);
    5766    m_webPage->corePage()->unmarkAllTextMatches();
    5867
     
    7079}
    7180
    72 void FindController::findString(const String& string, FindDirection findDirection, FindOptions findOptions, unsigned maxMatchCount)
     81void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount)
    7382{
    7483    m_webPage->corePage()->unmarkAllTextMatches();
    7584
    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));
    8086
    8187    Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
     
    9298        m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string));
    9399    } else {
    94         shouldShowOverlay = findOptions & FindOptionsShowOverlay;
     100        shouldShowOverlay = options & FindOptionsShowOverlay;
    95101
    96102        if (shouldShowOverlay) {
    97             unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, caseSensitivity, false, maxMatchCount + 1);
     103            unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1);
    98104
    99105            // Check if we have more matches than allowed.
     
    106112        }
    107113
    108         if (!(findOptions & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) {
     114        if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) {
    109115            // Either we shouldn't show the find indicator, or we couldn't update it.
    110116            hideFindIndicator();
  • trunk/WebKit2/WebProcess/WebPage/FindController.h

    r71685 r72887  
    2727#define FindController_h
    2828
    29 #include "FindOptions.h"
    3029#include "PageOverlay.h"
     30#include "WebFindOptions.h"
    3131#include <wtf/Forward.h>
    3232#include <wtf/Noncopyable.h>
     
    4949    virtual ~FindController();
    5050
    51     void findString(const String&, FindDirection, FindOptions, unsigned maxMatchCount);
     51    void findString(const String&, FindOptions, unsigned maxMatchCount);
    5252    void hideFindUI();
    53     void countStringMatches(const String&, bool caseInsensitive, unsigned maxMatchCount);
     53    void countStringMatches(const String&, FindOptions, unsigned maxMatchCount);
    5454   
    5555    void hideFindIndicator();
  • trunk/WebKit2/WebProcess/WebPage/WebPage.cpp

    r72666 r72887  
    999999}
    10001000
    1001 void WebPage::findString(const String& string, uint32_t findDirection, uint32_t findOptions, uint32_t maxMatchCount)
    1002 {
    1003     m_findController.findString(string, static_cast<FindDirection>(findDirection), static_cast<FindOptions>(findOptions), maxMatchCount);
     1001void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
     1002{
     1003    m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
    10041004}
    10051005
     
    10091009}
    10101010
    1011 void WebPage::countStringMatches(const String& string, bool caseInsensitive, uint32_t maxMatchCount)
    1012 {
    1013     m_findController.countStringMatches(string, caseInsensitive, maxMatchCount);
     1011void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
     1012{
     1013    m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
    10141014}
    10151015
  • trunk/WebKit2/WebProcess/WebPage/WebPage.h

    r72666 r72887  
    291291    void didRemoveEditCommand(uint64_t commandID);
    292292
    293     void findString(const String&, uint32_t findDirection, uint32_t findOptions, uint32_t maxMatchCount);
     293    void findString(const String&, uint32_t findOptions, uint32_t maxMatchCount);
    294294    void hideFindUI();
    295     void countStringMatches(const String&, bool caseInsensitive, uint32_t maxMatchCount);
     295    void countStringMatches(const String&, uint32_t findOptions, uint32_t maxMatchCount);
    296296
    297297#if PLATFORM(QT)
  • trunk/WebKit2/WebProcess/WebPage/WebPage.messages.in

    r72438 r72887  
    7979
    8080    # Find.
    81     FindString(WTF::String string, uint32_t findDirection, uint32_t findOptions, unsigned maxMatchCount)
     81    FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
    8282    HideFindUI()
    83     CountStringMatches(WTF::String string, bool caseInsensitive, unsigned maxMatchCount)
     83    CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
    8484
    8585    # Popup menu.
  • trunk/WebKit2/win/WebKit2.vcproj

    r72857 r72887  
    553553                        </File>
    554554                        <File
     555                                RelativePath="..\Shared\WebFindOptions.h"
     556                                >
     557                        </File>
     558                        <File
    555559                                RelativePath="..\Shared\WebKeyboardEvent.cpp"
    556560                                >
  • trunk/WebKitTools/ChangeLog

    r72868 r72887  
     12010-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
    1172010-11-29  Johnny Ding  <jnd@chromium.org>
    218
  • trunk/WebKitTools/DumpRenderTree/LayoutTestController.cpp

    r72591 r72887  
    443443}
    444444
     445static 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
    445461static JSValueRef counterValueForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    446462{
     
    19171933        { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    19181934        { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     1935        { "findString", findStringCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    19191936        { "counterValueForElementById", counterValueForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    19201937        { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
  • trunk/WebKitTools/DumpRenderTree/LayoutTestController.h

    r72591 r72887  
    5353    JSStringRef copyDecodedHostName(JSStringRef name);
    5454    JSStringRef copyEncodedHostName(JSStringRef name);
     55    JSRetainPtr<JSStringRef> counterValueForElementById(JSStringRef id);
    5556    void disableImageLoading();
    5657    void dispatchPendingLoadRequests();
    5758    void display();
    5859    void execCommand(JSStringRef name, JSStringRef value);
    59     JSRetainPtr<JSStringRef> counterValueForElementById(JSStringRef id);
     60    bool findString(JSContextRef, JSStringRef, JSObjectRef optionsArray);
    6061    bool isCommandEnabled(JSStringRef name);
    6162    void keepWebHistory();
  • trunk/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm

    r72591 r72887  
    584584}
    585585
     586bool 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
    586622void LayoutTestController::setCacheModel(int cacheModel)
    587623{
  • trunk/WebKitTools/MiniBrowser/mac/BrowserWindowController.m

    r70790 r72887  
    691691    WKStringRef string = WKStringCreateWithCFString((CFStringRef)[sender stringValue]);
    692692
    693     WKPageFindString(_webView.pageRef, string, kWKFindDirectionForward,
    694                      kWKFindOptionsCaseInsensitive | kWKFindOptionsWrapAround | kWKFindOptionsShowFindIndicator | kWKFindOptionsShowOverlay, 100);
     693    WKPageFindString(_webView.pageRef, string, kWKFindOptionsCaseInsensitive | kWKFindOptionsWrapAround | kWKFindOptionsShowFindIndicator | kWKFindOptionsShowOverlay, 100);
    695694}
    696695
Note: See TracChangeset for help on using the changeset viewer.