ziko 0.49.6 → 0.50.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 (104) hide show
  1. package/dist/ziko.cjs +374 -363
  2. package/dist/ziko.js +686 -971
  3. package/dist/ziko.min.js +2 -2
  4. package/dist/ziko.mjs +678 -953
  5. package/package.json +4 -1
  6. package/src/{reactivity → --reactivity-deprecated}/hooks/head/useFavIcon.js +4 -4
  7. package/src/{reactivity → --reactivity-deprecated}/hooks/head/useTitle.js +1 -1
  8. package/src/{reactivity → --reactivity-deprecated}/hooks/index.js +3 -3
  9. package/src/{reactivity → --reactivity-deprecated}/index.js +1 -1
  10. package/src/{use → --use-deprecated}/index.js +1 -1
  11. package/src/{use/use-event-emmiter.js → --use-deprecated/use-event-emmiter.js.txt} +3 -3
  12. package/src/__ziko__/__state__.js +1 -1
  13. package/src/app/ziko-app.js +6 -6
  14. package/src/events/binders/custom-event.js +11 -7
  15. package/src/events/binders/index.js +69 -13
  16. package/src/events/details-setter/index.js +2 -0
  17. package/src/events/details-setter/key.js +14 -0
  18. package/src/events/{binders → details-setter}/pointer.js +1 -15
  19. package/src/events/{__Events__.js → events-map/index.js} +7 -3
  20. package/src/events/index.js +1 -1
  21. package/src/events/types/__Shared__.d.ts +3 -3
  22. package/src/events/types/clipboard.d.ts +2 -2
  23. package/src/events/types/focus.d.ts +2 -2
  24. package/src/events/types/pointer.d.ts +2 -2
  25. package/src/events/{__ZikoEvent__.js → ziko-event.js} +17 -16
  26. package/src/hooks/index.js +10 -2
  27. package/src/hooks/use-event-emitter.js +68 -0
  28. package/src/hooks/use-favicon.js +59 -0
  29. package/src/hooks/{use-channel.js → use-ipc.js} +5 -22
  30. package/src/hooks/use-media-query.js +59 -0
  31. package/src/hooks/use-root.js +73 -0
  32. package/src/hooks/use-storage.js +73 -47
  33. package/src/hooks/use-thread.js +55 -0
  34. package/src/hooks/use-title.js +43 -0
  35. package/src/index.js +1 -1
  36. package/src/ui/__methods__/events.js +19 -5
  37. package/src/ui/constructors/UIElement.js +14 -12
  38. package/src/ui/constructors/UIElementCore.js +3 -136
  39. package/types/hooks/index.d.ts +9 -2
  40. package/types/hooks/use-Thread.d.ts +33 -0
  41. package/types/hooks/use-event-emitter.d.ts +46 -0
  42. package/types/hooks/use-favicon.d.ts +41 -0
  43. package/types/hooks/{use-channel.d.ts → use-ipc.d.ts} +2 -2
  44. package/types/hooks/use-media-query.d.ts +24 -0
  45. package/types/hooks/use-root.d.ts +15 -0
  46. package/types/hooks/use-storage.d.ts +47 -0
  47. package/types/hooks/use-title.d.ts +37 -0
  48. package/src/events/binders/click.js +0 -20
  49. package/src/events/binders/clipboard.js +0 -16
  50. package/src/events/binders/drag.js +0 -16
  51. package/src/events/binders/focus.js +0 -16
  52. package/src/events/binders/hash.js +0 -16
  53. package/src/events/binders/key.js +0 -27
  54. package/src/events/binders/mouse.js +0 -16
  55. package/src/events/binders/touch.js +0 -16
  56. package/src/events/binders/wheel.js +0 -16
  57. package/src/events/index.d.ts.txt +0 -3
  58. /package/src/{reactivity → --reactivity-deprecated}/events/Input.js +0 -0
  59. /package/src/{reactivity → --reactivity-deprecated}/events/ZikoEvent.js +0 -0
  60. /package/src/{reactivity → --reactivity-deprecated}/events/__note__ +0 -0
  61. /package/src/{reactivity → --reactivity-deprecated}/events/custom-event.js +0 -0
  62. /package/src/{reactivity → --reactivity-deprecated}/events/hash.js +0 -0
  63. /package/src/{reactivity → --reactivity-deprecated}/events/index.js +0 -0
  64. /package/src/{reactivity → --reactivity-deprecated}/events/media.js +0 -0
  65. /package/src/{reactivity → --reactivity-deprecated}/events/mouse.js +0 -0
  66. /package/src/{reactivity → --reactivity-deprecated}/events/swipe.js +0 -0
  67. /package/src/{reactivity → --reactivity-deprecated}/events/touch.js +0 -0
  68. /package/src/{reactivity → --reactivity-deprecated}/hooks/Contexte/index.js +0 -0
  69. /package/src/{reactivity → --reactivity-deprecated}/hooks/Contexte/useSuccesifKeys.js +0 -0
  70. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/index.js +0 -0
  71. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useCssLink.js +0 -0
  72. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useLinearGradient.js +0 -0
  73. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useMediaQuery.js +0 -0
  74. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useRadialGradient.js +0 -0
  75. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useRoot.js +0 -0
  76. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useStyle.js +0 -0
  77. /package/src/{reactivity → --reactivity-deprecated}/hooks/UI/useTheme.js +0 -0
  78. /package/src/{reactivity → --reactivity-deprecated}/hooks/head/_useCssText.js +0 -0
  79. /package/src/{reactivity → --reactivity-deprecated}/hooks/head/index.js +0 -0
  80. /package/src/{reactivity → --reactivity-deprecated}/hooks/head/useHead.js +0 -0
  81. /package/src/{reactivity → --reactivity-deprecated}/hooks/head/useMeta.js +0 -0
  82. /package/src/{reactivity → --reactivity-deprecated}/hooks/todo.md +0 -0
  83. /package/src/{reactivity → --reactivity-deprecated}/idea +0 -0
  84. /package/src/{reactivity → --reactivity-deprecated}/observer/attributes.js +0 -0
  85. /package/src/{reactivity → --reactivity-deprecated}/observer/children.js +0 -0
  86. /package/src/{reactivity → --reactivity-deprecated}/observer/index.js +0 -0
  87. /package/src/{reactivity → --reactivity-deprecated}/observer/intersection.js +0 -0
  88. /package/src/{reactivity → --reactivity-deprecated}/observer/mutation.js +0 -0
  89. /package/src/{reactivity → --reactivity-deprecated}/observer/resize.js +0 -0
  90. /package/src/{reactivity → --reactivity-deprecated}/observer/screen.js +0 -0
  91. /package/src/{reactivity → --reactivity-deprecated}/observer/screen.js.txt +0 -0
  92. /package/src/{reactivity → --reactivity-deprecated}/observer/screen.txt +0 -0
  93. /package/src/{use → --use-deprecated}/use-channel.js.txt +0 -0
  94. /package/src/{use → --use-deprecated}/use-favicon.js +0 -0
  95. /package/src/{use → --use-deprecated}/use-link.js +0 -0
  96. /package/src/{use → --use-deprecated}/use-meta.js +0 -0
  97. /package/src/{use → --use-deprecated}/use-root.js +0 -0
  98. /package/src/{use → --use-deprecated}/use-storage.js.txt +0 -0
  99. /package/src/{use → --use-deprecated}/use-thread.js +0 -0
  100. /package/src/{use → --use-deprecated}/use-title.js +0 -0
  101. /package/src/events/{custom-events → custom-events-registry}/click-away.js +0 -0
  102. /package/src/events/{custom-events → custom-events-registry}/index.js +0 -0
  103. /package/src/events/{custom-events → custom-events-registry}/swipe.js +0 -0
  104. /package/src/events/{custom-events → custom-events-registry}/view.js +0 -0
package/dist/ziko.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  Project: ziko.js
4
4
  Author: Zakaria Elalaoui
5
- Date : Wed Nov 26 2025 12:01:55 GMT+0100 (UTC+01:00)
5
+ Date : Tue Dec 02 2025 12:55:22 GMT+0100 (UTC+01:00)
6
6
  Git-Repo : https://github.com/zakarialaoui10/ziko.js
7
7
  Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki
8
8
  Released under MIT License
@@ -1179,37 +1179,29 @@ const __CACHE__ = {
1179
1179
  }
1180
1180
  };
1181
1181
 
1182
- class UseChannel {
1183
- // private fields
1182
+ class UseIPC {
1184
1183
  #channel;
1185
1184
  #eventData;
1186
1185
  #handlers;
1187
1186
  #uuid;
1188
1187
  #subscribers;
1189
- #currentRooms; // now a Set for multiple rooms
1190
-
1188
+ #currentRooms;
1191
1189
  constructor(name = "") {
1192
1190
  this.#channel = new BroadcastChannel(name);
1193
1191
  this.#eventData = new Map();
1194
1192
  this.#handlers = new Map(); // Map<event, Array<{fn, rooms}>>
1195
1193
  this.#uuid = "ziko-channel:" + Random.string(10);
1196
1194
  this.#subscribers = new Set([this.#uuid]);
1197
- this.#currentRooms = new Set(); // multiple rooms
1198
-
1195
+ this.#currentRooms = new Set();
1199
1196
  this.#channel.addEventListener("message", (e) => {
1200
1197
  const { last_sent_event, userId, eventData, rooms } = e.data;
1201
-
1202
1198
  if (userId === this.#uuid) return; // ignore own messages
1203
-
1204
1199
  // broadcast if no rooms, else check intersection
1205
1200
  if (rooms && rooms.length && !rooms.some(r => this.#currentRooms.has(r))) return;
1206
-
1207
1201
  this.#subscribers.add(userId);
1208
1202
  this.#eventData = new Map(eventData);
1209
-
1210
1203
  const handlersList = this.#handlers.get(last_sent_event);
1211
1204
  if (!handlersList) return;
1212
-
1213
1205
  handlersList.forEach(({ fn, rooms: handlerRooms }) => {
1214
1206
  // trigger if listener has no room filter, or intersects subscriber rooms
1215
1207
  if (!handlerRooms || handlerRooms.length === 0 ||
@@ -1223,24 +1215,20 @@ class UseChannel {
1223
1215
  emit(event, data, rooms) {
1224
1216
  this.#eventData.set(event, data);
1225
1217
  if(typeof rooms === 'string') rooms = [rooms];
1226
-
1227
1218
  this.#channel.postMessage({
1228
1219
  eventData: Array.from(this.#eventData.entries()),
1229
1220
  last_sent_event: event,
1230
1221
  userId: this.#uuid,
1231
1222
  rooms: rooms && rooms.length ? rooms : undefined
1232
1223
  });
1233
-
1234
1224
  return this;
1235
1225
  }
1236
-
1237
1226
  on(event, handler = console.log, rooms) {
1238
1227
  if (!this.#handlers.has(event)) this.#handlers.set(event, []);
1239
1228
  if(typeof rooms === 'string') rooms = [rooms];
1240
1229
  this.#handlers.get(event).push({ fn: handler, rooms });
1241
1230
  return this;
1242
1231
  }
1243
-
1244
1232
  off(event, handler) {
1245
1233
  if (!this.#handlers.has(event)) return this;
1246
1234
  this.#handlers.set(
@@ -1249,7 +1237,6 @@ class UseChannel {
1249
1237
  );
1250
1238
  return this;
1251
1239
  }
1252
-
1253
1240
  once(event, handler, rooms) {
1254
1241
  const wrapper = (data) => {
1255
1242
  handler(data);
@@ -1258,95 +1245,115 @@ class UseChannel {
1258
1245
  this.on(event, wrapper, rooms);
1259
1246
  return this;
1260
1247
  }
1261
-
1262
1248
  join(...rooms) {
1263
1249
  rooms.forEach(r => this.#currentRooms.add(r));
1264
1250
  return this;
1265
1251
  }
1266
-
1267
1252
  leave(...rooms) {
1268
1253
  if (!rooms.length) this.#currentRooms.clear();
1269
1254
  else rooms.forEach(r => this.#currentRooms.delete(r));
1270
1255
  return this;
1271
1256
  }
1272
-
1273
1257
  close() {
1274
1258
  this.#channel.close();
1275
1259
  return this;
1276
1260
  }
1277
-
1278
1261
  }
1279
1262
 
1280
- const useChannel = (name) => new UseChannel(name);
1263
+ const useIPC = (name) => new UseIPC(name);
1281
1264
 
1282
- // To do : remove old items
1283
- class UseStorage{
1284
- constructor(storage, globalKey, initialValue){
1285
- this.cache={
1265
+ class UseStorage {
1266
+ constructor(storage, globalKey, initialValue, use_channel = true) {
1267
+ this.cache = {
1286
1268
  storage,
1287
1269
  globalKey,
1288
- channel:useChannel(`Ziko:useStorage-${globalKey}`),
1289
- oldItemKeys:new Set()
1270
+ channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null,
1271
+ oldItemKeys: new Set()
1290
1272
  };
1291
- this.#init(initialValue);
1292
- this.#maintain();
1273
+
1274
+ this.#init(initialValue, use_channel);
1293
1275
  }
1294
- get items(){
1295
- return JSON.parse(this.cache.storage[this.cache.globalKey]??null);
1276
+
1277
+ get items() {
1278
+ const raw = this.cache.storage.getItem(this.cache.globalKey);
1279
+ if (!raw) return {};
1280
+ try {
1281
+ return JSON.parse(raw);
1282
+ } catch {
1283
+ return {};
1284
+ }
1296
1285
  }
1286
+
1297
1287
  #maintain() {
1298
- for(let i in this.items)Object.assign(this, { [[i]]: this.items[i] });
1299
- }
1300
- #init(initialValue){
1301
- this.cache.channel=useChannel(`Ziko:useStorage-${this.cache.globalKey}`);
1302
- this.cache.channel.on("Ziko-Storage-Updated",()=>this.#maintain());
1303
- if(!initialValue)return;
1304
- if(this.cache.storage[this.cache.globalKey]){
1305
- Object.keys(this.items).forEach(key=>this.cache.oldItemKeys.add(key));
1306
- // console.group("Ziko:useStorage")
1307
- // console.warn(`Storage key '${this.cache.globalKey}' already exists. we will not overwrite it.`);
1308
- // console.info(`%cWe'll keep the existing data.`,"background-color:#2222dd; color:gold;");
1309
- // console.group("")
1288
+ const items = this.items;
1289
+ this.cache.oldItemKeys.forEach(k => delete this[k]);
1290
+ for (const key in items) {
1291
+ this[key] = items[key];
1292
+ this.cache.oldItemKeys.add(key);
1293
+ }
1294
+ }
1295
+ #init(initialValue, use_channel) {
1296
+ if (use_channel && this.cache.channel) this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
1297
+ if (!initialValue) {
1298
+ this.#maintain();
1299
+ return;
1310
1300
  }
1301
+ if (this.cache.storage.getItem(this.cache.globalKey)) {
1302
+ const existing = this.items;
1303
+ Object.keys(existing).forEach(k => this.cache.oldItemKeys.add(k));
1304
+ this.#maintain();
1305
+ }
1311
1306
  else this.set(initialValue);
1312
1307
  }
1313
- set(data){
1314
- this.cache.storage.setItem(this.cache.globalKey,JSON.stringify(data));
1315
- this.cache.channel.emit("Ziko-Storage-Updated",{});
1316
- Object.keys(data).forEach(key=>this.cache.oldItemKeys.add(key));
1308
+
1309
+ set(data) {
1310
+ this.cache.storage.setItem(this.cache.globalKey, JSON.stringify(data));
1311
+ if (this.cache.channel) this.cache.channel.emit("Ziko-Storage-Updated", data);
1317
1312
  this.#maintain();
1318
- return this
1313
+ return this;
1319
1314
  }
1320
- add(data){
1321
- const db={
1315
+
1316
+ add(data) {
1317
+ this.set({
1322
1318
  ...this.items,
1323
1319
  ...data
1324
- };
1325
- this.cache.storage.setItem(this.cache.globalKey,JSON.stringify(db));
1326
- this.#maintain();
1320
+ });
1327
1321
  return this;
1328
1322
  }
1329
- remove(...keys){
1330
- const db={...this.items};
1331
- for(let i=0;i<keys.length;i++){
1332
- delete db[keys[i]];
1333
- delete this[keys[i]];
1334
- }
1335
- this.set(db);
1323
+ remove(...keys) {
1324
+ const items = { ...this.items };
1325
+ keys.forEach(key => {
1326
+ delete items[key];
1327
+ delete this[key];
1328
+ this.cache.oldItemKeys.delete(key);
1329
+ });
1330
+ this.set(items);
1336
1331
  return this;
1337
1332
  }
1338
- get(key){
1333
+ get(key) {
1339
1334
  return this.items[key];
1340
1335
  }
1341
- clear(){
1336
+ clear() {
1342
1337
  this.cache.storage.removeItem(this.cache.globalKey);
1338
+ this.cache.oldItemKeys.forEach(k => delete this[k]);
1339
+ this.cache.oldItemKeys.clear();
1343
1340
  this.#maintain();
1344
1341
  return this;
1345
1342
  }
1346
-
1343
+ onStorageUpdated(callback) {
1344
+ if (this.cache.channel) {
1345
+ this.cache.channel.on("Ziko-Storage-Updated", callback);
1346
+ }
1347
+ return this;
1348
+ }
1347
1349
  }
1348
- const useLocaleStorage=(key,initialValue)=>new UseStorage(localStorage,key,initialValue);
1349
- const useSessionStorage=(key,initialValue)=>new UseStorage(sessionStorage,key,initialValue);
1350
+
1351
+ // factory functions
1352
+ const useLocaleStorage = (key, initialValue, use_channel = true) =>
1353
+ new UseStorage(localStorage, key, initialValue, use_channel);
1354
+
1355
+ const useSessionStorage = (key, initialValue, use_channel = true) =>
1356
+ new UseStorage(sessionStorage, key, initialValue, use_channel);
1350
1357
 
1351
1358
  const __State__ = {
1352
1359
  store : new Map(),
@@ -1882,7 +1889,7 @@ var DomMethods = /*#__PURE__*/Object.freeze({
1882
1889
  unrenderAfter: unrenderAfter
1883
1890
  });
1884
1891
 
1885
- const Events = {
1892
+ const EventsMap = {
1886
1893
  'Click' : [
1887
1894
  'Click',
1888
1895
  'DblClick',
@@ -1942,21 +1949,7 @@ const getEvent=(event = "")=>{
1942
1949
  return event.toLowerCase()
1943
1950
  };
1944
1951
 
1945
- function event_controller(e, event_name, details_setter, customizer, push_object){
1946
- this.cache.currentEvent = event_name;
1947
- this.cache.event = e;
1948
- details_setter?.call(this);
1949
- customizer?.hasOwnProperty("prototype") ? customizer?.call(this) : customizer?.call(null, this);
1950
- // if(customizer?.hasOwnProperty("prototype")) customizer?.call(this)
1951
- // else customizer?.call(null, this)
1952
- if(this.cache.preventDefault[event_name]) e.preventDefault();
1953
- if(this.cache.stopPropagation[event_name]) e.stopPropagation();
1954
- if(this.cache.stopImmediatePropagation[event_name]) e.stopImmediatePropagation();
1955
-
1956
- if(this.cache.stream.enabled[event_name]&&push_object)this.cache.stream.history[event_name].push(push_object);
1957
- this.cache.callbacks[event_name]?.map(n=>n(this));
1958
- }
1959
- class __ZikoEvent__ {
1952
+ let ZikoEvent$1 = class ZikoEvent {
1960
1953
  constructor(target = null, Events = [], details_setter, customizer){
1961
1954
  this.target = target;
1962
1955
  this.cache = {
@@ -2100,92 +2093,24 @@ class __ZikoEvent__ {
2100
2093
 
2101
2094
  return this;
2102
2095
  }
2103
- }
2104
-
2105
- // import { register_click_away_event } from "./custom-events/click-away.js";
2106
- class ZikoEventClick extends __ZikoEvent__{
2107
- constructor(target, customizer){
2108
- super(target, Events.Click, details_setter$a, customizer);
2109
- // register_click_away_event(target.element)
2110
- }
2111
- }
2112
- function details_setter$a(){
2113
- if(this.currentEvent==="click") this.dx = 0;
2114
- else this.dx = 1;
2115
- // console.log(this.currentEvent)
2116
- }
2117
- const bind_click_event = (target, customizer) => new ZikoEventClick(target, customizer);
2118
-
2119
- class ZikoEventClipboard extends __ZikoEvent__{
2120
- constructor(target, customizer){
2121
- super(target, Events.Clipboard, details_setter$9, customizer);
2122
- }
2123
- }
2124
- function details_setter$9(){
2125
-
2126
- }
2127
- const bind_clipboard_event = (target, customizer) => new ZikoEventClipboard(target, customizer);
2128
-
2129
- class ZikoEventCustom extends __ZikoEvent__{
2130
- constructor(target, events, customizer){
2131
- super(target, events, details_setter$8, customizer);
2132
- }
2133
- _register_events(events){
2134
- super._register_events(events, null, null, false);
2135
- return this;
2136
- }
2137
- emit(event_name, details = {}){
2138
- const event=new Event(event_name);
2139
- this.targetElement.dispatchEvent(event);
2140
- return this;
2141
- }
2142
- on(event_name, ...callbacks){
2143
- if(!this.cache.options.hasOwnProperty(event_name)) this._register_events([event_name]);
2144
- this.__onEvent(event_name, this.cache.options[event_name], {}, ...callbacks);
2145
- return this;
2146
- }
2147
- }
2148
- function details_setter$8(){
2149
-
2150
- }
2151
- const bindCustomEvent = (target, events, customizer) => new ZikoEventCustom(target, events, customizer);
2152
-
2153
- class ZikoEventDrag extends __ZikoEvent__{
2154
- constructor(target, customizer){
2155
- super(target, Events.Drag, details_setter$7, customizer);
2156
- }
2157
- }
2158
- function details_setter$7(){
2159
-
2160
- }
2161
- const bind_drag_event = (target, customizer) => new ZikoEventDrag(target, customizer);
2162
-
2163
- class ZikoEventFocus extends __ZikoEvent__{
2164
- constructor(target, customizer){
2165
- super(target, Events.Focus, details_setter$6, customizer);
2166
- }
2167
- }
2168
- function details_setter$6(){
2169
-
2170
- }
2171
- const bind_focus_event = (target, customizer) => new ZikoEventFocus(target, customizer);
2172
-
2173
- class ZikoEventHash extends __ZikoEvent__{
2174
- constructor(target, customizer){
2175
- super(target, Events.Hash, details_setter$5, customizer);
2176
- }
2177
- }
2178
- function details_setter$5(){
2096
+ };
2179
2097
 
2180
- }
2181
- const bindHashEvent = (target, customizer) => new ZikoEventHash(target, customizer);
2098
+ function event_controller(e, event_name, details_setter, customizer, push_object){
2099
+ this.cache.currentEvent = event_name;
2100
+ this.cache.event = e;
2101
+ details_setter?.call(this);
2102
+ customizer?.hasOwnProperty("prototype") ? customizer?.call(this) : customizer?.call(null, this);
2103
+ // if(customizer?.hasOwnProperty("prototype")) customizer?.call(this)
2104
+ // else customizer?.call(null, this)
2105
+ if(this.cache.preventDefault[event_name]) e.preventDefault();
2106
+ if(this.cache.stopPropagation[event_name]) e.stopPropagation();
2107
+ if(this.cache.stopImmediatePropagation[event_name]) e.stopImmediatePropagation();
2108
+
2109
+ if(this.cache.stream.enabled[event_name]&&push_object)this.cache.stream.history[event_name].push(push_object);
2110
+ this.cache.callbacks[event_name]?.map(n=>n(this));
2111
+ }
2182
2112
 
2183
- class ZikoEventKey extends __ZikoEvent__{
2184
- constructor(target, customizer){
2185
- super(target, Events.Key, details_setter$4, customizer);
2186
- }
2187
- }
2188
- function details_setter$4(){
2113
+ function key_details_setter(){
2189
2114
  switch(this.currentEvent){
2190
2115
  case "keydown" : {
2191
2116
  this.kd = this.event.key;
@@ -2198,26 +2123,9 @@ function details_setter$4(){
2198
2123
  } break;
2199
2124
 
2200
2125
  }
2201
- }
2202
- const bind_key_event = (target, customizer) => new ZikoEventKey(target, customizer);
2203
-
2204
- class ZikoEventMouse extends __ZikoEvent__{
2205
- constructor(target, customizer){
2206
- super(target, Events.Mouse, details_setter$3, customizer);
2207
- }
2208
- }
2209
- function details_setter$3(){
2210
-
2211
- }
2212
- const bind_mouse_event = (target, customizer) => new ZikoEventMouse(target, customizer);
2126
+ }
2213
2127
 
2214
- class ZikoEventPointer extends __ZikoEvent__{
2215
- constructor(target, customizer){
2216
- super(target, Events.Ptr, details_setter$2, customizer);
2217
- this.isDown = false;
2218
- }
2219
- }
2220
- function details_setter$2(){
2128
+ function ptr_details_setter(){
2221
2129
  switch(this.currentEvent){
2222
2130
  case "pointerdown" : {
2223
2131
  this.dx = parseInt(this.event.offsetX);
@@ -2249,28 +2157,107 @@ function details_setter$2(){
2249
2157
  // if(this.currentEvent==="click") this.dx = 0
2250
2158
  // else this.dx = 1
2251
2159
  // console.log(this.currentEvent)
2252
- }
2253
- const bind_pointer_event = (target, customizer) => new ZikoEventPointer(target, customizer);
2160
+ }
2254
2161
 
2255
- class ZikoEventTouch extends __ZikoEvent__{
2256
- constructor(target, customizer){
2257
- super(target, Events.Touch, details_setter$1, customizer);
2258
- }
2162
+ class ClickAwayEvent extends Event {
2163
+ constructor(originalEvent, targetElement) {
2164
+ super("clickaway", { bubbles: true, cancelable: true });
2165
+ this.originalEvent = originalEvent;
2166
+ this.targetElement = targetElement;
2167
+ }
2259
2168
  }
2260
- function details_setter$1(){
2261
2169
 
2262
- }
2263
- const bindTouchEvent = (target, customizer) => new ZikoEventTouch(target, customizer);
2264
-
2265
- class ZikoEventWheel extends __ZikoEvent__{
2266
- constructor(target, customizer){
2267
- super(target, Events.Wheel, details_setter, customizer);
2170
+ function register_click_away_event(element) {
2171
+ console.log(element);
2172
+ function handler(e) {
2173
+ if (!element.contains(e.target)) {
2174
+ const clickAwayEvent = new ClickAwayEvent(e, element);
2175
+ element.dispatchEvent(clickAwayEvent);
2268
2176
  }
2269
- }
2270
- function details_setter(){
2177
+ }
2271
2178
 
2179
+ globalThis?.document?.addEventListener("click", handler);
2180
+
2181
+ return () => globalThis?.document?.removeEventListener("click", handler);
2182
+
2272
2183
  }
2273
- const bind_wheel_event = (target, customizer) => new ZikoEventWheel(target, customizer);
2184
+
2185
+ // // Example usage
2186
+ // const box = document.querySelector("#my-box");
2187
+
2188
+ // const stop = listenClickAway(box);
2189
+
2190
+ // box.addEventListener("clickaway", (e) => {
2191
+ // console.log("Clicked outside box!", e);
2192
+ // });
2193
+
2194
+ // // later, you can stop listening:
2195
+ // // stop();
2196
+
2197
+ const bind_click_event = (target, customizer) => {
2198
+ register_click_away_event(target.element);
2199
+ return new ZikoEvent$1(
2200
+ target,
2201
+ EventsMap.Click,
2202
+ null,
2203
+ customizer
2204
+ );
2205
+ };
2206
+ const bind_clipboard_event = (target, customizer) => new ZikoEvent$1(
2207
+ target,
2208
+ EventsMap.Clipboard,
2209
+ null,
2210
+ customizer
2211
+ );
2212
+ const bind_drag_event = (target, customizer) => new ZikoEvent$1(
2213
+ target,
2214
+ EventsMap.Drag,
2215
+ null,
2216
+ customizer
2217
+ );
2218
+ const bind_focus_event = (target, customizer) => new ZikoEvent$1(
2219
+ target,
2220
+ EventsMap.Focus,
2221
+ null,
2222
+ customizer
2223
+ );
2224
+ const bind_key_event = (target, customizer) => new ZikoEvent$1(
2225
+ target,
2226
+ EventsMap.Key,
2227
+ key_details_setter,
2228
+ customizer
2229
+ );
2230
+ const bind_mouse_event = (target, customizer) => new ZikoEvent$1(
2231
+ target,
2232
+ EventsMap.Mouse,
2233
+ null,
2234
+ customizer
2235
+ );
2236
+ const bind_pointer_event = (target, customizer) => new ZikoEvent$1(
2237
+ target,
2238
+ EventsMap.Ptr,
2239
+ ptr_details_setter,
2240
+ customizer
2241
+ );
2242
+ const bind_touch_event = (target, customizer) => new ZikoEvent$1(
2243
+ target,
2244
+ EventsMap.Touch,
2245
+ null,
2246
+ customizer
2247
+ );
2248
+ const bind_wheel_event = (target, customizer) => new ZikoEvent$1(
2249
+ target,
2250
+ EventsMap.Wheel,
2251
+ null,
2252
+ customizer
2253
+ );
2254
+
2255
+
2256
+ // function details_setter(){
2257
+ // if(this.currentEvent==="click") this.dx = 0
2258
+ // else this.dx = 1
2259
+ // // console.log(this.currentEvent)
2260
+ // }
2274
2261
 
2275
2262
  const binderMap = {
2276
2263
  ptr: bind_pointer_event,
@@ -2285,7 +2272,7 @@ const binderMap = {
2285
2272
 
2286
2273
  const EventsMethodes = {};
2287
2274
 
2288
- Object.entries(Events).forEach(([name, eventList]) => {
2275
+ Object.entries(EventsMap).forEach(([name, eventList]) => {
2289
2276
  eventList.forEach(event => {
2290
2277
  const methodName = `on${event}`;
2291
2278
  EventsMethodes[methodName] = function (...callbacks) {
@@ -4798,76 +4785,79 @@ const timeTaken = callback => {
4798
4785
  };
4799
4786
 
4800
4787
  class UseEventEmitter {
4801
- constructor() {
4802
- this.events = {};
4803
- this.maxListeners = 10;
4788
+ constructor(maxListeners = 10) {
4789
+ this.events = {};
4790
+ this.maxListeners = maxListeners;
4804
4791
  }
4792
+
4805
4793
  on(event, listener) {
4806
- if (!this.events[event]) {
4807
- this.events[event] = [];
4808
- }
4809
- this.events[event].push(listener);
4810
- if (this.events[event].length > this.maxListeners) {
4811
- console.warn(`Warning: Possible memory leak. Event '${event}' has more than ${this.maxListeners} listeners.`);
4812
- }
4794
+ if (!this.events[event]) this.events[event] = [];
4795
+ this.events[event].push(listener);
4796
+ if (this.events[event].length > this.maxListeners) {
4797
+ console.warn(`Warning: Possible memory leak. Event '${event}' has more than ${this.maxListeners} listeners.`);
4798
+ }
4799
+ return this;
4813
4800
  }
4801
+
4814
4802
  once(event, listener) {
4815
- const onceListener = (data) => {
4816
- this.off(event, onceListener); // Remove the listener after it's been called
4817
- listener(data);
4818
- };
4819
- this.on(event, onceListener);
4803
+ const wrapper = (...args) => {
4804
+ this.off(event, wrapper);
4805
+ listener(...args);
4806
+ };
4807
+ return this.on(event, wrapper);
4820
4808
  }
4821
-
4809
+
4822
4810
  off(event, listener) {
4823
- const listeners = this.events[event];
4824
- if (listeners) {
4811
+ const listeners = this.events[event];
4812
+ if (!listeners) return this;
4813
+
4825
4814
  const index = listeners.indexOf(listener);
4826
4815
  if (index !== -1) {
4827
- listeners.splice(index, 1);
4816
+ listeners.splice(index, 1);
4828
4817
  }
4829
- }
4818
+
4819
+ return this;
4830
4820
  }
4831
-
4821
+
4832
4822
  emit(event, data) {
4833
- const listeners = this.events[event];
4834
- if (listeners) {
4835
- listeners.forEach(listener => {
4836
- listener(data);
4823
+ const listeners = this.events[event];
4824
+ if (!listeners) return false;
4825
+
4826
+ // Make a copy so removing listeners inside callbacks doesn't affect iteration
4827
+ [...listeners].forEach(listener => {
4828
+ try {
4829
+ listener(data);
4830
+ } catch (e) {
4831
+ console.error(`Error in listener for '${event}':`, e);
4832
+ }
4837
4833
  });
4838
- }
4839
- }
4840
-
4841
- clear(event) {
4842
- if (event) {
4843
- delete this.events[event];
4844
- } else {
4845
- this.events = {};
4846
- }
4834
+
4835
+ return true;
4847
4836
  }
4848
-
4849
- setMaxListener(event, max) {
4850
- this.maxListeners = max;
4837
+ remove(event){
4838
+ delete this.events[event];
4839
+ return this;
4851
4840
  }
4852
-
4853
- removeAllListeners(event) {
4854
- if (event) {
4855
- this.events[event] = [];
4856
- } else {
4841
+ clear() {
4857
4842
  this.events = {};
4858
- }
4843
+ return this;
4859
4844
  }
4860
- }
4861
4845
 
4862
- const useEventEmitter=()=>new UseEventEmitter();
4846
+ setMaxListeners(max) {
4847
+ this.maxListeners = max;
4848
+ return this;
4849
+ }
4850
+ }
4851
+
4852
+ const useEventEmitter = (maxListeners) => new UseEventEmitter(maxListeners);
4863
4853
 
4864
4854
  class ZikoUseFavIcon{
4865
- constructor(FavIcon,useEventEmitter=true){
4855
+ constructor(FavIcon,withEmitter=true){
4866
4856
  this.#init();
4867
4857
  this.cache={
4868
4858
  Emitter:null
4869
4859
  };
4870
- if(useEventEmitter)this.useEventEmitter();
4860
+ if(withEmitter)this.useEventEmitter();
4871
4861
  this.set(FavIcon);
4872
4862
  }
4873
4863
  #init(){
@@ -4896,7 +4886,7 @@ class ZikoUseFavIcon{
4896
4886
  }
4897
4887
 
4898
4888
  }
4899
- const useFavIcon=(FavIcon,useEventEmitter)=>new ZikoUseFavIcon(FavIcon,useEventEmitter);
4889
+ const useFavIcon=(FavIcon,withEmitter)=>new ZikoUseFavIcon(FavIcon,withEmitter);
4900
4890
 
4901
4891
  class ZikoMeta{
4902
4892
  constructor({viewport,charset,description,author,keywords}){
@@ -4976,7 +4966,7 @@ class ZikoUseTitle{
4976
4966
  return this;
4977
4967
  }
4978
4968
  }
4979
- const useTitle=(title, useEventEmitter)=>new ZikoUseTitle(title, useEventEmitter);
4969
+ const useTitle$1=(title, useEventEmitter)=>new ZikoUseTitle(title, useEventEmitter);
4980
4970
 
4981
4971
  // import {useLink} from "./";
4982
4972
  class ZikoHead{
@@ -4984,7 +4974,7 @@ class ZikoHead{
4984
4974
  this.html = globalThis?.document?.documentElement;
4985
4975
  this.head = globalThis?.document?.head;
4986
4976
 
4987
- title && useTitle(title);
4977
+ title && useTitle$1(title);
4988
4978
  lang && this.setLang(lang);
4989
4979
  icon && useFavIcon(icon);
4990
4980
  meta && useMeta(meta);
@@ -5221,7 +5211,7 @@ function useDerived(deriveFn, sources) {
5221
5211
  const subscribers = new Set();
5222
5212
 
5223
5213
  sources.forEach(source => {
5224
- const srcValue = source(); // getValue()
5214
+ const srcValue = source();
5225
5215
  srcValue._subscribe(() => {
5226
5216
  {
5227
5217
  const newVal = deriveFn(...sources.map(s => s().value));
@@ -5250,121 +5240,155 @@ const useReactive = (nested_value) => mapfun$1(
5250
5240
  nested_value
5251
5241
  );
5252
5242
 
5253
- class UseThreed {
5254
- #workerContent;
5243
+ class UseThread {
5244
+ #worker;
5245
+ #callbacks = new Map();
5246
+ #idCounter = 0;
5247
+
5255
5248
  constructor() {
5256
- this.#workerContent = (
5257
- function (msg) {
5249
+ const workerCode = `
5250
+ this.onmessage = function(e) {
5251
+ const { id, funStr, args, close } = e.data;
5258
5252
  try {
5259
- const func = new Function("return " + msg.data.fun)();
5260
- let result = func();
5261
- postMessage({ result });
5253
+ const func = new Function("return " + funStr)();
5254
+ const result = func(...args);
5255
+ postMessage({ id, result });
5262
5256
  } catch (error) {
5263
- postMessage({ error: error.message });
5257
+ postMessage({ id, error: error.message });
5264
5258
  } finally {
5265
- if (msg.data.close) self.close();
5259
+ if (close) self.close();
5266
5260
  }
5267
5261
  }
5268
- ).toString();
5269
- this.blob = new Blob(["this.onmessage = " + this.#workerContent], { type: "text/javascript" });
5270
- this.worker = new Worker(window.URL.createObjectURL(this.blob));
5262
+ `;
5263
+ const blob = new Blob([workerCode], { type: "text/javascript" });
5264
+ this.#worker = new Worker(URL.createObjectURL(blob));
5265
+
5266
+ this.#worker.addEventListener("message", (e) => {
5267
+ const { id, result, error } = e.data;
5268
+ const callback = this.#callbacks.get(id);
5269
+ if (!callback) return;
5270
+
5271
+ callback(result, error);
5272
+ this.#callbacks.delete(id);
5273
+ });
5271
5274
  }
5272
- call(func, callback, close = true) {
5273
- this.worker.postMessage({
5274
- fun: func.toString(),
5275
+ call(func, callback, args = [], close = true) {
5276
+ if (typeof func !== "function") throw new TypeError("func must be a function");
5277
+ const id = ++this.#idCounter;
5278
+ this.#callbacks.set(id, callback);
5279
+
5280
+ this.#worker.postMessage({
5281
+ id,
5282
+ funStr: func.toString(),
5283
+ args,
5275
5284
  close
5276
5285
  });
5277
- this.worker.onmessage = function (e) {
5278
- if (e.data.error) {
5279
- console.error(e.data.error);
5280
- } else {
5281
- callback(e.data.result);
5282
- }
5283
- };
5286
+
5284
5287
  return this;
5285
5288
  }
5286
- }
5287
5289
 
5288
- const useThread = (func, callback , close) => {
5289
- const T = new UseThreed();
5290
- if (func) {
5291
- T.call(func, callback , close);
5290
+ terminate() {
5291
+ this.#worker.terminate();
5292
5292
  }
5293
- return T;
5294
- };
5293
+ }
5295
5294
 
5296
- class UseRoot {
5297
- constructor(PropsMap, {namespace = 'Ziko', register, ValidateCssProps = false} = {}){
5298
- this.currentPropsMap = PropsMap;
5299
- this.namespace = namespace;
5300
- this.ValidateCssProps = ValidateCssProps;
5301
- // this.pairs = {};
5302
- // this.#maintain()
5303
- this.use(PropsMap);
5304
- }
5305
- use(PropsMap){
5306
- if(this.ValidateCssProps) ValidateCssProps(PropsMap);
5307
- this.currentPropsMap = PropsMap;
5308
- this.#maintain();
5309
- return this;
5295
+ /*
5296
+ [
5297
+ {
5298
+ query: '(min-width: 600px)',
5299
+ callback: () => console.log(1)
5300
+ },
5301
+ {
5302
+ query: '(max-width: 300px)',
5303
+ callback: () => console.log(2)
5310
5304
  }
5311
- #maintain(){
5312
- const root = globalThis?.document?.documentElement?.style;
5313
- for(let prop in this.currentPropsMap){
5314
- const cssProp = this.namespace ? `--${this.namespace}-${prop}` : `--${prop}`;
5315
- root.setProperty(
5316
- cssProp,
5317
- this.currentPropsMap[prop]
5318
- );
5319
- // Object.assign(this.pairs, {
5320
- // [prop] : `var(--${this.namespace}-${prop})`
5321
- // })
5322
- Object.defineProperty(this, prop, {
5323
- value: `var(${cssProp})`,
5324
- writable: true,
5325
- configurable: true,
5326
- enumerable: false
5327
- });
5328
- }
5305
+ ]
5306
+ */
5307
+
5308
+ class UseMediaQuery {
5309
+ #mediaQueryRules;
5310
+ #fallback;
5311
+ #lastCalledCallback = null;
5312
+
5313
+ constructor(mediaQueryRules = [], fallback = () => {}) {
5314
+ this.#mediaQueryRules = mediaQueryRules;
5315
+ this.#fallback = fallback;
5316
+
5317
+ this.#init();
5329
5318
  }
5330
- }
5331
5319
 
5332
- function ValidateCssProps(PropsMap){
5333
- const validProps = new Set(Object.keys(document.documentElement.style));
5334
- for (let key in PropsMap) {
5335
- if (!validProps.has(key)) {
5336
- throw new Error(`Invalid CSS property: "${key}"`);
5337
- }
5320
+ // PRIVATE: check if ANY rule matches
5321
+ #checkAllRules() {
5322
+ return this.#mediaQueryRules.some(
5323
+ ({ query }) => globalThis.matchMedia(query).matches
5324
+ );
5338
5325
  }
5339
- }
5340
5326
 
5341
- const useRoot = (PropsMap, {namespace, register, ValidateCssProps} = {}) => new UseRoot(PropsMap, {namespace, register, ValidateCssProps});
5327
+ // PRIVATE: installs listeners and initial checks
5328
+ #init() {
5329
+ this.#mediaQueryRules.forEach(({ query, callback }) => {
5330
+ const mediaQueryList = globalThis.matchMedia(query);
5342
5331
 
5343
- // Usage
5332
+ const checkMatches = () => {
5333
+ const anyMatch = this.#checkAllRules();
5344
5334
 
5345
- /*
5346
- const Styles = {
5347
- S1 : {
5348
- background : 'white',
5349
- color : 'darkblue'
5350
- border : '2px darkblue solid"'
5351
- },
5352
- S2 : {
5353
- background : 'darkblue',
5354
- color : 'white'
5355
- border : '2px green solid"'
5356
- }
5335
+ if (mediaQueryList.matches) {
5336
+ callback();
5337
+ this.#lastCalledCallback = callback;
5338
+ } else if (!anyMatch && this.#lastCalledCallback !== this.#fallback) {
5339
+ this.#fallback();
5340
+ this.#lastCalledCallback = this.#fallback;
5341
+ }
5342
+ };
5343
+
5344
+ checkMatches();
5345
+ mediaQueryList.addEventListener("change", checkMatches);
5346
+ });
5347
+ }
5357
5348
  }
5358
- const {use, border, background, color} = useRoot(Style.S1)
5359
5349
 
5360
- tags.p("Test useRoot ").style({
5361
- border,
5362
- color,
5363
- background,
5364
- padding : '10px'
5365
- })
5350
+ const useMediaQuery = (mediaQueryRules, fallback) =>
5351
+ new UseMediaQuery(mediaQueryRules, fallback);
5352
+
5353
+ class UseTitle {
5354
+ constructor(title = document.title, withEmitter = true) {
5355
+ this.cache = {
5356
+ emitter: null
5357
+ };
5358
+
5359
+ if (withEmitter) this.useEventEmitter();
5360
+ this.set(title);
5361
+ }
5366
5362
 
5367
- */
5363
+ useEventEmitter() {
5364
+ this.cache.emitter = useEventEmitter();
5365
+ return this;
5366
+ }
5367
+
5368
+ setTitle(title) {
5369
+ if (title !== document.title) {
5370
+ document.title = title;
5371
+
5372
+ if (this.cache.emitter) {
5373
+ this.cache.emitter.emit("ziko:title-changed", title);
5374
+ }
5375
+ }
5376
+ return this;
5377
+ }
5378
+
5379
+ get current() {
5380
+ return document.title;
5381
+ }
5382
+
5383
+ onChange(callback) {
5384
+ if (this.cache.emitter) {
5385
+ this.cache.emitter.on("ziko:title-changed", callback);
5386
+ }
5387
+ return this;
5388
+ }
5389
+ }
5390
+
5391
+ const useTitle = (title, withEmitter = true) => new UseTitle(title, withEmitter);
5368
5392
 
5369
5393
  let {sqrt, cos, sin, exp, log, cosh, sinh} = Math;
5370
5394
  // Math.abs = new Proxy(Math.abs, {
@@ -5459,26 +5483,15 @@ exports.UINode = UINode;
5459
5483
  exports.UISVGWrapper = UISVGWrapper;
5460
5484
  exports.UISwitch = UISwitch;
5461
5485
  exports.UIView = UIView;
5462
- exports.UseRoot = UseRoot;
5486
+ exports.UseThread = UseThread;
5463
5487
  exports.Utils = Utils;
5464
5488
  exports.View = View;
5465
5489
  exports.ZikoApp = ZikoApp;
5466
- exports.ZikoEventClick = ZikoEventClick;
5467
- exports.ZikoEventClipboard = ZikoEventClipboard;
5468
- exports.ZikoEventCustom = ZikoEventCustom;
5469
- exports.ZikoEventDrag = ZikoEventDrag;
5470
- exports.ZikoEventFocus = ZikoEventFocus;
5471
- exports.ZikoEventHash = ZikoEventHash;
5472
- exports.ZikoEventKey = ZikoEventKey;
5473
- exports.ZikoEventMouse = ZikoEventMouse;
5474
- exports.ZikoEventPointer = ZikoEventPointer;
5475
- exports.ZikoEventTouch = ZikoEventTouch;
5476
- exports.ZikoEventWheel = ZikoEventWheel;
5490
+ exports.ZikoEvent = ZikoEvent$1;
5477
5491
  exports.ZikoSPA = ZikoSPA;
5478
5492
  exports.ZikoUIFlex = ZikoUIFlex;
5479
5493
  exports.ZikoUISuspense = ZikoUISuspense;
5480
5494
  exports.ZikoUIText = ZikoUIText;
5481
- exports.__ZikoEvent__ = __ZikoEvent__;
5482
5495
  exports.abs = abs;
5483
5496
  exports.accum = accum;
5484
5497
  exports.acos = acos$1;
@@ -5495,9 +5508,6 @@ exports.atan = atan;
5495
5508
  exports.atan2 = atan2;
5496
5509
  exports.atanh = atanh;
5497
5510
  exports.back = back;
5498
- exports.bindCustomEvent = bindCustomEvent;
5499
- exports.bindHashEvent = bindHashEvent;
5500
- exports.bindTouchEvent = bindTouchEvent;
5501
5511
  exports.bind_click_event = bind_click_event;
5502
5512
  exports.bind_clipboard_event = bind_clipboard_event;
5503
5513
  exports.bind_drag_event = bind_drag_event;
@@ -5505,6 +5515,7 @@ exports.bind_focus_event = bind_focus_event;
5505
5515
  exports.bind_key_event = bind_key_event;
5506
5516
  exports.bind_mouse_event = bind_mouse_event;
5507
5517
  exports.bind_pointer_event = bind_pointer_event;
5518
+ exports.bind_touch_event = bind_touch_event;
5508
5519
  exports.bind_wheel_event = bind_wheel_event;
5509
5520
  exports.cartesianProduct = cartesianProduct;
5510
5521
  exports.ceil = ceil;
@@ -5631,15 +5642,15 @@ exports.tick = tick;
5631
5642
  exports.timeTaken = timeTaken;
5632
5643
  exports.time_memory_Taken = time_memory_Taken;
5633
5644
  exports.timeout = timeout;
5634
- exports.useChannel = useChannel;
5635
5645
  exports.useDerived = useDerived;
5636
5646
  exports.useEventEmitter = useEventEmitter;
5647
+ exports.useIPC = useIPC;
5637
5648
  exports.useLocaleStorage = useLocaleStorage;
5649
+ exports.useMediaQuery = useMediaQuery;
5638
5650
  exports.useReactive = useReactive;
5639
- exports.useRoot = useRoot;
5640
5651
  exports.useSessionStorage = useSessionStorage;
5641
5652
  exports.useState = useState;
5642
- exports.useThread = useThread;
5653
+ exports.useTitle = useTitle;
5643
5654
  exports.wait = wait;
5644
5655
  exports.waitForUIElm = waitForUIElm;
5645
5656
  exports.waitForUIElmSync = waitForUIElmSync;