@readium/navigator
Version:
Next generation SDK for publications in Web Apps
185 lines (175 loc) • 7.31 kB
text/typescript
import { ConfigurablePreferences } from "../../preferences/Configurable.ts";
import {
TextAlignment,
fontSizeRangeConfig,
fontWeightRangeConfig,
fontWidthRangeConfig
} from "../../preferences/Types.ts";
import {
ensureBoolean,
ensureEnumValue,
ensureFilter,
ensureNonNegative,
ensureString,
ensureValueInRange
} from "../../preferences/guards.ts";
export interface IEpubPreferences {
backgroundColor?: string | null,
blendFilter?: boolean | null,
columnCount?: number | null,
constraint?: number | null,
darkenFilter?: boolean | number | null,
deprecatedFontSize?: boolean | null,
fontFamily?: string | null,
fontSize?: number | null,
fontSizeNormalize?: boolean | null,
fontOpticalSizing?: boolean | null,
fontWeight?: number | null,
fontWidth?: number | null,
hyphens?: boolean | null,
invertFilter?: boolean | number | null,
invertGaijiFilter?: boolean | number | null,
iOSPatch?: boolean | null,
iPadOSPatch?: boolean | null,
letterSpacing?: number | null,
ligatures?: boolean | null,
lineHeight?: number | null,
linkColor?: string | null,
maximalLineLength?: number | null,
minimalLineLength?: number | null,
noRuby?: boolean | null,
optimalLineLength?: number | null,
pageGutter?: number | null,
paragraphIndent?: number | null,
paragraphSpacing?: number | null,
scroll?: boolean | null,
scrollPaddingTop?: number | null,
scrollPaddingBottom?: number | null,
scrollPaddingLeft?: number | null,
scrollPaddingRight?: number | null,
selectionBackgroundColor?: string | null,
selectionTextColor?: string | null,
textAlign?: TextAlignment | null,
textColor?: string | null,
textNormalization?: boolean | null,
visitedColor?: string | null,
wordSpacing?: number | null
}
export class EpubPreferences implements ConfigurablePreferences<EpubPreferences> {
backgroundColor?: string | null;
blendFilter?: boolean | null;
constraint?: number | null;
columnCount?: number | null;
darkenFilter?: boolean | number | null;
deprecatedFontSize?: boolean | null;
fontFamily?: string | null;
fontSize?: number | null;
fontSizeNormalize?: boolean | null;
fontOpticalSizing?: boolean | null;
fontWeight?: number | null;
fontWidth?: number | null;
hyphens?: boolean | null;
invertFilter?: boolean | number | null;
invertGaijiFilter?: boolean | number | null;
iOSPatch?: boolean | null;
iPadOSPatch?: boolean | null;
letterSpacing?: number | null;
ligatures?: boolean | null;
lineHeight?: number | null;
linkColor?: string | null;
maximalLineLength?: number | null;
minimalLineLength?: number | null;
noRuby?: boolean | null;
optimalLineLength?: number | null;
pageGutter?: number | null;
paragraphIndent?: number | null;
paragraphSpacing?: number | null;
scroll?: boolean | null;
scrollPaddingTop?: number | null;
scrollPaddingBottom?: number | null;
scrollPaddingLeft?: number | null;
scrollPaddingRight?: number | null;
selectionBackgroundColor?: string | null;
selectionTextColor?: string | null;
textAlign?: TextAlignment | null;
textColor?: string | null;
textNormalization?: boolean | null;
visitedColor?: string | null;
wordSpacing?: number | null;
constructor(preferences: IEpubPreferences = {}) {
this.backgroundColor = ensureString(preferences.backgroundColor);
this.blendFilter = ensureBoolean(preferences.blendFilter);
this.constraint = ensureNonNegative(preferences.constraint);
this.columnCount = ensureNonNegative(preferences.columnCount);
this.darkenFilter = ensureFilter(preferences.darkenFilter);
this.deprecatedFontSize = ensureBoolean(preferences.deprecatedFontSize);
this.fontFamily = ensureString(preferences.fontFamily);
this.fontSize = ensureValueInRange(preferences.fontSize, fontSizeRangeConfig.range);
this.fontSizeNormalize = ensureBoolean(preferences.fontSizeNormalize);
this.fontOpticalSizing = ensureBoolean(preferences.fontOpticalSizing);
this.fontWeight = ensureValueInRange(preferences.fontWeight, fontWeightRangeConfig.range);
this.fontWidth = ensureValueInRange(preferences.fontWidth,fontWidthRangeConfig.range);
this.hyphens = ensureBoolean(preferences.hyphens);
this.invertFilter = ensureFilter(preferences.invertFilter);
this.invertGaijiFilter = ensureFilter(preferences.invertGaijiFilter);
this.iOSPatch = ensureBoolean(preferences.iOSPatch);
this.iPadOSPatch = ensureBoolean(preferences.iPadOSPatch);
this.letterSpacing = ensureNonNegative(preferences.letterSpacing);
this.ligatures = ensureBoolean(preferences.ligatures);
this.lineHeight = ensureNonNegative(preferences.lineHeight);
this.linkColor = ensureString(preferences.linkColor);
this.noRuby = ensureBoolean(preferences.noRuby);
this.pageGutter = ensureNonNegative(preferences.pageGutter);
this.paragraphIndent = ensureNonNegative(preferences.paragraphIndent);
this.paragraphSpacing = ensureNonNegative(preferences.paragraphSpacing);
this.scroll = ensureBoolean(preferences.scroll);
this.scrollPaddingTop = ensureNonNegative(preferences.scrollPaddingTop);
this.scrollPaddingBottom = ensureNonNegative(preferences.scrollPaddingBottom);
this.scrollPaddingLeft = ensureNonNegative(preferences.scrollPaddingLeft);
this.scrollPaddingRight = ensureNonNegative(preferences.scrollPaddingRight);
this.selectionBackgroundColor = ensureString(preferences.selectionBackgroundColor);
this.selectionTextColor = ensureString(preferences.selectionTextColor);
this.textAlign = ensureEnumValue<TextAlignment>(preferences.textAlign, TextAlignment);
this.textColor = ensureString(preferences.textColor);
this.textNormalization = ensureBoolean(preferences.textNormalization);
this.visitedColor = ensureString(preferences.visitedColor);
this.wordSpacing = ensureNonNegative(preferences.wordSpacing);
this.optimalLineLength = ensureNonNegative(preferences.optimalLineLength);
this.maximalLineLength = ensureNonNegative(preferences.maximalLineLength);
this.minimalLineLength = ensureNonNegative(preferences.minimalLineLength);
}
static serialize(preferences: EpubPreferences): string {
const { ...properties } = preferences;
return JSON.stringify(properties);
}
static deserialize(preferences: string): EpubPreferences | null {
try {
const parsedPreferences = JSON.parse(preferences);
return new EpubPreferences(parsedPreferences);
} catch (error) {
console.error("Failed to deserialize preferences:", error);
return null;
}
}
merging(other: EpubPreferences): EpubPreferences {
const merged: IEpubPreferences = { ...this };
for (const key of Object.keys(other) as (keyof IEpubPreferences)[]) {
if (
other[key] !== undefined &&
(
key !== "maximalLineLength" ||
other[key] === null ||
(other[key] >= (other.optimalLineLength ?? merged.optimalLineLength ?? 65))
) &&
(
key !== "minimalLineLength" ||
other[key] === null ||
(other[key] <= (other.optimalLineLength ?? merged.optimalLineLength ?? 65))
)
) {
(merged as Record<string, unknown>)[key] = other[key];
}
}
return new EpubPreferences(merged);
}
}