lilact 0.31.11 → 0.31.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lilact",
3
- "version": "0.31.11",
3
+ "version": "0.31.13",
4
4
  "description": "A Little React/JSX Runtime Implementation for Browser",
5
5
  "repository": "github:arashkazemi/lilact",
6
6
  "homepage": "https://arashkazemi.github.io/lilact/",
package/src/events.jsx CHANGED
@@ -29,269 +29,86 @@
29
29
  */
30
30
 
31
31
 
32
- // Minimal shims (small and explicit)
33
- if (typeof Element !== 'undefined' && !Element.prototype.matches) {
34
- Element.prototype.matches = Element.prototype.msMatchesSelector ||
35
- Element.prototype.webkitMatchesSelector ||
36
- function(s) {
37
- var matches = (this.document || this.ownerDocument).querySelectorAll(s);
38
- var i = matches.length;
39
- while (--i >= 0 && matches.item(i) !== this) {}
40
- return i > -1;
41
- };
42
- }
43
-
44
- if (typeof Event !== 'undefined' && !Event.prototype.composedPath) {
45
- Event.prototype.composedPath = function() {
46
- var path = [];
47
- var el = this.target;
48
- while (el) {
49
- path.push(el);
50
- el = el.parentElement;
32
+ export class SyntheticEvent {
33
+ constructor(nativeEvent, currentTarget) {
34
+ this.nativeEvent = nativeEvent;
35
+ this.type = nativeEvent.type;
36
+ this.target = nativeEvent.target || nativeEvent.srcElement || null;
37
+ this.currentTarget = currentTarget || nativeEvent.currentTarget || null;
38
+ this.timeStamp = nativeEvent.timeStamp ?? Date.now();
39
+ this.defaultPrevented = !!nativeEvent.defaultPrevented;
40
+
41
+ let propagationStopped = false;
42
+
43
+ this.isDefaultPrevented = () => this.defaultPrevented;
44
+ this.isPropagationStopped = () => propagationStopped;
45
+ this.preventDefault = () => {
46
+ nativeEvent.preventDefault?.();
47
+ this.defaultPrevented = true;
48
+ };
49
+ this.stopPropagation = () => {
50
+ nativeEvent.stopPropagation?.();
51
+ propagationStopped = true;
52
+ };
53
+
54
+ // Modern React doesn't pool events, so persist is a no-op.
55
+ this.persist = () => {};
56
+ this.isPersistent = () => true;
57
+
58
+ for (
59
+ let source = nativeEvent;
60
+ source && source !== Object.prototype;
61
+ source = Object.getPrototypeOf(source)
62
+ ) {
63
+ for (const key of Object.getOwnPropertyNames(source)) {
64
+ if (key === "constructor" || key in this) continue;
65
+
66
+ Object.defineProperty(this, key, {
67
+ configurable: true,
68
+ enumerable: true,
69
+ get() {
70
+ const value = nativeEvent[key];
71
+ return typeof value === "function"
72
+ ? value.bind(nativeEvent)
73
+ : value;
74
+ },
75
+ });
76
+ }
51
77
  }
52
- path.push(window);
53
- return path;
54
- };
78
+ }
55
79
  }
56
80
 
57
- // Event pool for reuse
58
- const _pool = [];
59
- const MAX_POOL_SIZE = 10;
60
- const POINTER_TYPES = ["mouse", "pen", "touch"];
61
-
62
- export function createSyntheticEvent(nativeEvent, currentTarget)
63
- {
64
- const e = _pool.length ? _pool.pop() : {};
65
-
66
- e.nativeEvent = nativeEvent;
67
- e.type = nativeEvent.type;
68
- e.target = nativeEvent.target || nativeEvent.srcElement || null;
69
- e.currentTarget = currentTarget || nativeEvent.currentTarget || null;
70
- e.timeStamp = nativeEvent.timeStamp || Date.now();
71
-
72
- // Standard flags
73
- e.defaultPrevented = !!nativeEvent.defaultPrevented;
74
- e.isPropagationStopped = false;
75
- e.isPersistent = false;
76
-
77
- // Common DOM meta when present
78
- e.bubbles = !!nativeEvent.bubbles;
79
- e.cancelable = !!nativeEvent.cancelable;
80
- e.composed = !!nativeEvent.composed;
81
- e.detail = nativeEvent.detail;
82
-
83
- e.relatedTarget =
84
- nativeEvent.relatedTarget ||
85
- (nativeEvent.fromElement ? nativeEvent.fromElement : null) ||
86
- (nativeEvent.toElement ? nativeEvent.toElement : null) ||
87
- null;
88
-
89
- // Modifier keys
90
- e.altKey = !!nativeEvent.altKey;
91
- e.ctrlKey = !!nativeEvent.ctrlKey;
92
- e.metaKey = !!nativeEvent.metaKey;
93
- e.shiftKey = !!nativeEvent.shiftKey;
94
-
95
- // preventDefault / stopPropagation
96
- e.isDefaultPrevented = () => e.defaultPrevented;
97
- e.preventDefault = () => {
98
- if (nativeEvent.preventDefault) nativeEvent.preventDefault();
99
- e.defaultPrevented = true;
100
- };
101
-
102
- e.stopPropagation = () => {
103
- if (nativeEvent.stopPropagation) nativeEvent.stopPropagation();
104
- e.isPropagationStopped = true;
105
- };
106
-
107
- e.persist = () => { e.isPersistent = true; };
108
-
109
- // Key/mouse/pointer related
110
- e.key = nativeEvent.key || null;
111
- e.code = nativeEvent.code || null;
112
- e.which = nativeEvent.which ?? nativeEvent.keyCode ?? null;
113
-
114
- // Mouse / Pointer button state normalization
115
- // - "button" often is 0/1/2 for mouse; for pointer events it's also present.
116
- // - "buttons" is a bitmask of which buttons are down (often important for drag).
117
- e.button = nativeEvent.button ?? null;
118
- e.buttons = nativeEvent.buttons ?? null;
119
-
120
- // Pointer identity + type (critical for multi-touch / pointer capture)
121
- e.pointerId = nativeEvent.pointerId ?? null;
122
- e.pointerType = nativeEvent.pointerType ?? null;
123
- e.isPrimary = nativeEvent.isPrimary ?? null;
124
-
125
- // Coordinates: React/SyntheticEvent uses these directly (React provides them too)
126
- e.clientX = nativeEvent.clientX ?? 0;
127
- e.clientY = nativeEvent.clientY ?? 0;
128
- e.screenX = nativeEvent.screenX ?? 0;
129
- e.screenY = nativeEvent.screenY ?? 0;
130
-
131
- // pageX/pageY might be derived; keep if present
132
- // (Using pageX/pageY only if you need it; most drag uses clientX/Y.)
133
- e.pageX = nativeEvent.pageX ?? null;
134
- e.pageY = nativeEvent.pageY ?? null;
135
-
136
- // movementX/movementY exist on some mouse events; harmless if absent
137
- e.movementX = nativeEvent.movementX ?? 0;
138
- e.movementY = nativeEvent.movementY ?? 0;
139
-
140
- // Pressure/tilt (Pointer Events)
141
- e.pressure = nativeEvent.pressure ?? null;
142
- e.tiltX = nativeEvent.tiltX ?? null;
143
- e.tiltY = nativeEvent.tiltY ?? null;
144
- e.width = nativeEvent.width ?? null;
145
- e.height = nativeEvent.height ?? null;
146
-
147
- // If the native event has a pointer capture API, you can forward bind/capture calls.
148
- // (These are methods on the EventTarget, not on the event, but keeping fields is enough.)
149
- e.pointerEventsSupported = POINTER_TYPES.includes(e.pointerType);
150
-
151
- // For input-like events normalize value and checked
152
- try {
153
- const tgt = e.target;
154
- e.value = tgt && ("value" in tgt) ? tgt.value : undefined;
155
- e.checked = tgt && ("checked" in tgt) ? tgt.checked : undefined;
156
-
157
- // Some input events have selectionStart/selectionEnd etc.
158
- e.selectionStart = tgt && ("selectionStart" in tgt) ? tgt.selectionStart : undefined;
159
- e.selectionEnd = tgt && ("selectionEnd" in tgt) ? tgt.selectionEnd : undefined;
160
- } catch (err) {
161
- e.value = undefined;
162
- e.checked = undefined;
163
- e.selectionStart = undefined;
164
- e.selectionEnd = undefined;
165
- }
166
-
167
- // Touch lists (useful for touch events; sometimes pointerType === "touch" uses pointer events instead)
168
- // Keep references only if they exist.
169
- e.touches = nativeEvent.touches || null;
170
- e.targetTouches = nativeEvent.targetTouches || null;
171
- e.changedTouches = nativeEvent.changedTouches || null;
172
-
173
- // composedPath helper
174
- e.path = typeof nativeEvent.composedPath === "function"
175
- ? nativeEvent.composedPath()
176
- : [e.target];
177
-
178
- // Additional keyboard extras when present
179
- e.repeat = nativeEvent.repeat ?? false;
180
- e.location = nativeEvent.location ?? 0;
181
-
182
- return e;
81
+ export function createSyntheticEvent(nativeEvent, currentTarget) {
82
+ return new SyntheticEvent(nativeEvent, currentTarget);
183
83
  }
184
84
 
185
- export function releaseSyntheticEvent(e)
186
- {
187
- if (e && !e.isPersistent) {
188
- e.nativeEvent = null;
189
- e.type = null;
190
- e.target = null;
191
- e.currentTarget = null;
192
- e.timeStamp = 0;
193
-
194
- e.defaultPrevented = false;
195
- e.isPropagationStopped = false;
196
-
197
- e.isPersistent = false;
198
-
199
- e.isDefaultPrevented = null;
200
- e.preventDefault = null;
201
- e.stopPropagation = null;
202
- e.persist = null;
203
-
204
- e.bubbles = false;
205
- e.cancelable = false;
206
- e.composed = false;
207
- e.detail = undefined;
208
- e.relatedTarget = null;
209
-
210
- // modifier keys
211
- e.altKey = false;
212
- e.ctrlKey = false;
213
- e.metaKey = false;
214
- e.shiftKey = false;
215
-
216
- // pointer/mouse fields
217
- e.key = null;
218
- e.code = null;
219
- e.which = null;
220
-
221
- e.button = null;
222
- e.buttons = null;
223
- e.pointerId = null;
224
- e.pointerType = null;
225
- e.isPrimary = null;
226
-
227
- e.clientX = 0;
228
- e.clientY = 0;
229
- e.screenX = 0;
230
- e.screenY = 0;
231
- e.pageX = null;
232
- e.pageY = null;
233
-
234
- e.movementX = 0;
235
- e.movementY = 0;
236
-
237
- e.pressure = null;
238
- e.tiltX = null;
239
- e.tiltY = null;
240
- e.width = null;
241
- e.height = null;
242
-
243
- // input-like
244
- e.value = undefined;
245
- e.checked = undefined;
246
- e.selectionStart = undefined;
247
- e.selectionEnd = undefined;
248
-
249
- // touch lists
250
- e.touches = null;
251
- e.targetTouches = null;
252
- e.changedTouches = null;
253
-
254
- e.path = null;
255
- e.repeat = false;
256
- e.location = 0;
257
-
258
- if (_pool.length < MAX_POOL_SIZE) _pool.push(e);
259
- }
85
+ export function releaseSyntheticEvent(event) {
86
+ if (event) event.currentTarget = null;
260
87
  }
261
88
 
262
-
263
- // Main wrapper factory
264
- // fn: function(syntheticEvent) { ... }
265
- // opts: { capture: bool, passive: bool, once: bool, stopPropagationOnTrueReturn: bool }
266
- export function wrapListener(fn, opts = {})
267
- {
89
+ export function wrapListener(fn, opts = {}) {
268
90
  const { stopPropagationOnTrueReturn = false } = opts;
269
91
 
270
92
  return function handler(nativeEvent) {
271
-
272
- const currentTarget = this || nativeEvent.currentTarget || null;
273
- const sEvent = createSyntheticEvent(nativeEvent, currentTarget);
93
+ const event = createSyntheticEvent(
94
+ nativeEvent,
95
+ this || nativeEvent.currentTarget || null
96
+ );
274
97
 
275
98
  try {
276
- const result = fn(sEvent);
277
-
278
- // If user returns true and opted in, stop propagation
99
+ const result = fn(event);
279
100
  if (stopPropagationOnTrueReturn && result === true) {
280
- sEvent.stopPropagation();
101
+ event.stopPropagation();
281
102
  }
282
103
  } finally {
283
- // Release back to pool unless persisted
284
- releaseSyntheticEvent(sEvent);
104
+ releaseSyntheticEvent(event);
285
105
  }
286
106
  };
287
107
  }
288
108
 
289
- // Convenience: add/remove wrapper-managed listener
290
- export function addWrappedEventListener(target, type, fn, options = {})
291
- {
109
+ export function addWrappedEventListener(target, type, fn, options = {}) {
292
110
  const handler = wrapListener(fn, options);
293
-
294
111
  target.addEventListener(type, handler, options);
295
- // Return a remover
112
+
296
113
  return () => target.removeEventListener(type, handler, options);
297
114
  }
package/src/jsx.js CHANGED
@@ -170,6 +170,8 @@ function parseComment(code, index, container)
170
170
  index++;
171
171
  }
172
172
 
173
+
174
+
173
175
  raiseError(`Unterminated comment`, b.begin);
174
176
  }
175
177
 
@@ -997,6 +999,8 @@ export function transpileJSX( jsx, {
997
999
  transpilerConfig.preprocessorDelimiter ??= 'ʔ'; // alt+shift+. on apple abc extended layout
998
1000
  transpilerConfig.injectTraceLabels ??= injectTraceLabels;
999
1001
 
1002
+ jsx+='\n';
1003
+
1000
1004
  const eols = scanEOLs(jsx);
1001
1005
 
1002
1006
  raiseError = ((eols, msg, index)=>{
package/src/run.jsx CHANGED
@@ -137,9 +137,8 @@ function loadModule(path, options = {}) {
137
137
  path = joinPaths(options.requirer.path, path);
138
138
  }
139
139
 
140
- const loadAsync =
141
- Boolean(Lilact[LAZY]) ||
142
- Boolean(options.isLazy);
140
+ const loadAsync = Boolean(Lilact[LAZY]) ||
141
+ Boolean(options.isLazy);
143
142
 
144
143
  const module = getOrCreateModule(path, {});
145
144