|
1 | 1 | /* |
2 | | - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
| 2 | + * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 | 3 | * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
4 | 4 | * |
5 | 5 | * Redistribution and use in source and binary forms, with or without |
@@ -2913,90 +2913,96 @@ bool Editor::findString(const String& target, bool forward, bool caseFlag, bool |
2913 | 2913 |
|
2914 | 2914 | bool Editor::findString(const String& target, FindOptions options) |
2915 | 2915 | { |
2916 | | - if (target.isEmpty()) |
| 2916 | + VisibleSelection selection = m_frame->selection()->selection(); |
| 2917 | + |
| 2918 | + RefPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options); |
| 2919 | + |
| 2920 | + if (!resultRange) |
2917 | 2921 | return false; |
2918 | 2922 |
|
| 2923 | + m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM)); |
| 2924 | + m_frame->selection()->revealSelection(); |
| 2925 | + return true; |
| 2926 | +} |
| 2927 | + |
| 2928 | +PassRefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options) |
| 2929 | +{ |
| 2930 | + if (target.isEmpty()) |
| 2931 | + return 0; |
| 2932 | + |
2919 | 2933 | if (m_frame->excludeFromTextSearch()) |
2920 | | - return false; |
| 2934 | + return 0; |
2921 | 2935 |
|
2922 | | - // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge |
| 2936 | + // Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge |
2923 | 2937 | // is used depends on whether we're searching forward or backward, and whether startInSelection is set. |
2924 | 2938 | RefPtr<Range> searchRange(rangeOfContents(m_frame->document())); |
2925 | | - VisibleSelection selection = m_frame->selection()->selection(); |
2926 | 2939 |
|
2927 | 2940 | 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()); |
| 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 | + } |
2933 | 2948 |
|
2934 | | - RefPtr<Node> shadowTreeRoot = selection.nonBoundaryShadowTreeRootNode(); |
| 2949 | + RefPtr<Node> shadowTreeRoot = referenceRange && referenceRange->startContainer() ? referenceRange->startContainer()->nonBoundaryShadowTreeRootNode() : 0; |
2935 | 2950 | if (shadowTreeRoot) { |
2936 | | - ExceptionCode ec = 0; |
2937 | 2951 | if (forward) |
2938 | | - searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount(), ec); |
| 2952 | + searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount()); |
2939 | 2953 | else |
2940 | | - searchRange->setStart(shadowTreeRoot.get(), 0, ec); |
| 2954 | + searchRange->setStart(shadowTreeRoot.get(), 0); |
2941 | 2955 | } |
2942 | 2956 |
|
2943 | 2957 | 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. |
2945 | 2959 | // Build a selection with the found range to remove collapsed whitespace. |
2946 | 2960 | // 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)) { |
2948 | 2962 | searchRange = rangeOfContents(m_frame->document()); |
2949 | 2963 | if (forward) |
2950 | | - setStart(searchRange.get(), selection.visibleEnd()); |
| 2964 | + searchRange->setStart(referenceRange->endPosition()); |
2951 | 2965 | else |
2952 | | - setEnd(searchRange.get(), selection.visibleStart()); |
| 2966 | + searchRange->setEnd(referenceRange->startPosition()); |
2953 | 2967 |
|
2954 | 2968 | if (shadowTreeRoot) { |
2955 | | - ExceptionCode ec = 0; |
2956 | 2969 | if (forward) |
2957 | | - searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount(), ec); |
| 2970 | + searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount()); |
2958 | 2971 | else |
2959 | | - searchRange->setStart(shadowTreeRoot.get(), 0, ec); |
| 2972 | + searchRange->setStart(shadowTreeRoot.get(), 0); |
2960 | 2973 | } |
2961 | 2974 |
|
2962 | 2975 | resultRange = findPlainText(searchRange.get(), target, options); |
2963 | 2976 | } |
2964 | 2977 |
|
2965 | | - ExceptionCode exception = 0; |
2966 | | - |
2967 | 2978 | // 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) { |
2969 | 2980 | searchRange = rangeOfContents(m_frame->document()); |
2970 | 2981 | if (forward) |
2971 | | - searchRange->setStartAfter(shadowTreeRoot->shadowAncestorNode(), exception); |
| 2982 | + searchRange->setStartAfter(shadowTreeRoot->shadowAncestorNode()); |
2972 | 2983 | else |
2973 | | - searchRange->setEndBefore(shadowTreeRoot->shadowAncestorNode(), exception); |
| 2984 | + searchRange->setEndBefore(shadowTreeRoot->shadowAncestorNode()); |
2974 | 2985 |
|
2975 | 2986 | resultRange = findPlainText(searchRange.get(), target, options); |
2976 | 2987 | } |
2977 | 2988 |
|
2978 | 2989 | if (!insideVisibleArea(resultRange.get())) { |
2979 | 2990 | resultRange = nextVisibleRange(resultRange.get(), target, options); |
2980 | 2991 | if (!resultRange) |
2981 | | - return false; |
| 2992 | + return 0; |
2982 | 2993 | } |
2983 | 2994 |
|
2984 | 2995 | // If we didn't find anything and we're wrapping, search again in the entire document (this will |
2985 | 2996 | // redundantly re-search the area already searched in some cases). |
2986 | | - if (resultRange->collapsed(exception) && options & WrapAround) { |
| 2997 | + if (resultRange->collapsed() && options & WrapAround) { |
2987 | 2998 | searchRange = rangeOfContents(m_frame->document()); |
2988 | 2999 | resultRange = findPlainText(searchRange.get(), target, options); |
2989 | 3000 | // 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 |
2991 | 3002 | // this should be a success case instead, so we'll just fall through in that case. |
2992 | 3003 | } |
2993 | 3004 |
|
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(); |
3000 | 3006 | } |
3001 | 3007 |
|
3002 | 3008 | static bool isFrameInRange(Frame* frame, Range* range) |
|
0 commit comments