@xuda.io/runtime-bundle 1.0.1434 → 1.0.1435

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.
@@ -23611,6 +23611,23 @@ func.runtime.platform = {
23611
23611
  return false;
23612
23612
  }
23613
23613
  },
23614
+ get_cookie_item: function (key) {
23615
+ if (!key) {
23616
+ return null;
23617
+ }
23618
+ const doc = func.runtime.platform.get_document();
23619
+ const cookie_string = doc?.cookie;
23620
+ if (!cookie_string) {
23621
+ return null;
23622
+ }
23623
+ const cookie_entry = cookie_string.split('; ').find(function (cookie) {
23624
+ return cookie.startsWith(key + '=');
23625
+ });
23626
+ if (!cookie_entry) {
23627
+ return null;
23628
+ }
23629
+ return cookie_entry.split('=').slice(1).join('=') || null;
23630
+ },
23614
23631
  get_url_href: function () {
23615
23632
  return func.runtime.platform.get_location()?.href || '';
23616
23633
  },
@@ -28141,11 +28158,14 @@ func.runtime.ui.create_screen_host = function (SESSION_ID, screen_type, params,
28141
28158
  };
28142
28159
  };
28143
28160
  func.runtime.ui.find_xu_ui_in_root = function (SESSION_ID, xu_ui_id) {
28161
+ if (!SESSION_ID || !xu_ui_id) {
28162
+ return func.runtime.ui._wrap_matches([]);
28163
+ }
28144
28164
  if (func.runtime.ui.get_refresh_indexed_element_by_ui_id) {
28145
28165
  const elm = func.runtime.ui.get_refresh_indexed_element_by_ui_id(SESSION_ID, xu_ui_id);
28146
28166
  return func.runtime.ui._wrap_matches(elm ? [elm] : []);
28147
28167
  }
28148
- return func.runtime.ui.find_in_root(SESSION_ID, `[xu-ui-id=${xu_ui_id}]`);
28168
+ return func.runtime.ui.find_in_root(SESSION_ID, `[xu-ui-id="${xu_ui_id}"]`);
28149
28169
  };
28150
28170
  func.runtime.ui.find_panel_wrapper_in_root = function (SESSION_ID, xu_ui_id) {
28151
28171
  if (func.runtime.ui.get_refresh_indexed_panel_wrapper_by_id) {
@@ -28266,6 +28286,14 @@ func.runtime.ui.find_element_by_id = function (element_id) {
28266
28286
  }
28267
28287
  return null;
28268
28288
  };
28289
+ func.runtime.ui.get_parent_element_id = function (element_id) {
28290
+ if (!element_id) {
28291
+ return null;
28292
+ }
28293
+ const clean_id = element_id.startsWith('#') ? element_id.substring(1) : element_id;
28294
+ const element = func.runtime.ui.find_element_by_id(clean_id);
28295
+ return element?.parentElement?.id || null;
28296
+ };
28269
28297
  func.runtime.ui.get_session_root = function (SESSION_ID) {
28270
28298
  if (typeof document !== 'undefined') {
28271
28299
  return document.getElementById('embed_' + SESSION_ID) || null;
@@ -28815,12 +28843,23 @@ func.runtime.ui.build_xu_ui_id_seed = function (nodeP, dsSessionP, key_path, cur
28815
28843
  const elem_key = `${nodeId}-${key_path}-${currentRecordId}`;
28816
28844
  return `${nodeP.id}-${elem_key}-${dsSessionP?.toString() || ''}`;
28817
28845
  };
28846
+ func.runtime.ui.build_container_key_path = function (container_xu_data, keyP, parent_infoP, nodeP, parent_nodeP) {
28847
+ const key_segment = typeof keyP === 'undefined' || keyP === null ? '0' : `${keyP}`;
28848
+ let key_path = `${container_xu_data?.key_path || '0'}-${key_segment}`;
28849
+ const parent_identity = parent_nodeP?.xu_tree_id || parent_nodeP?.id;
28850
+ const node_identity = nodeP?.xu_tree_id || nodeP?.id;
28851
+ const is_iterated_clone = !!(parent_infoP?.iterate_info && parent_identity && node_identity && parent_identity === node_identity);
28852
+ if (is_iterated_clone) {
28853
+ key_path += '-iter';
28854
+ }
28855
+ return key_path;
28856
+ };
28818
28857
  func.runtime.ui.generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP, precomputed = {}) {
28819
28858
  const dsSessionP = paramsP.dsSessionP;
28820
28859
  const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP];
28821
28860
  const containerXuData = precomputed.container_xu_data || func.runtime.ui.get_data($container)?.xuData;
28822
28861
  const currentRecordId = typeof precomputed.currentRecordId !== 'undefined' ? precomputed.currentRecordId : containerXuData?.recordid || _ds?.currentRecordId || '';
28823
- const key_path = precomputed.key_path || `${containerXuData?.key_path || '0'}-${keyP || '0'}`;
28862
+ const key_path = precomputed.key_path || func.runtime.ui.build_container_key_path(containerXuData, keyP, precomputed.parent_infoP, nodeP, precomputed.parent_nodeP);
28824
28863
  const ui_id = func.runtime.ui.build_xu_ui_id_seed(nodeP, dsSessionP, key_path, currentRecordId);
28825
28864
 
28826
28865
  if (func.runtime.ui.ui_id_hash_cache.has(ui_id)) {
@@ -28849,13 +28888,15 @@ func.runtime.ui.create_container = async function (options) {
28849
28888
  const currentRecordId = container_xu_data?.recordid || (_ds ? _ds.currentRecordId : '');
28850
28889
 
28851
28890
  try {
28852
- const key_path = `${container_xu_data?.key_path || '0'}-${options.keyP || '0'}`;
28891
+ const key_path = func.runtime.ui.build_container_key_path(container_xu_data, options.keyP, options.parent_infoP, options.nodeP, options.parent_nodeP);
28853
28892
  const elem_key = `${options.nodeP.xu_tree_id || options.nodeP.id}-${key_path}-${currentRecordId}`;
28854
28893
  const $div = func.runtime.ui.create_container_element(options.div_typeP, options.attr_str, options.prop, options.nodeP, $appendTo);
28855
28894
  const new_ui_id = await func.runtime.ui.generate_xu_ui_id(options.SESSION_ID, options.nodeP, options.$container, options.paramsP, options.keyP, {
28856
28895
  container_xu_data,
28857
28896
  currentRecordId,
28858
28897
  key_path,
28898
+ parent_infoP: options.parent_infoP,
28899
+ parent_nodeP: options.parent_nodeP,
28859
28900
  });
28860
28901
 
28861
28902
  func.runtime.ui.apply_container_meta($div, {
@@ -29187,9 +29228,7 @@ func.UI.utils.get_url_attribute = function (SESSION_ID, key) {
29187
29228
  const root_attribute = func.runtime.ui.get_attr(_session.root_element, key);
29188
29229
  const option_param = _session.opt?.params?.[key];
29189
29230
  const option_value = _session.opt?.[key];
29190
- const cookie_value = (typeof document !== 'undefined' && document.cookie)
29191
- ? (document.cookie.split('; ').find(c => c.startsWith(key + '='))?.split('=').slice(1).join('=') || null)
29192
- : null;
29231
+ const cookie_value = platform.get_cookie_item(key);
29193
29232
  const storage_value = platform.get_storage_item(key, 'local');
29194
29233
 
29195
29234
  return url_param || root_attribute || option_param || option_value || cookie_value || storage_value;
@@ -30446,8 +30485,40 @@ func.UI.worker.execute = async function (SESSION_ID, queue_obj) {
30446
30485
  get_live_element_context: function (elem_key, fallback_$elm, context = {}) {
30447
30486
  let raw_$elm = elem_key ? fx.get_element_by_ui_id(elem_key) : fallback_$elm;
30448
30487
  let $elm = func.runtime?.ui?.get_preferred_live_element ? func.runtime.ui.get_preferred_live_element(raw_$elm) : raw_$elm;
30488
+ const matches_context = function (node_xu_data, allow_loose_match = false) {
30489
+ if (!node_xu_data) {
30490
+ return false;
30491
+ }
30492
+ if (context.node_id && node_xu_data.nodeid !== context.node_id) {
30493
+ return false;
30494
+ }
30495
+ if (typeof context.key !== 'undefined' && context.key !== null && node_xu_data.key !== context.key) {
30496
+ return false;
30497
+ }
30498
+ if (context.key_path && node_xu_data.key_path !== context.key_path) {
30499
+ return false;
30500
+ }
30501
+ if (context.recordid && node_xu_data.recordid !== context.recordid) {
30502
+ return false;
30503
+ }
30504
+ if (!allow_loose_match) {
30505
+ if (context.prog_id && node_xu_data.paramsP?.prog_id !== context.prog_id) {
30506
+ return false;
30507
+ }
30508
+ if (context.parent_element_ui_id && node_xu_data.parent_element_ui_id !== context.parent_element_ui_id) {
30509
+ return false;
30510
+ }
30511
+ }
30512
+ if (node_xu_data.pending_to_delete) {
30513
+ return false;
30514
+ }
30515
+ return true;
30516
+ };
30517
+ const resolved_node = func.runtime.ui.get_first_node($elm);
30518
+ const resolved_data = resolved_node ? func.runtime.ui.get_data(resolved_node)?.xuData : null;
30519
+ const has_matching_resolved_node = matches_context(resolved_data);
30449
30520
 
30450
- if (context.node_id) {
30521
+ if (context.node_id && !has_matching_resolved_node) {
30451
30522
  const $root = func.UI.worker.get_session_root(SESSION_ID);
30452
30523
  const runtime_nodes = func.runtime?.ui?.get_refresh_index_elements
30453
30524
  ? func.runtime.ui.get_refresh_index_elements(SESSION_ID, $root).toArray()
@@ -30458,22 +30529,7 @@ func.UI.worker.execute = async function (SESSION_ID, queue_obj) {
30458
30529
  const node = runtime_nodes[index];
30459
30530
  const node_data = func.runtime.ui.get_data(node);
30460
30531
  const node_xu_data = node_data?.xuData;
30461
- if (!node_xu_data) {
30462
- continue;
30463
- }
30464
- if (node_xu_data.nodeid !== context.node_id) {
30465
- continue;
30466
- }
30467
- if (context.recordid && node_xu_data.recordid !== context.recordid) {
30468
- continue;
30469
- }
30470
- if (context.prog_id && node_xu_data.paramsP?.prog_id !== context.prog_id) {
30471
- continue;
30472
- }
30473
- if (context.parent_element_ui_id && node_xu_data.parent_element_ui_id !== context.parent_element_ui_id) {
30474
- continue;
30475
- }
30476
- if (node_xu_data.pending_to_delete) {
30532
+ if (!matches_context(node_xu_data)) {
30477
30533
  continue;
30478
30534
  }
30479
30535
  matching_nodes.push(node);
@@ -30484,16 +30540,7 @@ func.UI.worker.execute = async function (SESSION_ID, queue_obj) {
30484
30540
  const node = runtime_nodes[index];
30485
30541
  const node_data = func.runtime.ui.get_data(node);
30486
30542
  const node_xu_data = node_data?.xuData;
30487
- if (!node_xu_data) {
30488
- continue;
30489
- }
30490
- if (node_xu_data.nodeid !== context.node_id) {
30491
- continue;
30492
- }
30493
- if (context.recordid && node_xu_data.recordid !== context.recordid) {
30494
- continue;
30495
- }
30496
- if (node_xu_data.pending_to_delete) {
30543
+ if (!matches_context(node_xu_data, true)) {
30497
30544
  continue;
30498
30545
  }
30499
30546
  matching_nodes.push(node);
@@ -30611,10 +30658,10 @@ func.UI.worker.execute = async function (SESSION_ID, queue_obj) {
30611
30658
  const iterate_info = options.iterate_info;
30612
30659
  const iterate_key = iterate_info
30613
30660
  ? [
30614
- iterate_info.iterator_key || '',
30615
- iterate_info.iterator_val || '',
30616
- iterate_info._key || '',
30617
- iterate_info._val || '',
30661
+ iterate_info.iterator_key ?? '',
30662
+ iterate_info.iterator_val ?? '',
30663
+ iterate_info._key ?? '',
30664
+ iterate_info._val ?? '',
30618
30665
  ].join('::')
30619
30666
  : '';
30620
30667
 
@@ -33564,6 +33611,8 @@ func.runtime.ui.build_refresh_job_obj = function (options, elem_key, elem_val, e
33564
33611
  fields_arr: options.fields_arr,
33565
33612
  elem_key,
33566
33613
  node_id: elm_data?.xuData?.nodeid,
33614
+ key: elm_data?.xuData?.key,
33615
+ key_path: elm_data?.xuData?.key_path,
33567
33616
  recordid: elm_data?.xuData?.recordid,
33568
33617
  parent_element_ui_id: elm_data?.xuData?.parent_element_ui_id,
33569
33618
  prog_id: elm_data?.xuData?.paramsP?.prog_id,
@@ -35070,6 +35119,43 @@ func.runtime.render.scope_css_to_xu_ui = function ($elm, cssText) {
35070
35119
  return parser.getCSSForEditor(parsed);
35071
35120
  };
35072
35121
  func.runtime.render.bind_xu_event = function (options) {
35122
+ const decode_html_entities = function (value) {
35123
+ if (typeof value !== 'string' || value.indexOf('&') === -1) {
35124
+ return value;
35125
+ }
35126
+
35127
+ if (typeof document !== 'undefined') {
35128
+ const textarea = document.createElement('textarea');
35129
+ textarea.innerHTML = value;
35130
+ return textarea.value;
35131
+ }
35132
+
35133
+ return value
35134
+ .replaceAll('"', '"')
35135
+ .replaceAll('"', '"')
35136
+ .replaceAll(''', "'")
35137
+ .replaceAll(''', "'")
35138
+ .replaceAll('&lt;', '<')
35139
+ .replaceAll('&gt;', '>')
35140
+ .replaceAll('&amp;', '&');
35141
+ };
35142
+ const normalize_event_handlers = function (raw_handlers) {
35143
+ if (typeof raw_handlers !== 'string') {
35144
+ return raw_handlers;
35145
+ }
35146
+
35147
+ const decoded_value = decode_html_entities(raw_handlers).trim();
35148
+ if (!decoded_value) {
35149
+ return [];
35150
+ }
35151
+
35152
+ try {
35153
+ return JSON5.parse(decoded_value);
35154
+ } catch (error) {
35155
+ console.error('XUDA RUNTIME', `xu-on has invalid workflow syntax: ${decoded_value}`, error);
35156
+ return [];
35157
+ }
35158
+ };
35073
35159
  CLIENT_ACTIVITY_TS = Date.now();
35074
35160
  const trigger = options.val.key.split('xu-on:')[1].toLowerCase();
35075
35161
  const handler_key = `_xuda_xuOn_${trigger.replace(/[^a-z0-9_]/gi, '_')}`;
@@ -35081,27 +35167,33 @@ func.runtime.render.bind_xu_event = function (options) {
35081
35167
  const _$elm = evt.currentTarget;
35082
35168
  const elm_data = func.runtime.ui.get_data(_$elm);
35083
35169
  const xuAttributes = elm_data?.xuAttributes;
35084
- const event_handlers = xuAttributes?.['xu-on:' + evt.type];
35170
+ const event_attr_key = 'xu-on:' + evt.type;
35171
+ const event_handlers = normalize_event_handlers(xuAttributes?.[event_attr_key]);
35172
+ if (xuAttributes && event_handlers !== xuAttributes?.[event_attr_key]) {
35173
+ xuAttributes[event_attr_key] = event_handlers;
35174
+ }
35085
35175
  if (xu_isEmpty(xuAttributes) || xu_isEmpty(event_handlers)) return;
35086
35176
  const handler_keys = Object.keys(event_handlers);
35087
35177
 
35088
35178
  for (let handler_index = 0; handler_index < handler_keys.length; handler_index++) {
35089
35179
  const val = event_handlers[handler_keys[handler_index]];
35090
- if (!xu_isEmpty(val.props.condition)) {
35091
- const expCond = await func.expression.get(options.SESSION_ID, val.props.condition, options.paramsP.dsSessionP, 'condition', options.paramsP.recordid);
35180
+ const handler_props = val?.props || {};
35181
+ if (!xu_isEmpty(handler_props.condition)) {
35182
+ const expCond = await func.expression.get(options.SESSION_ID, handler_props.condition, options.paramsP.dsSessionP, 'condition', options.paramsP.recordid);
35092
35183
  if (!expCond.result) continue;
35093
35184
  }
35094
35185
 
35095
- if (val.event_modifiers && evt[val.event_modifiers]) {
35186
+ if (val?.event_modifiers && evt[val.event_modifiers]) {
35096
35187
  evt[val.event_modifiers]();
35097
35188
  }
35098
35189
 
35099
- const workflow = val.workflow || val.event;
35190
+ const workflow = val?.workflow || val?.event;
35100
35191
  if (workflow) {
35101
35192
  const workflow_keys = Object.keys(workflow);
35102
35193
  for (let workflow_index = 0; workflow_index < workflow_keys.length; workflow_index++) {
35103
35194
  const val2 = workflow[workflow_keys[workflow_index]];
35104
- if (!val2.data.enabled) continue;
35195
+ if (!val2?.data?.action) continue;
35196
+ if (val2.data.enabled === false) continue;
35105
35197
 
35106
35198
  func.events.add_to_queue(
35107
35199
  options.SESSION_ID,
@@ -36825,18 +36917,12 @@ func.runtime.render.handle_xu_for = async function (options) {
36825
36917
  }
36826
36918
  }
36827
36919
 
36828
- // Strip xu-ui-id from template elements before removal so that
36829
- // delete_meta does not destroy the meta entry shared by iteration-0
36830
- // (the template and first iteration child share the same xu-ui-id
36831
- // because their key_path values collide).
36832
36920
  const _live_node = func.runtime.ui.get_first_node($live_elm);
36833
36921
  if (_live_node) {
36834
- _live_node.removeAttribute('xu-ui-id');
36835
36922
  func.runtime.ui.remove($live_elm);
36836
36923
  }
36837
36924
  const _options_node = func.runtime.ui.get_first_node(options.$elm);
36838
36925
  if (_options_node && _options_node !== _live_node) {
36839
- _options_node.removeAttribute('xu-ui-id');
36840
36926
  func.runtime.ui.remove(options.$elm);
36841
36927
  }
36842
36928
  return { abort: true, consume_placeholder: true };
@@ -37432,10 +37518,31 @@ func.runtime.widgets = func.runtime.widgets || {};
37432
37518
  // Browser-only common xu handler factories live here so registry composition can stay small.
37433
37519
 
37434
37520
  func.runtime.render.build_base_xu_handlers = function (options, _ds) {
37521
+ const decode_html_entities = function (value) {
37522
+ if (typeof value !== 'string' || value.indexOf('&') === -1) {
37523
+ return value;
37524
+ }
37525
+
37526
+ if (typeof document !== 'undefined') {
37527
+ const textarea = document.createElement('textarea');
37528
+ textarea.innerHTML = value;
37529
+ return textarea.value;
37530
+ }
37531
+
37532
+ return value
37533
+ .replaceAll('&quot;', '"')
37534
+ .replaceAll('&#34;', '"')
37535
+ .replaceAll('&#39;', "'")
37536
+ .replaceAll('&#039;', "'")
37537
+ .replaceAll('&lt;', '<')
37538
+ .replaceAll('&gt;', '>')
37539
+ .replaceAll('&amp;', '&');
37540
+ };
37435
37541
  const parse_object_value = function (attr_name, val, shape = 'object') {
37436
37542
  let parsed_value = val?.value;
37437
37543
  if (typeof parsed_value === 'string') {
37438
- const trimmed_value = parsed_value.trim();
37544
+ const decoded_value = decode_html_entities(parsed_value);
37545
+ const trimmed_value = decoded_value.trim();
37439
37546
  const wrapped_candidate =
37440
37547
  trimmed_value.startsWith('(') && trimmed_value.endsWith(')')
37441
37548
  ? trimmed_value.slice(1, -1).trim()
@@ -39542,8 +39649,9 @@ func.datasource.clean = function (SESSION_ID, screenIdP) {
39542
39649
  var arr = [];
39543
39650
  for (const [key, val] of Object.entries(SESSION_OBJ[SESSION_ID].DS_GLB)) {
39544
39651
  try {
39545
- const _screen_el = val.screenId ? document.getElementById(val.screenId) : null;
39546
- const screen_parent_id = _screen_el?.parentElement?.id || null;
39652
+ const screen_parent_id = val.screenId && func.runtime?.ui?.get_parent_element_id
39653
+ ? func.runtime.ui.get_parent_element_id(val.screenId)
39654
+ : null;
39547
39655
  if (
39548
39656
  Number(key) > 0 &&
39549
39657
  (val.screenId === screenIdP ||
@@ -39552,7 +39660,7 @@ func.datasource.clean = function (SESSION_ID, screenIdP) {
39552
39660
  (val && val.parentDataSourceNo && arr.includes(val.parentDataSourceNo.toString())))
39553
39661
  ) {
39554
39662
  arr.push(key);
39555
- if (val.screenId) func.UI.utils.screen_blocker(false, val.screenId);
39663
+ if (val.screenId && func.UI?.utils?.screen_blocker) func.UI.utils.screen_blocker(false, val.screenId);
39556
39664
  }
39557
39665
  } catch (err) {
39558
39666
  console.warn('func.datasource.clean failed');
@@ -43408,6 +43516,7 @@ func.events.execute = async function (
43408
43516
  },
43409
43517
  execute_native_javascript: async function () {
43410
43518
  const module = await func.common.get_module(SESSION_ID, 'xuda-event-javascript-module.mjs');
43519
+ const resolved_element_expr = `(func.runtime.ui && func.runtime.ui.find_xu_ui_in_root && func.runtime.ui.get_first_node ? func.runtime.ui.get_first_node(func.runtime.ui.find_xu_ui_in_root(SESSION_ID, ${JSON.stringify(elementP)})) : null)`;
43411
43520
 
43412
43521
  const result = await module.run_javascript(
43413
43522
  SESSION_ID,
@@ -43415,7 +43524,7 @@ func.events.execute = async function (
43415
43524
  dsSession,
43416
43525
  `(async function(el,evt) {
43417
43526
  ${refIdP.value}
43418
- })(document.querySelector(\`[xu-ui-id="${elementP}"]\`),evt)`,
43527
+ })(${resolved_element_expr},evt)`,
43419
43528
  null,
43420
43529
  null,
43421
43530
  null,
@@ -43428,6 +43537,7 @@ func.events.execute = async function (
43428
43537
  },
43429
43538
  execute_evaluate_javascript: async function () {
43430
43539
  const module = await func.common.get_module(SESSION_ID, 'xuda-event-javascript-module.mjs');
43540
+ const resolved_element_expr = `(func.runtime.ui && func.runtime.ui.find_xu_ui_in_root && func.runtime.ui.get_first_node ? func.runtime.ui.get_first_node(func.runtime.ui.find_xu_ui_in_root(SESSION_ID, ${JSON.stringify(elementP)})) : null)`;
43431
43541
 
43432
43542
  const result = await module.run_javascript(
43433
43543
  SESSION_ID,
@@ -43435,7 +43545,7 @@ func.events.execute = async function (
43435
43545
  dsSession,
43436
43546
  `(async function(el,evt) {
43437
43547
  ${refIdP.value}
43438
- })(document.querySelector(\`[xu-ui-id="${elementP}"]\`),evt)`,
43548
+ })(${resolved_element_expr},evt)`,
43439
43549
  true,
43440
43550
  null,
43441
43551
  null,