| 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 trydart.interaction_manager; | 5 library trydart.interaction_manager; |
| 6 | 6 |
| 7 import 'dart:html'; | 7 import 'dart:html'; |
| 8 | 8 |
| 9 import 'dart:convert' show | 9 import 'dart:convert' show |
| 10 JSON; | 10 JSON; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 // In rare cases, some UI components can be independent of this state | 101 // In rare cases, some UI components can be independent of this state |
| 102 // machine. For example, animation and auto-save loops. | 102 // machine. For example, animation and auto-save loops. |
| 103 | 103 |
| 104 // Implementation note: The state machine is actually implemented by | 104 // Implementation note: The state machine is actually implemented by |
| 105 // [InteractionContext], this class represents public event handlers. | 105 // [InteractionContext], this class represents public event handlers. |
| 106 | 106 |
| 107 factory InteractionManager() => new InteractionContext(); | 107 factory InteractionManager() => new InteractionContext(); |
| 108 | 108 |
| 109 InteractionManager.internal(); | 109 InteractionManager.internal(); |
| 110 | 110 |
| 111 // TODO(ahe): Remove this. |
| 112 Set<AnchorElement> get oldDiagnostics; |
| 113 |
| 111 void onInput(Event event); | 114 void onInput(Event event); |
| 112 | 115 |
| 113 // TODO(ahe): Rename to onKeyDown (as it is called in response to keydown | 116 // TODO(ahe): Rename to onKeyDown (as it is called in response to keydown |
| 114 // event). | 117 // event). |
| 115 void onKeyUp(KeyboardEvent event); | 118 void onKeyUp(KeyboardEvent event); |
| 116 | 119 |
| 117 void onMutation(List<MutationRecord> mutations, MutationObserver observer); | 120 void onMutation(List<MutationRecord> mutations, MutationObserver observer); |
| 118 | 121 |
| 119 void onSelectionChange(Event event); | 122 void onSelectionChange(Event event); |
| 120 | 123 |
| 121 /// Called when the content of a CompilationUnit changed. | 124 /// Called when the content of a CompilationUnit changed. |
| 122 void onCompilationUnitChanged(CompilationUnit unit); | 125 void onCompilationUnitChanged(CompilationUnit unit); |
| 123 | 126 |
| 124 Future<List<String>> projectFileNames(); | 127 Future<List<String>> projectFileNames(); |
| 125 | 128 |
| 126 /// Called when the user selected a new project file. | 129 /// Called when the user selected a new project file. |
| 127 void onProjectFileSelected(String projectFile); | 130 void onProjectFileSelected(String projectFile); |
| 128 | 131 |
| 129 /// Called when notified about a project file changed (on the server). | 132 /// Called when notified about a project file changed (on the server). |
| 130 void onProjectFileFsEvent(MessageEvent e); | 133 void onProjectFileFsEvent(MessageEvent e); |
| 131 | 134 |
| 132 /// Called every 500ms. | 135 /// Called every 500ms. |
| 133 void onHeartbeat(Timer timer); | 136 void onHeartbeat(Timer timer); |
| 134 | 137 |
| 135 /// Called by [:window.onMessage.listen:]. | 138 /// Called by [:window.onMessage.listen:]. |
| 136 void onMessage(MessageEvent event); | 139 void onMessage(MessageEvent event); |
| 140 |
| 141 void onCompilationDone(); |
| 142 |
| 143 /// Called when a compilation is starting, but just before sending the |
| 144 /// initiating message to the compiler isolate. |
| 145 void compilationStarting(); |
| 137 } | 146 } |
| 138 | 147 |
| 139 /** | 148 /** |
| 140 * State machine for UI interactions. | 149 * State machine for UI interactions. |
| 141 */ | 150 */ |
| 142 class InteractionContext extends InteractionManager { | 151 class InteractionContext extends InteractionManager { |
| 143 InteractionState state; | 152 InteractionState state; |
| 144 | 153 |
| 145 final Map<String, CompilationUnit> projectFiles = <String, CompilationUnit>{}; | 154 final Map<String, CompilationUnit> projectFiles = <String, CompilationUnit>{}; |
| 146 | 155 |
| 147 final Set<CompilationUnit> modifiedUnits = new Set<CompilationUnit>(); | 156 final Set<CompilationUnit> modifiedUnits = new Set<CompilationUnit>(); |
| 148 | 157 |
| 149 final Queue<CompilationUnit> unitsToSave = new Queue<CompilationUnit>(); | 158 final Queue<CompilationUnit> unitsToSave = new Queue<CompilationUnit>(); |
| 150 | 159 |
| 151 final Stopwatch saveTimer = new Stopwatch(); | 160 final Stopwatch saveTimer = new Stopwatch(); |
| 152 | 161 |
| 153 final Stopwatch compileTimer = new Stopwatch(); | 162 final Stopwatch compileTimer = new Stopwatch(); |
| 154 | 163 |
| 155 CompilationUnit currentCompilationUnit = | 164 CompilationUnit currentCompilationUnit = |
| 156 // TODO(ahe): Don't use a fake unit. | 165 // TODO(ahe): Don't use a fake unit. |
| 157 new CompilationUnit('fake', ''); | 166 new CompilationUnit('fake', ''); |
| 158 | 167 |
| 159 Timer heartbeat; | 168 Timer heartbeat; |
| 160 | 169 |
| 161 Completer<String> completeSaveOperation; | 170 Completer<String> completeSaveOperation; |
| 162 | 171 |
| 172 final Set<AnchorElement> oldDiagnostics = new Set<AnchorElement>(); |
| 173 |
| 163 InteractionContext() | 174 InteractionContext() |
| 164 : super.internal() { | 175 : super.internal() { |
| 165 state = new InitialState(this); | 176 state = new InitialState(this); |
| 166 heartbeat = new Timer.periodic(HEARTBEAT_INTERVAL, onHeartbeat); | 177 heartbeat = new Timer.periodic(HEARTBEAT_INTERVAL, onHeartbeat); |
| 167 } | 178 } |
| 168 | 179 |
| 169 void onInput(Event event) => state.onInput(event); | 180 void onInput(Event event) => state.onInput(event); |
| 170 | 181 |
| 171 void onKeyUp(KeyboardEvent event) => state.onKeyUp(event); | 182 void onKeyUp(KeyboardEvent event) => state.onKeyUp(event); |
| 172 | 183 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 return state.onProjectFileSelected(projectFile); | 223 return state.onProjectFileSelected(projectFile); |
| 213 } | 224 } |
| 214 | 225 |
| 215 void onProjectFileFsEvent(MessageEvent e) { | 226 void onProjectFileFsEvent(MessageEvent e) { |
| 216 return state.onProjectFileFsEvent(e); | 227 return state.onProjectFileFsEvent(e); |
| 217 } | 228 } |
| 218 | 229 |
| 219 void onHeartbeat(Timer timer) => state.onHeartbeat(timer); | 230 void onHeartbeat(Timer timer) => state.onHeartbeat(timer); |
| 220 | 231 |
| 221 void onMessage(MessageEvent event) => state.onMessage(event); | 232 void onMessage(MessageEvent event) => state.onMessage(event); |
| 233 |
| 234 void onCompilationDone() => state.onCompilationDone(); |
| 235 |
| 236 void compilationStarting() => state.compilationStarting(); |
| 222 } | 237 } |
| 223 | 238 |
| 224 abstract class InteractionState implements InteractionManager { | 239 abstract class InteractionState implements InteractionManager { |
| 225 InteractionContext get context; | 240 InteractionContext get context; |
| 226 | 241 |
| 242 // TODO(ahe): Remove this. |
| 243 Set<AnchorElement> get oldDiagnostics { |
| 244 throw 'Use context.oldDiagnostics instead'; |
| 245 } |
| 246 |
| 227 void set state(InteractionState newState); | 247 void set state(InteractionState newState); |
| 228 | 248 |
| 229 void onStateChanged(InteractionState previous) { | 249 void onStateChanged(InteractionState previous) { |
| 230 print('State change ${previous.runtimeType} -> ${runtimeType}.'); | 250 print('State change ${previous.runtimeType} -> ${runtimeType}.'); |
| 231 } | 251 } |
| 232 | 252 |
| 233 void transitionToInitialState() { | 253 void transitionToInitialState() { |
| 234 state = new InitialState(context); | 254 state = new InitialState(context); |
| 235 } | 255 } |
| 236 } | 256 } |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 window.console | 597 window.console |
| 578 ..groupCollapsed('Bad message') | 598 ..groupCollapsed('Bad message') |
| 579 ..dir(event) | 599 ..dir(event) |
| 580 ..log(event.source.runtimeType) | 600 ..log(event.source.runtimeType) |
| 581 ..groupEnd(); | 601 ..groupEnd(); |
| 582 } | 602 } |
| 583 | 603 |
| 584 void consolePrintLine(data) { | 604 void consolePrintLine(data) { |
| 585 outputDiv.appendText('$data\n'); | 605 outputDiv.appendText('$data\n'); |
| 586 } | 606 } |
| 607 |
| 608 void onCompilationDone() { |
| 609 for (AnchorElement diagnostic in context.oldDiagnostics) { |
| 610 if (diagnostic.parent != null) { |
| 611 // Problem fixed, remove the diagnostic. |
| 612 diagnostic.replaceWith(new Text(getText(diagnostic))); |
| 613 } |
| 614 } |
| 615 context.oldDiagnostics.clear(); |
| 616 observer.takeRecords(); // Discard mutations. |
| 617 } |
| 618 |
| 619 void compilationStarting() { |
| 620 context.oldDiagnostics |
| 621 ..clear() |
| 622 ..addAll(mainEditorPane.querySelectorAll('a.diagnostic')); |
| 623 } |
| 587 } | 624 } |
| 588 | 625 |
| 589 Future<String> getString(uri) { | 626 Future<String> getString(uri) { |
| 590 return new Future<String>.sync(() => HttpRequest.getString('$uri')); | 627 return new Future<String>.sync(() => HttpRequest.getString('$uri')); |
| 591 } | 628 } |
| 592 | 629 |
| 593 class PendingInputState extends InitialState { | 630 class PendingInputState extends InitialState { |
| 594 PendingInputState(InteractionContext context) | 631 PendingInputState(InteractionContext context) |
| 595 : super(context); | 632 : super(context); |
| 596 | 633 |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1026 return text.split(new RegExp('^', multiLine: true)); | 1063 return text.split(new RegExp('^', multiLine: true)); |
| 1027 } | 1064 } |
| 1028 | 1065 |
| 1029 void removeCodeCompletion() { | 1066 void removeCodeCompletion() { |
| 1030 List<Node> highlighting = | 1067 List<Node> highlighting = |
| 1031 mainEditorPane.querySelectorAll('.dart-code-completion'); | 1068 mainEditorPane.querySelectorAll('.dart-code-completion'); |
| 1032 for (Element element in highlighting) { | 1069 for (Element element in highlighting) { |
| 1033 element.remove(); | 1070 element.remove(); |
| 1034 } | 1071 } |
| 1035 } | 1072 } |
| OLD | NEW |