1 | import { makeValidator, makeParser } from '../core/properties';
|
2 | import { Trace } from '../../trace';
|
3 | export class Font {
|
4 | get isItalic() {
|
5 | return this.fontStyle === FontStyle.ITALIC;
|
6 | }
|
7 | get isBold() {
|
8 | return this.fontWeight === FontWeight.SEMI_BOLD || this.fontWeight === FontWeight.BOLD || this.fontWeight === '700' || this.fontWeight === FontWeight.EXTRA_BOLD || this.fontWeight === FontWeight.BLACK;
|
9 | }
|
10 | constructor(fontFamily, fontSize, fontStyle, fontWeight, fontScale, fontVariationSettings) {
|
11 | this.fontFamily = fontFamily;
|
12 | this.fontSize = fontSize;
|
13 | this.fontVariationSettings = fontVariationSettings;
|
14 | this.fontStyle = fontStyle ?? FontStyle.NORMAL;
|
15 | this.fontWeight = fontWeight ?? FontWeight.NORMAL;
|
16 | this.fontScale = fontScale ?? 1;
|
17 | }
|
18 | static equals(value1, value2) {
|
19 |
|
20 | if (!value1 && !value2) {
|
21 | return true;
|
22 | }
|
23 |
|
24 | if (!value1 || !value2) {
|
25 | return false;
|
26 | }
|
27 | return value1.fontFamily === value2.fontFamily && value1.fontSize === value2.fontSize && value1.fontStyle === value2.fontStyle && value1.fontWeight === value2.fontWeight && value1.fontScale === value2.fontScale && FontVariationSettings.toString(value1.fontVariationSettings) === FontVariationSettings.toString(value2.fontVariationSettings);
|
28 | }
|
29 | }
|
30 | Font.default = undefined;
|
31 | export var FontStyle;
|
32 | (function (FontStyle) {
|
33 | FontStyle.NORMAL = 'normal';
|
34 | FontStyle.ITALIC = 'italic';
|
35 | FontStyle.isValid = makeValidator(FontStyle.NORMAL, FontStyle.ITALIC);
|
36 | FontStyle.parse = makeParser(FontStyle.isValid);
|
37 | })(FontStyle || (FontStyle = {}));
|
38 | export var FontWeight;
|
39 | (function (FontWeight) {
|
40 | FontWeight.THIN = '100';
|
41 | FontWeight.EXTRA_LIGHT = '200';
|
42 | FontWeight.LIGHT = '300';
|
43 | FontWeight.NORMAL = 'normal';
|
44 | FontWeight.MEDIUM = '500';
|
45 | FontWeight.SEMI_BOLD = '600';
|
46 | FontWeight.BOLD = 'bold';
|
47 | FontWeight.EXTRA_BOLD = '800';
|
48 | FontWeight.BLACK = '900';
|
49 | FontWeight.isValid = makeValidator(FontWeight.THIN, FontWeight.EXTRA_LIGHT, FontWeight.LIGHT, FontWeight.NORMAL, '400', FontWeight.MEDIUM, FontWeight.SEMI_BOLD, FontWeight.BOLD, '700', FontWeight.EXTRA_BOLD, FontWeight.BLACK);
|
50 | FontWeight.parse = makeParser(FontWeight.isValid);
|
51 | })(FontWeight || (FontWeight = {}));
|
52 | export var FontVariationSettings;
|
53 | (function (FontVariationSettings) {
|
54 | function parse(fontVariationSettings) {
|
55 | if (!fontVariationSettings) {
|
56 | return null;
|
57 | }
|
58 | const allowedValues = ['normal', 'inherit', 'initial', 'revert', 'revert-layer', 'unset'];
|
59 | const variationSettingsValue = fontVariationSettings.trim();
|
60 | if (allowedValues.indexOf(variationSettingsValue.toLowerCase()) !== -1) {
|
61 | return null;
|
62 | }
|
63 | const chunks = variationSettingsValue.split(',');
|
64 | if (chunks.length) {
|
65 | const parsed = [];
|
66 | for (const chunk of chunks) {
|
67 | const trimmedChunk = chunk.trim();
|
68 | const axisChunks = trimmedChunk.split(' ');
|
69 | if (axisChunks.length === 2) {
|
70 | const axisName = axisChunks[0].trim();
|
71 | const axisValue = parseFloat(axisChunks[1]);
|
72 |
|
73 |
|
74 | if (!isNaN(axisValue) && axisName.length === 6 && ((axisName.startsWith("'") && axisName.endsWith("'")) || (axisName.startsWith('"') && axisName.endsWith('"')))) {
|
75 |
|
76 | const unquotedAxisName = axisName.substring(1, axisName.length - 1);
|
77 | parsed.push({ axis: unquotedAxisName, value: axisValue });
|
78 | }
|
79 | else {
|
80 | Trace.write('Invalid value (font-variation-settings): ' + variationSettingsValue, Trace.categories.Error, Trace.messageType.error);
|
81 | }
|
82 | }
|
83 | else {
|
84 | Trace.write('Invalid value (font-variation-settings): ' + variationSettingsValue, Trace.categories.Error, Trace.messageType.error);
|
85 | }
|
86 | }
|
87 | return parsed;
|
88 | }
|
89 | Trace.write('Invalid value (font-variation-settings): ' + variationSettingsValue, Trace.categories.Error, Trace.messageType.error);
|
90 | }
|
91 | FontVariationSettings.parse = parse;
|
92 | function toString(fontVariationSettings) {
|
93 | if (fontVariationSettings?.length) {
|
94 | return fontVariationSettings.map(({ axis, value }) => `'${axis}' ${value}`).join(', ');
|
95 | }
|
96 | return null;
|
97 | }
|
98 | FontVariationSettings.toString = toString;
|
99 | })(FontVariationSettings || (FontVariationSettings = {}));
|
100 | export function parseFontFamily(value) {
|
101 | if (!value) {
|
102 | return [];
|
103 | }
|
104 | return value
|
105 | .split(',')
|
106 | .map((v) => (v || '').trim().replace(/['"]+/g, ''))
|
107 | .filter((v) => !!v);
|
108 | }
|
109 | export var genericFontFamilies;
|
110 | (function (genericFontFamilies) {
|
111 | genericFontFamilies.serif = 'serif';
|
112 | genericFontFamilies.sansSerif = 'sans-serif';
|
113 | genericFontFamilies.monospace = 'monospace';
|
114 | genericFontFamilies.system = 'system';
|
115 | })(genericFontFamilies || (genericFontFamilies = {}));
|
116 | const styles = new Set();
|
117 | [FontStyle.NORMAL, FontStyle.ITALIC].forEach((val, i, a) => styles.add(val));
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 | const weights = new Set();
|
131 | [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));
|
132 | export function parseFont(fontValue) {
|
133 | const result = {
|
134 | fontStyle: 'normal',
|
135 | fontVariant: 'normal',
|
136 | fontWeight: 'normal',
|
137 | };
|
138 | const parts = fontValue.split(/\s+/);
|
139 | let part;
|
140 | while ((part = parts.shift())) {
|
141 | if (part === 'normal') {
|
142 |
|
143 | }
|
144 | else if (part === 'small-caps') {
|
145 |
|
146 | result.fontVariant = part;
|
147 | }
|
148 | else if (styles.has(part)) {
|
149 | result.fontStyle = part;
|
150 | }
|
151 | else if (weights.has(part)) {
|
152 | result.fontWeight = part;
|
153 | }
|
154 | else if (!result.fontSize) {
|
155 | const sizes = part.split('/');
|
156 | result.fontSize = sizes[0];
|
157 | result.lineHeight = sizes.length > 1 ? sizes[1] : undefined;
|
158 | }
|
159 | else {
|
160 | result.fontFamily = part;
|
161 | if (parts.length) {
|
162 | result.fontFamily += ' ' + parts.join(' ');
|
163 | }
|
164 | break;
|
165 | }
|
166 | }
|
167 | return result;
|
168 | }
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | export function fuzzySearch(query, dataset) {
|
175 | const q = query ? query.trim().toLowerCase() : '';
|
176 | const result = [];
|
177 | if (!q.length) {
|
178 | return null;
|
179 | }
|
180 | dataset.forEach((item) => {
|
181 | const s = item.trim().toLowerCase();
|
182 | let n = -1;
|
183 | for (const char of q) {
|
184 | n = s.indexOf(char, n + 1);
|
185 | if (!~n) {
|
186 | return;
|
187 | }
|
188 | }
|
189 | result.push(item);
|
190 | });
|
191 | return result.length ? result : null;
|
192 | }
|
193 |
|
\ | No newline at end of file |