@xuda.io/runtime-bundle 1.0.1437 → 1.0.1438

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.
@@ -1836,6 +1836,128 @@ func.runtime.platform.set_cursor = function (element, cursor) {
1836
1836
  node.style.cursor = cursor;
1837
1837
  }
1838
1838
  };
1839
+ func.runtime.program.normalize_doc_for_runtime = function (doc) {
1840
+ if (!doc || doc.__xudaRuntimeNormalized || !Array.isArray(doc.progUi) || !doc.progUi.length) {
1841
+ return doc;
1842
+ }
1843
+
1844
+ const normalize_tag_name = function (tag_name) {
1845
+ return `${tag_name || ''}`.trim().toLowerCase();
1846
+ };
1847
+ const merge_attributes = function (target, source) {
1848
+ const merged = { ...(target || {}) };
1849
+ const source_attributes = source || {};
1850
+ const keys = Object.keys(source_attributes);
1851
+
1852
+ for (let index = 0; index < keys.length; index++) {
1853
+ const key = keys[index];
1854
+ const value = source_attributes[key];
1855
+ if (typeof value === 'undefined') {
1856
+ continue;
1857
+ }
1858
+
1859
+ if (key === 'class' && merged.class && value) {
1860
+ const next_value = `${merged.class} ${value}`.trim();
1861
+ merged.class = Array.from(new Set(next_value.split(/\s+/).filter(Boolean))).join(' ');
1862
+ continue;
1863
+ }
1864
+
1865
+ if (key === 'style' && merged.style && value) {
1866
+ merged.style = `${merged.style}; ${value}`.trim();
1867
+ continue;
1868
+ }
1869
+
1870
+ if (typeof merged[key] === 'undefined') {
1871
+ merged[key] = value;
1872
+ }
1873
+ }
1874
+
1875
+ return merged;
1876
+ };
1877
+ const normalize_nodes = function (nodes, state) {
1878
+ const normalized_nodes = [];
1879
+
1880
+ for (let index = 0; index < (nodes || []).length; index++) {
1881
+ const node = nodes[index];
1882
+ if (!node || typeof node !== 'object') {
1883
+ continue;
1884
+ }
1885
+
1886
+ const tag_name = normalize_tag_name(node.tagName);
1887
+
1888
+ if (tag_name === '!doctype') {
1889
+ state.changed = true;
1890
+ continue;
1891
+ }
1892
+
1893
+ if (tag_name === 'html') {
1894
+ state.changed = true;
1895
+ state.root_attributes = merge_attributes(state.root_attributes, node.attributes);
1896
+ normalized_nodes.push.apply(normalized_nodes, normalize_nodes(node.children, state));
1897
+ continue;
1898
+ }
1899
+
1900
+ if (tag_name === 'head') {
1901
+ state.changed = true;
1902
+ normalized_nodes.push.apply(normalized_nodes, normalize_nodes(node.children, state));
1903
+ continue;
1904
+ }
1905
+
1906
+ if (tag_name === 'body') {
1907
+ state.changed = true;
1908
+ state.root_attributes = merge_attributes(state.root_attributes, node.attributes);
1909
+ normalized_nodes.push.apply(normalized_nodes, normalize_nodes(node.children, state));
1910
+ continue;
1911
+ }
1912
+
1913
+ let next_node = node;
1914
+ if (Array.isArray(node.children) && node.children.length) {
1915
+ const next_children = normalize_nodes(node.children, state);
1916
+ if (next_children !== node.children) {
1917
+ next_node = {
1918
+ ...node,
1919
+ children: next_children,
1920
+ };
1921
+ state.changed = true;
1922
+ }
1923
+ }
1924
+
1925
+ normalized_nodes.push(next_node);
1926
+ }
1927
+
1928
+ return normalized_nodes;
1929
+ };
1930
+
1931
+ const [root_node, ...extra_nodes] = doc.progUi;
1932
+ if (!root_node || typeof root_node !== 'object') {
1933
+ return doc;
1934
+ }
1935
+
1936
+ const state = {
1937
+ changed: false,
1938
+ root_attributes: {},
1939
+ };
1940
+
1941
+ const normalized_children = normalize_nodes([...(root_node.children || []), ...extra_nodes], state);
1942
+ const merged_attributes = merge_attributes(root_node.attributes, state.root_attributes);
1943
+
1944
+ if (!state.changed && !Object.keys(state.root_attributes).length) {
1945
+ doc.__xudaRuntimeNormalized = true;
1946
+ return doc;
1947
+ }
1948
+
1949
+ return {
1950
+ ...doc,
1951
+ __xudaRuntimeNormalized: true,
1952
+ progUi: [
1953
+ {
1954
+ ...root_node,
1955
+ attributes: merged_attributes,
1956
+ children: normalized_children,
1957
+ },
1958
+ ],
1959
+ };
1960
+ };
1839
1961
 
1840
1962
  func.runtime.env = {
1841
1963
  get_url_params: function () {
@@ -7951,6 +8073,13 @@ func.utils.DOCS_OBJ = {};
7951
8073
  func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
7952
8074
  if (!idP || idP === '0') return;
7953
8075
 
8076
+ const normalize_runtime_doc = function (doc) {
8077
+ if (!doc || !func.runtime.program?.normalize_doc_for_runtime) {
8078
+ return doc;
8079
+ }
8080
+ return func.runtime.program.normalize_doc_for_runtime(doc);
8081
+ };
8082
+
7954
8083
  var _session = SESSION_OBJ[SESSION_ID];
7955
8084
  const _app_id = _session.app_id;
7956
8085
  if (!DOCS_OBJ[_app_id]) {
@@ -7972,7 +8101,8 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
7972
8101
  }
7973
8102
  let val = _session.project_data?.programs?.[idP];
7974
8103
  if (val) {
7975
- return (DOCS_OBJ[_app_id][idP] = val);
8104
+ DOCS_OBJ[_app_id][idP] = normalize_runtime_doc(val);
8105
+ return DOCS_OBJ[_app_id][idP];
7976
8106
  }
7977
8107
  }
7978
8108
 
@@ -7980,7 +8110,7 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
7980
8110
  const module = await func.common.get_module(SESSION_ID, `xuda-progs-loader-module.mjs`);
7981
8111
 
7982
8112
  if (idP !== 'system') {
7983
- DOCS_OBJ[_app_id][idP] = await module.DOCS_OBJ_get(SESSION_ID, idP);
8113
+ DOCS_OBJ[_app_id][idP] = normalize_runtime_doc(await module.DOCS_OBJ_get(SESSION_ID, idP));
7984
8114
  if (DOCS_OBJ[_app_id][idP] && xu_isEmpty(DOCS_OBJ[_app_id][idP])) {
7985
8115
  await func.utils.remove_cached_objects(SESSION_ID);
7986
8116
 
@@ -17786,6 +17916,68 @@ const create_runtime_head_element = function (doc, tag_name, attributes, asset_k
17786
17916
  return node;
17787
17917
  };
17788
17918
 
17919
+ const queue_runtime_html_script_task = function (task) {
17920
+ const queue =
17921
+ func.runtime.render._html_script_queue ||
17922
+ (func.runtime.render._html_script_queue = {
17923
+ items: [],
17924
+ scheduled: false,
17925
+ running: false,
17926
+ });
17927
+
17928
+ queue.items.push(task);
17929
+
17930
+ if (queue.scheduled || queue.running) {
17931
+ return;
17932
+ }
17933
+
17934
+ queue.scheduled = true;
17935
+
17936
+ const drain_queue = async function () {
17937
+ if (queue.running) {
17938
+ return;
17939
+ }
17940
+
17941
+ queue.running = true;
17942
+ queue.scheduled = false;
17943
+
17944
+ try {
17945
+ while (queue.items.length) {
17946
+ const next_task = queue.items.shift();
17947
+ await next_task();
17948
+ }
17949
+ } catch (error) {
17950
+ console.error(error);
17951
+ } finally {
17952
+ queue.running = false;
17953
+ if (queue.items.length && !queue.scheduled) {
17954
+ queue.scheduled = true;
17955
+ schedule_runtime_html_script_queue();
17956
+ }
17957
+ }
17958
+ };
17959
+
17960
+ const schedule_runtime_html_script_queue = function () {
17961
+ const win = func.runtime.platform.get_window?.();
17962
+ const run_later = function () {
17963
+ setTimeout(function () {
17964
+ drain_queue();
17965
+ }, 0);
17966
+ };
17967
+
17968
+ if (win?.requestAnimationFrame) {
17969
+ win.requestAnimationFrame(function () {
17970
+ win.requestAnimationFrame(run_later);
17971
+ });
17972
+ return;
17973
+ }
17974
+
17975
+ run_later();
17976
+ };
17977
+
17978
+ schedule_runtime_html_script_queue();
17979
+ };
17980
+
17789
17981
  const upsert_runtime_head_element = async function (options) {
17790
17982
  const doc = func.runtime.platform.get_document?.();
17791
17983
  const head = doc?.head;
@@ -17899,19 +18091,21 @@ const render_runtime_html_asset = async function (options) {
17899
18091
  if (!src && !content.trim()) {
17900
18092
  return options.$container;
17901
18093
  }
17902
- await upsert_runtime_head_element({
17903
- tag_name,
17904
- attributes,
17905
- content,
17906
- asset_key,
17907
- signature,
17908
- find_existing_attr: src
17909
- ? {
17910
- name: 'src',
17911
- value: src,
17912
- }
17913
- : null,
17914
- await_load: !!src,
18094
+ queue_runtime_html_script_task(async function () {
18095
+ await upsert_runtime_head_element({
18096
+ tag_name,
18097
+ attributes,
18098
+ content,
18099
+ asset_key,
18100
+ signature,
18101
+ find_existing_attr: src
18102
+ ? {
18103
+ name: 'src',
18104
+ value: src,
18105
+ }
18106
+ : null,
18107
+ await_load: !!src,
18108
+ });
17915
18109
  });
17916
18110
  return options.$container;
17917
18111
  }