Commit 7c9568d1 authored by justing's avatar justing

LayoutTests:

        Reviewed by levi
        
        <rdar://problem/4549980>
        REGRESSION: "Find Again" can get stuck when searching for string with a trailing space

        * editing/execCommand/findString-expected.checksum: Added.
        * editing/execCommand/findString-expected.png: Added.
        * editing/execCommand/findString-expected.txt: Added.
        * editing/execCommand/findString.html: Added.

WebCore:

        Reviewed by levi
        
        <rdar://problem/4549980>
        REGRESSION: "Find Again" can get stuck when searching for string with a trailing space

        * bridge/mac/FrameMac.h: Moved findString to Frame.
        * bridge/mac/FrameMac.mm: Ditto.
        * bridge/mac/WebCoreFrameBridge.mm:
        (-[WebCoreFrameBridge searchFor:direction:caseSensitive:wrap:]): 
        Convert the NSString to a String.
        * editing/JSEditor.cpp: Added execCommand(FindString, ...)
        * editing/Selection.cpp: Added a constructor for Ranges
        (WebCore::Selection::Selection): 
        * editing/Selection.h:
        * page/Frame.cpp:
        (WebCore::Frame::findString): Moved from FrameMac.  Compare a selection created 
        using the found range with the current selection in case the current selection is
        the found range minus some collapsed whitespace on the edges.
        * page/Frame.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@14782 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c88fb512
2006-06-09 Justin Garcia <justin.garcia@apple.com>
Reviewed by levi
<rdar://problem/4549980>
REGRESSION: "Find Again" can get stuck when searching for string with a trailing space
* editing/execCommand/findString-expected.checksum: Added.
* editing/execCommand/findString-expected.png: Added.
* editing/execCommand/findString-expected.txt: Added.
* editing/execCommand/findString.html: Added.
2006-06-09 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>
Reviewed by Hyatt.
19392fc36136b2b5b4e1bb8053dee2b6
\ No newline at end of file
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {P} at (0,0) size 784x18
RenderText {#text} at (0,0) size 350x18
text run at (0,0) width 350: "In the block below, the second 'bar ' should be selected."
RenderBlock {DIV} at (0,34) size 52x38 [border: (1px solid #000000)]
RenderText {#text} at (1,1) size 45x18
text run at (1,1) width 45: "foo bar"
RenderInline {SPAN} at (0,0) size 20x18
RenderText {#text} at (1,19) size 20x18
text run at (1,19) width 20: "bar"
RenderText {#text} at (21,19) size 26x18
text run at (21,19) width 26: " baz"
selection start: position 0 of child 1 {SPAN} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
selection end: position 1 of child 2 {#text} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
<p>In the block below, the second 'bar ' should be selected.</p>
<div style="border: 1px solid black; width:50px;">foo bar <span>bar</span> baz</div>
<script>
document.execCommand("FindString", false, "bar ");
document.execCommand("FindString", false, "bar ");
document.execCommand("FindString", false, "bar ");
</script>
\ No newline at end of file
2006-06-09 Justin Garcia <justin.garcia@apple.com>
Reviewed by levi
<rdar://problem/4549980>
REGRESSION: "Find Again" can get stuck when searching for string with a trailing space
* bridge/mac/FrameMac.h: Moved findString to Frame.
* bridge/mac/FrameMac.mm: Ditto.
* bridge/mac/WebCoreFrameBridge.mm:
(-[WebCoreFrameBridge searchFor:direction:caseSensitive:wrap:]):
Convert the NSString to a String.
* editing/JSEditor.cpp: Added execCommand(FindString, ...)
* editing/Selection.cpp: Added a constructor for Ranges
(WebCore::Selection::Selection):
* editing/Selection.h:
* page/Frame.cpp:
(WebCore::Frame::findString): Moved from FrameMac. Compare a selection created
using the found range with the current selection in case the current selection is
the found range minus some collapsed whitespace on the edges.
* page/Frame.h:
2006-06-09 Steve Falkenburg <sfalken@apple.com>
Fix build break
......
......@@ -232,8 +232,6 @@ public:
NSString* searchForLabelsBeforeElement(NSArray* labels, Element* element);
NSString* matchLabelsAgainstElement(NSArray* labels, Element* element);
bool findString(NSString* str, bool forward, bool caseFlag, bool wrapFlag);
virtual void tokenizerProcessedData();
virtual String overrideMediaType() const;
......
......@@ -412,53 +412,6 @@ NSString *FrameMac::matchLabelsAgainstElement(NSArray *labels, Element *element)
return nil;
}
// Searches from the beginning of the document if nothing is selected.
bool FrameMac::findString(NSString *string, bool forward, bool caseFlag, bool wrapFlag)
{
String target = string;
if (target.isEmpty())
return false;
// Initially search from the start (if forward) or end (if backward) of the selection, and search to edge of document.
RefPtr<Range> searchRange(rangeOfContents(document()));
if (selection().start().node()) {
if (forward)
setStart(searchRange.get(), VisiblePosition(selection().start(), selection().affinity()));
else
setEnd(searchRange.get(), VisiblePosition(selection().end(), selection().affinity()));
}
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
// If we re-found the (non-empty) selected range, then search again starting just past the selected range.
if (selection().start().node() && *resultRange == *selection().toRange()) {
searchRange = rangeOfContents(document());
if (forward)
setStart(searchRange.get(), VisiblePosition(selection().end(), selection().affinity()));
else
setEnd(searchRange.get(), VisiblePosition(selection().start(), selection().affinity()));
resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
}
int exception = 0;
// if we didn't find anything and we're wrapping, search again in the entire document (this will
// redundantly re-search the area already searched in some cases).
if (resultRange->collapsed(exception) && wrapFlag) {
searchRange = rangeOfContents(document());
resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
// We used to return false here if we ended up with the same range that we started with
// (e.g., the selection was already the only instance of this text). But we decided that
// this should be a success case instead, so we'll just fall through in that case.
}
if (resultRange->collapsed(exception))
return false;
setSelection(SelectionController(resultRange.get(), DOWNSTREAM));
revealSelection();
return true;
}
void FrameMac::submitForm(const ResourceRequest& request)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
......
......@@ -1186,7 +1186,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag
{
return m_frame->findString(string, forward, caseFlag, wrapFlag);
return m_frame->findString(String(string), forward, caseFlag, wrapFlag);
}
- (unsigned)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag
......
......@@ -227,6 +227,12 @@ bool execDelete(Frame *frame, bool userInterface, const String &value)
return true;
}
// FIXME: Come up with a way to send more parameters to execCommand so that we can support all of the features of Frame::findString.
bool execFindString(Frame *frame, bool userInterface, const String &value)
{
return frame->findString(value, true, false, true);
}
bool execForwardDelete(Frame *frame, bool userInterface, const String &value)
{
TypingCommand::forwardDeleteKeyPressed(frame->document());
......@@ -622,6 +628,7 @@ CommandMap *createCommandDictionary()
{ "CreateLink", { execCreateLink, enabledAnyRichlyEditableRangeSelection, stateNone, valueNull } },
{ "Cut", { execCut, enabledAnyEditableRangeSelection, stateNone, valueNull } },
{ "Delete", { execDelete, enabledAnyEditableSelection, stateNone, valueNull } },
{ "FindString", { execFindString, enabled, stateNone, valueNull } },
{ "FontName", { execFontName, enabledAnySelection, stateNone, valueFontName } },
{ "FontSize", { execFontSize, enabledAnySelection, stateNone, valueFontSize } },
{ "FontSizeDelta", { execFontSizeDelta, enabledAnySelection, stateNone, valueFontSizeDelta } },
......
......@@ -64,6 +64,16 @@ Selection::Selection(const Position &base, const Position &extent, EAffinity aff
validate();
}
Selection::Selection(const Range *range, EAffinity affinity)
: m_base(range->startPosition()), m_extent(range->endPosition())
, m_affinity(affinity)
, m_granularity(CharacterGranularity)
, m_state(NONE)
, m_baseIsFirst(true)
{
validate();
}
Selection Selection::selectionFromContentsOfNode(Node* node)
{
return Selection(Position(node, 0), Position(node, maxDeepOffset(node)), DOWNSTREAM);
......
......@@ -44,6 +44,7 @@ public:
Selection();
Selection(const Position &, EAffinity);
Selection(const Position &, const Position &, EAffinity);
Selection(const Range *, EAffinity = DOWNSTREAM);
static Selection selectionFromContentsOfNode(Node*);
......
......@@ -3350,6 +3350,52 @@ DeprecatedValueList<MarkedTextUnderline> Frame::markedTextUnderlines() const
return d->m_markedTextUnderlines;
}
// Searches from the beginning of the document if nothing is selected.
bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag)
{
if (target.isEmpty())
return false;
// Initially search from the start (if forward) or end (if backward) of the selection, and search to edge of document.
RefPtr<Range> searchRange(rangeOfContents(document()));
if (selection().start().node()) {
if (forward)
setStart(searchRange.get(), VisiblePosition(selection().start(), selection().affinity()));
else
setEnd(searchRange.get(), VisiblePosition(selection().end(), selection().affinity()));
}
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
Selection sel = selection().selection();
// If the found range is one that's already selected, find again.
if (!sel.isNone() && Selection(resultRange.get()) == sel) {
searchRange = rangeOfContents(document());
if (forward)
setStart(searchRange.get(), VisiblePosition(sel.end(), sel.affinity()));
else
setEnd(searchRange.get(), VisiblePosition(sel.start(), sel.affinity()));
resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
}
int exception = 0;
// If we didn't find anything and we're wrapping, search again in the entire document (this will
// redundantly re-search the area already searched in some cases).
if (resultRange->collapsed(exception) && wrapFlag) {
searchRange = rangeOfContents(document());
resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
// We used to return false here if we ended up with the same range that we started with
// (e.g., the selection was already the only instance of this text). But we decided that
// this should be a success case instead, so we'll just fall through in that case.
}
if (resultRange->collapsed(exception))
return false;
setSelection(SelectionController(resultRange.get(), DOWNSTREAM));
revealSelection();
return true;
}
unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag)
{
if (target.isEmpty())
......
......@@ -310,6 +310,8 @@ public:
* Returns the text the user has marked.
*/
virtual String selectedText() const;
bool findString(const String&, bool, bool, bool);
/**
* Returns the granularity of the selection (character, word, line, paragraph).
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment