@xuda.io/runtime-bundle 1.0.1246 → 1.0.1248

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.
@@ -2676,11 +2676,6 @@ func.common.get_data_from_websocket = async function (SESSION_ID, serviceP, data
2676
2676
  };
2677
2677
 
2678
2678
  func.common.sha256 = async function (inputString) {
2679
- // const enc = new TextEncoder();
2680
- // const buf = await crypto.subtle.digest('SHA-256', enc.encode(str));
2681
- // const bytes = new Uint8Array(buf);
2682
- // return [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('');
2683
-
2684
2679
  // 1. Create a hash buffer from the input string using SHA-256.
2685
2680
  // This part remains the same as it provides a strong, unique cryptographic starting point.
2686
2681
  const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(inputString));
@@ -3277,7 +3272,7 @@ func.datasource.prepare = async function (SESSION_ID, prog_id, dataSourceNoP, pa
3277
3272
  _ds.data_feed = {};
3278
3273
 
3279
3274
  // _ds.v.old_dataSource = _.cloneDeep(_ds);
3280
- _ds.v.old_dataSource = klona(_ds);
3275
+ _ds.v.old_dataSource = klona.klona(_ds);
3281
3276
  } catch (err) {
3282
3277
  console.error('function: init_existing_dataSource - error');
3283
3278
  return;
@@ -4908,11 +4903,11 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
4908
4903
  }
4909
4904
 
4910
4905
  // await func.UI.screen.refresh_xu_attributes(SESSION_ID, _.cloneDeep(fields_changed), null, null, findMin(datasource_changed), avoid_xu_for_refresh, trigger);
4911
- await func.UI.screen.refresh_xu_attributes(SESSION_ID, klona(fields_changed), null, null, findMin(datasource_changed), avoid_xu_for_refresh, trigger);
4906
+ await func.UI.screen.refresh_xu_attributes(SESSION_ID, klona.klona(fields_changed), null, null, findMin(datasource_changed), avoid_xu_for_refresh, trigger);
4912
4907
  // await removed from the below function cause to dead lock Mar 3 25
4913
4908
  await func.UI.screen.refresh_screen(
4914
4909
  SESSION_ID,
4915
- klona(fields_changed), // _.cloneDeep(fields_changed),
4910
+ klona.klona(fields_changed), // _.cloneDeep(fields_changed),
4916
4911
  null,
4917
4912
  datasource_changed[0], // refresh the current datasource only
4918
4913
  );
@@ -5564,7 +5559,7 @@ func.datasource.set_VIEW_data = async function (SESSION_ID, args, _ds) {
5564
5559
  _ds.viewEventExec_arr = {};
5565
5560
 
5566
5561
  // var view = _.cloneDeep(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
5567
- var view = klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
5562
+ var view = klona.klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
5568
5563
 
5569
5564
  _ds.v.dataSourceSrcType = view.dataSourceSrcType;
5570
5565
 
@@ -9039,7 +9034,7 @@ func.UI.screen.init = async function (SESSION_ID, prog_id, sourceScreenP, callin
9039
9034
  let _session = SESSION_OBJ[SESSION_ID];
9040
9035
 
9041
9036
  // const screenInfo = _.cloneDeep(screen_ret);
9042
- const screenInfo = klona(screen_ret);
9037
+ const screenInfo = klona.klona(screen_ret);
9043
9038
 
9044
9039
  var screen_type = source_functionP?.split('_')?.[1]; //|| (is_panelP && "panel");
9045
9040
 
@@ -9184,7 +9179,7 @@ func.UI.screen.init = async function (SESSION_ID, prog_id, sourceScreenP, callin
9184
9179
  }
9185
9180
  var node;
9186
9181
  // node = _.cloneDeep(viewDoc.progUi);
9187
- node = klona(viewDoc.progUi);
9182
+ node = klona.klona(viewDoc.progUi);
9188
9183
  if (!node.length) return console.warn('ui node empty');
9189
9184
  const ret_render_$container = await func.UI.screen.render_ui_tree(SESSION_ID, $rootFrame, node[0], null, params, jobNoP, null, null, null, null, null, $rootFrame);
9190
9185
 
@@ -9751,7 +9746,7 @@ func.UI.screen.refresh_screen = async function (SESSION_ID, fields_changed_arr,
9751
9746
  const new_$div = await func.UI.screen.render_ui_tree(
9752
9747
  SESSION_ID,
9753
9748
  $elm, // the wrapper
9754
- klona($elm.data().xuData.node), //_.cloneDeep($elm.data().xuData.node), // the xu-panel node
9749
+ klona.klona($elm.data().xuData.node), //_.cloneDeep($elm.data().xuData.node), // the xu-panel node
9755
9750
  {},
9756
9751
  elm_data.xuData.paramsP, // the wrapper params
9757
9752
  null,
@@ -10715,7 +10710,7 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
10715
10710
  reference_source_obj,
10716
10711
  };
10717
10712
  // let _parent_info = _.cloneDeep(parent_infoP) || {};
10718
- let _parent_info = klona(parent_infoP) || {};
10713
+ let _parent_info = klona.klona(parent_infoP) || {};
10719
10714
  _parent_info.iterate_info = iterate_info;
10720
10715
 
10721
10716
  const $divP = await func.UI.screen.render_ui_tree(
@@ -11043,62 +11038,408 @@ func.UI.screen.fix_val_defaults = function (key, val) {
11043
11038
  return ret;
11044
11039
  };
11045
11040
 
11041
+ // func.UI.screen.set_attributes_new = async function (SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $elm, is_init, execute_attributes = [], refreshed_ds) {
11042
+ // var done_exp = [];
11043
+
11044
+ // const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
11045
+ // if (!_ds) return { abort: true };
11046
+
11047
+ // const get_attr_value = async function (key) {
11048
+ // let ret = func.UI.screen.fix_val_defaults(key, nodeP.attributes[key]);
11049
+ // if (nodeP?.attributes?.hasOwnProperty(`xu-exp:${key}`)) {
11050
+ // ret = await get_xuExp(key);
11051
+ // }
11052
+ // return ret;
11053
+ // };
11054
+
11055
+ // const get_xuExp = async function (attrib) {
11056
+ // if (is_skeleton) return;
11057
+ // if (glb.new_xu_render) {
11058
+ // let _xuData = $elm.data().xuData;
11059
+ // if (!_xuData.attr_exp_info) {
11060
+ // _xuData.attr_exp_info = {};
11061
+ // }
11062
+ // }
11063
+ // const attr = `xu-exp:${attrib}`;
11064
+
11065
+ // if (!nodeP?.attributes?.hasOwnProperty(attr)) return;
11066
+ // // const attr = `xu-exp-${attrib}`;
11067
+ // var exp = nodeP.attributes[attr];
11068
+ // // if (!value) return func.UI.screen.fix_val_defaults(attrib, exp || nodeP.attributes[attrib]);
11069
+
11070
+ // var res = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId);
11071
+ // if (glb.new_xu_render) {
11072
+ // _xuData.attr_exp_info[attrib] = res;
11073
+ // }
11074
+ // // nodeP.attributes[attr] = value; //{ value: value, res: res };
11075
+ // done_exp.push(attr);
11076
+ // return res.result; //func.UI.screen.fix_val_defaults(attrib, res.result);
11077
+ // };
11078
+
11079
+ // var _ret = {};
11080
+ // if (nodeP.type !== 'element' || !nodeP.attributes) return _ret;
11081
+
11082
+ // for (let [key, val] of Object.entries(nodeP.attributes)) {
11083
+ // // REMOVE STATIC ATTRIBUTES IF EXP EXISTS to avoid dup
11084
+ // if (key.substring(0, 6) === 'xu-exp') {
11085
+ // if (_.isEmpty(val)) {
11086
+ // delete nodeP.attributes[key];
11087
+ // continue;
11088
+ // }
11089
+ // const clean_key = key.split(':')[1];
11090
+ // if (typeof nodeP.attributes[clean_key] !== 'undefined') {
11091
+ // delete nodeP.attributes[clean_key];
11092
+ // }
11093
+ // }
11094
+ // // FIX abbreviations
11095
+ // if (glb.attr_abbreviations_arr.includes(key)) {
11096
+ // nodeP.attributes[`xu-on:${key.substring(3)}`] = [
11097
+ // {
11098
+ // handler: 'custom',
11099
+ // props: {},
11100
+ // event: [
11101
+ // {
11102
+ // id: Date.now(),
11103
+ // data: {
11104
+ // action: 'update',
11105
+ // name: { value: val },
11106
+ // enabled: true,
11107
+ // },
11108
+ // props: {},
11109
+ // },
11110
+ // ],
11111
+ // },
11112
+ // ];
11113
+ // delete nodeP.attributes[key];
11114
+ // }
11115
+ // }
11116
+
11117
+ // for (let [key, val] of Object.entries(nodeP.attributes)) {
11118
+ // // FIX STATIC DEFAULTS
11119
+ // val = func.UI.screen.fix_val_defaults(key, val);
11120
+
11121
+ // // REMOVE UNDEFINED or NULL ATTRIBUTES
11122
+ // if (typeof val === 'undefined' || val === null) {
11123
+ // delete nodeP.attributes[key];
11124
+ // }
11125
+
11126
+ // // REMOVE ATTRIBUTES WITH EMPTY VALUES
11127
+ // if (glb.solid_attributes.includes(key) && !val) {
11128
+ // delete nodeP.attributes[key];
11129
+ // }
11130
+ // }
11131
+
11132
+ // // XU-ATTRS
11133
+ // if (nodeP?.attributes?.['xu-attrs'] || nodeP?.attributes?.['xu-exp:xu-attrs']) {
11134
+ // const attr = 'xu-attrs';
11135
+ // let ret = await func.UI.screen.execute_xu_functions(
11136
+ // SESSION_ID,
11137
+ // is_skeleton,
11138
+ // $root_container,
11139
+ // nodeP,
11140
+ // $container,
11141
+ // paramsP,
11142
+ // parent_infoP,
11143
+ // jobNoP,
11144
+ // keyP,
11145
+ // parent_nodeP,
11146
+ // attr,
11147
+ // $elm,
11148
+ // {
11149
+ // key: attr,
11150
+ // value: await get_attr_value(attr),
11151
+ // },
11152
+ // is_init,
11153
+ // );
11154
+ // }
11155
+
11156
+ // // BEFORE
11157
+ // if (!_.isEmpty(nodeP.attributes)) {
11158
+ // for await (const [key, attr] of Object.entries(glb.run_xu_before)) {
11159
+ // if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
11160
+ // if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) {
11161
+ // continue;
11162
+ // }
11163
+
11164
+ // if (!nodeP?.attributes?.hasOwnProperty(attr) && !nodeP?.attributes?.hasOwnProperty(`xu-exp:${attr}`)) {
11165
+ // continue;
11166
+ // }
11167
+
11168
+ // if (!nodeP.attributes[`xu-exp:${attr}`] && nodeP?.attributes?.hasOwnProperty(attr) && typeof func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]) === 'undefined') {
11169
+ // continue;
11170
+ // }
11171
+
11172
+ // let ret = await func.UI.screen.execute_xu_functions(
11173
+ // SESSION_ID,
11174
+ // is_skeleton,
11175
+ // $root_container,
11176
+ // nodeP,
11177
+ // $container,
11178
+ // paramsP,
11179
+ // parent_infoP,
11180
+ // jobNoP,
11181
+ // keyP,
11182
+ // parent_nodeP,
11183
+ // attr,
11184
+ // $elm,
11185
+ // {
11186
+ // key: attr,
11187
+
11188
+ // value: await get_attr_value(attr),
11189
+ // },
11190
+ // is_init,
11191
+ // );
11192
+ // _ret = _.assignIn(_ret, ret);
11193
+ // }
11194
+ // }
11195
+
11196
+ // // ALL
11197
+
11198
+ // for await (const [key, val] of Object.entries(nodeP.attributes)) {
11199
+ // if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
11200
+ // if (glb.html5_events_handler.includes(key) || execute_attributes.includes(key)) {
11201
+ // continue;
11202
+ // }
11203
+
11204
+ // const new_key = key.split(':')[0]; // break expression
11205
+ // if (
11206
+ // nodeP.tagName !== 'xu-panel' &&
11207
+ // nodeP.tagName !== 'xu-teleport' && // nodeP.tagName.substr(0, 3) !== "xu-" &&
11208
+ // (new_key.substr(0, 2) !== 'xu' || new_key.substr(2, 1) !== '-')
11209
+ // ) {
11210
+ // // handle common html attributes
11211
+ // try {
11212
+ // $elm.get(0).setAttribute(key, val);
11213
+ // } catch (err) {
11214
+ // console.error(err.message);
11215
+ // }
11216
+
11217
+ // continue;
11218
+ // }
11219
+ // // handle xu attributes
11220
+ // try {
11221
+ // if ($elm?.data()?.xuAttributes) {
11222
+ // // in some cases xu data delete in purpose when refreshing the screen
11223
+ // $elm.data().xuAttributes[key] = val;
11224
+ // }
11225
+ // } catch (error) {
11226
+ // debugger;
11227
+ // console.error(error);
11228
+ // }
11229
+
11230
+ // if (new_key === 'xu-exp' || nodeP.attributes['xu-exp:' + new_key] || glb.run_xu_before.includes(new_key) || glb.run_xu_after.includes(new_key)) {
11231
+ // continue;
11232
+ // }
11233
+
11234
+ // if (new_key === 'xu-on') {
11235
+ // let ret = await func.UI.screen.execute_xu_functions(
11236
+ // SESSION_ID,
11237
+ // is_skeleton,
11238
+ // $root_container,
11239
+ // nodeP,
11240
+ // $container,
11241
+ // paramsP,
11242
+ // parent_infoP,
11243
+ // jobNoP,
11244
+ // keyP,
11245
+ // parent_nodeP,
11246
+ // 'xu-on',
11247
+ // $elm,
11248
+ // {
11249
+ // key: key,
11250
+ // // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
11251
+ // value: await get_attr_value(key),
11252
+ // },
11253
+ // is_init,
11254
+ // refreshed_ds,
11255
+ // );
11256
+ // _ret = _.assignIn(_ret, ret);
11257
+ // continue;
11258
+ // }
11259
+
11260
+ // let ret = await func.UI.screen.execute_xu_functions(
11261
+ // SESSION_ID,
11262
+ // is_skeleton,
11263
+ // $root_container,
11264
+ // nodeP,
11265
+ // $container,
11266
+ // paramsP,
11267
+ // parent_infoP,
11268
+ // jobNoP,
11269
+ // keyP,
11270
+ // parent_nodeP,
11271
+ // new_key,
11272
+ // $elm,
11273
+ // {
11274
+ // key: key,
11275
+ // // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
11276
+ // value: await get_attr_value(key),
11277
+ // },
11278
+ // is_init,
11279
+ // refreshed_ds,
11280
+ // );
11281
+
11282
+ // _ret = _.assignIn(_ret, ret);
11283
+ // }
11284
+
11285
+ // // EXP for
11286
+
11287
+ // for await (const [key, val] of Object.entries(nodeP.attributes)) {
11288
+ // if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
11289
+
11290
+ // const attr = key.split('xu-exp:')[1];
11291
+
11292
+ // if (!attr) {
11293
+ // continue;
11294
+ // }
11295
+
11296
+ // if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
11297
+
11298
+ // if (done_exp.includes(key)) {
11299
+ // continue;
11300
+ // }
11301
+ // let ret = await func.UI.screen.execute_xu_functions(
11302
+ // SESSION_ID,
11303
+ // is_skeleton,
11304
+ // $root_container,
11305
+ // nodeP,
11306
+ // $container,
11307
+ // paramsP,
11308
+ // parent_infoP,
11309
+ // jobNoP,
11310
+ // keyP,
11311
+ // parent_nodeP,
11312
+ // 'xu-exp',
11313
+ // $elm,
11314
+ // {
11315
+ // key: attr,
11316
+ // value: val,
11317
+ // },
11318
+ // true,
11319
+ // refreshed_ds,
11320
+ // );
11321
+ // _ret = _.assignIn(_ret, ret);
11322
+ // }
11323
+
11324
+ // // AFTER
11325
+
11326
+ // for await (const [key, attr] of Object.entries(glb.run_xu_after)) {
11327
+ // if ($container?.data()?.xuData?.pending_to_delete) break;
11328
+
11329
+ // if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
11330
+
11331
+ // if (!nodeP.attributes || !nodeP.attributes[attr] & !nodeP.attributes[`xu-exp:${attr}`]) continue;
11332
+
11333
+ // let ret = await func.UI.screen.execute_xu_functions(
11334
+ // SESSION_ID,
11335
+ // is_skeleton,
11336
+ // $root_container,
11337
+ // nodeP,
11338
+ // $container,
11339
+ // paramsP,
11340
+ // parent_infoP,
11341
+ // jobNoP,
11342
+ // keyP,
11343
+ // parent_nodeP,
11344
+ // attr,
11345
+ // $elm,
11346
+ // {
11347
+ // key: attr,
11348
+ // // value: (await get_xuExp(attr)) || func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]),
11349
+ // value: await get_attr_value(attr),
11350
+ // },
11351
+ // is_init,
11352
+ // refreshed_ds,
11353
+ // );
11354
+ // _ret = _.assignIn(_ret, ret);
11355
+ // }
11356
+
11357
+ // // REGISTER EVENTS ATTRIBUTES
11358
+
11359
+ // for await (const [key, val] of Object.entries(nodeP.attributes)) {
11360
+ // if ($container?.data()?.xuData?.pending_to_delete) break;
11361
+ // if (!glb.html5_events_handler.includes(key)) break;
11362
+ // // $elm.attr(key, await get_xuExp(key)) || val;
11363
+ // $elm.attr(key, await get_xuExp(key)) || val;
11364
+ // }
11365
+
11366
+ // return _ret;
11367
+ // };
11368
+
11046
11369
  func.UI.screen.set_attributes_new = async function (SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $elm, is_init, execute_attributes = [], refreshed_ds) {
11047
- var done_exp = [];
11370
+ const done_exp = new Set(); // Use Set for O(1) lookups instead of array
11048
11371
 
11049
11372
  const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
11050
11373
  if (!_ds) return { abort: true };
11051
11374
 
11375
+ // Early return if not an element or no attributes
11376
+ if (nodeP.type !== 'element' || !nodeP.attributes) return {};
11377
+
11378
+ // Cache frequently accessed values
11379
+ const nodeAttrs = nodeP.attributes;
11380
+ const elmData = $elm.data();
11381
+ const xuData = elmData.xuData;
11382
+ const containerData = $container?.data();
11383
+ const containerXuData = containerData?.xuData;
11384
+
11052
11385
  const get_attr_value = async function (key) {
11053
- let ret = func.UI.screen.fix_val_defaults(key, nodeP.attributes[key]);
11054
- if (nodeP?.attributes?.hasOwnProperty(`xu-exp:${key}`)) {
11055
- ret = await get_xuExp(key);
11386
+ const expKey = `xu-exp:${key}`;
11387
+ if (nodeAttrs.hasOwnProperty(expKey)) {
11388
+ return await get_xuExp(key);
11056
11389
  }
11057
- return ret;
11390
+ return func.UI.screen.fix_val_defaults(key, nodeAttrs[key]);
11058
11391
  };
11059
11392
 
11060
11393
  const get_xuExp = async function (attrib) {
11061
11394
  if (is_skeleton) return;
11395
+
11396
+ const attr = `xu-exp:${attrib}`;
11397
+ if (!nodeAttrs.hasOwnProperty(attr)) return;
11398
+
11062
11399
  if (glb.new_xu_render) {
11063
- let _xuData = $elm.data().xuData;
11064
- if (!_xuData.attr_exp_info) {
11065
- _xuData.attr_exp_info = {};
11400
+ if (!xuData.attr_exp_info) {
11401
+ xuData.attr_exp_info = {};
11066
11402
  }
11067
11403
  }
11068
- const attr = `xu-exp:${attrib}`;
11069
11404
 
11070
- if (!nodeP?.attributes?.hasOwnProperty(attr)) return;
11071
- // const attr = `xu-exp-${attrib}`;
11072
- var exp = nodeP.attributes[attr];
11073
- // if (!value) return func.UI.screen.fix_val_defaults(attrib, exp || nodeP.attributes[attrib]);
11405
+ const exp = nodeAttrs[attr];
11406
+ const res = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId);
11074
11407
 
11075
- var res = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId);
11076
11408
  if (glb.new_xu_render) {
11077
- _xuData.attr_exp_info[attrib] = res;
11409
+ xuData.attr_exp_info[attrib] = res;
11078
11410
  }
11079
- // nodeP.attributes[attr] = value; //{ value: value, res: res };
11080
- done_exp.push(attr);
11081
- return res.result; //func.UI.screen.fix_val_defaults(attrib, res.result);
11082
- };
11083
11411
 
11084
- var _ret = {};
11085
- if (nodeP.type !== 'element' || !nodeP.attributes) return _ret;
11412
+ done_exp.add(attr);
11413
+ return res.result;
11414
+ };
11086
11415
 
11087
- for (let [key, val] of Object.entries(nodeP.attributes)) {
11088
- // REMOVE STATIC ATTRIBUTES IF EXP EXISTS to avoid dup
11089
- if (key.substring(0, 6) === 'xu-exp') {
11416
+ // Create Sets for O(1) lookups
11417
+ const html5EventsSet = new Set(glb.html5_events_handler);
11418
+ const executeAttrsSet = new Set(execute_attributes);
11419
+ const solidAttrsSet = new Set(glb.solid_attributes);
11420
+ const abbreviationsSet = new Set(glb.attr_abbreviations_arr);
11421
+ const runXuBeforeSet = new Set(Object.values(glb.run_xu_before));
11422
+ const runXuAfterSet = new Set(Object.values(glb.run_xu_after));
11423
+
11424
+ // Process attributes in a single pass where possible
11425
+ const attrsToDelete = [];
11426
+ const xuOnAttrs = {};
11427
+
11428
+ for (const [key, val] of Object.entries(nodeAttrs)) {
11429
+ // Handle xu-exp attributes
11430
+ if (key.startsWith('xu-exp:')) {
11090
11431
  if (_.isEmpty(val)) {
11091
- delete nodeP.attributes[key];
11432
+ attrsToDelete.push(key);
11092
11433
  continue;
11093
11434
  }
11094
- const clean_key = key.split(':')[1];
11095
- if (typeof nodeP.attributes[clean_key] !== 'undefined') {
11096
- delete nodeP.attributes[clean_key];
11435
+ const clean_key = key.slice(7); // 'xu-exp:'.length = 7
11436
+ if (nodeAttrs[clean_key] !== undefined) {
11437
+ attrsToDelete.push(clean_key);
11097
11438
  }
11098
11439
  }
11099
- // FIX abbreviations
11100
- if (glb.attr_abbreviations_arr.includes(key)) {
11101
- nodeP.attributes[`xu-on:${key.substring(3)}`] = [
11440
+ // Handle abbreviations
11441
+ else if (abbreviationsSet.has(key)) {
11442
+ xuOnAttrs[`xu-on:${key.slice(3)}`] = [
11102
11443
  {
11103
11444
  handler: 'custom',
11104
11445
  props: {},
@@ -11115,257 +11456,131 @@ func.UI.screen.set_attributes_new = async function (SESSION_ID, is_skeleton, $ro
11115
11456
  ],
11116
11457
  },
11117
11458
  ];
11118
- delete nodeP.attributes[key];
11459
+ attrsToDelete.push(key);
11119
11460
  }
11120
11461
  }
11121
11462
 
11122
- for (let [key, val] of Object.entries(nodeP.attributes)) {
11123
- // FIX STATIC DEFAULTS
11124
- val = func.UI.screen.fix_val_defaults(key, val);
11463
+ // Delete marked attributes
11464
+ for (const key of attrsToDelete) {
11465
+ delete nodeAttrs[key];
11466
+ }
11125
11467
 
11126
- // REMOVE UNDEFINED or NULL ATTRIBUTES
11127
- if (typeof val === 'undefined' || val === null) {
11128
- delete nodeP.attributes[key];
11129
- }
11468
+ // Add xu-on attributes
11469
+ Object.assign(nodeAttrs, xuOnAttrs);
11130
11470
 
11131
- // REMOVE ATTRIBUTES WITH EMPTY VALUES
11132
- if (glb.solid_attributes.includes(key) && !val) {
11133
- delete nodeP.attributes[key];
11471
+ // Clean up attributes
11472
+ for (const [key, val] of Object.entries(nodeAttrs)) {
11473
+ const fixedVal = func.UI.screen.fix_val_defaults(key, val);
11474
+
11475
+ if (fixedVal === undefined || fixedVal === null) {
11476
+ delete nodeAttrs[key];
11477
+ } else if (solidAttrsSet.has(key) && !fixedVal) {
11478
+ delete nodeAttrs[key];
11479
+ } else {
11480
+ nodeAttrs[key] = fixedVal;
11134
11481
  }
11135
11482
  }
11136
11483
 
11484
+ const _ret = {};
11485
+
11486
+ // Helper to check abort condition
11487
+ const shouldAbort = () => _ret.abort || containerXuData?.pending_to_delete;
11488
+
11137
11489
  // XU-ATTRS
11138
- if (nodeP?.attributes?.['xu-attrs'] || nodeP?.attributes?.['xu-exp:xu-attrs']) {
11490
+ if (nodeAttrs['xu-attrs'] || nodeAttrs['xu-exp:xu-attrs']) {
11139
11491
  const attr = 'xu-attrs';
11140
- let ret = await func.UI.screen.execute_xu_functions(
11141
- SESSION_ID,
11142
- is_skeleton,
11143
- $root_container,
11144
- nodeP,
11145
- $container,
11146
- paramsP,
11147
- parent_infoP,
11148
- jobNoP,
11149
- keyP,
11150
- parent_nodeP,
11151
- attr,
11152
- $elm,
11153
- {
11154
- key: attr,
11155
- value: await get_attr_value(attr),
11156
- },
11157
- is_init,
11158
- );
11492
+ await func.UI.screen.execute_xu_functions(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, attr, $elm, { key: attr, value: await get_attr_value(attr) }, is_init);
11159
11493
  }
11160
11494
 
11161
11495
  // BEFORE
11162
- if (!_.isEmpty(nodeP.attributes)) {
11163
- for await (const [key, attr] of Object.entries(glb.run_xu_before)) {
11164
- if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
11165
- if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) {
11166
- continue;
11167
- }
11496
+ if (!_.isEmpty(nodeAttrs)) {
11497
+ for (const [key, attr] of Object.entries(glb.run_xu_before)) {
11498
+ if (shouldAbort()) break;
11499
+ if (html5EventsSet.has(attr) || executeAttrsSet.has(attr)) continue;
11168
11500
 
11169
- if (!nodeP?.attributes?.hasOwnProperty(attr) && !nodeP?.attributes?.hasOwnProperty(`xu-exp:${attr}`)) {
11170
- continue;
11171
- }
11172
-
11173
- if (!nodeP.attributes[`xu-exp:${attr}`] && nodeP?.attributes?.hasOwnProperty(attr) && typeof func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]) === 'undefined') {
11174
- continue;
11175
- }
11501
+ const expKey = `xu-exp:${attr}`;
11502
+ if (!nodeAttrs.hasOwnProperty(attr) && !nodeAttrs.hasOwnProperty(expKey)) continue;
11503
+ if (!nodeAttrs[expKey] && nodeAttrs.hasOwnProperty(attr) && func.UI.screen.fix_val_defaults(attr, nodeAttrs[attr]) === undefined) continue;
11176
11504
 
11177
- let ret = await func.UI.screen.execute_xu_functions(
11178
- SESSION_ID,
11179
- is_skeleton,
11180
- $root_container,
11181
- nodeP,
11182
- $container,
11183
- paramsP,
11184
- parent_infoP,
11185
- jobNoP,
11186
- keyP,
11187
- parent_nodeP,
11188
- attr,
11189
- $elm,
11190
- {
11191
- key: attr,
11192
-
11193
- value: await get_attr_value(attr),
11194
- },
11195
- is_init,
11196
- );
11197
- _ret = _.assignIn(_ret, ret);
11505
+ const ret = await func.UI.screen.execute_xu_functions(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, attr, $elm, { key: attr, value: await get_attr_value(attr) }, is_init);
11506
+ Object.assign(_ret, ret);
11198
11507
  }
11199
11508
  }
11200
11509
 
11201
- // ALL
11510
+ // ALL - Process attributes
11511
+ const isXuPanel = nodeP.tagName === 'xu-panel';
11512
+ const isXuTeleport = nodeP.tagName === 'xu-teleport';
11513
+ const elmElement = $elm.get(0);
11202
11514
 
11203
- for await (const [key, val] of Object.entries(nodeP.attributes)) {
11204
- if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
11205
- if (glb.html5_events_handler.includes(key) || execute_attributes.includes(key)) {
11206
- continue;
11207
- }
11515
+ for (const [key, val] of Object.entries(nodeAttrs)) {
11516
+ if (shouldAbort()) break;
11517
+ if (html5EventsSet.has(key) || executeAttrsSet.has(key)) continue;
11208
11518
 
11209
- const new_key = key.split(':')[0]; // break expression
11210
- if (
11211
- nodeP.tagName !== 'xu-panel' &&
11212
- nodeP.tagName !== 'xu-teleport' && // nodeP.tagName.substr(0, 3) !== "xu-" &&
11213
- (new_key.substr(0, 2) !== 'xu' || new_key.substr(2, 1) !== '-')
11214
- ) {
11215
- // handle common html attributes
11519
+ const colonIndex = key.indexOf(':');
11520
+ const new_key = colonIndex > -1 ? key.slice(0, colonIndex) : key;
11521
+
11522
+ if (!isXuPanel && !isXuTeleport && (!new_key.startsWith('xu-') || new_key.length < 3 || new_key[2] !== '-')) {
11216
11523
  try {
11217
- $elm.get(0).setAttribute(key, val);
11524
+ elmElement.setAttribute(key, val);
11218
11525
  } catch (err) {
11219
11526
  console.error(err.message);
11220
11527
  }
11221
-
11222
11528
  continue;
11223
11529
  }
11224
- // handle xu attributes
11225
- try {
11226
- if ($elm?.data()?.xuAttributes) {
11227
- // in some cases xu data delete in purpose when refreshing the screen
11228
- $elm.data().xuAttributes[key] = val;
11229
- }
11230
- } catch (error) {
11231
- debugger;
11232
- console.error(error);
11530
+
11531
+ // Store xu attributes
11532
+ if (elmData.xuAttributes) {
11533
+ elmData.xuAttributes[key] = val;
11233
11534
  }
11234
11535
 
11235
- if (new_key === 'xu-exp' || nodeP.attributes['xu-exp:' + new_key] || glb.run_xu_before.includes(new_key) || glb.run_xu_after.includes(new_key)) {
11536
+ const expKey = `xu-exp:${new_key}`;
11537
+ if (new_key === 'xu-exp' || nodeAttrs[expKey] || runXuBeforeSet.has(new_key) || runXuAfterSet.has(new_key)) {
11236
11538
  continue;
11237
11539
  }
11238
11540
 
11239
11541
  if (new_key === 'xu-on') {
11240
- let ret = await func.UI.screen.execute_xu_functions(
11241
- SESSION_ID,
11242
- is_skeleton,
11243
- $root_container,
11244
- nodeP,
11245
- $container,
11246
- paramsP,
11247
- parent_infoP,
11248
- jobNoP,
11249
- keyP,
11250
- parent_nodeP,
11251
- 'xu-on',
11252
- $elm,
11253
- {
11254
- key: key,
11255
- // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
11256
- value: await get_attr_value(key),
11257
- },
11258
- is_init,
11259
- refreshed_ds,
11260
- );
11261
- _ret = _.assignIn(_ret, ret);
11542
+ const ret = await func.UI.screen.execute_xu_functions(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, 'xu-on', $elm, { key: key, value: await get_attr_value(key) }, is_init, refreshed_ds);
11543
+ Object.assign(_ret, ret);
11262
11544
  continue;
11263
11545
  }
11264
11546
 
11265
- let ret = await func.UI.screen.execute_xu_functions(
11266
- SESSION_ID,
11267
- is_skeleton,
11268
- $root_container,
11269
- nodeP,
11270
- $container,
11271
- paramsP,
11272
- parent_infoP,
11273
- jobNoP,
11274
- keyP,
11275
- parent_nodeP,
11276
- new_key,
11277
- $elm,
11278
- {
11279
- key: key,
11280
- // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
11281
- value: await get_attr_value(key),
11282
- },
11283
- is_init,
11284
- refreshed_ds,
11285
- );
11286
-
11287
- _ret = _.assignIn(_ret, ret);
11547
+ const ret = await func.UI.screen.execute_xu_functions(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, new_key, $elm, { key: key, value: await get_attr_value(key) }, is_init, refreshed_ds);
11548
+ Object.assign(_ret, ret);
11288
11549
  }
11289
11550
 
11290
- // EXP for
11291
-
11292
- for await (const [key, val] of Object.entries(nodeP.attributes)) {
11293
- if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
11551
+ // EXP - Process expressions
11552
+ for (const [key, val] of Object.entries(nodeAttrs)) {
11553
+ if (shouldAbort()) break;
11294
11554
 
11295
- const attr = key.split('xu-exp:')[1];
11296
-
11297
- if (!attr) {
11298
- continue;
11299
- }
11555
+ if (!key.startsWith('xu-exp:')) continue;
11556
+ const attr = key.slice(7);
11300
11557
 
11301
- if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
11558
+ if (html5EventsSet.has(attr) || executeAttrsSet.has(attr)) continue;
11559
+ if (done_exp.has(key)) continue;
11302
11560
 
11303
- if (done_exp.includes(key)) {
11304
- continue;
11305
- }
11306
- let ret = await func.UI.screen.execute_xu_functions(
11307
- SESSION_ID,
11308
- is_skeleton,
11309
- $root_container,
11310
- nodeP,
11311
- $container,
11312
- paramsP,
11313
- parent_infoP,
11314
- jobNoP,
11315
- keyP,
11316
- parent_nodeP,
11317
- 'xu-exp',
11318
- $elm,
11319
- {
11320
- key: attr,
11321
- value: val,
11322
- },
11323
- true,
11324
- refreshed_ds,
11325
- );
11326
- _ret = _.assignIn(_ret, ret);
11561
+ const ret = await func.UI.screen.execute_xu_functions(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, 'xu-exp', $elm, { key: attr, value: val }, true, refreshed_ds);
11562
+ Object.assign(_ret, ret);
11327
11563
  }
11328
11564
 
11329
11565
  // AFTER
11566
+ for (const [key, attr] of Object.entries(glb.run_xu_after)) {
11567
+ if (containerXuData?.pending_to_delete) break;
11568
+ if (html5EventsSet.has(attr) || executeAttrsSet.has(attr)) continue;
11330
11569
 
11331
- for await (const [key, attr] of Object.entries(glb.run_xu_after)) {
11332
- if ($container?.data()?.xuData?.pending_to_delete) break;
11333
-
11334
- if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
11335
-
11336
- if (!nodeP.attributes || !nodeP.attributes[attr] & !nodeP.attributes[`xu-exp:${attr}`]) continue;
11570
+ const expKey = `xu-exp:${attr}`;
11571
+ if (!nodeAttrs || (!nodeAttrs[attr] && !nodeAttrs[expKey])) continue;
11337
11572
 
11338
- let ret = await func.UI.screen.execute_xu_functions(
11339
- SESSION_ID,
11340
- is_skeleton,
11341
- $root_container,
11342
- nodeP,
11343
- $container,
11344
- paramsP,
11345
- parent_infoP,
11346
- jobNoP,
11347
- keyP,
11348
- parent_nodeP,
11349
- attr,
11350
- $elm,
11351
- {
11352
- key: attr,
11353
- // value: (await get_xuExp(attr)) || func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]),
11354
- value: await get_attr_value(attr),
11355
- },
11356
- is_init,
11357
- refreshed_ds,
11358
- );
11359
- _ret = _.assignIn(_ret, ret);
11573
+ const ret = await func.UI.screen.execute_xu_functions(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, attr, $elm, { key: attr, value: await get_attr_value(attr) }, is_init, refreshed_ds);
11574
+ Object.assign(_ret, ret);
11360
11575
  }
11361
11576
 
11362
11577
  // REGISTER EVENTS ATTRIBUTES
11578
+ for (const [key, val] of Object.entries(nodeAttrs)) {
11579
+ if (containerXuData?.pending_to_delete) break;
11580
+ if (!html5EventsSet.has(key)) break;
11363
11581
 
11364
- for await (const [key, val] of Object.entries(nodeP.attributes)) {
11365
- if ($container?.data()?.xuData?.pending_to_delete) break;
11366
- if (!glb.html5_events_handler.includes(key)) break;
11367
- // $elm.attr(key, await get_xuExp(key)) || val;
11368
- $elm.attr(key, await get_xuExp(key)) || val;
11582
+ const expVal = await get_xuExp(key);
11583
+ $elm.attr(key, expVal || val);
11369
11584
  }
11370
11585
 
11371
11586
  return _ret;
@@ -11430,7 +11645,7 @@ func.UI.screen.panel_post_render_handler = async function (
11430
11645
 
11431
11646
  const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP) {
11432
11647
  // const _paramsP = _.cloneDeep(paramsP);
11433
- const _paramsP = klona(paramsP);
11648
+ const _paramsP = klona.klona(paramsP);
11434
11649
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
11435
11650
 
11436
11651
  const currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
@@ -11444,7 +11659,7 @@ const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP
11444
11659
 
11445
11660
  func.UI.screen.create_container = async function (SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, classP, elem_propP, div_typeP, $appendToP, attr_str, is_placeholder) {
11446
11661
  // const _paramsP = _.cloneDeep(paramsP);
11447
- const _paramsP = klona(paramsP);
11662
+ const _paramsP = klona.klona(paramsP);
11448
11663
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
11449
11664
  var $appendTo = $container;
11450
11665
  if ($appendToP) $appendTo = $appendToP;
@@ -12462,7 +12677,7 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
12462
12677
  });
12463
12678
  $.each($div.data().xuAttributes, function (key, val) {
12464
12679
  // $container.data().xuAttributes[key] = _.cloneDeep(val);
12465
- $container.data().xuAttributes[key] = klona(val);
12680
+ $container.data().xuAttributes[key] = klona.klona(val);
12466
12681
  });
12467
12682
 
12468
12683
  return await render_screen_type($div);