--<> --<>

Auto menu

This file illustrates a combination of the linker.js and popup.js techniques.

The idea is to insert popup menus automatically just as linker.js inserts links.

Here is an example of the linker.js style of data array:


var replacements =
[[["directories","directory"], "http://www.yahoo.com",],
 [["google"],      "http://www.google.com","../../words/google.gif"],
 [["find"],        "http://find.com","find.gif"],
 [["free"],        "http://www.fsf.org","free.gif"],
 [["links"],       "http://www.links.com",],
 [["my"],          "http://my.org","my.gif"]];

Notice that it provides a list of texts to be replaced but only a single replacement. To implement menus all we need to do is replace the link and image URLs with an array. Of course we have to rewrite the code that inserts the link and we also have to rewrite the code that turns the array into a more program friendly internal form because it expects the outer array to be composed of arrays each containing three items.

I think that the easiest way is to make the replacements into an array as well:

var replacements =
[[["directories","directory"],[["http://www.yahoo.com"]]],
 [["google"],     [["http://www.google.com","../../words/google.gif"]]],
 [["find"],       [["http://find.com","find.gif"]]],
 [["free"],       [["http://www.fsf.org","free.gif"]]],
 [["links"],      [["http://www.links.com"]]],
 [["my"],         [["http://my.org","my.gif"]]]];

Of course that doesn't hold enough information for the menu because there is no text for the menu link so add it as follows:

var replacements =
[[["directories","directory"],[["", "http://www.yahoo.com"]]],
 [["google"],     [["", "http://www.google.com","../../words/google.gif"]]],
 [["find"],       [["", "http://find.com","find.gif"]]],
 [["free"],       [["", "http://www.fsf.org","free.gif"]]],
 [["links"],      [["", "http://www.links.com"]]],
 [["my"],         [["", "http://my.org","my.gif"]]]];

Notice that in each case the text is empty; that's because I have only provided one replacement which means that a menu will not be created just a single href anchor.

Finally here is an example that would create menus:

var replacements =
[
  [
    ["directories","directory"], 
      [["Yahoo",        "http://www.yahoo.com"]],
       ["SomeOne Else", "http://www.someoneelse.com"]]],
  [
    ["google"],     
      [["", "http://www.google.com","../../words/google.gif"]]],
  [
    ["freedom","free","fsf","beer","lunch"],       
      [["Freedom", "http://www.fsf.org","free.gif"]],
       ["Beer",    "http://www.makeyourown.org",]],
       ["Lunch",   "http://www.nosuchthing.org"]]],
  [
    ["links"],      
      [["", "http://www.links.com"]]],
  [
    ["my"],         
      [["", "http://my.org","my.gif"]]]];

That deals with the input side, now we must make some changes to the process. The changes are principally to the makeNode function and the statements that call it. Remember that the replacement link and img properties with an array of arrays. We change the makeNode argument list to accept that array of menu items instead of the URL and image source. Actually we still need most of the code but we have to add a layer between processNode and makeNode to create the menu.

Here are some examples created from the definitions above.

If you want to search you can use a human created directory or a machine created index like Google. I prefer Google because it gives me more freedom in in how I search and what I search for. With Google I normally get a good link in the first couple of pages instead of having to trawl through layers of hierarchical categories. So now all that is left is to fix the code that puts the image in place of the text for an anchor.

Unfortunately this doesn't work if the generated links are in a table. Presumably it wouldn't work if they were statically created HTML in a table either.
Here are some words that should show menus: freedom, directory. Where do they appear?

They appear at the top of the document. This suggests that relative positioning might be part of the answer. However just changing the stylesheet to say relative doesn't work. Another possibility is that the event coordinates are relative. They are not and this was confirmed by adding an alert to the show function. The culprit is offsetTop. This is relative to the container, at least in IE6.