Chromium Code Reviews| 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 class_tree_element; | 5 library class_tree_element; |
| 6 | 6 |
| 7 import 'observatory_element.dart'; | 7 import 'dart:html'; |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:html'; | 9 import 'package:observatory/models.dart' as M; |
| 10 import 'package:logging/logging.dart'; | 10 import 'package:observatory/src/elements/class_ref.dart'; |
| 11 import 'package:observatory/app.dart'; | 11 import 'package:observatory/src/elements/containers/virtual_tree.dart'; |
| 12 import 'package:observatory/service.dart'; | 12 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| 13 import 'package:polymer/polymer.dart'; | 13 import 'package:observatory/src/elements/helpers/tag.dart'; |
| 14 import 'package:observatory/src/elements/helpers/uris.dart'; | |
| 15 import 'package:observatory/src/elements/nav/bar.dart'; | |
| 16 import 'package:observatory/src/elements/nav/isolate_menu.dart'; | |
| 17 import 'package:observatory/src/elements/nav/menu.dart'; | |
| 18 import 'package:observatory/src/elements/nav/notify.dart'; | |
| 19 import 'package:observatory/src/elements/nav/top_menu.dart'; | |
| 20 import 'package:observatory/src/elements/nav/vm_menu.dart'; | |
| 14 | 21 |
| 22 | |
| 23 class ClassTreeElement extends HtmlElement implements Renderable{ | |
| 24 static const tag = const Tag<ClassTreeElement>('class-tree', | |
| 25 dependencies: const [ClassRefElement.tag, | |
| 26 NavBarElement.tag, | |
| 27 NavIsolateMenuElement.tag, | |
| 28 NavMenuElement.tag, | |
| 29 NavNotifyElement.tag, | |
| 30 NavTopMenuElement.tag, | |
| 31 NavVMMenuElement.tag]); | |
| 32 | |
| 33 RenderingScheduler _r; | |
| 34 | |
| 35 Stream<RenderedEvent<ClassTreeElement>> get onRendered => _r.onRendered; | |
| 36 | |
| 37 M.VMRef _vm; | |
| 38 M.IsolateRef _isolate; | |
| 39 M.EventRepository _events; | |
| 40 M.NotificationRepository _notifications; | |
| 41 M.ClassRepository _classes; | |
| 42 M.InstanceRepository _instances; | |
| 43 M.Class _object; | |
| 44 final _subclasses = <String, Iterable<M.Class>>{}; | |
| 45 final _mixins = <String, List<M.Class>>{}; | |
| 46 | |
| 47 factory ClassTreeElement(M.VMRef vm, M.IsolateRef isolate, | |
| 48 M.EventRepository events, | |
| 49 M.NotificationRepository notifications, | |
| 50 M.ClassRepository classes, | |
| 51 M.InstanceRepository instances, | |
| 52 {RenderingQueue queue}) { | |
| 53 assert(vm != null); | |
| 54 assert(isolate != null); | |
| 55 assert(events != null); | |
| 56 assert(notifications != null); | |
| 57 assert(classes != null); | |
| 58 assert(instances != null); | |
| 59 ClassTreeElement e = document.createElement(tag.name); | |
| 60 e._r = new RenderingScheduler(e, queue: queue); | |
| 61 e._vm = vm; | |
| 62 e._isolate = isolate; | |
| 63 e._events = events; | |
| 64 e._notifications = notifications; | |
| 65 e._classes = classes; | |
| 66 e._instances = instances; | |
| 67 return e; | |
| 68 } | |
| 69 | |
| 70 ClassTreeElement.created() : super.created(); | |
| 71 | |
| 72 @override | |
| 73 void attached() { | |
| 74 super.attached(); | |
| 75 _refresh(); | |
| 76 _r.enable(); | |
| 77 } | |
| 78 | |
| 79 @override | |
| 80 void detached() { | |
| 81 super.detached(); | |
| 82 children = []; | |
| 83 _r.disable(notify: true); | |
| 84 } | |
| 85 | |
| 86 VirtualTreeElement _tree; | |
| 87 | |
| 88 void render() { | |
| 89 children = [ | |
| 90 new NavBarElement(queue: _r.queue) | |
| 91 ..children = [ | |
| 92 new NavTopMenuElement(queue: _r.queue), | |
| 93 new NavVMMenuElement(_vm, _events, queue: _r.queue), | |
| 94 new NavIsolateMenuElement(_isolate, _events, queue: _r.queue), | |
| 95 new NavMenuElement('class hierarchy', link: Uris.classTree(_isolate), | |
| 96 last: true, queue: _r.queue), | |
| 97 new NavNotifyElement(_notifications, queue: _r.queue) | |
| 98 ], | |
| 99 new DivElement() | |
| 100 ..classes = ['content-centered'] | |
| 101 ..children = [ | |
| 102 new HeadingElement.h1()..text = 'Class Hierarchy', | |
| 103 new BRElement(), new HRElement(), | |
| 104 _object == null ? (new HeadingElement.h2()..text = 'Loading...') | |
| 105 : _createTree() | |
| 106 ] | |
| 107 ]; | |
| 108 } | |
| 109 | |
| 110 Element _createTree() { | |
| 111 _tree = new VirtualTreeElement(_create, _update, _children, | |
| 112 items: [_object], queue: _r.queue); | |
| 113 _tree.expand(_object, autoExpandWholeTree: true); | |
| 114 return _tree; | |
| 115 } | |
| 116 | |
| 117 Future _refresh() async { | |
| 118 _object = null; | |
| 119 _subclasses.clear(); | |
| 120 _mixins.clear(); | |
| 121 _object = await _register(await _classes.getObject()); | |
| 122 _r.dirty(); | |
| 123 } | |
| 124 | |
| 125 Future<M.Class> _register(M.Class cls) async { | |
| 126 _subclasses[cls.id] = await Future.wait( | |
| 127 (await Future.wait(cls.subclasses.map(_getActualChildrens))) | |
| 128 .expand((f) => f) | |
| 129 .map(_register) | |
| 130 ); | |
| 131 return cls; | |
| 132 } | |
| 133 | |
| 134 Future<Iterable<M.Class>> _getActualChildrens(M.ClassRef ref) async { | |
| 135 var cls = await _classes.get(ref.id); | |
| 136 if (cls.isPatch) { | |
| 137 return const []; | |
| 138 } | |
| 139 if (cls.mixin == null) { | |
| 140 return [cls]; | |
| 141 } | |
| 142 var mixin = await _instances.get(cls.mixin.id); | |
| 143 return (await Future.wait(cls.subclasses.map(_getActualChildrens))) | |
| 144 .expand((f) => f) | |
| 145 ..forEach((subcls) { | |
| 146 // non canonical type. | |
| 147 if (mixin.typeClass == null) { | |
| 148 return; | |
| 149 } | |
| 150 _mixins[subcls.id] = (_mixins[subcls.id] ?? [])..add(mixin.typeClass); | |
| 151 }); | |
| 152 } | |
| 153 | |
| 154 static Element _create(toggle) { | |
| 155 return new DivElement()..classes = ['class-tree-item'] | |
| 156 ..children = [ | |
| 157 new SpanElement()..classes = ['lines'], | |
| 158 new SpanElement()..classes = ['expander'] | |
| 159 ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)), | |
| 160 new SpanElement()..classes = ['name'] | |
| 161 ]; | |
| 162 } | |
| 163 | |
| 164 void _update(HtmlElement el, M.Class cls, int index) { | |
| 165 virtualTreeUpdateLines(el.children[0], index); | |
| 166 if (cls.subclasses.isEmpty) { | |
| 167 el.children[1].text = ''; | |
| 168 } else { | |
| 169 el.children[1].text = _tree.isExpanded(cls) ? '▼' : '►'; | |
| 170 } | |
| 171 el.children[2].children = [ | |
| 172 new ClassRefElement(_isolate, cls, queue: _r.queue) | |
| 173 ]; | |
| 174 if (_mixins[cls.id] != null) { | |
| 175 el.children[2].children.addAll(_createMixins(_mixins[cls.id])); | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 List<Element> _createMixins(List<M.Class> classes) { | |
| 180 final children = classes.expand((cls) => [ | |
| 181 new SpanElement()..text = ', ', | |
| 182 new ClassRefElement(_isolate, cls, queue: _r.queue) | |
| 183 ]).toList(); | |
| 184 children.first.text = ' width '; | |
| 185 return children; | |
| 186 } | |
| 187 | |
| 188 Iterable<M.Class> _children(M.Class cls) { | |
| 189 return _subclasses[cls.id]; | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 /* | |
|
Cutch
2016/08/05 13:23:18
remove deleted code
cbernaschina
2016/08/05 17:16:46
Done.
| |
| 15 class ClassTreeRow extends TableTreeRow { | 194 class ClassTreeRow extends TableTreeRow { |
| 16 @reflectable final Isolate isolate; | 195 @reflectable final Isolate isolate; |
| 17 @reflectable final Class cls; | 196 @reflectable final Class cls; |
| 18 ClassTreeRow(this.isolate, this.cls, TableTree tree, ClassTreeRow parent) | 197 ClassTreeRow(this.isolate, this.cls, TableTree tree, ClassTreeRow parent) |
| 19 : super(tree, parent) { | 198 : super(tree, parent) { |
| 20 assert(isolate != null); | 199 assert(isolate != null); |
| 21 assert(cls != null); | 200 assert(cls != null); |
| 22 } | 201 } |
| 23 | 202 |
| 24 void _addChildren(List<Class> subclasses) { | 203 void _addChildren(List<Class> subclasses) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 } catch (e, stackTrace) { | 323 } catch (e, stackTrace) { |
| 145 Logger.root.warning('_update', e, stackTrace); | 324 Logger.root.warning('_update', e, stackTrace); |
| 146 } | 325 } |
| 147 // Check if we only have one node at the root and expand it. | 326 // Check if we only have one node at the root and expand it. |
| 148 if (tree.rows.length == 1) { | 327 if (tree.rows.length == 1) { |
| 149 tree.toggle(tree.rows[0]); | 328 tree.toggle(tree.rows[0]); |
| 150 } | 329 } |
| 151 notifyPropertyChange(#tree, null, tree); | 330 notifyPropertyChange(#tree, null, tree); |
| 152 } | 331 } |
| 153 } | 332 } |
| 333 */ | |
| 334 | |
| 335 /* | |
| 336 <polymer-element name="class-tree"> | |
| 337 <template> | |
| 338 <link rel="stylesheet" href="css/shared.css"> | |
| 339 <style> | |
| 340 .table { | |
| 341 border-spacing: 0px; | |
| 342 width: 100%; | |
| 343 margin-bottom: 20px | |
| 344 vertical-align: middle; | |
| 345 } | |
| 346 | |
| 347 tr { | |
| 348 background-color: #FFFFFF; | |
| 349 } | |
| 350 | |
| 351 tr:hover { | |
| 352 background-color: #FAFAFA; | |
| 353 } | |
| 354 | |
| 355 th { | |
| 356 text-align: left; | |
| 357 } | |
| 358 </style> | |
| 359 <nav-bar> | |
| 360 <top-nav-menu></top-nav-menu> | |
| 361 <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu> | |
| 362 <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu> | |
| 363 <nav-menu link="{{ makeLink('/class-tree', isolate) }}" anchor="class hier archy" last="{{ true }}"></nav-menu> | |
| 364 <nav-notify notifications="{{ app.notifications }}"></nav-notify> | |
| 365 </nav-bar> | |
| 366 <div class="content-centered"> | |
| 367 <h1>Class Hierarchy</h1> | |
| 368 <table id="tableTree" class="table"> | |
| 369 <tbody id="tableTreeBody"></tbody> | |
| 370 </table> | |
| 371 </div> | |
| 372 </template> | |
| 373 </polymer-element> | |
| 374 */ | |
| OLD | NEW |