Archive for the ‘Programming’ Category

Recently I noticed that one of my Greasemonkey script called “Google Reader Unread Count in Gmail” was displaying the wrong count. I was too busy but at least two users urged me to solve the problem so I took a look into the issue, which turned out to be very simple and easy to fix.

In fact Google changed the xml schema of the output so my script was displaying a timestamp. That’s why the count look so strange :)

Now the source code on userscripts.org is updated(here’s the diff). Please update your local version if you’re facing the same problem.

A very common purpose of Greasemonkey scripts is modifying the DOM structure of the document, mostly adding something new.

I’ve written several scripts before and have been doing such modifications in the “load” event handler, as in this script. The problem is that “load” event is fired after all images on the page have been downloaded completely, so users may suffer a great delay to see the changes occur if there’re many images.

jQuery users know that jQuery has a function “ready”. It won’t wait for the images to load. We are writing Greasemonkey scripts, so we only care about Firefox. Firefox has a “DOMContentLoaded” event explained in detail here.

Fired on a Window object when a document’s DOM content is finished loaded, but unlike “load”, does not wait till all images are loaded. Used for example by GreaseMonkey to sneak in to alter pages before they are displayed.

So when writing my last script I tried to rely on this event:

window.addEventListener('DOMContentLoaded', function(e) {
	...
}, false);

But the codes in the handler were not executed.

I was confused and did some searching. Finally I got this page saying that “the code in a Greasemonkey user script gets invoked when the DOMContentLoaded event fires”. That explains all. The “DOMContentLoaded” event was already fired so the codes never had a chance to get executed.

The solution, of course, is pulling the handler codes out of the wrapper. If your script doesn’t really rely on the “load” event, don’t put them into its handler because there may be a obvious delay.

I’m a fan of Google Reader. Although FeedDemon went free recently and it offers synchronization with NewsGator which is great attraction for many people, I still couldn’t drop Google Reader.

However the panel above the subscription list takes up too much space for my humble screen resolution of 1024×768. As Google rolled out the much complained “Friends’ shared items” feature, it became an urgent task for me to hide the annoying but never used panel. It took up 1/3 of the vertical space on the left sidebar!

No, not just hiding. Sometimes I need to clear the number of unread friends’ shared items. So it should be a “toggler” like the sidebar (or nav-bar as called by Google) toggler natively built in Google Reader. Like this:

Before hiding, with mouse hovering on the toggler:

toggler

When the panel is hidden:

panel hidden

You can still open it at any time. Basically, it works in the same way as the native sidebar toggler.

This is done by writing a user script for Greasemonkey, so you must have Greasemonkey installed to use it.

Get it now.

Today I did some modifications to Starbox to let it utilize the power of Prototip. They are both cool JavaScript libraries written by Nick Stakenburg.

Starbox prototip

How does it work? When you hover your mouse on a star, a tip shows you a brief word like “lame” or “great” which helps you with your choice. If the rating box is locked, a single tip is shown wherever you hover on the box. Check out the demo. View its source to see how to get it working.

You can globally set the tips, or specify a group of tips for each specific rating box instance.

Get it

View Diff | Download the modified version

CSS for the tip (included in the zip archive):

.prototip .startip {
 color: infotext;
 background-color: infobackground;
 border: 1px solid infotext;
 padding: 1px;
}

I saw on the web many discussions about “the best JavaScript editor”. This kind of discussions are quite like “the best PHP editor”. Neither of these two languages has a good editor as other languages like C++/Java. The difficulty in making a good PHP editor is that PHP codes are always mixed with HTML. And the difficulty in making a good JavaScript editor is that JavaScript is too flexible and even worse, different browsers have different implementations.

But there are some good JavaScript editors that’s recommended by people engaged in the discussions. The most mentioned two are JSEclipse and Aptana.

Aptana

I only tried it (the free plugin for Eclipse) for two weeks and gave up.

In Aptana’s editor, you can select a piece of code and press Ctrl+Shift+F to format it, which is like the Java editor. That’s good. But the formatting result is not as good, unfortunately. I couldn’t configure it to generate the same formatting as Java code. So actually this good feature is of no use for me. Even worse, when you press } to close a block, it will “help” you format this block. Clever, but ugly.

Aptana shows its suggestions for you almost every time in type in a character. But the suggestions are absolutely useless most of the times.

Features described on its homepage are quite promising but I didn’t try them all. These two mentioned above are already too annoying. So I switched back to JSEclipse.

JSEclipse

I use JSEclipse most of the time. It’s very simple compared to Aptana. You can see a list of features on its homepage. For me, the most useful feature is that when the cursor is on some identifier (variable, function name, etc.), all occurrences of the same identifier are highlighted. Even though sometimes it will wrongly mark some extra identifiers, it doesn’t matter much.

Sadly it’s acquired by Adobe. You see, the links given above are adobe’s. The original homepage, however, is here. The last update to JSEclipse was on April 2, 2007. So it’s almost dead. It’s really a pity. See this post in Adobe forums.

Anyway, these are only my own experiences and may be full of prejudices. Which editor are you using for editing JavaScript? please comment below.

When I started working on the Neighbor Post Preview plugin, I expected WordPress to have a built-in function to get an excerpt from an arbitrary post. But it doesn’t have one, sadly.

There is only an the_excerpt tag for use within The Loop. It’s defined in wp-includes/post-template.php (version 2.3.2 code):

function the_excerpt() {
	echo apply_filters('the_excerpt', get_the_excerpt());
}

function get_the_excerpt($deprecated = true) {
	global $id, $post;
	$output = '';
	$output = $post->post_excerpt;
	if ( !empty($post->post_password) ) { // if there's a password
		if ( $_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password ) {  // and it doesn't match the cookie
			$output = __('There is no excerpt because this is a protected post.');
			return $output;
		}
	}

	return apply_filters('get_the_excerpt', $output);
}

See the bad code? I don’t know who wrote this, but the line “$output = $post->post_excerpt;” should be placed after the if block. OK, this is out of topic :) .

Generally the function retrieves the explicit post excerpt and apply filters “get_the_excerpt” and “the_excerpt”. What is the explicit excerpt? When you’re writing or editing a post, its input is right below your editing area. I never wrote one, though. Most bloggers don’t write excerpts, I believe. So what happens when we apply filter “get_the_excerpt” to an empty string?

Let’s have a look at the code in wp-includes/default-filters.php:

add_filter('the_excerpt', 'wptexturize');
add_filter('the_excerpt', 'convert_smilies');
add_filter('the_excerpt', 'convert_chars');
add_filter('the_excerpt', 'wpautop');
add_filter('get_the_excerpt', 'wp_trim_excerpt');

By default, the string is processed only by the function wp_trim_excerpt (defined in wp-includes/formatting.php) before applying “the_excerpt” filters:

function wp_trim_excerpt($text) { // Fakes an excerpt if needed
	global $post;
	if ( '' == $text ) {
		$text = get_the_content('');
		$text = apply_filters('the_content', $text);
		$text = str_replace(']]>', ']]>', $text);
		$text = strip_tags($text);
		$excerpt_length = 55;
		$words = explode(' ', $text, $excerpt_length + 1);
		if (count($words) > $excerpt_length) {
			array_pop($words);
			array_push($words, '[...]');
			$text = implode(' ', $words);
		}
	}
	return $text;
}

If the string is empty, the excerpt is faked using the content of the global $post. After that, the excerpt is filtered by some functions to make some “clean” text.

So I wrote this helper function for use in the plugin:

function tlnpp_excerpt($text, $excerpt_length = 55) {
	$text = str_replace(']]>', ']]>', $text);
	$text = strip_tags($text);
	$words = explode(' ', $text, $excerpt_length + 1);
	if (count($words) > $excerpt_length) {
		array_pop($words);
		array_push($words, '[...]');
		$text = implode(' ', $words);
	}

	return apply_filters('the_excerpt', $text);
}

This function truncate an arbitrary piece of text to 55 words by default, and process the result using the default WordPress filter functions (converts smiley’s, for example). It truncates text by words not characters, and the result is safe.

For more information, have a look at the code of the plugin. It’s very simple. Any suggestions?