Bookmark: Add UI to edit the 'via' field.

Change-Id: I2803622d248e0d59a7178382126ad573441c02f9
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
index 40f7166..d35a1dc 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
@@ -62,6 +62,7 @@
       @FormParam("uri") @NotNull URI uri,
       @FormParam("title") @NotEmpty String title,
       @FormParam("description") @CheckForNull String description,
+      @FormParam("via") @CheckForNull String via,
       @FormParam("visibility") @NotNull Post.Visibility visibility)
       throws URISyntaxException {
 
@@ -69,6 +70,7 @@
 
     var bookmark = new Bookmark();
     bookmark.uri = uri.toString();
+    bookmark.via = (via != null && !via.trim().isEmpty()) ? via : null;
     bookmark.tags = Set.of();
     bookmark.owner = user;
     bookmark.date = OffsetDateTime.now();
@@ -94,6 +96,7 @@
       @FormParam("uri") @NotNull URI uri,
       @FormParam("title") @NotEmpty String title,
       @FormParam("description") @CheckForNull String description,
+      @FormParam("via") @CheckForNull String via,
       @FormParam("visibility") Post.Visibility visibility)
       throws URISyntaxException {
 
@@ -110,6 +113,7 @@
     }
 
     bookmark.uri = uri.toString();
+    bookmark.via = (via != null && !via.trim().isEmpty()) ? via : null;
     bookmark.tags = Set.of();
     bookmark.setTitle(title);
     bookmark.setDescription(description);
diff --git a/src/main/resources/META-INF/resources/bookmarks/MlkBookmarkSubmissionForm.js b/src/main/resources/META-INF/resources/bookmarks/MlkBookmarkSubmissionForm.js
index 83242ba..2a2c779 100644
--- a/src/main/resources/META-INF/resources/bookmarks/MlkBookmarkSubmissionForm.js
+++ b/src/main/resources/META-INF/resources/bookmarks/MlkBookmarkSubmissionForm.js
@@ -21,6 +21,9 @@
       <label for="description-input">Description:</label>
       <textarea name="description" id="description-input" placeholder="Description"></textarea>
 
+      <label for="via-input">Via:</label>
+      <input name="via" id="via-input" type="text" placeholder="Source URI" />
+
       <label for="visibility-input">Visibility:</label>
       <select id="visibility-input" name="visibility" required>
         <option value="PUBLIC" selected>Public</option>
@@ -41,6 +44,7 @@
   titleInput: HTMLInputElement;
   uriInput: HTMLInputElement;
   uriSpinner: ProgressSpinner;
+  viaInput: HTMLInputElement;
   visibilityInput: HTMLInputElement;
   loaded: boolean;
   */
@@ -50,7 +54,7 @@
     this.loaded = false;
   }
 
-  static get observedAttributes() {
+  static get observedAttributes() /*: Array<string>*/ {
     return [];
   }
 
@@ -76,6 +80,8 @@
         cast(shadow.getElementById('uri-input'));
     this.uriSpinner =
         cast(shadow.getElementById('uri-spinner'));
+    this.viaInput =
+        cast(shadow.getElementById('via-input'));
     this.visibilityInput =
         cast(shadow.getElementById('visibility-input'));
 
@@ -88,6 +94,7 @@
     this.uriInput.value = this.uri || "";
     this.titleInput.value = this.titleText || "";
     this.descriptionInput.innerText = this.description || "";
+    this.viaInput.value = this.via || "";
   }
 
   get editedId() /*:number | null*/ {
@@ -99,7 +106,7 @@
     return parseInt(attr, 10);
   }
 
-  get isEditor() {
+  get isEditor() /*: boolean*/ {
     return this.editedId !== null;
   }
 
@@ -112,18 +119,22 @@
   attributeChangedCallback(name /*:string*/, oldValue /*:string*/, newValue /*:string*/) {
   }
 
-  get uri() {
+  get uri() /*: ?string*/ {
     return this.getAttribute("uri");
   }
 
-  get titleText() {
+  get titleText() /*: ?string*/ {
     return this.getAttribute("title");
   }
 
-  get description() {
+  get description() /*: ?string*/ {
     return this.getAttribute("description");
   }
 
+  get via() /*: ?string*/ {
+    return this.getAttribute("via");
+  }
+
   focus() {
     this.show();
     if (!this.uriInput.value) {
@@ -172,6 +183,7 @@
 
     let post = await r.json();
     this.uriInput.value = post.uri;
+    this.viaInput.value = post.via || "";
     this.visibilityInput.value = post.visibility;
     if (post.texts['']) {
       this.titleInput.value = post.texts[''].title;