Author Archives: david

IE6 doesn’t support onclick handlers for

Instead, you have to use an onchange handler in the SELECT, like this:

<html>
<head>
<script>
function fAlertA() { alert(‘A’); }
function fAlertB() { alert(‘B’); }
function fHandleActionSelection(nSelect)
{
var iOptionIndex = nSelect.selectedIndex;
if (iOptionIndex > 0) { //skip over ‘Actions’
var sFnName = nSelect.options[iOptionIndex].value;
eval(sFnName+”()”);
}
}
</script>
</head>
<body>
<select onchange=”fHandleActionSelection(this)”>
<option>Actions</option>
<option value=”fAlertA”>a</option>
<option value=”fAlertB”>b</option>
</select>
</body>
</html>

Avoid signin delay for audio and video checks when using AIMcc in a server context

If you’re using the Open AIM libraries (aka AIMcc) and your client doesn’t provide audio or video messaging capability, then you can speed up sign on by telling AIMcc not to try to enumerate all AV devices that are present when it signs on a user.  Do this:

oAccSession.Prefs.SetValue(“aimcc.av.enumDevices”, 0);

oAccSession.Prefs.SetValue(“aimcc.av.audio.permissions.buddies”, AccPermissions.AccPermissions_RejectAll);
oAccSession.Prefs.SetValue(“aimcc.av.audio.permissions.nonBuddies”, AccPermissions.AccPermissions_RejectAll);
oAccSession.Prefs.SetValue(“aimcc.av.video.permissions.buddies”, AccPermissions.AccPermissions_RejectAll);
oAccSession.Prefs.SetValue(“aimcc.av.video.permissions.nonBuddies”, AccPermissions.AccPermissions_RejectAll);

AIMcc char encoding

On 01/22/07 Ira said on aimcc-questions:
Some legacy clients don’t handle utf-8 IMs, so if IM text can’t be encoded in ASCII or Latin-1, it’s encoded in ucs-2.

Showing and hiding rows of a table

Great advice here:
http://blog.delaguardia.com.mx/index.php?op=ViewArticle&articleId=28&blogId=1

In FF1.5, if a <tr>’s style is changed from display:none to display:block, the row doesn’t appear correctly; for example, a <textarea> within a <td> might appear very small.

The poor display gets worse if one toggles back and forth; for me, vertical space where the row would normally go kept growing with each toggle.

The external blog entry points out that FF1.5 uses display:table-row for displaying, so one might do this:

  try {
    e.style.display = “table-row”;
  } catch (e) { //for IE, etc
    e.style.display = “block”;
  }

“Internet Explorer cannot open the Internet site…Operation aborted”

There was another problem that just appeared today where IE was popping an error saying “Internet Explorer cannot open the Internet site…Operation aborted”. Web search indicated people saw a similar problem when using the Google Maps API, evidently because IE doesn’t like scripted changes to a table DOM before the rendering finishes:

http://vidmar.net/weblog/archive/2005/08/22/2121.aspx

http://www.ryangrant.net/archives/internet-explorer-cannot-open-the-internet-site-operation-aborted-google-map-api

The suggested change was to wrap the JS inside a setTimeout with wait of 1ms. That worked for me.

Unspecified error for createStyleSheet()

Our rich text editor (RTE) was working in IE just yesterday, at least from my dev server. But once installed in QA, a JS error was being popped whenever the Compose page loaded, and the error indicated M$ method createStyleSheet(), which is called on the RTE iframe’s doc object. If one takes the option to debug offered by the error popup, VisualStudio can only say “unspecified error”, but then the RTE becomes usable!

This suggested a timing problem, and sure enough, a web search turned up problems if one calls createStyleSheet() before the doc obj’s readyState property reaches “complete”:

http://dojotoolkit.org/pipermail/dojo-interest/2006-May/008587.html

To workaround this, one could just keep trying:

function foo (sCssPath) {

try {

eDoc.createStyleSheet(sCssPath);

} catch() {

setTimeout(“foo(‘”+sCssPath+”‘)”, 10);

}

}

But that runs the risk of looping forever. A better way might be to use the M$-only onReadyStateChange handler:

if (bIE) {

if (eDoc.readyState == “complete”) {

eDoc.createStyleSheet(sCssPath);

} else {

eDoc.onreadystatechange = function() {

if (eDoc.readyState == “complete”) {

eDoc.createStyleSheet(sCssPath);

}

};

}

}

Details at MSDN

Window.onload and document.body.onload are the same

I’m used to coding with window.onload but while integrating code from someone else I found references to document.body.onload, and I thought this must be some other event.  But on page 135 of “Dynamic HTML” by Goodman, he says:

by a quirk of HTML tag structure, all window object event handlers are associated with the BODY element

Don’t rely on the text of

Sometimes I see dropdowns marked up like this:

<option><%= localized string %></option>

which forces the server-side code to do checks like this:

if (sDropdownChoice == L10nStrings(“localized string”))

Looking up strings server-side to do comparisons like this is is inefficient. Instead, markup the page like this:

<option value=”sender”><%= localized string %></option>

so the server code can compare like this:

if (sDropdownChoice.Equals(“sender”))

Even better, use a staticly-defined string such as,

static public readonly string s_sSender = “sender”;

and use that in both the markup creation and the comparison, which helps avoid typos and helps with maintainability by making sure that if the string ever needs changing, the update is made everywhere it should be.

Parsing strings into other types in C#

What’s the best way of parsing a string into some other type, and making sure nothing more is done if that conversion fails?  A typical way would be:

  try {
    int i = UInt.Parse(s);
  } catch (ex) {
    …blah blah
  }
  next step

but this requires that something happen in the ‘catch’ to prevent doing anything at ‘next step’, and often that is left to a TODO that never gets implemented.  Instead, try this:

  int i;
if (!UInt.TryParse(s, out i)) { return; }
next step

Avoid script collisions via namespaces

If you plan to use a JS function named something generic like “update()”, then you run the risk of another engineer on your team unknowlingly writing a same-named function and killing yours.  Just as bad, some external party like an ad vendor might have script with the same name.

Another problem is when you have to maintain someone else’s code, and figure out where “update()” is defined.

To avoid such problems, put all your methods in object(s) that are named after your dev team and that suggest what file they are defined in.  Furthermore, make the name specific enough to indicate the specific functionality.  For example, change “update()” to

var aol = {wsl: {
fUpdatePagesDropdown: function(sNewDefaultId) {

,fSelect…
}};

If I see a JS call that starts “aol.wsl.”, I immediately know it’s defined in lite.js.  Similarly, if I have inline script in a page like Compose, I’ll create a namespace called “aolCompose”.

btw, I like putting the commas before object properties, because it helps me remember not to put a comma after the last property — which is a common source of hard-to-debug problems.

Avoid cross-site scripting vulnerabilities

“Cross-site scripting” (aka XSRF = cross-site request forgery) is an evil practice where someone tries to trigger your site into sending sensitive info, such as user logins, to their own site. A typical method is to “inject” script into your pages so the user’s browser will render the script as though it came from you, and the script might send the user’s cookies to the hacker site so they could append them to their own requests, making it very difficult for your server to tell the requests aren’t coming from the real user, and thereby allowing the hacker to damage the account.

A typical trick is to put an unbalanced quote before some evil script into a form, such as:

‘ <script>document.location=”document.cookie”</script>

The bet is that, if you take this submission and paste this value into your response html to confirm what was typed in, that you will wrap your input value in the same kind of quote. This embedded quote then breaks the html at that point, and the hacker’s <script> would be executed as though it was part of your intended markup.

One way to avoid such vulnerabilities is to “sanitize” everything you paste into your pages that wasn’t created directly by you. For example, anything from the request or from a data-layer whose data is created by some user (such as email or contact names) should be sanitized before sending it out as part of a response.

You’ll want one sanitizing method that accepts HTML and alters it such that control over fonts, colors, etc is preserved. You might also want a stricter method that escapes markup or strips it completely. The former is useful when sanitizing html-formatted email messages, and the later, for sanitizing names, addresses, filenames, etc where you do not want to allow any idiosyncratic styling.

Writing a good sanitizer is hard. If I come across a good open-source one, I’ll post about it. AntiSamy seems like a great solution, and is open.

Indicating type in names (“Hungarian notation”)

The practice of indicating type when one names something is an old practice, and still a great idea. Some say that it’s not necessary if one uses a modern IDE that shows type on hover, etc. But have you seen any IDE that does that for interpreted languages like JS? And what about when you have to look at code outside of an IDE, such as in an email or in a diff?

I don’t know of any industry-wide consensus on what characters to use for common types, but my (ever evolving) set is:

x – unknown type
i – int
o – object
b – bool
s – string
f – function (especially helpful when passing function pointers and refs)
sb – StringBuilder
e – DOM element
as – array of strings
ao – array of objects
hs – string of html
zs, zhs – “sanitized” string; stripped of possible cross-site scripting attacks
ht – hashtable (used in JS when an obj is used just to collect properties)

Similarly, it’s very helpful to know what kind of result a function returns. I indicate the return type after the “f”, like this:

fbSubmitCompose – returns a bool
fsbSubmitButtonHTML – returns a StringBuilder of markup
fPreparePagesDropdown – doesn’t return a value

btw, perhaps fhsbSubmitButton would be better.

If it’s a member var, prepend with “m_” and if it’s a static member, with “s_”. This is very important, because if you ever work with a web framework that creates just one object per class (like Java servlets), you want to be very mindful of what’s stored in member and static vars, since some uses lead to loss of thread safety. It also helps when reading a long function to know which of the objects are defined outside.

Using curly braces in a format string in C#

Because curly braces are used in C# to indicate where values should be pasted in, like this…

sb.AppendFormat(“Email: {0}”, sEmail);

…therefore, if you need to display curly braces in the final string, you’ll need to escape them, like this:

sb.AppendFormat(“var oContact = {email:'{0}’}“, sEmail);

Don’t use + to build strings

First, using + to create strings in JS is fine because there is no alternative.

But in C# and ASPX (and Java), string objects are “immutable”, which means you can’t alter their properties; when you use +, a whole new string is created to contain the two original pieces. So when you use a chain of +’s, you’re creating a lot of objects and then throwing them away.

Instead, use StringBuilder.Append or AppendFormat.  For example, change

  s = “[” + s + “]”;

to

//10 is an estimate of the final # of chars
  StringBuilder sb = new StringBuilder(10);
  sb.Append(“[“);
  sb.Append(s);
  sb.Append(“]”);
  s = sb.ToString();

or

  //10 is an estimate of the final # of chars
  StringBuilder sb = new StringBuilder(10);
  sb.AppendFormat(“[{0}]”, s);
  s = sb.ToString();

Note that this means you don’t want + inside your calls to Append, either.

Coding with empty string

When you need to put an empty string in C#  or ASPX code, use String.Empty rather than “”, since this saves creating an object for every appearance of “”.

When checking for empty string, create a utility method like !Util.NullOrEmptyString(s) instead of (s != null && s != “”).  It’s more readable, and one is less prone to forget that one usually has to check for both null and empty string.

Always use curly braces for 1-line statement blocks

Always use {} to wrap the actions of conditionals and such, even if they are just one line. We’ve had bugs where someone added a second line without realizing it was part of a “then” clause, and tracking this down took a surprisingly long time.

For example,

   if (foo)
     act;

should be

   if (foo) {
     act;
   }

JavaScript debugging

Copied from someone’s email:
This link has great info, tips, tools to debug Dojo and JavaScript, etc.

http://dojo.jot.com/DebuggingJavascript

I believe some of you asked how to do step-thru debugging of individual JS files that use the Dojo toolkit. You have to set “djConfig.debugAtAllCosts=true” and make sure the page has the “dojo.hostenv.writeIncludes();” statement added in a script element. (I believe it has to be in the head section.)

Firefox 1.5 ignores changing tabIndex of input type=file

One can change the tabIndex of a file input in FF1.5 and verify the value has changed, but the browser will ignore the change and use whatever value was staticly defined at page load.

As a workaround, see if you can define ‘tabindex’ for all items in the markup. If you’ll be dynamicly adding non-file inputs, set their tabIndex to be the same as whatever they should come after in tab order — browsers use doc order to break ties in tabIndex values. To dynamicly add file inputs, put something like this in the markup:

  <input type=file id=file0 tabindex=N onchange… /><span id=file1container></span>

Then, when you add a new file input, assign to the innerHTML property of the span rather than using createElement. (You probably also want to style the old input as display:none, depending on what you’re trying to do.)  The tabindex of the new input can be N also.

UPDATE: Once the file input is filled, one might want to take it out of the tab order. Setting tabIndex = -1 has no effect in FF1.5, and setting the style to display:none (or visibility:hidden) will cause Safari 2.0.3 to ignore it when sending the request. I haven’t found a solution that works for all browsers.

Nonvisible file inputs are not “Accessible”

File inputs are pretty ugly, and can be confusing to naive users (e.g., “Should I type what I want in that box?”).  Quirksmode describes a nicer solution that mail.aol.com (Compose) happens to use:
http://www.quirksmode.org/dom/inputfile.html

But if one cares about Big-A accessibility, such a solution won’t work for users with normal vision who are limited to the keyboard (no mice), such as those with carpal tunnel syndrome.  The reason it won’t work is that such users rely on tab order, and tabbing into an invisible file input consumes 2 tabs before one sees any visible result — the user won’t know they are on top of the Browse button.

One might suggest putting the nonfunctional button in the tab order, and when it receives focus, call click() on the nonvisible file input. But in my experiments, click() did not trigger a FileOpen dialog.

One might also suggest faking focus on the nonfunctional button by drawing a rectangle around it when the nonvisible file input receives focus.  But remember that file inputs consume 2 tabs — it might make sense to draw the rectangle on the second tab, when focus is on the Browse button, but what about the first tab?  Even if there are separate events from the file input from the tabs, which seems doubtful, what would one display for the first tab?

A decent compromise is to get rid of the nonfunctional button and make the file input visible.  But like the mail.aol.com use, hide the inputs once they are used and show a checkbox with the filename instead, with focus moved to this checkbox (so blind users will be aware of the result of their file selection).

Debugging Javascript in IE when you don’t control the page

So everything works great from your dev server, but once deployed, a script problem is discovered. Even worse, it only happens in IE.

Something that worked for me was to install Fiddler for .Net 2.0. There’s a nice walkthrough WMV video (why do voices in walkthrough videos all sound like the famous Ruby one?). The video doesn’t say much that one couldn’t figure out from the UI, with one exception: The black bar at the lower right for setting breakpoint patterns. For example, enter “bpu” followed by a space and some substring of the filename you’d like to break on. (If “Capturing” isn’t already showing in the bottom left status bar, click there and it will begin recording.) When one visits the page of interest, Fiddler will suspend the network request and flash in the taskbar. A red ‘T‘ will show in the left panel for the breakpointed resource, and a red box will show in the right panel. Click on the yellow ‘Break on Response’ button, and if it shows “response is encoded” below that, double-click on that message. You should see a ‘Text View’ tab; click on it. Edit the resource as you like, and then click the green ‘Run to completion’ button. Note that Fiddler breakpoints even if the file is already in cache!

This allows for inserting JS alerts and such, but it seems it could also allow one to insert a script tag for FirebugLite, and then you’d be able to debug after page load, too.

The particular problem this helped with was: Our rich text editor (RTE) wouldn’t allow one to type in it (after the page load and as long as the page was in view). This usually happened only after the cache had been cleared. This pointed to a timing issue, and sure enough, the problem was that the RTE’s iframe wasn’t complete before we tried to enable design mode on it. This is the same issue I blogged about with IE’s createStyleSheet method, but in this case there was no script error indicated. Our code to handle this case had a typo in it — I had spelled “onreadystatechange” as “onReadyStateChange” as O’Reilly’s Dynamic HTML: The Definitive Reference spells it, which is a typographic convention for highlighting the words within handler names that will cause you grief if you follow the spelling literally. Use all lowercase!

OnBeforeUnload fires twice in IE when href!=# and onclick causes nav away

We had been using href=foo for leftNav links instead of href=# because screenreaders read <a href=#…> as “link this page” and that may mislead SR users to tab around looking for the content. (The real action of clicking is to submit a form via an onclick.)

But we have to use href=# because otherwise IE fires onbeforeunload once because href!=# and once because the onclick causes a nav change (because it calls submit() on a form). We can’t use setTimeout to ignore the 2nd firing because we need the form submission to happen, and we can’t skip the 1st firing because we need it when the user clicks a non-link (such as form buttons and the window ‘X’ close button).

So, we have to live with the screenreader (JAWS) behavior of reading these links as “link this page”.

Request.Cookies == Response.Cookies in ASP.NET

Be careful when setting a Response.Cookies property that you don’t need to check the same property in Request.Cookies later while processing the same http session, because these collections reference the same object, so changing one immediately overwrites the value in the other.

IEDeveloperToolbar almost as useful as Firebug

I was just told that there’s an IE Developer Toolbar:
http://www.windowsmarketplace.com/details.aspx?view=info&itemid=2695980

At first glance, it provides a significant fraction of the utility of Firebug, such as showing DOM structure changes post-load. It also has a “Trace Style” feature, evidently for revealing the cascade of styles that apply to a particular element, but when I tried it all it did was open a window displaying my stylesheet.

It does not appear to support live editing of markup or styles.

“System.FormatException: Input string was not in a correct format.”

When using .Net’s StringBuilder, you might see this error. The likely cause is that you have a curly brace in the format string that you want to appear in the final string.  That will mislead .Net into thinking it’s a placeholder (the expected use of curly braces), and escaping with doesn’t seem to help.

Break up the format string so that the “literal” curly braces appear only in Append’s.

Read “Effective Java” book to improve skills in Java or C#

Although my knowledgeable programmer friends seem to have known about this book for awhile, I discovered Joshua Bloch’s book “Effective Java” just recently.  This book is chock-full of great advice that applies not just to Java but also C# and the C family. If you read just one book about programming, I recommend this one.

I have heard, and strongly suspected myself, that C# is just a layer on top of Microsoft’s old implementation of Java. So it’s well-worth understanding Java even if you consider yourself dedicated to C# (which doesn’t seem sensible to me, but you may have your reasons).

Write better JS by watching YUI Theater

Yahoo has a great set of videos about JS: http://developer.yahoo.com/yui/theater/

The ones by Douglas Crockford — “The JavaScript Programming Language”, “An Inconvenient API: The Theory of the DOM”, and “Advanced JavaScript” — are intended to be watched in that order, but I think watching the DOM one first helps to clarify what happens in the browser when JS is run.

btw, Yahoo Video has no rewind/forward capability, so you might want to download the slides as well (linked next to each video).

IE JS doesn’t support indexOf() for arrays

Firefox supports indexOf() for arrays, but IE doesn’t (at least IE7 doesn’t). To work around this, write your own version…maybe like this:

function fiArrayContains(ax, xTarget) {

var n;
if (fbIsArray(ax)) {

n = ax.length;
for (i=0; i < n; i++) {

if (ax[i] == xTarget) {

return i;

}

}

}
return -1;

}

function fbIsArray(x) {

return fbIsObject(x) && x.constructor == Array;

}
function
fbIsObject(x) {

return (typeof x == ‘object’ && !!x) || fbIsFunction(x);

}
function
fbIsFunction(x) {

return typeof x == ‘function’;

}

Multicast router simulator in pure C

In the fall of ’98 I took a networking class. For the final project, we were to code a simulation of a router that supports multicast. For example, machine M1 might want to subscribe to events broadcast by machine M4 to its registered listeners, and they might be separated by 3 hops or more. Furthermore, any of the machines could be both broadcasters or listeners (IIRC). I learned enough that the solution seemed worth sharing.