Changeset 94124 in webkit


Ignore:
Timestamp:
Aug 30, 2011, 4:36:47 PM (13 years ago)
Author:
mitz@apple.com
Message:

Source/WebCore: WebCore part of <rdar://problem/9281695> Add text search API for getting the DOM range of a text match
https://bugs.webkit.org/show_bug.cgi?id=67230

Reviewed by Darin Adler.

Test: TestWebKitAPI/Tests/mac/DOMRangeOfString.

  • WebCore.exp.in: Export Page::rangeOfString().
  • dom/Range.h: Added a default ASSERT_NO_EXCEPTION to a few more member functions.
  • editing/Editor.cpp:

(WebCore::Editor::findString): Moved most of the logic into rangeOfString(), which this function
now calls, passing in the current selection as the reference range and setting the selection to
the returned range.
(WebCore::Editor::rangeOfString): Added. Contains the find logic from findString().

  • editing/Editor.h:
  • page/Page.cpp:

(WebCore::Page::rangeOfString): Added. This function is similar to findString(), but it takes an optional
reference range and returns a Range, rather than using the current selection as the reference range and setting the
selection to the next match.

  • page/Page.h:

Source/WebKit/mac: <rdar://problem/9281695> Add text search API for getting the DOM range of a text match
https://bugs.webkit.org/show_bug.cgi?id=67230

Reviewed by Darin Adler.

  • WebView/WebHTMLView.mm:
  • WebView/WebView.mm:

(coreOptions): Moved this function from WebHTMLView.mm to here and made
it accessible from both this file and WebHTMLView.mm.
(-[WebView DOMRangeOfString:relativeTo:options:]): Added this new API.

  • WebView/WebViewInternal.h:
  • WebView/WebViewPrivate.h:

Tools: Test for <rdar://problem/9281695> Add text search API for getting the DOM range of a text match
https://bugs.webkit.org/show_bug.cgi?id=67230

Reviewed by Darin Adler.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/mac/DOMRangeOfString.html: Added.
  • TestWebKitAPI/Tests/mac/DOMRangeOfString.mm: Added.

(-[DOMRangeOfStringFrameLoadDelegate webView:didFinishLoadForFrame:]):
(TestWebKitAPI::TEST):

Location:
trunk
Files:
2 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r94123 r94124  
     12011-08-30  Dan Bernstein  <mitz@apple.com>
     2
     3        WebCore part of <rdar://problem/9281695> Add text search API for getting the DOM range of a text match
     4        https://bugs.webkit.org/show_bug.cgi?id=67230
     5
     6        Reviewed by Darin Adler.
     7
     8        Test: TestWebKitAPI/Tests/mac/DOMRangeOfString.
     9
     10        * WebCore.exp.in: Export Page::rangeOfString().
     11        * dom/Range.h: Added a default ASSERT_NO_EXCEPTION to a few more member functions.
     12        * editing/Editor.cpp:
     13        (WebCore::Editor::findString): Moved most of the logic into rangeOfString(), which this function
     14        now calls, passing in the current selection as the reference range and setting the selection to
     15        the returned range.
     16        (WebCore::Editor::rangeOfString): Added. Contains the find logic from findString().
     17        * editing/Editor.h:
     18        * page/Page.cpp:
     19        (WebCore::Page::rangeOfString): Added. This function is similar to findString(), but it takes an optional
     20        reference range and returns a Range, rather than using the current selection as the reference range and setting the
     21        selection to the next match.
     22        * page/Page.h:
     23
    1242011-08-30  Sam Weinig  <sam@webkit.org>
    225
  • trunk/Source/WebCore/WebCore.exp.in

    r94093 r94124  
    700700__ZN7WebCore4Page11PageClientsD1Ev
    701701__ZN7WebCore4Page12setGroupNameERKN3WTF6StringE
     702__ZN7WebCore4Page13rangeOfStringERKN3WTF6StringEPNS_5RangeEj
    702703__ZN7WebCore4Page14setMediaVolumeEf
    703704__ZN7WebCore4Page15addSchedulePairEN3WTF10PassRefPtrINS_12SchedulePairEEE
  • trunk/Source/WebCore/dom/Range.h

    r93199 r94124  
    9494    PassRefPtr<Range> cloneRange(ExceptionCode&) const;
    9595
    96     void setStartAfter(Node*, ExceptionCode&);
    97     void setEndBefore(Node*, ExceptionCode&);
    98     void setEndAfter(Node*, ExceptionCode&);
    99     void selectNode(Node*, ExceptionCode&);
     96    void setStartAfter(Node*, ExceptionCode& = ASSERT_NO_EXCEPTION);
     97    void setEndBefore(Node*, ExceptionCode& = ASSERT_NO_EXCEPTION);
     98    void setEndAfter(Node*, ExceptionCode& = ASSERT_NO_EXCEPTION);
     99    void selectNode(Node*, ExceptionCode& = ASSERT_NO_EXCEPTION);
    100100    void selectNodeContents(Node*, ExceptionCode&);
    101101    void surroundContents(PassRefPtr<Node>, ExceptionCode&);
     
    104104    const Position startPosition() const { return m_start.toPosition(); }
    105105    const Position endPosition() const { return m_end.toPosition(); }
    106     void setStart(const Position&, ExceptionCode&);
    107     void setEnd(const Position&, ExceptionCode&);
     106    void setStart(const Position&, ExceptionCode& = ASSERT_NO_EXCEPTION);
     107    void setEnd(const Position&, ExceptionCode& = ASSERT_NO_EXCEPTION);
    108108
    109109    Node* firstNode() const;
  • trunk/Source/WebCore/editing/Editor.cpp

    r93392 r94124  
    11/*
    2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
    44 *
     
    29142914bool Editor::findString(const String& target, FindOptions options)
    29152915{
     2916    VisibleSelection selection = m_frame->selection()->selection();
     2917
     2918    RefPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options);
     2919
     2920    if (!resultRange)
     2921        return false;
     2922
     2923    m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
     2924    m_frame->selection()->revealSelection();
     2925    return true;
     2926}
     2927
     2928PassRefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
     2929{
    29162930    if (target.isEmpty())
    2917         return false;
     2931        return 0;
    29182932
    29192933    if (m_frame->excludeFromTextSearch())
    2920         return false;
    2921 
    2922     // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
     2934        return 0;
     2935
     2936    // Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge
    29232937    // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
    29242938    RefPtr<Range> searchRange(rangeOfContents(m_frame->document()));
    2925     VisibleSelection selection = m_frame->selection()->selection();
    29262939
    29272940    bool forward = !(options & Backwards);
    2928     bool startInSelection = options & StartInSelection;
    2929     if (forward)
    2930         setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
    2931     else
    2932         setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
    2933 
    2934     RefPtr<Node> shadowTreeRoot = selection.nonBoundaryShadowTreeRootNode();
     2941    bool startInReferenceRange = referenceRange && (options & StartInSelection);
     2942    if (referenceRange) {
     2943        if (forward)
     2944            searchRange->setStart(startInReferenceRange ? referenceRange->startPosition() : referenceRange->endPosition());
     2945        else
     2946            searchRange->setEnd(startInReferenceRange ? referenceRange->endPosition() : referenceRange->startPosition());
     2947    }
     2948
     2949    RefPtr<Node> shadowTreeRoot = referenceRange && referenceRange->startContainer() ? referenceRange->startContainer()->nonBoundaryShadowTreeRootNode() : 0;
    29352950    if (shadowTreeRoot) {
    2936         ExceptionCode ec = 0;
    29372951        if (forward)
    2938             searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount(), ec);
     2952            searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
    29392953        else
    2940             searchRange->setStart(shadowTreeRoot.get(), 0, ec);
     2954            searchRange->setStart(shadowTreeRoot.get(), 0);
    29412955    }
    29422956
    29432957    RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options));
    2944     // If we started in the selection and the found range exactly matches the existing selection, find again.
     2958    // If we started in the reference range and the found range exactly matches the reference range, find again.
    29452959    // Build a selection with the found range to remove collapsed whitespace.
    29462960    // Compare ranges instead of selection objects to ignore the way that the current selection was made.
    2947     if (startInSelection && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), selection.toNormalizedRange().get())) {
     2961    if (startInReferenceRange && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), referenceRange)) {
    29482962        searchRange = rangeOfContents(m_frame->document());
    29492963        if (forward)
    2950             setStart(searchRange.get(), selection.visibleEnd());
     2964            searchRange->setStart(referenceRange->endPosition());
    29512965        else
    2952             setEnd(searchRange.get(), selection.visibleStart());
     2966            searchRange->setEnd(referenceRange->startPosition());
    29532967
    29542968        if (shadowTreeRoot) {
    2955             ExceptionCode ec = 0;
    29562969            if (forward)
    2957                 searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount(), ec);
     2970                searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
    29582971            else
    2959                 searchRange->setStart(shadowTreeRoot.get(), 0, ec);
     2972                searchRange->setStart(shadowTreeRoot.get(), 0);
    29602973        }
    29612974
     
    29632976    }
    29642977
    2965     ExceptionCode exception = 0;
    2966 
    29672978    // If nothing was found in the shadow tree, search in main content following the shadow tree.
    2968     if (resultRange->collapsed(exception) && shadowTreeRoot) {
     2979    if (resultRange->collapsed() && shadowTreeRoot) {
    29692980        searchRange = rangeOfContents(m_frame->document());
    29702981        if (forward)
    2971             searchRange->setStartAfter(shadowTreeRoot->shadowAncestorNode(), exception);
     2982            searchRange->setStartAfter(shadowTreeRoot->shadowAncestorNode());
    29722983        else
    2973             searchRange->setEndBefore(shadowTreeRoot->shadowAncestorNode(), exception);
     2984            searchRange->setEndBefore(shadowTreeRoot->shadowAncestorNode());
    29742985
    29752986        resultRange = findPlainText(searchRange.get(), target, options);
     
    29792990        resultRange = nextVisibleRange(resultRange.get(), target, options);
    29802991        if (!resultRange)
    2981             return false;
     2992            return 0;
    29822993    }
    29832994
    29842995    // If we didn't find anything and we're wrapping, search again in the entire document (this will
    29852996    // redundantly re-search the area already searched in some cases).
    2986     if (resultRange->collapsed(exception) && options & WrapAround) {
     2997    if (resultRange->collapsed() && options & WrapAround) {
    29872998        searchRange = rangeOfContents(m_frame->document());
    29882999        resultRange = findPlainText(searchRange.get(), target, options);
    29893000        // We used to return false here if we ended up with the same range that we started with
    2990         // (e.g., the selection was already the only instance of this text). But we decided that
     3001        // (e.g., the reference range was already the only instance of this text). But we decided that
    29913002        // this should be a success case instead, so we'll just fall through in that case.
    29923003    }
    29933004
    2994     if (resultRange->collapsed(exception))
    2995         return false;
    2996 
    2997     m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
    2998     m_frame->selection()->revealSelection();
    2999     return true;
     3005    return resultRange->collapsed() ? 0 : resultRange.release();
    30003006}
    30013007
  • trunk/Source/WebCore/editing/Editor.h

    r93273 r94124  
    336336    bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
    337337
     338    PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
     339
    338340    const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
    339341    void setMark(const VisibleSelection&);
  • trunk/Source/WebCore/page/Page.cpp

    r93913 r94124  
    500500}
    501501
     502PassRefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
     503{
     504    if (target.isEmpty() || !mainFrame())
     505        return 0;
     506
     507    if (referenceRange && referenceRange->ownerDocument()->page() != this)
     508        return 0;
     509
     510    bool shouldWrap = options & WrapAround;
     511    Frame* frame = referenceRange ? referenceRange->ownerDocument()->frame() : mainFrame();
     512    Frame* startFrame = frame;
     513    do {
     514        if (RefPtr<Range> resultRange = frame->editor()->rangeOfString(target, frame == startFrame ? referenceRange : 0, (options & ~WrapAround) | StartInSelection))
     515            return resultRange.release();
     516
     517        frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
     518    } while (frame && frame != startFrame);
     519
     520    // Search contents of startFrame, on the other side of the reference range that we did earlier.
     521    // We cheat a bit and just search again with wrap on.
     522    if (shouldWrap && referenceRange) {
     523        if (RefPtr<Range> resultRange = startFrame->editor()->rangeOfString(target, referenceRange, options | WrapAround | StartInSelection))
     524            return resultRange.release();
     525    }
     526
     527    return 0;
     528}
     529
    502530unsigned int Page::markAllMatchesForText(const String& target, TextCaseSensitivity caseSensitivity, bool shouldHighlight, unsigned limit)
    503531{
  • trunk/Source/WebCore/page/Page.h

    r93303 r94124  
    7676    class PluginData;
    7777    class ProgressTracker;
     78    class Range;
    7879    class RenderTheme;
    7980    class VisibleSelection;
     
    211212        // FIXME: Switch callers over to the FindOptions version and retire this one.
    212213        bool findString(const String&, TextCaseSensitivity, FindDirection, bool shouldWrap);
     214
     215        PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
     216
    213217        unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned);
    214218        // FIXME: Switch callers over to the FindOptions version and retire this one.
  • trunk/Source/WebKit/mac/ChangeLog

    r94122 r94124  
     12011-08-30  Dan Bernstein  <mitz@apple.com>
     2
     3        <rdar://problem/9281695> Add text search API for getting the DOM range of a text match
     4        https://bugs.webkit.org/show_bug.cgi?id=67230
     5
     6        Reviewed by Darin Adler.
     7
     8        * WebView/WebHTMLView.mm:
     9        * WebView/WebView.mm:
     10        (coreOptions): Moved this function from WebHTMLView.mm to here and made
     11        it accessible from both this file and WebHTMLView.mm.
     12        (-[WebView DOMRangeOfString:relativeTo:options:]): Added this new API.
     13        * WebView/WebViewInternal.h:
     14        * WebView/WebViewPrivate.h:
     15
    1162011-08-30  Beth Dakin  <bdakin@apple.com>
    217
  • trunk/Source/WebKit/mac/WebView/WebHTMLView.mm

    r92068 r94124  
    535535}
    536536
    537 static FindOptions coreOptions(WebFindOptions options)
    538 {
    539     return (options & WebFindOptionsCaseInsensitive ? CaseInsensitive : 0)
    540         | (options & WebFindOptionsAtWordStarts ? AtWordStarts : 0)
    541         | (options & WebFindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0)
    542         | (options & WebFindOptionsBackwards ? Backwards : 0)
    543         | (options & WebFindOptionsWrapAround ? WrapAround : 0)
    544         | (options & WebFindOptionsStartInSelection ? StartInSelection : 0);
    545 }
    546 
    547537@implementation WebHTMLViewPrivate
    548538
  • trunk/Source/WebKit/mac/WebView/WebView.mm

    r94122 r94124  
    375375@end
    376376
     377FindOptions coreOptions(WebFindOptions options)
     378{
     379    return (options & WebFindOptionsCaseInsensitive ? CaseInsensitive : 0)
     380        | (options & WebFindOptionsAtWordStarts ? AtWordStarts : 0)
     381        | (options & WebFindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0)
     382        | (options & WebFindOptionsBackwards ? Backwards : 0)
     383        | (options & WebFindOptionsWrapAround ? WrapAround : 0)
     384        | (options & WebFindOptionsStartInSelection ? StartInSelection : 0);
     385}
     386
    377387@interface WebView (WebFileInternal)
    378388- (float)_deviceScaleFactor;
     
    45484558}
    45494559
     4560- (DOMRange *)DOMRangeOfString:(NSString *)string relativeTo:(DOMRange *)previousRange options:(WebFindOptions)options
     4561{
     4562    if (!_private->page)
     4563        return nil;
     4564
     4565    return kit(_private->page->rangeOfString(string, core(previousRange), coreOptions(options)).get());
     4566}
     4567
    45504568- (void)setHoverFeedbackSuspended:(BOOL)newValue
    45514569{
  • trunk/Source/WebKit/mac/WebView/WebViewInternal.h

    r93980 r94124  
    3535
    3636#ifdef __cplusplus
     37#import <WebCore/FindOptions.h>
    3738#import <WebCore/WebCoreKeyboardUIMode.h>
    3839
     
    5657
    5758#ifdef __cplusplus
     59
     60WebCore::FindOptions coreOptions(WebFindOptions options);
    5861
    5962@interface WebView (WebViewEditingExtras)
  • trunk/Source/WebKit/mac/WebView/WebViewPrivate.h

    r94122 r94124  
    118118
    119119- (BOOL)findString:(NSString *)string options:(WebFindOptions)options;
     120- (DOMRange *)DOMRangeOfString:(NSString *)string relativeTo:(DOMRange *)previousRange options:(WebFindOptions)options;
    120121
    121122- (void)setMainFrameDocumentReady:(BOOL)mainFrameDocumentReady;
  • trunk/Tools/ChangeLog

    r94121 r94124  
     12011-08-30  Dan Bernstein  <mitz@apple.com>
     2
     3        Test for <rdar://problem/9281695> Add text search API for getting the DOM range of a text match
     4        https://bugs.webkit.org/show_bug.cgi?id=67230
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     9        * TestWebKitAPI/Tests/mac/DOMRangeOfString.html: Added.
     10        * TestWebKitAPI/Tests/mac/DOMRangeOfString.mm: Added.
     11        (-[DOMRangeOfStringFrameLoadDelegate webView:didFinishLoadForFrame:]):
     12        (TestWebKitAPI::TEST):
     13
    1142011-08-30  Aaron Colwell  <acolwell@chromium.org>
    215
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r93418 r94124  
    2020                33E79E06137B5FD900E32D99 /* mouse-move-listener.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */; };
    2121                37200B9213A16230007A4FAD /* VectorReverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37200B9113A16230007A4FAD /* VectorReverse.cpp */; };
     22                37DC678D140D7C5000ABCCDB /* DOMRangeOfString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */; };
     23                37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */; };
    2224                4BFDFFA71314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */; };
    2325                4BFDFFA9131477770061F24B /* HitTestResultNodeHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA8131477770061F24B /* HitTestResultNodeHandle.cpp */; };
     
    113115                                C01A23F21266156700C9ED55 /* spacebar-scrolling.html in Copy Resources */,
    114116                                BC2D006412AA04CE00E732A3 /* file-with-anchor.html in Copy Resources */,
     117                                37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */,
    115118                                1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */,
    116119                        );
     
    132135                33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "mouse-move-listener.html"; sourceTree = "<group>"; };
    133136                37200B9113A16230007A4FAD /* VectorReverse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VectorReverse.cpp; path = WTF/VectorReverse.cpp; sourceTree = "<group>"; };
     137                37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMRangeOfString.mm; sourceTree = "<group>"; };
     138                37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DOMRangeOfString.html; sourceTree = "<group>"; };
    134139                4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestResultNodeHandle_Bundle.cpp; sourceTree = "<group>"; };
    135140                4BFDFFA8131477770061F24B /* HitTestResultNodeHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestResultNodeHandle.cpp; sourceTree = "<group>"; };
     
    404409                        children = (
    405410                                C07E6CB013FD737C0038B22B /* Resources */,
     411                                37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */,
    406412                                C07E6CAE13FD67650038B22B /* DynamicDeviceScaleFactor.mm */,
    407413                        );
     
    412418                        isa = PBXGroup;
    413419                        children = (
     420                                37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */,
    414421                                C07E6CB113FD738A0038B22B /* devicePixelRatio.html */,
    415422                        );
     
    551558                                C08587FC13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm in Sources */,
    552559                                C085880013FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm in Sources */,
     560                                37DC678D140D7C5000ABCCDB /* DOMRangeOfString.mm in Sources */,
    553561                        );
    554562                        runOnlyForDeploymentPostprocessing = 0;
Note: See TracChangeset for help on using the changeset viewer.