| Index: sky/examples/terminal/terminal.sky
|
| diff --git a/sky/examples/terminal/terminal.sky b/sky/examples/terminal/terminal.sky
|
| index 489e46e5d35205012b958c8c166664cdbf102bb1..246bdfccf682fda7ea82dc69f6b9f64be64521de 100644
|
| --- a/sky/examples/terminal/terminal.sky
|
| +++ b/sky/examples/terminal/terminal.sky
|
| @@ -4,22 +4,43 @@
|
| // found in the LICENSE file.
|
| -->
|
| <import src="/sky/framework/elements/sky-element.sky" />
|
| -<import src="/sky/framework/elements/sky-scrollable.sky" />
|
| <sky-element>
|
| <template>
|
| <style>
|
| - #control {
|
| + #container {
|
| height: -webkit-fill-available;
|
| + }
|
| + #input-box {
|
| + position: absolute;
|
| + left: 0;
|
| + top: 0;
|
| + z-index: 10;
|
| + width: 100%;
|
| + height: 100%;
|
| + opacity: 0;
|
| + }
|
| + #output-box {
|
| + position: absolute;
|
| + left: 0;
|
| + top: 0;
|
| + z-index: 0;
|
| + width: 100%;
|
| + height: 100%;
|
| background-color: black;
|
| color: rgb(255, 191, 0);
|
| font-family: 'Courier', 'monospace';
|
| font-size: small;
|
| }
|
| .line {
|
| + height: 1em;
|
| white-space: nowrap;
|
| }
|
| </style>
|
| - <sky-scrollable id="control" contenteditable />
|
| + <div id="container">
|
| + <div id="input-box" contenteditable />
|
| + <div id="output-box" />
|
| + </div>
|
| + </div>
|
| </template>
|
| <script>
|
| import 'dart:async';
|
| @@ -35,7 +56,9 @@ import 'terminal_file_impl.dart';
|
| // |terminal.TerminalClient| service.
|
| @Tagname('terminal')
|
| class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
| - Element _control;
|
| + Element _inputBox;
|
| + Element _outputBox;
|
| + int _maxLines;
|
|
|
| // Queue of unconsumed input (keystrokes), with the head at index 0.
|
| // Keystrokes end up here if there's no reader (i.e., |getChar()|) pending,
|
| @@ -54,13 +77,22 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
| }
|
|
|
| void shadowRootReady() {
|
| - _control = shadowRoot.getElementById('control');
|
| - _control.addEventListener('keydown', _handleKeyDown);
|
| - _control.addEventListener('keypress', _handleKeyPress);
|
| + _inputBox = shadowRoot.getElementById('input-box');
|
| + _inputBox.addEventListener('keydown', _handleKeyDown);
|
| + _inputBox.addEventListener('keypress', _handleKeyPress);
|
| + _inputBox.addEventListener('wheel', _handleWheel);
|
| + _outputBox = shadowRoot.getElementById('output-box');
|
| +
|
| + // Hack to allow |_newLine()| to work.
|
| + _maxLines = 100;
|
|
|
| // Initialize with the first line.
|
| _newLine();
|
|
|
| + // Actually compute the maximum number of lines.
|
| + // TODO(vtl): Recompute on resize.
|
| + _maxLines = _outputBox.clientHeight ~/ _outputBox.firstChild.offsetHeight;
|
| +
|
| var url = getAttribute('url');
|
| if (url != null) {
|
| connect(url);
|
| @@ -81,10 +113,16 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
| }
|
|
|
| void _handleKeyPress(KeyboardEvent event) {
|
| - _enqueueChar(event.charCode);
|
| + if (event.charCode != 0) {
|
| + _enqueueChar(event.charCode);
|
| + }
|
| event.preventDefault();
|
| }
|
|
|
| + void _handleWheel(WheelEvent event) {
|
| + _outputBox.dispatchEvent(event);
|
| + }
|
| +
|
| void _enqueueChar(int charCode) {
|
| // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on.
|
|
|
| @@ -96,22 +134,28 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
| }
|
|
|
| void _backspace() {
|
| - var oldText = _control.lastChild.textContent;
|
| + var oldText = _outputBox.lastChild.textContent;
|
| if (oldText.length > 0) {
|
| - _control.lastChild.textContent = oldText.substring(0, oldText.length - 1);
|
| + _outputBox.lastChild.textContent = oldText.substring(0,
|
| + oldText.length - 1);
|
| }
|
| }
|
|
|
| void _newLine() {
|
| var line = document.createElement('div');
|
| line.setAttribute('class', 'line');
|
| - _control.appendChild(line);
|
| + _outputBox.appendChild(line);
|
| +
|
| + // Scroll if necessary.
|
| + var children = _outputBox.getChildNodes();
|
| + if (children.length > _maxLines) {
|
| + children = new List.from(children.skip(children.length - _maxLines));
|
| + _outputBox.setChildren(children);
|
| + }
|
| }
|
|
|
| void _clear() {
|
| - while (_control.firstChild != null) {
|
| - _control.firstChild.remove();
|
| - }
|
| + _outputBox.setChildren([]);
|
| _newLine();
|
| }
|
|
|
| @@ -134,7 +178,7 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
| void putChar(int byte) {
|
| // Fast-path for printable chars.
|
| if (byte >= 32) {
|
| - _control.lastChild.textContent += new String.fromCharCode(byte);
|
| + _outputBox.lastChild.textContent += new String.fromCharCode(byte);
|
| return;
|
| }
|
|
|
|
|