aboutsummaryrefslogtreecommitdiff
path: root/static/js/update.ts
blob: df29f4936ea3f349d91fa2863a7e1c98e0bcea46 (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
(function () {

  const cookiesDisabled = !navigator.cookieEnabled;

  if (cookiesDisabled) {
    document.cookie = "disabled";
    document.cookie.indexOf("disabled");
    return console.warn("WARNING: Update check disabled due to cookie restrictions");
  }

  function fetch(url, method, callback) {
    const http = new XMLHttpRequest();
    http.onreadystatechange = function () {
      if (http.readyState === 4 && http.status === 200) {
        if (callback) callback(http);
      }
    };
    http.open(method, url);
    http.setRequestHeader("Pragma", "no-cache");
    http.setRequestHeader("Cache-Control", "no-cache");
    http.send();
    return http;
  }

  const state = "on";
  const key = "config.update";

  let stamps = {};

  if (!sessionStorage[key + ".urls"]) sessionStorage[key + ".urls"] = JSON.stringify(stamps);

  function update() {
    const url = self.location.href.split("#")[0].split("?")[0];

    const indicator = document.querySelector("a[data-update]");
    if (indicator === null || indicator.dataset.update === "refresh") return;
    const anchor = indicator.cloneNode();

    fetch(url, "HEAD", function (request) {
      const local = document.querySelector('meta[name="last-modified"]').content || document.lastModified;
      const remote = request.getResponseHeader("last-modified") || '';
      const modified = Date.parse(remote || local) > Date.parse(local);
      const drift = Date.parse(remote || local) - Date.parse(local);

      if (drift < 10000) return;

      function reset() {
        indicator.href = anchor.href;
        indicator.setAttribute("id", anchor.id);
        indicator.dataset.update = anchor.dataset.update;
      }

      stamps = JSON.parse(sessionStorage[key + ".urls"]);
      if (stamps[url] === remote) return;
      stamps[url] = remote;
      sessionStorage[key + ".urls"] = JSON.stringify(stamps);

      if (remote && modified) {
        fetch(url, "GET", function () {
          indicator.href = url.replace(/^https:/, "http:");
          indicator.removeAttribute("id");
          indicator.dataset.update = "refresh";
          console.log("INFO: R: " + remote);
          console.log("INFO: L: " + local);
          console.log("INFO: D: " + drift);
          console.log("INFO: M: " + modified);
        });
      }
    });
  }

  let scrolled;
  let delay = 1000;
  let delayed = 0;

  self.addEventListener("scroll", function () {
    if (scrolled) clearTimeout(scrolled);
    scrolled = setTimeout(function () { update(); delay = delay + delayed; delayed = delay - delayed; }, delay);
  });

  ["focus", "load", "URLChangedCustomEvent"].forEach(function (event) {
    self.addEventListener(event, function () { update(); });
  });
})();