@ng-native/fabric 0.3.0 → 0.4.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.
@@ -11,4 +11,8 @@
11
11
  * is widened to the sixteen values native wants.
12
12
  */
13
13
  export type TransformEntry = Readonly<Record<string, number | string | readonly number[]>>;
14
- export declare function transformList(value: string): TransformEntry[];
14
+ /**
15
+ * The list, or undefined for a value CSS cannot read, which a browser drops: the transform a rule
16
+ * sets then applies instead.
17
+ */
18
+ export declare function transformList(value: string): TransformEntry[] | undefined;
@@ -4,18 +4,46 @@ const AXES = {
4
4
  skew: ['skewX', 'skewY'],
5
5
  };
6
6
  const PX = /^-?\d*\.?\d+(px)?$/;
7
+ /** A transform function's argument: a number, a length, an angle or a percentage. */
8
+ const ARGUMENT = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?(?:%|[a-z]+)?$/i;
9
+ /** CSS whitespace: a space, a tab, a newline, a carriage return or a form feed, and no other. */
10
+ const SPACE = /^[ \t\n\r\f]*$/;
11
+ const PADDED = /^[ \t\n\r\f]+|[ \t\n\r\f]+$/g;
12
+ const FUNCTIONS = /([a-zA-Z0-9]+)\(([^)]*)\)/g;
13
+ /** The transform functions native has, by their name in any case, as CSS reads one. */
14
+ const NAMES = new Map([
15
+ ...['matrix', 'matrix3d', 'perspective', 'rotate', 'rotateX', 'rotateY', 'rotateZ'],
16
+ ...['scale', 'scaleX', 'scaleY', 'skew', 'skewX', 'skewY'],
17
+ ...['translate', 'translateX', 'translateY'],
18
+ ].map((name) => [name.toLowerCase(), name]));
7
19
  function argument(raw) {
8
20
  return PX.test(raw) ? parseFloat(raw) : raw;
9
21
  }
22
+ /** Each function and its arguments, or undefined where anything else is in the value. */
23
+ function readCalls(value) {
24
+ const calls = [...value.matchAll(FUNCTIONS)].map(([, name, body]) => ({
25
+ name: NAMES.get(name.toLowerCase()),
26
+ raw: body.split(/[ \t\n\r\f,]+/).filter(Boolean),
27
+ }));
28
+ // Functions native has, CSS whitespace between them and nothing else, and arguments CSS reads.
29
+ const readable = calls.length &&
30
+ SPACE.test(value.replace(FUNCTIONS, '')) &&
31
+ calls.every(({ name, raw }) => name && raw.length && raw.every((arg) => ARGUMENT.test(arg)));
32
+ return readable ? calls : undefined;
33
+ }
34
+ /**
35
+ * The list, or undefined for a value CSS cannot read, which a browser drops: the transform a rule
36
+ * sets then applies instead.
37
+ */
10
38
  export function transformList(value) {
11
39
  const out = [];
12
- if (value.trim() === 'none')
40
+ if (value.replace(PADDED, '').toLowerCase() === 'none')
13
41
  return out;
14
- for (const [, name, body] of value.matchAll(/([a-zA-Z0-9]+)\(([^)]*)\)/g)) {
15
- const args = body
16
- .split(/[\s,]+/)
17
- .filter(Boolean)
18
- .map(argument);
42
+ const calls = readCalls(value);
43
+ if (!calls)
44
+ return undefined;
45
+ for (const { name, raw } of calls) {
46
+ const args = raw.map(argument);
19
47
  const axes = AXES[name];
20
48
  if (axes && args.length === 2) {
21
49
  out.push({ [axes[0]]: args[0] }, { [axes[1]]: args[1] });
@@ -1 +1 @@
1
- {"version":3,"file":"inline-transform.js","sourceRoot":"","sources":["../src/inline-transform.ts"],"names":[],"mappings":"AAcA,MAAM,IAAI,GAAwD;IAChE,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;IACvC,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC3B,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,EAAE,GAAG,oBAAoB,CAAC;AAEhC,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,GAAG,CAAC;IACxC,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,GAAG,IAAK;aACf,KAAK,CAAC,QAAQ,CAAC;aACf,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAK,CAAC,CAAC;QACzB,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACpC,yFAAyF;YACzF,4EAA4E;YAC5E,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAgB,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAE,EAAE,CAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAE,EAAE,CAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAE,EAAE,CAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;aAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAgB,EAAE,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * A CSS transform string, as the list React Native's Fabric reads.\n *\n * A class's transform is compiled to this list at build time. A bound style -\n * `[style.transform]=\"'rotate(' + angle + 'deg)'\"` - has no build step, and Fabric drops a string\n * without a word. React Native's JavaScript would have run `processTransform` over it first; there\n * is none of that JavaScript between this engine and Fabric, so this does the same job.\n *\n * Lengths in pixels become numbers, angles and percentages stay strings, as React Native keeps\n * them. A two-argument `translate`, `scale` or `skew` is split into its axes, and a 2D `matrix()`\n * is widened to the sixteen values native wants.\n */\nexport type TransformEntry = Readonly<Record<string, number | string | readonly number[]>>;\n\nconst AXES: Readonly<Record<string, readonly [string, string]>> = {\n translate: ['translateX', 'translateY'],\n scale: ['scaleX', 'scaleY'],\n skew: ['skewX', 'skewY'],\n};\n\nconst PX = /^-?\\d*\\.?\\d+(px)?$/;\n\nfunction argument(raw: string): number | string {\n return PX.test(raw) ? parseFloat(raw) : raw;\n}\n\nexport function transformList(value: string): TransformEntry[] {\n const out: TransformEntry[] = [];\n if (value.trim() === 'none') return out;\n for (const [, name, body] of value.matchAll(/([a-zA-Z0-9]+)\\(([^)]*)\\)/g)) {\n const args = body!\n .split(/[\\s,]+/)\n .filter(Boolean)\n .map(argument);\n const axes = AXES[name!];\n if (axes && args.length === 2) {\n out.push({ [axes[0]]: args[0]! }, { [axes[1]]: args[1]! });\n } else if (axes && name !== 'scale') {\n // `translate(4px)` and `skew(10deg)` move along the first axis only; `scale(2)` is both,\n // which React Native spells as a key of its own and falls through to below.\n out.push({ [axes[0]]: args[0]! });\n } else if (name === 'matrix' && args.length === 6) {\n const [a, b, c, d, e, f] = args as number[];\n out.push({ matrix: [a!, b!, 0, 0, c!, d!, 0, 0, 0, 0, 1, 0, e!, f!, 0, 1] });\n } else if (name === 'matrix3d') {\n out.push({ matrix: args as number[] });\n } else {\n out.push({ [name!]: args[0]! });\n }\n }\n return out;\n}\n"]}
1
+ {"version":3,"file":"inline-transform.js","sourceRoot":"","sources":["../src/inline-transform.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A CSS transform string, as the list React Native's Fabric reads.\n *\n * A class's transform is compiled to this list at build time. A bound style -\n * `[style.transform]=\"'rotate(' + angle + 'deg)'\"` - has no build step, and Fabric drops a string\n * without a word. React Native's JavaScript would have run `processTransform` over it first; there\n * is none of that JavaScript between this engine and Fabric, so this does the same job.\n *\n * Lengths in pixels become numbers, angles and percentages stay strings, as React Native keeps\n * them. A two-argument `translate`, `scale` or `skew` is split into its axes, and a 2D `matrix()`\n * is widened to the sixteen values native wants.\n */\nexport type TransformEntry = Readonly<Record<string, number | string | readonly number[]>>;\n\nconst AXES: Readonly<Record<string, readonly [string, string]>> = {\n translate: ['translateX', 'translateY'],\n scale: ['scaleX', 'scaleY'],\n skew: ['skewX', 'skewY'],\n};\n\nconst PX = /^-?\\d*\\.?\\d+(px)?$/;\n/** A transform function's argument: a number, a length, an angle or a percentage. */\nconst ARGUMENT = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?(?:%|[a-z]+)?$/i;\n/** CSS whitespace: a space, a tab, a newline, a carriage return or a form feed, and no other. */\nconst SPACE = /^[ \\t\\n\\r\\f]*$/;\nconst PADDED = /^[ \\t\\n\\r\\f]+|[ \\t\\n\\r\\f]+$/g;\nconst FUNCTIONS = /([a-zA-Z0-9]+)\\(([^)]*)\\)/g;\n/** The transform functions native has, by their name in any case, as CSS reads one. */\nconst NAMES = new Map(\n [\n ...['matrix', 'matrix3d', 'perspective', 'rotate', 'rotateX', 'rotateY', 'rotateZ'],\n ...['scale', 'scaleX', 'scaleY', 'skew', 'skewX', 'skewY'],\n ...['translate', 'translateX', 'translateY'],\n ].map((name) => [name.toLowerCase(), name]),\n);\n\nfunction argument(raw: string): number | string {\n return PX.test(raw) ? parseFloat(raw) : raw;\n}\n\n/** Each function and its arguments, or undefined where anything else is in the value. */\nfunction readCalls(value: string): { name: string; raw: string[] }[] | undefined {\n const calls = [...value.matchAll(FUNCTIONS)].map(([, name, body]) => ({\n name: NAMES.get(name!.toLowerCase())!,\n raw: body!.split(/[ \\t\\n\\r\\f,]+/).filter(Boolean),\n }));\n // Functions native has, CSS whitespace between them and nothing else, and arguments CSS reads.\n const readable =\n calls.length &&\n SPACE.test(value.replace(FUNCTIONS, '')) &&\n calls.every(({ name, raw }) => name && raw.length && raw.every((arg) => ARGUMENT.test(arg)));\n return readable ? calls : undefined;\n}\n\n/**\n * The list, or undefined for a value CSS cannot read, which a browser drops: the transform a rule\n * sets then applies instead.\n */\nexport function transformList(value: string): TransformEntry[] | undefined {\n const out: TransformEntry[] = [];\n if (value.replace(PADDED, '').toLowerCase() === 'none') return out;\n const calls = readCalls(value);\n if (!calls) return undefined;\n for (const { name, raw } of calls) {\n const args = raw.map(argument);\n const axes = AXES[name];\n if (axes && args.length === 2) {\n out.push({ [axes[0]]: args[0]! }, { [axes[1]]: args[1]! });\n } else if (axes && name !== 'scale') {\n // `translate(4px)` and `skew(10deg)` move along the first axis only; `scale(2)` is both,\n // which React Native spells as a key of its own and falls through to below.\n out.push({ [axes[0]]: args[0]! });\n } else if (name === 'matrix' && args.length === 6) {\n const [a, b, c, d, e, f] = args as number[];\n out.push({ matrix: [a!, b!, 0, 0, c!, d!, 0, 0, 0, 0, 1, 0, e!, f!, 0, 1] });\n } else if (name === 'matrix3d') {\n out.push({ matrix: args as number[] });\n } else {\n out.push({ [name!]: args[0]! });\n }\n }\n return out;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-native/fabric",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Angular Native's engine: a retained view tree committed to React Native's Fabric, with events, the responder system and a CSS cascade.",
5
5
  "keywords": [
6
6
  "angular",