@triniwiz/nativescript-masonkit 1.0.0-beta.120 → 1.0.0-beta.121
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.
- package/README.md +67 -27
- package/angular/README.md +7 -9
- package/button/index.windows.js +1 -1
- package/button/index.windows.js.map +1 -1
- package/common.d.ts +8 -2
- package/common.js +45 -30
- package/common.js.map +1 -1
- package/css-shorthands.js +14 -2
- package/css-shorthands.js.map +1 -1
- package/display-density.d.ts +9 -0
- package/display-density.js +21 -0
- package/display-density.js.map +1 -0
- package/foreign-layout.js +1 -1
- package/foreign-layout.js.map +1 -1
- package/gradient-stops.d.ts +17 -0
- package/gradient-stops.js +66 -0
- package/gradient-stops.js.map +1 -1
- package/index.d.ts +6 -3
- package/index.ios.d.ts +3 -0
- package/index.ios.js +3 -0
- package/index.ios.js.map +1 -1
- package/index.windows.d.ts +1 -1
- package/index.windows.js +1 -1
- package/index.windows.js.map +1 -1
- package/{html-windows.js → inner-html.windows.js} +6 -1
- package/inner-html.windows.js.map +1 -0
- package/input/index.ios.d.ts +2 -0
- package/input/index.ios.js +7 -0
- package/input/index.ios.js.map +1 -1
- package/input/index.windows.js +1 -1
- package/input/index.windows.js.map +1 -1
- package/li/index.windows.js +1 -1
- package/li/index.windows.js.map +1 -1
- package/list/index.windows.js +1 -1
- package/list/index.windows.js.map +1 -1
- package/mask.d.ts +54 -0
- package/mask.js +27 -0
- package/mask.js.map +1 -0
- package/{windows-mask.d.ts → mask.windows.d.ts} +24 -30
- package/{windows-mask.js → mask.windows.js} +97 -11
- package/mask.windows.js.map +1 -0
- package/nativescript.webpack.js +35 -0
- package/package.json +1 -1
- package/panel-helpers.d.ts +3 -0
- package/panel-helpers.js +9 -0
- package/panel-helpers.js.map +1 -0
- package/{windows-panel-helpers.js → panel-helpers.windows.js} +1 -1
- package/{windows-panel-helpers.js.map → panel-helpers.windows.js.map} +1 -1
- package/platforms/android/masonkit-release.aar +0 -0
- package/platforms/ios/Mason.xcframework/Info.plist +4 -4
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Headers/Mason-Swift.h +11 -2
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Headers/mason_native.h +10 -0
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Mason +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.abi.json +7069 -15103
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.private.swiftinterface +17 -5
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.swiftinterface +17 -5
- package/platforms/ios/Mason.xcframework/ios-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +9735 -9456
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Headers/Mason-Swift.h +22 -4
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Headers/mason_native.h +10 -0
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Mason +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.abi.json +7069 -15103
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +17 -5
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.swiftinterface +17 -5
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.abi.json +7069 -15103
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +17 -5
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +17 -5
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/_CodeSignature/CodeResources +28 -28
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +2 -2
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +9729 -9450
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/x86_64/Mason.yml +9286 -9010
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Headers/Mason-Swift.h +10 -2
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Headers/mason_native.h +10 -0
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Mason +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-xros.swiftsourceinfo +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.abi.json +6726 -14794
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.private.swiftinterface +16 -5
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.swiftdoc +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.swiftinterface +16 -5
- package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +9218 -8945
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Headers/Mason-Swift.h +10 -2
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Headers/mason_native.h +10 -0
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Mason +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/Project/arm64-apple-xros-simulator.swiftsourceinfo +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.abi.json +6726 -14794
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.private.swiftinterface +16 -5
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.swiftdoc +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.swiftinterface +16 -5
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/_CodeSignature/CodeResources +16 -16
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/DWARF/Mason +0 -0
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/dSYMs/Mason.framework.dSYM/Contents/Resources/Relocations/aarch64/Mason.yml +9217 -8944
- package/platforms/windows/arm64/NativeScript.Mason.dll +0 -0
- package/platforms/windows/arm64/NativeScript.Mason.winmd +0 -0
- package/platforms/windows/x64/NativeScript.Mason.dll +0 -0
- package/platforms/windows/x64/NativeScript.Mason.winmd +0 -0
- package/postcss-guard.js +64 -0
- package/properties.d.ts +6 -2
- package/properties.js +78 -13
- package/properties.js.map +1 -1
- package/scroll/index.windows.js +1 -1
- package/scroll/index.windows.js.map +1 -1
- package/style.d.ts +40 -11
- package/style.js +364 -52
- package/style.js.map +1 -1
- package/svg-path.windows.d.ts +8 -0
- package/svg-path.windows.js +204 -0
- package/svg-path.windows.js.map +1 -0
- package/text/index.windows.js +1 -1
- package/text/index.windows.js.map +1 -1
- package/textarea/index.ios.d.ts +2 -0
- package/textarea/index.ios.js +7 -0
- package/textarea/index.ios.js.map +1 -1
- package/tree/index.android.js +14 -3
- package/tree/index.android.js.map +1 -1
- package/tree/index.ios.js +11 -3
- package/tree/index.ios.js.map +1 -1
- package/tree/index.windows.js +20 -0
- package/tree/index.windows.js.map +1 -1
- package/typings/android.d.ts +13 -0
- package/typings/objc!Mason.d.ts +6 -0
- package/units.d.ts +7 -0
- package/units.js +30 -2
- package/units.js.map +1 -1
- package/utils/index.android.js +28 -27
- package/utils/index.android.js.map +1 -1
- package/utils/index.ios.d.ts +1 -1
- package/view/index.windows.js +1 -1
- package/view/index.windows.js.map +1 -1
- package/vue/README.md +12 -7
- package/web.js +4 -3
- package/web.js.map +1 -1
- package/html-windows.js.map +0 -1
- package/windows-mask.js.map +0 -1
- /package/{html-windows.d.ts → inner-html.windows.d.ts} +0 -0
- /package/{windows-panel-helpers.d.ts → panel-helpers.windows.d.ts} +0 -0
package/style.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { layout as coreLayout } from '@nativescript/core/utils';
|
|
2
2
|
import { cssUnits } from './units';
|
|
3
|
+
import { displayDensity, masonLayout } from './display-density';
|
|
3
4
|
import { isMasonView_, style_ } from './symbols';
|
|
4
5
|
import { pickFontFamily } from './fonts';
|
|
5
|
-
import { masonEngine } from './
|
|
6
|
+
import { masonEngine } from './panel-helpers';
|
|
6
7
|
import { reportCssDiagnostic } from './diagnostics';
|
|
7
8
|
import { expandColorStops, resolveStopPositions } from './gradient-stops';
|
|
8
9
|
import { encodeBoxShadows, parseBoxShadows } from './box-shadow';
|
|
9
10
|
import { encodeCssFilter, parseCssFilter } from './css-filter';
|
|
10
11
|
import { resolveCssColors } from './css-colors';
|
|
11
12
|
import { evaluateCssMath, hasCssMathFunction, isCssMathFunction, substituteCssMath } from './css-math';
|
|
12
|
-
import { encodeWindowsBackground, encodeWindowsBorderImage, encodeWindowsMask, WINDOWS_MASK_PROPERTIES } from './
|
|
13
|
+
import { encodeWindowsBackground, encodeWindowsBackgroundLayers, encodeWindowsBorderImage, encodeWindowsColorClip, encodeWindowsGradientBackground, hasCustomBackgroundBoxes, needsWindowsBackgroundLayers, encodeWindowsMask, WINDOWS_MASK_PROPERTIES } from './mask';
|
|
14
|
+
import { splitBackground } from './css-shorthands';
|
|
13
15
|
import { Color, Length as CoreLength, PercentLength as CorePercentLength, Screen, knownFolders } from '@nativescript/core';
|
|
14
16
|
// The Windows shell lays out in XAML DIPs, so its style buffer holds DIPs. Core's Windows density
|
|
15
17
|
// is 1 until the window has a XamlRoot, so converting stored early styles unscaled and later ones scaled.
|
|
16
|
-
const layout = __WINDOWS__ ? { ...coreLayout, getDisplayDensity: () => 1, toDevicePixels: (value) => value, toDeviceIndependentPixels: (value) => value } : coreLayout;
|
|
18
|
+
const layout = __WINDOWS__ ? { ...coreLayout, getDisplayDensity: () => 1, toDevicePixels: (value) => value, toDeviceIndependentPixels: (value) => value } : { ...coreLayout, ...masonLayout };
|
|
17
19
|
var StyleKeys;
|
|
18
20
|
(function (StyleKeys) {
|
|
19
21
|
// <style-keys:offsets> generated from tools/scripts/style-keys/style-keys.schema, run `npm run gen:style-keys`
|
|
@@ -352,6 +354,7 @@ function unitToCssPx(n, unit, emBasis) {
|
|
|
352
354
|
case 'vh':
|
|
353
355
|
case 'vmin':
|
|
354
356
|
case 'vmax': {
|
|
357
|
+
noteViewportUnit();
|
|
355
358
|
const { viewportWidth: w, viewportHeight: h } = cssUnits;
|
|
356
359
|
if (w <= 0 || h <= 0) {
|
|
357
360
|
reportCssDiagnostic({ kind: 'unsupported-unit', name: 'length', value: `${n}${unit}`, detail: 'viewport size not known yet, resolved to 0' });
|
|
@@ -380,6 +383,19 @@ function evaluateLengthMath(value, emBasis) {
|
|
|
380
383
|
export function resolveCssMathIn(value, emBasis) {
|
|
381
384
|
return substituteCssMath(value, (n, unit) => unitToCssPx(n, unit, emBasis));
|
|
382
385
|
}
|
|
386
|
+
const GRID_RELATIVE_LENGTH = /(^|[\s(,\]])([+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)(rem|em|pt|vw|vh|vmin|vmax)(?=$|[\s),[])/gi;
|
|
387
|
+
/** A grid track list with relative units and math functions resolved to `px`, which the native parser reads. */
|
|
388
|
+
export function resolveGridTrackUnits(value, emBasis) {
|
|
389
|
+
if (!value) {
|
|
390
|
+
return value;
|
|
391
|
+
}
|
|
392
|
+
let out = hasCssMathFunction(value) ? resolveCssMathIn(value, emBasis) : value;
|
|
393
|
+
out = out.replace(GRID_RELATIVE_LENGTH, (_m, lead, n, unit) => `${lead}${finite(unitToCssPx(parseFloat(n), unit.toLowerCase(), emBasis) ?? 0)}px`);
|
|
394
|
+
if (hasCssMathFunction(out)) {
|
|
395
|
+
reportCssDiagnostic({ kind: 'not-implemented', name: 'grid track list', value, detail: 'a math function mixing % with a length, dropped by the track parser' });
|
|
396
|
+
}
|
|
397
|
+
return out;
|
|
398
|
+
}
|
|
383
399
|
/**
|
|
384
400
|
* A math function in a `<length-percentage>` as the buffer's type/value pair,
|
|
385
401
|
* or undefined when `t` isn't one or doesn't resolve.
|
|
@@ -430,6 +446,7 @@ function tokenToDevicePx(token, raw, emBasis) {
|
|
|
430
446
|
if (t.endsWith('pt'))
|
|
431
447
|
return layout.toDevicePixels(n * PX_PER_PT);
|
|
432
448
|
if (t.endsWith('vmin') || t.endsWith('vmax') || t.endsWith('vw') || t.endsWith('vh')) {
|
|
449
|
+
noteViewportUnit();
|
|
433
450
|
if (cssUnits.viewportWidth <= 0 || cssUnits.viewportHeight <= 0) {
|
|
434
451
|
reportCssDiagnostic({ kind: 'unsupported-unit', name: 'length', value: t, detail: 'viewport size not known yet, resolved to 0' });
|
|
435
452
|
return 0;
|
|
@@ -538,6 +555,14 @@ export function cssLengthToDip(value, emBasis) {
|
|
|
538
555
|
}
|
|
539
556
|
return layout.toDeviceIndependentPixels(tokenToDevicePx(t, n, emBasis));
|
|
540
557
|
}
|
|
558
|
+
const SIZING_KEYWORD = /^(min-content|max-content|fit-content|stretch|content|fit-content\(.+\))$/;
|
|
559
|
+
export function isSizingKeyword(value) {
|
|
560
|
+
return typeof value === 'string' && SIZING_KEYWORD.test(value.trim());
|
|
561
|
+
}
|
|
562
|
+
/** The keyword carried as the unit of a core length object, if any. */
|
|
563
|
+
function sizingKeywordOf(value) {
|
|
564
|
+
return isSizingKeyword(value?.unit) ? value.unit : undefined;
|
|
565
|
+
}
|
|
541
566
|
function dimensionFromString(value, emBasis) {
|
|
542
567
|
const t = value.trim();
|
|
543
568
|
if (t === '' || t === 'auto') {
|
|
@@ -870,22 +895,32 @@ export function parseLinearGradientCss(value) {
|
|
|
870
895
|
corner = parseGradientCorner(head);
|
|
871
896
|
start = 1;
|
|
872
897
|
}
|
|
898
|
+
const { colors, positions, lengths } = parseGradientStops(parts.slice(start));
|
|
899
|
+
if (colors.length < 1)
|
|
900
|
+
return null;
|
|
901
|
+
return { angle, ...(corner && { corner }), offsets: resolveStopPositions(positions), colors, interpolation, positions, ...(lengths && { lengths }) };
|
|
902
|
+
}
|
|
903
|
+
// A length stop needs the gradient line's length, which only the painter knows.
|
|
904
|
+
function parseGradientStops(stops) {
|
|
873
905
|
const colors = [];
|
|
874
906
|
const positions = [];
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const pos = /\s+(-?[\d.]+)(%|[a-z]+)
|
|
907
|
+
const lengths = [];
|
|
908
|
+
let anyLength = false;
|
|
909
|
+
for (const stop of expandColorStops(stops)) {
|
|
910
|
+
const pos = /\s+(-?[\d.]+)(%|[a-z]+)?\s*$/i.exec(stop);
|
|
879
911
|
const colorStr = pos ? stop.slice(0, pos.index).trim() : stop;
|
|
880
912
|
const argb = normalizeColorValue(colorStr);
|
|
881
913
|
if (argb == null)
|
|
882
914
|
continue;
|
|
883
915
|
colors.push(argb >>> 0);
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
916
|
+
const percent = pos?.[2] === '%';
|
|
917
|
+
const length = pos && !percent ? cssLengthToDip(pos[1] + (pos[2] ?? 'px')) : undefined;
|
|
918
|
+
positions.push(percent ? parseFloat(pos[1]) / 100 : null);
|
|
919
|
+
lengths.push(length ?? null);
|
|
920
|
+
if (length != null)
|
|
921
|
+
anyLength = true;
|
|
922
|
+
}
|
|
923
|
+
return { colors, positions, ...(anyLength && { lengths }) };
|
|
889
924
|
}
|
|
890
925
|
const RADIAL_GRADIENT_ARGS = /radial-gradient\s*\(([\s\S]*)\)\s*$/i;
|
|
891
926
|
function positionFraction(token, axis) {
|
|
@@ -955,23 +990,17 @@ export function parseRadialGradientCss(value) {
|
|
|
955
990
|
if (sizeKeyword)
|
|
956
991
|
size = sizeKeyword[1].toLowerCase();
|
|
957
992
|
}
|
|
993
|
+
const shape = head.replace(/\bat\s+.+$/i, '');
|
|
994
|
+
const circleLength = /\bcircle\b/i.test(shape) || /^\s*-?[\d.]+[a-z]*\s*$/i.test(shape) ? /(-?[\d.]+(?:px|r?em|pt|vw|vh)?)(?=\s|$)/i.exec(shape) : null;
|
|
995
|
+
const circleRadius = circleLength ? cssLengthToDip(/[a-z]$/i.test(circleLength[1]) ? circleLength[1] : circleLength[1] + 'px') : undefined;
|
|
996
|
+
const circle = /\bcircle\b/i.test(shape) || circleRadius != null ? ['closest-side', 'farthest-side', 'closest-corner', 'farthest-corner'].indexOf(size) : undefined;
|
|
958
997
|
const sideX = size.startsWith('closest') ? Math.min(cx, 1 - cx) : Math.max(cx, 1 - cx);
|
|
959
998
|
const sideY = size.startsWith('closest') ? Math.min(cy, 1 - cy) : Math.max(cy, 1 - cy);
|
|
960
999
|
const corner = size.endsWith('corner') ? Math.SQRT2 : 1;
|
|
961
|
-
const colors =
|
|
962
|
-
const positions = [];
|
|
963
|
-
for (const stop of expandColorStops(parts.slice(start))) {
|
|
964
|
-
const pos = /\s+(-?[\d.]+)(%|[a-z]+)\s*$/i.exec(stop);
|
|
965
|
-
const colorStr = pos ? stop.slice(0, pos.index).trim() : stop;
|
|
966
|
-
const argb = normalizeColorValue(colorStr);
|
|
967
|
-
if (argb == null)
|
|
968
|
-
continue;
|
|
969
|
-
colors.push(argb >>> 0);
|
|
970
|
-
positions.push(pos && pos[2] === '%' ? parseFloat(pos[1]) / 100 : null);
|
|
971
|
-
}
|
|
1000
|
+
const { colors, positions, lengths } = parseGradientStops(parts.slice(start));
|
|
972
1001
|
if (colors.length < 1)
|
|
973
1002
|
return null;
|
|
974
|
-
return { cx, cy, rx: Math.max(sideX * corner, 0.001), ry: Math.max(sideY * corner, 0.001), offsets: resolveStopPositions(positions), colors, interpolation };
|
|
1003
|
+
return { cx, cy, rx: Math.max(sideX * corner, 0.001), ry: Math.max(sideY * corner, 0.001), offsets: resolveStopPositions(positions), colors, interpolation, positions, ...(lengths && { lengths }), ...(circle != null && { circle }), ...(circleRadius != null && { circleRadius }) };
|
|
975
1004
|
}
|
|
976
1005
|
export function backgroundFit(size) {
|
|
977
1006
|
const t = (size ?? '').trim().toLowerCase();
|
|
@@ -1048,6 +1077,8 @@ function radiusCorners(t) {
|
|
|
1048
1077
|
}
|
|
1049
1078
|
let deviceScaleCache = 0;
|
|
1050
1079
|
function deviceScale() {
|
|
1080
|
+
if (__ANDROID__)
|
|
1081
|
+
return displayDensity();
|
|
1051
1082
|
return deviceScaleCache || (deviceScaleCache = Screen.mainScreen.scale);
|
|
1052
1083
|
}
|
|
1053
1084
|
function parseWindowsRadius(token, emBasis) {
|
|
@@ -1080,6 +1111,41 @@ export function parseBorderRadiusShorthand(value, emBasis) {
|
|
|
1080
1111
|
return { tl: vals[0], tr: vals[1], br: vals[2], bl: vals[3] };
|
|
1081
1112
|
}
|
|
1082
1113
|
}
|
|
1114
|
+
const CORNER_SHAPE_KEYWORDS = { round: 1, squircle: 2, bevel: 0, scoop: -1, notch: -Infinity, square: Infinity };
|
|
1115
|
+
const SUPERELLIPSE = /^superellipse\(\s*(-?infinity|[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)\s*\)$/;
|
|
1116
|
+
/** corner-shape as each corner's superellipse parameter K (TL TR BR BL), or null if a token is invalid. An empty value resets to round. */
|
|
1117
|
+
export function parseCornerShape(value) {
|
|
1118
|
+
const tokens = splitTopLevelSpaces(String(value ?? '')
|
|
1119
|
+
.trim()
|
|
1120
|
+
.toLowerCase());
|
|
1121
|
+
if (!tokens.length || (tokens.length === 1 && /^(initial|unset|revert|none)$/.test(tokens[0])))
|
|
1122
|
+
return [1, 1, 1, 1];
|
|
1123
|
+
if (tokens.length > 4)
|
|
1124
|
+
return null;
|
|
1125
|
+
const e = [];
|
|
1126
|
+
for (const token of tokens) {
|
|
1127
|
+
if (token in CORNER_SHAPE_KEYWORDS) {
|
|
1128
|
+
e.push(CORNER_SHAPE_KEYWORDS[token]);
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
const m = SUPERELLIPSE.exec(token);
|
|
1132
|
+
if (!m)
|
|
1133
|
+
return null;
|
|
1134
|
+
e.push(m[1] === 'infinity' ? Infinity : m[1] === '-infinity' ? -Infinity : Number(m[1]));
|
|
1135
|
+
}
|
|
1136
|
+
switch (e.length) {
|
|
1137
|
+
case 1:
|
|
1138
|
+
return [e[0], e[0], e[0], e[0]];
|
|
1139
|
+
case 2:
|
|
1140
|
+
return [e[0], e[1], e[0], e[1]];
|
|
1141
|
+
case 3:
|
|
1142
|
+
return [e[0], e[1], e[2], e[1]];
|
|
1143
|
+
default:
|
|
1144
|
+
return [e[0], e[1], e[2], e[3]];
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
const CORNER_SHAPE_KEYS = [StyleKeys.BORDER_RADIUS_TOP_LEFT_EXPONENT, StyleKeys.BORDER_RADIUS_TOP_RIGHT_EXPONENT, StyleKeys.BORDER_RADIUS_BOTTOM_RIGHT_EXPONENT, StyleKeys.BORDER_RADIUS_BOTTOM_LEFT_EXPONENT];
|
|
1148
|
+
const CORNER_SHAPE_LONGHANDS = { 'corner-shape-top-left': 0, 'corner-shape-top-right': 1, 'corner-shape-bottom-right': 2, 'corner-shape-bottom-left': 3 };
|
|
1083
1149
|
// Split on top-level whitespace, keeping parenthesised groups (e.g. `rgba(0,0,0,.5)`) intact.
|
|
1084
1150
|
function splitTopLevelSpaces(value) {
|
|
1085
1151
|
const out = [];
|
|
@@ -1458,6 +1524,56 @@ export function cssColorToRgba(color) {
|
|
|
1458
1524
|
}
|
|
1459
1525
|
return `rgba(${color_.r}, ${color_.g}, ${color_.b}, ${+(color_.a / 255).toFixed(4)})`;
|
|
1460
1526
|
}
|
|
1527
|
+
// Style writes that resolved a viewport unit, kept so a viewport change can write them again, as
|
|
1528
|
+
// a browser re-resolves vw/vh when the window resizes. Each setter is wrapped once below.
|
|
1529
|
+
const viewportWrites = new WeakMap();
|
|
1530
|
+
const viewportStyles = new Set();
|
|
1531
|
+
const writeTargets = [];
|
|
1532
|
+
const writeNames = [];
|
|
1533
|
+
const writeValues = [];
|
|
1534
|
+
let writeDepth = 0;
|
|
1535
|
+
const VIEWPORT_UNIT_TEXT = /\d(?:vw|vh|vmin|vmax)\b/i;
|
|
1536
|
+
/** Marks a style write in progress, so a viewport unit it resolves is remembered against `target[name] = value`. */
|
|
1537
|
+
export function beginStyleWrite(target, name, value) {
|
|
1538
|
+
viewportWrites.get(target)?.delete(name);
|
|
1539
|
+
writeTargets[writeDepth] = target;
|
|
1540
|
+
writeNames[writeDepth] = name;
|
|
1541
|
+
writeValues[writeDepth] = value;
|
|
1542
|
+
writeDepth++;
|
|
1543
|
+
// Android and iOS parse some CSS text natively, so the text itself marks a viewport unit.
|
|
1544
|
+
if (typeof value === 'string' && VIEWPORT_UNIT_TEXT.test(value))
|
|
1545
|
+
noteViewportUnit();
|
|
1546
|
+
}
|
|
1547
|
+
export function endStyleWrite() {
|
|
1548
|
+
writeDepth--;
|
|
1549
|
+
writeTargets[writeDepth] = writeValues[writeDepth] = undefined;
|
|
1550
|
+
}
|
|
1551
|
+
function noteViewportUnit() {
|
|
1552
|
+
if (!writeDepth)
|
|
1553
|
+
return;
|
|
1554
|
+
const target = writeTargets[writeDepth - 1];
|
|
1555
|
+
let writes = viewportWrites.get(target);
|
|
1556
|
+
if (!writes) {
|
|
1557
|
+
writes = new Map();
|
|
1558
|
+
viewportWrites.set(target, writes);
|
|
1559
|
+
viewportStyles.add(new WeakRef(target));
|
|
1560
|
+
}
|
|
1561
|
+
writes.set(writeNames[writeDepth - 1], writeValues[writeDepth - 1]);
|
|
1562
|
+
}
|
|
1563
|
+
/** Writes every style property that used vw/vh/vmin/vmax again, against the current viewport. */
|
|
1564
|
+
export function refreshViewportUnits() {
|
|
1565
|
+
for (const ref of viewportStyles) {
|
|
1566
|
+
const style = ref.deref();
|
|
1567
|
+
const writes = style && viewportWrites.get(style);
|
|
1568
|
+
if (!style || !writes || !writes.size) {
|
|
1569
|
+
viewportStyles.delete(ref);
|
|
1570
|
+
continue;
|
|
1571
|
+
}
|
|
1572
|
+
const keys = Array.from(writes.keys());
|
|
1573
|
+
for (let i = 0; i < keys.length; i++)
|
|
1574
|
+
style[keys[i]] = writes.get(keys[i]);
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1461
1577
|
export class Style {
|
|
1462
1578
|
constructor() {
|
|
1463
1579
|
this._bufferRequested = false;
|
|
@@ -1477,6 +1593,7 @@ export class Style {
|
|
|
1477
1593
|
this._synced = false;
|
|
1478
1594
|
this._windowsCss = new Map();
|
|
1479
1595
|
this._windowsImageBackground = false;
|
|
1596
|
+
this._windowsBackgroundShorthand = false;
|
|
1480
1597
|
this._windowsMaskSpec = '';
|
|
1481
1598
|
}
|
|
1482
1599
|
static fromView(view, nativeView) {
|
|
@@ -1692,11 +1809,36 @@ export class Style {
|
|
|
1692
1809
|
const layer = splitTopLevelCommas(v)[0]?.trim() ?? '';
|
|
1693
1810
|
const stopsOf = (g) => g.offsets.map((o, i) => o + ':' + (g.colors[i] >>> 0)).join(',');
|
|
1694
1811
|
try {
|
|
1812
|
+
const longhands = this.windowsBackgroundLonghands(shorthand, v);
|
|
1813
|
+
if (longhands && (needsWindowsBackgroundLayers(longhands) || (ANY_GRADIENT.test(v) && this.windowsScrolls()))) {
|
|
1814
|
+
const spec = encodeWindowsBackgroundLayers(longhands, this.windowsMaskContext());
|
|
1815
|
+
if (spec) {
|
|
1816
|
+
this._windowsImageBackground = true;
|
|
1817
|
+
NativeScript.Mason.Css.SetBackgroundLayers(this.nativeView, spec);
|
|
1818
|
+
if (longhands.color)
|
|
1819
|
+
this.backgroundColor = longhands.color;
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1695
1823
|
const url = /url\(\s*(['"]?)(.*?)\1\s*\)/i.exec(layer);
|
|
1696
1824
|
if (!url && this._windowsImageBackground) {
|
|
1697
1825
|
this._windowsImageBackground = false;
|
|
1698
1826
|
NativeScript.Mason.Css.SetBackgroundLayers(this.nativeView, '');
|
|
1699
1827
|
}
|
|
1828
|
+
const boxes = this.windowsBackgroundBoxes(shorthand ? layer : '');
|
|
1829
|
+
const setLayers = (spec) => {
|
|
1830
|
+
if (!spec)
|
|
1831
|
+
return false;
|
|
1832
|
+
this._windowsImageBackground = true;
|
|
1833
|
+
NativeScript.Mason.Css.SetBackgroundLayers(this.nativeView, spec);
|
|
1834
|
+
return true;
|
|
1835
|
+
};
|
|
1836
|
+
// Only the layer painter places a background in a box other than the CSS defaults.
|
|
1837
|
+
if (ANY_GRADIENT.test(layer) && (hasCustomBackgroundBoxes(boxes) || /^(repeating-|conic-gradient)/i.test(layer) || this.windowsColorUnder() || /\d(px|r?em|pt|vw|vh)\b|\bcircle\b/i.test(layer))) {
|
|
1838
|
+
const ctx = this.windowsMaskContext();
|
|
1839
|
+
setLayers(encodeWindowsGradientBackground(layer, this._windowsBackgroundSize ?? '', this._windowsBackgroundPosition ?? '', this._windowsCss.get('background-repeat') ?? '', ctx, boxes));
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1700
1842
|
if (/^radial-gradient/i.test(layer)) {
|
|
1701
1843
|
const g = parseRadialGradientCss(layer);
|
|
1702
1844
|
if (g)
|
|
@@ -1711,19 +1853,15 @@ export class Style {
|
|
|
1711
1853
|
}
|
|
1712
1854
|
if (url) {
|
|
1713
1855
|
const rest = layer.slice(url.index + url[0].length).trim();
|
|
1714
|
-
const keywords = /\b(no-repeat|repeat-x|repeat-y|repeat|space|round|scroll|fixed|local|border-box|padding-box|content-box)\b/gi;
|
|
1856
|
+
const keywords = /\b(no-repeat|repeat-x|repeat-y|repeat|space|round|scroll|fixed|local|border-box|padding-box|content-box|text)\b/gi;
|
|
1715
1857
|
const [positionPart, sizePart] = rest.split('/').map((p) => p.replace(keywords, '').trim());
|
|
1716
1858
|
const size = shorthand && sizePart ? sizePart.split(/\s+/).slice(0, 2).join(' ') : (this._windowsBackgroundSize ?? '');
|
|
1717
1859
|
const position = shorthand && positionPart ? positionPart : (this._windowsBackgroundPosition ?? '');
|
|
1718
1860
|
const repeatKeywords = shorthand ? (rest.match(/\b(no-repeat|repeat-x|repeat-y|repeat|space|round)\b/gi) ?? []).join(' ') : '';
|
|
1719
1861
|
const repeat = repeatKeywords || (this._windowsCss.get('background-repeat') ?? '');
|
|
1720
1862
|
// Painted natively over background-color (CssMask.h), which an ImageBrush would replace.
|
|
1721
|
-
|
|
1722
|
-
if (spec) {
|
|
1723
|
-
this._windowsImageBackground = true;
|
|
1724
|
-
NativeScript.Mason.Css.SetBackgroundLayers(this.nativeView, spec);
|
|
1863
|
+
if (setLayers(encodeWindowsBackground(url[2], size, position, repeat, this.windowsMaskContext(), boxes)))
|
|
1725
1864
|
return;
|
|
1726
|
-
}
|
|
1727
1865
|
let source = url[2];
|
|
1728
1866
|
if (source.startsWith('~/'))
|
|
1729
1867
|
source = source.replace('~/', knownFolders.currentApp().path + '/');
|
|
@@ -1734,12 +1872,60 @@ export class Style {
|
|
|
1734
1872
|
}
|
|
1735
1873
|
if (!ANY_GRADIENT.test(layer)) {
|
|
1736
1874
|
NativeScript.Mason.Css.ClearBackground(this.nativeView);
|
|
1737
|
-
|
|
1738
|
-
|
|
1875
|
+
const color = v.replace(/\b(border-box|padding-box|content-box|text)\b/gi, '').trim();
|
|
1876
|
+
if (shorthand && color.length && color.toLowerCase() !== 'none')
|
|
1877
|
+
this.backgroundColor = color;
|
|
1878
|
+
if (boxes.clip && hasCustomBackgroundBoxes({ clip: boxes.clip }))
|
|
1879
|
+
setLayers(encodeWindowsColorClip(boxes.clip, this.windowsMaskContext()));
|
|
1739
1880
|
}
|
|
1740
1881
|
}
|
|
1741
1882
|
catch (_) { }
|
|
1742
1883
|
}
|
|
1884
|
+
windowsScrolls() {
|
|
1885
|
+
if (!this.style_view)
|
|
1886
|
+
return false;
|
|
1887
|
+
const x = getInt8(this.style_view, StyleKeys.OVERFLOW_X);
|
|
1888
|
+
const y = getInt8(this.style_view, StyleKeys.OVERFLOW_Y);
|
|
1889
|
+
return x === 2 || x === 4 || y === 2 || y === 4;
|
|
1890
|
+
}
|
|
1891
|
+
windowsColorUnder() {
|
|
1892
|
+
return !!this.style_view && getUint32(this.style_view, StyleKeys.BACKGROUND_COLOR) >>> 24 > 0;
|
|
1893
|
+
}
|
|
1894
|
+
windowsReapplyGradient() {
|
|
1895
|
+
if (ANY_GRADIENT.test(this._windowsBackground ?? ''))
|
|
1896
|
+
this.applyWindowsBackground(this._windowsBackgroundShorthand);
|
|
1897
|
+
}
|
|
1898
|
+
windowsBackgroundLonghands(shorthand, value) {
|
|
1899
|
+
const css = this._windowsCss;
|
|
1900
|
+
const blend = css.get('background-blend-mode');
|
|
1901
|
+
if (!shorthand) {
|
|
1902
|
+
return { image: value, size: this._windowsBackgroundSize, position: this._windowsBackgroundPosition, repeat: css.get('background-repeat'), origin: css.get('background-origin'), clip: css.get('background-clip'), attachment: css.get('background-attachment'), blend };
|
|
1903
|
+
}
|
|
1904
|
+
let parts;
|
|
1905
|
+
try {
|
|
1906
|
+
parts = splitBackground(value);
|
|
1907
|
+
}
|
|
1908
|
+
catch (_) {
|
|
1909
|
+
return null;
|
|
1910
|
+
}
|
|
1911
|
+
const text = (part) => (typeof part === 'string' ? part : undefined);
|
|
1912
|
+
const [color, image, repeat, position, size, clip, origin, attachment] = parts.map(text);
|
|
1913
|
+
if (!image)
|
|
1914
|
+
return null;
|
|
1915
|
+
return { image, size, position, repeat, origin, clip, attachment, blend, color };
|
|
1916
|
+
}
|
|
1917
|
+
// background-origin and background-clip: the shorthand's box keywords (origin, then clip), else the longhands.
|
|
1918
|
+
// `text` is a clip only; url() and gradient arguments are skipped so a file name can't match it.
|
|
1919
|
+
windowsBackgroundBoxes(shorthandLayer) {
|
|
1920
|
+
const bare = shorthandLayer.replace(/[\w-]+\((?:[^()]|\([^()]*\))*\)/g, ' ');
|
|
1921
|
+
const keywords = bare.match(/\b(border-box|padding-box|content-box|text)\b/gi) ?? [];
|
|
1922
|
+
if (keywords.length) {
|
|
1923
|
+
const boxes = keywords.filter((k) => k.toLowerCase() !== 'text');
|
|
1924
|
+
const text = boxes.length < keywords.length;
|
|
1925
|
+
return { origin: boxes[0], clip: text ? 'text' : (boxes[1] ?? boxes[0]) };
|
|
1926
|
+
}
|
|
1927
|
+
return { origin: this._windowsCss.get('background-origin'), clip: this._windowsCss.get('background-clip') };
|
|
1928
|
+
}
|
|
1743
1929
|
windowsMaskContext() {
|
|
1744
1930
|
return {
|
|
1745
1931
|
length: (token) => cssLengthToDip(token, this.emBasisFor(token)),
|
|
@@ -1798,11 +1984,16 @@ export class Style {
|
|
|
1798
1984
|
// it lets VisualApply repaint the color.
|
|
1799
1985
|
if (name === 'background' || name === 'background-image') {
|
|
1800
1986
|
this._windowsBackground = typeof value === 'string' ? value : String(value ?? '');
|
|
1987
|
+
this._windowsBackgroundShorthand = name === 'background';
|
|
1801
1988
|
this.applyWindowsBackground(name === 'background');
|
|
1802
1989
|
return;
|
|
1803
1990
|
}
|
|
1804
|
-
if (name === 'background-
|
|
1805
|
-
|
|
1991
|
+
if (name === 'background-clip' || name === 'background-origin') {
|
|
1992
|
+
this.applyWindowsBackground(false);
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
if (name === 'background-repeat' || name === 'background-attachment' || name === 'background-blend-mode') {
|
|
1996
|
+
if (/url\(|gradient/i.test(this._windowsBackground ?? ''))
|
|
1806
1997
|
this.applyWindowsBackground(false);
|
|
1807
1998
|
return;
|
|
1808
1999
|
}
|
|
@@ -1811,7 +2002,7 @@ export class Style {
|
|
|
1811
2002
|
this._windowsBackgroundSize = String(value ?? '');
|
|
1812
2003
|
else
|
|
1813
2004
|
this._windowsBackgroundPosition = String(value ?? '');
|
|
1814
|
-
if (/url\(/i.test(this._windowsBackground ?? ''))
|
|
2005
|
+
if (/url\(|gradient/i.test(this._windowsBackground ?? ''))
|
|
1815
2006
|
this.applyWindowsBackground(false);
|
|
1816
2007
|
return;
|
|
1817
2008
|
}
|
|
@@ -1873,6 +2064,20 @@ export class Style {
|
|
|
1873
2064
|
this.commitState(StateKeys.BORDER_RADIUS);
|
|
1874
2065
|
return;
|
|
1875
2066
|
}
|
|
2067
|
+
if (name === 'corner-shape' || name in CORNER_SHAPE_LONGHANDS) {
|
|
2068
|
+
const text = typeof value === 'string' ? value : '';
|
|
2069
|
+
const e = parseCornerShape(text);
|
|
2070
|
+
if (!e || (name !== 'corner-shape' && splitTopLevelSpaces(text.trim()).length > 1))
|
|
2071
|
+
return;
|
|
2072
|
+
this.prepareMut();
|
|
2073
|
+
if (name === 'corner-shape')
|
|
2074
|
+
for (let i = 0; i < 4; i++)
|
|
2075
|
+
setFloat32(this.style_view, CORNER_SHAPE_KEYS[i], e[i]);
|
|
2076
|
+
else
|
|
2077
|
+
setFloat32(this.style_view, CORNER_SHAPE_KEYS[CORNER_SHAPE_LONGHANDS[name]], e[0]);
|
|
2078
|
+
this.commitState(StateKeys.BORDER_RADIUS);
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
1876
2081
|
if (name === 'border' || name === 'border-top' || name === 'border-right' || name === 'border-bottom' || name === 'border-left') {
|
|
1877
2082
|
const p = parseBorderShorthand(value, this.emBasisFor(value));
|
|
1878
2083
|
let style = p.style;
|
|
@@ -2125,7 +2330,7 @@ export class Style {
|
|
|
2125
2330
|
if (!this.style_view || getInt8(this.style_view, StyleKeys.FONT_SIZE_STATE) !== 1) {
|
|
2126
2331
|
return this.parentEmBasis();
|
|
2127
2332
|
}
|
|
2128
|
-
const own =
|
|
2333
|
+
const own = getFloat32(this.style_view, StyleKeys.FONT_SIZE);
|
|
2129
2334
|
if (own <= 0) {
|
|
2130
2335
|
return this.parentEmBasis();
|
|
2131
2336
|
}
|
|
@@ -2252,7 +2457,7 @@ export class Style {
|
|
|
2252
2457
|
return 16;
|
|
2253
2458
|
}
|
|
2254
2459
|
const type = getUint8(this.style_view, StyleKeys.FONT_SIZE_TYPE);
|
|
2255
|
-
const value =
|
|
2460
|
+
const value = getFloat32(this.style_view, StyleKeys.FONT_SIZE);
|
|
2256
2461
|
if (type === 1) {
|
|
2257
2462
|
return `${value / 100}%`;
|
|
2258
2463
|
}
|
|
@@ -2298,7 +2503,7 @@ export class Style {
|
|
|
2298
2503
|
else if (isDevicePixelToken(t)) {
|
|
2299
2504
|
resolved = layout.toDeviceIndependentPixels(n);
|
|
2300
2505
|
}
|
|
2301
|
-
|
|
2506
|
+
setFloat32(this.style_view, StyleKeys.FONT_SIZE, resolved);
|
|
2302
2507
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
|
|
2303
2508
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, isPercent ? 1 : 0);
|
|
2304
2509
|
this.commitState(StateKeys.FONT_SIZE);
|
|
@@ -2306,7 +2511,7 @@ export class Style {
|
|
|
2306
2511
|
}
|
|
2307
2512
|
case 'number':
|
|
2308
2513
|
this.prepareMut();
|
|
2309
|
-
|
|
2514
|
+
setFloat32(this.style_view, StyleKeys.FONT_SIZE, value);
|
|
2310
2515
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
|
|
2311
2516
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, 0);
|
|
2312
2517
|
this.commitState(StateKeys.FONT_SIZE);
|
|
@@ -2315,21 +2520,21 @@ export class Style {
|
|
|
2315
2520
|
switch (value.unit) {
|
|
2316
2521
|
case 'dip':
|
|
2317
2522
|
this.prepareMut();
|
|
2318
|
-
|
|
2523
|
+
setFloat32(this.style_view, StyleKeys.FONT_SIZE, finite(value.value));
|
|
2319
2524
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
|
|
2320
2525
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, 0);
|
|
2321
2526
|
this.commitState(StateKeys.FONT_SIZE);
|
|
2322
2527
|
break;
|
|
2323
2528
|
case 'px':
|
|
2324
2529
|
this.prepareMut();
|
|
2325
|
-
|
|
2530
|
+
setFloat32(this.style_view, StyleKeys.FONT_SIZE, finite(value.value));
|
|
2326
2531
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
|
|
2327
2532
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, 0);
|
|
2328
2533
|
this.commitState(StateKeys.FONT_SIZE);
|
|
2329
2534
|
break;
|
|
2330
2535
|
case '%':
|
|
2331
2536
|
this.prepareMut();
|
|
2332
|
-
|
|
2537
|
+
setFloat32(this.style_view, StyleKeys.FONT_SIZE, value.value * 100);
|
|
2333
2538
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_STATE, 1);
|
|
2334
2539
|
setInt8(this.style_view, StyleKeys.FONT_SIZE_TYPE, 1);
|
|
2335
2540
|
this.commitState(StateKeys.FONT_SIZE);
|
|
@@ -2492,6 +2697,8 @@ export class Style {
|
|
|
2492
2697
|
setInt8(this.style_view, StyleKeys.BACKGROUND_COLOR_STATE, 1);
|
|
2493
2698
|
setInt8(this.style_view, StyleKeys.BACKGROUND_COLOR_TYPE, 0);
|
|
2494
2699
|
this.commitState(StateKeys.BACKGROUND_COLOR);
|
|
2700
|
+
if (__WINDOWS__ && !this._windowsImageBackground && normalized >>> 24 > 0)
|
|
2701
|
+
this.windowsReapplyGradient();
|
|
2495
2702
|
}
|
|
2496
2703
|
get textWrap() {
|
|
2497
2704
|
if (!this.style_view) {
|
|
@@ -2510,6 +2717,8 @@ export class Style {
|
|
|
2510
2717
|
wrap = 1;
|
|
2511
2718
|
break;
|
|
2512
2719
|
case 'wrap':
|
|
2720
|
+
case 'pretty':
|
|
2721
|
+
case 'stable':
|
|
2513
2722
|
wrap = 0;
|
|
2514
2723
|
break;
|
|
2515
2724
|
case 'balance':
|
|
@@ -2683,7 +2892,7 @@ export class Style {
|
|
|
2683
2892
|
get flexWrap() {
|
|
2684
2893
|
switch (getInt8(this.style_view, StyleKeys.FLEX_WRAP)) {
|
|
2685
2894
|
case 0:
|
|
2686
|
-
return '
|
|
2895
|
+
return 'nowrap';
|
|
2687
2896
|
case 1:
|
|
2688
2897
|
return 'wrap';
|
|
2689
2898
|
case 2:
|
|
@@ -2697,6 +2906,7 @@ export class Style {
|
|
|
2697
2906
|
set flexWrap(value) {
|
|
2698
2907
|
let wrap = -1;
|
|
2699
2908
|
switch (value) {
|
|
2909
|
+
case 'nowrap':
|
|
2700
2910
|
case 'no-wrap':
|
|
2701
2911
|
wrap = 0;
|
|
2702
2912
|
break;
|
|
@@ -2849,8 +3059,18 @@ export class Style {
|
|
|
2849
3059
|
setInt8(this.style_view, StyleKeys.WIDTH_TYPE, 2);
|
|
2850
3060
|
setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, value.value);
|
|
2851
3061
|
break;
|
|
2852
|
-
default:
|
|
2853
|
-
|
|
3062
|
+
default: {
|
|
3063
|
+
// A sizing keyword routed through core (see sizingKeywordLength in properties.ts).
|
|
3064
|
+
const keyword = sizingKeywordOf(value);
|
|
3065
|
+
if (!keyword) {
|
|
3066
|
+
return;
|
|
3067
|
+
}
|
|
3068
|
+
this.prepareMut();
|
|
3069
|
+
const dim = dimensionFromString(keyword);
|
|
3070
|
+
setInt8(this.style_view, StyleKeys.WIDTH_TYPE, dim.type);
|
|
3071
|
+
setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, dim.value);
|
|
3072
|
+
break;
|
|
3073
|
+
}
|
|
2854
3074
|
}
|
|
2855
3075
|
break;
|
|
2856
3076
|
default:
|
|
@@ -2894,8 +3114,18 @@ export class Style {
|
|
|
2894
3114
|
setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, 2);
|
|
2895
3115
|
setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, value.value);
|
|
2896
3116
|
break;
|
|
2897
|
-
default:
|
|
2898
|
-
|
|
3117
|
+
default: {
|
|
3118
|
+
// A sizing keyword routed through core (see sizingKeywordLength in properties.ts).
|
|
3119
|
+
const keyword = sizingKeywordOf(value);
|
|
3120
|
+
if (!keyword) {
|
|
3121
|
+
return;
|
|
3122
|
+
}
|
|
3123
|
+
this.prepareMut();
|
|
3124
|
+
const dim = dimensionFromString(keyword);
|
|
3125
|
+
setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, dim.type);
|
|
3126
|
+
setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, dim.value);
|
|
3127
|
+
break;
|
|
3128
|
+
}
|
|
2899
3129
|
}
|
|
2900
3130
|
break;
|
|
2901
3131
|
default:
|
|
@@ -4312,6 +4542,7 @@ export class Style {
|
|
|
4312
4542
|
}
|
|
4313
4543
|
// A bare number can't marshal over JNI into the native String setter.
|
|
4314
4544
|
value = value == null ? '' : String(value);
|
|
4545
|
+
value = resolveGridTrackUnits(value, this.emBasisFor(value));
|
|
4315
4546
|
if (__ANDROID__) {
|
|
4316
4547
|
nodeHelper().setGridAutoRows(this.nativeView, value);
|
|
4317
4548
|
}
|
|
@@ -4340,6 +4571,7 @@ export class Style {
|
|
|
4340
4571
|
}
|
|
4341
4572
|
// See gridAutoRows above.
|
|
4342
4573
|
value = value == null ? '' : String(value);
|
|
4574
|
+
value = resolveGridTrackUnits(value, this.emBasisFor(value));
|
|
4343
4575
|
if (__ANDROID__) {
|
|
4344
4576
|
nodeHelper().setGridAutoColumns(this.nativeView, value);
|
|
4345
4577
|
}
|
|
@@ -4363,7 +4595,7 @@ export class Style {
|
|
|
4363
4595
|
}
|
|
4364
4596
|
}
|
|
4365
4597
|
set gridAutoFlow(value) {
|
|
4366
|
-
const v =
|
|
4598
|
+
const v = gridAutoFlowFromString(value);
|
|
4367
4599
|
if (v !== undefined) {
|
|
4368
4600
|
this.prepareMut();
|
|
4369
4601
|
setInt8(this.style_view, StyleKeys.GRID_AUTO_FLOW, v);
|
|
@@ -4584,6 +4816,7 @@ export class Style {
|
|
|
4584
4816
|
}
|
|
4585
4817
|
// null clears the template; also guards against a bare number (see gridAutoRows above).
|
|
4586
4818
|
value = value == null ? '' : String(value);
|
|
4819
|
+
value = resolveGridTrackUnits(value, this.emBasisFor(value));
|
|
4587
4820
|
if (__ANDROID__) {
|
|
4588
4821
|
nodeHelper().setGridTemplateRows(this.nativeView, value);
|
|
4589
4822
|
}
|
|
@@ -4624,6 +4857,7 @@ export class Style {
|
|
|
4624
4857
|
}
|
|
4625
4858
|
// null clears the template; also guards against a bare number (see gridAutoRows above).
|
|
4626
4859
|
value = value == null ? '' : String(value);
|
|
4860
|
+
value = resolveGridTrackUnits(value, this.emBasisFor(value));
|
|
4627
4861
|
if (__ANDROID__) {
|
|
4628
4862
|
nodeHelper().setGridTemplateColumns(this.nativeView, value);
|
|
4629
4863
|
}
|
|
@@ -4696,6 +4930,8 @@ export class Style {
|
|
|
4696
4930
|
}
|
|
4697
4931
|
}
|
|
4698
4932
|
this.commitState(StateKeys.OVERFLOW);
|
|
4933
|
+
if (__WINDOWS__)
|
|
4934
|
+
this.windowsReapplyGradient();
|
|
4699
4935
|
}
|
|
4700
4936
|
get overflowX() {
|
|
4701
4937
|
switch (getInt8(this.style_view, StyleKeys.OVERFLOW_X)) {
|
|
@@ -4713,6 +4949,8 @@ export class Style {
|
|
|
4713
4949
|
this.prepareMut();
|
|
4714
4950
|
setInt8(this.style_view, StyleKeys.OVERFLOW_X, v);
|
|
4715
4951
|
this.commitState(StateKeys.OVERFLOW_X);
|
|
4952
|
+
if (__WINDOWS__)
|
|
4953
|
+
this.windowsReapplyGradient();
|
|
4716
4954
|
}
|
|
4717
4955
|
}
|
|
4718
4956
|
get overflowY() {
|
|
@@ -4735,6 +4973,8 @@ export class Style {
|
|
|
4735
4973
|
this.prepareMut();
|
|
4736
4974
|
setInt8(this.style_view, StyleKeys.OVERFLOW_Y, v);
|
|
4737
4975
|
this.commitState(StateKeys.OVERFLOW_Y);
|
|
4976
|
+
if (__WINDOWS__)
|
|
4977
|
+
this.windowsReapplyGradient();
|
|
4738
4978
|
}
|
|
4739
4979
|
}
|
|
4740
4980
|
get flexGrow() {
|
|
@@ -4787,8 +5027,9 @@ export class Style {
|
|
|
4787
5027
|
}
|
|
4788
5028
|
set letterSpacing(value) {
|
|
4789
5029
|
if (typeof value === 'string') {
|
|
5030
|
+
const t = value.trim();
|
|
4790
5031
|
this.prepareMut();
|
|
4791
|
-
setFloat32(this.style_view, StyleKeys.LETTER_SPACING, tokenToDevicePx(
|
|
5032
|
+
setFloat32(this.style_view, StyleKeys.LETTER_SPACING, t === 'normal' ? 0 : finite(tokenToDevicePx(t, parseFloat(t) || 0, this.emBasisFor(t))));
|
|
4792
5033
|
setUint8(this.style_view, StyleKeys.LETTER_SPACING_STATE, 1);
|
|
4793
5034
|
this.commitState(StateKeys.LETTER_SPACING);
|
|
4794
5035
|
}
|
|
@@ -4821,12 +5062,18 @@ export class Style {
|
|
|
4821
5062
|
set lineHeight(value) {
|
|
4822
5063
|
if (typeof value === 'string') {
|
|
4823
5064
|
const t = value.trim();
|
|
5065
|
+
if (t === 'normal') {
|
|
5066
|
+
this.prepareMut();
|
|
5067
|
+
setUint8(this.style_view, StyleKeys.LINE_HEIGHT_STATE, 0);
|
|
5068
|
+
this.commitState(StateKeys.LINE_HEIGHT);
|
|
5069
|
+
return;
|
|
5070
|
+
}
|
|
4824
5071
|
// A unitless line-height is a multiplier (`line-height: 1.5`), not a
|
|
4825
5072
|
// length — TYPE 0 means "multiply by the resolved font size".
|
|
4826
5073
|
const unitless = /^-?[\d.]+$/.test(t);
|
|
4827
5074
|
this.prepareMut();
|
|
4828
5075
|
// An absolute line-height is stored in CSS px (iOS points, Android dip), as the number path.
|
|
4829
|
-
setFloat32(this.style_view, StyleKeys.LINE_HEIGHT, unitless ? finite(parseFloat(t) || 0) : layout.toDeviceIndependentPixels(tokenToDevicePx(t, parseFloat(t) || 0)));
|
|
5076
|
+
setFloat32(this.style_view, StyleKeys.LINE_HEIGHT, unitless ? finite(parseFloat(t) || 0) : finite(layout.toDeviceIndependentPixels(tokenToDevicePx(t, parseFloat(t) || 0, this.emBasisFor(t)))));
|
|
4830
5077
|
setUint8(this.style_view, StyleKeys.LINE_HEIGHT_STATE, 1);
|
|
4831
5078
|
setUint8(this.style_view, StyleKeys.LINE_HEIGHT_TYPE, unitless ? 0 : 1);
|
|
4832
5079
|
this.commitState(StateKeys.LINE_HEIGHT);
|
|
@@ -4902,7 +5149,7 @@ export class Style {
|
|
|
4902
5149
|
// clip ?
|
|
4903
5150
|
return 'start';
|
|
4904
5151
|
}
|
|
4905
|
-
const type =
|
|
5152
|
+
const type = getInt8(this.style_view, StyleKeys.TEXT_ALIGN);
|
|
4906
5153
|
switch (type) {
|
|
4907
5154
|
case 0:
|
|
4908
5155
|
// auto
|
|
@@ -4952,7 +5199,7 @@ export class Style {
|
|
|
4952
5199
|
}
|
|
4953
5200
|
if (align !== -1) {
|
|
4954
5201
|
this.prepareMut();
|
|
4955
|
-
|
|
5202
|
+
setInt8(this.style_view, StyleKeys.TEXT_ALIGN, align);
|
|
4956
5203
|
setInt8(this.style_view, StyleKeys.TEXT_ALIGN_STATE, 1);
|
|
4957
5204
|
this.commitState(StateKeys.TEXT_ALIGN);
|
|
4958
5205
|
}
|
|
@@ -6303,6 +6550,21 @@ export class Style {
|
|
|
6303
6550
|
setFloat32(this.style_view, StyleKeys.TRANSFORM_ORIGIN_Y_VALUE, parsed.y);
|
|
6304
6551
|
setUint8(this.style_view, StyleKeys.TRANSFORM_ORIGIN_STATE, 1);
|
|
6305
6552
|
this.commitState(StateKeys.TRANSFORM_ORIGIN);
|
|
6553
|
+
// Windows applies the origin with the transform, natively it isn't read from the buffer.
|
|
6554
|
+
if (__WINDOWS__)
|
|
6555
|
+
this.view?._applyWindowsTransform?.();
|
|
6556
|
+
}
|
|
6557
|
+
/** transform-origin as fractions of a `width` x `height` box, or null when it isn't set. */
|
|
6558
|
+
transformOriginFraction(width, height) {
|
|
6559
|
+
if (!this.style_view || !getUint8(this.style_view, StyleKeys.TRANSFORM_ORIGIN_STATE))
|
|
6560
|
+
return null;
|
|
6561
|
+
const side = (typeKey, valueKey, size) => {
|
|
6562
|
+
const value = getFloat32(this.style_view, valueKey);
|
|
6563
|
+
if (getUint8(this.style_view, typeKey) === 1)
|
|
6564
|
+
return value / 100;
|
|
6565
|
+
return size > 0 ? layout.toDeviceIndependentPixels(value) / size : 0;
|
|
6566
|
+
};
|
|
6567
|
+
return { x: side(StyleKeys.TRANSFORM_ORIGIN_X_TYPE, StyleKeys.TRANSFORM_ORIGIN_X_VALUE, width), y: side(StyleKeys.TRANSFORM_ORIGIN_Y_TYPE, StyleKeys.TRANSFORM_ORIGIN_Y_VALUE, height) };
|
|
6306
6568
|
}
|
|
6307
6569
|
set 'transform-origin'(value) {
|
|
6308
6570
|
this.transformOrigin = value;
|
|
@@ -6852,4 +7114,54 @@ export class Style {
|
|
|
6852
7114
|
};
|
|
6853
7115
|
}
|
|
6854
7116
|
}
|
|
7117
|
+
{
|
|
7118
|
+
const proto = Style.prototype;
|
|
7119
|
+
const names = Object.getOwnPropertyNames(proto);
|
|
7120
|
+
for (let i = 0; i < names.length; i++) {
|
|
7121
|
+
const name = names[i];
|
|
7122
|
+
const descriptor = Object.getOwnPropertyDescriptor(proto, name);
|
|
7123
|
+
const set = descriptor?.set;
|
|
7124
|
+
if (!set)
|
|
7125
|
+
continue;
|
|
7126
|
+
Object.defineProperty(proto, name, {
|
|
7127
|
+
...descriptor,
|
|
7128
|
+
set(value) {
|
|
7129
|
+
beginStyleWrite(this, name, value);
|
|
7130
|
+
try {
|
|
7131
|
+
set.call(this, value);
|
|
7132
|
+
}
|
|
7133
|
+
finally {
|
|
7134
|
+
endStyleWrite();
|
|
7135
|
+
}
|
|
7136
|
+
},
|
|
7137
|
+
});
|
|
7138
|
+
}
|
|
7139
|
+
}
|
|
7140
|
+
/** `grid-auto-flow` as its buffer value: `row`/`column` and `dense`, in either order. */
|
|
7141
|
+
export function gridAutoFlowFromString(value) {
|
|
7142
|
+
if (typeof value !== 'string') {
|
|
7143
|
+
return undefined;
|
|
7144
|
+
}
|
|
7145
|
+
const tokens = value.trim().toLowerCase().split(/\s+/);
|
|
7146
|
+
if (tokens.length === 0 || tokens.length > 2 || new Set(tokens).size !== tokens.length) {
|
|
7147
|
+
return undefined;
|
|
7148
|
+
}
|
|
7149
|
+
let column = false;
|
|
7150
|
+
let dense = false;
|
|
7151
|
+
for (const token of tokens) {
|
|
7152
|
+
if (token === 'dense') {
|
|
7153
|
+
dense = true;
|
|
7154
|
+
}
|
|
7155
|
+
else if (token === 'column') {
|
|
7156
|
+
column = true;
|
|
7157
|
+
}
|
|
7158
|
+
else if (token !== 'row') {
|
|
7159
|
+
return undefined;
|
|
7160
|
+
}
|
|
7161
|
+
}
|
|
7162
|
+
if (tokens.length === 2 && !dense) {
|
|
7163
|
+
return undefined;
|
|
7164
|
+
}
|
|
7165
|
+
return (column ? 1 : 0) + (dense ? 2 : 0);
|
|
7166
|
+
}
|
|
6855
7167
|
//# sourceMappingURL=style.js.map
|