JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://github.com/SteveSanderson/knockout.mapping/raw/master/build/output/knockout.mapping-latest.js"></script>
<script src="https://raw.github.com/jquery/globalize/master/lib/globalize.js"></script>
<script src="http://code.jquery.com/jquery-git.js"></script>
<ul data-bind="foreach: comments" class="comments">
    <li>
        <span data-bind="text: text, click: beginEdit, visible: read, css: { comment: true, placeHolding: isPlaceHolding}"></span>
        <textarea data-bind="event: { blur: endEdit }, visible: edit, value: text, hasfocus: edit(), autogrow: true"></textarea>
        -
        <span data-bind="text: username" class="username"></span>
        <span data-bind="text: dateFormated" class="date" ></span>
        <span data-bind="visible: isUpdated, attr: { title: updatedFormated }" class="edited" ></span>
    </li> 
</ul>

CSS

ul.comments li span.placeHolding {
    font-style:italic;
}

ul.comments li span.comment {
    white-space: pre; 
}

ul.comments {
    list-style-type: none;
    padding-left: 0px;
}

ul.comments li span.username {
    color: #0077CC
}

ul.comments li span.date {
    color: #999999;
}

ul.comments li:hover {
    background: #fafafa;
}

ul.comments li textarea {
    border: none;
    resize: none;
    overflow: hidden;
}

JavaScript

//Mock namespace
MyApp = {};
//Mock global settings
MyApp.settings = { username: "UserOne" };
//Mock utils
MyApp.utils = {
    repeatEvery: function(func, interval) {
        // Check current time and calculate the delay until next interval
        var now = new Date,
            delay = interval - now % interval;
    
        function start() {
            // Execute function now...
            func();
            // ... and every interval
            setInterval(func, interval);
        }
    
        // Delay execution until it's an even interval
        setTimeout(start, delay);
    }
};
//Other mocks
String.empty = "";

//Mock bindinghandlers
ko.bindingHandlers.autogrow = {
    init: function(self, valueAccessor, allBindingsAccessor) {            
            var $self        = $(self);            
            var noFlickerPad = $self.hasClass('autogrow-short') ? 0 : parseInt($self.css('lineHeight')) || 0;           
            
            var shadow = $('<div></div>').css({               
                position:    'absolute',
                top:         -10000,
                left:        -10000,
                width:       $self.width(),
                fontSize:    $self.css('fontSize'),
                fontFamily:  $self.css('fontFamily'),
                fontWeight:  $self.css('fontWeight'),
                lineHeight:  $self.css('lineHeight'),
                resize:      'none',
    			'word-wrap': 'break-word'
            }).appendTo(document.body);
            shadow.html("A");
            var removeHeight = shadow.height();
            shadow.html("");
            var minHeight = removeHeight;
            
            var times = function(string, number)
                {
                    for (var i=0, r=''; i<number; i++) r += string;
                    return r;
                };
            
            var update = function(event)
            {


                var val = self.value.replace(/</g, '&lt;')
                           ...