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 {
...