Remove framework URL script injection

This commit is contained in:
hensm
2026-03-14 16:40:25 +00:00
parent 6cdd0e548e
commit fd440b2983
5 changed files with 23 additions and 103 deletions

View File

@@ -49,26 +49,8 @@ export default opts => {
return { return {
name: "copy-files", name: "copy-files",
setup(build) { 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(() => { build.onEnd(() => {
isFirstRun = true; // Copy any source files that changed
// Copy any watched files that changed
for (const srcPath of matchingPaths) { for (const srcPath of matchingPaths) {
const destPath = path.resolve( const destPath = path.resolve(
opts.dest, opts.dest,

View File

@@ -4,10 +4,7 @@ import options from "../lib/options";
import { cacheUaInfo, getChromeUserAgentString } from "../lib/userAgents"; import { cacheUaInfo, getChromeUserAgentString } from "../lib/userAgents";
import { RemoteMatchPattern } from "../lib/matchPattern"; import { RemoteMatchPattern } from "../lib/matchPattern";
import { import { CAST_SDK_SCRIPT_URL_PATTERNS } from "../cast/urls";
CAST_FRAMEWORK_LOADER_SCRIPT_URL,
CAST_LOADER_SCRIPT_URL
} from "../cast/urls";
// Missing on @types/firefox-webext-browser // Missing on @types/firefox-webext-browser
type OnBeforeSendHeadersDetails = Parameters< 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({ await browser.scripting.executeScript({
target: { tabId: details.tabId, frameIds: [details.frameId] }, target: { tabId: details.tabId, frameIds: [details.frameId] },
files: ["cast/contentBridge.js"], files: ["cast/contentBridge.js"],
@@ -226,7 +214,7 @@ async function registerSiteWhitelist() {
browser.webRequest.onBeforeRequest.addListener( browser.webRequest.onBeforeRequest.addListener(
onBeforeCastSDKRequest, onBeforeCastSDKRequest,
{ urls: [CAST_LOADER_SCRIPT_URL, CAST_FRAMEWORK_LOADER_SCRIPT_URL] }, { urls: CAST_SDK_SCRIPT_URL_PATTERNS },
["blocking"] ["blocking"]
); );

View File

@@ -3,45 +3,15 @@
* script. Handles API object creation and initializes sender apps. * script. Handles API object creation and initializes sender apps.
*/ */
import logger from "../lib/logger";
import { loadScript } from "../lib/utils";
import pageMessaging from "./pageMessaging"; import pageMessaging from "./pageMessaging";
import CastSDK from "./sdk"; import CastSDK from "./sdk";
import { CAST_FRAMEWORK_SCRIPT_URL } from "./urls";
// Create page-accessible API object // Create page-accessible API object
window.chrome.cast = new CastSDK(); window.chrome.cast = new CastSDK();
let frameworkScriptPromise: Promise<HTMLScriptElement> | 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 => { pageMessaging.page.addListener(async message => {
switch (message.subject) { switch (message.subject) {
case "cast:instanceCreated": { case "cast:instanceCreated": {
// If framework API is loading, wait until completed
await frameworkScriptPromise;
// Call page script/framework API script's init function // Call page script/framework API script's init function
const initFn = window.__onGCastApiAvailable; const initFn = window.__onGCastApiAvailable;
if (initFn && typeof initFn === "function") { if (initFn && typeof initFn === "function") {

View File

@@ -4,7 +4,7 @@
* chrome-extension:// cast script loads. * 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 { declare global {
interface Object { interface Object {
@@ -19,17 +19,12 @@ declare global {
__onGCastApiAvailable: (isAvailable: boolean) => void; __onGCastApiAvailable: (isAvailable: boolean) => void;
} }
interface Navigator { interface Navigator {
presentation: object; presentation: object | undefined;
} }
} }
window.wrappedJSObject.chrome = cloneInto({}, window); window.wrappedJSObject.chrome = cloneInto({}, window);
if (!window.wrappedJSObject.navigator.presentation) {
/**
* YouTube won't load the cast SDK unless it thinks the presentation API
* exists.
*/
if (window.location.host === "www.youtube.com") {
window.wrappedJSObject.navigator.presentation = cloneInto({}, window); window.wrappedJSObject.navigator.presentation = cloneInto({}, window);
} }
@@ -48,8 +43,8 @@ Reflect.defineProperty(HTMLScriptElement.prototype.wrappedJSObject, "src", {
get: srcPropDesc?.get, get: srcPropDesc?.get,
set: exportFunction(function (this: HTMLScriptElement, value: string) { set: exportFunction(function (this: HTMLScriptElement, value: string) {
if (CAST_SCRIPT_URLS.includes(value)) { if (CAST_EXTENSION_SENDER_SCRIPT_URLS.includes(value)) {
return srcPropDesc?.set?.call(this, CAST_LOADER_SCRIPT_URL); return srcPropDesc?.set?.call(this, CAST_SDK_SCRIPT_URL);
} }
return srcPropDesc?.set?.call(this, value); return srcPropDesc?.set?.call(this, value);

View File

@@ -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 extension URLs.
* *
* Cast functionality in Chrome was previously provided by * Cast functionality in Chrome was previously provided by an extension. The
* an extension. The cast SDK scripts are still provided via * cast SDK scripts are still provided via chrome-extension: URLs for
* chrome-extension: URLs for compatibility reasons (?). * compatibility reasons (?).
*/ */
export const CAST_SCRIPT_URLS = [ export const CAST_EXTENSION_SENDER_SCRIPT_URLS = [
"chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_sender.js", "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_sender.js",
"chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/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 * The loader attempts to load the cast SDK from this URL. This is intercepted
* wrapper around the base SDK, and ditributed remotely, as * by the extension's webRequest handlers and redirected to the local cast SDK
* opposed to within the cast extension. * implementation.
*/ */
export const CAST_FRAMEWORK_SCRIPT_URL = export const CAST_SDK_SCRIPT_URL =
"https://www.gstatic.com/cast/sdk/libs/sender/1.0/cast_framework.js"; "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"
];