Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

April 2007 - Posts

What?????

I just don't understand Sony's PR strategy...
http://www.dailymail.co.uk/pages/live/articles/news/news.html?in_article_id=451414&in_page_id=1770&ct=5

UPDATE: Sony explains and apologizes:
http://www.joystiq.com/2007/04/30/sony-explains-god-of-wars-dead-goat-antics/

Posted: Apr 28 2007, 10:56 PM by Bertrand Le Roy | with 8 comment(s)
Filed under:
Woohoo! I'm on TV!

The .NET Show The latest episode of the .NET show is all about ASP.NET Ajax. Brad and Matt first have a really interesting discussion of the history and architecture of ASP.NET Ajax and then you can see me demo-ing UpdatePanel, extenders and localization.

Most of the demos are extracted from the short book Matt and I wrote on UpdatePanel. You can see that I was really nervous when I fail to remember the title of my own book... So the title is "ASP.NET Ajax UpdatePanel Control". <g>

Most of the code for the demos can be found here:
http://examples.oreilly.com/atlasupc/

Check it out!
http://msdn.microsoft.com/theshow/episode.aspx?xml=theshow/en/episode062/manifest.xml

Can you spot the silly words we agreed to inject into the show?

PrtSc now useless... or maybe not.

While looking for the character map in the accessory folder of Vista, I found a little gem that I just have to share. Vista now has a Snipping Tool that enables you to capture parts of the screen, highlight and draw on top of it and copy or save the results. Some would say it's about time and that there's about a million freewares that do this already, I'm just happy to have found it right there in Windows. It can even take non-rectangular snips:

Now I can remove one more useless key from my keyboard. That will undoubtedly become one of my favorite blogging tools (with Windows Live Writer). The only problem I found with it is that it can't capture itself (which of course is a feature...) or anything that disappears when it loses focus (which is a big problem if you're writing about where to find the snipping tool in the Start menu...). Wait, I just checked the FAQ and you can... But it uses the PrtSc key... Oh well.

Share and Enjoy!

The format for JavaScript doc comments

Xml documentation annotations are going to drive JavaScript IntelliSense in Visual Studio Orcas (the next version of Visual Studio). For more than a year now, we've been including xml doc comments to all public APIs in the Microsoft Ajax Library (which are a great place to check out some examples of those comments). We also use the doc comments to automatically generate parameter validation code in the debug version of our scripts.

The format we've been using is an extension of the format that C# and VB.NET are using so it should look familiar to .NET developers. The main differences are the additional attributes we added to convey the (optional) type information that is not provided by the language itself and the place where those comments are written.

Doc comment position

In C# or VB.NET, the doc comment are written before what they describe:

/// <summary>
/// Summary description for Class1
/// </summary>
public class Class1

In JavaScript, we decided to put that information *inside* what it describes so that it can be available at runtime: JavaScript has the interesting feature that calling toString on a function returns the code of this function (when it's propertly implemented), including the comments and thus the doc comments. Here's a similar example in JavaScript where the documentation is written inside of a class constructor:

MyNamespace.Class1 = function() {
    /// <summary>
    /// Summary description for Class1
    /// </summary>

Another difference with C# or VB.NET is that property and event accessors are two different entities in JavaScript. For this reason, we had to choose where the documentation should be for those members. Properties should be documented in the getter and events in the "adder" for this reason:

get_myProperty: function() {
    /// <value>Documentation goes on the getter.</value>
    return this._myProperty;
},
set_myProperty: function(value) {
    // No doc comments here
    this._myProperty = value;
}

Doc comment tags

The locid attribute

Most of the tags that I'm about to describe can have their description text inside of the tag itself or the tag can reference an external description using an identifier as the value of the locid attribute. This of course enables documentation to be localized.

The choice of the identifier is free but our team is using the following convention (the identifiers are actually being automatically generated by our preprocessor):

  • “T:J#MyNameSpace.MyType” for types
  • “M:J#MyNameSpace.MyType.myMethod” for methods (use #ctor as the method name for the constructor)
  • “P:J#MyNameSpace.MyType.myProperty” for properties (in this case the getter would be get_myProperty)
  • “F:J#MyNameSpace.MyType.myField” for fields
  • “E:J#MyNameSpace.MyType.myEvent” for events (in this case the adder would be add_myEvent)
Type attributes

The param, returns, value and field tags that are described below all share the same description of types using attributes. All type information is always optional but you should note that not specifying the type is not the same as specifying type="Object" as everything is not an instance of Object in JavaScript.

The type attribute is used to specify the name of the type of the parameter, return value, property or field.

There are a few cases though where that type is not enough. Namely, in JavaScript, there is no integer type, only a generic Number type. For that reason, and because it's often useful to make that distinction, you can explicitly specify that something is an integer by using both Number as the type and setting the integer attribute to true:

/// <field name="index" type="Number" integer="true"/>

Similarly, DOM elements don't have a type that's well-defined across all browsers. You can specify that somthing is a DOM element by setting the domElement attribute to true. No type should be specified in this case.

Recent research shows that non-null types are extremely useful and should probably represent the norm rather than the exception. For that reason, we added the mayBeNull attribute and made its default value false.

Finally, if the type is Array, it may be desirable to specify the type of the elements of the array (JavaScript has only one variant array type, there is no int[] or String[]). The elementType, elementInteger, elementDomElement and elementMayBeNull are the equivalents for the array elements of the type, integer, domElement and mayBeNull attributes.

<summary locid="descriptionID">Description</summary>

The summary tag can be used in a constructor to describe its class, interface or enumeration, or inside a method, property getter or event "adder" to describe respectively the method, property or event.

<param name="parameterName"
    mayBeNull="true|false" optional="true|false"
    type="ParameterType" parameterArray="true|false"
    integer="true|false" domElement="true|false"
    elementType="ArrayElementType" elementInteger="true|false"
    elementDomElement="true|false"
    elementMayBeNull="true|false">Description</param>

The param tag is used to describe the parameters of a method or constructor. The param tags should be in the same order as the method or constructor's parameters and have the same names.

Optional parameters (which are a way to work around the inexistence of overloads in JavaScript) can be specified using the optional attribute. Optional parameters should come last in the list of parameters and it's good practice to put the "most optional" parameters last.

The parameterArray attribute can be used on the last parameter to specify that this parameter may be repeated as many times as the caller desires. A typical example of this is String.format, which can take as many arguments as the format string enables.

<returns
    type="ValueType" integer="true|false" domElement="true|false"
    mayBeNull="true|false" elementType="ArrayElementType"
    elementInteger="true|false" elementDomElement="true|false"
    elementMayBeNull="true|false">Description</returns>

The returns tag is used to describe the return value of a method. It should be used only if the function returns a value (in other words if it contains a return statement that is not just "return;").

<value
    type="ValueType" integer="true|false" domElement="true|false"
    mayBeNull="true|false" elementType="ArrayElementType"
    elementInteger="true|false" elementDomElement="true|false"
    elementMayBeNull="true|false"
    locid="descriptionID">Description</value>

The value tag describes a property (which shouldn't have a summary tag).

<field name="fieldName" type="FieldType"
    integer="true|false" domElement="true|false" mayBeNull="true|false"
    elementType="ArrayElementType" elementInteger="true|false"
    elementDomElement="true|false" elementMayBeNull="true|false"
    locid="descriptionID">Description</field>

The field tag (which doesn't exist in C# and VB.NET because in those languages the summary tag can be used) is used inside of a class, interface or enumeration constructor to describe a field. A field can't be described near the field itself in JavaScript because the field itself doesn't have a body to contain that description.

<reference path="path/to/the/script/reference.js"
    assembly="Assembly.Name" name="ScriptResourceName.js"/>

The reference tag is used by Visual Studio to describe a dependency a script has with another script file. This enables the IDE to provide IntelliSense on the namespaces and types that are defined in this other file. This tag should be at the top of the file, outside of any code.

The description

The contents of the description itself, whether the tag is summary, param, returns, field or value, is described by the exact same convention that works for C# and VB.NET doc comments. It can be plain text or text containing other XML tags, as described here:

http://msdn2.microsoft.com/en-us/library/5ast78ax(VS.80).aspx

What's next?

This is the convention we're using to document and enhance our scripts and we encourage you to do the same, whether you use Microsoft Ajax or not if only to give your users IntelliSense in Visual Studio.

Similarly, there is no reason why Visual Studio should be the only IDE to handle XML doc comments. We would love it if other IDEs chose to use that format to provide better IntelliSense (or auto-completion).

In a future post, I'll describe how you can extract those XML documentation comments to build usable documentation using existing tools that were designed for managed code.

UPDATE: added the optional attribute for params, which I had omitted.

UPDATE 2: Omar Khan gave a great talk at Mix 07 on the new features in Visual Studio Orcas. Around minute 45, he starts demonstrating JavaScript IntelliSense:
http://sessions.visitmix.com/default.asp?event=1011&session=2012&pid=DEV14&disc=&id=1523&year=2007&search=DEV14

UPDATE 3: added "J#" to naming convention for the locids, to enable managed code and script to implement the same namespaces without a collision in the locids. Also removed locid from param and returns.

UPDATE 4: ScriptDoc, the documentation extraction tool that builds xml files from these doc comments for consumption by Sandcastle, is now available on Codeplex.

How to keep some context attached to a JavaScript event handler?

The problem is the following... You want to attach a handler to a DOM event but you want some information to remain associated with it. Let's say for example that the handler is a method of an object that makes use of the "this" pointer somewhere in its body (as it should, otherwise it should probably be static). As the API to attach a handler just takes a function pointer, and the "this" pointer is determined by the DOM element that triggered the event, it seems difficult to do. The Microsoft Ajax Library (like almost all Ajax libraries, let's be honest) provides an easy way to work around that. If you call:

var myDelegate = Function.createDelegate(this, this.myHandler);

then myDelegate will contain a reference to the this.myHandler function within which "this" will always mean the same thing as when you called createDelegate. For those of you who want to know how this works, feel free to look at the code. It's actually a simple application of closures.

We also have a variant of this that associates arbitrary context (not just the meaning of "this") with a function pointer. You can think of it as a differed execution of a function where the parameters are determined in advance:

var myCallback = Function.createCallback(myHandlerFunction, {foo: "bar"});

The callback function that this command creates can be called without any arguments but it will remember the argument that was passed in when the callback was created. For example, if the function body is:

function myHandlerFunction(p) {
    alert(p.foo);
}

Then calling myCallback() will display an alert with "bar" as the message. Now if you want to use this as an event handler and hook it some HTML element, you have to know that the function will be called with the DOM event object as the first parameter and your context parameter will be demoted to second parameter:

function myHandlerFunction(e, p) { // DOM event handler here
    alert(e.target.tagName + " raised an event with parameter " + p.foo);
}

But if you're building a component and all you want to do is hook up a bunch of DOM events to instance methods where you use the "this" pointer to refer to your component instance, the easiest way is probably to use $addHandlers (don't forget to also call $clearHandlers from dispose...):

$addHandlers($get("myElement"), {
        click: this._onclick,
        focus: this._onfocus,
        blur: this._onblur
    }, this);

This will create the delegates to _onclick, _onfocus and _onblur for you and attach them to the click, focus and blur events of myElement. That's a great helper if you're developing controls or behaviors.

There are a few more complex things that you can do with createCallback and createDelegate but that should give you the essential information. Feel free to ask questions in the comments section if you want to know more.

UPDATE: I forgot to mention that those techniques, beyond being quite common in JavaScript/DHTML, are closely related to "currying": http://en.wikipedia.org/wiki/Currying

UPDATE 2: I made the DOM event case a little clearer and included an example of that.

OpenAjax meetings

It was my great pleasure to be at the face to face OpenAjax Alliance meetings for the first time last month. Thanks to the nice people at IBM for hosting them. I really enjoyed the discussions with Alex from Dojo, Gideon from OpenSpot and many others. There were also great demos of OpenAjax-based interoperability.

It was also the occasion for me to visit New-York where I hadn't been in more than fifteen years. After the initial shock of not recognizing the skyline from the plane, which affected me more than I expected, I just realized how much I love the atmosphere of a city where people actually walk. It reminded me in a way of Paris, where I lived most of my life. Here are some pictures...

Atlas in New-York 
Atlas in New-York

A walk in the park
A walk in the park. The weather was mild enough to walk around without a jacket but the snow wasn't melted yet. Very nice.

Very thin ice indeed: probably no more than a few angströms
Very thin ice indeed: probably no more than a few angstroms.

A walk in the park

A walk in the park

A walk in the park 

A walk in the park

A walk in the park

A walk in the park

View from my hotel room
View from my hotel room.

Ice on lake Erie 
Ice on lake Erie as seen from the plane back to Seattle. To give a sense of scale, the blocks of ice are probably about a kilometer wide each.

Scott on JSON hijacking

Scott has a great post on how ASP.NET Ajax has built-in mitigations already in place for JSON hijacking attacks:
http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx

More Posts