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

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

Issue 197923002: Mock up code completion. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Too many changes to summarize in one line. 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.ui; 5 library trydart.ui;
6 6
7 import 'dart:html'; 7 import 'dart:html';
8 8
9 import 'dart:async' show 9 import 'dart:async' show
10 Future,
11 Timer,
10 scheduleMicrotask; 12 scheduleMicrotask;
11 13
14 import 'dart:convert' show JSON;
15
12 import 'cache.dart' show 16 import 'cache.dart' show
13 onLoad, 17 onLoad,
14 updateCacheStatus; 18 updateCacheStatus;
15 19
16 import 'editor.dart' show 20 import 'interaction_manager.dart' show InteractionManager;
17 onKeyUp,
18 onMutation;
19 21
20 import 'run.dart' show 22 import 'run.dart' show
21 makeOutputFrame; 23 makeOutputFrame;
22 24
23 import 'themes.dart' show 25 import 'themes.dart' show
24 THEMES, 26 THEMES,
25 Theme; 27 Theme;
26 28
27 import 'samples.dart' show 29 import 'samples.dart' show
28 EXAMPLE_FIBONACCI, 30 EXAMPLE_FIBONACCI,
29 EXAMPLE_FIBONACCI_HTML, 31 EXAMPLE_FIBONACCI_HTML,
30 EXAMPLE_HELLO, 32 EXAMPLE_HELLO,
31 EXAMPLE_HELLO_HTML, 33 EXAMPLE_HELLO_HTML,
32 EXAMPLE_SUNFLOWER; 34 EXAMPLE_SUNFLOWER;
33 35
36 import 'settings.dart';
37
38 import 'user_option.dart';
39
40 import 'messages.dart' show messages;
41
42 // TODO(ahe): Make internal to buildUI once all interactions have been moved to
43 // the manager.
44 InteractionManager interaction;
45
34 DivElement inputPre; 46 DivElement inputPre;
35 PreElement outputDiv; 47 PreElement outputDiv;
36 DivElement hackDiv; 48 DivElement hackDiv;
37 IFrameElement outputFrame; 49 IFrameElement outputFrame;
38 MutationObserver observer; 50 MutationObserver observer;
39 SpanElement cacheStatusElement; 51 SpanElement cacheStatusElement;
40 bool alwaysRunInWorker = window.localStorage['alwaysRunInWorker'] == 'true'; 52 Theme currentTheme = Theme.named(theme);
41 bool verboseCompiler = window.localStorage['verboseCompiler'] == 'true';
42 bool minified = window.localStorage['minified'] == 'true';
43 bool onlyAnalyze = window.localStorage['onlyAnalyze'] == 'true';
44 final String rawCodeFont = window.localStorage['codeFont'];
45 String codeFont = rawCodeFont == null ? '' : rawCodeFont;
46 String currentSample = window.localStorage['currentSample'];
47 Theme currentTheme = Theme.named(window.localStorage['theme']);
48 bool applyingSettings = false;
49 53
50 buildButton(message, action) { 54 buildButton(message, action) {
51 if (message is String) { 55 if (message is String) {
52 message = new Text(message); 56 message = new Text(message);
53 } 57 }
54 return new ButtonElement() 58 return new ButtonElement()
55 ..onClick.listen(action) 59 ..onClick.listen(action)
56 ..append(message); 60 ..append(message);
57 } 61 }
58 62
59 buildTab(message, id, action) { 63 buildTab(message, id, action) {
60 if (message is String) { 64 if (message is String) {
61 message = new Text(message); 65 message = new Text(message);
62 } 66 }
63 67
64 onClick(MouseEvent event) { 68 onClick(MouseEvent event) {
65 event.preventDefault(); 69 event.preventDefault();
66 Element e = event.target; 70 Element e = event.target;
67 LIElement parent = e.parent; 71 LIElement parent = e.parent;
68 parent.parent.query('li[class="active"]').classes.remove('active'); 72 parent.parent.querySelector('li[class="active"]').classes.remove('active');
69 parent.classes.add('active'); 73 parent.classes.add('active');
70 action(event); 74 action(event);
71 } 75 }
72 76
73 inspirationCallbacks[id] = action; 77 codeCallbacks[id] = action;
74 78
75 return new OptionElement()..append(message)..id = id; 79 return new OptionElement()..append(message)..id = id;
76 } 80 }
77 81
78 Map<String, Function> inspirationCallbacks = new Map<String, Function>(); 82 Map<String, Function> codeCallbacks = new Map<String, Function>();
79 83
80 void onInspirationChange(Event event) { 84 void onCodeChange(Event event) {
81 SelectElement select = event.target; 85 SelectElement select = event.target;
82 String id = select.queryAll('option')[select.selectedIndex].id; 86 String id = select.querySelectorAll('option')[select.selectedIndex].id;
83 Function action = inspirationCallbacks[id]; 87 Function action = codeCallbacks[id];
84 if (action != null) action(event); 88 if (action != null) action(event);
85 outputFrame.style.display = 'none'; 89 outputFrame.style.display = 'none';
86 } 90 }
87 91
88 buildUI() { 92 buildUI() {
93 interaction = new InteractionManager();
94
89 window.localStorage['currentSample'] = '$currentSample'; 95 window.localStorage['currentSample'] = '$currentSample';
90 96
91 var inspirationTabs = document.getElementById('inspiration'); 97 buildCode(interaction);
92 var htmlGroup = new OptGroupElement()..label = 'HTML';
93 var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';
94 inspirationTabs.append(new OptionElement()..appendText('Pick an example'));
95 inspirationTabs.onChange.listen(onInspirationChange);
96 // inspirationTabs.classes.addAll(['nav', 'nav-tabs']);
97 inspirationTabs.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
98 inputPre
99 ..nodes.clear()
100 ..appendText(EXAMPLE_HELLO);
101 }));
102 inspirationTabs.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
103 inputPre
104 ..nodes.clear()
105 ..appendText(EXAMPLE_FIBONACCI);
106 }));
107 inspirationTabs.append(htmlGroup);
108 // TODO(ahe): Restore benchmarks.
109 // inspirationTabs.append(benchmarkGroup);
110
111 htmlGroup.append(
112 buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
113 inputPre
114 ..nodes.clear()
115 ..appendText(EXAMPLE_HELLO_HTML);
116 }));
117 htmlGroup.append(
118 buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
119 inputPre
120 ..nodes.clear()
121 ..appendText(EXAMPLE_FIBONACCI_HTML);
122 }));
123 htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
124 inputPre
125 ..nodes.clear()
126 ..appendText(EXAMPLE_SUNFLOWER);
127 }));
128
129 benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
130 inputPre.contentEditable = 'false';
131 LinkElement link = query('link[rel="benchmark-DeltaBlue"]');
132 String deltaBlueUri = link.href;
133 link = query('link[rel="benchmark-base"]');
134 String benchmarkBaseUri = link.href;
135 HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
136 HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
137 benchmarkBase = benchmarkBase.replaceFirst(
138 'part of benchmark_harness;', '// part of benchmark_harness;');
139 deltaBlue = deltaBlue.replaceFirst(
140 "import 'package:benchmark_harness/benchmark_harness.dart';",
141 benchmarkBase);
142 inputPre
143 ..nodes.clear()
144 ..appendText(deltaBlue)
145 ..contentEditable = 'true';
146 });
147 });
148 }));
149
150 benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
151 inputPre.contentEditable = 'false';
152 LinkElement link = query('link[rel="benchmark-Richards"]');
153 String richardsUri = link.href;
154 link = query('link[rel="benchmark-base"]');
155 String benchmarkBaseUri = link.href;
156 HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
157 HttpRequest.getString(richardsUri).then((String richards) {
158 benchmarkBase = benchmarkBase.replaceFirst(
159 'part of benchmark_harness;', '// part of benchmark_harness;');
160 richards = richards.replaceFirst(
161 "import 'package:benchmark_harness/benchmark_harness.dart';",
162 benchmarkBase);
163 inputPre
164 ..nodes.clear()
165 ..appendText(richards)
166 ..contentEditable = 'true';
167 });
168 });
169 }));
170
171 // TODO(ahe): Update currentSample. Or try switching to a drop-down menu.
172 var active = inspirationTabs.query('[id="$currentSample"]');
173 if (active == null) {
174 // inspirationTabs.query('li').classes.add('active');
175 }
176 98
177 (inputPre = new DivElement()) 99 (inputPre = new DivElement())
178 ..classes.add('well') 100 ..classes.add('well')
179 ..style.backgroundColor = currentTheme.background.color 101 ..style.backgroundColor = currentTheme.background.color
180 ..style.color = currentTheme.foreground.color 102 ..style.color = currentTheme.foreground.color
181 ..style.overflow = 'auto' 103 ..style.overflow = 'visible'
182 ..style.whiteSpace = 'pre' 104 ..style.whiteSpace = 'pre'
183 ..style.font = codeFont 105 ..style.font = codeFont
184 ..spellcheck = false; 106 ..spellcheck = false;
185 107
186 inputPre.contentEditable = 'true'; 108 inputPre
187 inputPre.onKeyDown.listen(onKeyUp); 109 ..contentEditable = 'true'
110 ..onKeyDown.listen(interaction.onKeyUp)
111 ..onInput.listen(interaction.onInput);
112
113 document.onSelectionChange.listen(interaction.onSelectionChange);
188 114
189 var inputWrapper = new DivElement() 115 var inputWrapper = new DivElement()
190 ..append(inputPre) 116 ..append(inputPre)
191 ..style.position = 'relative'; 117 ..style.position = 'relative';
192 118
193 var inputHeader = new DivElement()..appendText('Code'); 119 var inputHeader = new DivElement()..appendText('Code');
194 120
195 inputHeader.style 121 inputHeader.style
196 ..right = '3px' 122 ..right = '3px'
197 ..top = '0px' 123 ..top = '0px'
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 save.download = 'untitled.dart'; 160 save.download = 'untitled.dart';
235 save.dispatchEvent(new Event.eventType('Event', 'click')); 161 save.dispatchEvent(new Event.eventType('Event', 'click'));
236 }) 162 })
237 ..style.position = 'absolute' 163 ..style.position = 'absolute'
238 ..style.right = '0px' 164 ..style.right = '0px'
239 ..appendText('Save'); 165 ..appendText('Save');
240 166
241 cacheStatusElement = document.getElementById('appcache-status'); 167 cacheStatusElement = document.getElementById('appcache-status');
242 updateCacheStatus(); 168 updateCacheStatus();
243 169
244 // TODO(ahe): Switch to two column layout so the console is on the right. 170 var section = document.querySelector('article[class="homepage"]>section');
245 var section = document.query('article[class="homepage"]>section');
246 171
247 DivElement tryColumn = document.getElementById('try-dart-column'); 172 DivElement tryColumn = document.getElementById('try-dart-column');
248 DivElement runColumn = document.getElementById('run-dart-column'); 173 DivElement runColumn = document.getElementById('run-dart-column');
249 174
250 tryColumn.append(inputWrapper); 175 tryColumn.append(inputWrapper);
251 outputFrame.style.display = 'none'; 176 outputFrame.style.display = 'none';
252 runColumn.append(outputFrame); 177 runColumn.append(outputFrame);
253 runColumn.append(outputWrapper); 178 runColumn.append(outputWrapper);
254 runColumn.append(hackDiv); 179 runColumn.append(hackDiv);
255 180
(...skipping 15 matching lines...) Expand all
271 if (scrollHeight > 0) { 196 if (scrollHeight > 0) {
272 outputFrame.style.height = '${scrollHeight}px'; 197 outputFrame.style.height = '${scrollHeight}px';
273 } 198 }
274 return; 199 return;
275 } 200 }
276 } 201 }
277 } 202 }
278 outputDiv.appendText('${event.data}\n'); 203 outputDiv.appendText('${event.data}\n');
279 }); 204 });
280 205
281 observer = new MutationObserver(onMutation) 206 observer = new MutationObserver(interaction.onMutation)
282 ..observe(inputPre, childList: true, characterData: true, subtree: true); 207 ..observe(inputPre, childList: true, characterData: true, subtree: true);
283 208
284 scheduleMicrotask(() { 209 scheduleMicrotask(() {
285 inputPre.appendText(window.localStorage['currentSource']); 210 inputPre.appendText(window.localStorage['currentSource']);
286 }); 211 });
287 212
288 // You cannot install event handlers on window.applicationCache 213 // You cannot install event handlers on window.applicationCache
289 // until the window has loaded. In dartium, that's later than this 214 // until the window has loaded. In dartium, that's later than this
290 // method is called. 215 // method is called.
291 window.onLoad.listen(onLoad); 216 window.onLoad.listen(onLoad);
292 217
293 // However, in dart2js, the window has already loaded, and onLoad is 218 // However, in dart2js, the window has already loaded, and onLoad is
294 // never called. 219 // never called.
295 onLoad(null); 220 onLoad(null);
296 } 221 }
297 222
223 buildCode(InteractionManager interaction) {
224 var codePicker =
225 document.getElementById('code-picker')
226 ..style.visibility = 'hidden'
227 ..onChange.listen(onCodeChange);
228 var htmlGroup = new OptGroupElement()..label = 'HTML';
229 var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';
230
231 new Future(() => HttpRequest.getString('project?list').then(
232 (String response) {
kasperl 2014/03/24 10:32:51 Maybe factor out the then and the catchError closu
ahe 2014/03/24 15:20:23 Yes. I'll rewrite this. I plan to get rid of the c
233 OptionElement none = new OptionElement()
234 ..appendText('--')
235 ..disabled = true;
236 codePicker.append(none);
237 for (String projectFile in JSON.decode(response)) {
238 codePicker.append(buildTab(projectFile, projectFile, (_) {
239 inputPre.contentEditable = 'false';
240 HttpRequest.getString('project/$projectFile').then((String text) {
241 inputPre
242 ..contentEditable = 'true'
243 ..nodes.clear();
244 observer.takeRecords();
245 inputPre.appendText(text);
246 });
247 }));
248 }
249 codePicker.style.visibility = 'visible';
250 codePicker.selectedIndex = 0;
251 })).catchError((error) {
252 codePicker.style.visibility = 'visible';
253 print(error);
254 OptionElement none = new OptionElement()
255 ..appendText('Pick an example')
256 ..disabled = true;
257 codePicker.append(none);
258
259 // codePicker.classes.addAll(['nav', 'nav-tabs']);
260 codePicker.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
261 inputPre
262 ..nodes.clear()
263 ..appendText(EXAMPLE_HELLO);
264 }));
265 codePicker.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
266 inputPre
267 ..nodes.clear()
268 ..appendText(EXAMPLE_FIBONACCI);
269 }));
270 codePicker.append(htmlGroup);
271 // TODO(ahe): Restore benchmarks.
272 // codePicker.append(benchmarkGroup);
273
274 htmlGroup.append(
275 buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
276 inputPre
277 ..nodes.clear()
278 ..appendText(EXAMPLE_HELLO_HTML);
279 }));
280 htmlGroup.append(
281 buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
282 inputPre
283 ..nodes.clear()
284 ..appendText(EXAMPLE_FIBONACCI_HTML);
285 }));
286 htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
287 inputPre
288 ..nodes.clear()
289 ..appendText(EXAMPLE_SUNFLOWER);
290 }));
291
292 benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
293 inputPre.contentEditable = 'false';
294 LinkElement link = querySelector('link[rel="benchmark-DeltaBlue"]');
295 String deltaBlueUri = link.href;
296 link = querySelector('link[rel="benchmark-base"]');
297 String benchmarkBaseUri = link.href;
298 HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
299 HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
300 benchmarkBase = benchmarkBase.replaceFirst(
301 'part of benchmark_harness;', '// part of benchmark_harness;');
302 deltaBlue = deltaBlue.replaceFirst(
303 "import 'package:benchmark_harness/benchmark_harness.dart';",
304 benchmarkBase);
305 inputPre
306 ..nodes.clear()
307 ..appendText(deltaBlue)
308 ..contentEditable = 'true';
309 });
310 });
311 }));
312
313 benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
314 inputPre.contentEditable = 'false';
315 LinkElement link = querySelector('link[rel="benchmark-Richards"]');
316 String richardsUri = link.href;
317 link = querySelector('link[rel="benchmark-base"]');
318 String benchmarkBaseUri = link.href;
319 HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
320 HttpRequest.getString(richardsUri).then((String richards) {
321 benchmarkBase = benchmarkBase.replaceFirst(
322 'part of benchmark_harness;', '// part of benchmark_harness;');
323 richards = richards.replaceFirst(
324 "import 'package:benchmark_harness/benchmark_harness.dart';",
325 benchmarkBase);
326 inputPre
327 ..nodes.clear()
328 ..appendText(richards)
329 ..contentEditable = 'true';
330 });
331 });
332 }));
333
334 codePicker.selectedIndex = 0;
335
336 // TODO(ahe): Update currentSample. Or try switching to a drop-down menu.
337 var active = codePicker.querySelector('[id="$currentSample"]');
338 if (active == null) {
339 // codePicker.query('li').classes.add('active');
kasperl 2014/03/24 10:32:51 ?
ahe 2014/03/24 15:20:23 Dead code.
340 }
341 });
342 }
343
344 num settingsHeight = 0;
345
298 void openSettings(MouseEvent event) { 346 void openSettings(MouseEvent event) {
299 event.preventDefault(); 347 event.preventDefault();
300 348
301 var backdrop = new DivElement()..classes.add('modal-backdrop'); 349 if (settingsHeight != 0) {
302 document.body.append(backdrop); 350 var dialog = document.getElementById('settings-dialog');
351 if (dialog.getBoundingClientRect().height > 0) {
352 dialog.style.height = '0px';
353 } else {
354 dialog.style.height = '${settingsHeight}px';
355 }
356 return;
357 }
303 358
304 void updateCodeFont(Event e) { 359 void updateCodeFont(Event e) {
305 TextInputElement target = e.target; 360 TextInputElement target = e.target;
306 codeFont = target.value; 361 codeFont = target.value;
307 inputPre.style.font = codeFont; 362 inputPre.style.font = codeFont;
308 backdrop.style.opacity = '0.0';
309 } 363 }
310 364
311 void updateTheme(Event e) { 365 void updateTheme(Event e) {
312 var select = e.target; 366 var select = e.target;
313 String theme = select.queryAll('option')[select.selectedIndex].text; 367 String theme = select.queryAll('option')[select.selectedIndex].text;
314 window.localStorage['theme'] = theme; 368 window.localStorage['theme'] = theme;
315 currentTheme = Theme.named(theme); 369 currentTheme = Theme.named(theme);
316 370
317 inputPre.style 371 inputPre.style
318 ..backgroundColor = currentTheme.background.color 372 ..backgroundColor = currentTheme.background.color
319 ..color = currentTheme.foreground.color; 373 ..color = currentTheme.foreground.color;
320 374
321 outputDiv.style 375 outputDiv.style
322 ..backgroundColor = currentTheme.background.color 376 ..backgroundColor = currentTheme.background.color
323 ..color = currentTheme.foreground.color; 377 ..color = currentTheme.foreground.color;
324 378
325 backdrop.style.opacity = '0.0'; 379 bool oldCompilationPaused = compilationPaused;
326 380 compilationPaused = true;
327 applyingSettings = true; 381 interaction.onMutation([], observer);
kasperl 2014/03/24 10:32:51 Worried about exceptions here at all? try-finally?
ahe 2014/03/24 15:20:23 onMutation has to be robust. When it throws an exc
328 onMutation([], observer); 382 compilationPaused = false;
329 applyingSettings = false;
330 } 383 }
331 384
332
333 var body = document.getElementById('settings-body'); 385 var body = document.getElementById('settings-body');
334 386
335 body.nodes.clear(); 387 body.nodes.clear();
336 388
337 var form = new FormElement(); 389 var form = new FormElement();
338 var fieldSet = new FieldSetElement(); 390 var fieldSet = new FieldSetElement();
339 body.append(form); 391 body.append(form);
340 form.append(fieldSet); 392 form.append(fieldSet);
341 393
342 buildCheckBox(String text, bool defaultValue, void action(Event e)) { 394 bool isChecked(CheckboxInputElement checkBox) => checkBox.checked;
343 var checkBox = new CheckboxInputElement() 395
344 // TODO(ahe): Used to be ..defaultChecked = defaultValue 396 String messageFor(UserOption option) {
345 ..checked = defaultValue 397 var message = messages[option.name];
346 ..onChange.listen(action); 398 if (message is List) message = message[0];
347 return new LabelElement() 399 return (message == null) ? option.name : message;
400 }
401
402 String placeHolderFor(UserOption option) {
403 var message = messages[option.name];
404 if (message is! List) return '';
405 message = message[1];
406 return (message == null) ? '' : message;
407 }
408
409 void addBooleanOption(BooleanUserOption option) {
410 CheckboxInputElement checkBox = new CheckboxInputElement()
411 ..checked = option.value
412 ..onChange.listen((Event e) { option.value = isChecked(e.target); });
413
414 LabelElement label = new LabelElement()
348 ..classes.add('checkbox') 415 ..classes.add('checkbox')
349 ..append(checkBox) 416 ..append(checkBox)
350 ..appendText(' $text'); 417 ..appendText(' ${messageFor(option)}');
418
419 fieldSet.append(label);
351 } 420 }
352 421
353 bool isChecked(CheckboxInputElement checkBox) => checkBox.checked; 422 void addStringOption(StringUserOption option) {
423 fieldSet.append(new LabelElement()..appendText(messageFor(option)));
424 var textInput = new TextInputElement();
425 textInput.classes.add('input-block-level');
426 String value = option.value;
427 if (!value.isEmpty) {
428 textInput.value = value;
429 }
430 textInput.placeholder = placeHolderFor(option);;
431 textInput.onChange.listen(updateCodeFont);
432 fieldSet.append(textInput);
433 }
354 434
355 // TODO(ahe): Build abstraction for flags/options. 435 void addThemeOption(StringUserOption option) {
356 fieldSet.append( 436 fieldSet.append(new LabelElement()..appendText('Theme:'));
357 buildCheckBox( 437 var themeSelector = new SelectElement();
358 'Always run in Worker thread.', alwaysRunInWorker, 438 themeSelector.classes.add('input-block-level');
359 (Event e) { alwaysRunInWorker = isChecked(e.target); })); 439 for (Theme theme in THEMES) {
440 OptionElement option = new OptionElement()..appendText(theme.name);
441 if (theme == currentTheme) option.selected = true;
442 themeSelector.append(option);
443 }
444 themeSelector.onChange.listen(updateTheme);
445 fieldSet.append(themeSelector);
446 }
360 447
361 fieldSet.append( 448 for (UserOption option in options) {
362 buildCheckBox( 449 if (option.isHidden) continue;
363 'Verbose compiler output.', verboseCompiler, 450 if (option.name == 'theme') {
364 (Event e) { verboseCompiler = isChecked(e.target); })); 451 addThemeOption(option);
365 452 } else if (option is BooleanUserOption) {
366 fieldSet.append( 453 addBooleanOption(option);
367 buildCheckBox( 454 } else if (option is StringUserOption) {
368 'Generate compact (minified) JavaScript.', minified, 455 addStringOption(option);
369 (Event e) { minified = isChecked(e.target); })); 456 }
370
371 fieldSet.append(
372 buildCheckBox(
373 'Only analyze program.', onlyAnalyze,
374 (Event e) { onlyAnalyze = isChecked(e.target); }));
375
376 fieldSet.append(new LabelElement()..appendText('Code font:'));
377 var textInput = new TextInputElement();
378 textInput.classes.add('input-block-level');
379 if (codeFont != null && codeFont != '') {
380 textInput.value = codeFont;
381 } 457 }
382 textInput.placeholder = 'Enter a size and font, for example, 11pt monospace';
383 textInput.onChange.listen(updateCodeFont);
384 fieldSet.append(textInput);
385
386 fieldSet.append(new LabelElement()..appendText('Theme:'));
387 var themeSelector = new SelectElement();
388 themeSelector.classes.add('input-block-level');
389 for (Theme theme in THEMES) {
390 OptionElement option = new OptionElement()..appendText(theme.name);
391 if (theme == currentTheme) option.selected = true;
392 themeSelector.append(option);
393 }
394 themeSelector.onChange.listen(updateTheme);
395 fieldSet.append(themeSelector);
396 458
397 var dialog = document.getElementById('settings-dialog'); 459 var dialog = document.getElementById('settings-dialog');
398 460
399 dialog.style.display = 'block'; 461 if (settingsHeight == 0) {
400 dialog.classes.add('in'); 462 settingsHeight = dialog.getBoundingClientRect().height;
463 dialog.classes
464 ..add('slider')
465 ..remove('myhidden');
466 Timer.run(() {
467 dialog.style.height = '${settingsHeight}px';
468 });
469 } else {
470 dialog.style.height = '${settingsHeight}px';
471 }
401 472
402 onSubmit(Event event) { 473 onSubmit(Event event) {
403 event.preventDefault(); 474 event.preventDefault();
404 475
405 window.localStorage['alwaysRunInWorker'] = '$alwaysRunInWorker'; 476 window.localStorage['alwaysRunInWorker'] = '$alwaysRunInWorker';
406 window.localStorage['verboseCompiler'] = '$verboseCompiler'; 477 window.localStorage['verboseCompiler'] = '$verboseCompiler';
407 window.localStorage['minified'] = '$minified'; 478 window.localStorage['minified'] = '$minified';
408 window.localStorage['onlyAnalyze'] = '$onlyAnalyze'; 479 window.localStorage['onlyAnalyze'] = '$onlyAnalyze';
480 window.localStorage['enableDartMind'] = '$enableDartMind';
481 window.localStorage['compilationPaused'] = '$compilationPaused';
409 window.localStorage['codeFont'] = '$codeFont'; 482 window.localStorage['codeFont'] = '$codeFont';
410 483
411 dialog.style.display = 'none'; 484 dialog.style.height = '0px';
412 dialog.classes.remove('in');
413 backdrop.remove();
414 } 485 }
415 form.onSubmit.listen(onSubmit); 486 form.onSubmit.listen(onSubmit);
416 487
417 var doneButton = document.getElementById('settings-done'); 488 var doneButton = document.getElementById('settings-done');
418 doneButton.onClick.listen(onSubmit); 489 doneButton.onClick.listen(onSubmit);
419 } 490 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698