@ng-native/fabric 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/aria-props.d.ts +16 -0
  2. package/dist/aria-props.js +78 -0
  3. package/dist/aria-props.js.map +1 -0
  4. package/dist/color-mix.js +1 -16
  5. package/dist/color-mix.js.map +1 -1
  6. package/dist/css.d.ts +169 -2
  7. package/dist/css.js +676 -34
  8. package/dist/css.js.map +1 -1
  9. package/dist/element-styles.d.ts +15 -0
  10. package/dist/element-styles.js +103 -0
  11. package/dist/element-styles.js.map +1 -0
  12. package/dist/engine.d.ts +252 -7
  13. package/dist/engine.js +1081 -80
  14. package/dist/engine.js.map +1 -1
  15. package/dist/font-faces.d.ts +5 -2
  16. package/dist/font-faces.js +13 -2
  17. package/dist/font-faces.js.map +1 -1
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.js +3 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/inline-derived-token.js +11 -10
  22. package/dist/inline-derived-token.js.map +1 -1
  23. package/dist/inline-token.d.ts +7 -0
  24. package/dist/inline-token.js +53 -8
  25. package/dist/inline-token.js.map +1 -1
  26. package/dist/inline-transform.d.ts +5 -1
  27. package/dist/inline-transform.js +34 -6
  28. package/dist/inline-transform.js.map +1 -1
  29. package/dist/native-drive.d.ts +21 -0
  30. package/dist/native-drive.js +60 -0
  31. package/dist/native-drive.js.map +1 -1
  32. package/dist/premultiplied-stops.d.ts +7 -0
  33. package/dist/premultiplied-stops.js +131 -0
  34. package/dist/premultiplied-stops.js.map +1 -0
  35. package/dist/scroll-animation.d.ts +11 -0
  36. package/dist/scroll-animation.js +29 -0
  37. package/dist/scroll-animation.js.map +1 -1
  38. package/dist/transition.d.ts +15 -0
  39. package/dist/transition.js +42 -1
  40. package/dist/transition.js.map +1 -1
  41. package/package.json +1 -1
@@ -16,9 +16,10 @@ type FontFace = NonNullable<StyleSheet['fonts']>[number];
16
16
  export declare const DROP_MATCHED_WEIGHT_AND_STYLE = true;
17
17
  /**
18
18
  * The name a face is registered under: the family, then its weight and its style where it
19
- * declares them. `Inter`, `Inter-600`, `Inter-italic`, `Inter-600-italic`.
19
+ * declares them. `Inter`, `Inter-600`, `Inter-italic`, `Inter-600-italic`. A variable font's
20
+ * range is both its ends, `Inter-100to900`, so two files that split a family by range differ.
20
21
  */
21
- export declare function faceName(face: Pick<FontFace, 'family' | 'weight' | 'style'>): string;
22
+ export declare function faceName(face: Pick<FontFace, 'family' | 'weight' | 'weightRange' | 'style'>): string;
22
23
  /**
23
24
  * The face CSS's matching picks among one family's, for a wanted weight and style.
24
25
  *
@@ -30,6 +31,8 @@ export declare function matchFace(faces: readonly FontFace[], weight: number, st
30
31
  /** Every face the engine has seen a sheet declare, by family. */
31
32
  export declare class FontFaces {
32
33
  private readonly byFamily;
34
+ /** Forget every face, before they are taken in again from the sheets still registered. */
35
+ clear(): void;
33
36
  /** Take faces in; whether any was new, which changes what text already matched may match. */
34
37
  add(faces: readonly FontFace[]): boolean;
35
38
  /**
@@ -6,12 +6,15 @@
6
6
  export const DROP_MATCHED_WEIGHT_AND_STYLE = true;
7
7
  /**
8
8
  * The name a face is registered under: the family, then its weight and its style where it
9
- * declares them. `Inter`, `Inter-600`, `Inter-italic`, `Inter-600-italic`.
9
+ * declares them. `Inter`, `Inter-600`, `Inter-italic`, `Inter-600-italic`. A variable font's
10
+ * range is both its ends, `Inter-100to900`, so two files that split a family by range differ.
10
11
  */
11
12
  export function faceName(face) {
12
13
  let name = face.family;
13
14
  if (face.weight !== undefined)
14
15
  name += `-${face.weight}`;
16
+ else if (face.weightRange)
17
+ name += `-${face.weightRange[0]}to${face.weightRange[1]}`;
15
18
  if (face.style)
16
19
  name += `-${face.style}`;
17
20
  return name;
@@ -42,7 +45,10 @@ export function matchFace(faces, weight, style) {
42
45
  const order = STYLE_ORDER[style] ?? STYLE_ORDER['normal'];
43
46
  const wantedStyle = order.find((one) => faces.some((face) => slant(face) === one));
44
47
  const candidates = faces.filter((face) => slant(face) === wantedStyle);
45
- const weightOfFace = (face) => face.weight ?? 400;
48
+ // A face that covers a range has every weight in it: the nearest it has to the one wanted.
49
+ const weightOfFace = (face) => face.weightRange
50
+ ? Math.min(Math.max(weight, face.weightRange[0]), face.weightRange[1])
51
+ : (face.weight ?? 400);
46
52
  const heavier = (from, to) => candidates
47
53
  .filter((face) => weightOfFace(face) >= from && weightOfFace(face) <= to)
48
54
  .sort((a, b) => weightOfFace(a) - weightOfFace(b))[0];
@@ -61,6 +67,10 @@ const familyKey = (family) => family.toLowerCase();
61
67
  /** Every face the engine has seen a sheet declare, by family. */
62
68
  export class FontFaces {
63
69
  byFamily = new Map();
70
+ /** Forget every face, before they are taken in again from the sheets still registered. */
71
+ clear() {
72
+ this.byFamily.clear();
73
+ }
64
74
  /** Take faces in; whether any was new, which changes what text already matched may match. */
65
75
  add(faces) {
66
76
  let added = false;
@@ -105,6 +115,7 @@ export class FontFaces {
105
115
  // upright one Android draws its system font slanted in place of the face, which iOS draws
106
116
  // upright anyway.
107
117
  delete style['fontStyle'];
118
+ // A face of one weight draws it. One that covers a range is told which, so the weight stays.
108
119
  if (face.weight !== undefined)
109
120
  delete style['fontWeight'];
110
121
  }
@@ -1 +1 @@
1
- {"version":3,"file":"font-faces.js","sourceRoot":"","sources":["../src/font-faces.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Font matching, which native does not do.\n *\n * A device finds a family by name and nothing else, so each `@font-face` is registered under a\n * name of its own (`faceName`), and a text asking for a declared family with a weight or a style\n * is pointed at the face CSS would pick for it. That happens on the resolved style, after the\n * cascade, because a family and a weight often come from different rules or from an ancestor.\n */\nimport type { StyleSheet } from './css.ts';\n\ntype FontFace = NonNullable<StyleSheet['fonts']>[number];\n\n/**\n * When a face was picked, whether to drop the `fontWeight` and `fontStyle` it was picked for from\n * what is committed. The face already draws them, and kept, the platform may embolden or slant it\n * again on top.\n */\nexport const DROP_MATCHED_WEIGHT_AND_STYLE = true;\n\n/**\n * The name a face is registered under: the family, then its weight and its style where it\n * declares them. `Inter`, `Inter-600`, `Inter-italic`, `Inter-600-italic`.\n */\nexport function faceName(face: Pick<FontFace, 'family' | 'weight' | 'style'>): string {\n let name = face.family;\n if (face.weight !== undefined) name += `-${face.weight}`;\n if (face.style) name += `-${face.style}`;\n return name;\n}\n\n/** CSS's fallback order for a style: the closest slant first, upright last. */\nconst STYLE_ORDER: Readonly<Record<string, readonly string[]>> = {\n italic: ['italic', 'oblique', 'normal'],\n oblique: ['oblique', 'italic', 'normal'],\n normal: ['normal', 'oblique', 'italic'],\n};\n\n/** A `fontWeight` as a number: `normal` and unset are 400, `bold` 700. NaN for anything else. */\nfunction weightOf(value: unknown): number {\n if (value === undefined || value === 'normal') return 400;\n if (value === 'bold') return 700;\n return Number(value);\n}\n\n/**\n * The face CSS's matching picks among one family's, for a wanted weight and style.\n *\n * Style first, then weight, as in CSS Fonts 4 section 5.2. For a weight from 400 to 500, the\n * weights up to 500 are tried first, then lighter ones, then heavier; under 400, lighter then\n * heavier; over 500, heavier then lighter. Each direction nearest first.\n */\nexport function matchFace(\n faces: readonly FontFace[],\n weight: number,\n style: string,\n): FontFace | undefined {\n const slant = (face: FontFace) => face.style ?? 'normal';\n const order = STYLE_ORDER[style] ?? STYLE_ORDER['normal']!;\n const wantedStyle = order.find((one) => faces.some((face) => slant(face) === one));\n const candidates = faces.filter((face) => slant(face) === wantedStyle);\n\n const weightOfFace = (face: FontFace) => face.weight ?? 400;\n const heavier = (from: number, to: number) =>\n candidates\n .filter((face) => weightOfFace(face) >= from && weightOfFace(face) <= to)\n .sort((a, b) => weightOfFace(a) - weightOfFace(b))[0];\n const lighter = (upTo: number) =>\n candidates\n .filter((face) => weightOfFace(face) <= upTo)\n .sort((a, b) => weightOfFace(b) - weightOfFace(a))[0];\n\n if (weight >= 400 && weight <= 500) {\n return heavier(weight, 500) ?? lighter(weight) ?? heavier(500, Infinity);\n }\n if (weight < 400) return lighter(weight) ?? heavier(weight, Infinity);\n return heavier(weight, Infinity) ?? lighter(weight);\n}\n\n/** A family as CSS compares it: without regard to case. */\nconst familyKey = (family: string) => family.toLowerCase();\n\n/** Every face the engine has seen a sheet declare, by family. */\nexport class FontFaces {\n private readonly byFamily = new Map<string, FontFace[]>();\n\n /** Take faces in; whether any was new, which changes what text already matched may match. */\n add(faces: readonly FontFace[]): boolean {\n let added = false;\n for (const face of faces) {\n const known = this.byFamily.get(familyKey(face.family));\n if (known?.some((one) => faceName(one) === faceName(face))) continue;\n if (known) known.push(face);\n else this.byFamily.set(familyKey(face.family), [face]);\n added = true;\n }\n return added;\n }\n\n /**\n * Point a resolved style's family at the face its weight and style ask for. A family nothing\n * declared is left alone, and so is the family of one whose match is the face registered under\n * the family itself.\n */\n apply(style: Record<string, unknown>): void {\n if (this.byFamily.size === 0) return;\n const family = style['fontFamily'];\n if (typeof family !== 'string') return;\n const faces = this.byFamily.get(familyKey(family));\n if (!faces) return;\n\n const weight = weightOf(style['fontWeight']);\n if (Number.isNaN(weight)) return;\n const face = matchFace(faces, weight, String(style['fontStyle'] ?? 'normal'));\n if (!face) return;\n const name = faceName(face);\n if (name !== family) style['fontFamily'] = name;\n\n if (!DROP_MATCHED_WEIGHT_AND_STYLE) return;\n // The style goes whichever face matched: a slanted face draws its slant, and beside an\n // upright one Android draws its system font slanted in place of the face, which iOS draws\n // upright anyway.\n delete style['fontStyle'];\n if (face.weight !== undefined) delete style['fontWeight'];\n }\n}\n"]}
1
+ {"version":3,"file":"font-faces.js","sourceRoot":"","sources":["../src/font-faces.ts"],"names":[],"mappings":"AAYA;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAmE;IAEnE,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;IACvB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;SACpD,IAAI,IAAI,CAAC,WAAW;QAAE,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,IAAI,IAAI,CAAC,KAAK;QAAE,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,MAAM,WAAW,GAAgD;IAC/D,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;IACvC,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACxC,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;CACxC,CAAC;AAEF,iGAAiG;AACjG,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAC1D,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,GAAG,CAAC;IACjC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,KAA0B,EAC1B,MAAc,EACd,KAAa;IAEb,MAAM,KAAK,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC;IACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAE,CAAC;IAC3D,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACnF,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC;IAEvE,2FAA2F;IAC3F,MAAM,YAAY,GAAG,CAAC,IAAc,EAAE,EAAE,CACtC,IAAI,CAAC,WAAW;QACd,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAU,EAAE,EAAE,CAC3C,UAAU;SACP,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAC/B,UAAU;SACP,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;SAC5C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1D,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,2DAA2D;AAC3D,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;AAE3D,iEAAiE;AACjE,MAAM,OAAO,SAAS;IACH,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE1D,0FAA0F;IAC1F,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,6FAA6F;IAC7F,GAAG,CAAC,KAA0B;QAC5B,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS;YACrE,IAAI,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;gBACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YACvD,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAA8B;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;QACnC,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO;QACjC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,KAAK,MAAM;YAAE,KAAK,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;QAEhD,IAAI,CAAC,6BAA6B;YAAE,OAAO;QAC3C,uFAAuF;QACvF,0FAA0F;QAC1F,kBAAkB;QAClB,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC;QAC1B,6FAA6F;QAC7F,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5D,CAAC;CACF","sourcesContent":["/**\n * Font matching, which native does not do.\n *\n * A device finds a family by name and nothing else, so each `@font-face` is registered under a\n * name of its own (`faceName`), and a text asking for a declared family with a weight or a style\n * is pointed at the face CSS would pick for it. That happens on the resolved style, after the\n * cascade, because a family and a weight often come from different rules or from an ancestor.\n */\nimport type { StyleSheet } from './css.ts';\n\ntype FontFace = NonNullable<StyleSheet['fonts']>[number];\n\n/**\n * When a face was picked, whether to drop the `fontWeight` and `fontStyle` it was picked for from\n * what is committed. The face already draws them, and kept, the platform may embolden or slant it\n * again on top.\n */\nexport const DROP_MATCHED_WEIGHT_AND_STYLE = true;\n\n/**\n * The name a face is registered under: the family, then its weight and its style where it\n * declares them. `Inter`, `Inter-600`, `Inter-italic`, `Inter-600-italic`. A variable font's\n * range is both its ends, `Inter-100to900`, so two files that split a family by range differ.\n */\nexport function faceName(\n face: Pick<FontFace, 'family' | 'weight' | 'weightRange' | 'style'>,\n): string {\n let name = face.family;\n if (face.weight !== undefined) name += `-${face.weight}`;\n else if (face.weightRange) name += `-${face.weightRange[0]}to${face.weightRange[1]}`;\n if (face.style) name += `-${face.style}`;\n return name;\n}\n\n/** CSS's fallback order for a style: the closest slant first, upright last. */\nconst STYLE_ORDER: Readonly<Record<string, readonly string[]>> = {\n italic: ['italic', 'oblique', 'normal'],\n oblique: ['oblique', 'italic', 'normal'],\n normal: ['normal', 'oblique', 'italic'],\n};\n\n/** A `fontWeight` as a number: `normal` and unset are 400, `bold` 700. NaN for anything else. */\nfunction weightOf(value: unknown): number {\n if (value === undefined || value === 'normal') return 400;\n if (value === 'bold') return 700;\n return Number(value);\n}\n\n/**\n * The face CSS's matching picks among one family's, for a wanted weight and style.\n *\n * Style first, then weight, as in CSS Fonts 4 section 5.2. For a weight from 400 to 500, the\n * weights up to 500 are tried first, then lighter ones, then heavier; under 400, lighter then\n * heavier; over 500, heavier then lighter. Each direction nearest first.\n */\nexport function matchFace(\n faces: readonly FontFace[],\n weight: number,\n style: string,\n): FontFace | undefined {\n const slant = (face: FontFace) => face.style ?? 'normal';\n const order = STYLE_ORDER[style] ?? STYLE_ORDER['normal']!;\n const wantedStyle = order.find((one) => faces.some((face) => slant(face) === one));\n const candidates = faces.filter((face) => slant(face) === wantedStyle);\n\n // A face that covers a range has every weight in it: the nearest it has to the one wanted.\n const weightOfFace = (face: FontFace) =>\n face.weightRange\n ? Math.min(Math.max(weight, face.weightRange[0]), face.weightRange[1])\n : (face.weight ?? 400);\n const heavier = (from: number, to: number) =>\n candidates\n .filter((face) => weightOfFace(face) >= from && weightOfFace(face) <= to)\n .sort((a, b) => weightOfFace(a) - weightOfFace(b))[0];\n const lighter = (upTo: number) =>\n candidates\n .filter((face) => weightOfFace(face) <= upTo)\n .sort((a, b) => weightOfFace(b) - weightOfFace(a))[0];\n\n if (weight >= 400 && weight <= 500) {\n return heavier(weight, 500) ?? lighter(weight) ?? heavier(500, Infinity);\n }\n if (weight < 400) return lighter(weight) ?? heavier(weight, Infinity);\n return heavier(weight, Infinity) ?? lighter(weight);\n}\n\n/** A family as CSS compares it: without regard to case. */\nconst familyKey = (family: string) => family.toLowerCase();\n\n/** Every face the engine has seen a sheet declare, by family. */\nexport class FontFaces {\n private readonly byFamily = new Map<string, FontFace[]>();\n\n /** Forget every face, before they are taken in again from the sheets still registered. */\n clear(): void {\n this.byFamily.clear();\n }\n\n /** Take faces in; whether any was new, which changes what text already matched may match. */\n add(faces: readonly FontFace[]): boolean {\n let added = false;\n for (const face of faces) {\n const known = this.byFamily.get(familyKey(face.family));\n if (known?.some((one) => faceName(one) === faceName(face))) continue;\n if (known) known.push(face);\n else this.byFamily.set(familyKey(face.family), [face]);\n added = true;\n }\n return added;\n }\n\n /**\n * Point a resolved style's family at the face its weight and style ask for. A family nothing\n * declared is left alone, and so is the family of one whose match is the face registered under\n * the family itself.\n */\n apply(style: Record<string, unknown>): void {\n if (this.byFamily.size === 0) return;\n const family = style['fontFamily'];\n if (typeof family !== 'string') return;\n const faces = this.byFamily.get(familyKey(family));\n if (!faces) return;\n\n const weight = weightOf(style['fontWeight']);\n if (Number.isNaN(weight)) return;\n const face = matchFace(faces, weight, String(style['fontStyle'] ?? 'normal'));\n if (!face) return;\n const name = faceName(face);\n if (name !== family) style['fontFamily'] = name;\n\n if (!DROP_MATCHED_WEIGHT_AND_STYLE) return;\n // The style goes whichever face matched: a slanted face draws its slant, and beside an\n // upright one Android draws its system font slanted in place of the face, which iOS draws\n // upright anyway.\n delete style['fontStyle'];\n // A face of one weight draws it. One that covers a range is told which, so the weight stays.\n if (face.weight !== undefined) delete style['fontWeight'];\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -11,9 +11,11 @@
11
11
  * animal and lives in `@ng-native/metro`.
12
12
  */
13
13
  export { StyleResolver, matches, styleSheetOf, type AttributeTest, type Combinator, type Compound, type Conditions, type DeferredDeclaration, type GradientTemplate, type HslChannel, type MediaCondition, type NthTest, type RuleIndex, type StyleCache, type StyleRule, type StyleSheet, type StyleTarget, type TokenKind, type TokenValue, } from './css.ts';
14
+ export { ELEMENT_STYLES, ELEMENT_STYLES_CSS } from './element-styles.ts';
14
15
  export { EngineIntersectionObserver, installDeferTriggers } from './defer-triggers.ts';
15
16
  export { faceName } from './font-faces.ts';
16
- export { DIRECT_EVENTS, Engine, SyntheticEvent, claimHost, declareNativeProps, fontsRegistered, markComponentHost, nativePlatform, onFontsRegistered, registerHoist, registerPlatformComponents, registerViewName, type PlatformViewName, type ViewNameOptions, viewNameOf, type EngineNode, type EngineOptions, type EngineStats, type FabricNode, type FabricNodeSet, type FabricUIManager, type HoistOptions, type NativeSyntheticEvent, type NodeKind, type ResponderEvent, type ResponderHandlers, type TouchPayload, type ViewNameNode, type WindowFrame, } from './engine.ts';
17
+ export { firstFamily } from './inline-token.ts';
18
+ export { DIRECT_EVENTS, Engine, SyntheticEvent, claimHost, keepNativeView, declareNativeProps, fontsLoading, fontsRegistered, fontsSettled, markComponentHost, nativePlatform, onFontsRegistered, onFontsSettled, registerHoist, registerPlatformComponents, registerViewName, type PlatformViewName, type ViewNameOptions, viewNameOf, type EngineNode, type EngineOptions, type EngineStats, type FabricNode, type FabricNodeSet, type FabricUIManager, type HoistOptions, type NativeSyntheticEvent, type NodeKind, type ResponderEvent, type ResponderHandlers, type TouchPayload, type ViewNameNode, type WindowFrame, } from './engine.ts';
17
19
  export { reportUnboundFormsInput, type NamedHostNode } from './forms-inputs.ts';
18
20
  export { HostEngine, type HostNode, type Settling } from './host.ts';
19
21
  export { getFabricUIManager } from './fabric.ts';
package/dist/index.js CHANGED
@@ -11,9 +11,11 @@
11
11
  * animal and lives in `@ng-native/metro`.
12
12
  */
13
13
  export { StyleResolver, matches, styleSheetOf, } from "./css.js";
14
+ export { ELEMENT_STYLES, ELEMENT_STYLES_CSS } from "./element-styles.js";
14
15
  export { EngineIntersectionObserver, installDeferTriggers } from "./defer-triggers.js";
15
16
  export { faceName } from "./font-faces.js";
16
- export { DIRECT_EVENTS, Engine, SyntheticEvent, claimHost, declareNativeProps, fontsRegistered, markComponentHost, nativePlatform, onFontsRegistered, registerHoist, registerPlatformComponents, registerViewName, viewNameOf, } from "./engine.js";
17
+ export { firstFamily } from "./inline-token.js";
18
+ export { DIRECT_EVENTS, Engine, SyntheticEvent, claimHost, keepNativeView, declareNativeProps, fontsLoading, fontsRegistered, fontsSettled, markComponentHost, nativePlatform, onFontsRegistered, onFontsSettled, registerHoist, registerPlatformComponents, registerViewName, viewNameOf, } from "./engine.js";
17
19
  export { reportUnboundFormsInput } from "./forms-inputs.js";
18
20
  export { HostEngine } from "./host.js";
19
21
  export { getFabricUIManager } from "./fabric.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,aAAa,EACb,OAAO,EACP,YAAY,GAiBb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EACL,aAAa,EACb,MAAM,EACN,cAAc,EACd,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,0BAA0B,EAC1B,gBAAgB,EAGhB,UAAU,GAeX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,uBAAuB,EAAsB,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAgC,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,WAAW,GAQZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,MAAM,EACN,WAAW,EACX,QAAQ,EACR,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,KAAK,GAMN,MAAM,iBAAiB,CAAC","sourcesContent":["/**\n * The engine's public surface.\n *\n * Nothing here imports Angular, and nothing here may start to: the engine stays\n * framework-agnostic (see docs/ARCHITECTURE.md), which is what keeps the commit logic testable without Angular in\n * the loop and a second adapter possible later.\n *\n * The CSS runtime lives here rather than in a package of its own because the cascade is driven\n * from the commit walk - the resolver runs per node, per tick - and because it is as\n * framework-agnostic as the rest of the engine. The build-time half of CSS is a different\n * animal and lives in `@ng-native/metro`.\n */\nexport {\n StyleResolver,\n matches,\n styleSheetOf,\n type AttributeTest,\n type Combinator,\n type Compound,\n type Conditions,\n type DeferredDeclaration,\n type GradientTemplate,\n type HslChannel,\n type MediaCondition,\n type NthTest,\n type RuleIndex,\n type StyleCache,\n type StyleRule,\n type StyleSheet,\n type StyleTarget,\n type TokenKind,\n type TokenValue,\n} from './css.ts';\nexport { EngineIntersectionObserver, installDeferTriggers } from './defer-triggers.ts';\nexport { faceName } from './font-faces.ts';\nexport {\n DIRECT_EVENTS,\n Engine,\n SyntheticEvent,\n claimHost,\n declareNativeProps,\n fontsRegistered,\n markComponentHost,\n nativePlatform,\n onFontsRegistered,\n registerHoist,\n registerPlatformComponents,\n registerViewName,\n type PlatformViewName,\n type ViewNameOptions,\n viewNameOf,\n type EngineNode,\n type EngineOptions,\n type EngineStats,\n type FabricNode,\n type FabricNodeSet,\n type FabricUIManager,\n type HoistOptions,\n type NativeSyntheticEvent,\n type NodeKind,\n type ResponderEvent,\n type ResponderHandlers,\n type TouchPayload,\n type ViewNameNode,\n type WindowFrame,\n} from './engine.ts';\nexport { reportUnboundFormsInput, type NamedHostNode } from './forms-inputs.ts';\nexport { HostEngine, type HostNode, type Settling } from './host.ts';\nexport { getFabricUIManager } from './fabric.ts';\nexport {\n pinnedRange,\n type DrivenProperty,\n type EventFeed,\n type NativeAnimated,\n type ScrollAxis,\n type ScrollDrive,\n type ScrollRange,\n type StaticTransform,\n} from './native-drive.ts';\nexport {\n bezier,\n interpolate,\n redirect,\n sample,\n settled,\n step,\n tracksOf,\n tween,\n type AnimationSpec,\n type Keyframe,\n type RunningAnimation,\n type Transition,\n type TransitionSpec,\n} from './transition.ts';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,aAAa,EACb,OAAO,EACP,YAAY,GAiBb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,aAAa,EACb,MAAM,EACN,cAAc,EACd,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,0BAA0B,EAC1B,gBAAgB,EAGhB,UAAU,GAeX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,uBAAuB,EAAsB,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAgC,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,WAAW,GAQZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,MAAM,EACN,WAAW,EACX,QAAQ,EACR,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,KAAK,GAMN,MAAM,iBAAiB,CAAC","sourcesContent":["/**\n * The engine's public surface.\n *\n * Nothing here imports Angular, and nothing here may start to: the engine stays\n * framework-agnostic (see docs/ARCHITECTURE.md), which is what keeps the commit logic testable without Angular in\n * the loop and a second adapter possible later.\n *\n * The CSS runtime lives here rather than in a package of its own because the cascade is driven\n * from the commit walk - the resolver runs per node, per tick - and because it is as\n * framework-agnostic as the rest of the engine. The build-time half of CSS is a different\n * animal and lives in `@ng-native/metro`.\n */\nexport {\n StyleResolver,\n matches,\n styleSheetOf,\n type AttributeTest,\n type Combinator,\n type Compound,\n type Conditions,\n type DeferredDeclaration,\n type GradientTemplate,\n type HslChannel,\n type MediaCondition,\n type NthTest,\n type RuleIndex,\n type StyleCache,\n type StyleRule,\n type StyleSheet,\n type StyleTarget,\n type TokenKind,\n type TokenValue,\n} from './css.ts';\nexport { ELEMENT_STYLES, ELEMENT_STYLES_CSS } from './element-styles.ts';\nexport { EngineIntersectionObserver, installDeferTriggers } from './defer-triggers.ts';\nexport { faceName } from './font-faces.ts';\nexport { firstFamily } from './inline-token.ts';\nexport {\n DIRECT_EVENTS,\n Engine,\n SyntheticEvent,\n claimHost,\n keepNativeView,\n declareNativeProps,\n fontsLoading,\n fontsRegistered,\n fontsSettled,\n markComponentHost,\n nativePlatform,\n onFontsRegistered,\n onFontsSettled,\n registerHoist,\n registerPlatformComponents,\n registerViewName,\n type PlatformViewName,\n type ViewNameOptions,\n viewNameOf,\n type EngineNode,\n type EngineOptions,\n type EngineStats,\n type FabricNode,\n type FabricNodeSet,\n type FabricUIManager,\n type HoistOptions,\n type NativeSyntheticEvent,\n type NodeKind,\n type ResponderEvent,\n type ResponderHandlers,\n type TouchPayload,\n type ViewNameNode,\n type WindowFrame,\n} from './engine.ts';\nexport { reportUnboundFormsInput, type NamedHostNode } from './forms-inputs.ts';\nexport { HostEngine, type HostNode, type Settling } from './host.ts';\nexport { getFabricUIManager } from './fabric.ts';\nexport {\n pinnedRange,\n type DrivenProperty,\n type EventFeed,\n type NativeAnimated,\n type ScrollAxis,\n type ScrollDrive,\n type ScrollRange,\n type StaticTransform,\n} from './native-drive.ts';\nexport {\n bezier,\n interpolate,\n redirect,\n sample,\n settled,\n step,\n tracksOf,\n tween,\n type AnimationSpec,\n type Keyframe,\n type RunningAnimation,\n type Transition,\n type TransitionSpec,\n} from './transition.ts';\n"]}
@@ -12,14 +12,15 @@
12
12
  * colours written out. Anything else is undefined, as a stylesheet refuses it.
13
13
  */
14
14
  import { MIX_SPACES } from "./color-mix.js";
15
- import { tokenFromValue } from "./inline-token.js";
16
- const SPACE = /\s*/y;
17
- const FUNCTION = /([a-z][a-z-]*)\(\s*/iy;
18
- const VAR = /var\(\s*(--[\w-]+)\s*/iy;
15
+ import { cssTrim, tokenFromValue } from "./inline-token.js";
16
+ /** CSS whitespace, and no other: a no-break space is part of a word, as it is in a browser. */
17
+ const SPACE = /[ \t\n\r\f]*/y;
18
+ const FUNCTION = /([a-z][a-z-]*)\([ \t\n\r\f]*/iy;
19
+ const VAR = /var\([ \t\n\r\f]*(--[\w-]+)[ \t\n\r\f]*/iy;
19
20
  const LITERAL = /([+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)(%|[a-z]+)?/iy;
20
- const WORD = /[^\s,/()]+/y;
21
+ const WORD = /[^ \t\n\r\f,/()]+/y;
21
22
  /** A fallback that is a `var()` or arithmetic, rather than a value written out. */
22
- const NESTED = /^\s*(var|calc|min|max)\(/i;
23
+ const NESTED = /^[ \t\n\r\f]*(var|calc|min|max)\(/i;
23
24
  /** What one of each unit counts as: points, degrees, milliseconds, or itself. */
24
25
  const PER_UNIT = {
25
26
  '': 1,
@@ -149,14 +150,14 @@ function factor(cursor, kind) {
149
150
  */
150
151
  function leafFallback(text, kind) {
151
152
  if (text !== undefined && NESTED.test(text)) {
152
- return whole(text.trim(), (cursor) => factor(cursor, kind)) ?? fail();
153
+ return whole(cssTrim(text), (cursor) => factor(cursor, kind)) ?? fail();
153
154
  }
154
155
  const token = fallbackToken(text);
155
156
  if (kind !== 'length')
156
157
  return numberFallback(token, kind);
157
158
  if (typeof token?.length === 'number')
158
159
  return token.length;
159
- const rem = text === undefined ? undefined : /^\s*(-?\d*\.?\d+)rem\s*$/i.exec(text);
160
+ const rem = text === undefined ? undefined : /^[ \t\n\r\f]*(-?\d*\.?\d+)rem[ \t\n\r\f]*$/i.exec(text);
160
161
  return rem ? Number(rem[1]) * PER_UNIT['rem'] : undefined;
161
162
  }
162
163
  /** A fallback where a number is wanted: a percentage kept apart from a bare number. */
@@ -288,8 +289,8 @@ function closing(cursor) {
288
289
  */
289
290
  function referenceColour({ reference: name, fallback }) {
290
291
  const alternatives = [];
291
- let rest = fallback?.trim();
292
- for (let next; rest && (next = whole(rest, nextReference)); rest = next.fallback?.trim()) {
292
+ let rest = fallback === undefined ? undefined : cssTrim(fallback);
293
+ for (let next; rest && (next = whole(rest, nextReference)); rest = next.fallback === undefined ? undefined : cssTrim(next.fallback)) {
293
294
  alternatives.push(next.reference);
294
295
  }
295
296
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"inline-derived-token.js","sourceRoot":"","sources":["../src/inline-derived-token.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A custom property set on an element to a value with a `var()` inside it,\n * `[style.--size]=\"'calc(var(--gap) * 2)'\"`, read into the form the same text in a stylesheet is\n * compiled to, which the cascade then works out where it is set, as it does that one\n * (`resolveAliases` in css.ts).\n *\n * The shapes are the build-time conversion's and no more (`deferCalcToken`, `deferHslToken`,\n * `deferChannelsToken` and `deferMixToken` in `@ng-native/metro/css/compile.cjs`): `calc()`,\n * `min()` or `max()` of numbers, lengths in `px` or `rem`, angles, times and `var()`, with + - * /\n * and brackets; an `hsl()` with a `var()` for a channel; `rgb()` or `hsl()` of one channels token,\n * with an alpha written or tokened; and a `color-mix()` of any of these colours, tokens and\n * colours written out. Anything else is undefined, as a stylesheet refuses it.\n */\nimport { MIX_SPACES, type HueMethod, type MixSpace } from './color-mix.ts';\nimport type { Channel } from './relative-colour.ts';\nimport type { ColourExpression, HslChannel, TokenValue } from './css.ts';\nimport { tokenFromValue } from './inline-token.ts';\n\ntype Marker = NonNullable<TokenValue['deferredCalc']>[number];\ntype Expression = Marker['expression'];\ntype Alpha = Extract<NonNullable<TokenValue['deferredColour']>, { channels: unknown }>['alpha'];\n\ninterface Cursor {\n readonly text: string;\n at: number;\n}\n\n/** A `var()`: the token it names, and the text of its fallback, read as its slot wants it. */\ninterface Reference {\n readonly reference: string;\n readonly fallback?: string;\n}\n\nconst SPACE = /\\s*/y;\nconst FUNCTION = /([a-z][a-z-]*)\\(\\s*/iy;\nconst VAR = /var\\(\\s*(--[\\w-]+)\\s*/iy;\nconst LITERAL = /([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?)(%|[a-z]+)?/iy;\nconst WORD = /[^\\s,/()]+/y;\n/** A fallback that is a `var()` or arithmetic, rather than a value written out. */\nconst NESTED = /^\\s*(var|calc|min|max)\\(/i;\n/** What one of each unit counts as: points, degrees, milliseconds, or itself. */\nconst PER_UNIT: Readonly<Record<string, number>> = {\n '': 1,\n px: 1,\n rem: 16,\n deg: 1,\n grad: 0.9,\n rad: 180 / Math.PI,\n turn: 360,\n ms: 1,\n s: 1000,\n};\nconst PERCENTAGE = /([+-]?(?:\\d+\\.?\\d*|\\.\\d+))%/y;\nconst HUE_UNITS: ReadonlySet<string> = new Set(['', 'deg', 'grad', 'rad', 'turn']);\nconst HUE_METHODS: ReadonlySet<string> = new Set(['shorter', 'longer', 'increasing', 'decreasing']);\nconst MATH: ReadonlySet<string> = new Set(['calc', 'min', 'max']);\nconst SPACES: Readonly<Record<string, 'rgb' | 'hsl'>> = {\n rgb: 'rgb',\n rgba: 'rgb',\n hsl: 'hsl',\n hsla: 'hsl',\n};\n\n/** Thrown where the text stops being one of the shapes, and caught by `whole`. */\nconst UNREADABLE = new Error('not a token made of others');\nconst fail = (): never => {\n throw UNREADABLE;\n};\n\nfunction match(cursor: Cursor, pattern: RegExp): RegExpExecArray | null {\n pattern.lastIndex = cursor.at;\n const found = pattern.exec(cursor.text);\n if (found) cursor.at = pattern.lastIndex;\n return found;\n}\n\n/** Whether the next character, past any space, is `char`; taken, with the space after it, if so. */\nfunction take(cursor: Cursor, char: string): boolean {\n match(cursor, SPACE);\n if (cursor.text[cursor.at] !== char) return false;\n cursor.at++;\n match(cursor, SPACE);\n return true;\n}\n\nfunction expect(cursor: Cursor, char: string): void {\n if (!take(cursor, char)) fail();\n}\n\n/** The whole text as `read` reads it, or undefined when it is not that shape. */\nfunction whole<T>(text: string, read: (cursor: Cursor) => T): T | undefined {\n const cursor = { text, at: 0 };\n try {\n const value = read(cursor);\n match(cursor, SPACE);\n return cursor.at === text.length ? value : undefined;\n } catch (error) {\n if (error === UNREADABLE) return undefined;\n throw error;\n }\n}\n\n/** A `var()` from its name on, to the bracket that closes it. */\nfunction reference(cursor: Cursor, name: string): Reference {\n if (take(cursor, ')')) return { reference: name };\n expect(cursor, ',');\n const start = cursor.at;\n for (let depth = 0; cursor.at < cursor.text.length; cursor.at++) {\n const char = cursor.text[cursor.at];\n if (char === '(') depth++;\n else if (char === ')' && depth-- === 0) break;\n }\n const fallback = cursor.text.slice(start, cursor.at);\n expect(cursor, ')');\n return { reference: name, fallback };\n}\n\n/** A fallback's token. One that is another `var()` is refused, as the compiler refuses it. */\nfunction fallbackToken(text: string | undefined): TokenValue | undefined {\n const token = text === undefined ? undefined : tokenFromValue(text);\n return token?.alias ? fail() : token;\n}\n\n/** A number, length, angle or time, as the number its slot counts in. */\nfunction literal(cursor: Cursor, units: (unit: string) => number | undefined): number {\n const found = match(cursor, LITERAL) ?? fail();\n return Number(found[1]) * (units((found[2] ?? '').toLowerCase()) ?? fail());\n}\n\n/** A number slot takes a percentage as a fraction, which a length slot cannot work out. */\nconst unitsOf =\n (kind: Marker['kind']) =>\n (unit: string): number | undefined =>\n unit === '%' ? (kind === 'number' ? 0.01 : undefined) : PER_UNIT[unit];\n\nfunction sum(cursor: Cursor, kind: Marker['kind']): Expression {\n let value = product(cursor, kind);\n for (let op; (op = (['+', '-'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, product(cursor, kind)];\n }\n return value;\n}\n\nfunction product(cursor: Cursor, kind: Marker['kind']): Expression {\n let value = factor(cursor, kind);\n for (let op; (op = (['*', '/'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, factor(cursor, kind)];\n }\n return value;\n}\n\nfunction factor(cursor: Cursor, kind: Marker['kind']): Expression {\n if (take(cursor, '(')) {\n const value = sum(cursor, kind);\n expect(cursor, ')');\n return value;\n }\n const name = match(cursor, VAR)?.[1];\n if (name) {\n const value = leafFallback(reference(cursor, name).fallback, kind);\n return value === undefined ? { reference: name } : { reference: name, fallback: value };\n }\n const fn = match(cursor, FUNCTION)?.[1];\n if (fn) return math(cursor, fn, kind);\n const value = literal(cursor, unitsOf(kind));\n // A percentage, kept apart from a bare number, as `literal` in the compiler keeps it.\n return cursor.text[cursor.at - 1] === '%' ? { percentage: value } : value;\n}\n\n/**\n * A `var()` fallback in arithmetic, as its slot reads it: another `var()` or arithmetic of its\n * own, read as a tree, `var(--a, calc(var(--gap) * 2))`, as `leaf` in the compiler reads it; a\n * length in points, `rem` included as the compiler counts it; or a bare number.\n */\nfunction leafFallback(text: string | undefined, kind: Marker['kind']): Expression | undefined {\n if (text !== undefined && NESTED.test(text)) {\n return whole(text.trim(), (cursor) => factor(cursor, kind)) ?? fail();\n }\n const token = fallbackToken(text);\n if (kind !== 'length') return numberFallback(token, kind);\n if (typeof token?.length === 'number') return token.length;\n const rem = text === undefined ? undefined : /^\\s*(-?\\d*\\.?\\d+)rem\\s*$/i.exec(text);\n return rem ? Number(rem[1]) * PER_UNIT['rem']! : undefined;\n}\n\n/** A fallback where a number is wanted: a percentage kept apart from a bare number. */\nfunction numberFallback(\n token: TokenValue | undefined,\n kind: Marker['kind'],\n): Expression | undefined {\n const percentage =\n kind === 'number' && typeof token?.length === 'string' && token.number !== undefined;\n return percentage ? { percentage: token.number! } : token?.number;\n}\n\n/** The rest of a `calc()`, or of a `min()` or `max()` of sums, once its name is read. */\nfunction math(cursor: Cursor, fn: string, kind: Marker['kind']): Expression {\n const name = fn.toLowerCase();\n if (!MATH.has(name)) fail();\n const sides = [sum(cursor, kind)];\n while (name !== 'calc' && take(cursor, ',')) sides.push(sum(cursor, kind));\n expect(cursor, ')');\n return sides.reduce((a, b) => [name as 'min' | 'max', a, b]);\n}\n\n/** Arithmetic of tokens, read as a length and as a number, whichever each reading makes of it. */\nfunction calcToken(text: string): TokenValue | undefined {\n const markers = (['length', 'number'] as const).flatMap((kind): Marker[] => {\n const expression = whole(text, (cursor) =>\n math(cursor, (match(cursor, FUNCTION) ?? fail())[1]!, kind),\n );\n return expression === undefined ? [] : [{ expression, kind }];\n });\n return markers.length ? { deferredCalc: markers } : undefined;\n}\n\n/** An argument of a colour function: a `var()`, or a word read as its slot wants it. */\ntype Argument = Reference | { readonly word: string };\n\n/**\n * A colour function's arguments, with the commas and the slash between them gone, and whether\n * commas were what separated them.\n */\nfunction colourArguments(cursor: Cursor): {\n space: 'rgb' | 'hsl';\n args: Argument[];\n legacy: boolean;\n} {\n const space = SPACES[(match(cursor, FUNCTION) ?? fail())[1]!.toLowerCase()] ?? fail();\n const args: Argument[] = [];\n let legacy = false;\n while (!take(cursor, ')')) {\n if (take(cursor, ',')) legacy = true;\n else if (!take(cursor, '/')) {\n const name = match(cursor, VAR)?.[1];\n args.push(name ? reference(cursor, name) : { word: (match(cursor, WORD) ?? fail())[0] });\n }\n }\n return { space, args, legacy };\n}\n\n/** What each argument of an `hsl()` is: a hue, a saturation and a lightness, then an alpha. */\nconst HSL_SLOTS = ['hue', 'percentage', 'percentage', 'alpha'] as const;\n\n/**\n * A written `hsl()` channel as its slot reads it, as `hslLiteral` in the compiler does: a hue in\n * degrees; a saturation or a lightness as a fraction, from a percentage or, in the space syntax\n * only, a bare number of percent; an alpha as a number or a fraction.\n */\nfunction hslLiteral(\n text: string,\n slot: (typeof HSL_SLOTS)[number],\n legacy: boolean,\n): number | undefined {\n const perUnit = (unit: string): number | undefined => {\n if (slot === 'hue') return HUE_UNITS.has(unit) ? PER_UNIT[unit] : undefined;\n if (unit === '%') return 0.01;\n if (unit !== '') return undefined;\n return slot === 'alpha' ? 1 : legacy ? undefined : 0.01;\n };\n return whole(text, (cursor) => literal(cursor, perUnit));\n}\n\nfunction hslChannel(arg: Argument, index: number, legacy: boolean): HslChannel {\n const slot = HSL_SLOTS[index]!;\n if ('word' in arg) return hslLiteral(arg.word, slot, legacy) ?? fail();\n const fallback = arg.fallback === undefined ? undefined : hslLiteral(arg.fallback, slot, legacy);\n return fallback === undefined\n ? { reference: arg.reference }\n : { reference: arg.reference, fallback };\n}\n\n/** A channels colour's alpha: none, written as a number or a percentage, or a token of its own. */\nfunction alphaOf(arg: Argument | undefined): Alpha {\n if (arg === undefined) return undefined;\n if ('word' in arg) {\n return whole(arg.word, (cursor) => literal(cursor, unitsOf('number'))) ?? fail();\n }\n const fallback = fallbackToken(arg.fallback)?.number;\n return fallback === undefined\n ? { reference: arg.reference }\n : { reference: arg.reference, fallback };\n}\n\n/** `rgba(var(--channels), <alpha>)`, as `deferChannelsToken` reads it. */\nfunction channelsToken(\n channels: Reference,\n alpha: Argument | undefined,\n space: 'rgb' | 'hsl',\n): TokenValue {\n const token = fallbackToken(channels.fallback);\n const fallback = space === 'hsl' ? token?.hslChannels : token?.channels;\n const opacity = alphaOf(alpha);\n return {\n deferredColour: {\n channels: { reference: channels.reference, ...(fallback ? { fallback } : {}), space },\n ...(opacity === undefined ? {} : { alpha: opacity }),\n },\n };\n}\n\n/** `hsl(var(--h) 100% 50%)` and the like, as `deferHslToken` reads it. */\nfunction hslToken(args: readonly Argument[], legacy: boolean): TokenValue {\n if (args.length !== 3 && args.length !== 4) fail();\n const [h, s, l, alpha] = args.map((arg, index) => hslChannel(arg, index, legacy));\n const legacyFlag = legacy ? { legacy: true as const } : {};\n return { hsl: { h: h!, s: s!, l: l!, ...(alpha === undefined ? {} : { alpha }), ...legacyFlag } };\n}\n\nfunction colourToken(text: string): TokenValue | undefined {\n return whole(text, (cursor) => {\n const { space, args, legacy } = colourArguments(cursor);\n const [channels, alpha, ...rest] = args;\n if (channels && 'reference' in channels && !rest.length) {\n return channelsToken(channels, alpha, space);\n }\n return space === 'hsl' ? hslToken(args, legacy) : fail();\n });\n}\n\n/** The index just past the bracket that closes the function the cursor is inside. */\nfunction closing(cursor: Cursor): number {\n for (let at = cursor.at, depth = 0; at < cursor.text.length; at++) {\n const char = cursor.text[at];\n if (char === '(') depth++;\n else if (char === ')' && depth-- === 0) return at + 1;\n }\n return fail();\n}\n\n/**\n * A `var()` in a colour, as `reference` in the compiler's colour-expression.cjs reads it: the\n * tokens its `var()` fallbacks name, tried in turn, then a colour, or one made of other tokens.\n */\nfunction referenceColour({ reference: name, fallback }: Reference): ColourExpression {\n const alternatives: string[] = [];\n let rest = fallback?.trim();\n for (let next; rest && (next = whole(rest, nextReference)); rest = next.fallback?.trim()) {\n alternatives.push(next.reference);\n }\n return {\n reference: name,\n ...(alternatives.length ? { alternatives } : {}),\n ...(rest ? colourFallback(rest) : {}),\n };\n}\n\n/** The colour a `var()` falls back to, or one made of other tokens; refused when it is neither. */\nfunction colourFallback(text: string): { fallback: string } | { fallbackToken: TokenValue } {\n const token = tokenFromValue(text);\n if (token?.hsl || token?.deferredColour) return { fallbackToken: token };\n return { fallback: token?.color ?? fail() };\n}\n\nconst nextReference = (cursor: Cursor): Reference =>\n reference(cursor, (match(cursor, VAR) ?? fail())[1]!);\n\n/**\n * One colour in a `color-mix()`: a `var()`, another mix, an `rgb()` or `hsl()` of tokens, or a\n * colour written out, which is kept as written for the mix to read.\n */\nfunction mixColour(cursor: Cursor): ColourExpression {\n const name = match(cursor, VAR)?.[1];\n if (name) return referenceColour(reference(cursor, name));\n const start = cursor.at;\n const fn = match(cursor, FUNCTION)?.[1]?.toLowerCase();\n if (fn === 'color-mix') return mixExpression(cursor);\n if (!fn) return { color: (match(cursor, WORD) ?? fail())[0] };\n if (RELATIVE[fn] && takeWord(cursor, 'from')) return relativeExpression(cursor, RELATIVE[fn]);\n cursor.at = closing(cursor);\n return functionColour(cursor.text.slice(start, cursor.at));\n}\n\n/** A colour function in a mix: of tokens, as a token of it is read, or written out, as it is. */\nfunction functionColour(text: string): ColourExpression {\n if (!text.includes('var(')) return { color: text };\n const token = colourToken(text);\n return token?.hsl ? { hsl: token.hsl } : (token?.deferredColour ?? fail());\n}\n\n/** One side of a mix: its colour, and the percentage written before or after it, if one is. */\nfunction mixSide(cursor: Cursor): { colour: ColourExpression; percentage?: number } {\n const percentage = () => {\n const found = match(cursor, PERCENTAGE);\n match(cursor, SPACE);\n return found ? Number(found[1]) : undefined;\n };\n const before = percentage();\n const colour = mixColour(cursor);\n match(cursor, SPACE);\n const after = before === undefined ? percentage() : undefined;\n const written = before ?? after;\n return written === undefined ? { colour } : { colour, percentage: written };\n}\n\n/**\n * The rest of a `color-mix(in <space> [<method> hue], <colour> [p%], <colour> [q%])` once its name\n * is read, as `mixExpression` in the compiler reads it.\n */\nfunction mixExpression(cursor: Cursor): ColourExpression {\n const words: string[] = [];\n while (!take(cursor, ',')) {\n words.push((match(cursor, WORD) ?? fail())[0].toLowerCase());\n match(cursor, SPACE);\n }\n const [keyword, space, method, hue, ...rest] = words;\n if (keyword !== 'in' || !MIX_SPACES.has(space!) || rest.length) fail();\n if (method !== undefined && (hue !== 'hue' || !HUE_METHODS.has(method))) fail();\n const a = mixSide(cursor);\n expect(cursor, ',');\n const b = mixSide(cursor);\n expect(cursor, ')');\n return {\n mix: {\n space: space as MixSpace,\n ...(method ? { hue: method as HueMethod } : {}),\n a: a.colour,\n ...(a.percentage === undefined ? {} : { aPercentage: a.percentage }),\n b: b.colour,\n ...(b.percentage === undefined ? {} : { bPercentage: b.percentage }),\n },\n };\n}\n\n/** A whole `color-mix()`, worked out where it is set, as `deferMixToken` in the compiler reads it. */\nfunction mixToken(text: string): TokenValue | undefined {\n const deferredColour = whole(text, (cursor) => {\n const colour = mixColour(cursor);\n return 'mix' in colour || 'relative' in colour ? colour : fail();\n });\n return deferredColour && { deferredColour };\n}\n\ninterface RelativeSpace {\n readonly space: MixSpace;\n readonly keywords: readonly string[];\n /** What 100% of each channel is; null for a hue, which takes an angle instead. */\n readonly full: readonly (number | null)[];\n}\n\n/** Each relative colour function, as `RELATIVE` in the compiler's colour-expression.cjs. */\nconst RELATIVE: Readonly<Record<string, RelativeSpace>> = {\n rgb: { space: 'srgb', keywords: ['r', 'g', 'b'], full: [255, 255, 255] },\n rgba: { space: 'srgb', keywords: ['r', 'g', 'b'], full: [255, 255, 255] },\n hsl: { space: 'hsl', keywords: ['h', 's', 'l'], full: [null, 100, 100] },\n hsla: { space: 'hsl', keywords: ['h', 's', 'l'], full: [null, 100, 100] },\n hwb: { space: 'hwb', keywords: ['h', 'w', 'b'], full: [null, 100, 100] },\n lab: { space: 'lab', keywords: ['l', 'a', 'b'], full: [100, 125, 125] },\n lch: { space: 'lch', keywords: ['l', 'c', 'h'], full: [100, 150, null] },\n oklab: { space: 'oklab', keywords: ['l', 'a', 'b'], full: [1, 0.4, 0.4] },\n oklch: { space: 'oklch', keywords: ['l', 'c', 'h'], full: [1, 0.4, null] },\n};\n\n/** Whether the next word is `word`, in any case; taken, with the space after it, if so. */\nfunction takeWord(cursor: Cursor, word: string): boolean {\n const start = cursor.at;\n if (match(cursor, WORD)?.[0].toLowerCase() === word) {\n match(cursor, SPACE);\n return true;\n }\n cursor.at = start;\n return false;\n}\n\n/**\n * The rest of `<space>(from <colour> <channel> <channel> <channel> [/ <alpha>])` once `from` is\n * read, as `relativeExpression` in the compiler reads it.\n */\nfunction relativeExpression(cursor: Cursor, { space, keywords, full }: RelativeSpace) {\n const from = mixColour(cursor);\n const names = [...keywords, 'alpha'];\n const channels = [0, 1, 2].map((index) => {\n match(cursor, SPACE);\n return relativeChannel(cursor, names, full[index]!);\n }) as [Channel, Channel, Channel];\n const alpha = take(cursor, '/') ? relativeChannel(cursor, names, 1) : undefined;\n expect(cursor, ')');\n return { relative: { space, from, channels, ...(alpha === undefined ? {} : { alpha }) } };\n}\n\n/**\n * One channel: a `calc()` of numbers and keywords, a keyword, a number, a percentage of the\n * channel's range, or an angle for a hue.\n */\nfunction relativeChannel(cursor: Cursor, keywords: readonly string[], full: number | null) {\n const fn = match(cursor, FUNCTION)?.[1]?.toLowerCase();\n if (fn) {\n const value = fn === 'calc' ? channelSum(cursor, keywords) : fail();\n expect(cursor, ')');\n return value;\n }\n const found = match(cursor, LITERAL);\n if (!found) return channelOperand(cursor, keywords);\n const value = Number(found[1]) * channelScale((found[2] ?? '').toLowerCase(), full);\n return Number.isFinite(value) ? value : fail();\n}\n\n/** What one of a written channel's unit is: a share of its range, degrees of a hue, or itself. */\nfunction channelScale(unit: string, full: number | null): number {\n if (unit === '%') return full === null ? NaN : full / 100;\n if (full !== null) return unit ? NaN : 1;\n return HUE_UNITS.has(unit) ? PER_UNIT[unit]! : NaN;\n}\n\n/** `a + b - c`, each side a product of numbers, keywords and bracketed sums. */\nfunction channelSum(cursor: Cursor, keywords: readonly string[]): Channel {\n let value = channelProduct(cursor, keywords);\n for (let op; (op = (['+', '-'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, channelProduct(cursor, keywords)];\n }\n return value;\n}\n\nfunction channelProduct(cursor: Cursor, keywords: readonly string[]): Channel {\n let value = channelFactor(cursor, keywords);\n for (let op; (op = (['*', '/'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, channelFactor(cursor, keywords)];\n }\n return value;\n}\n\nfunction channelFactor(cursor: Cursor, keywords: readonly string[]): Channel {\n if (take(cursor, '(')) {\n const value = channelSum(cursor, keywords);\n expect(cursor, ')');\n return value;\n }\n const found = match(cursor, LITERAL);\n // A percentage or an angle stands alone: inside arithmetic the keywords are numbers.\n if (found) return found[2] ? fail() : Number(found[1]);\n return channelOperand(cursor, keywords);\n}\n\nfunction channelOperand(cursor: Cursor, keywords: readonly string[]): string {\n const word = (match(cursor, WORD) ?? fail())[0];\n return keywords.includes(word) ? word : fail();\n}\n\n/**\n * A value with a `var()` inside it, or a `color-mix()`, as a token made of others; undefined if it\n * is no such shape.\n */\nexport function derivedToken(text: string): TokenValue | undefined {\n return calcToken(text) ?? colourToken(text) ?? mixToken(text);\n}\n"]}
1
+ {"version":3,"file":"inline-derived-token.js","sourceRoot":"","sources":["../src/inline-derived-token.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A custom property set on an element to a value with a `var()` inside it,\n * `[style.--size]=\"'calc(var(--gap) * 2)'\"`, read into the form the same text in a stylesheet is\n * compiled to, which the cascade then works out where it is set, as it does that one\n * (`resolveAliases` in css.ts).\n *\n * The shapes are the build-time conversion's and no more (`deferCalcToken`, `deferHslToken`,\n * `deferChannelsToken` and `deferMixToken` in `@ng-native/metro/css/compile.cjs`): `calc()`,\n * `min()` or `max()` of numbers, lengths in `px` or `rem`, angles, times and `var()`, with + - * /\n * and brackets; an `hsl()` with a `var()` for a channel; `rgb()` or `hsl()` of one channels token,\n * with an alpha written or tokened; and a `color-mix()` of any of these colours, tokens and\n * colours written out. Anything else is undefined, as a stylesheet refuses it.\n */\nimport { MIX_SPACES, type HueMethod, type MixSpace } from './color-mix.ts';\nimport type { Channel } from './relative-colour.ts';\nimport type { ColourExpression, HslChannel, TokenValue } from './css.ts';\nimport { cssTrim, tokenFromValue } from './inline-token.ts';\n\ntype Marker = NonNullable<TokenValue['deferredCalc']>[number];\ntype Expression = Marker['expression'];\ntype Alpha = Extract<NonNullable<TokenValue['deferredColour']>, { channels: unknown }>['alpha'];\n\ninterface Cursor {\n readonly text: string;\n at: number;\n}\n\n/** A `var()`: the token it names, and the text of its fallback, read as its slot wants it. */\ninterface Reference {\n readonly reference: string;\n readonly fallback?: string;\n}\n\n/** CSS whitespace, and no other: a no-break space is part of a word, as it is in a browser. */\nconst SPACE = /[ \\t\\n\\r\\f]*/y;\nconst FUNCTION = /([a-z][a-z-]*)\\([ \\t\\n\\r\\f]*/iy;\nconst VAR = /var\\([ \\t\\n\\r\\f]*(--[\\w-]+)[ \\t\\n\\r\\f]*/iy;\nconst LITERAL = /([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?)(%|[a-z]+)?/iy;\nconst WORD = /[^ \\t\\n\\r\\f,/()]+/y;\n/** A fallback that is a `var()` or arithmetic, rather than a value written out. */\nconst NESTED = /^[ \\t\\n\\r\\f]*(var|calc|min|max)\\(/i;\n/** What one of each unit counts as: points, degrees, milliseconds, or itself. */\nconst PER_UNIT: Readonly<Record<string, number>> = {\n '': 1,\n px: 1,\n rem: 16,\n deg: 1,\n grad: 0.9,\n rad: 180 / Math.PI,\n turn: 360,\n ms: 1,\n s: 1000,\n};\nconst PERCENTAGE = /([+-]?(?:\\d+\\.?\\d*|\\.\\d+))%/y;\nconst HUE_UNITS: ReadonlySet<string> = new Set(['', 'deg', 'grad', 'rad', 'turn']);\nconst HUE_METHODS: ReadonlySet<string> = new Set(['shorter', 'longer', 'increasing', 'decreasing']);\nconst MATH: ReadonlySet<string> = new Set(['calc', 'min', 'max']);\nconst SPACES: Readonly<Record<string, 'rgb' | 'hsl'>> = {\n rgb: 'rgb',\n rgba: 'rgb',\n hsl: 'hsl',\n hsla: 'hsl',\n};\n\n/** Thrown where the text stops being one of the shapes, and caught by `whole`. */\nconst UNREADABLE = new Error('not a token made of others');\nconst fail = (): never => {\n throw UNREADABLE;\n};\n\nfunction match(cursor: Cursor, pattern: RegExp): RegExpExecArray | null {\n pattern.lastIndex = cursor.at;\n const found = pattern.exec(cursor.text);\n if (found) cursor.at = pattern.lastIndex;\n return found;\n}\n\n/** Whether the next character, past any space, is `char`; taken, with the space after it, if so. */\nfunction take(cursor: Cursor, char: string): boolean {\n match(cursor, SPACE);\n if (cursor.text[cursor.at] !== char) return false;\n cursor.at++;\n match(cursor, SPACE);\n return true;\n}\n\nfunction expect(cursor: Cursor, char: string): void {\n if (!take(cursor, char)) fail();\n}\n\n/** The whole text as `read` reads it, or undefined when it is not that shape. */\nfunction whole<T>(text: string, read: (cursor: Cursor) => T): T | undefined {\n const cursor = { text, at: 0 };\n try {\n const value = read(cursor);\n match(cursor, SPACE);\n return cursor.at === text.length ? value : undefined;\n } catch (error) {\n if (error === UNREADABLE) return undefined;\n throw error;\n }\n}\n\n/** A `var()` from its name on, to the bracket that closes it. */\nfunction reference(cursor: Cursor, name: string): Reference {\n if (take(cursor, ')')) return { reference: name };\n expect(cursor, ',');\n const start = cursor.at;\n for (let depth = 0; cursor.at < cursor.text.length; cursor.at++) {\n const char = cursor.text[cursor.at];\n if (char === '(') depth++;\n else if (char === ')' && depth-- === 0) break;\n }\n const fallback = cursor.text.slice(start, cursor.at);\n expect(cursor, ')');\n return { reference: name, fallback };\n}\n\n/** A fallback's token. One that is another `var()` is refused, as the compiler refuses it. */\nfunction fallbackToken(text: string | undefined): TokenValue | undefined {\n const token = text === undefined ? undefined : tokenFromValue(text);\n return token?.alias ? fail() : token;\n}\n\n/** A number, length, angle or time, as the number its slot counts in. */\nfunction literal(cursor: Cursor, units: (unit: string) => number | undefined): number {\n const found = match(cursor, LITERAL) ?? fail();\n return Number(found[1]) * (units((found[2] ?? '').toLowerCase()) ?? fail());\n}\n\n/** A number slot takes a percentage as a fraction, which a length slot cannot work out. */\nconst unitsOf =\n (kind: Marker['kind']) =>\n (unit: string): number | undefined =>\n unit === '%' ? (kind === 'number' ? 0.01 : undefined) : PER_UNIT[unit];\n\nfunction sum(cursor: Cursor, kind: Marker['kind']): Expression {\n let value = product(cursor, kind);\n for (let op; (op = (['+', '-'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, product(cursor, kind)];\n }\n return value;\n}\n\nfunction product(cursor: Cursor, kind: Marker['kind']): Expression {\n let value = factor(cursor, kind);\n for (let op; (op = (['*', '/'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, factor(cursor, kind)];\n }\n return value;\n}\n\nfunction factor(cursor: Cursor, kind: Marker['kind']): Expression {\n if (take(cursor, '(')) {\n const value = sum(cursor, kind);\n expect(cursor, ')');\n return value;\n }\n const name = match(cursor, VAR)?.[1];\n if (name) {\n const value = leafFallback(reference(cursor, name).fallback, kind);\n return value === undefined ? { reference: name } : { reference: name, fallback: value };\n }\n const fn = match(cursor, FUNCTION)?.[1];\n if (fn) return math(cursor, fn, kind);\n const value = literal(cursor, unitsOf(kind));\n // A percentage, kept apart from a bare number, as `literal` in the compiler keeps it.\n return cursor.text[cursor.at - 1] === '%' ? { percentage: value } : value;\n}\n\n/**\n * A `var()` fallback in arithmetic, as its slot reads it: another `var()` or arithmetic of its\n * own, read as a tree, `var(--a, calc(var(--gap) * 2))`, as `leaf` in the compiler reads it; a\n * length in points, `rem` included as the compiler counts it; or a bare number.\n */\nfunction leafFallback(text: string | undefined, kind: Marker['kind']): Expression | undefined {\n if (text !== undefined && NESTED.test(text)) {\n return whole(cssTrim(text), (cursor) => factor(cursor, kind)) ?? fail();\n }\n const token = fallbackToken(text);\n if (kind !== 'length') return numberFallback(token, kind);\n if (typeof token?.length === 'number') return token.length;\n const rem =\n text === undefined ? undefined : /^[ \\t\\n\\r\\f]*(-?\\d*\\.?\\d+)rem[ \\t\\n\\r\\f]*$/i.exec(text);\n return rem ? Number(rem[1]) * PER_UNIT['rem']! : undefined;\n}\n\n/** A fallback where a number is wanted: a percentage kept apart from a bare number. */\nfunction numberFallback(\n token: TokenValue | undefined,\n kind: Marker['kind'],\n): Expression | undefined {\n const percentage =\n kind === 'number' && typeof token?.length === 'string' && token.number !== undefined;\n return percentage ? { percentage: token.number! } : token?.number;\n}\n\n/** The rest of a `calc()`, or of a `min()` or `max()` of sums, once its name is read. */\nfunction math(cursor: Cursor, fn: string, kind: Marker['kind']): Expression {\n const name = fn.toLowerCase();\n if (!MATH.has(name)) fail();\n const sides = [sum(cursor, kind)];\n while (name !== 'calc' && take(cursor, ',')) sides.push(sum(cursor, kind));\n expect(cursor, ')');\n return sides.reduce((a, b) => [name as 'min' | 'max', a, b]);\n}\n\n/** Arithmetic of tokens, read as a length and as a number, whichever each reading makes of it. */\nfunction calcToken(text: string): TokenValue | undefined {\n const markers = (['length', 'number'] as const).flatMap((kind): Marker[] => {\n const expression = whole(text, (cursor) =>\n math(cursor, (match(cursor, FUNCTION) ?? fail())[1]!, kind),\n );\n return expression === undefined ? [] : [{ expression, kind }];\n });\n return markers.length ? { deferredCalc: markers } : undefined;\n}\n\n/** An argument of a colour function: a `var()`, or a word read as its slot wants it. */\ntype Argument = Reference | { readonly word: string };\n\n/**\n * A colour function's arguments, with the commas and the slash between them gone, and whether\n * commas were what separated them.\n */\nfunction colourArguments(cursor: Cursor): {\n space: 'rgb' | 'hsl';\n args: Argument[];\n legacy: boolean;\n} {\n const space = SPACES[(match(cursor, FUNCTION) ?? fail())[1]!.toLowerCase()] ?? fail();\n const args: Argument[] = [];\n let legacy = false;\n while (!take(cursor, ')')) {\n if (take(cursor, ',')) legacy = true;\n else if (!take(cursor, '/')) {\n const name = match(cursor, VAR)?.[1];\n args.push(name ? reference(cursor, name) : { word: (match(cursor, WORD) ?? fail())[0] });\n }\n }\n return { space, args, legacy };\n}\n\n/** What each argument of an `hsl()` is: a hue, a saturation and a lightness, then an alpha. */\nconst HSL_SLOTS = ['hue', 'percentage', 'percentage', 'alpha'] as const;\n\n/**\n * A written `hsl()` channel as its slot reads it, as `hslLiteral` in the compiler does: a hue in\n * degrees; a saturation or a lightness as a fraction, from a percentage or, in the space syntax\n * only, a bare number of percent; an alpha as a number or a fraction.\n */\nfunction hslLiteral(\n text: string,\n slot: (typeof HSL_SLOTS)[number],\n legacy: boolean,\n): number | undefined {\n const perUnit = (unit: string): number | undefined => {\n if (slot === 'hue') return HUE_UNITS.has(unit) ? PER_UNIT[unit] : undefined;\n if (unit === '%') return 0.01;\n if (unit !== '') return undefined;\n return slot === 'alpha' ? 1 : legacy ? undefined : 0.01;\n };\n return whole(text, (cursor) => literal(cursor, perUnit));\n}\n\nfunction hslChannel(arg: Argument, index: number, legacy: boolean): HslChannel {\n const slot = HSL_SLOTS[index]!;\n if ('word' in arg) return hslLiteral(arg.word, slot, legacy) ?? fail();\n const fallback = arg.fallback === undefined ? undefined : hslLiteral(arg.fallback, slot, legacy);\n return fallback === undefined\n ? { reference: arg.reference }\n : { reference: arg.reference, fallback };\n}\n\n/** A channels colour's alpha: none, written as a number or a percentage, or a token of its own. */\nfunction alphaOf(arg: Argument | undefined): Alpha {\n if (arg === undefined) return undefined;\n if ('word' in arg) {\n return whole(arg.word, (cursor) => literal(cursor, unitsOf('number'))) ?? fail();\n }\n const fallback = fallbackToken(arg.fallback)?.number;\n return fallback === undefined\n ? { reference: arg.reference }\n : { reference: arg.reference, fallback };\n}\n\n/** `rgba(var(--channels), <alpha>)`, as `deferChannelsToken` reads it. */\nfunction channelsToken(\n channels: Reference,\n alpha: Argument | undefined,\n space: 'rgb' | 'hsl',\n): TokenValue {\n const token = fallbackToken(channels.fallback);\n const fallback = space === 'hsl' ? token?.hslChannels : token?.channels;\n const opacity = alphaOf(alpha);\n return {\n deferredColour: {\n channels: { reference: channels.reference, ...(fallback ? { fallback } : {}), space },\n ...(opacity === undefined ? {} : { alpha: opacity }),\n },\n };\n}\n\n/** `hsl(var(--h) 100% 50%)` and the like, as `deferHslToken` reads it. */\nfunction hslToken(args: readonly Argument[], legacy: boolean): TokenValue {\n if (args.length !== 3 && args.length !== 4) fail();\n const [h, s, l, alpha] = args.map((arg, index) => hslChannel(arg, index, legacy));\n const legacyFlag = legacy ? { legacy: true as const } : {};\n return { hsl: { h: h!, s: s!, l: l!, ...(alpha === undefined ? {} : { alpha }), ...legacyFlag } };\n}\n\nfunction colourToken(text: string): TokenValue | undefined {\n return whole(text, (cursor) => {\n const { space, args, legacy } = colourArguments(cursor);\n const [channels, alpha, ...rest] = args;\n if (channels && 'reference' in channels && !rest.length) {\n return channelsToken(channels, alpha, space);\n }\n return space === 'hsl' ? hslToken(args, legacy) : fail();\n });\n}\n\n/** The index just past the bracket that closes the function the cursor is inside. */\nfunction closing(cursor: Cursor): number {\n for (let at = cursor.at, depth = 0; at < cursor.text.length; at++) {\n const char = cursor.text[at];\n if (char === '(') depth++;\n else if (char === ')' && depth-- === 0) return at + 1;\n }\n return fail();\n}\n\n/**\n * A `var()` in a colour, as `reference` in the compiler's colour-expression.cjs reads it: the\n * tokens its `var()` fallbacks name, tried in turn, then a colour, or one made of other tokens.\n */\nfunction referenceColour({ reference: name, fallback }: Reference): ColourExpression {\n const alternatives: string[] = [];\n let rest = fallback === undefined ? undefined : cssTrim(fallback);\n for (\n let next;\n rest && (next = whole(rest, nextReference));\n rest = next.fallback === undefined ? undefined : cssTrim(next.fallback)\n ) {\n alternatives.push(next.reference);\n }\n return {\n reference: name,\n ...(alternatives.length ? { alternatives } : {}),\n ...(rest ? colourFallback(rest) : {}),\n };\n}\n\n/** The colour a `var()` falls back to, or one made of other tokens; refused when it is neither. */\nfunction colourFallback(text: string): { fallback: string } | { fallbackToken: TokenValue } {\n const token = tokenFromValue(text);\n if (token?.hsl || token?.deferredColour) return { fallbackToken: token };\n return { fallback: token?.color ?? fail() };\n}\n\nconst nextReference = (cursor: Cursor): Reference =>\n reference(cursor, (match(cursor, VAR) ?? fail())[1]!);\n\n/**\n * One colour in a `color-mix()`: a `var()`, another mix, an `rgb()` or `hsl()` of tokens, or a\n * colour written out, which is kept as written for the mix to read.\n */\nfunction mixColour(cursor: Cursor): ColourExpression {\n const name = match(cursor, VAR)?.[1];\n if (name) return referenceColour(reference(cursor, name));\n const start = cursor.at;\n const fn = match(cursor, FUNCTION)?.[1]?.toLowerCase();\n if (fn === 'color-mix') return mixExpression(cursor);\n if (!fn) return { color: (match(cursor, WORD) ?? fail())[0] };\n if (RELATIVE[fn] && takeWord(cursor, 'from')) return relativeExpression(cursor, RELATIVE[fn]);\n cursor.at = closing(cursor);\n return functionColour(cursor.text.slice(start, cursor.at));\n}\n\n/** A colour function in a mix: of tokens, as a token of it is read, or written out, as it is. */\nfunction functionColour(text: string): ColourExpression {\n if (!text.includes('var(')) return { color: text };\n const token = colourToken(text);\n return token?.hsl ? { hsl: token.hsl } : (token?.deferredColour ?? fail());\n}\n\n/** One side of a mix: its colour, and the percentage written before or after it, if one is. */\nfunction mixSide(cursor: Cursor): { colour: ColourExpression; percentage?: number } {\n const percentage = () => {\n const found = match(cursor, PERCENTAGE);\n match(cursor, SPACE);\n return found ? Number(found[1]) : undefined;\n };\n const before = percentage();\n const colour = mixColour(cursor);\n match(cursor, SPACE);\n const after = before === undefined ? percentage() : undefined;\n const written = before ?? after;\n return written === undefined ? { colour } : { colour, percentage: written };\n}\n\n/**\n * The rest of a `color-mix(in <space> [<method> hue], <colour> [p%], <colour> [q%])` once its name\n * is read, as `mixExpression` in the compiler reads it.\n */\nfunction mixExpression(cursor: Cursor): ColourExpression {\n const words: string[] = [];\n while (!take(cursor, ',')) {\n words.push((match(cursor, WORD) ?? fail())[0].toLowerCase());\n match(cursor, SPACE);\n }\n const [keyword, space, method, hue, ...rest] = words;\n if (keyword !== 'in' || !MIX_SPACES.has(space!) || rest.length) fail();\n if (method !== undefined && (hue !== 'hue' || !HUE_METHODS.has(method))) fail();\n const a = mixSide(cursor);\n expect(cursor, ',');\n const b = mixSide(cursor);\n expect(cursor, ')');\n return {\n mix: {\n space: space as MixSpace,\n ...(method ? { hue: method as HueMethod } : {}),\n a: a.colour,\n ...(a.percentage === undefined ? {} : { aPercentage: a.percentage }),\n b: b.colour,\n ...(b.percentage === undefined ? {} : { bPercentage: b.percentage }),\n },\n };\n}\n\n/** A whole `color-mix()`, worked out where it is set, as `deferMixToken` in the compiler reads it. */\nfunction mixToken(text: string): TokenValue | undefined {\n const deferredColour = whole(text, (cursor) => {\n const colour = mixColour(cursor);\n return 'mix' in colour || 'relative' in colour ? colour : fail();\n });\n return deferredColour && { deferredColour };\n}\n\ninterface RelativeSpace {\n readonly space: MixSpace;\n readonly keywords: readonly string[];\n /** What 100% of each channel is; null for a hue, which takes an angle instead. */\n readonly full: readonly (number | null)[];\n}\n\n/** Each relative colour function, as `RELATIVE` in the compiler's colour-expression.cjs. */\nconst RELATIVE: Readonly<Record<string, RelativeSpace>> = {\n rgb: { space: 'srgb', keywords: ['r', 'g', 'b'], full: [255, 255, 255] },\n rgba: { space: 'srgb', keywords: ['r', 'g', 'b'], full: [255, 255, 255] },\n hsl: { space: 'hsl', keywords: ['h', 's', 'l'], full: [null, 100, 100] },\n hsla: { space: 'hsl', keywords: ['h', 's', 'l'], full: [null, 100, 100] },\n hwb: { space: 'hwb', keywords: ['h', 'w', 'b'], full: [null, 100, 100] },\n lab: { space: 'lab', keywords: ['l', 'a', 'b'], full: [100, 125, 125] },\n lch: { space: 'lch', keywords: ['l', 'c', 'h'], full: [100, 150, null] },\n oklab: { space: 'oklab', keywords: ['l', 'a', 'b'], full: [1, 0.4, 0.4] },\n oklch: { space: 'oklch', keywords: ['l', 'c', 'h'], full: [1, 0.4, null] },\n};\n\n/** Whether the next word is `word`, in any case; taken, with the space after it, if so. */\nfunction takeWord(cursor: Cursor, word: string): boolean {\n const start = cursor.at;\n if (match(cursor, WORD)?.[0].toLowerCase() === word) {\n match(cursor, SPACE);\n return true;\n }\n cursor.at = start;\n return false;\n}\n\n/**\n * The rest of `<space>(from <colour> <channel> <channel> <channel> [/ <alpha>])` once `from` is\n * read, as `relativeExpression` in the compiler reads it.\n */\nfunction relativeExpression(cursor: Cursor, { space, keywords, full }: RelativeSpace) {\n const from = mixColour(cursor);\n const names = [...keywords, 'alpha'];\n const channels = [0, 1, 2].map((index) => {\n match(cursor, SPACE);\n return relativeChannel(cursor, names, full[index]!);\n }) as [Channel, Channel, Channel];\n const alpha = take(cursor, '/') ? relativeChannel(cursor, names, 1) : undefined;\n expect(cursor, ')');\n return { relative: { space, from, channels, ...(alpha === undefined ? {} : { alpha }) } };\n}\n\n/**\n * One channel: a `calc()` of numbers and keywords, a keyword, a number, a percentage of the\n * channel's range, or an angle for a hue.\n */\nfunction relativeChannel(cursor: Cursor, keywords: readonly string[], full: number | null) {\n const fn = match(cursor, FUNCTION)?.[1]?.toLowerCase();\n if (fn) {\n const value = fn === 'calc' ? channelSum(cursor, keywords) : fail();\n expect(cursor, ')');\n return value;\n }\n const found = match(cursor, LITERAL);\n if (!found) return channelOperand(cursor, keywords);\n const value = Number(found[1]) * channelScale((found[2] ?? '').toLowerCase(), full);\n return Number.isFinite(value) ? value : fail();\n}\n\n/** What one of a written channel's unit is: a share of its range, degrees of a hue, or itself. */\nfunction channelScale(unit: string, full: number | null): number {\n if (unit === '%') return full === null ? NaN : full / 100;\n if (full !== null) return unit ? NaN : 1;\n return HUE_UNITS.has(unit) ? PER_UNIT[unit]! : NaN;\n}\n\n/** `a + b - c`, each side a product of numbers, keywords and bracketed sums. */\nfunction channelSum(cursor: Cursor, keywords: readonly string[]): Channel {\n let value = channelProduct(cursor, keywords);\n for (let op; (op = (['+', '-'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, channelProduct(cursor, keywords)];\n }\n return value;\n}\n\nfunction channelProduct(cursor: Cursor, keywords: readonly string[]): Channel {\n let value = channelFactor(cursor, keywords);\n for (let op; (op = (['*', '/'] as const).find((char) => take(cursor, char)));) {\n value = [op, value, channelFactor(cursor, keywords)];\n }\n return value;\n}\n\nfunction channelFactor(cursor: Cursor, keywords: readonly string[]): Channel {\n if (take(cursor, '(')) {\n const value = channelSum(cursor, keywords);\n expect(cursor, ')');\n return value;\n }\n const found = match(cursor, LITERAL);\n // A percentage or an angle stands alone: inside arithmetic the keywords are numbers.\n if (found) return found[2] ? fail() : Number(found[1]);\n return channelOperand(cursor, keywords);\n}\n\nfunction channelOperand(cursor: Cursor, keywords: readonly string[]): string {\n const word = (match(cursor, WORD) ?? fail())[0];\n return keywords.includes(word) ? word : fail();\n}\n\n/**\n * A value with a `var()` inside it, or a `color-mix()`, as a token made of others; undefined if it\n * is no such shape.\n */\nexport function derivedToken(text: string): TokenValue | undefined {\n return calcToken(text) ?? colourToken(text) ?? mixToken(text);\n}\n"]}
@@ -12,4 +12,11 @@
12
12
  * as a token of the wrong kind does.
13
13
  */
14
14
  import { type TokenValue } from './css.ts';
15
+ export declare const cssTrim: (text: string) => string;
16
+ /**
17
+ * The first family of a `font-family` stack, as a stylesheet reads it (`firstFamily` in
18
+ * values.cjs): `'Inter Display', sans-serif` is `Inter Display`, and `Segoe UI` is one name of two
19
+ * words. Undefined for anything that is not a stack.
20
+ */
21
+ export declare function firstFamily(value: string): string | undefined;
15
22
  export declare function tokenFromValue(value: unknown): TokenValue | undefined;
@@ -13,7 +13,7 @@
13
13
  */
14
14
  import { CSS_SPACE } from "./css.js";
15
15
  import { derivedToken } from "./inline-derived-token.js";
16
- import { isNamedColor } from "./transition.js";
16
+ import { HUE_DEGREES, isNamedColor } from "./transition.js";
17
17
  const PX = /^(-?\d*\.?\d+)px$/;
18
18
  const PERCENT = /^-?\d*\.?\d+%$/;
19
19
  const NUMBER = /^-?\d*\.?\d+$/;
@@ -23,21 +23,66 @@ const COLOR_FUNCTION = /^(#[\da-f]{3,8}|(rgba?|hsla?|hwb)\(.*\))$/i;
23
23
  const WORD = /^-?[a-z][\w-]*$/i;
24
24
  /** One colour channel: a number, a percentage, or a hue with its unit. */
25
25
  const CHANNEL = /^(-?(?:\d+\.?\d*|\.\d+))(%|deg|grad|rad|turn)?$/;
26
- const HUE_UNITS = { deg: 1, grad: 0.9, rad: 180 / Math.PI, turn: 360 };
27
26
  /** `var(--name)` or `var(--name, <fallback>)`, the whole value. */
28
- const VAR = /^var\(\s*(--[\w-]+)\s*(?:,([\s\S]*))?\)$/i;
27
+ const VAR = /^var\([ \t\n\r\f]*(--[\w-]+)[ \t\n\r\f]*(?:,([\s\S]*))?\)$/i;
29
28
  /**
30
29
  * A value worked out where it is set: one with a `var()` in it, a `color-mix()`, or a relative
31
30
  * colour, of tokens or of colours written out.
32
31
  */
33
- const DERIVED = /var\(|^color-mix\(|^[a-z]+\(\s*from\s/i;
32
+ const DERIVED = /var\(|^color-mix\(|^[a-z]+\([ \t\n\r\f]*from[ \t\n\r\f]/i;
34
33
  const WEIGHTS = { normal: '400', bold: '700' };
35
34
  /**
36
35
  * CSS whitespace at either end: a space, a tab, a newline, a carriage return or a form feed. A
37
36
  * no-break space is part of the value, as it is in a browser, where `trim()` would drop it.
38
37
  */
39
38
  const PADDED = new RegExp(`^${CSS_SPACE.source}|${CSS_SPACE.source}$`, 'g');
40
- const cssTrim = (text) => text.replace(PADDED, '');
39
+ export const cssTrim = (text) => text.replace(PADDED, '');
40
+ /** A family name's parts: a quoted string, which may hold escapes, or a bare word. */
41
+ const FAMILY_PART = /^(?:'((?:[^'\\]|\\[\s\S])*)'|"((?:[^"\\]|\\[\s\S])*)"|(-?[a-z_][\w-]*))/i;
42
+ const LEADING_SPACE = new RegExp(`^${CSS_SPACE.source}`);
43
+ /**
44
+ * A CSS escape: up to six hex digits and one whitespace after them, a newline, which only joins
45
+ * the lines either side, or any other character.
46
+ */
47
+ const ESCAPE = /\\([\da-f]{1,6})(?:\r\n|[ \t\n\r\f])?|\\(\r\n|[\n\r\f])|\\([\s\S])/gi;
48
+ /** A quoted string's text with its escapes decoded. One naming no character is U+FFFD. */
49
+ const decodeEscapes = (text) => text.replace(ESCAPE, (_, hex, newline, char) => {
50
+ if (newline !== undefined)
51
+ return '';
52
+ if (hex === undefined)
53
+ return char;
54
+ const code = parseInt(hex, 16);
55
+ return code && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff)
56
+ ? String.fromCodePoint(code)
57
+ : '\ufffd';
58
+ });
59
+ /**
60
+ * The first family of a `font-family` stack, as a stylesheet reads it (`firstFamily` in
61
+ * values.cjs): `'Inter Display', sans-serif` is `Inter Display`, and `Segoe UI` is one name of two
62
+ * words. Undefined for anything that is not a stack.
63
+ */
64
+ export function firstFamily(value) {
65
+ let rest = cssTrim(value);
66
+ const words = [];
67
+ while (rest && !rest.startsWith(',')) {
68
+ const part = FAMILY_PART.exec(rest);
69
+ if (!part)
70
+ return undefined;
71
+ const quoted = part[1] ?? part[2];
72
+ words.push(quoted === undefined ? part[3] : decodeEscapes(quoted));
73
+ rest = rest.slice(part[0].length).replace(LEADING_SPACE, '');
74
+ }
75
+ return words.length ? words.join(' ') : undefined;
76
+ }
77
+ /**
78
+ * A value kept as written, and a family too when it reads as one: `'Inter-Bold'` is the family
79
+ * `Inter-Bold`, and a stack its first. The written word stays the keyword, so a quoted `"none"` is
80
+ * still no display.
81
+ */
82
+ function fromText(text) {
83
+ const family = firstFamily(text);
84
+ return family === undefined || family === text ? { keyword: text } : { keyword: text, family };
85
+ }
41
86
  /**
42
87
  * CSS takes a bare 0 wherever it takes a length, and no other bare number. A number from 1 to 1000
43
88
  * is a weight as well, at the nearest hundred, which is every weight native draws.
@@ -94,7 +139,7 @@ function rgbChannels(values) {
94
139
  }
95
140
  /** As `hsl()` reads them: a hue, then two percentages, which the space syntax may write bare. */
96
141
  function hslOf([hue, ...rest], spaced) {
97
- const degrees = hue.n * (hue.unit === '' ? 1 : (HUE_UNITS[hue.unit] ?? NaN));
142
+ const degrees = hue.n * (hue.unit === '' ? 1 : (HUE_DEGREES[hue.unit] ?? NaN));
98
143
  const fractions = rest.map((v) => v.unit === '%' || (spaced && v.unit === '') ? clamp(v.n / 100, 0, 1) : NaN);
99
144
  const hsl = [degrees, ...fractions];
100
145
  return hsl.every(Number.isFinite) ? hsl : undefined;
@@ -152,7 +197,7 @@ export function tokenFromValue(value) {
152
197
  const angle = ANGLE.exec(text);
153
198
  if (angle) {
154
199
  const [, value, unit] = angle;
155
- return { angle: Number(value) * HUE_UNITS[unit.toLowerCase()], number: Number(value) };
200
+ return { angle: Number(value) * HUE_DEGREES[unit.toLowerCase()], number: Number(value) };
156
201
  }
157
202
  if (NUMBER.test(text))
158
203
  return fromNumber(Number(text));
@@ -160,6 +205,6 @@ export function tokenFromValue(value) {
160
205
  return withTokens(text);
161
206
  if (COLOR_FUNCTION.test(text))
162
207
  return { color: text };
163
- return fromChannels(text) ?? (WORD.test(text) ? fromWord(text) : { keyword: text });
208
+ return fromChannels(text) ?? (WORD.test(text) ? fromWord(text) : fromText(text));
164
209
  }
165
210
  //# sourceMappingURL=inline-token.js.map