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

Unified Diff: lib/runtime/messages_widget.dart

Issue 988483006: Add widget to display errors, and report dependency_graph errors correctly (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 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
Index: lib/runtime/messages_widget.dart
diff --git a/lib/runtime/messages_widget.dart b/lib/runtime/messages_widget.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4c4d24882d24e97bdfa9e00dea8cf73921540158
--- /dev/null
+++ b/lib/runtime/messages_widget.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
Siggi Cherem (dart-lang) 2015/03/07 02:43:01 this is adapted from the code in polymer. Simplifi
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library provides a single function called injectLogs which when called
+/// will request a logs json file and build a small widget out of them which
+/// groups the logs by level.
+library polymer.build.log_injector;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
+
+import 'package:path/path.dart' as path;
+import 'package:source_span/source_span.dart';
+import 'package:dev_compiler/src/summary.dart';
+
+main() async => displayMessages(await HttpRequest.getString('messages.json'));
+
+void displayMessages(String data) {
+ var summary = GlobalSummary.parse(JSON.decode(data));
+ var messagesByLevel = _getMessagesByLevel(summary);
+ if (messagesByLevel.isEmpty) return;
+
+ // Build the wrapper, menu, and content divs.
+ var menuWrapper = new DivElement()..classes.add('menu');
+ var contentWrapper = new DivElement()..classes.add('content');
+ var wrapperDiv = new DivElement()
+ ..classes.add('dev-compiler-messages')
+ ..append(menuWrapper)
+ ..append(contentWrapper);
+
+ var selectedMenu = new _Selection();
+ var selectedContent = new _Selection();
+
+ // Add a menu item, content section, and messages for each log level.
+ messagesByLevel.forEach((level, messages) {
+ var contentItem = new DivElement()..classes.add(level);
+ var menuItem = new Element.html('<div class="$level">'
+ '$level <span class="num">(${messages.length})</span>'
+ '</div>');
+ menuWrapper.append(menuItem);
+ contentWrapper.append(contentItem);
+ menuItem.onClick.listen((_) {
+ selectedMenu.select(menuItem);
+ selectedContent.select(contentItem);
+ });
+
+ // TODO(sigmund): add permanent links to error messages like in polymer.
+ for (var m in messages) {
+ var message = _hyperlinkUrls(_escape(m.message));
+ var span = m.span;
+ var sb = new StringBuffer();
+ sb.write('<div class="message"><div class="text $level">$message</div>');
+ if (span != null) {
+ sb.write('<div class="location">'
+ ' <span class="location">${span.start.toolString}</span></div>'
+ ' <span class="text">${_escape(span.text)}</span></div></div>');
+ }
+ sb.write('</div>');
+
+ var logElement = new Element.html('$sb',
+ validator: new NodeValidatorBuilder.common()
+ ..allowNavigation(new _OpenUriPolicy()));
+ contentItem.append(logElement);
+ var messageElement = logElement.querySelector('div.text');
+ messageElement.onClick.listen((e) {
+ if (e.target == messageElement) {
+ messageElement.classes.toggle('expanded');
+ }
+ });
+ }
+ });
+
+ document.body.append(wrapperDiv);
+}
+
+/// Toggles classes to match which item of a list of items is selected.
+class _Selection {
+ Element _selected;
+
+ select(Element newItem) {
+ if (_selected == newItem) {
+ _selected = null;
+ } else {
+ if (_selected != null) {
+ _selected.classes.remove('active');
+ }
+ _selected = newItem;
+ }
+ newItem.classes.toggle('active');
+ }
+}
+
+final _urlRegex = new RegExp('http://[^ ]*');
+final _escaper = new HtmlEscape();
+String _hyperlinkUrls(String text) => text.replaceAllMapped(_urlRegex,
+ (m) => '<a href="${m.group(0)}" target="blank">${m.group(0)}</a>');
+String _escape(String text) => _escaper.convert(text);
+
+class _OpenUriPolicy implements UriPolicy {
+ bool allowsUri(String uri) => true;
+}
+
+Map<String, List<MessageSummary>> _getMessagesByLevel(GlobalSummary messages) {
+ var visitor = new _Visitor();
+ messages.accept(visitor);
+ return visitor.messagesByLevel;
+}
+
+class _Visitor extends RecursiveSummaryVisitor {
+ final Map<String, List<MessageSummary>> messagesByLevel = {};
+
+ @override
+ void visitMessage(MessageSummary message) {
+ var level = message.level.toLowerCase();
+ messagesByLevel.putIfAbsent(level, () => []);
+ messagesByLevel[level].add(message);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698