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

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

Issue 2212253002: Converted Observatory class-tree element (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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/class_tree.dart
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 16f6928fbd72a7b193f0445f2b021e5909b929b9..cb927b272e16b5aa9106a0093ab1035e36f64d92 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -4,14 +4,193 @@
library class_tree_element;
-import 'observatory_element.dart';
-import 'dart:async';
import 'dart:html';
-import 'package:logging/logging.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/containers/virtual_tree.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+
+
+class ClassTreeElement extends HtmlElement implements Renderable{
+ static const tag = const Tag<ClassTreeElement>('class-tree',
+ dependencies: const [ClassRefElement.tag,
+ NavBarElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavNotifyElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag]);
+
+ RenderingScheduler _r;
+
+ Stream<RenderedEvent<ClassTreeElement>> get onRendered => _r.onRendered;
+
+ M.VMRef _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.ClassRepository _classes;
+ M.InstanceRepository _instances;
+ M.Class _object;
+ final _subclasses = <String, Iterable<M.Class>>{};
+ final _mixins = <String, List<M.Class>>{};
+
+ factory ClassTreeElement(M.VMRef vm, M.IsolateRef isolate,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.ClassRepository classes,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(classes != null);
+ assert(instances != null);
+ ClassTreeElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._classes = classes;
+ e._instances = instances;
+ return e;
+ }
+
+ ClassTreeElement.created() : super.created();
+
+ @override
+ void attached() {
+ super.attached();
+ _refresh();
+ _r.enable();
+ }
+
+ @override
+ void detached() {
+ super.detached();
+ children = [];
+ _r.disable(notify: true);
+ }
+
+ VirtualTreeElement _tree;
+
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavMenuElement('class hierarchy', link: Uris.classTree(_isolate),
+ last: true, queue: _r.queue),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()
+ ..classes = ['content-centered']
+ ..children = [
+ new HeadingElement.h1()..text = 'Class Hierarchy',
+ new BRElement(), new HRElement(),
+ _object == null ? (new HeadingElement.h2()..text = 'Loading...')
+ : _createTree()
+ ]
+ ];
+ }
+
+ Element _createTree() {
+ _tree = new VirtualTreeElement(_create, _update, _children,
+ items: [_object], queue: _r.queue);
+ _tree.expand(_object, autoExpandWholeTree: true);
+ return _tree;
+ }
+
+ Future _refresh() async {
+ _object = null;
+ _subclasses.clear();
+ _mixins.clear();
+ _object = await _register(await _classes.getObject());
+ _r.dirty();
+ }
+ Future<M.Class> _register(M.Class cls) async {
+ _subclasses[cls.id] = await Future.wait(
+ (await Future.wait(cls.subclasses.map(_getActualChildrens)))
+ .expand((f) => f)
+ .map(_register)
+ );
+ return cls;
+ }
+
+ Future<Iterable<M.Class>> _getActualChildrens(M.ClassRef ref) async {
+ var cls = await _classes.get(ref.id);
+ if (cls.isPatch) {
+ return const [];
+ }
+ if (cls.mixin == null) {
+ return [cls];
+ }
+ var mixin = await _instances.get(cls.mixin.id);
+ return (await Future.wait(cls.subclasses.map(_getActualChildrens)))
+ .expand((f) => f)
+ ..forEach((subcls) {
+ // non canonical type.
+ if (mixin.typeClass == null) {
+ return;
+ }
+ _mixins[subcls.id] = (_mixins[subcls.id] ?? [])..add(mixin.typeClass);
+ });
+ }
+
+ static Element _create(toggle) {
+ return new DivElement()..classes = ['class-tree-item']
+ ..children = [
+ new SpanElement()..classes = ['lines'],
+ new SpanElement()..classes = ['expander']
+ ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+ new SpanElement()..classes = ['name']
+ ];
+ }
+
+ void _update(HtmlElement el, M.Class cls, int index) {
+ virtualTreeUpdateLines(el.children[0], index);
+ if (cls.subclasses.isEmpty) {
+ el.children[1].text = '';
+ } else {
+ el.children[1].text = _tree.isExpanded(cls) ? '▼' : '►';
+ }
+ el.children[2].children = [
+ new ClassRefElement(_isolate, cls, queue: _r.queue)
+ ];
+ if (_mixins[cls.id] != null) {
+ el.children[2].children.addAll(_createMixins(_mixins[cls.id]));
+ }
+ }
+
+ List<Element> _createMixins(List<M.Class> classes) {
+ final children = classes.expand((cls) => [
+ new SpanElement()..text = ', ',
+ new ClassRefElement(_isolate, cls, queue: _r.queue)
+ ]).toList();
+ children.first.text = ' width ';
+ return children;
+ }
+
+ Iterable<M.Class> _children(M.Class cls) {
+ return _subclasses[cls.id];
+ }
+}
+
+/*
Cutch 2016/08/05 13:23:18 remove deleted code
cbernaschina 2016/08/05 17:16:46 Done.
class ClassTreeRow extends TableTreeRow {
@reflectable final Isolate isolate;
@reflectable final Class cls;
@@ -151,3 +330,45 @@ class ClassTreeElement extends ObservatoryElement {
notifyPropertyChange(#tree, null, tree);
}
}
+*/
+
+/*
+<polymer-element name="class-tree">
+ <template>
+ <link rel="stylesheet" href="css/shared.css">
+ <style>
+ .table {
+ border-spacing: 0px;
+ width: 100%;
+ margin-bottom: 20px
+ vertical-align: middle;
+ }
+
+ tr {
+ background-color: #FFFFFF;
+ }
+
+ tr:hover {
+ background-color: #FAFAFA;
+ }
+
+ th {
+ text-align: left;
+ }
+ </style>
+ <nav-bar>
+ <top-nav-menu></top-nav-menu>
+ <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
+ <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
+ <nav-menu link="{{ makeLink('/class-tree', isolate) }}" anchor="class hierarchy" last="{{ true }}"></nav-menu>
+ <nav-notify notifications="{{ app.notifications }}"></nav-notify>
+ </nav-bar>
+ <div class="content-centered">
+ <h1>Class Hierarchy</h1>
+ <table id="tableTree" class="table">
+ <tbody id="tableTreeBody"></tbody>
+ </table>
+ </div>
+ </template>
+</polymer-element>
+ */

Powered by Google App Engine
This is Rietveld 408576698