mass rename and rebranding from xwt to ibex - fixed to use ixt files
[org.ibex.core.git] / src / org / xwt / builtin / edit_lib.xwt
diff --git a/src/org/xwt/builtin/edit_lib.xwt b/src/org/xwt/builtin/edit_lib.xwt
deleted file mode 100644 (file)
index abcc8eb..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-<!-- Copyright 2002 NeuronForge Pty Ltd, see COPYING file for licensing [LGPL] -->
-<xwt>
-    <static>
-        var cursors = [];
-        var worddivider = [' ', '-'];
-
-        xwt.thread = function() {
-            while (true) { xwt.sleep(1000); for (var i=0; cursors.length > i; i++) { cursors[i].blink = !cursors[i].blink; } }
-        }
-
-        // Returns the number of characters the pixel position pos is into text t. end is the pixel with of t.
-        //  t     : string -- basis for character counting.
-        //  pxpos : int    -- pixel position on the text from string t.
-        //  pxlen : int    -- pixel width of text t (known in form of box length, so passed for speed).
-        //  tfont : string -- name of font used for width of text.
-        var getpos = function(t, pxpos, pxlen, tfont) {
-            // Short circuit extremes.
-            if (0 >= pxpos) return 0;
-            if (pxpos >= pxlen) return t.length;
-
-            // Inital guess based on average character width.
-            var guessch = xwt.math.min(t.length, xwt.math.floor(pxpos / (pxlen / t.length)));
-            var guesspx = xwt.textwidth(tfont, t.substring(0, guessch));
-
-            if (guesspx > pxpos) {
-                while (guesspx > pxpos) {
-                    // Textwidth of individual character must account for font kerning.
-                    guesspx -= xwt.textwidth(tfont, t.substring(guessch -1, guessch +1)) - xwt.textwidth(tfont, t.charAt(guessch));
-                    guessch--;
-                }
-            } else if (pxpos > guesspx) {
-                while (pxpos > guesspx) {
-                    guessch++;
-                    if (guessch >= t.length) break;
-                    guesspx += xwt.textwidth(tfont, t.substring(guessch -1, guessch+1)) - xwt.textwidth(tfont, t.charAt(guessch));
-                }
-                guessch--;  // Round down.
-            }
-
-            return guessch;
-        }
-    </static>
-
-
-    <template>
-        _multiline = function(v) {
-            if (!v) {
-                while (content.numchildren > 1) { reapLine(content[content.numchildren -1]); }
-                wrap = null;
-            }
-        }
-
-        _disabled = function(v) {
-            curs.disabled = v;
-        }
-
-        _editable = function(v) {
-        }
-
-        _wrap = function(v) {
-            // Used on _SizeChange if wrap needs to know.
-            var resize = function() {
-                xwt.thread = function() {
-                    // TODO: Only run this change if the width is different.
-                    for (var i = 0; content.numchildren > i; i++) { content[i].fulltext = content[i].fulltext; }
-                };
-            };
-
-            if (multiline and v == "line") {
-                content.vshrink = true;
-                content.hshrink = false;
-                content.maxwidth = xwt.maxdim; // Must reset maxwidth after shrink = true.
-                ref_fulltext = fulltext_linewrap;
-                _SizeChange = resize;
-
-            } else if (multiline and v == "word") {
-                content.vshrink = true;
-                content.hshrink = false;
-                content.maxwidth = xwt.maxdim;
-                ref_fulltext = fulltext_wordwrap;
-                _SizeChange = resize;
-
-            } else {
-                content.shrink = true;
-                ref_fulltext = fulltext_nowrap;
-                _SizeChange = null;
-            }
-
-            // Reset functions on current lines.
-            for (var i = 0; content.numchildren > i; i++) {
-                content[i]._fulltext = ref_fulltext;
-                content[i].fulltext  = content[i].fulltext;
-            }
-        }
-
-        _selectcolor = function(v) { sel1.color = sel2.color = v; }
-        _selecttextcolor = function(v) { sel1.textcolor = sel2.textcolor = v; }
-
-        _font = function(f) {
-            lineheight = xwt.textheight(f);
-            if (lineheight > 0) { minheight = content.minheight = linecount * lineheight; }
-            for (var i=0; content.numchildren > i; i++) { content[i].font = f; }
-            sel1.font = sel2.font = curs.font = f;
-        }
-
-        __text = function(t) {
-            if (arguments.length == 0) {
-                var s = content[0].fulltext;
-                for (var i=1; content.numchildren > i; i++) { s = s + '\n' + content[i].fulltext; }
-                return s;
-            }
-
-            deleteText(0, 0, content.numchildren - 1, content[content.numchildren - 1].fulltext.length);
-            insertText(0, 0, t);
-        }
-
-        __selection = function(t) {
-            if (arguments.length == 0) {
-                if (sel1.cl == -1) return "";
-
-                var s = sel1.text;
-
-                if (sel1.cl == sel2.cl) {
-                    for (var i=sel1.cy+1; sel2.cy > i; i++) { s += content[sel1.cl][i].text; }
-                } else {
-                    for (var i=sel1.cy+1; content[sel1.cl].numchildren > i; i++) { s += content[sel1.cl][i].text; }
-                    for (var i=sel1.cl+1; sel2.cl > i; i++) { s += '\n' + content[i].fulltext; }
-                    s += '\n';
-                    for (var i=0; sel2.cy > i; i++) { s += content[sel2.cl][i].text; }
-                    s += sel2.text;
-                }
-
-                return s;
-            }
-
-            deleteSelection();
-            insertText(curs.cl, curs.cx, t);
-        }
-
-
-        // PRIVATE VARIABLES //////////////////////////////////////////////////////////////////////////////////////////
-
-        // Stores the inital point of the current selection.
-        var sel = { cl : 0, cy : 0, px : 0 };
-
-        // The pixel height of the current font.
-        var _lineheight = function(l) { curs.height = sel1.height = sel2.height = l; }
-
-        // Number of soft lines currently in this edit widget. Controlled by newLine() and reapLine().
-        var _linecount = function(l) {
-            arguments.cascade(l);  if (l == 0) l = 1;
-            if (lineheight > 0) { minheight = content.minheight = l * lineheight; }
-        }
-
-        // Total number of characters stored in this text field.
-        var length = 0;
-
-
-        // PUBLIC FUNCTIONS  //////////////////////////////////////////////////////////////////////////////////////////
-
-        // Insert the given text at the given position.
-        insertText = function(cl, cx, t) {
-            // Check passed string.
-            if (t == null || 1 > t.length) return;
-            t = t.toString();
-
-            // Limit checking.
-            if (limit > 0 and length + t.length > limit) {
-                xwt.println("WARNING: Limit applied on inserted text.");
-                t = t.substring(0, limit - length);
-            }
-
-            // Make sure there are enough lines before hand.
-            for (var i=content.numchildren; cl >= i; i++) { content[i] = newLine(); }
-
-            // Parse the carridge returns out of t.
-            var newT = t.split("\n");
-
-            if (newT.length == 0) {
-                return;
-            } else if (newT.length == 1) {
-                content[cl].fulltext = content[cl].fulltext.substring(0, cx) + t + content[cl].fulltext.substring(cx);
-                length += t.length;
-
-                moveCursor(cl, cx+t.length);
-            } else {
-                if (multiline) {
-                    // Add extra lines required by passed text.
-                    for (var i = newT.length - 1; i > 0; i--) { content[cl+1] = newLine(); }
-
-                    // Add the new text
-                    var lastline = newT[newT.length - 1] + content[cl].fulltext.substring(cx);
-                    content[cl].fulltext = content[cl].fulltext.substring(0, cx) + newT[0];
-                    for (var i=1; newT.length-1 > i; i++) { content[cl+i].fulltext = newT[i]; }
-                    content[cl + newT.length - 1].fulltext = lastline;
-
-                    moveCursor(cl + newT.length - 1, newT[newT.length -1].length);
-                } else {
-                    xwt.println("WARNING: Single line edit, ignoring all text after the carrige return.");
-                    content[0].fulltext = content[0].fulltext.substring(0, cx) + newT[0] + content[0].fulltext.substring(cx);
-
-                    moveCursor(0, cx + newT[0].length);
-                }
-            }
-        }
-
-        // Delete the text within the given range.
-        deleteText = function(cl1, cx1, cl2, cx2) {
-            content[cl1].fulltext = content[cl1].fulltext.substring(0, cx1) + content[cl2].fulltext.substring(cx2);
-            for (; cl2 > cl1; cl2--) { reapLine(content[cl2]); }
-        }
-
-        // Select the text within the given range.
-        selectText = function(cl1, cx1, cl2, cx2) {
-            // Find cy1 and px1.
-            var cy1 = 0;
-            var px1 = cx1;
-            for (; content[cl1].numchildren > cy1; cy1++) {
-                if (content[cl1][cy1].text.length > px1) { break; }
-                else { px1 -= content[cl1][cy1].text.length; }
-            }
-
-            // Find cy2 and px2.
-            var cy2 = 0;
-            var px2 = cx2;
-            for (; content[cl2].numchildren > cy2; cy2++) {
-                if (content[cl2][cy2].text.length >= px2) { break; }
-                else { px2 -= content[cl2][cy2].text.length; }
-            }
-
-            // Call the internal select function.
-            sel.cl = cl1; sel.cy = cy1; sel.px = px1;
-            select(cl1, cy1, px1, cl2, cy2, px2);
-            moveCursorToCy(cl2, cy2, px2);
-        }
-
-        // Clear the current selection.
-        clearSelection = function() {
-            if (sel.cl == -1 || sel1.cl == -1) return;
-            moveCursorToCy(sel1.cl, sel1.cy, sel1.px);
-
-            // Clear any selected lines.
-            for (var i=sel1.cl; sel2.cl >= i; i++) { if (content[i] != null) content[i].selected = false; }
-
-            // Clear the selection values
-            sel.cl = sel.px = sel.cy = sel1.cl = sel1.cx = sel1.cy = sel2.cl = sel2.cx = sel2.cy = -1;
-            sel1.text  = sel2.text  = "";
-        }
-
-        // Delete the text currently within the selected range.
-        deleteSelection = function() {
-            if (sel1.cl == -1 || sel2.cl == -1) return;
-            deleteText(sel1.cl, calcCx(sel1.cl, sel1.cy, sel1.px), sel2.cl, calcCx(sel2.cl, sel2.cy, sel2.px));
-            clearSelection();
-        }
-
-        // External interface for moving the mouse cursor.
-        moveCursor = function(cl, cx) {
-            // Work out what subline cx is on.
-            var cy, px;
-
-            if (cl >= content.numchildren) return;
-
-            if (cx > content[cl].fulltext.length) {
-                if (content.numchildren -1 > cl) {
-                    cl++; cx = 0; cy = 0; px = 0;
-                } else {
-                    cx = content[cl].fulltext.length;
-                    cy = content[cl].numchildren -1;
-                    px = content[cl][cy].text.length;
-                }
-            } else {
-                px = cx;
-
-                for (cy = 0; content[cl].numchildren > cy; cy++) {
-                    if (content[cl][cy].text.length >= px) break;
-                    px -= content[cl][cy].text.length;
-                }
-            }
-
-            // Call internal move function.
-            moveCursorToPos(cl, cx, cy, px);
-        }
-
-
-        // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////
-
-        var updateSelectionCx = function(cl, cx) {
-            if (cl >= content.numchildren) {
-                var t = content[content.numchildren -1];
-                updateSelection(content.numchildren -1, t.numchildren, t[t.numchildren -1].text.length);
-                return;
-            } else if (cx > content[cl].fulltext.length) {
-                updateSelection(cl, content[cl].numchildren -1, content[cl][content[cl].numchildren -1].text.length);
-                return;
-            }
-
-            var cy;
-            for (cy = 0; cx > 0; cy++) {
-                cx -= content[cl][cy].text.length;
-            }
-            cy--;
-
-            updateSelection(cl, cy, content[cl][cy].text.length + cx);
-        }
-
-        // Used in the _KeyPress trap to literally update a current selection. The new 'floating point' is passed, and
-        // the original value stored in the private property sel is used to balance with.
-        var updateSelection = function(cl, cy, px) {
-            // Very very very padentic checking. I dare you to do more checking. :-)
-            if (0 > px || 0 > cy || 0 > cl) {
-                if (cy - 1 >= 0) { cy--; px = content[cl][cy].text.length; }
-                else if (cl - 1 >= 0) { cl--; cy = content[cl].numchildren - 1; px = content[cl][cy].text.length; }
-                else { cl = 0; cy = 0; px = 0; }
-            } else if (cl >= content.numchildren) {
-                cl = content.numchildren - 1;
-                cy = content[cl].numchildren - 1;
-                px = content[cl][cy].text.length;
-            } else if (cy >= content[cl].numchildren || px > content[cl][cy].text.length) {
-                if (content[cl].numchildren > cy + 1) { cy++; px = 0; }
-                else if (content.numchildren > cl + 1) { cl++; cy = 0; px = 0; }
-                else { cl = content.numchildren - 1; cy = content[cl].numchildren - 1; px = content[cl][cy].text.length; }
-            }
-
-            // If there is no current selection, set to current mouse position.
-            if (sel.cl == -1) { sel.cl = curs.cl; sel.cy = curs.cy; sel.px = curs.px; }
-
-            // Decide on dominant point and call internal select function.
-            if (cl > sel.cl || (cl == sel.cl and cy > sel.cy) || (cl == sel.cl and cy == sel.cy and px > sel.px)) {
-                select(sel.cl, sel.cy, sel.px, cl, cy, px);
-            } else {
-                select(cl, cy, px, sel.cl, sel.cy, sel.px);
-            }
-
-            // Update cursor position.
-            moveCursorToCy(cl, cy, px);
-        }
-
-        // The meat behind all select calls. This function draws the select boxes on top of the edit widget.
-        var select = function(cl1, cy1, px1, cl2, cy2, px2) {
-            if (disabled) return;
-
-            // Deselect the current full-selection lines that are outside the new selection area.
-            if (sel1.cl == cl1) {
-                for (var i=sel1.cy+1; cy1 >= i; i++) { content[cl1][i].selected = false; }
-            } else if (cl1 > sel1.cl) {
-                for (var i=xwt.math.max(0, sel1.cl); cl1 >= i; i++) { content[i].selected = false; }
-            }
-            if (sel2.cl == cl2) { 
-                for (var i=sel2.cy-1; i >= cy2; i--) { content[cl2][i].selected = false; }
-            } else if (sel2.cl > cl2) {
-                for (var i=xwt.math.max(0, sel2.cl); i >= cl2; i--) { content[i].selected = false; }
-            }
-
-            // Store point data.
-            sel1.cl = cl1; sel1.cy = cy1; sel1.px = px1;
-            sel2.cl = cl2; sel2.cy = cy2; sel2.px = px2;
-
-            // Place first select box.
-            sel1.y = content[cl1].y + content[cl1][cy1].y;
-            sel1.x = xwt.textwidth(font, content[cl1][cy1].text.substring(0, px1));
-
-            if (cl1 == cl2 and cy1 == cy2) {
-                // Only the first select box is required.
-                sel1.text = content[cl1][cy1].text.substring(px1, px2);
-                sel2.text = "";
-            } else {
-                sel1.text = content[cl1][cy1].text.substring(px1);
-                sel2.y = content[cl2].y + content[cl2][cy2].y;
-                sel2.x = 0;
-                sel2.text = content[cl2][cy2].text.substring(0, px2);
-
-                // Mark middle lines.
-                if (cl1 == cl2) {
-                    for (var i=cy1+1; cy2 > i; i++) { content[cl1][i].selected = true; }
-                } else {
-                    for (var i=cy1+1; content[cl1].numchildren > i; i++) { content[cl1][i].selected = true; }
-                    for (var i=cl1+1; cl2 > i; i++) { content[i].selected = true; }
-                    for (var i=0; cy2 > i; i++) { content[cl2][i].selected = true; }
-                }
-            }
-        }
-
-        // Internal reference function. Calculates the cx position of the cursor based on cl, cy and px,
-        // and then passes it to the primary internal function moveCursorToPos() for movement.
-        var moveCursorToCy = function(cl, cy, px) { moveCursorToPos(cl, calcCx(cl, cy, px), cy, px); }
-
-        var calcCx = function(cl, cy, px) { for (cy--; cy >= 0; cy--) { px += content[cl][cy].text.length; } return px; }
-
-        // Internal function for moving the mouse cursor. px represents number of characters over in specified subline.
-        // NOTE: The mouse cursor is the closest the external functions get to affecting the internal structure of a line.
-        var moveCursorToPos = function(cl, cx, cy, px) {
-            // Check the passed values are within reasonable constaints.
-            if (cl >= content.numchildren) { cl = content.numchildren - 1; }
-            if (cy >= content[cl].numchildren) {
-                if (content.numchildren - 1 > cl) { cl++; cy = 0; cx = calcCx(cl, cy, px); }
-                else { cy = content[cl].numchildren -1; cx = calcCx(cl, cy, px); }
-            } else if (0 > cy) {
-                if (cl > 0) { cl--; cy = content[cl].numchildren - 1; cx = calcCx(cl, cy, px); }
-                else { cy = 0; cx = calcCx(cl, cy, px); }
-            }
-            if (0 > px) { px = 0; cx = calcCx(cl, cy, px); }
-            else if (px > content[cl][cy].text.length) { px = content[cl][cy].text.length; cx = calcCx(cl, cy, px); }
-
-            // Move the cursor.
-            curs.cl = cl; curs.cx = cx; curs.cy = cy; curs.px = px;
-            curs.y = content.y + content[cl].y + (lineheight * cy);
-            curs.x = content.x + xwt.textwidth(font, content[cl][cy].text.substring(0, px)) -1;
-            curs.blink = false;
-
-            // Speed Hack: As the cursor has values that match the names used by the focusarea variable, we
-            //             simply pass the curs reference as the focusarea.
-            focusarea = curs;
-
-            if (0 > curs.x) curs.x = 0;
-        }
-
-        // Returns a box ready to be a full line, armed with the current fulltext trap.
-        var newLine = function() {
-            var b = xwt.newBox();
-
-            b.color     = color;
-            b.align     = "topleft";
-            b.invisible = false;
-
-            b[0] = newSoftline();
-            b._Press1   = function() { ref_press(arguments.trapee); }
-            b._selected = function(s) { for (var i=0; b.numchildren > i; i++) { b[i].selected = s; } }
-            b._font     = function(f) { for (var i=0; b.numchildren > i; i++) { b[i].font     = f; } }
-            b._fulltext = ref_fulltext;
-            b.fulltext  = "";
-            b.orient    = "vertical";
-            b.vshrink   = true;
-
-            return b;
-        }
-
-        // Returns a box ready to be a soft line; one of the components of a line.
-        var newSoftline = function() {
-            var b = xwt.newBox();
-
-            b._selected = function(s) {
-                arguments.trapee.color     = s ? selectcolor : color;
-                arguments.trapee.textcolor = s ? selecttextcolor : textcolor;
-            };
-            b.minheight = lineheight;
-            b.shrink    = true;
-            b.color     = color;
-            b.textcolor = textcolor;
-            b.font      = font;
-            b.align     = "topleft";
-            b.invisible = false;
-
-            linecount++;
-
-            return b;
-        }
-
-        // Takes the given line and strips it of traps and returns it to the static stack.
-        var reapLine = function(toReap) {
-            if (content.indexof(toReap) == -1) {
-                // Soft-line
-                linecount--;
-            } else {
-                // Hard-line, count all softline children.
-                linecount -= toReap.numchildren;
-            }
-
-            toReap.thisbox = null;
-        }
-
-
-        // SUBLINE FUNCTIONS //////////////////////////////////////////////
-
-        var fulltext_nowrap = function(t) {
-            arguments.trapee[0].text = t;
-        }
-        var fulltext_linewrap = function(t) {
-            var cw = width;
-
-            if (cw == 0) return;
-
-            var i = 0;
-            if (t.length == 0) arguments.trapee[0].text = "";
-
-            for (; t.length > 0; i++) {
-                if (i == arguments.trapee.numchildren) { arguments.trapee[i] = newSoftline(); }
-
-                // TODO: Switch to getpos
-                var nl = static.getpos(t, cw, xwt.textwidth(font, t), font);
-                arguments.trapee[i].text = t.substring(0, nl);
-                t = t.substring(nl);
-            }
-
-            // Remove any excess lines.
-            if (i == 0) i++;
-            while (arguments.trapee.numchildren > i) { reapLine(arguments.trapee[i]); }
-        }
-        var fulltext_wordwrap = function(t) {
-            var cw = width;
-
-            if (cw == 0) return;
-
-            var i = 0;
-            if (t.length == 0) arguments.trapee[0].text = "";
-
-            for (; t.length > 0; i++) {
-                if (i == arguments.trapee.numchildren) { arguments.trapee[i] = newSoftline(); }
-
-                var nl = static.getpos(t, cw, xwt.textwidth(font, t), font);
-
-                var rl = nl;
-                if (t.length > nl) {
-                    // TODO: Clean up, make it work off a static array of possible break points.
-                    // TODO: Make it themeable as well.
-                    for (; rl > 0; rl--) {
-                        if (t.charAt(rl) == ' ' || t.charAt(rl) == '-') { rl++; break; }
-                    }
-                    if (0 >= rl || rl > nl) rl = nl;
-                }
-
-                arguments.trapee[i].text = t.substring(0, rl);
-                t = t.substring(rl);
-            }
-
-            // Remove any excess lines.
-            if (i == 0) i++;
-            while (arguments.trapee.numchildren > i) { reapLine(arguments.trapee[i]); }
-        }
-
-        // Reference to the current function to use for the fulltext trap.
-        var ref_fulltext = fulltext_nowrap;
-
-        // Handles selection/cursor movement from mouse events.
-        //  The passed value is a reference to the selected hard line.
-        var ref_press = function(refline) {
-            if (disabled) return;
-
-            root._Move = function() {
-                // Update Selection.
-                var linediff = xwt.math.floor((content.mousey - (content[sel.cl].y + content[sel.cl][sel.cy].y)) / lineheight);
-
-                var cl = sel.cl;
-                var cy = sel.cy;
-
-                // End of selection comes after start.
-                while (linediff > 0) {
-                    cy++;
-                    if (cy >= content[cl].numchildren) { cl++; cy = 0; }
-                    if (cl >= content.numchildren) { cl--; break; }
-                    linediff--;
-                }
-
-                // End of selection comes before start.
-                while (0 > linediff) {
-                    cy--;
-                    if (0 > cy) { cl--; cy = content[cl].numchildren -1; }
-                    if (0 > cl) { cl=0; cy = 0; break; }
-                    linediff++;
-                }
-
-                var px = static.getpos(content[cl][cy].text, content[cl][cy].mousex, content[cl][cy].width, font);
-
-                updateSelection(cl, cy, px);
-            }
-
-            root._Release1 = function() {
-                root._Move = root._Release1 = null;
-                // TODO: Put selection to clipboard.
-            }
-
-            // Set selection root position.
-            clearSelection();
-            sel.cl = content.indexof(refline);
-            sel.cy = xwt.math.floor(refline.mousey / lineheight);
-
-            if (sel.cy >= refline.numchildren) sel.cy = refline.numchildren -1;
-            else if (0 > sel.cy)               sel.cy = 0;
-
-            sel.px = static.getpos(refline[sel.cy].text, refline[sel.cy].mousex, refline[sel.cy].width, font);
-
-            moveCursorToCy(sel.cl, sel.cy, sel.px);
-        }
-
-
-        // HELPER FUNCTIONS  //////////////////////////////////////////////
-
-        // Nessesary for when a used clicks in the middle of a current selection.
-        _sel1 = _sel2 = function(s) {
-            if (s != null) {
-                s._Press1 = function(t) { if (arguments.trapee.cl >= 0) content[arguments.trapee.cl].Press1 = t; };
-                s._Release1 = function(t) { if (arguments.trapee.cl >= 0) content[arguments.trapee.cl].Release1 = t; };
-            }
-        }
-
-        _content = function(c) { if (c != null and c.numchildren == 0) c[0] = newLine(); }
-
-        _curs = function(c) {
-            if (c == null) {
-                for (var i=0; static.cursors.length > i; i++) {
-                    if (static.cursors[i] == arguments.cascade()) { static.cursors[i] = null; break; }
-                }
-            } else {
-                // Add cursor to static array for 'blinking'.
-                static.cursors[static.cursors.length] = c;
-            }
-        }
-
-        key_enter = function() {
-            if (!multiline) return;
-            content[curs.cl +1] = newLine();
-            content[curs.cl +1].fulltext = content[curs.cl].fulltext.substring(curs.cx);
-            content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx);
-            xwt.thread = function() { moveCursor(curs.cl +1, 0); }
-        }
-
-        key_back_space = function() {
-            if (curs.cx == 0) {
-                if (curs.cl > 0) {
-                    var px = content[curs.cl -1].fulltext.length;
-                    content[curs.cl -1].fulltext = content[curs.cl -1].fulltext + content[curs.cl].fulltext;
-                    reapLine(content[curs.cl]);
-                    moveCursor(curs.cl -1, px); // Safe, moving up not down.
-                }
-            } else {
-                content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx -1) + content[curs.cl].fulltext.substring(curs.cx);
-                moveCursor(curs.cl, curs.cx -1); // Safe, not moving cl.
-            }
-        }
-
-        key_delete = function() {
-            if (curs.cx == content[curs.cl].fulltext.length) {
-                if (content.numchildren > 1) {
-                    content[curs.cl].fulltext = content[curs.cl].fulltext + content[curs.cl +1].fulltext;
-                    reapLine(content[curs.cl +1]);
-                }
-            } else {
-                content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx) + content[curs.cl].fulltext.substring(curs.cx +1);
-            }
-        }
-
-        // KEY HANDLER       //////////////////////////////////////////////
-        _keypress = function(k) {
-            if (k == null || !editable || disabled) return;
-
-            // Process shortcut for single character entries.
-            if (k.length == 1) {
-                deleteSelection();
-
-                if (k.charAt(0) == '\n') {
-                    insertText(curs.cl, curs.cx, k);
-                } else {
-                    content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx)
-                        + k + content[curs.cl].fulltext.substring(curs.cx);
-                    xwt.thread = function() { moveCursor(curs.cl, curs.cx+1); }
-                    textChanged = true;
-                }
-
-                return;
-            }
-
-            k = k.substring(k.lastIndexOf('-')+1);
-
-            // Process movement commands.
-            if (k == "enter") {
-                deleteSelection(); key_enter();
-                textChanged = true;
-            } else if (k == "back_space") {
-                if (sel1.cl > -1) { deleteSelection(); }
-                else              { key_back_space(); }
-                textChanged = true;
-            } else if (k == "delete") {
-                if (sel1.cl > -1) { deleteSelection(); }
-                else              { key_delete(); }
-                textChanged = true;
-            }
-        }
-
-    </template>
-</xwt>