Test Failed
Push — main ( 2ac75e...34ff35 )
by Jochen
08:37
created

byceps/static/behavior/common.js (1 issue)

1
/**
2
 * Register a function to be called when the document is "ready", i.e.
3
 * all the markup has been placed on the page.
4
 *
5
 * It does not wait until additional resources (stylesheets, images,
6
 * subframes) have been loaded.
7
 */
8
function onDomReady(callback) {
9
  if (document.readyState === 'complete' || document.readyState !== 'loading') {
10
    // The document has already fully loaded.
11
    callback();
12
  } else {
13
    document.addEventListener('DOMContentLoaded', callback);
14
  }
15
}
16
17
18
// ---------------------------------------------------------------------
19
// XHR requests
20
21
function post_on_click(selector) {
22
  _request_on_click(selector, 'POST');
23
}
24
25
function post_on_click_then_reload(selector) {
26
  _request_on_click_then_reload(selector, 'POST');
27
}
28
29
function confirmed_post_on_click(selector, confirmation_label) {
30
  _confirmed_request_on_click(selector, confirmation_label, 'POST');
31
}
32
33
function confirmed_post_on_click_then_reload(selector, confirmation_label) {
34
  _confirmed_request_on_click_then_reload(selector, confirmation_label, 'POST');
35
}
36
37
function delete_on_click(selector) {
38
  _request_on_click(selector, 'DELETE');
39
}
40
41
function delete_on_click_then_reload(selector) {
42
  _request_on_click_then_reload(selector, 'DELETE');
43
}
44
45
function confirmed_delete_on_click(selector, confirmation_label) {
46
  _confirmed_request_on_click(selector, confirmation_label, 'DELETE');
47
}
48
49
function confirmed_delete_on_click_then_reload(selector, confirmation_label) {
50
  _confirmed_request_on_click_then_reload(selector, confirmation_label, 'DELETE');
51
}
52
53
function _request_on_click(selector, method) {
54
  _onClickCallbackWithHref(selector, href => {
55
    _ajax_then_redirect_to_location_response_header(method, href);
56
  });
57
}
58
59
function _request_on_click_then_reload(selector, method) {
60
  _onClickCallbackWithHref(selector, href => {
61
    _ajax_then_reload(method, href);
62
  });
63
}
64
65
function _confirmed_request_on_click(selector, confirmation_label, method) {
66
  _onClickCallbackWithHref(selector, href => {
67
    if (confirm(confirmation_label)) {
68
      _ajax_then_redirect_to_location_response_header(method, href);
69
    };
70
  });
71
}
72
73
function _confirmed_request_on_click_then_reload(selector, confirmation_label, method) {
74
  _onClickCallbackWithHref(selector, href => {
75
    if (confirm(confirmation_label)) {
76
      _ajax_then_reload(method, href);
77
    };
78
  });
79
}
80
81
82
function _onClickCallbackWithHref(selector, callback) {
83
  const elements = document.querySelectorAll(selector);
84
  elements.forEach(element => {
85
    element.addEventListener('click', event => {
86
      const href = element.getAttribute('href');
87
      callback(href);
88
89
      event.preventDefault();
90
    });
91
  });
92
}
93
94
function _ajax_then_redirect_to_location_response_header(method, request_url) {
95
  _ajax(method, request_url, response => {
96
    if (response.status == 204) {
97
      const redirectUrl = response.headers.get('Location');
98
      if (redirectUrl !== null) {
99
        location.href = redirectUrl;
100
      }
101
    }
102
  });
103
}
104
105
function _ajax_then_reload(method, request_url) {
106
  _ajax(method, request_url, response => {
107
    if (response.status == 204) {
108
      location.href = location.href;
109
    }
110
  });
111
}
112
113
function _ajax(method, url, on_complete) {
114
  fetch(url, {method: method})
115
    .then(response => on_complete(response));
116
}
117
118
119
// ---------------------------------------------------------------------
120
// dropdown menus
121
122
123
/**
124
 * Make dropdown menus open if their respective trigger is clicked.
125
 */
126
function enableDropdownMenuToggles() {
127
  const dropdownToggles = document.querySelectorAll('.dropdown .dropdown-toggle');
128
  dropdownToggles.forEach(triggerElement => {
129
    triggerElement.addEventListener('click', event => {
130
      const dropdown = triggerElement.parentNode;
131
      dropdown.classList.toggle('open');
132
133
      event.preventDefault();
134
    });
135
  });
136
}
137
138
139
/**
140
 * Close all open dropdown menus but the one that has been clicked (if
141
 * any).
142
 */
143
function closeOpenDropdownMenus(clickTarget) {
144
  const openDropdowns = document.querySelectorAll('.dropdown.open');
145
  openDropdowns.forEach(openDropdown => {
146
    if (!openDropdown.contains(clickTarget)) {
147
      // Click was outside of this dropdown menu, so close it.
148
      openDropdown.classList.remove('open');
149
    }
150
  });
151
}
152
153
154
// Add behavior to dropdown menus.
155
onDomReady(() => {
156
  enableDropdownMenuToggles();
157
158
  // Close open dropdowns if user clicks outside of an open dropdown.
159
  document.addEventListener('click', event => closeOpenDropdownMenus(event.target));
160
});
161
162
163
// ---------------------------------------------------------------------
164
// clipboard
165
166
167
/**
168
 * Register an element as click trigger to copy the value of a field to
169
 * the clipboard.
170
 */
171
function enableCopyToClipboard(triggerElementId) {
172
  const triggerElement = document.getElementById(triggerElementId);
173
  if (triggerElement == null) {
0 ignored issues
show
Comparing triggerElement to null using the == operator is not safe. Consider using === instead.
Loading history...
174
    return;
175
  }
176
177
  triggerElement.addEventListener('click', () => {
178
    const fieldId = triggerElement.dataset.fieldId;
179
    const field = document.getElementById(fieldId);
180
181
    field.focus();
182
    field.select();
183
    try {
184
      document.execCommand('copy');
185
    } catch (err) {}
186
    field.blur();
187
  });
188
}
189
190
191
// ---------------------------------------------------------------------
192
// forms
193
194
195
// Disable the submit button of forms with class
196
// `disable-submit-button-on-submit` on submit.
197
onDomReady(() => {
198
  const formsWhoseSubmitButtonShouldBeDisabledOnSubmit = document
199
      .querySelectorAll('form.disable-submit-button-on-submit');
200
201
  formsWhoseSubmitButtonShouldBeDisabledOnSubmit.forEach(form => {
202
    form.addEventListener('submit', () => {
203
      const submitButton = form.querySelector('button[type="submit"]');
204
      submitButton.disabled = true;
205
      submitButton.innerHTML += ' <svg class="icon spinning"><use xlink:href="/static/style/icons.svg#spinner"></use></svg>';
206
    });
207
  });
208
});
209
210
211
// ---------------------------------------------------------------------
212
// log-out
213
214
215
// Enable log-out.
216
onDomReady(() => {
217
  document.querySelectorAll('a[data-action="log-out"]')
218
    .forEach(anchor => {
219
      anchor.addEventListener('click', event => {
220
        if (confirm('Wirklich abmelden?')) {
221
          const href = anchor.getAttribute('href');
222
          fetch(href, {method: 'POST'})
223
            .then(response => location.href = '/authentication/log_in');
224
        };
225
226
        event.preventDefault();
227
      });
228
    });
229
});
230