chrome border textarea scroll bug fix

by lid0

HTML

<pre style="background:#cfcfcf;padding:10px;">
    Fix Chrome top-border bug and caret scrolling, in editablecontent elements (textarea,div,etc)
    
    For this fix to work, the element must have CSS line-height propery set, 
    assume px units for all calculations
</pre>

<textarea id="t" contenteditable="false">Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10
Line 11
Line 12
Line 13
Line 14
Line 15
Line 16
Line 17
Line 18
Line 19
Line 20
Line 21
Line 22
Line 23
Line 24
Line 25
Line 26
Line 27
Line 28
Line 29
Line 30
    </textarea>
<br>
<button id="a" />console.log state</button>
<br>
<button id="b" />scroll+18</button>
<button id="c" />scroll-18</button>
<br>

CSS

#t {
    height:200px;
    border-top:30px solid red;
    line-height:18px;
    width:300px;
}

JavaScript

/** 
Fix Chrome bug with text area
**/
function isVisible() {
    var t = $("#t"); //textarea element
    var line_height = t.css("line-height").replace(/[^-\d\.]/g, ''); //get line-height remove unit
    var cur_line = getline();
    var cur_scroll = t.scrollTop();
    //var view_port_height = t.css("height").replace(/[^-\d\.]/g, ''); //get line-height remove unit
    console.log(cur_line * line_height - line_height);
    if ((cur_line * line_height - line_height) < cur_scroll - 3) { //current line is hidden
        console.log("Line is hidden - on top ", cur_scroll % line_height);
        console.log("#,", cur_scroll / line_height);

        if ((off = cur_scroll % line_height) === 0) {
            off = line_height;
        }
        console.log("Curren ScrollTop:", t.scrollTop(), "OFF", off);
        t.scrollTop(t.scrollTop() - off - line_height);
    }
}

function getline() {
    var t = $("#t")[0];
    return (t.value.substr(0, t.selectionStart).split("\n").length);
}

//UI
$("#b").click(function () {
    var t = $("#t");
    t.scrollTop(t.scrollTop() + 24);
});
$("#c").click(function () {
    var t = $("#t");
    t.scrollTop(t.scrollTop() - 24);
});

$("#a").click(function () {
    var t = $("#t");
    var cline = getline();
    console.log("current Line:", cline);
    console.log("current ScrollTop:", t.scrollTop());
    //isVisible();


});



$("#t").keyup(function () {
    isVisible(); //check if line is visible and correct offset
});