mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00

Add parsers for the background css shorthand property, make ViewBase unit testable in node environment Add background parser and linear-gradient parser Use sticky regexes Simplify some types, introduce generic Parsed<T> instead of & TokenRange Apply each parser to return a { start, end, value } object Move the css selector parser to the css/parser and unify types Add the first steps toward building homegrown css parser Add somewhat standards compliant tokenizer, add baseline, rework and shady css parsers Enable all tests again, skip flaky perf test Improve css parser tokenizer by converting some char token types to simple string Implement 'parse a stylesheet' Add gonzales css-parser Add parseLib and css-tree perf Add a thin parser layer that will convert CSS3 tokens to values, for now output is compatible with rework Make root tsc green Return the requires of tns-core-modules to use relative paths for webpack to work Implement support for '@import 'url-string'; Fix function parser, function-token is no-longer neglected Make the style-scope be able to load from "css" and "css-ast" modules Add a loadAppCss event so theme can be added to snapshot separately from loaded
169 lines
5.1 KiB
TypeScript
169 lines
5.1 KiB
TypeScript
import { Font as FontDefinition, ParsedFont } from "./font";
|
|
import { makeValidator, makeParser } from "../core/properties";
|
|
|
|
export abstract class Font implements FontDefinition {
|
|
public static default = undefined;
|
|
|
|
get isItalic(): boolean {
|
|
return this.fontStyle === FontStyle.ITALIC;
|
|
}
|
|
|
|
get isBold(): boolean {
|
|
return this.fontWeight === FontWeight.SEMI_BOLD ||
|
|
this.fontWeight === FontWeight.BOLD ||
|
|
this.fontWeight === "700" ||
|
|
this.fontWeight === FontWeight.EXTRA_BOLD ||
|
|
this.fontWeight === FontWeight.BLACK;
|
|
}
|
|
|
|
protected constructor(
|
|
public readonly fontFamily: string,
|
|
public readonly fontSize: number,
|
|
public readonly fontStyle: FontStyle,
|
|
public readonly fontWeight: FontWeight) {
|
|
}
|
|
|
|
public abstract getAndroidTypeface(): any /* android.graphics.Typeface */;
|
|
public abstract getUIFont(defaultFont: any /* UIFont */): any /* UIFont */;
|
|
public abstract withFontFamily(family: string): Font;
|
|
public abstract withFontStyle(style: string): Font;
|
|
public abstract withFontWeight(weight: string): Font;
|
|
public abstract withFontSize(size: number): Font;
|
|
|
|
public static equals(value1: Font, value2: Font): boolean {
|
|
// both values are falsy
|
|
if (!value1 && !value2) {
|
|
return true;
|
|
}
|
|
|
|
// only one is falsy
|
|
if (!value1 || !value2) {
|
|
return false;
|
|
}
|
|
|
|
return value1.fontFamily === value2.fontFamily &&
|
|
value1.fontSize === value2.fontSize &&
|
|
value1.fontStyle === value2.fontStyle &&
|
|
value1.fontWeight === value2.fontWeight;
|
|
}
|
|
}
|
|
|
|
export type FontStyle = "normal" | "italic";
|
|
export namespace FontStyle {
|
|
export const NORMAL: "normal" = "normal";
|
|
export const ITALIC: "italic" = "italic";
|
|
export const isValid = makeValidator<FontStyle>(NORMAL, ITALIC);
|
|
export const parse = makeParser<FontStyle>(isValid);
|
|
}
|
|
|
|
export type FontWeight = "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900";
|
|
export namespace FontWeight {
|
|
export const THIN: "100" = "100";
|
|
export const EXTRA_LIGHT: "200" = "200";
|
|
export const LIGHT: "300" = "300";
|
|
export const NORMAL: "normal" = "normal";
|
|
export const MEDIUM: "500" = "500";
|
|
export const SEMI_BOLD: "600" = "600";
|
|
export const BOLD: "bold" = "bold";
|
|
export const EXTRA_BOLD: "800" = "800";
|
|
export const BLACK: "900" = "900";
|
|
export const isValid = makeValidator<FontWeight>(THIN, EXTRA_LIGHT, LIGHT, NORMAL, "400", MEDIUM, SEMI_BOLD, BOLD, "700", EXTRA_BOLD, BLACK);
|
|
export const parse = makeParser<FontStyle>(isValid);
|
|
}
|
|
|
|
export function parseFontFamily(value: string): Array<string> {
|
|
const result = new Array<string>();
|
|
if (!value) {
|
|
return result;
|
|
}
|
|
|
|
const split = value.split(",");
|
|
for (let i = 0; i < split.length; i++) {
|
|
let str = split[i].trim().replace(/['"]+/g, '');
|
|
if (str) {
|
|
result.push(str);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export module genericFontFamilies {
|
|
export const serif = "serif";
|
|
export const sansSerif = "sans-serif";
|
|
export const monospace = "monospace";
|
|
export const system = "system";
|
|
}
|
|
|
|
const styles = new Set();
|
|
[
|
|
FontStyle.NORMAL,
|
|
FontStyle.ITALIC
|
|
].forEach((val, i, a) => styles.add(val));
|
|
|
|
// http://www.w3schools.com/cssref/pr_font_weight.asp
|
|
//- normal(same as 400)
|
|
//- bold(same as 700)
|
|
//- 100(Thin) (API16 -thin)
|
|
//- 200(Extra Light / Ultra Light) (API16 -light)
|
|
//- 300(Light) (API16 -light)
|
|
//- 400(Normal)
|
|
//- 500(Medium) (API21 -medium)
|
|
//- 600(Semi Bold / Demi Bold) (API21 -medium)
|
|
//- 700(Bold) (API16 -bold)
|
|
//- 800(Extra Bold / Ultra Bold) (API16 -bold)
|
|
//- 900(Black / Heavy) (API21 -black)
|
|
const weights = new Set();
|
|
[
|
|
FontWeight.THIN,
|
|
FontWeight.EXTRA_LIGHT,
|
|
FontWeight.LIGHT,
|
|
FontWeight.NORMAL,
|
|
"400",
|
|
FontWeight.MEDIUM,
|
|
FontWeight.SEMI_BOLD,
|
|
FontWeight.BOLD,
|
|
"700",
|
|
FontWeight.EXTRA_BOLD,
|
|
FontWeight.BLACK
|
|
].forEach((val, i, a) => weights.add(val));
|
|
|
|
export function parseFont(fontValue: string): ParsedFont {
|
|
let result: ParsedFont = {
|
|
fontStyle: "normal",
|
|
fontVariant: "normal",
|
|
fontWeight: "normal"
|
|
}
|
|
|
|
const parts = fontValue.split(/\s+/);
|
|
let part: string;
|
|
while (part = parts.shift()) {
|
|
if (part === "normal") {
|
|
// nothing to do here
|
|
}
|
|
else if (part === "small-caps") {
|
|
// The only supported font variant in shorthand font
|
|
result.fontVariant = part;
|
|
}
|
|
else if (styles.has(part)) {
|
|
result.fontStyle = <any>part;
|
|
}
|
|
else if (weights.has(part)) {
|
|
result.fontWeight = <any>part;
|
|
}
|
|
else if (!result.fontSize) {
|
|
let sizes = part.split("/");
|
|
result.fontSize = sizes[0];
|
|
result.lineHeight = sizes.length > 1 ? sizes[1] : undefined;
|
|
}
|
|
else {
|
|
result.fontFamily = part;
|
|
if (parts.length) {
|
|
result.fontFamily += " " + parts.join(" ");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|