PageSourceSearch

https://ai-agent.buzz/assets/js/iframe-tracker.js?m=1784312666.0

js ai-agent.buzz collected 2026-09-29 08:53:53 UTC 5,160 bytes, 96 lines download raw bytes

1/* iframe-tracker.js — canvas iframe sister-app URL tracking + cast-save (Phase 4 / 0.9.0; cast 0.x)
2 *
3 * A trusted sister app (piratesbargain.com, 2plot.ai, cast.2plot.net, …) posts to the canvas. Two
4 * envelopes, both accepted ONLY when event.origin is on the server-provided allow-list
5 * (window.__trustedEmbedOrigins, mirrored from the `trusted-embed-origins` store by a clientside
6 * callback) and matched to the iframe that sent them by contentWindow:
7 *
8 *   1) {type:'canvas-iframe-url', url: location.href}  — a navigation beacon. We push {id, url, ts}
9 *      into `iframe-url-sync`; a server callback persists the tile's `last_url` so the iframe reopens
10 *      its last page across save/reload.
11 *   2) {type:'cast-save', filmstrip: <manifest>}  — an embedded cast.2plot.net session baked a run and
12 *      the user clicked "Save to canvas". We push {filmstrip, source_id, ts} into `cast-save-sync`; a
13 *      server callback (state_sync.sync_cast_save) validates the manifest (URL frames only) and spawns
14 *      a DashFilmstrip tile next to the source session. The manifest is a few KB of CDN URLs — the
15 *      canvas never touches image bytes.
16 *   3) {type:'canvas-iframe-thumb', thumb_url: <https image URL>}  — a self-reported thumbnail: the
17 *      sister app hands us a pre-rendered screenshot of itself. We push {id, thumb_url, ts} into
18 *      `iframe-thumb-sync`; a server callback persists it and the save-time rehost
19 *      (lib/iframe_thumbs) downloads it into OUR R2 in place of a cast Chromium capture. URLs only —
20 *      the bytes move server-side at save time.
21 *
22 * SECURITY: fails CLOSED — an empty/undefined allow-list rejects every message; arbitrary external sites
23 * (which we don't control and whose URL the browser SOP hides anyway) are never tracked. This is exactly
24 * the mechanism that lifts that wall for the sister apps we DO control. Origin is verified BEFORE we read
25 * any field of event.data, and each message is only ever associated with the frame that actually sent it.
26 */
27(function () {
28    'use strict';
29    if (window.__iframeTrackerBound) return;
30    window.__iframeTrackerBound = true;
31    window.__trustedEmbedOrigins = window.__trustedEmbedOrigins || [];
32
33    function parseCompId(frame) {
34        // The canvas iframe id is the stringified pattern {"type":"canvas-iframe","index":"<comp_id>"}.
35        try {
36            var parsed = JSON.parse(frame.id);
37            if (parsed && parsed.type === 'canvas-iframe' && parsed.index) return parsed.index;
38        } catch (e) { /* not a canvas iframe */ }
39        return null;
40    }
41
42    function sourceCompId(source) {
43        // The comp_id of the canvas iframe tile whose contentWindow sent this message (or null).
44        var frames = document.querySelectorAll('iframe');
45        for (var i = 0; i < frames.length; i++) {
46            if (frames[i].contentWindow === source) return parseCompId(frames[i]);
47        }
48        return null;
49    }
50
51    window.addEventListener('message', function (event) {
52        // 1) Origin gate FIRST — fail closed.
53        var allow = window.__trustedEmbedOrigins;
54        if (!Array.isArray(allow) || allow.indexOf(event.origin) === -1) return;
55
56        var d = event.data;
57        if (!d || typeof d !== 'object') return;
58        if (!(window.dash_clientside && window.dash_clientside.set_props)) return;
59
60        // 2a) Navigation beacon — persist the iframe's last URL (matched to the frame that sent it).
61        if (d.type === 'canvas-iframe-url' && typeof d.url === 'string') {
62            var compId = sourceCompId(event.source);
63            if (compId) {
64                window.dash_clientside.set_props('iframe-url-sync', {
65                    data: { id: compId, url: d.url, ts: Date.now() }
66                });
67            }
68            return;
69        }
70
71        // 2c) Self-reported thumbnail — the sister app hands us a pre-rendered screenshot URL of
72        // itself. Server-side validation + the actual byte transfer happen at save time
73        // (state_sync.sync_iframe_thumb → lib/iframe_thumbs rehost).
74        if (d.type === 'canvas-iframe-thumb' && typeof d.thumb_url === 'string') {
75            var tid = sourceCompId(event.source);
76            if (tid) {
77                window.dash_clientside.set_props('iframe-thumb-sync', {
78                    data: { id: tid, thumb_url: d.thumb_url, ts: Date.now() }
79                });
80            }
81            return;
82        }
83
84        // 2b) cast-save — an embedded cast.2plot.net session baked a run. Hand the manifest to the
85        // server (URLs only; validated server-side) along with the source session tile's id so the
86        // new filmstrip tile can be placed next to it.
87        if (d.type === 'cast-save' && d.filmstrip && typeof d.filmstrip === 'object') {
88            window.dash_clientside.set_props('cast-save-sync', {
89                data: { filmstrip: d.filmstrip, source_id: sourceCompId(event.source), ts: Date.now() }
90            });
91            return;
92        }
93    }, false);
94
95    console.log('🔗 iframe URL tracker + cast-save listener bound (trusted-embed sister-app integration)');
96})();

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.