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

Unified 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: Merged with r34309. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dart/site/try/src/settings.dart ('k') | dart/site/try/src/user_option.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/site/try/src/ui.dart
diff --git a/dart/site/try/src/ui.dart b/dart/site/try/src/ui.dart
index 65d66201191468afb3b91ba6a161c619e261d45c..d954d1823556f790586fe9c0c0b78d617e92c5a4 100644
--- a/dart/site/try/src/ui.dart
+++ b/dart/site/try/src/ui.dart
@@ -7,15 +7,17 @@ library trydart.ui;
import 'dart:html';
import 'dart:async' show
+ Future,
+ Timer,
scheduleMicrotask;
+import 'dart:convert' show JSON;
+
import 'cache.dart' show
onLoad,
updateCacheStatus;
-import 'editor.dart' show
- onKeyUp,
- onMutation;
+import 'interaction_manager.dart' show InteractionManager;
import 'run.dart' show
makeOutputFrame;
@@ -31,21 +33,23 @@ import 'samples.dart' show
EXAMPLE_HELLO_HTML,
EXAMPLE_SUNFLOWER;
+import 'settings.dart';
+
+import 'user_option.dart';
+
+import 'messages.dart' show messages;
+
+// TODO(ahe): Make internal to buildUI once all interactions have been moved to
+// the manager.
+InteractionManager interaction;
+
DivElement inputPre;
PreElement outputDiv;
DivElement hackDiv;
IFrameElement outputFrame;
MutationObserver observer;
SpanElement cacheStatusElement;
-bool alwaysRunInWorker = window.localStorage['alwaysRunInWorker'] == 'true';
-bool verboseCompiler = window.localStorage['verboseCompiler'] == 'true';
-bool minified = window.localStorage['minified'] == 'true';
-bool onlyAnalyze = window.localStorage['onlyAnalyze'] == 'true';
-final String rawCodeFont = window.localStorage['codeFont'];
-String codeFont = rawCodeFont == null ? '' : rawCodeFont;
-String currentSample = window.localStorage['currentSample'];
-Theme currentTheme = Theme.named(window.localStorage['theme']);
-bool applyingSettings = false;
+Theme currentTheme = Theme.named(theme);
buildButton(message, action) {
if (message is String) {
@@ -65,126 +69,48 @@ buildTab(message, id, action) {
event.preventDefault();
Element e = event.target;
LIElement parent = e.parent;
- parent.parent.query('li[class="active"]').classes.remove('active');
+ parent.parent.querySelector('li[class="active"]').classes.remove('active');
parent.classes.add('active');
action(event);
}
- inspirationCallbacks[id] = action;
+ codeCallbacks[id] = action;
return new OptionElement()..append(message)..id = id;
}
-Map<String, Function> inspirationCallbacks = new Map<String, Function>();
+Map<String, Function> codeCallbacks = new Map<String, Function>();
-void onInspirationChange(Event event) {
+void onCodeChange(Event event) {
SelectElement select = event.target;
- String id = select.queryAll('option')[select.selectedIndex].id;
- Function action = inspirationCallbacks[id];
+ String id = select.querySelectorAll('option')[select.selectedIndex].id;
+ Function action = codeCallbacks[id];
if (action != null) action(event);
outputFrame.style.display = 'none';
}
buildUI() {
- window.localStorage['currentSample'] = '$currentSample';
+ interaction = new InteractionManager();
- var inspirationTabs = document.getElementById('inspiration');
- var htmlGroup = new OptGroupElement()..label = 'HTML';
- var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';
- inspirationTabs.append(new OptionElement()..appendText('Pick an example'));
- inspirationTabs.onChange.listen(onInspirationChange);
- // inspirationTabs.classes.addAll(['nav', 'nav-tabs']);
- inspirationTabs.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
- inputPre
- ..nodes.clear()
- ..appendText(EXAMPLE_HELLO);
- }));
- inspirationTabs.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
- inputPre
- ..nodes.clear()
- ..appendText(EXAMPLE_FIBONACCI);
- }));
- inspirationTabs.append(htmlGroup);
- // TODO(ahe): Restore benchmarks.
- // inspirationTabs.append(benchmarkGroup);
-
- htmlGroup.append(
- buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
- inputPre
- ..nodes.clear()
- ..appendText(EXAMPLE_HELLO_HTML);
- }));
- htmlGroup.append(
- buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
- inputPre
- ..nodes.clear()
- ..appendText(EXAMPLE_FIBONACCI_HTML);
- }));
- htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
- inputPre
- ..nodes.clear()
- ..appendText(EXAMPLE_SUNFLOWER);
- }));
-
- benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
- inputPre.contentEditable = 'false';
- LinkElement link = query('link[rel="benchmark-DeltaBlue"]');
- String deltaBlueUri = link.href;
- link = query('link[rel="benchmark-base"]');
- String benchmarkBaseUri = link.href;
- HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
- HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
- benchmarkBase = benchmarkBase.replaceFirst(
- 'part of benchmark_harness;', '// part of benchmark_harness;');
- deltaBlue = deltaBlue.replaceFirst(
- "import 'package:benchmark_harness/benchmark_harness.dart';",
- benchmarkBase);
- inputPre
- ..nodes.clear()
- ..appendText(deltaBlue)
- ..contentEditable = 'true';
- });
- });
- }));
-
- benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
- inputPre.contentEditable = 'false';
- LinkElement link = query('link[rel="benchmark-Richards"]');
- String richardsUri = link.href;
- link = query('link[rel="benchmark-base"]');
- String benchmarkBaseUri = link.href;
- HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
- HttpRequest.getString(richardsUri).then((String richards) {
- benchmarkBase = benchmarkBase.replaceFirst(
- 'part of benchmark_harness;', '// part of benchmark_harness;');
- richards = richards.replaceFirst(
- "import 'package:benchmark_harness/benchmark_harness.dart';",
- benchmarkBase);
- inputPre
- ..nodes.clear()
- ..appendText(richards)
- ..contentEditable = 'true';
- });
- });
- }));
+ window.localStorage['currentSample'] = '$currentSample';
- // TODO(ahe): Update currentSample. Or try switching to a drop-down menu.
- var active = inspirationTabs.query('[id="$currentSample"]');
- if (active == null) {
- // inspirationTabs.query('li').classes.add('active');
- }
+ buildCode(interaction);
(inputPre = new DivElement())
..classes.add('well')
..style.backgroundColor = currentTheme.background.color
..style.color = currentTheme.foreground.color
- ..style.overflow = 'auto'
+ ..style.overflow = 'visible'
..style.whiteSpace = 'pre'
..style.font = codeFont
..spellcheck = false;
- inputPre.contentEditable = 'true';
- inputPre.onKeyDown.listen(onKeyUp);
+ inputPre
+ ..contentEditable = 'true'
+ ..onKeyDown.listen(interaction.onKeyUp)
+ ..onInput.listen(interaction.onInput);
+
+ document.onSelectionChange.listen(interaction.onSelectionChange);
var inputWrapper = new DivElement()
..append(inputPre)
@@ -241,8 +167,7 @@ buildUI() {
cacheStatusElement = document.getElementById('appcache-status');
updateCacheStatus();
- // TODO(ahe): Switch to two column layout so the console is on the right.
- var section = document.query('article[class="homepage"]>section');
+ var section = document.querySelector('article[class="homepage"]>section');
DivElement tryColumn = document.getElementById('try-dart-column');
DivElement runColumn = document.getElementById('run-dart-column');
@@ -278,7 +203,7 @@ buildUI() {
outputDiv.appendText('${event.data}\n');
});
- observer = new MutationObserver(onMutation)
+ observer = new MutationObserver(interaction.onMutation)
..observe(inputPre, childList: true, characterData: true, subtree: true);
scheduleMicrotask(() {
@@ -295,17 +220,140 @@ buildUI() {
onLoad(null);
}
+buildCode(InteractionManager interaction) {
+ var codePicker =
+ document.getElementById('code-picker')
+ ..style.visibility = 'hidden'
+ ..onChange.listen(onCodeChange);
+ var htmlGroup = new OptGroupElement()..label = 'HTML';
+ var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';
+
+ new Future(() => HttpRequest.getString('project?list').then(
+ (String response) {
+ OptionElement none = new OptionElement()
+ ..appendText('--')
+ ..disabled = true;
+ codePicker.append(none);
+ for (String projectFile in JSON.decode(response)) {
+ codePicker.append(buildTab(projectFile, projectFile, (_) {
+ inputPre.contentEditable = 'false';
+ HttpRequest.getString('project/$projectFile').then((String text) {
+ inputPre
+ ..contentEditable = 'true'
+ ..nodes.clear();
+ observer.takeRecords();
+ inputPre.appendText(text);
+ });
+ }));
+ }
+ codePicker.style.visibility = 'visible';
+ codePicker.selectedIndex = 0;
+ })).catchError((error) {
+ codePicker.style.visibility = 'visible';
+ print(error);
+ OptionElement none = new OptionElement()
+ ..appendText('Pick an example')
+ ..disabled = true;
+ codePicker.append(none);
+
+ // codePicker.classes.addAll(['nav', 'nav-tabs']);
+ codePicker.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
+ inputPre
+ ..nodes.clear()
+ ..appendText(EXAMPLE_HELLO);
+ }));
+ codePicker.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
+ inputPre
+ ..nodes.clear()
+ ..appendText(EXAMPLE_FIBONACCI);
+ }));
+ codePicker.append(htmlGroup);
+ // TODO(ahe): Restore benchmarks.
+ // codePicker.append(benchmarkGroup);
+
+ htmlGroup.append(
+ buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
+ inputPre
+ ..nodes.clear()
+ ..appendText(EXAMPLE_HELLO_HTML);
+ }));
+ htmlGroup.append(
+ buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
+ inputPre
+ ..nodes.clear()
+ ..appendText(EXAMPLE_FIBONACCI_HTML);
+ }));
+ htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
+ inputPre
+ ..nodes.clear()
+ ..appendText(EXAMPLE_SUNFLOWER);
+ }));
+
+ benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
+ inputPre.contentEditable = 'false';
+ LinkElement link = querySelector('link[rel="benchmark-DeltaBlue"]');
+ String deltaBlueUri = link.href;
+ link = querySelector('link[rel="benchmark-base"]');
+ String benchmarkBaseUri = link.href;
+ HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
+ HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
+ benchmarkBase = benchmarkBase.replaceFirst(
+ 'part of benchmark_harness;', '// part of benchmark_harness;');
+ deltaBlue = deltaBlue.replaceFirst(
+ "import 'package:benchmark_harness/benchmark_harness.dart';",
+ benchmarkBase);
+ inputPre
+ ..nodes.clear()
+ ..appendText(deltaBlue)
+ ..contentEditable = 'true';
+ });
+ });
+ }));
+
+ benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
+ inputPre.contentEditable = 'false';
+ LinkElement link = querySelector('link[rel="benchmark-Richards"]');
+ String richardsUri = link.href;
+ link = querySelector('link[rel="benchmark-base"]');
+ String benchmarkBaseUri = link.href;
+ HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
+ HttpRequest.getString(richardsUri).then((String richards) {
+ benchmarkBase = benchmarkBase.replaceFirst(
+ 'part of benchmark_harness;', '// part of benchmark_harness;');
+ richards = richards.replaceFirst(
+ "import 'package:benchmark_harness/benchmark_harness.dart';",
+ benchmarkBase);
+ inputPre
+ ..nodes.clear()
+ ..appendText(richards)
+ ..contentEditable = 'true';
+ });
+ });
+ }));
+
+ codePicker.selectedIndex = 0;
+ });
+}
+
+num settingsHeight = 0;
+
void openSettings(MouseEvent event) {
event.preventDefault();
- var backdrop = new DivElement()..classes.add('modal-backdrop');
- document.body.append(backdrop);
+ if (settingsHeight != 0) {
+ var dialog = document.getElementById('settings-dialog');
+ if (dialog.getBoundingClientRect().height > 0) {
+ dialog.style.height = '0px';
+ } else {
+ dialog.style.height = '${settingsHeight}px';
+ }
+ return;
+ }
void updateCodeFont(Event e) {
TextInputElement target = e.target;
codeFont = target.value;
inputPre.style.font = codeFont;
- backdrop.style.opacity = '0.0';
}
void updateTheme(Event e) {
@@ -322,14 +370,12 @@ void openSettings(MouseEvent event) {
..backgroundColor = currentTheme.background.color
..color = currentTheme.foreground.color;
- backdrop.style.opacity = '0.0';
-
- applyingSettings = true;
- onMutation([], observer);
- applyingSettings = false;
+ bool oldCompilationPaused = compilationPaused;
+ compilationPaused = true;
+ interaction.onMutation([], observer);
+ compilationPaused = false;
}
-
var body = document.getElementById('settings-body');
body.nodes.clear();
@@ -339,65 +385,84 @@ void openSettings(MouseEvent event) {
body.append(form);
form.append(fieldSet);
- buildCheckBox(String text, bool defaultValue, void action(Event e)) {
- var checkBox = new CheckboxInputElement()
- // TODO(ahe): Used to be ..defaultChecked = defaultValue
- ..checked = defaultValue
- ..onChange.listen(action);
- return new LabelElement()
+ bool isChecked(CheckboxInputElement checkBox) => checkBox.checked;
+
+ String messageFor(UserOption option) {
+ var message = messages[option.name];
+ if (message is List) message = message[0];
+ return (message == null) ? option.name : message;
+ }
+
+ String placeHolderFor(UserOption option) {
+ var message = messages[option.name];
+ if (message is! List) return '';
+ message = message[1];
+ return (message == null) ? '' : message;
+ }
+
+ void addBooleanOption(BooleanUserOption option) {
+ CheckboxInputElement checkBox = new CheckboxInputElement()
+ ..checked = option.value
+ ..onChange.listen((Event e) { option.value = isChecked(e.target); });
+
+ LabelElement label = new LabelElement()
..classes.add('checkbox')
..append(checkBox)
- ..appendText(' $text');
+ ..appendText(' ${messageFor(option)}');
+
+ fieldSet.append(label);
}
- bool isChecked(CheckboxInputElement checkBox) => checkBox.checked;
+ void addStringOption(StringUserOption option) {
+ fieldSet.append(new LabelElement()..appendText(messageFor(option)));
+ var textInput = new TextInputElement();
+ textInput.classes.add('input-block-level');
+ String value = option.value;
+ if (!value.isEmpty) {
+ textInput.value = value;
+ }
+ textInput.placeholder = placeHolderFor(option);;
+ textInput.onChange.listen(updateCodeFont);
+ fieldSet.append(textInput);
+ }
- // TODO(ahe): Build abstraction for flags/options.
- fieldSet.append(
- buildCheckBox(
- 'Always run in Worker thread.', alwaysRunInWorker,
- (Event e) { alwaysRunInWorker = isChecked(e.target); }));
-
- fieldSet.append(
- buildCheckBox(
- 'Verbose compiler output.', verboseCompiler,
- (Event e) { verboseCompiler = isChecked(e.target); }));
-
- fieldSet.append(
- buildCheckBox(
- 'Generate compact (minified) JavaScript.', minified,
- (Event e) { minified = isChecked(e.target); }));
-
- fieldSet.append(
- buildCheckBox(
- 'Only analyze program.', onlyAnalyze,
- (Event e) { onlyAnalyze = isChecked(e.target); }));
-
- fieldSet.append(new LabelElement()..appendText('Code font:'));
- var textInput = new TextInputElement();
- textInput.classes.add('input-block-level');
- if (codeFont != null && codeFont != '') {
- textInput.value = codeFont;
+ void addThemeOption(StringUserOption option) {
+ fieldSet.append(new LabelElement()..appendText('Theme:'));
+ var themeSelector = new SelectElement();
+ themeSelector.classes.add('input-block-level');
+ for (Theme theme in THEMES) {
+ OptionElement option = new OptionElement()..appendText(theme.name);
+ if (theme == currentTheme) option.selected = true;
+ themeSelector.append(option);
+ }
+ themeSelector.onChange.listen(updateTheme);
+ fieldSet.append(themeSelector);
}
- textInput.placeholder = 'Enter a size and font, for example, 11pt monospace';
- textInput.onChange.listen(updateCodeFont);
- fieldSet.append(textInput);
-
- fieldSet.append(new LabelElement()..appendText('Theme:'));
- var themeSelector = new SelectElement();
- themeSelector.classes.add('input-block-level');
- for (Theme theme in THEMES) {
- OptionElement option = new OptionElement()..appendText(theme.name);
- if (theme == currentTheme) option.selected = true;
- themeSelector.append(option);
+
+ for (UserOption option in options) {
+ if (option.isHidden) continue;
+ if (option.name == 'theme') {
+ addThemeOption(option);
+ } else if (option is BooleanUserOption) {
+ addBooleanOption(option);
+ } else if (option is StringUserOption) {
+ addStringOption(option);
+ }
}
- themeSelector.onChange.listen(updateTheme);
- fieldSet.append(themeSelector);
var dialog = document.getElementById('settings-dialog');
- dialog.style.display = 'block';
- dialog.classes.add('in');
+ if (settingsHeight == 0) {
+ settingsHeight = dialog.getBoundingClientRect().height;
+ dialog.classes
+ ..add('slider')
+ ..remove('myhidden');
+ Timer.run(() {
+ dialog.style.height = '${settingsHeight}px';
+ });
+ } else {
+ dialog.style.height = '${settingsHeight}px';
+ }
onSubmit(Event event) {
event.preventDefault();
@@ -406,11 +471,11 @@ void openSettings(MouseEvent event) {
window.localStorage['verboseCompiler'] = '$verboseCompiler';
window.localStorage['minified'] = '$minified';
window.localStorage['onlyAnalyze'] = '$onlyAnalyze';
+ window.localStorage['enableDartMind'] = '$enableDartMind';
+ window.localStorage['compilationPaused'] = '$compilationPaused';
window.localStorage['codeFont'] = '$codeFont';
- dialog.style.display = 'none';
- dialog.classes.remove('in');
- backdrop.remove();
+ dialog.style.height = '0px';
}
form.onSubmit.listen(onSubmit);
« no previous file with comments | « dart/site/try/src/settings.dart ('k') | dart/site/try/src/user_option.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698