JointJS - Resize element based on the text inside

Resize JointJS HTML Element based on the text inside an input

HTML

<script src="http://jointjs.com/js/joint.js"></script>
<link rel="stylesheet" href="http://jointjs.com/css/joint.css">
<!-- JointJS Fiddle -->
<div id="paper"></div>

CSS

#paper {
   position: relative;
   border: 1px solid gray;
   display: inline-block;
   background: transparent;
   overflow: hidden;
}
#paper svg {
   background: transparent;
}
#paper svg .link {
   z-index: 2;
}
.html-element {
   position: absolute;
   background: #3498DB;
   /* Make sure events are propagated to the JointJS element so, e.g. dragging works.*/
   pointer-events: none;
   -webkit-user-select: none;
   border-radius: 4px;
   border: 2px solid #2980B9;
   box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
   padding: 5px;
   box-sizing: border-box;
   z-index: 2;
}
.html-element select,
.html-element input,
.html-element button {
   /* Enable interacting with inputs only. */
   pointer-events: auto;   
}
.html-element button.delete {
   color: white;
   border: none;
   background-color: #C0392B;
   border-radius: 20px;
   width: 15px;
   height: 15px;
   line-height: 15px;
   text-align: middle;
   position: absolute;
   top: -15px;
   left: -15px;
   padding: 0;
   margin: 0;
   font-weight: bold;
   cursor: pointer;
}
.html-element button.delete:hover {
   width: 20px;
   height: 20px;
   line-height: 20px;
}
.html-element select {
   position: absolute;
   right: 2px;
   bottom: 28px;
}
.html-element input {
   position: absolute;
   bottom: 0;
   left: 0;
   right: 0;
   border: none;
   color: #333;
   padding: 5px;
   height: 16px;
}
.html-element label {
   color: #333;
   text-shadow: 1px 0 0 lightgray;
   font-weight: bold;
}
.html-element span {
   position: absolute;
   top: 2px;
   right: 9px;
   color: white;
   font-size: 10px;
}

JavaScript

var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({ el: $('#paper'), width: 650, height: 400, gridSize: 1, model: graph });

// Create a custom element.
// ------------------------

joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
    defaults: joint.util.deepSupplement({
        type: 'html.Element',
        attrs: {
            rect: { stroke: 'none', 'fill-opacity': 0 }
        }
    }, joint.shapes.basic.Rect.prototype.defaults)
});

// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------

joint.shapes.html.ElementView = joint.dia.ElementView.extend({

    template: [
        '<div class="html-element">',
        '<label></label>',
        '<input type="text" value="I\'m HTML input" />',
        '</div>'
    ].join(''),

    initialize: function() {

        _.bindAll(this, 'updateBox', 'onTextInput');

        joint.dia.ElementView.prototype.initialize.apply(this, arguments);

        this.$box = $(_.template(this.template)());
        this.$input = this.$box.find('input').on('input', this.onTextInput);

        this.model.on('change', this.updateBox, this);
        this.model.on('remove', this.removeBox, this);

        this.updateBox();
    },

    onTextInput: function(evt) {

        var $input = $(evt.target);
        $input.attr('size', Math.max($input.val().length, 10));

        this.model.resize($input.outerWidth() + 5, $input.outerHeight() + 40);
        this.model.set('input', $input.val());
    },

    render: function() {
        joint.dia.ElementView.prototype.render.apply(this, arguments);
        this.paper.$el.prepend(this.$box);
        this.$input.trigger('input');
        return this;
    },

    updateBox: function() {
        // Set the position and dimension of the box so that it covers the JointJS element.
        var bbox = this.model.getBBox();
        // Example of updating the HTML...