Chromium Code Reviews| Index: sky/examples/terminal/terminal.sky |
| diff --git a/sky/examples/terminal/terminal.sky b/sky/examples/terminal/terminal.sky |
| index cecacdec96e5947b29e056eda383e599ac72be21..ebdbb1c4fb00c5b51d79ca9ade3a5263954b3fdd 100644 |
| --- a/sky/examples/terminal/terminal.sky |
| +++ b/sky/examples/terminal/terminal.sky |
| @@ -14,8 +14,8 @@ |
| color: rgb(255, 191, 0); |
| font-family: 'Courier', 'monospace'; |
| } |
| - span { |
| - white-space: nowrap; |
| + .line { |
| + white-space: pre; |
| } |
| </style> |
| <sky-scrollable id="control" contenteditable /> |
| @@ -54,6 +54,7 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay { |
| void shadowRootReady() { |
| _control = shadowRoot.getElementById('control'); |
| + _control.addEventListener('keydown', _handleKeyDown); |
| _control.addEventListener('keypress', _handleKeyPress); |
| // Initialize with the first line. |
| @@ -62,20 +63,52 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay { |
| _connect(getAttribute('url')); |
| } |
| + void _handleKeyDown(KeyboardEvent event) { |
|
ojan
2015/03/12 20:11:48
FWIW, you're better off just not using keypress. U
|
| + // 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) { |
| + _enqueueChar(event.charCode); |
| + event.preventDefault(); |
| + } |
| + |
| + void _enqueueChar(int charCode) { |
| // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on. |
| if (_readerQueue.isEmpty) { |
| - _inputQueue.add(event.charCode); |
| + _inputQueue.add(charCode); |
| } 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() { |
| - _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 |
| @@ -91,11 +124,29 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay { |
| @override |
| void putChar(int byte) { |
| - if (byte == 10 || byte == 13) { |
| - _newLine(); |
| + // Fast-path for printable chars. |
| + if (byte >= 32) { |
| + _control.lastChild.textContent += new String.fromCharCode(byte); |
| 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 |