fix: run deep probe and scraper in MAIN world for access to page globals
CI / test (pull_request) Successful in 24s

The root cause of repeated 'does not detect any videos' failures was that
m3u8DeepProbeFn and scrapeFn were injected via chrome.scripting.executeScript
in the isolated world (default). From the isolated world:

- window.__goon_plugin_data (set by main-world interceptors) — NOT visible
- window.Hls / Hls.cast (page's hls.js) — NOT visible
- Player globals (PHPlayer, flowplayer, etc.) — NOT visible
- Config globals (__NEXT_DATA__, appData, etc.) — NOT visible

Only DOM properties like video._goon_hls_manifest cross the boundary, making
the detection pipeline mostly blind on real HLS sites.

Fix: set world: 'MAIN' on both executeScript calls so all 6 deep probe
strategies and all 5 scrape priorities actually work. Chrome MV3 supports
this since Chrome 108; our build targets chrome110.
This commit is contained in:
robot committed 2026-08-12 11:11:06 +00:00
1 parent 11e697915e
commit a128babde0
1 file changed
+17 -2
+17 -2
View File
@@ -323,13 +323,21 @@ function filterValidTabs(tabs) {
/** /**
* Probe all frames in a tab for HLS manifests. * Probe all frames in a tab for HLS manifests.
* Runs in the MAIN world so strategies that depend on page globals work:
* - window.__goon_plugin_data.manifests (set by main-world interceptors)
* - window.Hls / Hls.cast (page's hls.js global)
* - player globals (PHPlayer, flowplayer, etc.)
* - config globals (__NEXT_DATA__, appData, etc.)
*
* The default isolated world cannot see these — only DOM properties like
* video._goon_hls_manifest cross the boundary.
* @param {number} tabId * @param {number} tabId
* @returns {Promise<Array>} array of { url, player } or empty on error * @returns {Promise<Array>} array of { url, player } or empty on error
*/ */
async function probeHlsManifests(tabId) { async function probeHlsManifests(tabId) {
try { try {
const results = await chrome.scripting.executeScript({ const results = await chrome.scripting.executeScript({
target: { tabId, allFrames: true }, target: { tabId, allFrames: true, world: 'MAIN' },
func: m3u8DeepProbeFn, func: m3u8DeepProbeFn,
}); });
return results.flatMap(r => r.result || []); return results.flatMap(r => r.result || []);
@@ -384,6 +392,13 @@ async function queryContentScript(tabId) {
* Scrape video elements from ALL frames in a tab. * Scrape video elements from ALL frames in a tab.
* On sites like Pornhub, the video player lives inside an iframe — main-frame-only * On sites like Pornhub, the video player lives inside an iframe — main-frame-only
* scraping sees zero <video> elements. Running allFrames catches them. * scraping sees zero <video> elements. Running allFrames catches them.
*
* Runs in the MAIN world so it can see page globals:
* - Hls.cast(video) — the official hls.js API to get bound instances
* - window.__goon_plugin_data (interceptor-collected manifests)
*
* The default isolated world would miss all of these, causing the same
* "does not detect any videos" failure kfj001 reported.
* @param {number} tabId * @param {number} tabId
* @param {Array} manifests - HLS manifests found by probing * @param {Array} manifests - HLS manifests found by probing
* @returns {Promise<Object|null>} scrape result or null on error * @returns {Promise<Object|null>} scrape result or null on error
@@ -391,7 +406,7 @@ async function queryContentScript(tabId) {
async function scrapeTab(tabId, manifests) { async function scrapeTab(tabId, manifests) {
try { try {
const results = await chrome.scripting.executeScript({ const results = await chrome.scripting.executeScript({
target: { tabId, allFrames: true }, target: { tabId, allFrames: true, world: 'MAIN' },
func: scrapeFn, func: scrapeFn,
args: [manifests], args: [manifests],
}); });