@xuda.io/runtime-bundle 1.0.1440 → 1.0.1442

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 || {};
@@ -17956,6 +17956,40 @@ const wait_for_runtime_asset_load = function (node) {
17956
17956
  });
17957
17957
  };
17958
17958
 
17959
+ const is_runtime_tailwind_script_src = function (src) {
17960
+ const normalized_src = `${src || ''}`.trim().toLowerCase();
17961
+ if (!normalized_src) {
17962
+ return false;
17963
+ }
17964
+
17965
+ return normalized_src.includes('cdn.tailwindcss.com') || /(?:^|\/)tailwind\.cdn\.js(?:[?#].*)?$/.test(normalized_src);
17966
+ };
17967
+
17968
+ const is_runtime_tailwind_config_script = function (content) {
17969
+ return /(?:^|[^\w.])tailwind\.config\s*=/.test(`${content || ''}`);
17970
+ };
17971
+
17972
+ const has_runtime_tailwind = function () {
17973
+ const win = func.runtime.platform.get_window?.();
17974
+ return !!win?.tailwind;
17975
+ };
17976
+
17977
+ const refresh_runtime_tailwind = async function () {
17978
+ const win = func.runtime.platform.get_window?.();
17979
+ const refresh = win?.tailwind?.refresh;
17980
+ if (typeof refresh !== 'function') {
17981
+ return false;
17982
+ }
17983
+
17984
+ try {
17985
+ await refresh();
17986
+ return true;
17987
+ } catch (error) {
17988
+ console.error(error);
17989
+ return false;
17990
+ }
17991
+ };
17992
+
17959
17993
  const remove_runtime_head_asset = function (node) {
17960
17994
  if (node?.parentNode?.removeChild) {
17961
17995
  node.parentNode.removeChild(node);
@@ -18126,10 +18160,16 @@ const render_runtime_html_asset = async function (options) {
18126
18160
  }
18127
18161
  case 'script': {
18128
18162
  const src = `${attributes.src || ''}`.trim();
18163
+ const is_tailwind_script = is_runtime_tailwind_script_src(src);
18164
+ const is_tailwind_config_script = is_runtime_tailwind_config_script(content);
18129
18165
  if (!src && !content.trim()) {
18130
18166
  return options.$container;
18131
18167
  }
18132
18168
  queue_runtime_html_script_task(async function () {
18169
+ if (src && is_tailwind_script && has_runtime_tailwind()) {
18170
+ return;
18171
+ }
18172
+
18133
18173
  await upsert_runtime_head_element({
18134
18174
  tag_name,
18135
18175
  attributes,
@@ -18144,6 +18184,10 @@ const render_runtime_html_asset = async function (options) {
18144
18184
  : null,
18145
18185
  await_load: !!src,
18146
18186
  });
18187
+
18188
+ if (is_tailwind_config_script) {
18189
+ await refresh_runtime_tailwind();
18190
+ }
18147
18191
  });
18148
18192
  return options.$container;
18149
18193
  }
@@ -20796,6 +20840,34 @@ func.UI.screen.live_preview_hot_module_reload = async function (SESSION_ID, doc)
20796
20840
  };
20797
20841
  func.UI.component = {};
20798
20842
 
20843
+ func.UI.component.get_wrapped_nodes = function (target) {
20844
+ if (!target) {
20845
+ return [];
20846
+ }
20847
+ if (typeof target.toArray === "function") {
20848
+ return target.toArray().filter(Boolean);
20849
+ }
20850
+ if (Array.isArray(target)) {
20851
+ return target.filter(Boolean);
20852
+ }
20853
+ const first_node = func.runtime.ui.get_first_node(target);
20854
+ return first_node ? [first_node] : [];
20855
+ };
20856
+
20857
+ func.UI.component.move_wrapped_nodes = function (target, source) {
20858
+ const target_node = func.runtime.ui.get_first_node(target);
20859
+ if (!target_node) {
20860
+ return false;
20861
+ }
20862
+
20863
+ const nodes = func.UI.component.get_wrapped_nodes(source);
20864
+ for (let index = 0; index < nodes.length; index++) {
20865
+ target_node.appendChild(nodes[index]);
20866
+ }
20867
+
20868
+ return true;
20869
+ };
20870
+
20799
20871
  func.UI.component.create_app_modal_component = function (
20800
20872
  SESSION_ID,
20801
20873
  modal_content_name
@@ -21030,8 +21102,7 @@ func.UI.component.create_app_root_component = function (SESSION_ID) {
21030
21102
  connectedCallback() {
21031
21103
  const xu_nav = SESSION_OBJ[SESSION_ID].root_element.querySelector("xu-nav");
21032
21104
  const xu_nav_data = func.runtime.ui.get_data(xu_nav);
21033
- const _node = func.runtime.ui.get_first_node(xu_nav_data.xuData.$div);
21034
- if (_node) this.appendChild(_node);
21105
+ func.UI.component.move_wrapped_nodes(this, xu_nav_data?.xuData?.$div);
21035
21106
  const root_component_callback = xu_nav_data.xuData.root_component_callback;
21036
21107
  if (root_component_callback) {
21037
21108
  root_component_callback();
@@ -21068,8 +21139,7 @@ func.UI.component.create_app_popover_component = function (SESSION_ID) {
21068
21139
  }
21069
21140
 
21070
21141
  popover_el.innerHTML = '';
21071
- const _popNode = func.runtime.ui.get_first_node(params.$dialogDiv);
21072
- if (_popNode) popover_el.appendChild(_popNode);
21142
+ func.UI.component.move_wrapped_nodes(popover_el, params.$dialogDiv);
21073
21143
  }
21074
21144
  }
21075
21145
  );
@@ -21090,8 +21160,7 @@ func.UI.component.create_camera_select_popover_component = function (
21090
21160
 
21091
21161
  var params = func.runtime.ui.get_data(xu_popover_controller, "xuControllerParams");
21092
21162
 
21093
- const _camNode = func.runtime.ui.get_first_node(params.$dialogDiv);
21094
- if (_camNode) this.appendChild(_camNode);
21163
+ func.UI.component.move_wrapped_nodes(this, params.$dialogDiv);
21095
21164
  }
21096
21165
  }
21097
21166
  );