Closed Bug 9550 Opened 25 years ago Closed 23 years ago

window.find() is returning undefined

Categories

(Core :: DOM: Core & HTML, defect, P3)

defect

Tracking

()

VERIFIED FIXED
mozilla1.0

People

(Reporter: desale, Assigned: jst)

References

Details

(Keywords: arch, helpwanted, testcase, Whiteboard: [Need ETA] [PDT-])

Attachments

(4 files, 3 obsolete files)

Method window.find() is returning undefined. So either its not
implemented or not working.

PRODUCT: Seamonkey [Apprunner/Viewer]
BUILD: 07-08-08.
OS: Win95, WinNT, Win98, MacOS.

STEPS TO REPRODUCE:
1] Please copy code I'm providing. Save as HTML file.
2] Open this HTML file in Apprunner as well as Viewer.
3] You'll see the return value of window.find() getting
printed on
screen.

NOTE: In actual code [testcase] the method is used without parantheses in order
to know what it is exactly.

EXPECTED RESULTS:
window.find() = function find() { [native code] }

ACTUAL RESULTS:
window.find() = undefined

CODE:

<html>
<head>
<title>Test Page</title>
</head>
<body>
<form name="workform">
<SCRIPT LANGUAGE="JavaScript">
document.writeln("window.find() = ");
document.writeln(window.find);
</SCRIPT>
</form>
</body>
</html>

END OF CODE
Whiteboard: [TESTCASE] window.find() must be implemented
the next one. updated status to "[TESTCASE]..." standard.
law, do you own the Find stuff?  Would you be willing to take this bug?

I think we don't need this for beta, myself.
Assignee: vidur → law
OK, I think I can help out here.  Agreed that it's post-beta (I don't think this
is too crucial for many sites out there).  "Find" via the UI does work.

I wouldn't be surprised if we don't see more bugs like this.  I opened an
identidcal one for window.onresize last week.
Whiteboard: [TESTCASE] window.find() must be implemented → [HELP WANTED][TESTCASE] window.find() must be implemented
Assignee: law → sford4
Status: NEW → ASSIGNED
Whiteboard: [HELP WANTED][TESTCASE] window.find() must be implemented → TESTCASE] window.find() must be implemented
Whiteboard: TESTCASE] window.find() must be implemented → [TESTCASE] window.find() must be implemented
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → LATER
This will have to wait until the new webshell lands around mid-november
Status: RESOLVED → VERIFIED
OK.
This one was closed almost one & half yesr back with Later Mark & we expect it 
to fix some time.

Reopening this one.
Status: VERIFIED → REOPENED
Resolution: LATER → ---
SPAM: mozilla 0.9 (and M1, and 0.8.1, etc.) has left the building.  please
update the target milestone so we can get a good idea of what's left for 0.9.1.
Johhney, 
This one was closed with LATER resolution & re-opened it today.
This is just not implimented, so with backward compatibility it goes for 
nsbeta1.
adding keywords nsbeta1 & mozilla0.9.1.

Please update Target Milestone for this. 
Assignee: sford4 → jst
Status: REOPENED → NEW
Hardware: PC → All
Whiteboard: [TESTCASE] window.find() must be implemented → window.find() must be implemented
Target Milestone: M15 → ---
what should window.find() do? It should be easy to hook up; see findUtils.js.
Updating the keyword to propose mozilla1.0. In case bug 84718 doesn't get 
fixed, I'd at least like my bookmarklet to still work. (Of course window.find 
is also useful in other situations.)

Can I suggest that the functionality be somewhat enhanced from window.find in 
Navigator 4.x? In 4.x it took the following params: stringToFind, 
caseSensitive, and backwards. If stringToFind is omitted it shows the Find 
dialog. If caseSensitive is omitted it assumes false (case insensitve find), 
and if backwards is omitted it defaults to false (finds forward). It returns 
true if stringToFind is found. 

I'd like to suggest adding three additional parameters: wholeWord, wrapAround, 
and showDialog. wholeWord will be false if omitted. If included, it will force 
finding whole words and not substring. (Of course this assumes that the find 
will support this. See bug 14871.) wrapAround will force the find to wrap 
around to the top (or bottom) when it finds the last (or first) match on the 
page. showDialog will force the dialog to always be on, even if the 
stringToFind is included. If showDialog is set, window.find will find the first 
match and also show the Find dialog. I believe that if these are included after 
the existing params and have defaults it won't cause any compatability problems.

If this bug is the wrong place for this, just tell me and I'll log a new bug. I 
just figured that since it's going to need to be implemented anyway, might as 
well enhance it while working on it.
Keywords: mozilla0.9.1mozilla1.0
Targetting for mozilla1.0
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla1.0
OK let's discuss design issues. I have implemented this in my tree, but I have
several questions.
1) Six args, like tpowell suggested, is a serious usability problem. Even I, who
implemented the function, couldn't remember what each arg was for without
looking at the interface. Since wholeWord doesn't seem to work yet in the Find
API, I suggest the following args:
boolean find(in DOMString str, in boolean caseSensitive, in boolean backwards,
in boolean wrapAround);
showDialog imho is not necessary because if you use an empty string, the dialog
will pop up. wholeWord is not yet implemented it seems (correct me if I'm wrong).
4 arguments is much more reasonable.
2) I had to change some js in finddialog.js because when I pass the
nsIWebBrowserFind as argument to OpenDialog, it becomes an nsISupports, so I
have to QueryInterface back to nsIWebBrowserFind. I also have to explicitely
initialize the UI of the dialog with the attributes of the find instance. Does
that cause a problem to anyone?
3) In my patch I QueryInterface only to nsIWebBrowserFind, not to
nsIWebBrowserFindInFrames, because I am not sure what the behavior of
window.find() in a framed page should be. Anyone has a good theory?

Anyway after these issues are debated, I'll post the patch (which is pretty
straightforward).

Thanks in advance for your comments!
I'm not terribly concerned about the complexity of the API [have you looked at 
the number of params for window.open() lately? :-)] because I'm interested in 
providing the functionality necessary. Since most params are optional, I don't 
see this as a big deal. I'm requesting these additional params in order to 
improve my find bookmarklet, and also because it'd be useful in web 
applications.

1) Removing WholeWord is fine by me, since it doesn't work yet. ShowDialog 
would be useful in my opinion because there's no other way to mimic the 
behavior of an application find button. In applications, the find dialog 
usually pops up with default text and remains visible. There's no way to do 
that with the current API.

2) I don't know enough to comment about this.

3) I'm not sure what proper behavior is here, but searching a single document 
makes more sense to me. My find bookmarklet works by searching a frame in N4 
once you give a frame focus. Somehow it appears the get the appropriate frame 
document context and does the find in just that document. Typing javascript:void
(window.find('stringtofind',1)) in the URL bar of a frameset does not seem to 
get past the frameset and so it fails. (Perhaps this really should be 
document.find? It seems that little thought was given about what to do with 
framesets when this was introduced with N4. Maybe there should be a 
document.find in addition to a window.find that does the find in the entire 
frameset.) I'd be happy with the equivalent to N4 behavior here.
As near as I can tell, IE uses document.body.createTextRange().findText
(stringToFind) to find text in the page. Getting the text selected is a little 
more complicated, and this doesn't support find again without extra work: 
t=document.body.createTextRange();var s=t.findText(stringToFind);if(s)t.select
(); IE also supports flags for match backwards, match case, wholeword, etc. 
http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/findText.asp
> Since most params are optional, [...]
Since the call goes directly to XPConnect, this is not true (correct me if I'm
wrong). Is it possible to declare overloaded functions like
GlobalWindowImpl::Find() { /* ... */ }
GlobalWindowImpl::Find(nsAReadableString& aStr) { /* ... */ }
? How does window.open() deal with different number of arguments?

About the frames, it's likely that it will work that way in Mozilla too,
although I haven't yet tested it.

About IE: I rather reuse the existing Find mechanism instead of implementing a
new Range-based find system :P

jst, I tested NS4 and unfortunately it does admit a variable number of arguments.
Do we want to do something similar?
Sorry, I made some assumptions. As a general rule, JavaScript allows a variable 
number of params in function calls. Find should definitely support this for 4xp 
compatibility (adding keyword). See my 2001-06-20 11:15 comment above for the 
default values when params are omitted.

About IE: I agree that window.find is a better technique. I included IE 
information mainly to point out how beautiful this feature is in 
Netscape/Mozilla, but also to show that it's document related in IE.
Keywords: 4xp
Fabian, the most important reason for implementing this method is for
compatibility with 4.x so first priority is to make the method work like it did
in 4.x. Once that's done we have the option of extending the functionality if we
so choose.
OK I think I got it right this time. I checked the documentation on DevEdge and
all the behaviors described there are correct. Except that they state that
"caseSensitive: Boolean value. If true, specifies a case-sensitive search. If
you supply this parameter, you must also supply backward."
In my implementation you don't have to supply the "backward" argument. I guess
that's really an enhancement.
I didn't implement the new features yet, I just wanted to get the
backwards-compatibility complete like jst suggested. Patch coming up.
When reviewing, please check very carefully my string usage, because I really
got confused at some point in all the strings. 
Thanks in advance!
- No need for FindInternal() to be virtual, use nsresult and not NS_IMETHOD as
the return type of the method in the header file.

- To convert the arguments to booleans, use JS_ValueToBoolean() which will
convert any type of value to booleans, not only boolean values, do something
like this:

  if (argc > 1 && !JS_ValueToBoolean(cx, argv[1], &caseSensitive))
    caseSensitive = PR_FALSE;

  if (argc > 2 && !JS_ValueToBoolean(cx, argv[2], &backwards))
    backwards = PR_FALSE;
 
- This code will leak string data:

+  nsAutoString searchString(aStr);
+  rv = finder->SetSearchString(searchString.ToNewUnicode());

do something like this in stead:

+  rv = finder->SetSearchString(PromiseFlatString(aStr).get());

- No need to QI this to a nsIDOMWindowInternal, this is an nsIDOMWindowInternal
so this code:

+      nsCOMPtr<nsIDOMWindowInternal> win =
+        getter_AddRefs(NS_STATIC_CAST(nsIDOMWindowInternal *, this));
+      if(win && finder) {
+        nsCOMPtr<nsIDOMWindow> dialog;
+        rv = win->OpenDialog(...);

can be changed to this:

+      if(finder) {
+        nsCOMPtr<nsIDOMWindow> dialog;
+        rv = OpenDialog(...);

You might run into security manager trouble with this code (since JS is not
supposed to be able to open chrome urls), if you do let me know and we'll work
around that.

- There's a few indentation problems in FindInternal() that should be cleaned up.

Other than that, the changes look good, it seems like we could easily add
support for searching for entire words, wrap around, and searching in frames w/o
breaking backwards compatibility by simply supporting more arguments, you wanna
code that too while you're at it? :-)

Thanks alot for implementing this in mozilla!
Comment on attachment 48458 [details] [diff] [review]
Implement window.find() with variable arguments

Addressed jst's comments and added wrapAround and showDialog flags.
Attachment #48458 - Attachment is obsolete: true
Comment on attachment 48573 [details] [diff] [review]
Implement window.find(), third revision. Add features.

Ok the new patch adds wholeWord and searchInFrames as discussed on IRC. There is only one bug left: If we opened the find dialog via window.find(), we can open a second find dialog by using the Find in this Page menuitem of the search menu. This is because the menuitem checks for the window.findDialog var. I tried to fix it but jag said that might break embedding and I'm not supposed to access the XUL window. So here is a dilemna.
Warning: patch not yet tested in frames. Will do later. sfraser, I'd appreciate your feedback on the finddialog.js changes. Thanks!
Attachment #48573 - Attachment is obsolete: true
Attachment #48573 - Flags: needs-work+
This is awesome! Many many thanks.

How does it know where to begin the find? It appears that 4.x starts where you 
are on the page. (Or perhaps where your selection is.) Does this do the same? 
For example, can I do a find for a and then do a find b to give me the first b 
after the first a? Or does the find for b reset the position? Would a "start at 
top" option be useful? See bug 87037. 

How does this patch affect the browser Find feature? Could it be used to fix 
bug 14871, for example? It sounds like you implemented what's required. It'd be 
nice if the window.find function provided everything that's necessary for the 
Find dialog.

Sorry if this is extending the bug. I'd be more than happy if what you have now 
was checked in and more work could be done in another bug.
Answer to both requests is unfortunately no:
1) window.find() as I implemented it works exactly the same way as the Find
dialog does. It starts the search from the current selection or from the top if
nothing is selected (at least from what I understand). And I don't want to
implement bug 87037 because I like the current behavior better.
2) Since I re-use the current Find API, which doesn't support whole word
searches, the "wholeWord" argument of window.find() is only implemented for
future-compatibility. It doesn't do anything at the moment.
One last thing about these changes, if "gecko" is running embedded in something
other than Mozilla/Netscape6x, the window mediator is most likely not available.
To make this code work a little better in that case you should change the code:

+    nsCOMPtr<nsIWindowMediator> windowMediator =
+             do_GetService(kWindowMediatorCID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIDOMWindowInternal> findDialog;
+    windowMediator->GetMostRecentWindow(NS_LITERAL_STRING("findInPage").get(),
+                                        getter_AddRefs(findDialog));

to:

+    nsCOMPtr<nsIWindowMediator> windowMediator =
+      do_GetService(kWindowMediatorCID);
+
+    nsCOMPtr<nsIDOMWindowInternal> findDialog;
+
+    if (windowMediator) {
+      windowMediator->GetMostRecentWindow(NS_LITERAL_STRING("findInPage").get(),
+                                          getter_AddRefs(findDialog));
+    }

Other than that, sr=jst. Thank you Fabian for implementing this method!
Attachment #50082 - Attachment is obsolete: true
Attachment #50082 - Flags: needs-work+
sicking, do you have time review the patch? Thanks a lot.
One minor nit:

+    nsCOMPtr<nsIWindowMediator> windowMediator =
+      do_GetService(kWindowMediatorCID, &rv);

'rv' is not used anywhere, so you could remove that argument from
do_GetService() as I did in my above comment. Not a showstopper, but please
remove it before checking in if you remember to.
Comments:

+static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); // For 
window.find()

Can't you use a contract ID instead?

+// Scriptable version of window.find() which takes a veriable number of

spelling.

+NS_IMETHODIMP
+GlobalWindowImpl::Find(PRBool *aReturn)

'aReturn' needs a better name. What does it mean? 'aDidFind' might be better.

+  rv = sXPConnect->GetCurrentNativeCallContext(getter_AddRefs(ncc));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!ncc) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }

You might want to put an NS_ASSERTION here, to tell people who try to call this 
routine from C++ that they are doing something wrong.

+  if (argc > 1 && !JS_ValueToBoolean(cx, argv[1], &caseSensitive)) {
+    // Second arg is the case sensitivity
+    caseSensitive = PR_FALSE;
+  }

Why this pattern of setting the value back to false in the case of failure. Is it 
the case that JS_ValueToBoolean() can mess with the out param even when it fails?

+nsresult
+GlobalWindowImpl::FindInternal(nsAReadableString& aStr,
+                               PRBool caseSensitive,
+                               PRBool backwards,
+                               PRBool wrapAround,
+                               PRBool showDialog,
+                               PRBool wholeWord,
+                               PRBool searchInFrames,
+                               PRBool *aReturn)

It seems wrong that the 'showdDialog' is in the middle of the other params. I 
would expect it to be either the second, or the penultimate parameter.

+
+  // Scriptable version of find(). See nsIDOMWindowInternal for the
+  // non-scriptable version. It takes 6 optional arguments.
+  boolean                   find();                

Say what the optional arguments are.

+  dialog.findKey.value           = gFindInst.searchString ? 
gFindInst.searchString : findService.searchString;
+  dialog.caseSensitive.checked   = gFindInst.matchCase ? gFindInst.matchCase : 
findService.matchCase;
+  dialog.wrap.checked            = gFindInst.wrapFind ? gFindInst.wrapFind : 
findService.wrapFind;
+  dialog.searchBackwards.checked = gFindInst.findBackwards ? 
gFindInst.findBackwards : findService.findBackwards;

Is this right? Or do you want

  dialog.findKey.value           = gFindInst ? gFindInst.searchString : 
findService.searchString;
etc?
"It seems wrong that the 'showdDialog' is in the middle of the other params. I 
would expect it to be either the second, or the penultimate parameter."

showDialog can't be second because that would break backward compatability with 
4.x. It makes sense for it to be last, after searchinframes.
>+static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); // For 
>window.find()
>Can't you use a contract ID instead?
The contract ID is only used in js files for some reason. In cpp files the way I
did it is used. Any good reason to change it?

>Why this pattern of setting the value back to false in the case of failure. Is
>it the case that JS_ValueToBoolean() can mess with the out param even when it
>fails?
I trusted jst on this one (see his comment of 2001-09-06).

>It seems wrong that the 'showdDialog' is in the middle of the other params. I 
>would expect it to be either the second, or the penultimate parameter.µ
Fixed.

>+  dialog.findKey.value           = gFindInst.searchString ? 
>gFindInst.searchString : findService.searchString;
>Is this right? Or do you want
>dialog.findKey.value           = gFindInst ? gFindInst.searchString : 
>findService.searchString;
I really want the former because gFindInst will always evaluate to true:
findUtils.js passes a nsIWebBrowserFind instance, but its attributes are null.
However window.find() passes a nsIWebBrowserFind instance whose attributes are
already initialized.

The rest is fixed.



Comment on attachment 50710 [details] [diff] [review]
Patch incorporating comments of smfr

r=sfraser
Attachment #50710 - Flags: review+
Comment on attachment 50710 [details] [diff] [review]
Patch incorporating comments of smfr

sr=jst
Attachment #50710 - Flags: superreview+
CC'ing bz who kindly volunteered to check this in. Thanks bz!
checked in on trunk.
Status: ASSIGNED → RESOLVED
Closed: 25 years ago23 years ago
Resolution: --- → FIXED
Yes! As described in bug 84718, my Find bookmarklet available from
http://www.worldtimzone.com/bookmarklets.html now works in Mozilla. Thanks to
everyone who made this happen. I still haven't tested the new parameters, but
the basic find for a string in a window is working.
Reopening this bug to explore the possibility of this fix getting into branch.
We already have fix for it checked in trunk.
I think this bug is pretty important because.
1] It is backward compatibility issue, so there couldbe lots of websites out 
there using this.
2] Window.find() is not working at all, so we are missing complete feature.

example webiste its not working on http://www.worldtimzone.com/bookmarklets.html

Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Nominating for nsbranch. [We have fix in hand on trunk]
Keywords: nsbranch
Did anyone test this patch extensively besides me? Tpowell, have you had time to
test more than your bookmarklet? I don't think we should send this patch on the
branch if nobody else tested it.
The chances of getting this checked in on the branch are getting slim, I
wouldn't hold my breath on this being accepted on the branch :-(
clayton, nisheeth is on vacation, can you let us know, if this one is nsbranch+
worthy?
Whiteboard: window.find() must be implemented
Whiteboard: [Need ETA]
I don't think it is, fwiw.
Did 6.1 ship this way? Is this code path only exercised when it hits the Javascript?
6.1 shipped w/o support for window.find(), IMO window.find() is not used on
enough sites for us to risk putting this on the branch at this time.
gonna mark this one PDT- per JST's comments.
Whiteboard: [Need ETA] → [Need ETA] [PDT-]
IMHO this should be put on the branch. N6 is the browser that is most 
compatible to all kind of standards, but now it does not fully implement 
ECMAScript.
This has nothing to do with our support for ECMAScript, this is purely a DOM0
(an unwritten defacto standard) compatibility issue.
Testing has shown that window.find works correctly as a bookmarklet, but not 
when typing directly on the URL, for example, javascript:alert(window.find
('find')). This is different behavior than Nav4, which let you type this as a 
URL. As a bookmarklet, the three parameters for Nav4.x compatability 
(StringToFind, caseSensitive, backwards) seem to be working fine. With all 
parameters omitted "window.find()", it also correctly pops up the find dialog. 
The wrapAround parameter works correctly "window.find('find',0,0,1)". I have 
not tested the other parameters yet.

I'd love to see this in a Netscape product again, but can't judge what risk 
this has.
Blocks: 104166
It appears that using javascript: urls in the url bar is not consistent
depending on the url (?!?) I'll file a bug about it.
For example, at bugzilla.mozilla.org I can type
javascript:void(document.bgColor = "blue");
and the background color of the page will turn to blue.
However the same code at www.mozilla.org will do nothing.
It also does work on file:/// pages.
Please try this code:
javascript:void(window.find("yourString"));
at bugzilla.mozilla.org or at a local file and see if it works.
Blocks: 107065
Keywords: nsbranch
Marking FIXED since this is not going on the branch apparently ([PDT-] in the
whiteboard) and there's no point in keeping it open any longer. I'll file the
urlbar problems as another bug.
Status: REOPENED → RESOLVED
Closed: 23 years ago23 years ago
Resolution: --- → FIXED
verified.
Status: RESOLVED → VERIFIED
The find dialog in firefox has a "highlight all" flag.
It would be nice if this could be used in the API also.
This way I could mark for example all words "look here" by javascript.
Is it possible to use it with searchInFrames==true AND ShowDialog==false ?
I'm using it in userscript ( source: http://userscripts.org/scripts/review/8356 ), and I get 'Error: Access to restricted URI denied' when I set parameters as described.
Anyway, otherwise it works pretty well. Neat!
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: