| Index: runtime/observatory/lib/src/elements/debugger.dart
|
| diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
|
| index 2098d9355d4fb92da2afbebb0dab2b5c3fe85bde..7b8364b8314aac2b58495fd03d189b79fdffc678 100644
|
| --- a/runtime/observatory/lib/src/elements/debugger.dart
|
| +++ b/runtime/observatory/lib/src/elements/debugger.dart
|
| @@ -1207,6 +1207,7 @@ class DebuggerPageElement extends ObservatoryElement {
|
| class DebuggerStackElement extends ObservatoryElement {
|
| @published Isolate isolate;
|
| @observable bool hasStack = false;
|
| + @observable bool hasMessages = false;
|
| @observable bool isSampled = false;
|
| @observable int currentFrame;
|
| ObservatoryDebugger debugger;
|
| @@ -1228,7 +1229,18 @@ class DebuggerStackElement extends ObservatoryElement {
|
| frameList.insert(0, li);
|
| }
|
|
|
| - void updateStack(ServiceMap newStack, ServiceEvent pauseEvent) {
|
| + _addMessage(List messageList, ServiceMap messageInfo) {
|
| + DebuggerMessageElement messageElement = new Element.tag('debugger-message');
|
| + messageElement.message = messageInfo;
|
| +
|
| + var li = new LIElement();
|
| + li.classes.add('list-group-item');
|
| + li.children.insert(0, messageElement);
|
| +
|
| + messageList.add(li);
|
| + }
|
| +
|
| + void updateStackFrames(ServiceMap newStack) {
|
| List frameElements = $['frameList'].children;
|
| List newFrames = newStack['frames'];
|
|
|
| @@ -1275,10 +1287,47 @@ class DebuggerStackElement extends ObservatoryElement {
|
| }
|
| }
|
|
|
| - isSampled = pauseEvent == null;
|
| hasStack = frameElements.isNotEmpty;
|
| }
|
|
|
| + void updateStackMessages(ServiceMap newStack) {
|
| + List messageElements = $['messageList'].children;
|
| + List newMessages = newStack['messages'];
|
| +
|
| + // Remove any extra message elements.
|
| + if (messageElements.length > newMessages.length) {
|
| + // Remove old messages from the front of the queue.
|
| + int removeCount = messageElements.length - newMessages.length;
|
| + for (int i = 0; i < removeCount; i++) {
|
| + messageElements.removeAt(0);
|
| + }
|
| + }
|
| +
|
| + // Add any new messages to the tail of the queue.
|
| + int newStartingIndex = messageElements.length;
|
| + if (messageElements.length < newMessages.length) {
|
| + for (int i = newStartingIndex; i < newMessages.length; i++) {
|
| + _addMessage(messageElements, newMessages[i]);
|
| + }
|
| + }
|
| + assert(messageElements.length == newMessages.length);
|
| +
|
| + if (messageElements.isNotEmpty) {
|
| + // Update old messages.
|
| + for (int i = 0; i < newStartingIndex; i++) {
|
| + messageElements[i].children[0].updateMessage(newMessages[i]);
|
| + }
|
| + }
|
| +
|
| + hasMessages = messageElements.isNotEmpty;
|
| + }
|
| +
|
| + void updateStack(ServiceMap newStack, ServiceEvent pauseEvent) {
|
| + updateStackFrames(newStack);
|
| + updateStackMessages(newStack);
|
| + isSampled = pauseEvent == null;
|
| + }
|
| +
|
| void setCurrentFrame(int value) {
|
| currentFrame = value;
|
| List frameElements = $['frameList'].children;
|
| @@ -1400,6 +1449,100 @@ class DebuggerFrameElement extends ObservatoryElement {
|
| }
|
| }
|
|
|
| +@CustomTag('debugger-message')
|
| +class DebuggerMessageElement extends ObservatoryElement {
|
| + @published ServiceMap message;
|
| + @observable ServiceObject preview;
|
| +
|
| + // Is this the current message?
|
| + bool _current = false;
|
| +
|
| + // Has this message been pinned open?
|
| + bool _pinned = false;
|
| +
|
| + void setCurrent(bool value) {
|
| + _current = value;
|
| + var messageOuter = $['messageOuter'];
|
| + if (_current) {
|
| + messageOuter.classes.add('current');
|
| + expanded = true;
|
| + messageOuter.classes.add('shadow');
|
| + scrollIntoView();
|
| + } else {
|
| + messageOuter.classes.remove('current');
|
| + if (_pinned) {
|
| + expanded = true;
|
| + messageOuter.classes.add('shadow');
|
| + } else {
|
| + expanded = false;
|
| + messageOuter.classes.remove('shadow');
|
| + }
|
| + }
|
| + }
|
| +
|
| + @observable String scriptHeight;
|
| + @observable bool expanded = false;
|
| + @observable bool busy = false;
|
| +
|
| + DebuggerMessageElement.created() : super.created();
|
| +
|
| + void updateMessage(ServiceMap newMessage) {
|
| + bool messageChanged =
|
| + (message['messageObjectId'] != newMessage['messageObjectId']);
|
| + message['depth'] = newMessage['depth'];
|
| + message['handlerFunction'] = newMessage['handlerFunction'];
|
| + message['messageObjectId'] = newMessage['messageObjectId'];
|
| + if (messageChanged) {
|
| + // Message object id has changed: clear preview and collapse.
|
| + preview = null;
|
| + if (expanded) {
|
| + toggleExpand(null, null, null);
|
| + }
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void attached() {
|
| + super.attached();
|
| + int windowHeight = window.innerHeight;
|
| + scriptHeight = '${windowHeight ~/ 1.6}px';
|
| + }
|
| +
|
| + void toggleExpand(var a, var b, var c) {
|
| + if (busy) {
|
| + return;
|
| + }
|
| + busy = true;
|
| + var function = message['handlerFunction'];
|
| + var loadedFunction;
|
| + if (function == null) {
|
| + // Complete immediately.
|
| + loadedFunction = new Future.value(null);
|
| + } else {
|
| + loadedFunction = function.load();
|
| + }
|
| + loadedFunction.then((_) {
|
| + _pinned = !_pinned;
|
| + var messageOuter = $['messageOuter'];
|
| + if (_pinned) {
|
| + expanded = true;
|
| + messageOuter.classes.add('shadow');
|
| + } else {
|
| + expanded = false;
|
| + messageOuter.classes.remove('shadow');
|
| + }
|
| + busy = false;
|
| + });
|
| + }
|
| +
|
| + Future<ServiceObject> previewMessage(_) {
|
| + return message.isolate.getObject(message['messageObjectId']).then((result) {
|
| + preview = result;
|
| + return result;
|
| + });
|
| + }
|
| +}
|
| +
|
| @CustomTag('debugger-console')
|
| class DebuggerConsoleElement extends ObservatoryElement {
|
| @published Isolate isolate;
|
|
|