@triniwiz/nativescript-masonkit 1.0.0-beta.117 → 1.0.0-beta.118

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 (81) hide show
  1. package/DOCS.md +15 -2
  2. package/common.d.ts +7 -9
  3. package/common.js +26 -49
  4. package/common.js.map +1 -1
  5. package/css-math.d.ts +34 -0
  6. package/css-math.js +301 -0
  7. package/css-math.js.map +1 -0
  8. package/css-shorthands.d.ts +24 -0
  9. package/css-shorthands.js +145 -0
  10. package/css-shorthands.js.map +1 -1
  11. package/index.d.ts +45 -0
  12. package/input/common.d.ts +13 -0
  13. package/input/common.js +97 -0
  14. package/input/common.js.map +1 -1
  15. package/package.json +3 -3
  16. package/platforms/android/masonkit-release.aar +0 -0
  17. package/platforms/ios/Mason.xcframework/Info.plist +11 -11
  18. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Headers/Mason-Swift.h +2 -0
  19. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Mason +0 -0
  20. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  21. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.abi.json +6069 -14580
  22. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.private.swiftinterface +31 -7
  23. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  24. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.swiftinterface +31 -7
  25. package/platforms/ios/Mason.xcframework/ios-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  26. package/platforms/ios/Mason.xcframework/ios-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +9346 -9349
  27. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Headers/Mason-Swift.h +4 -0
  28. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Mason +0 -0
  29. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
  30. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
  31. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.abi.json +6069 -14580
  32. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +31 -7
  33. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  34. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.swiftinterface +31 -7
  35. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.abi.json +6069 -14580
  36. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +31 -7
  37. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  38. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +31 -7
  39. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/_CodeSignature/CodeResources +26 -26
  40. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +2 -2
  41. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +9340 -9343
  42. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/x86_64/Mason.yml +8906 -8915
  43. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Headers/Mason-Swift.h +2 -0
  44. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Mason +0 -0
  45. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-xros.swiftsourceinfo +0 -0
  46. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.abi.json +6069 -14580
  47. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.private.swiftinterface +31 -7
  48. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.swiftdoc +0 -0
  49. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.swiftinterface +31 -7
  50. package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  51. package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +8837 -8839
  52. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Headers/Mason-Swift.h +2 -0
  53. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Mason +0 -0
  54. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-xros-simulator.swiftsourceinfo +0 -0
  55. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.abi.json +6069 -14580
  56. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.private.swiftinterface +31 -7
  57. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.swiftdoc +0 -0
  58. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.swiftinterface +31 -7
  59. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/_CodeSignature/CodeResources +14 -14
  60. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  61. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +8836 -8838
  62. package/platforms/windows/arm64/NativeScript.Mason.dll +0 -0
  63. package/platforms/windows/arm64/NativeScript.Mason.winmd +0 -0
  64. package/platforms/windows/x64/NativeScript.Mason.dll +0 -0
  65. package/platforms/windows/x64/NativeScript.Mason.winmd +0 -0
  66. package/properties.d.ts +20 -9
  67. package/properties.js +285 -70
  68. package/properties.js.map +1 -1
  69. package/style.d.ts +54 -4
  70. package/style.js +328 -29
  71. package/style.js.map +1 -1
  72. package/svelte/README.md +6 -1
  73. package/svelte/package.json +1 -1
  74. package/svelte/src/element-registry.js +1 -1
  75. package/svelte/src/element-registry.js.map +1 -1
  76. package/svelte/src/mason-element-node.d.ts +2 -2
  77. package/svelte/src/mason-element-node.d.ts.map +1 -1
  78. package/svelte/src/mason-element-node.js +1 -1
  79. package/svelte/src/mason-element-node.js.map +1 -1
  80. package/web.js +2 -0
  81. package/web.js.map +1 -1
package/style.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { layout as coreLayout } from '@nativescript/core/utils';
2
2
  import { cssUnits } from './units';
3
+ import { style_ } from './symbols';
3
4
  import { pickFontFamily } from './fonts';
4
5
  import { masonEngine } from './windows-panel-helpers';
5
6
  import { reportCssDiagnostic } from './diagnostics';
@@ -7,6 +8,7 @@ import { expandColorStops, resolveStopPositions } from './gradient-stops';
7
8
  import { encodeBoxShadows, parseBoxShadows } from './box-shadow';
8
9
  import { encodeCssFilter, parseCssFilter } from './css-filter';
9
10
  import { resolveCssColors } from './css-colors';
11
+ import { evaluateCssMath, hasCssMathFunction, isCssMathFunction, substituteCssMath } from './css-math';
10
12
  import { encodeWindowsBackground, encodeWindowsBorderImage, encodeWindowsMask, WINDOWS_MASK_PROPERTIES } from './windows-mask';
11
13
  import { Color, Length as CoreLength, PercentLength as CorePercentLength, Screen, knownFolders } from '@nativescript/core';
12
14
  // The Windows shell lays out in XAML DIPs, so its style buffer holds DIPs. Core's Windows density
@@ -14,6 +16,7 @@ import { Color, Length as CoreLength, PercentLength as CorePercentLength, Screen
14
16
  const layout = __WINDOWS__ ? { ...coreLayout, getDisplayDensity: () => 1, toDevicePixels: (value) => value, toDeviceIndependentPixels: (value) => value } : coreLayout;
15
17
  var StyleKeys;
16
18
  (function (StyleKeys) {
19
+ // <style-keys:offsets> generated from tools/scripts/style-keys/style-keys.schema, run `npm run gen:style-keys`
17
20
  StyleKeys[StyleKeys["DISPLAY"] = 0] = "DISPLAY";
18
21
  StyleKeys[StyleKeys["POSITION"] = 1] = "POSITION";
19
22
  StyleKeys[StyleKeys["DIRECTION"] = 2] = "DIRECTION";
@@ -27,7 +30,7 @@ var StyleKeys;
27
30
  StyleKeys[StyleKeys["JUSTIFY_ITEMS"] = 10] = "JUSTIFY_ITEMS";
28
31
  StyleKeys[StyleKeys["JUSTIFY_SELF"] = 11] = "JUSTIFY_SELF";
29
32
  StyleKeys[StyleKeys["JUSTIFY_CONTENT"] = 12] = "JUSTIFY_CONTENT";
30
- // Contiguous types, then contiguous values per group
33
+ // Each box side group: four types, then four values.
31
34
  StyleKeys[StyleKeys["INSET_LEFT_TYPE"] = 13] = "INSET_LEFT_TYPE";
32
35
  StyleKeys[StyleKeys["INSET_RIGHT_TYPE"] = 14] = "INSET_RIGHT_TYPE";
33
36
  StyleKeys[StyleKeys["INSET_TOP_TYPE"] = 15] = "INSET_TOP_TYPE";
@@ -102,16 +105,15 @@ var StyleKeys;
102
105
  StyleKeys[StyleKeys["MIN_CONTENT_HEIGHT"] = 186] = "MIN_CONTENT_HEIGHT";
103
106
  StyleKeys[StyleKeys["MAX_CONTENT_WIDTH"] = 190] = "MAX_CONTENT_WIDTH";
104
107
  StyleKeys[StyleKeys["MAX_CONTENT_HEIGHT"] = 194] = "MAX_CONTENT_HEIGHT";
105
- // Border Style (per side)
106
108
  StyleKeys[StyleKeys["BORDER_LEFT_STYLE"] = 198] = "BORDER_LEFT_STYLE";
107
109
  StyleKeys[StyleKeys["BORDER_RIGHT_STYLE"] = 199] = "BORDER_RIGHT_STYLE";
108
110
  StyleKeys[StyleKeys["BORDER_TOP_STYLE"] = 200] = "BORDER_TOP_STYLE";
109
111
  StyleKeys[StyleKeys["BORDER_BOTTOM_STYLE"] = 201] = "BORDER_BOTTOM_STYLE";
110
- // Border Color (per side)
111
112
  StyleKeys[StyleKeys["BORDER_LEFT_COLOR"] = 202] = "BORDER_LEFT_COLOR";
112
113
  StyleKeys[StyleKeys["BORDER_RIGHT_COLOR"] = 206] = "BORDER_RIGHT_COLOR";
113
114
  StyleKeys[StyleKeys["BORDER_TOP_COLOR"] = 210] = "BORDER_TOP_COLOR";
114
115
  StyleKeys[StyleKeys["BORDER_BOTTOM_COLOR"] = 214] = "BORDER_BOTTOM_COLOR";
116
+ // Elliptical radii: eight types, eight values, then four squircle exponents.
115
117
  StyleKeys[StyleKeys["BORDER_RADIUS_TOP_LEFT_X_TYPE"] = 218] = "BORDER_RADIUS_TOP_LEFT_X_TYPE";
116
118
  StyleKeys[StyleKeys["BORDER_RADIUS_TOP_LEFT_Y_TYPE"] = 219] = "BORDER_RADIUS_TOP_LEFT_Y_TYPE";
117
119
  StyleKeys[StyleKeys["BORDER_RADIUS_TOP_RIGHT_X_TYPE"] = 220] = "BORDER_RADIUS_TOP_RIGHT_X_TYPE";
@@ -132,7 +134,6 @@ var StyleKeys;
132
134
  StyleKeys[StyleKeys["BORDER_RADIUS_TOP_RIGHT_EXPONENT"] = 262] = "BORDER_RADIUS_TOP_RIGHT_EXPONENT";
133
135
  StyleKeys[StyleKeys["BORDER_RADIUS_BOTTOM_RIGHT_EXPONENT"] = 266] = "BORDER_RADIUS_BOTTOM_RIGHT_EXPONENT";
134
136
  StyleKeys[StyleKeys["BORDER_RADIUS_BOTTOM_LEFT_EXPONENT"] = 270] = "BORDER_RADIUS_BOTTOM_LEFT_EXPONENT";
135
- // Float
136
137
  StyleKeys[StyleKeys["FLOAT"] = 274] = "FLOAT";
137
138
  StyleKeys[StyleKeys["CLEAR"] = 275] = "CLEAR";
138
139
  StyleKeys[StyleKeys["OBJECT_FIT"] = 276] = "OBJECT_FIT";
@@ -153,6 +154,7 @@ var StyleKeys;
153
154
  StyleKeys[StyleKeys["LIST_STYLE_POSITION_STATE"] = 318] = "LIST_STYLE_POSITION_STATE";
154
155
  StyleKeys[StyleKeys["LIST_STYLE_TYPE_STATE"] = 319] = "LIST_STYLE_TYPE_STATE";
155
156
  StyleKeys[StyleKeys["REF_COUNT"] = 320] = "REF_COUNT";
157
+ // Inherited text fields. A *_STATE byte is nonzero once the node sets the field.
156
158
  StyleKeys[StyleKeys["FONT_COLOR"] = 324] = "FONT_COLOR";
157
159
  StyleKeys[StyleKeys["FONT_COLOR_STATE"] = 328] = "FONT_COLOR_STATE";
158
160
  StyleKeys[StyleKeys["FONT_SIZE"] = 329] = "FONT_SIZE";
@@ -197,14 +199,22 @@ var StyleKeys;
197
199
  StyleKeys[StyleKeys["TEXT_SHADOW_STATE"] = 395] = "TEXT_SHADOW_STATE";
198
200
  StyleKeys[StyleKeys["TEXT_OVERFLOW"] = 396] = "TEXT_OVERFLOW";
199
201
  StyleKeys[StyleKeys["TEXT_OVERFLOW_STATE"] = 397] = "TEXT_OVERFLOW_STATE";
200
- // Pseudo set mask: 128-bit bitmask (two longs) tracking which properties
201
- // were explicitly set on a pseudo style buffer. Uses the same bit layout
202
- // as StateKeys. Zero-copy: lives in the style buffer itself.
202
+ // Which StateKeys a pseudo-class buffer sets explicitly (same bit layout).
203
203
  StyleKeys[StyleKeys["PSEUDO_SET_MASK_LOW"] = 398] = "PSEUDO_SET_MASK_LOW";
204
204
  StyleKeys[StyleKeys["PSEUDO_SET_MASK_HIGH"] = 406] = "PSEUDO_SET_MASK_HIGH";
205
- // font-variant-numeric bitmask (byte) + state
205
+ // 414-418 free.
206
206
  StyleKeys[StyleKeys["FONT_VARIANT_NUMERIC"] = 419] = "FONT_VARIANT_NUMERIC";
207
207
  StyleKeys[StyleKeys["FONT_VARIANT_NUMERIC_STATE"] = 420] = "FONT_VARIANT_NUMERIC_STATE";
208
+ // Up to six inline transform ops, or a full matrix.
209
+ StyleKeys[StyleKeys["TRANSFORM_COUNT"] = 422] = "TRANSFORM_COUNT";
210
+ StyleKeys[StyleKeys["TRANSFORM_FLAGS"] = 423] = "TRANSFORM_FLAGS";
211
+ StyleKeys[StyleKeys["TRANSFORM_OP_0"] = 424] = "TRANSFORM_OP_0";
212
+ StyleKeys[StyleKeys["TRANSFORM_OP_1"] = 436] = "TRANSFORM_OP_1";
213
+ StyleKeys[StyleKeys["TRANSFORM_OP_2"] = 448] = "TRANSFORM_OP_2";
214
+ StyleKeys[StyleKeys["TRANSFORM_OP_3"] = 460] = "TRANSFORM_OP_3";
215
+ StyleKeys[StyleKeys["TRANSFORM_OP_4"] = 472] = "TRANSFORM_OP_4";
216
+ StyleKeys[StyleKeys["TRANSFORM_OP_5"] = 484] = "TRANSFORM_OP_5";
217
+ StyleKeys[StyleKeys["TRANSFORM_MATRIX"] = 496] = "TRANSFORM_MATRIX";
208
218
  StyleKeys[StyleKeys["OBJECT_POSITION_X_TYPE"] = 560] = "OBJECT_POSITION_X_TYPE";
209
219
  StyleKeys[StyleKeys["OBJECT_POSITION_Y_TYPE"] = 561] = "OBJECT_POSITION_Y_TYPE";
210
220
  StyleKeys[StyleKeys["OBJECT_POSITION_X_VALUE"] = 562] = "OBJECT_POSITION_X_VALUE";
@@ -223,6 +233,14 @@ var StyleKeys;
223
233
  StyleKeys[StyleKeys["WORD_SPACING_STATE"] = 587] = "WORD_SPACING_STATE";
224
234
  StyleKeys[StyleKeys["FONT_STRETCH"] = 588] = "FONT_STRETCH";
225
235
  StyleKeys[StyleKeys["FONT_STRETCH_STATE"] = 592] = "FONT_STRETCH_STATE";
236
+ StyleKeys[StyleKeys["LINE_CLAMP"] = 593] = "LINE_CLAMP";
237
+ StyleKeys[StyleKeys["LINE_CLAMP_STATE"] = 597] = "LINE_CLAMP_STATE";
238
+ StyleKeys[StyleKeys["TRANSFORM_ORIGIN_X_TYPE"] = 598] = "TRANSFORM_ORIGIN_X_TYPE";
239
+ StyleKeys[StyleKeys["TRANSFORM_ORIGIN_Y_TYPE"] = 599] = "TRANSFORM_ORIGIN_Y_TYPE";
240
+ StyleKeys[StyleKeys["TRANSFORM_ORIGIN_X_VALUE"] = 600] = "TRANSFORM_ORIGIN_X_VALUE";
241
+ StyleKeys[StyleKeys["TRANSFORM_ORIGIN_Y_VALUE"] = 604] = "TRANSFORM_ORIGIN_Y_VALUE";
242
+ StyleKeys[StyleKeys["TRANSFORM_ORIGIN_STATE"] = 608] = "TRANSFORM_ORIGIN_STATE";
243
+ // </style-keys:offsets>
226
244
  })(StyleKeys || (StyleKeys = {}));
227
245
  // Windows: the native Style.UpdateGrid takes all grid strings at once. To set one while preserving
228
246
  // the others, read the current values back from the Grid*Css getters. (Layout grid props like
@@ -315,18 +333,93 @@ function finite(n) {
315
333
  }
316
334
  /** 1pt = 1/72in and 1 CSS px = 1/96in, so a point is 96/72 CSS px. */
317
335
  const PX_PER_PT = 96 / 72;
336
+ /** `n<unit>` in CSS px inside a math function, or undefined for an unknown unit. */
337
+ function unitToCssPx(n, unit, emBasis) {
338
+ switch (unit) {
339
+ case 'px':
340
+ case 'dip':
341
+ return n;
342
+ case 'dppx':
343
+ return layout.toDeviceIndependentPixels(n);
344
+ case 'rem':
345
+ return n * cssUnits.rootFontSize;
346
+ case 'em':
347
+ return n * (emBasis && emBasis > 0 ? emBasis : cssUnits.rootFontSize);
348
+ case 'pt':
349
+ return n * PX_PER_PT;
350
+ case 'vw':
351
+ case 'vh':
352
+ case 'vmin':
353
+ case 'vmax': {
354
+ const { viewportWidth: w, viewportHeight: h } = cssUnits;
355
+ if (w <= 0 || h <= 0) {
356
+ reportCssDiagnostic({ kind: 'unsupported-unit', name: 'length', value: `${n}${unit}`, detail: 'viewport size not known yet, resolved to 0' });
357
+ return 0;
358
+ }
359
+ const basis = unit === 'vw' ? w : unit === 'vh' ? h : unit === 'vmin' ? Math.min(w, h) : Math.max(w, h);
360
+ return (n / 100) * basis;
361
+ }
362
+ default:
363
+ return undefined;
364
+ }
365
+ }
366
+ /**
367
+ * A math function `font-size`: `em` is parent-relative like `%`, so `calc(1.5em)` is `150%`.
368
+ * Mixed with absolute lengths, `em` and `%` resolve against the root font size instead.
369
+ */
370
+ function fontSizeMath(value) {
371
+ const parentRelative = evaluateCssMath(value, (n, unit) => (unit === 'em' ? { percent: n * 100 } : unitToCssPx(n, unit)));
372
+ return parentRelative ?? evaluateCssMath(value, (n, unit) => (unit === '%' ? (n / 100) * cssUnits.rootFontSize : unitToCssPx(n, unit)));
373
+ }
374
+ /** A calc()/min()/max()/clamp() length, with `em` against `emBasis`. */
375
+ function evaluateLengthMath(value, emBasis) {
376
+ return evaluateCssMath(value, (n, unit) => unitToCssPx(n, unit, emBasis));
377
+ }
378
+ /** `value` with every resolvable math function replaced by its result, for the native parsers. */
379
+ export function resolveCssMathIn(value, emBasis) {
380
+ return substituteCssMath(value, (n, unit) => unitToCssPx(n, unit, emBasis));
381
+ }
382
+ /**
383
+ * A math function in a `<length-percentage>` as the buffer's type/value pair,
384
+ * or undefined when `t` isn't one or doesn't resolve.
385
+ */
386
+ function mathLengthPercentage(t, emBasis, lengthType, percentType) {
387
+ if (!isCssMathFunction(t)) {
388
+ return undefined;
389
+ }
390
+ const math = evaluateLengthMath(t, emBasis);
391
+ switch (math?.kind) {
392
+ case 'length':
393
+ return { type: lengthType, value: layout.toDevicePixels(finite(math.px)) };
394
+ case 'number':
395
+ return { type: lengthType, value: layout.toDevicePixels(finite(math.value)) };
396
+ case 'percent':
397
+ // percentages are stored as a [0.0, 1.0] fraction, not percentage points
398
+ return { type: percentType, value: finite(math.percent) / 100 };
399
+ default:
400
+ return undefined;
401
+ }
402
+ }
318
403
  /**
319
404
  * Resolve a CSS length token to the device pixels the geometry buffers store.
320
405
  *
321
- * `emBasis` is the font size `em` is relative to, in CSS px — the element's own
406
+ * `emBasis` is the font size `em` is relative to, in CSS px: the element's own
322
407
  * for a length, the parent's for `font-size` itself. It falls back to the root
323
408
  * font size when the element has no font size of its own yet.
324
409
  *
325
410
  * Suffix order matters: `rem` also ends with `em`, and `dppx` with `px`.
326
411
  */
327
412
  function tokenToDevicePx(token, raw, emBasis) {
328
- const n = finite(raw);
329
413
  const t = token.trim().toLowerCase();
414
+ if (isCssMathFunction(t)) {
415
+ const math = evaluateLengthMath(t, emBasis);
416
+ if (math?.kind === 'length')
417
+ return layout.toDevicePixels(finite(math.px));
418
+ // A bare number is a CSS px to Mason, as outside calc().
419
+ if (math?.kind === 'number')
420
+ return layout.toDevicePixels(finite(math.value));
421
+ }
422
+ const n = finite(raw);
330
423
  if (t.endsWith(DEVICE_PIXEL_UNIT))
331
424
  return n;
332
425
  if (t.endsWith('rem'))
@@ -348,13 +441,12 @@ function tokenToDevicePx(token, raw, emBasis) {
348
441
  return layout.toDevicePixels((n / 100) * cssUnits.viewportWidth);
349
442
  return layout.toDevicePixels((n / 100) * cssUnits.viewportHeight);
350
443
  }
351
- // A function value — calc(), clamp(), min(), max(), var() — leaves parseFloat
352
- // with nothing, so the declaration collapses to 0. Core evaluates calc() and
353
- // var() for stylesheet declarations before mason sees them, but an inline
354
- // style or a direct JSX assignment comes straight here.
444
+ // A function value Mason can't evaluate (var(), or math mixing % with a length)
445
+ // collapses to 0.
355
446
  const fn = /^([a-z-]+)\(/.exec(t);
356
447
  if (fn) {
357
- reportCssDiagnostic({ kind: 'not-implemented', name: 'length', value: t, detail: `${fn[1]}() is not evaluated here; it resolves only in a stylesheet, where core expands it first` });
448
+ const detail = isCssMathFunction(t) ? `${fn[1]}() mixes % with a length, or doesn't parse, so it can't be evaluated before layout` : `${fn[1]}() is not evaluated here; it resolves only in a stylesheet, where core expands it first`;
449
+ reportCssDiagnostic({ kind: 'not-implemented', name: 'length', value: t, detail });
358
450
  return 0;
359
451
  }
360
452
  // A trailing alphabetic run that isn't a unit we know is a silent
@@ -426,6 +518,15 @@ export function cssLengthToDip(value, emBasis) {
426
518
  if (t === '' || t === 'auto' || t.endsWith('%')) {
427
519
  return undefined;
428
520
  }
521
+ if (isCssMathFunction(t)) {
522
+ const math = evaluateLengthMath(t, emBasis);
523
+ if (math?.kind === 'length')
524
+ return math.px;
525
+ if (math?.kind === 'number')
526
+ return math.value;
527
+ // A percentage, or % mixed with a length, keeps its own path.
528
+ return undefined;
529
+ }
429
530
  // Sizing keywords and function values have their own handling.
430
531
  if (!/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?[a-z]*$/.test(t)) {
431
532
  return undefined;
@@ -453,6 +554,10 @@ function dimensionFromString(value, emBasis) {
453
554
  case 'content':
454
555
  return { type: 9, value: 0 };
455
556
  }
557
+ const math = mathLengthPercentage(t, emBasis, 1, 2);
558
+ if (math) {
559
+ return math;
560
+ }
456
561
  if (t.startsWith('fit-content(') && t.endsWith(')')) {
457
562
  const limit = t.slice('fit-content('.length, -1).trim();
458
563
  if (limit.endsWith('%')) {
@@ -475,6 +580,10 @@ function lengthPercentageAutoFromString(value, emBasis) {
475
580
  if (t === '' || t === 'auto') {
476
581
  return { type: 0, value: 0 };
477
582
  }
583
+ const math = mathLengthPercentage(t, emBasis, 1, 2);
584
+ if (math) {
585
+ return math;
586
+ }
478
587
  if (t.endsWith('%')) {
479
588
  return { type: 2, value: finite(parseFloat(t) || 0) / 100 };
480
589
  }
@@ -484,6 +593,10 @@ function lengthPercentageAutoFromString(value, emBasis) {
484
593
  // Same as lengthPercentageAutoFromString but for padding (no "auto", type 0/1 swapped)
485
594
  function lengthPercentageFromString(value, emBasis) {
486
595
  const t = value.trim();
596
+ const math = mathLengthPercentage(t, emBasis, 0, 1);
597
+ if (math) {
598
+ return math;
599
+ }
487
600
  if (t.endsWith('%')) {
488
601
  return { type: 1, value: finite(parseFloat(t) || 0) / 100 };
489
602
  }
@@ -535,6 +648,7 @@ class StateKeys {
535
648
  }
536
649
  }
537
650
  StateKeys.NONE = new StateKeys(0, 0, 0, 0);
651
+ // <style-keys:state> generated from tools/scripts/style-keys/style-keys.schema, run `npm run gen:style-keys`
538
652
  StateKeys.DISPLAY = StateKeys.flag(0);
539
653
  StateKeys.POSITION = StateKeys.flag(1);
540
654
  StateKeys.DIRECTION = StateKeys.flag(2);
@@ -584,7 +698,7 @@ StateKeys.OBJECT_FIT = StateKeys.flag(45);
584
698
  StateKeys.Z_INDEX = StateKeys.flag(46);
585
699
  StateKeys.LIST_STYLE_POSITION = StateKeys.flag(47);
586
700
  StateKeys.LIST_STYLE_TYPE = StateKeys.flag(48);
587
- StateKeys.INVALIDATE_TEXT = StateKeys.flag(49);
701
+ StateKeys.INVALIDATE_TEXT = StateKeys.flag(49); // Kotlin's INVALIDATE_TEXT is every bit
588
702
  StateKeys.FONT_COLOR = StateKeys.flag(50);
589
703
  StateKeys.DECORATION_LINE = StateKeys.flag(51);
590
704
  StateKeys.DECORATION_COLOR = StateKeys.flag(52);
@@ -614,9 +728,13 @@ StateKeys.HYPHENS = StateKeys.flag(75);
614
728
  StateKeys.CARET_COLOR = StateKeys.flag(76);
615
729
  StateKeys.WORD_SPACING = StateKeys.flag(77);
616
730
  StateKeys.FONT_STRETCH = StateKeys.flag(78);
731
+ StateKeys.TEXT_INDENT = StateKeys.flag(79);
732
+ StateKeys.LINE_CLAMP = StateKeys.flag(80);
733
+ StateKeys.TRANSFORM_ORIGIN = StateKeys.flag(81);
734
+ // </style-keys:state>
617
735
  StateKeys.DISPLAY_AND_MODE = StateKeys.DISPLAY.or(StateKeys.DISPLAY_MODE);
618
736
  StateKeys.FLOW_TYPE = StateKeys.DISPLAY.or(StateKeys.DISPLAY_MODE).or(StateKeys.POSITION).or(StateKeys.FLOAT);
619
- StateKeys.WINDOWS_TEXT = [49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 77, 78].reduce((mask, n) => mask.or(StateKeys.flag(n)), StateKeys.NONE);
737
+ StateKeys.WINDOWS_TEXT = [StateKeys.INVALIDATE_TEXT, StateKeys.FONT_COLOR, StateKeys.DECORATION_LINE, StateKeys.DECORATION_COLOR, StateKeys.TEXT_ALIGN, StateKeys.TEXT_JUSTIFY, StateKeys.FONT_SIZE, StateKeys.TEXT_TRANSFORM, StateKeys.FONT_STYLE, StateKeys.FONT_STYLE_SLANT, StateKeys.TEXT_WRAP, StateKeys.TEXT_OVERFLOW, StateKeys.DECORATION_STYLE, StateKeys.WHITE_SPACE, StateKeys.FONT_WEIGHT, StateKeys.LINE_HEIGHT, StateKeys.VERTICAL_ALIGN, StateKeys.DECORATION_THICKNESS, StateKeys.TEXT_SHADOWS, StateKeys.FONT_FAMILY, StateKeys.LETTER_SPACING, StateKeys.FONT_VARIANT_NUMERIC, StateKeys.WRITING_MODE, StateKeys.UNICODE_BIDI, StateKeys.HYPHENS, StateKeys.WORD_SPACING, StateKeys.FONT_STRETCH, StateKeys.TEXT_INDENT, StateKeys.LINE_CLAMP].reduce((mask, key) => mask.or(key), StateKeys.NONE);
620
738
  function wordsToBigInt(w0, w1, w2, w3) {
621
739
  return BigInt(w0 >>> 0) | (BigInt(w1 >>> 0) << 32n) | (BigInt(w2 >>> 0) << 64n) | (BigInt(w3 >>> 0) << 96n);
622
740
  }
@@ -1186,6 +1304,30 @@ function parseObjectPosition(value) {
1186
1304
  return null;
1187
1305
  return { xType: x.type, xVal: x.val, yType: y.type, yVal: y.val };
1188
1306
  }
1307
+ const ORIGIN_X_KEYWORDS = { left: 0, center: 50, right: 100 };
1308
+ const ORIGIN_Y_KEYWORDS = { top: 0, center: 50, bottom: 100 };
1309
+ /** `transform-origin` as two (type, value) pairs: type 0 is device px, 1 is percent. A z offset is ignored. */
1310
+ export function parseTransformOrigin(value, emBasis) {
1311
+ const parts = value.trim().toLowerCase().split(/\s+/).filter(Boolean);
1312
+ if (parts.length === 0 || parts.length > 3)
1313
+ return null;
1314
+ const length = (token) => {
1315
+ const n = parseFloat(token);
1316
+ if (!Number.isFinite(n))
1317
+ return null;
1318
+ return token.endsWith('%') ? { type: 1, value: n } : { type: 0, value: tokenToDevicePx(token, n, emBasis) };
1319
+ };
1320
+ let [first, second = 'center'] = parts;
1321
+ // Keywords may come in either order (`top left`); lengths are always x then y.
1322
+ if (ORIGIN_Y_KEYWORDS[first] !== undefined && first !== 'center' && (ORIGIN_X_KEYWORDS[second] !== undefined || parts.length === 1)) {
1323
+ [first, second] = [second, first];
1324
+ }
1325
+ const x = ORIGIN_X_KEYWORDS[first] !== undefined ? { type: 1, value: ORIGIN_X_KEYWORDS[first] } : length(first);
1326
+ const y = ORIGIN_Y_KEYWORDS[second] !== undefined ? { type: 1, value: ORIGIN_Y_KEYWORDS[second] } : length(second);
1327
+ if (!x || !y)
1328
+ return null;
1329
+ return { xType: x.type, x: x.value, yType: y.type, y: y.value };
1330
+ }
1189
1331
  const FONT_STRETCH_KEYWORDS = {
1190
1332
  'ultra-condensed': 5000,
1191
1333
  'extra-condensed': 6250,
@@ -1490,7 +1632,9 @@ export class Style {
1490
1632
  // whose parsers don't read modern colour syntax; see css-colors.ts.
1491
1633
  coerceCssStringValue(value) {
1492
1634
  if (typeof value === 'string') {
1493
- return resolveCssColors(value, cssColorToRgba);
1635
+ // Nor do they evaluate calc()/min()/max()/clamp(); see css-math.ts.
1636
+ const resolved = hasCssMathFunction(value) ? resolveCssMathIn(value, this.emBasis()) : value;
1637
+ return resolveCssColors(resolved, cssColorToRgba);
1494
1638
  }
1495
1639
  if (value == null) {
1496
1640
  return '';
@@ -1820,6 +1964,34 @@ export class Style {
1820
1964
  this.writeBorderSide(side, null, null, color);
1821
1965
  this.commitState(StateKeys.BORDER_COLOR);
1822
1966
  }
1967
+ // Per-side colors by name, as pseudo-class styles and the border shorthands assign them.
1968
+ borderSideColor(key) {
1969
+ return new Color(getUint32(this.style_view, key)).hex;
1970
+ }
1971
+ get borderTopColor() {
1972
+ return this.borderSideColor(StyleKeys.BORDER_TOP_COLOR);
1973
+ }
1974
+ set borderTopColor(value) {
1975
+ this.setBorderSideColor('top', value);
1976
+ }
1977
+ get borderRightColor() {
1978
+ return this.borderSideColor(StyleKeys.BORDER_RIGHT_COLOR);
1979
+ }
1980
+ set borderRightColor(value) {
1981
+ this.setBorderSideColor('right', value);
1982
+ }
1983
+ get borderBottomColor() {
1984
+ return this.borderSideColor(StyleKeys.BORDER_BOTTOM_COLOR);
1985
+ }
1986
+ set borderBottomColor(value) {
1987
+ this.setBorderSideColor('bottom', value);
1988
+ }
1989
+ get borderLeftColor() {
1990
+ return this.borderSideColor(StyleKeys.BORDER_LEFT_COLOR);
1991
+ }
1992
+ set borderLeftColor(value) {
1993
+ this.setBorderSideColor('left', value);
1994
+ }
1823
1995
  resetState() {
1824
1996
  this._hasDirty = false;
1825
1997
  this._d0 = this._d1 = this._d2 = this._d3 = 0;
@@ -1875,7 +2047,7 @@ export class Style {
1875
2047
  const target = new Uint8Array(NSWinRT.interop.arrayBufferFromBuffer(masonEngine().StyleValues(text)));
1876
2048
  target.set(this.u8View.subarray(StyleKeys.FONT_COLOR, StyleKeys.BACKGROUND_COLOR), StyleKeys.FONT_COLOR);
1877
2049
  target.set(this.u8View.subarray(StyleKeys.DECORATION_LINE, StyleKeys.PSEUDO_SET_MASK_LOW), StyleKeys.DECORATION_LINE);
1878
- target.set(this.u8View.subarray(StyleKeys.HYPHENS, StyleKeys.FONT_STRETCH_STATE + 1), StyleKeys.HYPHENS);
2050
+ target.set(this.u8View.subarray(StyleKeys.HYPHENS, StyleKeys.LINE_CLAMP_STATE + 1), StyleKeys.HYPHENS);
1879
2051
  if (block) {
1880
2052
  target[StyleKeys.DISPLAY] = 3;
1881
2053
  target[StyleKeys.DISPLAY_MODE] = 0 /* DisplayMode.None */;
@@ -1918,19 +2090,35 @@ export class Style {
1918
2090
  return this.view_;
1919
2091
  }
1920
2092
  /**
1921
- * The font size `em` resolves against, in CSS px: the element's own when it has
1922
- * one, otherwise the root font size. FONT_SIZE is stored in dip, which is the
1923
- * same as a CSS px, so no conversion is needed.
2093
+ * The font size `em` resolves against, in CSS px: the element's computed one,
2094
+ * with a percentage of the parent's, or the inherited one when unset.
1924
2095
  */
1925
2096
  emBasis() {
1926
- if (!this.style_view) {
1927
- return cssUnits.rootFontSize;
1928
- }
1929
- if (getInt8(this.style_view, StyleKeys.FONT_SIZE_STATE) !== 1) {
1930
- return cssUnits.rootFontSize;
2097
+ if (!this.style_view || getInt8(this.style_view, StyleKeys.FONT_SIZE_STATE) !== 1) {
2098
+ return this.parentEmBasis();
1931
2099
  }
1932
2100
  const own = getInt32(this.style_view, StyleKeys.FONT_SIZE);
1933
- return own > 0 ? own : cssUnits.rootFontSize;
2101
+ if (own <= 0) {
2102
+ return this.parentEmBasis();
2103
+ }
2104
+ // `0.75em` is stored as 75 (%), not 75px.
2105
+ return getInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE) === 1 ? (own / 100) * this.parentEmBasis() : own;
2106
+ }
2107
+ /**
2108
+ * The nearest Mason ancestor's font size (the element's own for a pseudo-class
2109
+ * style). Reads only existing styles, since building one creates the native view.
2110
+ */
2111
+ parentEmBasis() {
2112
+ const view = this.view_;
2113
+ let ancestor = (this._pseudo ? view : view?.parent);
2114
+ for (let depth = 0; ancestor && depth < 256; depth++) {
2115
+ const style = ancestor[style_];
2116
+ if (style instanceof Style && style !== this) {
2117
+ return style.emBasis();
2118
+ }
2119
+ ancestor = ancestor.parent;
2120
+ }
2121
+ return cssUnits.rootFontSize;
1934
2122
  }
1935
2123
  prepareMut() {
1936
2124
  if (this._pseudo) {
@@ -2061,7 +2249,12 @@ export class Style {
2061
2249
  this.prepareMut();
2062
2250
  let resolved = n;
2063
2251
  let isPercent = false;
2064
- if (t.endsWith('%')) {
2252
+ const math = isCssMathFunction(t) ? fontSizeMath(t) : undefined;
2253
+ if (math) {
2254
+ isPercent = math.kind === 'percent';
2255
+ resolved = finite(math.kind === 'length' ? math.px : math.kind === 'percent' ? math.percent : math.value);
2256
+ }
2257
+ else if (t.endsWith('%')) {
2065
2258
  isPercent = true;
2066
2259
  }
2067
2260
  else if (t.endsWith('rem')) {
@@ -5927,6 +6120,109 @@ export class Style {
5927
6120
  setUint8(this.style_view, StyleKeys.HYPHENS_STATE, 1);
5928
6121
  this.commitState(StateKeys.HYPHENS);
5929
6122
  }
6123
+ get textIndent() {
6124
+ if (!this.style_view || !getUint8(this.style_view, StyleKeys.TEXT_INDENT_STATE))
6125
+ return '0px';
6126
+ const value = getFloat32(this.style_view, StyleKeys.TEXT_INDENT);
6127
+ return getUint8(this.style_view, StyleKeys.TEXT_INDENT_TYPE) === 1 ? `${value}%` : `${layout.toDeviceIndependentPixels(value)}px`;
6128
+ }
6129
+ set textIndent(value) {
6130
+ if (!this.style_view)
6131
+ return;
6132
+ let type = 0;
6133
+ let indent;
6134
+ if (typeof value === 'number') {
6135
+ indent = layout.toDevicePixels(value);
6136
+ }
6137
+ else {
6138
+ // `each-line` and `hanging` are not supported; the length still applies.
6139
+ const token = String(value ?? '')
6140
+ .trim()
6141
+ .split(/\s+/)
6142
+ .find((t) => t !== 'each-line' && t !== 'hanging');
6143
+ if (!token)
6144
+ return;
6145
+ const n = parseFloat(token);
6146
+ if (!Number.isFinite(n))
6147
+ return;
6148
+ if (token.endsWith('%')) {
6149
+ type = 1;
6150
+ indent = n;
6151
+ }
6152
+ else {
6153
+ indent = tokenToDevicePx(token, n, this.emBasis());
6154
+ }
6155
+ }
6156
+ this.prepareMut();
6157
+ setFloat32(this.style_view, StyleKeys.TEXT_INDENT, indent);
6158
+ setUint8(this.style_view, StyleKeys.TEXT_INDENT_TYPE, type);
6159
+ setUint8(this.style_view, StyleKeys.TEXT_INDENT_STATE, 1);
6160
+ this.commitState(StateKeys.TEXT_INDENT);
6161
+ }
6162
+ set 'text-indent'(value) {
6163
+ this.textIndent = value;
6164
+ }
6165
+ get 'text-indent'() {
6166
+ return this.textIndent;
6167
+ }
6168
+ get lineClamp() {
6169
+ if (!this.style_view || !getUint8(this.style_view, StyleKeys.LINE_CLAMP_STATE))
6170
+ return 'none';
6171
+ const lines = getInt32(this.style_view, StyleKeys.LINE_CLAMP);
6172
+ return lines > 0 ? lines : 'none';
6173
+ }
6174
+ set lineClamp(value) {
6175
+ if (!this.style_view)
6176
+ return;
6177
+ const lines = value === 'none' ? 0 : Math.trunc(Number(value));
6178
+ if (!Number.isFinite(lines) || lines < 0)
6179
+ return;
6180
+ this.prepareMut();
6181
+ setInt32(this.style_view, StyleKeys.LINE_CLAMP, lines);
6182
+ setUint8(this.style_view, StyleKeys.LINE_CLAMP_STATE, 1);
6183
+ this.commitState(StateKeys.LINE_CLAMP);
6184
+ }
6185
+ set 'line-clamp'(value) {
6186
+ this.lineClamp = value;
6187
+ }
6188
+ get 'line-clamp'() {
6189
+ return this.lineClamp;
6190
+ }
6191
+ set '-webkit-line-clamp'(value) {
6192
+ this.lineClamp = value;
6193
+ }
6194
+ get '-webkit-line-clamp'() {
6195
+ return this.lineClamp;
6196
+ }
6197
+ get transformOrigin() {
6198
+ if (!this.style_view || !getUint8(this.style_view, StyleKeys.TRANSFORM_ORIGIN_STATE))
6199
+ return '50% 50%';
6200
+ const side = (typeKey, valueKey) => {
6201
+ const value = getFloat32(this.style_view, valueKey);
6202
+ return getUint8(this.style_view, typeKey) === 1 ? `${value}%` : `${layout.toDeviceIndependentPixels(value)}px`;
6203
+ };
6204
+ return `${side(StyleKeys.TRANSFORM_ORIGIN_X_TYPE, StyleKeys.TRANSFORM_ORIGIN_X_VALUE)} ${side(StyleKeys.TRANSFORM_ORIGIN_Y_TYPE, StyleKeys.TRANSFORM_ORIGIN_Y_VALUE)}`;
6205
+ }
6206
+ set transformOrigin(value) {
6207
+ if (!this.style_view)
6208
+ return;
6209
+ const parsed = parseTransformOrigin(String(value ?? ''), this.emBasis());
6210
+ if (!parsed)
6211
+ return;
6212
+ this.prepareMut();
6213
+ setUint8(this.style_view, StyleKeys.TRANSFORM_ORIGIN_X_TYPE, parsed.xType);
6214
+ setUint8(this.style_view, StyleKeys.TRANSFORM_ORIGIN_Y_TYPE, parsed.yType);
6215
+ setFloat32(this.style_view, StyleKeys.TRANSFORM_ORIGIN_X_VALUE, parsed.x);
6216
+ setFloat32(this.style_view, StyleKeys.TRANSFORM_ORIGIN_Y_VALUE, parsed.y);
6217
+ setUint8(this.style_view, StyleKeys.TRANSFORM_ORIGIN_STATE, 1);
6218
+ this.commitState(StateKeys.TRANSFORM_ORIGIN);
6219
+ }
6220
+ set 'transform-origin'(value) {
6221
+ this.transformOrigin = value;
6222
+ }
6223
+ get 'transform-origin'() {
6224
+ return this.transformOrigin;
6225
+ }
5930
6226
  get backdropFilter() {
5931
6227
  if (!this.nativeView)
5932
6228
  return '';
@@ -6463,6 +6759,9 @@ export class Style {
6463
6759
  caretColor: this.caretColor,
6464
6760
  wordSpacing: this.wordSpacing,
6465
6761
  fontStretch: this.fontStretch,
6762
+ textIndent: this.textIndent,
6763
+ lineClamp: this.lineClamp,
6764
+ transformOrigin: this.transformOrigin,
6466
6765
  };
6467
6766
  }
6468
6767
  }