Introducing PixelPerfectJs

PixelPerfectJs allows developers to put an image overlay on top of your HTML page and achieve pixel precise results.

How to use:
———–
Save the following link as a bookmark, or drag it to the links/bookmarks bar in your browser:

PixelPerfectJS

Or if you don’t want to use the bookmarklet, just add the following line before your closing body tag:
<script type="text/javascript" src="//dl.dropbox.com/u/2369055/pixelperfectjs/_ui/js/pixelPerfect.all.js"></script>

The PixelPerfectJS panel will then be displayed.

Settings:
———
* Enable: Yes/No. Whether you want to enable PixelPerfectJs or not
* Designs: Enter the image URL you want to overlay on top of your HTML. It must be either an absolute or relative URL. You can add as many images as you want.
* Position: You can manually set the position of the overlay
* Opacity: Control the opacity of the overlay.

Features:
———
* Simple! Just add 1 line of javascript!
* Not an extension or addon. Will work in any browser!
* No image size restrictions!
* Multiple overlays support
* Your settings are saved between sessions.

Contact:
———
Please send bug reports and ideas for future versions to: asvin.balloo@gmail.com

You can find the code on GitHub too: https://github.com/asvinb/pixelperfectjs
Feel free to contribute!

Writing your first Greasemonkey script – adding menus to Facebook’s top menu

This post will show you how to write a basic Greasemonkey script that will add two more menu items to Facebook’s friends top menu as shown below.

These 2 menu items are :

  • “Recently Updated” – show all your friends with recent updates
  • “Status Updates” – show the latest status updates of your friends

About Greasemonkey

Greasemonkey is a Firefox extension that allows you to write scripts that alter the web pages you visit. You can

  • use it to make a web site more readable or more usable
  • fix rendering bugs that the site owner can’t be bothered to fix themselves.
  • alter pages so they work better with assistive technologies that speak a web page out loud or convert it to Braille
  • even automatically retrieve data from other sites to make two sites more interconnected.

Greasemonkey by itself does none of these things. In fact, after you install it, you won’t notice any change at all… until you start installing what are called “user scripts”. A user script is just a chunk of javascript code, with some additional information that tells Greasemonkey where and when it should be run. Each user script can target a specific page, a specific site, or a group of sites.

Install Greasemonkey addon for Firefox

Go to Greasemonkey addon page, click on the “Add to Firefox” button and follow the instructions. After restarting Firefox, you will notice a monkey’s head sitting at the bottom right its status bar.
If you right click on the monkey’s head and choose “Manage User Scripts” from the resulting menu, you will notice there isn’t any script which is quite normal since we have not installed any ;-).

Creating your first Greasemonkey script.

For a Greasemonkey to be recognized, it must end with .user.js, so let us create an empty file and save it as myfirstscript.user.js
Fire up your favourite text editor and open your newly created file.

Greasemonkey script metadata

All user scripts has a meta data section which tells Greasemonkey about the script itself, where it came from, and when to run it. For example, our script :

// ==UserScript==
// @name          My First GM script
// @namespace     http://htmlblog.net
// @description   basic Greasemonkey script
// @include       http://www.facebook.com/
// ==/UserScript==

You can find more information about the metadata here.

Remember we want our script available only for Facebook pages, that is why we use @include http://www.facebook.com

Show me some code.

Alright, to add our own menus, we need to get the parent element holding the drop down menu. After inspecting Facebook’s source code, we can rapidly come to the conclusion that the parent element’s id is “fb_menu_friends_dropdown”. So the current Facebook code looks like that :

<div class="fb_menu_dropdown hidden_elem" id="fb_menu_friends_dropdown">
<div class="fb_menu_item"><a href="http://www.facebook.com/friends/?added&amp;ref=tn">Recently Added</a></div>
<div class="fb_menu_item"><a href="http://www.facebook.com/friends/?everyone&amp;ref=tn">All Friends</a></div>
<div class="fb_menu_separator"></div>
<div class="fb_menu_item"><a href="http://www.facebook.com/invite.php?ref=tn">Invite Friends</a></div>
<div class="fb_menu_item"><a href="http://www.facebook.com/find-friends/?ref=friends">Find Friends</a></div>
</div>

and our goal is to insert the two menu items before the “Recently Added” item.

For us to do that, we need to get the first child of the parent element and then insert our elements before it and to help us, i.e walking through the DOM selecting parent and childs, I use a little piece of code found on Github, which eliminates whitespace issues between elements among other features. So our myfirstscript.user.js can be updated to :

// ==UserScript==
// @name          My First GM script
// @namespace     http://htmlblog.net
// @description   basic <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> script
// @include       http://www.facebook.com/
// ==/UserScript==
DOM = function () {

    function get(id) {
        if (id && typeof id === 'string') {
            id = document.getElementById(id);
        }
        return id || null;
    }

    function walk(element, tag, walk, start, all) {
        var el = get(element)[start || walk], elements = all ? [] : null;
        while (el) {
            if (el.nodeType === 1 && (!tag || el.tagName.toLowerCase() === tag)) {
                if (!all) {
                    return el;
                }
                elements.push(el);
            }
            el = el[walk];
        }
        return elements;
    }

    return {

        // Get the element by its id
        get: get,

        walk: walk,

        // Returns the previousSibling of the Element (excluding text nodes).
        getPrevious: function (el, tag) {
            return walk(el, tag, 'previousSibling');
        },

        // Like getPrevious, but returns a collection of all the matched previousSiblings.
        getAllPrevious: function (el, tag) {
            return walk(el, tag, 'previousSibling', null, true);
        },

        // As getPrevious, but tries to find the nextSibling (excluding text nodes).
        getNext: function (el, tag) {
            return walk(el, tag, 'nextSibling');
        },

        // Like getNext, but returns a collection of all the matched nextSiblings.
        getAllNext: function (el, tag) {
            return walk(el, tag, 'nextSibling', null, true);
        },

        // Works as getPrevious, but tries to find the firstChild (excluding text nodes).
        getFirst: function (el, tag) {
            return walk(el, tag, 'nextSibling', 'firstChild');
        },

        // Works as getPrevious, but tries to find the lastChild.
        getLast: function (el, tag) {
            return walk(el, tag, 'previousSibling', 'lastChild');
        },

        // Works as getPrevious, but tries to find the parentNode.
        getParent: function (el, tag) {
            return walk(el, tag, 'parentNode');
        },

        // Like getParent, but returns a collection of all the matched parentNodes up the tree.
        getParents: function (el, tag) {
            return walk(el, tag, 'parentNode', null, true);
        },

        // Returns all the Element's children (excluding text nodes).
        getChildren: function (el, tag) {
            return walk(el, tag, 'nextSibling', 'firstChild', true);
        },

        // Removes the Element from the DOM.
        dispose: function (el) {
            el = get(el);
            return (el.parentNode) ? el.parentNode.removeChild(el) : el;
        }

    };
}();

To get the parent element and its first child, we then append the following code :

// get drop down menu
var parentNode = DOM.get('fb_menu_friends_dropdown');
// get its first child
var firstNode = DOM.getFirst('fb_menu_friends_dropdown');

Creating our nodes

Now we must create our two nodes which will be inserted afterward. This is done easily with the following code which is self explanatory :

/** For "Recently Updated" */
// create our div with class fb_menu_item
var recentDiv = document.createElement('div');
recentDiv.setAttribute('class', 'fb_menu_item');

// create our link
var recentLink = document.createElement('a');
recentLink.href = 'http://www.facebook.com/friends/?recent&ref=tn';
	
// add text to our link
var recentDivContent = document.createTextNode('Recently Updated');
recentLink.appendChild(recentDivContent);
	
// add link to our div
recentDiv.appendChild(recentLink);


/** For "Status Updates" */
// create our div with class fb_menu_item
var statusDiv = document.createElement('div');
statusDiv.setAttribute('class', 'fb_menu_item');
	
// create our link
var statusLink = document.createElement('a');
statusLink.href = 'http://www.facebook.com/friends/?status&ref=tn';
	
// add text to our link
var statusDivContent = document.createTextNode('Status Updates');
statusLink.appendChild(statusDivContent);
	
// add link to our div
statusDiv.appendChild(statusLink);

We can also add a separator, for having a cleaner look :

/** Creates a separator, just to look good */
var separatorDiv = document.createElement('div');
separatorDiv.setAttribute('class', 'fb_menu_separator');

Finally we insert these 3 nodes before the first child element we got earlier on :

// add all divs before first child of menu
parentNode.insertBefore(statusDiv, firstNode);
parentNode.insertBefore(recentDiv, firstNode);
parentNode.insertBefore(separatorDiv, firstNode);

Just to be on the safe side of things, we surround the whole block of code with a try and catch statement.

Putting it all together

So finally our code is like this :

// ==UserScript==
// @name          My First GM script
// @namespace     http://htmlblog.net
// @description   basic <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> script
// @include       http://www.facebook.com/
// ==/UserScript==

DOM = function () {

    function get(id) {
        if (id && typeof id === 'string') {
            id = document.getElementById(id);
        }
        return id || null;
    }

    function walk(element, tag, walk, start, all) {
        var el = get(element)[start || walk], elements = all ? [] : null;
        while (el) {
            if (el.nodeType === 1 && (!tag || el.tagName.toLowerCase() === tag)) {
                if (!all) {
                    return el;
                }
                elements.push(el);
            }
            el = el[walk];
        }
        return elements;
    }

    return {

        // Get the element by its id
        get: get,

        walk: walk,

        // Returns the previousSibling of the Element (excluding text nodes).
        getPrevious: function (el, tag) {
            return walk(el, tag, 'previousSibling');
        },

        // Like getPrevious, but returns a collection of all the matched previousSiblings.
        getAllPrevious: function (el, tag) {
            return walk(el, tag, 'previousSibling', null, true);
        },

        // As getPrevious, but tries to find the nextSibling (excluding text nodes).
        getNext: function (el, tag) {
            return walk(el, tag, 'nextSibling');
        },

        // Like getNext, but returns a collection of all the matched nextSiblings.
        getAllNext: function (el, tag) {
            return walk(el, tag, 'nextSibling', null, true);
        },

        // Works as getPrevious, but tries to find the firstChild (excluding text nodes).
        getFirst: function (el, tag) {
            return walk(el, tag, 'nextSibling', 'firstChild');
        },

        // Works as getPrevious, but tries to find the lastChild.
        getLast: function (el, tag) {
            return walk(el, tag, 'previousSibling', 'lastChild');
        },

        // Works as getPrevious, but tries to find the parentNode.
        getParent: function (el, tag) {
            return walk(el, tag, 'parentNode');
        },

        // Like getParent, but returns a collection of all the matched parentNodes up the tree.
        getParents: function (el, tag) {
            return walk(el, tag, 'parentNode', null, true);
        },

        // Returns all the Element's children (excluding text nodes).
        getChildren: function (el, tag) {
            return walk(el, tag, 'nextSibling', 'firstChild', true);
        },

        // Removes the Element from the DOM.
        dispose: function (el) {
            el = get(el);
            return (el.parentNode) ? el.parentNode.removeChild(el) : el;
        }

    };
}();

try{
	// get drop down menu
	var parentNode = DOM.get('fb_menu_friends_dropdown');
	// get its first child
	var firstNode = DOM.getFirst('fb_menu_friends_dropdown');
	
	/** For "Recently Updated" */
	// create our div with class fb_menu_item
	var recentDiv = document.createElement('div');
	recentDiv.setAttribute('class', 'fb_menu_item');
	
	// create our link
	var recentLink = document.createElement('a');
	recentLink.href = 'http://www.facebook.com/friends/?recent&ref=tn';
	
	// add text to our link
	var recentDivContent = document.createTextNode('Recently Updated');
	recentLink.appendChild(recentDivContent);
	
	// add link to our div
	recentDiv.appendChild(recentLink);

	
	/** For "Status Updates" */
	// create our div with class fb_menu_item
	var statusDiv = document.createElement('div');
	statusDiv.setAttribute('class', 'fb_menu_item');
	
	// create our link
	var statusLink = document.createElement('a');
	statusLink.href = 'http://www.facebook.com/friends/?status&ref=tn';
	
	// add text to our link
	var statusDivContent = document.createTextNode('Status Updates');
	statusLink.appendChild(statusDivContent);
	
	// add link to our div
	statusDiv.appendChild(statusLink);

	/** Creates a separator, just to look good */
	var separatorDiv = document.createElement('div');
	separatorDiv.setAttribute('class', 'fb_menu_separator');
	
	// add both divs before first child of menu
	parentNode.insertBefore(statusDiv, firstNode);
	parentNode.insertBefore(recentDiv, firstNode);
	parentNode.insertBefore(separatorDiv, firstNode);
}
catch(e){};

Installing and testing our script

Fire up Firefox and select “File” -> “Open File…” in the menu bar and then browse for your script, i.e myfirstscript.user.js in our case. You will be prompted to install the script by Greasemonkey. After installation is complete, head to Facebook, login and hover over the “Friends” menu, you will see your newly created menus.

Download script
Install script

WP To Top – a WordPress plugin that takes you to the top

About WP To Top

WP To Top is a WordPress plugin that adds a “Back to top” link in your blog without modifying your template files. This is useful especially if you have long posts or long pages. You will have a nice “Back to top” or whatever-text-you-want link floating at the bottom right/left of your page.

Features

  • Smooth scrolling animation and fade in, fade out effect, powered by the YUI library
  • Customizable options via the admin panel, from the text to the position of the link
  • Works on almost all browsers including IE6 (yes!)

Download

You can get the plugin here

Demo

You have a demo on this page. Just scroll a little bit and you will see a nice “Take me up” link appearing at the bottom of your page.

Installation

  • Extract wptotop.zip in the “/wp-content/plugins/” directory
  • Activate the plugin through the “Plugins” menu in WordPress
  • Go to “Settings” and then “WP To Top” to configure the plugin. The options are self explanatory and easy to understand.

Thanks

I got the inspiration to write this plugin after having a look at David Walsh’s jQuery topLink Plugin. Thanks to the YUI team for the great YUI library and Semih’s Animated Page Scroll with YUI.

twitree.com – see on which leaves the birds are…

I am happy to announce the launch of twitree.com. It’s a twitter application which allows a twitterer to view his followers in a tree-like navigation, which can be expanded.

twitree

twitree makes extensive use of the YUI library. The following components were used :

  • grids css – for the layout
  • yahoo dom event – for DOM and event handling
  • connection manager – for AJAX requests like getting the list of followers for a user
  • container family – to display modal dialogs like prompting for a twitter username, displaying the loading panel
  • JSON utility – to parse the JSON data twitree receives from the twitter servers
  • cookie utility – to fetch username information from a cookie so that the user doesn’t have to input his username every time
  • and finally the treeview control which provides a nice tree and dynamically loads the data upon clicking on a node

The application is very much in an initial phase and there are some limitations, like only 100 followers are being returned, rate limiting, etc…

Stay tuned for further information

Latest update :

twitterers can now

  • update their status via twitree
  • follow a user by right clicking on the user and choose “Follow” from the contextual menu
  • send a direct message to a fellow twitterer by right clicking on the user and choose “Send message” from the contextual menu

FAQ has also been added

Alternate colors to table rows with javascript (YUI)

This article will show you how to add alternate colors to table rows without any server side development or hard coding your scripts, thus providing good readability for your users and great flexibility for you. We will use the YUI library for that.
Continue reading Alternate colors to table rows with javascript (YUI)

Bubble menu javascript or playing with YUI’s event delegation

bubble
Image courtesy of jobee59’s photostream

Event delegation refers to the use of a single event listener on a parent object to listen for events happening on its children (or deeper descendants). Event delegation allows developers to be sparse in their application of event listeners while still reacting to events as they happen on highly specific targets. This proves to be a key strategy for maintaining high performance in event-rich web projects, where the creation of hundreds of event listeners can quickly degrade performance. More on event delegation including examples.

This post illustrates the use of event delegation to create a “bubble” menu, inspired by Bedrich Rios’ post on Nettuts.
Continue reading Bubble menu javascript or playing with YUI’s event delegation

8 practical tips to make your web pages faster

Yahoo’s Exceptional Performance team has compiled a list of 34 best practices to have faster web pages. In this post I’ll show you 8 tips which helped me to get a B grade in YSlow! for web pages that I develop. Currently YSlow’s web page analysis is based on 13 identified basic rules that affect web page performance. In decreasing order of priority they are:

  1. Make Fewer HTTP Requests
  2. Use a Content Delivery Network
  3. Add an Expires Header
  4. Gzip Components
  5. Put CSS at the Top
  6. Move Scripts to the Bottom
  7. Avoid CSS Expressions
  8. Make JavaScript and CSS External
  9. Reduce DNS Lookups
  10. Minify JavaScript
  11. Avoid Redirects
  12. Remove Duplicate Scripts
  13. Configure ETags

You can get more info by clicking on each item. Of course using a CDN is not affordable by everybody, including me. This didn’t prevent me to have a B grade though. I will guide you through some of the items which worked for me.
Continue reading 8 practical tips to make your web pages faster

Pixidou – an Open Source AJAX Image Editor (PHP and YUI based)

Pixidou is a new open source AJAX image editor which will allow you to :

  • adjust brightness
  • adjust contrast
  • cropping
  • flipping
  • negative
  • resizing
  • rotating
  • tint

images.
Continue reading Pixidou – an Open Source AJAX Image Editor (PHP and YUI based)

Show/hide containers by only adding CSS classes without writing javascript code (YUI-based)

This post will show you how to add the collapse/expand functionality in your HTML pages, perfect for FAQs by only adding two class names to your existing page and including the scripts below. Of course it’s all YUI-based and also a demo of the fantastic YUI selector utility.

Continue reading Show/hide containers by only adding CSS classes without writing javascript code (YUI-based)