function countLines(str, cols)
{
  var lines = 1;
  var lastPos = 0;
  while (lastPos >= 0)
  {
    newPos = str.indexOf("\n", lastPos+1);
    // if we found a newline
    if (newPos > 0)
    {
      // increase lines because of this newline
      lines++;
      // increase lines for any wrapping before it
      while (newPos > lastPos+cols+1)
      {
        lines++;
        lastPos += cols;
      }
    }
    // else there are no more newlines
    else if (newPos < 0)
    {
      lines += Math.ceil((str.length + 1 - lastPos) / cols);
    }
    lastPos = newPos;
  }
  return lines;
}

function resizeTextAreas()
{
  for (var form in document.forms)
  {
    for (var field in document.forms[form])
    {
      if (!document.forms[form][field]) continue;
      if(typeof document.forms[form][field].rows != "number") continue;
      var newRows = Math.max(5, Math.ceil(1.2*countLines(document.forms[form][field].value, document.forms[form][field].cols)));
      document.forms[form][field].rows = newRows;
    }
  }
}

addLoadEvent(function() {
  for (var form in document.forms)
  {
    for (var field in document.forms[form])
    {
      if (document.forms[form][field] && typeof document.forms[form][field].rows == "number")
      {
        document.forms[form][field].onkeyup = resizeTextAreas;
      }
    }
  }
  resizeTextAreas();
});

// -----------------------------------------------------------
// addLoadEvent from Simon Willison
// http://simonwillison.net/2004/May/26/addLoadEvent/
// I had the idea independently but didn't write this version.
// -----------------------------------------------------------

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}