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

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

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

Powered by Google App Engine
This is Rietveld 408576698