@triniwiz/nativescript-masonkit 1.0.0-beta.85 → 1.0.0-beta.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/br/index.windows.d.ts +11 -0
- package/br/index.windows.js +31 -0
- package/br/index.windows.js.map +1 -0
- package/button/index.windows.d.ts +12 -0
- package/button/index.windows.js +44 -0
- package/button/index.windows.js.map +1 -0
- package/common.d.ts +2 -0
- package/common.js +257 -19
- package/common.js.map +1 -1
- package/img/index.windows.d.ts +12 -0
- package/img/index.windows.js +48 -0
- package/img/index.windows.js.map +1 -0
- package/index.windows.d.ts +12 -0
- package/index.windows.js +13 -0
- package/index.windows.js.map +1 -0
- package/input/index.windows.d.ts +14 -0
- package/input/index.windows.js +96 -0
- package/input/index.windows.js.map +1 -0
- package/li/index.windows.d.ts +13 -0
- package/li/index.windows.js +50 -0
- package/li/index.windows.js.map +1 -0
- package/list/common.js +0 -1
- package/list/common.js.map +1 -1
- package/list/index.ios.js +0 -1
- package/list/index.ios.js.map +1 -1
- package/list/index.windows.d.ts +21 -0
- package/list/index.windows.js +68 -0
- package/list/index.windows.js.map +1 -0
- package/package.json +6 -3
- package/platforms/ios/Mason.xcframework/ios-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios.abi.json +2640 -11192
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-ios-simulator.abi.json +2640 -11192
- package/platforms/ios/Mason.xcframework/ios-arm64_x86_64-simulator/Mason.framework/Modules/Mason.swiftmodule/x86_64-apple-ios-simulator.abi.json +2640 -11192
- package/platforms/ios/Mason.xcframework/xros-arm64/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros.abi.json +2640 -11192
- package/platforms/ios/Mason.xcframework/xros-arm64-simulator/Mason.framework/Modules/Mason.swiftmodule/arm64-apple-xros-simulator.abi.json +2640 -11192
- package/platforms/windows/arm64/NativeScript.Mason.dll +0 -0
- package/platforms/windows/arm64/NativeScript.Mason.winmd +0 -0
- package/platforms/windows/plugin.props +9 -0
- package/platforms/windows/plugin.targets +50 -0
- package/platforms/windows/x64/NativeScript.Mason.dll +0 -0
- package/platforms/windows/x64/NativeScript.Mason.winmd +0 -0
- package/scroll/index.windows.d.ts +14 -0
- package/scroll/index.windows.js +63 -0
- package/scroll/index.windows.js.map +1 -0
- package/style.d.ts +3 -0
- package/style.js +507 -5
- package/style.js.map +1 -1
- package/text/index.windows.d.ts +13 -0
- package/text/index.windows.js +39 -0
- package/text/index.windows.js.map +1 -0
- package/text-node/index.windows.d.ts +14 -0
- package/text-node/index.windows.js +42 -0
- package/text-node/index.windows.js.map +1 -0
- package/textarea/index.windows.d.ts +15 -0
- package/textarea/index.windows.js +63 -0
- package/textarea/index.windows.js.map +1 -0
- package/tree/index.windows.d.ts +36 -0
- package/tree/index.windows.js +68 -0
- package/tree/index.windows.js.map +1 -0
- package/utils/index.windows.d.ts +128 -0
- package/utils/index.windows.js +155 -0
- package/utils/index.windows.js.map +1 -0
- package/view/index.windows.d.ts +15 -0
- package/view/index.windows.js +52 -0
- package/view/index.windows.js.map +1 -0
- package/web.d.ts +2 -2
- package/web.js +2 -2
- package/web.js.map +1 -1
- package/windows-panel-helpers.d.ts +2 -0
- package/windows-panel-helpers.js +27 -0
- package/windows-panel-helpers.js.map +1 -0
package/style.js
CHANGED
|
@@ -212,6 +212,50 @@ var StyleKeys;
|
|
|
212
212
|
StyleKeys[StyleKeys["FONT_STRETCH"] = 588] = "FONT_STRETCH";
|
|
213
213
|
StyleKeys[StyleKeys["FONT_STRETCH_STATE"] = 592] = "FONT_STRETCH_STATE";
|
|
214
214
|
})(StyleKeys || (StyleKeys = {}));
|
|
215
|
+
// Windows: the native Style.UpdateGrid takes all grid strings at once. To set one while preserving
|
|
216
|
+
// the others, read the current values back from the Grid*Css getters. (Layout grid props like
|
|
217
|
+
// grid-auto-flow and gap are buffer-stored and already flow through the live style buffer.)
|
|
218
|
+
function windowsSetGrid(nativeView, field, value) {
|
|
219
|
+
const s = nativeView?.Style;
|
|
220
|
+
if (!s)
|
|
221
|
+
return;
|
|
222
|
+
const g = {
|
|
223
|
+
gridAutoRows: s.GridAutoRowsCss,
|
|
224
|
+
gridAutoColumns: s.GridAutoColumnsCss,
|
|
225
|
+
gridColumn: s.GridColumnCss,
|
|
226
|
+
gridColumnStart: s.GridColumnStartCss,
|
|
227
|
+
gridColumnEnd: s.GridColumnEndCss,
|
|
228
|
+
gridRow: s.GridRowCss,
|
|
229
|
+
gridRowStart: s.GridRowStartCss,
|
|
230
|
+
gridRowEnd: s.GridRowEndCss,
|
|
231
|
+
gridTemplateRows: s.GridTemplateRowsCss,
|
|
232
|
+
gridTemplateColumns: s.GridTemplateColumnsCss,
|
|
233
|
+
gridArea: s.GridAreaCss,
|
|
234
|
+
gridTemplateAreas: s.GridTemplateAreasCss,
|
|
235
|
+
};
|
|
236
|
+
g[field] = value ?? '';
|
|
237
|
+
// `grid-row` / `grid-column` are SHORTHANDS for their `{start,end}` pair. UpdateGrid applies the
|
|
238
|
+
// shorthand first and then the start/end parts — and the parts (read back here as their defaults
|
|
239
|
+
// before this change) would overwrite the span we just set, collapsing the item to a single track.
|
|
240
|
+
// Derive start/end from the shorthand so the three stay consistent (`span 2` -> start `span 2`,
|
|
241
|
+
// end auto; `1 / 3` -> start `1`, end `3`).
|
|
242
|
+
if (field === 'gridRow' || field === 'gridColumn') {
|
|
243
|
+
const parts = String(value ?? '')
|
|
244
|
+
.split('/')
|
|
245
|
+
.map((p) => p.trim());
|
|
246
|
+
g[field + 'Start'] = parts[0] ?? '';
|
|
247
|
+
g[field + 'End'] = parts.length > 1 ? (parts[1] ?? '') : '';
|
|
248
|
+
}
|
|
249
|
+
s.UpdateGrid(g.gridAutoRows, g.gridAutoColumns, g.gridColumn, g.gridColumnStart, g.gridColumnEnd, g.gridRow, g.gridRowStart, g.gridRowEnd, g.gridTemplateRows, g.gridTemplateColumns, g.gridArea, g.gridTemplateAreas);
|
|
250
|
+
// UpdateGrid mutates the node's (non-buffer) grid placement directly; unlike a buffer write it does
|
|
251
|
+
// not mark the node dirty / invalidate XAML measure, so a grid ITEM's placement change wouldn't
|
|
252
|
+
// re-run the parent container's grid layout. SyncStyle marks the node dirty + InvalidateMeasure,
|
|
253
|
+
// which propagates up to the container.
|
|
254
|
+
try {
|
|
255
|
+
nativeView.SyncStyle('0', '0');
|
|
256
|
+
}
|
|
257
|
+
catch (_) { }
|
|
258
|
+
}
|
|
215
259
|
function parseLengthPercentageAuto(type, value) {
|
|
216
260
|
switch (type) {
|
|
217
261
|
case 0:
|
|
@@ -383,6 +427,233 @@ const getFloat32 = (view, offset) => {
|
|
|
383
427
|
const setFloat32 = (view, offset, value) => {
|
|
384
428
|
view.setFloat32(offset, value, true);
|
|
385
429
|
};
|
|
430
|
+
// Split a comma-separated list at top level only (commas inside parentheses, e.g. rgba(0,0,0,.5),
|
|
431
|
+
// are kept with their token).
|
|
432
|
+
function splitTopLevelCommas(s) {
|
|
433
|
+
const out = [];
|
|
434
|
+
let depth = 0;
|
|
435
|
+
let cur = '';
|
|
436
|
+
for (const ch of s) {
|
|
437
|
+
if (ch === '(')
|
|
438
|
+
depth++;
|
|
439
|
+
else if (ch === ')')
|
|
440
|
+
depth = Math.max(0, depth - 1);
|
|
441
|
+
if (ch === ',' && depth === 0) {
|
|
442
|
+
out.push(cur);
|
|
443
|
+
cur = '';
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
cur += ch;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (cur.trim().length)
|
|
450
|
+
out.push(cur);
|
|
451
|
+
return out;
|
|
452
|
+
}
|
|
453
|
+
// Map a CSS gradient direction token to a CSS angle in degrees (0deg = to top, 90deg = to right).
|
|
454
|
+
function parseGradientAngle(token) {
|
|
455
|
+
const t = token.trim().toLowerCase();
|
|
456
|
+
const deg = /^(-?[\d.]+)deg$/.exec(t);
|
|
457
|
+
if (deg)
|
|
458
|
+
return parseFloat(deg[1]);
|
|
459
|
+
if (/^(-?[\d.]+)turn$/.exec(t))
|
|
460
|
+
return parseFloat(t) * 360;
|
|
461
|
+
if (/^(-?[\d.]+)rad$/.exec(t))
|
|
462
|
+
return (parseFloat(t) * 180) / Math.PI;
|
|
463
|
+
if (t === 'to top')
|
|
464
|
+
return 0;
|
|
465
|
+
if (t === 'to right')
|
|
466
|
+
return 90;
|
|
467
|
+
if (t === 'to bottom')
|
|
468
|
+
return 180;
|
|
469
|
+
if (t === 'to left')
|
|
470
|
+
return 270;
|
|
471
|
+
if (t === 'to top right' || t === 'to right top')
|
|
472
|
+
return 45;
|
|
473
|
+
if (t === 'to bottom right' || t === 'to right bottom')
|
|
474
|
+
return 135;
|
|
475
|
+
if (t === 'to bottom left' || t === 'to left bottom')
|
|
476
|
+
return 225;
|
|
477
|
+
if (t === 'to top left' || t === 'to left top')
|
|
478
|
+
return 315;
|
|
479
|
+
return 180; // CSS default is 'to bottom'
|
|
480
|
+
}
|
|
481
|
+
// Parse `linear-gradient(<dir>?, <color> <stop>?, ...)` into a CSS angle + per-stop argb + offsets.
|
|
482
|
+
function parseLinearGradientCss(value) {
|
|
483
|
+
const m = /linear-gradient\s*\(([\s\S]*)\)\s*$/i.exec(value.trim());
|
|
484
|
+
if (!m)
|
|
485
|
+
return null;
|
|
486
|
+
const parts = splitTopLevelCommas(m[1])
|
|
487
|
+
.map((p) => p.trim())
|
|
488
|
+
.filter(Boolean);
|
|
489
|
+
if (parts.length < 2)
|
|
490
|
+
return null;
|
|
491
|
+
let angle = 180;
|
|
492
|
+
let start = 0;
|
|
493
|
+
if (/^(to\s|-?[\d.]+(deg|rad|turn))/i.test(parts[0])) {
|
|
494
|
+
angle = parseGradientAngle(parts[0]);
|
|
495
|
+
start = 1;
|
|
496
|
+
}
|
|
497
|
+
const colors = [];
|
|
498
|
+
const offsets = [];
|
|
499
|
+
const stops = parts.slice(start);
|
|
500
|
+
for (let i = 0; i < stops.length; i++) {
|
|
501
|
+
// A stop is `<color> [<percentage>]`; the color is everything up to a trailing % offset.
|
|
502
|
+
const stop = stops[i];
|
|
503
|
+
const pct = /\s+(-?[\d.]+)%\s*$/.exec(stop);
|
|
504
|
+
const colorStr = pct ? stop.slice(0, pct.index).trim() : stop;
|
|
505
|
+
const argb = normalizeColorValue(colorStr);
|
|
506
|
+
if (argb == null)
|
|
507
|
+
continue;
|
|
508
|
+
colors.push(argb >>> 0);
|
|
509
|
+
offsets.push(pct ? parseFloat(pct[1]) / 100 : -1);
|
|
510
|
+
}
|
|
511
|
+
if (colors.length < 1)
|
|
512
|
+
return null;
|
|
513
|
+
// Fill any unspecified offsets evenly across [0,1].
|
|
514
|
+
for (let i = 0; i < offsets.length; i++) {
|
|
515
|
+
if (offsets[i] < 0)
|
|
516
|
+
offsets[i] = offsets.length > 1 ? i / (offsets.length - 1) : 0;
|
|
517
|
+
}
|
|
518
|
+
return { angle, offsets, colors };
|
|
519
|
+
}
|
|
520
|
+
// Parse one side of a padding/margin shorthand into a Length the buffer setters accept.
|
|
521
|
+
function parseSideLength(tok) {
|
|
522
|
+
if (typeof tok === 'number')
|
|
523
|
+
return tok;
|
|
524
|
+
const t = String(tok).trim();
|
|
525
|
+
if (t === 'auto')
|
|
526
|
+
return 'auto';
|
|
527
|
+
const m = /^(-?[\d.]+)(px|%)?$/.exec(t);
|
|
528
|
+
if (!m)
|
|
529
|
+
return 0;
|
|
530
|
+
const n = parseFloat(m[1]);
|
|
531
|
+
if (m[2] === 'px')
|
|
532
|
+
return { value: n, unit: 'px' };
|
|
533
|
+
if (m[2] === '%')
|
|
534
|
+
return { value: n, unit: '%' };
|
|
535
|
+
return n; // bare number = dip
|
|
536
|
+
}
|
|
537
|
+
// Expand a CSS padding/margin shorthand (number or 1-4 space-separated values) to per-side lengths.
|
|
538
|
+
function parseSidesShorthand(value) {
|
|
539
|
+
if (typeof value === 'number')
|
|
540
|
+
return { top: value, right: value, bottom: value, left: value };
|
|
541
|
+
const parts = String(value ?? '')
|
|
542
|
+
.trim()
|
|
543
|
+
.split(/\s+/)
|
|
544
|
+
.filter(Boolean)
|
|
545
|
+
.map(parseSideLength);
|
|
546
|
+
switch (parts.length) {
|
|
547
|
+
case 1:
|
|
548
|
+
return { top: parts[0], right: parts[0], bottom: parts[0], left: parts[0] };
|
|
549
|
+
case 2:
|
|
550
|
+
return { top: parts[0], right: parts[1], bottom: parts[0], left: parts[1] };
|
|
551
|
+
case 3:
|
|
552
|
+
return { top: parts[0], right: parts[1], bottom: parts[2], left: parts[1] };
|
|
553
|
+
case 4:
|
|
554
|
+
return { top: parts[0], right: parts[1], bottom: parts[2], left: parts[3] };
|
|
555
|
+
default:
|
|
556
|
+
return { top: 0, right: 0, bottom: 0, left: 0 };
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
// Parse a CSS `border-radius` shorthand into per-corner px radii. Handles 1-4 space-separated
|
|
560
|
+
// values (CSS order: top-left, top-right, bottom-right, bottom-left) and ignores the optional
|
|
561
|
+
// `/ <vertical>` part (we treat radii as circular). `parseFloat` strips the `px` unit.
|
|
562
|
+
function parseBorderRadiusShorthand(value) {
|
|
563
|
+
const horizontal = String(value ?? '')
|
|
564
|
+
.split('/')[0]
|
|
565
|
+
.trim();
|
|
566
|
+
const vals = horizontal.length ? horizontal.split(/\s+/).map((v) => parseFloat(v) || 0) : [0];
|
|
567
|
+
switch (vals.length) {
|
|
568
|
+
case 1:
|
|
569
|
+
return { tl: vals[0], tr: vals[0], br: vals[0], bl: vals[0] };
|
|
570
|
+
case 2:
|
|
571
|
+
return { tl: vals[0], tr: vals[1], br: vals[0], bl: vals[1] };
|
|
572
|
+
case 3:
|
|
573
|
+
return { tl: vals[0], tr: vals[1], br: vals[2], bl: vals[1] };
|
|
574
|
+
default:
|
|
575
|
+
return { tl: vals[0], tr: vals[1], br: vals[2], bl: vals[3] };
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
// Split on top-level whitespace, keeping parenthesised groups (e.g. `rgba(0,0,0,.5)`) intact.
|
|
579
|
+
function splitTopLevelSpaces(value) {
|
|
580
|
+
const out = [];
|
|
581
|
+
let depth = 0;
|
|
582
|
+
let cur = '';
|
|
583
|
+
for (let i = 0; i < value.length; i++) {
|
|
584
|
+
const ch = value[i];
|
|
585
|
+
if (ch === '(')
|
|
586
|
+
depth++;
|
|
587
|
+
else if (ch === ')')
|
|
588
|
+
depth = Math.max(0, depth - 1);
|
|
589
|
+
if (depth === 0 && /\s/.test(ch)) {
|
|
590
|
+
if (cur.length) {
|
|
591
|
+
out.push(cur);
|
|
592
|
+
cur = '';
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
cur += ch;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
if (cur.length)
|
|
600
|
+
out.push(cur);
|
|
601
|
+
return out;
|
|
602
|
+
}
|
|
603
|
+
// Parse a `border` / `border-<side>` shorthand (`<width> <style> <color>`, any order) into px width,
|
|
604
|
+
// border-style enum and argb color; each is null when absent.
|
|
605
|
+
function parseBorderShorthand(value) {
|
|
606
|
+
let width = null;
|
|
607
|
+
let style = null;
|
|
608
|
+
let color = null;
|
|
609
|
+
for (const tok of splitTopLevelSpaces(String(value ?? '').trim())) {
|
|
610
|
+
const s = borderStyleToEnum(tok);
|
|
611
|
+
if (s !== -1) {
|
|
612
|
+
style = s;
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
const lower = tok.toLowerCase();
|
|
616
|
+
if (lower === 'thin') {
|
|
617
|
+
width = 1;
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
if (lower === 'medium') {
|
|
621
|
+
width = 3;
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
if (lower === 'thick') {
|
|
625
|
+
width = 5;
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
if (/^-?\d*\.?\d+(px|dip|dp|rem|em|pt)?$/i.test(tok)) {
|
|
629
|
+
const n = parseFloat(tok);
|
|
630
|
+
if (!isNaN(n)) {
|
|
631
|
+
width = n;
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
const c = normalizeColorValue(tok);
|
|
636
|
+
if (c != null)
|
|
637
|
+
color = c;
|
|
638
|
+
}
|
|
639
|
+
return { width, style, color };
|
|
640
|
+
}
|
|
641
|
+
// Parse a 1-4 token `border-color` shorthand into per-side argb (CSS order top/right/bottom/left).
|
|
642
|
+
function parseSidesColorShorthand(value) {
|
|
643
|
+
const cols = splitTopLevelSpaces(String(value ?? '').trim()).map((t) => normalizeColorValue(t));
|
|
644
|
+
switch (cols.length) {
|
|
645
|
+
case 0:
|
|
646
|
+
return { t: null, r: null, b: null, l: null };
|
|
647
|
+
case 1:
|
|
648
|
+
return { t: cols[0], r: cols[0], b: cols[0], l: cols[0] };
|
|
649
|
+
case 2:
|
|
650
|
+
return { t: cols[0], r: cols[1], b: cols[0], l: cols[1] };
|
|
651
|
+
case 3:
|
|
652
|
+
return { t: cols[0], r: cols[1], b: cols[2], l: cols[1] };
|
|
653
|
+
default:
|
|
654
|
+
return { t: cols[0], r: cols[1], b: cols[2], l: cols[3] };
|
|
655
|
+
}
|
|
656
|
+
}
|
|
386
657
|
const i8Buffer = new Int8Array(4);
|
|
387
658
|
const f32Buffer = new Uint8Array(Float32Array.BYTES_PER_ELEMENT * 4);
|
|
388
659
|
const f32View = new Float32Array(f32Buffer.buffer);
|
|
@@ -515,6 +786,20 @@ export class Style {
|
|
|
515
786
|
ret.i8View = new Int8Array(buffer);
|
|
516
787
|
ret.u8View = new Uint8Array(buffer);
|
|
517
788
|
}
|
|
789
|
+
else if (__WINDOWS__) {
|
|
790
|
+
let style = nativeView?.Style;
|
|
791
|
+
if (!style) {
|
|
792
|
+
style = NativeScript.Mason.Mason.Instance().CreateNode(false).Style;
|
|
793
|
+
}
|
|
794
|
+
// Live IBuffer over the engine's arena style memory; the @nativescript/windows runtime
|
|
795
|
+
// projects it as a writable ArrayBuffer, so the same StyleKeys-offset writes used on
|
|
796
|
+
// iOS/Android land straight in the node's style.
|
|
797
|
+
//@ts-ignore
|
|
798
|
+
const buffer = NSWinRT.interop.arrayBufferFromBuffer(style.Values);
|
|
799
|
+
ret.style_view = new DataView(buffer);
|
|
800
|
+
ret.i8View = new Int8Array(buffer);
|
|
801
|
+
ret.u8View = new Uint8Array(buffer);
|
|
802
|
+
}
|
|
518
803
|
//console.timeEnd('fromView');
|
|
519
804
|
return ret;
|
|
520
805
|
}
|
|
@@ -626,6 +911,140 @@ export class Style {
|
|
|
626
911
|
applyApple();
|
|
627
912
|
}
|
|
628
913
|
}
|
|
914
|
+
if (__WINDOWS__) {
|
|
915
|
+
// Android/Apple parse these CSS-string props in native setters; on Windows we write the
|
|
916
|
+
// buffer-backed ones (border-radius) directly to the live style buffer so VisualApply renders
|
|
917
|
+
// them. Border stroke / box-shadow / gradients still need the Css decoration overlay (TODO).
|
|
918
|
+
this.applyWindowsCssString(name, value);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
// Apply a CSS-string property on Windows. Buffer-backed props (border-radius) are written to the
|
|
922
|
+
// live style buffer for VisualApply; gradients use the native Css helper to paint the Panel
|
|
923
|
+
// background directly.
|
|
924
|
+
applyWindowsCssString(name, value) {
|
|
925
|
+
// `background` shorthand: gradient -> native Css gradient brush; solid color -> BACKGROUND_COLOR
|
|
926
|
+
// buffer (VisualApply paints it). Switching between them must override the other, so a gradient
|
|
927
|
+
// clears the solid bg first, and a solid write lets VisualApply repaint over a prior gradient brush.
|
|
928
|
+
if (name === 'background' || name === 'background-image') {
|
|
929
|
+
const v = typeof value === 'string' ? value : String(value ?? '');
|
|
930
|
+
if (/linear-gradient/i.test(v)) {
|
|
931
|
+
const g = parseLinearGradientCss(v);
|
|
932
|
+
if (g && g.colors.length) {
|
|
933
|
+
if (this.style_view) {
|
|
934
|
+
this.prepareMut();
|
|
935
|
+
setUint32(this.style_view, StyleKeys.BACKGROUND_COLOR, 0);
|
|
936
|
+
this.commitState(StateKeys.BACKGROUND_COLOR);
|
|
937
|
+
}
|
|
938
|
+
try {
|
|
939
|
+
// Pass stops as an "offset:argb,..." string — WinRT array_view params don't marshal
|
|
940
|
+
// reliably from the NS-Windows JS runtime (plain arrays -> E_FAIL, typed arrays -> crash).
|
|
941
|
+
const stops = g.offsets.map((o, i) => o + ':' + (g.colors[i] >>> 0)).join(',');
|
|
942
|
+
NativeScript.Mason.Css.ApplyLinearGradient(this.nativeView, g.angle, stops);
|
|
943
|
+
}
|
|
944
|
+
catch (_) { }
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
else if (v.trim().length && !/gradient/i.test(v)) {
|
|
948
|
+
// Solid color background; reuse the backgroundColor buffer setter -> VisualApply repaints,
|
|
949
|
+
// overriding any gradient brush set previously.
|
|
950
|
+
this.backgroundColor = v;
|
|
951
|
+
}
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
// padding / margin SHORTHANDS route here (paddingProperty/marginProperty -> paddingCss/marginCss).
|
|
955
|
+
// Expand to the per-side buffer setters, which Mason already applies in layout.
|
|
956
|
+
if (name === 'padding' || name === 'margin') {
|
|
957
|
+
const s = parseSidesShorthand(value);
|
|
958
|
+
if (name === 'padding') {
|
|
959
|
+
this.paddingTop = s.top;
|
|
960
|
+
this.paddingRight = s.right;
|
|
961
|
+
this.paddingBottom = s.bottom;
|
|
962
|
+
this.paddingLeft = s.left;
|
|
963
|
+
}
|
|
964
|
+
else {
|
|
965
|
+
this.marginTop = s.top;
|
|
966
|
+
this.marginRight = s.right;
|
|
967
|
+
this.marginBottom = s.bottom;
|
|
968
|
+
this.marginLeft = s.left;
|
|
969
|
+
}
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
if (!this.style_view) {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
if (name === 'border-radius') {
|
|
976
|
+
const r = parseBorderRadiusShorthand(value);
|
|
977
|
+
this.prepareMut();
|
|
978
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_TOP_LEFT_X_VALUE, r.tl);
|
|
979
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_TOP_LEFT_Y_VALUE, r.tl);
|
|
980
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_TOP_RIGHT_X_VALUE, r.tr);
|
|
981
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_TOP_RIGHT_Y_VALUE, r.tr);
|
|
982
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_RIGHT_X_VALUE, r.br);
|
|
983
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_RIGHT_Y_VALUE, r.br);
|
|
984
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_LEFT_X_VALUE, r.bl);
|
|
985
|
+
setFloat32(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_LEFT_Y_VALUE, r.bl);
|
|
986
|
+
// Type bytes: 0 = length (px).
|
|
987
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_TOP_LEFT_X_TYPE, 0);
|
|
988
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_TOP_LEFT_Y_TYPE, 0);
|
|
989
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_TOP_RIGHT_X_TYPE, 0);
|
|
990
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_TOP_RIGHT_Y_TYPE, 0);
|
|
991
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_RIGHT_X_TYPE, 0);
|
|
992
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_RIGHT_Y_TYPE, 0);
|
|
993
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_LEFT_X_TYPE, 0);
|
|
994
|
+
setUint8(this.style_view, StyleKeys.BORDER_RADIUS_BOTTOM_LEFT_Y_TYPE, 0);
|
|
995
|
+
this.commitState(StateKeys.BORDER_RADIUS);
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (name === 'border' || name === 'border-top' || name === 'border-right' || name === 'border-bottom' || name === 'border-left') {
|
|
999
|
+
const p = parseBorderShorthand(value);
|
|
1000
|
+
let style = p.style;
|
|
1001
|
+
if (style == null && (p.width != null || p.color != null))
|
|
1002
|
+
style = 4; // solid
|
|
1003
|
+
const sides = name === 'border' ? ['left', 'right', 'top', 'bottom'] : name === 'border-left' ? ['left'] : name === 'border-right' ? ['right'] : name === 'border-top' ? ['top'] : ['bottom'];
|
|
1004
|
+
for (const s of sides)
|
|
1005
|
+
this.writeBorderSide(s, p.width, style, p.color);
|
|
1006
|
+
this.commitState(StateKeys.BORDER);
|
|
1007
|
+
this.commitState(StateKeys.BORDER_STYLE);
|
|
1008
|
+
this.commitState(StateKeys.BORDER_COLOR);
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
if (name === 'border-color') {
|
|
1012
|
+
const c = parseSidesColorShorthand(value);
|
|
1013
|
+
this.writeBorderSide('top', null, null, c.t);
|
|
1014
|
+
this.writeBorderSide('right', null, null, c.r);
|
|
1015
|
+
this.writeBorderSide('bottom', null, null, c.b);
|
|
1016
|
+
this.writeBorderSide('left', null, null, c.l);
|
|
1017
|
+
this.commitState(StateKeys.BORDER_COLOR);
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
// Write one side's border width/style/color into the style buffer; null components are skipped.
|
|
1022
|
+
writeBorderSide(side, width, style, color) {
|
|
1023
|
+
if (!this.style_view)
|
|
1024
|
+
return;
|
|
1025
|
+
const W = side === 'left' ? StyleKeys.BORDER_LEFT_VALUE : side === 'right' ? StyleKeys.BORDER_RIGHT_VALUE : side === 'top' ? StyleKeys.BORDER_TOP_VALUE : StyleKeys.BORDER_BOTTOM_VALUE;
|
|
1026
|
+
const T = side === 'left' ? StyleKeys.BORDER_LEFT_TYPE : side === 'right' ? StyleKeys.BORDER_RIGHT_TYPE : side === 'top' ? StyleKeys.BORDER_TOP_TYPE : StyleKeys.BORDER_BOTTOM_TYPE;
|
|
1027
|
+
const S = side === 'left' ? StyleKeys.BORDER_LEFT_STYLE : side === 'right' ? StyleKeys.BORDER_RIGHT_STYLE : side === 'top' ? StyleKeys.BORDER_TOP_STYLE : StyleKeys.BORDER_BOTTOM_STYLE;
|
|
1028
|
+
const C = side === 'left' ? StyleKeys.BORDER_LEFT_COLOR : side === 'right' ? StyleKeys.BORDER_RIGHT_COLOR : side === 'top' ? StyleKeys.BORDER_TOP_COLOR : StyleKeys.BORDER_BOTTOM_COLOR;
|
|
1029
|
+
this.prepareMut();
|
|
1030
|
+
if (width != null) {
|
|
1031
|
+
setInt8(this.style_view, T, 0);
|
|
1032
|
+
setFloat32(this.style_view, W, width);
|
|
1033
|
+
}
|
|
1034
|
+
if (style != null)
|
|
1035
|
+
setInt8(this.style_view, S, style);
|
|
1036
|
+
if (color != null)
|
|
1037
|
+
setUint32(this.style_view, C, color >>> 0);
|
|
1038
|
+
}
|
|
1039
|
+
setBorderColor(value) {
|
|
1040
|
+
if (!__WINDOWS__ || !this.style_view)
|
|
1041
|
+
return;
|
|
1042
|
+
const c = parseSidesColorShorthand(String(value ?? ''));
|
|
1043
|
+
this.writeBorderSide('top', null, null, c.t);
|
|
1044
|
+
this.writeBorderSide('right', null, null, c.r);
|
|
1045
|
+
this.writeBorderSide('bottom', null, null, c.b);
|
|
1046
|
+
this.writeBorderSide('left', null, null, c.l);
|
|
1047
|
+
this.commitState(StateKeys.BORDER_COLOR);
|
|
629
1048
|
}
|
|
630
1049
|
resetState() {
|
|
631
1050
|
this.isDirty = -1n;
|
|
@@ -643,6 +1062,11 @@ export class Style {
|
|
|
643
1062
|
// @ts-ignore
|
|
644
1063
|
view.mason_syncStyle(low, high);
|
|
645
1064
|
}
|
|
1065
|
+
else if (__WINDOWS__) {
|
|
1066
|
+
// @ts-ignore
|
|
1067
|
+
const view = this.view?.windows ?? this.view._view;
|
|
1068
|
+
view.SyncStyle(low, high);
|
|
1069
|
+
}
|
|
646
1070
|
this.resetState();
|
|
647
1071
|
}
|
|
648
1072
|
setOrAppendState(value) {
|
|
@@ -709,6 +1133,17 @@ export class Style {
|
|
|
709
1133
|
this.i8View = new Int8Array(buffer);
|
|
710
1134
|
this.u8View = new Uint8Array(buffer);
|
|
711
1135
|
}
|
|
1136
|
+
if (__WINDOWS__) {
|
|
1137
|
+
let style = this.nativeView?.Style;
|
|
1138
|
+
if (!style) {
|
|
1139
|
+
style = NativeScript.Mason.Mason.Instance().CreateNode(false).Style;
|
|
1140
|
+
}
|
|
1141
|
+
style.PrepareForMutation();
|
|
1142
|
+
const buffer = style.Values;
|
|
1143
|
+
this.style_view = new DataView(buffer);
|
|
1144
|
+
this.i8View = new Int8Array(buffer);
|
|
1145
|
+
this.u8View = new Uint8Array(buffer);
|
|
1146
|
+
}
|
|
712
1147
|
}
|
|
713
1148
|
}
|
|
714
1149
|
get boxSizing() {
|
|
@@ -1212,10 +1647,27 @@ export class Style {
|
|
|
1212
1647
|
}
|
|
1213
1648
|
set width(value) {
|
|
1214
1649
|
switch (typeof value) {
|
|
1215
|
-
case 'string':
|
|
1650
|
+
case 'string': {
|
|
1651
|
+
// Parse the string instead of forcing `auto`. Reactively-applied sizes arrive as strings
|
|
1652
|
+
// ("48", "48px", "50%") — the old stub dropped them to auto (0), so dynamically-added boxes
|
|
1653
|
+
// rendered 0x0. unitless/dip → device pixels; px → as-is; % → percent.
|
|
1216
1654
|
this.prepareMut();
|
|
1217
|
-
|
|
1655
|
+
const t = value.trim();
|
|
1656
|
+
if (t === '' || t === 'auto') {
|
|
1657
|
+
setInt8(this.style_view, StyleKeys.WIDTH_TYPE, 0);
|
|
1658
|
+
setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, 0);
|
|
1659
|
+
}
|
|
1660
|
+
else if (t.endsWith('%')) {
|
|
1661
|
+
setInt8(this.style_view, StyleKeys.WIDTH_TYPE, 2);
|
|
1662
|
+
setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, parseFloat(t) || 0);
|
|
1663
|
+
}
|
|
1664
|
+
else {
|
|
1665
|
+
const n = parseFloat(t) || 0;
|
|
1666
|
+
setInt8(this.style_view, StyleKeys.WIDTH_TYPE, 1);
|
|
1667
|
+
setFloat32(this.style_view, StyleKeys.WIDTH_VALUE, t.endsWith('px') ? n : layout.toDevicePixels(n));
|
|
1668
|
+
}
|
|
1218
1669
|
break;
|
|
1670
|
+
}
|
|
1219
1671
|
case 'number':
|
|
1220
1672
|
this.prepareMut();
|
|
1221
1673
|
setInt8(this.style_view, StyleKeys.WIDTH_TYPE, 1);
|
|
@@ -1250,11 +1702,25 @@ export class Style {
|
|
|
1250
1702
|
}
|
|
1251
1703
|
set height(value) {
|
|
1252
1704
|
switch (typeof value) {
|
|
1253
|
-
case 'string':
|
|
1705
|
+
case 'string': {
|
|
1706
|
+
// Parse the string (see width setter) — the old stub forced auto/0, breaking string sizes.
|
|
1254
1707
|
this.prepareMut();
|
|
1255
|
-
|
|
1256
|
-
|
|
1708
|
+
const t = value.trim();
|
|
1709
|
+
if (t === '' || t === 'auto') {
|
|
1710
|
+
setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, 0);
|
|
1711
|
+
setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, 0);
|
|
1712
|
+
}
|
|
1713
|
+
else if (t.endsWith('%')) {
|
|
1714
|
+
setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, 2);
|
|
1715
|
+
setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, parseFloat(t) || 0);
|
|
1716
|
+
}
|
|
1717
|
+
else {
|
|
1718
|
+
const n = parseFloat(t) || 0;
|
|
1719
|
+
setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, 1);
|
|
1720
|
+
setFloat32(this.style_view, StyleKeys.HEIGHT_VALUE, t.endsWith('px') ? n : layout.toDevicePixels(n));
|
|
1721
|
+
}
|
|
1257
1722
|
break;
|
|
1723
|
+
}
|
|
1258
1724
|
case 'number':
|
|
1259
1725
|
this.prepareMut();
|
|
1260
1726
|
setInt8(this.style_view, StyleKeys.HEIGHT_TYPE, 1);
|
|
@@ -2520,6 +2986,9 @@ export class Style {
|
|
|
2520
2986
|
if (__APPLE__) {
|
|
2521
2987
|
this.nativeView.style.gridAutoRows = value;
|
|
2522
2988
|
}
|
|
2989
|
+
if (__WINDOWS__) {
|
|
2990
|
+
windowsSetGrid(this.nativeView, 'gridAutoRows', value);
|
|
2991
|
+
}
|
|
2523
2992
|
}
|
|
2524
2993
|
get gridAutoColumns() {
|
|
2525
2994
|
if (!this.nativeView) {
|
|
@@ -2543,6 +3012,9 @@ export class Style {
|
|
|
2543
3012
|
if (__APPLE__) {
|
|
2544
3013
|
this.nativeView.style.gridAutoColumns = value;
|
|
2545
3014
|
}
|
|
3015
|
+
if (__WINDOWS__) {
|
|
3016
|
+
windowsSetGrid(this.nativeView, 'gridAutoColumns', value);
|
|
3017
|
+
}
|
|
2546
3018
|
}
|
|
2547
3019
|
get gridAutoFlow() {
|
|
2548
3020
|
switch (getInt8(this.style_view, StyleKeys.GRID_AUTO_FLOW)) {
|
|
@@ -2586,6 +3058,9 @@ export class Style {
|
|
|
2586
3058
|
if (__APPLE__) {
|
|
2587
3059
|
this.nativeView.style.gridColumn = value;
|
|
2588
3060
|
}
|
|
3061
|
+
if (__WINDOWS__) {
|
|
3062
|
+
windowsSetGrid(this.nativeView, 'gridColumn', value);
|
|
3063
|
+
}
|
|
2589
3064
|
}
|
|
2590
3065
|
get gridColumn() {
|
|
2591
3066
|
if (!this.nativeView) {
|
|
@@ -2621,6 +3096,9 @@ export class Style {
|
|
|
2621
3096
|
if (__APPLE__) {
|
|
2622
3097
|
this.nativeView.style.gridColumnStart = value;
|
|
2623
3098
|
}
|
|
3099
|
+
if (__WINDOWS__) {
|
|
3100
|
+
windowsSetGrid(this.nativeView, 'gridColumnStart', value);
|
|
3101
|
+
}
|
|
2624
3102
|
}
|
|
2625
3103
|
get gridColumnEnd() {
|
|
2626
3104
|
if (!this.nativeView) {
|
|
@@ -2644,6 +3122,9 @@ export class Style {
|
|
|
2644
3122
|
if (__APPLE__) {
|
|
2645
3123
|
this.nativeView.style.gridColumnEnd = value;
|
|
2646
3124
|
}
|
|
3125
|
+
if (__WINDOWS__) {
|
|
3126
|
+
windowsSetGrid(this.nativeView, 'gridColumnEnd', value);
|
|
3127
|
+
}
|
|
2647
3128
|
}
|
|
2648
3129
|
set gridRow(value) {
|
|
2649
3130
|
if (!this.nativeView) {
|
|
@@ -2655,6 +3136,9 @@ export class Style {
|
|
|
2655
3136
|
if (__APPLE__) {
|
|
2656
3137
|
this.nativeView.style.gridRow = value;
|
|
2657
3138
|
}
|
|
3139
|
+
if (__WINDOWS__) {
|
|
3140
|
+
windowsSetGrid(this.nativeView, 'gridRow', value);
|
|
3141
|
+
}
|
|
2658
3142
|
}
|
|
2659
3143
|
get gridRow() {
|
|
2660
3144
|
if (!this.nativeView) {
|
|
@@ -2690,6 +3174,9 @@ export class Style {
|
|
|
2690
3174
|
if (__APPLE__) {
|
|
2691
3175
|
this.nativeView.style.gridRowStart = value;
|
|
2692
3176
|
}
|
|
3177
|
+
if (__WINDOWS__) {
|
|
3178
|
+
windowsSetGrid(this.nativeView, 'gridRowStart', value);
|
|
3179
|
+
}
|
|
2693
3180
|
}
|
|
2694
3181
|
get gridRowEnd() {
|
|
2695
3182
|
if (!this.nativeView) {
|
|
@@ -2713,6 +3200,9 @@ export class Style {
|
|
|
2713
3200
|
if (__APPLE__) {
|
|
2714
3201
|
this.nativeView.style.gridRowEnd = value;
|
|
2715
3202
|
}
|
|
3203
|
+
if (__WINDOWS__) {
|
|
3204
|
+
windowsSetGrid(this.nativeView, 'gridRowEnd', value);
|
|
3205
|
+
}
|
|
2716
3206
|
}
|
|
2717
3207
|
set gridArea(value) {
|
|
2718
3208
|
if (!this.nativeView) {
|
|
@@ -2724,6 +3214,9 @@ export class Style {
|
|
|
2724
3214
|
if (__APPLE__) {
|
|
2725
3215
|
this.nativeView.style.gridArea = value;
|
|
2726
3216
|
}
|
|
3217
|
+
if (__WINDOWS__) {
|
|
3218
|
+
windowsSetGrid(this.nativeView, 'gridArea', value);
|
|
3219
|
+
}
|
|
2727
3220
|
}
|
|
2728
3221
|
get gridArea() {
|
|
2729
3222
|
if (!this.nativeView) {
|
|
@@ -2750,6 +3243,9 @@ export class Style {
|
|
|
2750
3243
|
if (__APPLE__) {
|
|
2751
3244
|
this.nativeView.style.gridTemplateRows = value;
|
|
2752
3245
|
}
|
|
3246
|
+
if (__WINDOWS__) {
|
|
3247
|
+
windowsSetGrid(this.nativeView, 'gridTemplateRows', value);
|
|
3248
|
+
}
|
|
2753
3249
|
}
|
|
2754
3250
|
get gridTemplateRows() {
|
|
2755
3251
|
if (!this.nativeView) {
|
|
@@ -2788,6 +3284,9 @@ export class Style {
|
|
|
2788
3284
|
if (__APPLE__) {
|
|
2789
3285
|
this.nativeView.style.gridTemplateColumns = value;
|
|
2790
3286
|
}
|
|
3287
|
+
if (__WINDOWS__) {
|
|
3288
|
+
windowsSetGrid(this.nativeView, 'gridTemplateColumns', value);
|
|
3289
|
+
}
|
|
2791
3290
|
}
|
|
2792
3291
|
get gridTemplateAreas() {
|
|
2793
3292
|
if (!this.nativeView) {
|
|
@@ -2813,6 +3312,9 @@ export class Style {
|
|
|
2813
3312
|
if (__APPLE__) {
|
|
2814
3313
|
this.nativeView.style.gridTemplateAreas = value;
|
|
2815
3314
|
}
|
|
3315
|
+
if (__WINDOWS__) {
|
|
3316
|
+
windowsSetGrid(this.nativeView, 'gridTemplateAreas', value);
|
|
3317
|
+
}
|
|
2816
3318
|
}
|
|
2817
3319
|
get overflow() {
|
|
2818
3320
|
const x = this.overflowX;
|