| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library eval_box_element; | 5 library eval_box_element; |
| 6 | 6 |
| 7 import 'dart:html'; | 7 import 'dart:html'; |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'package:observatory/models.dart' as M; | 9 import 'package:observatory/models.dart' as M; |
| 10 import 'package:observatory/src/elements/helpers/any_ref.dart'; | 10 import 'package:observatory/src/elements/helpers/any_ref.dart'; |
| 11 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | 11 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| 12 import 'package:observatory/src/elements/helpers/tag.dart'; | 12 import 'package:observatory/src/elements/helpers/tag.dart'; |
| 13 import 'package:observatory/src/elements/instance_ref.dart'; | 13 import 'package:observatory/src/elements/instance_ref.dart'; |
| 14 | 14 |
| 15 class EvalBoxElement extends HtmlElement implements Renderable { | 15 class EvalBoxElement extends HtmlElement implements Renderable { |
| 16 static const tag = const Tag<EvalBoxElement>('eval-box', | 16 static const tag = const Tag<EvalBoxElement>('eval-box', |
| 17 dependencies: const [ | 17 dependencies: const [InstanceRefElement.tag]); |
| 18 InstanceRefElement.tag | |
| 19 ]); | |
| 20 | 18 |
| 21 RenderingScheduler<EvalBoxElement> _r; | 19 RenderingScheduler<EvalBoxElement> _r; |
| 22 | 20 |
| 23 Stream<RenderedEvent<EvalBoxElement>> get onRendered => _r.onRendered; | 21 Stream<RenderedEvent<EvalBoxElement>> get onRendered => _r.onRendered; |
| 24 | 22 |
| 25 M.IsolateRef _isolate; | 23 M.IsolateRef _isolate; |
| 26 M.ObjectRef _context; | 24 M.ObjectRef _context; |
| 27 M.InstanceRepository _instances; | 25 M.InstanceRepository _instances; |
| 28 M.EvalRepository _eval; | 26 M.EvalRepository _eval; |
| 29 final _results = <_ExpressionDescription>[]; | 27 final _results = <_ExpressionDescription>[]; |
| 30 String _expression = ''; | 28 String _expression = ''; |
| 31 bool _multiline; | 29 bool _multiline; |
| 32 Iterable<String> _quickExpressions; | 30 Iterable<String> _quickExpressions; |
| 33 | 31 |
| 34 M.IsolateRef get isolate => _isolate; | 32 M.IsolateRef get isolate => _isolate; |
| 35 M.ObjectRef get context => _context; | 33 M.ObjectRef get context => _context; |
| 36 | 34 |
| 37 factory EvalBoxElement(M.IsolateRef isolate, M.ObjectRef context, | 35 factory EvalBoxElement(M.IsolateRef isolate, M.ObjectRef context, |
| 38 M.InstanceRepository instances, | 36 M.InstanceRepository instances, M.EvalRepository eval, |
| 39 M.EvalRepository eval, | 37 {bool multiline: false, |
| 40 {bool multiline: false, | 38 Iterable<String> quickExpressions: const [], |
| 41 Iterable<String> quickExpressions: const [], | 39 RenderingQueue queue}) { |
| 42 RenderingQueue queue}) { | |
| 43 assert(isolate != null); | 40 assert(isolate != null); |
| 44 assert(context != null); | 41 assert(context != null); |
| 45 assert(instances != null); | 42 assert(instances != null); |
| 46 assert(eval != null); | 43 assert(eval != null); |
| 47 assert(multiline != null); | 44 assert(multiline != null); |
| 48 assert(quickExpressions != null); | 45 assert(quickExpressions != null); |
| 49 EvalBoxElement e = document.createElement(tag.name); | 46 EvalBoxElement e = document.createElement(tag.name); |
| 50 e._r = new RenderingScheduler(e, queue: queue); | 47 e._r = new RenderingScheduler(e, queue: queue); |
| 51 e._isolate = isolate; | 48 e._isolate = isolate; |
| 52 e._context = context; | 49 e._context = context; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 68 @override | 65 @override |
| 69 void detached() { | 66 void detached() { |
| 70 super.detached(); | 67 super.detached(); |
| 71 _r.disable(notify: true); | 68 _r.disable(notify: true); |
| 72 children = []; | 69 children = []; |
| 73 _results.clear(); | 70 _results.clear(); |
| 74 } | 71 } |
| 75 | 72 |
| 76 void render() { | 73 void render() { |
| 77 children = [ | 74 children = [ |
| 78 new DivElement()..classes = ['quicks'] | 75 new DivElement() |
| 79 ..children = _quickExpressions.map((q) => | 76 ..classes = ['quicks'] |
| 80 new ButtonElement() | 77 ..children = _quickExpressions.map((q) => new ButtonElement() |
| 81 ..text = q | 78 ..text = q |
| 82 ..onClick.listen((_) { | 79 ..onClick.listen((_) { |
| 83 _expression = q; | 80 _expression = q; |
| 84 _run(); | 81 _run(); |
| 85 }) | 82 })), |
| 86 ), | 83 new DivElement() |
| 87 new DivElement()..classes = ['heading'] | 84 ..classes = ['heading'] |
| 88 ..children = [ | 85 ..children = [ |
| 89 new FormElement() | 86 new FormElement() |
| 90 ..autocomplete = 'on' | 87 ..autocomplete = 'on' |
| 91 ..children = [ | 88 ..children = [ |
| 92 _multiline ? _createEvalTextArea() : _createEvalTextBox(), | 89 _multiline ? _createEvalTextArea() : _createEvalTextBox(), |
| 93 new SpanElement()..classes = ['buttons'] | 90 new SpanElement() |
| 91 ..classes = ['buttons'] |
| 94 ..children = [ | 92 ..children = [ |
| 95 _createEvalButton(), | 93 _createEvalButton(), |
| 96 _createMultilineCheckbox(), | 94 _createMultilineCheckbox(), |
| 97 new SpanElement()..text = 'multi-line' | 95 new SpanElement()..text = 'multi-line' |
| 98 ] | 96 ] |
| 99 ] | 97 ] |
| 100 ], | 98 ], |
| 101 new TableElement() | 99 new TableElement() |
| 102 ..children = _results.reversed.map((result) => | 100 ..children = _results.reversed |
| 103 new TableRowElement() | 101 .map((result) => new TableRowElement() |
| 104 ..children = [ | 102 ..children = [ |
| 105 new TableCellElement()..classes = ['historyExpr'] | 103 new TableCellElement() |
| 106 ..children = [ | 104 ..classes = ['historyExpr'] |
| 107 new ButtonElement()..text = result.expression | 105 ..children = [ |
| 108 ..onClick.listen((_) { | 106 new ButtonElement() |
| 109 _expression = result.expression; | 107 ..text = result.expression |
| 110 _r.dirty(); | 108 ..onClick.listen((_) { |
| 111 }) | 109 _expression = result.expression; |
| 112 ], | 110 _r.dirty(); |
| 113 new TableCellElement()..classes = ['historyValue'] | 111 }) |
| 114 ..children = [ | 112 ], |
| 115 result.isPending | 113 new TableCellElement() |
| 116 ? (new SpanElement()..text = 'Pending...') | 114 ..classes = ['historyValue'] |
| 117 : anyRef(_isolate, result.value, _instances, | 115 ..children = [ |
| 118 queue: _r.queue) | 116 result.isPending |
| 119 ], | 117 ? (new SpanElement()..text = 'Pending...') |
| 120 new TableCellElement()..classes = ['historyDelete'] | 118 : anyRef(_isolate, result.value, _instances, |
| 121 ..children = [ | 119 queue: _r.queue) |
| 122 new ButtonElement()..text = '✖ Remove' | 120 ], |
| 123 ..onClick.listen((_) { | 121 new TableCellElement() |
| 124 _results.remove(result); | 122 ..classes = ['historyDelete'] |
| 125 _r.dirty(); | 123 ..children = [ |
| 126 }) | 124 new ButtonElement() |
| 127 ] | 125 ..text = '✖ Remove' |
| 128 ]).toList() | 126 ..onClick.listen((_) { |
| 127 _results.remove(result); |
| 128 _r.dirty(); |
| 129 }) |
| 130 ] |
| 131 ]) |
| 132 .toList() |
| 129 ]; | 133 ]; |
| 130 } | 134 } |
| 131 | 135 |
| 132 TextInputElement _createEvalTextArea() { | 136 TextInputElement _createEvalTextArea() { |
| 133 var area = new TextAreaElement() | 137 var area = new TextAreaElement() |
| 134 ..classes = ['textbox'] | 138 ..classes = ['textbox'] |
| 135 ..placeholder = 'evaluate an expression' | 139 ..placeholder = 'evaluate an expression' |
| 136 ..value = _expression | 140 ..value = _expression |
| 137 ..onKeyUp | 141 ..onKeyUp.where((e) => e.key == '\n').listen((e) { |
| 138 .where((e) => e.key == '\n') | 142 e.preventDefault(); |
| 139 .listen((e) { | 143 _run(); |
| 140 e.preventDefault(); | 144 }); |
| 141 _run(); | |
| 142 }); | |
| 143 area.onInput.listen((e) { | 145 area.onInput.listen((e) { |
| 144 _expression = area.value; | 146 _expression = area.value; |
| 145 }); | 147 }); |
| 146 return area; | 148 return area; |
| 147 } | 149 } |
| 148 | 150 |
| 149 TextInputElement _createEvalTextBox() { | 151 TextInputElement _createEvalTextBox() { |
| 150 _expression = (_expression ?? '').split('\n')[0]; | 152 _expression = (_expression ?? '').split('\n')[0]; |
| 151 var textbox = new TextInputElement() | 153 var textbox = new TextInputElement() |
| 152 ..classes = ['textbox'] | 154 ..classes = ['textbox'] |
| 153 ..placeholder = 'evaluate an expression' | 155 ..placeholder = 'evaluate an expression' |
| 154 ..value = _expression | 156 ..value = _expression |
| 155 ..onKeyUp | 157 ..onKeyUp.where((e) => e.key == '\n').listen((e) { |
| 156 .where((e) => e.key == '\n') | 158 e.preventDefault(); |
| 157 .listen((e) { | 159 _run(); |
| 158 e.preventDefault(); | 160 }); |
| 159 _run(); | |
| 160 }); | |
| 161 textbox.onInput.listen((e) { | 161 textbox.onInput.listen((e) { |
| 162 _expression = textbox.value; | 162 _expression = textbox.value; |
| 163 }); | 163 }); |
| 164 return textbox; | 164 return textbox; |
| 165 } | 165 } |
| 166 | 166 |
| 167 ButtonElement _createEvalButton() { | 167 ButtonElement _createEvalButton() { |
| 168 final button = new ButtonElement() | 168 final button = new ButtonElement() |
| 169 ..text = 'evaluate' | 169 ..text = 'evaluate' |
| 170 ..onClick.listen((e) { | 170 ..onClick.listen((e) { |
| 171 e.preventDefault(); | 171 e.preventDefault(); |
| 172 _run(); | 172 _run(); |
| 173 }); | 173 }); |
| 174 return button; | 174 return button; |
| 175 } | 175 } |
| 176 | 176 |
| 177 CheckboxInputElement _createMultilineCheckbox() { | 177 CheckboxInputElement _createMultilineCheckbox() { |
| 178 final checkbox = new CheckboxInputElement() | 178 final checkbox = new CheckboxInputElement()..checked = _multiline; |
| 179 ..checked = _multiline; | |
| 180 checkbox.onClick.listen((e) { | 179 checkbox.onClick.listen((e) { |
| 181 e.preventDefault(); | 180 e.preventDefault(); |
| 182 _multiline = checkbox.checked; | 181 _multiline = checkbox.checked; |
| 183 _r.dirty(); | 182 _r.dirty(); |
| 184 }); | 183 }); |
| 185 return checkbox; | 184 return checkbox; |
| 186 } | 185 } |
| 187 | 186 |
| 188 Future _run() async { | 187 Future _run() async { |
| 189 if (_expression == null || _expression.isEmpty) return; | 188 if (_expression == null || _expression.isEmpty) return; |
| 190 final expression = _expression; | 189 final expression = _expression; |
| 191 _expression = null; | 190 _expression = null; |
| 192 final result = new _ExpressionDescription.pending(expression); | 191 final result = new _ExpressionDescription.pending(expression); |
| 193 _results.add(result); | 192 _results.add(result); |
| 194 _r.dirty(); | 193 _r.dirty(); |
| 195 final index = _results.indexOf(result); | 194 final index = _results.indexOf(result); |
| 196 _results[index] = new _ExpressionDescription(expression, | 195 _results[index] = new _ExpressionDescription( |
| 197 await _eval.evaluate(_isolate, _context, expression)); | 196 expression, await _eval.evaluate(_isolate, _context, expression)); |
| 198 _r.dirty(); | 197 _r.dirty(); |
| 199 } | 198 } |
| 200 } | 199 } |
| 201 | 200 |
| 202 class _ExpressionDescription { | 201 class _ExpressionDescription { |
| 203 final String expression; | 202 final String expression; |
| 204 final M.ObjectRef value; | 203 final M.ObjectRef value; |
| 205 bool get isPending => value == null; | 204 bool get isPending => value == null; |
| 206 | 205 |
| 207 _ExpressionDescription(this.expression, this.value); | 206 _ExpressionDescription(this.expression, this.value); |
| 208 _ExpressionDescription.pending(this.expression) | 207 _ExpressionDescription.pending(this.expression) : value = null; |
| 209 : value = null; | |
| 210 } | 208 } |
| OLD | NEW |