summaryrefslogtreecommitdiff
path: root/src/main/resources/META-INF/resources/bookmarks/MlkBookmarkSubmissionForm.js
blob: 0a8fad7ee4c1f55101966e0e77bf5f20430422fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// @flow

import /*:: ProgressSpinner from */ "../web_modules/elix/define/ProgressSpinner.js";
import { cast } from "../cms2/types.js";

const template = document.createElement('template');
template.innerHTML = `
  <link rel="stylesheet" type="text/css" href="/cms2/base.css" />
  <link rel="stylesheet" type="text/css" href="/bookmarks/MlkBookmarkSubmissionForm.css" />

  <form class="pure-form" method="post" action="/bookmarks">
    <fieldset>
      <legend>New Bookmark</legend>

      <label for="uri-input">URI:</label>
      <input name="uri" id="uri-input" type="text" placeholder="URI" required />
      <elix-progress-spinner id="uri-spinner" hidden></elix-progress-spinner>

      <label for="title-input">Title:</label>
      <input name="title" id="title-input" type="text" placeholder="Title" required />

      <label for="description-input">Description:</label>
      <textarea name="description" id="description-input" placeholder="Description"></textarea>

      <label for="visibility-input">Visibility:</label>
      <select id="visibility-input" name="visibility" required>
        <option value="public" selected>Public</option>
        <option value="semiprivate">Semiprivate</option>
        <option value="private">Private</option>
      </select>

      <div class="controls">
        <button type="submit" class="pure-button pure-button-primary">Submit Bookmark</button>
      </div>
    </fieldset>
  </form>`;

export class MlkBookmarkSubmissionForm extends HTMLElement {
  /*::
  descriptionInput: HTMLTextAreaElement;
  titleInput: HTMLInputElement;
  uriInput: HTMLInputElement;
  uriSpinner: ProgressSpinner;
  */

  constructor() {
    super();

    let shadow = this.attachShadow({mode: "open"});
    shadow.appendChild(template.content.cloneNode(true));

    this.descriptionInput =
        cast(shadow.getElementById('description-input'));
    this.titleInput =
        cast(shadow.getElementById('title-input'));
    this.uriInput =
        cast(shadow.getElementById('uri-input'));
    this.uriSpinner =
        cast(shadow.getElementById('uri-spinner'));
  }

  static get observedAttributes() {
    return [];
  }

  connectedCallback () {
    this.uriInput.addEventListener('blur', this.onUriBlur.bind(this));
    this.uriInput.value = this.uri || "";
    this.titleInput.value = this.titleText || "";
    this.descriptionInput.innerText = this.description || "";
  }

  disconnectedCallback () {
    this.uriInput.removeEventListener('blur', this.onUriBlur.bind(this));
  }

  attributeChangedCallback(name /*:string*/, oldValue /*:string*/, newValue /*:string*/) {
  }

  get uri() {
    return this.getAttribute("uri");
  }

  get titleText() {
    return this.getAttribute("title");
  }

  get description() {
    return this.getAttribute("description");
  }

  focus() {
    if (!this.uriInput.value) {
      this.uriInput.focus();
    } else if (!this.titleInput.value) {
      this.titleInput.focus();
      this.onUriBlur();
    } else {
      this.descriptionInput.focus();
    }
  }

  async onUriBlur() {
    if (!this.uriInput.value) {
      return;
    }

    this.uriSpinner.hidden = false;
    this.uriSpinner.playing = true;
    let searchParams = new URLSearchParams({'uri': this.uriInput.value});
    console.log(`/bookmarks/page-info?${searchParams.toString()}`);
    let fetchUrl = new URL(`/bookmarks/page-info?${searchParams.toString()}`, document.URL);
    let r = await fetch(fetchUrl);
    this.uriSpinner.hidden = true;
    this.uriSpinner.playing = false;

    if (!r.ok) {
      return;
    }

    let pageInfo = await r.json();
    this.titleInput.value = pageInfo.title;
  }
}

customElements.define("mlk-bookmark-submission-form", MlkBookmarkSubmissionForm);