@triniwiz/nativescript-masonkit 1.0.0-beta.89 → 1.0.0-beta.90

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 (109) hide show
  1. package/angular/fesm2022/triniwiz-nativescript-masonkit-angular.mjs +23 -66
  2. package/angular/fesm2022/triniwiz-nativescript-masonkit-angular.mjs.map +1 -1
  3. package/angular/types/triniwiz-nativescript-masonkit-angular.d.ts +9 -17
  4. package/common.d.ts +1 -0
  5. package/common.js +21 -1
  6. package/common.js.map +1 -1
  7. package/diagnostics.d.ts +51 -0
  8. package/diagnostics.js +53 -0
  9. package/diagnostics.js.map +1 -0
  10. package/elements.d.ts +55 -0
  11. package/elements.js +80 -0
  12. package/elements.js.map +1 -0
  13. package/fonts.d.ts +9 -0
  14. package/fonts.js +24 -0
  15. package/fonts.js.map +1 -0
  16. package/index.android.d.ts +3 -0
  17. package/index.android.js +5 -0
  18. package/index.android.js.map +1 -1
  19. package/index.d.ts +25 -2
  20. package/index.ios.d.ts +3 -0
  21. package/index.ios.js +3 -0
  22. package/index.ios.js.map +1 -1
  23. package/index.windows.d.ts +2 -0
  24. package/index.windows.js +2 -0
  25. package/index.windows.js.map +1 -1
  26. package/package.json +1 -1
  27. package/platforms/android/masonkit-release.aar +0 -0
  28. package/platforms/ios/Mason.xcframework/Info.plist +36 -2
  29. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Headers/Mason-Swift.h +16 -0
  30. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Mason +0 -0
  31. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  32. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.abi.json +11806 -2726
  33. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.private.swiftinterface +7 -0
  34. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  35. package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.swiftinterface +7 -0
  36. package/platforms/ios/Mason.xcframework/ios-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  37. package/platforms/ios/Mason.xcframework/ios-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +8413 -8374
  38. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Headers/Mason-Swift.h +32 -0
  39. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Mason +0 -0
  40. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
  41. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
  42. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.abi.json +11806 -2726
  43. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +7 -0
  44. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  45. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.swiftinterface +7 -0
  46. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.abi.json +11806 -2726
  47. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +7 -0
  48. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  49. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +7 -0
  50. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/_CodeSignature/CodeResources +26 -26
  51. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  52. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +8408 -8369
  53. package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/x86_64/Mason.yml +8049 -8008
  54. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Headers/Mason-Swift.h +2030 -0
  55. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Headers/Mason.h +25 -0
  56. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Headers/mason_native.h +524 -0
  57. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Info.plist +0 -0
  58. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Mason +0 -0
  59. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-xros.swiftsourceinfo +0 -0
  60. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.abi.json +110027 -0
  61. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.private.swiftinterface +3524 -0
  62. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.swiftdoc +0 -0
  63. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.swiftinterface +3524 -0
  64. package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/module.modulemap +10 -0
  65. package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Info.plist +20 -0
  66. package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  67. package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +8016 -0
  68. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Headers/Mason-Swift.h +2030 -0
  69. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Headers/Mason.h +25 -0
  70. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Headers/mason_native.h +524 -0
  71. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Info.plist +0 -0
  72. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Mason +0 -0
  73. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-xros-simulator.swiftsourceinfo +0 -0
  74. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.abi.json +110027 -0
  75. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.private.swiftinterface +3524 -0
  76. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.swiftdoc +0 -0
  77. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.swiftinterface +3524 -0
  78. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/module.modulemap +10 -0
  79. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/_CodeSignature/CodeResources +212 -0
  80. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Info.plist +20 -0
  81. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
  82. package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +8016 -0
  83. package/properties.d.ts +5 -0
  84. package/properties.js +341 -110
  85. package/properties.js.map +1 -1
  86. package/style.d.ts +38 -5
  87. package/style.js +434 -72
  88. package/style.js.map +1 -1
  89. package/symbols.d.ts +0 -1
  90. package/symbols.js +0 -1
  91. package/symbols.js.map +1 -1
  92. package/tree/index.android.js +3 -0
  93. package/tree/index.android.js.map +1 -1
  94. package/tree/index.ios.d.ts +5 -1
  95. package/tree/index.ios.js +18 -0
  96. package/tree/index.ios.js.map +1 -1
  97. package/tree/index.windows.d.ts +5 -1
  98. package/tree/index.windows.js +4 -0
  99. package/tree/index.windows.js.map +1 -1
  100. package/units.d.ts +22 -0
  101. package/units.js +17 -0
  102. package/units.js.map +1 -0
  103. package/utils/index.android.js +5 -5
  104. package/utils/index.android.js.map +1 -1
  105. package/utils/index.ios.js +5 -5
  106. package/utils/index.ios.js.map +1 -1
  107. package/web.d.ts +142 -10
  108. package/web.js +459 -12
  109. package/web.js.map +1 -1
package/style.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { layout } from '@nativescript/core/utils';
2
+ import { cssUnits } from './units';
3
+ import { reportCssDiagnostic } from './diagnostics';
2
4
  import { Color, Length as CoreLength, PercentLength as CorePercentLength } from '@nativescript/core';
3
5
  var StyleKeys;
4
6
  (function (StyleKeys) {
@@ -256,12 +258,14 @@ function windowsSetGrid(nativeView, field, value) {
256
258
  }
257
259
  catch (_) { }
258
260
  }
261
+ // The buffer holds device pixels; `px` on the way out means a CSS pixel, the
262
+ // same as on the way in, so a get/set round-trip is lossless.
259
263
  function parseDimension(type, value) {
260
264
  switch (type) {
261
265
  case 0:
262
266
  return 'auto';
263
267
  case 1:
264
- return { value, unit: 'px' };
268
+ return { value: layout.toDeviceIndependentPixels(value), unit: 'px' };
265
269
  case 2:
266
270
  return { value, unit: '%' };
267
271
  case 3:
@@ -271,7 +275,7 @@ function parseDimension(type, value) {
271
275
  case 5:
272
276
  return 'fit-content';
273
277
  case 6:
274
- return `fit-content(${value}px)`;
278
+ return `fit-content(${layout.toDeviceIndependentPixels(value)}px)`;
275
279
  case 7:
276
280
  return `fit-content(${value}%)`;
277
281
  case 8:
@@ -283,7 +287,78 @@ function parseDimension(type, value) {
283
287
  function parseLengthPercentageAuto(type, value) {
284
288
  return parseDimension(type, value);
285
289
  }
286
- function dimensionFromString(value) {
290
+ // CSS `px` is a CSS pixel, which is the same size as a dip — so it scales with
291
+ // the device, exactly as on the web. This deliberately differs from
292
+ // @nativescript/core, where `px` means a literal device pixel; `dppx` is the
293
+ // escape hatch for that meaning.
294
+ const DEVICE_PIXEL_UNIT = 'dppx';
295
+ function isDevicePixelToken(token) {
296
+ return token.trim().toLowerCase().endsWith(DEVICE_PIXEL_UNIT);
297
+ }
298
+ // A declaration that parses to a non-finite number (`1e999px`, `calc(infinity *
299
+ // 1px)` after core evaluates it) is not usable; treat it as 0, matching how the
300
+ // existing parsers already handle an unparsable value.
301
+ function finite(n) {
302
+ if (Number.isFinite(n)) {
303
+ return n;
304
+ }
305
+ reportCssDiagnostic({ kind: 'unparsable-value', name: 'length', value: String(n), detail: 'not a finite number, treated as 0' });
306
+ return 0;
307
+ }
308
+ /** 1pt = 1/72in and 1 CSS px = 1/96in, so a point is 96/72 CSS px. */
309
+ const PX_PER_PT = 96 / 72;
310
+ /**
311
+ * Resolve a CSS length token to the device pixels the geometry buffers store.
312
+ *
313
+ * `emBasis` is the font size `em` is relative to, in CSS px — the element's own
314
+ * for a length, the parent's for `font-size` itself. It falls back to the root
315
+ * font size when the element has no font size of its own yet.
316
+ *
317
+ * Suffix order matters: `rem` also ends with `em`, and `dppx` with `px`.
318
+ */
319
+ function tokenToDevicePx(token, raw, emBasis) {
320
+ const n = finite(raw);
321
+ const t = token.trim().toLowerCase();
322
+ if (t.endsWith(DEVICE_PIXEL_UNIT))
323
+ return n;
324
+ if (t.endsWith('rem'))
325
+ return layout.toDevicePixels(n * cssUnits.rootFontSize);
326
+ if (t.endsWith('em'))
327
+ return layout.toDevicePixels(n * (emBasis && emBasis > 0 ? emBasis : cssUnits.rootFontSize));
328
+ if (t.endsWith('pt'))
329
+ return layout.toDevicePixels(n * PX_PER_PT);
330
+ if (t.endsWith('vmin') || t.endsWith('vmax') || t.endsWith('vw') || t.endsWith('vh')) {
331
+ if (cssUnits.viewportWidth <= 0 || cssUnits.viewportHeight <= 0) {
332
+ reportCssDiagnostic({ kind: 'unsupported-unit', name: 'length', value: t, detail: 'viewport size not known yet, resolved to 0' });
333
+ return 0;
334
+ }
335
+ if (t.endsWith('vmin'))
336
+ return layout.toDevicePixels((n / 100) * Math.min(cssUnits.viewportWidth, cssUnits.viewportHeight));
337
+ if (t.endsWith('vmax'))
338
+ return layout.toDevicePixels((n / 100) * Math.max(cssUnits.viewportWidth, cssUnits.viewportHeight));
339
+ if (t.endsWith('vw'))
340
+ return layout.toDevicePixels((n / 100) * cssUnits.viewportWidth);
341
+ return layout.toDevicePixels((n / 100) * cssUnits.viewportHeight);
342
+ }
343
+ // A function value — calc(), clamp(), min(), max(), var() — leaves parseFloat
344
+ // with nothing, so the declaration collapses to 0. Core evaluates calc() and
345
+ // var() for stylesheet declarations before mason sees them, but an inline
346
+ // style or a direct JSX assignment comes straight here.
347
+ const fn = /^([a-z-]+)\(/.exec(t);
348
+ if (fn) {
349
+ 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` });
350
+ return 0;
351
+ }
352
+ // A trailing alphabetic run that isn't a unit we know is a silent
353
+ // mis-resolution waiting to happen — `1ch` would quietly become 1 CSS px.
354
+ const unit = /[a-z%]+$/.exec(t)?.[0];
355
+ if (unit && unit !== 'px' && unit !== 'dip') {
356
+ reportCssDiagnostic({ kind: 'unsupported-unit', name: 'length', value: t, detail: `unknown unit "${unit}", treated as CSS px` });
357
+ }
358
+ // px, dip and a bare number are all CSS pixels.
359
+ return layout.toDevicePixels(n);
360
+ }
361
+ function dimensionFromString(value, emBasis) {
287
362
  const t = value.trim();
288
363
  if (t === '' || t === 'auto') {
289
364
  return { type: 0, value: 0 };
@@ -304,43 +379,43 @@ function dimensionFromString(value) {
304
379
  const limit = t.slice('fit-content('.length, -1).trim();
305
380
  if (limit.endsWith('%')) {
306
381
  // taffy percentages are a [0.0, 1.0] fraction, not [0.0, 100.0]
307
- return { type: 7, value: (parseFloat(limit) || 0) / 100 };
382
+ return { type: 7, value: finite(parseFloat(limit) || 0) / 100 };
308
383
  }
309
384
  const n = parseFloat(limit) || 0;
310
- return { type: 6, value: limit.endsWith('px') ? n : layout.toDevicePixels(n) };
385
+ return { type: 6, value: tokenToDevicePx(limit, n, emBasis) };
311
386
  }
312
387
  if (t.endsWith('%')) {
313
388
  // percentages are stored as a [0.0, 1.0] fraction, not percentage points
314
- return { type: 2, value: (parseFloat(t) || 0) / 100 };
389
+ return { type: 2, value: finite(parseFloat(t) || 0) / 100 };
315
390
  }
316
391
  const n = parseFloat(t) || 0;
317
- return { type: 1, value: t.endsWith('px') ? n : layout.toDevicePixels(n) };
392
+ return { type: 1, value: tokenToDevicePx(t, n, emBasis) };
318
393
  }
319
394
  // Shared parser for LengthPercentageAuto props (min/max width/height, margin, inset)
320
- function lengthPercentageAutoFromString(value) {
395
+ function lengthPercentageAutoFromString(value, emBasis) {
321
396
  const t = value.trim();
322
397
  if (t === '' || t === 'auto') {
323
398
  return { type: 0, value: 0 };
324
399
  }
325
400
  if (t.endsWith('%')) {
326
- return { type: 2, value: (parseFloat(t) || 0) / 100 };
401
+ return { type: 2, value: finite(parseFloat(t) || 0) / 100 };
327
402
  }
328
403
  const n = parseFloat(t) || 0;
329
- return { type: 1, value: t.endsWith('px') ? n : layout.toDevicePixels(n) };
404
+ return { type: 1, value: tokenToDevicePx(t, n, emBasis) };
330
405
  }
331
406
  // Same as lengthPercentageAutoFromString but for padding (no "auto", type 0/1 swapped)
332
- function lengthPercentageFromString(value) {
407
+ function lengthPercentageFromString(value, emBasis) {
333
408
  const t = value.trim();
334
409
  if (t.endsWith('%')) {
335
- return { type: 1, value: (parseFloat(t) || 0) / 100 };
410
+ return { type: 1, value: finite(parseFloat(t) || 0) / 100 };
336
411
  }
337
412
  const n = parseFloat(t) || 0;
338
- return { type: 0, value: t.endsWith('px') ? n : layout.toDevicePixels(n) };
413
+ return { type: 0, value: tokenToDevicePx(t, n, emBasis) };
339
414
  }
340
415
  function parseLengthPercentage(type, value) {
341
416
  switch (type) {
342
417
  case 0:
343
- return { value, unit: 'px' };
418
+ return { value: layout.toDeviceIndependentPixels(value), unit: 'px' };
344
419
  case 1:
345
420
  return { value, unit: '%' };
346
421
  }
@@ -624,6 +699,22 @@ function parseSideLength(tok) {
624
699
  return { value: n, unit: '%' };
625
700
  return n; // bare number = dip
626
701
  }
702
+ // Split a `margin`/`padding`/`inset` shorthand into its four sides in CSS order.
703
+ // The raw token strings are handed to the longhand setters rather than parsed
704
+ // here, so there stays exactly one place that knows how to read a length.
705
+ function expandSidesShorthand(value) {
706
+ const parts = value.trim().split(/\s+/).filter(Boolean);
707
+ if (parts.length < 2)
708
+ return null;
709
+ switch (parts.length) {
710
+ case 2:
711
+ return [parts[0], parts[1], parts[0], parts[1]];
712
+ case 3:
713
+ return [parts[0], parts[1], parts[2], parts[1]];
714
+ default:
715
+ return [parts[0], parts[1], parts[2], parts[3]];
716
+ }
717
+ }
627
718
  // Expand a CSS padding/margin shorthand (number or 1-4 space-separated values) to per-side lengths.
628
719
  function parseSidesShorthand(value) {
629
720
  if (typeof value === 'number')
@@ -1205,6 +1296,21 @@ export class Style {
1205
1296
  get view() {
1206
1297
  return this.view_;
1207
1298
  }
1299
+ /**
1300
+ * The font size `em` resolves against, in CSS px: the element's own when it has
1301
+ * one, otherwise the root font size. FONT_SIZE is stored in dip, which is the
1302
+ * same as a CSS px, so no conversion is needed.
1303
+ */
1304
+ emBasis() {
1305
+ if (!this.style_view) {
1306
+ return cssUnits.rootFontSize;
1307
+ }
1308
+ if (getInt8(this.style_view, StyleKeys.FONT_SIZE_STATE) !== 1) {
1309
+ return cssUnits.rootFontSize;
1310
+ }
1311
+ const own = getInt32(this.style_view, StyleKeys.FONT_SIZE);
1312
+ return own > 0 ? own : cssUnits.rootFontSize;
1313
+ }
1208
1314
  prepareMut() {
1209
1315
  // always mut
1210
1316
  if (this._pseudo) {
@@ -1274,6 +1380,39 @@ export class Style {
1274
1380
  this.commitState(StateKeys.BOX_SIZING);
1275
1381
  }
1276
1382
  }
1383
+ get listStyleType() {
1384
+ switch (getUint8(this.style_view, StyleKeys.LIST_STYLE_TYPE)) {
1385
+ case 1:
1386
+ return 'custom';
1387
+ case 2:
1388
+ return 'disc';
1389
+ case 3:
1390
+ return 'circle';
1391
+ case 4:
1392
+ return 'square';
1393
+ case 5:
1394
+ return 'decimal';
1395
+ default:
1396
+ return 'none';
1397
+ }
1398
+ }
1399
+ // Resolved by `View.kt`'s/`MasonUIView.swift`'s `drawListItemMarkers`
1400
+ // (walks a plain container's children for `TextType.Li`-flavored text and
1401
+ // draws a bullet/number to the left of each) — not wired to Taffy layout
1402
+ // at all, purely a draw-time lookup on whichever of the `<li>` or its
1403
+ // parent set this explicitly (`LIST_STYLE_TYPE_STATE` marks "explicitly
1404
+ // set" vs "inherit", matching every other per-tag CSS default in this file).
1405
+ set listStyleType(value) {
1406
+ const map = { none: 0, custom: 1, disc: 2, circle: 3, square: 4, decimal: 5 };
1407
+ const mapped = map[value];
1408
+ if (mapped === undefined) {
1409
+ return;
1410
+ }
1411
+ this.prepareMut();
1412
+ setUint8(this.style_view, StyleKeys.LIST_STYLE_TYPE, mapped);
1413
+ setInt8(this.style_view, StyleKeys.LIST_STYLE_TYPE_STATE, 1);
1414
+ this.commitState(StateKeys.LIST_STYLE_TYPE);
1415
+ }
1277
1416
  get fontSize() {
1278
1417
  if (!this.style_view) {
1279
1418
  // BLACK ?
@@ -1291,6 +1430,42 @@ export class Style {
1291
1430
  return;
1292
1431
  }
1293
1432
  switch (typeof value) {
1433
+ case 'string': {
1434
+ // FONT_SIZE is stored in dip (the natives apply the density themselves),
1435
+ // so a CSS px value goes in as-is; `dppx` is the one spelling that has to
1436
+ // be converted back out of device pixels.
1437
+ //
1438
+ // On font-size, `em` is relative to the *parent's* font size — which is
1439
+ // exactly what the buffer's percent type already means, so `1.5em`
1440
+ // becomes `150%` and inheritance resolves it natively. `rem` is absolute
1441
+ // against the root font size.
1442
+ const t = value.trim().toLowerCase();
1443
+ const n = finite(parseFloat(t) || 0);
1444
+ this.prepareMut();
1445
+ let resolved = n;
1446
+ let isPercent = false;
1447
+ if (t.endsWith('%')) {
1448
+ isPercent = true;
1449
+ }
1450
+ else if (t.endsWith('rem')) {
1451
+ resolved = n * cssUnits.rootFontSize;
1452
+ }
1453
+ else if (t.endsWith('em')) {
1454
+ resolved = n * 100;
1455
+ isPercent = true;
1456
+ }
1457
+ else if (t.endsWith('pt')) {
1458
+ resolved = n * PX_PER_PT;
1459
+ }
1460
+ else if (isDevicePixelToken(t)) {
1461
+ resolved = layout.toDeviceIndependentPixels(n);
1462
+ }
1463
+ setInt32(this.style_view, StyleKeys.FONT_SIZE, resolved);
1464
+ setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
1465
+ setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, isPercent ? 1 : 0);
1466
+ this.commitState(StateKeys.FONT_SIZE);
1467
+ break;
1468
+ }
1294
1469
  case 'number':
1295
1470
  this.prepareMut();
1296
1471
  setInt32(this.style_view, StyleKeys.FONT_SIZE, value);
@@ -1302,14 +1477,14 @@ export class Style {
1302
1477
  switch (value.unit) {
1303
1478
  case 'dip':
1304
1479
  this.prepareMut();
1305
- setInt32(this.style_view, StyleKeys.FONT_SIZE, layout.toDeviceIndependentPixels(value.value));
1480
+ setInt32(this.style_view, StyleKeys.FONT_SIZE, finite(value.value));
1306
1481
  setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
1307
1482
  setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, 0);
1308
1483
  this.commitState(StateKeys.FONT_SIZE);
1309
1484
  break;
1310
1485
  case 'px':
1311
1486
  this.prepareMut();
1312
- setInt32(this.style_view, StyleKeys.FONT_SIZE, value.value);
1487
+ setInt32(this.style_view, StyleKeys.FONT_SIZE, finite(value.value));
1313
1488
  setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
1314
1489
  setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, 0);
1315
1490
  this.commitState(StateKeys.FONT_SIZE);
@@ -1688,7 +1863,7 @@ export class Style {
1688
1863
  switch (typeof value) {
1689
1864
  case 'string': {
1690
1865
  this.prepareMut();
1691
- const dim = lengthPercentageAutoFromString(value);
1866
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
1692
1867
  setInt8(this.style_view, StyleKeys.MIN_WIDTH_TYPE, dim.type);
1693
1868
  setFloat32(this.style_view, StyleKeys.MIN_WIDTH_VALUE, dim.value);
1694
1869
  break;
@@ -1708,7 +1883,7 @@ export class Style {
1708
1883
  case 'px':
1709
1884
  this.prepareMut();
1710
1885
  setInt8(this.style_view, StyleKeys.MIN_WIDTH_TYPE, 1);
1711
- setFloat32(this.style_view, StyleKeys.MIN_WIDTH_VALUE, value.value);
1886
+ setFloat32(this.style_view, StyleKeys.MIN_WIDTH_VALUE, layout.toDevicePixels(value.value));
1712
1887
  break;
1713
1888
  case '%':
1714
1889
  this.prepareMut();
@@ -1729,7 +1904,7 @@ export class Style {
1729
1904
  switch (typeof value) {
1730
1905
  case 'string': {
1731
1906
  this.prepareMut();
1732
- const dim = lengthPercentageAutoFromString(value);
1907
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
1733
1908
  setInt8(this.style_view, StyleKeys.MIN_HEIGHT_TYPE, dim.type);
1734
1909
  setFloat32(this.style_view, StyleKeys.MIN_HEIGHT_VALUE, dim.value);
1735
1910
  break;
@@ -1749,7 +1924,7 @@ export class Style {
1749
1924
  case 'px':
1750
1925
  this.prepareMut();
1751
1926
  setInt8(this.style_view, StyleKeys.MIN_HEIGHT_TYPE, 1);
1752
- setFloat32(this.style_view, StyleKeys.MIN_HEIGHT_VALUE, value.value);
1927
+ setFloat32(this.style_view, StyleKeys.MIN_HEIGHT_VALUE, layout.toDevicePixels(value.value));
1753
1928
  break;
1754
1929
  case '%':
1755
1930
  this.prepareMut();
@@ -1770,7 +1945,7 @@ export class Style {
1770
1945
  switch (typeof value) {
1771
1946
  case 'string': {
1772
1947
  this.prepareMut();
1773
- const dim = dimensionFromString(value);
1948
+ const dim = dimensionFromString(value, this.emBasis());
1774
1949
  setInt8(this.style_view, StyleKeys.WIDTH_TYPE, dim.type);
1775
1950
  setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, dim.value);
1776
1951
  break;
@@ -1790,7 +1965,7 @@ export class Style {
1790
1965
  case 'px':
1791
1966
  this.prepareMut();
1792
1967
  setInt8(this.style_view, StyleKeys.WIDTH_TYPE, 1);
1793
- setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, value.value);
1968
+ setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, layout.toDevicePixels(value.value));
1794
1969
  break;
1795
1970
  case '%':
1796
1971
  this.prepareMut();
@@ -1811,7 +1986,7 @@ export class Style {
1811
1986
  switch (typeof value) {
1812
1987
  case 'string': {
1813
1988
  this.prepareMut();
1814
- const dim = dimensionFromString(value);
1989
+ const dim = dimensionFromString(value, this.emBasis());
1815
1990
  setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, dim.type);
1816
1991
  setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, dim.value);
1817
1992
  break;
@@ -1831,7 +2006,7 @@ export class Style {
1831
2006
  case 'px':
1832
2007
  this.prepareMut();
1833
2008
  setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, 1);
1834
- setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, value.value);
2009
+ setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, layout.toDevicePixels(value.value));
1835
2010
  break;
1836
2011
  case '%':
1837
2012
  this.prepareMut();
@@ -1852,7 +2027,7 @@ export class Style {
1852
2027
  switch (typeof value) {
1853
2028
  case 'string': {
1854
2029
  this.prepareMut();
1855
- const dim = lengthPercentageAutoFromString(value);
2030
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
1856
2031
  setInt8(this.style_view, StyleKeys.MAX_WIDTH_TYPE, dim.type);
1857
2032
  setFloat32(this.style_view, StyleKeys.MAX_WIDTH_VALUE, dim.value);
1858
2033
  break;
@@ -1872,7 +2047,7 @@ export class Style {
1872
2047
  case 'px':
1873
2048
  this.prepareMut();
1874
2049
  setInt8(this.style_view, StyleKeys.MAX_WIDTH_TYPE, 1);
1875
- setFloat32(this.style_view, StyleKeys.MAX_WIDTH_VALUE, value.value);
2050
+ setFloat32(this.style_view, StyleKeys.MAX_WIDTH_VALUE, layout.toDevicePixels(value.value));
1876
2051
  break;
1877
2052
  case '%':
1878
2053
  this.prepareMut();
@@ -1893,7 +2068,7 @@ export class Style {
1893
2068
  switch (typeof value) {
1894
2069
  case 'string': {
1895
2070
  this.prepareMut();
1896
- const dim = lengthPercentageAutoFromString(value);
2071
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
1897
2072
  setInt8(this.style_view, StyleKeys.MAX_HEIGHT_TYPE, dim.type);
1898
2073
  setFloat32(this.style_view, StyleKeys.MAX_HEIGHT_VALUE, dim.value);
1899
2074
  break;
@@ -1913,7 +2088,7 @@ export class Style {
1913
2088
  case 'px':
1914
2089
  this.prepareMut();
1915
2090
  setInt8(this.style_view, StyleKeys.MAX_HEIGHT_TYPE, 1);
1916
- setFloat32(this.style_view, StyleKeys.MAX_HEIGHT_VALUE, value.value);
2091
+ setFloat32(this.style_view, StyleKeys.MAX_HEIGHT_VALUE, layout.toDevicePixels(value.value));
1917
2092
  break;
1918
2093
  case '%':
1919
2094
  this.prepareMut();
@@ -1932,6 +2107,13 @@ export class Style {
1932
2107
  }
1933
2108
  set borderLeftWidth(value) {
1934
2109
  switch (typeof value) {
2110
+ case 'string': {
2111
+ this.prepareMut();
2112
+ const dim = lengthPercentageFromString(value, this.emBasis());
2113
+ setInt8(this.style_view, StyleKeys.BORDER_LEFT_TYPE, dim.type);
2114
+ setFloat32(this.style_view, StyleKeys.BORDER_LEFT_VALUE, dim.value);
2115
+ break;
2116
+ }
1935
2117
  case 'number':
1936
2118
  this.prepareMut();
1937
2119
  setInt8(this.style_view, StyleKeys.BORDER_LEFT_TYPE, 0);
@@ -1947,7 +2129,7 @@ export class Style {
1947
2129
  case 'px':
1948
2130
  this.prepareMut();
1949
2131
  setInt8(this.style_view, StyleKeys.BORDER_LEFT_TYPE, 0);
1950
- setFloat32(this.style_view, StyleKeys.BORDER_LEFT_VALUE, value.value);
2132
+ setFloat32(this.style_view, StyleKeys.BORDER_LEFT_VALUE, layout.toDevicePixels(value.value));
1951
2133
  break;
1952
2134
  case '%':
1953
2135
  this.prepareMut();
@@ -1966,6 +2148,13 @@ export class Style {
1966
2148
  }
1967
2149
  set borderRightWidth(value) {
1968
2150
  switch (typeof value) {
2151
+ case 'string': {
2152
+ this.prepareMut();
2153
+ const dim = lengthPercentageFromString(value, this.emBasis());
2154
+ setInt8(this.style_view, StyleKeys.BORDER_RIGHT_TYPE, dim.type);
2155
+ setFloat32(this.style_view, StyleKeys.BORDER_RIGHT_VALUE, dim.value);
2156
+ break;
2157
+ }
1969
2158
  case 'number':
1970
2159
  this.prepareMut();
1971
2160
  setInt8(this.style_view, StyleKeys.BORDER_RIGHT_TYPE, 0);
@@ -1981,7 +2170,7 @@ export class Style {
1981
2170
  case 'px':
1982
2171
  this.prepareMut();
1983
2172
  setInt8(this.style_view, StyleKeys.BORDER_RIGHT_TYPE, 0);
1984
- setFloat32(this.style_view, StyleKeys.BORDER_RIGHT_VALUE, value.value);
2173
+ setFloat32(this.style_view, StyleKeys.BORDER_RIGHT_VALUE, layout.toDevicePixels(value.value));
1985
2174
  break;
1986
2175
  case '%':
1987
2176
  this.prepareMut();
@@ -2000,6 +2189,13 @@ export class Style {
2000
2189
  }
2001
2190
  set borderTopWidth(value) {
2002
2191
  switch (typeof value) {
2192
+ case 'string': {
2193
+ this.prepareMut();
2194
+ const dim = lengthPercentageFromString(value, this.emBasis());
2195
+ setInt8(this.style_view, StyleKeys.BORDER_TOP_TYPE, dim.type);
2196
+ setFloat32(this.style_view, StyleKeys.BORDER_TOP_VALUE, dim.value);
2197
+ break;
2198
+ }
2003
2199
  case 'number':
2004
2200
  this.prepareMut();
2005
2201
  setInt8(this.style_view, StyleKeys.BORDER_TOP_TYPE, 0);
@@ -2015,7 +2211,7 @@ export class Style {
2015
2211
  case 'px':
2016
2212
  this.prepareMut();
2017
2213
  setInt8(this.style_view, StyleKeys.BORDER_TOP_TYPE, 0);
2018
- setFloat32(this.style_view, StyleKeys.BORDER_TOP_VALUE, value.value);
2214
+ setFloat32(this.style_view, StyleKeys.BORDER_TOP_VALUE, layout.toDevicePixels(value.value));
2019
2215
  break;
2020
2216
  case '%':
2021
2217
  this.prepareMut();
@@ -2034,6 +2230,13 @@ export class Style {
2034
2230
  }
2035
2231
  set borderBottomWidth(value) {
2036
2232
  switch (typeof value) {
2233
+ case 'string': {
2234
+ this.prepareMut();
2235
+ const dim = lengthPercentageFromString(value, this.emBasis());
2236
+ setInt8(this.style_view, StyleKeys.BORDER_BOTTOM_TYPE, dim.type);
2237
+ setFloat32(this.style_view, StyleKeys.BORDER_BOTTOM_VALUE, dim.value);
2238
+ break;
2239
+ }
2037
2240
  case 'number':
2038
2241
  this.prepareMut();
2039
2242
  setInt8(this.style_view, StyleKeys.BORDER_BOTTOM_TYPE, 0);
@@ -2049,7 +2252,7 @@ export class Style {
2049
2252
  case 'px':
2050
2253
  this.prepareMut();
2051
2254
  setInt8(this.style_view, StyleKeys.BORDER_BOTTOM_TYPE, 0);
2052
- setFloat32(this.style_view, StyleKeys.BORDER_BOTTOM_VALUE, value.value);
2255
+ setFloat32(this.style_view, StyleKeys.BORDER_BOTTOM_VALUE, layout.toDevicePixels(value.value));
2053
2256
  break;
2054
2257
  case '%':
2055
2258
  this.prepareMut();
@@ -2062,11 +2265,25 @@ export class Style {
2062
2265
  this.commitState(StateKeys.BORDER);
2063
2266
  }
2064
2267
  set inset(value) {
2268
+ if (typeof value === 'string') {
2269
+ const sides = expandSidesShorthand(value);
2270
+ if (sides) {
2271
+ const wasInBatch = this.inBatch;
2272
+ this.inBatch = true;
2273
+ this.top = sides[0];
2274
+ this.right = sides[1];
2275
+ this.bottom = sides[2];
2276
+ this.left = sides[3];
2277
+ this.inBatch = wasInBatch;
2278
+ this.commitState(StateKeys.INSET);
2279
+ return;
2280
+ }
2281
+ }
2065
2282
  var type;
2066
2283
  var insetValue;
2067
2284
  switch (typeof value) {
2068
2285
  case 'string': {
2069
- const dim = lengthPercentageAutoFromString(value);
2286
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2070
2287
  type = dim.type;
2071
2288
  insetValue = dim.value;
2072
2289
  break;
@@ -2083,7 +2300,7 @@ export class Style {
2083
2300
  break;
2084
2301
  case 'px':
2085
2302
  type = 1;
2086
- insetValue = value.value;
2303
+ insetValue = layout.toDevicePixels(value.value);
2087
2304
  break;
2088
2305
  case '%':
2089
2306
  type = 2;
@@ -2110,7 +2327,7 @@ export class Style {
2110
2327
  switch (typeof value) {
2111
2328
  case 'string': {
2112
2329
  this.prepareMut();
2113
- const dim = lengthPercentageAutoFromString(value);
2330
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2114
2331
  setInt8(this.style_view, StyleKeys.INSET_LEFT_TYPE, dim.type);
2115
2332
  setFloat32(this.style_view, StyleKeys.INSET_LEFT_VALUE, dim.value);
2116
2333
  break;
@@ -2130,7 +2347,7 @@ export class Style {
2130
2347
  case 'px':
2131
2348
  this.prepareMut();
2132
2349
  setInt8(this.style_view, StyleKeys.INSET_LEFT_TYPE, 1);
2133
- setFloat32(this.style_view, StyleKeys.INSET_LEFT_VALUE, value.value);
2350
+ setFloat32(this.style_view, StyleKeys.INSET_LEFT_VALUE, layout.toDevicePixels(value.value));
2134
2351
  break;
2135
2352
  case '%':
2136
2353
  this.prepareMut();
@@ -2151,7 +2368,7 @@ export class Style {
2151
2368
  switch (typeof value) {
2152
2369
  case 'string': {
2153
2370
  this.prepareMut();
2154
- const dim = lengthPercentageAutoFromString(value);
2371
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2155
2372
  setInt8(this.style_view, StyleKeys.INSET_RIGHT_TYPE, dim.type);
2156
2373
  setFloat32(this.style_view, StyleKeys.INSET_RIGHT_VALUE, dim.value);
2157
2374
  break;
@@ -2171,7 +2388,7 @@ export class Style {
2171
2388
  case 'px':
2172
2389
  this.prepareMut();
2173
2390
  setInt8(this.style_view, StyleKeys.INSET_RIGHT_TYPE, 1);
2174
- setFloat32(this.style_view, StyleKeys.INSET_RIGHT_VALUE, value.value);
2391
+ setFloat32(this.style_view, StyleKeys.INSET_RIGHT_VALUE, layout.toDevicePixels(value.value));
2175
2392
  break;
2176
2393
  case '%':
2177
2394
  this.prepareMut();
@@ -2192,7 +2409,7 @@ export class Style {
2192
2409
  switch (typeof value) {
2193
2410
  case 'string': {
2194
2411
  this.prepareMut();
2195
- const dim = lengthPercentageAutoFromString(value);
2412
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2196
2413
  setInt8(this.style_view, StyleKeys.INSET_TOP_TYPE, dim.type);
2197
2414
  setFloat32(this.style_view, StyleKeys.INSET_TOP_VALUE, dim.value);
2198
2415
  break;
@@ -2212,7 +2429,7 @@ export class Style {
2212
2429
  case 'px':
2213
2430
  this.prepareMut();
2214
2431
  setInt8(this.style_view, StyleKeys.INSET_TOP_TYPE, 1);
2215
- setFloat32(this.style_view, StyleKeys.INSET_TOP_VALUE, value.value);
2432
+ setFloat32(this.style_view, StyleKeys.INSET_TOP_VALUE, layout.toDevicePixels(value.value));
2216
2433
  break;
2217
2434
  case '%':
2218
2435
  this.prepareMut();
@@ -2233,7 +2450,7 @@ export class Style {
2233
2450
  switch (typeof value) {
2234
2451
  case 'string': {
2235
2452
  this.prepareMut();
2236
- const dim = lengthPercentageAutoFromString(value);
2453
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2237
2454
  setInt8(this.style_view, StyleKeys.INSET_BOTTOM_TYPE, dim.type);
2238
2455
  setFloat32(this.style_view, StyleKeys.INSET_BOTTOM_VALUE, dim.value);
2239
2456
  break;
@@ -2253,7 +2470,7 @@ export class Style {
2253
2470
  case 'px':
2254
2471
  this.prepareMut();
2255
2472
  setInt8(this.style_view, StyleKeys.INSET_BOTTOM_TYPE, 1);
2256
- setFloat32(this.style_view, StyleKeys.INSET_BOTTOM_VALUE, value.value);
2473
+ setFloat32(this.style_view, StyleKeys.INSET_BOTTOM_VALUE, layout.toDevicePixels(value.value));
2257
2474
  break;
2258
2475
  case '%':
2259
2476
  this.prepareMut();
@@ -2266,11 +2483,25 @@ export class Style {
2266
2483
  this.commitState(StateKeys.INSET);
2267
2484
  }
2268
2485
  set margin(value) {
2486
+ if (typeof value === 'string') {
2487
+ const sides = expandSidesShorthand(value);
2488
+ if (sides) {
2489
+ const wasInBatch = this.inBatch;
2490
+ this.inBatch = true;
2491
+ this.marginTop = sides[0];
2492
+ this.marginRight = sides[1];
2493
+ this.marginBottom = sides[2];
2494
+ this.marginLeft = sides[3];
2495
+ this.inBatch = wasInBatch;
2496
+ this.commitState(StateKeys.MARGIN);
2497
+ return;
2498
+ }
2499
+ }
2269
2500
  var type;
2270
2501
  var marginValue;
2271
2502
  switch (typeof value) {
2272
2503
  case 'string': {
2273
- const dim = lengthPercentageAutoFromString(value);
2504
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2274
2505
  type = dim.type;
2275
2506
  marginValue = dim.value;
2276
2507
  break;
@@ -2287,7 +2518,7 @@ export class Style {
2287
2518
  break;
2288
2519
  case 'px':
2289
2520
  type = 1;
2290
- marginValue = value.value;
2521
+ marginValue = layout.toDevicePixels(value.value);
2291
2522
  break;
2292
2523
  case '%':
2293
2524
  type = 2;
@@ -2314,7 +2545,7 @@ export class Style {
2314
2545
  switch (typeof value) {
2315
2546
  case 'string': {
2316
2547
  this.prepareMut();
2317
- const dim = lengthPercentageAutoFromString(value);
2548
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2318
2549
  setInt8(this.style_view, StyleKeys.MARGIN_LEFT_TYPE, dim.type);
2319
2550
  setFloat32(this.style_view, StyleKeys.MARGIN_LEFT_VALUE, dim.value);
2320
2551
  break;
@@ -2334,7 +2565,7 @@ export class Style {
2334
2565
  case 'px':
2335
2566
  this.prepareMut();
2336
2567
  setInt8(this.style_view, StyleKeys.MARGIN_LEFT_TYPE, 1);
2337
- setFloat32(this.style_view, StyleKeys.MARGIN_LEFT_VALUE, value.value);
2568
+ setFloat32(this.style_view, StyleKeys.MARGIN_LEFT_VALUE, layout.toDevicePixels(value.value));
2338
2569
  break;
2339
2570
  case '%':
2340
2571
  this.prepareMut();
@@ -2355,7 +2586,7 @@ export class Style {
2355
2586
  switch (typeof value) {
2356
2587
  case 'string': {
2357
2588
  this.prepareMut();
2358
- const dim = lengthPercentageAutoFromString(value);
2589
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2359
2590
  setInt8(this.style_view, StyleKeys.MARGIN_RIGHT_TYPE, dim.type);
2360
2591
  setFloat32(this.style_view, StyleKeys.MARGIN_RIGHT_VALUE, dim.value);
2361
2592
  break;
@@ -2375,7 +2606,7 @@ export class Style {
2375
2606
  case 'px':
2376
2607
  this.prepareMut();
2377
2608
  setInt8(this.style_view, StyleKeys.MARGIN_RIGHT_TYPE, 1);
2378
- setFloat32(this.style_view, StyleKeys.MARGIN_RIGHT_VALUE, value.value);
2609
+ setFloat32(this.style_view, StyleKeys.MARGIN_RIGHT_VALUE, layout.toDevicePixels(value.value));
2379
2610
  break;
2380
2611
  case '%':
2381
2612
  this.prepareMut();
@@ -2396,7 +2627,7 @@ export class Style {
2396
2627
  switch (typeof value) {
2397
2628
  case 'string': {
2398
2629
  this.prepareMut();
2399
- const dim = lengthPercentageAutoFromString(value);
2630
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2400
2631
  setInt8(this.style_view, StyleKeys.MARGIN_TOP_TYPE, dim.type);
2401
2632
  setFloat32(this.style_view, StyleKeys.MARGIN_TOP_VALUE, dim.value);
2402
2633
  break;
@@ -2416,7 +2647,7 @@ export class Style {
2416
2647
  case 'px':
2417
2648
  this.prepareMut();
2418
2649
  setInt8(this.style_view, StyleKeys.MARGIN_TOP_TYPE, 1);
2419
- setFloat32(this.style_view, StyleKeys.MARGIN_TOP_VALUE, value.value);
2650
+ setFloat32(this.style_view, StyleKeys.MARGIN_TOP_VALUE, layout.toDevicePixels(value.value));
2420
2651
  break;
2421
2652
  case '%':
2422
2653
  this.prepareMut();
@@ -2437,7 +2668,7 @@ export class Style {
2437
2668
  switch (typeof value) {
2438
2669
  case 'string': {
2439
2670
  this.prepareMut();
2440
- const dim = lengthPercentageAutoFromString(value);
2671
+ const dim = lengthPercentageAutoFromString(value, this.emBasis());
2441
2672
  setInt8(this.style_view, StyleKeys.MARGIN_BOTTOM_TYPE, dim.type);
2442
2673
  setFloat32(this.style_view, StyleKeys.MARGIN_BOTTOM_VALUE, dim.value);
2443
2674
  break;
@@ -2457,7 +2688,7 @@ export class Style {
2457
2688
  case 'px':
2458
2689
  this.prepareMut();
2459
2690
  setInt8(this.style_view, StyleKeys.MARGIN_BOTTOM_TYPE, 1);
2460
- setFloat32(this.style_view, StyleKeys.MARGIN_BOTTOM_VALUE, value.value);
2691
+ setFloat32(this.style_view, StyleKeys.MARGIN_BOTTOM_VALUE, layout.toDevicePixels(value.value));
2461
2692
  break;
2462
2693
  case '%':
2463
2694
  this.prepareMut();
@@ -2470,9 +2701,24 @@ export class Style {
2470
2701
  this.commitState(StateKeys.MARGIN);
2471
2702
  }
2472
2703
  set padding(value) {
2704
+ if (typeof value === 'string') {
2705
+ const sides = expandSidesShorthand(value);
2706
+ if (sides) {
2707
+ const wasInBatch = this.inBatch;
2708
+ this.inBatch = true;
2709
+ this.paddingTop = sides[0];
2710
+ this.paddingRight = sides[1];
2711
+ this.paddingBottom = sides[2];
2712
+ this.paddingLeft = sides[3];
2713
+ this.inBatch = wasInBatch;
2714
+ this.commitState(StateKeys.PADDING);
2715
+ return;
2716
+ }
2717
+ }
2718
+ const wasInBatch = this.inBatch;
2473
2719
  this.inBatch = true;
2474
2720
  this.paddingBottom = this.paddingLeft = this.paddingRight = this.paddingTop = value;
2475
- this.inBatch = false;
2721
+ this.inBatch = wasInBatch;
2476
2722
  this.commitState(StateKeys.PADDING);
2477
2723
  }
2478
2724
  get paddingLeft() {
@@ -2484,7 +2730,7 @@ export class Style {
2484
2730
  switch (typeof value) {
2485
2731
  case 'string': {
2486
2732
  this.prepareMut();
2487
- const dim = lengthPercentageFromString(value);
2733
+ const dim = lengthPercentageFromString(value, this.emBasis());
2488
2734
  setInt8(this.style_view, StyleKeys.PADDING_LEFT_TYPE, dim.type);
2489
2735
  setFloat32(this.style_view, StyleKeys.PADDING_LEFT_VALUE, dim.value);
2490
2736
  break;
@@ -2504,7 +2750,7 @@ export class Style {
2504
2750
  case 'px':
2505
2751
  this.prepareMut();
2506
2752
  setInt8(this.style_view, StyleKeys.PADDING_LEFT_TYPE, 0);
2507
- setFloat32(this.style_view, StyleKeys.PADDING_LEFT_VALUE, value.value);
2753
+ setFloat32(this.style_view, StyleKeys.PADDING_LEFT_VALUE, layout.toDevicePixels(value.value));
2508
2754
  break;
2509
2755
  case '%':
2510
2756
  this.prepareMut();
@@ -2525,7 +2771,7 @@ export class Style {
2525
2771
  switch (typeof value) {
2526
2772
  case 'string': {
2527
2773
  this.prepareMut();
2528
- const dim = lengthPercentageFromString(value);
2774
+ const dim = lengthPercentageFromString(value, this.emBasis());
2529
2775
  setInt8(this.style_view, StyleKeys.PADDING_RIGHT_TYPE, dim.type);
2530
2776
  setFloat32(this.style_view, StyleKeys.PADDING_RIGHT_VALUE, dim.value);
2531
2777
  break;
@@ -2545,7 +2791,7 @@ export class Style {
2545
2791
  case 'px':
2546
2792
  this.prepareMut();
2547
2793
  setInt8(this.style_view, StyleKeys.PADDING_RIGHT_TYPE, 0);
2548
- setFloat32(this.style_view, StyleKeys.PADDING_RIGHT_VALUE, value.value);
2794
+ setFloat32(this.style_view, StyleKeys.PADDING_RIGHT_VALUE, layout.toDevicePixels(value.value));
2549
2795
  break;
2550
2796
  case '%':
2551
2797
  this.prepareMut();
@@ -2566,7 +2812,7 @@ export class Style {
2566
2812
  switch (typeof value) {
2567
2813
  case 'string': {
2568
2814
  this.prepareMut();
2569
- const dim = lengthPercentageFromString(value);
2815
+ const dim = lengthPercentageFromString(value, this.emBasis());
2570
2816
  setInt8(this.style_view, StyleKeys.PADDING_TOP_TYPE, dim.type);
2571
2817
  setFloat32(this.style_view, StyleKeys.PADDING_TOP_VALUE, dim.value);
2572
2818
  break;
@@ -2586,7 +2832,7 @@ export class Style {
2586
2832
  case 'px':
2587
2833
  this.prepareMut();
2588
2834
  setInt8(this.style_view, StyleKeys.PADDING_TOP_TYPE, 0);
2589
- setFloat32(this.style_view, StyleKeys.PADDING_TOP_VALUE, value.value);
2835
+ setFloat32(this.style_view, StyleKeys.PADDING_TOP_VALUE, layout.toDevicePixels(value.value));
2590
2836
  break;
2591
2837
  case '%':
2592
2838
  this.prepareMut();
@@ -2607,7 +2853,7 @@ export class Style {
2607
2853
  switch (typeof value) {
2608
2854
  case 'string': {
2609
2855
  this.prepareMut();
2610
- const dim = lengthPercentageFromString(value);
2856
+ const dim = lengthPercentageFromString(value, this.emBasis());
2611
2857
  setInt8(this.style_view, StyleKeys.PADDING_BOTTOM_TYPE, dim.type);
2612
2858
  setFloat32(this.style_view, StyleKeys.PADDING_BOTTOM_VALUE, dim.value);
2613
2859
  break;
@@ -2627,7 +2873,7 @@ export class Style {
2627
2873
  case 'px':
2628
2874
  this.prepareMut();
2629
2875
  setInt8(this.style_view, StyleKeys.PADDING_BOTTOM_TYPE, 0);
2630
- setFloat32(this.style_view, StyleKeys.PADDING_BOTTOM_VALUE, value.value);
2876
+ setFloat32(this.style_view, StyleKeys.PADDING_BOTTOM_VALUE, layout.toDevicePixels(value.value));
2631
2877
  break;
2632
2878
  case '%':
2633
2879
  this.prepareMut();
@@ -2678,6 +2924,13 @@ export class Style {
2678
2924
  }
2679
2925
  set rowGap(value) {
2680
2926
  switch (typeof value) {
2927
+ case 'string': {
2928
+ this.prepareMut();
2929
+ const dim = lengthPercentageFromString(value, this.emBasis());
2930
+ setInt8(this.style_view, StyleKeys.GAP_ROW_TYPE, dim.type);
2931
+ setFloat32(this.style_view, StyleKeys.GAP_ROW_VALUE, dim.value);
2932
+ break;
2933
+ }
2681
2934
  case 'number':
2682
2935
  this.prepareMut();
2683
2936
  setInt8(this.style_view, StyleKeys.GAP_ROW_TYPE, 0);
@@ -2693,7 +2946,7 @@ export class Style {
2693
2946
  case 'px':
2694
2947
  this.prepareMut();
2695
2948
  setInt8(this.style_view, StyleKeys.GAP_ROW_TYPE, 0);
2696
- setFloat32(this.style_view, StyleKeys.GAP_ROW_VALUE, value.value);
2949
+ setFloat32(this.style_view, StyleKeys.GAP_ROW_VALUE, layout.toDevicePixels(value.value));
2697
2950
  break;
2698
2951
  case '%':
2699
2952
  this.prepareMut();
@@ -2712,6 +2965,13 @@ export class Style {
2712
2965
  }
2713
2966
  set columnGap(value) {
2714
2967
  switch (typeof value) {
2968
+ case 'string': {
2969
+ this.prepareMut();
2970
+ const dim = lengthPercentageFromString(value, this.emBasis());
2971
+ setInt8(this.style_view, StyleKeys.GAP_COLUMN_TYPE, dim.type);
2972
+ setFloat32(this.style_view, StyleKeys.GAP_COLUMN_VALUE, dim.value);
2973
+ break;
2974
+ }
2715
2975
  case 'number':
2716
2976
  this.prepareMut();
2717
2977
  setInt8(this.style_view, StyleKeys.GAP_COLUMN_TYPE, 0);
@@ -2727,7 +2987,7 @@ export class Style {
2727
2987
  case 'px':
2728
2988
  this.prepareMut();
2729
2989
  setInt8(this.style_view, StyleKeys.GAP_COLUMN_TYPE, 0);
2730
- setFloat32(this.style_view, StyleKeys.GAP_COLUMN_VALUE, value.value);
2990
+ setFloat32(this.style_view, StyleKeys.GAP_COLUMN_VALUE, layout.toDevicePixels(value.value));
2731
2991
  break;
2732
2992
  case '%':
2733
2993
  this.prepareMut();
@@ -2758,7 +3018,7 @@ export class Style {
2758
3018
  switch (typeof value) {
2759
3019
  case 'string': {
2760
3020
  this.prepareMut();
2761
- const dim = dimensionFromString(value);
3021
+ const dim = dimensionFromString(value, this.emBasis());
2762
3022
  setInt8(this.style_view, StyleKeys.FLEX_BASIS_TYPE, dim.type);
2763
3023
  setFloat32(this.style_view, StyleKeys.FLEX_BASIS_VALUE, dim.value);
2764
3024
  break;
@@ -2778,7 +3038,7 @@ export class Style {
2778
3038
  case 'px':
2779
3039
  this.prepareMut();
2780
3040
  setInt8(this.style_view, StyleKeys.FLEX_BASIS_TYPE, 1);
2781
- setFloat32(this.style_view, StyleKeys.FLEX_BASIS_VALUE, value.value);
3041
+ setFloat32(this.style_view, StyleKeys.FLEX_BASIS_VALUE, layout.toDevicePixels(value.value));
2782
3042
  break;
2783
3043
  case '%':
2784
3044
  this.prepareMut();
@@ -3617,7 +3877,7 @@ export class Style {
3617
3877
  break;
3618
3878
  case 'px':
3619
3879
  this.prepareMut();
3620
- setFloat32(this.style_view, StyleKeys.SCROLLBAR_WIDTH, value.value);
3880
+ setFloat32(this.style_view, StyleKeys.SCROLLBAR_WIDTH, layout.toDevicePixels(value.value));
3621
3881
  this.commitState(StateKeys.SCROLLBAR_WIDTH);
3622
3882
  break;
3623
3883
  }
@@ -3627,7 +3887,13 @@ export class Style {
3627
3887
  return getFloat32(this.style_view, StyleKeys.LETTER_SPACING);
3628
3888
  }
3629
3889
  set letterSpacing(value) {
3630
- if (typeof value === 'number') {
3890
+ if (typeof value === 'string') {
3891
+ this.prepareMut();
3892
+ setFloat32(this.style_view, StyleKeys.LETTER_SPACING, tokenToDevicePx(value, parseFloat(value) || 0));
3893
+ setUint8(this.style_view, StyleKeys.LETTER_SPACING_STATE, 1);
3894
+ this.commitState(StateKeys.LETTER_SPACING);
3895
+ }
3896
+ else if (typeof value === 'number') {
3631
3897
  this.prepareMut();
3632
3898
  setFloat32(this.style_view, StyleKeys.LETTER_SPACING, value);
3633
3899
  setUint8(this.style_view, StyleKeys.LETTER_SPACING_STATE, 1);
@@ -3643,7 +3909,7 @@ export class Style {
3643
3909
  break;
3644
3910
  case 'px':
3645
3911
  this.prepareMut();
3646
- setFloat32(this.style_view, StyleKeys.LETTER_SPACING, value.value);
3912
+ setFloat32(this.style_view, StyleKeys.LETTER_SPACING, layout.toDevicePixels(value.value));
3647
3913
  setUint8(this.style_view, StyleKeys.LETTER_SPACING_STATE, 1);
3648
3914
  this.commitState(StateKeys.LETTER_SPACING);
3649
3915
  break;
@@ -3654,7 +3920,18 @@ export class Style {
3654
3920
  return getFloat32(this.style_view, StyleKeys.LINE_HEIGHT);
3655
3921
  }
3656
3922
  set lineHeight(value) {
3657
- if (typeof value === 'number') {
3923
+ if (typeof value === 'string') {
3924
+ const t = value.trim();
3925
+ // A unitless line-height is a multiplier (`line-height: 1.5`), not a
3926
+ // length — TYPE 0 means "multiply by the resolved font size".
3927
+ const unitless = /^-?[\d.]+$/.test(t);
3928
+ this.prepareMut();
3929
+ setFloat32(this.style_view, StyleKeys.LINE_HEIGHT, unitless ? finite(parseFloat(t) || 0) : tokenToDevicePx(t, parseFloat(t) || 0));
3930
+ setUint8(this.style_view, StyleKeys.LINE_HEIGHT_STATE, 1);
3931
+ setUint8(this.style_view, StyleKeys.LINE_HEIGHT_TYPE, unitless ? 0 : 1);
3932
+ this.commitState(StateKeys.LINE_HEIGHT);
3933
+ }
3934
+ else if (typeof value === 'number') {
3658
3935
  this.prepareMut();
3659
3936
  setFloat32(this.style_view, StyleKeys.LINE_HEIGHT, value);
3660
3937
  setUint8(this.style_view, StyleKeys.LINE_HEIGHT_STATE, 1);
@@ -3674,7 +3951,7 @@ export class Style {
3674
3951
  break;
3675
3952
  case 'px':
3676
3953
  this.prepareMut();
3677
- setFloat32(this.style_view, StyleKeys.LINE_HEIGHT, value.value);
3954
+ setFloat32(this.style_view, StyleKeys.LINE_HEIGHT, layout.toDevicePixels(value.value));
3678
3955
  setUint8(this.style_view, StyleKeys.LINE_HEIGHT_STATE, 1);
3679
3956
  setUint8(this.style_view, StyleKeys.LINE_HEIGHT_TYPE, 1);
3680
3957
  this.commitState(StateKeys.LINE_HEIGHT);
@@ -3936,6 +4213,91 @@ export class Style {
3936
4213
  value = this.coerceCssStringValue(value);
3937
4214
  this.setPseudoCssStringValue('border-radius', value, () => org.nativescript.mason.masonkit.NodeHelper.getShared().setBorderRadius(this.nativeView, value), () => (this.nativeView.style.borderRadius = value));
3938
4215
  }
4216
+ get whiteSpace() {
4217
+ const map = ['normal', 'pre', 'pre-wrap', 'pre-line', 'nowrap', 'break-spaces'];
4218
+ return map[getUint8(this.style_view, StyleKeys.WHITE_SPACE)] ?? 'normal';
4219
+ }
4220
+ /**
4221
+ * The native text engine has always honoured `white-space` (TextEngine,
4222
+ * TextView and TextNode all read it, and `<pre>` relies on it), but the byte
4223
+ * was only ever written by the native inline-style parser — there was no JS or
4224
+ * CSS path to it.
4225
+ */
4226
+ set whiteSpace(value) {
4227
+ const map = { normal: 0, pre: 1, 'pre-wrap': 2, 'pre-line': 3, nowrap: 4, 'break-spaces': 5 };
4228
+ const mapped = map[value];
4229
+ if (mapped === undefined) {
4230
+ return;
4231
+ }
4232
+ this.prepareMut();
4233
+ setUint8(this.style_view, StyleKeys.WHITE_SPACE, mapped);
4234
+ setInt8(this.style_view, StyleKeys.WHITE_SPACE_STATE, 1);
4235
+ this.commitState(StateKeys.WHITE_SPACE);
4236
+ }
4237
+ get objectFit() {
4238
+ const map = ['contain', 'cover', 'fill', 'none', 'scale-down'];
4239
+ return map[getUint8(this.style_view, StyleKeys.OBJECT_FIT)] ?? 'contain';
4240
+ }
4241
+ /** Read by `Img`; previously reachable only through the native HTML parser. */
4242
+ set objectFit(value) {
4243
+ const map = { contain: 0, cover: 1, fill: 2, none: 3, 'scale-down': 4 };
4244
+ const mapped = map[value];
4245
+ if (mapped === undefined) {
4246
+ return;
4247
+ }
4248
+ this.prepareMut();
4249
+ setUint8(this.style_view, StyleKeys.OBJECT_FIT, mapped);
4250
+ this.commitState(StateKeys.OBJECT_FIT);
4251
+ }
4252
+ get textJustify() {
4253
+ const value = getInt8(this.style_view, StyleKeys.TEXT_JUSTIFY);
4254
+ const map = { [-1]: 'none', 0: 'auto', 1: 'inter-word', 2: 'inter-character', 3: 'distribute' };
4255
+ return map[value] ?? 'auto';
4256
+ }
4257
+ set textJustify(value) {
4258
+ const map = { none: -1, auto: 0, 'inter-word': 1, 'inter-character': 2, distribute: 3 };
4259
+ const mapped = map[value];
4260
+ if (mapped === undefined) {
4261
+ return;
4262
+ }
4263
+ this.prepareMut();
4264
+ setInt8(this.style_view, StyleKeys.TEXT_JUSTIFY, mapped);
4265
+ setInt8(this.style_view, StyleKeys.TEXT_JUSTIFY_STATE, 1);
4266
+ this.commitState(StateKeys.TEXT_JUSTIFY);
4267
+ }
4268
+ get textDecorationThickness() {
4269
+ return layout.toDeviceIndependentPixels(getFloat32(this.style_view, StyleKeys.DECORATION_THICKNESS));
4270
+ }
4271
+ /** Read by TextNode when stroking the decoration line. */
4272
+ set textDecorationThickness(value) {
4273
+ this.prepareMut();
4274
+ const devicePx = typeof value === 'number' ? layout.toDevicePixels(finite(value)) : tokenToDevicePx(value, parseFloat(value) || 0, this.emBasis());
4275
+ setFloat32(this.style_view, StyleKeys.DECORATION_THICKNESS, devicePx);
4276
+ setInt8(this.style_view, StyleKeys.DECORATION_THICKNESS_STATE, 1);
4277
+ this.commitState(StateKeys.DECORATION_THICKNESS);
4278
+ }
4279
+ get fontFamily() {
4280
+ if (!this.nativeView)
4281
+ return '';
4282
+ if (__ANDROID__) {
4283
+ return org.nativescript.mason.masonkit.NodeHelper.getShared().getFontFamily(this.nativeView);
4284
+ }
4285
+ if (__APPLE__) {
4286
+ return this.nativeView.style.fontFamily;
4287
+ }
4288
+ return '';
4289
+ }
4290
+ /**
4291
+ * `font-family` is a native Style property on both platforms (it builds a
4292
+ * FontFace), not a style-buffer field — so unlike a length it can't be written
4293
+ * through the shared buffer. There was no JS or CSS path to it at all before
4294
+ * this: `FONT_FAMILY_STATE` existed with no value slot, and core's
4295
+ * `fontInternalProperty.setNative` hook is Windows-only.
4296
+ */
4297
+ set fontFamily(value) {
4298
+ value = this.coerceCssStringValue(value);
4299
+ this.setPseudoCssStringValue('font-family', value, () => org.nativescript.mason.masonkit.NodeHelper.getShared().setFontFamily(this.nativeView, value), () => (this.nativeView.style.fontFamily = value));
4300
+ }
3939
4301
  set textDecoration(value) {
3940
4302
  value = this.coerceCssStringValue(value);
3941
4303
  this.setPseudoCssStringValue('text-decoration', value, () => org.nativescript.mason.masonkit.NodeHelper.getShared().setTextDecoration(this.nativeView, value), () => this.nativeView.style.setTextDecoration(value));
@@ -4191,7 +4553,7 @@ export class Style {
4191
4553
  case 'px':
4192
4554
  this.prepareMut();
4193
4555
  setUint8(this.style_view, StyleKeys.VERTICAL_ALIGN_IS_PERCENT_OFFSET, 0);
4194
- setFloat32(this.style_view, StyleKeys.VERTICAL_ALIGN_OFFSET_OFFSET, parsed.value);
4556
+ setFloat32(this.style_view, StyleKeys.VERTICAL_ALIGN_OFFSET_OFFSET, layout.toDevicePixels(parsed.value));
4195
4557
  setUint8(this.style_view, StyleKeys.VERTICAL_ALIGN_ENUM_OFFSET, 0);
4196
4558
  break;
4197
4559
  case 'dip':
@@ -4218,7 +4580,7 @@ export class Style {
4218
4580
  case 'px':
4219
4581
  this.prepareMut();
4220
4582
  setUint8(this.style_view, StyleKeys.VERTICAL_ALIGN_IS_PERCENT_OFFSET, 0);
4221
- setFloat32(this.style_view, StyleKeys.VERTICAL_ALIGN_OFFSET_OFFSET, value.value);
4583
+ setFloat32(this.style_view, StyleKeys.VERTICAL_ALIGN_OFFSET_OFFSET, layout.toDevicePixels(value.value));
4222
4584
  setUint8(this.style_view, StyleKeys.VERTICAL_ALIGN_ENUM_OFFSET, 0);
4223
4585
  break;
4224
4586
  case 'dip':