Use trailingComma: all setting in .prettierrc (#1435)
This commit is contained in:
parent
bf3adbc812
commit
0dff5ea3a3
@ -1,6 +1,6 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"trailingComma": "all",
|
||||
"printWidth": 88,
|
||||
"tabWidth": 4,
|
||||
"semi": true
|
||||
"semi": true,
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ import { postRequest } from "../lib/postrequest";
|
||||
|
||||
export async function getCardStats(cardId: number): Promise<Stats.CardStatsResponse> {
|
||||
return Stats.CardStatsResponse.decode(
|
||||
await postRequest("/_anki/cardStats", JSON.stringify({ cardId }))
|
||||
await postRequest("/_anki/cardStats", JSON.stringify({ cardId })),
|
||||
);
|
||||
}
|
||||
|
@ -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> {
|
||||
await state.setTargetNotetypeIndex(
|
||||
parseInt((event.target! as HTMLSelectElement).value)
|
||||
parseInt((event.target! as HTMLSelectElement).value),
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
@ -14,7 +14,7 @@ import { nightModeKey } from "../components/context-keys";
|
||||
export async function changeNotetypePage(
|
||||
target: HTMLDivElement,
|
||||
oldNotetypeId: number,
|
||||
newNotetypeId: number
|
||||
newNotetypeId: number,
|
||||
): Promise<ChangeNotetypePage> {
|
||||
const [info, names] = await Promise.all([
|
||||
getChangeNotetypeInfo(oldNotetypeId, newNotetypeId),
|
||||
|
@ -65,14 +65,14 @@ const exampleInfoSame = {
|
||||
function differentState(): ChangeNotetypeState {
|
||||
return new ChangeNotetypeState(
|
||||
Notetypes.NotetypeNames.fromObject(exampleNames),
|
||||
Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoDifferent)
|
||||
Notetypes.ChangeNotetypeInfo.fromObject(exampleInfoDifferent),
|
||||
);
|
||||
}
|
||||
|
||||
function sameState(): ChangeNotetypeState {
|
||||
return new ChangeNotetypeState(
|
||||
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, 2)).toBe("Add Reverse");
|
||||
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, 1)).toBe(1);
|
||||
@ -102,7 +102,7 @@ test("mapping", () => {
|
||||
|
||||
// the same template shouldn't be mappable twice
|
||||
expect(
|
||||
get(state.info).getOldNamesIncludingNothing(MapContext.Template)
|
||||
get(state.info).getOldNamesIncludingNothing(MapContext.Template),
|
||||
).toStrictEqual(["Card 1", "(Nothing)"]);
|
||||
expect(get(state.info).getOldIndex(MapContext.Template, 0)).toBe(0);
|
||||
expect(get(state.info).getOldIndex(MapContext.Template, 1)).toBe(1);
|
||||
|
@ -12,24 +12,24 @@ import { isEqual } from "lodash-es";
|
||||
|
||||
export async function getNotetypeNames(): Promise<Notetypes.NotetypeNames> {
|
||||
return Notetypes.NotetypeNames.decode(
|
||||
await postRequest("/_anki/notetypeNames", "")
|
||||
await postRequest("/_anki/notetypeNames", ""),
|
||||
);
|
||||
}
|
||||
|
||||
export async function getChangeNotetypeInfo(
|
||||
oldNotetypeId: number,
|
||||
newNotetypeId: number
|
||||
newNotetypeId: number,
|
||||
): Promise<Notetypes.ChangeNotetypeInfo> {
|
||||
return Notetypes.ChangeNotetypeInfo.decode(
|
||||
await postRequest(
|
||||
"/_anki/changeNotetypeInfo",
|
||||
JSON.stringify({ oldNotetypeId, newNotetypeId })
|
||||
)
|
||||
JSON.stringify({ oldNotetypeId, newNotetypeId }),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export async function changeNotetype(
|
||||
input: Notetypes.ChangeNotetypeRequest
|
||||
input: Notetypes.ChangeNotetypeRequest,
|
||||
): Promise<void> {
|
||||
const data: Uint8Array = Notetypes.ChangeNotetypeRequest.encode(input).finish();
|
||||
await postRequest("/_anki/changeNotetype", data);
|
||||
@ -98,7 +98,7 @@ export class ChangeNotetypeInfoWrapper {
|
||||
const usedEntries = new Set(this.mapForContext(ctx).filter((v) => v !== null));
|
||||
const oldNames = this.getOldNames(ctx);
|
||||
const unusedIdxs = [...Array(oldNames.length).keys()].filter(
|
||||
(idx) => !usedEntries.has(idx)
|
||||
(idx) => !usedEntries.has(idx),
|
||||
);
|
||||
const unusedNames = unusedIdxs.map((idx) => oldNames[idx]);
|
||||
unusedNames.sort();
|
||||
@ -150,7 +150,7 @@ export class ChangeNotetypeState {
|
||||
|
||||
constructor(
|
||||
notetypes: Notetypes.NotetypeNames,
|
||||
info: Notetypes.ChangeNotetypeInfo
|
||||
info: Notetypes.ChangeNotetypeInfo,
|
||||
) {
|
||||
this.info_ = new ChangeNotetypeInfoWrapper(info);
|
||||
this.info = readable(this.info_, (set) => {
|
||||
@ -168,7 +168,7 @@ export class ChangeNotetypeState {
|
||||
this.notetypesSetter(this.buildNotetypeList());
|
||||
const newInfo = await getChangeNotetypeInfo(
|
||||
this.info_.input().oldNotetypeId,
|
||||
this.info_.input().newNotetypeId
|
||||
this.info_.input().newNotetypeId,
|
||||
);
|
||||
|
||||
this.info_ = new ChangeNotetypeInfoWrapper(newInfo);
|
||||
@ -215,7 +215,7 @@ export class ChangeNotetypeState {
|
||||
idx,
|
||||
name: entry.name,
|
||||
current: entry.id === currentId,
|
||||
} as NotetypeListEntry)
|
||||
} as NotetypeListEntry),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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) =>
|
||||
addComponent(button, (added, parent) =>
|
||||
insertElement(added, parent, position)
|
||||
insertElement(added, parent, position),
|
||||
);
|
||||
const appendButton = (button: SvelteComponent, position: Identifier = -1) =>
|
||||
addComponent(button, (added, parent) =>
|
||||
appendElement(added, parent, position)
|
||||
appendElement(added, parent, position),
|
||||
);
|
||||
|
||||
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) =>
|
||||
updateRegistration(
|
||||
({ detach }) => detach.update((old: boolean): boolean => !old),
|
||||
id
|
||||
id,
|
||||
);
|
||||
|
||||
Object.assign(api, {
|
||||
|
@ -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) =>
|
||||
addComponent(group, (added, parent) =>
|
||||
insertElement(added, parent, position)
|
||||
insertElement(added, parent, position),
|
||||
);
|
||||
const appendGroup = (group: SvelteComponent, position: Identifier = -1) =>
|
||||
addComponent(group, (added, parent) =>
|
||||
appendElement(added, parent, position)
|
||||
appendElement(added, parent, position),
|
||||
);
|
||||
|
||||
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) =>
|
||||
updateRegistration(
|
||||
({ detach }) => detach.update((old: boolean): boolean => !old),
|
||||
id
|
||||
id,
|
||||
);
|
||||
|
||||
Object.assign(api, {
|
||||
|
@ -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) =>
|
||||
addComponent(group, (added, parent) =>
|
||||
insertElement(added, parent, position)
|
||||
insertElement(added, parent, position),
|
||||
);
|
||||
const append = (group: SvelteComponent, position: Identifier = -1) =>
|
||||
addComponent(group, (added, parent) =>
|
||||
appendElement(added, parent, position)
|
||||
appendElement(added, parent, position),
|
||||
);
|
||||
|
||||
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) =>
|
||||
updateRegistration(
|
||||
({ detach }) => detach.update((old: boolean): boolean => !old),
|
||||
id
|
||||
id,
|
||||
);
|
||||
|
||||
Object.assign(api, { insert, append, show, hide, toggle });
|
||||
|
@ -15,7 +15,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
registerShortcut(
|
||||
(event: KeyboardEvent) => dispatch("action", { originalEvent: event }),
|
||||
keyCombination,
|
||||
target as any
|
||||
)
|
||||
target as any,
|
||||
),
|
||||
);
|
||||
</script>
|
||||
|
@ -27,7 +27,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
export function updateAllState(event: Event): void {
|
||||
updateAllStateWithCallback((key: KeyType): boolean =>
|
||||
updaterMap.get(key)!(event)
|
||||
updaterMap.get(key)!(event),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
export function mergeTooltipAndShortcut(
|
||||
tooltip: string | undefined,
|
||||
shortcutLabel: string | undefined
|
||||
shortcutLabel: string | undefined,
|
||||
): string | undefined {
|
||||
if (!tooltip && !shortcutLabel) {
|
||||
return undefined;
|
||||
|
@ -4,7 +4,7 @@ export type Identifier = string | number;
|
||||
|
||||
export function findElement(
|
||||
collection: HTMLCollection,
|
||||
idOrIndex: Identifier
|
||||
idOrIndex: Identifier,
|
||||
): [number, Element] | null {
|
||||
let result: [number, Element] | null = null;
|
||||
|
||||
@ -37,7 +37,7 @@ export function findElement(
|
||||
export function insertElement(
|
||||
element: Element,
|
||||
collection: Element,
|
||||
idOrIndex: Identifier
|
||||
idOrIndex: Identifier,
|
||||
): number {
|
||||
const match = findElement(collection.children, idOrIndex);
|
||||
|
||||
@ -54,7 +54,7 @@ export function insertElement(
|
||||
export function appendElement(
|
||||
element: Element,
|
||||
collection: Element,
|
||||
idOrIndex: Identifier
|
||||
idOrIndex: Identifier,
|
||||
): number {
|
||||
const match = findElement(collection.children, idOrIndex);
|
||||
|
||||
@ -72,7 +72,7 @@ export function appendElement(
|
||||
export function updateElement(
|
||||
f: (element: Element) => void,
|
||||
collection: Element,
|
||||
idOrIndex: Identifier
|
||||
idOrIndex: Identifier,
|
||||
): number {
|
||||
const match = findElement(collection.children, idOrIndex);
|
||||
|
||||
|
@ -28,11 +28,11 @@ export interface RegistrationAPI<T extends Registration> {
|
||||
export interface DynamicRegistrationAPI<T> {
|
||||
addComponent: (
|
||||
component: SvelteComponent,
|
||||
add: (added: Element, parent: Element) => number
|
||||
add: (added: Element, parent: Element) => number,
|
||||
) => void;
|
||||
updateRegistration: (
|
||||
update: (registration: T) => void,
|
||||
position: Identifier
|
||||
position: Identifier,
|
||||
) => void;
|
||||
}
|
||||
|
||||
@ -41,14 +41,14 @@ export function nodeIsElement(node: Node): node is Element {
|
||||
}
|
||||
|
||||
export function makeInterface<T extends Registration>(
|
||||
makeRegistration: () => T
|
||||
makeRegistration: () => T,
|
||||
): RegistrationAPI<T> {
|
||||
const registrations: T[] = [];
|
||||
const items = writable(registrations);
|
||||
|
||||
function registerComponent(
|
||||
index: number = registrations.length,
|
||||
registration = makeRegistration()
|
||||
registration = makeRegistration(),
|
||||
): T {
|
||||
items.update((registrations) => {
|
||||
registrations.splice(index, 0, registration);
|
||||
@ -64,13 +64,13 @@ export function makeInterface<T extends Registration>(
|
||||
function getDynamicInterface(elementRef: HTMLElement): DynamicRegistrationAPI<T> {
|
||||
function addComponent(
|
||||
component: SvelteComponent,
|
||||
add: (added: Element, parent: Element) => number
|
||||
add: (added: Element, parent: Element) => number,
|
||||
): void {
|
||||
const registration = makeRegistration();
|
||||
|
||||
const callback = (
|
||||
mutations: MutationRecord[],
|
||||
observer: MutationObserver
|
||||
observer: MutationObserver,
|
||||
): void => {
|
||||
for (const mutation of mutations) {
|
||||
for (const addedNode of mutation.addedNodes) {
|
||||
@ -99,7 +99,7 @@ export function makeInterface<T extends Registration>(
|
||||
|
||||
function updateRegistration(
|
||||
update: (registration: T) => void,
|
||||
position: Identifier
|
||||
position: Identifier,
|
||||
): void {
|
||||
const match = findElement(elementRef.children, position);
|
||||
|
||||
|
@ -8,7 +8,7 @@ import * as tr from "../lib/ftl";
|
||||
|
||||
export async function getCongratsInfo(): Promise<Scheduler.CongratsInfoResponse> {
|
||||
return Scheduler.CongratsInfoResponse.decode(
|
||||
await postRequest("/_anki/congratsInfo", "")
|
||||
await postRequest("/_anki/congratsInfo", ""),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import { nightModeKey, touchDeviceKey, modalsKey } from "../components/context-k
|
||||
|
||||
export async function deckOptions(
|
||||
target: HTMLDivElement,
|
||||
deckId: number
|
||||
deckId: number,
|
||||
): Promise<DeckOptionsPage> {
|
||||
const [info] = await Promise.all([
|
||||
getDeckOptionsInfo(deckId),
|
||||
|
@ -94,7 +94,7 @@ const exampleData = {
|
||||
function startingState(): DeckOptionsState {
|
||||
return new DeckOptionsState(
|
||||
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<
|
||||
string,
|
||||
unknown
|
||||
>
|
||||
>,
|
||||
);
|
||||
expect(json).toStrictEqual([
|
||||
// other deck comes first
|
||||
|
@ -13,15 +13,15 @@ import { localeCompare } from "../lib/i18n";
|
||||
import type { DynamicSvelteComponent } from "../sveltelib/dynamicComponent";
|
||||
|
||||
export async function getDeckOptionsInfo(
|
||||
deckId: number
|
||||
deckId: number,
|
||||
): Promise<DeckConfig.DeckConfigsForUpdate> {
|
||||
return DeckConfig.DeckConfigsForUpdate.decode(
|
||||
await postRequest("/_anki/deckConfigsForUpdate", JSON.stringify({ deckId }))
|
||||
await postRequest("/_anki/deckConfigsForUpdate", JSON.stringify({ deckId })),
|
||||
);
|
||||
}
|
||||
|
||||
export async function saveDeckOptions(
|
||||
input: DeckConfig.UpdateDeckConfigsRequest
|
||||
input: DeckConfig.UpdateDeckConfigsRequest,
|
||||
): Promise<void> {
|
||||
const data: Uint8Array = DeckConfig.UpdateDeckConfigsRequest.encode(input).finish();
|
||||
await postRequest("/_anki/updateDeckConfigs", data);
|
||||
@ -84,7 +84,7 @@ export class DeckOptionsState {
|
||||
});
|
||||
this.selectedIdx = Math.max(
|
||||
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.haveAddons = data.haveAddons;
|
||||
@ -284,17 +284,17 @@ export class DeckOptionsState {
|
||||
|
||||
private getParentLimits(): ParentLimits {
|
||||
const parentConfigs = this.configs.filter((c) =>
|
||||
this.currentDeck.parentConfigIds.includes(c.config.id)
|
||||
this.currentDeck.parentConfigIds.includes(c.config.id),
|
||||
);
|
||||
const newCards = parentConfigs.reduce(
|
||||
(previous, current) =>
|
||||
Math.min(previous, current.config.config?.newPerDay ?? 0),
|
||||
2 ** 31
|
||||
2 ** 31,
|
||||
);
|
||||
const reviews = parentConfigs.reduce(
|
||||
(previous, current) =>
|
||||
Math.min(previous, current.config.config?.reviewsPerDay ?? 0),
|
||||
2 ** 31
|
||||
2 ** 31,
|
||||
);
|
||||
return {
|
||||
newCards,
|
||||
|
@ -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 mirror: (
|
||||
editable: HTMLElement,
|
||||
params: { store: Writable<DocumentFragment> }
|
||||
params: { store: Writable<DocumentFragment> },
|
||||
) => void;
|
||||
</script>
|
||||
|
||||
|
@ -39,7 +39,7 @@ export interface DecoratedElementConstructor
|
||||
}
|
||||
|
||||
export class CustomElementArray<
|
||||
T extends CustomElementConstructor & WithTagName
|
||||
T extends CustomElementConstructor & WithTagName,
|
||||
> extends Array<T> {
|
||||
push(...elements: T[]): number {
|
||||
for (const element of elements) {
|
||||
|
@ -17,7 +17,7 @@ import Mathjax_svelte from "./Mathjax.svelte";
|
||||
function moveNodeOutOfElement(
|
||||
element: Element,
|
||||
node: Node,
|
||||
placement: "beforebegin" | "afterend"
|
||||
placement: "beforebegin" | "afterend",
|
||||
): Node {
|
||||
element.removeChild(node);
|
||||
|
||||
@ -105,7 +105,7 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax
|
||||
return typeof block === "string" && block !== "false"
|
||||
? `\\[${text}\\]`
|
||||
: `\\(${text}\\)`;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -114,11 +114,12 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax
|
||||
.replace(
|
||||
mathjaxBlockDelimiterPattern,
|
||||
(_match: string, text: string) =>
|
||||
`<anki-mathjax block="true">${text}</anki-mathjax>`
|
||||
`<anki-mathjax block="true">${text}</anki-mathjax>`,
|
||||
)
|
||||
.replace(
|
||||
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();
|
||||
context.set(
|
||||
nightModeKey,
|
||||
document.documentElement.classList.contains("night-mode")
|
||||
document.documentElement.classList.contains("night-mode"),
|
||||
);
|
||||
|
||||
this.component = new Mathjax_svelte({
|
||||
|
@ -32,7 +32,7 @@ function getEmptyIcon(style: HTMLStyleElement): [string, string] {
|
||||
export function convertMathjax(
|
||||
input: string,
|
||||
nightMode: boolean,
|
||||
fontSize: number
|
||||
fontSize: number,
|
||||
): [string, string] {
|
||||
const style = getStyle(getCSS(nightMode, fontSize));
|
||||
|
||||
|
@ -50,7 +50,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
{},
|
||||
{
|
||||
editor: { get: () => codeMirror },
|
||||
}
|
||||
},
|
||||
) as CodeMirrorAPI;
|
||||
</script>
|
||||
|
||||
|
@ -43,7 +43,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingSetTextColor(),
|
||||
shortcutLabel
|
||||
shortcutLabel,
|
||||
)}
|
||||
{disabled}
|
||||
on:click={forecolorWrap}
|
||||
@ -60,7 +60,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingChangeColor(),
|
||||
shortcutLabel
|
||||
shortcutLabel,
|
||||
)}
|
||||
{disabled}
|
||||
widthMultiplier={0.5}
|
||||
|
@ -58,8 +58,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
direction: {
|
||||
get: () => $directionStore,
|
||||
},
|
||||
}
|
||||
) as EditorFieldAPI
|
||||
},
|
||||
) as EditorFieldAPI,
|
||||
);
|
||||
</script>
|
||||
|
||||
|
@ -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 {
|
||||
fieldSave.schedule(
|
||||
() => 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 },
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
@ -271,7 +271,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
on:focusout={() => {
|
||||
$currentField = null;
|
||||
bridgeCommand(
|
||||
`blur:${index}:${getNoteId()}:${get(fieldStores[index])}`
|
||||
`blur:${index}:${getNoteId()}:${get(fieldStores[index])}`,
|
||||
);
|
||||
}}
|
||||
--label-color={cols[index] === "dupe"
|
||||
|
@ -23,7 +23,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
}
|
||||
|
||||
onMount(() =>
|
||||
registerShortcut(toggle, keyCombination, editorField.element as HTMLElement)
|
||||
registerShortcut(toggle, keyCombination, editorField.element as HTMLElement),
|
||||
);
|
||||
</script>
|
||||
|
||||
|
@ -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 element of fragment.querySelectorAll(
|
||||
decorated.tagName
|
||||
decorated.tagName,
|
||||
) as NodeListOf<DecoratedElement>) {
|
||||
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) {
|
||||
richTextPromise.then((richText) =>
|
||||
wrapInternal(richText.getRootNode() as any, before, after, false)
|
||||
wrapInternal(richText.getRootNode() as any, before, after, false),
|
||||
);
|
||||
},
|
||||
preventResubscription,
|
||||
|
@ -30,7 +30,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
let tagTypes: TagType[];
|
||||
function tagsToTagTypes(tags: string[]): void {
|
||||
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(
|
||||
"/_anki/completeTag",
|
||||
Tags.CompleteTagRequest.encode(
|
||||
Tags.CompleteTagRequest.create({ input, matchLimit: 500 })
|
||||
).finish()
|
||||
Tags.CompleteTagRequest.create({ input, matchLimit: 500 }),
|
||||
).finish(),
|
||||
);
|
||||
const response = Tags.CompleteTagResponse.decode(data);
|
||||
return response.tags;
|
||||
@ -86,7 +86,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
(names: string[]): string[] => {
|
||||
autocompleteDisabled = names.length === 0;
|
||||
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(
|
||||
index: number,
|
||||
start: number,
|
||||
end: number
|
||||
end: number,
|
||||
): Promise<void> {
|
||||
if (autocomplete.hasSelected()) {
|
||||
autocomplete.chooseSelected();
|
||||
@ -334,7 +334,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
function deselect() {
|
||||
tagTypes = tagTypes.map(
|
||||
(tag: TagType): TagType => ({ ...tag, selected: false })
|
||||
(tag: TagType): TagType => ({ ...tag, selected: false }),
|
||||
);
|
||||
selectionAnchor = null;
|
||||
selectionFocus = null;
|
||||
|
@ -127,7 +127,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
event.preventDefault();
|
||||
name = `${before.slice(0, -1)}${delimChar}${name.slice(
|
||||
positionEnd,
|
||||
name.length
|
||||
name.length,
|
||||
)}`;
|
||||
|
||||
await tick();
|
||||
@ -199,7 +199,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
const selection = document.getSelection();
|
||||
event.clipboardData!.setData(
|
||||
"text/plain",
|
||||
replaceWithColons(selection!.toString())
|
||||
replaceWithColons(selection!.toString()),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingAttachPicturesaudiovideo(),
|
||||
shortcutLabel
|
||||
shortcutLabel,
|
||||
)}
|
||||
iconSize={70}
|
||||
{disabled}
|
||||
@ -85,7 +85,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
on:click={() =>
|
||||
$activeInput?.surround(
|
||||
"<anki-mathjax focusonmount>",
|
||||
"</anki-mathjax>"
|
||||
"</anki-mathjax>",
|
||||
)}
|
||||
on:mount={withButton(createShortcut)}
|
||||
>
|
||||
@ -103,7 +103,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
on:click={() =>
|
||||
$activeInput?.surround(
|
||||
'<anki-mathjax block="true" focusonmount>',
|
||||
"</anki-matjax>"
|
||||
"</anki-matjax>",
|
||||
)}
|
||||
on:mount={withButton(createShortcut)}
|
||||
>
|
||||
@ -121,7 +121,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
on:click={() =>
|
||||
$activeInput?.surround(
|
||||
"<anki-mathjax focusonmount>\\ce{",
|
||||
"}</anki-mathjax>"
|
||||
"}</anki-mathjax>",
|
||||
)}
|
||||
on:mount={withButton(createShortcut)}
|
||||
>
|
||||
|
@ -9,7 +9,7 @@ export function appendInParentheses(text: string, appendix: string): string {
|
||||
export function execCommand(
|
||||
command: string,
|
||||
showUI?: boolean | undefined,
|
||||
value?: string | undefined
|
||||
value?: string | undefined,
|
||||
): void {
|
||||
document.execCommand(command, showUI, value);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
const nth =
|
||||
Array.prototype.indexOf.call(
|
||||
(element.parentNode! as Document | ShadowRoot).children,
|
||||
element
|
||||
element,
|
||||
) + 1;
|
||||
return [`${tagName}:nth-child(${nth})`, ...tokens];
|
||||
} else {
|
||||
@ -46,7 +46,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
1;
|
||||
return createPathRecursive(
|
||||
[`${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(
|
||||
"height",
|
||||
height < maxHeight ? `${height}px` : "auto",
|
||||
"important"
|
||||
"important",
|
||||
);
|
||||
} else {
|
||||
// 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(
|
||||
"width",
|
||||
width < maxWidth ? `${width}px` : "auto",
|
||||
"important"
|
||||
"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);
|
||||
const index = sheet.insertRule(
|
||||
`${createPath(image)} {}`,
|
||||
sheet.cssRules.length
|
||||
sheet.cssRules.length,
|
||||
);
|
||||
const rule = sheet.cssRules[index] as CSSStyleRule;
|
||||
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 addedImages = mutations.flatMap((mutation) =>
|
||||
filterImages([...mutation.addedNodes])
|
||||
filterImages([...mutation.addedNodes]),
|
||||
);
|
||||
|
||||
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) =>
|
||||
filterImages([...mutation.removedNodes])
|
||||
filterImages([...mutation.removedNodes]),
|
||||
);
|
||||
|
||||
for (const image of removedImages) {
|
||||
|
@ -15,7 +15,7 @@ export const $editorToolbar = new Promise(noop);
|
||||
export function pasteHTML(
|
||||
html: string,
|
||||
internal: boolean,
|
||||
extendedMode: boolean
|
||||
extendedMode: boolean,
|
||||
): void {
|
||||
html = filterHTML(html, internal, extendedMode);
|
||||
|
||||
@ -76,7 +76,7 @@ function setupNoteEditor(i18n: Promise<void>): Promise<OldEditorAdapter> {
|
||||
|
||||
context.set(
|
||||
nightModeKey,
|
||||
document.documentElement.classList.contains("night-mode")
|
||||
document.documentElement.classList.contains("night-mode"),
|
||||
);
|
||||
|
||||
i18n.then(() => {
|
||||
|
@ -40,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
addedData,
|
||||
graphRange,
|
||||
dispatch,
|
||||
$browserLinksSupported
|
||||
$browserLinksSupported,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
targetYear,
|
||||
nightMode,
|
||||
revlogRange,
|
||||
calendarFirstDayOfWeek.set
|
||||
calendarFirstDayOfWeek.set,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
[histogramData, tableData] = prepareData(
|
||||
gatherData(sourceData),
|
||||
dispatch,
|
||||
$browserLinksSupported
|
||||
$browserLinksSupported,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
graphRange,
|
||||
$futureDueShowBacklog,
|
||||
dispatch,
|
||||
$browserLinksSupported
|
||||
$browserLinksSupported,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
intervalData,
|
||||
range,
|
||||
dispatch,
|
||||
$browserLinksSupported
|
||||
$browserLinksSupported,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
bounds,
|
||||
graphData,
|
||||
graphRange,
|
||||
showTime
|
||||
showTime,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -20,25 +20,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
async function getGraphData(
|
||||
search: string,
|
||||
days: number
|
||||
days: number,
|
||||
): Promise<Stats.GraphsResponse> {
|
||||
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> {
|
||||
return Stats.GraphPreferences.decode(
|
||||
await postRequest("/_anki/graphPreferences", JSON.stringify({}))
|
||||
await postRequest("/_anki/graphPreferences", JSON.stringify({})),
|
||||
);
|
||||
}
|
||||
|
||||
async function setGraphPreferences(
|
||||
prefs: PreferencePayload<Stats.GraphPreferences>
|
||||
prefs: PreferencePayload<Stats.GraphPreferences>,
|
||||
): Promise<void> {
|
||||
await postRequest(
|
||||
"/_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,
|
||||
Stats.GraphPreferences.toObject.bind(Stats.GraphPreferences) as (
|
||||
preferences: Stats.GraphPreferences,
|
||||
options: { defaults: boolean }
|
||||
) => PreferenceRaw<Stats.GraphPreferences>
|
||||
)
|
||||
options: { defaults: boolean },
|
||||
) => PreferenceRaw<Stats.GraphPreferences>,
|
||||
),
|
||||
);
|
||||
|
||||
$: revlogRange = daysToRevlogRange($days);
|
||||
|
@ -51,7 +51,7 @@ export function buildHistogram(
|
||||
data: GraphData,
|
||||
range: GraphRange,
|
||||
dispatch: SearchDispatch,
|
||||
browserLinksSupported: boolean
|
||||
browserLinksSupported: boolean,
|
||||
): [HistogramData | null, TableDatum[]] {
|
||||
// get min/max
|
||||
const total = data.daysAdded.length;
|
||||
@ -91,7 +91,7 @@ export function buildHistogram(
|
||||
|
||||
const adjustedRange = scaleLinear().range([0.7, 0.3]);
|
||||
const colourScale = scaleSequential((n) =>
|
||||
interpolateBlues(adjustedRange(n)!)
|
||||
interpolateBlues(adjustedRange(n)!),
|
||||
).domain([xMax!, xMin!]);
|
||||
|
||||
const totalInPeriod = sum(bins, (bin) => bin.length);
|
||||
@ -111,7 +111,7 @@ export function buildHistogram(
|
||||
function hoverText(
|
||||
bin: Bin<number, number>,
|
||||
cumulative: number,
|
||||
_percent: number
|
||||
_percent: number,
|
||||
): string {
|
||||
const day = dayLabel(bin.x0!, bin.x1!);
|
||||
const cards = tr.statisticsCards({ cards: bin.length });
|
||||
|
@ -97,7 +97,7 @@ export function renderButtons(
|
||||
svgElem: SVGElement,
|
||||
bounds: GraphBounds,
|
||||
origData: Stats.GraphsResponse,
|
||||
range: GraphRange
|
||||
range: GraphRange,
|
||||
): void {
|
||||
const sourceData = gatherData(origData, range);
|
||||
const data = [
|
||||
@ -129,7 +129,7 @@ export function renderButtons(
|
||||
const total = sum(groupData, (d) => d.count);
|
||||
const correct = sum(
|
||||
groupData.filter((d) => d.buttonNum > 1),
|
||||
(d) => d.count
|
||||
(d) => d.count,
|
||||
);
|
||||
const percent = total ? ((correct / total) * 100).toFixed(2) : "0";
|
||||
return { total, correct, percent };
|
||||
@ -170,8 +170,8 @@ export function renderButtons(
|
||||
}
|
||||
return `${kind} \u200e(${totalCorrect(d).percent}%)`;
|
||||
}) as any)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -193,8 +193,8 @@ export function renderButtons(
|
||||
selection.transition(trans).call(
|
||||
axisLeft(y)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -207,7 +207,7 @@ export function renderButtons(
|
||||
.transition(trans)
|
||||
.attr(
|
||||
"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("height", (d: Datum) => y(0)! - y(d.count)!)
|
||||
@ -225,7 +225,7 @@ export function renderButtons(
|
||||
.attr(
|
||||
"x",
|
||||
(d: Datum) =>
|
||||
xGroup(d.group)! + xButton(d.buttonNum.toString())!
|
||||
xGroup(d.group)! + xButton(d.buttonNum.toString())!,
|
||||
)
|
||||
.attr("y", y(0)!)
|
||||
.attr("height", 0)
|
||||
@ -233,8 +233,8 @@ export function renderButtons(
|
||||
(update) => update.call(updateBar),
|
||||
(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
|
||||
|
@ -54,7 +54,7 @@ const Weekday = Stats.GraphPreferences.Weekday; /* enum */
|
||||
|
||||
export function gatherData(
|
||||
data: Stats.GraphsResponse,
|
||||
firstDayOfWeek: WeekdayType
|
||||
firstDayOfWeek: WeekdayType,
|
||||
): GraphData {
|
||||
const reviewCount = new Map<number, number>();
|
||||
|
||||
@ -63,7 +63,7 @@ export function gatherData(
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
reviewCount.set(day, count + 1);
|
||||
@ -86,7 +86,7 @@ export function renderCalendar(
|
||||
targetYear: number,
|
||||
nightMode: boolean,
|
||||
revlogRange: RevlogRange,
|
||||
setFirstDayOfWeek: (d: number) => void
|
||||
setFirstDayOfWeek: (d: number) => void,
|
||||
): void {
|
||||
const svg = select(svgElem);
|
||||
const now = new Date();
|
||||
@ -187,8 +187,8 @@ export function renderCalendar(
|
||||
.on("click", null)
|
||||
.filter((d: number) =>
|
||||
[Weekday.SUNDAY, Weekday.MONDAY, Weekday.FRIDAY, Weekday.SATURDAY].includes(
|
||||
d
|
||||
)
|
||||
d,
|
||||
),
|
||||
)
|
||||
.on("click", (_event: MouseEvent, d: number) => setFirstDayOfWeek(d));
|
||||
|
||||
|
@ -124,7 +124,7 @@ function countCards(cards: Cards.ICard[], separateInactive: boolean): Count[] {
|
||||
|
||||
export function gatherData(
|
||||
data: Stats.GraphsResponse,
|
||||
separateInactive: boolean
|
||||
separateInactive: boolean,
|
||||
): GraphData {
|
||||
const totalCards = data.cards.length;
|
||||
const counts = countCards(data.cards, separateInactive);
|
||||
@ -158,7 +158,7 @@ export interface TableDatum {
|
||||
export function renderCards(
|
||||
svgElem: SVGElement,
|
||||
bounds: GraphBounds,
|
||||
sourceData: GraphData
|
||||
sourceData: GraphData,
|
||||
): TableDatum[] {
|
||||
const summed = cumsum(sourceData.counts, (d: Count) => d[1]);
|
||||
const data = Array.from(summed).map((n, idx) => {
|
||||
@ -200,12 +200,12 @@ export function renderCards(
|
||||
d.transition(trans).attrTween("d", (d) => {
|
||||
const interpolator = interpolate(
|
||||
{ startAngle: 0, endAngle: 0 },
|
||||
d
|
||||
d,
|
||||
);
|
||||
return (t): string => arcGen(interpolator(t) as any) as string;
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
x.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
|
||||
|
@ -46,7 +46,7 @@ function makeQuery(start: number, end: number): string {
|
||||
function getAdjustedScaleAndTicks(
|
||||
min: number,
|
||||
max: number,
|
||||
desiredBars: number
|
||||
desiredBars: number,
|
||||
): [ScaleLinear<number, number, never>, number[]] {
|
||||
const prescale = scaleLinear().domain([min, max]).nice();
|
||||
const ticks = prescale.ticks(desiredBars);
|
||||
@ -70,7 +70,7 @@ function getAdjustedScaleAndTicks(
|
||||
export function prepareData(
|
||||
data: GraphData,
|
||||
dispatch: SearchDispatch,
|
||||
browserLinksSupported: boolean
|
||||
browserLinksSupported: boolean,
|
||||
): [HistogramData | null, TableDatum[]] {
|
||||
// get min/max
|
||||
const allEases = data.eases;
|
||||
|
@ -66,7 +66,7 @@ export function gatherData(data: Stats.GraphsResponse): GraphData {
|
||||
const dueCounts = rollup(
|
||||
due,
|
||||
(v) => v.length,
|
||||
(d) => d
|
||||
(d) => d,
|
||||
);
|
||||
return { dueCounts, haveBacklog };
|
||||
}
|
||||
@ -95,7 +95,7 @@ export function buildHistogram(
|
||||
range: GraphRange,
|
||||
backlog: boolean,
|
||||
dispatch: SearchDispatch,
|
||||
browserLinksSupported: boolean
|
||||
browserLinksSupported: boolean,
|
||||
): FutureDueResponse {
|
||||
const output = { histogramData: null, tableData: [] };
|
||||
// get min/max
|
||||
@ -143,7 +143,7 @@ export function buildHistogram(
|
||||
|
||||
const adjustedRange = scaleLinear().range([0.7, 0.3]);
|
||||
const colourScale = scaleSequential((n) =>
|
||||
interpolateGreens(adjustedRange(n)!)
|
||||
interpolateGreens(adjustedRange(n)!),
|
||||
).domain([xMin!, xMax!]);
|
||||
|
||||
const total = sum(bins as any, binValue);
|
||||
@ -151,7 +151,7 @@ export function buildHistogram(
|
||||
function hoverText(
|
||||
bin: Bin<number, number>,
|
||||
cumulative: number,
|
||||
_percent: number
|
||||
_percent: number,
|
||||
): string {
|
||||
const days = dayLabel(bin.x0!, bin.x1!);
|
||||
const cards = tr.statisticsCardsDue({
|
||||
|
@ -56,7 +56,7 @@ export function defaultGraphBounds(): GraphBounds {
|
||||
|
||||
export function setDataAvailable(
|
||||
svg: Selection<SVGElement, any, any, any>,
|
||||
available: boolean
|
||||
available: boolean,
|
||||
): void {
|
||||
svg.select(".no-data")
|
||||
.attr("pointer-events", available ? "none" : "all")
|
||||
@ -67,7 +67,7 @@ export function setDataAvailable(
|
||||
|
||||
export function millisecondCutoffForRange(
|
||||
range: GraphRange,
|
||||
nextDayAtSecs: number
|
||||
nextDayAtSecs: number,
|
||||
): number {
|
||||
let days;
|
||||
switch (range) {
|
||||
@ -96,5 +96,5 @@ export interface TableDatum {
|
||||
export type SearchEventMap = { search: { query: string } };
|
||||
export type SearchDispatch = <EventKey extends Extract<keyof SearchEventMap, string>>(
|
||||
type: EventKey,
|
||||
detail: SearchEventMap[EventKey]
|
||||
detail: SearchEventMap[EventKey],
|
||||
) => void;
|
||||
|
@ -27,7 +27,7 @@
|
||||
],
|
||||
{
|
||||
controller: anki.RangeBox,
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
|
@ -31,7 +31,7 @@ export interface HistogramData {
|
||||
hoverText: (
|
||||
bin: Bin<number, number>,
|
||||
cumulative: number,
|
||||
percent: number
|
||||
percent: number,
|
||||
) => string;
|
||||
onClick: ((data: Bin<number, number>) => void) | null;
|
||||
showArea: boolean;
|
||||
@ -43,7 +43,7 @@ export interface HistogramData {
|
||||
export function histogramGraph(
|
||||
svgElem: SVGElement,
|
||||
bounds: GraphBounds,
|
||||
data: HistogramData | null
|
||||
data: HistogramData | null,
|
||||
): void {
|
||||
const svg = select(svgElem);
|
||||
const trans = svg.transition().duration(600) as any;
|
||||
@ -64,8 +64,8 @@ export function histogramGraph(
|
||||
axisBottom(x)
|
||||
.ticks(7)
|
||||
.tickSizeOuter(0)
|
||||
.tickFormat((data.xTickFormat ?? null) as any)
|
||||
)
|
||||
.tickFormat((data.xTickFormat ?? null) as any),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -81,8 +81,8 @@ export function histogramGraph(
|
||||
selection.transition(trans).call(
|
||||
axisLeft(y)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -118,8 +118,8 @@ export function histogramGraph(
|
||||
(update) => update.call(updateBar),
|
||||
(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
|
||||
@ -135,8 +135,8 @@ export function histogramGraph(
|
||||
selection.transition(trans).call(
|
||||
axisRight(yAreaScale)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -154,12 +154,12 @@ export function histogramGraph(
|
||||
}
|
||||
})
|
||||
.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(
|
||||
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]]
|
||||
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]],
|
||||
);
|
||||
|
||||
// hover/tooltip
|
||||
|
@ -60,7 +60,7 @@ function gatherData(data: Stats.GraphsResponse, range: GraphRange): Hour[] {
|
||||
}
|
||||
|
||||
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;
|
||||
if (review.buttonChosen != 1) {
|
||||
@ -75,7 +75,7 @@ export function renderHours(
|
||||
svgElem: SVGElement,
|
||||
bounds: GraphBounds,
|
||||
origData: Stats.GraphsResponse,
|
||||
range: GraphRange
|
||||
range: GraphRange,
|
||||
): void {
|
||||
const data = gatherData(origData, range);
|
||||
|
||||
@ -97,7 +97,7 @@ export function renderHours(
|
||||
.paddingInner(0.1);
|
||||
svg.select<SVGGElement>(".x-ticks")
|
||||
.call((selection) =>
|
||||
selection.transition(trans).call(axisBottom(x).tickSizeOuter(0))
|
||||
selection.transition(trans).call(axisBottom(x).tickSizeOuter(0)),
|
||||
)
|
||||
.selectAll(".tick")
|
||||
.selectAll("text")
|
||||
@ -121,8 +121,8 @@ export function renderHours(
|
||||
selection.transition(trans).call(
|
||||
axisLeft(y)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -156,8 +156,8 @@ export function renderHours(
|
||||
(update) => update.call(updateBar),
|
||||
(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")
|
||||
@ -166,8 +166,8 @@ export function renderHours(
|
||||
axisRight(yArea)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickFormat((n: any) => `${Math.round(n * 100)}%`)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -185,7 +185,7 @@ export function renderHours(
|
||||
.y1((d: Hour) => {
|
||||
const correctRatio = d.correctCount! / d.totalCount!;
|
||||
return yArea(isNaN(correctRatio) ? 0 : correctRatio)!;
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
function tooltipText(d: Hour): string {
|
||||
|
@ -29,7 +29,7 @@ export function graphs(
|
||||
search = "deck:current",
|
||||
days = 365,
|
||||
controller = null as SvelteComponent | null,
|
||||
} = {}
|
||||
} = {},
|
||||
): void {
|
||||
const nightMode = checkNightMode();
|
||||
|
||||
|
@ -46,7 +46,7 @@ export function gatherIntervalData(data: Stats.GraphsResponse): IntervalGraphDat
|
||||
export function intervalLabel(
|
||||
daysStart: number,
|
||||
daysEnd: number,
|
||||
cards: number
|
||||
cards: number,
|
||||
): string {
|
||||
if (daysEnd - daysStart <= 1) {
|
||||
// singular
|
||||
@ -79,7 +79,7 @@ export function prepareIntervalData(
|
||||
data: IntervalGraphData,
|
||||
range: IntervalRange,
|
||||
dispatch: SearchDispatch,
|
||||
browserLinksSupported: boolean
|
||||
browserLinksSupported: boolean,
|
||||
): [HistogramData | null, TableDatum[]] {
|
||||
// get min/max
|
||||
const allIntervals = data.intervals;
|
||||
@ -122,7 +122,7 @@ export function prepareIntervalData(
|
||||
|
||||
const prescale = scaleLinear().domain([xMin!, xMax!]);
|
||||
const scale = scaleLinear().domain(
|
||||
(niceNecessary ? prescale.nice() : prescale).domain().map(increment)
|
||||
(niceNecessary ? prescale.nice() : prescale).domain().map(increment),
|
||||
);
|
||||
|
||||
const bins = histogram()
|
||||
@ -137,13 +137,13 @@ export function prepareIntervalData(
|
||||
|
||||
const adjustedRange = scaleLinear().range([0.7, 0.3]);
|
||||
const colourScale = scaleSequential((n) =>
|
||||
interpolateBlues(adjustedRange(n)!)
|
||||
interpolateBlues(adjustedRange(n)!),
|
||||
).domain([xMax!, xMin!]);
|
||||
|
||||
function hoverText(
|
||||
bin: Bin<number, number>,
|
||||
_cumulative: number,
|
||||
percent: number
|
||||
percent: number,
|
||||
): string {
|
||||
// const day = dayLabel(bin.x0!, bin.x1!);
|
||||
const interval = intervalLabel(bin.x0!, bin.x1!, bin.length);
|
||||
|
@ -65,7 +65,7 @@ export function gatherData(data: Stats.GraphsResponse): GraphData {
|
||||
continue;
|
||||
}
|
||||
const day = Math.ceil(
|
||||
((review.id as number) / 1000 - data.nextDayAtSecs) / 86400
|
||||
((review.id as number) / 1000 - data.nextDayAtSecs) / 86400,
|
||||
);
|
||||
const countEntry =
|
||||
reviewCount.get(day) ?? reviewCount.set(day, { ...empty }).get(day)!;
|
||||
@ -131,7 +131,7 @@ export function renderReviews(
|
||||
bounds: GraphBounds,
|
||||
sourceData: GraphData,
|
||||
range: GraphRange,
|
||||
showTime: boolean
|
||||
showTime: boolean,
|
||||
): TableDatum[] {
|
||||
const svg = select(svgElem);
|
||||
const trans = svg.transition().duration(600) as any;
|
||||
@ -178,7 +178,7 @@ export function renderReviews(
|
||||
x.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
|
||||
svg.select<SVGGElement>(".x-ticks")
|
||||
.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");
|
||||
|
||||
@ -207,8 +207,8 @@ export function renderReviews(
|
||||
axisLeft(y)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickSizeOuter(0)
|
||||
.tickFormat(yTickFormat as any)
|
||||
)
|
||||
.tickFormat(yTickFormat as any),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -222,19 +222,19 @@ export function renderReviews(
|
||||
const cappedRange = scaleLinear().range([0.3, 0.5]);
|
||||
const shiftedRange = scaleLinear().range([0.4, 0.7]);
|
||||
const darkerGreens = scaleSequential((n) =>
|
||||
interpolateGreens(shiftedRange(n)!)
|
||||
interpolateGreens(shiftedRange(n)!),
|
||||
).domain(x.domain() as any);
|
||||
const lighterGreens = scaleSequential((n) =>
|
||||
interpolateGreens(cappedRange(n)!)
|
||||
interpolateGreens(cappedRange(n)!),
|
||||
).domain(x.domain() as any);
|
||||
const reds = scaleSequential((n) => interpolateReds(cappedRange(n)!)).domain(
|
||||
x.domain() as any
|
||||
x.domain() as any,
|
||||
);
|
||||
const oranges = scaleSequential((n) => interpolateOranges(cappedRange(n)!)).domain(
|
||||
x.domain() as any
|
||||
x.domain() as any,
|
||||
);
|
||||
const purples = scaleSequential((n) => interpolatePurples(cappedRange(n)!)).domain(
|
||||
x.domain() as any
|
||||
x.domain() as any,
|
||||
);
|
||||
|
||||
function binColor(idx: BinIndex): ScaleSequential<string> {
|
||||
@ -317,8 +317,8 @@ export function renderReviews(
|
||||
(update) => update.call((d) => updateBar(d, barNum)),
|
||||
(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)
|
||||
.ticks(bounds.height / 50)
|
||||
.tickFormat(yTickFormat as any)
|
||||
.tickSizeOuter(0)
|
||||
)
|
||||
.tickSizeOuter(0),
|
||||
),
|
||||
)
|
||||
.attr("direction", "ltr");
|
||||
|
||||
@ -356,12 +356,12 @@ export function renderReviews(
|
||||
}
|
||||
})
|
||||
.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(
|
||||
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]]
|
||||
(bin: Bin<number, number>, index: number) => [bin, areaData[index + 1]],
|
||||
);
|
||||
|
||||
// hover/tooltip
|
||||
|
@ -74,7 +74,7 @@ export function gatherData(data: Stats.GraphsResponse): TodayData {
|
||||
const againCount = answerCount - correctCount;
|
||||
let againCountText = tr.statisticsTodayAgainCount();
|
||||
againCountText += ` ${againCount} (${((againCount / answerCount) * 100).toFixed(
|
||||
2
|
||||
2,
|
||||
)}%)`;
|
||||
const typeCounts = tr.statisticsTodayTypeCounts({
|
||||
learnCount,
|
||||
|
@ -17,7 +17,7 @@ type FilterMethod = (element: Element) => void;
|
||||
|
||||
function filterAttributes(
|
||||
attributePredicate: (attributeName: string) => boolean,
|
||||
element: Element
|
||||
element: Element,
|
||||
): void {
|
||||
for (const attr of [...element.attributes]) {
|
||||
const attrName = attr.name.toUpperCase();
|
||||
@ -37,7 +37,7 @@ const allow =
|
||||
(element: Element): void =>
|
||||
filterAttributes(
|
||||
(attributeName: string) => attrs.includes(attributeName),
|
||||
element
|
||||
element,
|
||||
);
|
||||
|
||||
function unwrapElement(element: Element): void {
|
||||
|
@ -7,7 +7,7 @@ export function removeNode(element: Node): void {
|
||||
|
||||
function iterateElement(
|
||||
filter: (node: Node) => void,
|
||||
fragment: DocumentFragment | Element
|
||||
fragment: DocumentFragment | Element,
|
||||
): void {
|
||||
for (const child of [...fragment.childNodes]) {
|
||||
filter(child);
|
||||
|
@ -51,9 +51,9 @@ const filterStyling =
|
||||
};
|
||||
|
||||
export const filterStylingNightMode = filterStyling(
|
||||
allowPropertiesBlockValues(stylingNightMode)
|
||||
allowPropertiesBlockValues(stylingNightMode),
|
||||
);
|
||||
export const filterStylingLightMode = filterStyling(
|
||||
allowPropertiesBlockValues(stylingLightMode)
|
||||
allowPropertiesBlockValues(stylingLightMode),
|
||||
);
|
||||
export const filterStylingInternal = filterStyling(blockProperties(stylingInternal));
|
||||
|
@ -106,7 +106,7 @@ const isListItem = (element: Element): element is HTMLLIElement =>
|
||||
const isParagraph = (element: Element): element is HTMLParamElement =>
|
||||
element.tagName === "P";
|
||||
const isBlockElement = (
|
||||
element: Element
|
||||
element: Element,
|
||||
): element is HTMLLIElement & HTMLParamElement =>
|
||||
isListItem(element) || isParagraph(element);
|
||||
|
||||
|
@ -21,19 +21,19 @@ function toFluentNumber(num: number): FluentNumber {
|
||||
}
|
||||
|
||||
function formatArgs(
|
||||
args: Record<string, FluentVariable>
|
||||
args: Record<string, FluentVariable>,
|
||||
): Record<string, FluentVariable> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(args).map(([key, value]) => [
|
||||
key,
|
||||
typeof value === "number" ? toFluentNumber(value) : value,
|
||||
])
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
export function getMessage(
|
||||
key: string,
|
||||
args: Record<string, FluentVariable> = {}
|
||||
args: Record<string, FluentVariable> = {},
|
||||
): string | null {
|
||||
for (const bundle of bundles) {
|
||||
const msg = bundle.getMessage(key);
|
||||
|
@ -43,7 +43,7 @@ let langs: string[] = [];
|
||||
|
||||
export function toLocaleString(
|
||||
date: Date,
|
||||
options?: Intl.DateTimeFormatOptions
|
||||
options?: Intl.DateTimeFormatOptions,
|
||||
): string {
|
||||
return date.toLocaleDateString(langs, options);
|
||||
}
|
||||
@ -51,7 +51,7 @@ export function toLocaleString(
|
||||
export function localeCompare(
|
||||
first: string,
|
||||
second: string,
|
||||
options?: Intl.CollatorOptions
|
||||
options?: Intl.CollatorOptions,
|
||||
): number {
|
||||
return first.localeCompare(second, langs, options);
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ export const checkModifiers =
|
||||
(
|
||||
matches: boolean,
|
||||
currentModifier: Modifier,
|
||||
currentIndex: number
|
||||
currentIndex: number,
|
||||
): boolean =>
|
||||
matches &&
|
||||
(optional.includes(currentModifier as Modifier) ||
|
||||
event.getModifierState(platformModifiers[currentIndex]) ===
|
||||
required.includes(currentModifier)),
|
||||
true
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
export async function postRequest(
|
||||
path: string,
|
||||
body: string | Uint8Array,
|
||||
headers: Record<string, string> = {}
|
||||
headers: Record<string, string> = {},
|
||||
): Promise<Uint8Array> {
|
||||
if (body instanceof Uint8Array) {
|
||||
headers["Content-type"] = "application/octet-stream";
|
||||
|
@ -21,7 +21,7 @@ export function unwrapOptionalNumber(
|
||||
| Generic.OptionalInt32
|
||||
| Generic.OptionalUInt32
|
||||
| null
|
||||
| undefined
|
||||
| undefined,
|
||||
): number | undefined {
|
||||
if (msg && msg !== null) {
|
||||
if (msg.val !== null) {
|
||||
|
@ -8,7 +8,7 @@ const prohibit = () => false;
|
||||
export function registerPackage(
|
||||
name: string,
|
||||
entries: Record<string, unknown>,
|
||||
deprecation?: Record<string, string>
|
||||
deprecation?: Record<string, string>,
|
||||
): void {
|
||||
const pack = deprecation
|
||||
? new Proxy(entries, {
|
||||
@ -36,7 +36,7 @@ function hasPackages(...names: string[]): boolean {
|
||||
const libraries = listPackages();
|
||||
return names.reduce(
|
||||
(accu: boolean, name: string) => accu && libraries.includes(name),
|
||||
true
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@ -53,5 +53,5 @@ registerPackage(
|
||||
},
|
||||
{
|
||||
[immediatelyDeprecated.name]: "Do not use this function",
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -47,7 +47,7 @@ function splitKeyCombinationString(keyCombinationString: string): string[][] {
|
||||
function toPlatformString(keyCombination: string[]): string {
|
||||
return (
|
||||
modifiersToPlatformString(
|
||||
keyCombination.slice(0, -1).filter(isRequiredModifier)
|
||||
keyCombination.slice(0, -1).filter(isRequiredModifier),
|
||||
) + keyToPlatformString(keyCombination[keyCombination.length - 1])
|
||||
);
|
||||
}
|
||||
@ -80,11 +80,11 @@ function removeTrailing(modifier: string): string {
|
||||
|
||||
// function checkModifiers(event: KeyboardEvent, modifiers: string[]): boolean {
|
||||
function separateRequiredOptionalModifiers(
|
||||
modifiers: string[]
|
||||
modifiers: string[],
|
||||
): [Modifier[], Modifier[]] {
|
||||
const [requiredModifiers, otherModifiers] = partition(
|
||||
isRequiredModifier,
|
||||
modifiers
|
||||
modifiers,
|
||||
);
|
||||
|
||||
const optionalModifiers = otherModifiers.map(removeTrailing);
|
||||
@ -104,7 +104,7 @@ function keyToCode(key: string): number {
|
||||
}
|
||||
|
||||
function keyCombinationToCheck(
|
||||
keyCombination: string[]
|
||||
keyCombination: string[],
|
||||
): (event: KeyboardEvent) => boolean {
|
||||
const keyCode = keyToCode(keyCombination[keyCombination.length - 1]);
|
||||
const modifiers = keyCombination.slice(0, -1);
|
||||
@ -147,7 +147,7 @@ function innerShortcut(
|
||||
export function registerShortcut(
|
||||
callback: (event: KeyboardEvent) => void,
|
||||
keyCombinationString: string,
|
||||
target: EventTarget | Document = document
|
||||
target: EventTarget | Document = document,
|
||||
): () => void {
|
||||
const [check, ...restChecks] =
|
||||
splitKeyCombinationString(keyCombinationString).map(keyCombinationToCheck);
|
||||
|
@ -107,7 +107,7 @@ export function studiedToday(cards: number, secs: number): string {
|
||||
|
||||
function i18nFuncForUnit(
|
||||
unit: TimespanUnit,
|
||||
short: boolean
|
||||
short: boolean,
|
||||
): ({ amount: number }) => string {
|
||||
if (short) {
|
||||
switch (unit) {
|
||||
|
@ -22,7 +22,7 @@ export function wrapInternal(
|
||||
root: DocumentOrShadowRoot,
|
||||
front: string,
|
||||
back: string,
|
||||
plainText: boolean
|
||||
plainText: boolean,
|
||||
): void {
|
||||
const selection = root.getSelection()!;
|
||||
const range = selection.getRangeAt(0);
|
||||
@ -41,7 +41,7 @@ export function wrapInternal(
|
||||
if (
|
||||
!span.innerHTML &&
|
||||
/* ugly solution: treat <anki-mathjax> differently than other wraps */ !front.includes(
|
||||
"<anki-mathjax"
|
||||
"<anki-mathjax",
|
||||
)
|
||||
) {
|
||||
moveCursorPastPostfix(selection, back);
|
||||
|
@ -6,13 +6,13 @@ import { postRequest } from "../lib/postrequest";
|
||||
|
||||
async function getNextStates(): Promise<Scheduler.NextCardStates> {
|
||||
return Scheduler.NextCardStates.decode(
|
||||
await postRequest("/_anki/nextCardStates", "")
|
||||
await postRequest("/_anki/nextCardStates", ""),
|
||||
);
|
||||
}
|
||||
|
||||
async function setNextStates(
|
||||
key: string,
|
||||
states: Scheduler.NextCardStates
|
||||
states: Scheduler.NextCardStates,
|
||||
): Promise<void> {
|
||||
const data: Uint8Array = Scheduler.NextCardStates.encode(states).finish();
|
||||
await postRequest("/_anki/setNextCardStates", data, { key });
|
||||
@ -20,7 +20,7 @@ async function setNextStates(
|
||||
|
||||
export async function mutateNextCardStates(
|
||||
key: string,
|
||||
mutator: (states: Scheduler.NextCardStates) => void
|
||||
mutator: (states: Scheduler.NextCardStates) => void,
|
||||
): Promise<void> {
|
||||
const states = await getNextStates();
|
||||
mutator(states);
|
||||
|
@ -11,7 +11,7 @@ function injectPreloadLink(href: string, as: string): void {
|
||||
|
||||
export function allImagesLoaded(): Promise<void[]> {
|
||||
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;
|
||||
const fragment = tmpl.content;
|
||||
const srcs = [...fragment.querySelectorAll("img[src]")].map(
|
||||
(img) => (img as HTMLImageElement).src
|
||||
(img) => (img as HTMLImageElement).src,
|
||||
);
|
||||
return srcs;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ export function getTypedAnswer(): string | null {
|
||||
}
|
||||
|
||||
function _runHook(
|
||||
hooks: Array<Callback>
|
||||
hooks: Array<Callback>,
|
||||
): Promise<PromiseSettledResult<void | Promise<void>>[]> {
|
||||
const promises: (Promise<void> | void)[] = [];
|
||||
|
||||
@ -90,7 +90,7 @@ const renderError =
|
||||
}
|
||||
return `<div>Invalid ${type} on card: ${errorMessage}\n${errorStack}</div>`.replace(
|
||||
/\n/g,
|
||||
"<br>"
|
||||
"<br>",
|
||||
);
|
||||
};
|
||||
|
||||
@ -98,7 +98,7 @@ export async function _updateQA(
|
||||
html: string,
|
||||
_unusused: unknown,
|
||||
onupdate: Callback,
|
||||
onshown: Callback
|
||||
onshown: Callback,
|
||||
): Promise<void> {
|
||||
onUpdateHook.length = 0;
|
||||
onUpdateHook.push(onupdate);
|
||||
@ -152,8 +152,8 @@ export function _showQuestion(q: string, a: string, bodyclass: string): void {
|
||||
}
|
||||
// preload images
|
||||
allImagesLoaded().then(() => preloadAnswerImages(q, a));
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -177,8 +177,8 @@ export function _showAnswer(a: string, bodyclass: string): void {
|
||||
},
|
||||
function () {
|
||||
/* noop */
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ function formatText(text: string): string {
|
||||
for (const keyword of ["type", "fields"]) {
|
||||
newText = newText.replace(
|
||||
new RegExp(`\\b${keyword.toUpperCase()}\\b`, "g"),
|
||||
keyword
|
||||
keyword,
|
||||
);
|
||||
}
|
||||
return newText;
|
||||
|
@ -9,6 +9,6 @@
|
||||
// ensure node can run the resulting code
|
||||
"noEmitHelpers": false,
|
||||
"importHelpers": false,
|
||||
"module": "commonjs",
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ const languageServiceHost: ts.LanguageServiceHost = {
|
||||
},
|
||||
getLength: () => text.length,
|
||||
getChangeRange: (
|
||||
_oldSnapshot: ts.IScriptSnapshot
|
||||
_oldSnapshot: ts.IScriptSnapshot,
|
||||
): ts.TextChangeRange | undefined => {
|
||||
return undefined;
|
||||
},
|
||||
@ -140,7 +140,7 @@ function readFile(file) {
|
||||
async function compileSingleSvelte(
|
||||
input: SvelteInput,
|
||||
binDir: string,
|
||||
genDir: string
|
||||
genDir: string,
|
||||
): Promise<void> {
|
||||
const preprocessOptions = preprocess({
|
||||
scss: {
|
||||
@ -215,7 +215,7 @@ async function extractArgsAndData(args: string[]): Promise<Args> {
|
||||
}
|
||||
|
||||
async function extractSvelteAndDeps(
|
||||
files: string[]
|
||||
files: string[],
|
||||
): Promise<[SvelteInput[], InputFile[]]> {
|
||||
const svelte: SvelteInput[] = [];
|
||||
const deps: InputFile[] = [];
|
||||
@ -249,7 +249,7 @@ function remapBinToSrcDir(file: string): string {
|
||||
async function compileSvelte(
|
||||
svelte: SvelteInput[],
|
||||
binDir: string,
|
||||
genDir: string
|
||||
genDir: string,
|
||||
): Promise<void> {
|
||||
for (const file of svelte) {
|
||||
await compileSingleSvelte(file, binDir, genDir);
|
||||
|
@ -8,6 +8,6 @@
|
||||
// ensure node can run the resulting code
|
||||
"noEmitHelpers": false,
|
||||
"importHelpers": false,
|
||||
"module": "commonjs",
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
|
@ -11,13 +11,13 @@ interface AsyncReactiveData<T, E> {
|
||||
|
||||
function useAsyncReactive<T, E>(
|
||||
asyncFunction: () => Promise<T>,
|
||||
dependencies: [Readable<unknown>, ...Readable<unknown>[]]
|
||||
dependencies: [Readable<unknown>, ...Readable<unknown>[]],
|
||||
): AsyncReactiveData<T, E> {
|
||||
const promise = derived(
|
||||
dependencies,
|
||||
(_, set: (value: Promise<T> | null) => void): void => set(asyncFunction()),
|
||||
// initialize with null to avoid duplicate fetch on init
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
const value = derived(
|
||||
@ -25,7 +25,7 @@ function useAsyncReactive<T, E>(
|
||||
($promise, set: (value: T) => void): void => {
|
||||
$promise?.then((value: T) => set(value));
|
||||
},
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
const error = derived(
|
||||
@ -34,7 +34,7 @@ function useAsyncReactive<T, E>(
|
||||
$promise?.catch((error: E) => set(error));
|
||||
return (): void => set(null);
|
||||
},
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
const loading = derived(
|
||||
@ -43,7 +43,7 @@ function useAsyncReactive<T, E>(
|
||||
$promise?.finally(() => set(false));
|
||||
return (): void => set(true);
|
||||
},
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
return { value, error, loading };
|
||||
|
@ -8,7 +8,7 @@ type ContextProperty<T> = [
|
||||
// this typing is a lie insofar that calling get
|
||||
// outside of the component's context will return undefined
|
||||
() => T,
|
||||
() => boolean
|
||||
() => boolean,
|
||||
];
|
||||
|
||||
function contextProperty<T>(key: symbol): ContextProperty<T> {
|
||||
|
@ -3,7 +3,7 @@
|
||||
import type { SvelteComponentDev } from "svelte/internal";
|
||||
|
||||
export interface DynamicSvelteComponent<
|
||||
T extends typeof SvelteComponentDev = typeof SvelteComponentDev
|
||||
T extends typeof SvelteComponentDev = typeof SvelteComponentDev,
|
||||
> {
|
||||
component: T;
|
||||
[k: string]: unknown;
|
||||
@ -12,9 +12,9 @@ export interface DynamicSvelteComponent<
|
||||
export const dynamicComponent =
|
||||
<
|
||||
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 => {
|
||||
return { component, ...props };
|
||||
|
@ -15,7 +15,7 @@ const config = {
|
||||
interface DOMMirror {
|
||||
mirror(
|
||||
element: Element,
|
||||
params: { store: Writable<DocumentFragment> }
|
||||
params: { store: Writable<DocumentFragment> },
|
||||
): { destroy(): void };
|
||||
preventResubscription(): () => void;
|
||||
}
|
||||
@ -33,7 +33,7 @@ function getDOMMirror(): DOMMirror {
|
||||
|
||||
function mirror(
|
||||
element: Element,
|
||||
{ store }: { store: Writable<DocumentFragment> }
|
||||
{ store }: { store: Writable<DocumentFragment> },
|
||||
): { destroy(): void } {
|
||||
function saveHTMLToStore(): void {
|
||||
const range = document.createRange();
|
||||
@ -80,7 +80,7 @@ function getDOMMirror(): DOMMirror {
|
||||
} else {
|
||||
element.removeEventListener("blur", subscribe);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -14,7 +14,7 @@ export interface NodeStore<T extends Node> extends Writable<T> {
|
||||
|
||||
export function nodeStore<T extends Node>(
|
||||
node?: T,
|
||||
preprocess: (node: T) => void = noop
|
||||
preprocess: (node: T) => void = noop,
|
||||
): NodeStore<T> {
|
||||
const subscribers: Set<Subscriber<T>> = new Set();
|
||||
|
||||
|
@ -22,7 +22,7 @@ export type PreferenceRaw<T> = {
|
||||
|
||||
function createPreference<T>(
|
||||
initialValue: T,
|
||||
savePreferences: () => void
|
||||
savePreferences: () => void,
|
||||
): CustomStore<T> {
|
||||
const { subscribe, set, update } = writable(initialValue);
|
||||
|
||||
@ -42,7 +42,7 @@ function createPreference<T>(
|
||||
function preparePreferences<T>(
|
||||
Preferences: T,
|
||||
setter: (payload: PreferencePayload<T>) => Promise<void>,
|
||||
toObject: (preferences: T, options: { defaults: boolean }) => PreferenceRaw<T>
|
||||
toObject: (preferences: T, options: { defaults: boolean }) => PreferenceRaw<T>,
|
||||
): PreferenceStore<T> {
|
||||
const preferences: Partial<PreferenceStore<T>> = {};
|
||||
|
||||
@ -61,7 +61,7 @@ function preparePreferences<T>(
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(
|
||||
toObject(Preferences, { defaults: true })
|
||||
toObject(Preferences, { defaults: true }),
|
||||
)) {
|
||||
preferences[key] = createPreference(value, savePreferences);
|
||||
}
|
||||
@ -72,7 +72,7 @@ function preparePreferences<T>(
|
||||
export async function getPreferences<T>(
|
||||
getter: () => Promise<T>,
|
||||
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>> {
|
||||
const initialPreferences = await getter();
|
||||
return preparePreferences(initialPreferences, setter, toObject);
|
||||
|
@ -13,7 +13,7 @@ export function shortcut(
|
||||
action: (event: KeyboardEvent) => void;
|
||||
keyCombination: string;
|
||||
target?: EventTarget;
|
||||
}
|
||||
},
|
||||
): { destroy: () => void } {
|
||||
const deregister = registerShortcut(action, keyCombination, target ?? document);
|
||||
|
||||
|
@ -12,7 +12,7 @@ interface StoreAccessors {
|
||||
function storeSubscribe<T>(
|
||||
store: Readable<T>,
|
||||
callback: (value: T) => void,
|
||||
start = true
|
||||
start = true,
|
||||
): StoreAccessors {
|
||||
function subscribe(): Unsubscriber {
|
||||
return store.subscribe(callback);
|
||||
|
Loading…
Reference in New Issue
Block a user