@xuda.io/runtime-bundle 1.0.1439 → 1.0.1441

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.
@@ -10685,6 +10685,60 @@ func.runtime.ui.set_style = function (target, prop, value) {
10685
10685
  target_node.style[prop] = value;
10686
10686
  return target_node;
10687
10687
  };
10688
+ func.runtime.ui.normalize_external_asset_url = function (value) {
10689
+ if (typeof value !== 'string' || !value.trim()) {
10690
+ return value;
10691
+ }
10692
+
10693
+ const trimmed_value = value.trim();
10694
+ try {
10695
+ const url = new URL(trimmed_value, typeof document !== 'undefined' ? document.baseURI : 'https://xuda.ai');
10696
+ if (url.hostname === 'via.placeholder.com') {
10697
+ url.hostname = 'placehold.co';
10698
+ return url.toString();
10699
+ }
10700
+ } catch (_) {
10701
+ if (trimmed_value.startsWith('https://via.placeholder.com/') || trimmed_value.startsWith('http://via.placeholder.com/')) {
10702
+ return trimmed_value.replace('via.placeholder.com', 'placehold.co');
10703
+ }
10704
+ }
10705
+
10706
+ return value;
10707
+ };
10708
+ func.runtime.ui.normalize_svg_path_value = function (value) {
10709
+ if (typeof value !== 'string' || !value.trim()) {
10710
+ return value;
10711
+ }
10712
+
10713
+ let normalized_value = value.trim();
10714
+
10715
+ // Common AI-generated typo: path data ends with a dangling command after closepath, e.g. "...zzm".
10716
+ normalized_value = normalized_value.replace(/([zZ])+\s*[mMlLhHvVcCsSqQtTaA]\s*$/g, '$1');
10717
+
10718
+ return normalized_value;
10719
+ };
10720
+ func.runtime.ui.normalize_attr_value = function (target_or_tag, key, value) {
10721
+ if (typeof value !== 'string') {
10722
+ return value;
10723
+ }
10724
+
10725
+ const target_tag_name =
10726
+ typeof target_or_tag === 'string'
10727
+ ? target_or_tag
10728
+ : func.runtime.ui.get_first_node(target_or_tag)?.tagName || '';
10729
+ const tag_name = `${target_tag_name || ''}`.trim().toLowerCase();
10730
+ const attr_name = `${key || ''}`.trim().toLowerCase();
10731
+
10732
+ if ((tag_name === 'img' || tag_name === 'image') && ['src', 'href', 'xlink:href'].includes(attr_name)) {
10733
+ return func.runtime.ui.normalize_external_asset_url(value);
10734
+ }
10735
+
10736
+ if (tag_name === 'path' && attr_name === 'd') {
10737
+ return func.runtime.ui.normalize_svg_path_value(value);
10738
+ }
10739
+
10740
+ return value;
10741
+ };
10688
10742
  func.runtime.ui.get_attr = function (target, key) {
10689
10743
  const target_node = func.runtime.ui.get_first_node(target);
10690
10744
  return target_node?.getAttribute?.(key) ?? undefined;
@@ -10692,7 +10746,12 @@ func.runtime.ui.get_attr = function (target, key) {
10692
10746
  func.runtime.ui.set_attr = function (target, key, value) {
10693
10747
  const target_node = func.runtime.ui.get_first_node(target);
10694
10748
  if (target_node?.setAttribute) {
10695
- target_node.setAttribute(key, value);
10749
+ const normalized_value = func.runtime.ui.normalize_attr_value(target_node, key, value);
10750
+ try {
10751
+ target_node.setAttribute(key, normalized_value);
10752
+ } catch (error) {
10753
+ console.warn(`Failed to set attribute "${key}" on <${target_node.tagName?.toLowerCase?.() || 'unknown'}>`, error);
10754
+ }
10696
10755
  }
10697
10756
  return target_node || target;
10698
10757
  };
@@ -10999,7 +11058,12 @@ func.runtime.ui.create_element = function (tag_name, attr_str) {
10999
11058
  while ((match = attr_regex.exec(attr_str)) !== null) {
11000
11059
  const key = match[1];
11001
11060
  const value = match[2] !== undefined ? match[2] : (match[3] !== undefined ? match[3] : (match[4] !== undefined ? match[4] : ''));
11002
- el.setAttribute(key, value);
11061
+ const normalized_value = func.runtime.ui.normalize_attr_value(tag_name, key, value);
11062
+ try {
11063
+ el.setAttribute(key, normalized_value);
11064
+ } catch (error) {
11065
+ console.warn(`Failed to set attribute "${key}" on <${tag_name}>`, error);
11066
+ }
11003
11067
  }
11004
11068
  }
11005
11069
  return el;
@@ -11009,7 +11073,8 @@ func.runtime.ui.create_svg_element = function (element, prop, nodeP, $appendTo)
11009
11073
  let attr_str = '';
11010
11074
  for (const [key, value] of Object.entries(prop)) {
11011
11075
  if (key.substr(0, 2) !== 'xu') {
11012
- attr_str += ` ${key}="${value}" `;
11076
+ const normalized_value = func.runtime.ui.normalize_attr_value(element, key, value);
11077
+ attr_str += ` ${key}="${normalized_value}" `;
11013
11078
  }
11014
11079
  }
11015
11080
  if (element === 'svg') {
@@ -17990,66 +18055,39 @@ const create_runtime_head_element = function (doc, tag_name, attributes, asset_k
17990
18055
  return node;
17991
18056
  };
17992
18057
 
17993
- const queue_runtime_html_script_task = function (task) {
17994
- const queue =
18058
+ const get_runtime_html_script_queue = function () {
18059
+ return (
17995
18060
  func.runtime.render._html_script_queue ||
17996
18061
  (func.runtime.render._html_script_queue = {
17997
18062
  items: [],
17998
- scheduled: false,
17999
18063
  running: false,
18000
- });
18064
+ })
18065
+ );
18066
+ };
18001
18067
 
18068
+ const queue_runtime_html_script_task = function (task) {
18069
+ const queue = get_runtime_html_script_queue();
18002
18070
  queue.items.push(task);
18071
+ };
18003
18072
 
18004
- if (queue.scheduled || queue.running) {
18073
+ func.runtime.render.flush_html_script_queue = async function () {
18074
+ const queue = get_runtime_html_script_queue();
18075
+ if (queue.running || !queue.items.length) {
18005
18076
  return;
18006
18077
  }
18007
18078
 
18008
- queue.scheduled = true;
18009
-
18010
- const drain_queue = async function () {
18011
- if (queue.running) {
18012
- return;
18013
- }
18014
-
18015
- queue.running = true;
18016
- queue.scheduled = false;
18079
+ queue.running = true;
18017
18080
 
18018
- try {
18019
- while (queue.items.length) {
18020
- const next_task = queue.items.shift();
18021
- await next_task();
18022
- }
18023
- } catch (error) {
18024
- console.error(error);
18025
- } finally {
18026
- queue.running = false;
18027
- if (queue.items.length && !queue.scheduled) {
18028
- queue.scheduled = true;
18029
- schedule_runtime_html_script_queue();
18030
- }
18031
- }
18032
- };
18033
-
18034
- const schedule_runtime_html_script_queue = function () {
18035
- const win = func.runtime.platform.get_window?.();
18036
- const run_later = function () {
18037
- setTimeout(function () {
18038
- drain_queue();
18039
- }, 0);
18040
- };
18041
-
18042
- if (win?.requestAnimationFrame) {
18043
- win.requestAnimationFrame(function () {
18044
- win.requestAnimationFrame(run_later);
18045
- });
18046
- return;
18081
+ try {
18082
+ while (queue.items.length) {
18083
+ const next_task = queue.items.shift();
18084
+ await next_task();
18047
18085
  }
18048
-
18049
- run_later();
18050
- };
18051
-
18052
- schedule_runtime_html_script_queue();
18086
+ } catch (error) {
18087
+ console.error(error);
18088
+ } finally {
18089
+ queue.running = false;
18090
+ }
18053
18091
  };
18054
18092
 
18055
18093
  const upsert_runtime_head_element = async function (options) {
@@ -18589,20 +18627,30 @@ func.runtime.render.render_ui_tree = async function (SESSION_ID, $container, nod
18589
18627
  keyP,
18590
18628
  parent_nodeP,
18591
18629
  });
18630
+ const render_depth = func.runtime.render._html_script_render_depth || (func.runtime.render._html_script_render_depth = {});
18631
+ render_depth[SESSION_ID] = (render_depth[SESSION_ID] || 0) + 1;
18592
18632
 
18593
- return await func.runtime.render.render_tree(treeP, {
18594
- SESSION_ID,
18595
- $container,
18596
- parent_infoP,
18597
- paramsP,
18598
- jobNoP,
18599
- is_skeleton,
18600
- keyP,
18601
- refreshed_ds,
18602
- parent_nodeP,
18603
- check_existP,
18604
- $root_container,
18605
- });
18633
+ try {
18634
+ return await func.runtime.render.render_tree(treeP, {
18635
+ SESSION_ID,
18636
+ $container,
18637
+ parent_infoP,
18638
+ paramsP,
18639
+ jobNoP,
18640
+ is_skeleton,
18641
+ keyP,
18642
+ refreshed_ds,
18643
+ parent_nodeP,
18644
+ check_existP,
18645
+ $root_container,
18646
+ });
18647
+ } finally {
18648
+ render_depth[SESSION_ID] = Math.max((render_depth[SESSION_ID] || 1) - 1, 0);
18649
+ if (render_depth[SESSION_ID] === 0) {
18650
+ await func.runtime.render.flush_html_script_queue?.();
18651
+ delete render_depth[SESSION_ID];
18652
+ }
18653
+ }
18606
18654
  };
18607
18655
  func.runtime = func.runtime || {};
18608
18656
  func.runtime.ui = func.runtime.ui || {};
@@ -10611,6 +10611,60 @@ func.runtime.ui.set_style = function (target, prop, value) {
10611
10611
  target_node.style[prop] = value;
10612
10612
  return target_node;
10613
10613
  };
10614
+ func.runtime.ui.normalize_external_asset_url = function (value) {
10615
+ if (typeof value !== 'string' || !value.trim()) {
10616
+ return value;
10617
+ }
10618
+
10619
+ const trimmed_value = value.trim();
10620
+ try {
10621
+ const url = new URL(trimmed_value, typeof document !== 'undefined' ? document.baseURI : 'https://xuda.ai');
10622
+ if (url.hostname === 'via.placeholder.com') {
10623
+ url.hostname = 'placehold.co';
10624
+ return url.toString();
10625
+ }
10626
+ } catch (_) {
10627
+ if (trimmed_value.startsWith('https://via.placeholder.com/') || trimmed_value.startsWith('http://via.placeholder.com/')) {
10628
+ return trimmed_value.replace('via.placeholder.com', 'placehold.co');
10629
+ }
10630
+ }
10631
+
10632
+ return value;
10633
+ };
10634
+ func.runtime.ui.normalize_svg_path_value = function (value) {
10635
+ if (typeof value !== 'string' || !value.trim()) {
10636
+ return value;
10637
+ }
10638
+
10639
+ let normalized_value = value.trim();
10640
+
10641
+ // Common AI-generated typo: path data ends with a dangling command after closepath, e.g. "...zzm".
10642
+ normalized_value = normalized_value.replace(/([zZ])+\s*[mMlLhHvVcCsSqQtTaA]\s*$/g, '$1');
10643
+
10644
+ return normalized_value;
10645
+ };
10646
+ func.runtime.ui.normalize_attr_value = function (target_or_tag, key, value) {
10647
+ if (typeof value !== 'string') {
10648
+ return value;
10649
+ }
10650
+
10651
+ const target_tag_name =
10652
+ typeof target_or_tag === 'string'
10653
+ ? target_or_tag
10654
+ : func.runtime.ui.get_first_node(target_or_tag)?.tagName || '';
10655
+ const tag_name = `${target_tag_name || ''}`.trim().toLowerCase();
10656
+ const attr_name = `${key || ''}`.trim().toLowerCase();
10657
+
10658
+ if ((tag_name === 'img' || tag_name === 'image') && ['src', 'href', 'xlink:href'].includes(attr_name)) {
10659
+ return func.runtime.ui.normalize_external_asset_url(value);
10660
+ }
10661
+
10662
+ if (tag_name === 'path' && attr_name === 'd') {
10663
+ return func.runtime.ui.normalize_svg_path_value(value);
10664
+ }
10665
+
10666
+ return value;
10667
+ };
10614
10668
  func.runtime.ui.get_attr = function (target, key) {
10615
10669
  const target_node = func.runtime.ui.get_first_node(target);
10616
10670
  return target_node?.getAttribute?.(key) ?? undefined;
@@ -10618,7 +10672,12 @@ func.runtime.ui.get_attr = function (target, key) {
10618
10672
  func.runtime.ui.set_attr = function (target, key, value) {
10619
10673
  const target_node = func.runtime.ui.get_first_node(target);
10620
10674
  if (target_node?.setAttribute) {
10621
- target_node.setAttribute(key, value);
10675
+ const normalized_value = func.runtime.ui.normalize_attr_value(target_node, key, value);
10676
+ try {
10677
+ target_node.setAttribute(key, normalized_value);
10678
+ } catch (error) {
10679
+ console.warn(`Failed to set attribute "${key}" on <${target_node.tagName?.toLowerCase?.() || 'unknown'}>`, error);
10680
+ }
10622
10681
  }
10623
10682
  return target_node || target;
10624
10683
  };
@@ -10925,7 +10984,12 @@ func.runtime.ui.create_element = function (tag_name, attr_str) {
10925
10984
  while ((match = attr_regex.exec(attr_str)) !== null) {
10926
10985
  const key = match[1];
10927
10986
  const value = match[2] !== undefined ? match[2] : (match[3] !== undefined ? match[3] : (match[4] !== undefined ? match[4] : ''));
10928
- el.setAttribute(key, value);
10987
+ const normalized_value = func.runtime.ui.normalize_attr_value(tag_name, key, value);
10988
+ try {
10989
+ el.setAttribute(key, normalized_value);
10990
+ } catch (error) {
10991
+ console.warn(`Failed to set attribute "${key}" on <${tag_name}>`, error);
10992
+ }
10929
10993
  }
10930
10994
  }
10931
10995
  return el;
@@ -10935,7 +10999,8 @@ func.runtime.ui.create_svg_element = function (element, prop, nodeP, $appendTo)
10935
10999
  let attr_str = '';
10936
11000
  for (const [key, value] of Object.entries(prop)) {
10937
11001
  if (key.substr(0, 2) !== 'xu') {
10938
- attr_str += ` ${key}="${value}" `;
11002
+ const normalized_value = func.runtime.ui.normalize_attr_value(element, key, value);
11003
+ attr_str += ` ${key}="${normalized_value}" `;
10939
11004
  }
10940
11005
  }
10941
11006
  if (element === 'svg') {
@@ -20731,6 +20796,34 @@ func.UI.screen.live_preview_hot_module_reload = async function (SESSION_ID, doc)
20731
20796
  };
20732
20797
  func.UI.component = {};
20733
20798
 
20799
+ func.UI.component.get_wrapped_nodes = function (target) {
20800
+ if (!target) {
20801
+ return [];
20802
+ }
20803
+ if (typeof target.toArray === "function") {
20804
+ return target.toArray().filter(Boolean);
20805
+ }
20806
+ if (Array.isArray(target)) {
20807
+ return target.filter(Boolean);
20808
+ }
20809
+ const first_node = func.runtime.ui.get_first_node(target);
20810
+ return first_node ? [first_node] : [];
20811
+ };
20812
+
20813
+ func.UI.component.move_wrapped_nodes = function (target, source) {
20814
+ const target_node = func.runtime.ui.get_first_node(target);
20815
+ if (!target_node) {
20816
+ return false;
20817
+ }
20818
+
20819
+ const nodes = func.UI.component.get_wrapped_nodes(source);
20820
+ for (let index = 0; index < nodes.length; index++) {
20821
+ target_node.appendChild(nodes[index]);
20822
+ }
20823
+
20824
+ return true;
20825
+ };
20826
+
20734
20827
  func.UI.component.create_app_modal_component = function (
20735
20828
  SESSION_ID,
20736
20829
  modal_content_name
@@ -20965,8 +21058,7 @@ func.UI.component.create_app_root_component = function (SESSION_ID) {
20965
21058
  connectedCallback() {
20966
21059
  const xu_nav = SESSION_OBJ[SESSION_ID].root_element.querySelector("xu-nav");
20967
21060
  const xu_nav_data = func.runtime.ui.get_data(xu_nav);
20968
- const _node = func.runtime.ui.get_first_node(xu_nav_data.xuData.$div);
20969
- if (_node) this.appendChild(_node);
21061
+ func.UI.component.move_wrapped_nodes(this, xu_nav_data?.xuData?.$div);
20970
21062
  const root_component_callback = xu_nav_data.xuData.root_component_callback;
20971
21063
  if (root_component_callback) {
20972
21064
  root_component_callback();
@@ -21003,8 +21095,7 @@ func.UI.component.create_app_popover_component = function (SESSION_ID) {
21003
21095
  }
21004
21096
 
21005
21097
  popover_el.innerHTML = '';
21006
- const _popNode = func.runtime.ui.get_first_node(params.$dialogDiv);
21007
- if (_popNode) popover_el.appendChild(_popNode);
21098
+ func.UI.component.move_wrapped_nodes(popover_el, params.$dialogDiv);
21008
21099
  }
21009
21100
  }
21010
21101
  );
@@ -21025,8 +21116,7 @@ func.UI.component.create_camera_select_popover_component = function (
21025
21116
 
21026
21117
  var params = func.runtime.ui.get_data(xu_popover_controller, "xuControllerParams");
21027
21118
 
21028
- const _camNode = func.runtime.ui.get_first_node(params.$dialogDiv);
21029
- if (_camNode) this.appendChild(_camNode);
21119
+ func.UI.component.move_wrapped_nodes(this, params.$dialogDiv);
21030
21120
  }
21031
21121
  }
21032
21122
  );