Thursday, October 14, 2004

MSIE and the <button> tag

MSIE doesn't really support the <button> as defined in the HTML 4 specification. Sure it does render a button, and something happens when you push on it. But it doesn't work as specified.

Why use <button> instead of a <input type="submit" ... />?

Simple, <button> gives you more power. For example, with the <button> tag the text on the button is different that the value submitted when the button is clicked. this is very usefull when you want to use a nicer description and don't want to use ugly value checks in your backend script.
<input type="submit" name="mybutton" value="add this new entry" /> displays:

When submitted the following details will be received by the back end script: mybutton = "add this new entry"
Sure it works when you only have only one button. But what if you have two buttons:

Now you will have to check the value of the action variable. It would be much nicer in the code if that value would be addChild or addSibling (also better for localization). But this is not possible with the <input> element.
That's where the <button> tag is usefull:
<button name="action" value="addChild" />add as child<button></button name="action" value="addSibling" />add as sibling</button> produces:

Depending on which button is pressed the value of action would be either addChild or addSibling while the text on the button is descriptive.
Another thing about the <button> is, that it's easier to use for style sheets, you don't have to set a special CSS class for all buttons (since not all Browsers support Input[type="submit"] elements in CSS).

But MSIE is broken

The <button> in MSIE doesn't work as it should. Instead of sending the value of the value property, it will send the value of the innerText (note: this is documented on MSDN), in other words, it will just behave like a normal <input> .
Another thing is that MSIE will include all <button> elements in the submit data, not just the one of the pressed button. So you would get something like: ?action=addChild&action=addSibling. This makes the button element complete useless since you don't know what button was pressed. This incorrect behavior isn't even documented on the MSDN.

A ugly workaround

I came up with an ugly workaround for just MSIE. It uses some javascript. Instead of creating a submit button I will create a normal button: <button type="button" onclick="onButtonClick(this, 'action', 'addChild')">Add as a child
Note, no value and no name have been set, this is very important. When this button is clicked it will call the following JavaScript code:
function onButtonClick(btn, name, value)
{
 btn.name = name;
 btn.value = value;
 btn.form.submit();
}
This will simply set the name of the button pressed to the desired name and set the value. After which it will submit the form.
Now when the button is pressed the text on the button will change to the desired value (yep, that's also incorrect behavior). But the form is submitted at once so it doesn't hurt a lot.
This bug exists in all MSIE versions that support the <button> tag, up to MSIE 6 sp2.
If everybody would switch to browsers that did support the standards as defined (like Mozilla, Firefox, or Opera) it wouldn't be a problem.

Friday, October 08, 2004

UnrealWiki Dev Journal 27-09-2004

UnCodeX Tribes:V ponderings:

Interfaces

Currently, there's only one root for the class tree. I'm going to add a new root item "Interfaces" that contains all interfaces.

Interfaces don't have parents, so this would be the best choice.
Things to think about:
  • auto expand Object works differently with more than 1 root node
  • no create subclass menu item for interfaces

Defines

I may have to redesign my complete parsing system. Maybe have to move it to a single pass parser. Right now I first construct the class tree, after that I analyse all the classes. This might not be possible anymore because of the #if ... #endif macros.
I'm pretty sure it's not possible to have a different class name, however, it might be possible that the parent class can be changed using these macros. So I would have to construct the tree and analyse the packages at the same time so all #defines are catched. The best method might be to mimick the way the unrealscript compiler does it: per package. This ofcourse would re-introduce the package order mechanism. This would be the nicest solution.

The other solution would be to extend the package scanner to parse through the whole source file every time just to capture the #define, #if...#endif macros.
Another thing I need to know is if the #define macros are system wide, or only for the subclasses. Most #defines are afaik in the Object class, so that would automatically make them system wide.
Also I would need to implement a expression evaluator for the #if macro.

Imports

Depending on what the import directive does I might have to implement this too. Mostlikely it's just identical to the #import macro, which will simply import type declarations. In this case I don't need to change anything (except to ingore the import lines).