@octane-xplat/patches 0.16.1 → 0.17.0
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/package.json +1 -1
- package/patches/@nativescript-community__octane@0.2.5.patch +335 -174
- package/patches/@nativescript-community__vite-octane@0.2.1.patch +35 -4
- package/patches/{@nativescript__vite@8.0.17.patch → @nativescript__vite@8.0.20.patch} +171 -164
- package/patches/{octane@0.11.0.patch → octane@0.14.0.patch} +272 -393
- package/patches/shaders@4.0.0.patch +60 -0
- package/patches/@nativescript-community__ui-image@5.0.17.patch +0 -30
- package/patches/@triniwiz__nativescript-masonkit@1.0.0-beta.110.patch +0 -13
|
@@ -1,16 +1,45 @@
|
|
|
1
|
+
diff --git a/dist/driver.d.ts b/dist/driver.d.ts
|
|
2
|
+
index 80e30299c44e889e3a066ce2c9a8feb6b7ceaa42..b17dc120c5c00ba4be701233fb95b6d2b3eb72d9 100644
|
|
3
|
+
--- a/dist/driver.d.ts
|
|
4
|
+
+++ b/dist/driver.d.ts
|
|
5
|
+
@@ -14,6 +14,9 @@ interface HostNode {
|
|
6
|
+
readonly muted: Set<string>;
|
|
7
|
+
/** Whether this node's `text` has been driven by `#text` children. */
|
|
8
|
+
textApplied: boolean;
|
|
9
|
+
+ readonly propDefaults: Map<string, unknown>;
|
|
10
|
+
+ readonly styleDefaults: Map<string, unknown>;
|
|
11
|
+
+ styleKeys: Set<string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A command `parent`: a host node id's node, the root container (`null`), or a
|
|
1
15
|
diff --git a/dist/driver.js b/dist/driver.js
|
|
2
|
-
index
|
|
16
|
+
index 8bc563add4cb675a12651184b63805b10224274d..ca251841c91abdd8c254fb6307e5af09f0707c0f 100644
|
|
3
17
|
--- a/dist/driver.js
|
|
4
18
|
+++ b/dist/driver.js
|
|
5
|
-
@@ -
|
|
19
|
+
@@ -1,8 +1,11 @@
|
|
20
|
+
-import { ActionBar, ContentView, FormattedString, LayoutBase, ListView, Span, TabView, TabViewItem, TextBase, View, unsetValue, } from '@nativescript/core';
|
|
21
|
+
+import { cssTreeParse } from '@nativescript/core/css/css-tree-parser';
|
|
22
|
+
+import { _getProperties, _getStyleProperties, } from '@nativescript/core/ui/core/properties';
|
|
23
|
+
+import { ActionBar, ContentView, FormattedString, LayoutBase, ListView, Span, TabView, TabViewItem, TextBase, View, Utils, unsetValue, } from '@nativescript/core';
|
|
24
|
+
import { createUniversalRoot, } from 'octane/universal/native';
|
|
6
25
|
import { NATIVESCRIPT_RENDERER_ID } from './config.js';
|
|
7
26
|
import { ELEMENTS, EVENT_PROP, eventNameFor, onElementReplaced, } from './elements.js';
|
|
8
27
|
import { releaseListView, setRenderItem, } from './list-view.js';
|
|
9
|
-
+import { Style as MasonStyle } from '@
|
|
28
|
+
+import { Style as MasonStyle } from '@octane-xplat/nativescript-masonkit/style';
|
|
10
29
|
/** `#text` nodes carry no view; the driver folds them into the parent's `text`. */
|
|
11
30
|
const TEXT = '#text';
|
|
12
31
|
/**
|
|
13
|
-
@@ -
|
|
32
|
+
@@ -62,6 +65,9 @@ function createNode(container, id, type, props) {
|
|
33
|
+
listeners: new Map(),
|
|
34
|
+
muted: new Set(),
|
|
35
|
+
textApplied: false,
|
|
36
|
+
+ propDefaults: new Map(),
|
|
37
|
+
+ styleDefaults: new Map(),
|
|
38
|
+
+ styleKeys: new Set(),
|
|
39
|
+
};
|
|
40
|
+
if (node.view !== null)
|
|
41
|
+
viewOwners.set(node.view, { container, node });
|
|
42
|
+
@@ -73,7 +79,10 @@ function instantiate(type) {
|
|
14
43
|
if (Element === undefined) {
|
|
15
44
|
throw new Error(`NativeScript driver: <${type}> is not a registered element.`);
|
|
16
45
|
}
|
|
@@ -22,35 +51,46 @@ index 8bc563a..4cb1f95 100644
|
|
|
22
51
|
}
|
|
23
52
|
function applyProps(node, props) {
|
|
24
53
|
if (node.view === null) {
|
|
25
|
-
@@ -
|
|
54
|
+
@@ -90,14 +99,16 @@ function applyProps(node, props) {
|
|
55
|
+
setProp(node, node.view, name, props[name]);
|
|
26
56
|
}
|
|
27
57
|
}
|
|
28
|
-
|
|
58
|
+
-/**
|
|
29
59
|
- * `update` carries the host's dynamic-prop snapshot; attributes that were
|
|
30
60
|
- * static in the compiled plan arrive only with `create`. Merge instead of
|
|
31
61
|
- * replace, or a first update would strip a node's static layout props.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
+ * installed returns to the prop's documented default. `undefined` never
|
|
35
|
-
+ * crosses the wire (the runtime elides it); `null` is "not supplied" for
|
|
36
|
-
+ * props without an explicit nullable contract — both reset through setProp.
|
|
37
|
-
*/
|
|
62
|
+
- */
|
|
63
|
+
+/** `update` is the complete next bag, including the plan's static props. */
|
|
38
64
|
function updateProps(node, next) {
|
|
39
|
-
+ const
|
|
40
|
-
+
|
|
41
|
-
+
|
|
42
|
-
+ dropped.push(name);
|
|
65
|
+
+ for (const name of Object.keys(node.props)) {
|
|
66
|
+
+ if (!Object.hasOwn(next, name) && node.view !== null)
|
|
67
|
+
+ setProp(node, node.view, name, undefined);
|
|
43
68
|
+ }
|
|
44
69
|
applyProps(node, next);
|
|
45
70
|
- node.props = { ...node.props, ...next };
|
|
46
|
-
+ for (const name of dropped) {
|
|
47
|
-
+ resetProp(node, node.view, name);
|
|
48
|
-
+ }
|
|
49
71
|
+ node.props = next;
|
|
72
|
+
+ if (node.parent !== null && MASON_CONTAINER_TAGS.has(node.parent.type))
|
|
73
|
+
+ applyMasonChildLayout(node, node.parent);
|
|
50
74
|
}
|
|
51
75
|
function setProp(node, view, name, value) {
|
|
52
76
|
if (name === 'children' || name === 'key' || name === 'ref')
|
|
53
|
-
@@ -
|
|
77
|
+
@@ -105,6 +116,15 @@ function setProp(node, view, name, value) {
|
|
78
|
+
// Event props arrive as their own `event` commands.
|
|
79
|
+
if (EVENT_PROP.test(name))
|
|
80
|
+
return;
|
|
81
|
+
+ if (value === undefined &&
|
|
82
|
+
+ !node.propDefaults.has(name) &&
|
|
83
|
+
+ (name !== 'style' || node.styleKeys.size === 0))
|
|
84
|
+
+ return;
|
|
85
|
+
+ if (value != null &&
|
|
86
|
+
+ value !== unsetValue &&
|
|
87
|
+
+ name !== 'style' &&
|
|
88
|
+
+ !node.propDefaults.has(name))
|
|
89
|
+
+ node.propDefaults.set(name, view[name]);
|
|
90
|
+
if (name === 'className' || name === 'class') {
|
|
91
|
+
view.className =
|
|
92
|
+
value == null || value === unsetValue
|
|
93
|
+
@@ -113,13 +133,31 @@ function setProp(node, view, name, value) {
|
|
54
94
|
return;
|
|
55
95
|
}
|
|
56
96
|
if (name === 'style') {
|
|
@@ -70,147 +110,126 @@ index 8bc563a..4cb1f95 100644
|
|
|
70
110
|
+ (MASON_CONTAINER_TAGS.has(node.type) ||
|
|
71
111
|
+ (node.parent !== null && MASON_CONTAINER_TAGS.has(node.parent.type))))
|
|
72
112
|
+ warnStyleOnlyProp(node, name);
|
|
73
|
-
+ //
|
|
74
|
-
+ //
|
|
75
|
-
+
|
|
76
|
-
+ // when a real value did.
|
|
113
|
+
+ // Never forward nullish values to coercing native setters. A never-applied
|
|
114
|
+
+ // prop has nothing to restore, including when its initial value is undefined.
|
|
115
|
+
+ const target = view;
|
|
77
116
|
+ if (value == null || value === unsetValue) {
|
|
78
|
-
+ if (
|
|
117
|
+
+ if (!node.propDefaults.has(name))
|
|
79
118
|
+ return;
|
|
80
|
-
+
|
|
81
|
-
+
|
|
119
|
+
+ value = isRegisteredProperty(view, name)
|
|
120
|
+
+ ? unsetValue
|
|
121
|
+
+ : node.propDefaults.get(name);
|
|
82
122
|
+ }
|
|
83
|
-
+ // Capture the pre-prop value once so a plain (non-Property) field can be
|
|
84
|
-
+ // restored when the prop is removed later.
|
|
85
|
-
+ const defaults = (node.propDefaults ??= {});
|
|
86
|
-
+ if (!(name in defaults))
|
|
87
|
-
+ defaults[name] = view[name];
|
|
88
123
|
// Core raises `<name>Change` for a script write exactly as for a user
|
|
89
124
|
// edit; a controlled input must not see its own value come back as one.
|
|
90
125
|
const echo = `${name}Change`;
|
|
91
|
-
@@ -
|
|
92
|
-
|
|
126
|
+
@@ -127,7 +165,10 @@ function setProp(node, view, name, value) {
|
|
127
|
+
if (listening)
|
|
128
|
+
node.muted.add(echo);
|
|
129
|
+
try {
|
|
130
|
+
- view[name] = value;
|
|
131
|
+
+ target[name] = value;
|
|
132
|
+
+ if (value === unsetValue &&
|
|
133
|
+
+ _getStyleProperties().some((p) => p.name === name))
|
|
134
|
+
+ refreshCss(view);
|
|
93
135
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
+function
|
|
97
|
-
+ if (view === null)
|
|
98
|
-
+ return;
|
|
99
|
-
+ if (name === 'children' || name === 'key' || name === 'ref')
|
|
100
|
-
+ return;
|
|
101
|
-
+ // `on*` handlers unbind through `event` commands, not props.
|
|
102
|
-
+ if (EVENT_PROP.test(name))
|
|
103
|
-
+ return;
|
|
104
|
-
+ if (name === 'className' || name === 'class') {
|
|
105
|
-
+ view.className = unsetValue;
|
|
106
|
-
+ return;
|
|
107
|
-
+ }
|
|
108
|
-
+ if (name === 'style') {
|
|
109
|
-
+ applyStyle(node, view, null);
|
|
110
|
-
+ return;
|
|
111
|
-
+ }
|
|
112
|
-
+ if (name === 'renderItem' && view instanceof ListView) {
|
|
113
|
-
+ setRenderItem(view, null, createNativeScriptRoot);
|
|
114
|
-
+ return;
|
|
115
|
-
+ }
|
|
116
|
-
+ const echo = `${name}Change`;
|
|
117
|
-
+ const listening = node.listeners.has(echo);
|
|
118
|
-
+ if (listening)
|
|
119
|
-
+ node.muted.add(echo);
|
|
120
|
-
+ try {
|
|
121
|
-
+ // Property/CssProperty setters consume the sentinel and restore the
|
|
122
|
-
+ // declared default. A plain field stores it raw — detect that and
|
|
123
|
-
+ // write back the captured pre-prop value instead.
|
|
124
|
-
+ view[name] = unsetValue;
|
|
125
|
-
+ if (view[name] === unsetValue)
|
|
126
|
-
+ view[name] = node.propDefaults?.[name];
|
|
127
|
-
+ }
|
|
128
|
-
+ finally {
|
|
129
|
-
+ if (listening)
|
|
130
|
-
+ node.muted.delete(echo);
|
|
131
|
-
+ }
|
|
132
|
-
+}
|
|
136
|
+
finally {
|
|
137
|
+
if (listening)
|
|
138
|
+
@@ -137,6 +178,8 @@ function setProp(node, view, name, value) {
|
|
133
139
|
// `class`/`className` compose clsx-style on the DOM renderer; join arrays
|
|
134
140
|
// with spaces so NativeScript's class selectors can match each class.
|
|
135
141
|
function normalizeClass(value) {
|
|
136
|
-
|
|
142
|
+
+ if (typeof value === 'number')
|
|
143
|
+
+ return value ? String(value) : '';
|
|
144
|
+
if (typeof value === 'string')
|
|
145
|
+
return value;
|
|
146
|
+
if (Array.isArray(value))
|
|
147
|
+
@@ -147,16 +190,298 @@ function normalizeClass(value) {
|
|
137
148
|
.join(' ');
|
|
138
149
|
return '';
|
|
139
150
|
}
|
|
140
151
|
-function applyStyle(view, value) {
|
|
141
152
|
- if (value == null || value === unsetValue)
|
|
142
153
|
- return;
|
|
143
|
-
+/**
|
|
144
|
-
+
|
|
145
|
-
+
|
|
146
|
-
+
|
|
147
|
-
+
|
|
148
|
-
+
|
|
154
|
+
+/** Match the actual registered setter, not merely a globally registered name. */
|
|
155
|
+
+function isRegisteredProperty(view, name) {
|
|
156
|
+
+ let prototype = view;
|
|
157
|
+
+ while (prototype !== null) {
|
|
158
|
+
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
|
|
159
|
+
+ if (descriptor !== undefined) {
|
|
160
|
+
+ return (_getProperties().some((property) => property.name === name && property.set === descriptor.set) ||
|
|
161
|
+
+ (_getStyleProperties().some((property) => property.name === name) &&
|
|
162
|
+
+ descriptor.set !== undefined &&
|
|
163
|
+
+ name in view.style));
|
|
164
|
+
+ }
|
|
165
|
+
+ prototype = Object.getPrototypeOf(prototype);
|
|
166
|
+
+ }
|
|
167
|
+
+ return false;
|
|
168
|
+
+}
|
|
169
|
+
+/** Core discards the cascaded value when a local value occupies its slot. */
|
|
170
|
+
+function refreshCss(view) {
|
|
171
|
+
+ // No public single-key refresh exists in core 9.1. setInlineStyle only writes
|
|
172
|
+
+ // declarations; the recursive _onCssStateChange would also touch descendants.
|
|
173
|
+
+ view._cssState?.onChange();
|
|
174
|
+
+}
|
|
175
|
+
+/** Replace authored keys; clearing a local CssProperty must restore class CSS. */
|
|
149
176
|
+function applyStyle(node, view, value) {
|
|
150
|
-
+ const
|
|
151
|
-
+
|
|
152
|
-
|
|
153
|
-
+
|
|
154
|
-
|
|
155
|
-
+
|
|
156
|
-
+
|
|
177
|
+
+ const style = view.style;
|
|
178
|
+
+ const next = typeof value === 'string'
|
|
179
|
+
+ ? inlineStyleKeys(value)
|
|
180
|
+
+ : value !== null && typeof value === 'object' && value !== unsetValue
|
|
181
|
+
+ ? new Set(Object.keys(value))
|
|
182
|
+
+ : new Set();
|
|
183
|
+
+ for (const key of node.styleKeys) {
|
|
184
|
+
+ if (!next.has(key))
|
|
185
|
+
+ unsetStyleKey(node, view, key);
|
|
157
186
|
+ }
|
|
158
|
-
+
|
|
159
|
-
+
|
|
160
|
-
+
|
|
187
|
+
+ for (const key of next) {
|
|
188
|
+
+ if (!node.styleDefaults.has(key))
|
|
189
|
+
+ node.styleDefaults.set(key, style[key]);
|
|
161
190
|
+ }
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
+ if (!(key in value))
|
|
165
|
-
+ unsetStyleKey(view, key);
|
|
166
|
-
+ }
|
|
191
|
+
if (typeof value === 'string') {
|
|
192
|
+
view.setInlineStyle(value);
|
|
167
193
|
+ }
|
|
168
|
-
+
|
|
169
|
-
+
|
|
170
|
-
+
|
|
171
|
-
+
|
|
172
|
-
+
|
|
173
|
-
+
|
|
174
|
-
+
|
|
175
|
-
+
|
|
176
|
-
+
|
|
177
|
-
+ leafStash[key] = nextValue == null ? undefined : nextValue;
|
|
178
|
-
+ if (masonLeaf !== undefined)
|
|
179
|
-
+ masonLeaf[key] = nextValue == null ? undefined : nextValue;
|
|
194
|
+
+ else if (value !== null &&
|
|
195
|
+
+ typeof value === 'object' &&
|
|
196
|
+
+ value !== unsetValue) {
|
|
197
|
+
+ for (const key of next) {
|
|
198
|
+
+ const entry = value[key];
|
|
199
|
+
+ if (entry == null || entry === unsetValue)
|
|
200
|
+
+ unsetStyleKey(node, view, key);
|
|
201
|
+
+ else
|
|
202
|
+
+ style[key] = entry;
|
|
180
203
|
+ }
|
|
181
|
-
+ if (nextValue == null)
|
|
182
|
-
+ unsetStyleKey(view, key);
|
|
183
|
-
+ else
|
|
184
|
-
+ view.style[key] = nextValue;
|
|
185
204
|
+ }
|
|
186
|
-
+ node.styleKeys =
|
|
187
|
-
+}
|
|
188
|
-
+function clearStyleKeys(view, keys) {
|
|
189
|
-
+ if (keys === undefined)
|
|
190
|
-
+ return;
|
|
191
|
-
+ for (const key of keys)
|
|
192
|
-
+ unsetStyleKey(view, key);
|
|
205
|
+
+ node.styleKeys = next;
|
|
193
206
|
+}
|
|
194
|
-
+function unsetStyleKey(view, name) {
|
|
207
|
+
+function unsetStyleKey(node, view, name) {
|
|
208
|
+
+ // The foreign-leaf binding observes the resolved style, so removal needs
|
|
209
|
+
+ // no leaf write here — the cascade restore raises the longhand's Change
|
|
210
|
+
+ // event and the binding re-syncs.
|
|
195
211
|
+ const style = view.style;
|
|
196
212
|
+ if (name.startsWith('--')) {
|
|
197
|
-
+ style.
|
|
198
|
-
+ return;
|
|
213
|
+
+ view.style.removeUnscopedCssVariable(name);
|
|
199
214
|
+ }
|
|
200
|
-
+
|
|
201
|
-
+
|
|
202
|
-
+
|
|
203
|
-
+
|
|
215
|
+
+ else {
|
|
216
|
+
+ const registered = _getStyleProperties().some((p) => p.name === name || p.cssLocalName === name);
|
|
217
|
+
+ style[name] = registered ? unsetValue : node.styleDefaults.get(name);
|
|
218
|
+
+ }
|
|
219
|
+
+ refreshCss(view);
|
|
204
220
|
+}
|
|
205
221
|
+function inlineStyleKeys(style) {
|
|
206
222
|
+ const keys = new Set();
|
|
207
|
-
+
|
|
208
|
-
+
|
|
209
|
-
+
|
|
210
|
-
+
|
|
211
|
-
+
|
|
212
|
-
+
|
|
213
|
-
+ keys.add(name.
|
|
223
|
+
+ const sheet = cssTreeParse(`local { ${style} }`, undefined);
|
|
224
|
+
+ for (const rule of sheet.stylesheet.rules) {
|
|
225
|
+
+ for (const declaration of rule.declarations ?? []) {
|
|
226
|
+
+ if (declaration.type !== 'declaration')
|
|
227
|
+
+ continue;
|
|
228
|
+
+ const name = declaration.property;
|
|
229
|
+
+ keys.add(name.startsWith('--')
|
|
230
|
+
+ ? name
|
|
231
|
+
+ : name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()));
|
|
232
|
+
+ }
|
|
214
233
|
+ }
|
|
215
234
|
+ return keys;
|
|
216
235
|
+}
|
|
@@ -240,12 +259,16 @@ index 8bc563a..4cb1f95 100644
|
|
|
240
259
|
+ 'flexWrapBefore', 'stretchLastChild', 'itemWidth', 'itemHeight',
|
|
241
260
|
+ 'rows', 'columns',
|
|
242
261
|
+]);
|
|
243
|
-
+//
|
|
244
|
-
+// the
|
|
245
|
-
+const MASON_LEAF_STYLE_KEYS =
|
|
246
|
-
+
|
|
247
|
-
+
|
|
248
|
-
+
|
|
262
|
+
+// Only leaf layout longhands: core expands shorthands before notifying.
|
|
263
|
+
+// Read the effective NS style, never copy authored values into another tier.
|
|
264
|
+
+const MASON_LEAF_STYLE_KEYS = [
|
|
265
|
+
+ 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',
|
|
266
|
+
+ 'marginTop', 'marginRight', 'marginBottom', 'marginLeft',
|
|
267
|
+
+ 'flexGrow', 'flexShrink', 'flexBasis', 'alignSelf', 'justifySelf',
|
|
268
|
+
+ 'order', 'position', 'left', 'top', 'right', 'bottom', 'aspectRatio',
|
|
269
|
+
+ 'gridRow', 'gridColumn', 'gridRowStart', 'gridRowEnd', 'gridColumnStart', 'gridColumnEnd',
|
|
270
|
+
+];
|
|
271
|
+
+const masonLeafBindings = new WeakMap();
|
|
249
272
|
+const warnedStyleOnlyProps = new Set();
|
|
250
273
|
+function warnStyleOnlyProp(node, name) {
|
|
251
274
|
+ const key = node.type + ':' + name;
|
|
@@ -303,7 +326,8 @@ index 8bc563a..4cb1f95 100644
|
|
|
303
326
|
+ style.overflowY = 'scroll';
|
|
304
327
|
+ style.overflowX = 'hidden';
|
|
305
328
|
+ }
|
|
306
|
-
+
|
|
329
|
+
+ // Core's alignItems CssProperty already defaults to stretch. A local
|
|
330
|
+
+ // write here would outrank every stylesheet rule, including centering.
|
|
307
331
|
+ // Containers establish the containing block for absolute descendants.
|
|
308
332
|
+ style.position = 'relative';
|
|
309
333
|
+}
|
|
@@ -329,31 +353,102 @@ index 8bc563a..4cb1f95 100644
|
|
|
329
353
|
+ }
|
|
330
354
|
+}
|
|
331
355
|
+
|
|
332
|
-
+/**
|
|
333
|
-
+ *
|
|
334
|
-
+ *
|
|
335
|
-
+ *
|
|
336
|
-
+ *
|
|
356
|
+
+/** Keep foreign leaves in sync with the effective NativeScript cascade.
|
|
357
|
+
+ * MasonKit's property handlers only forward to its own _styleHelper views.
|
|
358
|
+
+ * Observe longhand changes so classes, pseudo states, inline removal and
|
|
359
|
+
+ * stylesheet refreshes follow the same path. Rebind on loaded because the
|
|
360
|
+
+ * native leaf may not exist at insert, or may have been recreated. */
|
|
337
361
|
+function applyMasonChildLayout(node, parent) {
|
|
338
362
|
+ const view = node.view;
|
|
339
|
-
+ if (view
|
|
340
|
-
return;
|
|
341
|
-
+ const style = masonChildStyle(view);
|
|
342
|
-
+ if (style === undefined)
|
|
363
|
+
+ if (!view || view._styleHelper !== undefined)
|
|
343
364
|
+ return;
|
|
344
|
-
+
|
|
345
|
-
+
|
|
346
|
-
|
|
347
|
-
+ style[key] = leafStash[key];
|
|
365
|
+
+ if (masonLeafBindings.has(view)) {
|
|
366
|
+
+ masonLeafBindings.get(view).sync();
|
|
367
|
+
return;
|
|
348
368
|
}
|
|
349
369
|
- if (typeof value === 'object')
|
|
350
370
|
- Object.assign(view.style, value);
|
|
371
|
+
+ let native;
|
|
372
|
+
+ let leaf;
|
|
373
|
+
+ const applied = new Map();
|
|
374
|
+
+ const syncKey = (key) => {
|
|
375
|
+
+ if (!leaf)
|
|
376
|
+
+ return;
|
|
377
|
+
+ let value = view.style[key];
|
|
378
|
+
+ if (value === undefined || value === unsetValue) {
|
|
379
|
+
+ // Plain/unregistered fields can vanish without a CssProperty
|
|
380
|
+
+ // default. Mason requires an explicit grid reset (undefined is
|
|
381
|
+
+ // ignored by its setters).
|
|
382
|
+
+ if ((key === 'gridRow' || key === 'gridColumn') && applied.has(key))
|
|
383
|
+
+ value = 'auto';
|
|
384
|
+
+ else
|
|
385
|
+
+ return;
|
|
386
|
+
+ }
|
|
387
|
+
+ // Core's auto self-alignment is Mason's normal (-1 / parent default).
|
|
388
|
+
+ if ((key === 'alignSelf' || key === 'justifySelf') && value === 'auto')
|
|
389
|
+
+ value = 'normal';
|
|
390
|
+
+ if (typeof value === 'number' && !Number.isFinite(value))
|
|
391
|
+
+ value = 'auto';
|
|
392
|
+
+ // Mason's object px setter treats the number as DIP; core's parsed
|
|
393
|
+
+ // px length is physical pixels. Convert once at this boundary.
|
|
394
|
+
+ if (value && typeof value === 'object' && value.unit === 'px')
|
|
395
|
+
+ value = { value: Utils.layout.toDeviceIndependentPixels(value.value), unit: 'dip' };
|
|
396
|
+
+ const previous = applied.get(key);
|
|
397
|
+
+ if (Object.is(previous, value) || (value && previous && typeof value === 'object' &&
|
|
398
|
+
+ value.unit === previous.unit && value.value === previous.value))
|
|
399
|
+
+ return;
|
|
400
|
+
+ leaf[key] = value;
|
|
401
|
+
+ applied.set(key, value);
|
|
402
|
+
+ return true;
|
|
403
|
+
+ };
|
|
404
|
+
+ const sync = () => {
|
|
405
|
+
+ if (native !== view.nativeViewProtected || !leaf) {
|
|
406
|
+
+ native = view.nativeViewProtected;
|
|
407
|
+
+ leaf = masonChildStyle(view);
|
|
408
|
+
+ applied.clear();
|
|
409
|
+
+ }
|
|
410
|
+
+ let changed = false;
|
|
411
|
+
+ const update = () => {
|
|
412
|
+
+ for (const key of MASON_LEAF_STYLE_KEYS)
|
|
413
|
+
+ changed = syncKey(key) || changed;
|
|
414
|
+
+ };
|
|
415
|
+
+ // Foreign native style writes normally flush on a microtask, after
|
|
416
|
+
+ // core may already have measured the parent. Commit first, then ask
|
|
417
|
+
+ // the Mason container to recompute the foreign frame.
|
|
418
|
+
+ if (leaf?.batch)
|
|
419
|
+
+ leaf.batch(update);
|
|
420
|
+
+ else
|
|
421
|
+
+ update();
|
|
422
|
+
+ if (changed)
|
|
423
|
+
+ parent.view?.requestLayout?.();
|
|
424
|
+
+ };
|
|
425
|
+
+ const handlers = MASON_LEAF_STYLE_KEYS.map(key => {
|
|
426
|
+
+ const handler = () => sync();
|
|
427
|
+
+ view.style.on?.(key + 'Change', handler);
|
|
428
|
+
+ return [key + 'Change', handler];
|
|
429
|
+
+ });
|
|
430
|
+
+ view.on('loaded', sync);
|
|
431
|
+
+ masonLeafBindings.set(view, {
|
|
432
|
+
+ sync,
|
|
433
|
+
+ dispose() {
|
|
434
|
+
+ for (const [event, handler] of handlers)
|
|
435
|
+
+ view.style.off?.(event, handler);
|
|
436
|
+
+ view.off('loaded', sync);
|
|
437
|
+
+ },
|
|
438
|
+
+ });
|
|
439
|
+
+ sync();
|
|
440
|
+
+}
|
|
441
|
+
+function releaseMasonChildLayout(view) {
|
|
442
|
+
+ if (!view)
|
|
443
|
+
+ return;
|
|
444
|
+
+ masonLeafBindings.get(view)?.dispose();
|
|
445
|
+
+ masonLeafBindings.delete(view);
|
|
351
446
|
}
|
|
352
447
|
+
|
|
353
448
|
/** Recompute a text host's `text` from its `#text` children. */
|
|
354
449
|
function syncText(parent) {
|
|
355
450
|
if (parent === null || isPortalTarget(parent))
|
|
356
|
-
@@ -190,6 +
|
|
451
|
+
@@ -190,6 +515,15 @@ function addViewChild(parentView, view, index) {
|
|
357
452
|
parentView.insertChild(view, Math.min(index, parentView.getChildrenCount()));
|
|
358
453
|
return;
|
|
359
454
|
}
|
|
@@ -369,7 +464,7 @@ index 8bc563a..4cb1f95 100644
|
|
|
369
464
|
if (parentView instanceof ContentView) {
|
|
370
465
|
parentView.content = view;
|
|
371
466
|
return;
|
|
372
|
-
@@ -234,6 +
|
|
467
|
+
@@ -234,6 +568,13 @@ function removeViewChild(parentView, view) {
|
|
373
468
|
parentView.removeChild(view);
|
|
374
469
|
return;
|
|
375
470
|
}
|
|
@@ -383,13 +478,20 @@ index 8bc563a..4cb1f95 100644
|
|
|
383
478
|
if (parentView instanceof ContentView) {
|
|
384
479
|
if (parentView.content === view)
|
|
385
480
|
parentView.content = CLEARED;
|
|
386
|
-
@@ -
|
|
481
|
+
@@ -315,6 +656,7 @@ function tabViewOwning(node) {
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
function detach(container, node) {
|
|
485
|
+
+ releaseMasonChildLayout(node.view);
|
|
486
|
+
const parent = node.parent;
|
|
487
|
+
const siblings = childrenOf(container, parent);
|
|
488
|
+
const index = siblings.indexOf(node);
|
|
489
|
+
@@ -370,6 +712,12 @@ function attach(container, node) {
|
|
387
490
|
}
|
|
388
491
|
}
|
|
389
492
|
addViewChild(parentView, node.view, index);
|
|
390
493
|
+ // The child's mason leaf node exists only once the parent has attached it;
|
|
391
|
-
+ //
|
|
392
|
-
+ // the full sibling list).
|
|
494
|
+
+ // synchronize effective styles after attachment.
|
|
393
495
|
+ if (parent !== null && MASON_CONTAINER_TAGS.has(parent.type)) {
|
|
394
496
|
+ for (const sibling of childrenOf(container, parent))
|
|
395
497
|
+ applyMasonChildLayout(sibling, parent);
|
|
@@ -397,7 +499,46 @@ index 8bc563a..4cb1f95 100644
|
|
|
397
499
|
markTabView(tabViewOwning(node));
|
|
398
500
|
}
|
|
399
501
|
function insert(container, parent, node, before) {
|
|
400
|
-
@@ -
|
|
502
|
+
@@ -429,6 +777,7 @@ function setEvent(container, node, type, listener) {
|
|
503
|
+
view.on(type, handler);
|
|
504
|
+
}
|
|
505
|
+
function disposeListeners(node) {
|
|
506
|
+
+ releaseMasonChildLayout(node.view);
|
|
507
|
+
const view = node.view;
|
|
508
|
+
if (view !== null) {
|
|
509
|
+
for (const [type, handler] of node.listeners)
|
|
510
|
+
@@ -460,6 +809,7 @@ function recreateView(container, node) {
|
|
511
|
+
// no longer host them.
|
|
512
|
+
throw new Error(`NativeScript driver: re-registered <${node.type}> is a <${view.typeName}>, which cannot host portal children; the registration stays on the previous view.`);
|
|
513
|
+
}
|
|
514
|
+
+ releaseMasonChildLayout(previous);
|
|
515
|
+
const parentView = hostViewOf(container, node.parent);
|
|
516
|
+
for (const child of node.children) {
|
|
517
|
+
if (child.view !== null)
|
|
518
|
+
@@ -480,6 +830,9 @@ function recreateView(container, node) {
|
|
519
|
+
viewOwners.set(view, { container, node });
|
|
520
|
+
node.view = view;
|
|
521
|
+
node.textApplied = false;
|
|
522
|
+
+ node.propDefaults.clear();
|
|
523
|
+
+ node.styleDefaults.clear();
|
|
524
|
+
+ node.styleKeys.clear();
|
|
525
|
+
applyProps(node, node.props);
|
|
526
|
+
for (const [type, handler] of node.listeners)
|
|
527
|
+
view.on(type, handler);
|
|
528
|
+
@@ -500,6 +853,12 @@ function recreateView(container, node) {
|
|
529
|
+
addViewChild(view, child.view, index++);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
+ if (MASON_CONTAINER_TAGS.has(node.type)) {
|
|
533
|
+
+ for (const child of node.children) {
|
|
534
|
+
+ releaseMasonChildLayout(child.view);
|
|
535
|
+
+ applyMasonChildLayout(child, node);
|
|
536
|
+
+ }
|
|
537
|
+
+ }
|
|
538
|
+
syncText(node);
|
|
539
|
+
markTabView(node);
|
|
540
|
+
attach(container, node);
|
|
541
|
+
@@ -548,7 +907,7 @@ function preparePortalTarget(context) {
|
|
401
542
|
}
|
|
402
543
|
const target = owner?.node.view ?? suppliedTarget;
|
|
403
544
|
if (!(target instanceof LayoutBase)) {
|
|
@@ -406,7 +547,7 @@ index 8bc563a..4cb1f95 100644
|
|
|
406
547
|
}
|
|
407
548
|
let id = portalTargetIds.get(target);
|
|
408
549
|
if (id === undefined) {
|
|
409
|
-
@@ -641,7 +
|
|
550
|
+
@@ -641,7 +1000,7 @@ function applyCommand(container, command) {
|
|
410
551
|
}
|
|
411
552
|
export const nativeScriptDriver = {
|
|
412
553
|
id: NATIVESCRIPT_RENDERER_ID,
|
|
@@ -416,7 +557,7 @@ index 8bc563a..4cb1f95 100644
|
|
|
416
557
|
classify(name) {
|
|
417
558
|
if (!EVENT_PROP.test(name))
|
|
418
559
|
diff --git a/dist/elements.js b/dist/elements.js
|
|
419
|
-
index
|
|
560
|
+
index a13bcea75176146f58f047be1d9c7b0cdda1120a..e9988e174d0b89dcd70220d3014ca6b9bb1820e5 100644
|
|
420
561
|
--- a/dist/elements.js
|
|
421
562
|
+++ b/dist/elements.js
|
|
422
563
|
@@ -1,4 +1,7 @@
|
|
@@ -424,7 +565,7 @@ index a13bcea..e9988e1 100644
|
|
|
424
565
|
+import { ActionBar, ActionItem, ActivityIndicator, Button, LiquidGlass, ContentView, DatePicker, FormattedString, Frame, HtmlView, Image, Label, ListPicker, ListView, NavigationButton, Page, Placeholder, Progress, ProxyViewContainer, RootLayout, SearchBar, SegmentedBar, SegmentedBarItem, Slider, Span, Switch, TabView, TabViewItem, TextField, TextView, TimePicker, WebView, } from '@nativescript/core';
|
|
425
566
|
+// Mason cutover: container intrinsics resolve to MasonKit views; the driver
|
|
426
567
|
+// translates their NativeScript-shaped props into mason style writes.
|
|
427
|
-
+import { View as MasonView, Scroll as MasonScroll } from '@
|
|
568
|
+
+import { View as MasonView, Scroll as MasonScroll } from '@octane-xplat/nativescript-masonkit';
|
|
428
569
|
/**
|
|
429
570
|
* Lowercase tag name -> view constructor. The keys are the JSX tag names of
|
|
430
571
|
* `intrinsics.ts`; an app extends the vocabulary with `registerElement`.
|
|
@@ -473,12 +614,14 @@ index a13bcea..e9988e1 100644
|
|
|
473
614
|
for (const [tag, element] of BUILTIN_ELEMENTS)
|
|
474
615
|
registerElement(tag, element);
|
|
475
616
|
diff --git a/dist/intrinsics.d.ts b/dist/intrinsics.d.ts
|
|
476
|
-
index
|
|
617
|
+
index 45a47cbbce199df9635852ca4cdb2849e9bbc83d..23b81c44b6860e6099e8c1a70f975f6e792aa2b2 100644
|
|
477
618
|
--- a/dist/intrinsics.d.ts
|
|
478
619
|
+++ b/dist/intrinsics.d.ts
|
|
479
|
-
@@ -
|
|
620
|
+
@@ -23,10 +23,11 @@
|
|
621
|
+
* ```
|
|
480
622
|
*/
|
|
481
623
|
import type * as NS from '@nativescript/core';
|
|
624
|
+
+import type { CSSProperties } from 'octane/jsx-runtime';
|
|
482
625
|
export type NativeScriptNode = unknown;
|
|
483
626
|
-type Ref<TInstance> = ((instance: TInstance | null) => void) | {
|
|
484
627
|
+type Ref<TInstance> = ((instance: TInstance | null) => void | (() => void)) | {
|
|
@@ -488,10 +631,17 @@ index 45a47cb..668c920 100644
|
|
|
488
631
|
/**
|
|
489
632
|
* The driver assigns every non-event prop onto the view instance, so a JSX
|
|
490
633
|
* attribute is a NativeScript view property rather than a DOM attribute.
|
|
491
|
-
@@ -
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
634
|
+
@@ -72,16 +73,64 @@ export interface CommonEvents<TInstance> {
|
|
635
|
+
onFocus?: (event: NSEventData<TInstance>) => void;
|
|
636
|
+
onBlur?: (event: NSEventData<TInstance>) => void;
|
|
637
|
+
}
|
|
638
|
+
-/** Values accepted by the driver's `className` and `class` props. */
|
|
639
|
+
-export type ClassValue = string | boolean | null | undefined | readonly ClassValue[] | {
|
|
640
|
+
- readonly [className: string]: unknown;
|
|
641
|
+
-};
|
|
642
|
+
+/** Octane's class composition contract, shared unchanged with the DOM. */
|
|
643
|
+
+export type { ClassValue } from 'octane/jsx-runtime';
|
|
644
|
+
+import type { ClassValue } from 'octane/jsx-runtime';
|
|
495
645
|
+/** Mason engine style keys accepted through `style`/`className` — under a
|
|
496
646
|
+ * masonview parent a child's leaf style consumes them; on a masonview they
|
|
497
647
|
+ * are the container's own layout. These are the only way to set raw layout
|
|
@@ -547,17 +697,19 @@ index 45a47cb..668c920 100644
|
|
|
547
697
|
class?: ClassValue;
|
|
548
698
|
/** A string is parsed as inline CSS; an object is assigned onto `view.style`. */
|
|
549
699
|
- style?: string | Partial<NS.Style>;
|
|
550
|
-
+ style?: string | Partial<NS.Style> | MasonStyleProps;
|
|
700
|
+
+ style?: string | Partial<NS.Style> | MasonStyleProps | CSSProperties;
|
|
551
701
|
/**
|
|
552
702
|
* Name of the property on a slot-hosting parent (e.g. a drawer's
|
|
553
703
|
* `mainContent` / `leftDrawer`) this child should be assigned to instead of
|
|
554
|
-
|
|
704
|
+
@@ -89,21 +138,18 @@ export interface CommonAttributes {
|
|
555
705
|
*/
|
|
556
706
|
hostSlot?: string;
|
|
557
|
-
|
|
707
|
+
/**
|
|
558
708
|
- * Attached layout properties. The layout modules register these on `View` at
|
|
559
709
|
- * runtime, so they are absent from the `@nativescript/core` class typings.
|
|
560
|
-
-
|
|
710
|
+
+ * ARIA-shaped accessibility values; shared components emit plain strings
|
|
711
|
+
+ * through the escape-props helpers rather than the NativeScript enums.
|
|
712
|
+
*/
|
|
561
713
|
- row?: number | string;
|
|
562
714
|
- col?: number | string;
|
|
563
715
|
- rowSpan?: number | string;
|
|
@@ -570,10 +722,19 @@ index 45a47cb..668c920 100644
|
|
|
570
722
|
- flexWrapBefore?: boolean | string;
|
|
571
723
|
- alignSelf?: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
|
|
572
724
|
- order?: number | string;
|
|
725
|
+
+ accessibilityRole?: string;
|
|
726
|
+
+ accessibilityState?: string;
|
|
727
|
+
+ accessibilityLiveRegion?: string;
|
|
728
|
+
+ /** Platform escape bags — applied onto the native view by the leaf's
|
|
729
|
+
+ * applyEscapeProps, not by the driver. */
|
|
730
|
+
+ ios?: Record<string, unknown>;
|
|
731
|
+
+ android?: Record<string, unknown>;
|
|
732
|
+
+ windows?: Record<string, unknown>;
|
|
733
|
+
+ macos?: Record<string, unknown>;
|
|
573
734
|
}
|
|
574
735
|
export interface ListViewAttributes {
|
|
575
736
|
/**
|
|
576
|
-
@@ -117,25 +
|
|
737
|
+
@@ -117,25 +163,21 @@ export interface ListViewAttributes {
|
|
577
738
|
}
|
|
578
739
|
export interface OctaneAttributes<TInstance> {
|
|
579
740
|
key?: string | number;
|
|
@@ -600,7 +761,7 @@ index 45a47cb..668c920 100644
|
|
|
600
761
|
htmlview: Attributes<typeof NS.HtmlView>;
|
|
601
762
|
image: Attributes<typeof NS.Image>;
|
|
602
763
|
label: Attributes<typeof NS.Label>;
|
|
603
|
-
@@ -153,7 +
|
|
764
|
+
@@ -153,7 +195,6 @@ export interface NativeScriptElements {
|
|
604
765
|
segmentedbaritem: Attributes<typeof NS.SegmentedBarItem>;
|
|
605
766
|
slider: Attributes<typeof NS.Slider>;
|
|
606
767
|
span: Attributes<typeof NS.Span>;
|
|
@@ -608,7 +769,7 @@ index 45a47cb..668c920 100644
|
|
|
608
769
|
switch: Attributes<typeof NS.Switch>;
|
|
609
770
|
tabview: Attributes<typeof NS.TabView>;
|
|
610
771
|
tabviewitem: Attributes<typeof NS.TabViewItem>;
|
|
611
|
-
@@ -161,7 +
|
|
772
|
+
@@ -161,7 +202,8 @@ export interface NativeScriptElements {
|
|
612
773
|
textview: Attributes<typeof NS.TextView>;
|
|
613
774
|
timepicker: Attributes<typeof NS.TimePicker>;
|
|
614
775
|
webview: Attributes<typeof NS.WebView>;
|