Google Chrome : array evals return out of order

I just want to make others aware of a little quirk with Google Chrome’s Javascript engine (V8), eval’d associative JSON arrays (aka objects) are returned in the incorrect order . The problem is that the engine doesn’t do what a programmer would expect it to do, but the programmer should be aware of why its happening and that it does happen.

Basically, take the following psuedo associative array/object and its corresponding JSON version:

Psuedo Associative array
Array (
 3503 => '',
 3847 => '',
 6852 => ''
);

JSON Array
var data = {3503:'',3847:'',6852:''};

Pretty basic huh? But that happens when we loop over this array/object? In Firefox, Safari and IE we get the same result, which is the array elements in the order listed above. Chrome on the other hand returns the items out of order. Now I know you are probably thinking, “its an array/object, order doesn’t matter”. This is technically true, but not if you are relying on the order for some reason, then you might find bugs cropping up. Check out the code below:

var data = {3503:'',3847:'',6852:''};
var s = '';
for(var i in data) {
	s += i + ',';
}
alert("Expected order: 3503,3847,6852nOrder observed: " + s)

Firefox, Safari and IE all return the following alert:

Expected order: 3503,3847,6852
Order observed: 3503,3847,6852

Chrome on the other hand returns this:

Expected order: 3503,3847,6852
Order observed: 6852,3503,3847


Weird! Give it a try in your current browser by clicking here

Javascript guru, John Resig, has posted a note about this:
http://ejohn.org/blog/javascript-in-chrome/

Or for the official bug reports:
http://code.google.com/p/v8/issues/detail?id=6
http://code.google.com/p/chromium/issues/detail?id=883

As always with javascript programming, expect the unexpected… and…
Be Warned!

Trac ticket: reset to new

We have recently moved from Mantis to Trac at work for our bug/task tracking, but we have encountered a slight issue with Trac’s workflow management. The issue is that we wanted to be able to move a ticket from the ‘assigned’ state to the ‘new’ state. This is a common scenario if a team member leaves or goes on holiday while they have tasks assigned to them. Quite often you wouldn’t just want to blindly ‘reassign’ these issues to another member, but reset them to their new status so another member can pick the task up when they have the time.

We decided to introduce a new state called ‘reset’ in the trac.ini [ticket-workflow] block which allows us to easily reset a ticket to the ‘new’ status as if it had just been created in the system. The new block looks like this:

reset = * -> new
reset.operations = del_resolution
reset.permissions = TICKET_MODIFY

Now at the bottom of each ticket, we have an option which says:

[ ] reset  Next status will be 'new'

Hope this works for you too :)

jQuery fadeIn/fadeOut IE cleartype glitch

While using the jQuery  javascript library today at work, I noticed a glitch under IE7. When fading a html node with the .fadeIn() and .fadeOut() functions in jQuery, IE drops the windows Cleartype rendering; which results in very ugly text. This problem appears to be very common, but no one has a nice solution for the problem.

The most common way to solve this problem is by removing the filter CSS attribute. In normal javascript, it would look like this:

document.getElementById('node').style.removeAttribute('filter');

and in jQuery, it would look like this:

$('#node').fadeOut('slow', function() {
   this.style.removeAttribute('filter');
});

This means that every single time we want to fade an element, we need to remove the filter attribute, which makes our code look messy.

A simple, more elegant solution would be to wrap the .fadeIn() and .fadeOut() functions with a custom function via the plugin interface of jQuery. The code would be exactly the same, but instead of directly calling the fade functions, we call the wrapper. Like so:

$('#node').customFadeOut('slow', function() {
   //no more fiddling with attributes here
});

So, how do you get this working? Just include the following code after you include the jQuery library for the added functionality.

(function($) {
	$.fn.customFadeIn = function(speed, callback) {
		$(this).fadeIn(speed, function() {
			if(jQuery.browser.msie)
				$(this).get(0).style.removeAttribute('filter');
			if(callback != undefined)
				callback();
		});
	};
	$.fn.customFadeOut = function(speed, callback) {
		$(this).fadeOut(speed, function() {
			if(jQuery.browser.msie)
				$(this).get(0).style.removeAttribute('filter');
			if(callback != undefined)
				callback();
		});
	};
})(jQuery);

I have been informed by Steve Reynolds that the US Whitehouse Website is using some of the JS documented on this blog post. I would just like to say thanks to everyone who contributed in the comments. :)

APML2JSON Script/Service

This script takes an APML feed, and parses it into valid APML-JSON based on the APML-JSON spec on the APML wiki. Instead of manually parsing the APML into JSON, I have used the XSLT file attached to the aforementioned spec page along with xsltproc to generate the JSON data. The idea behind this script is based on John Resig’s RSS2JSON script.At the moment the script is pretty hacky for release, so I have provided a REST interface that can be accessed via a GET request.

A request to the interface would take the following form:
http://bmn.name/examples/apml2json/?url=URL&callback=CALLBACK

The callback parameter is optional. If specified, the resulting JSON is wrapped in the callback for easy parsing at the client end, otherwise the resulting JS Object is assigned to a variable which can be accessed via JS. The results from the call are cached hourly to reduce the load on the server. :)

Example Interface call: http://bmn.name/examples/apml2json/?
url=http://blog.bmn.name/index.php?apml=apml&callback=parseFeed

For more information on how to use the resulting JS, head over to John’s RSS2JSON page as he provides some sample JS.

JSON-APML Tag Cloud

As a member of the APML Google group, I’m constantly reading and keeping in touch with the APML developments. The latest development that sparked my interest was the need for a JSON equivalent of the APML standard which could be used as a more lightweight interchange format for more efficient web application implementations of the APML spec.

David Novakovic put his hand up to start working on the JSON-APML spec, and naturally, I decided to give him a hand. We decided to make the JSON-APML spec as close to the XML version as possible without the bloat of XML. You can read more about the spec proposed over at the JSON-APML Google Groups thread. Feel free to join the group and give your thoughts about the spec proposed.

Given this spec, I decided to do a quick working example of using the JSON-APML format. The example I created uses a service created by Paul Lamere over at Tastebroker. Paul’s script scrapes profile data from various websites, and returns a well-formed APML feed. My script uses these feeds as a base for conversion into the JSON-APML spec.

How it works:

The demo connects to a server with user and service information. The server then scrapes Paul’s APML feeds for a given user/service, parses the APML into JSON-APML and returns it to the browser. The browser then formats the data into a tag cloud using javascript.

Check the example of APML-JSON out.