diff --git a/extension/bin/lib/copyFilesPlugin.js b/extension/bin/lib/copyFilesPlugin.js index 7fa7408..ee3c863 100644 --- a/extension/bin/lib/copyFilesPlugin.js +++ b/extension/bin/lib/copyFilesPlugin.js @@ -49,26 +49,8 @@ export default opts => { return { name: "copy-files", setup(build) { - /** First run for the set of import paths in each build. */ - let isFirstRun = true; - build.onResolve({ filter: /.*/ }, () => { - /** - * Attach watch files to first resolve result. - * Presumably there is a much better way of doing - * this? - */ - if (isFirstRun) { - isFirstRun = false; - return { - watchFiles: matchingPaths - }; - } - }); - build.onEnd(() => { - isFirstRun = true; - - // Copy any watched files that changed + // Copy any source files that changed for (const srcPath of matchingPaths) { const destPath = path.resolve( opts.dest, diff --git a/extension/src/background/whitelist.ts b/extension/src/background/whitelist.ts index 26f651c..a1a9406 100644 --- a/extension/src/background/whitelist.ts +++ b/extension/src/background/whitelist.ts @@ -4,10 +4,7 @@ import options from "../lib/options"; import { cacheUaInfo, getChromeUserAgentString } from "../lib/userAgents"; import { RemoteMatchPattern } from "../lib/matchPattern"; -import { - CAST_FRAMEWORK_LOADER_SCRIPT_URL, - CAST_LOADER_SCRIPT_URL -} from "../cast/urls"; +import { CAST_SDK_SCRIPT_URL_PATTERNS } from "../cast/urls"; // Missing on @types/firefox-webext-browser type OnBeforeSendHeadersDetails = Parameters< @@ -194,15 +191,6 @@ async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) { } } - await browser.scripting.executeScript({ - target: { tabId: details.tabId, frameIds: [details.frameId] }, - func: (isFramework: boolean) => { - (window as any).isFramework = isFramework; - }, - args: [details.url === CAST_FRAMEWORK_LOADER_SCRIPT_URL], - injectImmediately: true - }); - await browser.scripting.executeScript({ target: { tabId: details.tabId, frameIds: [details.frameId] }, files: ["cast/contentBridge.js"], @@ -226,7 +214,7 @@ async function registerSiteWhitelist() { browser.webRequest.onBeforeRequest.addListener( onBeforeCastSDKRequest, - { urls: [CAST_LOADER_SCRIPT_URL, CAST_FRAMEWORK_LOADER_SCRIPT_URL] }, + { urls: CAST_SDK_SCRIPT_URL_PATTERNS }, ["blocking"] ); diff --git a/extension/src/cast/content.ts b/extension/src/cast/content.ts index 1e9f2e4..6ae5131 100644 --- a/extension/src/cast/content.ts +++ b/extension/src/cast/content.ts @@ -3,45 +3,15 @@ * script. Handles API object creation and initializes sender apps. */ -import logger from "../lib/logger"; -import { loadScript } from "../lib/utils"; - import pageMessaging from "./pageMessaging"; import CastSDK from "./sdk"; -import { CAST_FRAMEWORK_SCRIPT_URL } from "./urls"; // Create page-accessible API object window.chrome.cast = new CastSDK(); -let frameworkScriptPromise: Promise | undefined; - -// Load remote CAF script if requested in script URL params. -if (document.currentScript) { - const currentScript = document.currentScript as HTMLScriptElement; - const currentScriptParams = new URLSearchParams( - new URL(currentScript.src).search - ); - - if (currentScriptParams.get("loadCastFramework") === "1") { - frameworkScriptPromise = new Promise((resolve, reject) => { - const scriptEl = document.createElement("script"); - scriptEl.src = CAST_FRAMEWORK_SCRIPT_URL; - (document.head ?? document.documentElement).append(scriptEl); - scriptEl.addEventListener("load", () => resolve(scriptEl)); - scriptEl.addEventListener("error", () => reject()); - }); - frameworkScriptPromise.catch(() => { - logger.error("Failed to load CAF script!"); - }); - } -} - pageMessaging.page.addListener(async message => { switch (message.subject) { case "cast:instanceCreated": { - // If framework API is loading, wait until completed - await frameworkScriptPromise; - // Call page script/framework API script's init function const initFn = window.__onGCastApiAvailable; if (initFn && typeof initFn === "function") { diff --git a/extension/src/cast/contentInitial.ts b/extension/src/cast/contentInitial.ts index 4616df6..5a5af06 100644 --- a/extension/src/cast/contentInitial.ts +++ b/extension/src/cast/contentInitial.ts @@ -4,7 +4,7 @@ * chrome-extension:// cast script loads. */ -import { CAST_LOADER_SCRIPT_URL, CAST_SCRIPT_URLS } from "./urls"; +import { CAST_EXTENSION_SENDER_SCRIPT_URLS, CAST_SDK_SCRIPT_URL } from "./urls"; declare global { interface Object { @@ -19,17 +19,12 @@ declare global { __onGCastApiAvailable: (isAvailable: boolean) => void; } interface Navigator { - presentation: object; + presentation: object | undefined; } } window.wrappedJSObject.chrome = cloneInto({}, window); - -/** - * YouTube won't load the cast SDK unless it thinks the presentation API - * exists. - */ -if (window.location.host === "www.youtube.com") { +if (!window.wrappedJSObject.navigator.presentation) { window.wrappedJSObject.navigator.presentation = cloneInto({}, window); } @@ -48,8 +43,8 @@ Reflect.defineProperty(HTMLScriptElement.prototype.wrappedJSObject, "src", { get: srcPropDesc?.get, set: exportFunction(function (this: HTMLScriptElement, value: string) { - if (CAST_SCRIPT_URLS.includes(value)) { - return srcPropDesc?.set?.call(this, CAST_LOADER_SCRIPT_URL); + if (CAST_EXTENSION_SENDER_SCRIPT_URLS.includes(value)) { + return srcPropDesc?.set?.call(this, CAST_SDK_SCRIPT_URL); } return srcPropDesc?.set?.call(this, value); diff --git a/extension/src/cast/urls.ts b/extension/src/cast/urls.ts index 95ab1c9..754b75c 100644 --- a/extension/src/cast/urls.ts +++ b/extension/src/cast/urls.ts @@ -1,41 +1,26 @@ -/** - * Cast Chrome Sender SDK loader script. - * - * Since the actual SDK script is hosted locally within Chrome, - * this script just acts a loader script whilst also doing some - * UA string checking. - */ -export const CAST_LOADER_SCRIPT_URL = - "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"; - -/** - * Cast Chrome Sender Framework API loader script. - * - * Same URL as the usual loader script, but the additional - * search parameter is checked from within the script and - * the framework API script is conditionally loaded in - * addition to the regular SDK script. - */ -export const CAST_FRAMEWORK_LOADER_SCRIPT_URL = `${CAST_LOADER_SCRIPT_URL}?loadCastFramework=1`; - /** * Cast extension URLs. * - * Cast functionality in Chrome was previously provided by - * an extension. The cast SDK scripts are still provided via - * chrome-extension: URLs for compatibility reasons (?). + * Cast functionality in Chrome was previously provided by an extension. The + * cast SDK scripts are still provided via chrome-extension: URLs for + * compatibility reasons (?). */ -export const CAST_SCRIPT_URLS = [ +export const CAST_EXTENSION_SENDER_SCRIPT_URLS = [ "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_sender.js", "chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js" ]; /** - * Cast Chrome Sender Framework API script. + * Cast SDK script URLs loaded by the Google cast loader script. * - * The Cast Application Framework (CAF) is implemented as a - * wrapper around the base SDK, and ditributed remotely, as - * opposed to within the cast extension. + * The loader attempts to load the cast SDK from this URL. This is intercepted + * by the extension's webRequest handlers and redirected to the local cast SDK + * implementation. */ -export const CAST_FRAMEWORK_SCRIPT_URL = - "https://www.gstatic.com/cast/sdk/libs/sender/1.0/cast_framework.js"; +export const CAST_SDK_SCRIPT_URL = + "https://www.gstatic.com/eureka/clank/cast_sender.js"; + +export const CAST_SDK_SCRIPT_URL_PATTERNS = [ + "*://www.gstatic.com/eureka/clank/*/cast_sender.js", + "*://www.gstatic.com/eureka/clank/cast_sender.js" +];