This log primarily relates to the development of the cut the crap navigator javascript. It outlines the objectives of the framework and the problems and choices faced along the way.

This is potentially helpful to many people since although I have many years experience of computer system design and development, I have only really played with web development.

The Objective

At the end of the day, I wanted to have developed a simple framework that would allow the simple creation of content files for the website.

A major issue with any site is the navigation provided. I felt almost from the beginning that some kind of tree-view navigation interface was needed. Something that would feel familiar to users who are used to navigating file system browsers such as Windows Explorer or Macintosh Finder.

A key advantage of a treeview navigator is that it can display the context of the current page as well as providing means to navigate elsewhere. This is really important to help a visitor confidently explore a site.

It was clear from visited pages on the web that this approach is also preferred by many site developers. However, when I investigated the methods used by specific sites it became clear that finding a good, platform neutral, solution was not going to be straightforward.

The Options

One option that I ruled out straightaway was using some web development environment such as Frontpage or Dreamweaver. Partly this was because I wanted to use the project to learn as much as possible, but mainly because previous experience of these kind of tools means that you unavoidably end up working within the constraints of the tool rather than the underlying technology.

Java Applet

My programming background lead me to consider whether a java applet would be the best approach. But an applet by itself is not the whole solution, so I put this option to the back of my mind.

Transformation

Transformation is an excellent idea. With this approach you should be able to write simple, structured content that is then transformed into html for rendering in the browser.

In theory, XML and XSLT provide good options. There are two approaches possible, one would be to write some XSLT to generate html as part of the web publishing process, and upload the generated html to the website.

Alternatively, a suitable browser would be able to do the transfomation directly from the xml if provided with the XSLT.

However, the first approach requires a well organised environment, and whilst I would have little problem setting this up, this would not be a good option for othe developers.

The second approach runs bang into browser compatibility/capability problems.

The main issue tho', is that although transformation is itself an attractive option, XSLT must be just about the most ugly programming language thought up in the last twenty years.

They have got to be kidding! An interesting project might be to define a more syntactically appropriate language, and then generate XSLT from that - but not for now.

Server Side Includes

This approach uses the ability to run scripts on a server that generate html to be included in the content retrieved.

This could be interpreted as a kind of dynamic transformation.

The option was to invoke perl scripts to generate navigation structures appropriate for each document.

This did look like a strong possibility at first. The problem I had tho', was regarding the processing and data load this would place on the server.

For every page requested, possibly multiple scripts would need to be run. And the generated code may of course increase the size of the downloaded data considerably. Bearing in mind that sites tend to be charged according to bandwidth utilised, this was definitely a consideration.

Compatibility

A few issues here regarding unix and windows hosted servers. I had tested SSI with a local Apache Tomcat server. After modifying the configuration files to support SSI and CGI my test files worked as expected. However, when I uploaded to the server there were some problems.

Firstly the windows server did not want to process the .shtml file by default, so a home page index.shtml would not be loaded by simply accessing www.cutthecrap.biz.

A real pain is that the home directory for a perl interpreter is in a different directory in windows and unix servers. So, if a web site is moved from one type to another by your site management company, your scripts will fail.

When uploading perl scripts to unix servers, be sure to chmod to allow the script to be executable.

On tomcat, the SSI command VIRTUAL can process cgi scripts, but using EXEC seems to work on all servers - where VIRTUAL will often simply include the file contents.

Generation By Javascript

A much more attractive option, was to generate the navigation structures with javascript.

The big win here is that all the processing takes place in the browser, and that the scripts and stylesheets used would be downloaded once and cached for subsequent references.

Note also that the smaller the size of the downloaded files, the more that can be retained in any cache - its a win-win situation.

Javascript and Scalability

Having decided on a javascript interface, the next issue was what that (programming) interface would look like. A key objective was to be able to specify sub menus conveniently:

function menu1() {
  startMenu();
    back("../home.html");
		
    header("Subject 1");
		
    item("Item 1", "subject1/item1.html");
    item("Item 2", "subject1/item2.html");
  endMenu();
}
function mainMenu() {
  startMenu();
    header("Home");
		
    menu1();
    menu2();
  endMenu();
}

So that the javascript was interpreted in context, rather than passing parameters around. This would allow the easy embedding of one menu inside another.

A constraint on this was that a document that wanted to include javascript menus needed to specify the root of the document link structure - otherwise the links would not be resolved correctly.

A related issue was how to minimise the setup for each document including the menus. This ended up requiring the configuration of some java variables before including the main script file. For example:

<script type="text/javascript">
  var jspath="../";
  var mnupath = "../";
  var thisDoc = "software/devlog.html";
</script>
<script src="../ctcmnu.js" type="text/javascript"></script>

In this case the ctcmnu.js starts off with the following line:

document.write("<script src=\"" + jspath +"js/ctcutils.js\" _
  type=\"text/javascript\"></script>");

The Details

Out comes the DHTML book and the investigation begins.

The aim is cross platform, and elegance - or as much as is feasible anyhow.

User feedback and consistency is all important for this kind of interface. I knew that I wanted to be able to provide both cursor and element feedback as the user moved the mouse over the navigation area.

After much consideration I decided that the best element feedback would be to hilite an icon associated with the element. If possible I wanted to be able to use element style change to create the rollover effect of hiliting an associated graphic.

It seemed that I found a solution using list item elements. With a list item, it was possible to define a list item image that would be shown instead of the usual bullet points.

Early experimentation showed up a problem with spacing. It seemed that most browsers were not going to centre the image nicely for me, or create any default space beteen the graphic and the element content.

The solution was to create a gif larger than required, with transparent content serving to vertically align the image and provide the horizontal spacing required.

Using Mozilla 1.3, Netscape 7.0, Opera 6 and IE 6.0 on Windows 2000, the navigator scripts were functional, but it was harder than I had hoped to get a consistent display. The line items were a problem. On Mac OSX 10.1, IE 5.2 was a disaster! Firstly the line-item graphic defaulted to outside and even when this was overridden with explicit styles the graphic alignment was completely different.

Back to tables

It is easy to see why most websites use table structures to define layouts. The apparently elegant approach of using styled line-items was just too inconsistent in different browsers.

So it was necessary to generate a two column single row table to represent each menu item.

I also decided that although the IE approach to CSS was in my opinion better than Mozilla, the base browser that should be developed for should be Mozilla. This was a good decision, since if it looks good in Mozilla, it will look okay in IE 6 without any modifications, while developing for IE needs various frigs to get things working correctly elsewhere.

Mouse feedback

When the user moves the mouse over an active element, it is important to provide feedback, to show that they are moving over an active element, and also which element it is.

The idea was to wrap each menu item inside a styled DIV with registered event handlers, this seemed to work fine. When the mouse was moved over the element, the cursor was changed indicating an active element, and the graphic associated with that element modified to indicate selection.

IE 6 however, did not want to play. Although the correct cursor was displayed when the element was entered the graphic feedback was not updated unless the mouse was positioned over the table contents - the label or the graphic. This is to do with the trickle down event processing, but is clearly a bug.

All in all tho', it seemed to work okay.

Word wrap in menu item

There is a bug in IE that does not correctly word wrap text. There is little consistency here since some text is word-wrapped, it must be a boundary/margin calculation issue, I have seen the problem in both IE 6.0 and IE 5.5.

Safari on Mac OSX 10.2

On the new Safari browser - based on Konqueror - the list-item graphics did not work at all. Furthermore the submenus were displayed initially expanded.

With the table display, the menus looked fine, but were still expanded. However, it turned out that they could be collapsed and expanded once displayed. So it was not a fundamental problem with lack of support for the display style property.

After some investigation, the problem was resolved by changing the style syntax, so that style="{display:none}" was replaced with style="display:none" all browsers then accepted this.

Applet

The problems with the platform inconsistencies led me back to an Applet option.

The definition would be exactly the same as the javascript generated html, but instead of generating html the javascript would make method calls on a named applet.

It wasn't really that hard to produce the applet. Using java 1.1 classes, I was able to create a far more consistent navigator panel, with precisely the layout and feedback I required - and the word wrap worked consistently!

In a content page, the applet is indicated by setting a variable var useApplet=true; in the javascript.

Applet problems

For the applet to work as intended, the applet needed to be able to call back to javascript (when it needed resizing after initialization or when collapsing/expanding the submenus. The applet was configured by javascript invoked applet methods.

The first problem noted, was that Mozilla/Netscape, did not correctly resize the applet - or at least did not re-adjust the page boundary in response to dimension changes.

The second problem was that there was a problem with earlier browser versions supporting method calls on the applet from javascript - despite the inclusion of <param name="scriptable" value="true"> specifications.

Solutions

The best workaround to the applet resizing problem was simply to define a large applet initial height. Then if the applet could not be resized, at least there would be enough real estate.

The solution to the script access to the applet was to generate a list of tokens that could be passed to the applet when initialized. So, rather than create the applet and then call the methods from javascript, instead the javascript built a list of tokens that were used to initialize the applet when the last menu was defined.

By switching the processing order, this also then allows for a rough calculation of the maximum height required by the applet.

The applet now renders correctly in all tested browsers. There remained a problem in Safari that the showDocument method on AppletContext does not seem to be working correctly. On first use, a new window is created and even using the two argument method with "_self" as the target parameter does not improve the behaviour. But this has now been fixed with Safari beta 2.

The resizing problem is interesting. In IE, the resize and update is correct, but the height property value, that is updated to change the size of the applet, reports its original value, so you get the odd behaviour of if x < y then x = y not appearing to change the value of x although the update side-effect is as required. Whilst with Mozilla, the property appears to be modified correctly, but without the desired effect. Opera does update the layout as required, but does not always render the image correctly. All very unsatisfactory.

Colour

When I first began this exercise, I was fairly certain that I wanted to use greyscale alone to render the navigation items. I remember how neat the original Next machine looked with its 4-bit greyscale monitor. However, plain greyscale backgrounds just did not look right. I then changed to using shades of blue, and this looked a lot better.

After sorting out all the rendering and event processing problems I then returned to my colour concerns. Instead of rendering menu elements with a single colour, instead I created colour gradient images to serve as a background. This looked a lot better than the plain colours. However, this time it seemed harder to get the correct balance with different blue coloured gradients for each display type. I converted each gradient image to greyscale, and this seemed to work pretty well.

So, if there is a lesson here, it is that greyscale can look pretty good but only if you are able to make it come alive using some kind of texture or gradient to add some depth.

Success or Failure?

This exercise has taken more effort than I originally expected, but has yielded the benefits aimed for. It has been easy to correct errors, and make wholesale modifications to the look and feel without making any updates to the content pages.

The javascript version seems to work pretty well in all the browsers I have tested. The only remaining issues are to do with mouse/cursor feedback and the releated problem of active areas for event triggering.

The rendering of the gradient images varies with different browsers. IE does a good job under Windows 2000 and Safari looks good on the Mac, but all other browsers seem to render the image with visible banding. Presumably IE and Safari must be using dithering to improve jpeg rendering. I did try toggling off the "smart image dithering" option in IE to see if this reintroduced the banding, but it had no noticable effect.

Next Steps

It would be interesting to develop another set of javascript functions that render a completely different look and feel while preserving the same interface.

An obvious alternative would be to render the menus as a menubar, with drop-down and submenus. It may be possible that this could lead to a unified approach, with dropdown menus used for global navigation, whilst the navigation panel remains to provide context information and direct access to the most local menu.

Cookies could be utilised to allow the user to specify how they wanted to navigate the site on return visits. CGI scripts could be run to keep a tab on user preferences.

Not just yet tho'...