Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/zshall/program-guide/llms.txt

Use this file to discover all available pages before exploring further.

Helpers and YouTubeApi are static utility classes used throughout the simulator codebase. Neither class holds instance state — every method is static, so you call them directly on the class name without constructing an object. Helpers lives in js/helpers/helpers.js and provides general-purpose browser and string utilities. YouTubeApi lives in js/helpers/youtube-ctrl.js and wraps the YouTube IFrame API player methods used by channel implementations.
All methods on both Helpers and YouTubeApi are static. You never call new Helpers() or new YouTubeApi() — always call Helpers.methodName() or YouTubeApi.methodName() directly.

Helpers

Helpers.isMobile()

Helpers.isMobile(): object
Returns a plain object with per-platform detection functions. Each function tests navigator.userAgent with a regular expression and returns the regex match result (truthy on a match, null otherwise).
Helpers.isMobile().Android()     // matches /Android/i
Helpers.isMobile().BlackBerry()  // matches /BlackBerry/i
Helpers.isMobile().iOS()         // matches /iPhone|iPad|iPod/i
Helpers.isMobile().Opera()       // matches /Opera Mini/i
Helpers.isMobile().Windows()     // matches /IEMobile/i
Helpers.isMobile().any()         // truthy if any of the above match
The simulator uses isMobile().any() in TV.startUp() to conditionally add the .scanlines overlay and register the resize handler — both are skipped on mobile:
if (!Helpers.isMobile().any()) {
    $(window).resize(() => { this.handleResize(); });
    $('.screen').addClass('scanlines');
}

Helpers.padLeft(nr, n, str?)

Helpers.padLeft(nr: number | string, n: number, str?: string): string
Left-pads nr to at least n characters using the pad character str. If the string representation of nr is already n characters or longer, it is returned unchanged.
nr
number | string
required
The value to pad.
n
number
required
The minimum desired output length.
str
string
default:"'0'"
The pad character. Defaults to '0' when omitted or undefined.
Examples:
Helpers.padLeft(5, 3)     // → '005'
Helpers.padLeft(12, 2)    // → '12'
Helpers.padLeft(7, 3, ' ')// → '  7'
The simulator uses padLeft in two places:
  • TV.showChannel builds the layout path: channels/${Helpers.padLeft(number, 3)}/layout.html
  • TV.showChannel sets the channel-number overlay: Helpers.padLeft(number, 2)

Helpers.loadScript(scriptUrl)

Helpers.loadScript(scriptUrl: string): Promise<void>
Dynamically injects a <script> element into <head> and returns a Promise that resolves when the script fires its onload event, or rejects on error.
scriptUrl
string
required
The fully-qualified URL of the script to load.
// Inject an external script and wait for it to be ready
await Helpers.loadScript('https://www.youtube.com/iframe_api');
YouTubeApi.loadYouTubeAPI() calls this method internally. You can also use it directly when a channel needs to load a third-party library before its show() logic runs.
The onerror handler in the source contains a bug: reject(Error('Error loading ' + globalName || scriptUrl)) references globalName, which is not defined in scope. Due to JavaScript operator precedence this evaluates as reject(Error('Error loading ' + undefined) || scriptUrl), so the rejection message will read 'Error loading undefined' rather than the script URL. The onload path is unaffected.

YouTubeApi

YouTubeApi.loadYouTubeAPI()

static async YouTubeApi.loadYouTubeAPI(): Promise<void>
Injects the YouTube IFrame API script by calling Helpers.loadScript("https://www.youtube.com/iframe_api"). Called by TV.startUp() during initialization. When the script loads, the global onYouTubeIframeAPIReady callback fires automatically.

YouTubeApi.restartVideo(player)

static YouTubeApi.restartVideo(player: YT.Player): void
Stops the player and immediately resumes playback by calling stopVideo then playVideo on the player instance.
player
YT.Player
required
An initialized YouTube IFrame API player object.

YouTubeApi.stopVideo(player)

static YouTubeApi.stopVideo(player: YT.Player): void
Stops playback by calling player.stopVideo(). Called by Channel.teardown() if this.player is set, ensuring the video stops when switching channels.
player
YT.Player
required
An initialized YouTube IFrame API player object.

YouTubeApi.toggleMuteVideo(player)

static YouTubeApi.toggleMuteVideo(player: YT.Player): boolean
Toggles the mute state of the player. If currently muted, calls player.unMute(); otherwise calls player.mute(). Returns true if the player is now muted after the toggle, false if it is now unmuted.
player
YT.Player
required
An initialized YouTube IFrame API player object.
// In TV.toggleMute():
this.muted = YouTubeApi.toggleMuteVideo(this.channel.player);
The return value is !player.isMuted() evaluated after the toggle call. Because the YouTube IFrame API’s isMuted() can have a brief async lag, always use this.muted (stored in the TV instance) as the canonical mute state rather than querying the player directly.

YouTubeApi.muteVideo(player)

static YouTubeApi.muteVideo(player: YT.Player): void
Unconditionally mutes the player by calling player.mute().
player
YT.Player
required
An initialized YouTube IFrame API player object.

YouTubeApi.unmuteVideo(player)

static YouTubeApi.unmuteVideo(player: YT.Player): void
Unconditionally unmutes the player by calling player.unMute().
player
YT.Player
required
An initialized YouTube IFrame API player object.

Global Callback

onYouTubeIframeAPIReady()

function onYouTubeIframeAPIReady(): void
A globally scoped function required by the YouTube IFrame API. When the IFrame API script finishes loading, YouTube’s infrastructure calls this function automatically. The simulator’s implementation dispatches a custom DOM event:
function onYouTubeIframeAPIReady() {
    document.dispatchEvent(new CustomEvent('youtubeReady', {}));
}
TV.startUp() listens for the youtubeReady event via document.addEventListener('youtubeReady', ...) and uses it as the signal to fetch data/guide.xml and load the default channel. This decouples the guide data fetch from the script-load callback, keeping the TV class independent of the global function name.

Build docs developers (and LLMs) love