A crappy "netcat"-type example (in Dart).
It's especially crappy since it doesn't actually do much/any error handling. Use: $ sky/tools/skydb start out/Debug \ 'sky/examples/terminal/index.sky?url=mojo:netcat?host=localhost%26port=80' (Note: We don't have a resolver yet, so the host either has to be "localhost" or an IPv4 address in the form N1.N2.N3.N4.) R=erg@chromium.org Review URL: https://codereview.chromium.org/1032743002
This commit is contained in:
parent
0593b9f813
commit
94d55d4003
@ -4,22 +4,43 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
-->
|
-->
|
||||||
<import src="/sky/framework/elements/sky-element.sky" />
|
<import src="/sky/framework/elements/sky-element.sky" />
|
||||||
<import src="/sky/framework/elements/sky-scrollable.sky" />
|
|
||||||
<sky-element>
|
<sky-element>
|
||||||
<template>
|
<template>
|
||||||
<style>
|
<style>
|
||||||
#control {
|
#container {
|
||||||
height: -webkit-fill-available;
|
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;
|
background-color: black;
|
||||||
color: rgb(255, 191, 0);
|
color: rgb(255, 191, 0);
|
||||||
font-family: 'Courier', 'monospace';
|
font-family: 'Courier', 'monospace';
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
.line {
|
.line {
|
||||||
|
height: 1em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<sky-scrollable id="control" contenteditable />
|
<div id="container">
|
||||||
|
<div id="input-box" contenteditable />
|
||||||
|
<div id="output-box" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
@ -35,7 +56,9 @@ import 'terminal_file_impl.dart';
|
|||||||
// |terminal.TerminalClient| service.
|
// |terminal.TerminalClient| service.
|
||||||
@Tagname('terminal')
|
@Tagname('terminal')
|
||||||
class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
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.
|
// Queue of unconsumed input (keystrokes), with the head at index 0.
|
||||||
// Keystrokes end up here if there's no reader (i.e., |getChar()|) pending,
|
// 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() {
|
void shadowRootReady() {
|
||||||
_control = shadowRoot.getElementById('control');
|
_inputBox = shadowRoot.getElementById('input-box');
|
||||||
_control.addEventListener('keydown', _handleKeyDown);
|
_inputBox.addEventListener('keydown', _handleKeyDown);
|
||||||
_control.addEventListener('keypress', _handleKeyPress);
|
_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.
|
// Initialize with the first line.
|
||||||
_newLine();
|
_newLine();
|
||||||
|
|
||||||
|
// Actually compute the maximum number of lines.
|
||||||
|
// TODO(vtl): Recompute on resize.
|
||||||
|
_maxLines = _outputBox.clientHeight ~/ _outputBox.firstChild.offsetHeight;
|
||||||
|
|
||||||
var url = getAttribute('url');
|
var url = getAttribute('url');
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
connect(url);
|
connect(url);
|
||||||
@ -81,10 +113,16 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleKeyPress(KeyboardEvent event) {
|
void _handleKeyPress(KeyboardEvent event) {
|
||||||
_enqueueChar(event.charCode);
|
if (event.charCode != 0) {
|
||||||
|
_enqueueChar(event.charCode);
|
||||||
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleWheel(WheelEvent event) {
|
||||||
|
_outputBox.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void _enqueueChar(int charCode) {
|
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.
|
||||||
|
|
||||||
@ -96,22 +134,28 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _backspace() {
|
void _backspace() {
|
||||||
var oldText = _control.lastChild.textContent;
|
var oldText = _outputBox.lastChild.textContent;
|
||||||
if (oldText.length > 0) {
|
if (oldText.length > 0) {
|
||||||
_control.lastChild.textContent = oldText.substring(0, oldText.length - 1);
|
_outputBox.lastChild.textContent = oldText.substring(0,
|
||||||
|
oldText.length - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _newLine() {
|
void _newLine() {
|
||||||
var line = document.createElement('div');
|
var line = document.createElement('div');
|
||||||
line.setAttribute('class', 'line');
|
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() {
|
void _clear() {
|
||||||
while (_control.firstChild != null) {
|
_outputBox.setChildren([]);
|
||||||
_control.firstChild.remove();
|
|
||||||
}
|
|
||||||
_newLine();
|
_newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +178,7 @@ class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
|
|||||||
void putChar(int byte) {
|
void putChar(int byte) {
|
||||||
// Fast-path for printable chars.
|
// Fast-path for printable chars.
|
||||||
if (byte >= 32) {
|
if (byte >= 32) {
|
||||||
_control.lastChild.textContent += new String.fromCharCode(byte);
|
_outputBox.lastChild.textContent += new String.fromCharCode(byte);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user