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!

imgble.com – adaptive image resizing for mobile devices

I am happy to announce the launch of www.imgble.com. imgbleis a web-based utility that formats a specified image to best fit in different mobile screens. Those who work with mobile CMS, rendering image for the mobile devices into suitable format and dimension is obviously a big point to be considered which consumes a big portion of the development time. Based on the mobile device’s screen resolution, imgble automatically resizes your image, keeping its aspect ratio. imgble also supports the chaining of different effects on your image, such as blurring, adding borders, rotating, etc. You can find everything in the documentation.

So let me know your views, comments, and how imgble will be useful to you ;)

Attachment unavailable

Just had some issues with the server and all attachments have gone including pictures, zip files, demo files etc ;-(

Trying to restore from what’s left… not too optimistic though…

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.

10 useful PHP PEAR packages

MDB2

PEAR MDB2 is a merge of the PEAR DB and Metabase php database abstraction layers.

It provides a common API for all supported RDBMS. The main difference to most
other DB abstraction packages is that MDB2 goes much further to ensure
portability. MDB2 provides most of its many features optionally that
can be used to construct portable SQL statements:

  • Object-Oriented API
  • A DSN (data source name) or array format for specifying database servers
  • Datatype abstraction and on demand datatype conversion
  • Various optional fetch modes to fix portability issues
  • Portable error codes
  • Sequential and non sequential row fetching as well as bulk fetching
  • Ability to make buffered and unbuffered queries
  • Ordered array and associative array for the fetched rows
  • Prepare/execute (bind) named and unnamed placeholder emulation
  • Sequence/autoincrement emulation
  • Replace emulation
  • Limited sub select emulation
  • Row limit emulation
  • Transactions/savepoint support
  • Large Object support
  • Index/Unique Key/Primary Key support
  • Pattern matching abstraction
  • Module framework to load advanced functionality on demand
  • Ability to read the information schema
  • RDBMS management methods (creating, dropping, altering)
  • Reverse engineering schemas from an existing database
  • SQL function call abstraction
  • Full integration into the PEAR Framework
  • PHPDoc API documentation

MDB2 – InstallationWiki
How to use PHP and PEAR MDB2

Text_CAPTCHA

Implementation of CAPTCHAs (Completely Automated Public Turing tests to tell Computers and Humans Apart).
Using PEAR’s Text_CAPTCHA to Secure Web Forms

Log

The Log package provides an abstracted logging framework. It includes output handlers for log files, databases, syslog, email, Firebug, and the console. It also provides composite and subject-observer logging mechanisms.
The Log Package
PHPBuilder
Debugging PHP With Firebug
Advanced Logging in PHP with PEAR

LiveUser

LiveUser is a set of classes for dealing with user authentication
and permission management. Basically, there are three main elements that make up this package:

  • The LiveUser class
  • The Auth containers
  • The Perm containers

The LiveUser class takes care of the login process and can be configured to use a certain permission container and one or more different auth containers.
That means, you can have your users’ data scattered amongst many data containers and have the LiveUser class try each defined container until the user is found.
For example, you can have all website users who can apply for a new account online on the webserver’s local database. Also, you want to enable all your company’s employees to login to the site without the need to create new accounts for all of them. To achieve that, a second container can be defined to be used by the LiveUser class.

You can also define a permission container of your choice that will manage the rights for each user. Depending on the container, you can implement any kind of permission schemes for your application while having one consistent API.
Using different permission and auth containers, it’s easily possible to integrate newly written applications with older ones that have their own ways of storing permissions and user data. Just make a new container type and you’re ready to go!

PEAR::LiveUser Wiki
Getting Started with LiveUser Permissions
Authentication
PHP Authentication and Access Control Libraries

Translation2

This class provides an easy way to retrieve all the strings for a multilingual site from a data source (i.e. db).
The following containers are provided, more will follow:

  • PEAR::DB
  • PEAR::MDB
  • PEAR::MDB2
  • gettext
  • XML
  • PEAR::DB_DataObject (experimental)

It is designed to reduce the number of queries to the db, caching the results when possible.
An Admin class is provided to easily manage translations (add/remove a language, add/remove a string).
Currently, the following decorators are provided:

  • CacheLiteFunction (for file-based caching)
  • CacheMemory (for memory-based caching)
  • DefaultText (to replace empty strings with their keys)
  • ErrorText (to replace empty strings with a custom error text)
  • Iconv (to switch from/to different encodings)
  • Lang (resort to fallback languages for empty strings)
  • SpecialChars (replace html entities with their hex codes)
  • UTF-8 (to convert UTF-8 strings to ISO-8859-1)

PEAR::Translation2 tutorials

Validate

Package to validate various data. It includes :

  • numbers (min/max, decimal or not)
  • email (syntax, domain check, rfc822)
  • string (predefined type alpha upper and/or lowercase, numeric,…)
  • date (min, max, rfc822 compliant)
  • uri (RFC2396)
  • possibility valid multiple data with a single method call (::multiple)

An introduction to PEAR’s Validate package

Spreadsheet_Excel_Writer

Spreadsheet_Excel_Writer was born as a porting of the Spreadsheet::WriteExcel Perl module to PHP.
It allows writing of Excel spreadsheets without the need for COM objects.
It supports formulas, images (BMP) and all kinds of formatting for text and cells.
It currently supports the BIFF5 format (Excel 5.0), so functionality appeared in the latest Excel versions is not yet available.
Generating Spreadsheets with PHP and PEAR
What is Spreadsheet_Excel_Writer?

Net_GeoIP

A library that uses Maxmind’s GeoIP databases to accurately determine geographic location of an IP address.
Tutorial from HTML Blog

File_Archive

This library makes it very easy to use, writing simple code, yet the library is very powerful.
It lets you easily read or generate tar, gz, tgz, bz2, tbz, zip, ar (or deb) archives to files, memory, mail or standard output.
File_Archive tutorial
SitePoint » File_Archive

XML_Serializer

XML_Serializer serializes complex data structures like arrays or object as XML documents.
This class helps you generating any XML document you require without the need for DOM.
Furthermore this package can be used as a replacement to serialize() and unserialize() as it comes with a matching

XML_Unserializer that is able to create PHP data structures (like arrays and objects) from XML documents, if type hints are available.
If you use the XML_Unserializer on standard XML files, it will try to guess how it has to be unserialized. In most cases it does exactly what you expect it to do.

Dev Shed XML_Serializer
Instant XML with PHP and PEAR::XML_Serializer

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.
»Read More

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.
»Read More

9 tips to validate your XHTML code

What is validation ?

According to the W3c, Validation is a process of checking your documents against a formal Standard, such as those published by the World Wide Web Consortium (W3C) for HTML and XML-derived Web document types, or by the WapForum for WML, etc. It serves a similar purpose to spell checking and proofreading for grammar and syntax, but is much more precise and reliable than any of those processes because it is dealing with precisely-specified machine languages, not with nebulously-defined human natural language.


Why taking the trouble to validate your XHTML ?

  • Properly written XHTML code will render better, render on more browsers, and render faster than XHTML with errors. It’s also more easily adapted to print and alternative browsing devices like mobile phones and handheld computers.
  • Properly written XHTML code is more likely to be “future-proof” (backward compatible with future standards and future web browsers).
  • Browsers are becoming more standards compliant, and it is becoming increasingly necessary and important to write valid and standards compliant XHTML code
  • Poorly written XHTML can greatly reduce the amount of traffic your web site receives from search engines.
  • Write XHTML code right the first time and write it once.
  • You don’t want to look foolish among your friends while not knowing the rules, uh?

»Read More