mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor(site): drop redundant window. prefix on browser globals (#24500)
This commit is contained in:
@@ -62,6 +62,10 @@ When investigating or editing TypeScript/React code, always use the TypeScript l
|
||||
- Destructure imports when possible (eg. import { foo } from 'bar')
|
||||
- Prefer `for...of` over `forEach` for iteration
|
||||
- **Biome** handles both linting and formatting (not ESLint/Prettier)
|
||||
- Access browser globals like `location`, `navigator`, and `document`
|
||||
directly. Do not prefix them with `window.` (e.g., write
|
||||
`location.href`, not `window.location.href`). They are globally
|
||||
available in every browser context.
|
||||
- Always use react-query for data fetching. Do not attempt to manage any
|
||||
data life cycle manually. Do not ever call an `API` function directly
|
||||
within a component.
|
||||
|
||||
@@ -129,7 +129,7 @@ type RenderResult = ReturnType<typeof renderUseClipboard>["result"];
|
||||
// execCommand is the workaround for copying text to the clipboard on HTTP-only
|
||||
// connections
|
||||
const originalExecCommand = global.document.execCommand;
|
||||
const originalNavigator = window.navigator;
|
||||
const originalNavigator = navigator;
|
||||
|
||||
// Not a big fan of describe.each most of the time, but since we need to test
|
||||
// the exact same test cases against different inputs, and we want them to run
|
||||
|
||||
@@ -61,7 +61,7 @@ export const useClipboard = (
|
||||
};
|
||||
|
||||
try {
|
||||
await window.navigator.clipboard.writeText(textToCopy);
|
||||
await navigator.clipboard.writeText(textToCopy);
|
||||
markSuccess();
|
||||
} catch (err) {
|
||||
const fallbackCopySuccessful = simulateClipboardWrite(textToCopy);
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ window.addEventListener("vite:preloadError", () => {
|
||||
const now = Date.now();
|
||||
if (!last || now - Number(last) > 10_000) {
|
||||
sessionStorage.setItem(key, String(now));
|
||||
window.location.reload();
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ export const getAppHref = (
|
||||
}
|
||||
|
||||
if (host && app.subdomain && app.subdomain_name) {
|
||||
const baseUrl = `${window.location.protocol}//${host.replace(/\*/g, app.subdomain_name)}`;
|
||||
const baseUrl = `${location.protocol}//${host.replace(/\*/g, app.subdomain_name)}`;
|
||||
const url = new URL(baseUrl);
|
||||
url.pathname = "/";
|
||||
return url.toString();
|
||||
|
||||
@@ -335,7 +335,7 @@ const UserSettingsSub: FC<UserSettingsSubProps> = ({
|
||||
|
||||
export const includeOrigin = (target: string): string => {
|
||||
if (target.startsWith("/")) {
|
||||
const baseUrl = window.location.origin;
|
||||
const baseUrl = location.origin;
|
||||
return `${baseUrl}${target}`;
|
||||
}
|
||||
return target;
|
||||
|
||||
@@ -236,7 +236,7 @@ const TaskSidebarMenuItem: FC<TaskSidebarMenuItemProps> = ({ task }) => {
|
||||
<RouterLink
|
||||
to={{
|
||||
pathname: `/tasks/${task.owner_name}/${task.id}`,
|
||||
search: window.location.search,
|
||||
search: location.search,
|
||||
}}
|
||||
>
|
||||
<TaskSidebarMenuItemStatus task={task} />
|
||||
|
||||
@@ -65,7 +65,7 @@ export const TemplateFiles: FC<TemplateFilesProps> = ({
|
||||
<TemplateFileTree
|
||||
fileTree={fileTree}
|
||||
onSelect={(path: string) => {
|
||||
window.location.hash = path;
|
||||
location.hash = path;
|
||||
document.getElementById(path)?.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
|
||||
@@ -195,7 +195,7 @@ const RefreshSessionButton: FC = () => {
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setIsRefreshing(true);
|
||||
window.location.reload();
|
||||
location.reload();
|
||||
}}
|
||||
>
|
||||
<RefreshCwIcon className={cn(isRefreshing && "animate-spin")} />
|
||||
|
||||
@@ -359,7 +359,7 @@ export const AgentChatInput: FC<AgentChatInputProps> = ({
|
||||
// Listen for OAuth2 completion postMessage from popup.
|
||||
useEffect(() => {
|
||||
const handler = (event: MessageEvent) => {
|
||||
if (event.origin !== window.location.origin) return;
|
||||
if (event.origin !== location.origin) return;
|
||||
if (
|
||||
event.data?.type === "mcp-oauth2-complete" &&
|
||||
typeof event.data.serverID === "string"
|
||||
|
||||
@@ -13,7 +13,7 @@ export const ChatAccessDeniedAlert: FC = () => {
|
||||
<Alert
|
||||
severity="info"
|
||||
actions={
|
||||
<Button size="sm" onClick={() => window.location.reload()}>
|
||||
<Button size="sm" onClick={() => location.reload()}>
|
||||
Refresh
|
||||
</Button>
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ export const MCPServerPicker: FC<MCPServerPickerProps> = ({
|
||||
// Listen for OAuth2 completion postMessage from popup.
|
||||
useEffect(() => {
|
||||
const handler = (event: MessageEvent) => {
|
||||
if (event.origin !== window.location.origin) return;
|
||||
if (event.origin !== location.origin) return;
|
||||
if (
|
||||
event.data?.type === "mcp-oauth2-complete" &&
|
||||
typeof event.data.serverID === "string"
|
||||
|
||||
@@ -4,7 +4,7 @@ import { pageTitle } from "#/utils/page";
|
||||
import { CliInstallPageView } from "./CliInstallPageView";
|
||||
|
||||
const CliInstallPage: FC = () => {
|
||||
const origin = isChromatic() ? "https://example.com" : window.location.origin;
|
||||
const origin = isChromatic() ? "https://example.com" : location.origin;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -94,7 +94,7 @@ const ExternalAuthPage: FC = () => {
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
// Redirect to the auth flow again. *crosses fingers*
|
||||
window.location.href = `/external-auth/${provider}/callback`;
|
||||
location.href = `/external-auth/${provider}/callback`;
|
||||
}}
|
||||
>
|
||||
Retry
|
||||
@@ -102,7 +102,7 @@ const ExternalAuthPage: FC = () => {
|
||||
</SignInLayout>
|
||||
);
|
||||
}
|
||||
window.location.href = `/external-auth/${provider}/callback`;
|
||||
location.href = `/external-auth/${provider}/callback`;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,10 +62,10 @@ const LoginOauthDevicePageWithState: FC<{ state: string }> = ({ state }) => {
|
||||
if (!exchangeExternalAuthDeviceQuery.isSuccess) {
|
||||
return;
|
||||
}
|
||||
// We use window.location.href in lieu of a navigate hook
|
||||
// We use location.href in lieu of a navigate hook
|
||||
// because we need to refresh the page after the GitHub
|
||||
// callback query sets a session cookie.
|
||||
window.location.href = exchangeExternalAuthDeviceQuery.data.redirect_url;
|
||||
location.href = exchangeExternalAuthDeviceQuery.data.redirect_url;
|
||||
}, [
|
||||
exchangeExternalAuthDeviceQuery.isSuccess,
|
||||
exchangeExternalAuthDeviceQuery.data?.redirect_url,
|
||||
|
||||
@@ -13,8 +13,8 @@ import LoginPage from "./LoginPage";
|
||||
|
||||
describe("LoginPage", () => {
|
||||
// Capture original values before any test stubs take effect.
|
||||
const origLocationOrigin = window.location.origin;
|
||||
const origLocationHref = window.location.href;
|
||||
const origLocationOrigin = location.origin;
|
||||
const origLocationHref = location.href;
|
||||
const locationHrefSpy = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -124,7 +124,7 @@ describe("Setup Page", () => {
|
||||
|
||||
it("calls sendBeacon with telemetry", async () => {
|
||||
const sendBeacon = vi.fn();
|
||||
Object.defineProperty(window.navigator, "sendBeacon", {
|
||||
Object.defineProperty(navigator, "sendBeacon", {
|
||||
value: sendBeacon,
|
||||
});
|
||||
renderWithRouter(
|
||||
|
||||
@@ -281,7 +281,7 @@ function getClipboardCopyContent(
|
||||
organization: string,
|
||||
buttonValues: ButtonValues | undefined,
|
||||
): string {
|
||||
const deploymentUrl = `${window.location.protocol}//${window.location.host}`;
|
||||
const deploymentUrl = `${location.protocol}//${location.host}`;
|
||||
const createWorkspaceUrl = `${deploymentUrl}/templates/${organization}/${templateName}/workspace`;
|
||||
const createWorkspaceParams = new URLSearchParams(buttonValues);
|
||||
const buttonUrl = `${createWorkspaceUrl}?${createWorkspaceParams.toString()}`;
|
||||
|
||||
@@ -38,9 +38,8 @@ Object.defineProperty(window, "matchMedia", {
|
||||
});
|
||||
|
||||
const createWorkspaceTerminalWebSocket = () => {
|
||||
const websocketProtocol =
|
||||
window.location.protocol === "https:" ? "wss" : "ws";
|
||||
const websocketUrl = `${websocketProtocol}://${window.location.host}/api/v2/workspaceagents/${MockWorkspaceAgent.id}/pty?reconnect=${reconnectToken}&height=24&width=80`;
|
||||
const websocketProtocol = location.protocol === "https:" ? "wss" : "ws";
|
||||
const websocketUrl = `${websocketProtocol}://${location.host}/api/v2/workspaceagents/${MockWorkspaceAgent.id}/pty?reconnect=${reconnectToken}&height=24&width=80`;
|
||||
|
||||
return new WS(websocketUrl);
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ const SecurityPage: FC = () => {
|
||||
toast.success("Updated password.");
|
||||
// Refresh the browser session. We need to improve the AuthProvider
|
||||
// to include better API to handle these scenarios
|
||||
window.location.href = location.origin;
|
||||
location.href = location.origin;
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -36,10 +36,10 @@ export const redirectToOIDCAuth = (
|
||||
) => {
|
||||
switch (toType) {
|
||||
case "github":
|
||||
window.location.href = `/api/v2/users/oauth2/github/callback?oidc_merge_state=${stateString}&redirect=${redirectTo}`;
|
||||
location.href = `/api/v2/users/oauth2/github/callback?oidc_merge_state=${stateString}&redirect=${redirectTo}`;
|
||||
break;
|
||||
case "oidc":
|
||||
window.location.href = `/api/v2/users/oidc/callback?oidc_merge_state=${stateString}&redirect=${redirectTo}`;
|
||||
location.href = `/api/v2/users/oidc/callback?oidc_merge_state=${stateString}&redirect=${redirectTo}`;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown login type ${toType}`);
|
||||
|
||||
Reference in New Issue
Block a user