@viewfly/core 0.0.1-alpha.9 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/bundles/foundation/_utils.d.ts +4 -13
- package/bundles/foundation/renderer.d.ts +0 -1
- package/bundles/index.esm.js +265 -328
- package/bundles/index.js +265 -329
- package/bundles/jsx.d.ts +13 -0
- package/bundles/model/component.d.ts +14 -15
- package/bundles/model/jsx-element.d.ts +9 -23
- package/bundles/public-api.d.ts +1 -0
- package/bundles/viewfly.d.ts +2 -3
- package/jsx-runtime/index.d.ts +18 -0
- package/jsx-runtime/package.json +5 -0
- package/package.json +4 -7
- package/jsx-dev-runtime.js +0 -8
- package/jsx-runtime.d.ts +0 -16
- /package/{jsx-runtime.js → jsx-runtime/index.esm.js} +0 -0
- /package/{jsx-runtime.umd.js → jsx-runtime/index.js} +0 -0
package/bundles/index.esm.js
CHANGED
|
@@ -43,175 +43,19 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
43
43
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const jsxErrorFn = makeError('JSX');
|
|
47
|
-
const Fragment = function Fragment() {
|
|
48
|
-
throw jsxErrorFn('Fragment does not support calling.');
|
|
49
|
-
};
|
|
50
|
-
function jsx(setup, config, key) {
|
|
51
|
-
if (typeof setup === 'string') {
|
|
52
|
-
return new JSXElement(setup, config, key);
|
|
53
|
-
}
|
|
54
|
-
return new JSXComponent(function (context) {
|
|
55
|
-
return new Component(context, setup, config, key);
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
function jsxs(setup, config, key) {
|
|
59
|
-
if (typeof setup === 'string') {
|
|
60
|
-
return new JSXElement(setup, config, key);
|
|
61
|
-
}
|
|
62
|
-
return new JSXComponent(function (context) {
|
|
63
|
-
return new Component(context, setup, config, key);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
class JSXText {
|
|
67
|
-
constructor(text) {
|
|
68
|
-
this.text = text;
|
|
69
|
-
this.$$typeOf = '#text';
|
|
70
|
-
}
|
|
71
|
-
is(target) {
|
|
72
|
-
return target.$$typeOf === this.$$typeOf;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
class Props {
|
|
76
|
-
constructor(props) {
|
|
77
|
-
this.attrs = new Map();
|
|
78
|
-
this.styles = new Map();
|
|
79
|
-
this.classes = '';
|
|
80
|
-
this.listeners = {};
|
|
81
|
-
this.children = [];
|
|
82
|
-
if (!props) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
Object.keys(props).forEach(key => {
|
|
86
|
-
if (key === 'children') {
|
|
87
|
-
if (props.children !== null && typeof props.children !== 'undefined') {
|
|
88
|
-
if (Array.isArray(props.children)) {
|
|
89
|
-
this.children = props.children;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
this.children = [props.children];
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (key === 'class') {
|
|
98
|
-
this.classes = Props.classToString(props[key]);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (key === 'style') {
|
|
102
|
-
const style = props.style || '';
|
|
103
|
-
if (typeof style === 'string') {
|
|
104
|
-
style.split(';').map(s => s.split(':')).forEach(v => {
|
|
105
|
-
if (!v[0] || !v[1]) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
this.styles.set(v[0].trim(), v[1].trim());
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
else if (typeof style === 'object') {
|
|
112
|
-
Object.keys(style).forEach(key => {
|
|
113
|
-
this.styles.set(key, style[key]);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (/^on[A-Z]/.test(key)) {
|
|
119
|
-
const listener = props[key];
|
|
120
|
-
if (typeof listener === 'function') {
|
|
121
|
-
this.listeners[key.replace(/^on/, '').toLowerCase()] = listener;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
this.attrs.set(key, listener);
|
|
125
|
-
}
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
this.attrs.set(key, props[key]);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
static classToString(config) {
|
|
132
|
-
if (!config) {
|
|
133
|
-
return '';
|
|
134
|
-
}
|
|
135
|
-
if (typeof config === 'string') {
|
|
136
|
-
return config;
|
|
137
|
-
}
|
|
138
|
-
else if (Array.isArray(config)) {
|
|
139
|
-
return config.map(i => {
|
|
140
|
-
return Props.classToString(i);
|
|
141
|
-
}).join(' ');
|
|
142
|
-
}
|
|
143
|
-
else if (typeof config === 'object') {
|
|
144
|
-
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
|
|
145
|
-
return config.toString();
|
|
146
|
-
}
|
|
147
|
-
const classes = [];
|
|
148
|
-
for (const key in config) {
|
|
149
|
-
if ({}.hasOwnProperty.call(config, key) && config[key]) {
|
|
150
|
-
classes.push(key);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return classes.join(' ');
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
static classToArray(config) {
|
|
157
|
-
const classes = [];
|
|
158
|
-
if (!config) {
|
|
159
|
-
return classes;
|
|
160
|
-
}
|
|
161
|
-
if (typeof config === 'string') {
|
|
162
|
-
const items = config.match(/\S+/g);
|
|
163
|
-
return items || classes;
|
|
164
|
-
}
|
|
165
|
-
else if (Array.isArray(config)) {
|
|
166
|
-
for (const i of config) {
|
|
167
|
-
classes.push(...Props.classToArray(i));
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else if (typeof config === 'object') {
|
|
171
|
-
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
|
|
172
|
-
classes.push(config.toString());
|
|
173
|
-
return classes;
|
|
174
|
-
}
|
|
175
|
-
for (const key in config) {
|
|
176
|
-
if ({}.hasOwnProperty.call(config, key) && config[key]) {
|
|
177
|
-
classes.push(key);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return classes;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
class JSXElement {
|
|
185
|
-
constructor(name, config, key) {
|
|
186
|
-
this.name = name;
|
|
187
|
-
this.config = config;
|
|
188
|
-
this.key = key;
|
|
189
|
-
this.$$typeOf = this.name;
|
|
190
|
-
this.props = new Props(config);
|
|
191
|
-
}
|
|
192
|
-
is(target) {
|
|
193
|
-
return target.$$typeOf === this.$$typeOf;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
46
|
const componentSetupStack = [];
|
|
198
|
-
const
|
|
199
|
-
const derivedStack = [];
|
|
47
|
+
const signalDepsStack = [];
|
|
200
48
|
const componentErrorFn = makeError('component');
|
|
201
49
|
function getSetupContext(need = true) {
|
|
202
50
|
const current = componentSetupStack[componentSetupStack.length - 1];
|
|
203
51
|
if (!current && need) {
|
|
204
52
|
// 防止因外部捕获异常引引起的缓存未清理的问题
|
|
205
|
-
componentRendingStack.pop();
|
|
206
53
|
throw componentErrorFn('cannot be called outside the component!');
|
|
207
54
|
}
|
|
208
55
|
return current;
|
|
209
56
|
}
|
|
210
|
-
function
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
function getDerivedContext() {
|
|
214
|
-
return derivedStack[derivedStack.length - 1];
|
|
57
|
+
function getSignalDepsContext() {
|
|
58
|
+
return signalDepsStack[signalDepsStack.length - 1];
|
|
215
59
|
}
|
|
216
60
|
class JSXComponent {
|
|
217
61
|
constructor(createInstance) {
|
|
@@ -228,12 +72,12 @@ class Component extends ReflectiveInjector {
|
|
|
228
72
|
get changed() {
|
|
229
73
|
return this._changed;
|
|
230
74
|
}
|
|
231
|
-
constructor(context,
|
|
75
|
+
constructor(context, type, props, key) {
|
|
232
76
|
super(context, []);
|
|
233
|
-
this.
|
|
234
|
-
this.
|
|
77
|
+
this.type = type;
|
|
78
|
+
this.props = props;
|
|
235
79
|
this.key = key;
|
|
236
|
-
this.$$typeOf = this.
|
|
80
|
+
this.$$typeOf = this.type;
|
|
237
81
|
this.destroyCallbacks = [];
|
|
238
82
|
this.mountCallbacks = [];
|
|
239
83
|
this.propsChangedCallbacks = [];
|
|
@@ -243,7 +87,6 @@ class Component extends ReflectiveInjector {
|
|
|
243
87
|
this.updatedDestroyCallbacks = [];
|
|
244
88
|
this.propsChangedDestroyCallbacks = [];
|
|
245
89
|
this.isFirstRending = true;
|
|
246
|
-
this.props = new Props(config);
|
|
247
90
|
this.parentComponent = this.parentInjector;
|
|
248
91
|
}
|
|
249
92
|
is(target) {
|
|
@@ -251,16 +94,14 @@ class Component extends ReflectiveInjector {
|
|
|
251
94
|
}
|
|
252
95
|
addProvide(providers) {
|
|
253
96
|
providers = Array.isArray(providers) ? providers : [providers];
|
|
254
|
-
providers.
|
|
255
|
-
this.normalizedProviders.push(normalizeProvider(p));
|
|
256
|
-
});
|
|
97
|
+
this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
|
|
257
98
|
}
|
|
258
99
|
init() {
|
|
259
100
|
const self = this;
|
|
260
|
-
const props = new Proxy(this.
|
|
101
|
+
const props = new Proxy(this.props, {
|
|
261
102
|
get(_, key) {
|
|
262
|
-
if (self.
|
|
263
|
-
return self.
|
|
103
|
+
if (self.props) {
|
|
104
|
+
return self.props[key];
|
|
264
105
|
}
|
|
265
106
|
},
|
|
266
107
|
set() {
|
|
@@ -268,30 +109,30 @@ class Component extends ReflectiveInjector {
|
|
|
268
109
|
if (isSetup) {
|
|
269
110
|
componentSetupStack.pop();
|
|
270
111
|
}
|
|
271
|
-
if (isRending) {
|
|
272
|
-
componentRendingStack.pop();
|
|
273
|
-
}
|
|
274
112
|
throw componentErrorFn('component props is readonly!');
|
|
275
113
|
}
|
|
276
114
|
});
|
|
277
115
|
componentSetupStack.push(this);
|
|
278
116
|
let isSetup = true;
|
|
279
|
-
const render = this.
|
|
117
|
+
const render = this.type(props);
|
|
280
118
|
isSetup = false;
|
|
281
119
|
componentSetupStack.pop();
|
|
282
|
-
|
|
283
|
-
let isRending = true;
|
|
120
|
+
signalDepsStack.push([]);
|
|
284
121
|
const template = render();
|
|
285
|
-
|
|
286
|
-
|
|
122
|
+
const deps = signalDepsStack.pop();
|
|
123
|
+
this.unWatch = useEffect(deps, () => {
|
|
124
|
+
this.markAsDirtied();
|
|
125
|
+
});
|
|
287
126
|
return {
|
|
288
127
|
template,
|
|
289
128
|
render: () => {
|
|
290
|
-
|
|
291
|
-
|
|
129
|
+
this.unWatch();
|
|
130
|
+
signalDepsStack.push([]);
|
|
292
131
|
const template = render();
|
|
293
|
-
|
|
294
|
-
|
|
132
|
+
const deps = signalDepsStack.pop();
|
|
133
|
+
this.unWatch = useEffect(deps, () => {
|
|
134
|
+
this.markAsDirtied();
|
|
135
|
+
});
|
|
295
136
|
return template;
|
|
296
137
|
}
|
|
297
138
|
};
|
|
@@ -301,6 +142,9 @@ class Component extends ReflectiveInjector {
|
|
|
301
142
|
this.markAsChanged();
|
|
302
143
|
}
|
|
303
144
|
markAsChanged() {
|
|
145
|
+
if (this._changed) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
304
148
|
this._changed = true;
|
|
305
149
|
this.parentComponent.markAsChanged();
|
|
306
150
|
}
|
|
@@ -317,8 +161,8 @@ class Component extends ReflectiveInjector {
|
|
|
317
161
|
}
|
|
318
162
|
}
|
|
319
163
|
invokePropsChangedHooks(newProps) {
|
|
320
|
-
const oldProps = this.
|
|
321
|
-
this.
|
|
164
|
+
const oldProps = this.props;
|
|
165
|
+
this.props = newProps;
|
|
322
166
|
this.propsChangedDestroyCallbacks.forEach(fn => {
|
|
323
167
|
fn();
|
|
324
168
|
});
|
|
@@ -331,6 +175,7 @@ class Component extends ReflectiveInjector {
|
|
|
331
175
|
}
|
|
332
176
|
}
|
|
333
177
|
destroy() {
|
|
178
|
+
this.unWatch();
|
|
334
179
|
this.updatedDestroyCallbacks.forEach(fn => {
|
|
335
180
|
fn();
|
|
336
181
|
});
|
|
@@ -379,7 +224,7 @@ class Component extends ReflectiveInjector {
|
|
|
379
224
|
* }
|
|
380
225
|
* ```
|
|
381
226
|
*/
|
|
382
|
-
function
|
|
227
|
+
function onMounted(callback) {
|
|
383
228
|
const component = getSetupContext();
|
|
384
229
|
component.mountCallbacks.push(callback);
|
|
385
230
|
}
|
|
@@ -522,18 +367,10 @@ const depsKey = Symbol('deps');
|
|
|
522
367
|
* }
|
|
523
368
|
*/
|
|
524
369
|
function useSignal(state) {
|
|
525
|
-
const usedComponents = new Set();
|
|
526
370
|
function signal() {
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
derivedContext.push(signal);
|
|
531
|
-
}
|
|
532
|
-
if (component && !usedComponents.has(component)) {
|
|
533
|
-
usedComponents.add(component);
|
|
534
|
-
component.destroyCallbacks.push(() => {
|
|
535
|
-
usedComponents.delete(component);
|
|
536
|
-
});
|
|
371
|
+
const depsContext = getSignalDepsContext();
|
|
372
|
+
if (depsContext) {
|
|
373
|
+
depsContext.push(signal);
|
|
537
374
|
}
|
|
538
375
|
return state;
|
|
539
376
|
}
|
|
@@ -542,9 +379,6 @@ function useSignal(state) {
|
|
|
542
379
|
return;
|
|
543
380
|
}
|
|
544
381
|
state = newState;
|
|
545
|
-
for (const component of usedComponents) {
|
|
546
|
-
component.markAsDirtied();
|
|
547
|
-
}
|
|
548
382
|
for (const fn of signal[depsKey]) {
|
|
549
383
|
fn();
|
|
550
384
|
}
|
|
@@ -561,9 +395,9 @@ function useSignal(state) {
|
|
|
561
395
|
*/
|
|
562
396
|
function useDerived(callback, isContinue) {
|
|
563
397
|
const deps = [];
|
|
564
|
-
|
|
398
|
+
signalDepsStack.push(deps);
|
|
565
399
|
const data = callback();
|
|
566
|
-
|
|
400
|
+
signalDepsStack.pop();
|
|
567
401
|
const signal = useSignal(data);
|
|
568
402
|
if (deps.length) {
|
|
569
403
|
const unListen = useEffect(deps, () => {
|
|
@@ -634,12 +468,54 @@ function inject(token, notFoundValue, flags) {
|
|
|
634
468
|
return component.parentInjector.get(token, notFoundValue, flags);
|
|
635
469
|
}
|
|
636
470
|
|
|
471
|
+
const Fragment = function Fragment(props) {
|
|
472
|
+
return () => {
|
|
473
|
+
return props.children;
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
function jsx(setup, config, key) {
|
|
477
|
+
if (typeof setup === 'string') {
|
|
478
|
+
return new JSXElement(setup, config, key);
|
|
479
|
+
}
|
|
480
|
+
return new JSXComponent(function (context) {
|
|
481
|
+
return new Component(context, setup, config, key);
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
function jsxs(setup, config, key) {
|
|
485
|
+
if (typeof setup === 'string') {
|
|
486
|
+
return new JSXElement(setup, config, key);
|
|
487
|
+
}
|
|
488
|
+
return new JSXComponent(function (context) {
|
|
489
|
+
return new Component(context, setup, config, key);
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
class JSXText {
|
|
493
|
+
constructor(text) {
|
|
494
|
+
this.text = text;
|
|
495
|
+
this.$$typeOf = '#text';
|
|
496
|
+
}
|
|
497
|
+
is(target) {
|
|
498
|
+
return target.$$typeOf === this.$$typeOf;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
class JSXElement {
|
|
502
|
+
constructor(type, props, key) {
|
|
503
|
+
this.type = type;
|
|
504
|
+
this.props = props;
|
|
505
|
+
this.key = key;
|
|
506
|
+
this.$$typeOf = this.type;
|
|
507
|
+
}
|
|
508
|
+
is(target) {
|
|
509
|
+
return target.$$typeOf === this.$$typeOf;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
637
513
|
/**
|
|
638
514
|
* Viewfly 根组件,用于实现组件状态更新事件通知
|
|
639
515
|
*/
|
|
640
516
|
class RootComponent extends Component {
|
|
641
517
|
constructor(factory, parentInjector = new NullInjector()) {
|
|
642
|
-
super(parentInjector, factory,
|
|
518
|
+
super(parentInjector, factory, {});
|
|
643
519
|
this.changeEmitter = new Subject();
|
|
644
520
|
}
|
|
645
521
|
markAsChanged() {
|
|
@@ -649,77 +525,67 @@ class RootComponent extends Component {
|
|
|
649
525
|
}
|
|
650
526
|
|
|
651
527
|
const refKey = 'ref';
|
|
652
|
-
function getObjectChanges(
|
|
528
|
+
function getObjectChanges(newProps, oldProps) {
|
|
653
529
|
const changes = {
|
|
654
530
|
remove: [],
|
|
655
|
-
add: []
|
|
531
|
+
add: [],
|
|
532
|
+
replace: []
|
|
656
533
|
};
|
|
657
|
-
Object.keys(
|
|
658
|
-
const leftValue =
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (leftValue === rightValue) {
|
|
534
|
+
Object.keys(newProps).forEach(key => {
|
|
535
|
+
const leftValue = newProps[key];
|
|
536
|
+
const rightValue = oldProps[key];
|
|
537
|
+
if (Reflect.has(oldProps, key)) {
|
|
538
|
+
if (leftValue !== rightValue) {
|
|
539
|
+
changes.replace.push([key, leftValue, rightValue]);
|
|
540
|
+
}
|
|
665
541
|
return;
|
|
666
542
|
}
|
|
667
543
|
changes.add.push([key, leftValue]);
|
|
668
|
-
changes.remove.push([key, rightValue]);
|
|
669
544
|
});
|
|
670
|
-
Object.keys(
|
|
671
|
-
if (!Reflect.has(
|
|
672
|
-
changes.remove.push([key,
|
|
545
|
+
Object.keys(oldProps).forEach(key => {
|
|
546
|
+
if (!Reflect.has(newProps, key)) {
|
|
547
|
+
changes.remove.push([key, oldProps[key]]);
|
|
673
548
|
}
|
|
674
549
|
});
|
|
675
550
|
return changes;
|
|
676
551
|
}
|
|
677
|
-
function
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
552
|
+
function classToString(config) {
|
|
553
|
+
if (!config) {
|
|
554
|
+
return '';
|
|
555
|
+
}
|
|
556
|
+
if (typeof config === 'string') {
|
|
557
|
+
return config;
|
|
558
|
+
}
|
|
559
|
+
else if (Array.isArray(config)) {
|
|
560
|
+
return config.map(i => {
|
|
561
|
+
return classToString(i);
|
|
562
|
+
}).join(' ');
|
|
563
|
+
}
|
|
564
|
+
else if (typeof config === 'object') {
|
|
565
|
+
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
|
|
566
|
+
return config.toString();
|
|
686
567
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
const newValue = target.get(key);
|
|
692
|
-
if (value !== newValue) {
|
|
693
|
-
changes.remove.push([key, value]);
|
|
568
|
+
const classes = [];
|
|
569
|
+
for (const key in config) {
|
|
570
|
+
if ({}.hasOwnProperty.call(config, key) && config[key]) {
|
|
571
|
+
classes.push(key);
|
|
694
572
|
}
|
|
695
|
-
return;
|
|
696
573
|
}
|
|
697
|
-
|
|
698
|
-
|
|
574
|
+
return classes.join(' ');
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
function styleToObject(style) {
|
|
578
|
+
if (typeof style !== 'string') {
|
|
579
|
+
return style;
|
|
580
|
+
}
|
|
581
|
+
const obj = {};
|
|
582
|
+
style.split(';').map(s => s.split(':')).forEach(v => {
|
|
583
|
+
if (!v[0] || !v[1]) {
|
|
584
|
+
return;
|
|
699
585
|
}
|
|
586
|
+
obj[v[0].trim()] = v[1].trim();
|
|
700
587
|
});
|
|
701
|
-
return
|
|
702
|
-
}
|
|
703
|
-
const compareText = '0'.repeat(6);
|
|
704
|
-
function getNodeChanges(newVNode, oldVNode) {
|
|
705
|
-
const newProps = newVNode.props;
|
|
706
|
-
const oldProps = oldVNode.props;
|
|
707
|
-
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
708
|
-
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
709
|
-
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
710
|
-
return {
|
|
711
|
-
styleChanges,
|
|
712
|
-
attrChanges,
|
|
713
|
-
listenerChanges,
|
|
714
|
-
isChanged: [
|
|
715
|
-
attrChanges.set.length,
|
|
716
|
-
attrChanges.remove.length,
|
|
717
|
-
styleChanges.set.length,
|
|
718
|
-
styleChanges.remove.length,
|
|
719
|
-
listenerChanges.add.length,
|
|
720
|
-
listenerChanges.remove.length
|
|
721
|
-
].join('') !== compareText
|
|
722
|
-
};
|
|
588
|
+
return obj;
|
|
723
589
|
}
|
|
724
590
|
|
|
725
591
|
class RootComponentRef {
|
|
@@ -757,10 +623,12 @@ let Renderer = class Renderer {
|
|
|
757
623
|
reconcile(component, context) {
|
|
758
624
|
if (component.dirty) {
|
|
759
625
|
this.applyChanges(component, context);
|
|
626
|
+
component.rendered();
|
|
760
627
|
}
|
|
761
628
|
else if (component.changed) {
|
|
762
629
|
const atom = this.componentAtomCaches.get(component).atom.child;
|
|
763
630
|
this.reconcileElement(atom, context);
|
|
631
|
+
component.rendered();
|
|
764
632
|
}
|
|
765
633
|
else {
|
|
766
634
|
const prevSibling = this.getPrevSibling(component);
|
|
@@ -823,7 +691,6 @@ let Renderer = class Renderer {
|
|
|
823
691
|
atom.child = null;
|
|
824
692
|
}
|
|
825
693
|
this.diff(atom.child, diffAtom, context, 0, 0);
|
|
826
|
-
component.rendered();
|
|
827
694
|
}
|
|
828
695
|
diff(newAtom, oldAtom, context, expectIndex, index) {
|
|
829
696
|
const oldChildren = [];
|
|
@@ -839,9 +706,9 @@ let Renderer = class Renderer {
|
|
|
839
706
|
const changeCommits = {
|
|
840
707
|
reuseComponent: (start, reusedAtom, expectIndex, diffIndex) => {
|
|
841
708
|
commits.push(() => {
|
|
842
|
-
const {
|
|
843
|
-
if (
|
|
844
|
-
reusedAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.
|
|
709
|
+
const { add, remove, replace } = getObjectChanges(start.jsxNode.props, reusedAtom.jsxNode.props);
|
|
710
|
+
if (add.length || remove.length || replace.length) {
|
|
711
|
+
reusedAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.props);
|
|
845
712
|
}
|
|
846
713
|
const newProps = start.jsxNode.props;
|
|
847
714
|
start.jsxNode = reusedAtom.jsxNode;
|
|
@@ -916,7 +783,7 @@ let Renderer = class Renderer {
|
|
|
916
783
|
});
|
|
917
784
|
}
|
|
918
785
|
};
|
|
919
|
-
while (newAtom
|
|
786
|
+
while (newAtom) {
|
|
920
787
|
this.createChanges(newAtom, expectIndex, oldChildren, changeCommits);
|
|
921
788
|
newAtom = newAtom.sibling;
|
|
922
789
|
expectIndex++;
|
|
@@ -974,7 +841,7 @@ let Renderer = class Renderer {
|
|
|
974
841
|
isClean = true;
|
|
975
842
|
}
|
|
976
843
|
if (atom.jsxNode instanceof JSXElement) {
|
|
977
|
-
const ref = atom.jsxNode.props
|
|
844
|
+
const ref = atom.jsxNode.props[refKey];
|
|
978
845
|
this.applyRefs(ref, atom.nativeNode, false);
|
|
979
846
|
}
|
|
980
847
|
}
|
|
@@ -1046,24 +913,23 @@ let Renderer = class Renderer {
|
|
|
1046
913
|
}
|
|
1047
914
|
createChainByComponentFactory(context, factory, parent) {
|
|
1048
915
|
const component = factory.createInstance(context);
|
|
1049
|
-
if (component.setup === Fragment) {
|
|
1050
|
-
|
|
1051
|
-
|
|
916
|
+
// if (component.setup === Fragment) {
|
|
917
|
+
// const children = component.props.children
|
|
918
|
+
// return this.createChainByChildren(
|
|
919
|
+
// component,
|
|
920
|
+
// Array.isArray(children) ? children : [children],
|
|
921
|
+
// parent
|
|
922
|
+
// )
|
|
923
|
+
// }
|
|
1052
924
|
return new Atom(component, parent);
|
|
1053
925
|
}
|
|
1054
|
-
createChainByTemplate(context, template, parent) {
|
|
1055
|
-
if (template instanceof JSXElement) {
|
|
1056
|
-
return this.createChainByJSXElement(context, template, parent);
|
|
1057
|
-
}
|
|
1058
|
-
if (template instanceof JSXComponent) {
|
|
1059
|
-
return this.createChainByComponentFactory(context, template, parent);
|
|
1060
|
-
}
|
|
1061
|
-
return parent;
|
|
1062
|
-
}
|
|
1063
926
|
createChainByJSXElement(context, element, parent) {
|
|
1064
927
|
const atom = new Atom(element, parent);
|
|
1065
|
-
|
|
1066
|
-
|
|
928
|
+
if (Reflect.has(element.props, 'children')) {
|
|
929
|
+
const jsxChildren = element.props.children;
|
|
930
|
+
const children = this.createChainByChildren(context, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom);
|
|
931
|
+
this.link(atom, children);
|
|
932
|
+
}
|
|
1067
933
|
return atom;
|
|
1068
934
|
}
|
|
1069
935
|
createChainByJSXText(node, parent) {
|
|
@@ -1078,12 +944,7 @@ let Renderer = class Renderer {
|
|
|
1078
944
|
}
|
|
1079
945
|
if (item instanceof JSXComponent) {
|
|
1080
946
|
const childAtom = this.createChainByComponentFactory(context, item, parent);
|
|
1081
|
-
|
|
1082
|
-
atoms.push(...childAtom);
|
|
1083
|
-
}
|
|
1084
|
-
else {
|
|
1085
|
-
atoms.push(childAtom);
|
|
1086
|
-
}
|
|
947
|
+
atoms.push(childAtom);
|
|
1087
948
|
continue;
|
|
1088
949
|
}
|
|
1089
950
|
if (typeof item === 'string' && item.length) {
|
|
@@ -1101,10 +962,8 @@ let Renderer = class Renderer {
|
|
|
1101
962
|
return atoms;
|
|
1102
963
|
}
|
|
1103
964
|
linkTemplate(template, component, parent) {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
this.link(parent, Array.isArray(child) ? child : [child]);
|
|
1107
|
-
}
|
|
965
|
+
const children = Array.isArray(template) ? template : [template];
|
|
966
|
+
this.link(parent, this.createChainByChildren(component, children, parent));
|
|
1108
967
|
}
|
|
1109
968
|
link(parent, children) {
|
|
1110
969
|
for (let i = 1; i < children.length; i++) {
|
|
@@ -1114,25 +973,38 @@ let Renderer = class Renderer {
|
|
|
1114
973
|
parent.child = children[0] || null;
|
|
1115
974
|
}
|
|
1116
975
|
createElement(vNode) {
|
|
1117
|
-
const nativeNode = this.nativeRenderer.createElement(vNode.
|
|
976
|
+
const nativeNode = this.nativeRenderer.createElement(vNode.type);
|
|
1118
977
|
const props = vNode.props;
|
|
1119
978
|
let bindingRefs;
|
|
1120
|
-
|
|
979
|
+
const keys = Object.keys(props);
|
|
980
|
+
for (const key of keys) {
|
|
981
|
+
if (key === 'children') {
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
if (key === 'class') {
|
|
985
|
+
this.nativeRenderer.setClass(nativeNode, classToString(props[key]));
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
if (key === 'style') {
|
|
989
|
+
const style = styleToObject(props.style);
|
|
990
|
+
Object.keys(style).forEach(key => {
|
|
991
|
+
this.nativeRenderer.setStyle(nativeNode, key, style[key]);
|
|
992
|
+
});
|
|
993
|
+
continue;
|
|
994
|
+
}
|
|
995
|
+
if (/^on[A-Z]/.test(key)) {
|
|
996
|
+
const listener = props[key];
|
|
997
|
+
if (typeof listener === 'function') {
|
|
998
|
+
this.nativeRenderer.listen(nativeNode, key.replace(/^on/, '').toLowerCase(), listener);
|
|
999
|
+
}
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1121
1002
|
if (key === refKey) {
|
|
1122
|
-
bindingRefs =
|
|
1123
|
-
|
|
1003
|
+
bindingRefs = props[key];
|
|
1004
|
+
continue;
|
|
1124
1005
|
}
|
|
1125
|
-
this.nativeRenderer.setProperty(nativeNode, key,
|
|
1126
|
-
});
|
|
1127
|
-
props.styles.forEach((value, key) => {
|
|
1128
|
-
this.nativeRenderer.setStyle(nativeNode, key, value);
|
|
1129
|
-
});
|
|
1130
|
-
if (props.classes) {
|
|
1131
|
-
this.nativeRenderer.setClass(nativeNode, props.classes);
|
|
1006
|
+
this.nativeRenderer.setProperty(nativeNode, key, props[key]);
|
|
1132
1007
|
}
|
|
1133
|
-
Object.keys(props.listeners).forEach(type => {
|
|
1134
|
-
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1135
|
-
});
|
|
1136
1008
|
return {
|
|
1137
1009
|
nativeNode,
|
|
1138
1010
|
applyRefs: () => {
|
|
@@ -1144,46 +1016,109 @@ let Renderer = class Renderer {
|
|
|
1144
1016
|
return this.nativeRenderer.createTextNode(child.text);
|
|
1145
1017
|
}
|
|
1146
1018
|
updateNativeNodeProperties(newVNode, oldVNode, nativeNode) {
|
|
1147
|
-
const
|
|
1148
|
-
const oldProps = oldVNode.props;
|
|
1149
|
-
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
1150
|
-
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
1151
|
-
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
1152
|
-
styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
|
|
1153
|
-
styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
|
|
1019
|
+
const changes = getObjectChanges(newVNode.props, oldVNode.props);
|
|
1154
1020
|
let unBindRefs;
|
|
1155
|
-
|
|
1021
|
+
let bindRefs;
|
|
1022
|
+
for (const [key, value] of changes.remove) {
|
|
1023
|
+
if (key === 'children') {
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
1026
|
+
if (key === 'class') {
|
|
1027
|
+
this.nativeRenderer.setClass(nativeNode, '');
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
if (key === 'style') {
|
|
1031
|
+
Object.keys(styleToObject(value)).forEach(styleName => {
|
|
1032
|
+
this.nativeRenderer.removeStyle(nativeNode, styleName);
|
|
1033
|
+
});
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
if (/^on[A-Z]/.test(key)) {
|
|
1037
|
+
if (typeof value === 'function') {
|
|
1038
|
+
this.nativeRenderer.unListen(nativeNode, key.replace(/^on/, '').toLowerCase(), value);
|
|
1039
|
+
}
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1156
1042
|
if (key === refKey) {
|
|
1157
1043
|
unBindRefs = value;
|
|
1158
|
-
|
|
1044
|
+
continue;
|
|
1159
1045
|
}
|
|
1160
1046
|
this.nativeRenderer.removeProperty(nativeNode, key);
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1047
|
+
}
|
|
1048
|
+
for (const [key, newValue, oldValue] of changes.replace) {
|
|
1049
|
+
if (key === 'children') {
|
|
1050
|
+
continue;
|
|
1051
|
+
}
|
|
1052
|
+
if (key === 'class') {
|
|
1053
|
+
const oldClassName = classToString(oldValue);
|
|
1054
|
+
const newClassName = classToString(newValue);
|
|
1055
|
+
if (oldClassName !== newClassName) {
|
|
1056
|
+
this.nativeRenderer.setClass(nativeNode, newClassName);
|
|
1057
|
+
}
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
if (key === 'style') {
|
|
1061
|
+
const styleChanges = getObjectChanges(styleToObject(newValue) || {}, styleToObject(oldValue) || {});
|
|
1062
|
+
for (const [styleName] of styleChanges.remove) {
|
|
1063
|
+
this.nativeRenderer.removeStyle(nativeNode, styleName);
|
|
1064
|
+
}
|
|
1065
|
+
for (const [styleName, styleValue] of [...styleChanges.add, ...styleChanges.replace]) {
|
|
1066
|
+
this.nativeRenderer.setStyle(nativeNode, styleName, styleValue);
|
|
1067
|
+
}
|
|
1068
|
+
continue;
|
|
1069
|
+
}
|
|
1070
|
+
if (/^on[A-Z]/.test(key)) {
|
|
1071
|
+
const listenType = key.replace(/^on/, '').toLowerCase();
|
|
1072
|
+
if (typeof oldValue === 'function') {
|
|
1073
|
+
this.nativeRenderer.unListen(nativeNode, listenType, oldValue);
|
|
1074
|
+
}
|
|
1075
|
+
if (typeof newValue === 'function') {
|
|
1076
|
+
this.nativeRenderer.listen(nativeNode, listenType, newValue);
|
|
1077
|
+
}
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
if (key === refKey) {
|
|
1081
|
+
unBindRefs = oldValue;
|
|
1082
|
+
bindRefs = newValue;
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
this.nativeRenderer.setProperty(nativeNode, key, newValue);
|
|
1086
|
+
}
|
|
1087
|
+
for (const [key, value] of changes.add) {
|
|
1088
|
+
if (key === 'children') {
|
|
1089
|
+
continue;
|
|
1090
|
+
}
|
|
1091
|
+
if (key === 'class') {
|
|
1092
|
+
this.nativeRenderer.setClass(nativeNode, classToString(value));
|
|
1093
|
+
continue;
|
|
1094
|
+
}
|
|
1095
|
+
if (key === 'style') {
|
|
1096
|
+
const styleObj = styleToObject(value);
|
|
1097
|
+
Object.keys(styleObj).forEach(styleName => {
|
|
1098
|
+
this.nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName]);
|
|
1099
|
+
});
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
if (/^on[A-Z]/.test(key)) {
|
|
1103
|
+
if (typeof value === 'function') {
|
|
1104
|
+
this.nativeRenderer.listen(nativeNode, key.replace(/^on/, '').toLowerCase(), value);
|
|
1105
|
+
}
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1164
1108
|
if (key === refKey) {
|
|
1165
1109
|
bindRefs = value;
|
|
1166
|
-
|
|
1110
|
+
continue;
|
|
1167
1111
|
}
|
|
1168
1112
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
1169
|
-
});
|
|
1170
|
-
if (newProps.classes !== oldProps.classes) {
|
|
1171
|
-
this.nativeRenderer.setClass(nativeNode, newProps.classes);
|
|
1172
1113
|
}
|
|
1173
|
-
listenerChanges.remove.forEach(i => {
|
|
1174
|
-
this.nativeRenderer.unListen(nativeNode, i[0], i[1]);
|
|
1175
|
-
});
|
|
1176
|
-
listenerChanges.add.forEach(i => {
|
|
1177
|
-
this.nativeRenderer.listen(nativeNode, i[0], i[1]);
|
|
1178
|
-
});
|
|
1179
1114
|
return () => {
|
|
1180
1115
|
this.applyRefs(unBindRefs, nativeNode, false);
|
|
1181
1116
|
this.applyRefs(bindRefs, nativeNode, true);
|
|
1182
1117
|
};
|
|
1183
1118
|
}
|
|
1184
1119
|
applyRefs(refs, nativeNode, binding) {
|
|
1185
|
-
|
|
1186
|
-
for (const item of
|
|
1120
|
+
const refList = Array.isArray(refs) ? refs : [refs];
|
|
1121
|
+
for (const item of refList) {
|
|
1187
1122
|
if (item instanceof Ref) {
|
|
1188
1123
|
binding ? item.bind(nativeNode) : item.unBind(nativeNode);
|
|
1189
1124
|
}
|
|
@@ -1209,7 +1144,6 @@ class Viewfly extends ReflectiveInjector {
|
|
|
1209
1144
|
provide: RootComponentRef,
|
|
1210
1145
|
useFactory: () => {
|
|
1211
1146
|
return {
|
|
1212
|
-
host: config.host,
|
|
1213
1147
|
component: this.rootComponent
|
|
1214
1148
|
};
|
|
1215
1149
|
}
|
|
@@ -1228,8 +1162,11 @@ class Viewfly extends ReflectiveInjector {
|
|
|
1228
1162
|
}
|
|
1229
1163
|
/**
|
|
1230
1164
|
* 启动 Viewfly
|
|
1165
|
+
* @param host 应用根节点
|
|
1231
1166
|
*/
|
|
1232
|
-
|
|
1167
|
+
mount(host) {
|
|
1168
|
+
const rootComponentRef = this.get(RootComponentRef);
|
|
1169
|
+
rootComponentRef.host = host;
|
|
1233
1170
|
const renderer = this.get(Renderer);
|
|
1234
1171
|
renderer.render();
|
|
1235
1172
|
if (this.config.autoUpdate === false) {
|
|
@@ -1258,4 +1195,4 @@ class Viewfly extends ReflectiveInjector {
|
|
|
1258
1195
|
}
|
|
1259
1196
|
}
|
|
1260
1197
|
|
|
1261
|
-
export { Component, Fragment, JSXComponent, JSXElement, JSXText, NativeRenderer,
|
|
1198
|
+
export { Component, Fragment, JSXComponent, JSXElement, JSXText, NativeRenderer, Ref, Renderer, RootComponent, RootComponentRef, Viewfly, inject, jsx, jsxs, makeError, onDestroy, onMounted, onPropsChanged, onUpdated, provide, useDerived, useEffect, useRef, useSignal };
|