| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library debugger_page_element; | 5 library debugger_page_element; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:html'; | 8 import 'dart:html'; |
| 9 import 'observatory_element.dart'; | 9 import 'observatory_element.dart'; |
| 10 import 'package:observatory/cli.dart'; | 10 import 'package:observatory/cli.dart'; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 String helpShort = 'List commands or provide details about a specific command'
; | 98 String helpShort = 'List commands or provide details about a specific command'
; |
| 99 | 99 |
| 100 String helpLong = | 100 String helpLong = |
| 101 'List commands or provide details about a specific command.\n' | 101 'List commands or provide details about a specific command.\n' |
| 102 '\n' | 102 '\n' |
| 103 'Syntax: help - Show a list of all commands\n' | 103 'Syntax: help - Show a list of all commands\n' |
| 104 ' help <command> - Help for a specific command\n'; | 104 ' help <command> - Help for a specific command\n'; |
| 105 } | 105 } |
| 106 | 106 |
| 107 class PrintCommand extends DebuggerCommand { |
| 108 PrintCommand(Debugger debugger) : super(debugger, 'print', []) { |
| 109 alias = 'p'; |
| 110 } |
| 111 |
| 112 Future run(List<String> args) { |
| 113 if (args.length < 1) { |
| 114 debugger.console.print('print expects arguments'); |
| 115 return new Future.value(null); |
| 116 } |
| 117 var expr = args.join(''); |
| 118 return debugger.isolate.evalFrame(debugger.currentFrame, expr) |
| 119 .then((response) { |
| 120 if (response is DartError) { |
| 121 debugger.console.print(response.message); |
| 122 } else { |
| 123 ServiceMap instance = response; |
| 124 debugger.console.print('= ', newline:false); |
| 125 debugger.console.printRef(instance); |
| 126 } |
| 127 }); |
| 128 } |
| 129 |
| 130 String helpShort = 'Evaluate and print an expression in the current frame'; |
| 131 |
| 132 String helpLong = |
| 133 'Evaluate and print an expression in the current frame.\n' |
| 134 '\n' |
| 135 'Syntax: print <expression>\n' |
| 136 ' p <expression>\n'; |
| 137 } |
| 138 |
| 139 class DownCommand extends DebuggerCommand { |
| 140 DownCommand(Debugger debugger) : super(debugger, 'down', []); |
| 141 |
| 142 Future run(List<String> args) { |
| 143 int count = 1; |
| 144 if (args.length == 1) { |
| 145 count = int.parse(args[0]); |
| 146 } else if (args.length > 1) { |
| 147 debugger.console.print('down expects 0 or 1 argument'); |
| 148 return new Future.value(null); |
| 149 } |
| 150 if (debugger.currentFrame == null) { |
| 151 debugger.console.print('No stack'); |
| 152 return new Future.value(null); |
| 153 } |
| 154 try { |
| 155 debugger.currentFrame -= count; |
| 156 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 157 } catch (e) { |
| 158 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 159 } |
| 160 return new Future.value(null); |
| 161 } |
| 162 |
| 163 String helpShort = 'Move down one or more frames'; |
| 164 |
| 165 String helpLong = |
| 166 'Move down one or more frames.\n' |
| 167 '\n' |
| 168 'Syntax: down\n' |
| 169 ' down <count>\n'; |
| 170 } |
| 171 |
| 172 class UpCommand extends DebuggerCommand { |
| 173 UpCommand(Debugger debugger) : super(debugger, 'up', []); |
| 174 |
| 175 Future run(List<String> args) { |
| 176 int count = 1; |
| 177 if (args.length == 1) { |
| 178 count = int.parse(args[0]); |
| 179 } else if (args.length > 1) { |
| 180 debugger.console.print('up expects 0 or 1 argument'); |
| 181 return new Future.value(null); |
| 182 } |
| 183 if (debugger.currentFrame == null) { |
| 184 debugger.console.print('No stack'); |
| 185 return new Future.value(null); |
| 186 } |
| 187 try { |
| 188 debugger.currentFrame += count; |
| 189 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 190 } on RangeError catch (e) { |
| 191 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 192 } |
| 193 return new Future.value(null); |
| 194 } |
| 195 |
| 196 String helpShort = 'Move up one or more frames'; |
| 197 |
| 198 String helpLong = |
| 199 'Move up one or more frames.\n' |
| 200 '\n' |
| 201 'Syntax: up\n' |
| 202 ' up <count>\n'; |
| 203 } |
| 204 |
| 205 class FrameCommand extends DebuggerCommand { |
| 206 FrameCommand(Debugger debugger) : super(debugger, 'frame', []) { |
| 207 alias = 'f'; |
| 208 } |
| 209 |
| 210 Future run(List<String> args) { |
| 211 int frame = 1; |
| 212 if (args.length == 1) { |
| 213 frame = int.parse(args[0]); |
| 214 } else { |
| 215 debugger.console.print('frame expects 1 argument'); |
| 216 return new Future.value(null); |
| 217 } |
| 218 if (debugger.currentFrame == null) { |
| 219 debugger.console.print('No stack'); |
| 220 return new Future.value(null); |
| 221 } |
| 222 try { |
| 223 debugger.currentFrame = frame; |
| 224 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 225 } on RangeError catch (e) { |
| 226 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 227 } |
| 228 return new Future.value(null); |
| 229 } |
| 230 |
| 231 String helpShort = 'Set the current frame'; |
| 232 |
| 233 String helpLong = |
| 234 'Set the current frame.\n' |
| 235 '\n' |
| 236 'Syntax: frame <number>\n' |
| 237 ' f <count>\n'; |
| 238 } |
| 239 |
| 107 class PauseCommand extends DebuggerCommand { | 240 class PauseCommand extends DebuggerCommand { |
| 108 PauseCommand(Debugger debugger) : super(debugger, 'pause', []); | 241 PauseCommand(Debugger debugger) : super(debugger, 'pause', []); |
| 109 | 242 |
| 110 Future run(List<String> args) { | 243 Future run(List<String> args) { |
| 111 if (!debugger.isolatePaused()) { | 244 if (!debugger.isolatePaused()) { |
| 112 return debugger.isolate.pause(); | 245 return debugger.isolate.pause(); |
| 113 } else { | 246 } else { |
| 114 debugger.console.print('The program is already paused'); | 247 debugger.console.print('The program is already paused'); |
| 115 return new Future.value(null); | 248 return new Future.value(null); |
| 116 } | 249 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 138 debugger.console.print('The program must be paused'); | 271 debugger.console.print('The program must be paused'); |
| 139 return new Future.value(null); | 272 return new Future.value(null); |
| 140 } | 273 } |
| 141 } | 274 } |
| 142 | 275 |
| 143 String helpShort = 'Resume execution of the isolate'; | 276 String helpShort = 'Resume execution of the isolate'; |
| 144 | 277 |
| 145 String helpLong = | 278 String helpLong = |
| 146 'Continue running the isolate.\n' | 279 'Continue running the isolate.\n' |
| 147 '\n' | 280 '\n' |
| 148 'Syntax: continue\n'; | 281 'Syntax: continue\n' |
| 282 ' c\n'; |
| 149 } | 283 } |
| 150 | 284 |
| 151 class NextCommand extends DebuggerCommand { | 285 class NextCommand extends DebuggerCommand { |
| 152 NextCommand(Debugger debugger) : super(debugger, 'next', []); | 286 NextCommand(Debugger debugger) : super(debugger, 'next', []); |
| 153 | 287 |
| 154 Future run(List<String> args) { | 288 Future run(List<String> args) { |
| 155 if (debugger.isolatePaused()) { | 289 if (debugger.isolatePaused()) { |
| 156 var event = debugger.isolate.pauseEvent; | 290 var event = debugger.isolate.pauseEvent; |
| 157 if (event.eventType == ServiceEvent.kPauseStart) { | 291 if (event.eventType == ServiceEvent.kPauseStart) { |
| 158 debugger.console.print("Type 'continue' to start the isolate"); | 292 debugger.console.print("Type 'continue' to start the isolate"); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 } | 617 } |
| 484 | 618 |
| 485 String helpShort = 'List all isolates'; | 619 String helpShort = 'List all isolates'; |
| 486 | 620 |
| 487 String helpLong = | 621 String helpLong = |
| 488 'List all isolates.\n' | 622 'List all isolates.\n' |
| 489 '\n' | 623 '\n' |
| 490 'Syntax: info isolates\n'; | 624 'Syntax: info isolates\n'; |
| 491 } | 625 } |
| 492 | 626 |
| 627 class InfoFrameCommand extends DebuggerCommand { |
| 628 InfoFrameCommand(Debugger debugger) : super(debugger, 'frame', []); |
| 629 |
| 630 Future run(List<String> args) { |
| 631 if (args.length > 0) { |
| 632 debugger.console.print('info frame expects 1 argument'); |
| 633 return new Future.value(null); |
| 634 } |
| 635 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 636 return new Future.value(null); |
| 637 } |
| 638 |
| 639 String helpShort = 'Show current frame'; |
| 640 |
| 641 String helpLong = |
| 642 'Show current frame.\n' |
| 643 '\n' |
| 644 'Syntax: info frame\n'; |
| 645 } |
| 646 |
| 493 class InfoCommand extends DebuggerCommand { | 647 class InfoCommand extends DebuggerCommand { |
| 494 InfoCommand(Debugger debugger) : super(debugger, 'info', [ | 648 InfoCommand(Debugger debugger) : super(debugger, 'info', [ |
| 495 new InfoBreakpointsCommand(debugger), | 649 new InfoBreakpointsCommand(debugger), |
| 496 new InfoIsolatesCommand(debugger), | 650 new InfoIsolatesCommand(debugger), |
| 651 new InfoFrameCommand(debugger), |
| 497 ]); | 652 ]); |
| 498 | 653 |
| 499 Future run(List<String> args) { | 654 Future run(List<String> args) { |
| 500 debugger.console.print("'info' expects a subcommand (see 'help info')"); | 655 debugger.console.print("'info' expects a subcommand (see 'help info')"); |
| 501 return new Future.value(null); | 656 return new Future.value(null); |
| 502 } | 657 } |
| 503 | 658 |
| 504 String helpShort = 'Show information on a variety of topics'; | 659 String helpShort = 'Show information on a variety of topics'; |
| 505 | 660 |
| 506 String helpLong = | 661 String helpLong = |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 '\n' | 721 '\n' |
| 567 'Syntax: refresh <subcommand>\n'; | 722 'Syntax: refresh <subcommand>\n'; |
| 568 } | 723 } |
| 569 | 724 |
| 570 // Tracks the state for an isolate debugging session. | 725 // Tracks the state for an isolate debugging session. |
| 571 class ObservatoryDebugger extends Debugger { | 726 class ObservatoryDebugger extends Debugger { |
| 572 RootCommand cmd; | 727 RootCommand cmd; |
| 573 DebuggerConsoleElement console; | 728 DebuggerConsoleElement console; |
| 574 DebuggerStackElement stackElement; | 729 DebuggerStackElement stackElement; |
| 575 ServiceMap stack; | 730 ServiceMap stack; |
| 576 int currentFrame = 0; | 731 |
| 732 int get currentFrame => _currentFrame; |
| 733 void set currentFrame(int value) { |
| 734 if (value != null && (value < 0 || value >= stackDepth)) { |
| 735 throw new RangeError.range(value, 0, stackDepth); |
| 736 } |
| 737 _currentFrame = value; |
| 738 if (stackElement != null) { |
| 739 stackElement.setCurrentFrame(value); |
| 740 } |
| 741 } |
| 742 int _currentFrame = null; |
| 743 |
| 744 int get stackDepth => stack['frames'].length; |
| 577 | 745 |
| 578 ObservatoryDebugger() { | 746 ObservatoryDebugger() { |
| 579 cmd = new RootCommand([ | 747 cmd = new RootCommand([ |
| 580 new HelpCommand(this), | 748 new HelpCommand(this), |
| 749 new PrintCommand(this), |
| 750 new DownCommand(this), |
| 751 new UpCommand(this), |
| 752 new FrameCommand(this), |
| 581 new PauseCommand(this), | 753 new PauseCommand(this), |
| 582 new ContinueCommand(this), | 754 new ContinueCommand(this), |
| 583 new NextCommand(this), | 755 new NextCommand(this), |
| 584 new StepCommand(this), | 756 new StepCommand(this), |
| 585 new FinishCommand(this), | 757 new FinishCommand(this), |
| 586 new BreakCommand(this), | 758 new BreakCommand(this), |
| 587 new ClearCommand(this), | 759 new ClearCommand(this), |
| 588 new DeleteCommand(this), | 760 new DeleteCommand(this), |
| 589 new InfoCommand(this), | 761 new InfoCommand(this), |
| 590 new RefreshCommand(this), | 762 new RefreshCommand(this), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 Future refreshStack() { | 795 Future refreshStack() { |
| 624 return _refreshStack(isolate.pauseEvent).then((_) { | 796 return _refreshStack(isolate.pauseEvent).then((_) { |
| 625 reportStatus(); | 797 reportStatus(); |
| 626 }); | 798 }); |
| 627 } | 799 } |
| 628 | 800 |
| 629 bool isolatePaused() { | 801 bool isolatePaused() { |
| 630 // TODO(turnidge): Stop relying on the isolate to track the last | 802 // TODO(turnidge): Stop relying on the isolate to track the last |
| 631 // pause event. Since we listen to events directly in the | 803 // pause event. Since we listen to events directly in the |
| 632 // debugger, this could introduce a race. | 804 // debugger, this could introduce a race. |
| 633 return (isolate.pauseEvent != null && | 805 return (isolate != null && |
| 806 isolate.pauseEvent != null && |
| 634 isolate.pauseEvent.eventType != ServiceEvent.kResume); | 807 isolate.pauseEvent.eventType != ServiceEvent.kResume); |
| 635 } | 808 } |
| 636 | 809 |
| 637 void warnOutOfDate() { | 810 void warnOutOfDate() { |
| 638 // Wait a bit, then tell the user that the stack may be out of date. | 811 // Wait a bit, then tell the user that the stack may be out of date. |
| 639 new Timer(const Duration(seconds:2), () { | 812 new Timer(const Duration(seconds:2), () { |
| 640 if (!isolatePaused()) { | 813 if (!isolatePaused()) { |
| 641 stackElement.isSampled = true; | 814 stackElement.isSampled = true; |
| 642 } | 815 } |
| 643 }); | 816 }); |
| 644 } | 817 } |
| 645 | 818 |
| 646 Future<ServiceMap> _refreshStack(ServiceEvent pauseEvent) { | 819 Future<ServiceMap> _refreshStack(ServiceEvent pauseEvent) { |
| 647 return isolate.getStack().then((result) { | 820 return isolate.getStack().then((result) { |
| 648 stack = result; | 821 stack = result; |
| 649 // TODO(turnidge): Replace only the changed part of the stack to | 822 // TODO(turnidge): Replace only the changed part of the stack to |
| 650 // reduce flicker. | 823 // reduce flicker. |
| 651 stackElement.updateStack(stack, pauseEvent); | 824 stackElement.updateStack(stack, pauseEvent); |
| 825 if (stack['frames'].length > 0) { |
| 826 currentFrame = 0; |
| 827 } else { |
| 828 currentFrame = null; |
| 829 } |
| 652 }); | 830 }); |
| 653 } | 831 } |
| 654 | 832 |
| 655 void reportStatus() { | 833 void reportStatus() { |
| 656 if (_isolate.idle) { | 834 if (_isolate.idle) { |
| 657 console.print('Isolate is idle'); | 835 console.print('Isolate is idle'); |
| 658 } else if (_isolate.running) { | 836 } else if (_isolate.running) { |
| 659 console.print("Isolate is running (type 'pause' to interrupt)"); | 837 console.print("Isolate is running (type 'pause' to interrupt)"); |
| 660 } else if (_isolate.pauseEvent != null) { | 838 } else if (_isolate.pauseEvent != null) { |
| 661 _reportPause(_isolate.pauseEvent); | 839 _reportPause(_isolate.pauseEvent); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 debugger.init(); | 1049 debugger.init(); |
| 872 } | 1050 } |
| 873 | 1051 |
| 874 } | 1052 } |
| 875 | 1053 |
| 876 @CustomTag('debugger-stack') | 1054 @CustomTag('debugger-stack') |
| 877 class DebuggerStackElement extends ObservatoryElement { | 1055 class DebuggerStackElement extends ObservatoryElement { |
| 878 @published Isolate isolate; | 1056 @published Isolate isolate; |
| 879 @observable bool hasStack = false; | 1057 @observable bool hasStack = false; |
| 880 @observable bool isSampled = false; | 1058 @observable bool isSampled = false; |
| 1059 @observable int currentFrame; |
| 881 ObservatoryDebugger debugger; | 1060 ObservatoryDebugger debugger; |
| 882 | 1061 |
| 883 _addFrame(List frameList, ObservableMap frameInfo, bool expand) { | 1062 _addFrame(List frameList, ObservableMap frameInfo) { |
| 884 DebuggerFrameElement frameElement = new Element.tag('debugger-frame'); | 1063 DebuggerFrameElement frameElement = new Element.tag('debugger-frame'); |
| 885 frameElement.expand = expand; | |
| 886 frameElement.frame = frameInfo; | 1064 frameElement.frame = frameInfo; |
| 887 | 1065 |
| 1066 if (frameInfo['depth'] == currentFrame) { |
| 1067 frameElement.setCurrent(true); |
| 1068 } else { |
| 1069 frameElement.setCurrent(false); |
| 1070 } |
| 1071 |
| 888 var li = new LIElement(); | 1072 var li = new LIElement(); |
| 889 li.classes.add('list-group-item'); | 1073 li.classes.add('list-group-item'); |
| 890 li.children.insert(0, frameElement); | 1074 li.children.insert(0, frameElement); |
| 891 | 1075 |
| 892 frameList.insert(0, li); | 1076 frameList.insert(0, li); |
| 893 } | 1077 } |
| 894 | 1078 |
| 895 void updateStack(ServiceMap newStack, ServiceEvent pauseEvent) { | 1079 void updateStack(ServiceMap newStack, ServiceEvent pauseEvent) { |
| 896 List frameElements = $['frameList'].children; | 1080 List frameElements = $['frameList'].children; |
| 897 List newFrames = newStack['frames']; | 1081 List newFrames = newStack['frames']; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 921 frameElements.removeAt(0); | 1105 frameElements.removeAt(0); |
| 922 } | 1106 } |
| 923 } | 1107 } |
| 924 | 1108 |
| 925 // Add any new frames. | 1109 // Add any new frames. |
| 926 int newCount = 0; | 1110 int newCount = 0; |
| 927 if (frameElements.length < newFrames.length) { | 1111 if (frameElements.length < newFrames.length) { |
| 928 // Add new frames to the top of stack. | 1112 // Add new frames to the top of stack. |
| 929 newCount = newFrames.length - frameElements.length; | 1113 newCount = newFrames.length - frameElements.length; |
| 930 for (int i = newCount-1; i >= 0; i--) { | 1114 for (int i = newCount-1; i >= 0; i--) { |
| 931 _addFrame(frameElements, newFrames[i], i == 0); | 1115 _addFrame(frameElements, newFrames[i]); |
| 932 } | 1116 } |
| 933 } | 1117 } |
| 934 assert(frameElements.length == newFrames.length); | 1118 assert(frameElements.length == newFrames.length); |
| 935 | 1119 |
| 936 if (frameElements.isNotEmpty) { | 1120 if (frameElements.isNotEmpty) { |
| 937 frameElements[0].children[0].expand = true; | |
| 938 for (int i = newCount; i < frameElements.length; i++) { | 1121 for (int i = newCount; i < frameElements.length; i++) { |
| 939 frameElements[i].children[0].updateFrame(newFrames[i]); | 1122 frameElements[i].children[0].updateFrame(newFrames[i]); |
| 940 } | 1123 } |
| 941 } | 1124 } |
| 942 | 1125 |
| 943 isSampled = pauseEvent == null; | 1126 isSampled = pauseEvent == null; |
| 944 hasStack = frameElements.isNotEmpty; | 1127 hasStack = frameElements.isNotEmpty; |
| 945 } | 1128 } |
| 946 | 1129 |
| 1130 void setCurrentFrame(int value) { |
| 1131 currentFrame = value; |
| 1132 List frameElements = $['frameList'].children; |
| 1133 for (var frameElement in frameElements) { |
| 1134 var dbgFrameElement = frameElement.children[0]; |
| 1135 if (dbgFrameElement.frame['depth'] == currentFrame) { |
| 1136 dbgFrameElement.setCurrent(true); |
| 1137 } else { |
| 1138 dbgFrameElement.setCurrent(false); |
| 1139 } |
| 1140 } |
| 1141 } |
| 1142 |
| 947 Set<Script> activeScripts() { | 1143 Set<Script> activeScripts() { |
| 948 var s = new Set<Script>(); | 1144 var s = new Set<Script>(); |
| 949 List frameElements = $['frameList'].children; | 1145 List frameElements = $['frameList'].children; |
| 950 for (var frameElement in frameElements) { | 1146 for (var frameElement in frameElements) { |
| 951 s.add(frameElement.children[0].script); | 1147 s.add(frameElement.children[0].script); |
| 952 } | 1148 } |
| 953 return s; | 1149 return s; |
| 954 } | 1150 } |
| 955 | 1151 |
| 956 doPauseIsolate(_) { | 1152 doPauseIsolate(_) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 969 } | 1165 } |
| 970 } | 1166 } |
| 971 | 1167 |
| 972 DebuggerStackElement.created() : super.created(); | 1168 DebuggerStackElement.created() : super.created(); |
| 973 } | 1169 } |
| 974 | 1170 |
| 975 @CustomTag('debugger-frame') | 1171 @CustomTag('debugger-frame') |
| 976 class DebuggerFrameElement extends ObservatoryElement { | 1172 class DebuggerFrameElement extends ObservatoryElement { |
| 977 @published ObservableMap frame; | 1173 @published ObservableMap frame; |
| 978 | 1174 |
| 979 // When true, the frame will start out expanded. | 1175 // Is this the current frame? |
| 980 @published bool expand = false; | 1176 bool _current = false; |
| 1177 |
| 1178 // Has this frame been pinned open? |
| 1179 bool _pinned = false; |
| 1180 |
| 1181 void setCurrent(bool value) { |
| 1182 busy = true; |
| 1183 frame['function'].load().then((func) { |
| 1184 _current = value; |
| 1185 var frameOuter = $['frameOuter']; |
| 1186 if (_current) { |
| 1187 frameOuter.classes.add('current'); |
| 1188 expanded = true; |
| 1189 frameOuter.classes.add('shadow'); |
| 1190 scrollIntoView(); |
| 1191 } else { |
| 1192 frameOuter.classes.remove('current'); |
| 1193 if (_pinned) { |
| 1194 expanded = true; |
| 1195 frameOuter.classes.add('shadow'); |
| 1196 } else { |
| 1197 expanded = false; |
| 1198 frameOuter.classes.remove('shadow'); |
| 1199 } |
| 1200 } |
| 1201 busy = false; |
| 1202 }); |
| 1203 } |
| 981 | 1204 |
| 982 @observable String scriptHeight; | 1205 @observable String scriptHeight; |
| 983 @observable bool expanded = false; | 1206 @observable bool expanded = false; |
| 984 @observable bool busy = false; | 1207 @observable bool busy = false; |
| 985 | 1208 |
| 986 DebuggerFrameElement.created() : super.created(); | 1209 DebuggerFrameElement.created() : super.created(); |
| 987 | 1210 |
| 988 bool matchFrame(ObservableMap newFrame) { | 1211 bool matchFrame(ObservableMap newFrame) { |
| 989 return newFrame['function'].id == frame['function'].id; | 1212 return newFrame['function'].id == frame['function'].id; |
| 990 } | 1213 } |
| 991 | 1214 |
| 992 void updateFrame(ObservableMap newFrame) { | 1215 void updateFrame(ObservableMap newFrame) { |
| 993 assert(matchFrame(newFrame)); | 1216 assert(matchFrame(newFrame)); |
| 994 frame['depth'] = newFrame['depth']; | 1217 frame['depth'] = newFrame['depth']; |
| 995 frame['tokenPos'] = newFrame['tokenPos']; | 1218 frame['tokenPos'] = newFrame['tokenPos']; |
| 996 frame['vars'] = newFrame['vars']; | 1219 frame['vars'] = newFrame['vars']; |
| 997 } | 1220 } |
| 998 | 1221 |
| 999 Script get script => frame['script']; | 1222 Script get script => frame['script']; |
| 1000 | 1223 |
| 1001 @override | 1224 @override |
| 1002 void attached() { | 1225 void attached() { |
| 1003 super.attached(); | 1226 super.attached(); |
| 1004 int windowHeight = window.innerHeight; | 1227 int windowHeight = window.innerHeight; |
| 1005 scriptHeight = '${windowHeight ~/ 1.6}px'; | 1228 scriptHeight = '${windowHeight ~/ 1.6}px'; |
| 1006 } | 1229 } |
| 1007 | 1230 |
| 1008 void expandChanged(oldValue) { | |
| 1009 if (expand != expanded) { | |
| 1010 toggleExpand(null, null, null); | |
| 1011 } | |
| 1012 } | |
| 1013 | |
| 1014 void toggleExpand(var a, var b, var c) { | 1231 void toggleExpand(var a, var b, var c) { |
| 1015 if (busy) { | 1232 if (busy) { |
| 1016 return; | 1233 return; |
| 1017 } | 1234 } |
| 1018 busy = true; | 1235 busy = true; |
| 1019 frame['function'].load().then((func) { | 1236 frame['function'].load().then((func) { |
| 1020 expanded = !expanded; | 1237 _pinned = !_pinned; |
| 1021 var frameOuter = $['frameOuter']; | 1238 var frameOuter = $['frameOuter']; |
| 1022 if (expanded) { | 1239 if (_pinned) { |
| 1240 expanded = true; |
| 1023 frameOuter.classes.add('shadow'); | 1241 frameOuter.classes.add('shadow'); |
| 1024 } else { | 1242 } else { |
| 1243 expanded = false; |
| 1025 frameOuter.classes.remove('shadow'); | 1244 frameOuter.classes.remove('shadow'); |
| 1026 } | 1245 } |
| 1027 busy = false; | 1246 busy = false; |
| 1028 }); | 1247 }); |
| 1029 } | 1248 } |
| 1030 } | 1249 } |
| 1031 | 1250 |
| 1032 @CustomTag('debugger-console') | 1251 @CustomTag('debugger-console') |
| 1033 class DebuggerConsoleElement extends ObservatoryElement { | 1252 class DebuggerConsoleElement extends ObservatoryElement { |
| 1034 @published Isolate isolate; | 1253 @published Isolate isolate; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1050 var span = new SpanElement(); | 1269 var span = new SpanElement(); |
| 1051 span.classes.add('bold'); | 1270 span.classes.add('bold'); |
| 1052 span.appendText(line); | 1271 span.appendText(line); |
| 1053 if (newline) { | 1272 if (newline) { |
| 1054 span.appendText('\n'); | 1273 span.appendText('\n'); |
| 1055 } | 1274 } |
| 1056 $['consoleText'].children.add(span); | 1275 $['consoleText'].children.add(span); |
| 1057 span.scrollIntoView(); | 1276 span.scrollIntoView(); |
| 1058 } | 1277 } |
| 1059 | 1278 |
| 1279 void printRef(ServiceMap ref, { bool newline:true }) { |
| 1280 var refElement = new Element.tag('instance-ref'); |
| 1281 refElement.ref = ref; |
| 1282 $['consoleText'].children.add(refElement); |
| 1283 if (newline) { |
| 1284 this.newline(); |
| 1285 } |
| 1286 refElement.scrollIntoView(); |
| 1287 } |
| 1288 |
| 1060 void newline() { | 1289 void newline() { |
| 1061 var br = new BRElement(); | 1290 var br = new BRElement(); |
| 1062 $['consoleText'].children.add(br); | 1291 $['consoleText'].children.add(br); |
| 1063 br.scrollIntoView(); | 1292 br.scrollIntoView(); |
| 1064 } | 1293 } |
| 1065 } | 1294 } |
| 1066 | 1295 |
| 1067 @CustomTag('debugger-input') | 1296 @CustomTag('debugger-input') |
| 1068 class DebuggerInputElement extends ObservatoryElement { | 1297 class DebuggerInputElement extends ObservatoryElement { |
| 1069 @published Isolate isolate; | 1298 @published Isolate isolate; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 default: | 1347 default: |
| 1119 busy = false; | 1348 busy = false; |
| 1120 break; | 1349 break; |
| 1121 } | 1350 } |
| 1122 }); | 1351 }); |
| 1123 } | 1352 } |
| 1124 | 1353 |
| 1125 DebuggerInputElement.created() : super.created(); | 1354 DebuggerInputElement.created() : super.created(); |
| 1126 } | 1355 } |
| 1127 | 1356 |
| OLD | NEW |