@octane-xplat/nativescript-mason-core 0.0.1 → 1.0.0-beta.1

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 (194) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +198 -2
  3. package/artifact-inventory.json +774 -0
  4. package/box-shadow.d.ts +10 -0
  5. package/box-shadow.js +48 -0
  6. package/common.d.ts +485 -0
  7. package/common.js +2659 -0
  8. package/css-colors.d.ts +17 -0
  9. package/css-colors.js +54 -0
  10. package/css-environment.d.ts +49 -0
  11. package/css-environment.js +309 -0
  12. package/css-filter.d.ts +17 -0
  13. package/css-filter.js +140 -0
  14. package/css-keyframes.d.ts +41 -0
  15. package/css-keyframes.js +437 -0
  16. package/css-math.d.ts +34 -0
  17. package/css-math.js +300 -0
  18. package/css-shorthands.d.ts +65 -0
  19. package/css-shorthands.js +673 -0
  20. package/css-transform.d.ts +6 -0
  21. package/css-transform.js +100 -0
  22. package/diagnostics.d.ts +51 -0
  23. package/diagnostics.js +52 -0
  24. package/display-density.d.ts +9 -0
  25. package/display-density.js +20 -0
  26. package/fonts.d.ts +20 -0
  27. package/fonts.js +88 -0
  28. package/foreign-layout.d.ts +6 -0
  29. package/foreign-layout.js +151 -0
  30. package/gradient-stops.d.ts +25 -0
  31. package/gradient-stops.js +112 -0
  32. package/index.android.d.ts +11 -0
  33. package/index.android.js +9 -0
  34. package/index.d.ts +12 -0
  35. package/index.ios.d.ts +11 -0
  36. package/index.ios.js +9 -0
  37. package/ios-host-README.md +124 -0
  38. package/layout-types.d.ts +192 -0
  39. package/mask.d.ts +54 -0
  40. package/mask.js +26 -0
  41. package/native-environment.android.d.ts +3 -0
  42. package/native-environment.android.js +69 -0
  43. package/native-environment.d.ts +3 -0
  44. package/native-environment.ios.d.ts +3 -0
  45. package/native-environment.ios.js +65 -0
  46. package/native-types-README.md +51 -0
  47. package/package.json +47 -6
  48. package/panel-helpers.d.ts +3 -0
  49. package/panel-helpers.js +8 -0
  50. package/platforms/android/MasonCore.aar +0 -0
  51. package/platforms/android/include.gradle +6 -0
  52. package/platforms/android/manifest.json +73 -0
  53. package/platforms/ios/FontManager.LICENSE +201 -0
  54. package/platforms/ios/MasonCore.xcframework/Info.plist +43 -0
  55. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Headers/Mason.h +25 -0
  56. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Headers/MasonCore-Swift.h +1739 -0
  57. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Headers/mason_native.h +601 -0
  58. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Info.plist +0 -0
  59. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/MasonCore +0 -0
  60. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Modules/MasonCore.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  61. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios.abi.json +100095 -0
  62. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios.private.swiftinterface +3174 -0
  63. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  64. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios.swiftinterface +3174 -0
  65. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/Modules/module.modulemap +9 -0
  66. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/SDWebImage_SDWebImage.bundle/Info.plist +0 -0
  67. package/platforms/ios/MasonCore.xcframework/ios-arm64/MasonCore.framework/SDWebImage_SDWebImage.bundle/PrivacyInfo.xcprivacy +23 -0
  68. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Headers/Mason.h +25 -0
  69. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Headers/MasonCore-Swift.h +1739 -0
  70. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Headers/mason_native.h +601 -0
  71. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Info.plist +0 -0
  72. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/MasonCore +0 -0
  73. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Modules/MasonCore.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
  74. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios-simulator.abi.json +100095 -0
  75. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +3174 -0
  76. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  77. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Modules/MasonCore.swiftmodule/arm64-apple-ios-simulator.swiftinterface +3174 -0
  78. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/Modules/module.modulemap +9 -0
  79. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/SDWebImage_SDWebImage.bundle/Info.plist +0 -0
  80. package/platforms/ios/MasonCore.xcframework/ios-arm64-simulator/MasonCore.framework/SDWebImage_SDWebImage.bundle/PrivacyInfo.xcprivacy +23 -0
  81. package/platforms/ios/Package.resolved +24 -0
  82. package/platforms/ios/SDWebImage.LICENSE +20 -0
  83. package/platforms/ios/build.xcconfig +4 -0
  84. package/platforms/ios/device-manifest.json +213 -0
  85. package/platforms/ios/include/FontManager/NSCFontDescriptors.h +36 -0
  86. package/platforms/ios/include/FontManager/NSCFontFace.h +98 -0
  87. package/platforms/ios/include/FontManager/NSCFontFaceSet.h +73 -0
  88. package/platforms/ios/include/FontManager/NSCFontManagerUmbrella.h +7 -0
  89. package/platforms/ios/include/FontManager/NSCFontParser.h +22 -0
  90. package/platforms/ios/include/FontManager/NSCFontRegex.h +4 -0
  91. package/platforms/ios/include/FontManager/NSCFontResolver.h +43 -0
  92. package/platforms/ios/include/FontManager/NSCFontStyle.h +27 -0
  93. package/platforms/ios/include/FontManager/NSCFontTypes.h +41 -0
  94. package/platforms/ios/include/SDWebImage/NSButton+WebCache.h +340 -0
  95. package/platforms/ios/include/SDWebImage/NSData+ImageContentType.h +63 -0
  96. package/platforms/ios/include/SDWebImage/NSImage+Compatibility.h +67 -0
  97. package/platforms/ios/include/SDWebImage/SDAnimatedImage.h +136 -0
  98. package/platforms/ios/include/SDWebImage/SDAnimatedImagePlayer.h +113 -0
  99. package/platforms/ios/include/SDWebImage/SDAnimatedImageRep.h +33 -0
  100. package/platforms/ios/include/SDWebImage/SDAnimatedImageView+WebCache.h +168 -0
  101. package/platforms/ios/include/SDWebImage/SDAnimatedImageView.h +125 -0
  102. package/platforms/ios/include/SDWebImage/SDCallbackQueue.h +59 -0
  103. package/platforms/ios/include/SDWebImage/SDDiskCache.h +146 -0
  104. package/platforms/ios/include/SDWebImage/SDGraphicsImageRenderer.h +84 -0
  105. package/platforms/ios/include/SDWebImage/SDImageAPNGCoder.h +19 -0
  106. package/platforms/ios/include/SDWebImage/SDImageAWebPCoder.h +23 -0
  107. package/platforms/ios/include/SDWebImage/SDImageCache.h +482 -0
  108. package/platforms/ios/include/SDWebImage/SDImageCacheConfig.h +153 -0
  109. package/platforms/ios/include/SDWebImage/SDImageCacheDefine.h +179 -0
  110. package/platforms/ios/include/SDWebImage/SDImageCachesManager.h +81 -0
  111. package/platforms/ios/include/SDWebImage/SDImageCoder.h +347 -0
  112. package/platforms/ios/include/SDWebImage/SDImageCoderHelper.h +251 -0
  113. package/platforms/ios/include/SDWebImage/SDImageCodersManager.h +58 -0
  114. package/platforms/ios/include/SDWebImage/SDImageFrame.h +44 -0
  115. package/platforms/ios/include/SDWebImage/SDImageGIFCoder.h +22 -0
  116. package/platforms/ios/include/SDWebImage/SDImageGraphics.h +28 -0
  117. package/platforms/ios/include/SDWebImage/SDImageHEICCoder.h +25 -0
  118. package/platforms/ios/include/SDWebImage/SDImageIOAnimatedCoder.h +65 -0
  119. package/platforms/ios/include/SDWebImage/SDImageIOCoder.h +30 -0
  120. package/platforms/ios/include/SDWebImage/SDImageLoader.h +146 -0
  121. package/platforms/ios/include/SDWebImage/SDImageLoadersManager.h +40 -0
  122. package/platforms/ios/include/SDWebImage/SDImageTransformer.h +283 -0
  123. package/platforms/ios/include/SDWebImage/SDMemoryCache.h +78 -0
  124. package/platforms/ios/include/SDWebImage/SDWebImage.h +91 -0
  125. package/platforms/ios/include/SDWebImage/SDWebImageCacheKeyFilter.h +35 -0
  126. package/platforms/ios/include/SDWebImage/SDWebImageCacheSerializer.h +39 -0
  127. package/platforms/ios/include/SDWebImage/SDWebImageCompat.h +102 -0
  128. package/platforms/ios/include/SDWebImage/SDWebImageDefine.h +420 -0
  129. package/platforms/ios/include/SDWebImage/SDWebImageDownloader.h +320 -0
  130. package/platforms/ios/include/SDWebImage/SDWebImageDownloaderConfig.h +113 -0
  131. package/platforms/ios/include/SDWebImage/SDWebImageDownloaderDecryptor.h +52 -0
  132. package/platforms/ios/include/SDWebImage/SDWebImageDownloaderOperation.h +191 -0
  133. package/platforms/ios/include/SDWebImage/SDWebImageDownloaderRequestModifier.h +72 -0
  134. package/platforms/ios/include/SDWebImage/SDWebImageDownloaderResponseModifier.h +72 -0
  135. package/platforms/ios/include/SDWebImage/SDWebImageError.h +33 -0
  136. package/platforms/ios/include/SDWebImage/SDWebImageIndicator.h +119 -0
  137. package/platforms/ios/include/SDWebImage/SDWebImageManager.h +290 -0
  138. package/platforms/ios/include/SDWebImage/SDWebImageOperation.h +27 -0
  139. package/platforms/ios/include/SDWebImage/SDWebImageOptionsProcessor.h +78 -0
  140. package/platforms/ios/include/SDWebImage/SDWebImagePrefetcher.h +168 -0
  141. package/platforms/ios/include/SDWebImage/SDWebImageTransition.h +131 -0
  142. package/platforms/ios/include/SDWebImage/UIButton+WebCache.h +402 -0
  143. package/platforms/ios/include/SDWebImage/UIImage+ExtendedCacheData.h +24 -0
  144. package/platforms/ios/include/SDWebImage/UIImage+ForceDecode.h +52 -0
  145. package/platforms/ios/include/SDWebImage/UIImage+GIF.h +26 -0
  146. package/platforms/ios/include/SDWebImage/UIImage+MemoryCacheCost.h +27 -0
  147. package/platforms/ios/include/SDWebImage/UIImage+Metadata.h +104 -0
  148. package/platforms/ios/include/SDWebImage/UIImage+MultiFormat.h +81 -0
  149. package/platforms/ios/include/SDWebImage/UIImage+Transform.h +164 -0
  150. package/platforms/ios/include/SDWebImage/UIImageView+HighlightedWebCache.h +142 -0
  151. package/platforms/ios/include/SDWebImage/UIImageView+WebCache.h +209 -0
  152. package/platforms/ios/include/SDWebImage/UIView+WebCache.h +131 -0
  153. package/platforms/ios/include/SDWebImage/UIView+WebCacheOperation.h +52 -0
  154. package/platforms/ios/include/SDWebImage/UIView+WebCacheState.h +63 -0
  155. package/platforms/ios/include/module.modulemap +2 -0
  156. package/platforms/ios/manifest.json +132 -0
  157. package/platforms/ios/simulator-manifest.json +213 -0
  158. package/plugin-README.md +234 -0
  159. package/properties.d.ts +154 -0
  160. package/properties.js +2456 -0
  161. package/pseudo.d.ts +9 -0
  162. package/pseudo.js +57 -0
  163. package/scroll/index.android.d.ts +15 -0
  164. package/scroll/index.android.js +72 -0
  165. package/scroll/index.d.ts +5 -0
  166. package/scroll/index.ios.d.ts +18 -0
  167. package/scroll/index.ios.js +106 -0
  168. package/style.d.ts +768 -0
  169. package/style.js +7167 -0
  170. package/symbols.d.ts +25 -0
  171. package/symbols.js +41 -0
  172. package/tree/index.android.d.ts +11 -0
  173. package/tree/index.android.js +42 -0
  174. package/tree/index.d.ts +15 -0
  175. package/tree/index.ios.d.ts +26 -0
  176. package/tree/index.ios.js +53 -0
  177. package/typings/android-declarations.d.ts +4 -0
  178. package/typings/android.d.ts +9730 -0
  179. package/typings/manifest.json +45 -0
  180. package/typings/native.d.ts +5 -0
  181. package/typings/objc!FontManager.d.ts +389 -0
  182. package/typings/objc!MasonCore.d.ts +2472 -0
  183. package/typings/objc!SDWebImage.d.ts +3378 -0
  184. package/units.d.ts +29 -0
  185. package/units.js +44 -0
  186. package/utils/index.android.d.ts +211 -0
  187. package/utils/index.android.js +595 -0
  188. package/utils/index.ios.d.ts +222 -0
  189. package/utils/index.ios.js +790 -0
  190. package/view/index.android.d.ts +13 -0
  191. package/view/index.android.js +74 -0
  192. package/view/index.d.ts +2 -0
  193. package/view/index.ios.d.ts +24 -0
  194. package/view/index.ios.js +157 -0
package/properties.js ADDED
@@ -0,0 +1,2456 @@
1
+ import { environmentStyleValue, cssEnvironmentShorthand } from './css-environment';
2
+ import { CssProperty, CssAnimationProperty, InheritedCssProperty, backgroundColorProperty, Style, ShorthandProperty, Length as CoreLength, fontSizeProperty, textAlignmentProperty, textDecorationProperty, textTransformProperty, PercentLength as CorePercentLength, Trace, CoreTypes, unsetValue, verticalAlignmentProperty, textShadowProperty, Font, Property, makeParser, makeValidator, marginTopProperty, marginRightProperty, marginBottomProperty, marginLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, minWidthProperty, minHeightProperty, widthProperty, heightProperty, lineHeightProperty, letterSpacingProperty, } from '@nativescript/core';
3
+ import { isMasonView_, touchAction_ } from './symbols';
4
+ /** Marks a Style whose size accessors already resolve Mason's units. */
5
+ const MASON_SIZE_UNITS = Symbol('mason:size-units');
6
+ import { beginStyleWrite, cssLengthToDip, endStyleWrite, isSizingKeyword, parseAspectRatio } from './style';
7
+ import { isCssMathFunction } from './css-math';
8
+ import { alignItemsProperty, alignSelfProperty, flexDirectionProperty, flexGrowProperty, flexShrinkProperty, flexWrapProperty, justifyContentProperty } from '@nativescript/core/ui/layouts/flexbox-layout';
9
+ import { parseCSSShadow } from '@nativescript/core/ui/styling/css-shadow';
10
+ import { installKeyframes, interpolatePositionList, interpolateSizeList, registerKeyframeProperty } from './css-keyframes';
11
+ import { borderTopLeftRadiusProperty, borderTopRightRadiusProperty, borderBottomRightRadiusProperty, borderBottomLeftRadiusProperty, borderTopColorProperty, borderRightColorProperty, borderBottomColorProperty, borderLeftColorProperty } from '@nativescript/core/ui/styling/style-properties';
12
+ import { BORDER_WIDTH_KEYWORDS, passThrough, splitBorder, splitBorderSide, splitBorderStyle, splitBorderStyleStartEnd, splitBorderWidthStartEnd, splitBorderColorStartEnd, splitInsetStartEnd, splitMarginStartEnd, splitPaddingStartEnd, splitBackground, splitMask, splitMaskBorder, splitWebkitMask, webkitMaskBox, webkitMaskComposite, splitBorderColor, splitBorderRadius, splitBorderWidth, splitFlex, splitFlexFlow, splitGap, splitMargin, splitOverflow, splitPadding } from './css-shorthands';
13
+ import { cssLength, isCssLength, toCamelCase } from './css-shorthands';
14
+ import { splitListStyle, splitPlace } from './css-shorthands';
15
+ function getViewStyle(view) {
16
+ const ret = (__ANDROID__ ? view?.get() : view?.deref());
17
+ // Undefined for a plain NativeScript view (and for a cleared ref): only mason's
18
+ // own view classes define `_styleHelper`.
19
+ return ret?._styleHelper;
20
+ }
21
+ /** Mason views write these in setNative, which core runs after valueChanged; one write is enough. */
22
+ function appliedInSetNative(target, property) {
23
+ const ref = target?.viewRef;
24
+ const view = ref ? (__ANDROID__ ? ref.get() : ref.deref()) : undefined;
25
+ return !!(view && view[isMasonView_] && view[property.setNative]);
26
+ }
27
+ // Mason parses CSS values itself, so for its own elements the raw declaration is
28
+ // passed straight through; anything else has to go through core's parser first.
29
+ //
30
+ // This asks specifically whether the view *is* a mason element, not whether it
31
+ // sits inside one. A plain NativeScript view parented into a mason tree has no
32
+ // mason style buffer — its value still has to be converted for core, or core's
33
+ // own setNative gets a string it can't use. See "Mixing with plain NativeScript
34
+ // views" in MASON_CONTEXT.md.
35
+ //
36
+ // `isMasonView_` is a plain marker set in the mason view constructors. Don't
37
+ // reach for `_styleHelper` here: its getter lazily builds the native view, and a
38
+ // valueConverter can run long before that should happen.
39
+ function isMasonView(style) {
40
+ if (style && style.viewRef) {
41
+ const view = __ANDROID__ ? style.viewRef.get() : style.viewRef.deref();
42
+ return !!(view && view[isMasonView_]);
43
+ }
44
+ return false;
45
+ }
46
+ const CSS_WIDE_KEYWORDS = new Set(['initial', 'inherit', 'unset', 'revert']);
47
+ export function shorthandConverter({ cssName, longhands, split }) {
48
+ return (value) => {
49
+ const text = typeof value === 'number' ? String(value) : value;
50
+ if (typeof text !== 'string') {
51
+ // Core 9.1 probes with unsetValue to learn the longhands, which a var()
52
+ // declaration needs all of.
53
+ return longhands.map((property) => [property, value]);
54
+ }
55
+ const trimmed = text.trim();
56
+ if (!trimmed || CSS_WIDE_KEYWORDS.has(trimmed)) {
57
+ return longhands.map((property) => [property, trimmed]);
58
+ }
59
+ const parts = (['padding', 'margin', 'border-width'].includes(cssName) &&
60
+ cssEnvironmentShorthand(trimmed, split, longhands.length)) || split(trimmed);
61
+ return longhands.map((property, i) => [property, parts[i]]);
62
+ };
63
+ }
64
+ function masonShorthandProperty(entry, getter = () => undefined) {
65
+ return new ShorthandProperty({
66
+ name: toCamelCase(entry.cssName),
67
+ cssName: entry.cssName,
68
+ getter,
69
+ converter: shorthandConverter(entry),
70
+ });
71
+ }
72
+ export const textProperty = new Property({
73
+ name: 'text',
74
+ });
75
+ export const displayProperty = new CssProperty({
76
+ name: 'display',
77
+ cssName: 'display',
78
+ defaultValue: 'block',
79
+ valueChanged: (target, oldValue, newValue) => {
80
+ if (appliedInSetNative(target, displayProperty))
81
+ return;
82
+ const view = getViewStyle(target.viewRef);
83
+ if (view && newValue) {
84
+ view.display = newValue;
85
+ }
86
+ },
87
+ valueConverter: function (value) {
88
+ if (typeof value === 'number') {
89
+ switch (value) {
90
+ case 0:
91
+ return 'none';
92
+ case 1:
93
+ return 'flex';
94
+ case 2:
95
+ return 'grid';
96
+ case 3:
97
+ return 'block';
98
+ case 4:
99
+ return 'inline';
100
+ case 5:
101
+ return 'inline-block';
102
+ case 6:
103
+ return 'inline-flex';
104
+ case 7:
105
+ return 'inline-grid';
106
+ }
107
+ }
108
+ switch (value) {
109
+ case 'none':
110
+ case 'flex':
111
+ case 'grid':
112
+ case 'block':
113
+ case 'inline':
114
+ case 'inline-block':
115
+ case 'inline-flex':
116
+ case 'inline-grid':
117
+ return value;
118
+ // The legacy boxes `line-clamp` utilities ask for.
119
+ case '-webkit-box':
120
+ return 'block';
121
+ case '-webkit-inline-box':
122
+ return 'inline-block';
123
+ default:
124
+ return undefined;
125
+ }
126
+ },
127
+ });
128
+ export const filterProperty = new CssProperty({
129
+ name: 'filter',
130
+ cssName: 'filter',
131
+ });
132
+ export const borderColorProperty = new CssProperty({
133
+ name: 'borderColor',
134
+ cssName: 'border-color',
135
+ });
136
+ export const backgroundProperty = new CssProperty({
137
+ name: 'background',
138
+ cssName: 'background',
139
+ });
140
+ export const backgroundImageProperty = new CssProperty({
141
+ name: 'backgroundImage',
142
+ cssName: 'background-image',
143
+ });
144
+ export const backgroundRepeatProperty = new CssProperty({
145
+ name: 'backgroundRepeat',
146
+ cssName: 'background-repeat',
147
+ valueChanged(target, oldValue, newValue) {
148
+ const view = getViewStyle(target.viewRef);
149
+ if (view) {
150
+ view.backgroundRepeat = newValue;
151
+ }
152
+ },
153
+ });
154
+ export const backgroundPositionProperty = new CssProperty({
155
+ name: 'backgroundPosition',
156
+ cssName: 'background-position',
157
+ valueChanged(target, oldValue, newValue) {
158
+ const view = getViewStyle(target.viewRef);
159
+ if (view) {
160
+ view.backgroundPosition = newValue;
161
+ }
162
+ },
163
+ });
164
+ export const backgroundSizeProperty = new CssProperty({
165
+ name: 'backgroundSize',
166
+ cssName: 'background-size',
167
+ valueChanged(target, oldValue, newValue) {
168
+ const view = getViewStyle(target.viewRef);
169
+ if (view) {
170
+ view.backgroundSize = newValue;
171
+ }
172
+ },
173
+ });
174
+ export const backgroundClipProperty = new CssProperty({
175
+ name: 'backgroundClip',
176
+ cssName: 'background-clip',
177
+ valueChanged(target, oldValue, newValue) {
178
+ const view = getViewStyle(target.viewRef);
179
+ if (view) {
180
+ view.backgroundClip = newValue;
181
+ }
182
+ },
183
+ });
184
+ function overflowConverter(value) {
185
+ if (typeof value === 'number') {
186
+ switch (value) {
187
+ case 0:
188
+ return 'visible';
189
+ case 1:
190
+ return 'clip';
191
+ case 2:
192
+ return 'hidden';
193
+ case 3:
194
+ return 'scroll';
195
+ }
196
+ }
197
+ switch (value) {
198
+ case 'visible':
199
+ case 'hidden':
200
+ case 'clip':
201
+ case 'scroll':
202
+ case 'auto':
203
+ return value;
204
+ default:
205
+ return undefined;
206
+ }
207
+ }
208
+ export const overflowXProperty = new CssProperty({
209
+ name: 'overflowX',
210
+ cssName: 'overflow-x',
211
+ defaultValue: 'visible',
212
+ valueConverter: overflowConverter,
213
+ valueChanged: (target, oldValue, newValue) => {
214
+ if (newValue && appliedInSetNative(target, overflowXProperty))
215
+ return;
216
+ const view = getViewStyle(target.viewRef);
217
+ if (view) {
218
+ if (newValue) {
219
+ view.overflowX = newValue;
220
+ }
221
+ else {
222
+ // Revert to old value if newValue is invalid
223
+ target.overflowX = oldValue;
224
+ }
225
+ }
226
+ },
227
+ });
228
+ export const overflowYProperty = new CssProperty({
229
+ name: 'overflowY',
230
+ cssName: 'overflow-y',
231
+ defaultValue: 'visible',
232
+ valueConverter: overflowConverter,
233
+ valueChanged(target, oldValue, newValue) {
234
+ if (newValue && appliedInSetNative(target, overflowYProperty))
235
+ return;
236
+ const view = getViewStyle(target.viewRef);
237
+ if (view) {
238
+ if (newValue) {
239
+ view.overflowY = newValue;
240
+ }
241
+ else {
242
+ // Revert to old value if newValue is invalid
243
+ target.overflowY = oldValue;
244
+ }
245
+ }
246
+ },
247
+ });
248
+ const overflowShorthand = { cssName: 'overflow', longhands: [overflowXProperty, overflowYProperty], split: splitOverflow };
249
+ export const overflowProperty = masonShorthandProperty(overflowShorthand, function () {
250
+ if (this.overflowX === this.overflowY) {
251
+ return this.overflowX;
252
+ }
253
+ return `${this.overflowX} ${this.overflowY}`;
254
+ });
255
+ export const paddingProperty = new CssProperty({
256
+ name: 'padding',
257
+ cssName: 'padding',
258
+ });
259
+ // These four style-buffer fields were consumed by the natives all along but had
260
+ // no JS or CSS path to them: reserved StyleKeys nobody ever wrote. Same shape of
261
+ // gap as `list-style-type`. (`text-indent` and `font-variant-numeric` are
262
+ // deliberately left out — their offsets exist but nothing reads them yet, so
263
+ // exposing them would write bytes into the void.)
264
+ export const whiteSpaceProperty = new CssProperty({
265
+ name: 'whiteSpace',
266
+ cssName: 'white-space',
267
+ defaultValue: 'normal',
268
+ valueChanged(target, oldValue, newValue) {
269
+ const view = getViewStyle(target.viewRef);
270
+ if (view) {
271
+ view.whiteSpace = newValue;
272
+ }
273
+ },
274
+ });
275
+ /**
276
+ * CSS `touch-action` as the pan flags native scroll views read: 1 = pan-x,
277
+ * 2 = pan-y, 4 = pinch-zoom. A Mason scroll view only starts a drag along an
278
+ * axis every element from the touched one up to it allows, as browsers do.
279
+ */
280
+ export function parseTouchAction(value) {
281
+ const v = String(value ?? 'auto')
282
+ .trim()
283
+ .toLowerCase();
284
+ if (v === 'auto' || v === '')
285
+ return 7;
286
+ if (v === 'none')
287
+ return 0;
288
+ if (v === 'manipulation')
289
+ return 7;
290
+ let flags = 0;
291
+ for (const part of v.split(/\s+/)) {
292
+ if (part === 'pan-x' || part === 'pan-left' || part === 'pan-right')
293
+ flags |= 1;
294
+ else if (part === 'pan-y' || part === 'pan-up' || part === 'pan-down')
295
+ flags |= 2;
296
+ else if (part === 'pinch-zoom')
297
+ flags |= 4;
298
+ }
299
+ return flags;
300
+ }
301
+ export const touchActionProperty = new CssProperty({
302
+ name: 'touchAction',
303
+ cssName: 'touch-action',
304
+ defaultValue: 'auto',
305
+ valueChanged(target, oldValue, newValue) {
306
+ const ref = target?.viewRef;
307
+ const view = ref ? (__ANDROID__ ? ref.get() : ref.deref()) : undefined;
308
+ if (view && view[isMasonView_]) {
309
+ view[touchAction_] = parseTouchAction(newValue);
310
+ view._applyTouchAction?.();
311
+ }
312
+ },
313
+ });
314
+ export const objectFitProperty = new CssProperty({
315
+ name: 'objectFit',
316
+ cssName: 'object-fit',
317
+ defaultValue: 'fill',
318
+ valueChanged(target, oldValue, newValue) {
319
+ const view = getViewStyle(target.viewRef);
320
+ if (view) {
321
+ view.objectFit = newValue;
322
+ }
323
+ },
324
+ });
325
+ export const textJustifyProperty = new CssProperty({
326
+ name: 'textJustify',
327
+ cssName: 'text-justify',
328
+ defaultValue: 'auto',
329
+ valueChanged(target, oldValue, newValue) {
330
+ const view = getViewStyle(target.viewRef);
331
+ if (view) {
332
+ view.textJustify = newValue;
333
+ }
334
+ },
335
+ });
336
+ export const backgroundPositionXProperty = new CssProperty({
337
+ name: 'backgroundPositionX',
338
+ cssName: 'background-position-x',
339
+ valueChanged(target, oldValue, newValue) {
340
+ const view = getViewStyle(target.viewRef);
341
+ if (view) {
342
+ view.backgroundPositionX = newValue;
343
+ }
344
+ },
345
+ });
346
+ export const backgroundPositionYProperty = new CssProperty({
347
+ name: 'backgroundPositionY',
348
+ cssName: 'background-position-y',
349
+ valueChanged(target, oldValue, newValue) {
350
+ const view = getViewStyle(target.viewRef);
351
+ if (view) {
352
+ view.backgroundPositionY = newValue;
353
+ }
354
+ },
355
+ });
356
+ export const backgroundOriginProperty = new CssProperty({
357
+ name: 'backgroundOrigin',
358
+ cssName: 'background-origin',
359
+ valueChanged(target, oldValue, newValue) {
360
+ const view = getViewStyle(target.viewRef);
361
+ if (view) {
362
+ view.backgroundOrigin = newValue;
363
+ }
364
+ },
365
+ });
366
+ export const backgroundAttachmentProperty = new CssProperty({
367
+ name: 'backgroundAttachment',
368
+ cssName: 'background-attachment',
369
+ valueChanged(target, oldValue, newValue) {
370
+ const view = getViewStyle(target.viewRef);
371
+ if (view) {
372
+ view.backgroundAttachment = newValue;
373
+ }
374
+ },
375
+ });
376
+ export const backgroundBlendModeProperty = new CssProperty({
377
+ name: 'backgroundBlendMode',
378
+ cssName: 'background-blend-mode',
379
+ valueChanged(target, oldValue, newValue) {
380
+ const view = getViewStyle(target.viewRef);
381
+ if (view) {
382
+ view.backgroundBlendMode = newValue;
383
+ }
384
+ },
385
+ });
386
+ export const textDecorationLineProperty = new CssProperty({
387
+ name: 'textDecorationLine',
388
+ cssName: 'text-decoration-line',
389
+ valueChanged(target, oldValue, newValue) {
390
+ const view = getViewStyle(target.viewRef);
391
+ if (view) {
392
+ view.textDecorationLine = newValue;
393
+ }
394
+ },
395
+ });
396
+ export const textDecorationStyleProperty = new CssProperty({
397
+ name: 'textDecorationStyle',
398
+ cssName: 'text-decoration-style',
399
+ valueChanged(target, oldValue, newValue) {
400
+ const view = getViewStyle(target.viewRef);
401
+ if (view) {
402
+ view.textDecorationStyle = newValue;
403
+ }
404
+ },
405
+ });
406
+ export const textDecorationColorProperty = new CssProperty({
407
+ name: 'textDecorationColor',
408
+ cssName: 'text-decoration-color',
409
+ valueChanged(target, oldValue, newValue) {
410
+ const view = getViewStyle(target.viewRef);
411
+ if (view) {
412
+ view.textDecorationColor = newValue;
413
+ }
414
+ },
415
+ });
416
+ export const textDecorationThicknessProperty = new CssProperty({
417
+ name: 'textDecorationThickness',
418
+ cssName: 'text-decoration-thickness',
419
+ valueChanged(target, oldValue, newValue) {
420
+ const view = getViewStyle(target.viewRef);
421
+ if (view) {
422
+ view.textDecorationThickness = newValue;
423
+ }
424
+ },
425
+ });
426
+ // `font-family` had no path at all: FONT_FAMILY_STATE exists with no value slot
427
+ // (the natives keep the family on a FontFace, not in the buffer), and core's
428
+ // fontInternalProperty.setNative hook in common.ts is Windows-only. So on both
429
+ // mobile platforms this was unsettable from CSS *and* from TS.
430
+ export const fontFamilyProperty = new CssProperty({
431
+ name: 'fontFamily',
432
+ cssName: 'font-family',
433
+ valueChanged(target, oldValue, newValue) {
434
+ const view = getViewStyle(target.viewRef);
435
+ if (view) {
436
+ view.fontFamily = newValue;
437
+ }
438
+ },
439
+ });
440
+ // ---------------------------------------------------------------------------
441
+ // Registering alongside @nativescript/core
442
+ // ---------------------------------------------------------------------------
443
+ //
444
+ // `CssProperty.register()` installs its accessors with Object.defineProperty, so
445
+ // for a CSS name core already owns the last registration wins outright — and
446
+ // masonkit registers after core. That silently shadowed core's handling of
447
+ // `margin`, `padding`, `background`, `background-*`, `border-color`,
448
+ // `border-radius`, `box-shadow`, `transform`, `vertical-align`, `text-overflow`,
449
+ // `align-content`, `flex` and `flex-flow` for **every view in the app**, mason's
450
+ // or not: a plain StackLayout with `margin: 10` in a stylesheet got nothing,
451
+ // because mason's property only implements setNative on mason's own ViewBase.
452
+ //
453
+ // So instead of replacing core's accessor, keep both and pick at assignment
454
+ // time: a mason view gets mason's, anything else keeps core's untouched.
455
+ // Foreign-only grid shorthands invert the selection to preserve existing Mason
456
+ // direct setters while foreign views use core's longhand priority machinery.
457
+ function registerAlongsideCore(property, target = 'mason') {
458
+ const proto = Style.prototype;
459
+ const keys = [property.name, property.cssName, property.cssLocalName].filter((key) => typeof key === 'string' && key.length > 0);
460
+ const core = new Map();
461
+ for (const key of keys) {
462
+ const descriptor = Object.getOwnPropertyDescriptor(proto, key);
463
+ if (descriptor)
464
+ core.set(key, descriptor);
465
+ }
466
+ property.register(Style);
467
+ for (const [key, coreDescriptor] of core) {
468
+ const masonDescriptor = Object.getOwnPropertyDescriptor(proto, key);
469
+ if (!masonDescriptor)
470
+ continue;
471
+ Object.defineProperty(proto, key, {
472
+ enumerable: masonDescriptor.enumerable ?? true,
473
+ configurable: true,
474
+ get() {
475
+ const descriptor = isMasonView(this) === (target === 'mason') ? masonDescriptor : coreDescriptor;
476
+ return descriptor.get?.call(this);
477
+ },
478
+ set(value) {
479
+ const descriptor = isMasonView(this) === (target === 'mason') ? masonDescriptor : coreDescriptor;
480
+ descriptor.set?.call(this, value);
481
+ },
482
+ });
483
+ }
484
+ }
485
+ registerAlongsideCore(paddingProperty);
486
+ export const marginProperty = new CssProperty({
487
+ name: 'margin',
488
+ cssName: 'margin',
489
+ });
490
+ export const scrollBarWidthProperty = new CssProperty({
491
+ name: 'scrollBarWidth',
492
+ cssName: 'scrollbar-width',
493
+ defaultValue: 0,
494
+ valueConverter: parseFloat,
495
+ });
496
+ // Core keeps these parsers private, so the fallbacks below have to restate them.
497
+ // The value lists mirror @nativescript/core exactly — flexbox-layout-common's
498
+ // FlexWrap and text-base-common's textAlignment/textTransform converters.
499
+ const FlexWrapParse = makeParser(makeValidator('nowrap', 'wrap', 'wrap-reverse'));
500
+ const FlexDirectionParse = makeParser(makeValidator('row', 'row-reverse', 'column', 'column-reverse'));
501
+ const TextAlignmentParse = makeParser(makeValidator('left', 'center', 'right', 'justify'));
502
+ const TextTransformParse = makeParser(makeValidator('none', 'capitalize', 'uppercase', 'lowercase'));
503
+ /**
504
+ * Narrow one of @nativescript/core's own properties so mason views get mason's
505
+ * handling and every other view keeps core's, untouched. `overrideHandlers`
506
+ * replaces core's handlers outright, so the fallback to core's own handling
507
+ * has to be named explicitly.
508
+ */
509
+ function overrideForMasonViews(property, options) {
510
+ const handlers = {
511
+ valueChanged(target, _oldValue, newValue) {
512
+ if (appliedInSetNative(target, property))
513
+ return;
514
+ const masonStyle = getViewStyle(target.viewRef);
515
+ // No mason style means a plain NativeScript view: core's setNative owns
516
+ // it, so leave the value exactly as core produced it.
517
+ if (!masonStyle) {
518
+ return;
519
+ }
520
+ options.apply(masonStyle, newValue);
521
+ },
522
+ };
523
+ if (options.coreConverter) {
524
+ handlers.valueConverter = function (value) {
525
+ // Mason parses CSS itself, so its own elements get the raw declaration.
526
+ return isMasonView(this) ? value : options.coreConverter(value);
527
+ };
528
+ }
529
+ property.overrideHandlers(handlers);
530
+ }
531
+ const rawDeclarations = new WeakMap();
532
+ /** Plain views keep core's number; a mason view also records the raw declaration so its units survive. */
533
+ function keepRawDeclarationForMasonViews(property, coreConverter) {
534
+ property.overrideHandlers({
535
+ valueConverter(value) {
536
+ const converted = coreConverter(value);
537
+ if (isMasonView(this)) {
538
+ let raw = rawDeclarations.get(this);
539
+ if (!raw) {
540
+ raw = new Map();
541
+ rawDeclarations.set(this, raw);
542
+ }
543
+ raw.set(property.name, { converted, raw: value });
544
+ }
545
+ return converted;
546
+ },
547
+ });
548
+ }
549
+ /** The declaration behind `value` if it came from this view's own CSS, else `value`. */
550
+ export function masonRawDeclaration(style, propertyName, value) {
551
+ const raw = rawDeclarations.get(style)?.get(propertyName);
552
+ if (!raw) {
553
+ return value;
554
+ }
555
+ if (Object.is(raw.converted, value)) {
556
+ return raw.raw;
557
+ }
558
+ rawDeclarations.get(style).delete(propertyName);
559
+ return value;
560
+ }
561
+ keepRawDeclarationForMasonViews(lineHeightProperty, (v) => parseFloat(v));
562
+ keepRawDeclarationForMasonViews(letterSpacingProperty, (v) => parseFloat(v));
563
+ overrideForMasonViews(flexDirectionProperty, {
564
+ coreConverter: FlexDirectionParse,
565
+ apply: (style, value) => {
566
+ style.flexDirection = value;
567
+ },
568
+ });
569
+ overrideForMasonViews(flexWrapProperty, {
570
+ coreConverter: FlexWrapParse,
571
+ apply: (style, value) => {
572
+ style.flexWrap = value;
573
+ },
574
+ });
575
+ flexGrowProperty.overrideHandlers({
576
+ name: 'flexGrow',
577
+ cssName: 'flex-grow',
578
+ valueChanged(target, oldValue, newValue) {
579
+ if (typeof newValue === 'number' && !isNaN(newValue) && appliedInSetNative(target, flexGrowProperty))
580
+ return;
581
+ const view = getViewStyle(target.viewRef);
582
+ if (view) {
583
+ // 0 is a valid flex-grow; don't treat it as falsy/invalid
584
+ if (typeof newValue === 'number' && !isNaN(newValue)) {
585
+ view.flexGrow = newValue;
586
+ }
587
+ else {
588
+ // Revert to old value if newValue is invalid
589
+ // @ts-ignore
590
+ target.flexGrow = oldValue;
591
+ }
592
+ }
593
+ },
594
+ });
595
+ fontSizeProperty.overrideHandlers({
596
+ name: 'fontSize',
597
+ cssName: 'font-size',
598
+ valueConverter: function (value) {
599
+ if (isMasonView(this)) {
600
+ return value;
601
+ }
602
+ return parseFloat(value);
603
+ },
604
+ valueChanged(target, oldValue, newValue) {
605
+ if (newValue && appliedInSetNative(target, fontSizeProperty))
606
+ return;
607
+ const view = getViewStyle(target.viewRef);
608
+ if (view) {
609
+ if (newValue) {
610
+ if (typeof newValue === 'string') {
611
+ // @ts-ignore
612
+ if (isCssMathFunction(newValue)) {
613
+ // Mason's setter evaluates calc()/min()/max()/clamp() itself.
614
+ view.fontSize = newValue;
615
+ // @ts-ignore
616
+ }
617
+ else if (newValue.indexOf('%') !== -1) {
618
+ view.fontSize = {
619
+ value: parseFloat(newValue) / 100,
620
+ unit: '%',
621
+ };
622
+ // @ts-ignore
623
+ }
624
+ else if (newValue.indexOf('dip') !== -1) {
625
+ view.fontSize = parseFloat(newValue);
626
+ // @ts-ignore
627
+ }
628
+ else if (newValue.indexOf('px') !== -1) {
629
+ view.fontSize = {
630
+ value: parseFloat(newValue),
631
+ unit: 'px',
632
+ };
633
+ }
634
+ else {
635
+ view.fontSize = parseFloat(newValue);
636
+ }
637
+ }
638
+ else {
639
+ view.fontSize = newValue;
640
+ }
641
+ }
642
+ else {
643
+ // Revert to old value if newValue is invalid
644
+ // @ts-ignore
645
+ target.fontSize = oldValue;
646
+ }
647
+ }
648
+ else {
649
+ // fallback to core behavior
650
+ const currentFont = target.fontInternal || Font.default;
651
+ if (currentFont.fontSize !== newValue) {
652
+ const newFont = currentFont.withFontSize(newValue);
653
+ target.fontInternal = Font.equals(Font.default, newFont) ? unsetValue : newFont;
654
+ }
655
+ }
656
+ },
657
+ });
658
+ export const rowGapProperty = new CssProperty({
659
+ name: 'rowGap',
660
+ cssName: 'row-gap',
661
+ defaultValue: 0,
662
+ // @ts-ignore
663
+ valueConverter: masonGapConverter,
664
+ // @ts-ignore
665
+ equalityComparer: masonLengthEquals,
666
+ valueChanged(target, oldValue, newValue) {
667
+ if (appliedInSetNative(target, rowGapProperty))
668
+ return;
669
+ const view = getViewStyle(target.viewRef);
670
+ if (view) {
671
+ view.rowGap = newValue;
672
+ }
673
+ },
674
+ });
675
+ export const columnGapProperty = new CssProperty({
676
+ name: 'columnGap',
677
+ cssName: 'column-gap',
678
+ defaultValue: 0,
679
+ // @ts-ignore
680
+ valueConverter: masonGapConverter,
681
+ // @ts-ignore
682
+ equalityComparer: masonLengthEquals,
683
+ valueChanged(target, oldValue, newValue) {
684
+ if (appliedInSetNative(target, columnGapProperty))
685
+ return;
686
+ const view = getViewStyle(target.viewRef);
687
+ if (view) {
688
+ view.columnGap = newValue;
689
+ }
690
+ },
691
+ });
692
+ /** A gap longhand as CSS text: CSS text as is, a number in px, a core length as `<n><unit>`. */
693
+ function gapText(value) {
694
+ if (typeof value === 'number') {
695
+ return `${value}px`;
696
+ }
697
+ if (value && typeof value === 'object') {
698
+ const { value: amount, unit } = value;
699
+ return unit === '%' ? `${Math.round((amount ?? 0) * 1e6) / 1e4}%` : `${amount ?? 0}${unit === 'dip' ? 'px' : (unit ?? 'px')}`;
700
+ }
701
+ return String(value ?? '');
702
+ }
703
+ function gapGetter() {
704
+ if (this.rowGap === this.columnGap) {
705
+ return this.rowGap;
706
+ }
707
+ const row = gapText(this.rowGap);
708
+ const column = gapText(this.columnGap);
709
+ // Two equal parses are different objects.
710
+ return row === column ? row : `${row} ${column}`;
711
+ }
712
+ const gapShorthand = { cssName: 'gap', longhands: [rowGapProperty, columnGapProperty], split: splitGap };
713
+ const gridGapShorthand = { ...gapShorthand, cssName: 'grid-gap' };
714
+ export const gridGapProperty = masonShorthandProperty(gridGapShorthand, gapGetter);
715
+ export const gapProperty = masonShorthandProperty(gapShorthand, gapGetter);
716
+ export const gridRowGapProperty = new ShorthandProperty({
717
+ name: 'gridRowGap',
718
+ cssName: 'grid-row-gap',
719
+ getter: function () {
720
+ return this.rowGap;
721
+ },
722
+ converter(value) {
723
+ return [[rowGapProperty, value]];
724
+ },
725
+ });
726
+ export const gridColumnGapProperty = new ShorthandProperty({
727
+ name: 'gridColumnGap',
728
+ cssName: 'grid-column-gap',
729
+ getter: function () {
730
+ return this.columnGap;
731
+ },
732
+ converter(value) {
733
+ return [[columnGapProperty, value]];
734
+ },
735
+ });
736
+ overrideForMasonViews(textAlignmentProperty, {
737
+ coreConverter: TextAlignmentParse,
738
+ apply: (style, value) => {
739
+ style.textAlignment = value;
740
+ },
741
+ });
742
+ overrideForMasonViews(textTransformProperty, {
743
+ coreConverter: TextTransformParse,
744
+ apply: (style, value) => {
745
+ style.textTransform = value;
746
+ },
747
+ });
748
+ function masonLengthParse(value) {
749
+ try {
750
+ return CoreLength.parse(value);
751
+ }
752
+ catch (e) {
753
+ return undefined;
754
+ }
755
+ }
756
+ function masonLengthPercentParse(value) {
757
+ try {
758
+ return CorePercentLength.parse(value);
759
+ }
760
+ catch (e) {
761
+ return undefined;
762
+ }
763
+ }
764
+ /** Lengths in units core's parsers read as bare numbers. */
765
+ const UNITS_CORE_MISREADS = /^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?(r?em|pt|vw|vh|vmin|vmax|dppx)$/i;
766
+ /** CSS text for a length in a unit core can't parse (rem, em, vw), else undefined. */
767
+ function masonLengthText(value) {
768
+ if (typeof value !== 'string') {
769
+ return undefined;
770
+ }
771
+ const t = value.trim();
772
+ // Core can't evaluate math functions either; Mason's setter does.
773
+ return UNITS_CORE_MISREADS.test(t) || isCssMathFunction(t) ? t : undefined;
774
+ }
775
+ /** `left`/`top`/`right`/`bottom`: Mason's units, else core's parse (`%`, `auto`). */
776
+ function masonInsetConverter(value) {
777
+ return (masonLengthText(value) ?? masonLengthPercentParse(value));
778
+ }
779
+ /** `row-gap`/`column-gap`: as the insets, but anything unparsable is 0. */
780
+ function masonGapConverter(value) {
781
+ const text = masonLengthText(value);
782
+ if (text !== undefined) {
783
+ return text;
784
+ }
785
+ const parsed = masonLengthPercentParse(value);
786
+ if (parsed === undefined || typeof parsed === 'string') {
787
+ return 0;
788
+ }
789
+ return parsed;
790
+ }
791
+ /** Compares CSS text as text: core's `PercentLength.equals` calls any two strings equal. */
792
+ function masonLengthEquals(a, b) {
793
+ if (typeof a === 'string' || typeof b === 'string') {
794
+ return a === b;
795
+ }
796
+ return CorePercentLength.equals(a, b);
797
+ }
798
+ /** As `masonSizeConverter`, for Mason's own max-* properties (core has none). */
799
+ function masonMaxSizeConverter(value) {
800
+ const resolved = masonSizeValue(value);
801
+ return (resolved ?? masonLengthPercentParse(value));
802
+ }
803
+ export const maxWidthProperty = new CssProperty({
804
+ name: 'maxWidth',
805
+ cssName: 'max-width',
806
+ defaultValue: 'auto',
807
+ // @ts-ignore
808
+ equalityComparer: CorePercentLength.equals,
809
+ // masonLengthParse has no '%' handling; match width/height's converter.
810
+ // @ts-ignore
811
+ valueConverter: masonMaxSizeConverter,
812
+ valueChanged: (target, oldValue, newValue) => {
813
+ if (appliedInSetNative(target, maxWidthProperty))
814
+ return;
815
+ const view = getViewStyle(target.viewRef);
816
+ if (view) {
817
+ view.maxWidth = newValue;
818
+ }
819
+ else {
820
+ Trace.write(`${newValue} not set to view's property because ".viewRef" is cleared`, Trace.categories.Style, Trace.messageType.warn);
821
+ }
822
+ },
823
+ });
824
+ export const maxHeightProperty = new CssProperty({
825
+ name: 'maxHeight',
826
+ cssName: 'max-height',
827
+ defaultValue: 'auto',
828
+ // @ts-ignore
829
+ equalityComparer: CorePercentLength.equals,
830
+ // @ts-ignore
831
+ valueConverter: masonMaxSizeConverter,
832
+ valueChanged(target, oldValue, newValue) {
833
+ if (appliedInSetNative(target, maxHeightProperty))
834
+ return;
835
+ const view = getViewStyle(target.viewRef);
836
+ if (view) {
837
+ view.maxHeight = newValue;
838
+ }
839
+ },
840
+ });
841
+ // Core's minWidth/minHeight already route into this Style via setNative
842
+ // (common.ts), so no new CssProperty is needed — just fix the '%' handling.
843
+ // Core's min-width/min-height converter is Length.parse, which has no '%'
844
+ // handling; mason needs percentages. Core's own valueChanged (which sets
845
+ // effectiveMinWidth) is deliberately left in place for both kinds of view, so
846
+ // only the converter is narrowed — a plain view must still get a plain Length,
847
+ // or core's Length.toDevicePixels mis-reads a percentage.
848
+ /**
849
+ * Resolve a size value with Mason's own length parser before core sees it.
850
+ *
851
+ * `width`/`height`/`min-*` reach core's `PercentLength.parse` first, which
852
+ * misreads `100vh`/`1rem` as a bare dip count and `px` as a device pixel
853
+ * rather than Mason's CSS pixel. Resolve every unit Mason understands here
854
+ * as the equivalent dip; percentages, `auto` and keywords fall through
855
+ * untouched.
856
+ */
857
+ function masonSizeValue(value) {
858
+ const dip = cssLengthToDip(value);
859
+ return dip === undefined ? undefined : { value: dip, unit: 'dip' };
860
+ }
861
+ function masonMinSizeConverter(value) {
862
+ if (isMasonView(this)) {
863
+ const resolved = masonSizeValue(value);
864
+ if (resolved) {
865
+ return resolved;
866
+ }
867
+ return masonLengthPercentParse(value);
868
+ }
869
+ return CoreLength.parse(value);
870
+ }
871
+ minWidthProperty.overrideHandlers({
872
+ name: 'minWidth',
873
+ cssName: 'min-width',
874
+ // @ts-ignore
875
+ equalityComparer: CorePercentLength.equals,
876
+ // @ts-ignore
877
+ valueConverter: masonMinSizeConverter,
878
+ });
879
+ minHeightProperty.overrideHandlers({
880
+ name: 'minHeight',
881
+ cssName: 'min-height',
882
+ // @ts-ignore
883
+ equalityComparer: CorePercentLength.equals,
884
+ // @ts-ignore
885
+ valueConverter: masonMinSizeConverter,
886
+ });
887
+ /**
888
+ * Rewrite a size declaration for mason views before core parses it.
889
+ *
890
+ * `width`/`height` are `CssAnimationProperty`s with no `overrideHandlers`, so
891
+ * mason can't narrow their converter the way it does for `min-*`. Rewriting
892
+ * the declaration itself works instead: `100vh` becomes its resolved dip
893
+ * count, which core's parser then reads correctly (and, deliberately, so
894
+ * does a bare `px`, which core reads as a device pixel but mason as a CSS
895
+ * pixel).
896
+ */
897
+ function masonLengthDeclaration(value) {
898
+ if (typeof value !== 'string') {
899
+ return value;
900
+ }
901
+ const keyword = sizingKeywordLength(value);
902
+ if (keyword) {
903
+ return keyword;
904
+ }
905
+ const dip = cssLengthToDip(value);
906
+ // A bare number is a dip to core and a CSS pixel to mason — the same size.
907
+ return dip === undefined ? value : String(dip);
908
+ }
909
+ /** Core throws on sizing keywords; a negative length reads as auto to core and carries the keyword as its unit. */
910
+ function sizingKeywordLength(value) {
911
+ return isSizingKeyword(value) ? { unit: value.trim(), value: -2 } : undefined;
912
+ }
913
+ const MASON_SIZE_KEYS = [widthProperty, heightProperty, minWidthProperty, minHeightProperty, maxWidthProperty, maxHeightProperty].flatMap((property) => [property.name, property.cssName, property.cssLocalName]).filter((key) => typeof key === 'string' && key.length > 0);
914
+ /**
915
+ * The stylesheet-facing accessor a `CssAnimationProperty` installs is
916
+ * non-configurable, so it can't be overridden on `Style.prototype`. Shadow it
917
+ * on a prototype between `Style.prototype` and each mason view's Style.
918
+ */
919
+ const masonStyleProtos = new WeakMap();
920
+ function masonStyleProto(proto) {
921
+ let masonProto = masonStyleProtos.get(proto);
922
+ if (masonProto) {
923
+ return masonProto;
924
+ }
925
+ masonProto = Object.create(proto);
926
+ for (const key of new Set(MASON_SIZE_KEYS)) {
927
+ const descriptor = Object.getOwnPropertyDescriptor(proto, key);
928
+ const set = descriptor?.set;
929
+ const get = descriptor?.get;
930
+ if (!set) {
931
+ continue;
932
+ }
933
+ Object.defineProperty(masonProto, key, {
934
+ enumerable: false,
935
+ configurable: true,
936
+ get,
937
+ set(value) {
938
+ beginStyleWrite(this, key, value);
939
+ try {
940
+ set.call(this, masonLengthDeclaration(environmentStyleValue(this, key, value)));
941
+ }
942
+ finally {
943
+ endStyleWrite();
944
+ }
945
+ },
946
+ });
947
+ }
948
+ Object.defineProperty(masonProto, MASON_SIZE_UNITS, { value: true, enumerable: false });
949
+ masonStyleProtos.set(proto, masonProto);
950
+ return masonProto;
951
+ }
952
+ export function installMasonSizeUnits(style) {
953
+ if (!style || style[MASON_SIZE_UNITS]) {
954
+ return;
955
+ }
956
+ Object.setPrototypeOf(style, masonStyleProto(Object.getPrototypeOf(style)));
957
+ }
958
+ export const insetProperty = new ShorthandProperty({
959
+ name: 'inset',
960
+ cssName: 'inset',
961
+ getter: function () {
962
+ if (this.top === this.right && this.top === this.bottom && this.top === this.left) {
963
+ if (typeof this.top === 'string') {
964
+ if (this.top === 'auto') {
965
+ return this.top;
966
+ }
967
+ const value = CorePercentLength.parse(this.top);
968
+ if (Number.isNaN(value)) {
969
+ return this.top;
970
+ }
971
+ else {
972
+ return CorePercentLength.convertToString(value);
973
+ }
974
+ }
975
+ }
976
+ if (CorePercentLength.equals(this.top, this.right) && CorePercentLength.equals(this.top, this.bottom) && CorePercentLength.equals(this.top, this.left)) {
977
+ return this.top;
978
+ }
979
+ return `${CorePercentLength.convertToString(this.paddingTop)} ${CorePercentLength.convertToString(this.paddingRight)} ${CorePercentLength.convertToString(this.paddingBottom)} ${CorePercentLength.convertToString(this.paddingLeft)}`;
980
+ },
981
+ converter: convertToInsets,
982
+ });
983
+ function parseShorthandPositioning(value) {
984
+ const arr = value.split(/[ ,]+/);
985
+ let top;
986
+ let right;
987
+ let bottom;
988
+ let left;
989
+ if (arr.length === 1) {
990
+ top = arr[0];
991
+ right = arr[0];
992
+ bottom = arr[0];
993
+ left = arr[0];
994
+ }
995
+ else if (arr.length === 2) {
996
+ top = arr[0];
997
+ bottom = arr[0];
998
+ right = arr[1];
999
+ left = arr[1];
1000
+ }
1001
+ else if (arr.length === 3) {
1002
+ top = arr[0];
1003
+ right = arr[1];
1004
+ left = arr[1];
1005
+ bottom = arr[2];
1006
+ }
1007
+ else if (arr.length === 4) {
1008
+ top = arr[0];
1009
+ right = arr[1];
1010
+ bottom = arr[2];
1011
+ left = arr[3];
1012
+ }
1013
+ else {
1014
+ throw new Error('Expected 1, 2, 3 or 4 parameters. Actual: ' + value);
1015
+ }
1016
+ return {
1017
+ top: top,
1018
+ right: right,
1019
+ bottom: bottom,
1020
+ left: left,
1021
+ };
1022
+ }
1023
+ function convertToInsets(value) {
1024
+ if (typeof value === 'string' && value !== 'auto') {
1025
+ const thickness = parseShorthandPositioning(value);
1026
+ return [
1027
+ [topProperty, masonInsetConverter(thickness.top)],
1028
+ [rightProperty, masonInsetConverter(thickness.right)],
1029
+ [bottomProperty, masonInsetConverter(thickness.bottom)],
1030
+ [leftProperty, masonInsetConverter(thickness.left)],
1031
+ ];
1032
+ }
1033
+ else {
1034
+ return [
1035
+ [topProperty, value],
1036
+ [rightProperty, value],
1037
+ [bottomProperty, value],
1038
+ [leftProperty, value],
1039
+ ];
1040
+ }
1041
+ }
1042
+ export const leftProperty = new CssProperty({
1043
+ name: 'left',
1044
+ cssName: 'left',
1045
+ defaultValue: 'auto',
1046
+ // @ts-ignore
1047
+ equalityComparer: masonLengthEquals,
1048
+ // @ts-ignore
1049
+ valueConverter: masonInsetConverter,
1050
+ valueChanged(target, oldValue, newValue) {
1051
+ if (appliedInSetNative(target, leftProperty))
1052
+ return;
1053
+ const view = getViewStyle(target.viewRef);
1054
+ if (view) {
1055
+ view.left = newValue;
1056
+ }
1057
+ },
1058
+ });
1059
+ export const rightProperty = new CssProperty({
1060
+ name: 'right',
1061
+ cssName: 'right',
1062
+ defaultValue: 'auto',
1063
+ // @ts-ignore
1064
+ equalityComparer: masonLengthEquals,
1065
+ // @ts-ignore
1066
+ valueConverter: masonInsetConverter,
1067
+ valueChanged(target, oldValue, newValue) {
1068
+ if (appliedInSetNative(target, rightProperty))
1069
+ return;
1070
+ const view = getViewStyle(target.viewRef);
1071
+ if (view) {
1072
+ view.right = newValue;
1073
+ }
1074
+ },
1075
+ });
1076
+ export const topProperty = new CssProperty({
1077
+ name: 'top',
1078
+ cssName: 'top',
1079
+ defaultValue: 'auto',
1080
+ // @ts-ignore
1081
+ equalityComparer: masonLengthEquals,
1082
+ // @ts-ignore
1083
+ valueConverter: masonInsetConverter,
1084
+ valueChanged(target, oldValue, newValue) {
1085
+ if (appliedInSetNative(target, topProperty))
1086
+ return;
1087
+ const view = getViewStyle(target.viewRef);
1088
+ if (view) {
1089
+ view.top = newValue;
1090
+ }
1091
+ },
1092
+ });
1093
+ export const bottomProperty = new CssProperty({
1094
+ name: 'bottom',
1095
+ cssName: 'bottom',
1096
+ defaultValue: 'auto',
1097
+ // @ts-ignore
1098
+ equalityComparer: masonLengthEquals,
1099
+ // @ts-ignore
1100
+ valueConverter: masonInsetConverter,
1101
+ valueChanged(target, oldValue, newValue) {
1102
+ if (appliedInSetNative(target, bottomProperty))
1103
+ return;
1104
+ const view = getViewStyle(target.viewRef);
1105
+ if (view) {
1106
+ view.bottom = newValue;
1107
+ }
1108
+ },
1109
+ });
1110
+ export const positionProperty = new CssProperty({
1111
+ name: 'position',
1112
+ cssName: 'position',
1113
+ defaultValue: 'static',
1114
+ valueChanged(target, oldValue, newValue) {
1115
+ if (appliedInSetNative(target, positionProperty))
1116
+ return;
1117
+ const view = getViewStyle(target.viewRef);
1118
+ if (view) {
1119
+ view.position = newValue;
1120
+ }
1121
+ },
1122
+ });
1123
+ export const boxSizingProperty = new CssProperty({
1124
+ name: 'boxSizing',
1125
+ cssName: 'box-sizing',
1126
+ defaultValue: 'border-box',
1127
+ valueChanged(target, oldValue, newValue) {
1128
+ if (newValue && appliedInSetNative(target, boxSizingProperty))
1129
+ return;
1130
+ const view = getViewStyle(target.viewRef);
1131
+ if (view) {
1132
+ if (newValue) {
1133
+ view.boxSizing = newValue;
1134
+ }
1135
+ else {
1136
+ // Revert to old value if newValue is invalid
1137
+ target.boxSizing = oldValue;
1138
+ }
1139
+ }
1140
+ },
1141
+ valueConverter(value) {
1142
+ switch (value) {
1143
+ case 'content-box':
1144
+ case 'border-box':
1145
+ return value;
1146
+ default:
1147
+ return undefined;
1148
+ }
1149
+ },
1150
+ });
1151
+ export const borderRadiusProperty = new CssProperty({
1152
+ name: 'borderRadius',
1153
+ cssName: 'border-radius',
1154
+ });
1155
+ // Core's alignItems/alignSelf validator rejects Box Alignment keywords
1156
+ // ("start"/"end") masonkit's own Style setter accepts fine; bypass it for
1157
+ // Mason views/children like alignContent/justifyContent already do below.
1158
+ export const AlignItemsIsValid = makeValidator('normal', 'start', 'end', 'flex-start', 'flex-end', 'center', 'baseline', 'stretch');
1159
+ export const AlignItemsParse = makeParser(AlignItemsIsValid);
1160
+ export const AlignSelfIsValid = makeValidator('normal', 'start', 'end', 'flex-start', 'flex-end', 'center', 'baseline', 'stretch');
1161
+ export const AlignSelfParse = makeParser(AlignSelfIsValid);
1162
+ alignItemsProperty.overrideHandlers({
1163
+ name: 'alignItems',
1164
+ cssName: 'align-items',
1165
+ valueConverter: function (value) {
1166
+ if (isMasonView(this)) {
1167
+ return value;
1168
+ }
1169
+ return AlignItemsParse(value);
1170
+ },
1171
+ valueChanged(target, oldValue, newValue) {
1172
+ if (newValue && appliedInSetNative(target, alignItemsProperty))
1173
+ return;
1174
+ const view = getViewStyle(target.viewRef);
1175
+ if (view) {
1176
+ if (newValue) {
1177
+ view.alignItems = newValue;
1178
+ }
1179
+ else {
1180
+ // Revert to old value if newValue is invalid
1181
+ // @ts-ignore
1182
+ target.alignItems = oldValue;
1183
+ }
1184
+ }
1185
+ },
1186
+ });
1187
+ alignSelfProperty.overrideHandlers({
1188
+ name: 'alignSelf',
1189
+ cssName: 'align-self',
1190
+ valueConverter: function (value) {
1191
+ if (isMasonView(this)) {
1192
+ return value;
1193
+ }
1194
+ return AlignSelfParse(value);
1195
+ },
1196
+ valueChanged(target, oldValue, newValue) {
1197
+ if (newValue && appliedInSetNative(target, alignSelfProperty))
1198
+ return;
1199
+ const view = getViewStyle(target.viewRef);
1200
+ if (view) {
1201
+ if (newValue) {
1202
+ view.alignSelf = newValue;
1203
+ }
1204
+ else {
1205
+ // Revert to old value if newValue is invalid
1206
+ // @ts-ignore
1207
+ target.alignSelf = oldValue;
1208
+ }
1209
+ }
1210
+ },
1211
+ });
1212
+ export const AlignContentIsValid = makeValidator('flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'space-evenly', 'stretch', 'normal', 'start', 'end');
1213
+ export const AlignContentParse = makeParser(AlignContentIsValid);
1214
+ export const alignContentProperty = new CssProperty({
1215
+ name: 'alignContent',
1216
+ cssName: 'align-content',
1217
+ defaultValue: 'normal',
1218
+ valueConverter: function (value) {
1219
+ if (isMasonView(this)) {
1220
+ return value;
1221
+ }
1222
+ return AlignContentParse(value);
1223
+ },
1224
+ valueChanged(target, oldValue, newValue) {
1225
+ if (newValue && appliedInSetNative(target, alignContentProperty))
1226
+ return;
1227
+ const view = getViewStyle(target.viewRef);
1228
+ if (view) {
1229
+ if (newValue) {
1230
+ view.alignContent = newValue;
1231
+ }
1232
+ else {
1233
+ // Revert to old value if newValue is invalid
1234
+ // @ts-ignore
1235
+ target.alignContent = oldValue;
1236
+ }
1237
+ }
1238
+ },
1239
+ });
1240
+ export const justifyItemsProperty = new CssProperty({
1241
+ name: 'justifyItems',
1242
+ cssName: 'justify-items',
1243
+ defaultValue: 'normal',
1244
+ valueChanged(target, oldValue, newValue) {
1245
+ if (newValue && appliedInSetNative(target, justifyItemsProperty))
1246
+ return;
1247
+ const view = getViewStyle(target.viewRef);
1248
+ if (view) {
1249
+ if (newValue) {
1250
+ view.justifyItems = newValue;
1251
+ }
1252
+ else {
1253
+ // Revert to old value if newValue is invalid
1254
+ // @ts-ignore
1255
+ target.justifyItems = oldValue;
1256
+ }
1257
+ }
1258
+ },
1259
+ });
1260
+ export const justifySelfProperty = new CssProperty({
1261
+ name: 'justifySelf',
1262
+ cssName: 'justify-self',
1263
+ defaultValue: 'normal',
1264
+ valueChanged(target, oldValue, newValue) {
1265
+ if (newValue && appliedInSetNative(target, justifySelfProperty))
1266
+ return;
1267
+ const view = getViewStyle(target.viewRef);
1268
+ if (view) {
1269
+ if (newValue) {
1270
+ view.justifySelf = newValue;
1271
+ }
1272
+ else {
1273
+ // Revert to old value if newValue is invalid
1274
+ // @ts-ignore
1275
+ target.justifySelf = oldValue;
1276
+ }
1277
+ }
1278
+ },
1279
+ });
1280
+ export const placeShorthands = [
1281
+ { cssName: 'place-items', longhands: [alignItemsProperty, justifyItemsProperty], split: splitPlace },
1282
+ { cssName: 'place-content', longhands: [alignContentProperty, justifyContentProperty], split: splitPlace },
1283
+ { cssName: 'place-self', longhands: [alignSelfProperty, justifySelfProperty], split: splitPlace },
1284
+ ];
1285
+ for (const entry of placeShorthands) {
1286
+ masonShorthandProperty(entry).register(Style);
1287
+ }
1288
+ export const JustifyContentIsValid = makeValidator('flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'space-evenly', 'stretch', 'normal', 'start', 'end');
1289
+ export const JustifyContentParse = makeParser(JustifyContentIsValid);
1290
+ justifyContentProperty.overrideHandlers({
1291
+ name: 'justifyContent',
1292
+ cssName: 'justify-content',
1293
+ valueConverter: function (value) {
1294
+ if (isMasonView(this)) {
1295
+ return value;
1296
+ }
1297
+ return JustifyContentParse(value);
1298
+ },
1299
+ valueChanged(target, oldValue, newValue) {
1300
+ if (newValue && appliedInSetNative(target, justifyContentProperty))
1301
+ return;
1302
+ const view = getViewStyle(target.viewRef);
1303
+ if (view) {
1304
+ if (newValue) {
1305
+ view.justifyContent = newValue;
1306
+ }
1307
+ else {
1308
+ // Revert to old value if newValue is invalid
1309
+ // @ts-ignore
1310
+ target.justifyContent = oldValue;
1311
+ }
1312
+ }
1313
+ },
1314
+ });
1315
+ export const flexBasisProperty = new CssProperty({
1316
+ name: 'flexBasis',
1317
+ cssName: 'flex-basis',
1318
+ defaultValue: 'auto',
1319
+ // @ts-ignore
1320
+ equalityComparer: masonLengthEquals,
1321
+ // @ts-ignore
1322
+ valueConverter: (value) => (isSizingKeyword(value) ? value.trim() : masonInsetConverter(value)),
1323
+ valueChanged(target, oldValue, newValue) {
1324
+ if (appliedInSetNative(target, flexBasisProperty))
1325
+ return;
1326
+ const view = getViewStyle(target.viewRef);
1327
+ if (view) {
1328
+ view.flexBasis = newValue;
1329
+ }
1330
+ },
1331
+ });
1332
+ export const aspectRatioProperty = new CssProperty({
1333
+ name: 'aspectRatio',
1334
+ cssName: 'aspect-ratio',
1335
+ defaultValue: Number.NaN,
1336
+ // Without this the raw declaration reached the buffer's setFloat32, where the
1337
+ // `<ratio>` form (`2 / 3`) coerces to NaN — i.e. no ratio at all.
1338
+ // @ts-ignore
1339
+ valueConverter: parseAspectRatio,
1340
+ valueChanged(target, oldValue, newValue) {
1341
+ if (appliedInSetNative(target, aspectRatioProperty))
1342
+ return;
1343
+ const view = getViewStyle(target.viewRef);
1344
+ if (view) {
1345
+ view.aspectRatio = newValue;
1346
+ }
1347
+ },
1348
+ });
1349
+ export const gridAutoRowsProperty = new CssProperty({
1350
+ name: 'gridAutoRows',
1351
+ cssName: 'grid-auto-rows',
1352
+ defaultValue: '',
1353
+ valueChanged(target, oldValue, newValue) {
1354
+ if (appliedInSetNative(target, gridAutoRowsProperty))
1355
+ return;
1356
+ const view = getViewStyle(target.viewRef);
1357
+ if (view) {
1358
+ view.gridAutoRows = newValue;
1359
+ }
1360
+ },
1361
+ });
1362
+ export const gridAutoColumnsProperty = new CssProperty({
1363
+ name: 'gridAutoColumns',
1364
+ cssName: 'grid-auto-columns',
1365
+ defaultValue: '',
1366
+ valueChanged(target, oldValue, newValue) {
1367
+ if (appliedInSetNative(target, gridAutoColumnsProperty))
1368
+ return;
1369
+ const view = getViewStyle(target.viewRef);
1370
+ if (view) {
1371
+ view.gridAutoColumns = newValue;
1372
+ }
1373
+ },
1374
+ });
1375
+ export const gridAutoFlowProperty = new CssProperty({
1376
+ name: 'gridAutoFlow',
1377
+ cssName: 'grid-auto-flow',
1378
+ defaultValue: 'row',
1379
+ valueChanged(target, oldValue, newValue) {
1380
+ if (appliedInSetNative(target, gridAutoFlowProperty))
1381
+ return;
1382
+ const view = getViewStyle(target.viewRef);
1383
+ if (view) {
1384
+ view.gridAutoFlow = newValue;
1385
+ }
1386
+ },
1387
+ });
1388
+ export const gridAreaProperty = new CssProperty({
1389
+ name: 'gridArea',
1390
+ cssName: 'grid-area',
1391
+ defaultValue: '',
1392
+ valueChanged(target, oldValue, newValue) {
1393
+ if (appliedInSetNative(target, gridAreaProperty))
1394
+ return;
1395
+ const view = getViewStyle(target.viewRef);
1396
+ if (view) {
1397
+ view.gridArea = newValue;
1398
+ }
1399
+ },
1400
+ });
1401
+ export const gridColumnStartProperty = new CssProperty({
1402
+ name: 'gridColumnStart',
1403
+ cssName: 'grid-column-start',
1404
+ defaultValue: 'auto',
1405
+ valueChanged(target, oldValue, newValue) {
1406
+ if (appliedInSetNative(target, gridColumnStartProperty))
1407
+ return;
1408
+ const view = getViewStyle(target.viewRef);
1409
+ if (view) {
1410
+ view.gridColumnStart = newValue;
1411
+ }
1412
+ },
1413
+ });
1414
+ export const gridColumnEndProperty = new CssProperty({
1415
+ name: 'gridColumnEnd',
1416
+ cssName: 'grid-column-end',
1417
+ defaultValue: 'auto',
1418
+ valueChanged(target, oldValue, newValue) {
1419
+ if (appliedInSetNative(target, gridColumnEndProperty))
1420
+ return;
1421
+ const view = getViewStyle(target.viewRef);
1422
+ if (view) {
1423
+ view.gridColumnEnd = newValue;
1424
+ }
1425
+ },
1426
+ });
1427
+ export const gridColumnProperty = new CssProperty({
1428
+ name: 'gridColumn',
1429
+ cssName: 'grid-column',
1430
+ defaultValue: '',
1431
+ valueChanged(target, oldValue, newValue) {
1432
+ if (appliedInSetNative(target, gridColumnProperty))
1433
+ return;
1434
+ const view = getViewStyle(target.viewRef);
1435
+ if (view) {
1436
+ view.gridColumn = newValue;
1437
+ }
1438
+ },
1439
+ });
1440
+ export const gridRowStartProperty = new CssProperty({
1441
+ name: 'gridRowStart',
1442
+ cssName: 'grid-row-start',
1443
+ defaultValue: 'auto',
1444
+ valueChanged(target, oldValue, newValue) {
1445
+ if (appliedInSetNative(target, gridRowStartProperty))
1446
+ return;
1447
+ const view = getViewStyle(target.viewRef);
1448
+ if (view) {
1449
+ view.gridRowStart = newValue;
1450
+ }
1451
+ },
1452
+ });
1453
+ export const gridRowEndProperty = new CssProperty({
1454
+ name: 'gridRowEnd',
1455
+ cssName: 'grid-row-end',
1456
+ defaultValue: 'auto',
1457
+ valueChanged(target, oldValue, newValue) {
1458
+ if (appliedInSetNative(target, gridRowEndProperty))
1459
+ return;
1460
+ const view = getViewStyle(target.viewRef);
1461
+ if (view) {
1462
+ view.gridRowEnd = newValue;
1463
+ }
1464
+ },
1465
+ });
1466
+ export const gridRowProperty = new CssProperty({
1467
+ name: 'gridRow',
1468
+ cssName: 'grid-row',
1469
+ defaultValue: '',
1470
+ valueChanged(target, oldValue, newValue) {
1471
+ if (appliedInSetNative(target, gridRowProperty))
1472
+ return;
1473
+ const view = getViewStyle(target.viewRef);
1474
+ if (view) {
1475
+ view.gridRow = newValue;
1476
+ }
1477
+ },
1478
+ });
1479
+ export const gridTemplateAreasProperty = new CssProperty({
1480
+ name: 'gridTemplateAreas',
1481
+ cssName: 'grid-template-areas',
1482
+ defaultValue: null,
1483
+ valueChanged(target, oldValue, newValue) {
1484
+ if (appliedInSetNative(target, gridTemplateAreasProperty))
1485
+ return;
1486
+ const view = getViewStyle(target.viewRef);
1487
+ if (view) {
1488
+ view.gridTemplateAreas = newValue;
1489
+ }
1490
+ },
1491
+ });
1492
+ export const gridTemplateRowsProperty = new CssProperty({
1493
+ name: 'gridTemplateRows',
1494
+ cssName: 'grid-template-rows',
1495
+ defaultValue: null,
1496
+ valueChanged(target, oldValue, newValue) {
1497
+ if (appliedInSetNative(target, gridTemplateRowsProperty))
1498
+ return;
1499
+ const view = getViewStyle(target.viewRef);
1500
+ if (view) {
1501
+ view.gridTemplateRows = newValue;
1502
+ }
1503
+ },
1504
+ });
1505
+ export const gridTemplateColumnsProperty = new CssProperty({
1506
+ name: 'gridTemplateColumns',
1507
+ cssName: 'grid-template-columns',
1508
+ defaultValue: null,
1509
+ valueChanged(target, oldValue, newValue) {
1510
+ if (appliedInSetNative(target, gridTemplateColumnsProperty))
1511
+ return;
1512
+ const view = getViewStyle(target.viewRef);
1513
+ if (view) {
1514
+ view.gridTemplateColumns = newValue;
1515
+ }
1516
+ },
1517
+ });
1518
+ // @ts-ignore
1519
+ export const textWrapProperty = new CssProperty({
1520
+ name: 'textWrap',
1521
+ cssName: 'text-wrap',
1522
+ affectsLayout: true,
1523
+ defaultValue: 'wrap',
1524
+ valueChanged(target, oldValue, newValue) {
1525
+ if (appliedInSetNative(target, textWrapProperty))
1526
+ return;
1527
+ const view = target?.viewRef ? getViewStyle(target.viewRef) : target.view;
1528
+ if (view) {
1529
+ view.textWrap = newValue;
1530
+ }
1531
+ },
1532
+ });
1533
+ const flexFlowShorthand = { cssName: 'flex-flow', longhands: [flexDirectionProperty, flexWrapProperty], split: splitFlexFlow };
1534
+ const flexFlowProperty = masonShorthandProperty(flexFlowShorthand, function () {
1535
+ return `${this.flexDirection} ${this.flexWrap}`;
1536
+ });
1537
+ const flexShorthand = { cssName: 'flex', longhands: [flexGrowProperty, flexShrinkProperty, flexBasisProperty], split: splitFlex };
1538
+ const flexProperty = masonShorthandProperty(flexShorthand, function () {
1539
+ return `${this.flexGrow} ${this.flexShrink} ${this.flexBasis}`;
1540
+ });
1541
+ export const textOverFlowProperty = new CssProperty({
1542
+ name: 'textOverflow',
1543
+ cssName: 'text-overflow',
1544
+ defaultValue: 'clip',
1545
+ valueChanged(target, oldValue, newValue) {
1546
+ if (appliedInSetNative(target, textOverFlowProperty))
1547
+ return;
1548
+ const view = target?.viewRef ? getViewStyle(target.viewRef) : target.view;
1549
+ if (view) {
1550
+ view.textOverflow = newValue;
1551
+ }
1552
+ },
1553
+ });
1554
+ export const verticalAlignProperty = new CssProperty({
1555
+ name: 'verticalAlign',
1556
+ cssName: 'vertical-align',
1557
+ defaultValue: 'baseline',
1558
+ valueChanged: (target, oldValue, newValue) => {
1559
+ if (newValue && appliedInSetNative(target, verticalAlignProperty))
1560
+ return;
1561
+ const view = getViewStyle(target.viewRef);
1562
+ if (view) {
1563
+ if (newValue) {
1564
+ view.verticalAlign = newValue;
1565
+ }
1566
+ else {
1567
+ // Revert to old value if newValue is invalid
1568
+ target.verticalAlign = oldValue;
1569
+ }
1570
+ }
1571
+ },
1572
+ });
1573
+ verticalAlignmentProperty.overrideHandlers({
1574
+ name: 'verticalAlignment',
1575
+ cssName: 'vertical-align',
1576
+ valueConverter: function (value) {
1577
+ if (isMasonView(this)) {
1578
+ return value;
1579
+ }
1580
+ return CoreTypes.VerticalAlignmentText.parse(value);
1581
+ },
1582
+ valueChanged(target, oldValue, newValue) {
1583
+ const view = getViewStyle(target.viewRef);
1584
+ if (view) {
1585
+ if (newValue) {
1586
+ // @ts-ignore
1587
+ view.verticalAlign = newValue;
1588
+ }
1589
+ else {
1590
+ // Revert to old value if newValue is invalid
1591
+ // @ts-ignore
1592
+ target.verticalAlign = oldValue;
1593
+ }
1594
+ }
1595
+ },
1596
+ });
1597
+ overrideForMasonViews(textShadowProperty, {
1598
+ coreConverter: parseCSSShadow,
1599
+ apply: (style, value) => {
1600
+ style.textShadow = value;
1601
+ },
1602
+ });
1603
+ export const floatProperty = new CssProperty({
1604
+ name: 'float',
1605
+ cssName: 'float',
1606
+ defaultValue: 'none',
1607
+ });
1608
+ export const clearProperty = new CssProperty({
1609
+ name: 'clear',
1610
+ cssName: 'clear',
1611
+ defaultValue: 'none',
1612
+ });
1613
+ export const cornerShapeProperty = new CssProperty({
1614
+ name: 'cornerShape',
1615
+ cssName: 'corner-shape',
1616
+ });
1617
+ export const boxShadowProperty = new CssProperty({
1618
+ name: 'boxShadow',
1619
+ cssName: 'box-shadow',
1620
+ });
1621
+ export const transformProperty = new CssProperty({
1622
+ name: 'transform',
1623
+ cssName: 'transform',
1624
+ });
1625
+ export const cornerShapeTopLeftProperty = new CssProperty({
1626
+ name: 'cornerShapeTopLeft',
1627
+ cssName: 'corner-shape-top-left',
1628
+ valueChanged(target, oldValue, newValue) {
1629
+ const view = getViewStyle(target.viewRef);
1630
+ if (view) {
1631
+ view.cornerShapeTopLeft = newValue;
1632
+ }
1633
+ },
1634
+ });
1635
+ export const cornerShapeTopRightProperty = new CssProperty({
1636
+ name: 'cornerShapeTopRight',
1637
+ cssName: 'corner-shape-top-right',
1638
+ valueChanged(target, oldValue, newValue) {
1639
+ const view = getViewStyle(target.viewRef);
1640
+ if (view) {
1641
+ view.cornerShapeTopRight = newValue;
1642
+ }
1643
+ },
1644
+ });
1645
+ export const cornerShapeBottomRightProperty = new CssProperty({
1646
+ name: 'cornerShapeBottomRight',
1647
+ cssName: 'corner-shape-bottom-right',
1648
+ valueChanged(target, oldValue, newValue) {
1649
+ const view = getViewStyle(target.viewRef);
1650
+ if (view) {
1651
+ view.cornerShapeBottomRight = newValue;
1652
+ }
1653
+ },
1654
+ });
1655
+ export const cornerShapeBottomLeftProperty = new CssProperty({
1656
+ name: 'cornerShapeBottomLeft',
1657
+ cssName: 'corner-shape-bottom-left',
1658
+ valueChanged(target, oldValue, newValue) {
1659
+ const view = getViewStyle(target.viewRef);
1660
+ if (view) {
1661
+ view.cornerShapeBottomLeft = newValue;
1662
+ }
1663
+ },
1664
+ });
1665
+ registerAlongsideCore(cornerShapeProperty);
1666
+ registerAlongsideCore(boxShadowProperty);
1667
+ registerAlongsideCore(transformProperty);
1668
+ cornerShapeTopLeftProperty.register(Style);
1669
+ cornerShapeTopRightProperty.register(Style);
1670
+ cornerShapeBottomRightProperty.register(Style);
1671
+ cornerShapeBottomLeftProperty.register(Style);
1672
+ clearProperty.register(Style);
1673
+ floatProperty.register(Style);
1674
+ registerAlongsideCore(verticalAlignProperty);
1675
+ registerAlongsideCore(textOverFlowProperty);
1676
+ registerAlongsideCore(flexProperty);
1677
+ registerAlongsideCore(flexFlowProperty);
1678
+ textWrapProperty.register(Style);
1679
+ gridTemplateColumnsProperty.register(Style);
1680
+ gridTemplateRowsProperty.register(Style);
1681
+ registerAlongsideCore(alignContentProperty);
1682
+ justifySelfProperty.register(Style);
1683
+ justifyItemsProperty.register(Style);
1684
+ gridTemplateAreasProperty.register(Style);
1685
+ gridRowProperty.register(Style);
1686
+ gridRowStartProperty.register(Style);
1687
+ gridRowEndProperty.register(Style);
1688
+ gridColumnProperty.register(Style);
1689
+ gridColumnEndProperty.register(Style);
1690
+ gridColumnStartProperty.register(Style);
1691
+ gridAreaProperty.register(Style);
1692
+ // Foreign grid shorthands must share core's effective longhands: independent
1693
+ // scalar properties lose CSS/local priority (including an explicit `auto`).
1694
+ // Preserve Mason's direct accessors; core 9.1 stylesheet expansion uses these
1695
+ // same longhands for both kinds of view.
1696
+ /** A lone `<custom-ident>` placement, which an omitted end copies instead of `auto`. */
1697
+ function isGridIdent(part) {
1698
+ return /^-?[A-Za-z_][\w-]*$/.test(part) && !/^(auto|span)$/i.test(part);
1699
+ }
1700
+ /** Splits `a / b / ...` into `count` longhands, filling omitted ones as CSS Grid does. */
1701
+ export function gridParts(value, count) {
1702
+ const parts = String(value)
1703
+ .split('/')
1704
+ .map((part) => part.trim());
1705
+ if (parts.length > count || parts.some((part) => !part))
1706
+ throw new Error(`Invalid grid placement: ${value}`);
1707
+ // Omitted ends copy their start (grid-area: row-start, column-start, row-end, column-end).
1708
+ for (let i = parts.length; i < count; i++) {
1709
+ const start = parts[i - (count === 4 ? 2 : 1)] ?? parts[0];
1710
+ parts.push(isGridIdent(start) ? start : 'auto');
1711
+ }
1712
+ return parts;
1713
+ }
1714
+ const gridPlacementShorthands = [
1715
+ { cssName: 'grid-row', longhands: [gridRowStartProperty, gridRowEndProperty], split: (value) => gridParts(value, 2) },
1716
+ { cssName: 'grid-column', longhands: [gridColumnStartProperty, gridColumnEndProperty], split: (value) => gridParts(value, 2) },
1717
+ { cssName: 'grid-area', longhands: [gridRowStartProperty, gridColumnStartProperty, gridRowEndProperty, gridColumnEndProperty], split: (value) => gridParts(value, 4) },
1718
+ ];
1719
+ for (const entry of gridPlacementShorthands) {
1720
+ const shorthand = masonShorthandProperty(entry, function () {
1721
+ return entry.longhands.map((property) => this[property.name]).join(' / ');
1722
+ });
1723
+ registerAlongsideCore(shorthand, 'foreign');
1724
+ }
1725
+ gridAutoFlowProperty.register(Style);
1726
+ gridAutoRowsProperty.register(Style);
1727
+ gridAutoColumnsProperty.register(Style);
1728
+ aspectRatioProperty.register(Style);
1729
+ flexBasisProperty.register(Style);
1730
+ registerAlongsideCore(borderRadiusProperty);
1731
+ boxSizingProperty.register(Style);
1732
+ positionProperty.register(Style);
1733
+ insetProperty.register(Style);
1734
+ leftProperty.register(Style);
1735
+ rightProperty.register(Style);
1736
+ topProperty.register(Style);
1737
+ bottomProperty.register(Style);
1738
+ registerAlongsideCore(maxWidthProperty);
1739
+ registerAlongsideCore(maxHeightProperty);
1740
+ gridRowGapProperty.register(Style);
1741
+ gridColumnGapProperty.register(Style);
1742
+ gridGapProperty.register(Style);
1743
+ registerAlongsideCore(gapProperty);
1744
+ registerAlongsideCore(rowGapProperty);
1745
+ registerAlongsideCore(columnGapProperty);
1746
+ scrollBarWidthProperty.register(Style);
1747
+ registerAlongsideCore(marginProperty);
1748
+ overflowProperty.register(Style);
1749
+ overflowXProperty.register(Style);
1750
+ overflowYProperty.register(Style);
1751
+ registerAlongsideCore(backgroundProperty);
1752
+ registerAlongsideCore(backgroundRepeatProperty);
1753
+ registerAlongsideCore(backgroundPositionProperty);
1754
+ registerAlongsideCore(backgroundSizeProperty);
1755
+ backgroundClipProperty.register(Style);
1756
+ backgroundPositionXProperty.register(Style);
1757
+ backgroundPositionYProperty.register(Style);
1758
+ backgroundOriginProperty.register(Style);
1759
+ backgroundAttachmentProperty.register(Style);
1760
+ backgroundBlendModeProperty.register(Style);
1761
+ filterProperty.register(Style);
1762
+ registerAlongsideCore(borderColorProperty);
1763
+ // New CSS properties
1764
+ export const objectPositionProperty = new CssProperty({
1765
+ name: 'objectPosition',
1766
+ cssName: 'object-position',
1767
+ defaultValue: '50% 50%',
1768
+ valueChanged(target, oldValue, newValue) {
1769
+ const view = getViewStyle(target.viewRef);
1770
+ if (view) {
1771
+ view.objectPosition = newValue;
1772
+ }
1773
+ },
1774
+ });
1775
+ // Per-side style longhands; `border-style`, `border` and `border-<side>` expand into them.
1776
+ export const borderTopStyleProperty = new CssProperty({
1777
+ name: 'borderTopStyle',
1778
+ cssName: 'border-top-style',
1779
+ defaultValue: 'none',
1780
+ });
1781
+ export const borderRightStyleProperty = new CssProperty({
1782
+ name: 'borderRightStyle',
1783
+ cssName: 'border-right-style',
1784
+ defaultValue: 'none',
1785
+ });
1786
+ export const borderBottomStyleProperty = new CssProperty({
1787
+ name: 'borderBottomStyle',
1788
+ cssName: 'border-bottom-style',
1789
+ defaultValue: 'none',
1790
+ });
1791
+ export const borderLeftStyleProperty = new CssProperty({
1792
+ name: 'borderLeftStyle',
1793
+ cssName: 'border-left-style',
1794
+ defaultValue: 'none',
1795
+ });
1796
+ export const borderImageProperty = new CssProperty({
1797
+ name: 'borderImage',
1798
+ cssName: 'border-image',
1799
+ valueChanged(target, oldValue, newValue) {
1800
+ const view = getViewStyle(target.viewRef);
1801
+ if (view) {
1802
+ view.borderImage = newValue;
1803
+ }
1804
+ },
1805
+ });
1806
+ export const fontStretchProperty = new CssProperty({
1807
+ name: 'fontStretch',
1808
+ cssName: 'font-stretch',
1809
+ defaultValue: 'normal',
1810
+ valueChanged(target, oldValue, newValue) {
1811
+ const view = getViewStyle(target.viewRef);
1812
+ if (view) {
1813
+ view.fontStretch = newValue;
1814
+ }
1815
+ },
1816
+ });
1817
+ export const fontFeatureSettingsProperty = new CssProperty({
1818
+ name: 'fontFeatureSettings',
1819
+ cssName: 'font-feature-settings',
1820
+ defaultValue: 'normal',
1821
+ valueChanged(target, oldValue, newValue) {
1822
+ const view = getViewStyle(target.viewRef);
1823
+ if (view) {
1824
+ view.fontFeatureSettings = newValue;
1825
+ }
1826
+ },
1827
+ });
1828
+ export const wordSpacingProperty = new CssProperty({
1829
+ name: 'wordSpacing',
1830
+ cssName: 'word-spacing',
1831
+ defaultValue: 'normal',
1832
+ valueChanged(target, oldValue, newValue) {
1833
+ const view = getViewStyle(target.viewRef);
1834
+ if (view) {
1835
+ view.wordSpacing = newValue;
1836
+ }
1837
+ },
1838
+ });
1839
+ export const hyphensProperty = new CssProperty({
1840
+ name: 'hyphens',
1841
+ cssName: 'hyphens',
1842
+ defaultValue: 'manual',
1843
+ valueChanged(target, oldValue, newValue) {
1844
+ const view = getViewStyle(target.viewRef);
1845
+ if (view) {
1846
+ view.hyphens = newValue;
1847
+ }
1848
+ },
1849
+ });
1850
+ export const textIndentProperty = new CssProperty({
1851
+ name: 'textIndent',
1852
+ cssName: 'text-indent',
1853
+ defaultValue: '0px',
1854
+ valueChanged(target, oldValue, newValue) {
1855
+ const view = getViewStyle(target.viewRef);
1856
+ if (view) {
1857
+ view.textIndent = newValue;
1858
+ }
1859
+ },
1860
+ });
1861
+ function setLineClamp(target, value) {
1862
+ const view = getViewStyle(target.viewRef);
1863
+ if (view) {
1864
+ view.lineClamp = (value ?? 'none');
1865
+ }
1866
+ }
1867
+ export const lineClampProperty = new CssProperty({
1868
+ name: 'lineClamp',
1869
+ cssName: 'line-clamp',
1870
+ defaultValue: 'none',
1871
+ valueChanged: (target, oldValue, newValue) => setLineClamp(target, newValue),
1872
+ });
1873
+ // Tailwind's `line-clamp-*` pairs this with `display: -webkit-box`, read as block.
1874
+ export const webkitLineClampProperty = new CssProperty({
1875
+ name: 'webkitLineClamp',
1876
+ cssName: '-webkit-line-clamp',
1877
+ defaultValue: 'none',
1878
+ valueChanged: (target, oldValue, newValue) => setLineClamp(target, newValue),
1879
+ });
1880
+ export const transformOriginProperty = new CssProperty({
1881
+ name: 'transformOrigin',
1882
+ cssName: 'transform-origin',
1883
+ defaultValue: '50% 50%',
1884
+ valueChanged(target, oldValue, newValue) {
1885
+ const view = getViewStyle(target.viewRef);
1886
+ if (view) {
1887
+ view.transformOrigin = newValue;
1888
+ }
1889
+ },
1890
+ });
1891
+ export const backdropFilterProperty = new CssProperty({
1892
+ name: 'backdropFilter',
1893
+ cssName: 'backdrop-filter',
1894
+ valueChanged(target, oldValue, newValue) {
1895
+ const view = getViewStyle(target.viewRef);
1896
+ if (view) {
1897
+ view.backdropFilter = newValue;
1898
+ }
1899
+ },
1900
+ });
1901
+ // CSS masking. Android and iOS parse and draw these natively, the way they do backgrounds; the
1902
+ // `mask` shorthand is split into them here, like `background`.
1903
+ export const maskImageProperty = new CssProperty({
1904
+ name: 'maskImage',
1905
+ cssName: 'mask-image',
1906
+ valueChanged(target, oldValue, newValue) {
1907
+ const view = getViewStyle(target.viewRef);
1908
+ if (view) {
1909
+ view.maskImage = newValue;
1910
+ }
1911
+ },
1912
+ });
1913
+ export const maskSizeProperty = new CssAnimationProperty({
1914
+ name: 'maskSize',
1915
+ cssName: 'mask-size',
1916
+ valueConverter: (value) => value,
1917
+ valueChanged(target, oldValue, newValue) {
1918
+ const view = getViewStyle(target.viewRef);
1919
+ if (view) {
1920
+ view.maskSize = newValue;
1921
+ }
1922
+ },
1923
+ });
1924
+ export const maskPositionProperty = new CssAnimationProperty({
1925
+ name: 'maskPosition',
1926
+ cssName: 'mask-position',
1927
+ // Keyframes keep only declarations whose property has a converter; see css-keyframes.ts.
1928
+ valueConverter: (value) => value,
1929
+ valueChanged(target, oldValue, newValue) {
1930
+ const view = getViewStyle(target.viewRef);
1931
+ if (view) {
1932
+ view.maskPosition = newValue;
1933
+ }
1934
+ },
1935
+ });
1936
+ export const maskRepeatProperty = new CssProperty({
1937
+ name: 'maskRepeat',
1938
+ cssName: 'mask-repeat',
1939
+ valueChanged(target, oldValue, newValue) {
1940
+ const view = getViewStyle(target.viewRef);
1941
+ if (view) {
1942
+ view.maskRepeat = newValue;
1943
+ }
1944
+ },
1945
+ });
1946
+ export const maskOriginProperty = new CssProperty({
1947
+ name: 'maskOrigin',
1948
+ cssName: 'mask-origin',
1949
+ valueChanged(target, oldValue, newValue) {
1950
+ const view = getViewStyle(target.viewRef);
1951
+ if (view) {
1952
+ view.maskOrigin = newValue;
1953
+ }
1954
+ },
1955
+ });
1956
+ export const maskClipProperty = new CssProperty({
1957
+ name: 'maskClip',
1958
+ cssName: 'mask-clip',
1959
+ valueChanged(target, oldValue, newValue) {
1960
+ const view = getViewStyle(target.viewRef);
1961
+ if (view) {
1962
+ view.maskClip = newValue;
1963
+ }
1964
+ },
1965
+ });
1966
+ export const maskModeProperty = new CssProperty({
1967
+ name: 'maskMode',
1968
+ cssName: 'mask-mode',
1969
+ valueChanged(target, oldValue, newValue) {
1970
+ const view = getViewStyle(target.viewRef);
1971
+ if (view) {
1972
+ view.maskMode = newValue;
1973
+ }
1974
+ },
1975
+ });
1976
+ export const maskCompositeProperty = new CssProperty({
1977
+ name: 'maskComposite',
1978
+ cssName: 'mask-composite',
1979
+ valueChanged(target, oldValue, newValue) {
1980
+ const view = getViewStyle(target.viewRef);
1981
+ if (view) {
1982
+ view.maskComposite = newValue;
1983
+ }
1984
+ },
1985
+ });
1986
+ export const clipPathProperty = new CssProperty({
1987
+ name: 'clipPath',
1988
+ cssName: 'clip-path',
1989
+ valueChanged(target, oldValue, newValue) {
1990
+ const view = getViewStyle(target.viewRef);
1991
+ if (view) {
1992
+ view.clipPath = newValue;
1993
+ }
1994
+ },
1995
+ });
1996
+ export const maskBorderSourceProperty = new CssProperty({
1997
+ name: 'maskBorderSource',
1998
+ cssName: 'mask-border-source',
1999
+ valueChanged(target, oldValue, newValue) {
2000
+ const view = getViewStyle(target.viewRef);
2001
+ if (view) {
2002
+ view.maskBorderSource = newValue;
2003
+ }
2004
+ },
2005
+ });
2006
+ export const maskBorderSliceProperty = new CssProperty({
2007
+ name: 'maskBorderSlice',
2008
+ cssName: 'mask-border-slice',
2009
+ valueChanged(target, oldValue, newValue) {
2010
+ const view = getViewStyle(target.viewRef);
2011
+ if (view) {
2012
+ view.maskBorderSlice = newValue;
2013
+ }
2014
+ },
2015
+ });
2016
+ export const maskBorderWidthProperty = new CssProperty({
2017
+ name: 'maskBorderWidth',
2018
+ cssName: 'mask-border-width',
2019
+ valueChanged(target, oldValue, newValue) {
2020
+ const view = getViewStyle(target.viewRef);
2021
+ if (view) {
2022
+ view.maskBorderWidth = newValue;
2023
+ }
2024
+ },
2025
+ });
2026
+ export const maskBorderOutsetProperty = new CssProperty({
2027
+ name: 'maskBorderOutset',
2028
+ cssName: 'mask-border-outset',
2029
+ valueChanged(target, oldValue, newValue) {
2030
+ const view = getViewStyle(target.viewRef);
2031
+ if (view) {
2032
+ view.maskBorderOutset = newValue;
2033
+ }
2034
+ },
2035
+ });
2036
+ export const maskBorderRepeatProperty = new CssProperty({
2037
+ name: 'maskBorderRepeat',
2038
+ cssName: 'mask-border-repeat',
2039
+ valueChanged(target, oldValue, newValue) {
2040
+ const view = getViewStyle(target.viewRef);
2041
+ if (view) {
2042
+ view.maskBorderRepeat = newValue;
2043
+ }
2044
+ },
2045
+ });
2046
+ export const maskBorderModeProperty = new CssProperty({
2047
+ name: 'maskBorderMode',
2048
+ cssName: 'mask-border-mode',
2049
+ valueChanged(target, oldValue, newValue) {
2050
+ const view = getViewStyle(target.viewRef);
2051
+ if (view) {
2052
+ view.maskBorderMode = newValue;
2053
+ }
2054
+ },
2055
+ });
2056
+ // The -webkit- prefixed names older and autoprefixed CSS still uses, set on the same Style
2057
+ // properties. Composite operators and box keywords are translated to the standard ones.
2058
+ // Gradient-text CSS is usually written `-webkit-background-clip: text`.
2059
+ const webkitBackgroundClipProperty = new CssProperty({
2060
+ name: 'webkitBackgroundClip',
2061
+ cssName: '-webkit-background-clip',
2062
+ valueChanged(target, oldValue, newValue) {
2063
+ const view = getViewStyle(target.viewRef);
2064
+ if (view) {
2065
+ view.backgroundClip = newValue;
2066
+ }
2067
+ },
2068
+ });
2069
+ const webkitMaskImageProperty = new CssProperty({
2070
+ name: 'webkitMaskImage',
2071
+ cssName: '-webkit-mask-image',
2072
+ valueChanged(target, oldValue, newValue) {
2073
+ const view = getViewStyle(target.viewRef);
2074
+ if (view) {
2075
+ const value = newValue;
2076
+ view.maskImage = (typeof value === 'string' ? value : value);
2077
+ }
2078
+ },
2079
+ });
2080
+ const webkitMaskSizeProperty = new CssProperty({
2081
+ name: 'webkitMaskSize',
2082
+ cssName: '-webkit-mask-size',
2083
+ valueChanged(target, oldValue, newValue) {
2084
+ const view = getViewStyle(target.viewRef);
2085
+ if (view) {
2086
+ const value = newValue;
2087
+ view.maskSize = (typeof value === 'string' ? value : value);
2088
+ }
2089
+ },
2090
+ });
2091
+ const webkitMaskPositionProperty = new CssProperty({
2092
+ name: 'webkitMaskPosition',
2093
+ cssName: '-webkit-mask-position',
2094
+ valueChanged(target, oldValue, newValue) {
2095
+ const view = getViewStyle(target.viewRef);
2096
+ if (view) {
2097
+ const value = newValue;
2098
+ view.maskPosition = (typeof value === 'string' ? value : value);
2099
+ }
2100
+ },
2101
+ });
2102
+ const webkitMaskRepeatProperty = new CssProperty({
2103
+ name: 'webkitMaskRepeat',
2104
+ cssName: '-webkit-mask-repeat',
2105
+ valueChanged(target, oldValue, newValue) {
2106
+ const view = getViewStyle(target.viewRef);
2107
+ if (view) {
2108
+ const value = newValue;
2109
+ view.maskRepeat = (typeof value === 'string' ? value : value);
2110
+ }
2111
+ },
2112
+ });
2113
+ const webkitMaskOriginProperty = new CssProperty({
2114
+ name: 'webkitMaskOrigin',
2115
+ cssName: '-webkit-mask-origin',
2116
+ valueChanged(target, oldValue, newValue) {
2117
+ const view = getViewStyle(target.viewRef);
2118
+ if (view) {
2119
+ const value = newValue;
2120
+ view.maskOrigin = (typeof value === 'string' ? webkitMaskBox(value) : value);
2121
+ }
2122
+ },
2123
+ });
2124
+ const webkitMaskClipProperty = new CssProperty({
2125
+ name: 'webkitMaskClip',
2126
+ cssName: '-webkit-mask-clip',
2127
+ valueChanged(target, oldValue, newValue) {
2128
+ const view = getViewStyle(target.viewRef);
2129
+ if (view) {
2130
+ const value = newValue;
2131
+ view.maskClip = (typeof value === 'string' ? webkitMaskBox(value) : value);
2132
+ }
2133
+ },
2134
+ });
2135
+ const webkitMaskCompositeProperty = new CssProperty({
2136
+ name: 'webkitMaskComposite',
2137
+ cssName: '-webkit-mask-composite',
2138
+ valueChanged(target, oldValue, newValue) {
2139
+ const view = getViewStyle(target.viewRef);
2140
+ if (view) {
2141
+ const value = newValue;
2142
+ view.maskComposite = (typeof value === 'string' ? webkitMaskComposite(value) : value);
2143
+ }
2144
+ },
2145
+ });
2146
+ const maskShorthand = {
2147
+ cssName: 'mask',
2148
+ longhands: [maskImageProperty, maskPositionProperty, maskSizeProperty, maskRepeatProperty, maskOriginProperty, maskClipProperty, maskCompositeProperty, maskModeProperty],
2149
+ split: splitMask,
2150
+ };
2151
+ export const maskProperty = masonShorthandProperty(maskShorthand, function () {
2152
+ return this.maskImage;
2153
+ });
2154
+ const webkitMaskShorthand = { cssName: '-webkit-mask', longhands: maskShorthand.longhands, split: splitWebkitMask };
2155
+ const webkitMaskProperty = masonShorthandProperty(webkitMaskShorthand, function () {
2156
+ return this.maskImage;
2157
+ });
2158
+ const maskBorderShorthand = {
2159
+ cssName: 'mask-border',
2160
+ longhands: [maskBorderSourceProperty, maskBorderSliceProperty, maskBorderWidthProperty, maskBorderOutsetProperty, maskBorderRepeatProperty, maskBorderModeProperty],
2161
+ split: splitMaskBorder,
2162
+ };
2163
+ export const maskBorderProperty = masonShorthandProperty(maskBorderShorthand, function () {
2164
+ return this.maskBorderSource;
2165
+ });
2166
+ // WebKit's name for mask-border.
2167
+ const webkitMaskBoxImageShorthand = { cssName: '-webkit-mask-box-image', longhands: maskBorderShorthand.longhands, split: splitMaskBorder };
2168
+ const webkitMaskBoxImageProperty = masonShorthandProperty(webkitMaskBoxImageShorthand, function () {
2169
+ return this.maskBorderSource;
2170
+ });
2171
+ export const writingModeProperty = new CssProperty({
2172
+ name: 'writingMode',
2173
+ cssName: 'writing-mode',
2174
+ defaultValue: 'horizontal-tb',
2175
+ valueChanged(target, oldValue, newValue) {
2176
+ const view = getViewStyle(target.viewRef);
2177
+ if (view) {
2178
+ view.writingMode = newValue;
2179
+ }
2180
+ },
2181
+ });
2182
+ export const unicodeBidiProperty = new CssProperty({
2183
+ name: 'unicodeBidi',
2184
+ cssName: 'unicode-bidi',
2185
+ defaultValue: 'normal',
2186
+ valueChanged(target, oldValue, newValue) {
2187
+ const view = getViewStyle(target.viewRef);
2188
+ if (view) {
2189
+ view.unicodeBidi = newValue;
2190
+ }
2191
+ },
2192
+ });
2193
+ export const caretColorProperty = new CssProperty({
2194
+ name: 'caretColor',
2195
+ cssName: 'caret-color',
2196
+ defaultValue: 'auto',
2197
+ valueChanged(target, oldValue, newValue) {
2198
+ const view = getViewStyle(target.viewRef);
2199
+ if (view) {
2200
+ view.caretColor = newValue;
2201
+ }
2202
+ },
2203
+ });
2204
+ objectPositionProperty.register(Style);
2205
+ borderTopStyleProperty.register(Style);
2206
+ borderRightStyleProperty.register(Style);
2207
+ borderBottomStyleProperty.register(Style);
2208
+ borderLeftStyleProperty.register(Style);
2209
+ borderImageProperty.register(Style);
2210
+ fontStretchProperty.register(Style);
2211
+ fontFeatureSettingsProperty.register(Style);
2212
+ wordSpacingProperty.register(Style);
2213
+ hyphensProperty.register(Style);
2214
+ textIndentProperty.register(Style);
2215
+ lineClampProperty.register(Style);
2216
+ webkitLineClampProperty.register(Style);
2217
+ transformOriginProperty.register(Style);
2218
+ backdropFilterProperty.register(Style);
2219
+ maskImageProperty.register(Style);
2220
+ maskProperty.register(Style);
2221
+ // Keyframes can animate mask position and size; see css-keyframes.ts.
2222
+ registerKeyframeProperty(maskPositionProperty, interpolatePositionList, '0% 0%');
2223
+ registerKeyframeProperty(maskSizeProperty, interpolateSizeList, 'auto');
2224
+ installKeyframes();
2225
+ // Core has its own clip-path for plain views; MasonKit views draw theirs natively.
2226
+ registerAlongsideCore(clipPathProperty);
2227
+ maskBorderSourceProperty.register(Style);
2228
+ maskBorderSliceProperty.register(Style);
2229
+ maskBorderWidthProperty.register(Style);
2230
+ maskBorderOutsetProperty.register(Style);
2231
+ maskBorderRepeatProperty.register(Style);
2232
+ maskBorderModeProperty.register(Style);
2233
+ webkitBackgroundClipProperty.register(Style);
2234
+ webkitMaskImageProperty.register(Style);
2235
+ webkitMaskSizeProperty.register(Style);
2236
+ webkitMaskPositionProperty.register(Style);
2237
+ webkitMaskRepeatProperty.register(Style);
2238
+ webkitMaskOriginProperty.register(Style);
2239
+ webkitMaskClipProperty.register(Style);
2240
+ webkitMaskCompositeProperty.register(Style);
2241
+ webkitMaskProperty.register(Style);
2242
+ maskBorderProperty.register(Style);
2243
+ webkitMaskBoxImageProperty.register(Style);
2244
+ maskSizeProperty.register(Style);
2245
+ maskPositionProperty.register(Style);
2246
+ maskRepeatProperty.register(Style);
2247
+ maskOriginProperty.register(Style);
2248
+ maskClipProperty.register(Style);
2249
+ maskModeProperty.register(Style);
2250
+ maskCompositeProperty.register(Style);
2251
+ writingModeProperty.register(Style);
2252
+ unicodeBidiProperty.register(Style);
2253
+ caretColorProperty.register(Style);
2254
+ registerAlongsideCore(backgroundImageProperty);
2255
+ // Inherited, as in CSS, so a list's value reaches its items.
2256
+ export const listStyleTypeProperty = new InheritedCssProperty({
2257
+ name: 'listStyleType',
2258
+ cssName: 'list-style-type',
2259
+ });
2260
+ export const listStylePositionProperty = new InheritedCssProperty({
2261
+ name: 'listStylePosition',
2262
+ cssName: 'list-style-position',
2263
+ });
2264
+ listStyleTypeProperty.register(Style);
2265
+ listStylePositionProperty.register(Style);
2266
+ export const listStyleShorthand = { cssName: 'list-style', longhands: [listStyleTypeProperty, listStylePositionProperty], split: splitListStyle };
2267
+ export const listStyleProperty = masonShorthandProperty(listStyleShorthand, function () {
2268
+ const style = this;
2269
+ const parts = [style.listStyleType, style.listStylePosition].filter((part) => typeof part === 'string' && part);
2270
+ return parts.join(' ');
2271
+ });
2272
+ listStyleProperty.register(Style);
2273
+ // core owns `white-space` too (its Label honours nowrap), so dispatch.
2274
+ registerAlongsideCore(whiteSpaceProperty);
2275
+ objectFitProperty.register(Style);
2276
+ touchActionProperty.register(Style);
2277
+ textJustifyProperty.register(Style);
2278
+ textDecorationThicknessProperty.register(Style);
2279
+ textDecorationLineProperty.register(Style);
2280
+ textDecorationStyleProperty.register(Style);
2281
+ textDecorationColorProperty.register(Style);
2282
+ // Core validates `text-decoration` down to none/underline/line-through, so
2283
+ // overline, the error lines, styles, colors and thicknesses never reached
2284
+ // mason. Its own elements get the raw declaration; core keeps its parser.
2285
+ const TextDecorationParse = makeParser(makeValidator('none', 'underline', 'line-through', 'underline line-through'));
2286
+ textDecorationProperty.overrideHandlers({
2287
+ valueConverter: function (value) {
2288
+ return isMasonView(this) ? value : TextDecorationParse(value);
2289
+ },
2290
+ });
2291
+ // core owns `font-family` (through its Font shorthand), so this has to dispatch
2292
+ // rather than shadow it.
2293
+ // Windows keeps core's inherited font-family, whose fontInternal reaches common.ts and resolves app fonts.
2294
+ if (!false) {
2295
+ registerAlongsideCore(fontFamilyProperty);
2296
+ }
2297
+ displayProperty.register(Style);
2298
+ /**
2299
+ * A Mason view gets core's own parse with the CSS text attached (see
2300
+ * CssLength), so core's valueChanged and layout code read a finite length
2301
+ * while Mason's setNative parses the text. Core views keep core's converter.
2302
+ */
2303
+ function keepCssOnMasonViews(longhands, core) {
2304
+ for (const property of longhands) {
2305
+ property.overrideHandlers({
2306
+ name: property.name,
2307
+ cssName: property.cssLocalName,
2308
+ valueConverter(value) {
2309
+ const css = core.keywords?.get(value.trim()) ?? value;
2310
+ return isMasonView(this) ? cssLength(css, core.converter) : core.converter(css);
2311
+ },
2312
+ // Core's parse reads `10%` and `10rem` alike, so the CSS text decides.
2313
+ equalityComparer: (a, b) => (isCssLength(a) || isCssLength(b) ? a?.css === b?.css : core.comparer(a, b)),
2314
+ });
2315
+ }
2316
+ }
2317
+ const radiusLonghands = [borderTopLeftRadiusProperty, borderTopRightRadiusProperty, borderBottomRightRadiusProperty, borderBottomLeftRadiusProperty];
2318
+ const marginLonghands = [marginTopProperty, marginRightProperty, marginBottomProperty, marginLeftProperty];
2319
+ const paddingLonghands = [paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty];
2320
+ const borderWidthLonghands = [borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty];
2321
+ const borderColorLonghands = [borderTopColorProperty, borderRightColorProperty, borderBottomColorProperty, borderLeftColorProperty];
2322
+ // Core reads `50%` as 50 and skips a parsed 0 as equal to its default, so
2323
+ // `border-radius: 0` never reached a button's native 4px radius.
2324
+ keepCssOnMasonViews(radiusLonghands, { converter: CoreLength.parse, comparer: CoreLength.equals });
2325
+ keepCssOnMasonViews(marginLonghands, { converter: CorePercentLength.parse, comparer: CorePercentLength.equals });
2326
+ keepCssOnMasonViews(paddingLonghands, { converter: CoreLength.parse, comparer: CoreLength.equals });
2327
+ keepCssOnMasonViews(borderWidthLonghands, { converter: CoreLength.parse, comparer: CoreLength.equals, keywords: BORDER_WIDTH_KEYWORDS });
2328
+ /** The shorthands core registers; MasonKit builds these only to own core 9.1's parse-time split. */
2329
+ const coreShorthands = [
2330
+ { cssName: 'border-radius', longhands: radiusLonghands, split: splitBorderRadius },
2331
+ { cssName: 'margin', longhands: marginLonghands, split: splitMargin },
2332
+ { cssName: 'padding', longhands: paddingLonghands, split: splitPadding },
2333
+ { cssName: 'border-width', longhands: borderWidthLonghands, split: splitBorderWidth },
2334
+ { cssName: 'border-color', longhands: borderColorLonghands, split: splitBorderColor },
2335
+ {
2336
+ cssName: 'background',
2337
+ longhands: [backgroundColorProperty, backgroundImageProperty, backgroundRepeatProperty, backgroundPositionProperty, backgroundSizeProperty, backgroundClipProperty, backgroundOriginProperty, backgroundAttachmentProperty],
2338
+ split: splitBackground,
2339
+ },
2340
+ ];
2341
+ for (const entry of coreShorthands) {
2342
+ masonShorthandProperty(entry);
2343
+ }
2344
+ // `border`, `border-<side>` and `border-style` expand into the width, style and
2345
+ // color longhands, so the cascade resolves each longhand on its own.
2346
+ const SIDES = ['top', 'right', 'bottom', 'left'];
2347
+ /** A longhand's value as CSS text, for the shorthand getters. */
2348
+ function cssText(value) {
2349
+ if (value == null || value === unsetValue) {
2350
+ return '';
2351
+ }
2352
+ if (typeof value === 'string') {
2353
+ return value;
2354
+ }
2355
+ if (typeof value === 'number') {
2356
+ return `${value}px`;
2357
+ }
2358
+ if (isCssLength(value)) {
2359
+ return value.css;
2360
+ }
2361
+ const { hex, unit, value: amount } = value;
2362
+ if (typeof hex === 'string') {
2363
+ return hex;
2364
+ }
2365
+ if (typeof amount === 'number') {
2366
+ return unit === '%' ? `${amount * 100}%` : `${amount}px`;
2367
+ }
2368
+ return String(value);
2369
+ }
2370
+ const borderStyleLonghands = [borderTopStyleProperty, borderRightStyleProperty, borderBottomStyleProperty, borderLeftStyleProperty];
2371
+ const borderStyleShorthand = { cssName: 'border-style', longhands: borderStyleLonghands, split: splitBorderStyle };
2372
+ const borderShorthand = { cssName: 'border', longhands: [...borderWidthLonghands, ...borderStyleLonghands, ...borderColorLonghands], split: splitBorder };
2373
+ const borderSideShorthands = [0, 1, 2, 3].map((i) => ({
2374
+ cssName: `border-${SIDES[i]}`,
2375
+ longhands: [borderWidthLonghands[i], borderStyleLonghands[i], borderColorLonghands[i]],
2376
+ split: splitBorderSide,
2377
+ }));
2378
+ function sideValues(style, longhands) {
2379
+ return longhands.map(({ name }) => cssText(style[name]));
2380
+ }
2381
+ /** The shared value when every side agrees, else undefined. */
2382
+ function uniformSides(values) {
2383
+ return values.every((value) => value === values[0]) ? values[0] : undefined;
2384
+ }
2385
+ export const borderStyleProperty = masonShorthandProperty(borderStyleShorthand, function () {
2386
+ const styles = sideValues(this, borderStyleLonghands);
2387
+ return uniformSides(styles) ?? styles.join(' ');
2388
+ });
2389
+ export const borderProperty = masonShorthandProperty(borderShorthand, function () {
2390
+ const width = uniformSides(sideValues(this, borderWidthLonghands));
2391
+ const style = uniformSides(sideValues(this, borderStyleLonghands));
2392
+ const color = uniformSides(sideValues(this, borderColorLonghands));
2393
+ return width !== undefined && style !== undefined && color !== undefined ? [width, style, color].filter(Boolean).join(' ') : '';
2394
+ });
2395
+ function borderSideGetter(i) {
2396
+ return function () {
2397
+ return sideValues(this, [borderWidthLonghands[i], borderStyleLonghands[i], borderColorLonghands[i]]).filter(Boolean).join(' ');
2398
+ };
2399
+ }
2400
+ export const borderTopProperty = masonShorthandProperty(borderSideShorthands[0], borderSideGetter(0));
2401
+ export const borderRightProperty = masonShorthandProperty(borderSideShorthands[1], borderSideGetter(1));
2402
+ export const borderBottomProperty = masonShorthandProperty(borderSideShorthands[2], borderSideGetter(2));
2403
+ export const borderLeftProperty = masonShorthandProperty(borderSideShorthands[3], borderSideGetter(3));
2404
+ borderStyleProperty.register(Style);
2405
+ borderProperty.register(Style);
2406
+ borderTopProperty.register(Style);
2407
+ borderRightProperty.register(Style);
2408
+ borderBottomProperty.register(Style);
2409
+ borderLeftProperty.register(Style);
2410
+ const LOGICAL_SIDES = [
2411
+ ['block-start', 0],
2412
+ ['inline-end', 1],
2413
+ ['block-end', 2],
2414
+ ['inline-start', 3],
2415
+ ];
2416
+ /** `<prefix>-inline<suffix>`, `<prefix>-block<suffix>` and the four `-start`/`-end` sides. */
2417
+ function logicalSides(prefix, suffix, sides, splitAxis) {
2418
+ const inline = { cssName: `${prefix}-inline${suffix}`, longhands: [sides[3], sides[1]], split: splitAxis };
2419
+ const block = { cssName: `${prefix}-block${suffix}`, longhands: [sides[0], sides[2]], split: splitAxis };
2420
+ const perSide = LOGICAL_SIDES.map(([side, i]) => ({ cssName: `${prefix}-${side}${suffix}`, longhands: [sides[i]], split: passThrough }));
2421
+ return [inline, block, ...perSide];
2422
+ }
2423
+ const borderSideLonghands = (i) => [borderWidthLonghands[i], borderStyleLonghands[i], borderColorLonghands[i]];
2424
+ const logicalShorthands = [
2425
+ ...logicalSides('margin', '', marginLonghands, splitMarginStartEnd),
2426
+ ...logicalSides('padding', '', paddingLonghands, splitPaddingStartEnd),
2427
+ ...logicalSides('inset', '', [topProperty, rightProperty, bottomProperty, leftProperty], splitInsetStartEnd),
2428
+ ...logicalSides('border', '-width', borderWidthLonghands, splitBorderWidthStartEnd),
2429
+ ...logicalSides('border', '-style', borderStyleLonghands, splitBorderStyleStartEnd),
2430
+ ...logicalSides('border', '-color', borderColorLonghands, splitBorderColorStartEnd),
2431
+ // `border-inline: 1px solid` gives both sides the same border.
2432
+ { cssName: 'border-inline', longhands: [...borderSideLonghands(3), ...borderSideLonghands(1)], split: (value) => [...splitBorderSide(value), ...splitBorderSide(value)] },
2433
+ { cssName: 'border-block', longhands: [...borderSideLonghands(0), ...borderSideLonghands(2)], split: (value) => [...splitBorderSide(value), ...splitBorderSide(value)] },
2434
+ ...LOGICAL_SIDES.map(([side, i]) => ({ cssName: `border-${side}`, longhands: borderSideLonghands(i), split: splitBorderSide })),
2435
+ // Corners are <block>-<inline>: start-start is top-left.
2436
+ { cssName: 'border-start-start-radius', longhands: [borderTopLeftRadiusProperty], split: passThrough },
2437
+ { cssName: 'border-start-end-radius', longhands: [borderTopRightRadiusProperty], split: passThrough },
2438
+ { cssName: 'border-end-end-radius', longhands: [borderBottomRightRadiusProperty], split: passThrough },
2439
+ { cssName: 'border-end-start-radius', longhands: [borderBottomLeftRadiusProperty], split: passThrough },
2440
+ { cssName: 'inline-size', longhands: [widthProperty], split: passThrough },
2441
+ { cssName: 'block-size', longhands: [heightProperty], split: passThrough },
2442
+ { cssName: 'min-inline-size', longhands: [minWidthProperty], split: passThrough },
2443
+ { cssName: 'min-block-size', longhands: [minHeightProperty], split: passThrough },
2444
+ { cssName: 'max-inline-size', longhands: [maxWidthProperty], split: passThrough },
2445
+ { cssName: 'max-block-size', longhands: [maxHeightProperty], split: passThrough },
2446
+ { cssName: 'overflow-inline', longhands: [overflowXProperty], split: passThrough },
2447
+ { cssName: 'overflow-block', longhands: [overflowYProperty], split: passThrough },
2448
+ ];
2449
+ for (const entry of logicalShorthands) {
2450
+ masonShorthandProperty(entry, function () {
2451
+ const parts = entry.longhands.map((longhand) => cssText(this[longhand.name]));
2452
+ // The axis shorthands read back as one value when both sides agree.
2453
+ return entry.longhands.length === 2 && parts[0] === parts[1] ? parts[0] : parts.join(' ');
2454
+ }).register(Style);
2455
+ }
2456
+ export const masonShorthands = [...coreShorthands, ...gridPlacementShorthands, borderStyleShorthand, borderShorthand, ...borderSideShorthands, ...logicalShorthands, overflowShorthand, maskShorthand, webkitMaskShorthand, maskBorderShorthand, webkitMaskBoxImageShorthand, gapShorthand, gridGapShorthand, flexFlowShorthand, flexShorthand];