Use trailingComma: all setting in .prettierrc (#1435)

This commit is contained in:
Henrik Giesel 2021-10-19 01:06:00 +02:00 committed by GitHub
parent bf3adbc812
commit 0dff5ea3a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 252 additions and 251 deletions

View File

@ -1,6 +1,6 @@
{ {
"trailingComma": "es5", "trailingComma": "all",
"printWidth": 88, "printWidth": 88,
"tabWidth": 4, "tabWidth": 4,
"semi": true "semi": true,
} }

View File

@ -6,6 +6,6 @@ import { postRequest } from "../lib/postrequest";
export async function getCardStats(cardId: number): Promise<Stats.CardStatsResponse> { export async function getCardStats(cardId: number): Promise<Stats.CardStatsResponse> {
return Stats.CardStatsResponse.decode( return Stats.CardStatsResponse.decode(
await postRequest("/_anki/cardStats", JSON.stringify({ cardId })) await postRequest("/_anki/cardStats", JSON.stringify({ cardId })),
); );
} }

View File

@ -20,7 +20,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
async function blur(event: Event): Promise<void> { async function blur(event: Event): Promise<void> {
await state.setTargetNotetypeIndex( await state.setTargetNotetypeIndex(
parseInt((event.target! as HTMLSelectElement).value) parseInt((event.target! as HTMLSelectElement).value),
); );
} }
</script> </script>

View File

@ -14,7 +14,7 @@ import { nightModeKey } from "../components/context-keys";
export async function changeNotetypePage( export async function changeNotetypePage(
target: HTMLDivElement, target: HTMLDivElement,
oldNotetypeId: number, oldNotetypeId: number,
newNotetypeId: number newNotetypeId: number,
): Promise<ChangeNotetypePage> { ): Promise<ChangeNotetypePage> {
const [info, names] = await Promise.all([ const [info, names] = await Promise.all([
getChangeNotetypeInfo(oldNotetypeId, newNotetypeId), getChangeNotetypeInfo(oldNotetypeId, newNotetypeId),

View File

@ -65,14 +65,14 @@ const exampleInfoSame = {
function differentState(): ChangeNotetypeState { function differentState(): ChangeNotetypeState {
return new ChangeNotetypeState( return new ChangeNotetypeState(
Notetypes.NotetypeNames.fromObject(exampleNames), Notetypes.NotetypeNames.fromObject(exampleNames),
Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoDifferent) Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoDifferent),
); );
} }
function sameState(): ChangeNotetypeState { function sameState(): ChangeNotetypeState {
return new ChangeNotetypeState( return new ChangeNotetypeState(
Notetypes.NotetypeNames.fromObject(exampleNames), Notetypes.NotetypeNames.fromObject(exampleNames),
Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoSame) Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoSame),
); );
} }
@ -92,7 +92,7 @@ test("mapping", () => {
expect(get(state.info).getNewName(MapContext.Field, 1)).toBe("Back"); expect(get(state.info).getNewName(MapContext.Field, 1)).toBe("Back");
expect(get(state.info).getNewName(MapContext.Field, 2)).toBe("Add Reverse"); expect(get(state.info).getNewName(MapContext.Field, 2)).toBe("Add Reverse");
expect(get(state.info).getOldNamesIncludingNothing(MapContext.Field)).toStrictEqual( expect(get(state.info).getOldNamesIncludingNothing(MapContext.Field)).toStrictEqual(
["Front", "Back", "(Nothing)"] ["Front", "Back", "(Nothing)"],
); );
expect(get(state.info).getOldIndex(MapContext.Field, 0)).toBe(0); expect(get(state.info).getOldIndex(MapContext.Field, 0)).toBe(0);
expect(get(state.info).getOldIndex(MapContext.Field, 1)).toBe(1); expect(get(state.info).getOldIndex(MapContext.Field, 1)).toBe(1);
@ -102,7 +102,7 @@ test("mapping", () => {
// the same template shouldn't be mappable twice // the same template shouldn't be mappable twice
expect( expect(
get(state.info).getOldNamesIncludingNothing(MapContext.Template) get(state.info).getOldNamesIncludingNothing(MapContext.Template),
).toStrictEqual(["Card 1", "(Nothing)"]); ).toStrictEqual(["Card 1", "(Nothing)"]);
expect(get(state.info).getOldIndex(MapContext.Template, 0)).toBe(0); expect(get(state.info).getOldIndex(MapContext.Template, 0)).toBe(0);
expect(get(state.info).getOldIndex(MapContext.Template, 1)).toBe(1); expect(get(state.info).getOldIndex(MapContext.Template, 1)).toBe(1);

View File

@ -12,24 +12,24 @@ import { isEqual } from "lodash-es";
export async function getNotetypeNames(): Promise<Notetypes.NotetypeNames> { export async function getNotetypeNames(): Promise<Notetypes.NotetypeNames> {
return Notetypes.NotetypeNames.decode( return Notetypes.NotetypeNames.decode(
await postRequest("/_anki/notetypeNames", "") await postRequest("/_anki/notetypeNames", ""),
); );
} }
export async function getChangeNotetypeInfo( export async function getChangeNotetypeInfo(
oldNotetypeId: number, oldNotetypeId: number,
newNotetypeId: number newNotetypeId: number,
): Promise<Notetypes.ChangeNotetypeInfo> { ): Promise<Notetypes.ChangeNotetypeInfo> {
return Notetypes.ChangeNotetypeInfo.decode( return Notetypes.ChangeNotetypeInfo.decode(
await postRequest( await postRequest(
"/_anki/changeNotetypeInfo", "/_anki/changeNotetypeInfo",
JSON.stringify({ oldNotetypeId, newNotetypeId }) JSON.stringify({ oldNotetypeId, newNotetypeId }),
) ),
); );
} }
export async function changeNotetype( export async function changeNotetype(
input: Notetypes.ChangeNotetypeRequest input: Notetypes.ChangeNotetypeRequest,
): Promise<void> { ): Promise<void> {
const data: Uint8Array = Notetypes.ChangeNotetypeRequest.encode(input).finish(); const data: Uint8Array = Notetypes.ChangeNotetypeRequest.encode(input).finish();
await postRequest("/_anki/changeNotetype", data); await postRequest("/_anki/changeNotetype", data);
@ -98,7 +98,7 @@ export class ChangeNotetypeInfoWrapper {
const usedEntries = new Set(this.mapForContext(ctx).filter((v) => v !== null)); const usedEntries = new Set(this.mapForContext(ctx).filter((v) => v !== null));
const oldNames = this.getOldNames(ctx); const oldNames = this.getOldNames(ctx);
const unusedIdxs = [...Array(oldNames.length).keys()].filter( const unusedIdxs = [...Array(oldNames.length).keys()].filter(
(idx) => !usedEntries.has(idx) (idx) => !usedEntries.has(idx),
); );
const unusedNames = unusedIdxs.map((idx) => oldNames[idx]); const unusedNames = unusedIdxs.map((idx) => oldNames[idx]);
unusedNames.sort(); unusedNames.sort();
@ -150,7 +150,7 @@ export class ChangeNotetypeState {
constructor( constructor(
notetypes: Notetypes.NotetypeNames, notetypes: Notetypes.NotetypeNames,
info: Notetypes.ChangeNotetypeInfo info: Notetypes.ChangeNotetypeInfo,
) { ) {
this.info_ = new ChangeNotetypeInfoWrapper(info); this.info_ = new ChangeNotetypeInfoWrapper(info);
this.info = readable(this.info_, (set) => { this.info = readable(this.info_, (set) => {
@ -168,7 +168,7 @@ export class ChangeNotetypeState {
this.notetypesSetter(this.buildNotetypeList()); this.notetypesSetter(this.buildNotetypeList());
const newInfo = await getChangeNotetypeInfo( const newInfo = await getChangeNotetypeInfo(
this.info_.input().oldNotetypeId, this.info_.input().oldNotetypeId,
this.info_.input().newNotetypeId this.info_.input().newNotetypeId,
); );
this.info_ = new ChangeNotetypeInfoWrapper(newInfo); this.info_ = new ChangeNotetypeInfoWrapper(newInfo);
@ -215,7 +215,7 @@ export class ChangeNotetypeState {
idx, idx,
name: entry.name, name: entry.name,
current: entry.id === currentId, current: entry.id === currentId,
} as NotetypeListEntry) } as NotetypeListEntry),
); );
} }
} }

View File

@ -66,11 +66,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const insertButton = (button: SvelteComponent, position: Identifier = 0) => const insertButton = (button: SvelteComponent, position: Identifier = 0) =>
addComponent(button, (added, parent) => addComponent(button, (added, parent) =>
insertElement(added, parent, position) insertElement(added, parent, position),
); );
const appendButton = (button: SvelteComponent, position: Identifier = -1) => const appendButton = (button: SvelteComponent, position: Identifier = -1) =>
addComponent(button, (added, parent) => addComponent(button, (added, parent) =>
appendElement(added, parent, position) appendElement(added, parent, position),
); );
const showButton = (id: Identifier) => const showButton = (id: Identifier) =>
@ -80,7 +80,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const toggleButton = (id: Identifier) => const toggleButton = (id: Identifier) =>
updateRegistration( updateRegistration(
({ detach }) => detach.update((old: boolean): boolean => !old), ({ detach }) => detach.update((old: boolean): boolean => !old),
id id,
); );
Object.assign(api, { Object.assign(api, {

View File

@ -48,11 +48,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const insertGroup = (group: SvelteComponent, position: Identifier = 0) => const insertGroup = (group: SvelteComponent, position: Identifier = 0) =>
addComponent(group, (added, parent) => addComponent(group, (added, parent) =>
insertElement(added, parent, position) insertElement(added, parent, position),
); );
const appendGroup = (group: SvelteComponent, position: Identifier = -1) => const appendGroup = (group: SvelteComponent, position: Identifier = -1) =>
addComponent(group, (added, parent) => addComponent(group, (added, parent) =>
appendElement(added, parent, position) appendElement(added, parent, position),
); );
const showGroup = (id: Identifier) => const showGroup = (id: Identifier) =>
@ -62,7 +62,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const toggleGroup = (id: Identifier) => const toggleGroup = (id: Identifier) =>
updateRegistration( updateRegistration(
({ detach }) => detach.update((old: boolean): boolean => !old), ({ detach }) => detach.update((old: boolean): boolean => !old),
id id,
); );
Object.assign(api, { Object.assign(api, {

View File

@ -32,11 +32,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const insert = (group: SvelteComponent, position: Identifier = 0) => const insert = (group: SvelteComponent, position: Identifier = 0) =>
addComponent(group, (added, parent) => addComponent(group, (added, parent) =>
insertElement(added, parent, position) insertElement(added, parent, position),
); );
const append = (group: SvelteComponent, position: Identifier = -1) => const append = (group: SvelteComponent, position: Identifier = -1) =>
addComponent(group, (added, parent) => addComponent(group, (added, parent) =>
appendElement(added, parent, position) appendElement(added, parent, position),
); );
const show = (id: Identifier) => const show = (id: Identifier) =>
@ -46,7 +46,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const toggle = (id: Identifier) => const toggle = (id: Identifier) =>
updateRegistration( updateRegistration(
({ detach }) => detach.update((old: boolean): boolean => !old), ({ detach }) => detach.update((old: boolean): boolean => !old),
id id,
); );
Object.assign(api, { insert, append, show, hide, toggle }); Object.assign(api, { insert, append, show, hide, toggle });

View File

@ -15,7 +15,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
registerShortcut( registerShortcut(
(event: KeyboardEvent) => dispatch("action", { originalEvent: event }), (event: KeyboardEvent) => dispatch("action", { originalEvent: event }),
keyCombination, keyCombination,
target as any target as any,
) ),
); );
</script> </script>

View File

@ -27,7 +27,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export function updateAllState(event: Event): void { export function updateAllState(event: Event): void {
updateAllStateWithCallback((key: KeyType): boolean => updateAllStateWithCallback((key: KeyType): boolean =>
updaterMap.get(key)!(event) updaterMap.get(key)!(event),
); );
} }

View File

@ -2,7 +2,7 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export function mergeTooltipAndShortcut( export function mergeTooltipAndShortcut(
tooltip: string | undefined, tooltip: string | undefined,
shortcutLabel: string | undefined shortcutLabel: string | undefined,
): string | undefined { ): string | undefined {
if (!tooltip && !shortcutLabel) { if (!tooltip && !shortcutLabel) {
return undefined; return undefined;

View File

@ -4,7 +4,7 @@ export type Identifier = string | number;
export function findElement( export function findElement(
collection: HTMLCollection, collection: HTMLCollection,
idOrIndex: Identifier idOrIndex: Identifier,
): [number, Element] | null { ): [number, Element] | null {
let result: [number, Element] | null = null; let result: [number, Element] | null = null;
@ -37,7 +37,7 @@ export function findElement(
export function insertElement( export function insertElement(
element: Element, element: Element,
collection: Element, collection: Element,
idOrIndex: Identifier idOrIndex: Identifier,
): number { ): number {
const match = findElement(collection.children, idOrIndex); const match = findElement(collection.children, idOrIndex);
@ -54,7 +54,7 @@ export function insertElement(
export function appendElement( export function appendElement(
element: Element, element: Element,
collection: Element, collection: Element,
idOrIndex: Identifier idOrIndex: Identifier,
): number { ): number {
const match = findElement(collection.children, idOrIndex); const match = findElement(collection.children, idOrIndex);
@ -72,7 +72,7 @@ export function appendElement(
export function updateElement( export function updateElement(
f: (element: Element) => void, f: (element: Element) => void,
collection: Element, collection: Element,
idOrIndex: Identifier idOrIndex: Identifier,
): number { ): number {
const match = findElement(collection.children, idOrIndex); const match = findElement(collection.children, idOrIndex);

View File

@ -28,11 +28,11 @@ export interface RegistrationAPI<T extends Registration> {
export interface DynamicRegistrationAPI<T> { export interface DynamicRegistrationAPI<T> {
addComponent: ( addComponent: (
component: SvelteComponent, component: SvelteComponent,
add: (added: Element, parent: Element) => number add: (added: Element, parent: Element) => number,
) => void; ) => void;
updateRegistration: ( updateRegistration: (
update: (registration: T) => void, update: (registration: T) => void,
position: Identifier position: Identifier,
) => void; ) => void;
} }
@ -41,14 +41,14 @@ export function nodeIsElement(node: Node): node is Element {
} }
export function makeInterface<T extends Registration>( export function makeInterface<T extends Registration>(
makeRegistration: () => T makeRegistration: () => T,
): RegistrationAPI<T> { ): RegistrationAPI<T> {
const registrations: T[] = []; const registrations: T[] = [];
const items = writable(registrations); const items = writable(registrations);
function registerComponent( function registerComponent(
index: number = registrations.length, index: number = registrations.length,
registration = makeRegistration() registration = makeRegistration(),
): T { ): T {
items.update((registrations) => { items.update((registrations) => {
registrations.splice(index, 0, registration); registrations.splice(index, 0, registration);
@ -64,13 +64,13 @@ export function makeInterface<T extends Registration>(
function getDynamicInterface(elementRef: HTMLElement): DynamicRegistrationAPI<T> { function getDynamicInterface(elementRef: HTMLElement): DynamicRegistrationAPI<T> {
function addComponent( function addComponent(
component: SvelteComponent, component: SvelteComponent,
add: (added: Element, parent: Element) => number add: (added: Element, parent: Element) => number,
): void { ): void {
const registration = makeRegistration(); const registration = makeRegistration();
const callback = ( const callback = (
mutations: MutationRecord[], mutations: MutationRecord[],
observer: MutationObserver observer: MutationObserver,
): void => { ): void => {
for (const mutation of mutations) { for (const mutation of mutations) {
for (const addedNode of mutation.addedNodes) { for (const addedNode of mutation.addedNodes) {
@ -99,7 +99,7 @@ export function makeInterface<T extends Registration>(
function updateRegistration( function updateRegistration(
update: (registration: T) => void, update: (registration: T) => void,
position: Identifier position: Identifier,
): void { ): void {
const match = findElement(elementRef.children, position); const match = findElement(elementRef.children, position);

View File

@ -8,7 +8,7 @@ import * as tr from "../lib/ftl";
export async function getCongratsInfo(): Promise<Scheduler.CongratsInfoResponse> { export async function getCongratsInfo(): Promise<Scheduler.CongratsInfoResponse> {
return Scheduler.CongratsInfoResponse.decode( return Scheduler.CongratsInfoResponse.decode(
await postRequest("/_anki/congratsInfo", "") await postRequest("/_anki/congratsInfo", ""),
); );
} }

View File

@ -15,7 +15,7 @@ import { nightModeKey, touchDeviceKey, modalsKey } from "../components/context-k
export async function deckOptions( export async function deckOptions(
target: HTMLDivElement, target: HTMLDivElement,
deckId: number deckId: number,
): Promise<DeckOptionsPage> { ): Promise<DeckOptionsPage> {
const [info] = await Promise.all([ const [info] = await Promise.all([
getDeckOptionsInfo(deckId), getDeckOptionsInfo(deckId),

View File

@ -94,7 +94,7 @@ const exampleData = {
function startingState(): DeckOptionsState { function startingState(): DeckOptionsState {
return new DeckOptionsState( return new DeckOptionsState(
123, 123,
DeckConfig.DeckConfigsForUpdate.fromObject(exampleData) DeckConfig.DeckConfigsForUpdate.fromObject(exampleData),
); );
} }
@ -308,7 +308,7 @@ test("aux data", () => {
JSON.parse(new TextDecoder().decode((c.config as any).other)) as Record< JSON.parse(new TextDecoder().decode((c.config as any).other)) as Record<
string, string,
unknown unknown
> >,
); );
expect(json).toStrictEqual([ expect(json).toStrictEqual([
// other deck comes first // other deck comes first

View File

@ -13,15 +13,15 @@ import { localeCompare } from "../lib/i18n";
import type { DynamicSvelteComponent } from "../sveltelib/dynamicComponent"; import type { DynamicSvelteComponent } from "../sveltelib/dynamicComponent";
export async function getDeckOptionsInfo( export async function getDeckOptionsInfo(
deckId: number deckId: number,
): Promise<DeckConfig.DeckConfigsForUpdate> { ): Promise<DeckConfig.DeckConfigsForUpdate> {
return DeckConfig.DeckConfigsForUpdate.decode( return DeckConfig.DeckConfigsForUpdate.decode(
await postRequest("/_anki/deckConfigsForUpdate", JSON.stringify({ deckId })) await postRequest("/_anki/deckConfigsForUpdate", JSON.stringify({ deckId })),
); );
} }
export async function saveDeckOptions( export async function saveDeckOptions(
input: DeckConfig.UpdateDeckConfigsRequest input: DeckConfig.UpdateDeckConfigsRequest,
): Promise<void> { ): Promise<void> {
const data: Uint8Array = DeckConfig.UpdateDeckConfigsRequest.encode(input).finish(); const data: Uint8Array = DeckConfig.UpdateDeckConfigsRequest.encode(input).finish();
await postRequest("/_anki/updateDeckConfigs", data); await postRequest("/_anki/updateDeckConfigs", data);
@ -84,7 +84,7 @@ export class DeckOptionsState {
}); });
this.selectedIdx = Math.max( this.selectedIdx = Math.max(
0, 0,
this.configs.findIndex((c) => c.config.id === this.currentDeck.configId) this.configs.findIndex((c) => c.config.id === this.currentDeck.configId),
); );
this.v3Scheduler = data.v3Scheduler; this.v3Scheduler = data.v3Scheduler;
this.haveAddons = data.haveAddons; this.haveAddons = data.haveAddons;
@ -284,17 +284,17 @@ export class DeckOptionsState {
private getParentLimits(): ParentLimits { private getParentLimits(): ParentLimits {
const parentConfigs = this.configs.filter((c) => const parentConfigs = this.configs.filter((c) =>
this.currentDeck.parentConfigIds.includes(c.config.id) this.currentDeck.parentConfigIds.includes(c.config.id),
); );
const newCards = parentConfigs.reduce( const newCards = parentConfigs.reduce(
(previous, current) => (previous, current) =>
Math.min(previous, current.config.config?.newPerDay ?? 0), Math.min(previous, current.config.config?.newPerDay ?? 0),
2 ** 31 2 ** 31,
); );
const reviews = parentConfigs.reduce( const reviews = parentConfigs.reduce(
(previous, current) => (previous, current) =>
Math.min(previous, current.config.config?.reviewsPerDay ?? 0), Math.min(previous, current.config.config?.reviewsPerDay ?? 0),
2 ** 31 2 ** 31,
); );
return { return {
newCards, newCards,

View File

@ -10,7 +10,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let resolve: (editable: HTMLElement) => void; export let resolve: (editable: HTMLElement) => void;
export let mirror: ( export let mirror: (
editable: HTMLElement, editable: HTMLElement,
params: { store: Writable<DocumentFragment> } params: { store: Writable<DocumentFragment> },
) => void; ) => void;
</script> </script>

View File

@ -39,7 +39,7 @@ export interface DecoratedElementConstructor
} }
export class CustomElementArray< export class CustomElementArray<
T extends CustomElementConstructor & WithTagName T extends CustomElementConstructor & WithTagName,
> extends Array<T> { > extends Array<T> {
push(...elements: T[]): number { push(...elements: T[]): number {
for (const element of elements) { for (const element of elements) {

View File

@ -17,7 +17,7 @@ import Mathjax_svelte from "./Mathjax.svelte";
function moveNodeOutOfElement( function moveNodeOutOfElement(
element: Element, element: Element,
node: Node, node: Node,
placement: "beforebegin" | "afterend" placement: "beforebegin" | "afterend",
): Node { ): Node {
element.removeChild(node); element.removeChild(node);
@ -105,7 +105,7 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax
return typeof block === "string" && block !== "false" return typeof block === "string" && block !== "false"
? `\\[${text}\\]` ? `\\[${text}\\]`
: `\\(${text}\\)`; : `\\(${text}\\)`;
} },
); );
} }
@ -114,11 +114,12 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax
.replace( .replace(
mathjaxBlockDelimiterPattern, mathjaxBlockDelimiterPattern,
(_match: string, text: string) => (_match: string, text: string) =>
`<anki-mathjax block="true">${text}</anki-mathjax>` `<anki-mathjax block="true">${text}</anki-mathjax>`,
) )
.replace( .replace(
mathjaxInlineDelimiterPattern, mathjaxInlineDelimiterPattern,
(_match: string, text: string) => `<anki-mathjax>${text}</anki-mathjax>` (_match: string, text: string) =>
`<anki-mathjax>${text}</anki-mathjax>`,
); );
} }
@ -161,7 +162,7 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax
const context = new Map(); const context = new Map();
context.set( context.set(
nightModeKey, nightModeKey,
document.documentElement.classList.contains("night-mode") document.documentElement.classList.contains("night-mode"),
); );
this.component = new Mathjax_svelte({ this.component = new Mathjax_svelte({

View File

@ -32,7 +32,7 @@ function getEmptyIcon(style: HTMLStyleElement): [string, string] {
export function convertMathjax( export function convertMathjax(
input: string, input: string,
nightMode: boolean, nightMode: boolean,
fontSize: number fontSize: number,
): [string, string] { ): [string, string] {
const style = getStyle(getCSS(nightMode, fontSize)); const style = getStyle(getCSS(nightMode, fontSize));

View File

@ -50,7 +50,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{}, {},
{ {
editor: { get: () => codeMirror }, editor: { get: () => codeMirror },
} },
) as CodeMirrorAPI; ) as CodeMirrorAPI;
</script> </script>

View File

@ -43,7 +43,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<IconButton <IconButton
tooltip={appendInParentheses( tooltip={appendInParentheses(
tr.editingSetTextColor(), tr.editingSetTextColor(),
shortcutLabel shortcutLabel,
)} )}
{disabled} {disabled}
on:click={forecolorWrap} on:click={forecolorWrap}
@ -60,7 +60,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<IconButton <IconButton
tooltip={appendInParentheses( tooltip={appendInParentheses(
tr.editingChangeColor(), tr.editingChangeColor(),
shortcutLabel shortcutLabel,
)} )}
{disabled} {disabled}
widthMultiplier={0.5} widthMultiplier={0.5}

View File

@ -58,8 +58,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
direction: { direction: {
get: () => $directionStore, get: () => $directionStore,
}, },
} },
) as EditorFieldAPI ) as EditorFieldAPI,
); );
</script> </script>

View File

@ -168,7 +168,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function updateField(index: number, content: string): void { function updateField(index: number, content: string): void {
fieldSave.schedule( fieldSave.schedule(
() => bridgeCommand(`key:${index}:${getNoteId()}:${content}`), () => bridgeCommand(`key:${index}:${getNoteId()}:${content}`),
600 600,
); );
} }
@ -230,8 +230,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}, },
{ {
fields: { get: () => fieldApis }, fields: { get: () => fieldApis },
} },
) ),
); );
onMount(() => { onMount(() => {
@ -271,7 +271,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:focusout={() => { on:focusout={() => {
$currentField = null; $currentField = null;
bridgeCommand( bridgeCommand(
`blur:${index}:${getNoteId()}:${get(fieldStores[index])}` `blur:${index}:${getNoteId()}:${get(fieldStores[index])}`,
); );
}} }}
--label-color={cols[index] === "dupe" --label-color={cols[index] === "dupe"

View File

@ -23,7 +23,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
onMount(() => onMount(() =>
registerShortcut(toggle, keyCombination, editorField.element as HTMLElement) registerShortcut(toggle, keyCombination, editorField.element as HTMLElement),
); );
</script> </script>

View File

@ -62,7 +62,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
for (const decorated of decoratedElements) { for (const decorated of decoratedElements) {
for (const element of fragment.querySelectorAll( for (const element of fragment.querySelectorAll(
decorated.tagName decorated.tagName,
) as NodeListOf<DecoratedElement>) { ) as NodeListOf<DecoratedElement>) {
element.undecorate(); element.undecorate();
} }
@ -195,7 +195,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}, },
surround(before: string, after: string) { surround(before: string, after: string) {
richTextPromise.then((richText) => richTextPromise.then((richText) =>
wrapInternal(richText.getRootNode() as any, before, after, false) wrapInternal(richText.getRootNode() as any, before, after, false),
); );
}, },
preventResubscription, preventResubscription,

View File

@ -30,7 +30,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let tagTypes: TagType[]; let tagTypes: TagType[];
function tagsToTagTypes(tags: string[]): void { function tagsToTagTypes(tags: string[]): void {
tagTypes = tags.map( tagTypes = tags.map(
(tag: string): TagType => attachId(replaceWithUnicodeSeparator(tag)) (tag: string): TagType => attachId(replaceWithUnicodeSeparator(tag)),
); );
} }
@ -59,8 +59,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const data = await postRequest( const data = await postRequest(
"/_anki/completeTag", "/_anki/completeTag",
Tags.CompleteTagRequest.encode( Tags.CompleteTagRequest.encode(
Tags.CompleteTagRequest.create({ input, matchLimit: 500 }) Tags.CompleteTagRequest.create({ input, matchLimit: 500 }),
).finish() ).finish(),
); );
const response = Tags.CompleteTagResponse.decode(data); const response = Tags.CompleteTagResponse.decode(data);
return response.tags; return response.tags;
@ -86,7 +86,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
(names: string[]): string[] => { (names: string[]): string[] => {
autocompleteDisabled = names.length === 0; autocompleteDisabled = names.length === 0;
return names.map(replaceWithUnicodeSeparator); return names.map(replaceWithUnicodeSeparator);
} },
); );
} }
} }
@ -152,7 +152,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
async function enterBehavior( async function enterBehavior(
index: number, index: number,
start: number, start: number,
end: number end: number,
): Promise<void> { ): Promise<void> {
if (autocomplete.hasSelected()) { if (autocomplete.hasSelected()) {
autocomplete.chooseSelected(); autocomplete.chooseSelected();
@ -334,7 +334,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function deselect() { function deselect() {
tagTypes = tagTypes.map( tagTypes = tagTypes.map(
(tag: TagType): TagType => ({ ...tag, selected: false }) (tag: TagType): TagType => ({ ...tag, selected: false }),
); );
selectionAnchor = null; selectionAnchor = null;
selectionFocus = null; selectionFocus = null;

View File

@ -127,7 +127,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
event.preventDefault(); event.preventDefault();
name = `${before.slice(0, -1)}${delimChar}${name.slice( name = `${before.slice(0, -1)}${delimChar}${name.slice(
positionEnd, positionEnd,
name.length name.length,
)}`; )}`;
await tick(); await tick();
@ -199,7 +199,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const selection = document.getSelection(); const selection = document.getSelection();
event.clipboardData!.setData( event.clipboardData!.setData(
"text/plain", "text/plain",
replaceWithColons(selection!.toString()) replaceWithColons(selection!.toString()),
); );
} }

View File

@ -39,7 +39,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<IconButton <IconButton
tooltip={appendInParentheses( tooltip={appendInParentheses(
tr.editingAttachPicturesaudiovideo(), tr.editingAttachPicturesaudiovideo(),
shortcutLabel shortcutLabel,
)} )}
iconSize={70} iconSize={70}
{disabled} {disabled}
@ -85,7 +85,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:click={() => on:click={() =>
$activeInput?.surround( $activeInput?.surround(
"<anki-mathjax focusonmount>", "<anki-mathjax focusonmount>",
"</anki-mathjax>" "</anki-mathjax>",
)} )}
on:mount={withButton(createShortcut)} on:mount={withButton(createShortcut)}
> >
@ -103,7 +103,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:click={() => on:click={() =>
$activeInput?.surround( $activeInput?.surround(
'<anki-mathjax block="true" focusonmount>', '<anki-mathjax block="true" focusonmount>',
"</anki-matjax>" "</anki-matjax>",
)} )}
on:mount={withButton(createShortcut)} on:mount={withButton(createShortcut)}
> >
@ -121,7 +121,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:click={() => on:click={() =>
$activeInput?.surround( $activeInput?.surround(
"<anki-mathjax focusonmount>\\ce{", "<anki-mathjax focusonmount>\\ce{",
"}</anki-mathjax>" "}</anki-mathjax>",
)} )}
on:mount={withButton(createShortcut)} on:mount={withButton(createShortcut)}
> >

View File

@ -9,7 +9,7 @@ export function appendInParentheses(text: string, appendix: string): string {
export function execCommand( export function execCommand(
command: string, command: string,
showUI?: boolean | undefined, showUI?: boolean | undefined,
value?: string | undefined value?: string | undefined,
): void { ): void {
document.execCommand(command, showUI, value); document.execCommand(command, showUI, value);
} }

View File

@ -37,7 +37,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const nth = const nth =
Array.prototype.indexOf.call( Array.prototype.indexOf.call(
(element.parentNode! as Document | ShadowRoot).children, (element.parentNode! as Document | ShadowRoot).children,
element element,
) + 1; ) + 1;
return [`${tagName}:nth-child(${nth})`, ...tokens]; return [`${tagName}:nth-child(${nth})`, ...tokens];
} else { } else {
@ -46,7 +46,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
1; 1;
return createPathRecursive( return createPathRecursive(
[`${tagName}:nth-child(${nth})`, ...tokens], [`${tagName}:nth-child(${nth})`, ...tokens],
element.parentElement element.parentElement,
); );
} }
} }
@ -92,7 +92,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
rule.style.setProperty( rule.style.setProperty(
"height", "height",
height < maxHeight ? `${height}px` : "auto", height < maxHeight ? `${height}px` : "auto",
"important" "important",
); );
} else { } else {
// square or restricted by width // square or restricted by width
@ -100,7 +100,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
rule.style.setProperty( rule.style.setProperty(
"width", "width",
width < maxWidth ? `${width}px` : "auto", width < maxWidth ? `${width}px` : "auto",
"important" "important",
); );
rule.style.setProperty("height", "auto", "important"); rule.style.setProperty("height", "auto", "important");
@ -125,7 +125,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
images.push(image); images.push(image);
const index = sheet.insertRule( const index = sheet.insertRule(
`${createPath(image)} {}`, `${createPath(image)} {}`,
sheet.cssRules.length sheet.cssRules.length,
); );
const rule = sheet.cssRules[index] as CSSStyleRule; const rule = sheet.cssRules[index] as CSSStyleRule;
setImageRule(image, rule); setImageRule(image, rule);
@ -151,7 +151,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const mutationObserver = new MutationObserver((mutations) => { const mutationObserver = new MutationObserver((mutations) => {
const addedImages = mutations.flatMap((mutation) => const addedImages = mutations.flatMap((mutation) =>
filterImages([...mutation.addedNodes]) filterImages([...mutation.addedNodes]),
); );
for (const image of addedImages) { for (const image of addedImages) {
@ -159,7 +159,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
const removedImages = mutations.flatMap((mutation) => const removedImages = mutations.flatMap((mutation) =>
filterImages([...mutation.removedNodes]) filterImages([...mutation.removedNodes]),
); );
for (const image of removedImages) { for (const image of removedImages) {

View File

@ -15,7 +15,7 @@ export const $editorToolbar = new Promise(noop);
export function pasteHTML( export function pasteHTML(
html: string, html: string,
internal: boolean, internal: boolean,
extendedMode: boolean extendedMode: boolean,
): void { ): void {
html = filterHTML(html, internal, extendedMode); html = filterHTML(html, internal, extendedMode);
@ -76,7 +76,7 @@ function setupNoteEditor(i18n: Promise<void>): Promise<OldEditorAdapter> {
context.set( context.set(
nightModeKey, nightModeKey,
document.documentElement.classList.contains("night-mode") document.documentElement.classList.contains("night-mode"),
); );
i18n.then(() => { i18n.then(() => {

View File

@ -40,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
addedData, addedData,
graphRange, graphRange,
dispatch, dispatch,
$browserLinksSupported $browserLinksSupported,
); );
} }

View File

@ -64,7 +64,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
targetYear, targetYear,
nightMode, nightMode,
revlogRange, revlogRange,
calendarFirstDayOfWeek.set calendarFirstDayOfWeek.set,
); );
} }

View File

@ -30,7 +30,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
[histogramData, tableData] = prepareData( [histogramData, tableData] = prepareData(
gatherData(sourceData), gatherData(sourceData),
dispatch, dispatch,
$browserLinksSupported $browserLinksSupported,
); );
} }

View File

@ -42,7 +42,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
graphRange, graphRange,
$futureDueShowBacklog, $futureDueShowBacklog,
dispatch, dispatch,
$browserLinksSupported $browserLinksSupported,
)); ));
} }

View File

@ -42,7 +42,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
intervalData, intervalData,
range, range,
dispatch, dispatch,
$browserLinksSupported $browserLinksSupported,
); );
} }

View File

@ -40,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
bounds, bounds,
graphData, graphData,
graphRange, graphRange,
showTime showTime,
); );
} }

View File

@ -20,25 +20,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
async function getGraphData( async function getGraphData(
search: string, search: string,
days: number days: number,
): Promise<Stats.GraphsResponse> { ): Promise<Stats.GraphsResponse> {
return Stats.GraphsResponse.decode( return Stats.GraphsResponse.decode(
await postRequest("/_anki/graphData", JSON.stringify({ search, days })) await postRequest("/_anki/graphData", JSON.stringify({ search, days })),
); );
} }
async function getGraphPreferences(): Promise<Stats.GraphPreferences> { async function getGraphPreferences(): Promise<Stats.GraphPreferences> {
return Stats.GraphPreferences.decode( return Stats.GraphPreferences.decode(
await postRequest("/_anki/graphPreferences", JSON.stringify({})) await postRequest("/_anki/graphPreferences", JSON.stringify({})),
); );
} }
async function setGraphPreferences( async function setGraphPreferences(
prefs: PreferencePayload<Stats.GraphPreferences> prefs: PreferencePayload<Stats.GraphPreferences>,
): Promise<void> { ): Promise<void> {
await postRequest( await postRequest(
"/_anki/setGraphPreferences", "/_anki/setGraphPreferences",
Stats.GraphPreferences.encode(prefs).finish() Stats.GraphPreferences.encode(prefs).finish(),
); );
} }
@ -58,9 +58,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
setGraphPreferences, setGraphPreferences,
Stats.GraphPreferences.toObject.bind(Stats.GraphPreferences) as ( Stats.GraphPreferences.toObject.bind(Stats.GraphPreferences) as (
preferences: Stats.GraphPreferences, preferences: Stats.GraphPreferences,
options: { defaults: boolean } options: { defaults: boolean },
) => PreferenceRaw<Stats.GraphPreferences> ) => PreferenceRaw<Stats.GraphPreferences>,
) ),
); );
$: revlogRange = daysToRevlogRange($days); $: revlogRange = daysToRevlogRange($days);

View File

@ -51,7 +51,7 @@ export function buildHistogram(
data: GraphData, data: GraphData,
range: GraphRange, range: GraphRange,
dispatch: SearchDispatch, dispatch: SearchDispatch,
browserLinksSupported: boolean browserLinksSupported: boolean,
): [HistogramData | null, TableDatum[]] { ): [HistogramData | null, TableDatum[]] {
// get min/max // get min/max
const total = data.daysAdded.length; const total = data.daysAdded.length;
@ -91,7 +91,7 @@ export function buildHistogram(
const adjustedRange = scaleLinear().range([0.7, 0.3]); const adjustedRange = scaleLinear().range([0.7, 0.3]);
const colourScale = scaleSequential((n) => const colourScale = scaleSequential((n) =>
interpolateBlues(adjustedRange(n)!) interpolateBlues(adjustedRange(n)!),
).domain([xMax!, xMin!]); ).domain([xMax!, xMin!]);
const totalInPeriod = sum(bins, (bin) => bin.length); const totalInPeriod = sum(bins, (bin) => bin.length);
@ -111,7 +111,7 @@ export function buildHistogram(
function hoverText( function hoverText(
bin: Bin<number, number>, bin: Bin<number, number>,
cumulative: number, cumulative: number,
_percent: number _percent: number,
): string { ): string {
const day = dayLabel(bin.x0!, bin.x1!); const day = dayLabel(bin.x0!, bin.x1!);
const cards = tr.statisticsCards({ cards: bin.length }); const cards = tr.statisticsCards({ cards: bin.length });

View File

@ -97,7 +97,7 @@ export function renderButtons(
svgElem: SVGElement, svgElem: SVGElement,
bounds: GraphBounds, bounds: GraphBounds,
origData: Stats.GraphsResponse, origData: Stats.GraphsResponse,
range: GraphRange range: GraphRange,
): void { ): void {
const sourceData = gatherData(origData, range); const sourceData = gatherData(origData, range);
const data = [ const data = [
@ -129,7 +129,7 @@ export function renderButtons(
const total = sum(groupData, (d) => d.count); const total = sum(groupData, (d) => d.count);
const correct = sum( const correct = sum(
groupData.filter((d) => d.buttonNum > 1), groupData.filter((d) => d.buttonNum > 1),
(d) => d.count (d) => d.count,
); );
const percent = total ? ((correct / total) * 100).toFixed(2) : "0"; const percent = total ? ((correct / total) * 100).toFixed(2) : "0";
return { total, correct, percent }; return { total, correct, percent };
@ -170,8 +170,8 @@ export function renderButtons(
} }
return `${kind} \u200e(${totalCorrect(d).percent}%)`; return `${kind} \u200e(${totalCorrect(d).percent}%)`;
}) as any) }) as any)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -193,8 +193,8 @@ export function renderButtons(
selection.transition(trans).call( selection.transition(trans).call(
axisLeft(y) axisLeft(y)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -207,7 +207,7 @@ export function renderButtons(
.transition(trans) .transition(trans)
.attr( .attr(
"x", "x",
(d: Datum) => xGroup(d.group)! + xButton(d.buttonNum.toString())! (d: Datum) => xGroup(d.group)! + xButton(d.buttonNum.toString())!,
) )
.attr("y", (d: Datum) => y(d.count)!) .attr("y", (d: Datum) => y(d.count)!)
.attr("height", (d: Datum) => y(0)! - y(d.count)!) .attr("height", (d: Datum) => y(0)! - y(d.count)!)
@ -225,7 +225,7 @@ export function renderButtons(
.attr( .attr(
"x", "x",
(d: Datum) => (d: Datum) =>
xGroup(d.group)! + xButton(d.buttonNum.toString())! xGroup(d.group)! + xButton(d.buttonNum.toString())!,
) )
.attr("y", y(0)!) .attr("y", y(0)!)
.attr("height", 0) .attr("height", 0)
@ -233,8 +233,8 @@ export function renderButtons(
(update) => update.call(updateBar), (update) => update.call(updateBar),
(remove) => (remove) =>
remove.call((remove) => remove.call((remove) =>
remove.transition(trans).attr("height", 0).attr("y", y(0)!) remove.transition(trans).attr("height", 0).attr("y", y(0)!),
) ),
); );
// hover/tooltip // hover/tooltip

View File

@ -54,7 +54,7 @@ const Weekday = Stats.GraphPreferences.Weekday; /* enum */
export function gatherData( export function gatherData(
data: Stats.GraphsResponse, data: Stats.GraphsResponse,
firstDayOfWeek: WeekdayType firstDayOfWeek: WeekdayType,
): GraphData { ): GraphData {
const reviewCount = new Map<number, number>(); const reviewCount = new Map<number, number>();
@ -63,7 +63,7 @@ export function gatherData(
continue; continue;
} }
const day = Math.ceil( const day = Math.ceil(
((review.id as number) / 1000 - data.nextDayAtSecs) / 86400 ((review.id as number) / 1000 - data.nextDayAtSecs) / 86400,
); );
const count = reviewCount.get(day) ?? 0; const count = reviewCount.get(day) ?? 0;
reviewCount.set(day, count + 1); reviewCount.set(day, count + 1);
@ -86,7 +86,7 @@ export function renderCalendar(
targetYear: number, targetYear: number,
nightMode: boolean, nightMode: boolean,
revlogRange: RevlogRange, revlogRange: RevlogRange,
setFirstDayOfWeek: (d: number) => void setFirstDayOfWeek: (d: number) => void,
): void { ): void {
const svg = select(svgElem); const svg = select(svgElem);
const now = new Date(); const now = new Date();
@ -187,8 +187,8 @@ export function renderCalendar(
.on("click", null) .on("click", null)
.filter((d: number) => .filter((d: number) =>
[Weekday.SUNDAY, Weekday.MONDAY, Weekday.FRIDAY, Weekday.SATURDAY].includes( [Weekday.SUNDAY, Weekday.MONDAY, Weekday.FRIDAY, Weekday.SATURDAY].includes(
d d,
) ),
) )
.on("click", (_event: MouseEvent, d: number) => setFirstDayOfWeek(d)); .on("click", (_event: MouseEvent, d: number) => setFirstDayOfWeek(d));

View File

@ -124,7 +124,7 @@ function countCards(cards: Cards.ICard[], separateInactive: boolean): Count[] {
export function gatherData( export function gatherData(
data: Stats.GraphsResponse, data: Stats.GraphsResponse,
separateInactive: boolean separateInactive: boolean,
): GraphData { ): GraphData {
const totalCards = data.cards.length; const totalCards = data.cards.length;
const counts = countCards(data.cards, separateInactive); const counts = countCards(data.cards, separateInactive);
@ -158,7 +158,7 @@ export interface TableDatum {
export function renderCards( export function renderCards(
svgElem: SVGElement, svgElem: SVGElement,
bounds: GraphBounds, bounds: GraphBounds,
sourceData: GraphData sourceData: GraphData,
): TableDatum[] { ): TableDatum[] {
const summed = cumsum(sourceData.counts, (d: Count) => d[1]); const summed = cumsum(sourceData.counts, (d: Count) => d[1]);
const data = Array.from(summed).map((n, idx) => { const data = Array.from(summed).map((n, idx) => {
@ -200,12 +200,12 @@ export function renderCards(
d.transition(trans).attrTween("d", (d) => { d.transition(trans).attrTween("d", (d) => {
const interpolator = interpolate( const interpolator = interpolate(
{ startAngle: 0, endAngle: 0 }, { startAngle: 0, endAngle: 0 },
d d,
); );
return (t): string => arcGen(interpolator(t) as any) as string; return (t): string => arcGen(interpolator(t) as any) as string;
}) }),
); );
} },
); );
x.range([bounds.marginLeft, bounds.width - bounds.marginRight]); x.range([bounds.marginLeft, bounds.width - bounds.marginRight]);

View File

@ -46,7 +46,7 @@ function makeQuery(start: number, end: number): string {
function getAdjustedScaleAndTicks( function getAdjustedScaleAndTicks(
min: number, min: number,
max: number, max: number,
desiredBars: number desiredBars: number,
): [ScaleLinear<number, number, never>, number[]] { ): [ScaleLinear<number, number, never>, number[]] {
const prescale = scaleLinear().domain([min, max]).nice(); const prescale = scaleLinear().domain([min, max]).nice();
const ticks = prescale.ticks(desiredBars); const ticks = prescale.ticks(desiredBars);
@ -70,7 +70,7 @@ function getAdjustedScaleAndTicks(
export function prepareData( export function prepareData(
data: GraphData, data: GraphData,
dispatch: SearchDispatch, dispatch: SearchDispatch,
browserLinksSupported: boolean browserLinksSupported: boolean,
): [HistogramData | null, TableDatum[]] { ): [HistogramData | null, TableDatum[]] {
// get min/max // get min/max
const allEases = data.eases; const allEases = data.eases;

View File

@ -66,7 +66,7 @@ export function gatherData(data: Stats.GraphsResponse): GraphData {
const dueCounts = rollup( const dueCounts = rollup(
due, due,
(v) => v.length, (v) => v.length,
(d) => d (d) => d,
); );
return { dueCounts, haveBacklog }; return { dueCounts, haveBacklog };
} }
@ -95,7 +95,7 @@ export function buildHistogram(
range: GraphRange, range: GraphRange,
backlog: boolean, backlog: boolean,
dispatch: SearchDispatch, dispatch: SearchDispatch,
browserLinksSupported: boolean browserLinksSupported: boolean,
): FutureDueResponse { ): FutureDueResponse {
const output = { histogramData: null, tableData: [] }; const output = { histogramData: null, tableData: [] };
// get min/max // get min/max
@ -143,7 +143,7 @@ export function buildHistogram(
const adjustedRange = scaleLinear().range([0.7, 0.3]); const adjustedRange = scaleLinear().range([0.7, 0.3]);
const colourScale = scaleSequential((n) => const colourScale = scaleSequential((n) =>
interpolateGreens(adjustedRange(n)!) interpolateGreens(adjustedRange(n)!),
).domain([xMin!, xMax!]); ).domain([xMin!, xMax!]);
const total = sum(bins as any, binValue); const total = sum(bins as any, binValue);
@ -151,7 +151,7 @@ export function buildHistogram(
function hoverText( function hoverText(
bin: Bin<number, number>, bin: Bin<number, number>,
cumulative: number, cumulative: number,
_percent: number _percent: number,
): string { ): string {
const days = dayLabel(bin.x0!, bin.x1!); const days = dayLabel(bin.x0!, bin.x1!);
const cards = tr.statisticsCardsDue({ const cards = tr.statisticsCardsDue({

View File

@ -56,7 +56,7 @@ export function defaultGraphBounds(): GraphBounds {
export function setDataAvailable( export function setDataAvailable(
svg: Selection<SVGElement, any, any, any>, svg: Selection<SVGElement, any, any, any>,
available: boolean available: boolean,
): void { ): void {
svg.select(".no-data") svg.select(".no-data")
.attr("pointer-events", available ? "none" : "all") .attr("pointer-events", available ? "none" : "all")
@ -67,7 +67,7 @@ export function setDataAvailable(
export function millisecondCutoffForRange( export function millisecondCutoffForRange(
range: GraphRange, range: GraphRange,
nextDayAtSecs: number nextDayAtSecs: number,
): number { ): number {
let days; let days;
switch (range) { switch (range) {
@ -96,5 +96,5 @@ export interface TableDatum {
export type SearchEventMap = { search: { query: string } }; export type SearchEventMap = { search: { query: string } };
export type SearchDispatch = <EventKey extends Extract<keyof SearchEventMap, string>>( export type SearchDispatch = <EventKey extends Extract<keyof SearchEventMap, string>>(
type: EventKey, type: EventKey,
detail: SearchEventMap[EventKey] detail: SearchEventMap[EventKey],
) => void; ) => void;

View File

@ -27,7 +27,7 @@
], ],
{ {
controller: anki.RangeBox, controller: anki.RangeBox,
} },
); );
</script> </script>
</body> </body>

View File

@ -31,7 +31,7 @@ export interface HistogramData {
hoverText: ( hoverText: (
bin: Bin<number, number>, bin: Bin<number, number>,
cumulative: number, cumulative: number,
percent: number percent: number,
) => string; ) => string;
onClick: ((data: Bin<number, number>) => void) | null; onClick: ((data: Bin<number, number>) => void) | null;
showArea: boolean; showArea: boolean;
@ -43,7 +43,7 @@ export interface HistogramData {
export function histogramGraph( export function histogramGraph(
svgElem: SVGElement, svgElem: SVGElement,
bounds: GraphBounds, bounds: GraphBounds,
data: HistogramData | null data: HistogramData | null,
): void { ): void {
const svg = select(svgElem); const svg = select(svgElem);
const trans = svg.transition().duration(600) as any; const trans = svg.transition().duration(600) as any;
@ -64,8 +64,8 @@ export function histogramGraph(
axisBottom(x) axisBottom(x)
.ticks(7) .ticks(7)
.tickSizeOuter(0) .tickSizeOuter(0)
.tickFormat((data.xTickFormat ?? null) as any) .tickFormat((data.xTickFormat ?? null) as any),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -81,8 +81,8 @@ export function histogramGraph(
selection.transition(trans).call( selection.transition(trans).call(
axisLeft(y) axisLeft(y)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -118,8 +118,8 @@ export function histogramGraph(
(update) => update.call(updateBar), (update) => update.call(updateBar),
(remove) => (remove) =>
remove.call((remove) => remove.call((remove) =>
remove.transition(trans).attr("height", 0).attr("y", y(0)!) remove.transition(trans).attr("height", 0).attr("y", y(0)!),
) ),
); );
// cumulative area // cumulative area
@ -135,8 +135,8 @@ export function histogramGraph(
selection.transition(trans).call( selection.transition(trans).call(
axisRight(yAreaScale) axisRight(yAreaScale)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -154,12 +154,12 @@ export function histogramGraph(
} }
}) })
.y0(bounds.height - bounds.marginBottom) .y0(bounds.height - bounds.marginBottom)
.y1((d: any) => yAreaScale(d)!) as any .y1((d: any) => yAreaScale(d)!) as any,
); );
} }
const hoverData: [Bin<number, number>, number][] = data.bins.map( const hoverData: [Bin<number, number>, number][] = data.bins.map(
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]] (bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]],
); );
// hover/tooltip // hover/tooltip

View File

@ -60,7 +60,7 @@ function gatherData(data: Stats.GraphsResponse, range: GraphRange): Hour[] {
} }
const hour = Math.floor( const hour = Math.floor(
(((review.id as number) / 1000 + data.localOffsetSecs) / 3600) % 24 (((review.id as number) / 1000 + data.localOffsetSecs) / 3600) % 24,
); );
hours[hour].totalCount += 1; hours[hour].totalCount += 1;
if (review.buttonChosen != 1) { if (review.buttonChosen != 1) {
@ -75,7 +75,7 @@ export function renderHours(
svgElem: SVGElement, svgElem: SVGElement,
bounds: GraphBounds, bounds: GraphBounds,
origData: Stats.GraphsResponse, origData: Stats.GraphsResponse,
range: GraphRange range: GraphRange,
): void { ): void {
const data = gatherData(origData, range); const data = gatherData(origData, range);
@ -97,7 +97,7 @@ export function renderHours(
.paddingInner(0.1); .paddingInner(0.1);
svg.select<SVGGElement>(".x-ticks") svg.select<SVGGElement>(".x-ticks")
.call((selection) => .call((selection) =>
selection.transition(trans).call(axisBottom(x).tickSizeOuter(0)) selection.transition(trans).call(axisBottom(x).tickSizeOuter(0)),
) )
.selectAll(".tick") .selectAll(".tick")
.selectAll("text") .selectAll("text")
@ -121,8 +121,8 @@ export function renderHours(
selection.transition(trans).call( selection.transition(trans).call(
axisLeft(y) axisLeft(y)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -156,8 +156,8 @@ export function renderHours(
(update) => update.call(updateBar), (update) => update.call(updateBar),
(remove) => (remove) =>
remove.call((remove) => remove.call((remove) =>
remove.transition(trans).attr("height", 0).attr("y", y(0)!) remove.transition(trans).attr("height", 0).attr("y", y(0)!),
) ),
); );
svg.select<SVGGElement>(".y2-ticks") svg.select<SVGGElement>(".y2-ticks")
@ -166,8 +166,8 @@ export function renderHours(
axisRight(yArea) axisRight(yArea)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickFormat((n: any) => `${Math.round(n * 100)}%`) .tickFormat((n: any) => `${Math.round(n * 100)}%`)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -185,7 +185,7 @@ export function renderHours(
.y1((d: Hour) => { .y1((d: Hour) => {
const correctRatio = d.correctCount! / d.totalCount!; const correctRatio = d.correctCount! / d.totalCount!;
return yArea(isNaN(correctRatio) ? 0 : correctRatio)!; return yArea(isNaN(correctRatio) ? 0 : correctRatio)!;
}) }),
); );
function tooltipText(d: Hour): string { function tooltipText(d: Hour): string {

View File

@ -29,7 +29,7 @@ export function graphs(
search = "deck:current", search = "deck:current",
days = 365, days = 365,
controller = null as SvelteComponent | null, controller = null as SvelteComponent | null,
} = {} } = {},
): void { ): void {
const nightMode = checkNightMode(); const nightMode = checkNightMode();

View File

@ -46,7 +46,7 @@ export function gatherIntervalData(data: Stats.GraphsResponse): IntervalGraphDat
export function intervalLabel( export function intervalLabel(
daysStart: number, daysStart: number,
daysEnd: number, daysEnd: number,
cards: number cards: number,
): string { ): string {
if (daysEnd - daysStart <= 1) { if (daysEnd - daysStart <= 1) {
// singular // singular
@ -79,7 +79,7 @@ export function prepareIntervalData(
data: IntervalGraphData, data: IntervalGraphData,
range: IntervalRange, range: IntervalRange,
dispatch: SearchDispatch, dispatch: SearchDispatch,
browserLinksSupported: boolean browserLinksSupported: boolean,
): [HistogramData | null, TableDatum[]] { ): [HistogramData | null, TableDatum[]] {
// get min/max // get min/max
const allIntervals = data.intervals; const allIntervals = data.intervals;
@ -122,7 +122,7 @@ export function prepareIntervalData(
const prescale = scaleLinear().domain([xMin!, xMax!]); const prescale = scaleLinear().domain([xMin!, xMax!]);
const scale = scaleLinear().domain( const scale = scaleLinear().domain(
(niceNecessary ? prescale.nice() : prescale).domain().map(increment) (niceNecessary ? prescale.nice() : prescale).domain().map(increment),
); );
const bins = histogram() const bins = histogram()
@ -137,13 +137,13 @@ export function prepareIntervalData(
const adjustedRange = scaleLinear().range([0.7, 0.3]); const adjustedRange = scaleLinear().range([0.7, 0.3]);
const colourScale = scaleSequential((n) => const colourScale = scaleSequential((n) =>
interpolateBlues(adjustedRange(n)!) interpolateBlues(adjustedRange(n)!),
).domain([xMax!, xMin!]); ).domain([xMax!, xMin!]);
function hoverText( function hoverText(
bin: Bin<number, number>, bin: Bin<number, number>,
_cumulative: number, _cumulative: number,
percent: number percent: number,
): string { ): string {
// const day = dayLabel(bin.x0!, bin.x1!); // const day = dayLabel(bin.x0!, bin.x1!);
const interval = intervalLabel(bin.x0!, bin.x1!, bin.length); const interval = intervalLabel(bin.x0!, bin.x1!, bin.length);

View File

@ -65,7 +65,7 @@ export function gatherData(data: Stats.GraphsResponse): GraphData {
continue; continue;
} }
const day = Math.ceil( const day = Math.ceil(
((review.id as number) / 1000 - data.nextDayAtSecs) / 86400 ((review.id as number) / 1000 - data.nextDayAtSecs) / 86400,
); );
const countEntry = const countEntry =
reviewCount.get(day) ?? reviewCount.set(day, { ...empty }).get(day)!; reviewCount.get(day) ?? reviewCount.set(day, { ...empty }).get(day)!;
@ -131,7 +131,7 @@ export function renderReviews(
bounds: GraphBounds, bounds: GraphBounds,
sourceData: GraphData, sourceData: GraphData,
range: GraphRange, range: GraphRange,
showTime: boolean showTime: boolean,
): TableDatum[] { ): TableDatum[] {
const svg = select(svgElem); const svg = select(svgElem);
const trans = svg.transition().duration(600) as any; const trans = svg.transition().duration(600) as any;
@ -178,7 +178,7 @@ export function renderReviews(
x.range([bounds.marginLeft, bounds.width - bounds.marginRight]); x.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
svg.select<SVGGElement>(".x-ticks") svg.select<SVGGElement>(".x-ticks")
.call((selection) => .call((selection) =>
selection.transition(trans).call(axisBottom(x).ticks(7).tickSizeOuter(0)) selection.transition(trans).call(axisBottom(x).ticks(7).tickSizeOuter(0)),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -207,8 +207,8 @@ export function renderReviews(
axisLeft(y) axisLeft(y)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickSizeOuter(0) .tickSizeOuter(0)
.tickFormat(yTickFormat as any) .tickFormat(yTickFormat as any),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -222,19 +222,19 @@ export function renderReviews(
const cappedRange = scaleLinear().range([0.3, 0.5]); const cappedRange = scaleLinear().range([0.3, 0.5]);
const shiftedRange = scaleLinear().range([0.4, 0.7]); const shiftedRange = scaleLinear().range([0.4, 0.7]);
const darkerGreens = scaleSequential((n) => const darkerGreens = scaleSequential((n) =>
interpolateGreens(shiftedRange(n)!) interpolateGreens(shiftedRange(n)!),
).domain(x.domain() as any); ).domain(x.domain() as any);
const lighterGreens = scaleSequential((n) => const lighterGreens = scaleSequential((n) =>
interpolateGreens(cappedRange(n)!) interpolateGreens(cappedRange(n)!),
).domain(x.domain() as any); ).domain(x.domain() as any);
const reds = scaleSequential((n) => interpolateReds(cappedRange(n)!)).domain( const reds = scaleSequential((n) => interpolateReds(cappedRange(n)!)).domain(
x.domain() as any x.domain() as any,
); );
const oranges = scaleSequential((n) => interpolateOranges(cappedRange(n)!)).domain( const oranges = scaleSequential((n) => interpolateOranges(cappedRange(n)!)).domain(
x.domain() as any x.domain() as any,
); );
const purples = scaleSequential((n) => interpolatePurples(cappedRange(n)!)).domain( const purples = scaleSequential((n) => interpolatePurples(cappedRange(n)!)).domain(
x.domain() as any x.domain() as any,
); );
function binColor(idx: BinIndex): ScaleSequential<string> { function binColor(idx: BinIndex): ScaleSequential<string> {
@ -317,8 +317,8 @@ export function renderReviews(
(update) => update.call((d) => updateBar(d, barNum)), (update) => update.call((d) => updateBar(d, barNum)),
(remove) => (remove) =>
remove.call((remove) => remove.call((remove) =>
remove.transition(trans).attr("height", 0).attr("y", y(0)!) remove.transition(trans).attr("height", 0).attr("y", y(0)!),
) ),
); );
} }
@ -337,8 +337,8 @@ export function renderReviews(
axisRight(yAreaScale) axisRight(yAreaScale)
.ticks(bounds.height / 50) .ticks(bounds.height / 50)
.tickFormat(yTickFormat as any) .tickFormat(yTickFormat as any)
.tickSizeOuter(0) .tickSizeOuter(0),
) ),
) )
.attr("direction", "ltr"); .attr("direction", "ltr");
@ -356,12 +356,12 @@ export function renderReviews(
} }
}) })
.y0(bounds.height - bounds.marginBottom) .y0(bounds.height - bounds.marginBottom)
.y1((d: any) => yAreaScale(d)!) as any .y1((d: any) => yAreaScale(d)!) as any,
); );
} }
const hoverData: [Bin<number, number>, number][] = bins.map( const hoverData: [Bin<number, number>, number][] = bins.map(
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]] (bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]],
); );
// hover/tooltip // hover/tooltip

View File

@ -74,7 +74,7 @@ export function gatherData(data: Stats.GraphsResponse): TodayData {
const againCount = answerCount - correctCount; const againCount = answerCount - correctCount;
let againCountText = tr.statisticsTodayAgainCount(); let againCountText = tr.statisticsTodayAgainCount();
againCountText += ` ${againCount} (${((againCount / answerCount) * 100).toFixed( againCountText += ` ${againCount} (${((againCount / answerCount) * 100).toFixed(
2 2,
)}%)`; )}%)`;
const typeCounts = tr.statisticsTodayTypeCounts({ const typeCounts = tr.statisticsTodayTypeCounts({
learnCount, learnCount,

View File

@ -17,7 +17,7 @@ type FilterMethod = (element: Element) => void;
function filterAttributes( function filterAttributes(
attributePredicate: (attributeName: string) => boolean, attributePredicate: (attributeName: string) => boolean,
element: Element element: Element,
): void { ): void {
for (const attr of [...element.attributes]) { for (const attr of [...element.attributes]) {
const attrName = attr.name.toUpperCase(); const attrName = attr.name.toUpperCase();
@ -37,7 +37,7 @@ const allow =
(element: Element): void => (element: Element): void =>
filterAttributes( filterAttributes(
(attributeName: string) => attrs.includes(attributeName), (attributeName: string) => attrs.includes(attributeName),
element element,
); );
function unwrapElement(element: Element): void { function unwrapElement(element: Element): void {

View File

@ -7,7 +7,7 @@ export function removeNode(element: Node): void {
function iterateElement( function iterateElement(
filter: (node: Node) => void, filter: (node: Node) => void,
fragment: DocumentFragment | Element fragment: DocumentFragment | Element,
): void { ): void {
for (const child of [...fragment.childNodes]) { for (const child of [...fragment.childNodes]) {
filter(child); filter(child);

View File

@ -51,9 +51,9 @@ const filterStyling =
}; };
export const filterStylingNightMode = filterStyling( export const filterStylingNightMode = filterStyling(
allowPropertiesBlockValues(stylingNightMode) allowPropertiesBlockValues(stylingNightMode),
); );
export const filterStylingLightMode = filterStyling( export const filterStylingLightMode = filterStyling(
allowPropertiesBlockValues(stylingLightMode) allowPropertiesBlockValues(stylingLightMode),
); );
export const filterStylingInternal = filterStyling(blockProperties(stylingInternal)); export const filterStylingInternal = filterStyling(blockProperties(stylingInternal));

View File

@ -106,7 +106,7 @@ const isListItem = (element: Element): element is HTMLLIElement =>
const isParagraph = (element: Element): element is HTMLParamElement => const isParagraph = (element: Element): element is HTMLParamElement =>
element.tagName === "P"; element.tagName === "P";
const isBlockElement = ( const isBlockElement = (
element: Element element: Element,
): element is HTMLLIElement & HTMLParamElement => ): element is HTMLLIElement & HTMLParamElement =>
isListItem(element) || isParagraph(element); isListItem(element) || isParagraph(element);

View File

@ -21,19 +21,19 @@ function toFluentNumber(num: number): FluentNumber {
} }
function formatArgs( function formatArgs(
args: Record<string, FluentVariable> args: Record<string, FluentVariable>,
): Record<string, FluentVariable> { ): Record<string, FluentVariable> {
return Object.fromEntries( return Object.fromEntries(
Object.entries(args).map(([key, value]) => [ Object.entries(args).map(([key, value]) => [
key, key,
typeof value === "number" ? toFluentNumber(value) : value, typeof value === "number" ? toFluentNumber(value) : value,
]) ]),
); );
} }
export function getMessage( export function getMessage(
key: string, key: string,
args: Record<string, FluentVariable> = {} args: Record<string, FluentVariable> = {},
): string | null { ): string | null {
for (const bundle of bundles) { for (const bundle of bundles) {
const msg = bundle.getMessage(key); const msg = bundle.getMessage(key);

View File

@ -43,7 +43,7 @@ let langs: string[] = [];
export function toLocaleString( export function toLocaleString(
date: Date, date: Date,
options?: Intl.DateTimeFormatOptions options?: Intl.DateTimeFormatOptions,
): string { ): string {
return date.toLocaleDateString(langs, options); return date.toLocaleDateString(langs, options);
} }
@ -51,7 +51,7 @@ export function toLocaleString(
export function localeCompare( export function localeCompare(
first: string, first: string,
second: string, second: string,
options?: Intl.CollatorOptions options?: Intl.CollatorOptions,
): number { ): number {
return first.localeCompare(second, langs, options); return first.localeCompare(second, langs, options);
} }

View File

@ -23,13 +23,13 @@ export const checkModifiers =
( (
matches: boolean, matches: boolean,
currentModifier: Modifier, currentModifier: Modifier,
currentIndex: number currentIndex: number,
): boolean => ): boolean =>
matches && matches &&
(optional.includes(currentModifier as Modifier) || (optional.includes(currentModifier as Modifier) ||
event.getModifierState(platformModifiers[currentIndex]) === event.getModifierState(platformModifiers[currentIndex]) ===
required.includes(currentModifier)), required.includes(currentModifier)),
true true,
); );
}; };

View File

@ -4,7 +4,7 @@
export async function postRequest( export async function postRequest(
path: string, path: string,
body: string | Uint8Array, body: string | Uint8Array,
headers: Record<string, string> = {} headers: Record<string, string> = {},
): Promise<Uint8Array> { ): Promise<Uint8Array> {
if (body instanceof Uint8Array) { if (body instanceof Uint8Array) {
headers["Content-type"] = "application/octet-stream"; headers["Content-type"] = "application/octet-stream";

View File

@ -21,7 +21,7 @@ export function unwrapOptionalNumber(
| Generic.OptionalInt32 | Generic.OptionalInt32
| Generic.OptionalUInt32 | Generic.OptionalUInt32
| null | null
| undefined | undefined,
): number | undefined { ): number | undefined {
if (msg && msg !== null) { if (msg && msg !== null) {
if (msg.val !== null) { if (msg.val !== null) {

View File

@ -8,7 +8,7 @@ const prohibit = () => false;
export function registerPackage( export function registerPackage(
name: string, name: string,
entries: Record<string, unknown>, entries: Record<string, unknown>,
deprecation?: Record<string, string> deprecation?: Record<string, string>,
): void { ): void {
const pack = deprecation const pack = deprecation
? new Proxy(entries, { ? new Proxy(entries, {
@ -36,7 +36,7 @@ function hasPackages(...names: string[]): boolean {
const libraries = listPackages(); const libraries = listPackages();
return names.reduce( return names.reduce(
(accu: boolean, name: string) => accu && libraries.includes(name), (accu: boolean, name: string) => accu && libraries.includes(name),
true true,
); );
} }
@ -53,5 +53,5 @@ registerPackage(
}, },
{ {
[immediatelyDeprecated.name]: "Do not use this function", [immediatelyDeprecated.name]: "Do not use this function",
} },
); );

View File

@ -47,7 +47,7 @@ function splitKeyCombinationString(keyCombinationString: string): string[][] {
function toPlatformString(keyCombination: string[]): string { function toPlatformString(keyCombination: string[]): string {
return ( return (
modifiersToPlatformString( modifiersToPlatformString(
keyCombination.slice(0, -1).filter(isRequiredModifier) keyCombination.slice(0, -1).filter(isRequiredModifier),
) + keyToPlatformString(keyCombination[keyCombination.length - 1]) ) + keyToPlatformString(keyCombination[keyCombination.length - 1])
); );
} }
@ -80,11 +80,11 @@ function removeTrailing(modifier: string): string {
// function checkModifiers(event: KeyboardEvent, modifiers: string[]): boolean { // function checkModifiers(event: KeyboardEvent, modifiers: string[]): boolean {
function separateRequiredOptionalModifiers( function separateRequiredOptionalModifiers(
modifiers: string[] modifiers: string[],
): [Modifier[], Modifier[]] { ): [Modifier[], Modifier[]] {
const [requiredModifiers, otherModifiers] = partition( const [requiredModifiers, otherModifiers] = partition(
isRequiredModifier, isRequiredModifier,
modifiers modifiers,
); );
const optionalModifiers = otherModifiers.map(removeTrailing); const optionalModifiers = otherModifiers.map(removeTrailing);
@ -104,7 +104,7 @@ function keyToCode(key: string): number {
} }
function keyCombinationToCheck( function keyCombinationToCheck(
keyCombination: string[] keyCombination: string[],
): (event: KeyboardEvent) => boolean { ): (event: KeyboardEvent) => boolean {
const keyCode = keyToCode(keyCombination[keyCombination.length - 1]); const keyCode = keyToCode(keyCombination[keyCombination.length - 1]);
const modifiers = keyCombination.slice(0, -1); const modifiers = keyCombination.slice(0, -1);
@ -147,7 +147,7 @@ function innerShortcut(
export function registerShortcut( export function registerShortcut(
callback: (event: KeyboardEvent) => void, callback: (event: KeyboardEvent) => void,
keyCombinationString: string, keyCombinationString: string,
target: EventTarget | Document = document target: EventTarget | Document = document,
): () => void { ): () => void {
const [check, ...restChecks] = const [check, ...restChecks] =
splitKeyCombinationString(keyCombinationString).map(keyCombinationToCheck); splitKeyCombinationString(keyCombinationString).map(keyCombinationToCheck);

View File

@ -107,7 +107,7 @@ export function studiedToday(cards: number, secs: number): string {
function i18nFuncForUnit( function i18nFuncForUnit(
unit: TimespanUnit, unit: TimespanUnit,
short: boolean short: boolean,
): ({ amount: number }) => string { ): ({ amount: number }) => string {
if (short) { if (short) {
switch (unit) { switch (unit) {

View File

@ -22,7 +22,7 @@ export function wrapInternal(
root: DocumentOrShadowRoot, root: DocumentOrShadowRoot,
front: string, front: string,
back: string, back: string,
plainText: boolean plainText: boolean,
): void { ): void {
const selection = root.getSelection()!; const selection = root.getSelection()!;
const range = selection.getRangeAt(0); const range = selection.getRangeAt(0);
@ -41,7 +41,7 @@ export function wrapInternal(
if ( if (
!span.innerHTML && !span.innerHTML &&
/* ugly solution: treat <anki-mathjax> differently than other wraps */ !front.includes( /* ugly solution: treat <anki-mathjax> differently than other wraps */ !front.includes(
"<anki-mathjax" "<anki-mathjax",
) )
) { ) {
moveCursorPastPostfix(selection, back); moveCursorPastPostfix(selection, back);

View File

@ -6,13 +6,13 @@ import { postRequest } from "../lib/postrequest";
async function getNextStates(): Promise<Scheduler.NextCardStates> { async function getNextStates(): Promise<Scheduler.NextCardStates> {
return Scheduler.NextCardStates.decode( return Scheduler.NextCardStates.decode(
await postRequest("/_anki/nextCardStates", "") await postRequest("/_anki/nextCardStates", ""),
); );
} }
async function setNextStates( async function setNextStates(
key: string, key: string,
states: Scheduler.NextCardStates states: Scheduler.NextCardStates,
): Promise<void> { ): Promise<void> {
const data: Uint8Array = Scheduler.NextCardStates.encode(states).finish(); const data: Uint8Array = Scheduler.NextCardStates.encode(states).finish();
await postRequest("/_anki/setNextCardStates", data, { key }); await postRequest("/_anki/setNextCardStates", data, { key });
@ -20,7 +20,7 @@ async function setNextStates(
export async function mutateNextCardStates( export async function mutateNextCardStates(
key: string, key: string,
mutator: (states: Scheduler.NextCardStates) => void mutator: (states: Scheduler.NextCardStates) => void,
): Promise<void> { ): Promise<void> {
const states = await getNextStates(); const states = await getNextStates();
mutator(states); mutator(states);

View File

@ -11,7 +11,7 @@ function injectPreloadLink(href: string, as: string): void {
export function allImagesLoaded(): Promise<void[]> { export function allImagesLoaded(): Promise<void[]> {
return Promise.all( return Promise.all(
Array.from(document.getElementsByTagName("img")).map(imageLoaded) Array.from(document.getElementsByTagName("img")).map(imageLoaded),
); );
} }
@ -35,7 +35,7 @@ function extractImageSrcs(html: string): string[] {
tmpl.innerHTML = html; tmpl.innerHTML = html;
const fragment = tmpl.content; const fragment = tmpl.content;
const srcs = [...fragment.querySelectorAll("img[src]")].map( const srcs = [...fragment.querySelectorAll("img[src]")].map(
(img) => (img as HTMLImageElement).src (img) => (img as HTMLImageElement).src,
); );
return srcs; return srcs;
} }

View File

@ -31,7 +31,7 @@ export function getTypedAnswer(): string | null {
} }
function _runHook( function _runHook(
hooks: Array<Callback> hooks: Array<Callback>,
): Promise<PromiseSettledResult<void | Promise<void>>[]> { ): Promise<PromiseSettledResult<void | Promise<void>>[]> {
const promises: (Promise<void> | void)[] = []; const promises: (Promise<void> | void)[] = [];
@ -90,7 +90,7 @@ const renderError =
} }
return `<div>Invalid ${type} on card: ${errorMessage}\n${errorStack}</div>`.replace( return `<div>Invalid ${type} on card: ${errorMessage}\n${errorStack}</div>`.replace(
/\n/g, /\n/g,
"<br>" "<br>",
); );
}; };
@ -98,7 +98,7 @@ export async function _updateQA(
html: string, html: string,
_unusused: unknown, _unusused: unknown,
onupdate: Callback, onupdate: Callback,
onshown: Callback onshown: Callback,
): Promise<void> { ): Promise<void> {
onUpdateHook.length = 0; onUpdateHook.length = 0;
onUpdateHook.push(onupdate); onUpdateHook.push(onupdate);
@ -152,8 +152,8 @@ export function _showQuestion(q: string, a: string, bodyclass: string): void {
} }
// preload images // preload images
allImagesLoaded().then(() => preloadAnswerImages(q, a)); allImagesLoaded().then(() => preloadAnswerImages(q, a));
} },
) ),
); );
} }
@ -177,8 +177,8 @@ export function _showAnswer(a: string, bodyclass: string): void {
}, },
function () { function () {
/* noop */ /* noop */
} },
) ),
); );
} }

View File

@ -24,7 +24,7 @@ function formatText(text: string): string {
for (const keyword of ["type", "fields"]) { for (const keyword of ["type", "fields"]) {
newText = newText.replace( newText = newText.replace(
new RegExp(`\\b${keyword.toUpperCase()}\\b`, "g"), new RegExp(`\\b${keyword.toUpperCase()}\\b`, "g"),
keyword keyword,
); );
} }
return newText; return newText;

View File

@ -9,6 +9,6 @@
// ensure node can run the resulting code // ensure node can run the resulting code
"noEmitHelpers": false, "noEmitHelpers": false,
"importHelpers": false, "importHelpers": false,
"module": "commonjs", "module": "commonjs"
} }
} }

View File

@ -76,7 +76,7 @@ const languageServiceHost: ts.LanguageServiceHost = {
}, },
getLength: () => text.length, getLength: () => text.length,
getChangeRange: ( getChangeRange: (
_oldSnapshot: ts.IScriptSnapshot _oldSnapshot: ts.IScriptSnapshot,
): ts.TextChangeRange | undefined => { ): ts.TextChangeRange | undefined => {
return undefined; return undefined;
}, },
@ -140,7 +140,7 @@ function readFile(file) {
async function compileSingleSvelte( async function compileSingleSvelte(
input: SvelteInput, input: SvelteInput,
binDir: string, binDir: string,
genDir: string genDir: string,
): Promise<void> { ): Promise<void> {
const preprocessOptions = preprocess({ const preprocessOptions = preprocess({
scss: { scss: {
@ -215,7 +215,7 @@ async function extractArgsAndData(args: string[]): Promise<Args> {
} }
async function extractSvelteAndDeps( async function extractSvelteAndDeps(
files: string[] files: string[],
): Promise<[SvelteInput[], InputFile[]]> { ): Promise<[SvelteInput[], InputFile[]]> {
const svelte: SvelteInput[] = []; const svelte: SvelteInput[] = [];
const deps: InputFile[] = []; const deps: InputFile[] = [];
@ -249,7 +249,7 @@ function remapBinToSrcDir(file: string): string {
async function compileSvelte( async function compileSvelte(
svelte: SvelteInput[], svelte: SvelteInput[],
binDir: string, binDir: string,
genDir: string genDir: string,
): Promise<void> { ): Promise<void> {
for (const file of svelte) { for (const file of svelte) {
await compileSingleSvelte(file, binDir, genDir); await compileSingleSvelte(file, binDir, genDir);

View File

@ -8,6 +8,6 @@
// ensure node can run the resulting code // ensure node can run the resulting code
"noEmitHelpers": false, "noEmitHelpers": false,
"importHelpers": false, "importHelpers": false,
"module": "commonjs", "module": "commonjs"
} }
} }

View File

@ -11,13 +11,13 @@ interface AsyncReactiveData<T, E> {
function useAsyncReactive<T, E>( function useAsyncReactive<T, E>(
asyncFunction: () => Promise<T>, asyncFunction: () => Promise<T>,
dependencies: [Readable<unknown>, ...Readable<unknown>[]] dependencies: [Readable<unknown>, ...Readable<unknown>[]],
): AsyncReactiveData<T, E> { ): AsyncReactiveData<T, E> {
const promise = derived( const promise = derived(
dependencies, dependencies,
(_, set: (value: Promise<T> | null) => void): void => set(asyncFunction()), (_, set: (value: Promise<T> | null) => void): void => set(asyncFunction()),
// initialize with null to avoid duplicate fetch on init // initialize with null to avoid duplicate fetch on init
null null,
); );
const value = derived( const value = derived(
@ -25,7 +25,7 @@ function useAsyncReactive<T, E>(
($promise, set: (value: T) => void): void => { ($promise, set: (value: T) => void): void => {
$promise?.then((value: T) => set(value)); $promise?.then((value: T) => set(value));
}, },
null null,
); );
const error = derived( const error = derived(
@ -34,7 +34,7 @@ function useAsyncReactive<T, E>(
$promise?.catch((error: E) => set(error)); $promise?.catch((error: E) => set(error));
return (): void => set(null); return (): void => set(null);
}, },
null null,
); );
const loading = derived( const loading = derived(
@ -43,7 +43,7 @@ function useAsyncReactive<T, E>(
$promise?.finally(() => set(false)); $promise?.finally(() => set(false));
return (): void => set(true); return (): void => set(true);
}, },
true true,
); );
return { value, error, loading }; return { value, error, loading };

View File

@ -8,7 +8,7 @@ type ContextProperty<T> = [
// this typing is a lie insofar that calling get // this typing is a lie insofar that calling get
// outside of the component's context will return undefined // outside of the component's context will return undefined
() => T, () => T,
() => boolean () => boolean,
]; ];
function contextProperty<T>(key: symbol): ContextProperty<T> { function contextProperty<T>(key: symbol): ContextProperty<T> {

View File

@ -3,7 +3,7 @@
import type { SvelteComponentDev } from "svelte/internal"; import type { SvelteComponentDev } from "svelte/internal";
export interface DynamicSvelteComponent< export interface DynamicSvelteComponent<
T extends typeof SvelteComponentDev = typeof SvelteComponentDev T extends typeof SvelteComponentDev = typeof SvelteComponentDev,
> { > {
component: T; component: T;
[k: string]: unknown; [k: string]: unknown;
@ -12,9 +12,9 @@ export interface DynamicSvelteComponent<
export const dynamicComponent = export const dynamicComponent =
< <
Comp extends typeof SvelteComponentDev, Comp extends typeof SvelteComponentDev,
DefaultProps = NonNullable<ConstructorParameters<Comp>[0]["props"]> DefaultProps = NonNullable<ConstructorParameters<Comp>[0]["props"]>,
>( >(
component: Comp component: Comp,
) => ) =>
<Props = DefaultProps>(props: Props): DynamicSvelteComponent<Comp> & Props => { <Props = DefaultProps>(props: Props): DynamicSvelteComponent<Comp> & Props => {
return { component, ...props }; return { component, ...props };

View File

@ -15,7 +15,7 @@ const config = {
interface DOMMirror { interface DOMMirror {
mirror( mirror(
element: Element, element: Element,
params: { store: Writable<DocumentFragment> } params: { store: Writable<DocumentFragment> },
): { destroy(): void }; ): { destroy(): void };
preventResubscription(): () => void; preventResubscription(): () => void;
} }
@ -33,7 +33,7 @@ function getDOMMirror(): DOMMirror {
function mirror( function mirror(
element: Element, element: Element,
{ store }: { store: Writable<DocumentFragment> } { store }: { store: Writable<DocumentFragment> },
): { destroy(): void } { ): { destroy(): void } {
function saveHTMLToStore(): void { function saveHTMLToStore(): void {
const range = document.createRange(); const range = document.createRange();
@ -80,7 +80,7 @@ function getDOMMirror(): DOMMirror {
} else { } else {
element.removeEventListener("blur", subscribe); element.removeEventListener("blur", subscribe);
} }
} },
); );
return { return {

View File

@ -14,7 +14,7 @@ export interface NodeStore<T extends Node> extends Writable<T> {
export function nodeStore<T extends Node>( export function nodeStore<T extends Node>(
node?: T, node?: T,
preprocess: (node: T) => void = noop preprocess: (node: T) => void = noop,
): NodeStore<T> { ): NodeStore<T> {
const subscribers: Set<Subscriber<T>> = new Set(); const subscribers: Set<Subscriber<T>> = new Set();

View File

@ -22,7 +22,7 @@ export type PreferenceRaw<T> = {
function createPreference<T>( function createPreference<T>(
initialValue: T, initialValue: T,
savePreferences: () => void savePreferences: () => void,
): CustomStore<T> { ): CustomStore<T> {
const { subscribe, set, update } = writable(initialValue); const { subscribe, set, update } = writable(initialValue);
@ -42,7 +42,7 @@ function createPreference<T>(
function preparePreferences<T>( function preparePreferences<T>(
Preferences: T, Preferences: T,
setter: (payload: PreferencePayload<T>) => Promise<void>, setter: (payload: PreferencePayload<T>) => Promise<void>,
toObject: (preferences: T, options: { defaults: boolean }) => PreferenceRaw<T> toObject: (preferences: T, options: { defaults: boolean }) => PreferenceRaw<T>,
): PreferenceStore<T> { ): PreferenceStore<T> {
const preferences: Partial<PreferenceStore<T>> = {}; const preferences: Partial<PreferenceStore<T>> = {};
@ -61,7 +61,7 @@ function preparePreferences<T>(
} }
for (const [key, value] of Object.entries( for (const [key, value] of Object.entries(
toObject(Preferences, { defaults: true }) toObject(Preferences, { defaults: true }),
)) { )) {
preferences[key] = createPreference(value, savePreferences); preferences[key] = createPreference(value, savePreferences);
} }
@ -72,7 +72,7 @@ function preparePreferences<T>(
export async function getPreferences<T>( export async function getPreferences<T>(
getter: () => Promise<T>, getter: () => Promise<T>,
setter: (payload: PreferencePayload<T>) => Promise<void>, setter: (payload: PreferencePayload<T>) => Promise<void>,
toObject: (preferences: T, options: { defaults: boolean }) => PreferenceRaw<T> toObject: (preferences: T, options: { defaults: boolean }) => PreferenceRaw<T>,
): Promise<PreferenceStore<T>> { ): Promise<PreferenceStore<T>> {
const initialPreferences = await getter(); const initialPreferences = await getter();
return preparePreferences(initialPreferences, setter, toObject); return preparePreferences(initialPreferences, setter, toObject);

View File

@ -13,7 +13,7 @@ export function shortcut(
action: (event: KeyboardEvent) => void; action: (event: KeyboardEvent) => void;
keyCombination: string; keyCombination: string;
target?: EventTarget; target?: EventTarget;
} },
): { destroy: () => void } { ): { destroy: () => void } {
const deregister = registerShortcut(action, keyCombination, target ?? document); const deregister = registerShortcut(action, keyCombination, target ?? document);

View File

@ -12,7 +12,7 @@ interface StoreAccessors {
function storeSubscribe<T>( function storeSubscribe<T>(
store: Readable<T>, store: Readable<T>,
callback: (value: T) => void, callback: (value: T) => void,
start = true start = true,
): StoreAccessors { ): StoreAccessors {
function subscribe(): Unsubscriber { function subscribe(): Unsubscriber {
return store.subscribe(callback); return store.subscribe(callback);