Commit 0beafd35 authored by Viet-Trung Luu's avatar Viet-Trung Luu

Terminal: Add support for (and "fix") backspace.

Also:
* Fix consecutive spaces (don't collapse them).
* Add support for ^L.

Still doesn't work:
* Totally blank lines. (I know why, but I don't know why I can't seem to
  fix it.)

R=erg@chromium.org

Review URL: https://codereview.chromium.org/997873004
parent d34e0e4e
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
color: rgb(255, 191, 0); color: rgb(255, 191, 0);
font-family: 'Courier', 'monospace'; font-family: 'Courier', 'monospace';
} }
span { .line {
white-space: nowrap; white-space: pre;
} }
</style> </style>
<sky-scrollable id="control" contenteditable /> <sky-scrollable id="control" contenteditable />
...@@ -54,6 +54,7 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay { ...@@ -54,6 +54,7 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
void shadowRootReady() { void shadowRootReady() {
_control = shadowRoot.getElementById('control'); _control = shadowRoot.getElementById('control');
_control.addEventListener('keydown', _handleKeyDown);
_control.addEventListener('keypress', _handleKeyPress); _control.addEventListener('keypress', _handleKeyPress);
// Initialize with the first line. // Initialize with the first line.
...@@ -62,20 +63,52 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay { ...@@ -62,20 +63,52 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
_connect(getAttribute('url')); _connect(getAttribute('url'));
} }
void _handleKeyDown(KeyboardEvent event) {
// TODO(vtl): In general, our key handling is a total hack (due in part to
// sky's keyboard support being incomplete) -- e.g., we shouldn't have to
// make our div contenteditable. We have to intercept backspace (^H) here,
// since we won't actually get a keypress event for it. (Possibly, we should
// only handle keydown instead of keypress, but then we'd have to handle
// shift, etc. ourselves.)
if (event.key == 8) {
_enqueueChar(8);
event.preventDefault();
}
}
void _handleKeyPress(KeyboardEvent event) { void _handleKeyPress(KeyboardEvent event) {
_enqueueChar(event.charCode);
event.preventDefault();
}
void _enqueueChar(int charCode) {
// TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on. // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on.
if (_readerQueue.isEmpty) { if (_readerQueue.isEmpty) {
_inputQueue.add(event.charCode); _inputQueue.add(charCode);
} else { } else {
_readerQueue.removeAt(0).complete(event.charCode); _readerQueue.removeAt(0).complete(charCode);
} }
}
event.preventDefault(); void _backspace() {
var oldText = _control.lastChild.textContent;
if (oldText.length > 0) {
_control.lastChild.textContent = oldText.substring(0, oldText.length - 1);
}
} }
void _newLine() { void _newLine() {
_control.appendChild(document.createElement('span')); var line = document.createElement('div');
line.setAttribute('class', 'line');
_control.appendChild(line);
}
void _clear() {
while (_control.firstChild != null) {
_control.firstChild.remove();
}
_newLine();
} }
// TODO(vtl): Should we always auto-connect? Should there be facilities for // TODO(vtl): Should we always auto-connect? Should there be facilities for
...@@ -91,11 +124,29 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay { ...@@ -91,11 +124,29 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
@override @override
void putChar(int byte) { void putChar(int byte) {
if (byte == 10 || byte == 13) { // Fast-path for printable chars.
_newLine(); if (byte >= 32) {
_control.lastChild.textContent += new String.fromCharCode(byte);
return; return;
} }
_control.lastChild.textContent += new String.fromCharCode(byte);
switch (byte) {
case 8: // BS (^H).
_backspace();
break;
case 10: // LF ('\n').
_newLine(); // TODO(vtl): LF and CR should be separated.
break;
case 12: // FF (^L).
_clear();
break;
case 13: // CR ('\r').
_newLine(); // TODO(vtl): LF and CR should be separated.
break;
default:
// Should beep or something.
break;
}
} }
@override @override
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:core'; import 'dart:core';
import 'mojo:core'; import 'dart:mojo.core';
import 'package:services/files/file.mojom.dart' as files; import 'package:services/files/file.mojom.dart' as files;
import 'package:services/files/types.mojom.dart' as files; import 'package:services/files/types.mojom.dart' as files;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment