move presetWidths logic into new class PresetWidths
This commit is contained in:
48
src/lib/behavior/PresetWidths.ts
Normal file
48
src/lib/behavior/PresetWidths.ts
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -316,7 +316,7 @@ namespace Actions {
|
|||||||
export type Config = {
|
export type Config = {
|
||||||
manualScrollStep: number;
|
manualScrollStep: number;
|
||||||
manualResizeStep: number;
|
manualResizeStep: number;
|
||||||
presetWidths: PresetWidth[];
|
presetWidths: PresetWidths|null;
|
||||||
columnResizer: ColumnResizer;
|
columnResizer: ColumnResizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ class World {
|
|||||||
constructor(config: Config) {
|
constructor(config: Config) {
|
||||||
this.workspaceSignalManager = initWorkspaceSignalHandlers(this);
|
this.workspaceSignalManager = initWorkspaceSignalHandlers(this);
|
||||||
|
|
||||||
let presetWidths: PresetWidth[] = [];
|
let presetWidths: PresetWidths|null = null;
|
||||||
try {
|
try {
|
||||||
presetWidths = parsePresetWidths(config.presetWidths, config.gapsInnerHorizontal);
|
presetWidths = new PresetWidths(config.presetWidths, config.gapsInnerHorizontal);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
notificationInvalidPresetWidths.sendEvent();
|
notificationInvalidPresetWidths.sendEvent();
|
||||||
log("failed to parse presetWidths:", error);
|
log("failed to parse presetWidths:", error);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
tests.register("parsePresetWidths", 1, () => {
|
tests.register("PresetWidths", 1, () => {
|
||||||
const screenWidth = 800;
|
const screenWidth = 800;
|
||||||
const spacing = 10;
|
const spacing = 10;
|
||||||
|
|
||||||
@@ -19,15 +19,13 @@ tests.register("parsePresetWidths", 1, () => {
|
|||||||
{ str: " ", error: true },
|
{ str: " ", error: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
function applyPresetWidths(presetWidths: PresetWidth[]) {
|
|
||||||
return presetWidths.map(f => f(screenWidth));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const testCase of testCases) {
|
for (const testCase of testCases) {
|
||||||
try {
|
try {
|
||||||
const result = parsePresetWidths(testCase.str, spacing);
|
const presetWidths = new PresetWidths(testCase.str, spacing);
|
||||||
assert(!testCase.error);
|
assert(!testCase.error);
|
||||||
assertArrayEqual(applyPresetWidths(result), testCase.result!);
|
|
||||||
|
const result = presetWidths.get(screenWidth);
|
||||||
|
assertArrayEqual(result, testCase.result!);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
assert(testCase.error === true);
|
assert(testCase.error === true);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user