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.

Channel is the abstract base class that all simulator channels extend. It lives in js/helpers/channel.js and provides the shared constructor, timer-management infrastructure, and lifecycle hooks (show, teardown, ready). Channel12, defined in channels/012/script.js, is the only built-in concrete implementation — it renders the Prevue Channel grid, drives a YouTube player, and cycles through rotating advertisements.

Channel Base Class

Constructor

new Channel(container, guideData)
container
jQuery object
required
The .current-channel <div> element, passed as a jQuery-wrapped DOM node. The channel uses this reference to load layout elements, query sub-nodes with .find(), and .empty() itself during teardown.
guideData
jQuery XML
required
The parsed guide.xml document, stored in window.guideData by TV.startUp(). Passed as the result of $($.parseXML(responseText)). Channel implementations use .find('channel'), .find('ad'), etc. to query listings and ad content.

Properties

PropertyTypeDescription
this.containerjQueryReference to the .current-channel DOM element.
this.guideDatajQueryParsed guide.xml document.
this.timeoutsobjectNamed setTimeout handles. Stored as this.timeouts.myKey = setTimeout(...). All entries are cleared by teardown().
this.intervalsobjectNamed setInterval handles. Stored as this.intervals.myKey = setInterval(...). All entries are cleared by teardown().

Methods

show()

channel.show(): void
Lifecycle hook called by TV.showChannel() after the channel’s layout.html has been loaded into .current-channel. The base implementation simply logs 'Showing channel' to the console. Subclasses override this method to bootstrap their specific UI — creating YouTube players, starting timers, rendering listings, and loading ads.

teardown()

channel.teardown(): void
Cleans up all resources owned by the channel. The base implementation:
  1. Iterates this.timeouts and calls clearTimeout on each handle.
  2. Iterates this.intervals and calls clearInterval on each handle.
  3. If this.player exists, calls YouTubeApi.stopVideo(this.player).
  4. Calls this.container.empty() to remove all DOM children.
  5. Clears the container’s id attribute.
Subclasses that need additional teardown steps (e.g., stopping a marquee) should call super.teardown() after their own cleanup.

ready()

The base class does not define ready(). It is called by TV.showChannel() at the end of the fade-in animation as a post-show hook. Implement it in your subclass if you need to execute code only after the channel is fully visible.

Channel12

Channel12 extends Channel and implements the Prevue Channel — the simulator’s default channel. It renders a three-column program listings grid, drives a looping YouTube video, and cycles through ads loaded from guide.xml.

Constructor

constructor(container, guideData) {
    super(container, guideData);
    this.curTsStart = 19;
    // ads
    this.adList = [];
    this.currentAd = 0;
    this.defaultAdDuration = 30;
}
In addition to the properties inherited from Channel, the constructor initializes:
PropertyTypeDefaultDescription
this.curTsStartnumber19The half-hour timeslot index where the listings grid starts. 19 corresponds to 9:30 AM. The grid shows slots curTsStart, curTsStart + 1, and curTsStart + 2.
this.adListarray[]Array of ad objects loaded from <ad> elements in guide.xml. Each entry has the shape { content: string, duration: number }.
this.currentAdnumber0Index into adList pointing to the currently displayed ad.
this.defaultAdDurationnumber30Fallback ad display duration in seconds, used when an <ad> element omits the duration attribute.

Timeslot Calculation

curTsStart = 19 means the leftmost column of the listings grid shows programs at or before half-hour index 19 (9:30 AM). The three visible columns correspond to timeslots curTsStart (9:30 AM), curTsStart + 1 (10:00 AM), and curTsStart + 2 (10:30 AM). For each column, getFirstListing walks backward from the target timeslot to find the last program that started at or before that slot — this handles multi-hour programs that span column boundaries. When a program spans consecutive columns (its timeslot attribute matches adjacent slots), generateListing assigns a colspan so it fills the appropriate number of cells.

Methods

show()

channel12.show(): void
Overrides the base show(). Performs all Channel12 setup in sequence:
  1. Calls super.show().
  2. Creates a YT.Player instance targeting the #ytplayer element from layout.html, hardcoded to videoId: '9NSVU4Gv_wA', with autoplay: 1, controls: 0, and rel: 0.
  3. Activates the jQuery marquee plugin on the <marquee> element and re-queries all container sub-elements (required because the marquee plugin replaces DOM nodes).
  4. Starts this.intervals.timeInterval (1-second tick) to update the real-time clock, hour headers, and date display using moment.js.
  5. Empties #listing-grid and rebuilds it by iterating all <channel> elements in guideData: renders <notice> rows, skips noticeonly channels for data rows, and calls generateListing for each of the three visible timeslot columns.
  6. Populates this.adList from all <ad> elements in guideData.
  7. If adList.length > 0, calls nextAd() to start the ad cycle. Otherwise sets the ad panel to "THIS SPACE FOR RENT".

generateListing(listing, colspan)

channel12.generateListing(listing: jQuery, colspan?: number): jQuery
Creates and returns a <td> element for a single program listing cell.
listing
jQuery
required
A jQuery-wrapped <listing> XML element from guideData.
colspan
number
When provided, sets the colspan attribute on the <td> so a long-running program spans multiple columns.
The cell receives the .listing CSS class and its inner HTML is set to the listing element’s text content. If the listing’s type attribute is "movie", the cell additionally receives the .movie class (which applies a blue gradient background in the stylesheet).

getFirstListing(listings, timeslot)

channel12.getFirstListing(listings: jQuery, timeslot: number): Element
Finds the most recent program that started at or before the given timeslot. Starting at timeslot and counting down to 0, it returns the first <listing> element in listings whose timeslot attribute matches. Returns undefined if no listing is found.
listings
jQuery
required
A jQuery collection of <listing> elements for a single channel.
timeslot
number
required
The target half-hour index. The search walks backward from this value.

nextAd()

channel12.nextAd(): void
Advances to the next ad in adList with a fade transition:
  1. If adList.length <= 1, returns immediately — the cycle requires at least two ads.
  2. Fades out this.textLeft (the ad panel’s .inner-box).
  3. After the fade completes, waits 750 ms, then increments this.currentAd (wrapping to 0 at the end of the list).
  4. Sets the panel’s HTML to the new ad content and fades it back in.
  5. Schedules the next call to nextAd() after adList[this.currentAd].duration * 1000 milliseconds.
The timeout handle is stored in this.timeouts.nextAd so teardown() can cancel a pending ad transition during channel changes.

onPlayerReady(event)

channel12.onPlayerReady(event: YT.PlayerEvent): void
YouTube IFrame API callback, bound to the onReady event of the YT.Player. Calls event.target.playVideo() to start playback as soon as the player is initialized.

onPlayerStateChange(event)

channel12.onPlayerStateChange(event: YT.OnStateChangeEvent): void
YouTube IFrame API callback, bound to the onStateChange event. Currently logs 'Playing...' to the console when event.data === YT.PlayerState.PLAYING.

teardown()

channel12.teardown(): void
Overrides the base teardown(). First triggers this.marquee.trigger('stop') to halt the scrolling marquee, then calls super.teardown() to clear all timers, stop the YouTube player, and empty the container.

Build docs developers (and LLMs) love