Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 5b51efd

Browse files
r00stert3chguy
andauthored
Make system fonts work more reliably (#8602)
* Make system fonts work more reliably * Make it more sophisticated * Missing semicolon * Apply suggestions * Fix formatting Co-authored-by: Michael Telatynski <[email protected]> * Create FontWatcher-test.tsx * Add actual tests * Fix some errors * Apply suggestions * Apply suggestions from code review * Apply suggestions from code review * Apply suggestions from code review * Apply suggestions from code review * Fix FontWatcher tests * Correct test fixture Co-authored-by: Michael Telatynski <[email protected]>
1 parent b4d657b commit 5b51efd

File tree

4 files changed

+86
-16
lines changed

4 files changed

+86
-16
lines changed

src/settings/watchers/FontWatcher.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ export class FontWatcher implements IWatcher {
6464
};
6565

6666
private setSystemFont = ({ useSystemFont, font }) => {
67-
document.body.style.fontFamily = useSystemFont ? font : "";
67+
if (useSystemFont) {
68+
// Make sure that fonts with spaces in their names get interpreted properly
69+
document.body.style.fontFamily = font
70+
.split(',')
71+
.map(font => {
72+
font = font.trim();
73+
if (!font.startsWith('"') && !font.endsWith('"')) {
74+
font = `"${font}"`;
75+
}
76+
return font;
77+
})
78+
.join(',');
79+
} else {
80+
document.body.style.fontFamily = "";
81+
}
6882
};
6983
}

test/CallHandler-test.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ import EventEmitter from 'events';
2121
import CallHandler, {
2222
CallHandlerEvent, PROTOCOL_PSTN, PROTOCOL_PSTN_PREFIXED, PROTOCOL_SIP_NATIVE, PROTOCOL_SIP_VIRTUAL,
2323
} from '../src/CallHandler';
24-
import { stubClient, mkStubRoom } from './test-utils';
24+
import { stubClient, mkStubRoom, untilDispatch } from './test-utils';
2525
import { MatrixClientPeg } from '../src/MatrixClientPeg';
26-
import dis from '../src/dispatcher/dispatcher';
2726
import DMRoomMap from '../src/utils/DMRoomMap';
2827
import SdkConfig from '../src/SdkConfig';
29-
import { ActionPayload } from '../src/dispatcher/payloads';
3028
import { Action } from "../src/dispatcher/actions";
3129

3230
// The Matrix IDs that the user sees when talking to Alice & Bob
@@ -95,18 +93,6 @@ class FakeCall extends EventEmitter {
9593
}
9694
}
9795

98-
function untilDispatch(waitForAction: string): Promise<ActionPayload> {
99-
let dispatchHandle;
100-
return new Promise<ActionPayload>(resolve => {
101-
dispatchHandle = dis.register(payload => {
102-
if (payload.action === waitForAction) {
103-
dis.unregister(dispatchHandle);
104-
resolve(payload);
105-
}
106-
});
107-
});
108-
}
109-
11096
function untilCallHandlerEvent(callHandler: CallHandler, event: CallHandlerEvent): Promise<void> {
11197
return new Promise<void>((resolve) => {
11298
callHandler.addListener(event, () => {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
Copyright 2022 r00ster91 <[email protected]>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import { sleep } from 'matrix-js-sdk/src/utils';
18+
19+
import SettingsStore from '../../../src/settings/SettingsStore';
20+
import { SettingLevel } from '../../../src/settings/SettingLevel';
21+
import { FontWatcher } from "../../../src/settings/watchers/FontWatcher";
22+
import { Action } from "../../../src/dispatcher/actions";
23+
import { untilDispatch } from "../../test-utils";
24+
25+
async function setSystemFont(font: string): Promise<void> {
26+
await SettingsStore.setValue("systemFont", null, SettingLevel.DEVICE, font);
27+
await untilDispatch(Action.UpdateSystemFont);
28+
await sleep(1); // await the FontWatcher doing its action
29+
}
30+
31+
describe('FontWatcher', function() {
32+
let fontWatcher: FontWatcher;
33+
beforeEach(() => {
34+
fontWatcher = new FontWatcher();
35+
fontWatcher.start();
36+
return SettingsStore.setValue("useSystemFont", null, SettingLevel.DEVICE, true);
37+
});
38+
afterEach(() => {
39+
fontWatcher.stop();
40+
});
41+
42+
it('encloses the fonts by double quotes and sets them as the system font', async () => {
43+
await setSystemFont("Fira Sans Thin, Commodore 64");
44+
expect(document.body.style.fontFamily).toBe(`"Fira Sans Thin","Commodore 64"`);
45+
});
46+
it('does not add double quotes if already present and sets the font as the system font', async () => {
47+
await setSystemFont(`"Commodore 64"`);
48+
expect(document.body.style.fontFamily).toBe(`"Commodore 64"`);
49+
});
50+
it('trims whitespace, encloses the fonts by double quotes, and sets them as the system font', async () => {
51+
await setSystemFont(` Fira Code , "Commodore 64" `);
52+
expect(document.body.style.fontFamily).toBe(`"Fira Code","Commodore 64"`);
53+
});
54+
});

test/test-utils/utilities.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,24 @@ limitations under the License.
1717
import { ReactWrapper } from "enzyme";
1818
import EventEmitter from "events";
1919

20+
import { ActionPayload } from "../../src/dispatcher/payloads";
21+
import defaultDispatcher from "../../src/dispatcher/dispatcher";
22+
import { DispatcherAction } from "../../src/dispatcher/actions";
23+
2024
export const emitPromise = (e: EventEmitter, k: string | symbol) => new Promise(r => e.once(k, r));
2125

26+
export function untilDispatch(waitForAction: DispatcherAction): Promise<ActionPayload> {
27+
let dispatchHandle: string;
28+
return new Promise<ActionPayload>(resolve => {
29+
dispatchHandle = defaultDispatcher.register(payload => {
30+
if (payload.action === waitForAction) {
31+
defaultDispatcher.unregister(dispatchHandle);
32+
resolve(payload);
33+
}
34+
});
35+
});
36+
}
37+
2238
const findByAttr = (attr: string) => (component: ReactWrapper, value: string) => component.find(`[${attr}="${value}"]`);
2339
export const findByTestId = findByAttr('data-test-id');
2440
export const findById = findByAttr('id');

0 commit comments

Comments
 (0)