@simpreact/simpreact 0.0.0-alpha.dd6f145 → 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.
Files changed (72) hide show
  1. package/core/context.d.ts +18 -0
  2. package/core/context.js +18 -0
  3. package/core/createElement.d.ts +25 -16
  4. package/core/createElement.js +99 -28
  5. package/core/fragment.d.ts +1 -1
  6. package/core/fragment.js +1 -2
  7. package/core/hostAdapter.d.ts +20 -9
  8. package/core/hostAdapter.js +4 -1
  9. package/core/index.d.ts +68 -2
  10. package/core/index.js +6 -2
  11. package/core/internal.d.ts +11 -7
  12. package/core/internal.js +11 -7
  13. package/core/lifecycleEventBus.d.ts +26 -0
  14. package/core/lifecycleEventBus.js +2 -0
  15. package/core/mounting.d.ts +13 -9
  16. package/core/mounting.js +108 -38
  17. package/core/patching.d.ts +10 -7
  18. package/core/patching.js +186 -160
  19. package/core/portal.d.ts +2 -0
  20. package/core/portal.js +9 -0
  21. package/core/ref.d.ts +17 -0
  22. package/core/ref.js +27 -0
  23. package/core/rerender.d.ts +12 -1
  24. package/core/rerender.js +67 -3
  25. package/core/unmounting.d.ts +6 -8
  26. package/core/unmounting.js +33 -39
  27. package/dom/attach-element-to-dom.d.ts +4 -0
  28. package/dom/attach-element-to-dom.js +9 -0
  29. package/dom/domAdapter.d.ts +3 -2
  30. package/dom/domAdapter.js +49 -117
  31. package/dom/events.d.ts +19 -0
  32. package/dom/events.js +129 -0
  33. package/dom/index.d.ts +1733 -1
  34. package/dom/index.js +3 -1
  35. package/dom/namespace.d.ts +2 -0
  36. package/dom/namespace.js +1 -0
  37. package/dom/props/controlled/index.d.ts +7 -0
  38. package/dom/props/controlled/index.js +51 -0
  39. package/dom/props/controlled/input.d.ts +7 -0
  40. package/dom/props/controlled/input.js +80 -0
  41. package/dom/props/controlled/select.d.ts +6 -0
  42. package/dom/props/controlled/select.js +76 -0
  43. package/dom/props/controlled/textarea.d.ts +6 -0
  44. package/dom/props/controlled/textarea.js +61 -0
  45. package/dom/props/dangerInnerHTML.d.ts +7 -0
  46. package/dom/props/dangerInnerHTML.js +24 -0
  47. package/dom/props/index.d.ts +1 -0
  48. package/dom/props/index.js +1 -0
  49. package/dom/props/props.d.ts +5 -0
  50. package/dom/props/props.js +197 -0
  51. package/dom/props/style.d.ts +1 -0
  52. package/dom/props/style.js +32 -0
  53. package/dom/render.d.ts +4 -4
  54. package/dom/render.js +32 -18
  55. package/hooks/index.d.ts +23 -10
  56. package/hooks/index.js +126 -32
  57. package/jsx-runtime/index.d.ts +248 -5
  58. package/jsx-runtime/index.js +3 -6
  59. package/package.json +22 -14
  60. package/shared/EventBus.js +1 -3
  61. package/shared/index.d.ts +19 -4
  62. package/shared/index.js +5 -4
  63. package/shared/lang.d.ts +3 -4
  64. package/shared/lang.js +3 -4
  65. package/shared/utils.d.ts +3 -3
  66. package/shared/utils.js +3 -7
  67. package/core/global.d.ts +0 -21
  68. package/core/global.js +0 -5
  69. package/core/jsx-runtime.d.ts +0 -2
  70. package/core/jsx-runtime.js +0 -2
  71. package/shared/types.d.ts +0 -8
  72. package/shared/types.js +0 -1
package/core/mounting.js CHANGED
@@ -1,66 +1,136 @@
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/index.js';
2
+ import { hostAdapter } from './hostAdapter.js';
3
+ import { createTextElement, normalizeRoot } from './createElement.js';
4
+ import { applyRef } from './ref.js';
5
+ import { lifecycleEventBus } from './lifecycleEventBus.js';
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);
28
40
  // HOST element always has Maybe<Many<SimpElement>> children due to normalization process.
29
41
  const children = element.children;
30
- if (className != null && className !== '') {
31
- GLOBAL.hostAdapter.setClassname(hostReference, className);
32
- }
33
42
  if (Array.isArray(children)) {
34
- mountArrayChildren(children, hostReference, null);
43
+ mountArrayChildren(children, hostReference, null, contextMap, element, hostNamespaces?.children);
44
+ }
45
+ else if (children) {
46
+ children.parent = element;
47
+ mount(children, hostReference, null, contextMap, hostNamespaces?.children);
48
+ }
49
+ if (element.props) {
50
+ hostAdapter.mountProps(hostReference, element, hostNamespace);
51
+ // HOST elements can have either children elements or string children in the props due to normalization.
52
+ if (typeof element.props.children === 'string') {
53
+ hostAdapter.setTextContent(hostReference, element.props.children);
54
+ }
35
55
  }
36
- else if (children != null) {
37
- mount(children, hostReference, null);
56
+ if (element.className) {
57
+ hostAdapter.setClassname(hostReference, element.className, hostNamespace);
38
58
  }
39
- if (parentReference != null) {
40
- GLOBAL.hostAdapter.insertOrAppend(parentReference, hostReference, nextReference);
59
+ if (parentReference) {
60
+ hostAdapter.insertOrAppend(parentReference, hostReference, nextReference);
41
61
  }
42
- GLOBAL.hostAdapter.mountProps(hostReference, props);
62
+ applyRef(element);
43
63
  }
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 });
64
+ export function mountFunctionalElement(element, parentReference, nextReference, contextMap, hostNamespace) {
65
+ if (contextMap) {
66
+ element.contextMap = contextMap;
67
+ }
68
+ if (element.unmounted) {
69
+ element.unmounted = false;
70
+ }
71
+ element.store = { latestElement: element };
72
+ if (hostNamespace) {
73
+ element.store.hostNamespace = hostNamespace;
74
+ }
75
+ // FC element always has Maybe<SimpElement> children due to normalization process.
76
+ let children;
77
+ try {
78
+ lifecycleEventBus.publish({ type: 'beforeRender', element, phase: 'mounting' });
79
+ children = normalizeRoot(element.type(element.props || emptyObject), false);
80
+ lifecycleEventBus.publish({ type: 'afterRender', phase: 'mounting' });
81
+ }
82
+ catch (error) {
83
+ lifecycleEventBus.publish({ type: 'errored', element, error, phase: 'mounting' });
84
+ return;
85
+ }
86
+ if (children) {
87
+ children.parent = element;
88
+ mount((element.children = children), parentReference, nextReference, contextMap, hostNamespace);
89
+ }
90
+ lifecycleEventBus.publish({ type: 'mounted', element });
51
91
  }
52
- export function mountFragment(element, parentReference, nextReference) {
92
+ export function mountFragment(element, parentReference, nextReference, contextMap, hostNamespace) {
53
93
  // 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);
94
+ if (Array.isArray(element.children)) {
95
+ mountArrayChildren(element.children, parentReference, nextReference, contextMap, element, hostNamespace);
57
96
  }
58
- else if (children != null) {
59
- mount(children, parentReference, nextReference);
97
+ else if (element.children) {
98
+ element.children.parent = element;
99
+ mount(element.children, parentReference, nextReference, contextMap, hostNamespace);
60
100
  }
61
101
  }
62
- export function mountArrayChildren(children, reference, nextReference) {
102
+ export function mountArrayChildren(children, reference, nextReference, contextMap, parentElement, hostNamespace) {
63
103
  for (const child of children) {
64
- mount(child, reference, nextReference);
104
+ child.parent = parentElement;
105
+ mount(child, reference, nextReference, contextMap, hostNamespace);
106
+ }
107
+ }
108
+ export function mountProvider(element, parentReference, nextReference, contextMap, hostNamespace) {
109
+ contextMap = new Map(contextMap);
110
+ contextMap.set(element.type.context, element.props.value);
111
+ // PROVIDER element always has Maybe<Many<SimpElement>> children due to normalization process.
112
+ if (Array.isArray(element.children)) {
113
+ mountArrayChildren(element.children, parentReference, nextReference, contextMap, element, hostNamespace);
114
+ }
115
+ else if (element.children) {
116
+ element.children.parent = element;
117
+ mount(element.children, parentReference, nextReference, contextMap, hostNamespace);
118
+ }
119
+ }
120
+ export function mountConsumer(element, parentReference, nextReference, contextMap, hostNamespace) {
121
+ const children = normalizeRoot(element.type(element.props || emptyObject, contextMap || emptyMap), false);
122
+ if (!children) {
123
+ return;
124
+ }
125
+ children.parent = element;
126
+ mount((element.children = children), parentReference, nextReference, contextMap, hostNamespace);
127
+ }
128
+ export function mountPortal(element, parentReference, nextReference, contextMap) {
129
+ if (element.children) {
130
+ element.children.parent = element;
131
+ mount(element.children, element.ref, null, contextMap, hostAdapter.getHostNamespaces(element.children, undefined)?.self);
65
132
  }
133
+ const placeHolderElement = createTextElement('');
134
+ mountTextElement(placeHolderElement, parentReference, nextReference);
135
+ element.reference = placeHolderElement.reference;
66
136
  }
@@ -1,7 +1,10 @@
1
- import type { SimpElement } from './createElement';
2
- import type { Nullable } from '../shared';
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;
1
+ import type { Maybe, Nullable } from '../shared/index.js';
2
+ import type { SimpElement } from './createElement.js';
3
+ import type { HostReference } from './hostAdapter.js';
4
+ import type { SimpContextMap } from './context.js';
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,201 @@
1
- import { normalizeRoot } from './createElement';
2
- import { EMPTY_OBJECT, isArray, isPrimitive } from '../shared';
3
- import { clearElementHostReference, remove, removeAllChildren, unmount, unmountAllChildren } from './unmounting';
4
- import { mount, mountArrayChildren } from './mounting';
5
- import { GLOBAL } from './global';
6
- export function patch(prevElement, nextElement, parentReference, nextReference) {
1
+ import { emptyMap, emptyObject } from '../shared/index.js';
2
+ import { normalizeRoot } from './createElement.js';
3
+ import { hostAdapter } from './hostAdapter.js';
4
+ import { clearElementHostReference, remove, unmount } from './unmounting.js';
5
+ import { mount, mountArrayChildren } from './mounting.js';
6
+ import { applyRef } from './ref.js';
7
+ import { lifecycleEventBus } from './lifecycleEventBus.js';
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 || prevElement.props?.children, nextElement.children || nextElement.props?.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);
136
+ }
137
+ else if (typeof nextChildren === 'string') {
138
+ unmount(prevChildren);
139
+ hostAdapter.setTextContent(parentReference, nextChildren);
96
140
  }
97
- else if (isPrimitive(nextChildren)) {
98
- unmountAllChildren(prevChildren);
99
- GLOBAL.hostAdapter.setTextContent(parentReference, (nextChildren || ''));
141
+ else if (nextChildren) {
142
+ patchKeyedChildren(prevChildren, [nextChildren], parentReference, nextReference, contextMap, hostNamespace);
100
143
  }
101
144
  else {
102
- removeAllChildren(parentReference, parentElement, prevChildren);
103
- mount(nextChildren, parentReference, nextReference);
145
+ unmount(prevChildren);
146
+ hostAdapter.clearNode(parentReference);
104
147
  }
105
148
  }
106
- else if (isPrimitive(prevChildren)) {
107
- if (isArray(nextChildren)) {
108
- GLOBAL.hostAdapter.setTextContent(parentReference, '');
109
- mountArrayChildren(nextChildren, parentReference, nextReference);
149
+ else if (typeof prevChildren === 'string') {
150
+ if (Array.isArray(nextChildren)) {
151
+ hostAdapter.clearNode(parentReference);
152
+ mountArrayChildren(nextChildren, parentReference, nextReference, contextMap, nextElement, hostNamespace);
153
+ }
154
+ else if (typeof nextChildren === 'string') {
155
+ if (prevChildren !== nextChildren) {
156
+ hostAdapter.setTextContent(nextElement.reference, nextChildren, true);
157
+ }
110
158
  }
111
- else if (isPrimitive(nextChildren)) {
112
- patchSingleTextChild(prevChildren, nextChildren, parentReference);
159
+ else if (nextChildren) {
160
+ hostAdapter.clearNode(parentReference);
161
+ nextChildren.parent = nextElement;
162
+ mount(nextChildren, parentReference, nextReference, contextMap, hostNamespace);
113
163
  }
114
164
  else {
115
- GLOBAL.hostAdapter.setTextContent(parentReference, '');
116
- mount(nextChildren, parentReference, nextReference);
165
+ hostAdapter.clearNode(parentReference);
117
166
  }
118
167
  }
119
- else {
120
- if (isArray(nextChildren)) {
121
- replaceOneElementWithMultipleElements(prevChildren, nextChildren, parentReference);
168
+ else if (prevChildren) {
169
+ if (Array.isArray(nextChildren)) {
170
+ patchKeyedChildren([prevChildren], nextChildren, parentReference, nextReference, contextMap, hostNamespace);
122
171
  }
123
- else if (isPrimitive(nextChildren)) {
172
+ else if (typeof nextChildren === 'string') {
124
173
  unmount(prevChildren);
125
- GLOBAL.hostAdapter.setTextContent(parentReference, nextChildren);
174
+ hostAdapter.setTextContent(parentReference, nextChildren);
175
+ }
176
+ else if (nextChildren) {
177
+ nextChildren.parent = nextElement;
178
+ patch(prevChildren, nextChildren, parentReference, nextReference, contextMap, hostNamespace);
126
179
  }
127
180
  else {
128
- patch(prevChildren, nextChildren, parentReference, nextReference);
181
+ unmount(prevChildren);
182
+ hostAdapter.clearNode(parentReference);
129
183
  }
130
184
  }
131
- }
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);
185
+ else {
186
+ if (Array.isArray(nextChildren)) {
187
+ mountArrayChildren(nextChildren, parentReference, nextReference, contextMap, nextElement, hostNamespace);
188
+ }
189
+ else if (typeof nextChildren === 'string') {
190
+ hostAdapter.setTextContent(parentReference, nextChildren);
191
+ }
192
+ else if (nextChildren) {
193
+ nextChildren.parent = nextElement;
194
+ mount(nextChildren, parentReference, nextReference, contextMap, hostNamespace);
195
+ }
188
196
  }
189
197
  }
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;
198
+ export function patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference, contextMap, hostNamespace) {
198
199
  let prevStart = 0;
199
200
  let nextStart = 0;
200
201
  let prevEnd = prevChildren.length - 1;
@@ -203,21 +204,21 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
203
204
  while (prevStart <= prevEnd &&
204
205
  nextStart <= nextEnd &&
205
206
  prevChildren[prevStart].key === nextChildren[nextStart].key) {
206
- patch(prevChildren[prevStart], nextChildren[nextStart], parentReference, null);
207
+ patch(prevChildren[prevStart], nextChildren[nextStart], parentReference, null, contextMap, hostNamespace);
207
208
  prevStart++;
208
209
  nextStart++;
209
210
  }
210
211
  // Step 2: Sync from end
211
212
  while (prevStart <= prevEnd && nextStart <= nextEnd && prevChildren[prevEnd].key === nextChildren[nextEnd].key) {
212
- patch(prevChildren[prevEnd], nextChildren[nextEnd], parentReference, null);
213
+ patch(prevChildren[prevEnd], nextChildren[nextEnd], parentReference, null, contextMap, hostNamespace);
213
214
  prevEnd--;
214
215
  nextEnd--;
215
216
  }
216
217
  // Step 3: Mount new nodes if prev list is exhausted
217
218
  if (prevStart > prevEnd) {
218
- const before = ((_a = nextChildren[nextEnd + 1]) === null || _a === void 0 ? void 0 : _a.reference) || nextReference;
219
+ const before = nextChildren[nextEnd + 1]?.reference || nextReference;
219
220
  for (let i = nextStart; i <= nextEnd; i++) {
220
- mount(nextChildren[i], parentReference, before);
221
+ mount(nextChildren[i], parentReference, before, contextMap, hostNamespace);
221
222
  }
222
223
  // Step 4: Remove prev nodes if next list is exhausted
223
224
  }
@@ -232,8 +233,9 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
232
233
  const keyToPrevIndexMap = new Map();
233
234
  for (let i = prevStart; i <= prevEnd; i++) {
234
235
  const key = prevChildren[i].key;
235
- if (key != null)
236
+ if (key != null) {
236
237
  keyToPrevIndexMap.set(key, i);
238
+ }
237
239
  }
238
240
  // Track reused indices and move plan
239
241
  const toMove = new Array(nextEnd - nextStart + 1);
@@ -244,12 +246,12 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
244
246
  const prevIndex = keyToPrevIndexMap.get(nextChild.key);
245
247
  if (prevIndex != null) {
246
248
  const prevElement = prevChildren[prevIndex];
247
- patch(prevElement, nextChild, parentReference, null);
249
+ patch(prevElement, nextChild, parentReference, null, contextMap, hostNamespace);
248
250
  toMove[i - nextStart] = prevIndex;
249
251
  usedIndices.add(prevIndex);
250
252
  }
251
253
  else {
252
- mount(nextChild, parentReference, ((_b = nextChildren[i + 1]) === null || _b === void 0 ? void 0 : _b.reference) || nextReference);
254
+ mount(nextChild, parentReference, nextChildren[i + 1]?.reference || nextReference, contextMap, hostNamespace);
253
255
  toMove[i - nextStart] = -1;
254
256
  }
255
257
  }
@@ -262,10 +264,34 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
262
264
  // Insert in correct order
263
265
  for (let i = nextEnd; i >= nextStart; i--) {
264
266
  const currentChild = nextChildren[i];
265
- const reference = ((_c = nextChildren[i + 1]) === null || _c === void 0 ? void 0 : _c.reference) || nextReference;
267
+ const reference = nextChildren[i + 1]?.reference || nextReference;
266
268
  if (toMove[i - nextStart] !== -1) {
267
- GLOBAL.hostAdapter.insertBefore(parentReference, currentChild.reference, reference);
269
+ hostAdapter.insertBefore(parentReference, currentChild.reference, reference);
268
270
  }
269
271
  }
270
272
  }
271
273
  }
274
+ export function findParentReferenceFromElement(element) {
275
+ let flag;
276
+ let temp = element;
277
+ while (temp != null) {
278
+ flag = temp.flag;
279
+ if (flag === 'HOST') {
280
+ return temp.reference;
281
+ }
282
+ temp = temp.parent;
283
+ }
284
+ return null;
285
+ }
286
+ export function findHostReferenceFromElement(element) {
287
+ let flag;
288
+ let temp = element;
289
+ while (temp != null) {
290
+ flag = temp.flag;
291
+ if (flag === 'HOST' || flag === 'TEXT' || flag === 'PORTAL') {
292
+ return temp.reference;
293
+ }
294
+ temp = (Array.isArray(temp.children) ? temp.children[0] : temp.children);
295
+ }
296
+ return null;
297
+ }
@@ -0,0 +1,2 @@
1
+ import type { SimpElement, SimpNode } from './createElement.js';
2
+ export declare function createPortal(children: SimpNode, container: any): SimpElement;
package/core/portal.js ADDED
@@ -0,0 +1,9 @@
1
+ import { normalizeRoot } from './createElement.js';
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
+ }