PageSourceSearch

https://sciencecast.org/assets/controllers/data_room_controller-54…d0b64a2a7f05aa6bdb30029397fd80f34af1dde2.js

js sciencecast.org collected 2026-10-01 11:32:07 UTC 3,066 bytes, 94 lines download raw bytes

1import { Controller } from '@hotwired/stimulus';
2import * as ActiveStorage from '@rails/activestorage';
3
4export default class extends Controller {
5  static targets = ['submitBtn', 'fileEl', 'validationMessageEl']
6
7  connect() {
8    ActiveStorage.start();
9
10    addEventListener('direct-upload:initialize', this.directUploadInitialize);
11    addEventListener('direct-upload:start', this.directUploadStart);
12    addEventListener("direct-upload:progress", this.directUploadProgress);
13    addEventListener("direct-upload:error", this.directUploadError);
14    addEventListener("direct-upload:end", this.directUploadEnd);
15
16    this.fileElTarget.addEventListener('change', this.fileValidator.bind(this))
17  }
18
19  disconnect() {
20    removeEventListener('direct-upload:initialize', this.directUploadInitialize);
21    removeEventListener('direct-upload:start', this.directUploadStart);
22    removeEventListener("direct-upload:progress", this.directUploadProgress);
23    removeEventListener("direct-upload:error", this.directUploadError);
24    removeEventListener("direct-upload:end", this.directUploadEnd);
25
26    this.fileElTarget.removeEventListener('change', this.fileValidator)
27  }
28
29  fileValidator(event) {
30    const fileSizeInMb = Math.round(event.target.files[0].size / 1000 / 1000)
31
32    let validationMessages = []
33
34    if (fileSizeInMb > 100) {
35      validationMessages.push(`File is too big (${fileSizeInMb}Mb). Limit is 100Mb.`)
36    }
37
38    if (validationMessages.length != 0) {
39      this.validationMessageElTarget.innerHTML = `
40        <div class="alert alert-danger">
41          ${validationMessages.join(' ')}
42        </div>
43      `
44
45      this.submitBtnTarget.disabled = true
46    } else {
47      this.validationMessageElTarget.innerHTML = ''
48
49      this.submitBtnTarget.disabled = false
50    }
51  }
52
53  directUploadInitialize(event) {
54    const { target, detail } = event
55    const { id, file } = detail
56
57    target.insertAdjacentHTML("beforebegin", `
58      <div id="direct-upload-${id}" class="direct-upload direct-upload--pending">
59        <div id="direct-upload-progress-${id}" class="direct-upload__progress" style="width: 0%"></div>
60        <span class="direct-upload__filename">${file.name}</span>
61      </div>
62    `)
63  }
64
65  directUploadStart(event) {
66    const { id } = event.detail
67    const element = document.getElementById(`direct-upload-${id}`)
68
69    element.classList.remove('direct-upload--pending')
70  }
71
72  directUploadProgress(event) {
73    const { id, progress } = event.detail
74    const progressElement = document.getElementById(`direct-upload-progress-${id}`)
75
76    progressElement.style.width = `${progress}%`
77  }
78
79  directUploadError(event) {
80    event.preventDefault()
81    const { id, error } = event.detail
82    const element = document.getElementById(`direct-upload-${id}`)
83
84    element.classList.add('direct-upload--error')
85    element.setAttribute('title', error)
86  }
87
88  directUploadEnd(event) {
89    const { id } = event.detail
90    const element = document.getElementById(`direct-upload-${id}`)
91
92    element.classList.add('direct-upload--complete')
93  }
94};

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.