Converted Observatory nav-notify element

Still writing tests.

R=johnmccutchan@google.com, rmacnak@google.com

Review URL: https://codereview.chromium.org/2167053002 .
This commit is contained in:
Carlo Bernaschina
2016-07-24 12:54:04 -07:00
parent 5923966da3
commit 61e34b244b
106 changed files with 2093 additions and 533 deletions
+4
View File
@@ -12,6 +12,9 @@ import 'dart:math' as math;
import 'package:logging/logging.dart';
import 'package:observatory/service_html.dart';
import 'package:observatory/elements.dart';
import 'package:observatory/mocks.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/repositories.dart';
import 'package:observatory/tracer.dart';
import 'package:observatory/utils.dart';
import 'package:polymer/polymer.dart';
@@ -21,6 +24,7 @@ export 'package:observatory/utils.dart';
part 'src/app/application.dart';
part 'src/app/location_manager.dart';
part 'src/app/notification.dart';
part 'src/app/page.dart';
part 'src/app/settings.dart';
part 'src/app/target_manager.dart';
+16 -5
View File
@@ -63,14 +63,18 @@ import 'dart:async';
import 'package:observatory/src/elements/curly_block.dart';
import 'package:observatory/src/elements/curly_block_wrapper.dart';
import 'package:observatory/src/elements/nav/bar.dart';
import 'package:observatory/src/elements/nav/isolate_menu.dart';
import 'package:observatory/src/elements/nav/isolate_menu_wrapper.dart';
import 'package:observatory/src/elements/nav/class_menu.dart';
import 'package:observatory/src/elements/nav/class_menu_wrapper.dart';
import 'package:observatory/src/elements/nav/isolate_menu.dart';
import 'package:observatory/src/elements/nav/isolate_menu_wrapper.dart';
import 'package:observatory/src/elements/nav/menu.dart';
import 'package:observatory/src/elements/nav/menu_wrapper.dart';
import 'package:observatory/src/elements/nav/menu_item.dart';
import 'package:observatory/src/elements/nav/menu_item_wrapper.dart';
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/nav/notify_wrapper.dart';
import 'package:observatory/src/elements/nav/notify_event.dart';
import 'package:observatory/src/elements/nav/notify_exception.dart';
import 'package:observatory/src/elements/nav/refresh.dart';
import 'package:observatory/src/elements/nav/refresh_wrapper.dart';
import 'package:observatory/src/elements/nav/top_menu.dart';
@@ -85,10 +89,13 @@ export 'package:observatory/src/elements/helpers/rendering_queue.dart';
export 'package:observatory/src/elements/curly_block.dart';
export 'package:observatory/src/elements/nav/bar.dart';
export 'package:observatory/src/elements/nav/isolate_menu.dart';
export 'package:observatory/src/elements/nav/class_menu.dart';
export 'package:observatory/src/elements/nav/isolate_menu.dart';
export 'package:observatory/src/elements/nav/menu.dart';
export 'package:observatory/src/elements/nav/menu_item.dart';
export 'package:observatory/src/elements/nav/notify.dart';
export 'package:observatory/src/elements/nav/notify_event.dart';
export 'package:observatory/src/elements/nav/notify_exception.dart';
export 'package:observatory/src/elements/nav/refresh.dart';
export 'package:observatory/src/elements/nav/top_menu.dart';
export 'package:observatory/src/elements/nav/vm_menu.dart';
@@ -101,14 +108,18 @@ Future initElements() async {
CurlyBlockElement.tag.ensureRegistration();
CurlyBlockElementWrapper.tag.ensureRegistration();
NavBarElement.tag.ensureRegistration();
NavIsolateMenuElement.tag.ensureRegistration();
NavIsolateMenuElementWrapper.tag.ensureRegistration();
NavClassMenuElement.tag.ensureRegistration();
NavClassMenuElementWrapper.tag.ensureRegistration();
NavIsolateMenuElement.tag.ensureRegistration();
NavIsolateMenuElementWrapper.tag.ensureRegistration();
NavMenuElement.tag.ensureRegistration();
NavMenuElementWrapper.tag.ensureRegistration();
NavMenuItemElement.tag.ensureRegistration();
NavMenuItemElementWrapper.tag.ensureRegistration();
NavNotifyElement.tag.ensureRegistration();
NavNotifyElementWrapper.tag.ensureRegistration();
NavNotifyEventElement.tag.ensureRegistration();
NavNotifyExceptionElement.tag.ensureRegistration();
NavRefreshElement.tag.ensureRegistration();
NavRefreshElementWrapper.tag.ensureRegistration();
NavTopMenuElement.tag.ensureRegistration();
-1
View File
@@ -37,7 +37,6 @@
<link rel="import" href="src/elements/objectpool_view.html">
<link rel="import" href="src/elements/objectstore_view.html">
<link rel="import" href="src/elements/observatory_application.html">
<link rel="import" href="src/elements/observatory_element.html">
<link rel="import" href="src/elements/persistent_handles.html">
<link rel="import" href="src/elements/ports.html">
<link rel="import" href="src/elements/script_inset.html">
+10
View File
@@ -4,10 +4,20 @@
library mocks;
import 'dart:async';
import 'package:observatory/models.dart' as M;
part 'src/mocks/exceptions/connection_exception.dart';
part 'src/mocks/objects/error.dart';
part 'src/mocks/objects/event.dart';
part 'src/mocks/objects/class.dart';
part 'src/mocks/objects/isolate.dart';
part 'src/mocks/objects/notification.dart';
part 'src/mocks/objects/script.dart';
part 'src/mocks/objects/source_location.dart';
part 'src/mocks/objects/target.dart';
part 'src/mocks/objects/vm.dart';
part 'src/mocks/repositories/notification.dart';
+17 -1
View File
@@ -4,9 +4,25 @@
library models;
part 'src/models/objects/event.dart';
import 'dart:async';
part 'src/models/exceptions.dart';
part 'src/models/objects/class.dart';
part 'src/models/objects/breakpoint.dart';
part 'src/models/objects/error.dart';
part 'src/models/objects/event.dart';
part 'src/models/objects/extension_data.dart';
part 'src/models/objects/frame.dart';
part 'src/models/objects/instance.dart';
part 'src/models/objects/isolate.dart';
part 'src/models/objects/library.dart';
part 'src/models/objects/notification.dart';
part 'src/models/objects/object.dart';
part 'src/models/objects/script.dart';
part 'src/models/objects/source_location.dart';
part 'src/models/objects/target.dart';
part 'src/models/objects/timeline_event.dart';
part 'src/models/objects/vm.dart';
part 'src/models/repositories/notification.dart';
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library repositories;
import 'dart:async';
import 'package:observatory/models.dart' as M;
part 'src/repositories/notification.dart';
@@ -4,20 +4,12 @@
part of app;
class Notification {
Notification.fromEvent(this.event);
Notification.fromException(this.exception, this.stacktrace);
ServiceEvent event;
var exception;
var stacktrace;
}
/// The observatory application. Instances of this are created and owned
/// by the observatory_application custom element.
class ObservatoryApplication extends Observable {
static ObservatoryApplication app;
final RenderingQueue queue = new RenderingQueue();
final NotificationRepository notifications = new NotificationRepository();
final _pageRegistry = new List<Page>();
LocationManager _locationManager;
LocationManager get locationManager => _locationManager;
@@ -32,7 +24,7 @@ class ObservatoryApplication extends Observable {
}
if (_vm != null) {
// Disconnect from current VM.
notifications.clear();
notifications.deleteAll();
_vm.disconnect();
}
if (vm != null) {
@@ -42,7 +34,7 @@ class ObservatoryApplication extends Observable {
if (vm is WebSocketVM) {
targets.add(vm.target);
}
_removeDisconnectEvents();
notifications.deleteDisconnectEvents();
});
vm.onDisconnect.then((String reason) {
@@ -51,8 +43,8 @@ class ObservatoryApplication extends Observable {
return;
}
notifications.add(
new Notification.fromEvent(
new ServiceEvent.connectionClosed(reason)));
new EventNotification.fromServiceEvent(
new ServiceEvent.connectionClosed(reason)));
});
vm.listenEventStream(VM.kIsolateStream, _onEvent);
@@ -66,8 +58,6 @@ class ObservatoryApplication extends Observable {
TraceViewElement _traceView = null;
@reflectable ServiceObject lastErrorOrException;
@observable ObservableList<Notification> notifications =
new ObservableList<Notification>();
void _initOnce() {
assert(app == null);
@@ -78,15 +68,6 @@ class ObservatoryApplication extends Observable {
locationManager._visit();
}
void removePauseEvents(Isolate isolate) {
notifications.removeWhere((notification) {
var event = notification.event;
return (event != null &&
event.isolate == isolate &&
event.isPauseEvent);
});
}
void _onEvent(ServiceEvent event) {
assert(event.kind != ServiceEvent.kNone);
@@ -103,12 +84,12 @@ class ObservatoryApplication extends Observable {
break;
case ServiceEvent.kIsolateReload:
notifications.add(new Notification.fromEvent(event));
notifications.add(new EventNotification.fromServiceEvent(event));
break;
case ServiceEvent.kIsolateExit:
case ServiceEvent.kResume:
removePauseEvents(event.isolate);
notifications.deletePauseEvents(isolate: event.isolate);
break;
case ServiceEvent.kPauseStart:
@@ -116,12 +97,12 @@ class ObservatoryApplication extends Observable {
case ServiceEvent.kPauseBreakpoint:
case ServiceEvent.kPauseInterrupted:
case ServiceEvent.kPauseException:
removePauseEvents(event.isolate);
notifications.add(new Notification.fromEvent(event));
notifications.deletePauseEvents(isolate: event.isolate);
notifications.add(new EventNotification.fromServiceEvent(event));
break;
case ServiceEvent.kInspect:
notifications.add(new Notification.fromEvent(event));
notifications.add(new EventNotification.fromServiceEvent(event));
break;
default:
@@ -220,14 +201,6 @@ class ObservatoryApplication extends Observable {
_initOnce();
}
void _removeDisconnectEvents() {
notifications.removeWhere((notification) {
var event = notification.event;
return (event != null &&
event.kind == ServiceEvent.kConnectionClosed);
});
}
loadCrashDump(Map crashDump) {
this.vm = new FakeVM(crashDump['result']);
app.locationManager.go('#/vm');
@@ -243,7 +216,7 @@ class ObservatoryApplication extends Observable {
// TODO(turnidge): Report this failure via analytics.
Logger.root.warning('Caught exception: ${e}\n${st}');
notifications.add(new Notification.fromException(e, st));
notifications.add(new ExceptionNotification(e, stacktrace: st));
}
// This map keeps track of which curly-blocks have been expanded by the user.
@@ -54,6 +54,11 @@ class LocationManager extends Observable {
/// Update the application location. After this function returns,
/// [uri] and [debugArguments] will be updated.
_updateApplicationLocation(String url) {
if (url == makeLink('/vm-connect')) {
// When we go to the vm-connect page, drop all notifications.
_app.notifications.deleteAll();
}
// Chop off leading '#'.
if (url.startsWith('#')) {
url = url.substring(1);
@@ -115,11 +120,6 @@ class LocationManager extends Observable {
url = makeLink('/vm-connect');
}
if (url == makeLink('/vm-connect')) {
// When we go to the vm-connect page, drop all notifications.
_app.notifications.clear();
}
if (addToBrowserHistory) {
_addToBrowserHistory(url);
}
@@ -0,0 +1,115 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of app;
class ExceptionNotification implements M.ExceptionNotification {
final Exception exception;
/// [optional]
final StackTrace stacktrace;
ExceptionNotification(this.exception, {this.stacktrace});
}
class EventNotification implements M.EventNotification {
final M.Event event;
EventNotification(this.event);
factory EventNotification.fromServiceEvent(ServiceEvent event) {
M.Event e;
switch(event.kind) {
case ServiceEvent.kVMUpdate:
e = new VMUpdateEventMock(timestamp: event.timestamp, vm: event.vm);
break;
case ServiceEvent.kIsolateStart:
e = new IsolateStartEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kIsolateRunnable:
e = new IsolateRunnableEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kIsolateExit:
e = new IsolateExitEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kIsolateUpdate:
e = new IsolateUpdateEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kIsolateReload:
// TODO(bernaschina) add error: realoadError.
e = new IsolateRealodEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kServiceExtensionAdded:
e = new ServiceExtensionAddedEventMock(timestamp: event.timestamp,
isolate: event.isolate, extensionRPC: event.extensionRPC);
break;
case ServiceEvent.kPauseStart:
e = new PauseStartEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kPauseExit:
e = new PauseExitEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kPauseBreakpoint:
// TODO(cbernaschina) add pauseBreakpoints.
e = new PauseBreakpointEventMock(timestamp: event.timestamp,
isolate: event.isolate, breakpoint: event.breakpoint,
pauseBreakpoints: const <M.Breakpoint>[],
topFrame: event.topFrame,
atAsyncSuspension: event.atAsyncSuspension);
break;
case ServiceEvent.kPauseInterrupted:
e = new PauseInterruptedEventMock(timestamp: event.timestamp,
isolate: event.isolate, topFrame: event.topFrame,
atAsyncSuspension: event.atAsyncSuspension);
break;
case ServiceEvent.kPauseException:
// TODO(cbernaschina) add exception.
e = new PauseExceptionEventMock(timestamp: event.timestamp,
isolate: event.isolate, topFrame: event.topFrame);
break;
case ServiceEvent.kNone:
e = new NoneEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kResume:
e = new ResumeEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kBreakpointAdded:
e = new BreakpointAddedEventMock(timestamp: event.timestamp,
isolate: event.isolate, breakpoint: event.breakpoint);
break;
case ServiceEvent.kBreakpointResolved:
e = new BreakpointResolvedEventMock(timestamp: event.timestamp,
isolate: event.isolate, breakpoint: event.breakpoint);
break;
case ServiceEvent.kBreakpointRemoved:
e = new BreakpointRemovedEventMock(timestamp: event.timestamp,
isolate: event.isolate, breakpoint: event.breakpoint);
break;
case ServiceEvent.kGC:
e = new GCEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kInspect:
// TODO(cbernaschina) add inspectee: event.inspectee.
e = new InspectEventMock(timestamp: event.timestamp,
isolate: event.isolate);
break;
case ServiceEvent.kConnectionClosed:
e = new ConnectionClockedEventMock(timestamp: event.timestamp,
reason: event.reason);
break;
case ServiceEvent.kExtension:
e = new ExtensionEventMock(timestamp: event.timestamp,
isolate: event.isolate, extensionKind: event.extensionKind,
extensionData: event.extensionData);
break;
}
return new EventNotification(e);
}
}
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="action-link" extends="observatory-element">
<polymer-element name="action-link">
<template>
<style>
.idle {
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="class-ref" extends="service-ref">
<polymer-element name="class-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="class_ref.html">
<polymer-element name="class-tree" extends="observatory-element">
<polymer-element name="class-tree">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -8,11 +8,11 @@
<link rel="import" href="instance_ref.html">
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
<polymer-element name="class-view" extends="observatory-element">
<polymer-element name="class-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,7 +1,7 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="service_ref.html">
<polymer-element name="code-ref" extends="service-ref">
<polymer-element name="code-ref">
<template><link rel="stylesheet" href="css/shared.css"></template>
</polymer-element>
@@ -1,11 +1,11 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="script_ref.html">
<polymer-element name="code-view" extends="observatory-element">
<polymer-element name="code-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="context-ref" extends="service-ref">
<polymer-element name="context-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<span>
@@ -3,12 +3,12 @@
<link rel="import" href="field_ref.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="object_common.html">
<link rel="import" href="context_ref.html">
<polymer-element name="context-view" extends="observatory-element">
<polymer-element name="context-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -2,10 +2,10 @@
<link rel="import" href="code_ref.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="sliding_checkbox.html">
<polymer-element name="sample-buffer-control" extends="observatory-element">
<polymer-element name="sample-buffer-control">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -114,7 +114,7 @@
</template>
</polymer-element>
<polymer-element name="stack-trace-tree-config" extends="observatory-element">
<polymer-element name="stack-trace-tree-config">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -181,7 +181,7 @@
</template>
</polymer-element>
<polymer-element name="cpu-profile-tree" extends="observatory-element">
<polymer-element name="cpu-profile-tree">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -253,7 +253,7 @@
</template>
</polymer-element>
<polymer-element name="cpu-profile-virtual-tree" extends="observatory-element">
<polymer-element name="cpu-profile-virtual-tree">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -276,7 +276,7 @@
</polymer-element>
<polymer-element name="cpu-profile-table" extends="observatory-element">
<polymer-element name="cpu-profile-table">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -491,7 +491,7 @@
</template>
</polymer-element>
<polymer-element name="cpu-profile" extends="observatory-element">
<polymer-element name="cpu-profile">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -359,6 +359,81 @@ body.busy, body.busy * {
-webkit-animation: shake 0.5s;
}
/* nav-notify */
/* TODO(cbernaschina) fix nav-notify-ref-wrapped to nav-notify-ref when wrapper
removed */
nav-notify-wrapped > div {
float: right;
}
nav-notify-wrapped > div > div {
display: block;
position: absolute;
top: 98%;
right: 0;
margin: 0;
padding: 0;
width: auto;
z-index: 1000;
background: none;
}
/* nav-exception & nav-event */
nav-exception > div, nav-event > div {
position: relative;
padding: 16px;
margin-top: 10px;
margin-right: 10px;
padding-right: 25px;
width: 500px;
color: #ddd;
background: rgba(0,0,0,.6);
border: solid 2px white;
box-shadow: 0 0 5px black;
border-radius: 5px;
animation: fadein 1s;
}
nav-exception *, nav-event * {
color: #ddd;
font-size: 12px;
}
nav-exception > div > a, nav-event > div > a {
color: white;
text-decoration: none;
}
nav-exception > div > a:hover, nav-event > div > a:hover {
text-decoration: underline;
}
nav-exception > div > div {
margin-left:20px;
white-space: pre
}
nav-exception > div > button, nav-event > div > button {
background: transparent;
border: none;
position: absolute;
display: block;
top: 4px;
right: 4px;
height: 18px;
width: 18px;
line-height: 16px;
border-radius: 9px;
color: white;
font-size: 18px;
cursor: pointer;
text-align: center;
}
nav-exception > div > button:hover, nav-event > div > button:hover {
background: rgba(255,255,255,0.5);
}
/* nav-refresh */
/* TODO(cbernaschina) fix nav-refresh-wrapped to nav-refresh when wrapper
removed */
@@ -2,7 +2,7 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
@@ -72,7 +72,7 @@
</template>
</polymer-element>
<polymer-element name="debugger-page" extends="observatory-element">
<polymer-element name="debugger-page">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -134,7 +134,7 @@
</template>
</polymer-element>
<polymer-element name="debugger-stack" extends="observatory-element">
<polymer-element name="debugger-stack">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -185,7 +185,7 @@
</polymer-element>
<polymer-element name="debugger-frame" extends="observatory-element">
<polymer-element name="debugger-frame">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -301,7 +301,7 @@
</template>
</polymer-element>
<polymer-element name="debugger-message" extends="observatory-element">
<polymer-element name="debugger-message">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -406,7 +406,7 @@
</template>
</polymer-element>
<polymer-element name="debugger-console" extends="observatory-element">
<polymer-element name="debugger-console">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -445,7 +445,7 @@
</template>
</polymer-element>
<polymer-element name="debugger-input" extends="observatory-element">
<polymer-element name="debugger-input">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="error-ref" extends="service-ref">
<polymer-element name="error-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="error-view" extends="observatory-element">
<polymer-element name="error-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="error_ref.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="eval-box" extends="observatory-element">
<polymer-element name="eval-box">
<template>
<style>
.textbox {
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="error_ref.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="eval-link" extends="observatory-element">
<polymer-element name="eval-link">
<template>
<style>
.idle {
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="field-ref" extends="service-ref">
<polymer-element name="field-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<span>
@@ -4,9 +4,9 @@
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="script_ref.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="field-view" extends="observatory-element">
<polymer-element name="field-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="flag-list" extends="observatory-element">
<polymer-element name="flag-list">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -40,7 +40,7 @@
</template>
</polymer-element>
<polymer-element name="flag-item" extends="observatory-element">
<polymer-element name="flag-item">
<template>
<link rel="stylesheet" href="css/shared.css">
<span style="color:#aaa">// {{ flag['comment'] }}</span>
@@ -2,7 +2,7 @@
<link rel="import" href="class_ref.html">
<link rel="import" href="service_ref.html">
<polymer-element name="function-ref" extends="service-ref">
<polymer-element name="function-ref">
<template><link rel="stylesheet" href="css/shared.css"></template>
</polymer-element>
@@ -3,12 +3,12 @@
<link rel="import" href="code_ref.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="library_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
<polymer-element name="function-view" extends="observatory-element">
<polymer-element name="function-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="general-error" extends="observatory-element">
<polymer-element name="general-error">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="class_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<polymer-element name="heap-map" extends="observatory-element">
<polymer-element name="heap-map">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="class_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<polymer-element name="heap-profile" extends="observatory-element">
<polymer-element name="heap-profile">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="class_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<polymer-element name="heap-snapshot" extends="observatory-element">
<polymer-element name="heap-snapshot">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -5,12 +5,12 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="object_common.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<polymer-element name="icdata-view" extends="observatory-element">
<polymer-element name="icdata-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="field_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="inbound-reference" extends="service-ref">
<polymer-element name="inbound-reference">
<template>
<link rel="stylesheet" href="css/shared.css">
<div>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="instance-ref" extends="service-ref">
<polymer-element name="instance-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -7,12 +7,12 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="object_common.html">
<link rel="import" href="context_ref.html">
<polymer-element name="instance-view" extends="observatory-element">
<polymer-element name="instance-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -5,12 +5,12 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="object_common.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<polymer-element name="instructions-view" extends="observatory-element">
<polymer-element name="instructions-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="io-view" extends="observatory-element">
<polymer-element name="io-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -62,7 +62,7 @@
</template>
</polymer-element>
<polymer-element name="io-ref" extends="service-ref">
<polymer-element name="io-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<template if="{{ ref.type == 'Socket' }}">
@@ -83,7 +83,7 @@
</template>
</polymer-element>
<polymer-element name="io-http-server-list-view" extends="observatory-element">
<polymer-element name="io-http-server-list-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -111,14 +111,14 @@
</template>
</polymer-element>
<polymer-element name="io-http-server-ref" extends="service-ref">
<polymer-element name="io-http-server-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
</template>
</polymer-element>
<polymer-element name="io-http-server-view" extends="observatory-element">
<polymer-element name="io-http-server-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -173,14 +173,14 @@
</template>
</polymer-element>
<polymer-element name="io-http-server-connection-ref" extends="service-ref">
<polymer-element name="io-http-server-connection-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<a _href="{{ url }}">{{ name }}</a>
</template>
</polymer-element>
<polymer-element name="io-http-server-connection-view" extends="observatory-element">
<polymer-element name="io-http-server-connection-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -215,14 +215,14 @@
</template>
</polymer-element>
<polymer-element name="io-socket-ref" extends="service-ref">
<polymer-element name="io-socket-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
</template>
</polymer-element>
<polymer-element name="io-socket-list-view" extends="observatory-element">
<polymer-element name="io-socket-list-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -250,7 +250,7 @@
</template>
</polymer-element>
<polymer-element name="io-socket-view" extends="observatory-element">
<polymer-element name="io-socket-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -346,14 +346,14 @@
</template>
</polymer-element>
<polymer-element name="io-web-socket-ref" extends="service-ref">
<polymer-element name="io-web-socket-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
</template>
</polymer-element>
<polymer-element name="io-web-socket-list-view" extends="observatory-element">
<polymer-element name="io-web-socket-list-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -381,7 +381,7 @@
</template>
</polymer-element>
<polymer-element name="io-web-socket-view" extends="observatory-element">
<polymer-element name="io-web-socket-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -408,14 +408,14 @@
</template>
</polymer-element>
<polymer-element name="io-random-access-file-ref" extends="service-ref">
<polymer-element name="io-random-access-file-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
</template>
</polymer-element>
<polymer-element name="io-random-access-file-list-view" extends="observatory-element">
<polymer-element name="io-random-access-file-list-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -443,7 +443,7 @@
</template>
</polymer-element>
<polymer-element name="io-random-access-file-view" extends="observatory-element">
<polymer-element name="io-random-access-file-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -478,7 +478,7 @@
</template>
</polymer-element>
<polymer-element name="io-process-list-view" extends="observatory-element">
<polymer-element name="io-process-list-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -506,7 +506,7 @@
</template>
</polymer-element>
<polymer-element name="io-process-ref" extends="service-ref">
<polymer-element name="io-process-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<template if="{{ small }}">
@@ -518,7 +518,7 @@
</template>
</polymer-element>
<polymer-element name="io-process-view" extends="observatory-element">
<polymer-element name="io-process-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="isolate-reconnect" extends="observatory-element">
<polymer-element name="isolate-reconnect">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,6 +1,6 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="service_ref.html">
<polymer-element name="isolate-ref" extends="service-ref">
<polymer-element name="isolate-ref">
<template><link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" _href="{{ url }}">Isolate {{ ref.number }} ({{ ref.name }})</a>
</template>
@@ -2,10 +2,10 @@
<link rel="import" href="action_link.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="isolate_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
<polymer-element name="isolate-summary" extends="observatory-element">
<polymer-element name="isolate-summary">
<template>
<link rel="stylesheet" href="css/shared.css">
<div class="flex-row">
@@ -24,7 +24,7 @@
</template>
</polymer-element>
<polymer-element name="isolate-run-state" extends="observatory-element">
<polymer-element name="isolate-run-state">
<template>
<template if="{{ isolate.paused }}">
<strong title="{{ isolate.pauseEvent.timestamp.toString() }}">paused</strong>
@@ -44,7 +44,7 @@
</template>
</polymer-element>
<polymer-element name="isolate-location" extends="observatory-element">
<polymer-element name="isolate-location">
<template>
<template if="{{ isolate.pauseEvent != null }}">
<template if="{{ isolate.pauseEvent.kind == 'PauseStart' }}">
@@ -88,7 +88,7 @@
</template>
</polymer-element>
<polymer-element name="isolate-shared-summary" extends="observatory-element">
<polymer-element name="isolate-shared-summary">
<template>
<style>
.errorBox {
@@ -201,7 +201,7 @@
</template>
</polymer-element>
<polymer-element name="isolate-counter-chart" extends="observatory-element">
<polymer-element name="isolate-counter-chart">
<template>
<link rel="stylesheet" href="../../../../packages/charted/charts/themes/quantum_theme.css">
<style>
@@ -5,11 +5,11 @@
<link rel="import" href="isolate_summary.html">
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
<polymer-element name="isolate-view" extends="observatory-element">
<polymer-element name="isolate-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,7 +1,7 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="json-view" extends="observatory-element">
<polymer-element name="json-view">
<template>
<nav-bar>
<top-nav-menu last="{{ true }}"></top-nav-menu>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="library-ref" extends="service-ref">
<polymer-element name="library-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -4,12 +4,12 @@
<link rel="import" href="field_ref.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="script_ref.html">
<polymer-element name="library-view" extends="observatory-element">
<polymer-element name="library-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -2,10 +2,10 @@
<link rel="import" href="code_ref.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="sliding_checkbox.html">
<polymer-element name="logging-page" extends="observatory-element">
<polymer-element name="logging-page">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -5,12 +5,12 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="object_common.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<polymer-element name="megamorphiccache-view" extends="observatory-element">
<polymer-element name="megamorphiccache-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="metrics-page" extends="observatory-element">
<polymer-element name="metrics-page">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -66,7 +66,7 @@
</template>
</polymer-element>
<polymer-element name="metric-details" extends="observatory-element">
<polymer-element name="metric-details">
<template>
<link rel="stylesheet" href="css/shared.css">
<div class="content-centered">
@@ -125,7 +125,7 @@
</template>
</polymer-element>
<polymer-element name="metrics-graph" extends="observatory-element">
<polymer-element name="metrics-graph">
<template>
<link rel="stylesheet" href="css/shared.css">
<link rel="stylesheet" href="../../../../packages/charted/charts/themes/quantum_theme.css">
@@ -0,0 +1,90 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'dart:async';
import 'package:observatory/models.dart' as M;
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/nav/notify_event.dart';
import 'package:observatory/src/elements/nav/notify_exception.dart';
class NavNotifyElement extends HtmlElement implements Renderable {
static const tag = const Tag<NavNotifyElement>('nav-notify-wrapped',
dependencies: const [ NavNotifyEventElement.tag,
NavNotifyExceptionElement.tag ]);
RenderingScheduler _r;
Stream<RenderedEvent<NavNotifyElement>> get onRendered => _r.onRendered;
M.NotificationRepository _repository;
StreamSubscription _subscription;
bool _notifyOnPause;
bool get notifyOnPause => _notifyOnPause;
set notifyOnPause(bool value) =>
_notifyOnPause = _r.checkAndReact(_notifyOnPause, value);
factory NavNotifyElement(M.NotificationRepository repository,
{bool notifyOnPause: true, RenderingQueue queue}) {
assert(repository != null);
assert(notifyOnPause != null);
NavNotifyElement e = document.createElement(tag.name);
e._r = new RenderingScheduler(e, queue: queue);
e._repository = repository;
e._notifyOnPause = notifyOnPause;
return e;
}
NavNotifyElement.created() : super.created();
@override
void attached() {
super.attached();
_r.enable();
_subscription = _repository.onChange.listen((_) => _r.dirty());
}
@override
void detached() {
super.detached();
children = [];
_r.disable(notify: true);
_subscription.cancel();
}
void render() {
children = [
new DivElement()
..children = [
new DivElement()
..children = _repository.list()
.where(_filter).map(_toElement).toList()
]
];
}
bool _filter(M.Notification notification) {
if (!_notifyOnPause && notification is M.EventNotification) {
return !M.Event.isPauseEvent(notification.event);
}
return true;
}
HtmlElement _toElement(M.Notification notification) {
if (notification is M.EventNotification) {
return new NavNotifyEventElement(notification.event, queue: _r.queue)
..onDelete.listen((_) => _repository.delete(notification));
} else if (notification is M.ExceptionNotification) {
return new NavNotifyExceptionElement(
notification.exception, stacktrace: notification.stacktrace,
queue: _r.queue)
..onDelete.listen((_) => _repository.delete(notification));
} else {
assert(false);
return new DivElement()..text = 'Invalid Notification Type';
}
}
}
@@ -0,0 +1,232 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'dart:async';
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/helpers/uris.dart';
class EventDeleteEvent{
final M.Event event;
EventDeleteEvent(this.event);
}
class NavNotifyEventElement extends HtmlElement implements Renderable {
static const tag = const Tag<NavNotifyEventElement>('nav-event');
RenderingScheduler _r;
Stream<RenderedEvent<NavNotifyEventElement>> get onRendered => _r.onRendered;
final StreamController<EventDeleteEvent> _onDelete =
new StreamController<EventDeleteEvent>.broadcast();
Stream<EventDeleteEvent> get onDelete => _onDelete.stream;
M.Event _event;
M.Event get event => _event;
factory NavNotifyEventElement(M.Event event, {RenderingQueue queue}) {
assert(event != null);
NavNotifyEventElement e = document.createElement(tag.name);
e._r = new RenderingScheduler(e, queue: queue);
e._event = event;
return e;
}
NavNotifyEventElement.created() : super.created();
@override
void attached() {
super.attached();
_r.enable();
}
@override
void detached() {
super.detached();
children = [];
_r.disable(notify: true);
}
void render() {
children = [];
List<Element> content;
if (event is M.PauseStartEvent) {
content = _managePauseStartEvent(event as M.PauseStartEvent);
} else if (event is M.PauseExitEvent) {
content = _managePauseExitEvent(event as M.PauseExitEvent);
} else if (event is M.PauseBreakpointEvent) {
content = _managePauseBreakpointEvent(event as M.PauseBreakpointEvent);
} else if (event is M.PauseInterruptedEvent) {
content = _managePauseInterruptedEvent(event as M.PauseInterruptedEvent);
} else if (event is M.PauseExceptionEvent) {
content = _managePauseExceptionEvent(event as M.PauseExceptionEvent);
} else if (event is M.NoneEvent) {
content = _manageNoneEvent(event as M.NoneEvent);
} else if (event is M.ConnectionClosedEvent) {
content = _manageConnectionClosedEvent(event as M.ConnectionClosedEvent);
} else if (event is M.InspectEvent) {
content = _manageInspectEvent(event as M.InspectEvent);
} else if (event is M.IsolateReloadEvent) {
content = _manageIsolateReloadEvent(event as M.IsolateReloadEvent);
} else {
return;
}
children = [
new DivElement()
..children = []
..children.addAll(content)
..children.add(new ButtonElement()..innerHtml = '&times;'
..onClick.map(_toEvent).listen(_delete))
];
}
static List<Element> _managePauseStartEvent(M.PauseStartEvent event) {
return [
new SpanElement()..text = 'Isolate ',
new AnchorElement(
href: Uris.inspect(event.isolate))
..text = event.isolate.name,
new SpanElement()..text = ' is paused at isolate start',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(
href: Uris.debugger(event.isolate))
..text = 'debug',
new SpanElement()..text = ']'
];
}
static List<Element> _managePauseExitEvent(M.PauseExitEvent event) {
return [
new SpanElement()..text = 'Isolate ',
new AnchorElement(
href: Uris.inspect(event.isolate))
..text = event.isolate.name,
new SpanElement()..text = ' is paused at isolate exit',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(
href: Uris.debugger(event.isolate))
..text = 'debug',
new SpanElement()..text = ']'
];
}
static List<Element> _managePauseBreakpointEvent(M.PauseBreakpointEvent event) {
String message = ' is paused';
if (event.breakpoint != null) {
message += ' at breakpoint ${event.breakpoint.number}';
}
return [
new SpanElement()..text = 'Isolate ',
new AnchorElement(
href: Uris.inspect(event.isolate))
..text = event.isolate.name,
new SpanElement()
..text = message,
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(
href: Uris.debugger(event.isolate))
..text = 'debug',
new SpanElement()..text = ']'
];
}
static List<Element> _managePauseInterruptedEvent(M.PauseInterruptedEvent event) {
return [
new SpanElement()..text = 'Isolate ',
new AnchorElement(
href: Uris.inspect(event.isolate))
..text = event.isolate.name,
new SpanElement()
..text = ' is paused',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(
href: Uris.debugger(event.isolate))
..text = 'debug',
new SpanElement()..text = ']'
];
}
static List<Element> _managePauseExceptionEvent(M.PauseExceptionEvent event) {
return [
new SpanElement()..text = 'Isolate ',
new AnchorElement(
href: Uris.inspect(event.isolate))
..text = event.isolate.name,
new SpanElement()
..text = ' is paused due to exception',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(
href: Uris.debugger(event.isolate))
..text = 'debug',
new SpanElement()..text = ']'
];
}
static List<Element> _manageNoneEvent(M.NoneEvent event) {
return [
new SpanElement()..text = 'Isolate ',
new AnchorElement(
href: Uris.inspect(event.isolate))
..text = event.isolate.name,
new SpanElement()
..text = ' is paused',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(
href: Uris.debugger(event.isolate))
..text = 'debug',
new SpanElement()..text = ']'
];
}
static List<Element> _manageConnectionClosedEvent(M.ConnectionClosedEvent event) {
return [
new SpanElement()..text = 'Disconnected from VM: ${event.reason}',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(href: Uris.vmConnect())..text = 'Connect to a VM',
new SpanElement()..text = ']'
];
}
static List<Element> _manageInspectEvent(M.InspectEvent event) {
return [
new SpanElement()..text = 'Inspect ${event.inspectee.id}',
new BRElement(), new BRElement(), new SpanElement()..text = '[',
new AnchorElement(href: Uris.inspect(event.isolate,
object: event.inspectee))
..text = 'Inspect',
new SpanElement()..text = ']'
// TODO(cbernaschina) add InstanceRefElement back.
//new InstanceRefElement()..instance = event.inspectee
];
}
static List<Element> _manageIsolateReloadEvent(M.IsolateReloadEvent event) {
if (event.error != null) {
return [
new SpanElement()..text = 'Isolate reload failed:',
new BRElement(), new BRElement(),
new DivElement()
..classes = ["indent", "error"]
..text = event.error.message.toString()
];
} else {
return [new SpanElement()..text = 'Isolate reload'];
}
}
EventDeleteEvent _toEvent(_) {
return new EventDeleteEvent(_event);
}
void _delete(EventDeleteEvent e) {
_onDelete.add(e);
}
void delete() {
_onDelete.add(new EventDeleteEvent(_event));
}
}
@@ -0,0 +1,128 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'dart:async';
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/models.dart' show ConnectionException;
class ExceptionDeleteEvent{
final Exception exception;
final StackTrace stacktrace;
ExceptionDeleteEvent(this.exception, {this.stacktrace});
}
class NavNotifyExceptionElement extends HtmlElement implements Renderable {
static const tag = const Tag<NavNotifyExceptionElement>('nav-exception');
RenderingScheduler _r;
Stream<RenderedEvent<NavNotifyExceptionElement>> get onRendered =>
_r.onRendered;
final StreamController<ExceptionDeleteEvent> _onDelete =
new StreamController<ExceptionDeleteEvent>.broadcast();
Stream<ExceptionDeleteEvent> get onDelete => _onDelete.stream;
Exception _exception;
StackTrace _stacktrace;
Exception get exception => _exception;
StackTrace get stacktrace => _stacktrace;
factory NavNotifyExceptionElement(Exception exception,
{StackTrace stacktrace: null, RenderingQueue queue}) {
assert(exception != null);
NavNotifyExceptionElement e = document.createElement(tag.name);
e._r = new RenderingScheduler(e, queue: queue);
e._exception = exception;
e._stacktrace = stacktrace;
return e;
}
NavNotifyExceptionElement.created() : super.created();
@override
void attached() {
super.attached();
_r.enable();
}
@override
void detached() {
super.detached();
children = [];
_r.disable(notify: true);
}
void render() {
if (exception is ConnectionException) {
renderConnectionException();
} else {
renderGenericException();
}
}
void renderConnectionException() {
children = [
new DivElement()
..children = [
new SpanElement()..text = 'The request cannot be completed because the '
'VM is currently disconnected',
new BRElement(), new BRElement(),
new SpanElement()..text = '[',
new AnchorElement(href: Uris.vmConnect())
..text = 'Connect to a different VM',
new SpanElement()..text = ']',
new ButtonElement()..innerHtml = '&times;'
..onClick.map(_toEvent).listen(_delete)
]
];
}
void renderGenericException() {
List<Node> content;
content = [
new SpanElement()..text = 'Unexpected exception:',
new BRElement(), new BRElement(),
new DivElement()..text = exception.toString(),
new BRElement()
];
if (stacktrace != null) {
content.addAll([
new SpanElement()..text = 'Stacktrace:',
new BRElement(), new BRElement(),
new DivElement()..text = stacktrace.toString(),
new BRElement()
]);
}
content.addAll([
new SpanElement()..text = '[',
new AnchorElement(href: Uris.vmConnect())
..text = 'Connect to a different VM',
new SpanElement()..text = ']',
new ButtonElement()..innerHtml = '&times;'
..onClick.map(_toEvent).listen(_delete)
]);
children = [
new DivElement()
..children = content
];
}
ExceptionDeleteEvent _toEvent(_) {
return new ExceptionDeleteEvent(exception, stacktrace: stacktrace);
}
void _delete(ExceptionDeleteEvent e) {
_onDelete.add(e);
}
void delete() {
_onDelete.add(new ExceptionDeleteEvent(exception, stacktrace: stacktrace));
}
}
@@ -0,0 +1,123 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'package:observatory/app.dart';
import 'package:observatory/repositories.dart';
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/src/elements/shims/binding.dart';
import 'package:observatory/src/elements/nav/notify.dart';
class NavNotifyElementWrapper extends HtmlElement {
static final binder = new Binder<NavNotifyElementWrapper>(
const [const Binding('notifications'), const Binding('notifyOnPause')]);
static const tag = const Tag<NavNotifyElementWrapper>('nav-notify');
NotificationRepository _notifications;
bool _notifyOnPause = true;
NotificationRepository get notifications => _notifications;
bool get notifyOnPause => _notifyOnPause;
set notifications(NotificationRepository value) {
_notifications = value; render();
}
set notifyOnPause(bool value) {
_notifyOnPause = value; render();
}
NavNotifyElementWrapper.created() : super.created() {
binder.registerCallback(this);
createShadowRoot();
render();
}
@override
void attached() {
super.attached();
render();
}
void render() {
shadowRoot.children = [];
if (_notifications == null) return;
shadowRoot.children = [
new StyleElement()
..text = '''nav-notify-wrapped > div {
float: right;
}
nav-notify-wrapped > div > div {
display: block;
position: absolute;
top: 98%;
right: 0;
margin: 0;
padding: 0;
width: auto;
z-index: 1000;
background: none;
}
/* nav-exception & nav-event */
nav-exception > div, nav-event > div {
position: relative;
padding: 16px;
margin-top: 10px;
margin-right: 10px;
padding-right: 25px;
width: 500px;
color: #ddd;
background: rgba(0,0,0,.6);
border: solid 2px white;
box-shadow: 0 0 5px black;
border-radius: 5px;
animation: fadein 1s;
}
nav-exception *, nav-event * {
color: #ddd;
font-size: 12px;
}
nav-exception > div > a, nav-event > div > a {
color: white;
text-decoration: none;
}
nav-exception > div > a:hover, nav-event > div > a:hover {
text-decoration: underline;
}
nav-exception > div > div {
margin-left:20px;
white-space: pre
}
nav-exception > div > button, nav-event > div > button {
background: transparent;
border: none;
position: absolute;
display: block;
top: 4px;
right: 4px;
height: 18px;
width: 18px;
line-height: 16px;
border-radius: 9px;
color: white;
font-size: 18px;
cursor: pointer;
text-align: center;
}
nav-exception > div > button:hover, nav-event > div > button:hover {
background: rgba(255,255,255,0.5);
}''',
new NavNotifyElement(_notifications, notifyOnPause: notifyOnPause,
queue: ObservatoryApplication.app.queue)
];
}
}
@@ -4,10 +4,8 @@
library nav_bar_element;
import 'dart:html' hide Notification;
import 'observatory_element.dart';
import 'package:observatory/service.dart';
import 'package:observatory/app.dart' show Notification;
import 'package:polymer/polymer.dart';
@CustomTag('library-nav-menu')
@@ -17,52 +15,3 @@ class LibraryNavMenuElement extends ObservatoryElement {
LibraryNavMenuElement.created() : super.created();
}
@CustomTag('nav-notify')
class NavNotifyElement extends ObservatoryElement {
@published ObservableList<Notification> notifications;
@published bool notifyOnPause = true;
NavNotifyElement.created() : super.created();
}
@CustomTag('nav-notify-event')
class NavNotifyEventElement extends ObservatoryElement {
@published ObservableList<Notification> notifications;
@published Notification notification;
@published ServiceEvent event;
@published bool notifyOnPause = true;
void closeItem(MouseEvent e, var detail, Element target) {
notifications.remove(notification);
}
NavNotifyEventElement.created() : super.created();
}
@CustomTag('nav-notify-exception')
class NavNotifyExceptionElement extends ObservatoryElement {
@published ObservableList<Notification> notifications;
@published Notification notification;
@published var exception;
@published var stacktrace;
exceptionChanged() {
notifyPropertyChange(#isNetworkError, true, false);
notifyPropertyChange(#isUnexpectedError, true, false);
}
@observable get isNetworkError {
return (exception is NetworkRpcException);
}
@observable get isUnexpectedError {
return (exception is! NetworkRpcException);
}
void closeItem(MouseEvent e, var detail, Element target) {
notifications.remove(notification);
}
NavNotifyExceptionElement.created() : super.created();
}
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="action_link.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="library-nav-menu" extends="observatory-element">
<polymer-element name="library-nav-menu">
<template>
<nav-menu link="{{ makeLink('/inspect', library) }}"
anchor="{{ library.name }}" last="{{ last }}">
@@ -11,251 +11,4 @@
</template>
</polymer-element>
<polymer-element name="nav-notify" extends="observatory-element">
<template>
<style>
.menu {
float: right;
}
.menu .list {
display: block;
position: absolute;
top: 98%;
right: 0;
margin: 0;
padding: 0;
width: auto;
z-index: 1000;
font: 400 12px 'Montserrat', sans-serif;
color: white;
background: none;
}
</style>
<div class="menu">
<div class="list">
<template repeat="{{ notification in notifications }}">
<template if="{{ notification.event != null }}">
<nav-notify-event notifications="{{ notifications }}"
notification="{{ notification }}"
event="{{ notification.event }}"
notifyOnPause="{{ notifyOnPause }}">
</nav-notify-event>
</template>
<template if="{{ notification.exception != null }}">
<nav-notify-exception notifications="{{ notifications }}"
notification="{{ notification }}"
exception="{{ notification.exception }}"
stacktrace="{{ notification.stacktrace }}">
</nav-notify-exception>
</template>
</template>
</div>
</div>
</template>
</polymer-element>
<polymer-element name="nav-notify-event" extends="observatory-element">
<template>
<style>
.item {
position: relative;
padding: 16px;
margin-top: 10px;
margin-right: 10px;
padding-right: 25px;
width: 250px;
color: #ddd;
background: rgba(0,0,0,.6);
border: solid 2px white;
box-shadow: 0 0 5px black;
border-radius: 5px;
animation: fadein 1s;
}
.wide-item {
width: 50vw;
}
@keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
a.link {
color: white;
text-decoration: none;
}
a.link:hover {
text-decoration: underline;
}
a.boxclose {
position: absolute;
display: block;
top: 4px;
right: 4px;
height: 18px;
width: 18px;
line-height: 16px;
border-radius: 9px;
color: white;
font-size: 18px;
cursor: pointer;
text-align: center;
}
a.boxclose:hover {
background: rgba(255,255,255,0.5);
}
.error {
white-space: pre;
}
</style>
<template if="{{ event != null }}">
<template if="{{ notifyOnPause && event.isPauseEvent }}">
<div class="item">
Isolate
<a class="link" on-click="{{ goto }}"
_href="{{ gotoLink('/inspect', event.isolate) }}">{{ event.isolate.name }}</a>
is paused
<template if="{{ event.kind == 'PauseStart' }}">
at isolate start
</template>
<template if="{{ event.kind == 'PauseExit' }}">
at isolate exit
</template>
<template if="{{ event.breakpoint != null }}">
at breakpoint {{ event.breakpoint.number }}
</template>
<template if="{{ event.kind == 'PauseException' }}">
due to exception
</template>
<br><br>
[<a class="link" on-click="{{ goto }}"
_href="{{ gotoLink('/debugger', event.isolate) }}">debug</a>]
<a class="boxclose" on-click="{{ closeItem }}">&times;</a>
</div>
</template>
<template if="{{ event.kind == 'ConnectionClosed' }}">
<div class="item">
Disconnected from VM: {{ event.reason }}
<br><br>
[<a class="link" on-click="{{ goto }}"
_href="{{ gotoLink('/vm-connect') }}">Connect to a VM</a>]
<a class="boxclose" on-click="{{ closeItem }}">&times;</a>
</div>
</template>
<template if="{{ event.kind == 'Inspect' }}">
<div class="item">
Inspect <any-service-ref ref="{{ event.inspectee }}"></any-service-ref>
<br><br>
<a class="boxclose" on-click="{{ closeItem }}">&times;</a>
</div>
</template>
<template if="{{ event.kind == 'IsolateReload' }}">
<div class="wide-item item">
Isolate reload
<template if="{{ event.reloadError != null }}">
failed:
<br>
<br>
<div class="indent error">{{ event.reloadError.message.toString() }}</div><br>
</template>
<template if="{{ event.reloadError == null }}">
succeeded
</template>
<a class="boxclose" on-click="{{ closeItem }}">&times;</a>
</div>
</template>
</template>
</template>
</polymer-element>
<polymer-element name="nav-notify-exception" extends="observatory-element">
<template>
<style>
.item {
position: relative;
padding: 16px;
margin-top: 10px;
margin-right: 10px;
padding-right: 25px;
width: 500px;
color: #ddd;
background: rgba(0,0,0,.6);
border: solid 2px white;
box-shadow: 0 0 5px black;
border-radius: 5px;
animation: fadein 1s;
}
@keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
a.link {
color: white;
text-decoration: none;
}
a.link:hover {
text-decoration: underline;
}
.indent {
margin-left:20px;
}
a.boxclose {
position: absolute;
display: block;
top: 4px;
right: 4px;
height: 18px;
width: 18px;
line-height: 16px;
border-radius: 9px;
color: white;
font-size: 18px;
cursor: pointer;
text-align: center;
}
a.boxclose:hover {
background: rgba(255,255,255,0.5);
}
.stacktrace {
white-space: pre
}
</style>
<template if="{{ isUnexpectedError }}">
<!-- TODO(turnidge): Add a file-a-bug link to this notification -->
<div class="item">
Unexpected exception:<br><br>
<div class="indent">{{ exception.toString() }}</div><br>
<template if="{{ stacktrace != null }}">
Stacktrace:<br><br>
<div class="indent stacktrace">{{ stacktrace.toString() }}</div>
<br>
</template>
[<a class="link" on-click="{{ goto }}"
_href="{{ gotoLink('vm-connect') }}">Connect to a different VM</a>]
<a class="boxclose" on-click="{{ closeItem }}">&times;</a>
</div>
</template>
<template if="{{ isNetworkError }}">
<div class="item">
The request cannot be completed because the VM is currently
disconnected.
<br><br>
[<a class="link" on-click="{{ goto }}"
_href="{{ gotoLink('vm-connect') }}">Connect to a different VM</a>]
<a class="boxclose" on-click="{{ closeItem }}">&times;</a>
</div>
</template>
</template>
</polymer-element>
<script type="application/dart" src="nav_bar.dart"></script>
@@ -5,11 +5,11 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<polymer-element name="object-common" extends="observatory-element">
<polymer-element name="object-common">
<template>
<link rel="stylesheet" href="css/shared.css">
<div class="memberList">
@@ -5,12 +5,12 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="object_common.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<polymer-element name="object-view" extends="observatory-element">
<polymer-element name="object-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -5,12 +5,12 @@
<link rel="import" href="function_ref.html">
<link rel="import" href="inbound_reference.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="object_common.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="eval_link.html">
<polymer-element name="objectpool-view" extends="observatory-element">
<polymer-element name="objectpool-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -4,12 +4,12 @@
<link rel="import" href="field_ref.html">
<link rel="import" href="function_ref.html">
<link rel="import" href="instance_ref.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="script_ref.html">
<polymer-element name="objectstore-view" extends="observatory-element">
<polymer-element name="objectstore-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -1,7 +1,7 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_view.html">
<polymer-element name="observatory-application" extends="observatory-element">
<polymer-element name="observatory-application">
<!-- This element explicitly manages its child elements -->
</polymer-element>
@@ -11,7 +11,6 @@ import 'package:observatory/service.dart';
import 'package:polymer/polymer.dart';
/// Base class for all Observatory custom elements.
@CustomTag('observatory-element')
class ObservatoryElement extends PolymerElement {
ObservatoryElement.created() : super.created();
@@ -1,6 +0,0 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="observatory-element">
</polymer-element>
<script type="application/dart" src="observatory_element.dart"></script>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="persistent-handles-page" extends="observatory-element">
<polymer-element name="persistent-handles-page">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="ports-page" extends="observatory-element">
<polymer-element name="ports-page">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,5 +1,5 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="icon-refresh" noscript>
<template>
@@ -27,7 +27,7 @@
</template>
</polymer-element>
<polymer-element name="script-inset" extends="observatory-element">
<polymer-element name="script-inset">
<template>
<style>
a {
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="service_ref.html">
<polymer-element name="script-ref" extends="service-ref">
<polymer-element name="script-ref">
<template>
<link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" title="{{ hoverText }}" _href="{{ url }}">{{ name }}</a>
@@ -1,9 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<polymer-element name="script-view" extends="observatory-element">
<polymer-element name="script-view">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -14,7 +14,6 @@ import 'class_ref.dart';
import 'library_ref.dart';
import 'observatory_element.dart';
@CustomTag('service-ref')
class ServiceRefElement extends ObservatoryElement {
@published ServiceObject ref;
@published bool internal = false;
@@ -1,13 +1,9 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="service-ref" extends="observatory-element">
<polymer-element name="any-service-ref">
</polymer-element>
<polymer-element name="any-service-ref" extends="observatory-element">
</polymer-element>
<polymer-element name="object-ref" extends="service-ref">
<polymer-element name="object-ref">
<template><link rel="stylesheet" href="css/shared.css">
<template if="{{ ref.isObjectPool }}">
@@ -11,15 +11,15 @@
<link rel="import" href="instance_view.html">
<link rel="import" href="library_view.html">
<link rel="import" href="heap_snapshot.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_view.html">
<link rel="import" href="vm_view.html">
<polymer-element name="service-view" extends="observatory-element">
<polymer-element name="service-view">
<!-- This element explicitly manages the child elements to avoid setting
an observable property on the old element to an invalid type. -->
</polymer-element>
<polymer-element name="trace-view" extends="observatory-element">
<polymer-element name="trace-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -47,7 +47,7 @@
</template>
</polymer-element>
<polymer-element name="map-viewer" extends="observatory-element">
<polymer-element name="map-viewer">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -79,7 +79,7 @@
</template>
</polymer-element>
<polymer-element name="list-viewer" extends="observatory-element">
<polymer-element name="list-viewer">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="timeline-page" extends="observatory-element">
<polymer-element name="timeline-page">
<template>
<link rel="stylesheet" href="css/shared.css">
<nav-bar>
@@ -1,8 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<polymer-element name="vm-connect" extends="observatory-element">
<polymer-element name="vm-connect">
<template>
<link rel="stylesheet" href="css/shared.css">
<style>
@@ -1,7 +1,7 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="service_ref.html">
<polymer-element name="vm-ref" extends="service-ref">
<polymer-element name="vm-ref">
<template><link rel="stylesheet" href="css/shared.css">
<a on-click="{{ goto }}" _href="{{ url }}">{{ ref.name }}</a>
</template>
@@ -4,10 +4,10 @@
<link rel="import" href="isolate_summary.html">
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_ref.html">
<polymer-element name="vm-view" extends="observatory-element">
<polymer-element name="vm-view">
<template>
<link rel="stylesheet" href="css/shared.css">
@@ -0,0 +1,10 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of mocks;
class ConnectionExceptionMock implements M.ConnectionException {
final String message;
const ConnectionExceptionMock({this.message});
}
@@ -0,0 +1,20 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of mocks;
class ErrorRefMock implements M.ErrorRef {
final String id;
final M.ErrorKind kind;
final String message;
const ErrorRefMock({this.id, this.kind, this.message});
}
class ErrorMock implements M.Error {
final String id;
final M.ErrorKind kind;
final String message;
final int size;
const ErrorMock({this.id, this.kind, this.message, this.size});
}
@@ -6,11 +6,137 @@ part of mocks;
class VMUpdateEventMock implements M.VMUpdateEvent {
final M.VMRef vm;
const VMUpdateEventMock({this.vm});
final DateTime timestamp;
const VMUpdateEventMock({this.timestamp, this.vm});
}
class IsolateStartEventMock implements M.IsolateStartEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const IsolateStartEventMock({this.timestamp, this.isolate});
}
class IsolateRunnableEventMock implements M.IsolateRunnableEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const IsolateRunnableEventMock({this.timestamp, this.isolate});
}
class IsolateExitEventMock implements M.IsolateExitEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const IsolateExitEventMock({this.timestamp, this.isolate});
}
class IsolateUpdateEventMock implements M.IsolateUpdateEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const IsolateUpdateEventMock({this.timestamp, this.isolate});
}
class IsolateRealodEventMock implements M.IsolateReloadEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Error error;
const IsolateRealodEventMock({this.timestamp, this.isolate, this.error});
}
class ServiceExtensionAddedEventMock implements M.ServiceExtensionAddedEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final String extensionRPC;
const ServiceExtensionAddedEventMock({this.extensionRPC, this.isolate,
this.timestamp});
}
class PauseStartEventMock implements M.PauseStartEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const PauseStartEventMock({this.isolate, this.timestamp});
}
class PauseExitEventMock implements M.PauseExitEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const PauseExitEventMock({this.isolate, this.timestamp});
}
class PauseBreakpointEventMock implements M.PauseBreakpointEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Breakpoint breakpoint;
final List<M.Breakpoint> pauseBreakpoints;
final M.Frame topFrame;
final bool atAsyncSuspension;
const PauseBreakpointEventMock({this.timestamp, this.isolate, this.breakpoint,
this.pauseBreakpoints, this.topFrame, this.atAsyncSuspension});
}
class PauseInterruptedEventMock implements M.PauseInterruptedEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Frame topFrame;
final bool atAsyncSuspension;
const PauseInterruptedEventMock({this.timestamp, this.isolate, this.topFrame,
this.atAsyncSuspension});
}
class PauseExceptionEventMock implements M.PauseExceptionEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Frame topFrame;
final M.InstanceRef exception;
const PauseExceptionEventMock({this.timestamp, this.isolate, this.topFrame,
this.exception});
}
class ResumeEventMock implements M.ResumeEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const ResumeEventMock({this.timestamp, this.isolate});
}
class BreakpointAddedEventMock implements M.BreakpointAddedEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Breakpoint breakpoint;
const BreakpointAddedEventMock({this.timestamp, this.isolate,
this.breakpoint});
}
class BreakpointResolvedEventMock implements M.BreakpointResolvedEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Breakpoint breakpoint;
const BreakpointResolvedEventMock({this.timestamp, this.isolate,
this.breakpoint});
}
class BreakpointRemovedEventMock implements M.BreakpointRemovedEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.Breakpoint breakpoint;
const BreakpointRemovedEventMock({this.timestamp, this.isolate,
this.breakpoint});
}
class InspectEventMock implements M.InspectEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final M.InstanceRef inspectee;
const InspectEventMock({this.timestamp, this.isolate, this.inspectee});
}
class NoneEventMock implements M.NoneEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const NoneEventMock({this.timestamp, this.isolate});
}
class GCEventMock implements M.GCEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
const GCEventMock({this.timestamp, this.isolate});
}
class ExtensionEventMock implements M.ExtensionEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final String extensionKind;
final M.ExtensionData extensionData;
const ExtensionEventMock({this.timestamp, this.isolate, this.extensionKind,
this.extensionData});
}
class TimelineEventsEventMock implements M.TimelineEventsEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
final List<M.TimelineEvent> timelineEvents;
const TimelineEventsEventMock({this.timestamp, this.isolate,
this.timelineEvents});
}
class ConnectionClockedEventMock implements M.ConnectionClosedEvent {
final DateTime timestamp;
final String reason;
const ConnectionClockedEventMock({this.timestamp, this.reason});
}
@@ -0,0 +1,16 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of mocks;
class ExceptionNotificationMock implements M.ExceptionNotification {
final Exception exception;
final StackTrace stacktrace;
const ExceptionNotificationMock({this.exception, this.stacktrace});
}
class EventNotificationMock implements M.EventNotification {
final M.Event event;
const EventNotificationMock({this.event});
}
@@ -0,0 +1,31 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of mocks;
class ScriptRefMock implements M.ScriptRef {
final String id;
final String uri;
const ScriptRefMock({this.id, this.uri});
}
typedef int TokenToInt(int token);
class ScriptMock implements M.Script {
final String id;
final int size;
final String uri;
final String source;
final TokenToInt _tokenToLine;
final TokenToInt _tokenToCol;
int tokenToLine(int token) => _tokenToLine(token);
int tokenToCol(int token) => _tokenToCol(token);
const ScriptMock({this.id, this.size, this.uri, this.source,
TokenToInt tokenToLine, TokenToInt tokenToCol})
: _tokenToLine = tokenToLine,
_tokenToCol = tokenToCol;
}
@@ -0,0 +1,12 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of mocks;
class SourceLocationMock implements M.SourceLocation {
final M.ScriptRef script;
final int tokenPos;
final int endTokenPos;
const SourceLocationMock({this.script, this.tokenPos, this.endTokenPos});
}
@@ -0,0 +1,58 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of mocks;
class NotificationChangeEventMock implements M.NotificationChangeEvent {
final NotificationRepositoryMock repository;
const NotificationChangeEventMock({this.repository});
}
typedef void NotificationRepositoryMockCallback(M.Notification notification);
class NotificationRepositoryMock implements M.NotificationRepository {
final StreamController<M.NotificationChangeEvent> _onChange =
new StreamController<M.NotificationChangeEvent>.broadcast();
Stream<M.NotificationChangeEvent> get onChange => _onChange.stream;
bool get hasListeners => _onChange.hasListener;
final Iterable<M.Notification> _list;
final NotificationRepositoryMockCallback _add;
final NotificationRepositoryMockCallback _delete;
bool addInvoked = false;
bool listInvoked = false;
bool deleteInvoked = false;
bool deleteAllInvoked = false;
void add(M.Notification notification) {
addInvoked = true;
if (_add != null) _add(notification);
}
Iterable<M.Notification> list() {
listInvoked = true;
return _list;
}
void delete(M.Notification notification) {
deleteInvoked = true;
if (_add != null) _delete(notification);
}
void deleteAll() { deleteAllInvoked = true; }
void triggerChangeEvent() {
_onChange.add(new NotificationChangeEventMock(repository: this));
}
NotificationRepositoryMock({Iterable<M.Notification> list : const [],
NotificationRepositoryMockCallback add,
NotificationRepositoryMockCallback delete})
: _list = list,
_add = add,
_delete = delete;
}
@@ -0,0 +1,49 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class BasicException implements Exception {
String get message;
}
abstract class ConnectionException implements BasicException {}
abstract class ResponseException implements BasicException {}
abstract class RequestException implements BasicException {}
abstract class ParseErrorException implements RequestException {}
abstract class InvalidRequestException implements RequestException {}
abstract class MethodNotFoundException implements RequestException {}
abstract class InvalidParamsException implements RequestException {}
abstract class InternalErrorException implements RequestException {}
abstract class FeatureDisabledException implements RequestException {}
abstract class CannotAddBreakpointException implements RequestException {}
abstract class StreamAlreadySubscribedException implements RequestException {}
abstract class StreamNotSubscribedException implements RequestException {}
abstract class IsolateMustBeRunnableException implements RequestException {}
abstract class IsolateMustBePausedException implements RequestException {}
abstract class IsolateIsReloadingException implements RequestException {}
abstract class FileSystemAlreadyExistsException implements RequestException {}
abstract class FileSystemDoesNotExistException implements RequestException {}
abstract class FileDoesNotExistException implements RequestException {}
abstract class IsolateReloadFailedException implements RequestException {}
abstract class UnknownException implements RequestException {}
@@ -0,0 +1,13 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class Breakpoint extends Object {
/// A number identifying this breakpoint to the user.
int get number;
/// Has this breakpoint been assigned to a specific program location?
bool get resolved;
}
@@ -12,7 +12,7 @@ abstract class ClassRef extends ObjectRef {
abstract class Class extends ObjectRef implements ClassRef {
/// The error which occurred during class finalization, if it exists.
/// [optional]
//ErrorRef get error;
ErrorRef get error;
/// Is this an abstract class?
bool get isAbstract;
@@ -21,10 +21,10 @@ abstract class Class extends ObjectRef implements ClassRef {
bool get isConst;
/// The library which contains this class.
//LibraryRef get library;
LibraryRef get library;
/// The location of this class in the source code.[optional]
//SourceLocation get location;
SourceLocation get location;
/// The superclass of this class, if any. [optional]
ClassRef get superclass;
@@ -32,17 +32,17 @@ abstract class Class extends ObjectRef implements ClassRef {
/// The supertype for this class, if any.
///
/// The value will be of the kind: Type. [optional]
//InstanceRef get superType;
InstanceRef get superType;
/// A list of interface types for this class.
///
/// The values will be of the kind: Type.
//Iterable<InstanceRef> get interfaces;
Iterable<InstanceRef> get interfaces;
/// The mixin type for this class, if any.
///
/// The value will be of the kind: Type. [optional]
//Iterable<InstanceRef> get mixin;
Iterable<InstanceRef> get mixin;
/// A list of fields in this class. Does not include fields from
/// superclasses.
@@ -0,0 +1,27 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
enum ErrorKind {
/// The isolate has encountered an unhandled Dart exception.
UnhandledException,
/// The isolate has encountered a Dart language error in the program.
LanguageError,
/// The isolate has encounted an internal error. These errors should be
/// reported as bugs.
InternalError,
/// The isolate has been terminated by an external source.
TerminationError
}
abstract class ErrorRef extends ObjectRef {
String get id;
ErrorKind get kind;
String get message;
}
abstract class Error extends Object implements ErrorRef {
}
@@ -4,10 +4,72 @@
part of models;
abstract class VMUpdateEvent {
abstract class Event {
DateTime get timestamp;
static bool isPauseEvent(Event event) {
return event is PauseStartEvent || event is PauseExitEvent ||
event is PauseBreakpointEvent || event is PauseInterruptedEvent ||
event is PauseExceptionEvent || event is NoneEvent;
}
}
abstract class VMEvent extends Event {
VMRef get vm;
}
abstract class IsolateUpdateEvent {
abstract class VMUpdateEvent extends VMEvent {}
abstract class IsolateEvent extends Event {
IsolateRef get isolate;
}
abstract class IsolateStartEvent extends IsolateEvent {}
abstract class IsolateRunnableEvent extends IsolateEvent {}
abstract class IsolateExitEvent extends IsolateEvent {}
abstract class IsolateUpdateEvent extends IsolateEvent {}
abstract class IsolateReloadEvent extends IsolateEvent {
ErrorRef get error;
}
abstract class ServiceExtensionAddedEvent extends IsolateEvent {
String get extensionRPC;
}
abstract class DebugEvent extends IsolateEvent {}
abstract class PauseStartEvent extends DebugEvent {}
abstract class PauseExitEvent extends DebugEvent {}
abstract class PauseBreakpointEvent extends DebugEvent {
/// [optional]
Breakpoint get breakpoint;
Iterable<Breakpoint> get pauseBreakpoints;
Frame get topFrame;
bool get atAsyncSuspension;
}
abstract class PauseInterruptedEvent extends DebugEvent {
Frame get topFrame;
bool get atAsyncSuspension;
}
abstract class PauseExceptionEvent extends DebugEvent {
Frame get topFrame;
InstanceRef get exception;
}
abstract class ResumeEvent extends DebugEvent {}
abstract class BreakpointAddedEvent extends DebugEvent {
Breakpoint get breakpoint;
}
abstract class BreakpointResolvedEvent extends DebugEvent {
Breakpoint get breakpoint;
}
abstract class BreakpointRemovedEvent extends DebugEvent {
Breakpoint get breakpoint;
}
abstract class InspectEvent extends DebugEvent {
InstanceRef get inspectee;
}
abstract class NoneEvent extends DebugEvent {}
abstract class GCEvent extends IsolateEvent {}
abstract class ExtensionEvent extends Event {
IsolateRef get isolate;
String get extensionKind;
ExtensionData get extensionData;
}
abstract class TimelineEventsEvent extends IsolateEvent {
Iterable<TimelineEvent> get timelineEvents;
}
abstract class ConnectionClosedEvent extends Event {
String get reason;
}
@@ -0,0 +1,7 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class ExtensionData implements Map<String, dynamic> {}
@@ -0,0 +1,7 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class Frame {}
@@ -0,0 +1,7 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class InstanceRef extends ObjectRef {}
@@ -0,0 +1,33 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class LibraryRef extends ObjectRef {
/// The name of this library.
String get name;
/// The uri of this library.
String get uri;
}
abstract class Library extends Object implements LibraryRef {
/// Is this library debuggable? Default true.
bool get debuggable;
/// A list of the imports for this library.
//LibraryDependency[] dependencies;
// A list of the scripts which constitute this library.
Iterable<ScriptRef> get scripts;
// A list of the top-level variables in this library.
//List<FieldRef> get variables;
// A list of the top-level functions in this library.
//List<FunctionRef> get functions;
// A list of all classes in this library.
Iterable<ClassRef> get classes;
}
@@ -0,0 +1,17 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class Notification {}
abstract class ExceptionNotification implements Notification{
Exception get exception;
/// [optional]
StackTrace get stacktrace;
}
abstract class EventNotification implements Notification{
Event get event;
}
@@ -0,0 +1,22 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class ScriptRef extends ObjectRef {
/// The uri from which this script was loaded.
String get uri;
}
abstract class Script extends Object implements ScriptRef {
/// The library which owns this script.
// LibraryRef get library;
/// The source code for this script. For certain built-in scripts,
/// this may be reconstructed without source comments.
String get source;
int tokenToLine(int token);
int tokenToCol(int token);
}
@@ -0,0 +1,14 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class SourceLocation {
/// The script containing the source location.
ScriptRef get script;
/// The first token of the location.
int get tokenPos;
/// The last token of the location if this is a range. [optional]
int get endTokenPos;
}
@@ -0,0 +1,7 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class TimelineEvent implements Map<String, dynamic> {}
@@ -0,0 +1,16 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of models;
abstract class NotificationChangeEvent {
NotificationRepository get repository;
}
abstract class NotificationRepository {
Stream<NotificationChangeEvent> get onChange;
Iterable<Notification> list();
void delete(Notification);
void deleteAll();
}
@@ -0,0 +1,72 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file
part of repositories;
class NotificationChangeEvent implements M.NotificationChangeEvent {
final NotificationRepository repository;
NotificationChangeEvent(this.repository);
}
class NotificationRepository implements M.NotificationRepository {
final List<M.Notification> _list = new List<M.Notification>();
final StreamController<M.NotificationChangeEvent> _onChange =
new StreamController<M.NotificationChangeEvent>.broadcast();
Stream<M.NotificationChangeEvent> get onChange => _onChange.stream;
void add(M.Notification notification) {
assert(notification != null);
_list.add(notification);
_notify();
}
Iterable<M.Notification> list() => _list;
void delete(M.Notification notification) {
if (_list.remove(notification))
_notify();
}
void deleteAll() {
if (_list.isNotEmpty) {
_list.clear();
_notify();
}
}
NotificationRepository();
void _notify() {
_onChange.add(new NotificationChangeEvent(this));
}
void deleteWhere(bool test(M.Notification element)) {
int length = _list.length;
_list.removeWhere(test);
if (_list.length != length) _notify();
}
void deletePauseEvents({M.Isolate isolate}) {
if (isolate == null) {
deleteWhere((notification) {
return notification is M.EventNotification &&
M.Event.isPauseEvent(notification.event);
});
} else {
deleteWhere((notification) {
return notification is M.EventNotification &&
M.Event.isPauseEvent(notification.event) &&
notification.event.isolate == isolate;
});
}
}
void deleteDisconnectEvents() {
deleteWhere((notification) {
return notification is M.EventNotification &&
notification.event is M.ConnectionClosedEvent;
});
}
}
@@ -22,14 +22,14 @@ Future cancelFutureSubscription(
/// An RpcException represents an exceptional event that happened
/// while invoking an rpc.
abstract class RpcException implements Exception {
abstract class RpcException implements Exception, M.BasicException {
RpcException(this.message);
String message;
}
/// A ServerRpcException represents an error returned by the VM.
class ServerRpcException extends RpcException {
class ServerRpcException extends RpcException implements M.RequestException {
/// A list of well-known server error codes.
static const kParseError = -32700;
static const kInvalidRequest = -32600;
@@ -70,7 +70,8 @@ class ServerRpcException extends RpcException {
/// A NetworkRpcException is used to indicate that an rpc has
/// been canceled due to network error.
class NetworkRpcException extends RpcException {
class NetworkRpcException extends RpcException
implements M.ConnectionException {
NetworkRpcException(String message) : super(message);
String toString() => 'NetworkRpcException(${message})';
@@ -424,7 +425,8 @@ abstract class Location {
}
/// A [SourceLocation] represents a location or range in the source code.
class SourceLocation extends ServiceObject implements Location {
class SourceLocation extends ServiceObject implements Location,
M.SourceLocation {
Script script;
int tokenPos;
int endTokenPos;
@@ -1119,7 +1121,7 @@ class HeapSnapshot {
}
/// State for a running isolate.
class Isolate extends ServiceObjectOwner implements M.IsolateRef {
class Isolate extends ServiceObjectOwner implements M.Isolate {
static const kLoggingStream = '_Logging';
static const kExtensionStream = 'Extension';
@@ -2036,7 +2038,7 @@ class ServiceEvent extends ServiceObject {
}
}
class Breakpoint extends ServiceObject {
class Breakpoint extends ServiceObject implements M.Breakpoint {
Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner);
// TODO(turnidge): Add state to track if a breakpoint has been
@@ -2132,7 +2134,7 @@ class LibraryDependency {
}
class Library extends HeapObject {
class Library extends HeapObject implements M.LibraryRef {
@observable String uri;
@reflectable final dependencies = new ObservableList<LibraryDependency>();
@reflectable final scripts = new ObservableList<Script>();
@@ -2929,7 +2931,7 @@ class LocalVarLocation {
LocalVarLocation(this.line, this.column, this.endColumn);
}
class Script extends HeapObject {
class Script extends HeapObject implements M.Script {
final lines = new ObservableList<ScriptLine>();
@observable String uri;
@observable String kind;
@@ -2940,6 +2942,8 @@ class Script extends HeapObject {
@observable int columnOffset;
@observable Library library;
String source;
bool get immutable => true;
String _shortUri;
@@ -3041,6 +3045,7 @@ class Script extends HeapObject {
lineOffset = map['lineOffset'];
columnOffset = map['columnOffset'];
_parseTokenPosTable(map['tokenPosTable']);
source = map['source'];
_processSource(map['source']);
library = map['library'];
}
@@ -3998,7 +4003,7 @@ class MetricPoller {
}
}
class Frame extends ServiceObject {
class Frame extends ServiceObject implements M.Frame {
@observable int index;
@observable ServiceFunction function;
@observable SourceLocation location;
+31 -7
View File
@@ -16,6 +16,7 @@
'lib/mocks.dart',
'lib/models.dart',
'lib/object_graph.dart',
'lib/repositories.dart',
'lib/service.dart',
'lib/service_common.dart',
'lib/service_html.dart',
@@ -124,14 +125,18 @@
'lib/src/elements/nav_bar.dart',
'lib/src/elements/nav_bar.html',
'lib/src/elements/nav/bar.dart',
'lib/src/elements/nav/isolate_menu.dart',
'lib/src/elements/nav/isolate_menu_wrapper.dart',
'lib/src/elements/nav/class_menu.dart',
'lib/src/elements/nav/class_menu_wrapper.dart',
'lib/src/elements/nav/menu.dart',
'lib/src/elements/nav/menu_wrapper.dart',
'lib/src/elements/nav/isolate_menu.dart',
'lib/src/elements/nav/isolate_menu_wrapper.dart',
'lib/src/elements/nav/menu_item.dart',
'lib/src/elements/nav/menu_item_wrapper.dart',
'lib/src/elements/nav/menu.dart',
'lib/src/elements/nav/menu_wrapper.dart',
'lib/src/elements/nav/notify_event.dart',
'lib/src/elements/nav/notify_exception.dart',
'lib/src/elements/nav/notify.dart',
'lib/src/elements/nav/notify_wrapper.dart',
'lib/src/elements/nav/refresh.dart',
'lib/src/elements/nav/refresh_wrapper.dart',
'lib/src/elements/nav/top_menu.dart',
@@ -147,7 +152,6 @@
'lib/src/elements/observatory_application.dart',
'lib/src/elements/observatory_application.html',
'lib/src/elements/observatory_element.dart',
'lib/src/elements/observatory_element.html',
'lib/src/elements/persistent_handles.dart',
'lib/src/elements/persistent_handles.html',
'lib/src/elements/ports.dart',
@@ -168,23 +172,43 @@
'lib/src/elements/timeline_page.dart',
'lib/src/elements/timeline_page.html',
'lib/src/elements/view_footer.dart',
'lib/src/elements/vm_connect_target.dart',
'lib/src/elements/vm_connect_target_wrapper.dart',
'lib/src/elements/vm_connect.dart',
'lib/src/elements/vm_connect.html',
'lib/src/elements/vm_ref.dart',
'lib/src/elements/vm_ref.html',
'lib/src/elements/vm_view.dart',
'lib/src/elements/vm_view.html',
'lib/src/mocks/exceptions/connection_exception.dart',
'lib/src/mocks/objects/error.dart',
'lib/src/mocks/objects/event.dart',
'lib/src/mocks/objects/class.dart',
'lib/src/mocks/objects/isolate.dart',
'lib/src/mocks/objects/target.dart',
'lib/src/mocks/objects/notification.dart',
'lib/src/mocks/objects/script.dart',
'lib/src/mocks/objects/source_location.dart',
'lib/src/mocks/objects/vm.dart',
'lib/src/models/objects/event.dart',
'lib/src/mocks/repositories/notification.dart',
'lib/src/models/exceptions.dart',
'lib/src/models/objects/breakpoint.dart',
'lib/src/models/objects/class.dart',
'lib/src/models/objects/error.dart',
'lib/src/models/objects/event.dart',
'lib/src/models/objects/extension_data.dart',
'lib/src/models/objects/frame.dart',
'lib/src/models/objects/instance.dart',
'lib/src/models/objects/isolate.dart',
'lib/src/models/objects/library.dart',
'lib/src/models/objects/notification.dart',
'lib/src/models/objects/object.dart',
'lib/src/models/objects/script.dart',
'lib/src/models/objects/source_location.dart',
'lib/src/models/objects/target.dart',
'lib/src/models/objects/timeline_event.dart',
'lib/src/models/objects/vm.dart',
'lib/src/models/repositories/notification.dart',
'lib/src/repositories/notification.dart',
'lib/src/service/object.dart',
'lib/tracer.dart',
'lib/utils.dart',
@@ -0,0 +1,121 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html' hide Notification, NotificationEvent;
import 'package:unittest/unittest.dart';
import 'package:observatory/mocks.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/nav/notify_event.dart';
import 'package:observatory/src/elements/nav/notify_exception.dart';
main() {
NavNotifyElement.tag.ensureRegistration();
final evTag = NavNotifyEventElement.tag.name;
final exTag = NavNotifyExceptionElement.tag.name;
const vm = const VMRefMock();
const isolate = const IsolateRefMock(id: 'i-id', name: 'i-name');
group('instantiation', () {
test('default', () {
final NavNotifyElement e = new NavNotifyElement(
new NotificationRepositoryMock());
expect(e, isNotNull, reason: 'element correctly created');
expect(e.notifyOnPause, isTrue, reason: 'notifyOnPause is default');
});
test('notify on pause', () {
final NavNotifyElement e = new NavNotifyElement(
new NotificationRepositoryMock(), notifyOnPause: true);
expect(e, isNotNull, reason: 'element correctly created');
expect(e.notifyOnPause, isTrue, reason: 'notifyOnPause is the same');
});
test('do not notify on pause', () {
final NavNotifyElement e = new NavNotifyElement(
new NotificationRepositoryMock(), notifyOnPause: false);
expect(e, isNotNull, reason: 'element correctly created');
expect(e.notifyOnPause, isFalse, reason: 'notifyOnPause is the same');
});
});
test('is correctly listening', () async {
final NotificationRepositoryMock repository =
new NotificationRepositoryMock();
final NavNotifyElement e = new NavNotifyElement(repository);
document.body.append(e);
await e.onRendered.first;
expect(repository.hasListeners, isTrue, reason: 'is listening');
e.remove();
await e.onRendered.first;
expect(repository.hasListeners, isFalse, reason: 'is no more listening');
});
group('elements', () {
test('created after attachment', () async {
final NotificationRepositoryMock repository =
new NotificationRepositoryMock(list: [
new ExceptionNotificationMock(exception: new Exception("ex")),
const EventNotificationMock(event: const VMUpdateEventMock(vm: vm)),
const EventNotificationMock(event: const VMUpdateEventMock(vm: vm))
]);
final NavNotifyElement e = new NavNotifyElement(repository);
document.body.append(e);
await e.onRendered.first;
expect(repository.listInvoked, isTrue, reason: 'should invoke list()');
expect(e.children.length, isNonZero, reason: 'has elements');
expect(e.querySelectorAll(evTag).length, equals(2));
expect(e.querySelectorAll(exTag).length, equals(1));
e.remove();
await e.onRendered.first;
expect(e.children.length, isZero, reason: 'is empty');
});
test('react to notifyOnPause change', () async {
final NotificationRepositoryMock repository =
new NotificationRepositoryMock(list: [
new ExceptionNotificationMock(exception: new Exception("ex")),
const EventNotificationMock(event: const VMUpdateEventMock()),
const EventNotificationMock(
event: const PauseStartEventMock(isolate: isolate))
]);
final NavNotifyElement e = new NavNotifyElement(repository,
notifyOnPause: true);
document.body.append(e);
await e.onRendered.first;
expect(e.querySelectorAll(evTag).length, equals(2));
expect(e.querySelectorAll(exTag).length, equals(1));
e.notifyOnPause = false;
await e.onRendered.first;
expect(e.querySelectorAll(evTag).length, equals(1));
expect(e.querySelectorAll(exTag).length, equals(1));
e.notifyOnPause = true;
await e.onRendered.first;
expect(e.querySelectorAll(evTag).length, equals(2));
expect(e.querySelectorAll(exTag).length, equals(1));
e.remove();
await e.onRendered.first;
expect(e.children.length, isZero, reason: 'is empty');
});
test('react to update event', () async {
final List<M.Notification> list = [
new ExceptionNotificationMock(exception: new Exception("ex")),
const EventNotificationMock(event: const VMUpdateEventMock()),
];
final NotificationRepositoryMock repository =
new NotificationRepositoryMock(list: list);
final NavNotifyElement e = new NavNotifyElement(repository,
notifyOnPause: true);
document.body.append(e);
await e.onRendered.first;
expect(e.querySelectorAll(evTag).length, equals(1));
expect(e.querySelectorAll(exTag).length, equals(1));
list.add(const EventNotificationMock(
event: const PauseStartEventMock(isolate: isolate)));
repository.triggerChangeEvent();
await e.onRendered.first;
expect(e.querySelectorAll(evTag).length, equals(2));
expect(e.querySelectorAll(exTag).length, equals(1));
e.remove();
await e.onRendered.first;
expect(e.children.length, isZero, reason: 'is empty');
});
});
}
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="dart.unittest" content="full-stack-traces">
<style>
.unittest-table { font-family:monospace; border:1px; }
.unittest-pass { background: #6b3;}
.unittest-fail { background: #d55;}
.unittest-error { background: #a11;}
</style>
<script src="/packages/web_components/webcomponents.js"></script>
<script src="/packages/web_components/dart_support.js"></script>
</head>
<body>
<script type="text/javascript"
src="/root_dart/tools/testing/dart/test_controller.js"></script>
%TEST_SCRIPTS%
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More