Archive for February, 2009

Speaking about the web of data

Wednesday, February 25th, 2009

Today at 19:00 CET I’ll be speaking at a local web meet-up about the web of data. There’ll be a live feed of the talk available and since I’ll be speaking in English you can tune it. This is a quick translation of the abstract posted on Slovenian sites:

Numerous services are emerging on the web that provide data in a computer friendly form through APIs, microformats, feeds,… Even your blog is actually a database as it syndicates its content via feeds and new posts trigger a ping you can subscribe to.

This fact opens new ways of collaboration – so called mash-ups, but this isn’t really a new concept. What’s new about it is the fact that we don’t use this word anymore as all the new services are some sort of a mash-up leveraging existing services. But accessing data is not the only way to leveraging these services – it’s becoming increasingly easy to create an application that lives in other applications without their approval through browser extensions and bookmarklets.

Marko Mrdjenovič from Zemanta will talk about what you can do to make your site more mash-up friendly and why that’s becoming increasingly important. As a developer I’ll also present what options you have and give a few tips on what to do and what to avoid when developing these kind of apps.

If you have any questions during the talk use twitter to tell me and I’ll try to answer them. Or put them in the comments.

Update: The video is now online. It’s in English so go watch it and tell me what you think.

Reblog this post [with Zemanta]

Don’t make an ASS of U and ME

Friday, February 20th, 2009

What’s wrong with the following line of code (from WordPress 2.6.5, common.js)?

jQuery(function(){jQuery('#media-buttons a').tTips();});

What guarantees do you have that by the time the internal function executes the global jQuery will still be the one you expect it to be or that it will have the tTips plug-in you attached a few lines earlier? Nothing. You just ASSUME it will be. You didn’t put it there, so you can be sure that nobody will. Right.

jQuery developers knew this might be a problem so jQuery will pass a reference to the itself as an argument when triggering this event:

jQuery(function($){$('#media-buttons a').tTips();});

This would work and wouldn’t break. And it would make your platform a bit more hackable.

jQuery.readyOrDone

Thursday, February 19th, 2009

There’s a really small probability that someone might need something like this but I did and I’d like to share it.

At Zemanta we have a few different ways of loading our scripts and we cannot always control when they do. The Firefox extension will load the scripts on DOM ready, WordPress plugin will load them somewhere in the middle of the HTML, Drupal and MovableType plugins will load them in the head and IE extension will load them sometime while loading the page.

This all means that we have to delay some of our code execution to when DOM is ready and scripts are loaded. Which is where the problem kicks in.

jQuery has this nice way of doing this with $(document).ready(fn) or short $(fn) which waits until the document is ready and executes the passed fn function. If the document is ready it will execute the function immediately. Our issue lies in what “document is ready” means to jQuery – it means different thing in different browsers.

In browsers that support DOMContentLoaded (Firefox, Webkit, Opera – let’s call them modern browsers) “document is ready” means that either DOMContentLoaded event fired on the document or the load event fired on its window. On IE “document is ready” means that either onreadystatechange fired with readyState === 'complete' on the document or document.documentElement.doScroll("left") is successful (Diego Perini hack). To make this short – if you load jQuery after all the events fired in modern browsers jQuery will never know that the document is ready.

To get around this (we really don’t like having our own hacked version of jQuery) I wrote this little plugin:

(function ($) {
$.readyOrDone = function (fn) {
	var s = document.readyState;
	if (s === 'complete') {
		$.ready();
	}
	$(fn);
};
})(jQuery);

As you can see this will check if document is in a “complete” state and fire the ready method on jQuery which usually fires when DOM is ready – if it fired before it will do nothing. It will then add the function to the ready queue which also has this nice feature of firing immediately if DOM is ready.

All you have to do is change your $(fn) calls to $.readyOrDone(fn) and you have a bulletproof solution for executing functions when DOM is ready even if jQuery was late to the party and has no idea if the document is really ready.

Update: Filed a bug and hoping for the best.

Update 2: I found out that not all browsers provide the readyState property – Firefox on Ubuntu for example. Devised a new version that tries to smartly handle such cases:

(function ($) {
	var time = setTimeout(function () {}, 0),
		lastelm = null;
	$.readyOrDone = function (fn) {
		var s = document.readyState, getLast = function () {
			var elms = document.getElementsByTagName('*');
			return elms[elms.length - 1];
		};
		if (s === 'complete') {
			$.ready();
		} else if (typeof s === 'undefined') {
			lastelm = getLast();
			clearTimeout(time);
			time = setTimeout(function () {
				if (getLast() === lastelm && typeof document.readyState === 'undefined') {
					 $.ready();
				}
			}, 1000);
		}
		$(fn);
	};
})($);
Reblog this post [with Zemanta]