Sunday, January 08, 2006

PERL update

After almost 4 months of PERL this is what I have to say.

  • Its extremely handy for short and snappy stuff

  • Everything under the sun is available in CPAN but figuring out which is best suited for your needs is a bitch

  • While developing webapps with CGI not knowing use Carp::qw(fatalsToBrowser); is the last thing you want to do (coz I did that)

  • Why ? Oh why do warnings and use strict; exist if you can write stuff faster without it :((

addEvent()

A lots been said and done here. Here's my take if attachEvent does not give you access to the "this" pointer don't use it, instead use the age old method supported by most browsers :)
<html>
  <head>
    <title>Javascript Test Page</title>
<script type="text/javascript">
/*****************************************************************************
 *                          Helper Functions
 *****************************************************************************/
var onlyUnique = true; // default
function registerListener(target, event, listener) {
 if ( target[event + "Count"] ) {
  target[event + "Count"] = parseInt(target[event + "Count"]) + 1;
 } else {
  // first handler so add default event handler
  target[event + "Count"] = 1;
  target.defaultHandler = defaultHandler;
  target["on" + event] = function(evt) {
   evt = window.event ? window.event : evt;
   target.defaultHandler(event, evt);
  };
 }
 var currCount = parseInt(target[event + "Count"]) - 1;
 if ( onlyUnique ) {
  for ( var i = 0; i < currCount; i++ ) {
   if ( target[event + i] == listener ) {
    target[event + "Count"] = currCount;
    return false;
   }
  } // endfor i
 } // endif onlyUnique
 target[event + currCount] = listener;
 return true;
}
function unRegisterListener(target, event, listener) {
 if ( target[event + "Count"] ) {
  var currCount = parseInt(target[event + "Count"]);
  for ( var i = 0; i < currCount; i++ ) {
   if ( target[event + i] == listener ) {
    target[event + i] = null;
    currCount--; // removed one
    break;
   }
  } // endfor i
  for ( var j = i; j < currCount; j++ ) {
   target[event + j] = target[event + (j + 1)];
  } //  endfor j
  if ( currCount < 1 ) {
   // cleanup default event handler
   target["on" + event] = null;
  }
  target[event + "Count"] = currCount;
 }
}
function defaultHandler(eventName, evt) {
 if ( this[eventName + "Count"] ) {
  var currCount = parseInt(this[eventName + "Count"]);
  for ( var i = 0; i < currCount; i++ ) {
   this[eventName + i](evt);
  } // endfor i
 }
}
/*****************************************************************************
 *                  Event Handler Functions
 *****************************************************************************/
function addEvent(target, event, func) {
 if ( target.addEventListener ) {
  target.addEventListener(event, func, false);
 } else {
  registerListener(target, event, func)
 }
}
function removeEvent(target, event, func) {
 if ( target.removeEventListener ) {
  target.removeEventListener(event, func, false);
 } else {
  unRegisterListener(target, event, func)
 }
}
/*****************************************************************************/
function gel(idName) {
 return document.getElementById ? document.getElementById(idName) : false;
}
addEvent(window, "load", one);
addEvent(window, "load", two);
addEvent(window, "load", initialize);
var oneCount = 0;
function one() {
 var text = "[one][" + oneCount + "]" + this.id;
 oneCount++;
 var div = document.createElement("div");
 div.appendChild(document.createTextNode(text));
 gel("oneDiv").appendChild(div);
}
var twoCount = 0;
function two(evt) {
 var text = "[two][" + twoCount + "]" + evt.type;
 twoCount++;
 var div = document.createElement("div");
 div.appendChild(document.createTextNode(text));
 gel("twoDiv").appendChild(div);
}
function initialize() {
 alert("[initialize]");
 alert("adding one");
 add1();
 alert("adding two");
 add2();
 alert("done");
 addEvent(gel("remove1"), "click", remove1);
 addEvent(gel("remove2"), "click", remove2);
 addEvent(gel("add1"), "click", add1);
 addEvent(gel("add2"), "click", add2);
}
function remove1() {
 for ( var i = 0; i < 10; i++ ) {
  remove(one);
 }
 alert(gel("anchor").clickCount + " handler(s) left");
}
function remove2() {
 for ( var i = 0; i < 10; i++ ) {
  remove(two);
 }
 alert(gel("anchor").clickCount + " handler(s) left");
}
function remove(which) {
 removeEvent(gel("anchor"), "click", which);
}
function add1() {
 for ( var i = 0; i < 10; i++ ) {
  add(one);
 }
 alert(gel("anchor").clickCount + " handler(s) present");
}
function add2() {
 for ( var i = 0; i < 10; i++ ) {
  add(two);
 }
 alert(gel("anchor").clickCount + " handler(s) present");
}
function add(which) {
 addEvent(gel("anchor"), "click", which);
}
</script>
  </head>
  <body>
    <a id="anchor" href="#">[Test]</a>
    <a id="remove1" href="#">[Remove 1]</a>
    <a id="remove2" href="#">[Remove 2]</a>
    <a id="add1" href="#">[Add 1]</a>
    <a id="add2" href="#">[Add 2]</a>
    <div id="test"></div>
    <table>
      <tr>
        <td valign="top">
          <div id="oneDiv"></div>
        </td>
        <td valign="top">
          <div id="twoDiv"></div>
        </td>
      </tr>
    </table>
  </body>
</html>