From f94c9c82d144690bfe24a93554e47cfa6a3b2275 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Tue, 6 Oct 2015 16:36:45 +0200 Subject: Refactor renderLine Hide the cursor when console is blurred. Do not change the color of character under cursor when cursor is in the unblinked phase. --- js/codeq/console.js | 159 ++++++++++++++++++++++++---------------------------- 1 file changed, 73 insertions(+), 86 deletions(-) (limited to 'js') diff --git a/js/codeq/console.js b/js/codeq/console.js index ebf09cc..20f3a90 100644 --- a/js/codeq/console.js +++ b/js/codeq/console.js @@ -176,70 +176,27 @@ currentHistoryIndex = -1, instanceNumber = instanceCounter++, // unique instace number, to be used with stuff tied to this instance, e.g.: jqElt events, life-cycle debug output - renderSpan = function (lineDescriptor, startCol, length) { + renderLine = function (lineDescriptor) { var jqLine = lineDescriptor.jqLine, content = lineDescriptor.content, - classes = lineDescriptor.classNames, - endCol = startCol + length, - N = classes ? classes.length : 0, + classes = lineDescriptor.classNames || [], + cursor = currentRow == lineDescriptor.row ? currentCol : null, + startCol = 0, i = 0, spans = [], // what to render, items are of the form {'content': string, 'cssClass': string} - entry, classSpan, jq, span, s, prefixDelta, suffixDelta, e; - // seek out the first css class - while (i < N) { - entry = classes[i]; - if (((entry.start + entry.length) > startCol) && (entry.start < endCol)) break; - i++; - } - if (i < N) { - // render the first span - e = entry.start + entry.length; // end column of this css class - prefixDelta = entry.start < startCol ? startCol - entry.start : 0; - suffixDelta = e > endCol ? e - endCol : 0; - classSpan = entry.length - prefixDelta - suffixDelta; - span = {'content': content.substr(startCol, classSpan), 'cssClass': entry.name}; - spans.push(span); - startCol += classSpan; - i++; - // render the rest - while ((startCol < endCol) && (i < N)) { - entry = classes[i]; - e = entry.start + entry.length; // end column of this css class - prefixDelta = entry.start < startCol ? startCol - entry.start : 0; - suffixDelta = e > endCol ? e - endCol : 0; - classSpan = entry.length - prefixDelta - suffixDelta; - s = content.substr(startCol, classSpan); - if (entry.name === span.cssClass) { - span.content += s; // join content where the class is the same + entry, jq, e, beforeCursor, afterCursor, name, + addOrMergeSpan = function (content, className) { + if (spans.length > 0 && className === spans[spans.length-1].cssClass) { + // join content to previous span where the class is the same + spans[spans.length-1].content += content; } else { - span = {'content': s, 'cssClass': entry.name}; - spans.push(span); + // add a new span for a new class + spans.push({'content': content, 'cssClass': className}); } - startCol += classSpan; - i++; - } - } - // render any leftover - if (startCol < endCol) { - entry = makeClassDescriptor('', startCol, endCol - startCol); - spans.push({'content': content.substring(startCol, endCol), 'cssClass': ''}); - } - // render spans - for (i = 0; i < spans.length; i++) { - span = spans[i]; - jq = $(''); - jqLine.append(jq); - jq.text(span.content); - } - return entry; // return the last entry used - }, - - renderLine = function (lineDescriptor) { - var jqLine = lineDescriptor.jqLine, - content = lineDescriptor.content, - jqCursor, classDescriptor; + }; + // get or create line if (!jqLine) { jqLine = $('
');
                     if (lineDescriptor.row == 0) {
@@ -258,33 +215,47 @@
                     jqLine.empty();
                 }
 
-                if (currentRow == lineDescriptor.row) {
-                    // mark the cursor in the current line
-                    if (currentCol >= content.length) {
-                        // cursor after the last character
-                        renderSpan(lineDescriptor, 0, content.length);
-                        jqCursor = $(' ');
-                        jqLine.append(jqCursor);
-                    }
-                    else if (currentCol <= 0) {
-                        // cursor at the first character
-                        classDescriptor = lineDescriptor.classNames[0] || makeClassDescriptor('', 0, content.length);
-                        jqCursor = $('');
-                        jqLine.append(jqCursor);
-                        jqCursor.text(content.charAt(0));
-                        renderSpan(lineDescriptor, 1, content.length - 1);
+                // create spans
+                while (startCol < content.length) {
+                    entry = i < classes.length ? classes[i]
+                                               : makeClassDescriptor('', startCol, content.length - startCol);
+                    e = entry.start + entry.length; // end column of this css class
+                    if (cursor !== null && cursor >= entry.start && cursor < e) {
+                        // cursor is in this span
+                        beforeCursor = content.substr(startCol, cursor - startCol);
+                        if (beforeCursor) {
+                            addOrMergeSpan(beforeCursor, entry.name);
+                        }
+
+                        spans.push({'content': content.charAt(cursor), 'cssClass': 'cq-con-cursor ' + entry.name});
+                        afterCursor = content.substr(cursor + 1, e - cursor - 1);
+                        if (afterCursor) {
+                            spans.push({'content': afterCursor, 'cssClass': entry.name});
+                        }
                     }
                     else {
-                        // cursor somewhere in between
-                        classDescriptor = renderSpan(lineDescriptor, 0, currentCol);
-                        jqCursor = $('');
-                        jqLine.append(jqCursor);
-                        jqCursor.text(content.charAt(currentCol));
-                        renderSpan(lineDescriptor, currentCol + 1, content.length - currentCol - 1);
+                        // cursor is not in this span
+                        addOrMergeSpan(content.substr(startCol, entry.length), entry.name);
                     }
+                    startCol += entry.length;
+                    i++;
                 }
-                else {
-                    renderSpan(lineDescriptor, 0, content.length);
+                // add a fake space if cursor is at end of line
+                if (cursor !== null && cursor >= content.length) {
+                    name = entry ? entry.name : '';
+                    spans.push({'content': ' ', 'cssClass': 'cq-con-cursor ' + name});
+                }
+
+                // render spans
+                for (i = 0; i < spans.length; i++) {
+                    jq = $('');
+                    jqLine.append(jq);
+                    jq.text(spans[i].content);
+                }
+
+                // (re-)render cursor if it is in the current line
+                if (cursor !== null) {
+                    renderCursor();
                 }
             },
 
@@ -891,8 +862,27 @@
 
             clipboardPasteInProgress = false, // whether the previous keydown was a CTRL+V or shift+insert
             aKeyIsDown = false, // whether a key is currently pressed: if it's not and there is input, then we got a paste via mouse
+
             cursorBlinkRate = (options && options.cursorBlinkRate) || 750, // default: 750 ms
             blinkTimer = null,
+            renderCursor = function () {
+                if (blinkTimer) {
+                    clearInterval(blinkTimer);
+                    blinkTimer = null;
+                }
+                if (jqInput.is(':focus')) {
+                    jqContent.find('.cq-con-cursor').addClass('inverted');
+                    if ((typeof cursorBlinkRate === 'number') && (cursorBlinkRate >= 50)) { // have some sense of sanity
+                        blinkTimer = setInterval(function () {
+                            jqContent.find('.cq-con-cursor').toggleClass('inverted');
+                        }, cursorBlinkRate);
+                    }
+                }
+                else {
+                    jqContent.find('.cq-con-cursor').removeClass('inverted');
+                }
+            },
+
             i, j, a, b, c;
 
         // copy default key handlers
@@ -956,6 +946,10 @@
             aKeyIsDown = false;
         });
 
+        jqInput.on('blur focus', function () {
+            renderCursor();
+        });
+
         if ('oninput' in jqInput[0]) {
             // the element supports input events, use them in preference to keypress events
             jqInput.on('input', function (evt) {
@@ -982,13 +976,6 @@
             });
         }
 
-        // start the cursor blinking if so instructed
-        if ((typeof cursorBlinkRate === 'number') && (cursorBlinkRate >= 50)) { // have some sense of sanity
-            blinkTimer = setInterval(function () {
-                jqContent.find('.cq-con-cursor').toggleClass('inverted');
-            }, cursorBlinkRate);
-        }
-
         // emit greeting if provided
         if (options && options.greeting) {
             lines.push({content: options.greeting, className: 'greeting'});
-- 
cgit v1.2.1