| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 vm_connect_element; | 5 library vm_connect_element; |
| 6 | 6 |
| 7 import 'dart:html'; | 7 import 'dart:html'; |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'package:observatory/models.dart' as M; | 10 import 'package:observatory/models.dart' as M; |
| 11 import 'package:observatory/app.dart'; | 11 import 'package:observatory/app.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/helpers/rendering_scheduler.dart'; | 13 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| 14 import 'package:observatory/src/elements/helpers/nav_bar.dart'; | 14 import 'package:observatory/src/elements/helpers/nav_bar.dart'; |
| 15 import 'package:observatory/src/elements/nav/notify.dart'; | 15 import 'package:observatory/src/elements/nav/notify.dart'; |
| 16 import 'package:observatory/src/elements/nav/top_menu.dart'; | 16 import 'package:observatory/src/elements/nav/top_menu.dart'; |
| 17 import 'package:observatory/src/elements/view_footer.dart'; | 17 import 'package:observatory/src/elements/view_footer.dart'; |
| 18 import 'package:observatory/src/elements/vm_connect_target.dart'; | 18 import 'package:observatory/src/elements/vm_connect_target.dart'; |
| 19 | 19 |
| 20 typedef void CrashDumpLoadCallback(Map dump); | 20 typedef void CrashDumpLoadCallback(Map dump); |
| 21 | 21 |
| 22 class VMConnectElement extends HtmlElement implements Renderable { | 22 class VMConnectElement extends HtmlElement implements Renderable { |
| 23 static const tag = const Tag<VMConnectElement>('vm-connect', | 23 static const tag = |
| 24 dependencies: const [NavTopMenuElement.tag, | 24 const Tag<VMConnectElement>('vm-connect', dependencies: const [ |
| 25 NavNotifyElement.tag, | 25 NavTopMenuElement.tag, |
| 26 ViewFooterElement.tag, | 26 NavNotifyElement.tag, |
| 27 VMConnectTargetElement.tag]); | 27 ViewFooterElement.tag, |
| 28 VMConnectTargetElement.tag |
| 29 ]); |
| 28 | 30 |
| 29 RenderingScheduler _r; | 31 RenderingScheduler _r; |
| 30 | 32 |
| 31 Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered; | 33 Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered; |
| 32 | 34 |
| 33 CrashDumpLoadCallback _loadDump; | 35 CrashDumpLoadCallback _loadDump; |
| 34 M.NotificationRepository _notifications; | 36 M.NotificationRepository _notifications; |
| 35 M.TargetRepository _targets; | 37 M.TargetRepository _targets; |
| 36 StreamSubscription _targetsSubscription; | 38 StreamSubscription _targetsSubscription; |
| 37 | 39 |
| 38 String _address; | 40 String _address; |
| 39 | 41 |
| 40 factory VMConnectElement(M.TargetRepository targets, | 42 factory VMConnectElement(M.TargetRepository targets, |
| 41 CrashDumpLoadCallback loadDump, | 43 CrashDumpLoadCallback loadDump, M.NotificationRepository notifications, |
| 42 M.NotificationRepository notifications, | 44 {String address: '', RenderingQueue queue}) { |
| 43 {String address: '', RenderingQueue queue}) { | |
| 44 assert(address != null); | 45 assert(address != null); |
| 45 assert(loadDump != null); | 46 assert(loadDump != null); |
| 46 assert(notifications != null); | 47 assert(notifications != null); |
| 47 assert(targets != null); | 48 assert(targets != null); |
| 48 VMConnectElement e = document.createElement(tag.name); | 49 VMConnectElement e = document.createElement(tag.name); |
| 49 e._r = new RenderingScheduler(e, queue: queue); | 50 e._r = new RenderingScheduler(e, queue: queue); |
| 50 e._address = address; | 51 e._address = address; |
| 51 e._loadDump = loadDump; | 52 e._loadDump = loadDump; |
| 52 e._notifications = notifications; | 53 e._notifications = notifications; |
| 53 e._targets = targets; | 54 e._targets = targets; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 76 final port = window.location.port; | 77 final port = window.location.port; |
| 77 children = [ | 78 children = [ |
| 78 navBar([ | 79 navBar([ |
| 79 new NavTopMenuElement(queue: _r.queue), | 80 new NavTopMenuElement(queue: _r.queue), |
| 80 new NavNotifyElement(_notifications, queue: _r.queue) | 81 new NavNotifyElement(_notifications, queue: _r.queue) |
| 81 ]), | 82 ]), |
| 82 new DivElement() | 83 new DivElement() |
| 83 ..classes = ['content-centered'] | 84 ..classes = ['content-centered'] |
| 84 ..children = [ | 85 ..children = [ |
| 85 new HeadingElement.h1()..text = 'Connect to a Dart VM', | 86 new HeadingElement.h1()..text = 'Connect to a Dart VM', |
| 86 new BRElement(), new HRElement(), | 87 new BRElement(), |
| 88 new HRElement(), |
| 87 new DivElement() | 89 new DivElement() |
| 88 ..classes = ['flex-row'] | 90 ..classes = ['flex-row'] |
| 89 ..children = [ | 91 ..children = [ |
| 90 new DivElement() | 92 new DivElement() |
| 91 ..classes = ['flex-item-40-percent'] | 93 ..classes = ['flex-item-40-percent'] |
| 92 ..children = [ | 94 ..children = [ |
| 93 new HeadingElement.h2()..text = 'WebSocket', | 95 new HeadingElement.h2()..text = 'WebSocket', |
| 94 new BRElement(), | 96 new BRElement(), |
| 95 new UListElement() | 97 new UListElement() |
| 96 ..children = _targets.list().map((target) { | 98 ..children = _targets.list().map((target) { |
| 97 final ObservatoryApplication app = | 99 final ObservatoryApplication app = |
| 98 ObservatoryApplication.app; | 100 ObservatoryApplication.app; |
| 99 final bool current = app.isConnectedVMTarget(target); | 101 final bool current = app.isConnectedVMTarget(target); |
| 100 return new LIElement() | 102 return new LIElement() |
| 101 ..children = [new VMConnectTargetElement(target, | 103 ..children = [ |
| 102 current: current, queue: _r.queue) | 104 new VMConnectTargetElement(target, |
| 103 ..onConnect.listen(_connect) | 105 current: current, queue: _r.queue) |
| 104 ..onDelete.listen(_delete) | 106 ..onConnect.listen(_connect) |
| 107 ..onDelete.listen(_delete) |
| 105 ]; | 108 ]; |
| 106 }).toList(), | 109 }).toList(), |
| 107 new HRElement(), | 110 new HRElement(), |
| 108 new FormElement() | 111 new FormElement() |
| 109 ..autocomplete = 'on' | 112 ..autocomplete = 'on' |
| 110 ..children = [ | 113 ..children = [ |
| 111 _createAddressBox(), | 114 _createAddressBox(), |
| 112 new SpanElement()..text = ' ', | 115 new SpanElement()..text = ' ', |
| 113 new ButtonElement() | 116 new ButtonElement() |
| 114 ..classes = ['vm_connect'] | 117 ..classes = ['vm_connect'] |
| 115 ..text = 'Connect' | 118 ..text = 'Connect' |
| 116 ..onClick.listen((e) { | 119 ..onClick.listen((e) { |
| 117 e.preventDefault(); _create(); }), | 120 e.preventDefault(); |
| 121 _create(); |
| 122 }), |
| 118 ], | 123 ], |
| 119 new BRElement(), | 124 new BRElement(), |
| 120 new PreElement() | 125 new PreElement() |
| 121 ..classes = ['well'] | 126 ..classes = ['well'] |
| 122 ..text = 'Run Standalone with: \'--observe\'', | 127 ..text = 'Run Standalone with: \'--observe\'', |
| 123 new HRElement() | 128 new HRElement() |
| 124 ], | 129 ], |
| 125 new DivElement() | 130 new DivElement()..classes = ['flex-item-20-percent'], |
| 126 ..classes = ['flex-item-20-percent'], | |
| 127 new DivElement() | 131 new DivElement() |
| 128 ..classes = ['flex-item-40-percent'] | 132 ..classes = ['flex-item-40-percent'] |
| 129 ..children = [ | 133 ..children = [ |
| 130 new HeadingElement.h2()..text = 'Crash dump', | 134 new HeadingElement.h2()..text = 'Crash dump', |
| 131 new BRElement(), | 135 new BRElement(), |
| 132 _createCrushDumpLoader(), | 136 _createCrushDumpLoader(), |
| 133 new BRElement(), new BRElement(), | 137 new BRElement(), |
| 138 new BRElement(), |
| 134 new PreElement() | 139 new PreElement() |
| 135 ..classes = ['well'] | 140 ..classes = ['well'] |
| 136 ..text = 'Request a crash dump with:\n' | 141 ..text = 'Request a crash dump with:\n' |
| 137 '\'curl $host:$port/_getCrashDump > dump.json\'', | 142 '\'curl $host:$port/_getCrashDump > dump.json\'', |
| 138 new HRElement() | 143 new HRElement() |
| 139 ] | 144 ] |
| 140 ], | 145 ], |
| 141 ], | 146 ], |
| 142 new ViewFooterElement(queue: _r.queue) | 147 new ViewFooterElement(queue: _r.queue) |
| 143 ]; | 148 ]; |
| 144 } | 149 } |
| 145 | 150 |
| 146 TextInputElement _createAddressBox() { | 151 TextInputElement _createAddressBox() { |
| 147 var textbox = new TextInputElement() | 152 var textbox = new TextInputElement() |
| 148 ..classes = ['textbox'] | 153 ..classes = ['textbox'] |
| 149 ..placeholder = 'localhost:8181' | 154 ..placeholder = 'localhost:8181' |
| 150 ..value = _address | 155 ..value = _address |
| 151 ..onKeyUp | 156 ..onKeyUp.where((e) => e.key == '\n').listen((e) { |
| 152 .where((e) => e.key == '\n') | 157 e.preventDefault(); |
| 153 .listen((e) { e.preventDefault(); _create(); }); | 158 _create(); |
| 159 }); |
| 154 textbox.onInput.listen((e) { | 160 textbox.onInput.listen((e) { |
| 155 _address = textbox.value; | 161 _address = textbox.value; |
| 156 }); | 162 }); |
| 157 return textbox; | 163 return textbox; |
| 158 } | 164 } |
| 159 | 165 |
| 160 FileUploadInputElement _createCrushDumpLoader() { | 166 FileUploadInputElement _createCrushDumpLoader() { |
| 161 FileUploadInputElement e = new FileUploadInputElement() | 167 FileUploadInputElement e = new FileUploadInputElement() |
| 162 ..id = 'crashDumpFile'; | 168 ..id = 'crashDumpFile'; |
| 163 e.onChange.listen((_) { | 169 e.onChange.listen((_) { |
| 164 var reader = new FileReader(); | 170 var reader = new FileReader(); |
| 165 reader.readAsText(e.files[0]); | 171 reader.readAsText(e.files[0]); |
| 166 reader.onLoad.listen((_) { | 172 reader.onLoad.listen((_) { |
| 167 var crashDump = JSON.decode(reader.result); | 173 var crashDump = JSON.decode(reader.result); |
| 168 _loadDump(crashDump); | 174 _loadDump(crashDump); |
| 169 }); | 175 }); |
| 170 }); | 176 }); |
| 171 return e; | 177 return e; |
| 172 } | 178 } |
| 179 |
| 173 void _create() { | 180 void _create() { |
| 174 if (_address == null || _address.isEmpty) return; | 181 if (_address == null || _address.isEmpty) return; |
| 175 _targets.add(_normalizeStandaloneAddress(_address)); | 182 _targets.add(_normalizeStandaloneAddress(_address)); |
| 176 } | 183 } |
| 184 |
| 177 void _connect(TargetEvent e) { | 185 void _connect(TargetEvent e) { |
| 178 _targets.setCurrent(e.target); | 186 _targets.setCurrent(e.target); |
| 179 } | 187 } |
| 188 |
| 180 void _delete(TargetEvent e) => _targets.delete(e.target); | 189 void _delete(TargetEvent e) => _targets.delete(e.target); |
| 181 | 190 |
| 182 static String _normalizeStandaloneAddress(String networkAddress) { | 191 static String _normalizeStandaloneAddress(String networkAddress) { |
| 183 if (!networkAddress.startsWith('http') && !networkAddress.startsWith('ws'))
{ | 192 if (!networkAddress.startsWith('http') && |
| 193 !networkAddress.startsWith('ws')) { |
| 184 networkAddress = 'http://$networkAddress'; | 194 networkAddress = 'http://$networkAddress'; |
| 185 } | 195 } |
| 186 try { | 196 try { |
| 187 Uri uri = Uri.parse(networkAddress); | 197 Uri uri = Uri.parse(networkAddress); |
| 188 print('returning ${uri.host} ${uri.port}'); | 198 print('returning ${uri.host} ${uri.port}'); |
| 189 return 'ws://${uri.host}:${uri.port}/ws'; | 199 return 'ws://${uri.host}:${uri.port}/ws'; |
| 190 } catch (e) { | 200 } catch (e) { |
| 191 print('caught exception with: $networkAddress -- $e'); | 201 print('caught exception with: $networkAddress -- $e'); |
| 192 return networkAddress; | 202 return networkAddress; |
| 193 } | 203 } |
| 194 } | 204 } |
| 195 } | 205 } |
| OLD | NEW |