@simpreact/simpreact 0.0.0-alpha.dd6f145 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/core/context.d.ts +18 -0
  2. package/core/context.js +18 -0
  3. package/core/createElement.d.ts +24 -15
  4. package/core/createElement.js +93 -27
  5. package/core/fragment.js +1 -2
  6. package/core/hostAdapter.d.ts +19 -8
  7. package/core/hostAdapter.js +4 -1
  8. package/core/index.d.ts +68 -2
  9. package/core/index.js +6 -2
  10. package/core/internal.d.ts +7 -3
  11. package/core/internal.js +7 -3
  12. package/core/lifecycleEventBus.d.ts +26 -0
  13. package/core/lifecycleEventBus.js +2 -0
  14. package/core/mounting.d.ts +11 -7
  15. package/core/mounting.js +104 -38
  16. package/core/patching.d.ts +8 -5
  17. package/core/patching.js +157 -161
  18. package/core/portal.d.ts +2 -0
  19. package/core/portal.js +9 -0
  20. package/core/ref.d.ts +17 -0
  21. package/core/ref.js +27 -0
  22. package/core/rerender.d.ts +11 -0
  23. package/core/rerender.js +61 -3
  24. package/core/unmounting.d.ts +4 -6
  25. package/core/unmounting.js +33 -39
  26. package/dom/attach-element-to-dom.d.ts +4 -0
  27. package/dom/attach-element-to-dom.js +9 -0
  28. package/dom/domAdapter.d.ts +3 -2
  29. package/dom/domAdapter.js +42 -115
  30. package/dom/events.d.ts +19 -0
  31. package/dom/events.js +129 -0
  32. package/dom/index.d.ts +1733 -1
  33. package/dom/index.js +2 -0
  34. package/dom/namespace.d.ts +2 -0
  35. package/dom/namespace.js +1 -0
  36. package/dom/props/controlled/index.d.ts +7 -0
  37. package/dom/props/controlled/index.js +51 -0
  38. package/dom/props/controlled/input.d.ts +7 -0
  39. package/dom/props/controlled/input.js +80 -0
  40. package/dom/props/controlled/select.d.ts +6 -0
  41. package/dom/props/controlled/select.js +76 -0
  42. package/dom/props/controlled/textarea.d.ts +6 -0
  43. package/dom/props/controlled/textarea.js +61 -0
  44. package/dom/props/dangerInnerHTML.d.ts +7 -0
  45. package/dom/props/dangerInnerHTML.js +24 -0
  46. package/dom/props/index.d.ts +1 -0
  47. package/dom/props/index.js +1 -0
  48. package/dom/props/props.d.ts +5 -0
  49. package/dom/props/props.js +197 -0
  50. package/dom/props/style.d.ts +1 -0
  51. package/dom/props/style.js +32 -0
  52. package/dom/render.d.ts +3 -3
  53. package/dom/render.js +31 -17
  54. package/hooks/index.d.ts +23 -10
  55. package/hooks/index.js +126 -32
  56. package/jsx-runtime/index.d.ts +247 -4
  57. package/jsx-runtime/index.js +3 -6
  58. package/package.json +22 -15
  59. package/shared/EventBus.js +1 -3
  60. package/shared/index.d.ts +19 -4
  61. package/shared/index.js +5 -4
  62. package/shared/lang.d.ts +3 -4
  63. package/shared/lang.js +3 -4
  64. package/shared/utils.d.ts +3 -3
  65. package/shared/utils.js +3 -7
  66. package/core/global.d.ts +0 -21
  67. package/core/global.js +0 -5
  68. package/core/jsx-runtime.d.ts +0 -2
  69. package/core/jsx-runtime.js +0 -2
  70. package/shared/types.d.ts +0 -8
  71. package/shared/types.js +0 -1
package/core/mounting.js CHANGED
@@ -1,66 +1,132 @@
1
- import { EMPTY_OBJECT } from '../shared';
2
- import { GLOBAL } from './global';
3
- import { normalizeRoot } from './createElement';
4
- export function mount(element, parentReference, nextReference) {
1
+ import { emptyMap, emptyObject } from '../shared';
2
+ import { hostAdapter } from './hostAdapter';
3
+ import { createTextElement, normalizeRoot } from './createElement';
4
+ import { applyRef } from './ref';
5
+ import { lifecycleEventBus } from './lifecycleEventBus';
6
+ export function mount(element, parentReference, nextReference, contextMap, hostNamespace) {
5
7
  if (element.flag === 'TEXT') {
6
8
  mountTextElement(element, parentReference, nextReference);
7
9
  }
8
10
  else if (element.flag === 'HOST') {
9
- mountHostElement(element, parentReference, nextReference);
11
+ mountHostElement(element, parentReference, nextReference, contextMap, hostNamespace);
10
12
  }
11
13
  else if (element.flag === 'FC') {
12
- mountFunctionalElement(element, parentReference, nextReference);
14
+ mountFunctionalElement(element, parentReference, nextReference, contextMap, hostNamespace);
13
15
  }
14
16
  else if (element.flag === 'FRAGMENT') {
15
- mountFragment(element, parentReference, nextReference);
17
+ mountFragment(element, parentReference, nextReference, contextMap, hostNamespace);
18
+ }
19
+ else if (element.flag === 'PROVIDER') {
20
+ mountProvider(element, parentReference, nextReference, contextMap, hostNamespace);
21
+ }
22
+ else if (element.flag === 'PORTAL') {
23
+ mountPortal(element, parentReference, nextReference, contextMap);
24
+ }
25
+ else {
26
+ mountConsumer(element, parentReference, nextReference, contextMap, hostNamespace);
16
27
  }
17
28
  }
18
29
  export function mountTextElement(element, parentReference, nextReference) {
19
- const reference = (element.reference || (element.reference = GLOBAL.hostAdapter.createTextReference(element.children)));
20
- if (parentReference != null) {
21
- GLOBAL.hostAdapter.insertOrAppend(parentReference, reference, nextReference);
30
+ const reference = (element.reference = hostAdapter.createTextReference(element.children));
31
+ if (parentReference) {
32
+ hostAdapter.insertOrAppend(parentReference, reference, nextReference);
22
33
  }
23
34
  }
24
- export function mountHostElement(element, parentReference, nextReference) {
25
- const props = element.props;
26
- const className = element.className;
27
- const hostReference = (element.reference = GLOBAL.hostAdapter.createReference(element.type));
35
+ export function mountHostElement(element, parentReference, nextReference, contextMap, hostNamespace) {
36
+ const hostNamespaces = hostAdapter.getHostNamespaces(element, hostNamespace);
37
+ hostNamespace = hostNamespaces?.self;
38
+ const hostReference = (element.reference = hostAdapter.createReference(element.type, hostNamespace));
39
+ hostAdapter.attachElementToReference(element, hostReference);
40
+ if (parentReference) {
41
+ hostAdapter.insertOrAppend(parentReference, hostReference, nextReference);
42
+ }
28
43
  // HOST element always has Maybe<Many<SimpElement>> children due to normalization process.
29
44
  const children = element.children;
30
- if (className != null && className !== '') {
31
- GLOBAL.hostAdapter.setClassname(hostReference, className);
32
- }
33
45
  if (Array.isArray(children)) {
34
- mountArrayChildren(children, hostReference, null);
46
+ mountArrayChildren(children, hostReference, null, contextMap, element, hostNamespaces?.children);
47
+ }
48
+ else if (children) {
49
+ children.parent = element;
50
+ mount(children, hostReference, null, contextMap, hostNamespaces?.children);
35
51
  }
36
- else if (children != null) {
37
- mount(children, hostReference, null);
52
+ if (element.props) {
53
+ hostAdapter.mountProps(hostReference, element, hostNamespace);
38
54
  }
39
- if (parentReference != null) {
40
- GLOBAL.hostAdapter.insertOrAppend(parentReference, hostReference, nextReference);
55
+ if (element.className) {
56
+ hostAdapter.setClassname(hostReference, element.className, hostNamespace);
41
57
  }
42
- GLOBAL.hostAdapter.mountProps(hostReference, props);
58
+ applyRef(element);
43
59
  }
44
- export function mountFunctionalElement(element, parentReference, nextReference) {
45
- const type = element.type;
46
- GLOBAL.eventBus.publish({ type: 'beforeRender', element });
47
- element.children = normalizeRoot(type(element.props || EMPTY_OBJECT));
48
- GLOBAL.eventBus.publish({ type: 'afterRender' });
49
- mount(element.children, parentReference, nextReference);
50
- GLOBAL.eventBus.publish({ type: 'mounted', element });
60
+ export function mountFunctionalElement(element, parentReference, nextReference, contextMap, hostNamespace) {
61
+ if (contextMap) {
62
+ element.contextMap = contextMap;
63
+ }
64
+ if (element.unmounted) {
65
+ element.unmounted = false;
66
+ }
67
+ element.store = { latestElement: element };
68
+ if (hostNamespace) {
69
+ element.store.hostNamespace = hostNamespace;
70
+ }
71
+ // FC element always has Maybe<SimpElement> children due to normalization process.
72
+ let children;
73
+ try {
74
+ lifecycleEventBus.publish({ type: 'beforeRender', element, phase: 'mounting' });
75
+ children = normalizeRoot(element.type(element.props || emptyObject), false);
76
+ lifecycleEventBus.publish({ type: 'afterRender', phase: 'mounting' });
77
+ }
78
+ catch (error) {
79
+ lifecycleEventBus.publish({ type: 'errored', element, error, phase: 'mounting' });
80
+ return;
81
+ }
82
+ if (children) {
83
+ children.parent = element;
84
+ mount((element.children = children), parentReference, nextReference, contextMap, hostNamespace);
85
+ }
86
+ lifecycleEventBus.publish({ type: 'mounted', element });
51
87
  }
52
- export function mountFragment(element, parentReference, nextReference) {
88
+ export function mountFragment(element, parentReference, nextReference, contextMap, hostNamespace) {
53
89
  // FRAGMENT element always has Maybe<Many<SimpElement>> children due to normalization process.
54
- const children = element.children;
55
- if (Array.isArray(children)) {
56
- mountArrayChildren(children, parentReference, nextReference);
90
+ if (Array.isArray(element.children)) {
91
+ mountArrayChildren(element.children, parentReference, nextReference, contextMap, element, hostNamespace);
57
92
  }
58
- else if (children != null) {
59
- mount(children, parentReference, nextReference);
93
+ else if (element.children) {
94
+ element.children.parent = element;
95
+ mount(element.children, parentReference, nextReference, contextMap, hostNamespace);
60
96
  }
61
97
  }
62
- export function mountArrayChildren(children, reference, nextReference) {
98
+ export function mountArrayChildren(children, reference, nextReference, contextMap, parentElement, hostNamespace) {
63
99
  for (const child of children) {
64
- mount(child, reference, nextReference);
100
+ child.parent = parentElement;
101
+ mount(child, reference, nextReference, contextMap, hostNamespace);
102
+ }
103
+ }
104
+ export function mountProvider(element, parentReference, nextReference, contextMap, hostNamespace) {
105
+ contextMap = new Map(contextMap);
106
+ contextMap.set(element.type.context, element.props.value);
107
+ // PROVIDER element always has Maybe<Many<SimpElement>> children due to normalization process.
108
+ if (Array.isArray(element.children)) {
109
+ mountArrayChildren(element.children, parentReference, nextReference, contextMap, element, hostNamespace);
110
+ }
111
+ else if (element.children) {
112
+ element.children.parent = element;
113
+ mount(element.children, parentReference, nextReference, contextMap, hostNamespace);
114
+ }
115
+ }
116
+ export function mountConsumer(element, parentReference, nextReference, contextMap, hostNamespace) {
117
+ const children = normalizeRoot(element.type(element.props || emptyObject, contextMap || emptyMap), false);
118
+ if (!children) {
119
+ return;
120
+ }
121
+ children.parent = element;
122
+ mount((element.children = children), parentReference, nextReference, contextMap, hostNamespace);
123
+ }
124
+ export function mountPortal(element, parentReference, nextReference, contextMap) {
125
+ if (element.children) {
126
+ element.children.parent = element;
127
+ mount(element.children, element.ref, null, contextMap, hostAdapter.getHostNamespaces(element.children, undefined)?.self);
65
128
  }
129
+ const placeHolderElement = createTextElement('');
130
+ mountTextElement(placeHolderElement, parentReference, nextReference);
131
+ element.reference = placeHolderElement.reference;
66
132
  }
@@ -1,7 +1,10 @@
1
+ import type { Maybe, Nullable } from '../shared';
1
2
  import type { SimpElement } from './createElement';
2
- import type { Nullable } from '../shared';
3
3
  import type { HostReference } from './hostAdapter';
4
- export declare function patch<HostRef = HostReference>(prevElement: SimpElement, nextElement: SimpElement, parentReference: HostRef, nextReference: Nullable<HostRef>): void;
5
- export declare function findHostReferenceFromElement(element: SimpElement, startEdge: boolean): Nullable<HostReference>;
6
- export declare function updateFunctionalComponent(element: SimpElement, parentReference: HostReference, nextReference: Nullable<HostReference>): void;
7
- export declare function patchKeyedChildren<HostRef = HostReference>(prevChildren: SimpElement[], nextChildren: SimpElement[], parentReference: HostRef, nextReference: Nullable<HostRef>): void;
4
+ import type { SimpContextMap } from './context';
5
+ export declare function patch(prevElement: SimpElement, nextElement: SimpElement, parentReference: HostReference, nextReference: Nullable<HostReference>, contextMap: Nullable<SimpContextMap>, hostNamespace: Maybe<string>): void;
6
+ export declare function patchPortal(prevElement: SimpElement, nextElement: SimpElement, contextMap: Nullable<SimpContextMap>): void;
7
+ export declare function updateFunctionalComponent(element: SimpElement, parentReference: HostReference, nextReference: Nullable<HostReference>, contextMap: Nullable<SimpContextMap>, hostNamespace: Maybe<string>): void;
8
+ export declare function patchKeyedChildren(prevChildren: SimpElement[], nextChildren: SimpElement[], parentReference: HostReference, nextReference: Nullable<HostReference>, contextMap: Nullable<SimpContextMap>, hostNamespace: Maybe<string>): void;
9
+ export declare function findParentReferenceFromElement(element: SimpElement): Nullable<HostReference>;
10
+ export declare function findHostReferenceFromElement(element: SimpElement): Nullable<HostReference>;
package/core/patching.js CHANGED
@@ -1,200 +1,171 @@
1
+ import { emptyMap, emptyObject } from '../shared';
1
2
  import { normalizeRoot } from './createElement';
2
- import { EMPTY_OBJECT, isArray, isPrimitive } from '../shared';
3
- import { clearElementHostReference, remove, removeAllChildren, unmount, unmountAllChildren } from './unmounting';
3
+ import { hostAdapter } from './hostAdapter';
4
+ import { clearElementHostReference, remove, unmount } from './unmounting';
4
5
  import { mount, mountArrayChildren } from './mounting';
5
- import { GLOBAL } from './global';
6
- export function patch(prevElement, nextElement, parentReference, nextReference) {
6
+ import { applyRef } from './ref';
7
+ import { lifecycleEventBus } from './lifecycleEventBus';
8
+ export function patch(prevElement, nextElement, parentReference, nextReference, contextMap, hostNamespace) {
7
9
  if (prevElement.type !== nextElement.type || prevElement.key !== nextElement.key) {
8
- replaceWithNewElement(prevElement, nextElement, parentReference);
10
+ replaceWithNewElement(prevElement, nextElement, parentReference, contextMap, hostNamespace);
9
11
  }
10
12
  else if (nextElement.flag === 'HOST') {
11
- patchElement(prevElement, nextElement);
13
+ patchHostElement(prevElement, nextElement, contextMap, hostNamespace);
12
14
  }
13
15
  else if (nextElement.flag === 'FC') {
14
- if (prevElement.store != null) {
15
- nextElement.store = prevElement.store;
16
- }
17
- patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference);
16
+ patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference, contextMap, hostNamespace);
18
17
  }
19
18
  else if (nextElement.flag === 'TEXT') {
20
- patchText(prevElement, nextElement);
19
+ patchTextElement(prevElement, nextElement);
20
+ }
21
+ else if (nextElement.flag === 'FRAGMENT') {
22
+ patchFragment(prevElement, nextElement, parentReference, contextMap, hostNamespace);
23
+ }
24
+ else if (nextElement.flag === 'PROVIDER') {
25
+ patchProvider(prevElement, nextElement, parentReference, contextMap, hostNamespace);
26
+ }
27
+ else if (nextElement.flag === 'PORTAL') {
28
+ patchPortal(prevElement, nextElement, contextMap);
21
29
  }
22
30
  else {
23
- patchFragment(prevElement, nextElement, parentReference);
31
+ patchConsumer(prevElement, nextElement, parentReference, nextReference, contextMap, hostNamespace);
24
32
  }
25
33
  }
26
- function replaceWithNewElement(prevElement, nextElement, parentReference) {
34
+ function replaceWithNewElement(prevElement, nextElement, parentReference, contextMap, hostNamespace) {
27
35
  unmount(prevElement);
36
+ nextElement.parent = prevElement.parent;
28
37
  if (nextElement.flag === 'HOST' && prevElement.flag === 'HOST') {
29
- mount(nextElement, null, null);
30
- GLOBAL.hostAdapter.replaceChild(parentReference, nextElement.reference, prevElement.reference);
38
+ mount(nextElement, null, null, contextMap, hostNamespace);
39
+ hostAdapter.replaceChild(parentReference, nextElement.reference, prevElement.reference);
31
40
  }
32
41
  else {
33
- mount(nextElement, parentReference, findHostReferenceFromElement(prevElement, true));
42
+ mount(nextElement, parentReference, findHostReferenceFromElement(prevElement), contextMap, hostNamespace);
34
43
  clearElementHostReference(prevElement, parentReference);
35
44
  }
36
45
  }
37
- export function findHostReferenceFromElement(element, startEdge) {
38
- let flag;
39
- let temp = element;
40
- while (temp != null) {
41
- flag = temp.flag;
42
- if (flag === 'HOST' || flag === 'TEXT') {
43
- return temp.reference;
44
- }
45
- temp = findChildElement(temp, startEdge);
46
+ function patchHostElement(prevElement, nextElement, contextMap, hostNamespace) {
47
+ if (prevElement.ref) {
48
+ nextElement.ref = prevElement.ref;
46
49
  }
47
- return null;
48
- }
49
- function findChildElement(element, startEdge) {
50
- const children = element.children;
51
- if (isArray(children)) {
52
- return children[startEdge ? 0 : children.length - 1];
50
+ const hostNamespaces = hostAdapter.getHostNamespaces(nextElement, hostNamespace);
51
+ hostNamespace = hostNamespaces?.self;
52
+ nextElement.reference = prevElement.reference;
53
+ hostAdapter.attachElementToReference(nextElement, nextElement.reference);
54
+ patchChildren(prevElement.children, nextElement.children, nextElement.reference, null, nextElement, contextMap, hostNamespaces?.children);
55
+ hostAdapter.patchProps(nextElement.reference, prevElement, nextElement, hostNamespace);
56
+ if (prevElement.className !== nextElement.className) {
57
+ hostAdapter.setClassname(nextElement.reference, nextElement.className, hostNamespace);
53
58
  }
54
- return children;
59
+ applyRef(nextElement);
55
60
  }
56
- function patchElement(prevElement, nextElement) {
57
- const hostReference = (nextElement.reference = prevElement.reference);
58
- const prevProps = prevElement.props;
59
- const nextProps = nextElement.props;
60
- for (const propName in nextProps) {
61
- const prevValue = prevProps[propName];
62
- const nextValue = nextProps[propName];
63
- if (prevValue !== nextValue) {
64
- GLOBAL.hostAdapter.patchProp(hostReference, propName, prevValue, nextValue);
65
- }
61
+ function patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference, contextMap, hostNamespace) {
62
+ (nextElement.store = prevElement.store ||= {}).latestElement = nextElement;
63
+ if (hostNamespace) {
64
+ nextElement.store.hostNamespace = hostNamespace;
66
65
  }
67
- for (const propName in prevProps) {
68
- if (nextProps[propName] == null && prevProps[propName] != null) {
69
- GLOBAL.hostAdapter.patchProp(hostReference, propName, prevProps[propName], null);
70
- }
66
+ if (contextMap) {
67
+ nextElement.contextMap = contextMap;
68
+ }
69
+ let nextChildren;
70
+ try {
71
+ lifecycleEventBus.publish({ type: 'beforeRender', element: nextElement, phase: 'updating' });
72
+ nextChildren = normalizeRoot(nextElement.type(nextElement.props || emptyObject), false);
73
+ lifecycleEventBus.publish({ type: 'afterRender', phase: 'updating' });
74
+ }
75
+ catch (error) {
76
+ lifecycleEventBus.publish({ type: 'errored', element: nextElement, error, phase: 'updating' });
77
+ return;
71
78
  }
72
79
  const prevChildren = prevElement.children;
80
+ if (nextChildren) {
81
+ nextElement.children = nextChildren;
82
+ }
83
+ patchChildren(prevChildren, nextChildren, parentReference, nextReference, nextElement, contextMap, hostNamespace);
84
+ lifecycleEventBus.publish({ type: 'updated', element: nextElement });
85
+ }
86
+ function patchTextElement(prevElement, nextElement) {
87
+ nextElement.reference = prevElement.reference;
88
+ if (nextElement.children !== prevElement.children) {
89
+ hostAdapter.setTextContent(nextElement.reference, nextElement.children);
90
+ }
91
+ }
92
+ function patchFragment(prevElement, nextElement, parentReference, contextMap, hostNamespace) {
93
+ let nextReference = null;
94
+ if (Array.isArray(prevElement.children) && !Array.isArray(nextElement.children) && nextElement.children) {
95
+ nextReference = hostAdapter.findNextSiblingReference(findHostReferenceFromElement(prevElement.children[prevElement.children.length - 1]));
96
+ }
97
+ patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, contextMap, hostNamespace);
98
+ }
99
+ function patchProvider(prevElement, nextElement, parentReference, contextMap, hostNamespace) {
100
+ let nextReference = null;
101
+ if (Array.isArray(prevElement.children) && !Array.isArray(nextElement.children) && nextElement.children) {
102
+ nextReference = hostAdapter.findNextSiblingReference(findHostReferenceFromElement(prevElement.children[prevElement.children.length - 1]));
103
+ }
104
+ contextMap = new Map(contextMap);
105
+ contextMap.set(nextElement.type.context, nextElement.props.value);
106
+ patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, contextMap, hostNamespace);
107
+ }
108
+ function patchConsumer(prevElement, nextElement, parentReference, nextReference, contextMap, hostNamespace) {
109
+ const children = normalizeRoot(nextElement.type(nextElement.props || emptyObject, contextMap || emptyMap), false);
110
+ if (children) {
111
+ nextElement.children = children;
112
+ }
113
+ patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, contextMap, hostNamespace);
114
+ }
115
+ export function patchPortal(prevElement, nextElement, contextMap) {
116
+ const prevContainer = prevElement.ref;
117
+ const nextContainer = nextElement.ref;
73
118
  const nextChildren = nextElement.children;
74
- const nextClassName = nextElement.className;
75
- if (prevElement.className !== nextClassName) {
76
- GLOBAL.hostAdapter.setClassname(hostReference, nextClassName);
119
+ patchChildren(prevElement.children, nextChildren, prevContainer, null, nextElement, contextMap, hostAdapter.getHostNamespaces(nextChildren, undefined)?.self);
120
+ nextElement.reference = prevElement.reference;
121
+ if (prevContainer !== nextContainer && nextChildren != null) {
122
+ hostAdapter.removeChild(prevContainer, nextChildren.reference);
123
+ hostAdapter.appendChild(nextContainer, nextChildren.reference);
77
124
  }
78
- patchChildren(prevChildren, nextChildren, hostReference, null, prevElement);
79
125
  }
80
- function patchChildren(prevChildren, nextChildren, parentReference, nextReference, parentElement) {
81
- if (isArray(prevChildren)) {
82
- if (isArray(nextChildren)) {
83
- const prevChildrenLength = prevChildren.length;
84
- const nextChildrenLength = nextChildren.length;
85
- if (prevChildrenLength === 0) {
86
- if (nextChildrenLength > 0) {
87
- mountArrayChildren(nextChildren, parentReference, nextReference);
88
- }
89
- }
90
- else if (nextChildrenLength === 0) {
91
- removeAllChildren(parentReference, parentElement, prevChildren);
92
- }
93
- else {
94
- patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference);
126
+ export function updateFunctionalComponent(element, parentReference, nextReference, contextMap, hostNamespace) {
127
+ patchFunctionalComponent(element, element, parentReference, nextReference, contextMap, hostNamespace);
128
+ }
129
+ function patchChildren(prevChildren, nextChildren, parentReference, nextReference, nextElement, contextMap, hostNamespace) {
130
+ if (Array.isArray(prevChildren)) {
131
+ if (Array.isArray(nextChildren)) {
132
+ for (const child of nextChildren) {
133
+ child.parent = nextElement;
95
134
  }
135
+ patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference, contextMap, hostNamespace);
96
136
  }
97
- else if (isPrimitive(nextChildren)) {
98
- unmountAllChildren(prevChildren);
99
- GLOBAL.hostAdapter.setTextContent(parentReference, (nextChildren || ''));
137
+ else if (nextChildren) {
138
+ patchKeyedChildren(prevChildren, [nextChildren], parentReference, nextReference, contextMap, hostNamespace);
100
139
  }
101
140
  else {
102
- removeAllChildren(parentReference, parentElement, prevChildren);
103
- mount(nextChildren, parentReference, nextReference);
141
+ unmount(prevChildren);
142
+ hostAdapter.clearNode(parentReference);
104
143
  }
105
144
  }
106
- else if (isPrimitive(prevChildren)) {
107
- if (isArray(nextChildren)) {
108
- GLOBAL.hostAdapter.setTextContent(parentReference, '');
109
- mountArrayChildren(nextChildren, parentReference, nextReference);
145
+ else if (prevChildren) {
146
+ if (Array.isArray(nextChildren)) {
147
+ patchKeyedChildren([prevChildren], nextChildren, parentReference, nextReference, contextMap, hostNamespace);
110
148
  }
111
- else if (isPrimitive(nextChildren)) {
112
- patchSingleTextChild(prevChildren, nextChildren, parentReference);
149
+ else if (nextChildren) {
150
+ nextChildren.parent = nextElement;
151
+ patch(prevChildren, nextChildren, parentReference, nextReference, contextMap, hostNamespace);
113
152
  }
114
153
  else {
115
- GLOBAL.hostAdapter.setTextContent(parentReference, '');
116
- mount(nextChildren, parentReference, nextReference);
154
+ unmount(prevChildren);
155
+ hostAdapter.clearNode(parentReference);
117
156
  }
118
157
  }
119
158
  else {
120
- if (isArray(nextChildren)) {
121
- replaceOneElementWithMultipleElements(prevChildren, nextChildren, parentReference);
159
+ if (Array.isArray(nextChildren)) {
160
+ mountArrayChildren(nextChildren, parentReference, nextReference, contextMap, nextElement, hostNamespace);
122
161
  }
123
- else if (isPrimitive(nextChildren)) {
124
- unmount(prevChildren);
125
- GLOBAL.hostAdapter.setTextContent(parentReference, nextChildren);
126
- }
127
- else {
128
- patch(prevChildren, nextChildren, parentReference, nextReference);
162
+ else if (nextChildren) {
163
+ nextChildren.parent = nextElement;
164
+ mount(nextChildren, parentReference, nextReference, contextMap, hostNamespace);
129
165
  }
130
166
  }
131
167
  }
132
- function replaceOneElementWithMultipleElements(prevChildren, nextChildren, parentReference) {
133
- unmount(prevChildren);
134
- mountArrayChildren(nextChildren, parentReference, findHostReferenceFromElement(prevChildren, true));
135
- clearElementHostReference(prevChildren, parentReference);
136
- }
137
- function patchSingleTextChild(prevChildren, nextChildren, parentReference) {
138
- if (prevChildren !== nextChildren) {
139
- GLOBAL.hostAdapter.setTextContent(parentReference, nextChildren);
140
- }
141
- }
142
- // export function patchNonKeyedChildren(
143
- // prevChildren: SimpElement[],
144
- // nextChildren: SimpElement[],
145
- // parentReference: HostReference,
146
- // prevChildrenLength: number,
147
- // nextChildrenLength: number,
148
- // nextReference: Nullable<HostReference>
149
- // ): void {
150
- // const commonLength = prevChildrenLength > nextChildrenLength ? nextChildrenLength : prevChildrenLength;
151
- // let i = 0;
152
- // let prevChild;
153
- // let nextChild;
154
- //
155
- // for (; i < commonLength; ++i) {
156
- // nextChild = nextChildren[i];
157
- // prevChild = prevChildren[i];
158
- //
159
- // patch(prevChild as SimpElement, nextChild as SimpElement, parentReference, nextReference);
160
- // prevChildren[i] = nextChild!;
161
- // }
162
- // if (prevChildrenLength < nextChildrenLength) {
163
- // for (i = commonLength; i < nextChildrenLength; ++i) {
164
- // nextChild = nextChildren[i];
165
- // mount(nextChild as SimpElement, parentReference, nextReference);
166
- // }
167
- // } else if (prevChildrenLength > nextChildrenLength) {
168
- // for (i = commonLength; i < prevChildrenLength; ++i) {
169
- // remove(prevChildren[i] as SimpElement, parentReference);
170
- // }
171
- // }
172
- // }
173
- function patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference) {
174
- const prevChildren = prevElement.children;
175
- const type = nextElement.type;
176
- GLOBAL.eventBus.publish({ type: 'beforeRender', element: nextElement });
177
- const nextChildren = normalizeRoot(type(nextElement.props || EMPTY_OBJECT));
178
- GLOBAL.eventBus.publish({ type: 'afterRender' });
179
- patch(prevChildren, nextChildren, parentReference, nextReference);
180
- GLOBAL.eventBus.publish({ type: 'mounted', element: nextElement });
181
- nextElement.children = nextChildren;
182
- }
183
- function patchText(prevElement, nextElement) {
184
- const nextText = nextElement.children;
185
- const reference = (nextElement.reference = prevElement.reference);
186
- if (nextText !== prevElement.children) {
187
- GLOBAL.hostAdapter.setTextContent(reference, nextText);
188
- }
189
- }
190
- function patchFragment(prevElement, nextElement, parentReference) {
191
- patchChildren(prevElement.children, nextElement.children, parentReference, null, prevElement);
192
- }
193
- export function updateFunctionalComponent(element, parentReference, nextReference) {
194
- patch(element, element, parentReference, nextReference);
195
- }
196
- export function patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference) {
197
- var _a, _b, _c;
168
+ export function patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference, contextMap, hostNamespace) {
198
169
  let prevStart = 0;
199
170
  let nextStart = 0;
200
171
  let prevEnd = prevChildren.length - 1;
@@ -203,21 +174,21 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
203
174
  while (prevStart <= prevEnd &&
204
175
  nextStart <= nextEnd &&
205
176
  prevChildren[prevStart].key === nextChildren[nextStart].key) {
206
- patch(prevChildren[prevStart], nextChildren[nextStart], parentReference, null);
177
+ patch(prevChildren[prevStart], nextChildren[nextStart], parentReference, null, contextMap, hostNamespace);
207
178
  prevStart++;
208
179
  nextStart++;
209
180
  }
210
181
  // Step 2: Sync from end
211
182
  while (prevStart <= prevEnd && nextStart <= nextEnd && prevChildren[prevEnd].key === nextChildren[nextEnd].key) {
212
- patch(prevChildren[prevEnd], nextChildren[nextEnd], parentReference, null);
183
+ patch(prevChildren[prevEnd], nextChildren[nextEnd], parentReference, null, contextMap, hostNamespace);
213
184
  prevEnd--;
214
185
  nextEnd--;
215
186
  }
216
187
  // Step 3: Mount new nodes if prev list is exhausted
217
188
  if (prevStart > prevEnd) {
218
- const before = ((_a = nextChildren[nextEnd + 1]) === null || _a === void 0 ? void 0 : _a.reference) || nextReference;
189
+ const before = nextChildren[nextEnd + 1]?.reference || nextReference;
219
190
  for (let i = nextStart; i <= nextEnd; i++) {
220
- mount(nextChildren[i], parentReference, before);
191
+ mount(nextChildren[i], parentReference, before, contextMap, hostNamespace);
221
192
  }
222
193
  // Step 4: Remove prev nodes if next list is exhausted
223
194
  }
@@ -232,8 +203,9 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
232
203
  const keyToPrevIndexMap = new Map();
233
204
  for (let i = prevStart; i <= prevEnd; i++) {
234
205
  const key = prevChildren[i].key;
235
- if (key != null)
206
+ if (key != null) {
236
207
  keyToPrevIndexMap.set(key, i);
208
+ }
237
209
  }
238
210
  // Track reused indices and move plan
239
211
  const toMove = new Array(nextEnd - nextStart + 1);
@@ -244,12 +216,12 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
244
216
  const prevIndex = keyToPrevIndexMap.get(nextChild.key);
245
217
  if (prevIndex != null) {
246
218
  const prevElement = prevChildren[prevIndex];
247
- patch(prevElement, nextChild, parentReference, null);
219
+ patch(prevElement, nextChild, parentReference, null, contextMap, hostNamespace);
248
220
  toMove[i - nextStart] = prevIndex;
249
221
  usedIndices.add(prevIndex);
250
222
  }
251
223
  else {
252
- mount(nextChild, parentReference, ((_b = nextChildren[i + 1]) === null || _b === void 0 ? void 0 : _b.reference) || nextReference);
224
+ mount(nextChild, parentReference, nextChildren[i + 1]?.reference || nextReference, contextMap, hostNamespace);
253
225
  toMove[i - nextStart] = -1;
254
226
  }
255
227
  }
@@ -262,10 +234,34 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
262
234
  // Insert in correct order
263
235
  for (let i = nextEnd; i >= nextStart; i--) {
264
236
  const currentChild = nextChildren[i];
265
- const reference = ((_c = nextChildren[i + 1]) === null || _c === void 0 ? void 0 : _c.reference) || nextReference;
237
+ const reference = nextChildren[i + 1]?.reference || nextReference;
266
238
  if (toMove[i - nextStart] !== -1) {
267
- GLOBAL.hostAdapter.insertBefore(parentReference, currentChild.reference, reference);
239
+ hostAdapter.insertBefore(parentReference, currentChild.reference, reference);
268
240
  }
269
241
  }
270
242
  }
271
243
  }
244
+ export function findParentReferenceFromElement(element) {
245
+ let flag;
246
+ let temp = element;
247
+ while (temp != null) {
248
+ flag = temp.flag;
249
+ if (flag === 'HOST') {
250
+ return temp.reference;
251
+ }
252
+ temp = temp.parent;
253
+ }
254
+ return null;
255
+ }
256
+ export function findHostReferenceFromElement(element) {
257
+ let flag;
258
+ let temp = element;
259
+ while (temp != null) {
260
+ flag = temp.flag;
261
+ if (flag === 'HOST' || flag === 'TEXT' || flag === 'PORTAL') {
262
+ return temp.reference;
263
+ }
264
+ temp = (Array.isArray(temp.children) ? temp.children[0] : temp.children);
265
+ }
266
+ return null;
267
+ }
@@ -0,0 +1,2 @@
1
+ import type { SimpElement, SimpNode } from './createElement';
2
+ export declare function createPortal(children: SimpNode, container: any): SimpElement;
package/core/portal.js ADDED
@@ -0,0 +1,9 @@
1
+ import { normalizeRoot } from './createElement';
2
+ export function createPortal(children, container) {
3
+ const element = { flag: 'PORTAL', parent: null };
4
+ if ((children = normalizeRoot(children, false))) {
5
+ element.children = children;
6
+ }
7
+ element.ref = container;
8
+ return element;
9
+ }
package/core/ref.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type { SimpElement } from './createElement';
2
+ interface RefSimpElement extends SimpElement {
3
+ ref?: {
4
+ value: NonNullable<Ref<unknown>>;
5
+ cleanup?: () => void;
6
+ };
7
+ }
8
+ export interface RefObject<T> {
9
+ current: T;
10
+ }
11
+ export type RefCallback<T> = {
12
+ bivarianceHack(instance: T | null): (() => void) | void;
13
+ }['bivarianceHack'];
14
+ export type Ref<T> = RefCallback<T> | RefObject<T> | null;
15
+ export declare function unmountRef(element: RefSimpElement): void;
16
+ export declare function applyRef(element: RefSimpElement): void;
17
+ export {};