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

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: Add comments. 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
« no previous file with comments | « dart/site/try/src/editor.dart ('k') | dart/site/try/src/ui.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
82 /** 97 /**
83 * State machine for UI interactions. 98 * State machine for UI interactions.
84 */ 99 */
85 class InteractionContext extends InteractionManager { 100 class InteractionContext extends InteractionManager {
86 InteractionState state; 101 InteractionState state;
87 102
103 final Map<String, CompilationUnit> projectFiles = <String, CompilationUnit>{};
104
105 CompilationUnit currentCompilationUnit = new CompilationUnit('fake', '');
kasperl 2014/03/28 10:24:51 Maybe chose a fake name that isn't at all likely (
ahe 2014/03/28 11:53:14 This is a temporary hack. I'll add a todo.
106
88 InteractionContext() 107 InteractionContext()
89 : super.internal() { 108 : super.internal() {
90 state = new InitialState(this); 109 state = new InitialState(this);
91 } 110 }
92 111
93 void onInput(Event event) => state.onInput(event); 112 void onInput(Event event) => state.onInput(event);
94 113
95 void onKeyUp(KeyboardEvent event) => state.onKeyUp(event); 114 void onKeyUp(KeyboardEvent event) => state.onKeyUp(event);
96 115
97 void onMutation(List<MutationRecord> mutations, MutationObserver observer) { 116 void onMutation(List<MutationRecord> mutations, MutationObserver observer) {
98 return state.onMutation(mutations, observer); 117 return state.onMutation(mutations, observer);
99 } 118 }
100 119
101 void onSelectionChange(Event event) => state.onSelectionChange(event); 120 void onSelectionChange(Event event) => state.onSelectionChange(event);
121
122 void onCompilationUnitChanged(CompilationUnit unit) {
123 return state.onCompilationUnitChanged(unit);
124 }
125
126 Future<List<String>> projectFileNames() => state.projectFileNames();
127
128 void onProjectFileSelected(String projectFile) {
129 return state.onProjectFileSelected(projectFile);
130 }
102 } 131 }
103 132
104 abstract class InteractionState implements InteractionManager { 133 abstract class InteractionState implements InteractionManager {
105 void onStateChanged(InteractionState previous) { 134 void onStateChanged(InteractionState previous) {
106 print('State change ${previous.runtimeType} -> ${runtimeType}.'); 135 print('State change ${previous.runtimeType} -> ${runtimeType}.');
107 } 136 }
108 } 137 }
109 138
110 class InitialState extends InteractionState { 139 class InitialState extends InteractionState {
111 final InteractionContext context; 140 final InteractionContext context;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 while (child != null) { 255 while (child != null) {
227 walk4(child); 256 walk4(child);
228 if (hasSelection) return; 257 if (hasSelection) return;
229 child = child.nextNode; 258 child = child.nextNode;
230 } 259 }
231 } 260 }
232 if (selection.isCollapsed) { 261 if (selection.isCollapsed) {
233 walk4(mainEditorPane); 262 walk4(mainEditorPane);
234 } 263 }
235 264
236 editor.currentSource = mainEditorPane.text; 265 String currentText = mainEditorPane.text;
266 context.currentCompilationUnit.content = currentText;
237 mainEditorPane.nodes.clear(); 267 mainEditorPane.nodes.clear();
238 mainEditorPane.appendText(editor.currentSource); 268 mainEditorPane.appendText(currentText);
239 if (hasSelection) { 269 if (hasSelection) {
240 selection.collapse(mainEditorPane.firstChild, anchorOffset); 270 selection.collapse(mainEditorPane.firstChild, anchorOffset);
241 } 271 }
242 272
243 editor.isMalformedInput = false; 273 editor.isMalformedInput = false;
244 for (var n in new List.from(mainEditorPane.nodes)) { 274 for (var n in new List.from(mainEditorPane.nodes)) {
245 if (n is! Text) continue; 275 if (n is! Text) continue;
246 Text node = n; 276 Text node = n;
247 String text = node.text; 277 String text = node.text;
248 278
(...skipping 24 matching lines...) Expand all
273 selectionOffset -= str.length; 303 selectionOffset -= str.length;
274 selection.collapse(after, selectionOffset); 304 selection.collapse(after, selectionOffset);
275 } else { 305 } else {
276 selection.collapse(str, selectionOffset); 306 selection.collapse(str, selectionOffset);
277 } 307 }
278 } 308 }
279 node = after; 309 node = after;
280 } 310 }
281 } 311 }
282 312
283 window.localStorage['currentSource'] = editor.currentSource;
284 print('Saved source');
285
286 // Discard highlighting mutations. 313 // Discard highlighting mutations.
287 observer.takeRecords(); 314 observer.takeRecords();
288 } 315 }
289 316
290 void onSelectionChange(Event event) { 317 void onSelectionChange(Event event) {
291 } 318 }
292 319
293 void onStateChanged(InteractionState previous) { 320 void onStateChanged(InteractionState previous) {
294 super.onStateChanged(previous); 321 super.onStateChanged(previous);
295 scheduleCompilation(); 322 scheduleCompilation();
296 } 323 }
324
325 void onCompilationUnitChanged(CompilationUnit unit) {
326 if (unit == context.currentCompilationUnit) {
327 window.localStorage['currentSource'] = unit.content;
kasperl 2014/03/28 10:24:51 Add a setter for currentSource next to the getter?
ahe 2014/03/28 11:53:14 Also a temporary hack, but encapsulating the hacks
328 print('Saved source');
329 scheduleCompilation();
330 } else {
331 print("Unexpected change to compilation unit '${unit.name}'.");
332 }
333 }
334
335 Future<List<String>> projectFileNames() {
336 return getString('project?list').then((String response) {
337 return new List<String>.from(JSON.decode(response));
338 });
339 }
340
341 void onProjectFileSelected(String projectFile) {
342 // Disable editing whilst fetching data.
343 mainEditorPane.contentEditable = 'false';
344
345 CompilationUnit unit = context.projectFiles[projectFile];
346 Future<CompilationUnit> future;
347 if (unit != null) {
348 // This project file had been fetched already.
349 future = new Future<CompilationUnit>.value(unit);
350 } else {
351 // This project file has to be fetched.
352 future = getString('project/$projectFile').then((String text) {
353 CompilationUnit unit = context.projectFiles[projectFile];
354 if (unit == null) {
355 // Only create a new unit if the value hadn't arrived already.
356 unit = new CompilationUnit(projectFile, text);
357 context.projectFiles[projectFile] = unit;
358 }
359 return unit;
360 });
361 }
362 future.then((CompilationUnit unit) {
363 mainEditorPane
364 ..contentEditable = 'true'
365 ..nodes.clear();
366 observer.takeRecords(); // Discard mutations.
367
368 // Install the code, which will trigger a call to onMutation.
369 mainEditorPane.appendText(unit.content);
370 });
371 }
372 }
373
374 Future<String> getString(uri) {
375 return new Future<String>.sync(() => HttpRequest.getString('$uri'));
297 } 376 }
298 377
299 class PendingInputState extends InitialState { 378 class PendingInputState extends InitialState {
300 PendingInputState(InteractionContext context) 379 PendingInputState(InteractionContext context)
301 : super(context); 380 : super(context);
302 381
303 void onInput(Event event) { 382 void onInput(Event event) {
304 // Do nothing. 383 // Do nothing.
305 } 384 }
306 385
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 event.getModifierState("Fn") || 672 event.getModifierState("Fn") ||
594 event.getModifierState("Meta") || 673 event.getModifierState("Meta") ||
595 event.getModifierState("NumLock") || 674 event.getModifierState("NumLock") ||
596 event.getModifierState("ScrollLock") || 675 event.getModifierState("ScrollLock") ||
597 event.getModifierState("Scroll") || 676 event.getModifierState("Scroll") ||
598 event.getModifierState("Win") || 677 event.getModifierState("Win") ||
599 event.getModifierState("Shift") || 678 event.getModifierState("Shift") ||
600 event.getModifierState("SymbolLock") || 679 event.getModifierState("SymbolLock") ||
601 event.getModifierState("OS"); 680 event.getModifierState("OS");
602 } 681 }
OLDNEW
« no previous file with comments | « dart/site/try/src/editor.dart ('k') | dart/site/try/src/ui.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698