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

Side by Side Diff: sky/examples/terminal/terminal.sky

Issue 997873004: Terminal: Add support for (and "fix") backspace. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased/updated 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 unified diff | Download patch
« no previous file with comments | « no previous file | sky/examples/terminal/terminal_file_impl.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!-- 1 <!--
2 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Copyright 2015 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be 3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file. 4 // found in the LICENSE file.
5 --> 5 -->
6 <import src="/sky/framework/elements/sky-element.sky" /> 6 <import src="/sky/framework/elements/sky-element.sky" />
7 <import src="/sky/framework/elements/sky-scrollable.sky" /> 7 <import src="/sky/framework/elements/sky-scrollable.sky" />
8 <sky-element> 8 <sky-element>
9 <template> 9 <template>
10 <style> 10 <style>
11 #control { 11 #control {
12 height: -webkit-fill-available; 12 height: -webkit-fill-available;
13 background-color: black; 13 background-color: black;
14 color: rgb(255, 191, 0); 14 color: rgb(255, 191, 0);
15 font-family: 'Courier', 'monospace'; 15 font-family: 'Courier', 'monospace';
16 } 16 }
17 span { 17 .line {
18 white-space: nowrap; 18 white-space: pre;
19 } 19 }
20 </style> 20 </style>
21 <sky-scrollable id="control" contenteditable /> 21 <sky-scrollable id="control" contenteditable />
22 </template> 22 </template>
23 <script> 23 <script>
24 import 'dart:async'; 24 import 'dart:async';
25 import 'dart:core'; 25 import 'dart:core';
26 import 'dart:sky'; 26 import 'dart:sky';
27 import 'package:examples/echo_terminal/terminal_client.mojom.dart' as terminal; 27 import 'package:examples/echo_terminal/terminal_client.mojom.dart' as terminal;
28 import '/sky/framework/embedder.dart'; 28 import '/sky/framework/embedder.dart';
(...skipping 18 matching lines...) Expand all
47 // dequeued). 47 // dequeued).
48 List<Completer<int>> _readerQueue; 48 List<Completer<int>> _readerQueue;
49 49
50 TerminalDisplayImpl() 50 TerminalDisplayImpl()
51 : _inputQueue = new List<int>(), 51 : _inputQueue = new List<int>(),
52 _readerQueue = new List<Completer<int>>() { 52 _readerQueue = new List<Completer<int>>() {
53 } 53 }
54 54
55 void shadowRootReady() { 55 void shadowRootReady() {
56 _control = shadowRoot.getElementById('control'); 56 _control = shadowRoot.getElementById('control');
57 _control.addEventListener('keydown', _handleKeyDown);
57 _control.addEventListener('keypress', _handleKeyPress); 58 _control.addEventListener('keypress', _handleKeyPress);
58 59
59 // Initialize with the first line. 60 // Initialize with the first line.
60 _newLine(); 61 _newLine();
61 62
62 _connect(getAttribute('url')); 63 _connect(getAttribute('url'));
63 } 64 }
64 65
66 void _handleKeyDown(KeyboardEvent event) {
ojan 2015/03/12 20:11:48 FWIW, you're better off just not using keypress. U
67 // TODO(vtl): In general, our key handling is a total hack (due in part to
68 // sky's keyboard support being incomplete) -- e.g., we shouldn't have to
69 // make our div contenteditable. We have to intercept backspace (^H) here,
70 // since we won't actually get a keypress event for it. (Possibly, we should
71 // only handle keydown instead of keypress, but then we'd have to handle
72 // shift, etc. ourselves.)
73 if (event.key == 8) {
74 _enqueueChar(8);
75 event.preventDefault();
76 }
77 }
78
65 void _handleKeyPress(KeyboardEvent event) { 79 void _handleKeyPress(KeyboardEvent event) {
80 _enqueueChar(event.charCode);
81 event.preventDefault();
82 }
83
84 void _enqueueChar(int charCode) {
66 // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on. 85 // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on.
67 86
68 if (_readerQueue.isEmpty) { 87 if (_readerQueue.isEmpty) {
69 _inputQueue.add(event.charCode); 88 _inputQueue.add(charCode);
70 } else { 89 } else {
71 _readerQueue.removeAt(0).complete(event.charCode); 90 _readerQueue.removeAt(0).complete(charCode);
72 } 91 }
92 }
73 93
74 event.preventDefault(); 94 void _backspace() {
95 var oldText = _control.lastChild.textContent;
96 if (oldText.length > 0) {
97 _control.lastChild.textContent = oldText.substring(0, oldText.length - 1);
98 }
75 } 99 }
76 100
77 void _newLine() { 101 void _newLine() {
78 _control.appendChild(document.createElement('span')); 102 var line = document.createElement('div');
103 line.setAttribute('class', 'line');
104 _control.appendChild(line);
105 }
106
107 void _clear() {
108 while (_control.firstChild != null) {
109 _control.firstChild.remove();
110 }
111 _newLine();
79 } 112 }
80 113
81 // TODO(vtl): Should we always auto-connect? Should there be facilities for 114 // TODO(vtl): Should we always auto-connect? Should there be facilities for
82 // programmatically connecting? (What if the |url| attribute isn't set?) 115 // programmatically connecting? (What if the |url| attribute isn't set?)
83 void _connect(String url) { 116 void _connect(String url) {
84 var terminalClient = new terminal.TerminalClientProxy.unbound(); 117 var terminalClient = new terminal.TerminalClientProxy.unbound();
85 embedder.connectToService(url, terminalClient); 118 embedder.connectToService(url, terminalClient);
86 terminalClient.ptr.connectToTerminal(new TerminalFileImpl(this).stub); 119 terminalClient.ptr.connectToTerminal(new TerminalFileImpl(this).stub);
87 terminalClient.close(); 120 terminalClient.close();
88 } 121 }
89 122
90 // |TerminalDisplay| implementation: 123 // |TerminalDisplay| implementation:
91 124
92 @override 125 @override
93 void putChar(int byte) { 126 void putChar(int byte) {
94 if (byte == 10 || byte == 13) { 127 // Fast-path for printable chars.
95 _newLine(); 128 if (byte >= 32) {
129 _control.lastChild.textContent += new String.fromCharCode(byte);
96 return; 130 return;
97 } 131 }
98 _control.lastChild.textContent += new String.fromCharCode(byte); 132
133 switch (byte) {
134 case 8: // BS (^H).
135 _backspace();
136 break;
137 case 10: // LF ('\n').
138 _newLine(); // TODO(vtl): LF and CR should be separated.
139 break;
140 case 12: // FF (^L).
141 _clear();
142 break;
143 case 13: // CR ('\r').
144 _newLine(); // TODO(vtl): LF and CR should be separated.
145 break;
146 default:
147 // Should beep or something.
148 break;
149 }
99 } 150 }
100 151
101 @override 152 @override
102 Future<int> getChar() async { 153 Future<int> getChar() async {
103 if (_inputQueue.isNotEmpty) { 154 if (_inputQueue.isNotEmpty) {
104 return new Future.value(_inputQueue.removeAt(0)); 155 return new Future.value(_inputQueue.removeAt(0));
105 } 156 }
106 157
107 var completer = new Completer<int>(); 158 var completer = new Completer<int>();
108 _readerQueue.add(completer); 159 _readerQueue.add(completer);
109 return completer.future; 160 return completer.future;
110 } 161 }
111 } 162 }
112 163
113 _init(script) => register(script, TerminalDisplayImpl); 164 _init(script) => register(script, TerminalDisplayImpl);
114 </script> 165 </script>
115 </sky-element> 166 </sky-element>
OLDNEW
« no previous file with comments | « no previous file | sky/examples/terminal/terminal_file_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698