PageSourceSearch

https://takemetotheriver.net/assets/scripts/player.js

js takemetotheriver.net collected 2026-10-07 03:35:16 UTC 8,053 bytes, 278 lines download raw bytes

1(function () {
2  window.helpers.onPageLoadUnload(function () {
3    var player = document.querySelector('.player')
4
5    if (player) {
6      return attachPlayer(player)
7    }
8  })
9
10  function attachPlayer (player) {
11    var controls = player.querySelector('.player__controls')
12    var listeners = window.helpers.listeners()
13
14    if (!player || !controls) {
15      return
16    }
17
18    var previous = player.querySelector('.player__nav__item--previous')
19    var next = player.querySelector('.player__nav__item--next')
20    var progress = player.querySelector('.player__progress')
21    var progressBar = player.querySelector('.player__progress__bar')
22    var progressDisplay = player.querySelector('.player__progress__display')
23
24    player.getState = getState
25
26    listeners.add(window, 'keydown', function (event) {
27      switch (event.keyCode) {
28        case 37:
29          return player.previous()
30        case 39:
31          return player.next()
32        case 32:
33          if (player.getState('play')) {
34            player.dispatchEvent(new window.Event('pause'))
35            player.updatePlayStatus(false)
36          } else {
37            player.dispatchEvent(new window.Event('play'))
38            player.updatePlayStatus(true)
39          }
40      }
41    })
42
43    player.updateTime = function (time, duration) {
44      progressDisplay.textContent = [time, duration]
45        .filter(isNumber)
46        .map(formatTime)
47        .join(' / ')
48
49      if (isNumber(time) && isNumber(duration)) {
50        var percentage = ((time / duration) * 100)
51
52        progressBar.style.width = percentage.toFixed(1) + '%'
53
54        player.dispatchEvent(new window.CustomEvent('progress', {
55          detail: {
56            progress: time / duration
57          }
58        }))
59
60        if (percentage === 100 && next) {
61          player.next()
62        }
63      }
64    }
65
66    player.updatePlayStatus = function (status) {
67      player.classList[status ? 'add' : 'remove']('player--playing')
68      setState('play', status)
69    }
70
71    player.updateAudibleStatus = function (status) {
72      player.classList[status ? 'add' : 'remove']('player--audible')
73      setState('audible', status)
74    }
75
76    player.previous = function () {
77      if (previous) {
78        player.dispatchEvent(new window.Event('previous'))
79        previous.click()
80        return true
81      }
82    }
83
84    player.next = function () {
85      if (next) {
86        player.dispatchEvent(new window.Event('next'))
87        next.click()
88        return true
89      }
90    }
91
92    var navigation = {
93      next: player.querySelector('.player__nav__item--next'),
94      previous: player.querySelector('.player__nav__item--previous')
95    }
96
97    if (navigation.next) {
98      listeners.add(navigation.next, 'click', function () {
99        player.dispatchEvent(new window.Event('next'))
100      })
101    }
102
103    if (navigation.previous) {
104      listeners.add(navigation.previous, 'click', function () {
105        player.dispatchEvent(new window.Event('previous'))
106      })
107    }
108
109    player.updatePlayStatus(getState('play'))
110
111    const audibleState = player.getState('audible')
112
113    if (audibleState === null) {
114      player.updateAudibleStatus(true)
115    } else {
116      player.updateAudibleStatus(audibleState)
117    }
118
119    var buttons = {
120      play: player.querySelector('.player__button--play'),
121      pause: player.querySelector('.player__button--pause'),
122      mute: player.querySelector('.player__button--mute'),
123      unmute: player.querySelector('.player__button--unmute'),
124      fullscreen: player.querySelector('.player__button--fullscreen'),
125      exitFullscreen: player.querySelector('.player__button--exit-fullscreen')
126    }
127
128    listeners.add(buttons.play, 'click', function () {
129      player.dispatchEvent(new window.Event('play'))
130      player.updatePlayStatus(true)
131    })
132
133    listeners.add(buttons.pause, 'click', function () {
134      player.dispatchEvent(new window.Event('pause'))
135      player.updatePlayStatus(false)
136    })
137
138    listeners.add(buttons.mute, 'click', function () {
139      player.dispatchEvent(new window.Event('mute'))
140      player.updateAudibleStatus(false)
141    })
142
143    listeners.add(buttons.unmute, 'click', function () {
144      player.dispatchEvent(new window.Event('unmute'))
145      player.updateAudibleStatus(true)
146    })
147
148    listeners.add(buttons.fullscreen, 'click', function () {
149      if (window.screenfull.isEnabled) {
150        window.screenfull.request().then(function () {
151          player.dispatchEvent(new window.Event('fullscreen'))
152        })
153      }
154    })
155
156    listeners.add(buttons.exitFullscreen, 'click', function () {
157      if (window.screenfull.isEnabled) {
158        window.screenfull.exit().then(function () {
159          player.dispatchEvent(new window.Event('exit-fullscreen'))
160        })
161      }
162    })
163
164    if (!window.screenfull.isEnabled) {
165      buttons.fullscreen.classList.add('player__button--unavailable')
166      buttons.exitFullscreen.classList.add('player__button--unavailable')
167    }
168
169    updateFullscreenStatus()
170
171    if (window.screenfull.isEnabled) {
172      window.screenfull.on('change', updateFullscreenStatus)
173    }
174
175    function getSeekPosition (event) {
176      var pointer = 'changedTouches' in event ? event.changedTouches[0] : event
177      var rect = progress.getBoundingClientRect()
178      return (pointer.clientX - rect.left) / rect.width
179    }
180
181    function startSeeking (event) {
182      event.preventDefault()
183
184      var scrubbing = false
185      var startSeekPosition = getSeekPosition(event)
186
187      var scrub = window.helpers.throttle(function (event) {
188        if (!scrubbing) {
189          var change = Math.abs(getSeekPosition(event) - startSeekPosition)
190          var threshold = 0.025
191
192          if (change > threshold) {
193            scrubbing = true
194            player.dispatchEvent(new window.Event('scrubstart'))
195          } else {
196            return
197          }
198        }
199
200        player.dispatchEvent(new window.CustomEvent('seek', {
201          detail: getSeekPosition(event)
202        }))
203      }, 100)
204
205      function end () {
206        listeners.remove(document, 'mousemove', scrub)
207        listeners.remove(document, 'mouseup', end)
208        listeners.remove(document, 'touchmove', scrub)
209        listeners.remove(document, 'touchend', end)
210
211        if (scrubbing) {
212          player.dispatchEvent(new window.Event('scrubend'))
213        }
214      }
215
216      listeners.add(document, 'mousemove', scrub)
217      listeners.add(document, 'mouseup', end)
218      listeners.add(document, 'touchmove', scrub)
219      listeners.add(document, 'touchend', end)
220
221      player.dispatchEvent(new window.CustomEvent('seek', {
222        detail: startSeekPosition
223      }))
224    }
225
226    listeners.add(progress, 'mousedown', startSeeking)
227    listeners.add(progress, 'touchstart', startSeeking)
228
229    function updateFullscreenStatus () {
230      if (window.screenfull.isEnabled) {
231        var fullscreen = window.screenfull.isFullscreen
232        player.classList[fullscreen ? 'add' : 'remove']('player--fullscreen')
233      }
234    }
235
236    function formatTime (totalSeconds) {
237      var minutes = Math.floor(totalSeconds / 60)
238      var seconds = Math.round(totalSeconds - (minutes * 60))
239      var segments = [minutes, seconds.toString().padStart(2, '0')]
240      return segments.join(':')
241    }
242
243    function isNumber (value) {
244      return typeof value === 'number' && !Number.isNaN(value)
245    }
246
247    return function detachPlayer () {
248      if (window.screenfull.isEnabled) {
249        window.screenfull.off('change', updateFullscreenStatus)
250      }
251
252      listeners.clear()
253    }
254  }
255
256  function setState (key, value) {
257    // console.log('Set state', key, value)
258    window.localStorage.setItem(getStateKey(key), JSON.stringify(value))
259  }
260
261  function getState (key) {
262    try {
263      var value = JSON.parse(window.localStorage.getItem(getStateKey(key)))
264      // console.log('Get state', key, value)
265      return value
266    } catch (error) {
267      if (error) {
268        console.warn('Could not get state', key)
269      }
270
271      return null
272    }
273  }
274
275  function getStateKey (key) {
276    return `player-${key}`
277  }
278})()

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.