Remote Tab Opener — Google & YouTube
Open Google, run a search, read the first result, and pass it to a YouTube tab — safely and locally.
This page is a reproducible E2E example using only named actions (no eval()): open, focus, type, submit, read, navigate.
*.google.com and *.youtube.com.
What you’ll explore on this page
This demo shows how the Remote Tab Opener extension lets an admin page open, focus, type into, submit, and read from another browser tab—then forward what it finds to a second tab (YouTube). Everything runs locally in your browser: no servers, no proxies, no cookie sharing.
The guided journey
- Step 1 — Open Google: create a controlled tab (
tabKey="google") and mirror its status on this page. - Step 2 — Style, focus & type: highlight the search box, focus it, and type your query from this page’s input.
- Step 2b — Submit: trigger the Google search form directly from the admin page.
- Step 3 — Read a result: fetch the first result (title + snippet) and preview it here, as JSON-backed UI.
- Step 4 — Bridge to YouTube: open that result URL in a new or existing controlled YouTube tab.
- Step 5 — Secondary YouTube: spawn a separate controlled tab to illustrate independence between tabs.
- Step 6 — Read a suggestion: scrape a suggested video in YouTube and preview it locally; optionally open it in the main YouTube tab.
- Step 7 — Close or focus the tabs: cleanly close the controlled tabs - or Focus - and see the live list update.
What you’ll learn
- Named actions, not code injection: actions like
open,focusElement,domType,submit,getHtmlare invoked with predefined selectors—never witheval(). - Two-tab choreography: how to extract data from tab A (Google) and use it to drive tab B (YouTube).
- Live telemetry: this page mirrors URL and status events emitted by the extension for traceability.
- Resilience patterns: watchdogs, mutex for
getHtml, and busy-state UI to keep flows robust.
Safety & privacy model
- Allow-list only: actions run inside controlled pages for domains you explicitly allow in the popup.
- No SOP bypass: the extension never hands cookies or privileged context to this admin page.
- Local-first: all steps happen in your browser; this page only displays returned snippets/URLs.
What you need before trying
- Install/enable the extension, then allow-list
google.comandyoutube.com. - Open DevTools (F12) to inspect the JSON payloads for each action.
Common hiccups & quick fixes
EXT_NOT_DETECTED→ ensure the extension is installed and this page reloaded.DOMAIN_NOT_ALLOWED→ add the domain in the extension’s allow-list, then retry.ELEMENT_NOT_FOUND→ the selector changed; reload the target page or adjust the selector.NO_CONTROLLED_TAB→ (re)open the target tab via Step 1/5.TIMEOUT→ wait for page load or reduce competing actions; the mutex prevents interleaved reads.
Tip: this demo is reproducible—copy the page, change selectors, keep the named actions. You get reliable, local E2E control without infrastructure.
Step 0 — Prepare
- Install/enable the extension, then open this page.
- In the RTO popup, add
google.comandyoutube.comto the allow-list. - Keep your console open F12 to view JSON returns.
Guided demo — Google → YouTube
Controlled tabs: tabKey="google" and tabKey="youtube". The extension drives non-sensitive fields and submits the Google search.
Step 1 — Open Google
Open https://www.google.com/ in a controlled tab (tabKey="google") with focus. The status mirrors below.
open + focus and emits tabStatus.
If you see Domain not allowed , add google.com. Step 2 — Style, focus, and type the query
Highlight the Google search box, focus it, and type your keyword.
Remote form actions :
domSetStyle → focusElement → domType → submit.Step 3 — Read the first Google result
Fetch the first available result (title + snippet) and preview it here.
The first Google result will display here
Why RTO reads Google SERPs reliably
Google results are largely server-rendered: links, titles, and snippets are already present in the delivered HTML. There’s no complex hydration needed to get the “first result.”
Implications
- Stable anchors:
<a href="https://…">elements ship in the initial document. - RTO queries the tab’s DOM after load, which mirrors the received HTML.
- Edge cases: A/B modules or lazy blocks may delay some sections, but the “top result” is usually present without special focus.
#search .tF2Cxc .yuRUbf a[href^="http"]
.tF2Cxc a[href^="http"]
Step 4 — Open the first result in YouTube
Open the extracted URL in the main tabKey="youtube" (creates/focuses it).
https://… /watch?v=1234abcd, Step 6 will not work. If the YouTube tab is already open, please manually bring it to the foreground.
Why? YouTube renders only when its tab has focus. Otherwise, Step 6 will not work.
OPTIONAL - Step 5 — Open a secondary YouTube tab
Create an extra controlled tab (tabKey="youtube-extra") to demonstrate independence.
See below the Display : opened RTO tabs list
Step 6 — Read a suggested video
Read a video suggestion from the YouTube tab and preview it here.
The DOM doesn’t exist until the YouTube tab is brought to the foreground at least once.
The video card will display here
Why RTO can read YouTube
when “View Source” can’t
YouTube’s homepage is a Single-Page App. The downloaded HTML is mostly a lightweight shell plus a large JSON
object (e.g., ytInitialData). The actual cards—titles, thumbnails, and <a href="/watch"> links—
are created later by JavaScript and Web Components (hydration).
What the download does (and doesn’t) contain
- Skeleton markup: container elements and placeholders.
- Boot data: a big JS object (
ytInitialData) consumed on the client. - Missing pieces: no final
/watchanchors or hydrated titles at view-source time.
Tools that only “download the HTML” (network scrapers, view-source, plain fetch())
see the skeleton, not the rendered video list.
What RTO does differently
- Talks to the live tab: sends commands and queries the real, post-JS DOM.
- Post-hydration access: extracts only after selectors like
a#thumbnail[href^="/watch"]anda#video-titleexist for real. - Safe readout: returns sanitized
outerHTML/textContentsnippets.
ytd-rich-item-renderer:nth-of-type(N) a#thumbnail[href^="/watch"]
ytd-rich-item-renderer:nth-of-type(N) a#video-title
Mental model
Downloaded HTML ≠ Rendered DOM. RTO reads the Rendered DOM inside the real tab.
Step 6b — Using the YouTube suggestion
https://…Step 7 — Close of focus tabs
Display : opened RTO tabs
⚠️ if you add a delay update to the script, this list will automatically refresh.
RTO is exceptional by design
Lots of tools can “fetch HTML.” Very few can teach with it. RTO is built for live, post-JavaScript DOM reading and classroom-friendly control of real tabs, all through a tiny, predictable command set.
What makes RTO different
- Live DOM, not downloads: queries the rendered page after hydration (post-JS, post-framework).
- Named tab orchestration: address tabs by human keys (
google,youtube,youtube-extra (2)). - Deterministic commands:
open,navigate,getHtml,highlight,submit,runJs— small, teachable verbs. - Safety built-in: sanitized snippets, blocked sensitive inputs, allowlist by host/wildcard.
- Teaching ergonomics: control banner, transient highlights, preview-ready HTML/texte.
- Latency aware: gentle focus nudges and short timeouts to keep the UI snappy.
- MV3-ready core: resilient content injection + alias registry with push telemetry.
Why other approaches struggle
- “View Source” & raw fetch: see the skeleton, not the hydrated cards/links.
- Record-and-playback tools: great for macros, brittle for live teaching with previews.
- Headless scrapers: powerful, but run outside your browser; no immediate classroom feedback.
- Ad-hoc userscripts: flexible, but you must re-invent messaging, safety, tab registry, timeouts…
- Read a YouTube suggestion with
getHtmlon hydrated selectors (cards that don’t exist in “View Source”). - Open/focus by
tabKey(no tab explosion), thennavigatewithout losing the teaching context. - Show the safe preview: sanitized HTML, links forced to
target="_blank".
ytd-rich-item-renderer:nth-of-type(N) a#thumbnail[href^="/watch"]
ytd-rich-item-renderer:nth-of-type(N) a#video-title
Source codes : Base and Assets.
-
index.jsbase
Shared UI & utilities (detector banner, mirrors, helpers). -
demo_master.jsbus
Admin–extension handshake & tiny bus. - router + Step 5
-
lab_helpers.jshelpers
Minimal helpers for logging, clipboard, postMessage, and ping/waitFor.
- 1
-
google_style_and_type.js2
Step 2 — Style + focus + type query. -
google_submit.js2
Step 2 — Submit the Google form. -
google_first_result_reader.js3–4
Step 3–4 — Read first result and expose its URL. -
youtube_tab_manager.js4
Step 4 — Open/focus YouTube main or secondary tab. -
Step 5 — Included in router.js (see above).5
-
youtube_result_preview.js6
Step 6 — Read and preview a suggested video. -
close_main_tabs.js7
Step 7 — Close Google/YouTube tabs. -
rto_list_tabs_ui.jstabs
RTO tabs table (live list of controlled tabs). -
rto_core.jscore
Shared core helpers for this page. - mutex
-
open_in_same_tab.jsnav
Navigate within the current controlled tab.
Live results
- Current URL:
- Status: closed
google.com and youtube.com are allow-listed and the remote page has finished loading.