move presetWidths logic into new class PresetWidths

This commit is contained in:
Peter Fajdiga
2024-10-03 00:25:26 +02:00
parent c2931c9fbe
commit e91c9c825e
5 changed files with 56 additions and 48 deletions

View File

@@ -0,0 +1,48 @@
class PresetWidths {
private readonly presets: ((maxWidth: number) => number)[];
constructor(presetWidths: string, spacing: number) {
this.presets = PresetWidths.parsePresetWidths(presetWidths, spacing);
}
public get(maxWidth: number) {
return this.presets.map(f => f(maxWidth));
}
private static parsePresetWidths(presetWidths: string, spacing: number): ((maxWidth: number) => number)[] {
function getRatioFunction(ratio: number) {
return (maxWidth: number) => Math.floor((maxWidth + spacing) * ratio - spacing);
}
return presetWidths.split(",").map((widthStr: string) => {
widthStr = widthStr.trim();
const widthPx = PresetWidths.parseNumberWithSuffix(widthStr, "px");
if (widthPx !== undefined) {
return () => widthPx;
}
const widthPct = PresetWidths.parseNumberWithSuffix(widthStr, "%");
if (widthPct !== undefined) {
return getRatioFunction(widthPct / 100.0);
}
return getRatioFunction(PresetWidths.parseNumberSafe(widthStr));
});
}
private static parseNumberSafe(str: string) {
const num = Number(str);
if (isNaN(num) || num <= 0) {
throw new Error("Invalid number: " + str);
}
return num;
}
private static parseNumberWithSuffix(str: string, suffix: string) {
if (!str.endsWith(suffix)) {
return undefined;
}
return PresetWidths.parseNumberSafe(str.substring(0, str.length-suffix.length).trim());
}
}

View File

@@ -1,38 +0,0 @@
type PresetWidth = (maxWidth: number) => number;
function parsePresetWidths(presetWidths: string, spacing: number): PresetWidth[] {
function parseNumberSafe(str: string) {
const num = Number(str);
if (isNaN(num) || num <= 0) {
throw new Error("Invalid number: " + str);
}
return num;
}
function parseNumberWithSuffix(str: string, suffix: string) {
if (!str.endsWith(suffix)) {
return undefined;
}
return parseNumberSafe(str.substring(0, str.length-suffix.length).trim());
}
function getRatioFunction(ratio: number) {
return (maxWidth: number) => Math.floor((maxWidth + spacing) * ratio - spacing);
}
return presetWidths.split(",").map((widthStr: string) => {
widthStr = widthStr.trim();
const widthPx = parseNumberWithSuffix(widthStr, "px");
if (widthPx !== undefined) {
return () => widthPx;
}
const widthPct = parseNumberWithSuffix(widthStr, "%");
if (widthPct !== undefined) {
return getRatioFunction(widthPct / 100.0);
}
return getRatioFunction(parseNumberSafe(widthStr));
});
}

View File

@@ -316,7 +316,7 @@ namespace Actions {
export type Config = {
manualScrollStep: number;
manualResizeStep: number;
presetWidths: PresetWidth[];
presetWidths: PresetWidths|null;
columnResizer: ColumnResizer;
};

View File

@@ -9,9 +9,9 @@ class World {
constructor(config: Config) {
this.workspaceSignalManager = initWorkspaceSignalHandlers(this);
let presetWidths: PresetWidth[] = [];
let presetWidths: PresetWidths|null = null;
try {
presetWidths = parsePresetWidths(config.presetWidths, config.gapsInnerHorizontal);
presetWidths = new PresetWidths(config.presetWidths, config.gapsInnerHorizontal);
} catch (error: any) {
notificationInvalidPresetWidths.sendEvent();
log("failed to parse presetWidths:", error);

View File

@@ -1,4 +1,4 @@
tests.register("parsePresetWidths", 1, () => {
tests.register("PresetWidths", 1, () => {
const screenWidth = 800;
const spacing = 10;
@@ -19,15 +19,13 @@ tests.register("parsePresetWidths", 1, () => {
{ str: " ", error: true },
];
function applyPresetWidths(presetWidths: PresetWidth[]) {
return presetWidths.map(f => f(screenWidth));
}
for (const testCase of testCases) {
try {
const result = parsePresetWidths(testCase.str, spacing);
const presetWidths = new PresetWidths(testCase.str, spacing);
assert(!testCase.error);
assertArrayEqual(applyPresetWidths(result), testCase.result!);
const result = presetWidths.get(screenWidth);
assertArrayEqual(result, testCase.result!);
} catch (error) {
assert(testCase.error === true);
}