Closed Bug 147811 Opened 23 years ago Closed 16 years ago

JavaScript menus do not work?

Categories

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

x86
Windows 98
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: avs, Unassigned)

References

()

Details

Attachments

(3 files, 1 obsolete file)

From Bugzilla Helper: User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.0rc3) Gecko/20020523 BuildID: 2002052306 An image has a link to a menu defined in JavaScript as follows: <a href="javascript:window.showMenu(window.FOO);"><img SRC="FOO.jpg" ALT="foo menu" border="0"></a> However, nothing happens when clicking on the link. On Netscape 4.75, a menu opens and gives a possibility to open a link from the menu. The menu has been defined in JavaScript like this: function onLoad() { loadMenus(); } function loadMenus() { window.FOO = new Menu("FOO"); FOO.addMenuItem("Foo 1", "top.window.location='http://foo.com/'"); FOO.addMenuItem("Foo 2", "top.window.location='http://foo2.com/'"); FOO.addMenuSeparator(); FOO.addMenuItem("Close", "hideMenu"); FOO.bgColor = "#FFEEFF"; FOO.menuItemBgColor = "white"; FOO.fontColor ="0000bb"; FOO.fontSize = 8; FOO.fontWeight = "bold"; myMenu.writeMenus(); if (document.all) { loadMenus(); } Reproducible: Always Steps to Reproduce: 1. Go to a page having a JavaScript menu as described in Description 2. Click on the image link Actual Results: Nothing Expected Results: A menu should have appeared, allowing me to select a link (it does on Netscape 4.75).
If you don't provide a full working example it's impossible to see what is the problem, but it seems to be that the menus are only designed for IE and NS4
You use document.all, which is IE-only JavaScript code. Propose to mark INVALID.
Reassigning to DOM Level 0. This does look like a coding error, but there is not enough information to make a conclusion. Recall that only Microsoft IE supports |document.all|. Therefore I don't see how your code snippet if (document.all) { loadMenus(); } would work in Netscape 4.75, as you say. Antti, would it be possible for you to attach a reduced testcase by going to the URL of this bug, and then the "Create a New Attachment" link? This could be just a small menu with links pointing to public sites, just enough to see what the problem is - Otherwise, we can't make a final determination; thanks -
Assignee: rogerl → jst
Component: JavaScript Engine → DOM Level 0
QA Contact: pschwartau → desale
Added an example URL on a publicly available site and edited out some crud that was for IE only.
function writeMenus(container) { if (!container && document.layers) { if (eval("document.width")) container = new Layer(1000); } else if (!container && document.all) { if (!document.all["menuContainer"]) document.writeln('<SPAN ID="menuContainer"></SPAN>'); container = document.all["menuContainer"]; } So... Mozilla does not support document.layers or document.all. So |container| is never set. Then later you take the |if (!container) return;| early return. You want a document.getElementById branch here, methinks.
Boris is correct, but we actually have another problem as well. If you set breakpoints in Mozilla's JavaScript Debugger, you'll see that the writeMenus() function doesn't even get called in Mozilla. It is invoked this way by the script: <SCRIPT> function onLoad() {loadMenus();} function loadMenus(){ etc. etc. FOO.writeMenus();} </SCRIPT> The intention is to make the window onLoad handler call FOO.writeMenus() for us, but this is not working. Here is a simpler example: <SCRIPT> function onLoad() {alert('Hello');} </SCRIPT> When you load this in NN4.7, you get the alertbox. But in IE6 or Mozilla, you don't: the alert is not fired. Let me ask Boris and Johnny: is that correct behavior?
Status: UNCONFIRMED → NEW
Ever confirmed: true
Note we cab modify the script to make sure the writeMenus() function does get called, e.g. by commenting out these two lines: /////////////////function onLoad() { loadMenus(); ///////////////////////////////////} then we see exactly what Boris said above. Here is a longer excerpt from the writeMenus() function: function writeMenus(container) { if (!container && document.layers) { if (eval("document.width")) container = new Layer(1000); } else if (!container && document.all) { if (!document.all["menuContainer"]) document.writeln('<SPAN ID="menuContainer"></SPAN>'); container = document.all["menuContainer"]; } if (!container && !window.delayWriteMenus) { window.delayWriteMenus = this.writeMenus; window.menuContainerBgColor = this.menuContainerBgColor; setTimeout('delayWriteMenus()', 3000); return; } container.isContainer = "menuContainer" + menuContainers.length; etc. Because |document.layers| and |document.all| are non-W3C syntax not supported in Mozilla, the first time through this function we end up doing window.delayWriteMenus = this.writeMenus; and setTimeout('delayWriteMenus()', 3000); and returning. But we end up passing through the same function again, three seconds later. This time we make it to the line container.isContainer = etc. This causes an error, since |container| has never been set. To see this, Just comment out the lines I indicated above, and load the URL with the Mozilla JavaScript Console open. Three seconds after you load, you will see this error in the Console: Error: container has no properties Source File: (path to)/menu.js Line: 98
SUMMARY: 1. The site does not have a valid codepath for Mozilla. 2. There is still a question in Comment #6 about the use of onLoad handlers
Note this DOES work in Mozilla and IE6 as well as NN4.7: <SCRIPT> window.onload = function() {alert('Hello')} </SCRIPT> whereas the approach in Comment #6 does not, even if we are careful about using lower-case spelling of "onload": <SCRIPT> function onload() {alert('Hello');} </SCRIPT>
Blocks: 113492
Mass-reassigning bugs to dom_bugs@netscape.com
Assignee: jst → dom_bugs
I fail to see why function onLoad() { ... } would be called when the page is loaded if there is no <body onload="onLoad();"> or some such. If NS4 did that it doesn't make sense and imho shouldn't be emulated. Based on the comments and the analysis I suggest INVALID. Thoughts?
It worked in NS4 because it mapped "function onLoad" to "window.onload". We don't do that. We don't even map "function onload" to "window.onload", (which is arguably a bug, actually). But JS is case-sensitive, so "function onLoad" shouldn't do anything in any case.
> We don't even map "function onload" to "window.onload", (which is arguably a > bug, actually). We don't? That is a bug. Last I checked, though, we do. What's a testcase? /be
If I change that to window.onload = function onload() { alert('aaa'); } it works.
I bet the bug there is that the function declaration just defines the property on the JSObject and never ends up calling nsWindowSH::SetProperty
jst, did I regress this by redoing the way declared functions are defined (by prolog bytecode generated for each declaration)? (Erk, mid-air with bz saying the same thing: "I bet the bug there is that the function declaration just defines the property on the JSObject and never ends up calling nsWindowSH::SetProperty"). Or do we not try calling window.onload on each load event, where we once did? What does IE do with function onload? The old days, sigh, may matter so little now that we can WONTFIX every aspect of this bug (certainly, we shouldn't try to call onLoad). /be
Brendan, I can't say for sure that that's what regressed it, but it sure seems like it could be that. If I do "onload = onload;" after the function declaration in the above testcase, the onload function is called on load, w/o that it's not. Want a separate bug on this problem, since it's not exactly the problem described in this bug?
WONTFIX implies evangelism, of course. But we can fix things so function onload, when defined per ECMA-262 (created, so as to remove any pre-existing proprety), by checking for 'onload' as the id passed to nsWindowSH::AddProperty. /be
jst: what does IE do? Probably it doesn't call a function onload (guessing, based on naive ECMA implementation). We're violating compatibility, OTOH, and every little bit hurts, even if the pain is worth it (as in the case of dropping onLoad support). nsWindowSH::AddProperty can be modified easily to fix the bug (separate bug is ok, or keep talking here; I'm not picky). /be
Hmm, I was expecting IE to call the onload function by just defining it, but it doesn't! And even worse, if you define a function named onload, there doesn't seem to be anything you can do to the window object to make IE call that function on load, i.e. setting window.onload = onload doesn't do anything in this case (however, if no onload function is defined, then setting window.onload to some other function does cause that other function to be called on load). Ok. Let's keed talking here for now, since we have testcases etc here already.
W3C DOM working group owes us a DOM level 0 spec, dammit. I think we should restore compatibility with what we had before the ECMA changes, or the DOM-via-XPConnect changes, or whatever changes stopped function onload(){} at top level from defining window.onload. jst, care to do an AddProperty patch, so we can see how big it is? /be
Attachment #135604 - Attachment is obsolete: true
Attachment #135605 - Flags: superreview?(brendan)
Attachment #135605 - Flags: review?(caillon)
Attachment #135605 - Flags: review?(caillon) → review+
Comment on attachment 135605 [details] [diff] [review] Same thing for non-global scopes where event listeners belong. + if (!JSVAL_IS_STRING(id) || flags & JSRESOLVE_ASSIGNING) { Nit: overparenthesize the & expression (I do this to avoid brainprint for the case where parens are needed: == or != operators with &|^ operands). Thanks for doing this, looks nice and small, and may be worthwhile even if IE screws the pooch. /be
Attachment #135605 - Flags: superreview?(brendan) → superreview+
Thanks for the reviews, fix checked in. Leaving bug open to figure out if more is needed here.
I had to back out the change since it caused tinderbox to go orange due to a testing goofup on my end. The fix is correct, but I did most of my testing using mfcembed and the one time I did start Mozilla to see that things were still working I must have started the wrong build, since this patch makes Mozilla crash on startup. The problem is that we're now registering event handlers while compiling scripts in the XUL documents, and that causes us to try to atomize a JS string using a null cx since there's no script running at the time. Patch coming up that protects against doing that.
Attachment #135768 - Flags: superreview?(brendan)
Attachment #135768 - Flags: review?(caillon)
Comment on attachment 135768 [details] [diff] [review] Don't try to internalize JS strings on a null cx (diff -w) Sure -- I wouldn't have caught this by reviewing. But who runs mfcembed these days? ;-) /be
Attachment #135768 - Flags: superreview?(brendan) → superreview+
Comment on attachment 135768 [details] [diff] [review] Don't try to internalize JS strings on a null cx (diff -w) yeah, what are you doing running mfcembed? :) r=caillon
Attachment #135768 - Flags: review?(caillon) → review+
Thanks! (Hey, I used mfcEmbed since I can't debug mozilla while running an installed version! :-) Fix checked in again.
partly wfm Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.6b) Gecko/20031118 As the fix got checked in 11/17/2003 17:59, I was assuming BuildID 2003111808 would contain it. The testcase from Attachment: is working, I don´t see a menu however, using the URL from the URL: field: http://www.iki.fi/avs/mozjs.html Netscape 4.79 shows the menu.
See comment 12 and comment 16. The site needs evangelizing no matter what.
Last post here was over five years ago. The URL is dead. The site http://www.asiantuntijat.org/~avs/ looks like it works, although it doesn't seem to have any Javascript menus. Resolving this as fixed as there was a check-in.
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: