October 2001

10/31/2001 Wednesday

Nike iD: I initially wanted to structure the HTML to match the logical structure of the data - section layers would contain the question layers that belong to the sections and question layers would contain the options that belong to the question. This would minimize the repositioning required when questions were added during the process of configuring a product. On my first attempt, the options weren't in their own layers, rather a question layer contained a <table> which had one option per cell in a hybrid layer-and-table layout. The layers, at this point, were all positioned <div>s. Since the appearance of the options would change each time an option was selected or when interdependencies were encountered (selecting an option for on question may affect the options available in later questions), the table would have to be re-output. This caused instabilities in NS4.x and that browser would usually crash after a couple seconds of interaction. Converting the <div>s to <layer>s in NS4.x helped a bit in that it took longer for the browser to crash but a crash was inevitable. Though the crashes were obviously due to writing lots of HTML to the layers, they usually occured on mouseover events on the options instead of while the layer contents were changing. I then rewrote the tables as separate layers - two layers per options (an unselected and a selected state). This seemed to cure the crashing in NS4.x but NS4.x Win2k appeared to take much longer to update the view between option selections. It turns out that this browser / platform combination suffer from a bug where accessing elements of the layers[] collection take a very long time. The only solution was to flatten the layer structure (the sections, questions and options gave three levels of layering). This required a rewrite of the routines that position and set the visibility of questions and options (previously I could rely on the nesting of the layers to provide the correct relative positioning and inheritance of visibility). The final flattened, all-layers layout worked in all the target browsers (including IE4.5 Mac). At each rewrite, I took the opportunity to make the code more modular and, therefore, more maintainable and easier / quicker to change. Moral of the story: anticipate change; even changes that you would never anticipate. And, yes, this is possible.
10:20 permalink

Arjan Haverkamp has a different way to detect ActiveX components in IE5+ that uses Javascript instead of VBScript:

function activeXDetect(componentClassID) {
   componentVersion = document.body.getComponentVersion(
   if (componentVersion != null) {
      return parseInt(componentVersion);
   return false;


var flash = activeXDetect('D27CDB6E-AE6D-11CF-96B8-444553540000');
var sw = activeXDetect('2A202491-F00D-11CF-87CC-0020AFEECF20');
var wm = activeXDetect('22D6F312-B0F6-11D0-94AB-0080C74C7E95');

activeXDetect() returns the version of the component if it is installed or false if it isn't. The last three lines detect Flash, Shockwave, and Windows Media Player respectively (the argument to the function is the classid attribute value used in a <object> for the component). It's pretty cool because the code is short and it avoids instantiating the component.
09:35 permalink

10/30/2001 Tuesday

Nike iD: The first thing I started to code was the iframe that contains the questions. Since NS4.x doesn't recognize the <iframe> tag, I wanted to be able to duplicate it's behavior with DHTML. The NS4.x iframe consists of a content layer and a whole bunch of layers for the scrollbar. Capturing events on the various bits of the scrollbar didn't work too well, so I ended up putting a transparent layer over top of the scrollbar components that captures all scrollbar events (mouse clicks, drags and releases). In order to size and position the scrollbar thumb correctly, there is a named anchor (<a name>) at the bottom of the content in the content layer - the y-coordinate of the anchor gives you the height of the content. Because the height of the content changes as questions are added to the display, this y-coordinate will change regularly. So the y-coordinate value is queried once every 0.5 seconds and the scrollbar resizes and repositions accordingly. It also hides itself if the content height is less than the window height. I'll get around to talking about populating the iframe with the questions tomorrow.
17:00 permalink

More on Quicktime version detection: Eric Bin wrote to the good folk at Quicktime Engineering and got this reply (abridged):

There is no mapping between ActiveX version and QuickTime version. The control is essentially a "shim" that allows the QuickTime plug-in to work in Win IE.

Because we did not want to _require_ everyone that already had QuickTime installed to upgrade just because Microsoft dropped support for our plug-in, we made sure that the ActiveX control works correctly with every version of the QuickTime plug-in. Thus, it will work with QuickTime 3 or higher.

So in IE, you can't and won't be able to detect the QuickTime version. You could do a simple detection (like the one provided at the QuickTime site) and then use QuickTime itself to detect the version. Eric's recently written a tutorial on detecting the QuickTime version from within QuickTime. One modification you could make to the Javascript QuickTime detect is add a detection of QuickTime.QuickTime.1 in the VBScript. This will be present if the new ActiveX control is installed and indicates QuickTime 3 and up support. The QuickTimeCheckObject.QuickTimeCheck.1 object is installed with the plugin version 4.1.1 and up. I'm not sure if it is also installed by the new QuickTime ActiveX control (it may be simply to provide backwards compatibility with Javascript QuickTime detects).
09:10 permalink

10/29/2001 Monday

Nike iD: If you view the source of configurator.jsp for any product, 70-85% of it is a single line of code - the Product constructor call. I was fairly certain a line this long would cause the parser in some browsers to die and I'd be forced to build the constructor call with lots of single lines using temporary variables but it was fine in everything we tested. product.js contains all the object definitions required to describe a product. It's follows the XML tag grammar used on the backend pretty closely. I flattened the nesting of objects when I could get away with it - I didn't want too many objects and constructors. Even so, any given product is extremely complex. The one thing product.js doesn't have is any information about the visual appearance of products, sections, parameters or the various forms of attributes. All the information about how products are represented in HTML is isolated in ui.js. This separation gave the application the flexibility I needed when DHTML layout schemes ran up against obscure browser bugs which required these routines to be redesigned from scratch. More on ui.js and the user interface tomorrow.
10:30 permalink

10/26/2001 Friday

Nike iD: The configurator.jsp file has little in it. This keeps the amount of code that has to be parsed through on the server small. All configurator.jsp does is define a few global variables and create instances of the major objects used by the application - a configurator, a userPreferences, a ui, and a product object. Each of these is defined in a separate .js file that behave somewhat like modules to isolate information. There are also a number of other .js files that handle low-level functionality: function libraries that deal with cookies, popup windows, simple remote scripting (props to Brent Ashley), mimicking an <iframe> in NS4.x and the 1k DHTML API. The only other major file involved is questions.html which is loaded into the iframe on the right side of the configurator. Still, it doesn't actually contain much code. The vast bulk of stuff is taken care of by three .js files - product.js, ui.js, and configurator.js. I'll start with product.js on Monday.
10:45 permalink

10/25/2001 Thursday

I'm trying to write a Quicktime detection in Javascript that will return the version of Quicktime supported. I can get the version pretty easily from the plugin (the version of the plugin is the version of Quicktime supported) but am having trouble finding any version information in the activex control. There's a QuickTime.QuickTime.1 registry entry for the control. I'm guessing this is version 1 of the control but what is the mapping between this number and the version of Quicktime supported?
14:55 permalink

My wish for the ability to extend object constructors has been answered. Jim Cassidy and I were tossing some ideas back and forth when Stoo Goff sent a sample of what he uses in his DHTML library which fit the bill. Abridged and reworked it comes down to this:

function SuperClass(propertyValue) {
   this.property = propertyValue;

SuperClass.prototype.method = function() {
   // do something

function SubClass(propertyValue, otherPropertyValue) {
   this.x = new SuperClass(propertyValue);
   this.x.otherProperty = otherPropertyValue;
   this.x.otherMethod = function() {
      // do something else
   return this.x;

The secret is to over-ride the default behaviour of the constructor to return the this object (you can't assign anything directly to the this object so you have to create a property to assign to instead). So instances of SubClass have both property and otherProperty properties and both method and otherMethod methods. Very slick! The only drawback is that you can't assign methods to the prototype object of the subclass object (like I've done with the SuperClass methods). Methods assigned to the prototype object are inherited by instances of the object but aren't copied to the object. This decreases the memory required for the instance and instances still inherit methods that are assigned to the prototype object after the instance is created.
12:35 permalink

Nike iD, the project I've been working on recently, has launched. This was a ground-up rebuild of an existing, mostly-static site (which had won a Comm Arts award). The aim of the rebuild was to make the addition of products to the site easier. This also provided an opportunity to reskin the site and bring it in line with the look of other Nike sites. My responsibility was the clientside code for the "configurator" application. The logic for the application is entirely clientside - JSP is responsible for initializing the application and processing the application's returned data that represents a configured product but everything in between is handled by Javascript. Over the next little while, I'll write about various aspects of the configurator for your interest and edification. By the way, the backend is even more complex (takes into account factory capacity, holiday schedules, etc, etc) - full props to Terrance, Mike, Nathan, Ryan, and Shaun. Alan and Arch took care of the thousands of assets. And Sang QA-ed the whole enchilada.
08:40 permalink

10/24/2001 Wednesday

Nadav would like to be able to use multiple classes when assigning styles. I'd like something similar: the ability to subclass a class. Like using the extends keyword in Java. I'd also like to be able to do a similar thing in Javascript: allow object constructors to extend other object constructors. It would make life easier.
09:15 permalink

Rather than being an important part of a complex and fragile eco-system that has evolved over millions of years, a small brown nut from the upland forests of Central America is perfect for giving normal to slightly dry hair the bounce and shine you need in for your busy and exciting lifestyle.
08:25 permalink

10/23/2001 Tuesday

A List Apart: More than you'd ever want to know about the usage of em dash and en dash. (via xBlog)
10:20 permalink

This image of a black hole, though pretty, is mostly wrong. That's because it doesn't take into account that fact that intense gravitational fields bend lightbeams. The accretion disk should be warped (the front appearing more flattened and the back bent up more perpendicular to the line of sight) and there should be a streaky halo of light around the event horizon of the black hole. You can see some of the effect of a gravitational lensing in Abell 2218, a massive galaxy cluster which bends the light coming from another cluster behind it. Black holes, because they have a higher concentration of mass, would bend light even more. Because we are accustomed to well-behaved, flat space, it would be difficult to visualize the warped space around a black hole well enough to create an accurate image. It would be more beneficial to feed the physics involved into a computer and get it to produce the image.
10:15 permalink

10/22/2001 Monday

Macromedia Flash "version penetration" statistics - 72% of US browsers have Flash5, 94% have Flash4.
11:20 permalink

After the Browser Detect Lite on Linux affair, I received some encouraging email from folks thanking me for the site. I didn't respond at the time but I'd like to take this opportunity to thank them - you're the reason why I'm doing this and why the internet works. Thank you. If you don't like the site, a full refund is in the mail.
11:15 permalink

Can anyone confirm this possible AOL bug: I have a report that popup windows opened off-screen-origin (top and left are set to non-zero values in the window.open() method call) appear to have their content shifted so that there is a huge margin on the top and left of the document. I think that if you open the window at (0,0) and then shift it to the required position, the problem goes away. No idea what happens if you don't specify top and left and allow the OS to determine the window position.
11:00 permalink

Two interesting IE vulnerabilities on Bugtraq: about: urls can be used to execute scripts and javascript can be used to spoof the whole screen. The first has the interesting result that you can write cookies in IE5.5 and IE6 that are then accessible from any URL.
09:05 permalink

10/18/2001 Thursday

I like the Netscape 6 Evangelism site. Articles on detecting Gecko-based browsers, writing valid code, and what browsers allow underscores in CSS identifiers.
11:00 permalink

Bugzilla Bug 100309.
10:10 permalink

10/17/2001 Wednesday

I started reading an article entitled Managing Web Development Strategies, was immediately unimpressed and started to think that no-one has anything helpful to say about the large-scale web development process and that if I start to read another article that advises me to do mockups before coding my head will fall off when I read this:

Web developers are generally fairly intelligent people, "inspiring" pep talks and empty gestures (gifts, booze...) just don't cut it. They need to see you working just as hard as they do...

which isn't groundbreaking by any stretch of the imagination but I know a few people who would find it a startling revelation. I guess all those articles I think of as unimaginative and uninformative really are important and really do have an audience. Only I'm not it. Update: Have read more of the article. Many more common sense secrets revealed. If the above was a startling revelation to you, I hereby make the article required reading for you. Another update: Fixed the link (note to self: always QA). Thanks, Sang. (via Epiphany)
09:00 permalink

10/16/2001 Tuesday

Dynamically created pages (output using document.write()) won't print reliably in NS4.x. Even if most of the page is static and only a small portion is written using document.write(). You'll probably get a popup with the message "There are no pages to print". Find some way to avoid using document.write().
13:15 permalink

10/15/2001 Monday

It's been 1.5 months since I started work on The Project. It's starting to wrap up so life is getting back to normal. I think I managed to encounter every DHTML-related bug possible. When it launches, I'll go into detail about how and why it works (and how and why it frequently didn't work). In the meantime, here's some highlights:

  • Writing entire tables into positioned layers is a recipe for disaster. In IE4.5 Mac, portions of the javascript code will appear on screen covering the entire area of the layer except for areas with non-transparent images. Any HTML text content is obscured. Except &nbsp; which will hold table cells open but prevents the appearance of code unlike stretched transparent pixels. In NS4.x, dynamically written tables will crash the browser - usually when you rollover an image which has a name attribute. The crashing is unpredictable but usually happens within a minute.
  • Using layers instead of positioned <div>s or <span>s is pretty much required in complex DHTML applications. It helped a bit in the above situation. But not much.
  • NS4.x on Win2k suffers an obscure but show-stopping problem - accessing layers can slow processing to a crawl. An operation that would take 1 second in other browsers (including NS4.x on other platforms) can take 3 minutes or more! This problem has been encountered by others (here, here, and here) but the closest thing I found to an explaination is a hand-waving "it's something to do with complex data structures" which provides no solutions. The problem is due to nesting layers. In NS4.x, in order to retreive a reference to a given layer, you must iterate through all the layers. First, you check the first level of layers. If it's not in that level, you look at the layers contained in the first layer and so on searching through the tree of layers to find your layer. In NS4.x Win2k, inspecting the layers takes a long time. A low-level process is spawned each time which takes a long time to return and prevents any other code from executing. To prevent the problem, you must define all layers at the root level. This means that looking for a layer requires the inspection of only one set of layers. Because you can't avoid dealing with the layers collection, it's still slow (about 10 seconds) but much, much better. Flattening your layer structure isn't in your best interest for complex DHTML applications because the structure will deviate from the logical structure and bulk your code up so only do this if you need to have it work in NS4.x Win2k.
  • Not only can NS4.x not write to a layer until the document hasn't finished parsing, you have to wait until the document has finished laying out. The <body>'s onload event handler can execute before the document has finished laying out so attaching layer content writing code to onload may not be enough to prevent errors. You may need to throw in a delay as well to allow the document to display before messing with the layers.

I'm sure there were other problems and I now wish I had written them down as I usually do as I encountered them. Hopefully, they will all come back to me and I'll be able to tell you all about them. Stay tuned.
09:40 permalink

Setting a bgcolor and a partially transparent background for a table or table cell should result in the background color showing through the transparent parts of the background image. Not on IE4.5 Mac, though. Trying to print the document is worse - even in IE5 PC, the transparent background sections show the body background.
08:50 permalink

10/09/2001 Tuesday

Caption in a birthday card found in a rack labelled "Family":

I don't think we should be letting the dog watch us.

09:00 permalink

Received a rather strongly worded email to the effect that the Browser Detect Lite script doesn't work well in Linux. It is quite possible seeing as I don't have Linux installed. Now that I know of the problem, I will try to work on it. I should also take this opportunity to say that the scripts I provide are offered as is. If you encounter any problems with them, I will try to fix them. But you are getting what you paid for. I create and document these scripts in my spare time (which I don't have much of) and do as much testing as I can with the systems that are available to me. Bugs are bound to show up and you are all my beta-testers to some extent. Rest assured, I do use these scripts on my own and client projects. Getting back to the email, I don't really fear "a little contrivercy (sic) ... on slashdot". I'm a little concerned that Netscape would be annoyed that I borrowed rather heavily from their code. The box this site is being served from runs Linux so I'm pretty confident that it will be able to handle being /.-ed.
08:55 permalink

10/03/2001 Wednesday

Still busy. In the meantime, please enjoy the following ascii movie:

14:45 permalink

10/01/2001 Monday

Very, hopelessly busy. On top of everything, we bought an apartment this weekend. More later. Back to work.
09:00 permalink