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

Unified Diff: runtime/observatory/lib/src/elements/timeline_page.dart

Issue 2299613004: Converted Observatory timeline-page element (Closed)
Patch Set: Reverted change to service Created 4 years, 3 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: runtime/observatory/lib/src/elements/timeline_page.dart
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index 28f3046e7cc77f0dd24ac1bec0fbaab52d533bbf..8e7b3ef144da8c56af6b08bbfc40d16af3c92000 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -5,100 +5,231 @@
library timeline_page_element;
import 'dart:async';
-import 'dart:convert';
import 'dart:html';
-import 'observatory_element.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service_html.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:convert';
+import 'package:observatory/service.dart' as S;
+import 'package:observatory/service_html.dart' as SH;
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+
+enum _Profile {
+ none,
+ dart,
+ vm,
+ all,
+ custom
+}
+class TimelinePageElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<TimelinePageElement>('timeline-page',
+ dependencies: const [
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag
+ ]);
-@CustomTag('timeline-page')
-class TimelinePageElement extends ObservatoryElement {
- TimelinePageElement.created() : super.created() {
+ RenderingScheduler<TimelinePageElement> _r;
+
+ Stream<RenderedEvent<TimelinePageElement>> get onRendered => _r.onRendered;
+
+ M.VM _vm;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ String _recorderName = '';
+ _Profile _profile = _Profile.none;
+ final Set<String> _availableStreams = new Set<String>();
+ final Set<String> _recordedStreams = new Set<String>();
+
+ M.VMRef get vm => _vm;
+ M.NotificationRepository get notifications => _notifications;
+
+ factory TimelinePageElement(M.VM vm, M.EventRepository events,
+ M.NotificationRepository notifications,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(events != null);
+ assert(notifications != null);
+ TimelinePageElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._events = events;
+ e._notifications = notifications;
+ return e;
}
+ TimelinePageElement.created() : super.created();
+
+ @override
attached() {
super.attached();
- _resizeSubscription = window.onResize.listen((_) => _updateSize());
- _updateSize();
+ _r.enable();
_setupInitialState();
}
+ @override
detached() {
super.detached();
- if (_resizeSubscription != null) {
- _resizeSubscription.cancel();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ IFrameElement _frame;
+ DivElement _content;
+
+ void render() {
+ if (_frame == null) {
+ _frame = new IFrameElement()..src = 'timeline.html';
+ }
+ if (_content == null) {
+ _content = new DivElement()..classes = ['content-centered-big'];
+ }
+ _content.children = [
+ new HeadingElement.h1()..text = 'Timeline settings',
+ new DivElement()..classes = ['memberList']
+ ..children = [
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'Recorder:',
+ new DivElement()..classes = ['memberValue']
+ ..text = _recorderName
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'Recorded Streams Profile:',
+ new DivElement()..classes = ['memberValue']
+ ..children = _createProfileSelect()
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'Recorded Streams:',
+ new DivElement()..classes = ['memberValue']
+ ..children =
+ _availableStreams.map(_makeStreamToggle).toList()
+ ]
+ ]
+ ];
+ if (children.isEmpty) {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, last: true, queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ await _refresh();
+ e.element.disabled = false;
+ }),
+ new NavRefreshElement(label: 'clear', queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ await _clear();
+ e.element.disabled = false;
+ }),
+ new NavRefreshElement(label: 'save', queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ await _save();
+ e.element.disabled = false;
+ }),
+ new NavRefreshElement(label: 'load', queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ await _load();
+ e.element.disabled = false;
+ }),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ _content,
+ new DivElement()..classes = ['iframe']
+ ..children = [
+ _frame
+ ]
+ ];
}
}
- Future postMessage(String method) {
- IFrameElement e = $['root'];
- var isolateIds = new List();
- for (var isolate in app.vm.isolates) {
- isolateIds.add(isolate.id);
+ List<Element> _createProfileSelect() {
+ var s;
+ return [
+ s = new SelectElement()..classes = ['direction-select']
+ ..value = _profileToString(_profile)
+ ..children = _Profile.values.map((direction) {
+ return new OptionElement(value: _profileToString(direction),
+ selected: _profile == direction)
+ ..text = _profileToString(direction);
+ }).toList(growable: false)
+ ..onChange.listen((_) {
+ _profile = _Profile.values[s.selectedIndex];
+ _applyPreset();
+ _r.dirty();
+ })
+ ];
+ }
+
+ String _profileToString(_Profile profile) {
+ switch (profile) {
+ case _Profile.none: return 'none';
+ case _Profile.dart: return 'Dart Developer';
+ case _Profile.vm: return 'VM Developer';
+ case _Profile.all: return 'All';
+ case _Profile.custom: return 'Custom';
}
- var message = {
- 'method': method,
- 'params': {
- 'vmAddress': (app.vm as WebSocketVM).target.networkAddress,
- 'isolateIds': isolateIds
- }
- };
- e.contentWindow.postMessage(JSON.encode(message), window.location.href);
- return null;
+ throw new Exception('Unkown Profile ${profile}');
}
- void _processFlags(ServiceMap response) {
- // Grab the recorder name.
- recorderName = response['recorderName'];
- // Update the set of available streams.
- _availableStreams.clear();
- response['availableStreams'].forEach(
- (String streamName) => _availableStreams.add(streamName));
- // Update the set of recorded streams.
- _recordedStreams.clear();
- response['recordedStreams'].forEach(
- (String streamName) => _recordedStreams.add(streamName));
+ Future _refresh() async {
+ S.VM vm = _vm as S.VM;
+ await vm.reload();
+ await vm.reloadIsolates();
+ return _postMessage('refresh');
}
- Future _applyStreamChanges() {
- return app.vm.invokeRpc('_setVMTimelineFlags', {
- 'recordedStreams': '[${_recordedStreams.join(', ')}]',
- });
+ Future _clear() async {
+ S.VM vm = _vm as S.VM;
+ await vm.invokeRpc('_clearVMTimeline', {});
+ return _postMessage('clear');
}
- HtmlElement _makeStreamToggle(String streamName) {
- LabelElement label = new LabelElement();
- label.style.paddingLeft = '8px';
- SpanElement span = new SpanElement();
- span.text = streamName;
- InputElement checkbox = new InputElement();
- checkbox.onChange.listen((_) {
- if (checkbox.checked) {
- _recordedStreams.add(streamName);
- } else {
- _recordedStreams.remove(streamName);
- }
- _applyStreamChanges();
- _updateRecorderUI();
- });
- checkbox.type = 'checkbox';
- checkbox.checked = _recordedStreams.contains(streamName);
- label.children.add(checkbox);
- label.children.add(span);
- return label;
+ Future _save() async {
+ return _postMessage('save');
}
- void _refreshRecorderUI() {
- DivElement e = $['streamList'];
- e.children.clear();
+ Future _load() async {
+ return _postMessage('load');
+ }
- for (String streamName in _availableStreams) {
- e.children.add(_makeStreamToggle(streamName));
+ Future _postMessage(String method) {
+ S.VM vm = _vm as S.VM;
+ var isolateIds = new List();
+ for (var isolate in vm.isolates) {
+ isolateIds.add(isolate.id);
}
+ var message = {
+ 'method': method,
+ 'params': {
+ 'vmAddress': (vm as SH.WebSocketVM).target.networkAddress,
+ 'isolateIds': isolateIds
+ }
+ };
+ _frame.contentWindow.postMessage(JSON.encode(message), window.location.href);
+ return null;
+ }
- streamPresetSelector = streamPresetFromRecordedStreams();
+ Future _setupInitialState() async {
+ await _updateRecorderUI();
+ await _refresh();
}
// Dart developers care about the following streams:
@@ -109,45 +240,24 @@ class TimelinePageElement extends ObservatoryElement {
List<String> _vmPreset =
['GC', 'Compiler', 'Dart', 'Debugger', 'Embedder', 'Isolate', 'VM'];
- String streamPresetFromRecordedStreams() {
- if (_availableStreams.length == 0) {
- return 'None';
- }
- if (_recordedStreams.length == 0) {
- return 'None';
- }
- if (_recordedStreams.length == _availableStreams.length) {
- return 'All';
- }
- if ((_vmPreset.length == _recordedStreams.length) &&
- _recordedStreams.containsAll(_vmPreset)) {
- return 'VM';
- }
- if ((_dartPreset.length == _recordedStreams.length) &&
- _recordedStreams.containsAll(_dartPreset)) {
- return 'Dart';
- }
- return 'Custom';
- }
-
void _applyPreset() {
- switch (streamPresetSelector) {
- case 'None':
+ switch (_profile) {
+ case _Profile.none:
_recordedStreams.clear();
break;
- case 'All':
+ case _Profile.all:
_recordedStreams.clear();
_recordedStreams.addAll(_availableStreams);
break;
- case 'VM':
+ case _Profile.vm:
_recordedStreams.clear();
_recordedStreams.addAll(_vmPreset);
break;
- case 'Dart':
+ case _Profile.dart:
_recordedStreams.clear();
_recordedStreams.addAll(_dartPreset);
break;
- case 'Custom':
+ case _Profile.custom:
return;
}
_applyStreamChanges();
@@ -155,58 +265,56 @@ class TimelinePageElement extends ObservatoryElement {
}
Future _updateRecorderUI() async {
+ S.VM vm = _vm as S.VM;
// Grab the current timeline flags.
- ServiceMap response = await app.vm.invokeRpc('_getVMTimelineFlags', {});
+ S.ServiceMap response = await vm.invokeRpc('_getVMTimelineFlags', {});
assert(response['type'] == 'TimelineFlags');
// Process them so we know available streams.
_processFlags(response);
// Refresh the UI.
- _refreshRecorderUI();
+ _r.dirty();
}
- Future _setupInitialState() async {
- await _updateRecorderUI();
- SelectElement e = $['selectPreset'];
- e.onChange.listen((_) {
- _applyPreset();
+ Element _makeStreamToggle(String streamName) {
+ LabelElement label = new LabelElement();
+ label.style.paddingLeft = '8px';
+ SpanElement span = new SpanElement();
+ span.text = streamName;
+ InputElement checkbox = new InputElement();
+ checkbox.onChange.listen((_) {
+ if (checkbox.checked) {
+ _recordedStreams.add(streamName);
+ } else {
+ _recordedStreams.remove(streamName);
+ }
+ _applyStreamChanges();
+ _updateRecorderUI();
});
- // Finally, trigger a reload so we start with the latest timeline.
- await refresh();
- }
-
- Future refresh() async {
- await app.vm.reload();
- await app.vm.reloadIsolates();
- return postMessage('refresh');
- }
-
- Future clear() async {
- await app.vm.invokeRpc('_clearVMTimeline', {});
- return postMessage('clear');
- }
-
- Future saveTimeline() async {
- return postMessage('save');
+ checkbox.type = 'checkbox';
+ checkbox.checked = _recordedStreams.contains(streamName);
+ label.children.add(checkbox);
+ label.children.add(span);
+ return label;
}
- Future loadTimeline() async {
- return postMessage('load');
+ Future _applyStreamChanges() {
+ S.VM vm = _vm as S.VM;
+ return vm.invokeRpc('_setVMTimelineFlags', {
+ 'recordedStreams': '[${_recordedStreams.join(', ')}]',
+ });
}
- _updateSize() {
- IFrameElement e = $['root'];
- final totalHeight = window.innerHeight;
- final top = e.offset.top;
- final bottomMargin = 32;
- final mainHeight = totalHeight - top - bottomMargin;
- e.style.setProperty('height', '${mainHeight}px');
- e.style.setProperty('width', '100%');
+ void _processFlags(S.ServiceMap response) {
+ // Grab the recorder name.
+ _recorderName = response['recorderName'];
+ // Update the set of available streams.
+ _availableStreams.clear();
+ response['availableStreams'].forEach(
+ (String streamName) => _availableStreams.add(streamName));
+ // Update the set of recorded streams.
+ _recordedStreams.clear();
+ response['recordedStreams'].forEach(
+ (String streamName) => _recordedStreams.add(streamName));
+ _r.dirty();
}
-
-
- StreamSubscription _resizeSubscription;
- @observable String recorderName;
- @observable String streamPresetSelector = 'None';
- final Set<String> _availableStreams = new Set<String>();
- final Set<String> _recordedStreams = new Set<String>();
}
« no previous file with comments | « runtime/observatory/lib/src/elements/css/shared.css ('k') | runtime/observatory/lib/src/elements/timeline_page.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698