Skip to content

Commit ac13909

Browse files
AaronPlaveclaude
andcommitted
fix: Move isMacOs to browser.ts to fix SSR error
The isMacOs() function used the `browser` variable from SvelteKit's $app/environment but the import was missing after a rebase, causing a ReferenceError during SSR that broke all e2e tests. Moved isMacOs() from generic.ts to browser.ts for better separation of concerns and updated all import references. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3be48d4 commit ac13909

10 files changed

Lines changed: 67 additions & 55 deletions

src/components/parameters/ExtraneousParameters.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { createEventDispatcher } from 'svelte';
77
import type { ActivityErrorCategories } from '../../types/errors';
88
import type { ArgumentsMap } from '../../types/parameter';
9-
import { isMacOs } from '../../utilities/generic';
9+
import { isMacOs } from '../../utilities/browser';
1010
import { isMetaOrCtrlPressed } from '../../utilities/keyboardEvents';
1111
import { permissionHandler } from '../../utilities/permissionHandler';
1212
import { pluralize } from '../../utilities/text';

src/components/parameters/ValueSourceBadge.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import { browser } from '$app/environment';
55
import { createEventDispatcher } from 'svelte';
66
import type { ParameterType, ValueSource } from '../../types/parameter';
7-
import { classNames, isMacOs } from '../../utilities/generic';
7+
import { isMacOs } from '../../utilities/browser';
8+
import { classNames } from '../../utilities/generic';
89
import { isMetaOrCtrlPressed } from '../../utilities/keyboardEvents';
910
import { tooltip } from '../../utilities/tooltip';
1011
import { useActions, type ActionArray } from '../../utilities/useActions';

src/components/sequencing/EditorToolbar.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import { Braces, Bug, Clipboard, Download, FileOutput } from 'lucide-svelte';
66
import { createEventDispatcher } from 'svelte';
77
import type { ActionDefinition } from '../../types/actions';
8-
import { isMacOs } from '../../utilities/generic';
8+
import { isMacOs } from '../../utilities/browser';
99
import Tooltip from '../ui/Tooltip.svelte';
1010
import SequenceActionCombobox from './SequenceActionCombobox.svelte';
1111

src/components/timeline/TimelineInteractionModeControl.svelte

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import CursorDefaultIcon from '@nasa-jpl/stellar/icons/cursor_default.svg?component';
33
import MoveIcon from '@nasa-jpl/stellar/icons/move.svg?component';
44
import { createEventDispatcher, onMount } from 'svelte';
5-
import { addPageFocusListener } from '../../utilities/browser';
6-
import { isMacOs } from '../../utilities/generic';
5+
import { addPageFocusListener, isMacOs } from '../../utilities/browser';
76
import { isMetaOrCtrlPressed } from '../../utilities/keyboardEvents';
87
import { TimelineInteractionMode } from '../../utilities/timeline';
98
import { tooltip } from '../../utilities/tooltip';

src/components/ui/ActivityErrorsRollup.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import OutsideBoundsIcon from '../../assets/out-of-bounds.svg?component';
1616
import type { Dispatcher } from '../../types/component';
1717
import type { ActivityErrorCategories, ActivityErrorCounts } from '../../types/errors';
18-
import { isMacOs } from '../../utilities/generic';
18+
import { isMacOs } from '../../utilities/browser';
1919
import { isMetaOrCtrlPressed } from '../../utilities/keyboardEvents';
2020
import { permissionHandler } from '../../utilities/permissionHandler';
2121
import { pluralize } from '../../utilities/text';

src/utilities/browser.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { afterAll, describe, expect, test, vi } from 'vitest';
2+
3+
vi.mock('$app/environment', () => ({
4+
browser: true,
5+
}));
6+
7+
import { isMacOs } from './browser';
8+
9+
const mockNavigator = {
10+
platform: 'MacIntel',
11+
};
12+
13+
vi.stubGlobal('navigator', mockNavigator);
14+
15+
describe('Browser utility function tests', () => {
16+
afterAll(() => {
17+
vi.restoreAllMocks();
18+
});
19+
20+
describe('isMacOs', () => {
21+
test('Should return true for Mac browsers', () => {
22+
expect(isMacOs()).toEqual(true);
23+
24+
mockNavigator.platform = 'MacPPC';
25+
expect(isMacOs()).toEqual(true);
26+
27+
mockNavigator.platform = 'Mac68K';
28+
expect(isMacOs()).toEqual(true);
29+
});
30+
31+
test('Should return false for Windows browsers', () => {
32+
mockNavigator.platform = 'Win32';
33+
expect(isMacOs()).toEqual(false);
34+
35+
mockNavigator.platform = 'Windows';
36+
expect(isMacOs()).toEqual(false);
37+
});
38+
39+
test('Should return false for Linux browsers', () => {
40+
mockNavigator.platform = 'Linux i686';
41+
expect(isMacOs()).toEqual(false);
42+
43+
mockNavigator.platform = 'Linux x86_64';
44+
expect(isMacOs()).toEqual(false);
45+
});
46+
});
47+
});

src/utilities/browser.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import { browser } from '$app/environment';
22

3+
/**
4+
* Returns true if the current browser is running on MacOS
5+
*/
6+
export function isMacOs(): boolean {
7+
if (!browser) {
8+
return false;
9+
}
10+
// userAgentData is not yet in TypeScript's Navigator type (only supported in Chromium browsers)
11+
const nav = navigator as Navigator & { userAgentData?: { platform: string } };
12+
const platform = nav.userAgentData?.platform ?? navigator.platform;
13+
return /mac/i.test(platform);
14+
}
15+
316
/**
417
* Adds event listeners to document and window to track if the page is in focus.
518
* Returns a function that when called will remove the listeners.

src/utilities/generic.test.ts

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,11 @@ import {
1111
extractQuotes,
1212
filterEmpty,
1313
filterNullish,
14-
isMacOs,
1514
lowercase,
1615
parseJSONStream,
1716
unique,
1817
} from './generic';
1918

20-
const mockNavigator = {
21-
platform: 'MacIntel',
22-
};
23-
24-
vi.stubGlobal('navigator', mockNavigator);
25-
2619
describe('Generic utility function tests', () => {
2720
afterAll(() => {
2821
vi.restoreAllMocks();
@@ -129,34 +122,6 @@ describe('Generic utility function tests', () => {
129122
});
130123
});
131124

132-
describe('isMacOs', () => {
133-
test('Should return true for Mac browsers', () => {
134-
expect(isMacOs()).toEqual(true);
135-
136-
mockNavigator.platform = 'MacPPC';
137-
expect(isMacOs()).toEqual(true);
138-
139-
mockNavigator.platform = 'Mac68K';
140-
expect(isMacOs()).toEqual(true);
141-
});
142-
143-
test('Should return false for Windows browsers', () => {
144-
mockNavigator.platform = 'Win32';
145-
expect(isMacOs()).toEqual(false);
146-
147-
mockNavigator.platform = 'Windows';
148-
expect(isMacOs()).toEqual(false);
149-
});
150-
151-
test('Should return false for Linux browsers', () => {
152-
mockNavigator.platform = 'Linux i686';
153-
expect(isMacOs()).toEqual(false);
154-
155-
mockNavigator.platform = 'Linux x86_64';
156-
expect(isMacOs()).toEqual(false);
157-
});
158-
});
159-
160125
describe('unique', () => {
161126
test('Should make a list of primitives unique', () => {
162127
const base = [1, 7, 1, 3, 2, 4, 3, 4, 15, 10, 10];

src/utilities/generic.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,6 @@ export function isEmpty(value: any): boolean {
139139
return value === null || value === undefined || value === '' || Number.isNaN(value);
140140
}
141141

142-
/**
143-
* Returns true if the current browser is running on MacOS
144-
*/
145-
export function isMacOs(): boolean {
146-
if (!browser) {
147-
return false;
148-
}
149-
// userAgentData is not yet in TypeScript's Navigator type (only supported in Chromium browsers)
150-
const nav = navigator as Navigator & { userAgentData?: { platform: string } };
151-
const platform = nav.userAgentData?.platform ?? navigator.platform;
152-
return /mac/i.test(platform);
153-
}
154-
155142
/**
156143
* Returns true if the mouse event is a right click
157144
*/

src/utilities/keyboardEvents.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isMacOs } from './generic';
1+
import { isMacOs } from './browser';
22

33
export function isMetaOrCtrlPressed(event: KeyboardEvent | MouseEvent) {
44
return isMacOs() ? event.metaKey : event.ctrlKey;

0 commit comments

Comments
 (0)