spiegel-keyman/web/source/osk/lengthStyle.ts
Joshua Horton 64ba024a7a
chore(web): Apply suggestions from code review
Co-authored-by: Marc Durdin <marc@durdin.net>
2021-07-30 09:16:25 +07:00

76 lines
2.7 KiB
TypeScript

namespace com.keyman.osk {
export interface LengthStyle {
val: number,
absolute: boolean,
special?: 'em' | 'rem';
};
export class ParsedLengthStyle implements LengthStyle {
public readonly val: number;
public readonly absolute: boolean;
public readonly special: 'em' | 'rem';
public constructor(style: LengthStyle | string) {
Object.assign(this, typeof style == 'string' ? ParsedLengthStyle.parseLengthStyle(style) : style);
}
public get styleString(): string {
if(this.absolute) {
return this.val + 'px';
} else if(this.special) {
// Only 'em' and 'rem' are allowed, and both may be treated similarly.
// Both relate to font sizes, though the path to the reference element
// differs between them.
return this.val + this.special;
} else {
return (this.val * 100) + '%';
}
}
public scaledBy(scalar: number): ParsedLengthStyle {
return new ParsedLengthStyle({
val: scalar * this.val,
absolute: this.absolute
});
}
public static inPixels(val: number): ParsedLengthStyle {
return new ParsedLengthStyle({val: val, absolute: true});
}
public static inPercent(val: number): ParsedLengthStyle {
return new ParsedLengthStyle({val: val/100, absolute: false});
}
public static forScalar(val: number): ParsedLengthStyle {
return new ParsedLengthStyle({val: val, absolute: false});
}
public static special(val: number, suffix: 'em' | 'rem'): ParsedLengthStyle {
return new ParsedLengthStyle({val: val, absolute: false, special: suffix});
}
private static parseLengthStyle(spec: string): LengthStyle {
const val = parseFloat(spec);
if(isNaN(val)) {
// Cannot parse.
console.error("Could not properly parse specified length style info: '" + spec + "'.");
return null;
}
return spec.indexOf('px') != -1 ? {val: val, absolute: true} :
// 16 px ~= 12 pt.
// Reference: https://kyleschaeffer.com/css-font-size-em-vs-px-vs-pt-vs-percent
spec.indexOf('pt') != -1 ? {val: (4 * val / 3), absolute: true} :
spec.indexOf('%') != -1 ? {val: val/100, absolute: false} :
spec.indexOf('rem') != -1 ? {val: val, absolute: false, special: 'rem'} :
spec.indexOf('em') != -1 ? {val: val, absolute: false, special: 'em'} :
// At this point, assuming either Number or number in a string without units
// Note: this one is NOT natively handled by browsers!
// We'll treat it as if it were 'pt', since that's likely the user's
// most familiar font size unit.
{val: (4 * val / 3), absolute: true};
}
}
}