JAXL BOSH Demo: IM chat client for all WordPress blogs

Have you ever wished of a wordpress plugin capable of providing a facebook style chat bar on your blog post. In this blog post, I will lay down the details of how Jaxl‘s bosh support comes in handy for building such browser based real time application. Specifically, I will explain how I achieved building a plugin for my wordpress blog. If everything goes perfect over next few weeks, this plugin might be submitted in wordpress plugin’s directory.

Jaxl BOSH Support Framework
Jaxl BOSH support comprise of three main parts:

  • jaxl.jquery.js: JQuery extension written for Jaxl bosh support
  • jaxl4bosh.class.php: Connection manager in PHP
  • jaxl UI: Integrated UI framework for changing your application skin on the fly. Your application skin can be a simple facebook style chat bar (as on this page) or chesspark style whole html page

jaxl.jquery.js is responsible for initiating and maintaining a connection between the browser and the PHP connection manager. While jaxl4bosh.class.php implements the BOSH protocol and maintain a persistent connection with the jabber server.

jaxl.jquery.js provide a few basic methods like:

  • jaxl.connect: Call for initiating the connection
  • jaxl.sendMessage: Call for sending a message to other jid’s
  • jaxl.ping: Call to maintain the connection and gather any incoming data
  • jaxl.disconnect: Call for disconnecting

jaxl4bosh.class.php provide wordpress style filter/hooks which can be used to modify every incoming and outgoing messages.

  • jaxl_pre_connect: Call to perform initialization before jaxl connects to jabber server
  • jaxl_post_connect: Call to perform shutdown after jaxl is connected to jabber server
  • jaxl_send_message: Call to perform actions on outgoing messages from jaxl
  • jaxl_recv_message: Call to perform actions on incoming messages to jaxl
  • jaxl_send_presence: Call to perform actions on outgoing presence from jaxl
  • jaxl_recv_presence: Call to perform actions on incoming presence from jaxl
  • jaxl_pre_disconnect: Call to perform initialization before jaxl disconnects to jabber server
  • jaxl_post_disconnect: Call to perform shutdown after jaxl is disconnected to jabber server

Jaxl and WordPress
Using Jaxl bosh support require you to only edit the configuration file. Here are the config variables:

        // JAXL config
        define('JAXL_BOSH_HOST', 'localhost');
        define('JAXL_BOSH_SERVER', 'localhost');
        define('JAXL_BOSH_URL', 'http://localhost:7070/http-bind/');
        define('JAXL_ADMIN_JID', [email protected]');

You can configure Jaxl to use any of the available public xmpp services. However, I choose to host my own jabber server for my blog.

JAXL_ADMIN_JID is the admin jid to which Jaxl should route all incoming messages, added specifically for wordpress related requirement. PHP connection manager can be extended to route different chat sessions to different admins.

jaxl_recv_message handler is used to embed smiley’s and youtube videos by parsing the incoming chat messages.
jaxl-bosh-support-hook-demo-youtube-smiley

A few other hooks like jaxl_post_connect are used to notify JAXL_ADMIN_JID about the newly connected user.

Admin Screen
Below is a screen shot of how an admin desktop will look like while chatting with his site visitors:
Admin-screenshot-jaxl-bosh-support

Let me know if you are having any issues chatting using the chat bar at the bottom of the page. Code and installation might be buggy at times, and would appreciate any help from you on it.

Web Security : Using crumbs to protect your PHP API (Ajax) call from Cross-site request forgery (CSRF/XSRF) and other vulnerabilities

Have your API calls ever being used directly by someone without your permission? If yes, read on to find out how can we protect our API’s from such spammers and hackers. Before we go ahead and see a possible solution for this, lets try to list out a few cases, when our API’s can be accessed without our permissions.

Common cases of vulnerable API/Ajax calls

  • Ajax calls having no user authentication: This is the first place where a spammer will try to find out a loop hole. Take this example, suppose I created a group chat plugin for my blog. Since it’s a group chat plugin, I don’t really want the blog viewers to register before they can write a messages. Blog viewer only need to provide their name, email and url (just like wordpress comments). Thereafter, they can write messages which are submitted on the server side using ajax calls. And here is the “problem”. Anyone can pick up the ajax url, write a curl script, post the required parameters and fill up my database with millions of messages.
  • Ajax calls having user authentication: One day I realize my group chat plugin has received more than 1 million messages last night (all spams). Hence I decide to make my blog viewers to register before they can post a message on the group chat plugin, simply because someone is filling up my database by simulating ajax calls through a curl script. Anyone can write a script, since these ajax call do not authenticate the user making the call. But are my ajax calls safe after forcing users to register? NO, a registered user too can simulate these ajax calls and passing authentication by sending the right cookies.

Possible solutions and their flaws
If you look around on web, you will find a bunch of solution to such problems. But then every solution have it’s own problem which forces you not to use them. Listed below are 2 possible solutions to our problem:

  • Using X-Requested-With to protect ajax calls: All famous javascript frameworks like JQuery, YUI, Mootools etc sends an additional header parameter while making an XHR request. These libraries set “X-Requested-With=XMLHttpRequest” header, which can then be used on the server side to detect if the call was made through an ajax call. But a programmer can easily pass these headers using a curl script, making the server believe that the call was made through an XHR request.
  • Using HTTP Referrer: This solution comes in handy for cases when a spammer/hacker try to POST data into your site’s. We can check for the referrer page, before we go ahead and accept the POST data. If the POST data is coming from a page within your site, you go ahead and accept the data, otherwise reject it. But this solution again have it’s shortcomings. HTTP Referrer can be tampered in certain browsers using javascript and they can also be stripped away by some proxies and firewalls.

Using crumbs
Finally the idea is to have crumbs. A unique electronic key which is shared between server and client, and which have a short life time. But how are these useful? Suppose, in my group chat module, upon page load i generate a crumb whose life time is 30 minutes (tunable). Why 30 minutes? Because, I assume my blog viewers to either engage into the group chat module or leave that specific blog post within 30 minutes.

Now whenever a user writes a message, this crumb is passed back to the server side. If user writes a message before 30 minutes, this crumb will be validated and user shout submitted. (30 minutes should take care of 99.99% of the cases). In response, server api sends back the new crumb which should be sent back with the next ajax call.

Now when a spammer try to simulate the ajax request using curl calls, he will not be able to succeed because of the absence of the crumb. But he can capture the crumb from the site and simulate the effect, right? YES he can, but we can take care of this by reducing the life time of the generated crumb.

Generating crumbs using PHP
Here are the two functions, I use to generate and verify crumbs in PHP:

        // user for whom crumb is to be generated
        $uid = "[email protected]";

        // usually $salt = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH;
        $salt = "abcdefghijklmnopqrstuvwxyz";

        function challenge($data) {
                global $salt;
                return hash_hmac('md5', $data, $salt);
        }

        function issue_crumb($ttl, $action = -1) {
                global $uid;

                // ttl
                $i = ceil(time() / $ttl);

                // log
                echo "Generating crumb at time:".time().", i:".$i.", action:".$action.", uid:".$uid.PHP_EOL;

                // return crumb
                return substr(challenge($i . $action . $uid), -12, 10);
        }

        function verify_crumb($ttl, $crumb, $action = -1) {
                global $uid;

                // ttl
                $i = ceil(time() / $ttl);

                // log
                echo "Verifying crumb:".$crumb." at time:".time().", i:".$i.", action:".$action.", uid:".$uid.PHP_EOL;

                // verify crumb
                if(substr(challenge($i . $action . $uid), -12, 10) == $crumb || substr(challenge(($i - 1) . $action . $uid), -12, 10) == $crumb)
                        return true;
                return false;
        }

I can generate crumbs with a simple call:

$crumb = issue_crumb(300, "group_chat_module");

where $ttl = 300 (required), $action = “group_chat_module” (optional, defaults to -1)

Later on I can verify the crumb using another call:

var_dump(verify_crumb(300, $crumb, "group_chat_module"));

I hope this helps you protecting your API’s. Let me know of better methods to stop such attacks.
Enjoy!

Introducing jSlider: A Content Slider plugin for JQuery

jSlider is a light weight JQuery plugin for content sliding. By content we mean everything: HTML code, Images, Advertisements etc etc. jSlider allows to put our content in simple <div>‘s, and then it automatically generates a content slider for you, which one can customize using various options provided.

Screenshot
Below is a screen shot of a content slider using jSlider:

jSlider

Download and Demo
jSlider is hosted at google code. Use the following links for demo and downloads:

Using jslider.jquery.js
Below is a sample html code which will be processed by jslider:

Sample input to jslider

    <div id="jslider">
      <div>
        <input type="hidden" value="Title for Content 1"/>
        <div>
          HTML Content # 1
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 2"/>
        <div>
          HTML Content # 2
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 3"/>
        <div>
          HTML Content # 3
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 4"/>
        <div>
          HTML Content # 4
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 5"/>
        <div>
          HTML Content # 5
        </div>
      </div>
    </div>

One must preserve the div structure as given in the example above. The hidden input values will be taken as heading for that block of content. If you want to have no heading or a common heading, fill this hidden input field appropriately.

Sample output from jslider

  <div id="jslider">
    <div class="slider">
      <h2>Title for Content 1</h2>
      <ul>
        <li class="selected">1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
      </ul>
    </div>
    <div class="content">
      <div class="block">
        <input type="hidden" value="Title for Content 1"/>
        HTML Content # 1
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 2"/>
        HTML Content # 2
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 3"/>
        HTML Content # 3
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 4"/>
        HTML Content # 4
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 5"/>
        HTML Content # 5
      </div>
    </div>
  </div>

Customizing jslider.jquery.js
jSlider provides following options for customization:

  1. width: Width of jslider div above, defaults to ‘610px’
  2. height: Height of jslider div above, defaults to ‘225px’
  3. slider_height: Height of slider div above (navigation bar), defaults to ’24px’
  4. content_height: Height of content div above, defaults to ‘180px’
  5. block_width: Width of block div inside content div’s above, defaults to ‘590px’
  6. block_padding: Padding of block div inside content div’s above, defaults to ’10px’
  7. animation_time: Time taken by 1 slide of content, defaults to 300 msec
  8. animation_type: Animation type, defaults to ‘linear’. Other option is ‘swing’

Rest of the options like various padding etc can be controlled using the css properties. View demo for more implementation details. This is my first jquery plugin and I am only 2 weeks old in jquery. If you find any bug or need any enhancement, you are most welcome.

How to add wordpress like add_filter hooks in your PHP framework

I simply love wordpress mainly because of the architectural design it follows to deliver the good. WordPress provide a hook or filter functionality to almost everything that appears on your blog. If you are a wordpress plugin developer you surely must have used one of them, specially add_filter() hook.

add_filter functionality provides plugin developer a way to apply custom hooks on various page sections. For instance add_filter('the_content', 'HelloWorld') will force the content to be passed through the function HelloWorld($content) before being displayed to your blog users.

In this blog post I will show you how can you achieve doing the same thing for your custom PHP frameworks. Otherwise you can also use this in your day to day projects. We will start with a simple directory structure, assuming this is all we have in our framework to start with:

Files/Folder structure of our framework
— addHooks
    — index.php
    — applyHooks.php
    — hooks
          — Subscribe.php
          — Signature.php

addHooks: Our framework root directory.
index.php: Homepage for our framework.
applyHooks.php: Responsible for including and implementing various hooks.
hooks: Our hooks directory. We will put all our hooks here.
Subscribe.php: A simple hook which will add a subscribe my feed link.
Signature.php: Another simple hook which adds my signature.

Source code
Download the complete source code from here.

index.php

  // define some content
  // in this demo i will show to how to apply hook to $content, similar to wordpress blog $content
  $content = "In this blog post I will show you how to add wordpress like add_filter hooks in your PHP framework.";

  // Include our hook management file
  require_once("applyHooks.php");
  

Subscribe.php

  function Subscribe($content) {
    $subscribe = '';
    $subscribe .= 'Subscribe to my RSS feed';
    $subscribe .= '

'; return $subscribe.$content; } add_filter('the_content', 'Subscribe');

Signature.php

  function Signature($content) {
    $signature = '

'; $signature .= 'Abhinav Singh
'; $signature .= 'Follow on twitter @imoracle
'; return $content.$signature; } add_filter('the_content', 'Signature');

applyHooks.php

  /* plugin directory */
  $hook_dir = "hooks/";

  /* get all plugin files */
  $hook_files = glob($hook_dir."*.php");

  /* array saving all our hooks on the_content */
  $hooks['the_content'] = array();

  /* add_filter functionality */
  function add_filter($on, $func) {
    global $hooks;
    array_push($hooks[$on], $func);
  }

  /* include plugin files */
  foreach($hook_files as $hook_file) {
    require_once($hook_file);
  }

  /* implement the hooks */
  foreach($hooks['the_content'] as $hook) {
    $content = call_user_func($hook, $content);
  }

  echo $content;
  

Final Result
When you try to visit your framework opening page on your browser, i.e. index.php. You will see your $content being filtered/modified and displayed as:
add_filter_output

How does applyHooks.php works
So what allows us adding such hooks in our framework. call_user_func is a PHP function which allows you to call a user defined function. Here is in short how applyHooks.php work:

  1. applyHooks.php adds a method called add_filter($on, $func) before including the hook files
  2. add_filter() essentially takes input as $on = the element on which you want to apply the hook and $func = the hook you want to apply $on element.
  3. If you see our Signature.php code, you will find add_filter('the_content', 'Signature');. Which essentially means, apply the filter called $func=’Signature’, $on=’the_content’
  4. The applyHooks.php file keep registering these hooks and save them in $hooks array
  5. Finally it implement all hook one by one by calling the call_user_func function (PS: You may also want to use call_user_func_array)

Extending applyHooks.php
In this blog post I have shown a demo, how you can create a add_filter type functionality. You may want to extend this to include hooks like:

  • remove_filter
  • add_shortcode

and others.

Hope this will help you making your web apps more expendable and manageable. 😀

XML Parsing in PHP, XPATH way – The best I know so far

If you are a PHP developer, you surely must have done XML parsing at some stage or the other. Over the years I myself have implemented XML Parsing in atleast 3-4 different ways. Finally I have stuck to this approach which I personally find far more better than the rest, Not only because it’s quite simple but also because it’s extendable. By extendable I mean, you don’t have to touch your code if the XML structure changes at a later stage or if you need to parse a new node at a later stage in the project. In this blog post we will try to parse my twitter timeline, using the XPATH way. To start with let’s see how a my twitter timeline look like:

XML Source:
http://twitter.com/statuses/user_timeline/imoracle.xml
You may want to open this XML structure in a separate window of your browser for reference, as we walk through various XML parsing techniques.

Data Requirement:
Before we proceed to parse this twitter timeline, lets decide what all data do we want to extract out of the XML. Each <status></status> node consists of two parts. Information about the tweet and information about the user.

Lets finalize the following list of nodes which we want about the tweets and also their corresponding XPATH’s:

  1. id: ../statuses/status/id
  2. text: ../statuses/status/text
  3. source: ../statuses/status/source

Further lets zero out on list of nodes we want about the user details:

  1. id: ../statuses/status/user/id
  2. name: ../statuses/status/user/name
  3. screen_name: ../statuses/status/user/screen_name

XML Parsing:
Let us create a file called xpath.php, which will contain xpath of various nodes which we have finalized above. The xpath.php file will look like:

xpath.php

<?php

  $user_status = array(
                      'status_id' => '../statuses/status/id',
                      'status_text' => '../statuses/status/text',
                      'status_source' => '../statuses/status/source',
                      'user_id' => '../statuses/status/user/id',
                      'user_name' => '../statuses/status/user/name',
                      'user_screen_name' => '../statuses/status/user/screen_name'
                      );

?>

parser.php

<?php

  // include the xpath file
  require_once("xpath.php");

  // read the xml source as string
  $str = file_get_contents("imoracle.xml");

  // load the string as xml object
  $xml = simplexml_load_string($str);

  // initialize the return array
  $result = array();

  // parse the xml nodes
  foreach($user_status as $key => $xpath) {
    $values = $xml->xpath("{$xpath}");
    foreach($values as $value) {
      $result[$key][] = (string)$value;
    }
  }

  // print the return array
  print_r($result);

?>

Results:
If we try to print out this $result on a browser screen, here is how the result will look like:

Array
(
    [status_id] => Array
        (
            [0] => 2499838341
            [1] => 2499780899
            [2] => 2499724163
            [3] => 2499607183
        )

    [status_text] => Array
        (
            [0] => 13 Beautiful WordPress Showcase Sites
            [1] => 55 Really Creative And Unique Blog Design Showcase
            [2] => Need PHP symfony developer to complete tvguide.com clone
            [3] => 22 Open Source PHP Frameworks To Shorten Your Development Time
        )

    [status_source] => Array
        (
            [0] => <a href="http://apiwiki.twitter.com/">API</a>
            [1] => <a href="http://apiwiki.twitter.com/">API</a>
            [2] => <a href="http://apiwiki.twitter.com/">API</a>
            [3] => <a href="http://apiwiki.twitter.com/">API</a>
        )

    [user_id] => Array
        (
            [0] => 14574588
            [1] => 14574588
            [2] => 14574588
            [3] => 14574588
        )

    [user_name] => Array
        (
            [0] => Abhinav Singh
            [1] => Abhinav Singh
            [2] => Abhinav Singh
            [3] => Abhinav Singh
        )

    [user_screen_name] => Array
        (
            [0] => imoracle
            [1] => imoracle
            [2] => imoracle
            [3] => imoracle
        )

)

The Best Part:
The best part of this approach is that, suppose in future our project demands extraction of the following nodes too:

  1. truncated: ../statuses/status/truncated
  2. favorited: ../statuses/status/truncated ../statuses/status/favorited
  3. location: ../statuses/status/user/location
  4. description: ../statuses/status/user/description

All we need to do is, simply add these xpaths in xpath.php file, without having to change the parser.php file. In case of a project you may want to create a function or a class out of the parser.php file so that you can request data from that.

Download the source code from here:
http://abhinavsingh.googlecode.com/files/xml-parser-xpath-way.rar

If you liked the post, do not forget to leave a comment and follow me on twitter.
Do let me know of better methods if you know any. Happy XML Parsing!

Facebook type image rotation and more using PHP and Javascript

If you are a facebook geek like me, you must have noticed till now the image rotate functionality in the photo albums. Facebook allows you to rotate images 90 degree clockwise and anti-clockwise after image upload. If you haven’t tried that till now, below is a screenshot for your convenience.

facebook-image-rotate

Question:
But the question is how does facebook team succeed doing this in one click. Today I tried looking around for a solution over internet and I came across the inbuilt imagerotate functionality in PHP.

Problem:
Unfortunately the problem is that even if you have GD Library extension enabled in PHP, imagerotate function just doesn’t work. After some research I found that to enable imagerotate function inside PHP, you need to compile and build PHP manually and enable imagerotate while installing PHP. You can check your PHP installation support for imagerotate using the following command line:

php -r "var_dump(function_exists('imagerotate'));"

Solution:
Since I didn’t want to touch my current installation of PHP, ImageMagick came to my rescue. Below I will show you how did I achieve cloning facebook’s 90 degree rotation functionality and also added a custom degree rotation (functionality usually seen in collage tools).

Demo:
You can try a live demo of the application here:
http://abhinavsingh.com/webdemos/imagerotate/

facebook-image-rotate-using-php-javascript

Source Code:
Before you go ahead and try this demo, you will need to install imagemagick on your system. On debian and ubuntu this can be achieved by the following command:

apt-get install imagemagick

To make sure installation is alright, run the following command from the shell:

convert -version

You should see something like this:

Version: ImageMagick 6.2.4 02/10/07 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2005 ImageMagick Studio LLC

Convert is a command line utility provided by imagemagick. Read more about convert here.

The source code consists of the following files and folders:

  • index.php : Generates the Frontend UI part for the application
  • action.php : Responsible for handling requests and rotating image using imagemagick library
  • style.css : Used for styling the UI
  • script.js : Used for handling the horizontal slider
  • images : This folder contains all the required images for the application. The image which we will be rotating left and right is “me.jpg”

action.php

  // Image Path
  $image = "images/me.jpg";
  $original = "images/me-original.jpg";

  if($_POST['restore']) {
    exec("cp ".$original." ".$image);
  }
  else if($_GET['left'] == 1 || $_GET['right'] == 1 || $_POST['degree']) {
    // Rotation Degree
    if(isset($_GET['left'])) $degree = -90;
    if(isset($_GET['right'])) $degree = 90;
    if(isset($_POST['degree'])) $degree = $_POST['degree'];

    // rotate image
    if(is_numeric($degree)) exec("convert ".$image." -rotate ".$degree." ".$image);
  }

From the UI, a user can pass 4 kind of requests:

  • Rotate Image 90 degree clockwise by clicking the button on bottom right corner
  • Rotate Image 90 degree anti-clockwise by clicking the button on bottom right corner
  • Rotate Image x degree, by choosing the value of x using horizontal slider on bottom left
  • Restore the image back to the original self

action.php handles the incoming 4 cases, calculates $degree to rotate and passes as a parameters to the command line utility provided by imagemagick.

Download Code:
Download the complete source code from here:
http://abhinavsingh.googlecode.com/files/image-rotate-application.rar
Unzip into a folder, and make the images directory writable.
PS: Application not tested on IE browser

Don’t forget to share and leave a comment if you liked the post.
Cheers!

SEO Analyzer v 1.2 – Adding support for Bing along with Google and Yahoo

On May 28, 2009 Microsoft announced Bing which has now replaced Live search. And within 2 week of it’s release, Bing seems to have leapfrog Yahoo search in U.S.

With Bing coming up as a strong contender to Google and Yahoo search engines, I have added support for Bing in SEO Analyzer v 1.2. This will enable you to analyze a site’s ranking for a particular keyword on Bing search engine, along with Yahoo and Google search engines.

seoanalyzer-bing-support

SEO Analyzer Future Roadmap:

  • Saving reports on spreadsheets
  • Comparing two sites for a list of keywords
  • Keyword density extraction tool

Happy SEO Analysis!

SEO Analyzer – Version 1.1 – What’s New?

While SEO Analyzer v 1.0 focused primarily on getting page ranks and analyzing back links to your site url, SEO Analyzer v 1.1 adds another feather to the cap. It allows you to achieve following analysis:

Feature List:

  • Get google page rank for input site url
  • Get all backlinks to the input site url
  • Get the exact href tag (rel=”nofollow”, target=”_blank”, etc) used by the back linking sites
  • Get google page rank for the back linking sites
  • Get google and yahoo ranking for the input site for keyword(s)
  • And a lot more ….

Installation:

Demonstration:

Here in pictures is a small demonstration of what all can be achieved with SEO Analyzer 1.1:

1. Start SEO Analyzer v 1.1
seoanalyzerv11-1

2. Enter Site url you want to analyze and keywords (optional) for which you want to analyze
seoanalyzerv11-2

3. Hit Enter or Analyze to start analysis – All backlinks
seoanalyzerv11-3

4. Get input site’s ranking for analyzed keywords
seoanalyzerv11-4

To-Do’s:

  • Export the keyword analysis results as CSV file
  • Compare keyword analysis results for two sites
  • Find appropriate keywords for a particular web page

Enjoy SEO Analysis,
Awaiting Your Feedbacks 😀

Introducing SEO Analyzer

SEO Analyzer is a desktop based application build specifically for page rank checking and link analysis for seo purpose. It is built using Adobe AIR.

Note: SEO Analyzer v 1.1 is out. Read more about it here

Installation:

Features:
The tool currently provides the following features:

  • Retrieve Page Rank for a particular web url
  • Get all incoming links for the entered url
  • Get page rank for the sites linking back to the entered url

seoanalyzer

Suggestions for future enhancements are welcomed.

Using Image Maps in Javascript – A Demo Application

Past month I was busy with project back in office, JAXL web chat client and photolog – a custom made wp-plugin for converting it into a photo blog. As I am close to finish them all, I am back to blogging after more than a month.

Here I would like to demonstrate a cool technique which I explored while working for the india elections site. We decided to have a cool india map where we could show data for each state. Though flash is always the best method to go with for such applications (and finally we did it with flash :D) I wanted to explore if we can do the same thing efficiently with javascript.

Not being a javascript expert, I first moved to various friends expert in javascript and they told me about image map technique in javascript. I did some research, read various blog posts and finally came up with the application below. (I will be demonstrating the application and challenges you will face while building such application, for basics of image map kindly search for it, you will get many tutorials on web on javascript image maps)

Challenges I faced:
Javascript image map technique utilizes the (x,y) co-ordinates which you provide to javascript. Depending upon the input (x,y) co-ordinates, javascript will build an image map over the image. When I was building this application, the biggest challenge was how to get the pixel by pixel border for each and every state. I don’t know dreamweaver, photoshop or any other software which can tell me this. Moreover, even if I knew, I was not sure how much effort will it require to note down each and every pixel lying on the state borders. Finally to counter this problem I came up with a javascript, which makes this task 99% easier.

Using javascript to detect image borders pixel by pixel:
Javascript image map requires pixel to be given in the following format (x1,y1,x2,y2,….,xn,yn). So I wrote a javascript which will automatically generate the current pixels of your mouse, in above format as you move it.

Lets try this out. Click here to open this javascript hack. Click CNTR++ (i.e. zoom into your browser) as many times as you can. You will now have a very enlarged and a bit blurred india map in front of you. But good thing is you can clearly move your mouse over state borders. This javascript gets enabled on your 1st mouse click on the map. So choose a state and click your mouse on its border. Now start moving your mouse on this state’s border till you come back to the same point, where you started. Click 2nd time on that point to disable this javascript function and WOW! Below you have the border pixel positions in the required format to be used straight with javascript image maps. Copy and paste that to get a final image map like this.

View the final image map file by clicking here.

edges.html


  
    
  
  
    

Study the source of the final application by visiting here and use the above javascript to extract edge information of your map file. I know there are some questions unanswered but I will wait for your comments to answer them 😀

PS: By demoing my application here, I permit you to use this sample code for any purpose. However I do not permit you to copy paste the indian map images for your personal or professional sites or works.