| 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 part of app; | 5 part of app; |
| 6 | 6 |
| 7 /// A request response interceptor is called for each response. | 7 /// A [Pane] controls the user interface of Observatory. At any given time |
| 8 typedef void RequestResponseInterceptor(); | 8 /// one pane will be the current pane. Panes are registered at startup. |
| 9 /// When the user navigates within the application, each pane is asked if it |
| 10 /// can handle the current location, the first pane to say yes, wins. |
| 11 abstract class Pane extends Observable { |
| 12 final ObservatoryApplication app; |
| 13 |
| 14 @observable ObservatoryElement element; |
| 15 |
| 16 Pane(this.app); |
| 17 |
| 18 /// Called when the pane is installed, this callback must initialize |
| 19 /// [element]. |
| 20 void onInstall(); |
| 21 |
| 22 /// Called when the pane is uninstalled, this callback must clear |
| 23 /// [element]. |
| 24 void onUninstall() { |
| 25 element = null; |
| 26 } |
| 27 |
| 28 /// Called when the pane should update its state based on [url]. |
| 29 /// NOTE: Only called when the pane is installed. |
| 30 void visit(String url); |
| 31 |
| 32 /// Called to test whether this pane can visit [url]. |
| 33 bool canVisit(String url); |
| 34 } |
| 35 |
| 36 /// A general service object viewer. |
| 37 class ServiceObjectPane extends Pane { |
| 38 ServiceObjectPane(app) : super(app); |
| 39 |
| 40 void onInstall() { |
| 41 if (element == null) { |
| 42 /// Lazily create pane. |
| 43 element = new Element.tag('service-view'); |
| 44 } |
| 45 } |
| 46 |
| 47 void visit(String url) { |
| 48 assert(element != null); |
| 49 assert(canVisit(url)); |
| 50 /// Request url from VM and display it. |
| 51 app.vm.get(url).then((obj) { |
| 52 ServiceObjectViewElement pane = element; |
| 53 pane.object = obj; |
| 54 }); |
| 55 } |
| 56 |
| 57 /// Catch all. |
| 58 bool canVisit(String url) => true; |
| 59 } |
| 60 |
| 61 /// Class tree pane. |
| 62 class ClassTreePane extends Pane { |
| 63 static const _urlPrefix = 'class-tree/'; |
| 64 |
| 65 ClassTreePane(app) : super(app); |
| 66 |
| 67 void onInstall() { |
| 68 if (element == null) { |
| 69 element = new Element.tag('class-tree'); |
| 70 } |
| 71 } |
| 72 |
| 73 void visit(String url) { |
| 74 assert(element != null); |
| 75 assert(canVisit(url)); |
| 76 // ClassTree urls are 'class-tree/isolate-id', chop off prefix, leaving |
| 77 // isolate url. |
| 78 url = url.substring(_urlPrefix.length); |
| 79 /// Request the isolate url. |
| 80 app.vm.get(url).then((i) { |
| 81 if (element != null) { |
| 82 /// Update the pane. |
| 83 ClassTreeElement pane = element; |
| 84 pane.isolate = i; |
| 85 } |
| 86 }); |
| 87 } |
| 88 |
| 89 /// Catch all. |
| 90 bool canVisit(String url) => url.startsWith(_urlPrefix); |
| 91 } |
| 92 |
| 93 class ErrorViewPane extends Pane { |
| 94 ErrorViewPane(app) : super(app); |
| 95 |
| 96 void onInstall() { |
| 97 if (element == null) { |
| 98 /// Lazily create pane. |
| 99 element = new Element.tag('service-view'); |
| 100 } |
| 101 } |
| 102 |
| 103 void visit(String url) { |
| 104 assert(element != null); |
| 105 assert(canVisit(url)); |
| 106 (element as ServiceObjectViewElement).object = app.lastErrorOrException; |
| 107 } |
| 108 |
| 109 bool canVisit(String url) => url.startsWith('error/'); |
| 110 } |
| 9 | 111 |
| 10 /// The observatory application. Instances of this are created and owned | 112 /// The observatory application. Instances of this are created and owned |
| 11 /// by the observatory_application custom element. | 113 /// by the observatory_application custom element. |
| 12 class ObservatoryApplication extends Observable { | 114 class ObservatoryApplication extends Observable { |
| 115 final _paneRegistry = new List<Pane>(); |
| 116 ServiceObjectPane _serviceObjectPane; |
| 117 Pane _currentPane; |
| 13 @observable final LocationManager locationManager; | 118 @observable final LocationManager locationManager; |
| 14 @observable final VM vm; | 119 @observable final VM vm; |
| 15 @observable Isolate isolate; | 120 @observable Isolate isolate; |
| 16 | 121 @reflectable final ObservatoryApplicationElement rootElement; |
| 17 /// The current [ServiceObject] being viewed by the application. | 122 |
| 18 @observable ServiceObject response; | 123 @reflectable ServiceObject lastErrorOrException; |
| 19 | 124 |
| 20 /// Any client-level arguments for viewing the current response. | 125 /// Any client-level arguments for viewing the current response. |
| 21 @observable String args; | 126 @observable String args; |
| 22 // TODO(turnidge): Make args a Map. | 127 // TODO(turnidge): Make args a Map. |
| 23 | 128 |
| 24 void _initOnce() { | 129 void _initOnce() { |
| 25 // Only called once. | 130 _registerPanes(); |
| 26 assert(locationManager._app == null); | |
| 27 locationManager._app = this; | |
| 28 locationManager.init(); | |
| 29 vm.errors.stream.listen(_onError); | 131 vm.errors.stream.listen(_onError); |
| 30 vm.exceptions.stream.listen(_onException); | 132 vm.exceptions.stream.listen(_onException); |
| 133 location = locationManager; |
| 134 locationManager._init(this); |
| 135 } |
| 136 |
| 137 void _registerPanes() { |
| 138 if (_serviceObjectPane != null) { |
| 139 // Already done. |
| 140 return; |
| 141 } |
| 142 // Register ClassTreePane. |
| 143 _paneRegistry.add(new ClassTreePane(this)); |
| 144 _paneRegistry.add(new ErrorViewPane(this)); |
| 145 // Note that ServiceObjectPane must be the last entry in the list as it is |
| 146 // the catch all. |
| 147 _serviceObjectPane = new ServiceObjectPane(this); |
| 148 _paneRegistry.add(_serviceObjectPane); |
| 31 } | 149 } |
| 32 | 150 |
| 33 void _onError(ServiceError error) { | 151 void _onError(ServiceError error) { |
| 34 response = error; | 152 lastErrorOrException = error; |
| 35 // No id, clear the hash. | 153 _visit('error/'); |
| 36 locationManager.clearCurrentHash(); | |
| 37 } | 154 } |
| 38 | 155 |
| 39 void _onException(ServiceException exception) { | 156 void _onException(ServiceException exception) { |
| 40 response = exception; | 157 lastErrorOrException = exception; |
| 41 // No id, clear the hash. | 158 _visit('error/'); |
| 42 locationManager.clearCurrentHash(); | 159 } |
| 43 } | 160 |
| 44 | 161 void _visit(String url) { |
| 45 ObservatoryApplication.devtools() : | 162 for (var i = 0; i < _paneRegistry.length; i++) { |
| 46 locationManager = new LocationManager(), | 163 var pane = _paneRegistry[i]; |
| 164 if (pane.canVisit(url)) { |
| 165 _installPane(pane); |
| 166 pane.visit(url); |
| 167 return; |
| 168 } |
| 169 } |
| 170 throw new FallThroughError(); |
| 171 } |
| 172 |
| 173 /// Set the Observatory application pane. |
| 174 void _installPane(Pane pane) { |
| 175 assert(pane != null); |
| 176 print('Installing $pane'); |
| 177 if (_currentPane == pane) { |
| 178 // Already isntalled. |
| 179 return; |
| 180 } |
| 181 if (_currentPane != null) { |
| 182 _currentPane.onUninstall(); |
| 183 } |
| 184 pane.onInstall(); |
| 185 // Clear children. |
| 186 rootElement.children.clear(); |
| 187 // Add new pane. |
| 188 rootElement.children.add(pane.element); |
| 189 // Remember pane. |
| 190 _currentPane = pane; |
| 191 } |
| 192 |
| 193 ObservatoryApplication.devtools(this.rootElement) : |
| 194 locationManager = new HashLocationManager(), |
| 47 vm = new DartiumVM() { | 195 vm = new DartiumVM() { |
| 48 _initOnce(); | 196 _initOnce(); |
| 49 } | 197 } |
| 50 | 198 |
| 51 ObservatoryApplication() : | 199 ObservatoryApplication(this.rootElement) : |
| 52 locationManager = new LocationManager(), | 200 locationManager = new HashLocationManager(), |
| 53 vm = new WebSocketVM() { | 201 vm = new HttpVM() { |
| 54 _initOnce(); | 202 _initOnce(); |
| 55 } | 203 } |
| 56 } | 204 } |
| 205 |
| 206 LocationManager location; |
| OLD | NEW |