If you're wondering why this relatively long section has been devoted to Navigator 2.0 bugs, when presumably these have all been fixed in Navigator 3.0, remember that it doesn't matter what version of Navigator you run; it is the user's version that counts. Even with Navigator 3.0 released in final form, your scripts may still be run on many Navigator 2.0 platforms.
Navigator 2.0 is sufficiently buggy that apparently no one has attempted to make a complete list of all known bugs (if Netscape has one, they are not releasing it). The reason is simple: trying to produce a definitive list of bugs, for versions 2.0, 2.0.1, and 2.0.2, running on Windows 3.1, Windows 95, Windows NT, the Macintosh, and each of the many flavors of Unix that are supported would be a huge undertaking. Documenting all the bugs in all the versions on all the platforms in detail would probably require a book longer than this one.
For that reason, this section does not attempt to be a definitive list of bugs in Navigator 2.0. Instead, the aim is to inform you of the most serious and most commonly encountered bugs so that you will know how to avoid them and how to work around them when you can't avoid them. In a heterogeneous environment like the Internet, users of your scripts will be running a variety of Navigator versions on a variety of platforms. In effect, a bug on any one popular platform is a bug on all platforms, since the affected code or object cannot be safely used. For that reason, the bugs listed here are not categorized by platform or version.
Note that with release 2.0.2, development stopped on version 2.0 of Navigator. Thus, the bugs listed here will remain in the installed base of Navigator 2.0 browsers.
After describing the commonly encountered bugs, this chapter ends with a short section on debugging techniques that you may find useful for your scripts.
The first possibility you should consider when you encounter a strange bug in a script is to check whether you are violating Navigator's security restrictions. Remember that in versions 2.0.1 and 2.0.2, a script cannot read any properties of a window if the contents of that window came from a different server (i.e., a different host or a different protocol running on the same host) than the script did. The implications of this one restriction are far-reaching and have many implications for referencing properties across windows or frames. In particular, if you see the "Window has no properties" or "access disallowed from scripts at url to documents at url" error messages, you've probably run up against this security hobble.
Because of the nature of the 16-bit architecture of Windows 3.1, there is a limit on the length of scripts that can be handled on this platform. Programmers have reported having problems on this platform when their scripts reach 20Kb to 40Kb in length. A solution is to break the script up into separate modules and load each module into a separate frame or window, and then (carefully!) make function calls between frames or windows. When a script gets this long, another solution you should seriously consider is converting it to a CGI script run on the server, instead of forcing the user to download all the code.
i = .15 alert(i);
You can usually use the Date object to print out the current date, and you can use it to compute the interval (in milliseconds) between two dates or times in the same time zone, but you should probably not attempt more sophisticated uses of it than that.
The String method lastIndexOf() should search a string backward starting from the specified character position within the string (0 for the first character, and string.length - 1 for the last character). In 2.0, however, it begins the search one character before the specified character. The workaround in 2.0 is to add 1 to the desired index.
Using the eval() function crashes Navigator 2.0 and 2.01 when running on Windows 3.1 platforms. This bug is fixed in 2.02, however. The workaround is to avoid eval(), or to use the Navigator object to check what platform the script is running on, and refuse to run on a Windows 3.1/Navigator 2.0 or 2.01 platform.
The Window.open() method takes three arguments, a URL to display in the window, a window name, and a list of browser features that should be present or absent in the new window. Unfortunately, there are bugs with the first and third arguments.
// problems on Mac and Unix var w = open("http://www.ora.com"); // following works on all platforms var w = open(""); w.location.href = "http://www.ora.com";
In addition, the list of window features specified by the third argument to Window.open() does not work on Unix platforms running the X Window System. Width and height may be specified with this third argument, but no other features may be specified--all windows will be created without a menubar, toolbar, status line, and so on.
This situation occurs only in a couple of specific cases. The first is when you have a <SCRIPT> tag that sets properties before a <FRAMESET> tag that defines frames. (Doing this is probably a poor programming practice, by the way.) The second is when you have a script that sets properties in a window and then generates the frames itself by explicitly outputting the necessary <FRAMESET> and <FRAME> tags.
A related bug that serves to make this bug even more mysterious is that frame properties of a Window object are not detected by a for/in loop until they have actually been used once by a script!
When a document that does not contain frames but does contain images is loaded into a window, the Window object's onLoad() event handler may be called before the document is actually completely loaded. In this case, you cannot rely on onLoad() to tell you when the document is fully loaded and all document objects are defined. Therefore, you should be sure to check that the elements you want to access really exist before attempting to use them. For example, you might check that the last element of the last form is created before doing any manipulation of forms. If the element is not created when you check it, you can use setTimeout() to defer the code to be executed and to check again later.
Invoking the alert(), confirm(), or prompt() dialogs from an onUnload() event handler may crash Navigator. The only workaround is to avoid the temptation to do this--don't try to pop up a dialog to say good-bye to the user when they leave your page!
When you query the value of the status property of a Window, you get the value of the defaultStatus property of that Window, even if there is a status message currently displayed by the browser.
Also, on some platforms the defaultStatus message is not properly restored after a status message is displayed. For example, if you set the status property to a special message from the onMouseOver() event handler of a hypertext link, then this message may not be erased when the user moves the mouse off the link. You can address this problem by using setTimeout() to register a function to be executed after a couple of seconds which will explicitly set the status property to be the same as the defaultStatus.
As discussed in Chapter 12, Programming with Windows, Navigator 2.0 does not reclaim any memory used by a page until that page unloads. The setTimeout() method allocates memory each time it is called, even when called repeatedly with the same string argument. Therefore, pages that perform repetitive actions (such as animation) with setTimeout() will allocate more and more memory, and may eventually crash the browser.
These bugs affect the Document object.
You can set the Document.bgColor property at any time to change the background color of a document. Unfortunately, on Unix/X11 platforms, and possibly some others, doing this also erases any text displayed in the window. If you really want to change the document color, you will have to reload or rewrite the document contents, which will cause a noticeable flicker after the color changes.
Calling Document.close() on a document that contains the currently running script may crash the browser. The solution is to not do this. Obviously, any time Navigator crashes, it is a bug. But just as obviously, closing a document that contains the code that is currently being executed is not a useful thing to do, and it is not clear what such an attempt should actually do.
If you call Document.write() on the current document from an event handler or timeout, or call a function that calls Document.write() from an event handler or timeout, you will implicitly close the current document and open a new one to perform the write into. What this does is erase the contents of the document, including the currently executing function or event handler. At best you will get undefined results if you attempt to do this. Often, though, you will crash the browser.
The solution, of course, is to not do this. Note that you can safely overwrite the document of a separate frame or window.
This section describes bugs that affect HTML forms and the elements they contain.
A strange but very commonly encountered bug is the following: If a document contains images and forms, then all the <IMG> tags must have WIDTH and HEIGHT attributes, or the event handlers of the form may be ignored. Usually, adding these tags speeds document loading times, so it is a good idea to get in the habit of using them with all images.
An alternative workaround is to follow your forms with an empty pair of <SCRIPT> and </SCRIPT> tags.
When an HTML form contains more than one element with the same name, then those elements will be stored in an array by that name. This is commonly done for radio buttons and checkboxes. The elements are supposed to appear in the array in the same order that they appear in the HTML source. For obscure reasons, however, if the elements do not have event handlers defined, then they will be placed in these arrays backward. If some of the elements have event handlers and some do not, then they will be placed in the array in some chaotic order. The solution is to provide an event handler for each element, even if it is only a dummy handler like the following:
<INPUT TYPE="checkbox" NAME="opt" VALUE="case-sensitive" onClick="0">
The method property of a Form object specifies the technique used to submit the contents of a form to a server. This property should be a read/write property, but in Navigator 2.0, it is read-only and may be set only when the form is defined in HTML.
Unfortunately, however, the value property of the Text and Textarea objects is a mutable string in Navigator 2.0. Thus, if you assign the value property to a variable, and then you set (or the user types) new text into the Text or Textarea object, the string your variable refers to will change.
The way to prevent this behavior is to force the value property to be copied by value rather than by reference. You can do this by creating a new string object with the + operator. Add the empty string to the value property to create a new string that contains the same text as the value property:
var address = document.form1.address.value + "";