Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: dart/site/try/src/interaction_manager.dart

Issue 214513005: Add CompilationUnit abstraction for tracking "project files". (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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;
11 11
12 import 'dart:math' show 12 import 'dart:math' show
13 max, 13 max,
14 min; 14 min;
15 15
16 import 'dart:async' show
17 Future;
18
16 import 'package:compiler/implementation/scanner/scannerlib.dart' 19 import 'package:compiler/implementation/scanner/scannerlib.dart'
17 show 20 show
18 EOF_TOKEN, 21 EOF_TOKEN,
19 StringScanner, 22 StringScanner,
20 Token; 23 Token;
21 24
22 import 'package:compiler/implementation/source_file.dart' show 25 import 'package:compiler/implementation/source_file.dart' show
23 StringSourceFile; 26 StringSourceFile;
24 27
25 import 'compilation.dart' show 28 import 'compilation.dart' show
26 scheduleCompilation; 29 scheduleCompilation;
27 30
28 import 'ui.dart' show 31 import 'ui.dart' show
29 currentTheme, 32 currentTheme,
30 hackDiv, 33 hackDiv,
31 mainEditorPane, 34 mainEditorPane,
32 observer, 35 observer,
33 outputDiv; 36 outputDiv;
34 37
35 import 'decoration.dart' show 38 import 'decoration.dart' show
36 CodeCompletionDecoration, 39 CodeCompletionDecoration,
37 Decoration, 40 Decoration,
38 DiagnosticDecoration, 41 DiagnosticDecoration,
39 error, 42 error,
40 info, 43 info,
41 warning; 44 warning;
42 45
43 import 'html_to_text.dart' show 46 import 'html_to_text.dart' show
44 htmlToText; 47 htmlToText;
48
49 import 'compilation_unit.dart' show
50 CompilationUnit;
51
45 import 'editor.dart' as editor; 52 import 'editor.dart' as editor;
46 53
47 import 'mock.dart' as mock; 54 import 'mock.dart' as mock;
48 55
49 import 'settings.dart' as settings; 56 import 'settings.dart' as settings;
50 57
51 /** 58 /**
52 * UI interaction manager for the entire application. 59 * UI interaction manager for the entire application.
53 */ 60 */
54 abstract class InteractionManager { 61 abstract class InteractionManager {
(...skipping 15 matching lines...) Expand all
70 77
71 InteractionManager.internal(); 78 InteractionManager.internal();
72 79
73 void onInput(Event event); 80 void onInput(Event event);
74 81
75 void onKeyUp(KeyboardEvent event); 82 void onKeyUp(KeyboardEvent event);
76 83
77 void onMutation(List<MutationRecord> mutations, MutationObserver observer); 84 void onMutation(List<MutationRecord> mutations, MutationObserver observer);
78 85
79 void onSelectionChange(Event event); 86 void onSelectionChange(Event event);
87
88 /// Called when the content of a CompilationUnit changed.
89 void onCompilationUnitChanged(CompilationUnit unit);
90
91 Future<List<String>> projectFileNames();
92
93 /// Called when the user selected a new project file.
94 void onProjectFileSelected(String projectFile);
80 } 95 }
81 96
97
82 /** 98 /**
83 * State machine for UI interactions. 99 * State machine for UI interactions.
84 */ 100 */
85 class InteractionContext extends InteractionManager { 101 class InteractionContext extends InteractionManager {
86 InteractionState state; 102 InteractionState state;
87 103
104 final Map<String, CompilationUnit> projectFiles = <String, CompilationUnit>{};
105
106 CompilationUnit currentCompilationUnit = new CompilationUnit('fake', '');
107
88 InteractionContext() 108 InteractionContext()
89 : super.internal() { 109 : super.internal() {
90 state = new InitialState(this); 110 state = new InitialState(this);
91 } 111 }
92 112
93 void onInput(Event event) => state.onInput(event); 113 void onInput(Event event) => state.onInput(event);
94 114
95 void onKeyUp(KeyboardEvent event) => state.onKeyUp(event); 115 void onKeyUp(KeyboardEvent event) => state.onKeyUp(event);
96 116
97 void onMutation(List<MutationRecord> mutations, MutationObserver observer) { 117 void onMutation(List<MutationRecord> mutations, MutationObserver observer) {
98 return state.onMutation(mutations, observer); 118 return state.onMutation(mutations, observer);
99 } 119 }
100 120
101 void onSelectionChange(Event event) => state.onSelectionChange(event); 121 void onSelectionChange(Event event) => state.onSelectionChange(event);
122
123 void onCompilationUnitChanged(CompilationUnit unit) {
124 return state.onCompilationUnitChanged(unit);
125 }
126
127 Future<List<String>> projectFileNames() => state.projectFileNames();
128
129 void onProjectFileSelected(String projectFile) {
130 return state.onProjectFileSelected(projectFile);
131 }
102 } 132 }
103 133
104 abstract class InteractionState implements InteractionManager { 134 abstract class InteractionState implements InteractionManager {
105 void onStateChanged(InteractionState previous) { 135 void onStateChanged(InteractionState previous) {
106 print('State change ${previous.runtimeType} -> ${runtimeType}.'); 136 print('State change ${previous.runtimeType} -> ${runtimeType}.');
107 } 137 }
108 } 138 }
109 139
110 class InitialState extends InteractionState { 140 class InitialState extends InteractionState {
111 final InteractionContext context; 141 final InteractionContext context;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 while (child != null) { 256 while (child != null) {
227 walk4(child); 257 walk4(child);
228 if (hasSelection) return; 258 if (hasSelection) return;
229 child = child.nextNode; 259 child = child.nextNode;
230 } 260 }
231 } 261 }
232 if (selection.isCollapsed) { 262 if (selection.isCollapsed) {
233 walk4(mainEditorPane); 263 walk4(mainEditorPane);
234 } 264 }
235 265
236 editor.currentSource = mainEditorPane.text; 266 String currentText = mainEditorPane.text;
267 context.currentCompilationUnit.content = currentText;
237 mainEditorPane.nodes.clear(); 268 mainEditorPane.nodes.clear();
238 mainEditorPane.appendText(editor.currentSource); 269 mainEditorPane.appendText(currentText);
239 if (hasSelection) { 270 if (hasSelection) {
240 selection.collapse(mainEditorPane.firstChild, anchorOffset); 271 selection.collapse(mainEditorPane.firstChild, anchorOffset);
241 } 272 }
242 273
243 editor.isMalformedInput = false; 274 editor.isMalformedInput = false;
244 for (var n in new List.from(mainEditorPane.nodes)) { 275 for (var n in new List.from(mainEditorPane.nodes)) {
245 if (n is! Text) continue; 276 if (n is! Text) continue;
246 Text node = n; 277 Text node = n;
247 String text = node.text; 278 String text = node.text;
248 279
(...skipping 24 matching lines...) Expand all
273 selectionOffset -= str.length; 304 selectionOffset -= str.length;
274 selection.collapse(after, selectionOffset); 305 selection.collapse(after, selectionOffset);
275 } else { 306 } else {
276 selection.collapse(str, selectionOffset); 307 selection.collapse(str, selectionOffset);
277 } 308 }
278 } 309 }
279 node = after; 310 node = after;
280 } 311 }
281 } 312 }
282 313
283 window.localStorage['currentSource'] = editor.currentSource;
284 print('Saved source');
285
286 // Discard highlighting mutations. 314 // Discard highlighting mutations.
287 observer.takeRecords(); 315 observer.takeRecords();
288 } 316 }
289 317
290 void onSelectionChange(Event event) { 318 void onSelectionChange(Event event) {
291 } 319 }
292 320
293 void onStateChanged(InteractionState previous) { 321 void onStateChanged(InteractionState previous) {
294 super.onStateChanged(previous); 322 super.onStateChanged(previous);
295 scheduleCompilation(); 323 scheduleCompilation();
296 } 324 }
325
326 void onCompilationUnitChanged(CompilationUnit unit) {
327 if (unit == context.currentCompilationUnit) {
328 window.localStorage['currentSource'] = unit.content;
329 print('Saved source');
330 scheduleCompilation();
331 } else {
332 print("Unexpected change to compilation unit '${unit.name}'.");
333 }
334 }
335
336 Future<List<String>> projectFileNames() {
337 return getString('project?list').then((String response) {
338 return new List<String>.from(JSON.decode(response));
339 });
340 }
341
342 void onProjectFileSelected(String projectFile) {
343 // Disable editing.
344 mainEditorPane.contentEditable = 'false';
lukechurch 2014/03/27 16:08:23 If I read the code below correctly, it's going to
ahe 2014/03/27 23:32:34 Good idea.
345
346 CompilationUnit unit = context.projectFiles[projectFile];
347 Future<CompilationUnit> future;
348 if (unit != null) {
349 // This project file had been fetched already.
350 future = new Future<CompilationUnit>.value(unit);
351 } else {
352 // This project file has to be fetched.
353 future = getString('project/$projectFile').then((String text) {
354 CompilationUnit unit = context.projectFiles[projectFile];
355 if (unit == null) {
356 // Only create a new unit if the value hadn't arrived already.
357 unit = new CompilationUnit(projectFile, text);
358 context.projectFiles[projectFile] = unit;
359 }
360 return unit;
361 });
362 }
363 future.then((CompilationUnit unit) {
364 mainEditorPane
365 ..contentEditable = 'true'
366 ..nodes.clear();
367 observer.takeRecords(); // Discard mutations.
368
369 // Install the code, which will trigger a call to onMutation.
370 mainEditorPane.appendText(unit.content);
371 });
372 }
373 }
374
375 Future<String> getString(uri) {
376 return new Future<String>.sync(() => HttpRequest.getString('$uri'));
297 } 377 }
298 378
299 class PendingInputState extends InitialState { 379 class PendingInputState extends InitialState {
300 PendingInputState(InteractionContext context) 380 PendingInputState(InteractionContext context)
301 : super(context); 381 : super(context);
302 382
303 void onInput(Event event) { 383 void onInput(Event event) {
304 // Do nothing. 384 // Do nothing.
305 } 385 }
306 386
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 event.getModifierState("Fn") || 673 event.getModifierState("Fn") ||
594 event.getModifierState("Meta") || 674 event.getModifierState("Meta") ||
595 event.getModifierState("NumLock") || 675 event.getModifierState("NumLock") ||
596 event.getModifierState("ScrollLock") || 676 event.getModifierState("ScrollLock") ||
597 event.getModifierState("Scroll") || 677 event.getModifierState("Scroll") ||
598 event.getModifierState("Win") || 678 event.getModifierState("Win") ||
599 event.getModifierState("Shift") || 679 event.getModifierState("Shift") ||
600 event.getModifierState("SymbolLock") || 680 event.getModifierState("SymbolLock") ||
601 event.getModifierState("OS"); 681 event.getModifierState("OS");
602 } 682 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698