Facebook-style TextArea Autogrow

Grows the textarea using a shadow div to control height.

HTML

<textarea placeholder="Leave a comment..."></textarea>

CSS

textarea {
    line-height: 1.4em;
    resize: none;
    width: 100%;
    height: 1.4em;
    padding: 4px;
}

JavaScript

(function($) {

/*
 * Auto-growing textareas; technique ripped from Facebook
 */
$.fn.autogrow = function(options) {

    this.filter('textarea').each(function() {

        var $this       = $(this),
            minHeight   = $this.height(),
            lineHeight  = $this.css('lineHeight');
        
        var getRealWidth = function($elem){
            return $elem.innerWidth() - parseInt($elem.css('paddingLeft')) - parseInt($elem.css('paddingRight'));
        };

        var shadow = $('<div></div>').css({
            position:   'absolute',
//            top:        -10000,
//            left:       -10000,
            width:      getRealWidth($this),
            fontSize:   $this.css('fontSize'),
            fontFamily: $this.css('fontFamily'),
            lineHeight: $this.css('lineHeight'),
            padding: $this.css('padding'),
            border: $this.css('border'),
            display: $this.css('display'),
            resize:  'none'
        }).appendTo(document.body);

        var update = function() {

            var times = function(string, number) {
                for (var i = 0, r = ''; i < number; i ++) r += string;
                return r;
            };
            
            if(this.value){
                var val = this.value.replace(/</g, '&lt;')
                                    .replace(/>/g, '&gt;')
                                    .replace(/&/g, '&amp;')
                                    .replace(/\n$/, '<br/>&nbsp;')
                                    .replace(/\n/g, '<br/>')
                                    .replace(/ {2,}/g, function(space) { return times('&nbsp;', space.length -1) + ' ' });
    
                shadow.html(val);
            }
            shadow.css('width', getRealWidth($this));
            $this.css('height', Math.max(shadow.innerHeight(), minHeight));

        }

        $(this).change(update).keyup(update).keydown(update);
        $(window).resize(update);

        update.apply(this);

   ...