JSFiddle - React, Tailwind, and code Playground

by waxwing

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>
<div class="wrapper">
<textarea data-bind="highlighter: value"></textarea>
</div>

CSS

.highlighter {
    position: absolute;
    font-family: Arial;
    font-size: 13px;
    padding: 3px;
    top: 0;
    left: 0;
    color: transparent;
    height: 100px;
    width: 300px;
    word-break: break-word;
}

.highlighter .word {
    background-color: #ccf;
    border: 1px solid #aac;
}

.wrapper {
    position: relative;
}

textarea {
    position: absolute;
    font-family: Arial;
    font-size: 13px;
    top: 0;
    left: 0;
    background: transparent;
    width: 300px;
    height: 100px;
}

JavaScript

var dictionary = {
    'VALUE(P100001)': 'Movie',
    'VALUE(P100002)': 'Actor'
};

function findEdit(a,b) {
    var i = 0, type;
    if (a.length < b.length) {
        return findEdit(b,a);
    }
    while (i < a.length && a[i] === b[i]) {
        i++;
    }
    return i;
}

ko.bindingHandlers.highlighter = {
    init: function (element, valueAccessor) {
        var realValue = valueAccessor(),
            displayValue,
            highlightHtml;

        var z = '\ufeff';
        z = 'X';

        function toDisplay(val) {
            for (var key in dictionary) {
                val = val.replace(key, dictionary[key]);
            }
            return val;
        }

        function toHtml(val) {
            for (var key in dictionary) {
                val = val.replace(key, '<span class="word">' + 
                                  dictionary[key] + '</span>');
            }
            return val.replace(/\n/g, '<br>');
        }

        displayValue = ko.computed({
            read: function () {
                return toDisplay(realValue() || '');
            },
            write: function (newValue) {
                var old = realValue() || '',
                    i = 0, j = 0, newTail, oldTail, newNext, oldNext,
                    result = '';

                while (i < old.length) {
                    if (newValue[j] === z && old[i] === z) {
                        oldTail = old.substring(i);
                        oldNext = oldTail.indexOf(z);
                        newTail = newValue.substring(j);
                        newNext = newTail.indexOf(z);
                        
                        if (newNext > 0 && oldNext > 0) {
                            result += tail.substring(0, newNext);
                            j += newNext;
                            i += oldNext;
                        }
                        else if (newNext > 0) {
                            
                        }
                        else {
      ...