Scripts on an html page inside the about frame plugin are able to interact with wiki using specific messages - see: - About Frame Integrations - Frame Height
Considering the interaction between the wiki the embeddded HTML page we have **two sides** involved: 1. **The embedded HTML page** inside the `<iframe>`. 2. **The Federated Wiki client**, which hosts and renders that `<iframe>` using the `frame` plugin. These two use `window.postMessage()` to communicate across the frame boundary.
# What Happens and When?
digraph FrameMessageFlow { rankdir=LR; node [shape=box style=rounded fontsize=12 fontname="Helvetica"]; subgraph cluster_parent { label="Federated Wiki (Parent)"; style=dashed; wikiClient [label="Wiki Client\n(Parent Window)"]; } subgraph cluster_frame { label="Embedded Frame (iframe)"; style=dashed; framePage [label="HTML Page\n(DOM Content Loaded)"]; listener [label="Message Listener:\nhandleFrameContext"]; } framePage -> wikiClient [label="postMessage: sendFrameContext", style=bold, color=blue]; wikiClient -> listener [label="postMessage: frameContext", style=dashed, color=green]; listener -> listener [label="Remove listener", style=dotted, color=gray]; }
Let's examine an interaction where the HTML page requests the frame context - that is information about the wiki-page the plugin is situated on.
# Step 1: Embedded Page Requests Context Info When the embedded page loads (`DOMContentLoaded`), it sends a message to its parent (the wiki client) saying:
window.parent.postMessage({ action: "sendFrameContext" }, "*")
* **Sender**: the page **inside** the frame. * **Recipient**: the **wiki** client (parent window). * **When**: as soon as the embedded frame's DOM is loaded. * **Why**: to ask the wiki client for context like the page title, item ID, origin, site, etc.
# Step 2: Wiki Replies with Frame Context The wiki client understands the message (`action: "sendFrameContext"`), and will respond with a message like:
{ action: "frameContext", pageKey, itemId, origin, site, slug, item, page: {title, story} }
* **Sender**: the **wiki client (parent window)**. * **Recipient**: the **embedded HTML page**. * **When**: after receiving the `sendFrameContext` request. * **Why**: to give the embedded page access to the context it needs to adapt its behavior to the hosting wiki page.
# Step 3: Embedded Page Handles the Context The embedded page has already set up a listener:
window.addEventListener("message", handleFrameContext)
So when the parent sends the `"frameContext"` message, the handler does the following: * Logs the message and its content. * Optionally does something with the page title, item IDs, or story content. * **Removes** the event listener so it doesn’t listen multiple times.
# Frame Context Code Here we see the code demo including all the parts. You can see it in action on the About Frame Integrations page.
#
window.addEventListener("message", handleFrameContext) function handleFrameContext ({data}) { console.log("message received", data) if (data.action == "frameContext") { window.removeEventListener( "message", handleFrameContext) const {pageKey, itemId, origin, site, slug, item, page: {title, story}} = data const items = story.reduce((acc, {type}) => { acc[type] = (acc[type]||0)+1 return acc }, {}) console.log({title, items}) } } window.addEventListener( "DOMContentLoaded", () => window.parent.postMessage({ action: "sendFrameContext" }, "*") )
It may not be apparant, but the frameContext message contains the full page-json (inclusing the journal), but not inforamtion about the current lineup.
# Feature Requests
- [ ] **Lineup Array**. We would like to be able to retrieve information about the current lineup.
Full access to the dynamicly displayed content is probably not a good idea for security reasons - but knowledge of the browsers displayed url - or rather an ordered array of lineup items containing `title,slug,domain` would be useful in a number of contexts where a tool wishes to interact with page-json found in the lineup.
# See