"Do the best you can until you know better. Then when you know better, do better."
- Maya Angelo
0.0 Architecture Diagram
Each content page in this site is displayed in a Track Explorer iframe placed in
in the Explorer's right panel, with controls in the left panel to navigate to
other content pages.
Each Track Explorer is displayed in the site's PageHost's iframe that
fills the entire PageHost view except for a thin menu bar at the top.
The page you are viewing right now is an example: compare it to the diagram below.
All of the site technical content is housed in a content page, e.g., SiteDesign.html.
Content from each Track, e.g., Rust, is displayed by its ExploreRust.html explorer.
Explorers are charged with managing navigation through the Track's content using
links in its left panel.
The PageHost handles activities that cross Track boundaries, e.g., keeping bookmarks,
Content page address (not shown by the Browser address bar), and managing Full Screen
display.
1.0 View — PageHost.html
The outermost shell of the site is ../PageHost.html. It
provides the single browser tab the user interacts with throughout a session.
PageHost owns a full-viewport iframe whose src is set to a
track Explorer when the user selects a track, or when the site first loads.
PageHost also renders a URL bar at the top of the viewport that always shows
the address of the content page currently visible inside the nested iframe
chain, and a status indicator that lights while a new page is loading.
Because every piece of content ultimately lives inside that iframe, the
browser's address bar never changes during normal navigation. PageHost
receives page-URL messages posted up from content pages and writes them into
its own URL bar so users can copy or share a direct link at any time.
2.0 Track Explorers and Iframes
Each track is managed by a dedicated Explorer page
(e.g. Explore.html, ExploreCode.html,
ExploreRust.html, …). An Explorer is a two-panel
layout built with the <x-two-panel> web component:
Left panel — a scrollable navigation tree of links
that are specific to the track. Clicking a link sets the right-panel
iframe’s src to the target content page.
Right panel — a single iframe that fills the entire
panel. Every content page for the track is loaded here. The iframe is the
only thing in the right panel; no chrome surrounds it.
PageHost embeds the Explorer in its own iframe, so the full stack is:
PageHost → Explorer iframe → content iframe. Messages travel up
and down this chain via postMessage.
3.0 Content Partitioned into Tracks
All content pages are grouped into tracks: Site,
Rust, C++, C#,
Python, WebDev, SWDev,
Basics, and Code. Each track has its own
Explorer, its own CSS theme file, and its own colour palette so that users
always have a visual cue about which track they are browsing.
If a content page is opened directly (not through its Explorer), its load
script detects that it is the top-level window and redirects to
ExploreCode.html?src=<page-url> so the full two-panel
view is always presented.
4.0 Menus — Site-level and Page-level
The site uses two distinct layers of menu:
Site-level menus (top of view) — defined inside
each Explorer and rendered in the Explorer’s own header area at
the top of the visible viewport. These menus provide track navigation,
theme controls, and other cross-page operations.
Page-level menus (bottom of view) — rendered
inside each content page at the page’s bottom. Typical entries
are a Sections list for in-page navigation, a
Pages list for navigating within the track, and a
Keys list for keyboard shortcuts.
Visibility of site-level drop-down menus is toggled by Page Controls buttons in the
Explorer’s left panel and in the bottom page menu bar. When a user clicks a menu button the
Explorer posts a postMessage into the content iframe; the
content page listens for the message and shows or hides the corresponding
menu drop-down. This keeps the button controls visually in the Explorer left panel and page bottom menu while the
menus they control appear just below the top menu bar.
5.0 Window Messaging
Because content lives inside nested iframes, all cross-frame communication
uses window.postMessage with { key, value }
objects. The main message flows are:
Page URL → PageHost — when a content page
finishes loading it posts its full URL to window.top.
PageHost receives the message and writes the URL into its URL bar.
File name → Explorer — each content page also
posts its short file name to window.parent (the Explorer).
The Explorer uses this to highlight the matching link in its left-panel
navigation tree and to update its own session state.
Menu-toggle commands → content page — Explorer
site-level menu buttons post toggle messages down into the content iframe.
The content page responds by showing or hiding the requested page-level
menu panel (Sections, Pages, Keys).
Navigation commands → Explorer — content pages
can post next/prev/up/down navigation requests to the Explorer, which
responds by updating the right-panel iframe src.
Message handlers are centralised in
js/contentMessages.js (content-side),
js/PageHost.js (PageHost-side), and
js/ExplorerMsg.js (Explorer-side).