PageSourceSearch

https://my.pressable.com/assets/controllers/admin/hybrid_migration_plans/auto_refresh_controller-bcf7c5c5.js

js pressable.com collected 2026-09-24 15:22:05 UTC 2,304 bytes, 69 lines download raw bytes

1import { Controller } from "@hotwired/stimulus";
2
3export default class extends Controller {
4  static values = {
5    intervalMs: { type: Number, default: 20000 }
6  };
7
8  connect() {
9    this.reloading = false;
10    // The refresh is tracked as an absolute deadline rather than a repeating timer because
11    // every refresh is a full page load, so there is only ever one pending. Keeping the
12    // deadline fixed across a hide/show is what stops a brief alt-tab from pushing an
13    // already-due refresh out by another full interval — and a page that loads straight into
14    // a background tab ages from load, so its deadline is set here rather than on first focus.
15    this.deadline = Date.now() + this.intervalMsValue;
16    this.boundVisibilityChange = this.handleVisibilityChange.bind(this);
17    document.addEventListener("visibilitychange", this.boundVisibilityChange);
18    this.arm();
19  }
20
21  disconnect() {
22    document.removeEventListener("visibilitychange", this.boundVisibilityChange);
23    this.disarm();
24  }
25
26  handleVisibilityChange() {
27    // window.location.reload() does not commit synchronously, so a visibility event arriving
28    // in the gap before the navigation lands would otherwise start a second one.
29    if (this.reloading) return;
30
31    if (document.visibilityState !== "visible") {
32      // Polling stops entirely while hidden: a background tab that reloads on a timer spends
33      // requests nobody is reading, and the deadline above is enough to make the page current
34      // the moment someone looks at it again.
35      this.disarm();
36      return;
37    }
38
39    this.arm();
40  }
41
42  arm() {
43    if (this.timer) return;
44    if (document.visibilityState !== "visible") return;
45
46    const remaining = this.deadline - Date.now();
47
48    // The deadline passed while the tab was hidden, so the page is showing state from before
49    // the operator looked away — with the spinner still claiming it is live. Refresh at once
50    // instead of waiting out a fresh interval.
51    if (remaining <= 0) {
52      this.refresh();
53      return;
54    }
55
56    this.timer = setTimeout(() => this.refresh(), remaining);
57  }
58
59  disarm() {
60    if (!this.timer) return;
61    clearTimeout(this.timer);
62    this.timer = null;
63  }
64
65  refresh() {
66    this.reloading = true;
67    window.location.reload();
68  }
69}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.