@simpreact/simpreact 0.0.0-alpha.1f6ee65 → 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 (65) hide show
  1. package/core/createElement.d.ts +22 -15
  2. package/core/createElement.js +67 -23
  3. package/core/hostAdapter.d.ts +17 -7
  4. package/core/hostAdapter.js +4 -1
  5. package/core/index.d.ts +68 -3
  6. package/core/index.js +6 -3
  7. package/core/internal.d.ts +6 -3
  8. package/core/internal.js +6 -3
  9. package/core/lifecycleEventBus.d.ts +26 -0
  10. package/core/lifecycleEventBus.js +2 -0
  11. package/core/mounting.d.ts +9 -8
  12. package/core/mounting.js +87 -50
  13. package/core/patching.d.ts +6 -4
  14. package/core/patching.js +150 -162
  15. package/core/portal.d.ts +2 -0
  16. package/core/portal.js +9 -0
  17. package/core/ref.d.ts +17 -0
  18. package/core/ref.js +27 -0
  19. package/core/rerender.d.ts +11 -0
  20. package/core/rerender.js +61 -3
  21. package/core/unmounting.d.ts +2 -4
  22. package/core/unmounting.js +26 -27
  23. package/dom/attach-element-to-dom.d.ts +4 -0
  24. package/dom/attach-element-to-dom.js +9 -0
  25. package/dom/domAdapter.d.ts +3 -2
  26. package/dom/domAdapter.js +37 -113
  27. package/dom/events.d.ts +19 -0
  28. package/dom/events.js +129 -0
  29. package/dom/index.d.ts +1733 -1
  30. package/dom/index.js +2 -0
  31. package/dom/namespace.d.ts +2 -0
  32. package/dom/namespace.js +1 -0
  33. package/dom/props/controlled/index.d.ts +7 -0
  34. package/dom/props/controlled/index.js +51 -0
  35. package/dom/props/controlled/input.d.ts +7 -0
  36. package/dom/props/controlled/input.js +80 -0
  37. package/dom/props/controlled/select.d.ts +6 -0
  38. package/dom/props/controlled/select.js +76 -0
  39. package/dom/props/controlled/textarea.d.ts +6 -0
  40. package/dom/props/controlled/textarea.js +61 -0
  41. package/dom/props/dangerInnerHTML.d.ts +7 -0
  42. package/dom/props/dangerInnerHTML.js +24 -0
  43. package/dom/props/index.d.ts +1 -0
  44. package/dom/props/index.js +1 -0
  45. package/dom/props/props.d.ts +5 -0
  46. package/dom/props/props.js +197 -0
  47. package/dom/props/style.d.ts +1 -0
  48. package/dom/props/style.js +32 -0
  49. package/dom/render.d.ts +2 -2
  50. package/dom/render.js +31 -19
  51. package/hooks/index.d.ts +23 -12
  52. package/hooks/index.js +123 -29
  53. package/jsx-runtime/index.d.ts +247 -4
  54. package/jsx-runtime/index.js +2 -5
  55. package/package.json +22 -15
  56. package/shared/index.d.ts +19 -4
  57. package/shared/index.js +5 -4
  58. package/shared/lang.d.ts +3 -3
  59. package/shared/lang.js +3 -3
  60. package/shared/utils.d.ts +3 -2
  61. package/shared/utils.js +3 -6
  62. package/core/global.d.ts +0 -21
  63. package/core/global.js +0 -5
  64. package/shared/types.d.ts +0 -8
  65. package/shared/types.js +0 -1
@@ -1,2 +1,3 @@
1
- import type { HostAdapter } from '../core/internal';
2
- export declare const domAdapter: HostAdapter<HTMLElement, Text>;
1
+ import type { HostAdapter } from '../core/internal.js';
2
+ import type { Namespace } from './namespace';
3
+ export declare const domAdapter: HostAdapter<HTMLElement | SVGElement, Text, Namespace>;
package/dom/domAdapter.js CHANGED
@@ -1,20 +1,34 @@
1
+ import { attachElementToDom } from './attach-element-to-dom';
2
+ import { mountProps, patchProps, unmountProps } from './props';
3
+ import { defaultNamespace } from './namespace';
1
4
  export const domAdapter = {
2
- createReference(type) {
3
- return document.createElement(type);
5
+ createReference(type, namespace) {
6
+ if (namespace) {
7
+ return document.createElementNS(namespace, type);
8
+ }
9
+ else {
10
+ return document.createElement(type);
11
+ }
4
12
  },
5
13
  createTextReference(text) {
6
14
  return document.createTextNode(text);
7
15
  },
8
- mountProps(reference, props) {
9
- mountProps(props, reference);
16
+ mountProps(dom, element, namespace) {
17
+ mountProps(dom, element, namespace || defaultNamespace);
10
18
  },
11
- patchProp(reference, propName, prevValue, nextValue) {
12
- patchProp(propName, prevValue, nextValue, reference);
19
+ patchProps(dom, prevElement, nextElement, namespace) {
20
+ patchProps(dom, prevElement, nextElement, namespace || defaultNamespace);
13
21
  },
14
- setClassname(reference, className) {
22
+ unmountProps(dom, element) {
23
+ unmountProps(dom, element);
24
+ },
25
+ setClassname(reference, className, namespace) {
15
26
  if (!className) {
16
27
  reference.removeAttribute('class');
17
28
  }
29
+ else if (namespace === 'http://www.w3.org/2000/svg') {
30
+ reference.setAttribute('class', className);
31
+ }
18
32
  else {
19
33
  reference.className = className;
20
34
  }
@@ -45,115 +59,25 @@ export const domAdapter = {
45
59
  findParentReference(reference) {
46
60
  return reference.parentElement;
47
61
  },
62
+ findNextSiblingReference(reference) {
63
+ return reference.nextSibling;
64
+ },
48
65
  clearNode(reference) {
49
66
  reference.textContent = '';
50
67
  },
51
- };
52
- function mountProps(props, reference) {
53
- for (const propsKey in props) {
54
- patchProp(propsKey, null, props[propsKey], reference);
55
- }
56
- }
57
- function patchProp(propName, prevValue, nextValue, dom) {
58
- switch (propName) {
59
- case 'children':
60
- case 'childrenType':
61
- case 'className':
62
- case 'defaultValue':
63
- case 'key':
64
- case 'multiple':
65
- case 'ref':
66
- case 'selectedIndex':
67
- break;
68
- case 'autoFocus':
69
- dom.autofocus = !!nextValue;
70
- break;
71
- case 'allowfullscreen':
72
- case 'autoplay':
73
- case 'capture':
74
- case 'checked':
75
- case 'controls':
76
- case 'default':
77
- case 'disabled':
78
- case 'hidden':
79
- case 'indeterminate':
80
- case 'loop':
81
- case 'muted':
82
- case 'novalidate':
83
- case 'open':
84
- case 'readOnly':
85
- case 'required':
86
- case 'reversed':
87
- case 'scoped':
88
- case 'seamless':
89
- case 'selected':
90
- dom[propName] = !!nextValue;
91
- break;
92
- case 'defaultChecked':
93
- case 'value':
94
- case 'volume':
95
- patchDomProp(nextValue, dom, propName);
96
- break;
97
- case 'style':
98
- patchStyle(prevValue, nextValue, dom);
99
- break;
100
- default:
101
- if (propName.charCodeAt(0) === 111 && propName.charCodeAt(1) === 110) {
102
- patchEvent(propName, prevValue, nextValue, dom);
103
- }
104
- else if (nextValue == null) {
105
- dom.removeAttribute(propName);
106
- }
107
- else {
108
- dom.setAttribute(propName, nextValue);
109
- }
110
- break;
111
- }
112
- }
113
- function patchDomProp(nextValue, dom, propKey) {
114
- const value = nextValue == null ? '' : nextValue;
115
- if (dom[propKey] !== value) {
116
- dom[propKey] = value;
117
- }
118
- }
119
- function patchStyle(lastAttrValue, nextAttrValue, dom) {
120
- if (nextAttrValue == null) {
121
- dom.removeAttribute('style');
122
- return;
123
- }
124
- const domStyle = dom.style;
125
- let style;
126
- let value;
127
- if (typeof nextAttrValue === 'string') {
128
- domStyle.cssText = nextAttrValue;
129
- return;
130
- }
131
- if (lastAttrValue != null && typeof lastAttrValue !== 'string') {
132
- for (style in nextAttrValue) {
133
- value = nextAttrValue[style];
134
- if (value !== lastAttrValue[style]) {
135
- domStyle.setProperty(style, value);
136
- }
68
+ attachElementToReference(element, reference) {
69
+ attachElementToDom(element, reference);
70
+ },
71
+ getHostNamespaces(element, currentNamespace) {
72
+ if (element.type === 'svg') {
73
+ return { self: 'http://www.w3.org/2000/svg', children: 'http://www.w3.org/2000/svg' };
137
74
  }
138
- for (style in lastAttrValue) {
139
- if (nextAttrValue[style] == null) {
140
- domStyle.removeProperty(style);
141
- }
75
+ if (element.type === 'foreignObject') {
76
+ return { self: 'http://www.w3.org/2000/svg', children: null };
142
77
  }
143
- }
144
- else {
145
- for (style in nextAttrValue) {
146
- value = nextAttrValue[style];
147
- domStyle.setProperty(style, value);
78
+ if (currentNamespace && currentNamespace !== 'http://www.w3.org/1999/xhtml') {
79
+ return { self: currentNamespace, children: currentNamespace };
148
80
  }
149
- }
150
- }
151
- function patchEvent(name, lastValue, nextValue, dom) {
152
- name = name.toLowerCase().substring(2);
153
- if (typeof lastValue === 'function') {
154
- dom.removeEventListener(name, lastValue);
155
- }
156
- if (typeof nextValue === 'function') {
157
- dom.addEventListener(name, nextValue);
158
- }
159
- }
81
+ return null;
82
+ },
83
+ };
@@ -0,0 +1,19 @@
1
+ import type { Nullable } from '../shared';
2
+ type DelegatedEventType = 'click' | 'dblclick' | 'mousedown' | 'mouseup' | 'mousemove' | 'pointerdown' | 'pointerup' | 'pointermove' | 'touchstart' | 'touchmove' | 'touchend' | 'keydown' | 'keyup' | 'focusin' | 'focusout';
3
+ export declare class SyntheticEvent {
4
+ nativeEvent: Event;
5
+ currentTarget: Nullable<EventTarget>;
6
+ isPropagationStopped: boolean;
7
+ isDefaultPrevented: boolean;
8
+ constructor(event: Event);
9
+ get target(): EventTarget | null;
10
+ get type(): string;
11
+ stopPropagation(): void;
12
+ preventDefault(): void;
13
+ }
14
+ export declare function dispatchDelegatedEvent(event: Event): void;
15
+ export declare function patchEvent(name: string, prevValue: any, nextValue: any, dom: Element): void;
16
+ export declare function patchDelegatedEvent(eventType: DelegatedEventType, handler: any, eventHandlerCounts: Record<DelegatedEventType, number>): void;
17
+ export declare function patchNormalEvent(eventType: string, prevValue: any, nextValue: any, dom: Element, capture: boolean): void;
18
+ export declare function isPropNameEventName(name: string): boolean;
19
+ export {};
package/dom/events.js ADDED
@@ -0,0 +1,129 @@
1
+ import { syncRerenderLocker } from '../core/internal.js';
2
+ import { getElementFromDom } from './attach-element-to-dom';
3
+ const eventNameByTypes = {
4
+ click: 'onClick',
5
+ dblclick: 'onDblClick',
6
+ mousedown: 'onMouseDown',
7
+ mouseup: 'onMouseUp',
8
+ mousemove: 'onMouseMove',
9
+ pointerdown: 'onPointerDown',
10
+ pointerup: 'onPointerUp',
11
+ pointermove: 'onPointerMove',
12
+ touchstart: 'onTouchStart',
13
+ touchmove: 'onTouchMove',
14
+ touchend: 'onTouchEnd',
15
+ keydown: 'onKeyDown',
16
+ keyup: 'onKeyUp',
17
+ focusin: 'onFocusIn',
18
+ focusout: 'onFocusOut',
19
+ };
20
+ const delegatedEventTypes = new Set(Object.keys(eventNameByTypes));
21
+ const eventHandlerCounts = {
22
+ click: 0,
23
+ dblclick: 0,
24
+ mousedown: 0,
25
+ mouseup: 0,
26
+ mousemove: 0,
27
+ pointerdown: 0,
28
+ pointerup: 0,
29
+ pointermove: 0,
30
+ touchstart: 0,
31
+ touchmove: 0,
32
+ touchend: 0,
33
+ keydown: 0,
34
+ keyup: 0,
35
+ focusin: 0,
36
+ focusout: 0,
37
+ };
38
+ export class SyntheticEvent {
39
+ nativeEvent;
40
+ currentTarget = null;
41
+ isPropagationStopped = false;
42
+ isDefaultPrevented = false;
43
+ constructor(event) {
44
+ this.nativeEvent = event;
45
+ }
46
+ get target() {
47
+ return this.nativeEvent.target;
48
+ }
49
+ get type() {
50
+ return this.nativeEvent.type;
51
+ }
52
+ stopPropagation() {
53
+ this.isPropagationStopped = true;
54
+ this.nativeEvent.stopPropagation();
55
+ }
56
+ preventDefault() {
57
+ this.isDefaultPrevented = true;
58
+ this.nativeEvent.preventDefault();
59
+ }
60
+ }
61
+ export function dispatchDelegatedEvent(event) {
62
+ syncRerenderLocker.lock();
63
+ const syntheticEvent = new SyntheticEvent(event);
64
+ const captureHandlers = [];
65
+ const bubbleHandlers = [];
66
+ let element = getElementFromDom(event.target);
67
+ while (element) {
68
+ if (element.flag === 'HOST') {
69
+ const captureHandler = element.props?.[eventNameByTypes[event.type] + 'Capture'];
70
+ const bubbleHandler = element.props?.[eventNameByTypes[event.type]];
71
+ if (captureHandler) {
72
+ captureHandlers.push({ element, handler: captureHandler });
73
+ }
74
+ if (bubbleHandler) {
75
+ bubbleHandlers.push({ element, handler: bubbleHandler });
76
+ }
77
+ }
78
+ element = element.parent;
79
+ }
80
+ for (const { handler, element } of captureHandlers.reverse()) {
81
+ syntheticEvent.currentTarget = element.reference;
82
+ handler(syntheticEvent);
83
+ if (syntheticEvent.isPropagationStopped) {
84
+ return;
85
+ }
86
+ }
87
+ for (const { element, handler } of bubbleHandlers) {
88
+ syntheticEvent.currentTarget = element.reference;
89
+ handler(syntheticEvent);
90
+ if (syntheticEvent.isPropagationStopped) {
91
+ return;
92
+ }
93
+ }
94
+ syncRerenderLocker.flush();
95
+ }
96
+ const captureRegex = /Capture/;
97
+ export function patchEvent(name, prevValue, nextValue, dom) {
98
+ const isCapture = captureRegex.test(name);
99
+ name = name.replace(captureRegex, '').substring(2).toLowerCase();
100
+ if (delegatedEventTypes.has(name)) {
101
+ patchDelegatedEvent(name, nextValue, eventHandlerCounts);
102
+ }
103
+ else {
104
+ patchNormalEvent(name, prevValue, nextValue, dom, isCapture);
105
+ }
106
+ }
107
+ export function patchDelegatedEvent(eventType, handler, eventHandlerCounts) {
108
+ if (typeof handler === 'function') {
109
+ if (++eventHandlerCounts[eventType] === 1) {
110
+ document.addEventListener(eventType, dispatchDelegatedEvent);
111
+ }
112
+ }
113
+ else {
114
+ if (eventHandlerCounts[eventType] !== 0 && --eventHandlerCounts[eventType] === 0) {
115
+ document.removeEventListener(eventType, dispatchDelegatedEvent);
116
+ }
117
+ }
118
+ }
119
+ export function patchNormalEvent(eventType, prevValue, nextValue, dom, capture) {
120
+ if (typeof prevValue === 'function') {
121
+ dom.removeEventListener(eventType, prevValue, { capture });
122
+ }
123
+ if (typeof nextValue === 'function') {
124
+ dom.addEventListener(eventType, nextValue, { capture });
125
+ }
126
+ }
127
+ export function isPropNameEventName(name) {
128
+ return name.charCodeAt(0) === 111 && name.charCodeAt(1) === 110;
129
+ }