[results feed] Add links to Github issues in comments.
Support links like #20497 or "co19 #479" in comments.
Also support '\n' for line breaks in comments.
Change-Id: If86d3da68ea5ab9815149ee4fa73fd28c2afa4d6
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/133067
Reviewed-by: Jonas Termansen <sortie@google.com>
diff --git a/results_feed/lib/src/components/blamelist_component.dart b/results_feed/lib/src/components/blamelist_component.dart
index a1de2ab..2368b80 100644
--- a/results_feed/lib/src/components/blamelist_component.dart
+++ b/results_feed/lib/src/components/blamelist_component.dart
@@ -1,5 +1,6 @@
import 'package:angular/angular.dart';
import 'package:angular_components/laminate/enums/alignment.dart';
+import 'package:angular_components/simple_html/simple_html.dart';
import 'package:angular_forms/angular_forms.dart';
import '../formatting.dart';
@@ -8,7 +9,12 @@
@Component(
selector: 'blamelist-panel',
- directives: [coreDirectives, formDirectives, RelativePosition],
+ directives: [
+ coreDirectives,
+ formDirectives,
+ RelativePosition,
+ SimpleHtmlComponent,
+ ],
templateUrl: 'blamelist_component.html',
styleUrls: ['blamelist.css'],
exports: [formattedDate, formattedEmail])
diff --git a/results_feed/lib/src/components/blamelist_component.html b/results_feed/lib/src/components/blamelist_component.html
index b900c21..22d6c6e 100644
--- a/results_feed/lib/src/components/blamelist_component.html
+++ b/results_feed/lib/src/components/blamelist_component.html
@@ -16,6 +16,6 @@
<b>{{c.approvedText()}}</b>
<span class="nowrap">{{formattedDate(c.created)}}</span>
{{formattedEmail(c.author)}}<br>
- <div class="comment-body">{{c.comment}}</div>
+ <simple-html class="comment-body" [contents]="c.commentHtml"></simple-html>
</div>
</div>
diff --git a/results_feed/lib/src/components/blamelist_picker.dart b/results_feed/lib/src/components/blamelist_picker.dart
index a741ff5..9b4febc 100644
--- a/results_feed/lib/src/components/blamelist_picker.dart
+++ b/results_feed/lib/src/components/blamelist_picker.dart
@@ -6,9 +6,10 @@
import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
-import 'package:angular_forms/angular_forms.dart' show formDirectives;
import 'package:angular_components/material_radio/material_radio.dart';
import 'package:angular_components/material_radio/material_radio_group.dart';
+import 'package:angular_components/simple_html/simple_html.dart';
+import 'package:angular_forms/angular_forms.dart' show formDirectives;
import '../formatting.dart';
import '../model/comment.dart';
@@ -21,6 +22,7 @@
formDirectives,
MaterialRadioComponent,
MaterialRadioGroupComponent,
+ SimpleHtmlComponent,
],
templateUrl: 'blamelist_picker.html',
styleUrls: ([
diff --git a/results_feed/lib/src/components/blamelist_picker.html b/results_feed/lib/src/components/blamelist_picker.html
index b953576..33fc389 100644
--- a/results_feed/lib/src/components/blamelist_picker.html
+++ b/results_feed/lib/src/components/blamelist_picker.html
@@ -14,6 +14,6 @@
<b>{{c.approvedText()}}</b>
<span class="nowrap">{{formattedDate(c.created)}}</span><br>
{{formattedEmail(c.author)}}
- <div class="comment-body">{{c.comment}}</div>
+ <simple-html class="comment-body" [contents]="c.commentHtml"></simple-html>
</div>
</material-radio-group>
diff --git a/results_feed/lib/src/components/commit_component.html b/results_feed/lib/src/components/commit_component.html
index d102395..5df426f 100644
--- a/results_feed/lib/src/components/commit_component.html
+++ b/results_feed/lib/src/components/commit_component.html
@@ -40,7 +40,8 @@
failuresOnly></results-selector-panel>
</div>
<div *ngIf="approving" class="commit-bottom">
- Comment:<br>
+ Comment: (type #4567 for GitHub SDK issue 4567,
+ or co19 #123 for a co19 issue. Use \n for newline.)<br>
<material-input
multiline
label="Comment"
diff --git a/results_feed/lib/src/components/try_results_component.dart b/results_feed/lib/src/components/try_results_component.dart
index e4858fc..39796f3 100644
--- a/results_feed/lib/src/components/try_results_component.dart
+++ b/results_feed/lib/src/components/try_results_component.dart
@@ -9,6 +9,7 @@
import 'package:angular_components/material_button/material_button.dart';
import 'package:angular_components/material_input/material_input.dart';
import 'package:angular_components/material_input/material_input_multiline.dart';
+import 'package:angular_components/simple_html/simple_html.dart';
import 'package:angular_forms/angular_forms.dart' show formDirectives;
import 'package:angular_router/angular_router.dart';
@@ -28,7 +29,8 @@
MaterialButtonComponent,
MaterialMultilineInputComponent,
ResultsPanel,
- ResultsSelectorPanel
+ ResultsSelectorPanel,
+ SimpleHtmlComponent,
],
providers: [
ClassProvider(TryDataService),
diff --git a/results_feed/lib/src/components/try_results_component.html b/results_feed/lib/src/components/try_results_component.html
index d1baf68..1b6dd3a 100644
--- a/results_feed/lib/src/components/try_results_component.html
+++ b/results_feed/lib/src/components/try_results_component.html
@@ -21,10 +21,12 @@
<b>{{c.approvedText()}}</b>
<span class="nowrap">{{formattedDate(c.created)}}</span>
{{formattedEmail(c.author)}}<br>
- <div style="padding-left: 32px">{{c.comment}}</div>
+ <simple-html style="padding-left: 32px" [contents]="c.commentHtml">
+ </simple-html>
</div>
<div *ngIf="approving">
- Comment:<br>
+ Comment: (type #4567 for GitHub SDK issue 4567,
+ or co19 #123 for a co19 issue. Use \n for newline.)<br>
<material-input
multiline
style="width: 80%"
diff --git a/results_feed/lib/src/model/comment.dart b/results_feed/lib/src/model/comment.dart
index 40434b5..265cfd0 100644
--- a/results_feed/lib/src/model/comment.dart
+++ b/results_feed/lib/src/model/comment.dart
@@ -19,6 +19,7 @@
final int pinnedIndex;
final int review;
final int patchset;
+ String commentHtml;
Comment(
this.id,
@@ -36,7 +37,9 @@
this.review,
this.patchset)
: results = List<String>.from(_results),
- tryResults = List<String>.from(_tryResults);
+ tryResults = List<String>.from(_tryResults) {
+ commentHtml = createCommentHtml();
+ }
Comment.fromDocument(DocumentSnapshot document)
: id = document.id,
@@ -52,10 +55,30 @@
blamelistEndIndex = document.get('blamelist_end_index'),
pinnedIndex = document.get('pinned_index'),
review = document.get('review'),
- patchset = document.get('patchset');
+ patchset = document.get('patchset') {
+ commentHtml = createCommentHtml();
+ }
String approvedText() =>
(approved == null) ? "" : approved ? "approved" : "disapproved";
+ static const repositories = ['sdk', 'co19'];
+ // Matches a repository or nothing, followed by #[digits][word break].
+ static final issueMatcher =
+ RegExp('(${repositories.join("|")})?\\s*#(\\d+)\\b');
+
+ String createCommentHtml() {
+ final result = comment
+ ?.replaceAll('<', '<')
+ ?.replaceAll('\\n', '<br>')
+ ?.replaceAllMapped(
+ issueMatcher,
+ (match) =>
+ '<a target="_blank" rel="noopener" href="https://github.com/'
+ 'dart-lang/${match[1] ?? "sdk"}/issues/${match[2]}">'
+ '${match[0]}</a>');
+ return result;
+ }
+
int compareTo(Object other) => created.compareTo((other as Comment).created);
}
diff --git a/results_feed/web/main.dart b/results_feed/web/main.dart
index 9329437..0106553 100644
--- a/results_feed/web/main.dart
+++ b/results_feed/web/main.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:angular/angular.dart';
+import 'package:angular_components/simple_html/simple_html.dart'
+ show simpleHtmlUriWhitelist;
import 'package:angular_router/angular_router.dart';
import 'package:dart_results_feed/src/services/firestore_service.dart';
import 'package:dart_results_feed/src/components/routing_wrapper_component.template.dart'
@@ -14,7 +16,16 @@
// Use for deploying on staging website:
// @GenerateInjector([ClassProvider(FirestoreService, useClass: StagingFirestoreService), ...routerProviders])
-@GenerateInjector([ClassProvider(FirestoreService), ...routerProviders])
+// Allow links from comments to GitHub issues in the dart-lang organization.
+List<Uri> getUriWhitelist() => List.unmodifiable(<Uri>[
+ Uri.https('github.com', 'dart-lang/'),
+ ]);
+
+@GenerateInjector([
+ ClassProvider(FirestoreService),
+ FactoryProvider.forToken(simpleHtmlUriWhitelist, getUriWhitelist),
+ routerProviders
+])
final InjectorFactory injector = self.injector$Injector;
void main() {