@hypen-space/web 0.2.12 → 0.3.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.
- package/dist/src/canvas/index.js.map +1 -1
- package/dist/src/canvas/renderer.js.map +1 -1
- package/dist/src/dom/applicators/effects.js +38 -2
- package/dist/src/dom/applicators/effects.js.map +3 -3
- package/dist/src/dom/applicators/events.js +280 -397
- package/dist/src/dom/applicators/events.js.map +5 -4
- package/dist/src/dom/applicators/font.js +94 -5
- package/dist/src/dom/applicators/font.js.map +3 -3
- package/dist/src/dom/applicators/index.js +590 -425
- package/dist/src/dom/applicators/index.js.map +10 -9
- package/dist/src/dom/applicators/layout.js +33 -5
- package/dist/src/dom/applicators/layout.js.map +3 -3
- package/dist/src/dom/applicators/size.js +81 -16
- package/dist/src/dom/applicators/size.js.map +3 -3
- package/dist/src/dom/components/hypenapp.js +296 -0
- package/dist/src/dom/components/hypenapp.js.map +10 -0
- package/dist/src/dom/components/index.js +263 -1
- package/dist/src/dom/components/index.js.map +5 -4
- package/dist/src/dom/element-data.js +140 -0
- package/dist/src/dom/element-data.js.map +10 -0
- package/dist/src/dom/index.js +857 -430
- package/dist/src/dom/index.js.map +13 -11
- package/dist/src/dom/renderer.js +857 -430
- package/dist/src/dom/renderer.js.map +13 -11
- package/dist/src/hypen.js +857 -430
- package/dist/src/hypen.js.map +13 -11
- package/dist/src/index.js +862 -430
- package/dist/src/index.js.map +15 -12
- package/package.json +3 -3
- package/src/canvas/QUICKSTART.md +5 -7
- package/src/canvas/README.md +2 -2
- package/src/canvas/renderer.ts +1 -1
- package/src/dom/README.md +4 -4
- package/src/dom/applicators/effects.ts +45 -1
- package/src/dom/applicators/events.ts +348 -537
- package/src/dom/applicators/font.ts +127 -2
- package/src/dom/applicators/index.ts +117 -7
- package/src/dom/applicators/layout.ts +40 -4
- package/src/dom/applicators/size.ts +101 -16
- package/src/dom/components/hypenapp.ts +348 -0
- package/src/dom/components/index.ts +2 -0
- package/src/dom/element-data.ts +234 -0
- package/src/dom/renderer.ts +12 -9
- package/src/index.ts +5 -2
|
@@ -27,11 +27,105 @@ var __export = (target, all) => {
|
|
|
27
27
|
};
|
|
28
28
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
29
29
|
|
|
30
|
+
// src/dom/element-data.ts
|
|
31
|
+
import { getElementDisposables } from "@hypen-space/core";
|
|
32
|
+
function getHypenData(element) {
|
|
33
|
+
let data = elementDataMap.get(element);
|
|
34
|
+
if (!data) {
|
|
35
|
+
data = {};
|
|
36
|
+
elementDataMap.set(element, data);
|
|
37
|
+
}
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
function hasHypenData(element) {
|
|
41
|
+
return elementDataMap.has(element);
|
|
42
|
+
}
|
|
43
|
+
function clearHypenData(element) {
|
|
44
|
+
elementDataMap.delete(element);
|
|
45
|
+
}
|
|
46
|
+
function getEngine(element) {
|
|
47
|
+
return getHypenData(element).engine;
|
|
48
|
+
}
|
|
49
|
+
function setEngine(element, engine) {
|
|
50
|
+
getHypenData(element).engine = engine;
|
|
51
|
+
}
|
|
52
|
+
function findEngine(element) {
|
|
53
|
+
let current = element;
|
|
54
|
+
while (current) {
|
|
55
|
+
const engine = getEngine(current);
|
|
56
|
+
if (engine)
|
|
57
|
+
return engine;
|
|
58
|
+
current = current.parentElement;
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
function getRegisteredEvents(element) {
|
|
63
|
+
const data = getHypenData(element);
|
|
64
|
+
if (!data.registeredEvents) {
|
|
65
|
+
data.registeredEvents = new Set;
|
|
66
|
+
}
|
|
67
|
+
return data.registeredEvents;
|
|
68
|
+
}
|
|
69
|
+
function isEventRegistered(element, eventKey) {
|
|
70
|
+
return getRegisteredEvents(element).has(eventKey);
|
|
71
|
+
}
|
|
72
|
+
function registerEvent(element, eventKey) {
|
|
73
|
+
getRegisteredEvents(element).add(eventKey);
|
|
74
|
+
}
|
|
75
|
+
function unregisterEvent(element, eventKey) {
|
|
76
|
+
getRegisteredEvents(element).delete(eventKey);
|
|
77
|
+
}
|
|
78
|
+
function getKeyTarget(element) {
|
|
79
|
+
return getHypenData(element).keyTarget;
|
|
80
|
+
}
|
|
81
|
+
function setKeyTarget(element, key) {
|
|
82
|
+
getHypenData(element).keyTarget = key;
|
|
83
|
+
}
|
|
84
|
+
function getMeta(element, key) {
|
|
85
|
+
return getHypenData(element).meta?.[key];
|
|
86
|
+
}
|
|
87
|
+
function setMeta(element, key, value) {
|
|
88
|
+
const data = getHypenData(element);
|
|
89
|
+
if (!data.meta) {
|
|
90
|
+
data.meta = {};
|
|
91
|
+
}
|
|
92
|
+
data.meta[key] = value;
|
|
93
|
+
}
|
|
94
|
+
function disposeHypenElement(element) {
|
|
95
|
+
try {
|
|
96
|
+
const disposables = getElementDisposables(element);
|
|
97
|
+
disposables.dispose();
|
|
98
|
+
} catch {}
|
|
99
|
+
clearHypenData(element);
|
|
100
|
+
}
|
|
101
|
+
function getLegacyEngine(element) {
|
|
102
|
+
const engine = getEngine(element);
|
|
103
|
+
if (engine)
|
|
104
|
+
return engine;
|
|
105
|
+
return element[HYPEN_ENGINE_SYMBOL] ?? element.__hypenEngine;
|
|
106
|
+
}
|
|
107
|
+
function setLegacyEngine(element, engine) {
|
|
108
|
+
setEngine(element, engine);
|
|
109
|
+
element.__hypenEngine = engine;
|
|
110
|
+
}
|
|
111
|
+
var elementDataMap, HYPEN_ENGINE_SYMBOL, REGISTERED_EVENTS_SYMBOL, KEY_TARGET_SYMBOL;
|
|
112
|
+
var init_element_data = __esm(() => {
|
|
113
|
+
elementDataMap = new WeakMap;
|
|
114
|
+
HYPEN_ENGINE_SYMBOL = Symbol.for("hypen.engine");
|
|
115
|
+
REGISTERED_EVENTS_SYMBOL = Symbol.for("hypen.registeredEvents");
|
|
116
|
+
KEY_TARGET_SYMBOL = Symbol.for("hypen.keyTarget");
|
|
117
|
+
});
|
|
118
|
+
|
|
30
119
|
// src/dom/applicators/events.ts
|
|
31
120
|
var exports_events = {};
|
|
32
121
|
__export(exports_events, {
|
|
33
122
|
eventHandlers: () => eventHandlers
|
|
34
123
|
});
|
|
124
|
+
import {
|
|
125
|
+
getElementDisposables as getElementDisposables2,
|
|
126
|
+
disposableListener,
|
|
127
|
+
disposableTimeout
|
|
128
|
+
} from "@hypen-space/core";
|
|
35
129
|
function toPlainObject(value) {
|
|
36
130
|
if (value instanceof Map) {
|
|
37
131
|
const obj = {};
|
|
@@ -77,7 +171,13 @@ function extractActionDetails(value) {
|
|
|
77
171
|
}
|
|
78
172
|
for (const [key, val] of Object.entries(plain)) {
|
|
79
173
|
if (key !== "0") {
|
|
80
|
-
|
|
174
|
+
if (/^\d+$/.test(key) && val && typeof val === "object" && !Array.isArray(val)) {
|
|
175
|
+
for (const [innerKey, innerVal] of Object.entries(val)) {
|
|
176
|
+
payload[innerKey] = innerVal;
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
payload[key] = val;
|
|
180
|
+
}
|
|
81
181
|
}
|
|
82
182
|
}
|
|
83
183
|
}
|
|
@@ -115,420 +215,203 @@ function extractEventData(event, element) {
|
|
|
115
215
|
}
|
|
116
216
|
return data;
|
|
117
217
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
console.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : extractEventData(event, element);
|
|
135
|
-
console.log(`[EventApplicator] onClick payload:`, payload);
|
|
136
|
-
const engine = element.__hypenEngine;
|
|
137
|
-
if (engine) {
|
|
138
|
-
engine.dispatchAction(actionName, payload);
|
|
139
|
-
} else {
|
|
140
|
-
console.warn(`[EventApplicator] No engine attached to element for onClick`);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
element.__hypenClickListener = listener;
|
|
144
|
-
element.addEventListener("click", listener);
|
|
145
|
-
console.log(`[EventApplicator] onClick handler attached for action: ${actionName}`);
|
|
146
|
-
},
|
|
147
|
-
onPress: (element, value) => {
|
|
148
|
-
eventHandlers.onClick(element, value);
|
|
149
|
-
},
|
|
150
|
-
onChange: (element, value) => {
|
|
151
|
-
const { actionName } = extractActionDetails(value);
|
|
152
|
-
if (!actionName) {
|
|
153
|
-
console.warn(`[EventApplicator] onChange value must be an action reference starting with @, got:`, value);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const existingListener = element.__hypenChangeListener;
|
|
157
|
-
if (existingListener) {
|
|
158
|
-
element.removeEventListener("change", existingListener);
|
|
159
|
-
}
|
|
160
|
-
const listener = (event) => {
|
|
161
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onChange fired, dispatching action: ${actionName}`);
|
|
162
|
-
const payload = extractEventData(event, element);
|
|
163
|
-
const engine = element.__hypenEngine;
|
|
164
|
-
if (engine) {
|
|
165
|
-
engine.dispatchAction(actionName, payload);
|
|
166
|
-
} else {
|
|
167
|
-
console.warn(`[EventApplicator] No engine attached to element for onChange`);
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
element.__hypenChangeListener = listener;
|
|
171
|
-
element.addEventListener("change", listener);
|
|
172
|
-
console.log(`[EventApplicator] onChange handler attached for action: ${actionName}`);
|
|
173
|
-
},
|
|
174
|
-
onSubmit: (element, value) => {
|
|
175
|
-
const { actionName } = extractActionDetails(value);
|
|
176
|
-
if (!actionName) {
|
|
177
|
-
console.warn(`[EventApplicator] onSubmit value must be an action reference starting with @, got:`, value);
|
|
218
|
+
function createEventHandler(eventType, options = {}) {
|
|
219
|
+
return (element, value) => {
|
|
220
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
221
|
+
if (!actionName) {
|
|
222
|
+
console.warn(`[EventApplicator] ${eventType} requires an action reference starting with @, got:`, value);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const disposables = getElementDisposables2(element);
|
|
226
|
+
const eventKey = `${eventType}:${actionName}`;
|
|
227
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
registerEvent(element, eventKey);
|
|
231
|
+
let throttleTimer = null;
|
|
232
|
+
const listener = (event) => {
|
|
233
|
+
if (options.throttleMs && throttleTimer) {
|
|
178
234
|
return;
|
|
179
235
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
236
|
+
if (options.throttleMs) {
|
|
237
|
+
throttleTimer = disposableTimeout(() => {
|
|
238
|
+
throttleTimer = null;
|
|
239
|
+
}, options.throttleMs);
|
|
183
240
|
}
|
|
184
|
-
|
|
185
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onSubmit fired, dispatching action: ${actionName}`);
|
|
241
|
+
if (options.preventDefault) {
|
|
186
242
|
event.preventDefault();
|
|
187
|
-
const payload = extractEventData(event, element);
|
|
188
|
-
const engine = element.__hypenEngine;
|
|
189
|
-
if (engine) {
|
|
190
|
-
engine.dispatchAction(actionName, payload);
|
|
191
|
-
} else {
|
|
192
|
-
console.warn(`[EventApplicator] No engine attached to element for onSubmit`);
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
element.__hypenSubmitListener = listener;
|
|
196
|
-
element.addEventListener("submit", listener);
|
|
197
|
-
console.log(`[EventApplicator] onSubmit handler attached for action: ${actionName}`);
|
|
198
|
-
},
|
|
199
|
-
onInput: (element, value) => {
|
|
200
|
-
console.log(`[EventApplicator] onInput called with value:`, value);
|
|
201
|
-
const { actionName } = extractActionDetails(value);
|
|
202
|
-
if (!actionName) {
|
|
203
|
-
console.warn(`[EventApplicator] onInput value must be an action reference starting with @, got:`, value);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const existingListener = element.__hypenInputListener;
|
|
207
|
-
if (existingListener) {
|
|
208
|
-
element.removeEventListener("input", existingListener);
|
|
209
|
-
}
|
|
210
|
-
const listener = (event) => {
|
|
211
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onInput fired, dispatching action: ${actionName}`);
|
|
212
|
-
const target = event.target;
|
|
213
|
-
const payload = {
|
|
214
|
-
type: event.type,
|
|
215
|
-
timestamp: Date.now(),
|
|
216
|
-
value: target.value,
|
|
217
|
-
input: target.value
|
|
218
|
-
};
|
|
219
|
-
console.log(`[EventApplicator] onInput payload:`, payload);
|
|
220
|
-
const engine = element.__hypenEngine;
|
|
221
|
-
if (engine) {
|
|
222
|
-
engine.dispatchAction(actionName, payload);
|
|
223
|
-
} else {
|
|
224
|
-
console.warn(`[EventApplicator] No engine attached to element for onInput`);
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
element.__hypenInputListener = listener;
|
|
228
|
-
element.addEventListener("input", listener);
|
|
229
|
-
console.log(`[EventApplicator] onInput handler attached for action: ${actionName}`);
|
|
230
|
-
},
|
|
231
|
-
onKey: (element, value) => {
|
|
232
|
-
console.log(`[EventApplicator] onKey called with value:`, value);
|
|
233
|
-
const { actionName } = extractActionDetails(value);
|
|
234
|
-
if (actionName) {
|
|
235
|
-
const existingListener = element.__hypenKeyListener;
|
|
236
|
-
if (existingListener) {
|
|
237
|
-
element.removeEventListener("keydown", existingListener);
|
|
238
|
-
}
|
|
239
|
-
const listener = (event) => {
|
|
240
|
-
if (event.key === "Enter") {
|
|
241
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onKey fired (Enter), dispatching action: ${actionName}`);
|
|
242
|
-
event.preventDefault();
|
|
243
|
-
const target = event.target;
|
|
244
|
-
const payload = {
|
|
245
|
-
type: event.type,
|
|
246
|
-
timestamp: Date.now(),
|
|
247
|
-
key: event.key,
|
|
248
|
-
code: event.code,
|
|
249
|
-
value: target.value,
|
|
250
|
-
input: target.value,
|
|
251
|
-
ctrlKey: event.ctrlKey,
|
|
252
|
-
shiftKey: event.shiftKey,
|
|
253
|
-
altKey: event.altKey,
|
|
254
|
-
metaKey: event.metaKey
|
|
255
|
-
};
|
|
256
|
-
const engine = element.__hypenEngine;
|
|
257
|
-
if (engine) {
|
|
258
|
-
engine.dispatchAction(actionName, payload);
|
|
259
|
-
} else {
|
|
260
|
-
console.warn(`[EventApplicator] No engine attached to element for onKey`);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
element.__hypenKeyListener = listener;
|
|
265
|
-
element.addEventListener("keydown", listener);
|
|
266
|
-
console.log(`[EventApplicator] onKey handler attached for action: ${actionName} (triggers on Enter)`);
|
|
267
|
-
} else {
|
|
268
|
-
console.warn(`[EventApplicator] onKey value must be an action reference starting with @, got: ${value}`);
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
"onKey.key": (element, keyValue) => {
|
|
272
|
-
console.log(`[EventApplicator] onKey.key called with value:`, keyValue);
|
|
273
|
-
element.__hypenKeyTarget = keyValue;
|
|
274
|
-
},
|
|
275
|
-
"onKey.action": (element, value) => {
|
|
276
|
-
console.log(`[EventApplicator] onKey.action called with value:`, value);
|
|
277
|
-
const { actionName } = extractActionDetails(value);
|
|
278
|
-
if (actionName) {
|
|
279
|
-
const targetKey = element.__hypenKeyTarget || "Enter";
|
|
280
|
-
const existingListener = element.__hypenKeyListener;
|
|
281
|
-
if (existingListener) {
|
|
282
|
-
element.removeEventListener("keydown", existingListener);
|
|
283
|
-
}
|
|
284
|
-
const listener = (event) => {
|
|
285
|
-
const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
|
|
286
|
-
if (event.key === keyToMatch) {
|
|
287
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onKey fired (${keyToMatch}), dispatching action: ${actionName}`);
|
|
288
|
-
event.preventDefault();
|
|
289
|
-
const target = event.target;
|
|
290
|
-
const payload = {
|
|
291
|
-
type: event.type,
|
|
292
|
-
timestamp: Date.now(),
|
|
293
|
-
key: event.key,
|
|
294
|
-
code: event.code,
|
|
295
|
-
value: target.value,
|
|
296
|
-
input: target.value,
|
|
297
|
-
ctrlKey: event.ctrlKey,
|
|
298
|
-
shiftKey: event.shiftKey,
|
|
299
|
-
altKey: event.altKey,
|
|
300
|
-
metaKey: event.metaKey
|
|
301
|
-
};
|
|
302
|
-
const engine = element.__hypenEngine;
|
|
303
|
-
if (engine) {
|
|
304
|
-
engine.dispatchAction(actionName, payload);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
element.__hypenKeyListener = listener;
|
|
309
|
-
element.addEventListener("keydown", listener);
|
|
310
|
-
console.log(`[EventApplicator] onKey handler attached for action: ${actionName} on key: ${targetKey}`);
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
onScroll: (element, value) => {
|
|
314
|
-
console.log(`[EventApplicator] onScroll called with value:`, value);
|
|
315
|
-
const { actionName } = extractActionDetails(value);
|
|
316
|
-
if (actionName) {
|
|
317
|
-
const existingListener = element.__hypenScrollListener;
|
|
318
|
-
if (existingListener) {
|
|
319
|
-
element.removeEventListener("scroll", existingListener);
|
|
320
|
-
}
|
|
321
|
-
let throttleTimer = null;
|
|
322
|
-
const listener = (event) => {
|
|
323
|
-
if (throttleTimer)
|
|
324
|
-
return;
|
|
325
|
-
throttleTimer = setTimeout(() => {
|
|
326
|
-
throttleTimer = null;
|
|
327
|
-
}, 100);
|
|
328
|
-
const target = event.target;
|
|
329
|
-
const scrollTop = target.scrollTop;
|
|
330
|
-
const scrollHeight = target.scrollHeight;
|
|
331
|
-
const clientHeight = target.clientHeight;
|
|
332
|
-
const scrollPercentage = scrollTop / (scrollHeight - clientHeight) * 100;
|
|
333
|
-
const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
|
|
334
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onScroll fired, scrollTop: ${scrollTop}, nearBottom: ${nearBottom}`);
|
|
335
|
-
const payload = {
|
|
336
|
-
type: "scroll",
|
|
337
|
-
timestamp: Date.now(),
|
|
338
|
-
scrollTop,
|
|
339
|
-
scrollLeft: target.scrollLeft,
|
|
340
|
-
scrollHeight,
|
|
341
|
-
scrollWidth: target.scrollWidth,
|
|
342
|
-
clientHeight,
|
|
343
|
-
clientWidth: target.clientWidth,
|
|
344
|
-
scrollPercentage: Math.round(scrollPercentage),
|
|
345
|
-
nearBottom,
|
|
346
|
-
atBottom: scrollHeight - scrollTop === clientHeight,
|
|
347
|
-
atTop: scrollTop === 0
|
|
348
|
-
};
|
|
349
|
-
const engine = element.__hypenEngine;
|
|
350
|
-
if (engine) {
|
|
351
|
-
engine.dispatchAction(actionName, payload);
|
|
352
|
-
} else {
|
|
353
|
-
console.warn(`[EventApplicator] No engine attached to element for onScroll`);
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
element.__hypenScrollListener = listener;
|
|
357
|
-
element.addEventListener("scroll", listener, { passive: true });
|
|
358
|
-
console.log(`[EventApplicator] onScroll handler attached for action: ${actionName}`);
|
|
359
|
-
} else {
|
|
360
|
-
console.warn(`[EventApplicator] onScroll value must be an action reference starting with @, got: ${value}`);
|
|
361
243
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (!actionName) {
|
|
367
|
-
console.warn(`[EventApplicator] onLongClick value must be an action reference, got:`, value);
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
const existingDownListener = element.__hypenLongClickDownListener;
|
|
371
|
-
const existingUpListener = element.__hypenLongClickUpListener;
|
|
372
|
-
if (existingDownListener) {
|
|
373
|
-
element.removeEventListener("pointerdown", existingDownListener);
|
|
244
|
+
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : options.extractPayload ? options.extractPayload(event, element) : extractEventData(event, element);
|
|
245
|
+
const engine = getEngine(element);
|
|
246
|
+
if (engine) {
|
|
247
|
+
engine.dispatchAction(actionName, payload);
|
|
374
248
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
249
|
+
};
|
|
250
|
+
disposables.add(disposableListener(element, eventType, listener, {
|
|
251
|
+
passive: options.passive
|
|
252
|
+
}));
|
|
253
|
+
disposables.addCallback(() => {
|
|
254
|
+
unregisterEvent(element, eventKey);
|
|
255
|
+
if (throttleTimer) {
|
|
256
|
+
throttleTimer.dispose();
|
|
378
257
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
if (longClickTimer) {
|
|
401
|
-
clearTimeout(longClickTimer);
|
|
402
|
-
longClickTimer = null;
|
|
403
|
-
}
|
|
404
|
-
};
|
|
405
|
-
element.__hypenLongClickDownListener = downListener;
|
|
406
|
-
element.__hypenLongClickUpListener = upListener;
|
|
407
|
-
element.addEventListener("pointerdown", downListener);
|
|
408
|
-
element.addEventListener("pointerup", upListener);
|
|
409
|
-
element.addEventListener("pointerleave", upListener);
|
|
410
|
-
console.log(`[EventApplicator] onLongClick handler attached for action: ${actionName}`);
|
|
411
|
-
},
|
|
412
|
-
onFocus: (element, value) => {
|
|
413
|
-
console.log(`[EventApplicator] onFocus called with value:`, value);
|
|
414
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
415
|
-
if (!actionName) {
|
|
416
|
-
console.warn(`[EventApplicator] onFocus value must be an action reference, got:`, value);
|
|
258
|
+
});
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function createKeyHandler(defaultKey = "Enter") {
|
|
262
|
+
return (element, value) => {
|
|
263
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
264
|
+
if (!actionName) {
|
|
265
|
+
console.warn(`[EventApplicator] onKey requires an action reference starting with @, got:`, value);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const disposables = getElementDisposables2(element);
|
|
269
|
+
const eventKey = `keydown:${actionName}:${defaultKey}`;
|
|
270
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
registerEvent(element, eventKey);
|
|
274
|
+
const targetKey = getKeyTarget(element) || defaultKey;
|
|
275
|
+
const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
|
|
276
|
+
const listener = (event) => {
|
|
277
|
+
const keyEvent = event;
|
|
278
|
+
if (keyEvent.key !== keyToMatch) {
|
|
417
279
|
return;
|
|
418
280
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (engine) {
|
|
433
|
-
engine.dispatchAction(actionName, payload);
|
|
434
|
-
} else {
|
|
435
|
-
console.warn(`[EventApplicator] No engine attached to element for onFocus`);
|
|
436
|
-
}
|
|
281
|
+
event.preventDefault();
|
|
282
|
+
const target = event.target;
|
|
283
|
+
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
284
|
+
type: event.type,
|
|
285
|
+
timestamp: Date.now(),
|
|
286
|
+
key: keyEvent.key,
|
|
287
|
+
code: keyEvent.code,
|
|
288
|
+
value: target.value,
|
|
289
|
+
input: target.value,
|
|
290
|
+
ctrlKey: keyEvent.ctrlKey,
|
|
291
|
+
shiftKey: keyEvent.shiftKey,
|
|
292
|
+
altKey: keyEvent.altKey,
|
|
293
|
+
metaKey: keyEvent.metaKey
|
|
437
294
|
};
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
},
|
|
442
|
-
onBlur: (element, value) => {
|
|
443
|
-
console.log(`[EventApplicator] onBlur called with value:`, value);
|
|
444
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
445
|
-
if (!actionName) {
|
|
446
|
-
console.warn(`[EventApplicator] onBlur value must be an action reference, got:`, value);
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
const existingListener = element.__hypenBlurListener;
|
|
450
|
-
if (existingListener) {
|
|
451
|
-
element.removeEventListener("blur", existingListener);
|
|
295
|
+
const engine = getEngine(element);
|
|
296
|
+
if (engine) {
|
|
297
|
+
engine.dispatchAction(actionName, payload);
|
|
452
298
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
299
|
+
};
|
|
300
|
+
disposables.add(disposableListener(element, "keydown", listener));
|
|
301
|
+
disposables.addCallback(() => {
|
|
302
|
+
unregisterEvent(element, eventKey);
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function createLongClickHandler(thresholdMs = 500) {
|
|
307
|
+
return (element, value) => {
|
|
308
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
309
|
+
if (!actionName) {
|
|
310
|
+
console.warn(`[EventApplicator] onLongClick requires an action reference starting with @, got:`, value);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const disposables = getElementDisposables2(element);
|
|
314
|
+
const eventKey = `longclick:${actionName}`;
|
|
315
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
registerEvent(element, eventKey);
|
|
319
|
+
let longClickTimer = null;
|
|
320
|
+
const downListener = (event) => {
|
|
321
|
+
const pointerEvent = event;
|
|
322
|
+
longClickTimer = disposableTimeout(() => {
|
|
456
323
|
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
457
|
-
type: "
|
|
324
|
+
type: "longclick",
|
|
458
325
|
timestamp: Date.now(),
|
|
459
|
-
|
|
326
|
+
clientX: pointerEvent.clientX,
|
|
327
|
+
clientY: pointerEvent.clientY
|
|
460
328
|
};
|
|
461
|
-
const engine = element
|
|
329
|
+
const engine = getEngine(element);
|
|
462
330
|
if (engine) {
|
|
463
331
|
engine.dispatchAction(actionName, payload);
|
|
464
|
-
} else {
|
|
465
|
-
console.warn(`[EventApplicator] No engine attached to element for onBlur`);
|
|
466
332
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
475
|
-
if (!actionName) {
|
|
476
|
-
console.warn(`[EventApplicator] onMouseEnter value must be an action reference, got:`, value);
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
const existingListener = element.__hypenMouseEnterListener;
|
|
480
|
-
if (existingListener) {
|
|
481
|
-
element.removeEventListener("mouseenter", existingListener);
|
|
333
|
+
longClickTimer = null;
|
|
334
|
+
}, thresholdMs);
|
|
335
|
+
};
|
|
336
|
+
const cancelListener = () => {
|
|
337
|
+
if (longClickTimer) {
|
|
338
|
+
longClickTimer.dispose();
|
|
339
|
+
longClickTimer = null;
|
|
482
340
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
341
|
+
};
|
|
342
|
+
disposables.add(disposableListener(element, "pointerdown", downListener));
|
|
343
|
+
disposables.add(disposableListener(element, "pointerup", cancelListener));
|
|
344
|
+
disposables.add(disposableListener(element, "pointerleave", cancelListener));
|
|
345
|
+
disposables.addCallback(() => {
|
|
346
|
+
unregisterEvent(element, eventKey);
|
|
347
|
+
cancelListener();
|
|
348
|
+
});
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
var inputPayload = (event, element) => {
|
|
352
|
+
const target = element;
|
|
353
|
+
return {
|
|
354
|
+
type: event.type,
|
|
355
|
+
timestamp: Date.now(),
|
|
356
|
+
value: target.value,
|
|
357
|
+
input: target.value
|
|
358
|
+
};
|
|
359
|
+
}, scrollPayload = (_event, element) => {
|
|
360
|
+
const scrollTop = element.scrollTop;
|
|
361
|
+
const scrollHeight = element.scrollHeight;
|
|
362
|
+
const clientHeight = element.clientHeight;
|
|
363
|
+
const scrollPercentage = scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) * 100 : 0;
|
|
364
|
+
const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
|
|
365
|
+
return {
|
|
366
|
+
type: "scroll",
|
|
367
|
+
timestamp: Date.now(),
|
|
368
|
+
scrollTop,
|
|
369
|
+
scrollLeft: element.scrollLeft,
|
|
370
|
+
scrollHeight,
|
|
371
|
+
scrollWidth: element.scrollWidth,
|
|
372
|
+
clientHeight,
|
|
373
|
+
clientWidth: element.clientWidth,
|
|
374
|
+
scrollPercentage: Math.round(scrollPercentage),
|
|
375
|
+
nearBottom,
|
|
376
|
+
atBottom: scrollHeight - scrollTop === clientHeight,
|
|
377
|
+
atTop: scrollTop === 0
|
|
378
|
+
};
|
|
379
|
+
}, focusPayload = (event, element) => ({
|
|
380
|
+
type: event.type,
|
|
381
|
+
timestamp: Date.now(),
|
|
382
|
+
value: element.value ?? undefined
|
|
383
|
+
}), mousePayload = (event, _element) => {
|
|
384
|
+
const mouseEvent = event;
|
|
385
|
+
return {
|
|
386
|
+
type: event.type,
|
|
387
|
+
timestamp: Date.now(),
|
|
388
|
+
clientX: mouseEvent.clientX,
|
|
389
|
+
clientY: mouseEvent.clientY
|
|
390
|
+
};
|
|
391
|
+
}, eventHandlers;
|
|
392
|
+
var init_events = __esm(() => {
|
|
393
|
+
init_element_data();
|
|
394
|
+
eventHandlers = {
|
|
395
|
+
onClick: createEventHandler("click"),
|
|
396
|
+
onPress: createEventHandler("click"),
|
|
397
|
+
onChange: createEventHandler("change"),
|
|
398
|
+
onSubmit: createEventHandler("submit", { preventDefault: true }),
|
|
399
|
+
onInput: createEventHandler("input", { extractPayload: inputPayload }),
|
|
400
|
+
onKey: createKeyHandler("Enter"),
|
|
401
|
+
"onKey.key": (element, value) => {
|
|
402
|
+
setKeyTarget(element, String(value));
|
|
501
403
|
},
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
const listener = (event) => {
|
|
514
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onMouseLeave fired, dispatching action: ${actionName}`);
|
|
515
|
-
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
516
|
-
type: "mouseleave",
|
|
517
|
-
timestamp: Date.now(),
|
|
518
|
-
clientX: event.clientX,
|
|
519
|
-
clientY: event.clientY
|
|
520
|
-
};
|
|
521
|
-
const engine = element.__hypenEngine;
|
|
522
|
-
if (engine) {
|
|
523
|
-
engine.dispatchAction(actionName, payload);
|
|
524
|
-
} else {
|
|
525
|
-
console.warn(`[EventApplicator] No engine attached to element for onMouseLeave`);
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
element.__hypenMouseLeaveListener = listener;
|
|
529
|
-
element.addEventListener("mouseleave", listener);
|
|
530
|
-
console.log(`[EventApplicator] onMouseLeave handler attached for action: ${actionName}`);
|
|
531
|
-
}
|
|
404
|
+
"onKey.action": createKeyHandler("Enter"),
|
|
405
|
+
onScroll: createEventHandler("scroll", {
|
|
406
|
+
throttleMs: 100,
|
|
407
|
+
passive: true,
|
|
408
|
+
extractPayload: scrollPayload
|
|
409
|
+
}),
|
|
410
|
+
onLongClick: createLongClickHandler(500),
|
|
411
|
+
onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
|
|
412
|
+
onBlur: createEventHandler("blur", { extractPayload: focusPayload }),
|
|
413
|
+
onMouseEnter: createEventHandler("mouseenter", { extractPayload: mousePayload }),
|
|
414
|
+
onMouseLeave: createEventHandler("mouseleave", { extractPayload: mousePayload })
|
|
532
415
|
};
|
|
533
416
|
});
|
|
534
417
|
init_events();
|
|
@@ -537,4 +420,4 @@ export {
|
|
|
537
420
|
eventHandlers
|
|
538
421
|
};
|
|
539
422
|
|
|
540
|
-
//# debugId=
|
|
423
|
+
//# debugId=436C6B268F7401DA64756E2164756E21
|