@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.
@@ -24677,11 +24677,6 @@ func.common.get_data_from_websocket = async function (SESSION_ID, serviceP, data
24677
24677
  };
24678
24678
 
24679
24679
  func.common.sha256 = async function (inputString) {
24680
- // const enc = new TextEncoder();
24681
- // const buf = await crypto.subtle.digest('SHA-256', enc.encode(str));
24682
- // const bytes = new Uint8Array(buf);
24683
- // return [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('');
24684
-
24685
24680
  // 1. Create a hash buffer from the input string using SHA-256.
24686
24681
  // This part remains the same as it provides a strong, unique cryptographic starting point.
24687
24682
  const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(inputString));
@@ -28583,7 +28578,7 @@ func.datasource.prepare = async function (SESSION_ID, prog_id, dataSourceNoP, pa
28583
28578
  _ds.data_feed = {};
28584
28579
 
28585
28580
  // _ds.v.old_dataSource = _.cloneDeep(_ds);
28586
- _ds.v.old_dataSource = klona(_ds);
28581
+ _ds.v.old_dataSource = klona.klona(_ds);
28587
28582
  } catch (err) {
28588
28583
  console.error('function: init_existing_dataSource - error');
28589
28584
  return;
@@ -30214,11 +30209,11 @@ func.datasource.update = async function (SESSION_ID, datasource_changes, update_
30214
30209
  }
30215
30210
 
30216
30211
  // await func.UI.screen.refresh_xu_attributes(SESSION_ID, _.cloneDeep(fields_changed), null, null, findMin(datasource_changed), avoid_xu_for_refresh, trigger);
30217
- await func.UI.screen.refresh_xu_attributes(SESSION_ID, klona(fields_changed), null, null, findMin(datasource_changed), avoid_xu_for_refresh, trigger);
30212
+ await func.UI.screen.refresh_xu_attributes(SESSION_ID, klona.klona(fields_changed), null, null, findMin(datasource_changed), avoid_xu_for_refresh, trigger);
30218
30213
  // await removed from the below function cause to dead lock Mar 3 25
30219
30214
  await func.UI.screen.refresh_screen(
30220
30215
  SESSION_ID,
30221
- klona(fields_changed), // _.cloneDeep(fields_changed),
30216
+ klona.klona(fields_changed), // _.cloneDeep(fields_changed),
30222
30217
  null,
30223
30218
  datasource_changed[0], // refresh the current datasource only
30224
30219
  );
@@ -30870,7 +30865,7 @@ func.datasource.set_VIEW_data = async function (SESSION_ID, args, _ds) {
30870
30865
  _ds.viewEventExec_arr = {};
30871
30866
 
30872
30867
  // var view = _.cloneDeep(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
30873
- var view = klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
30868
+ var view = klona.klona(await func.utils.VIEWS_OBJ.get(SESSION_ID, args.prog_id));
30874
30869
 
30875
30870
  _ds.v.dataSourceSrcType = view.dataSourceSrcType;
30876
30871
 
@@ -31040,7 +31035,7 @@ func.UI.screen.init = async function (SESSION_ID, prog_id, sourceScreenP, callin
31040
31035
  let _session = SESSION_OBJ[SESSION_ID];
31041
31036
 
31042
31037
  // const screenInfo = _.cloneDeep(screen_ret);
31043
- const screenInfo = klona(screen_ret);
31038
+ const screenInfo = klona.klona(screen_ret);
31044
31039
 
31045
31040
  var screen_type = source_functionP?.split('_')?.[1]; //|| (is_panelP && "panel");
31046
31041
 
@@ -31185,7 +31180,7 @@ func.UI.screen.init = async function (SESSION_ID, prog_id, sourceScreenP, callin
31185
31180
  }
31186
31181
  var node;
31187
31182
  // node = _.cloneDeep(viewDoc.progUi);
31188
- node = klona(viewDoc.progUi);
31183
+ node = klona.klona(viewDoc.progUi);
31189
31184
  if (!node.length) return console.warn('ui node empty');
31190
31185
  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);
31191
31186
 
@@ -31752,7 +31747,7 @@ func.UI.screen.refresh_screen = async function (SESSION_ID, fields_changed_arr,
31752
31747
  const new_$div = await func.UI.screen.render_ui_tree(
31753
31748
  SESSION_ID,
31754
31749
  $elm, // the wrapper
31755
- klona($elm.data().xuData.node), //_.cloneDeep($elm.data().xuData.node), // the xu-panel node
31750
+ klona.klona($elm.data().xuData.node), //_.cloneDeep($elm.data().xuData.node), // the xu-panel node
31756
31751
  {},
31757
31752
  elm_data.xuData.paramsP, // the wrapper params
31758
31753
  null,
@@ -32716,7 +32711,7 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32716
32711
  reference_source_obj,
32717
32712
  };
32718
32713
  // let _parent_info = _.cloneDeep(parent_infoP) || {};
32719
- let _parent_info = klona(parent_infoP) || {};
32714
+ let _parent_info = klona.klona(parent_infoP) || {};
32720
32715
  _parent_info.iterate_info = iterate_info;
32721
32716
 
32722
32717
  const $divP = await func.UI.screen.render_ui_tree(
@@ -33044,62 +33039,408 @@ func.UI.screen.fix_val_defaults = function (key, val) {
33044
33039
  return ret;
33045
33040
  };
33046
33041
 
33042
+ // 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) {
33043
+ // var done_exp = [];
33044
+
33045
+ // const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
33046
+ // if (!_ds) return { abort: true };
33047
+
33048
+ // const get_attr_value = async function (key) {
33049
+ // let ret = func.UI.screen.fix_val_defaults(key, nodeP.attributes[key]);
33050
+ // if (nodeP?.attributes?.hasOwnProperty(`xu-exp:${key}`)) {
33051
+ // ret = await get_xuExp(key);
33052
+ // }
33053
+ // return ret;
33054
+ // };
33055
+
33056
+ // const get_xuExp = async function (attrib) {
33057
+ // if (is_skeleton) return;
33058
+ // if (glb.new_xu_render) {
33059
+ // let _xuData = $elm.data().xuData;
33060
+ // if (!_xuData.attr_exp_info) {
33061
+ // _xuData.attr_exp_info = {};
33062
+ // }
33063
+ // }
33064
+ // const attr = `xu-exp:${attrib}`;
33065
+
33066
+ // if (!nodeP?.attributes?.hasOwnProperty(attr)) return;
33067
+ // // const attr = `xu-exp-${attrib}`;
33068
+ // var exp = nodeP.attributes[attr];
33069
+ // // if (!value) return func.UI.screen.fix_val_defaults(attrib, exp || nodeP.attributes[attrib]);
33070
+
33071
+ // var res = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId);
33072
+ // if (glb.new_xu_render) {
33073
+ // _xuData.attr_exp_info[attrib] = res;
33074
+ // }
33075
+ // // nodeP.attributes[attr] = value; //{ value: value, res: res };
33076
+ // done_exp.push(attr);
33077
+ // return res.result; //func.UI.screen.fix_val_defaults(attrib, res.result);
33078
+ // };
33079
+
33080
+ // var _ret = {};
33081
+ // if (nodeP.type !== 'element' || !nodeP.attributes) return _ret;
33082
+
33083
+ // for (let [key, val] of Object.entries(nodeP.attributes)) {
33084
+ // // REMOVE STATIC ATTRIBUTES IF EXP EXISTS to avoid dup
33085
+ // if (key.substring(0, 6) === 'xu-exp') {
33086
+ // if (_.isEmpty(val)) {
33087
+ // delete nodeP.attributes[key];
33088
+ // continue;
33089
+ // }
33090
+ // const clean_key = key.split(':')[1];
33091
+ // if (typeof nodeP.attributes[clean_key] !== 'undefined') {
33092
+ // delete nodeP.attributes[clean_key];
33093
+ // }
33094
+ // }
33095
+ // // FIX abbreviations
33096
+ // if (glb.attr_abbreviations_arr.includes(key)) {
33097
+ // nodeP.attributes[`xu-on:${key.substring(3)}`] = [
33098
+ // {
33099
+ // handler: 'custom',
33100
+ // props: {},
33101
+ // event: [
33102
+ // {
33103
+ // id: Date.now(),
33104
+ // data: {
33105
+ // action: 'update',
33106
+ // name: { value: val },
33107
+ // enabled: true,
33108
+ // },
33109
+ // props: {},
33110
+ // },
33111
+ // ],
33112
+ // },
33113
+ // ];
33114
+ // delete nodeP.attributes[key];
33115
+ // }
33116
+ // }
33117
+
33118
+ // for (let [key, val] of Object.entries(nodeP.attributes)) {
33119
+ // // FIX STATIC DEFAULTS
33120
+ // val = func.UI.screen.fix_val_defaults(key, val);
33121
+
33122
+ // // REMOVE UNDEFINED or NULL ATTRIBUTES
33123
+ // if (typeof val === 'undefined' || val === null) {
33124
+ // delete nodeP.attributes[key];
33125
+ // }
33126
+
33127
+ // // REMOVE ATTRIBUTES WITH EMPTY VALUES
33128
+ // if (glb.solid_attributes.includes(key) && !val) {
33129
+ // delete nodeP.attributes[key];
33130
+ // }
33131
+ // }
33132
+
33133
+ // // XU-ATTRS
33134
+ // if (nodeP?.attributes?.['xu-attrs'] || nodeP?.attributes?.['xu-exp:xu-attrs']) {
33135
+ // const attr = 'xu-attrs';
33136
+ // let ret = await func.UI.screen.execute_xu_functions(
33137
+ // SESSION_ID,
33138
+ // is_skeleton,
33139
+ // $root_container,
33140
+ // nodeP,
33141
+ // $container,
33142
+ // paramsP,
33143
+ // parent_infoP,
33144
+ // jobNoP,
33145
+ // keyP,
33146
+ // parent_nodeP,
33147
+ // attr,
33148
+ // $elm,
33149
+ // {
33150
+ // key: attr,
33151
+ // value: await get_attr_value(attr),
33152
+ // },
33153
+ // is_init,
33154
+ // );
33155
+ // }
33156
+
33157
+ // // BEFORE
33158
+ // if (!_.isEmpty(nodeP.attributes)) {
33159
+ // for await (const [key, attr] of Object.entries(glb.run_xu_before)) {
33160
+ // if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
33161
+ // if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) {
33162
+ // continue;
33163
+ // }
33164
+
33165
+ // if (!nodeP?.attributes?.hasOwnProperty(attr) && !nodeP?.attributes?.hasOwnProperty(`xu-exp:${attr}`)) {
33166
+ // continue;
33167
+ // }
33168
+
33169
+ // if (!nodeP.attributes[`xu-exp:${attr}`] && nodeP?.attributes?.hasOwnProperty(attr) && typeof func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]) === 'undefined') {
33170
+ // continue;
33171
+ // }
33172
+
33173
+ // let ret = await func.UI.screen.execute_xu_functions(
33174
+ // SESSION_ID,
33175
+ // is_skeleton,
33176
+ // $root_container,
33177
+ // nodeP,
33178
+ // $container,
33179
+ // paramsP,
33180
+ // parent_infoP,
33181
+ // jobNoP,
33182
+ // keyP,
33183
+ // parent_nodeP,
33184
+ // attr,
33185
+ // $elm,
33186
+ // {
33187
+ // key: attr,
33188
+
33189
+ // value: await get_attr_value(attr),
33190
+ // },
33191
+ // is_init,
33192
+ // );
33193
+ // _ret = _.assignIn(_ret, ret);
33194
+ // }
33195
+ // }
33196
+
33197
+ // // ALL
33198
+
33199
+ // for await (const [key, val] of Object.entries(nodeP.attributes)) {
33200
+ // if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
33201
+ // if (glb.html5_events_handler.includes(key) || execute_attributes.includes(key)) {
33202
+ // continue;
33203
+ // }
33204
+
33205
+ // const new_key = key.split(':')[0]; // break expression
33206
+ // if (
33207
+ // nodeP.tagName !== 'xu-panel' &&
33208
+ // nodeP.tagName !== 'xu-teleport' && // nodeP.tagName.substr(0, 3) !== "xu-" &&
33209
+ // (new_key.substr(0, 2) !== 'xu' || new_key.substr(2, 1) !== '-')
33210
+ // ) {
33211
+ // // handle common html attributes
33212
+ // try {
33213
+ // $elm.get(0).setAttribute(key, val);
33214
+ // } catch (err) {
33215
+ // console.error(err.message);
33216
+ // }
33217
+
33218
+ // continue;
33219
+ // }
33220
+ // // handle xu attributes
33221
+ // try {
33222
+ // if ($elm?.data()?.xuAttributes) {
33223
+ // // in some cases xu data delete in purpose when refreshing the screen
33224
+ // $elm.data().xuAttributes[key] = val;
33225
+ // }
33226
+ // } catch (error) {
33227
+ // debugger;
33228
+ // console.error(error);
33229
+ // }
33230
+
33231
+ // 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)) {
33232
+ // continue;
33233
+ // }
33234
+
33235
+ // if (new_key === 'xu-on') {
33236
+ // let ret = await func.UI.screen.execute_xu_functions(
33237
+ // SESSION_ID,
33238
+ // is_skeleton,
33239
+ // $root_container,
33240
+ // nodeP,
33241
+ // $container,
33242
+ // paramsP,
33243
+ // parent_infoP,
33244
+ // jobNoP,
33245
+ // keyP,
33246
+ // parent_nodeP,
33247
+ // 'xu-on',
33248
+ // $elm,
33249
+ // {
33250
+ // key: key,
33251
+ // // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
33252
+ // value: await get_attr_value(key),
33253
+ // },
33254
+ // is_init,
33255
+ // refreshed_ds,
33256
+ // );
33257
+ // _ret = _.assignIn(_ret, ret);
33258
+ // continue;
33259
+ // }
33260
+
33261
+ // let ret = await func.UI.screen.execute_xu_functions(
33262
+ // SESSION_ID,
33263
+ // is_skeleton,
33264
+ // $root_container,
33265
+ // nodeP,
33266
+ // $container,
33267
+ // paramsP,
33268
+ // parent_infoP,
33269
+ // jobNoP,
33270
+ // keyP,
33271
+ // parent_nodeP,
33272
+ // new_key,
33273
+ // $elm,
33274
+ // {
33275
+ // key: key,
33276
+ // // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
33277
+ // value: await get_attr_value(key),
33278
+ // },
33279
+ // is_init,
33280
+ // refreshed_ds,
33281
+ // );
33282
+
33283
+ // _ret = _.assignIn(_ret, ret);
33284
+ // }
33285
+
33286
+ // // EXP for
33287
+
33288
+ // for await (const [key, val] of Object.entries(nodeP.attributes)) {
33289
+ // if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
33290
+
33291
+ // const attr = key.split('xu-exp:')[1];
33292
+
33293
+ // if (!attr) {
33294
+ // continue;
33295
+ // }
33296
+
33297
+ // if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
33298
+
33299
+ // if (done_exp.includes(key)) {
33300
+ // continue;
33301
+ // }
33302
+ // let ret = await func.UI.screen.execute_xu_functions(
33303
+ // SESSION_ID,
33304
+ // is_skeleton,
33305
+ // $root_container,
33306
+ // nodeP,
33307
+ // $container,
33308
+ // paramsP,
33309
+ // parent_infoP,
33310
+ // jobNoP,
33311
+ // keyP,
33312
+ // parent_nodeP,
33313
+ // 'xu-exp',
33314
+ // $elm,
33315
+ // {
33316
+ // key: attr,
33317
+ // value: val,
33318
+ // },
33319
+ // true,
33320
+ // refreshed_ds,
33321
+ // );
33322
+ // _ret = _.assignIn(_ret, ret);
33323
+ // }
33324
+
33325
+ // // AFTER
33326
+
33327
+ // for await (const [key, attr] of Object.entries(glb.run_xu_after)) {
33328
+ // if ($container?.data()?.xuData?.pending_to_delete) break;
33329
+
33330
+ // if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
33331
+
33332
+ // if (!nodeP.attributes || !nodeP.attributes[attr] & !nodeP.attributes[`xu-exp:${attr}`]) continue;
33333
+
33334
+ // let ret = await func.UI.screen.execute_xu_functions(
33335
+ // SESSION_ID,
33336
+ // is_skeleton,
33337
+ // $root_container,
33338
+ // nodeP,
33339
+ // $container,
33340
+ // paramsP,
33341
+ // parent_infoP,
33342
+ // jobNoP,
33343
+ // keyP,
33344
+ // parent_nodeP,
33345
+ // attr,
33346
+ // $elm,
33347
+ // {
33348
+ // key: attr,
33349
+ // // value: (await get_xuExp(attr)) || func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]),
33350
+ // value: await get_attr_value(attr),
33351
+ // },
33352
+ // is_init,
33353
+ // refreshed_ds,
33354
+ // );
33355
+ // _ret = _.assignIn(_ret, ret);
33356
+ // }
33357
+
33358
+ // // REGISTER EVENTS ATTRIBUTES
33359
+
33360
+ // for await (const [key, val] of Object.entries(nodeP.attributes)) {
33361
+ // if ($container?.data()?.xuData?.pending_to_delete) break;
33362
+ // if (!glb.html5_events_handler.includes(key)) break;
33363
+ // // $elm.attr(key, await get_xuExp(key)) || val;
33364
+ // $elm.attr(key, await get_xuExp(key)) || val;
33365
+ // }
33366
+
33367
+ // return _ret;
33368
+ // };
33369
+
33047
33370
  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) {
33048
- var done_exp = [];
33371
+ const done_exp = new Set(); // Use Set for O(1) lookups instead of array
33049
33372
 
33050
33373
  const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
33051
33374
  if (!_ds) return { abort: true };
33052
33375
 
33376
+ // Early return if not an element or no attributes
33377
+ if (nodeP.type !== 'element' || !nodeP.attributes) return {};
33378
+
33379
+ // Cache frequently accessed values
33380
+ const nodeAttrs = nodeP.attributes;
33381
+ const elmData = $elm.data();
33382
+ const xuData = elmData.xuData;
33383
+ const containerData = $container?.data();
33384
+ const containerXuData = containerData?.xuData;
33385
+
33053
33386
  const get_attr_value = async function (key) {
33054
- let ret = func.UI.screen.fix_val_defaults(key, nodeP.attributes[key]);
33055
- if (nodeP?.attributes?.hasOwnProperty(`xu-exp:${key}`)) {
33056
- ret = await get_xuExp(key);
33387
+ const expKey = `xu-exp:${key}`;
33388
+ if (nodeAttrs.hasOwnProperty(expKey)) {
33389
+ return await get_xuExp(key);
33057
33390
  }
33058
- return ret;
33391
+ return func.UI.screen.fix_val_defaults(key, nodeAttrs[key]);
33059
33392
  };
33060
33393
 
33061
33394
  const get_xuExp = async function (attrib) {
33062
33395
  if (is_skeleton) return;
33396
+
33397
+ const attr = `xu-exp:${attrib}`;
33398
+ if (!nodeAttrs.hasOwnProperty(attr)) return;
33399
+
33063
33400
  if (glb.new_xu_render) {
33064
- let _xuData = $elm.data().xuData;
33065
- if (!_xuData.attr_exp_info) {
33066
- _xuData.attr_exp_info = {};
33401
+ if (!xuData.attr_exp_info) {
33402
+ xuData.attr_exp_info = {};
33067
33403
  }
33068
33404
  }
33069
- const attr = `xu-exp:${attrib}`;
33070
33405
 
33071
- if (!nodeP?.attributes?.hasOwnProperty(attr)) return;
33072
- // const attr = `xu-exp-${attrib}`;
33073
- var exp = nodeP.attributes[attr];
33074
- // if (!value) return func.UI.screen.fix_val_defaults(attrib, exp || nodeP.attributes[attrib]);
33406
+ const exp = nodeAttrs[attr];
33407
+ const res = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId);
33075
33408
 
33076
- var res = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId);
33077
33409
  if (glb.new_xu_render) {
33078
- _xuData.attr_exp_info[attrib] = res;
33410
+ xuData.attr_exp_info[attrib] = res;
33079
33411
  }
33080
- // nodeP.attributes[attr] = value; //{ value: value, res: res };
33081
- done_exp.push(attr);
33082
- return res.result; //func.UI.screen.fix_val_defaults(attrib, res.result);
33083
- };
33084
33412
 
33085
- var _ret = {};
33086
- if (nodeP.type !== 'element' || !nodeP.attributes) return _ret;
33413
+ done_exp.add(attr);
33414
+ return res.result;
33415
+ };
33087
33416
 
33088
- for (let [key, val] of Object.entries(nodeP.attributes)) {
33089
- // REMOVE STATIC ATTRIBUTES IF EXP EXISTS to avoid dup
33090
- if (key.substring(0, 6) === 'xu-exp') {
33417
+ // Create Sets for O(1) lookups
33418
+ const html5EventsSet = new Set(glb.html5_events_handler);
33419
+ const executeAttrsSet = new Set(execute_attributes);
33420
+ const solidAttrsSet = new Set(glb.solid_attributes);
33421
+ const abbreviationsSet = new Set(glb.attr_abbreviations_arr);
33422
+ const runXuBeforeSet = new Set(Object.values(glb.run_xu_before));
33423
+ const runXuAfterSet = new Set(Object.values(glb.run_xu_after));
33424
+
33425
+ // Process attributes in a single pass where possible
33426
+ const attrsToDelete = [];
33427
+ const xuOnAttrs = {};
33428
+
33429
+ for (const [key, val] of Object.entries(nodeAttrs)) {
33430
+ // Handle xu-exp attributes
33431
+ if (key.startsWith('xu-exp:')) {
33091
33432
  if (_.isEmpty(val)) {
33092
- delete nodeP.attributes[key];
33433
+ attrsToDelete.push(key);
33093
33434
  continue;
33094
33435
  }
33095
- const clean_key = key.split(':')[1];
33096
- if (typeof nodeP.attributes[clean_key] !== 'undefined') {
33097
- delete nodeP.attributes[clean_key];
33436
+ const clean_key = key.slice(7); // 'xu-exp:'.length = 7
33437
+ if (nodeAttrs[clean_key] !== undefined) {
33438
+ attrsToDelete.push(clean_key);
33098
33439
  }
33099
33440
  }
33100
- // FIX abbreviations
33101
- if (glb.attr_abbreviations_arr.includes(key)) {
33102
- nodeP.attributes[`xu-on:${key.substring(3)}`] = [
33441
+ // Handle abbreviations
33442
+ else if (abbreviationsSet.has(key)) {
33443
+ xuOnAttrs[`xu-on:${key.slice(3)}`] = [
33103
33444
  {
33104
33445
  handler: 'custom',
33105
33446
  props: {},
@@ -33116,257 +33457,131 @@ func.UI.screen.set_attributes_new = async function (SESSION_ID, is_skeleton, $ro
33116
33457
  ],
33117
33458
  },
33118
33459
  ];
33119
- delete nodeP.attributes[key];
33460
+ attrsToDelete.push(key);
33120
33461
  }
33121
33462
  }
33122
33463
 
33123
- for (let [key, val] of Object.entries(nodeP.attributes)) {
33124
- // FIX STATIC DEFAULTS
33125
- val = func.UI.screen.fix_val_defaults(key, val);
33464
+ // Delete marked attributes
33465
+ for (const key of attrsToDelete) {
33466
+ delete nodeAttrs[key];
33467
+ }
33126
33468
 
33127
- // REMOVE UNDEFINED or NULL ATTRIBUTES
33128
- if (typeof val === 'undefined' || val === null) {
33129
- delete nodeP.attributes[key];
33130
- }
33469
+ // Add xu-on attributes
33470
+ Object.assign(nodeAttrs, xuOnAttrs);
33471
+
33472
+ // Clean up attributes
33473
+ for (const [key, val] of Object.entries(nodeAttrs)) {
33474
+ const fixedVal = func.UI.screen.fix_val_defaults(key, val);
33131
33475
 
33132
- // REMOVE ATTRIBUTES WITH EMPTY VALUES
33133
- if (glb.solid_attributes.includes(key) && !val) {
33134
- delete nodeP.attributes[key];
33476
+ if (fixedVal === undefined || fixedVal === null) {
33477
+ delete nodeAttrs[key];
33478
+ } else if (solidAttrsSet.has(key) && !fixedVal) {
33479
+ delete nodeAttrs[key];
33480
+ } else {
33481
+ nodeAttrs[key] = fixedVal;
33135
33482
  }
33136
33483
  }
33137
33484
 
33485
+ const _ret = {};
33486
+
33487
+ // Helper to check abort condition
33488
+ const shouldAbort = () => _ret.abort || containerXuData?.pending_to_delete;
33489
+
33138
33490
  // XU-ATTRS
33139
- if (nodeP?.attributes?.['xu-attrs'] || nodeP?.attributes?.['xu-exp:xu-attrs']) {
33491
+ if (nodeAttrs['xu-attrs'] || nodeAttrs['xu-exp:xu-attrs']) {
33140
33492
  const attr = 'xu-attrs';
33141
- let ret = await func.UI.screen.execute_xu_functions(
33142
- SESSION_ID,
33143
- is_skeleton,
33144
- $root_container,
33145
- nodeP,
33146
- $container,
33147
- paramsP,
33148
- parent_infoP,
33149
- jobNoP,
33150
- keyP,
33151
- parent_nodeP,
33152
- attr,
33153
- $elm,
33154
- {
33155
- key: attr,
33156
- value: await get_attr_value(attr),
33157
- },
33158
- is_init,
33159
- );
33493
+ 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);
33160
33494
  }
33161
33495
 
33162
33496
  // BEFORE
33163
- if (!_.isEmpty(nodeP.attributes)) {
33164
- for await (const [key, attr] of Object.entries(glb.run_xu_before)) {
33165
- if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
33166
- if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) {
33167
- continue;
33168
- }
33169
-
33170
- if (!nodeP?.attributes?.hasOwnProperty(attr) && !nodeP?.attributes?.hasOwnProperty(`xu-exp:${attr}`)) {
33171
- continue;
33172
- }
33173
-
33174
- if (!nodeP.attributes[`xu-exp:${attr}`] && nodeP?.attributes?.hasOwnProperty(attr) && typeof func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]) === 'undefined') {
33175
- continue;
33176
- }
33497
+ if (!_.isEmpty(nodeAttrs)) {
33498
+ for (const [key, attr] of Object.entries(glb.run_xu_before)) {
33499
+ if (shouldAbort()) break;
33500
+ if (html5EventsSet.has(attr) || executeAttrsSet.has(attr)) continue;
33177
33501
 
33178
- let ret = await func.UI.screen.execute_xu_functions(
33179
- SESSION_ID,
33180
- is_skeleton,
33181
- $root_container,
33182
- nodeP,
33183
- $container,
33184
- paramsP,
33185
- parent_infoP,
33186
- jobNoP,
33187
- keyP,
33188
- parent_nodeP,
33189
- attr,
33190
- $elm,
33191
- {
33192
- key: attr,
33502
+ const expKey = `xu-exp:${attr}`;
33503
+ if (!nodeAttrs.hasOwnProperty(attr) && !nodeAttrs.hasOwnProperty(expKey)) continue;
33504
+ if (!nodeAttrs[expKey] && nodeAttrs.hasOwnProperty(attr) && func.UI.screen.fix_val_defaults(attr, nodeAttrs[attr]) === undefined) continue;
33193
33505
 
33194
- value: await get_attr_value(attr),
33195
- },
33196
- is_init,
33197
- );
33198
- _ret = _.assignIn(_ret, ret);
33506
+ 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);
33507
+ Object.assign(_ret, ret);
33199
33508
  }
33200
33509
  }
33201
33510
 
33202
- // ALL
33511
+ // ALL - Process attributes
33512
+ const isXuPanel = nodeP.tagName === 'xu-panel';
33513
+ const isXuTeleport = nodeP.tagName === 'xu-teleport';
33514
+ const elmElement = $elm.get(0);
33203
33515
 
33204
- for await (const [key, val] of Object.entries(nodeP.attributes)) {
33205
- if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
33206
- if (glb.html5_events_handler.includes(key) || execute_attributes.includes(key)) {
33207
- continue;
33208
- }
33516
+ for (const [key, val] of Object.entries(nodeAttrs)) {
33517
+ if (shouldAbort()) break;
33518
+ if (html5EventsSet.has(key) || executeAttrsSet.has(key)) continue;
33209
33519
 
33210
- const new_key = key.split(':')[0]; // break expression
33211
- if (
33212
- nodeP.tagName !== 'xu-panel' &&
33213
- nodeP.tagName !== 'xu-teleport' && // nodeP.tagName.substr(0, 3) !== "xu-" &&
33214
- (new_key.substr(0, 2) !== 'xu' || new_key.substr(2, 1) !== '-')
33215
- ) {
33216
- // handle common html attributes
33520
+ const colonIndex = key.indexOf(':');
33521
+ const new_key = colonIndex > -1 ? key.slice(0, colonIndex) : key;
33522
+
33523
+ if (!isXuPanel && !isXuTeleport && (!new_key.startsWith('xu-') || new_key.length < 3 || new_key[2] !== '-')) {
33217
33524
  try {
33218
- $elm.get(0).setAttribute(key, val);
33525
+ elmElement.setAttribute(key, val);
33219
33526
  } catch (err) {
33220
33527
  console.error(err.message);
33221
33528
  }
33222
-
33223
33529
  continue;
33224
33530
  }
33225
- // handle xu attributes
33226
- try {
33227
- if ($elm?.data()?.xuAttributes) {
33228
- // in some cases xu data delete in purpose when refreshing the screen
33229
- $elm.data().xuAttributes[key] = val;
33230
- }
33231
- } catch (error) {
33232
- debugger;
33233
- console.error(error);
33531
+
33532
+ // Store xu attributes
33533
+ if (elmData.xuAttributes) {
33534
+ elmData.xuAttributes[key] = val;
33234
33535
  }
33235
33536
 
33236
- 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)) {
33537
+ const expKey = `xu-exp:${new_key}`;
33538
+ if (new_key === 'xu-exp' || nodeAttrs[expKey] || runXuBeforeSet.has(new_key) || runXuAfterSet.has(new_key)) {
33237
33539
  continue;
33238
33540
  }
33239
33541
 
33240
33542
  if (new_key === 'xu-on') {
33241
- let ret = await func.UI.screen.execute_xu_functions(
33242
- SESSION_ID,
33243
- is_skeleton,
33244
- $root_container,
33245
- nodeP,
33246
- $container,
33247
- paramsP,
33248
- parent_infoP,
33249
- jobNoP,
33250
- keyP,
33251
- parent_nodeP,
33252
- 'xu-on',
33253
- $elm,
33254
- {
33255
- key: key,
33256
- // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
33257
- value: await get_attr_value(key),
33258
- },
33259
- is_init,
33260
- refreshed_ds,
33261
- );
33262
- _ret = _.assignIn(_ret, ret);
33543
+ 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);
33544
+ Object.assign(_ret, ret);
33263
33545
  continue;
33264
33546
  }
33265
33547
 
33266
- let ret = await func.UI.screen.execute_xu_functions(
33267
- SESSION_ID,
33268
- is_skeleton,
33269
- $root_container,
33270
- nodeP,
33271
- $container,
33272
- paramsP,
33273
- parent_infoP,
33274
- jobNoP,
33275
- keyP,
33276
- parent_nodeP,
33277
- new_key,
33278
- $elm,
33279
- {
33280
- key: key,
33281
- // value: (await get_xuExp(new_key)) || func.UI.screen.fix_val_defaults(key, val),
33282
- value: await get_attr_value(key),
33283
- },
33284
- is_init,
33285
- refreshed_ds,
33286
- );
33287
-
33288
- _ret = _.assignIn(_ret, ret);
33548
+ 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);
33549
+ Object.assign(_ret, ret);
33289
33550
  }
33290
33551
 
33291
- // EXP for
33552
+ // EXP - Process expressions
33553
+ for (const [key, val] of Object.entries(nodeAttrs)) {
33554
+ if (shouldAbort()) break;
33292
33555
 
33293
- for await (const [key, val] of Object.entries(nodeP.attributes)) {
33294
- if (_ret.abort || $container?.data()?.xuData?.pending_to_delete) break;
33556
+ if (!key.startsWith('xu-exp:')) continue;
33557
+ const attr = key.slice(7);
33295
33558
 
33296
- const attr = key.split('xu-exp:')[1];
33559
+ if (html5EventsSet.has(attr) || executeAttrsSet.has(attr)) continue;
33560
+ if (done_exp.has(key)) continue;
33297
33561
 
33298
- if (!attr) {
33299
- continue;
33300
- }
33301
-
33302
- if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
33303
-
33304
- if (done_exp.includes(key)) {
33305
- continue;
33306
- }
33307
- let ret = await func.UI.screen.execute_xu_functions(
33308
- SESSION_ID,
33309
- is_skeleton,
33310
- $root_container,
33311
- nodeP,
33312
- $container,
33313
- paramsP,
33314
- parent_infoP,
33315
- jobNoP,
33316
- keyP,
33317
- parent_nodeP,
33318
- 'xu-exp',
33319
- $elm,
33320
- {
33321
- key: attr,
33322
- value: val,
33323
- },
33324
- true,
33325
- refreshed_ds,
33326
- );
33327
- _ret = _.assignIn(_ret, ret);
33562
+ 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);
33563
+ Object.assign(_ret, ret);
33328
33564
  }
33329
33565
 
33330
33566
  // AFTER
33567
+ for (const [key, attr] of Object.entries(glb.run_xu_after)) {
33568
+ if (containerXuData?.pending_to_delete) break;
33569
+ if (html5EventsSet.has(attr) || executeAttrsSet.has(attr)) continue;
33331
33570
 
33332
- for await (const [key, attr] of Object.entries(glb.run_xu_after)) {
33333
- if ($container?.data()?.xuData?.pending_to_delete) break;
33334
-
33335
- if (glb.html5_events_handler.includes(attr) || execute_attributes.includes(attr)) continue;
33336
-
33337
- if (!nodeP.attributes || !nodeP.attributes[attr] & !nodeP.attributes[`xu-exp:${attr}`]) continue;
33571
+ const expKey = `xu-exp:${attr}`;
33572
+ if (!nodeAttrs || (!nodeAttrs[attr] && !nodeAttrs[expKey])) continue;
33338
33573
 
33339
- let ret = await func.UI.screen.execute_xu_functions(
33340
- SESSION_ID,
33341
- is_skeleton,
33342
- $root_container,
33343
- nodeP,
33344
- $container,
33345
- paramsP,
33346
- parent_infoP,
33347
- jobNoP,
33348
- keyP,
33349
- parent_nodeP,
33350
- attr,
33351
- $elm,
33352
- {
33353
- key: attr,
33354
- // value: (await get_xuExp(attr)) || func.UI.screen.fix_val_defaults(attr, nodeP.attributes[attr]),
33355
- value: await get_attr_value(attr),
33356
- },
33357
- is_init,
33358
- refreshed_ds,
33359
- );
33360
- _ret = _.assignIn(_ret, ret);
33574
+ 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);
33575
+ Object.assign(_ret, ret);
33361
33576
  }
33362
33577
 
33363
33578
  // REGISTER EVENTS ATTRIBUTES
33579
+ for (const [key, val] of Object.entries(nodeAttrs)) {
33580
+ if (containerXuData?.pending_to_delete) break;
33581
+ if (!html5EventsSet.has(key)) break;
33364
33582
 
33365
- for await (const [key, val] of Object.entries(nodeP.attributes)) {
33366
- if ($container?.data()?.xuData?.pending_to_delete) break;
33367
- if (!glb.html5_events_handler.includes(key)) break;
33368
- // $elm.attr(key, await get_xuExp(key)) || val;
33369
- $elm.attr(key, await get_xuExp(key)) || val;
33583
+ const expVal = await get_xuExp(key);
33584
+ $elm.attr(key, expVal || val);
33370
33585
  }
33371
33586
 
33372
33587
  return _ret;
@@ -33431,7 +33646,7 @@ func.UI.screen.panel_post_render_handler = async function (
33431
33646
 
33432
33647
  const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP) {
33433
33648
  // const _paramsP = _.cloneDeep(paramsP);
33434
- const _paramsP = klona(paramsP);
33649
+ const _paramsP = klona.klona(paramsP);
33435
33650
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
33436
33651
 
33437
33652
  const currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
@@ -33445,7 +33660,7 @@ const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP
33445
33660
 
33446
33661
  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) {
33447
33662
  // const _paramsP = _.cloneDeep(paramsP);
33448
- const _paramsP = klona(paramsP);
33663
+ const _paramsP = klona.klona(paramsP);
33449
33664
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
33450
33665
  var $appendTo = $container;
33451
33666
  if ($appendToP) $appendTo = $appendToP;
@@ -34463,7 +34678,7 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
34463
34678
  });
34464
34679
  $.each($div.data().xuAttributes, function (key, val) {
34465
34680
  // $container.data().xuAttributes[key] = _.cloneDeep(val);
34466
- $container.data().xuAttributes[key] = klona(val);
34681
+ $container.data().xuAttributes[key] = klona.klona(val);
34467
34682
  });
34468
34683
 
34469
34684
  return await render_screen_type($div);