Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Unified Diff: sky/examples/terminal/terminal.sky

Issue 999193002: Add a simple prototype "terminal" example. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sky/examples/terminal/terminal.sky
diff --git a/sky/examples/terminal/terminal.sky b/sky/examples/terminal/terminal.sky
new file mode 100644
index 0000000000000000000000000000000000000000..74cd1d6e91d83ab0006f7a1b32e6ac272aa5647d
--- /dev/null
+++ b/sky/examples/terminal/terminal.sky
@@ -0,0 +1,114 @@
+<!--
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+-->
+<import src="/sky/framework/sky-element.sky" />
+<import src="/sky/framework/sky-scrollable.sky" />
+<sky-element>
+<template>
+ <style>
+ #control {
+ height: -webkit-fill-available;
+ background-color: black;
+ color: rgb(255, 191, 0);
+ font-family: 'Courier', 'monospace';
+ }
+ span {
+ white-space: nowrap;
+ }
+ </style>
+ <sky-scrollable id="control" contenteditable />
+</template>
+<script>
+import 'dart:async';
+import 'dart:core';
+import 'dart:sky';
+import 'package:examples/echo_terminal/terminal_client.mojom.dart' as terminal;
+import '/sky/framework/embedder.dart';
+import 'terminal_display.dart';
+import 'terminal_file_impl.dart';
+
+// Implements the <terminal> element, which implements a "terminal display". Has
+// an |url| attribute, whose value should be a Mojo app that provides the
+// |terminal.TerminalClient| service.
+@Tagname('terminal')
+class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
+ Element _control;
+
+ // Queue of unconsumed input (keystrokes), with the head at index 0.
+ // Keystrokes end up here if there's no reader (i.e., |getChar()|) pending,
+ // i.e., if |_readerQueue| is empty. Invariant: At most one of |_inputQueue|
+ // and |_readerQueue| may be nonempty at any given time.
+ List<int> _inputQueue;
+
+ // Queue of things waiting for input, with the head at index 0. If a keystroke
+ // is received and this is nonempty, the head is given that keystroke (and
+ // dequeued).
+ List<Completer<int>> _readerQueue;
+
+ TerminalDisplayImpl()
+ : _inputQueue = new List<int>(),
+ _readerQueue = new List<Completer<int>>() {
+ }
+
+ void shadowRootReady() {
+ _control = shadowRoot.getElementById('control');
+ _control.addEventListener('keypress', _handleKeyPress);
+
+ // Initialize with the first line.
+ _newLine();
+
+ _connect(getAttribute('url'));
+ }
+
+ void _handleKeyPress(KeyboardEvent event) {
+ // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on.
+
+ if (_readerQueue.isEmpty) {
+ _inputQueue.add(event.charCode);
+ } else {
+ _readerQueue.removeAt(0).complete(event.charCode);
+ }
Elliot Glaysher 2015/03/11 20:55:43 I look...forward...to seeing how well this perform
viettrungluu 2015/03/11 21:25:18 I think it already performs better than a connecti
Elliot Glaysher 2015/03/11 21:29:05 This is not actually reassuring.
+
+ event.preventDefault();
+ }
+
+ void _newLine() {
+ _control.appendChild(document.createElement('span'));
+ }
+
+ // TODO(vtl): Should we always auto-connect? Should there be facilities for
+ // programmatically connecting? (What if the |url| attribute isn't set?)
+ void _connect(String url) {
+ var terminalClient = new terminal.TerminalClientProxy.unbound();
+ embedder.connectToService(url, terminalClient);
+ terminalClient.ptr.connectToTerminal(new TerminalFileImpl(this).stub);
+ terminalClient.close();
+ }
+
+ // |TerminalDisplay| implementation:
+
+ @override
+ void putChar(int byte) {
+ if (byte == 10 || byte == 13) {
+ _newLine();
+ }
+ _control.lastChild.textContent += new String.fromCharCode(byte);
Elliot Glaysher 2015/03/11 20:55:43 Doesn't this mean that there's now a newline chara
viettrungluu 2015/03/11 21:25:18 Oops, I meant to put a return above. Fixed.
+ }
+
+ @override
+ Future<int> getChar() async {
+ if (_inputQueue.isNotEmpty) {
+ return new Future.value(_inputQueue.removeAt(0));
+ }
+
+ var completer = new Completer<int>();
+ _readerQueue.add(completer);
+ return completer.future;
+ }
+}
+
+_init(script) => register(script, TerminalDisplayImpl);
+</script>
+</sky-element>

Powered by Google App Engine
This is Rietveld 408576698