Closed
Bug 273304
Opened 20 years ago
Closed 16 years ago
Search results remain highlighted when turning off highlight again.
Categories
(Toolkit :: Find Toolbar, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: omeyer, Assigned: boissomag)
References
()
Details
Attachments
(4 files, 2 obsolete files)
7.61 KB,
application/x-zip-compressed
|
Details | |
174 bytes,
text/html
|
Details | |
3.34 KB,
patch
|
Details | Diff | Splinter Review | |
3.58 KB,
patch
|
masayuki
:
review-
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.7.5) Gecko/20041122 Firefox/1.0
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.7.5) Gecko/20041122 Firefox/1.0
If you use the fast search bar on the given page to search for 'because m'
(without the quotes) and then pressn highlight all occurances get highlighted.
If you press highlight again. Three highlights remain visible. I expect them to
return to normal.
You can repeat this by pressing reload with turns of highlighting completely and
pressing highlight twice.
Reproducible: Always
Steps to Reproduce:
0. Open the given page.
1. Ctrl+F
2. type: because m
3. press highlight
4. press highlight
Actual Results:
Three 'Because m' are highlighted
Expected Results:
ALL highlightes should be removed.
Reporter | ||
Comment 1•20 years ago
|
||
As google search results will change I included the saved webpage I use to
reproduce the bug.
Reporter | ||
Comment 2•20 years ago
|
||
This seems to correlate with part of the search result being bold. Searching for
'crying ' also produces this result. If you search for 'e but' the word 'but'
becomes bold after pressing highlight.
See also Bug #263849
Comment 3•20 years ago
|
||
Apparently highlighting becomes confused when it has to go outside an element:
highlighting "because" works, highlighting "because " (or anything beyond the
space) fails.
Updated•20 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 4•20 years ago
|
||
With Firefox 1.0 20050126 fr, the highlight function seems very bugged:
When I click "highlight", only the actual found word (which is already
highlighted in blue) becomes highlighted in green, and the highlight function
stays activated even if I click again on it.
Comment 5•20 years ago
|
||
*** Bug 302933 has been marked as a duplicate of this bug. ***
Notice also that in the test case, the "m" become bold.
If you replace "<b>because</b>" by "<b id="__firefox-findbar-search-id">because</b>" then the highlight disappear but the m stay bold.
The highlighted doc is:
<html><head><title>Bug 273304 testcase</title></head><body>
<b><span id="__firefox-findbar-search-id" style="padding: 0pt; background-color: yellow; color: black; display: inline; font-size: inherit;"><b>because</b> m</span></b>aybe
</body></html>
So there is really something wrong in the way the span element is inserted. Why <b> is duplicated ?
--
Firefox 1.5.0.1
The patch should take care of the problem that arise when extractContents duplicate a node. The span element was always inserted in the start container, I added two cases where it can be inserted in the end container or between both.
Ex:
<b>BOLD</b>mid<b>BOLD</b>
1) searching for "idBO"
extractContents = id<b>BO</b>
--> insert in startContainer (which is "mid")
2) searching for "LDmi"
extractContents = <b>LD</b>mi
--> insert in endContainer (which is "mid")
3) searching for LDmidBO
extractContents = <b>LD</b>mid<b>BO</b>
--> insert beetwen start and end
Comment 10•19 years ago
|
||
I'd say that this bug depends on bug 332148.
Comment 11•19 years ago
|
||
Comment on attachment 217017 [details] [diff] [review]
Patch1
> + var bFound = false;
We don't use Hungarian Notation. You should use just 'found'.
> + if (fchild.nodeType == 1 && lchild.nodeType == 1) {
> + var before = endContainer.parentNode;
> + } else {
> + if (fchild.nodeType == 1) {
> + container = endContainer;
> + offset = 0;
> + } else {
> + container = startContainer;
> + offset = startOffset;
> + }
> +
> + var before = container.splitText(offset);
> + }
Why there are |before| variables? I think that the |before| variable should be on outer block.
Updated•19 years ago
|
Assignee: firefox → nobody
QA Contact: fast.find
Assignee | ||
Comment 12•19 years ago
|
||
- Corrected "before" mistake and "bFound"
- There was still some cases where the highlight was not removed correctly
Attachment #217017 -
Attachment is obsolete: true
Comment 13•19 years ago
|
||
Comment on attachment 217310 [details] [diff] [review]
Patch2
I haven't fully understood what exactly this patch does (I'll try to do that later), but I have some general comments about the code added.
>Index: findBar.js
> while ((retRange = finder.Find(gLastHighlightString, searchRange,startPt, endPt))) {
> var startContainer = retRange.startContainer;
> var elem = null;
>+ var found = false;
> try {
> elem = startContainer.parentNode;
> }
> catch (e) { }
>
> if (elem && elem.getAttribute("id") == "__firefox-findbar-search-id") {
>+ found = true;
>+ }
>+
>+ if (!found) {
>+ try {
>+ elem = endContainer.parentNode;
>+ }
>+ catch (e) { }
>+
>+ if (elem && elem.getAttribute("id") == "__firefox-findbar-search-id") {
>+ found = true;
>+ }
>+ }
>+
>+ if (!found) {
>+ try {
>+ elem = startContainer.parentNode;
>+ while (elem=elem.parentNode) {
>+ if (elem.getAttribute("id") == "__firefox-findbar-search-id") {
>+ found = true;
>+ break;
>+ }
>+ }
>+ }
>+ catch (e) { }
>+ }
>+
If I understand this code correctly, I think it can be changed to the following:
function checkNode(aNode) {
if (aNode && aNode.getAttribute("id") == "__firefox-findbar-search-id")
return aNode;
return null;
}
var elem = checkNode(elem) || checkNode(endContainer.parentNode);
if (!elem) {
elem = startContainer.parentNode;
while (elem && !(elem = checkNode(elem)))
elem = elem.parentNode;
}
>+ if (found) {
Then this becomes |if (elem) {|
> function highlight(range, node)
> {
>+ var container, offset, before;
> var startContainer = range.startContainer;
> var startOffset = range.startOffset;
>+ var endContainer = range.endContainer;
> var endOffset = range.endOffset;
> var docfrag = range.extractContents();
>- var before = startContainer.splitText(startOffset);
>+ var fchild = docfrag.firstChild;
>+ var lchild = docfrag.lastChild;
>+
>+ if (fchild.nodeType == 1 && lchild.nodeType == 1) {
>+ before = endContainer.parentNode;
>+ } else {
>+ if (fchild.nodeType == 1) {
>+ container = endContainer;
>+ offset = 0;
>+ } else {
>+ container = startContainer;
>+ offset = startOffset;
>+ }
Indentation is weird above. No need for brackets around single-line statements.
Assignee | ||
Comment 14•19 years ago
|
||
Well, a little explanation using exemple from Comment #9
After highlight we get for each case:
1) <b>BOLD</b>m <span>id<b>BO</b></span> <b>LD</b>
the span element is the parent of the start container
2) In the same way, the span element is the parent of the end container
3) <b>BO</b> <span><b>LD</b>mid<b>BO</b></span> <b>LD</b>
The span element is the parent of both parent's containers in that case. But we don't know how much nested elements can be inside the span element. So we have to loop to find it.
> var elem = checkNode(elem) || checkNode(endContainer.parentNode);
> if (!elem) {
> elem = startContainer.parentNode;
> while (elem && !(elem = checkNode(elem)))
> elem = elem.parentNode;
> }
Ah! It looks better but it's not completely correct. The following works:
try {
var elem = checkNode(startContainer.parentNode);
if (!elem) {
elem = endContainer.parentNode;
while (!checkNode(elem))
elem = elem.parentNode;
}
}
catch (e) { elem = null; }
Comment 15•19 years ago
|
||
(In reply to comment #14)
> > var elem = checkNode(elem) || checkNode(endContainer.parentNode);
> > if (!elem) {
> > elem = startContainer.parentNode;
> > while (elem && !(elem = checkNode(elem)))
> > elem = elem.parentNode;
> > }
>
> Ah! It looks better but it's not completely correct. The following works:
>
> try {
> var elem = checkNode(startContainer.parentNode);
> if (!elem) {
> elem = endContainer.parentNode;
> while (!checkNode(elem))
> elem = elem.parentNode;
> }
> }
> catch (e) { elem = null; }
Why is the try{} block needed (what throws)? Won't !checkNode(elem) infinitely recurse if there are no matches? That code doesn't seem equivalent to that of the patch, either: after looping, the final elem would be the parent of the one that passed checkNode.
Assignee | ||
Comment 16•19 years ago
|
||
> Why is the try{} block needed (what throws)? Won't !checkNode(elem) infinitely
> recurse if there are no matches?
The try{} stop the loop when there is no more parent, so there is no need to test for elem. And without the try{}, only the first match is processed.
> That code doesn't seem equivalent to that of
> the patch, either: after looping, the final elem would
> be the parent of the one that passed checkNode.
I don't think so.
Comment 17•19 years ago
|
||
elem.parentNode returns null if the element has no parent. checkNode(null) returns null, which won't stop the loop. Relying on property accesses on a null object and try/catch blocks for flow control should be avoided, since it can mask other exceptions and is hard to follow.
Assignee | ||
Comment 18•19 years ago
|
||
Well, Ok. But the try catch is needed nevertheless.
Comment 19•19 years ago
|
||
(In reply to comment #18)
> Well, Ok. But the try catch is needed nevertheless.
Why?
Assignee | ||
Comment 20•19 years ago
|
||
I've already answered, even if I don't know the cause. It's on the original script too.
Comment 21•19 years ago
|
||
Yes, I know it's in the current code, but we should not assume that it is required just because it is pre-existing. If there is no apparent reason for it to be there, please remove it.
Assignee | ||
Comment 22•19 years ago
|
||
Since without it the script doesn't work, it will stay here unless someone has a better solution.
Comment 23•19 years ago
|
||
Yes, but *why* won't the script work? You say you don't know why it's needed, then you say that without it it won't work, so which one is it? :)
In other words, what exception is thrown and then caught?
Assignee | ||
Comment 24•19 years ago
|
||
(In reply to comment #16)
> test for elem. And without the try{}, only the first match is processed.
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
That's all I can say currently.
Assignee | ||
Comment 25•19 years ago
|
||
I finally took some time to look at it. There is an exception because elem may not have a getAttribute method. It can be fixed by replacing
startPt.setStartAfter(elem); by startPt.setStartAfter(next); when setting the range for the new iteration.
I'm not sure if it's completely safe though.
Assignee | ||
Comment 26•19 years ago
|
||
Updated using Gavin Sharp idea.
Attachment #217310 -
Attachment is obsolete: true
Assignee | ||
Comment 27•19 years ago
|
||
This is patch3 updated to work with the trunk (previous was for 1.8 branch)
Comment 28•18 years ago
|
||
I don't see this any more using Firefox 2.0 beta 2 on Windows XP.
Comment 29•18 years ago
|
||
Doh, I don't see it any more on that URL (which has probably since changed), but I DO still see it on the 'simplified testcase'. Sorry, I should have checked that out too first.
Assignee | ||
Comment 30•18 years ago
|
||
Comment on attachment 225281 [details] [diff] [review]
Patch3 for trunk
Er... seems like email was not accepted here too.
Explanations of the patch are in Comment #9 Comment #14 and Comment #25
Attachment #225281 -
Flags: review? → review?(masayuki)
Comment 31•18 years ago
|
||
Comment on attachment 225281 [details] [diff] [review]
Patch3 for trunk
> + if ((elem = startContainer.parentNode) &&
> + elem.getAttribute("id") != "__firefox-findbar-search-id")
I don't like this format. I misread the condition in first time. You should use another format like endContainer case.
I.e.,
var elem = startContainer.parentNode;
if (elem && elem.getAttribute("id") != "__firefox-findbar-search-id")
> - this.mStartPt.setStartAfter(elem);
> + this.mStartPt.setStartAfter(next);
I don't think that this change is right...
I think that you need to check whether the node is element node before calling getAttribute, right?
> + var fchild = docfrag.firstChild;
> + var lchild = docfrag.lastChild;
I don't like these names. Please use readable name like others.
I.e., fchild -> firstChild, lchild -> lastChild.
> + if (fchild.nodeType == 1 && lchild.nodeType == 1)
Don't use '1', you should use a constant like here.
http://lxr.mozilla.org/mozilla/source/toolkit/components/typeaheadfind/content/findBar.js#605
Attachment #225281 -
Flags: review?(masayuki) → review-
Assignee | ||
Comment 32•18 years ago
|
||
(In reply to comment #31)
> > - this.mStartPt.setStartAfter(elem);
> > + this.mStartPt.setStartAfter(next);
>
> I don't think that this change is right...
In fact, with setStartAfter(elem), it can stop twice on the same result because the new start point will end up before the reinserted search string.
> I think that you need to check whether the node is element
> node before calling getAttribute, right?
Yes, but this would only hide the problem.
Comment 33•18 years ago
|
||
There's rumors on the Internets that pkasting has a patch for this.
Comment 34•18 years ago
|
||
(In reply to comment #33)
> There's rumors on the Internets that pkasting has a patch for this.
I do not have a patch for this.
However, this bug will be auto-fixed by bug 263683 if I ever fix that.
Comment 35•18 years ago
|
||
This bug came up while I was doing litmus testing on Minefield.
As described above the highlighting does not remove.
Steps to reproduce:
1. Go to www.mozilla.org
2. Ctrl+f, type "firefox" in find box, click highlight all
3. Replace "firefox" with "mozilla" in find box.
4. Unclick highlight all
Both "mozilla" and "firefox" remain highlighted.
For verification, I tested the same on FF2.0.0.3. This problem appears to be isolated to Minefield.
Updated•17 years ago
|
Product: Firefox → Toolkit
Comment 37•16 years ago
|
||
Bug 263683 is now fixed on trunk, so this should be fixed too.
You need to log in
before you can comment on or make changes to this bug.
Description
•