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