Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Bug 2006036 - Site does not load on Firefox.
*
* They are doing something odd which appears to break Firefox on purpose.
*/
if (!window.chrome) {
console.info(
"The window environment is being altered for compatibility reasons. See https://bugzilla.mozilla.org/show_bug.cgi?id=2006036 for details."
);
delete window.InstallTrigger;
delete window.mozInnerScreenX;
delete window.mozInnerScreenY;
delete window.MozConsentBanner;
const nav = Object.getPrototypeOf(navigator);
const vendor = Object.getOwnPropertyDescriptor(nav, "vendor");
vendor.get = () => "Google Inc.";
Object.defineProperty(nav, "vendor", vendor);
const supports = Object.getOwnPropertyDescriptor(CSS, "supports");
const oldSupports = supports.value;
supports.value = function (query) {
if (query.includes("moz-")) {
return false;
}
return oldSupports.call(this, query);
};
Object.defineProperty(CSS, "supports", supports);
function generateTimeStamp(base, factor = 10) {
if (base) {
// increase another timestamp by a little
return (base + Math.random() * factor).toString().substr(0, 14);
}
const r = Math.random().toString();
const d10 = `1${r.substr(5, 9)}`;
const d3 = r.substr(2, 3);
return parseFloat(`${d10}.${d3}`);
}
const startLoadTime = generateTimeStamp();
const commitLoadTime = generateTimeStamp(startLoadTime);
const firstPaintTime = generateTimeStamp(commitLoadTime);
const finishDocumentLoadTime = generateTimeStamp(firstPaintTime);
const finishLoadTime = generateTimeStamp(finishDocumentLoadTime);
const csi = {
onloadT: parseInt(finishDocumentLoadTime * 100),
pageT: generateTimeStamp().toString().substr(-11),
startE: parseInt(parseFloat(startLoadTime * 100)),
tran: 10 + parseInt(4 + Math.random() * 4),
};
const loadTimes = {
commitLoadTime,
connectionInfo: "h3",
finishDocumentLoadTime,
finishLoadTime,
firstPaintAfterLoadTime: 0,
firstPaintTime,
navigationType: "Other",
npnNegotiatedProtocol: "h3",
requestTime: startLoadTime,
startLoadTime,
wasAlternateProtocolAvailable: false,
wasFetchedViaSpdy: true,
wasNpnNegotiated: true,
};
window.chrome = {
app: {
InstallState: {
DISABLED: "disabled",
INSTALLED: "installed",
NOT_INSTALLED: "not_installed",
},
RunningState: {
CANNOT_RUN: "cannot_run",
READY_TO_RUN: "ready_to_run",
RUNNING: "running",
},
getDetails() {
return null;
},
getIsInstalled() {
return false;
},
installState() {
return undefined;
},
isInstalled: false,
runningState() {
return window.chrome.app.InstallState.NOT_INSTALLED;
},
},
csi() {
return csi;
},
loadTimes() {
return loadTimes;
},
};
const ua = navigator.userAgent;
const mobile = ua.includes("Android");
// Very roughly matches Chromium's GetPlatformForUAMetadata()
let platform = "Linux";
if (mobile) {
platform = "Android";
} else if (navigator.platform.startsWith("Win")) {
platform = "Windows";
} else if (navigator.platform.startsWith("Mac")) {
platform = "macOS";
}
const version = ua.match(/Chrome\/([0-9]+)/)[1];
// These match Chrome's output as of version 126.
const brands = [
{
brand: "Not/A)Brand",
version: "8",
},
{
brand: "Chromium",
version,
},
{
brand: "Google Chrome",
version,
},
];
// Site checks the high-entropy platformVersion on Windows.
const userAgentData = {
brands,
mobile,
platform,
getHighEntropyValues() {
return Promise.resolve({
brands,
mobile,
platform,
platformVersion: "19.0.0",
});
},
};
Object.defineProperty(nav, "userAgentData", {
get: () => userAgentData,
set: () => {},
});
}