summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@araneo.org>2015-10-06 16:36:45 +0200
committerTimotej Lazar <timotej.lazar@araneo.org>2015-10-06 16:36:45 +0200
commitf94c9c82d144690bfe24a93554e47cfa6a3b2275 (patch)
treeaa1c3b01dab226de599935ce798e408e99c81cec
parente79eb3693220430ecbe2cac68187d525cf6474a3 (diff)
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.
-rw-r--r--css/codeq/console.css16
-rw-r--r--js/codeq/console.js159
2 files changed, 78 insertions, 97 deletions
diff --git a/css/codeq/console.css b/css/codeq/console.css
index c3ae853..723f3d5 100644
--- a/css/codeq/console.css
+++ b/css/codeq/console.css
@@ -14,20 +14,14 @@
padding: 0;
}
.cq-con-text {
-
}
-.cq-con-cursor {
- color: black;
- background: greenyellow;
-}
-.cq-con-cursor.inverted {
- color: greenyellow;
- background: black;
-}
-
.cq-con-text.input {
color: #a6e1ec;
}
.cq-con-text.error {
color: #d9534f;
-} \ No newline at end of file
+}
+.cq-con-cursor.inverted {
+ color: black;
+ background: greenyellow;
+}
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 = $('<span class="cq-con-text ' + span.cssClass + '"></span>');
- 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 = $('<pre class="cq-con-line"></pre>');
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 = $('<span class="cq-con-cursor">&nbsp;</span>');
- jqLine.append(jqCursor);
- }
- else if (currentCol <= 0) {
- // cursor at the first character
- classDescriptor = lineDescriptor.classNames[0] || makeClassDescriptor('', 0, content.length);
- jqCursor = $('<span class="cq-con-cursor ' + classDescriptor.name + '"></span>');
- 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 = $('<span class="cq-con-cursor ' + classDescriptor.name + '"></span>');
- 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 = $('<span class="cq-con-text ' + spans[i].cssClass + '"></span>');
+ 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'});