@xuda.io/runtime-bundle 1.0.1436 → 1.0.1437
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.
- package/js/xuda-runtime-bundle.js +1464 -69
- package/js/xuda-runtime-bundle.min.js +3 -3
- package/js/xuda-runtime-slim.js +1464 -69
- package/js/xuda-runtime-slim.min.es.js +1464 -69
- package/js/xuda-runtime-slim.min.js +3 -3
- package/js/xuda-server-bundle.min.mjs +1 -1
- package/js/xuda-server-bundle.mjs +901 -6
- package/js/xuda-worker-bundle.js +901 -6
- package/js/xuda-worker-bundle.min.js +1 -1
- package/js/xuda_common-bundle.js +216 -6
- package/js/xuda_common-bundle.min.js +1 -1
- package/package.json +1 -1
|
@@ -23706,7 +23706,30 @@ func.runtime.platform.emit = function (name, data) {
|
|
|
23706
23706
|
};
|
|
23707
23707
|
|
|
23708
23708
|
// ── Platform helpers for DOM-independent resource loading ──
|
|
23709
|
-
func.runtime.platform.
|
|
23709
|
+
func.runtime.platform.apply_element_attributes = function (node, attributes, excluded_keys = []) {
|
|
23710
|
+
if (!node?.setAttribute || !attributes) {
|
|
23711
|
+
return node;
|
|
23712
|
+
}
|
|
23713
|
+
|
|
23714
|
+
const excluded = new Set(excluded_keys || []);
|
|
23715
|
+
const attr_keys = Object.keys(attributes);
|
|
23716
|
+
for (let index = 0; index < attr_keys.length; index++) {
|
|
23717
|
+
const key = attr_keys[index];
|
|
23718
|
+
if (!key || excluded.has(key)) {
|
|
23719
|
+
continue;
|
|
23720
|
+
}
|
|
23721
|
+
|
|
23722
|
+
const value = attributes[key];
|
|
23723
|
+
if (value === false || typeof value === 'undefined') {
|
|
23724
|
+
continue;
|
|
23725
|
+
}
|
|
23726
|
+
|
|
23727
|
+
node.setAttribute(key, value === null ? '' : `${value}`);
|
|
23728
|
+
}
|
|
23729
|
+
|
|
23730
|
+
return node;
|
|
23731
|
+
};
|
|
23732
|
+
func.runtime.platform.load_script = function (url, type, callback, attributes) {
|
|
23710
23733
|
const doc = func.runtime.platform.get_document();
|
|
23711
23734
|
if (!doc?.createElement || !doc?.head?.appendChild) {
|
|
23712
23735
|
if (callback) {
|
|
@@ -23714,19 +23737,63 @@ func.runtime.platform.load_script = function (url, type, callback) {
|
|
|
23714
23737
|
}
|
|
23715
23738
|
return;
|
|
23716
23739
|
}
|
|
23740
|
+
const find_existing_script = function () {
|
|
23741
|
+
const asset_key = attributes?.['data-xuda-asset-key'];
|
|
23742
|
+
const scripts = doc.querySelectorAll ? Array.from(doc.querySelectorAll('script')) : [];
|
|
23743
|
+
return scripts.find(function (script) {
|
|
23744
|
+
if (asset_key && script.getAttribute('data-xuda-asset-key') === asset_key) {
|
|
23745
|
+
return true;
|
|
23746
|
+
}
|
|
23747
|
+
return !!(url && script.getAttribute('src') === url);
|
|
23748
|
+
}) || null;
|
|
23749
|
+
};
|
|
23750
|
+
|
|
23751
|
+
const existing_script = find_existing_script();
|
|
23752
|
+
if (existing_script) {
|
|
23753
|
+
if (callback) {
|
|
23754
|
+
if (existing_script.getAttribute('data-xuda-loaded') === 'true' || !url) {
|
|
23755
|
+
callback();
|
|
23756
|
+
} else {
|
|
23757
|
+
existing_script.addEventListener('load', callback, { once: true });
|
|
23758
|
+
existing_script.addEventListener('error', callback, { once: true });
|
|
23759
|
+
}
|
|
23760
|
+
}
|
|
23761
|
+
return existing_script;
|
|
23762
|
+
}
|
|
23763
|
+
|
|
23717
23764
|
const script = doc.createElement('script');
|
|
23718
23765
|
script.src = url;
|
|
23719
23766
|
if (type) script.type = type;
|
|
23720
|
-
script
|
|
23767
|
+
func.runtime.platform.apply_element_attributes(script, attributes, ['src', 'type']);
|
|
23768
|
+
script.onload = function () {
|
|
23769
|
+
script.setAttribute('data-xuda-loaded', 'true');
|
|
23770
|
+
if (callback) {
|
|
23771
|
+
callback();
|
|
23772
|
+
}
|
|
23773
|
+
};
|
|
23774
|
+
script.onerror = function () {
|
|
23775
|
+
if (callback) {
|
|
23776
|
+
callback();
|
|
23777
|
+
}
|
|
23778
|
+
};
|
|
23721
23779
|
doc.head.appendChild(script);
|
|
23780
|
+
return script;
|
|
23722
23781
|
};
|
|
23723
|
-
func.runtime.platform.load_css = function (href) {
|
|
23782
|
+
func.runtime.platform.load_css = function (href, attributes) {
|
|
23724
23783
|
const doc = func.runtime.platform.get_document();
|
|
23725
23784
|
if (!doc?.createElement || !doc?.head) {
|
|
23726
23785
|
return;
|
|
23727
23786
|
}
|
|
23728
23787
|
try {
|
|
23729
|
-
|
|
23788
|
+
const asset_key = attributes?.['data-xuda-asset-key'];
|
|
23789
|
+
const existing_links = doc.querySelectorAll ? Array.from(doc.querySelectorAll('link')) : [];
|
|
23790
|
+
const existing = existing_links.find(function (link) {
|
|
23791
|
+
if (asset_key && link.getAttribute('data-xuda-asset-key') === asset_key) {
|
|
23792
|
+
return true;
|
|
23793
|
+
}
|
|
23794
|
+
return !!(href && link.getAttribute('href') === href);
|
|
23795
|
+
});
|
|
23796
|
+
if (existing) return existing;
|
|
23730
23797
|
} catch (err) {
|
|
23731
23798
|
return;
|
|
23732
23799
|
}
|
|
@@ -23734,7 +23801,9 @@ func.runtime.platform.load_css = function (href) {
|
|
|
23734
23801
|
link.rel = 'stylesheet';
|
|
23735
23802
|
link.type = 'text/css';
|
|
23736
23803
|
link.href = href;
|
|
23804
|
+
func.runtime.platform.apply_element_attributes(link, attributes, ['href']);
|
|
23737
23805
|
doc.head.insertBefore(link, doc.head.firstChild);
|
|
23806
|
+
return link;
|
|
23738
23807
|
};
|
|
23739
23808
|
func.runtime.platform.remove_js_css = function (filename, filetype) {
|
|
23740
23809
|
const doc = func.runtime.platform.get_document();
|
|
@@ -24025,6 +24094,147 @@ func.runtime.workers.delete_promise = function (SESSION_ID, worker_id, promise_q
|
|
|
24025
24094
|
delete registry_entry.promise_queue[promise_queue_id];
|
|
24026
24095
|
return true;
|
|
24027
24096
|
};
|
|
24097
|
+
func.runtime.render.clone_runtime_options = function (value) {
|
|
24098
|
+
if (typeof structuredClone === 'function') {
|
|
24099
|
+
try {
|
|
24100
|
+
return structuredClone(value);
|
|
24101
|
+
} catch (_) {}
|
|
24102
|
+
}
|
|
24103
|
+
|
|
24104
|
+
if (Array.isArray(value)) {
|
|
24105
|
+
return value.map(function (item) {
|
|
24106
|
+
return func.runtime.render.clone_runtime_options(item);
|
|
24107
|
+
});
|
|
24108
|
+
}
|
|
24109
|
+
|
|
24110
|
+
if (value && typeof value === 'object') {
|
|
24111
|
+
const cloned = {};
|
|
24112
|
+
const keys = Object.keys(value);
|
|
24113
|
+
for (let index = 0; index < keys.length; index++) {
|
|
24114
|
+
const key = keys[index];
|
|
24115
|
+
cloned[key] = func.runtime.render.clone_runtime_options(value[key]);
|
|
24116
|
+
}
|
|
24117
|
+
return cloned;
|
|
24118
|
+
}
|
|
24119
|
+
|
|
24120
|
+
return value;
|
|
24121
|
+
};
|
|
24122
|
+
func.runtime.render.normalize_runtime_bootstrap = function (raw_options = {}) {
|
|
24123
|
+
const options = raw_options || {};
|
|
24124
|
+
let app_computing_mode = options.app_computing_mode || '';
|
|
24125
|
+
let app_render_mode = options.app_render_mode || '';
|
|
24126
|
+
let app_client_activation = options.app_client_activation || '';
|
|
24127
|
+
let ssr_payload = options.ssr_payload || null;
|
|
24128
|
+
|
|
24129
|
+
if (typeof ssr_payload === 'string') {
|
|
24130
|
+
try {
|
|
24131
|
+
ssr_payload = JSON.parse(ssr_payload);
|
|
24132
|
+
} catch (_) {
|
|
24133
|
+
ssr_payload = null;
|
|
24134
|
+
}
|
|
24135
|
+
}
|
|
24136
|
+
|
|
24137
|
+
if (ssr_payload && typeof ssr_payload === 'object') {
|
|
24138
|
+
ssr_payload = func.runtime.render.clone_runtime_options(ssr_payload);
|
|
24139
|
+
}
|
|
24140
|
+
|
|
24141
|
+
if (!app_computing_mode) {
|
|
24142
|
+
if (app_render_mode === 'ssr_first_page' || app_render_mode === 'ssr_full') {
|
|
24143
|
+
app_computing_mode = 'server';
|
|
24144
|
+
} else {
|
|
24145
|
+
app_computing_mode = 'main';
|
|
24146
|
+
}
|
|
24147
|
+
}
|
|
24148
|
+
|
|
24149
|
+
switch (app_computing_mode) {
|
|
24150
|
+
case 'main':
|
|
24151
|
+
app_render_mode = 'csr';
|
|
24152
|
+
app_client_activation = 'none';
|
|
24153
|
+
break;
|
|
24154
|
+
|
|
24155
|
+
case 'worker':
|
|
24156
|
+
app_render_mode = 'csr';
|
|
24157
|
+
app_client_activation = 'none';
|
|
24158
|
+
break;
|
|
24159
|
+
|
|
24160
|
+
default:
|
|
24161
|
+
app_computing_mode = 'server';
|
|
24162
|
+
if (app_render_mode !== 'ssr_full') {
|
|
24163
|
+
app_render_mode = 'ssr_first_page';
|
|
24164
|
+
}
|
|
24165
|
+
app_client_activation = app_render_mode === 'ssr_full' ? 'hydrate' : 'takeover';
|
|
24166
|
+
break;
|
|
24167
|
+
}
|
|
24168
|
+
|
|
24169
|
+
if (ssr_payload && typeof ssr_payload === 'object') {
|
|
24170
|
+
if (!ssr_payload.app_render_mode) {
|
|
24171
|
+
ssr_payload.app_render_mode = app_render_mode;
|
|
24172
|
+
}
|
|
24173
|
+
if (!ssr_payload.app_client_activation) {
|
|
24174
|
+
ssr_payload.app_client_activation = app_client_activation;
|
|
24175
|
+
}
|
|
24176
|
+
if (!ssr_payload.app_computing_mode) {
|
|
24177
|
+
ssr_payload.app_computing_mode = app_computing_mode;
|
|
24178
|
+
}
|
|
24179
|
+
}
|
|
24180
|
+
|
|
24181
|
+
return {
|
|
24182
|
+
app_computing_mode,
|
|
24183
|
+
app_render_mode,
|
|
24184
|
+
app_client_activation,
|
|
24185
|
+
ssr_payload,
|
|
24186
|
+
};
|
|
24187
|
+
};
|
|
24188
|
+
func.runtime.render.apply_runtime_bootstrap_defaults = function (target = {}) {
|
|
24189
|
+
const normalized = func.runtime.render.normalize_runtime_bootstrap(target);
|
|
24190
|
+
target.app_computing_mode = normalized.app_computing_mode;
|
|
24191
|
+
target.app_render_mode = normalized.app_render_mode;
|
|
24192
|
+
target.app_client_activation = normalized.app_client_activation;
|
|
24193
|
+
target.ssr_payload = normalized.ssr_payload;
|
|
24194
|
+
return normalized;
|
|
24195
|
+
};
|
|
24196
|
+
func.runtime.render.is_server_render_mode = function (target = {}) {
|
|
24197
|
+
const normalized = func.runtime.render.normalize_runtime_bootstrap(target?.opt || target);
|
|
24198
|
+
return normalized.app_computing_mode === 'server' && normalized.app_render_mode !== 'csr';
|
|
24199
|
+
};
|
|
24200
|
+
func.runtime.render.is_takeover_mode = function (target = {}) {
|
|
24201
|
+
const normalized = func.runtime.render.normalize_runtime_bootstrap(target?.opt || target);
|
|
24202
|
+
return normalized.app_client_activation === 'takeover';
|
|
24203
|
+
};
|
|
24204
|
+
func.runtime.render.is_hydration_mode = function (target = {}) {
|
|
24205
|
+
const normalized = func.runtime.render.normalize_runtime_bootstrap(target?.opt || target);
|
|
24206
|
+
return normalized.app_client_activation === 'hydrate';
|
|
24207
|
+
};
|
|
24208
|
+
func.runtime.render.get_ssr_payload = function (target = {}) {
|
|
24209
|
+
if (target?.opt?.ssr_payload) {
|
|
24210
|
+
return target.opt.ssr_payload;
|
|
24211
|
+
}
|
|
24212
|
+
if (target?.ssr_payload) {
|
|
24213
|
+
return target.ssr_payload;
|
|
24214
|
+
}
|
|
24215
|
+
const win = func.runtime.platform.get_window();
|
|
24216
|
+
return win?.__XUDA_SSR__ || null;
|
|
24217
|
+
};
|
|
24218
|
+
func.runtime.render.should_use_ssr_payload = function (SESSION_ID, paramsP) {
|
|
24219
|
+
const session = SESSION_OBJ?.[SESSION_ID];
|
|
24220
|
+
const payload = func.runtime.render.get_ssr_payload(session);
|
|
24221
|
+
if (!payload || payload._consumed) {
|
|
24222
|
+
return false;
|
|
24223
|
+
}
|
|
24224
|
+
if (paramsP?.prog_id && payload.prog_id && payload.prog_id !== paramsP.prog_id) {
|
|
24225
|
+
return false;
|
|
24226
|
+
}
|
|
24227
|
+
return true;
|
|
24228
|
+
};
|
|
24229
|
+
func.runtime.render.mark_ssr_payload_consumed = function (SESSION_ID) {
|
|
24230
|
+
const session = SESSION_OBJ?.[SESSION_ID];
|
|
24231
|
+
const payload = func.runtime.render.get_ssr_payload(session);
|
|
24232
|
+
if (!payload || typeof payload !== 'object') {
|
|
24233
|
+
return false;
|
|
24234
|
+
}
|
|
24235
|
+
payload._consumed = true;
|
|
24236
|
+
return true;
|
|
24237
|
+
};
|
|
24028
24238
|
func.runtime.render.get_root_data_system = function (SESSION_ID) {
|
|
24029
24239
|
return SESSION_OBJ[SESSION_ID]?.DS_GLB?.[0]?.data_system || null;
|
|
24030
24240
|
};
|
|
@@ -24428,10 +24638,10 @@ func.runtime.resources.load_cdn = async function (SESSION_ID, resource) {
|
|
|
24428
24638
|
await func.utils.load_js_on_demand(normalized_resource.src);
|
|
24429
24639
|
break;
|
|
24430
24640
|
case 'css':
|
|
24431
|
-
|
|
24641
|
+
func.runtime.platform.load_css(normalized_resource.src);
|
|
24432
24642
|
break;
|
|
24433
24643
|
case 'module':
|
|
24434
|
-
func.utils.load_js_on_demand(normalized_resource.src, 'module');
|
|
24644
|
+
await func.utils.load_js_on_demand(normalized_resource.src, 'module');
|
|
24435
24645
|
break;
|
|
24436
24646
|
default:
|
|
24437
24647
|
await func.utils.load_js_on_demand(normalized_resource.src);
|
|
@@ -25744,30 +25954,715 @@ func.common.get_data_from_websocket = async function (SESSION_ID, serviceP, data
|
|
|
25744
25954
|
// // The .toString(36) method handles the conversion to an alphanumeric representation (0-9, a-z).
|
|
25745
25955
|
// const base36Hash = bigInt.toString(36);
|
|
25746
25956
|
|
|
25747
|
-
// // 4. Take the first 10 characters. If it's shorter, it will just return the whole string.
|
|
25748
|
-
// // For a 64-bit integer, the Base36 representation will be about 13 characters long,
|
|
25749
|
-
// // so slicing is a reliable way to get a fixed length.
|
|
25750
|
-
// const shortHash = base36Hash.slice(0, 10);
|
|
25957
|
+
// // 4. Take the first 10 characters. If it's shorter, it will just return the whole string.
|
|
25958
|
+
// // For a 64-bit integer, the Base36 representation will be about 13 characters long,
|
|
25959
|
+
// // so slicing is a reliable way to get a fixed length.
|
|
25960
|
+
// const shortHash = base36Hash.slice(0, 10);
|
|
25961
|
+
|
|
25962
|
+
// // 5. Pad the start in the unlikely case the hash is shorter than 10 characters.
|
|
25963
|
+
// // This ensures the output is always exactly 10 characters long.
|
|
25964
|
+
// return shortHash.padStart(10, '0');
|
|
25965
|
+
// };
|
|
25966
|
+
|
|
25967
|
+
func.common.fastHash = function (inputString) {
|
|
25968
|
+
let hash = 0x811c9dc5; // FNV offset basis
|
|
25969
|
+
|
|
25970
|
+
for (let i = 0; i < inputString.length; i++) {
|
|
25971
|
+
hash ^= inputString.charCodeAt(i);
|
|
25972
|
+
// FNV prime multiplication with 32-bit overflow
|
|
25973
|
+
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
25974
|
+
}
|
|
25975
|
+
|
|
25976
|
+
// Convert to base36 and pad to 10 characters
|
|
25977
|
+
return ((hash >>> 0).toString(36) + '0000000000').slice(0, 10);
|
|
25978
|
+
};
|
|
25979
|
+
|
|
25980
|
+
glb.new_xu_render = false;
|
|
25981
|
+
func.runtime = func.runtime || {};
|
|
25982
|
+
func.runtime.ui = func.runtime.ui || {};
|
|
25983
|
+
func.runtime.render = func.runtime.render || {};
|
|
25984
|
+
func.runtime.widgets = func.runtime.widgets || {};
|
|
25985
|
+
|
|
25986
|
+
// Shared render-tree contract helpers live here so browser and headless runtimes can resolve the same UI structure.
|
|
25987
|
+
|
|
25988
|
+
func.runtime.render.TREE_CONTRACT_VERSION = func.runtime.render.TREE_CONTRACT_VERSION || 'xuda.render_tree.v1';
|
|
25989
|
+
func.runtime.render._tree_widget_capability_cache = func.runtime.render._tree_widget_capability_cache || {};
|
|
25990
|
+
|
|
25991
|
+
func.runtime.render.safe_clone_tree_value = function (value) {
|
|
25992
|
+
if (typeof structuredClone === 'function') {
|
|
25993
|
+
try {
|
|
25994
|
+
return structuredClone(value);
|
|
25995
|
+
} catch (_) {
|
|
25996
|
+
// Fall through to the recursive clone below.
|
|
25997
|
+
}
|
|
25998
|
+
}
|
|
25999
|
+
|
|
26000
|
+
if (Array.isArray(value)) {
|
|
26001
|
+
return value.map(function (item) {
|
|
26002
|
+
return func.runtime.render.safe_clone_tree_value(item);
|
|
26003
|
+
});
|
|
26004
|
+
}
|
|
26005
|
+
|
|
26006
|
+
if (value && typeof value === 'object') {
|
|
26007
|
+
const cloned = {};
|
|
26008
|
+
const keys = Object.keys(value);
|
|
26009
|
+
for (let index = 0; index < keys.length; index++) {
|
|
26010
|
+
const key = keys[index];
|
|
26011
|
+
cloned[key] = func.runtime.render.safe_clone_tree_value(value[key]);
|
|
26012
|
+
}
|
|
26013
|
+
return cloned;
|
|
26014
|
+
}
|
|
26015
|
+
|
|
26016
|
+
return value;
|
|
26017
|
+
};
|
|
26018
|
+
func.runtime.render.sort_tree_debug_value = function (value) {
|
|
26019
|
+
if (Array.isArray(value)) {
|
|
26020
|
+
return value.map(function (item) {
|
|
26021
|
+
return func.runtime.render.sort_tree_debug_value(item);
|
|
26022
|
+
});
|
|
26023
|
+
}
|
|
26024
|
+
|
|
26025
|
+
if (value && typeof value === 'object') {
|
|
26026
|
+
const sorted = {};
|
|
26027
|
+
const keys = Object.keys(value).sort();
|
|
26028
|
+
for (let index = 0; index < keys.length; index++) {
|
|
26029
|
+
const key = keys[index];
|
|
26030
|
+
sorted[key] = func.runtime.render.sort_tree_debug_value(value[key]);
|
|
26031
|
+
}
|
|
26032
|
+
return sorted;
|
|
26033
|
+
}
|
|
26034
|
+
|
|
26035
|
+
return value;
|
|
26036
|
+
};
|
|
26037
|
+
func.runtime.render.is_tree_node = function (nodeP) {
|
|
26038
|
+
return !!nodeP?.contract && nodeP.contract === func.runtime.render.TREE_CONTRACT_VERSION;
|
|
26039
|
+
};
|
|
26040
|
+
func.runtime.render.get_tree_source_node = function (nodeP) {
|
|
26041
|
+
if (!func.runtime.render.is_tree_node(nodeP)) {
|
|
26042
|
+
return nodeP || null;
|
|
26043
|
+
}
|
|
26044
|
+
return nodeP?.meta?.source_node || null;
|
|
26045
|
+
};
|
|
26046
|
+
func.runtime.render.get_tree_source_snapshot = function (nodeP) {
|
|
26047
|
+
if (!func.runtime.render.is_tree_node(nodeP)) {
|
|
26048
|
+
return func.runtime.render.safe_clone_tree_value(nodeP);
|
|
26049
|
+
}
|
|
26050
|
+
return nodeP?.meta?.source_snapshot || null;
|
|
26051
|
+
};
|
|
26052
|
+
func.runtime.render.get_tree_node_kind = function (nodeP) {
|
|
26053
|
+
const tag_name = typeof nodeP?.tagName === 'string' ? nodeP.tagName.toLowerCase() : '';
|
|
26054
|
+
const node_type = typeof nodeP?.type === 'string' ? nodeP.type.toLowerCase() : '';
|
|
26055
|
+
|
|
26056
|
+
if (tag_name === 'xu-widget') return 'widget';
|
|
26057
|
+
if (tag_name === 'xu-single-view') return 'single_view';
|
|
26058
|
+
if (tag_name === 'xu-multi-view') return 'multi_view';
|
|
26059
|
+
if (tag_name === 'xu-panel') return 'panel';
|
|
26060
|
+
if (tag_name === 'xu-teleport') return 'teleport';
|
|
26061
|
+
if (tag_name === 'xurender') return 'placeholder';
|
|
26062
|
+
if (tag_name === '#text' || node_type === 'text') return 'text';
|
|
26063
|
+
if (!tag_name && typeof nodeP?.content === 'string' && !Array.isArray(nodeP?.children)) return 'text';
|
|
26064
|
+
return 'element';
|
|
26065
|
+
};
|
|
26066
|
+
func.runtime.render.get_tree_node_id = function (nodeP, pathP) {
|
|
26067
|
+
if (nodeP?.id) {
|
|
26068
|
+
return nodeP.id;
|
|
26069
|
+
}
|
|
26070
|
+
if (nodeP?.id_org) {
|
|
26071
|
+
return nodeP.id_org;
|
|
26072
|
+
}
|
|
26073
|
+
const normalized_path = Array.isArray(pathP) && pathP.length ? pathP.join('.') : 'root';
|
|
26074
|
+
return `tree-node-${normalized_path}`;
|
|
26075
|
+
};
|
|
26076
|
+
func.runtime.render.get_tree_controls = function (attributes) {
|
|
26077
|
+
const attrs = attributes || {};
|
|
26078
|
+
const get_first_defined = function (keys) {
|
|
26079
|
+
for (let index = 0; index < keys.length; index++) {
|
|
26080
|
+
const key = keys[index];
|
|
26081
|
+
if (Object.prototype.hasOwnProperty.call(attrs, key)) {
|
|
26082
|
+
return attrs[key];
|
|
26083
|
+
}
|
|
26084
|
+
}
|
|
26085
|
+
return null;
|
|
26086
|
+
};
|
|
26087
|
+
return {
|
|
26088
|
+
xu_for: get_first_defined(['xu-for', 'xu-exp:xu-for']),
|
|
26089
|
+
xu_if: get_first_defined(['xu-if', 'xu-exp:xu-if']),
|
|
26090
|
+
xu_render: get_first_defined(['xu-render', 'xu-exp:xu-render']),
|
|
26091
|
+
};
|
|
26092
|
+
};
|
|
26093
|
+
func.runtime.render.get_tree_node_capabilities = async function (options) {
|
|
26094
|
+
const attributes = options?.attributes || {};
|
|
26095
|
+
const plugin_name = attributes['xu-widget'];
|
|
26096
|
+
if (!plugin_name) {
|
|
26097
|
+
return null;
|
|
26098
|
+
}
|
|
26099
|
+
|
|
26100
|
+
const cache = func.runtime.render._tree_widget_capability_cache;
|
|
26101
|
+
if (cache[plugin_name]) {
|
|
26102
|
+
return func.runtime.render.safe_clone_tree_value(cache[plugin_name]);
|
|
26103
|
+
}
|
|
26104
|
+
|
|
26105
|
+
let capabilities = {
|
|
26106
|
+
browser: true,
|
|
26107
|
+
headless: false,
|
|
26108
|
+
};
|
|
26109
|
+
|
|
26110
|
+
try {
|
|
26111
|
+
if (options.SESSION_ID && options.paramsP && func.runtime.widgets?.create_context && func.runtime.widgets?.get_definition) {
|
|
26112
|
+
const widget_context = func.runtime.widgets.create_context(options.SESSION_ID, options.paramsP, attributes);
|
|
26113
|
+
const definition = await func.runtime.widgets.get_definition(widget_context);
|
|
26114
|
+
capabilities = func.runtime.widgets.normalize_capabilities(definition);
|
|
26115
|
+
}
|
|
26116
|
+
} catch (_) {
|
|
26117
|
+
// Keep the safe browser-only default when the widget definition is unavailable.
|
|
26118
|
+
}
|
|
26119
|
+
|
|
26120
|
+
cache[plugin_name] = capabilities;
|
|
26121
|
+
return func.runtime.render.safe_clone_tree_value(capabilities);
|
|
26122
|
+
};
|
|
26123
|
+
func.runtime.render.ensure_tree_node = async function (options) {
|
|
26124
|
+
if (!options?.nodeP) {
|
|
26125
|
+
return null;
|
|
26126
|
+
}
|
|
26127
|
+
if (func.runtime.render.is_tree_node(options.nodeP)) {
|
|
26128
|
+
return options.nodeP;
|
|
26129
|
+
}
|
|
26130
|
+
return await func.runtime.render.build_tree(options);
|
|
26131
|
+
};
|
|
26132
|
+
func.runtime.render.build_tree = async function (options) {
|
|
26133
|
+
if (Array.isArray(options?.nodeP)) {
|
|
26134
|
+
return await func.runtime.render.build_tree_list({
|
|
26135
|
+
...options,
|
|
26136
|
+
nodesP: options.nodeP,
|
|
26137
|
+
});
|
|
26138
|
+
}
|
|
26139
|
+
|
|
26140
|
+
const nodeP = options?.nodeP;
|
|
26141
|
+
if (!nodeP) {
|
|
26142
|
+
return null;
|
|
26143
|
+
}
|
|
26144
|
+
if (func.runtime.render.is_tree_node(nodeP)) {
|
|
26145
|
+
return nodeP;
|
|
26146
|
+
}
|
|
26147
|
+
|
|
26148
|
+
const pathP = Array.isArray(options?.pathP) ? options.pathP.slice() : [];
|
|
26149
|
+
const tree_path = pathP.length ? pathP.slice() : [0];
|
|
26150
|
+
const attributes = func.runtime.render.safe_clone_tree_value(nodeP.attributes || {});
|
|
26151
|
+
if (typeof nodeP.content !== 'undefined' && typeof attributes['xu-content'] === 'undefined') {
|
|
26152
|
+
attributes['xu-content'] = func.runtime.render.safe_clone_tree_value(nodeP.content);
|
|
26153
|
+
}
|
|
26154
|
+
|
|
26155
|
+
const widget_capabilities = await func.runtime.render.get_tree_node_capabilities({
|
|
26156
|
+
SESSION_ID: options?.SESSION_ID,
|
|
26157
|
+
paramsP: options?.paramsP,
|
|
26158
|
+
attributes,
|
|
26159
|
+
});
|
|
26160
|
+
const children = [];
|
|
26161
|
+
const child_nodes = Array.isArray(nodeP.children) ? nodeP.children : [];
|
|
26162
|
+
const parent_tree_id = tree_path.join('.');
|
|
26163
|
+
|
|
26164
|
+
for (let index = 0; index < child_nodes.length; index++) {
|
|
26165
|
+
const child_tree = await func.runtime.render.build_tree({
|
|
26166
|
+
...options,
|
|
26167
|
+
nodeP: child_nodes[index],
|
|
26168
|
+
pathP: tree_path.concat(index),
|
|
26169
|
+
parent_tree_id: parent_tree_id,
|
|
26170
|
+
keyP: index,
|
|
26171
|
+
parent_nodeP: nodeP,
|
|
26172
|
+
});
|
|
26173
|
+
if (child_tree) {
|
|
26174
|
+
children.push(child_tree);
|
|
26175
|
+
}
|
|
26176
|
+
}
|
|
26177
|
+
|
|
26178
|
+
const tree = {
|
|
26179
|
+
contract: func.runtime.render.TREE_CONTRACT_VERSION,
|
|
26180
|
+
id: func.runtime.render.get_tree_node_id(nodeP, tree_path),
|
|
26181
|
+
xu_tree_id: `tree.${tree_path.join('.')}`,
|
|
26182
|
+
kind: func.runtime.render.get_tree_node_kind(nodeP),
|
|
26183
|
+
tagName: nodeP.tagName || null,
|
|
26184
|
+
attributes,
|
|
26185
|
+
text: typeof nodeP.text !== 'undefined' ? func.runtime.render.safe_clone_tree_value(nodeP.text) : null,
|
|
26186
|
+
content: typeof nodeP.content !== 'undefined' ? func.runtime.render.safe_clone_tree_value(nodeP.content) : null,
|
|
26187
|
+
children,
|
|
26188
|
+
meta: {
|
|
26189
|
+
tree_id: tree_path.join('.'),
|
|
26190
|
+
path: tree_path,
|
|
26191
|
+
parent_tree_id: options?.parent_tree_id || null,
|
|
26192
|
+
key: typeof options?.keyP === 'undefined' ? null : options.keyP,
|
|
26193
|
+
recordid: nodeP?.recordid || null,
|
|
26194
|
+
dependency_fields: func.runtime.render.safe_clone_tree_value(nodeP?.dependency_fields || null),
|
|
26195
|
+
iterate_info: func.runtime.render.safe_clone_tree_value(options?.parent_infoP?.iterate_info || nodeP?.iterate_info || null),
|
|
26196
|
+
controls: func.runtime.render.get_tree_controls(attributes),
|
|
26197
|
+
capabilities: widget_capabilities,
|
|
26198
|
+
widget: attributes['xu-widget']
|
|
26199
|
+
? {
|
|
26200
|
+
plugin_name: attributes['xu-widget'],
|
|
26201
|
+
method: attributes['xu-method'] || '_default',
|
|
26202
|
+
capabilities: widget_capabilities,
|
|
26203
|
+
}
|
|
26204
|
+
: null,
|
|
26205
|
+
source_node_id: nodeP?.id || nodeP?.id_org || null,
|
|
26206
|
+
source_node: nodeP,
|
|
26207
|
+
source_snapshot: func.runtime.ui?.get_node_snapshot
|
|
26208
|
+
? func.runtime.ui.get_node_snapshot(nodeP)
|
|
26209
|
+
: func.runtime.render.safe_clone_tree_value(nodeP),
|
|
26210
|
+
},
|
|
26211
|
+
};
|
|
26212
|
+
|
|
26213
|
+
return tree;
|
|
26214
|
+
};
|
|
26215
|
+
func.runtime.render.build_tree_list = async function (options) {
|
|
26216
|
+
const nodes = Array.isArray(options?.nodesP) ? options.nodesP : [];
|
|
26217
|
+
const trees = [];
|
|
26218
|
+
|
|
26219
|
+
for (let index = 0; index < nodes.length; index++) {
|
|
26220
|
+
const tree = await func.runtime.render.build_tree({
|
|
26221
|
+
...options,
|
|
26222
|
+
nodeP: nodes[index],
|
|
26223
|
+
pathP: Array.isArray(options?.pathP) && options.pathP.length ? options.pathP.concat(index) : [index],
|
|
26224
|
+
keyP: index,
|
|
26225
|
+
});
|
|
26226
|
+
if (tree) {
|
|
26227
|
+
trees.push(tree);
|
|
26228
|
+
}
|
|
26229
|
+
}
|
|
26230
|
+
|
|
26231
|
+
return trees;
|
|
26232
|
+
};
|
|
26233
|
+
func.runtime.render.sanitize_tree_for_debug = function (treeP) {
|
|
26234
|
+
if (Array.isArray(treeP)) {
|
|
26235
|
+
return treeP.map(function (child) {
|
|
26236
|
+
return func.runtime.render.sanitize_tree_for_debug(child);
|
|
26237
|
+
});
|
|
26238
|
+
}
|
|
26239
|
+
|
|
26240
|
+
if (!func.runtime.render.is_tree_node(treeP)) {
|
|
26241
|
+
return func.runtime.render.sort_tree_debug_value(func.runtime.render.safe_clone_tree_value(treeP));
|
|
26242
|
+
}
|
|
26243
|
+
|
|
26244
|
+
return {
|
|
26245
|
+
contract: treeP.contract,
|
|
26246
|
+
id: treeP.id,
|
|
26247
|
+
xu_tree_id: treeP.xu_tree_id || null,
|
|
26248
|
+
kind: treeP.kind,
|
|
26249
|
+
tagName: treeP.tagName,
|
|
26250
|
+
attributes: func.runtime.render.sort_tree_debug_value(treeP.attributes || {}),
|
|
26251
|
+
text: treeP.text,
|
|
26252
|
+
content: treeP.content,
|
|
26253
|
+
children: treeP.children.map(function (child) {
|
|
26254
|
+
return func.runtime.render.sanitize_tree_for_debug(child);
|
|
26255
|
+
}),
|
|
26256
|
+
meta: {
|
|
26257
|
+
tree_id: treeP.meta?.tree_id || null,
|
|
26258
|
+
path: func.runtime.render.safe_clone_tree_value(treeP.meta?.path || []),
|
|
26259
|
+
parent_tree_id: treeP.meta?.parent_tree_id || null,
|
|
26260
|
+
key: typeof treeP.meta?.key === 'undefined' ? null : treeP.meta.key,
|
|
26261
|
+
recordid: treeP.meta?.recordid || null,
|
|
26262
|
+
dependency_fields: func.runtime.render.sort_tree_debug_value(treeP.meta?.dependency_fields || null),
|
|
26263
|
+
iterate_info: func.runtime.render.sort_tree_debug_value(treeP.meta?.iterate_info || null),
|
|
26264
|
+
controls: func.runtime.render.sort_tree_debug_value(treeP.meta?.controls || null),
|
|
26265
|
+
capabilities: func.runtime.render.sort_tree_debug_value(treeP.meta?.capabilities || null),
|
|
26266
|
+
widget: treeP.meta?.widget
|
|
26267
|
+
? {
|
|
26268
|
+
plugin_name: treeP.meta.widget.plugin_name,
|
|
26269
|
+
method: treeP.meta.widget.method,
|
|
26270
|
+
capabilities: func.runtime.render.sort_tree_debug_value(treeP.meta.widget.capabilities || null),
|
|
26271
|
+
}
|
|
26272
|
+
: null,
|
|
26273
|
+
source_node_id: treeP.meta?.source_node_id || null,
|
|
26274
|
+
},
|
|
26275
|
+
};
|
|
26276
|
+
};
|
|
26277
|
+
func.runtime.render.serialize_tree = function (treeP, spacing = 2) {
|
|
26278
|
+
return JSON.stringify(func.runtime.render.sanitize_tree_for_debug(treeP), null, spacing);
|
|
26279
|
+
};
|
|
26280
|
+
func.runtime = func.runtime || {};
|
|
26281
|
+
func.runtime.ui = func.runtime.ui || {};
|
|
26282
|
+
func.runtime.render = func.runtime.render || {};
|
|
26283
|
+
func.runtime.widgets = func.runtime.widgets || {};
|
|
26284
|
+
|
|
26285
|
+
// Shared string-renderer helpers live here so headless/server runtimes can materialize the render tree without a DOM.
|
|
26286
|
+
|
|
26287
|
+
func.runtime.render.HTML_VOID_TAGS = func.runtime.render.HTML_VOID_TAGS || {
|
|
26288
|
+
area: true,
|
|
26289
|
+
base: true,
|
|
26290
|
+
br: true,
|
|
26291
|
+
col: true,
|
|
26292
|
+
embed: true,
|
|
26293
|
+
hr: true,
|
|
26294
|
+
img: true,
|
|
26295
|
+
input: true,
|
|
26296
|
+
link: true,
|
|
26297
|
+
meta: true,
|
|
26298
|
+
param: true,
|
|
26299
|
+
source: true,
|
|
26300
|
+
track: true,
|
|
26301
|
+
wbr: true,
|
|
26302
|
+
};
|
|
26303
|
+
func.runtime.render.escape_html = function (value) {
|
|
26304
|
+
return `${value ?? ''}`
|
|
26305
|
+
.replaceAll('&', '&')
|
|
26306
|
+
.replaceAll('<', '<')
|
|
26307
|
+
.replaceAll('>', '>')
|
|
26308
|
+
.replaceAll('"', '"')
|
|
26309
|
+
.replaceAll("'", ''');
|
|
26310
|
+
};
|
|
26311
|
+
func.runtime.render.escape_html_attribute = function (value) {
|
|
26312
|
+
return func.runtime.render.escape_html(value);
|
|
26313
|
+
};
|
|
26314
|
+
func.runtime.render.is_html_void_tag = function (tag_name) {
|
|
26315
|
+
return !!func.runtime.render.HTML_VOID_TAGS[(tag_name || '').toLowerCase()];
|
|
26316
|
+
};
|
|
26317
|
+
func.runtime.render.is_falsey_render_value = function (value) {
|
|
26318
|
+
if (value === false || value === null || typeof value === 'undefined') {
|
|
26319
|
+
return true;
|
|
26320
|
+
}
|
|
26321
|
+
if (typeof value === 'number') {
|
|
26322
|
+
return value === 0;
|
|
26323
|
+
}
|
|
26324
|
+
if (typeof value === 'string') {
|
|
26325
|
+
const normalized = value.trim().toLowerCase();
|
|
26326
|
+
return normalized === '' || normalized === 'false' || normalized === '0' || normalized === 'null' || normalized === 'undefined' || normalized === 'off' || normalized === 'no';
|
|
26327
|
+
}
|
|
26328
|
+
return false;
|
|
26329
|
+
};
|
|
26330
|
+
func.runtime.render.should_render_tree_node = function (treeP) {
|
|
26331
|
+
const controls = treeP?.meta?.controls || {};
|
|
26332
|
+
if (controls.xu_if !== null && controls.xu_if !== undefined && func.runtime.render.is_falsey_render_value(controls.xu_if)) {
|
|
26333
|
+
return false;
|
|
26334
|
+
}
|
|
26335
|
+
if (controls.xu_render !== null && controls.xu_render !== undefined && func.runtime.render.is_falsey_render_value(controls.xu_render)) {
|
|
26336
|
+
return false;
|
|
26337
|
+
}
|
|
26338
|
+
return true;
|
|
26339
|
+
};
|
|
26340
|
+
func.runtime.render.is_tree_control_attribute = function (key) {
|
|
26341
|
+
if (!key) {
|
|
26342
|
+
return false;
|
|
26343
|
+
}
|
|
26344
|
+
return (
|
|
26345
|
+
key.startsWith('xu-exp:') ||
|
|
26346
|
+
key === 'xu-widget' ||
|
|
26347
|
+
key === 'xu-method' ||
|
|
26348
|
+
key === 'xu-for' ||
|
|
26349
|
+
key === 'xu-for-key' ||
|
|
26350
|
+
key === 'xu-for-val' ||
|
|
26351
|
+
key === 'xu-if' ||
|
|
26352
|
+
key === 'xu-render' ||
|
|
26353
|
+
key === 'xu-bind' ||
|
|
26354
|
+
key === 'xu-content' ||
|
|
26355
|
+
key === 'xu-text' ||
|
|
26356
|
+
key === 'xu-html' ||
|
|
26357
|
+
key === 'xu-show' ||
|
|
26358
|
+
key === 'xu-panel-program' ||
|
|
26359
|
+
key === 'xu-teleport'
|
|
26360
|
+
);
|
|
26361
|
+
};
|
|
26362
|
+
func.runtime.render.get_string_renderer_tag_name = function (treeP) {
|
|
26363
|
+
switch (treeP?.kind) {
|
|
26364
|
+
case 'widget':
|
|
26365
|
+
case 'single_view':
|
|
26366
|
+
case 'multi_view':
|
|
26367
|
+
case 'panel':
|
|
26368
|
+
case 'teleport':
|
|
26369
|
+
return 'div';
|
|
26370
|
+
case 'placeholder':
|
|
26371
|
+
return null;
|
|
26372
|
+
case 'text':
|
|
26373
|
+
return null;
|
|
26374
|
+
default:
|
|
26375
|
+
return treeP?.tagName || 'div';
|
|
26376
|
+
}
|
|
26377
|
+
};
|
|
26378
|
+
func.runtime.render.get_tree_terminal_content = function (treeP) {
|
|
26379
|
+
const attributes = treeP?.attributes || {};
|
|
26380
|
+
if (typeof attributes['xu-html'] !== 'undefined' && attributes['xu-html'] !== null) {
|
|
26381
|
+
return {
|
|
26382
|
+
value: `${attributes['xu-html']}`,
|
|
26383
|
+
mode: 'html',
|
|
26384
|
+
};
|
|
26385
|
+
}
|
|
26386
|
+
if (typeof attributes['xu-content'] !== 'undefined' && attributes['xu-content'] !== null) {
|
|
26387
|
+
return {
|
|
26388
|
+
value: `${attributes['xu-content']}`,
|
|
26389
|
+
mode: 'html',
|
|
26390
|
+
};
|
|
26391
|
+
}
|
|
26392
|
+
if (typeof attributes['xu-text'] !== 'undefined' && attributes['xu-text'] !== null) {
|
|
26393
|
+
return {
|
|
26394
|
+
value: `${attributes['xu-text']}`,
|
|
26395
|
+
mode: 'text',
|
|
26396
|
+
};
|
|
26397
|
+
}
|
|
26398
|
+
if (treeP?.kind === 'text') {
|
|
26399
|
+
return {
|
|
26400
|
+
value: typeof treeP?.text !== 'undefined' && treeP?.text !== null ? `${treeP.text}` : `${treeP?.content || ''}`,
|
|
26401
|
+
mode: 'text',
|
|
26402
|
+
};
|
|
26403
|
+
}
|
|
26404
|
+
return null;
|
|
26405
|
+
};
|
|
26406
|
+
func.runtime.render.render_tree_terminal_content = function (treeP) {
|
|
26407
|
+
const terminal = func.runtime.render.get_tree_terminal_content(treeP);
|
|
26408
|
+
if (!terminal) {
|
|
26409
|
+
return null;
|
|
26410
|
+
}
|
|
26411
|
+
if (terminal.mode === 'html') {
|
|
26412
|
+
return terminal.value;
|
|
26413
|
+
}
|
|
26414
|
+
return func.runtime.render.escape_html(terminal.value);
|
|
26415
|
+
};
|
|
26416
|
+
func.runtime.render.get_widget_fallback_markup = function (treeP) {
|
|
26417
|
+
const widget_meta = treeP?.meta?.widget || {};
|
|
26418
|
+
const capability_state = widget_meta?.capabilities?.headless ? 'headless-capable' : 'browser-only';
|
|
26419
|
+
return `<!--xuda-widget:${func.runtime.render.escape_html(widget_meta.plugin_name || 'unknown')}:${capability_state}-->`;
|
|
26420
|
+
};
|
|
26421
|
+
func.runtime.render.get_tree_string_attributes = function (treeP, renderer_context) {
|
|
26422
|
+
const attributes = func.runtime.render.safe_clone_tree_value(treeP?.attributes || {});
|
|
26423
|
+
const attr_pairs = [];
|
|
26424
|
+
const keys = Object.keys(attributes);
|
|
26425
|
+
|
|
26426
|
+
for (let index = 0; index < keys.length; index++) {
|
|
26427
|
+
const key = keys[index];
|
|
26428
|
+
if (func.runtime.render.is_tree_control_attribute(key)) {
|
|
26429
|
+
continue;
|
|
26430
|
+
}
|
|
26431
|
+
const value = attributes[key];
|
|
26432
|
+
if (value === false || value === null || typeof value === 'undefined') {
|
|
26433
|
+
continue;
|
|
26434
|
+
}
|
|
26435
|
+
if (value === true) {
|
|
26436
|
+
attr_pairs.push(key);
|
|
26437
|
+
continue;
|
|
26438
|
+
}
|
|
26439
|
+
const normalized_value = typeof value === 'object' ? JSON.stringify(value) : `${value}`;
|
|
26440
|
+
attr_pairs.push(`${key}="${func.runtime.render.escape_html_attribute(normalized_value)}"`);
|
|
26441
|
+
}
|
|
26442
|
+
|
|
26443
|
+
attr_pairs.push(`data-xuda-kind="${func.runtime.render.escape_html_attribute(treeP?.kind || 'element')}"`);
|
|
26444
|
+
attr_pairs.push(`data-xuda-node-id="${func.runtime.render.escape_html_attribute(treeP?.id || treeP?.meta?.source_node_id || '')}"`);
|
|
26445
|
+
attr_pairs.push(`data-xuda-tree-id="${func.runtime.render.escape_html_attribute(treeP?.meta?.tree_id || '')}"`);
|
|
26446
|
+
|
|
26447
|
+
if (treeP?.kind === 'widget' && treeP?.meta?.widget) {
|
|
26448
|
+
attr_pairs.push(`data-xuda-widget="${func.runtime.render.escape_html_attribute(treeP.meta.widget.plugin_name || '')}"`);
|
|
26449
|
+
attr_pairs.push(`data-xuda-widget-method="${func.runtime.render.escape_html_attribute(treeP.meta.widget.method || '_default')}"`);
|
|
26450
|
+
attr_pairs.push(`data-xuda-widget-capability="${func.runtime.render.escape_html_attribute(treeP.meta.widget.capabilities?.headless ? 'headless' : 'browser')}"`);
|
|
26451
|
+
}
|
|
26452
|
+
|
|
26453
|
+
if (treeP?.kind === 'teleport' && treeP?.attributes?.['xu-teleport']) {
|
|
26454
|
+
attr_pairs.push(`data-xuda-teleport-target="${func.runtime.render.escape_html_attribute(treeP.attributes['xu-teleport'])}"`);
|
|
26455
|
+
}
|
|
26456
|
+
|
|
26457
|
+
if ((treeP?.meta?.controls?.xu_for !== null && treeP?.meta?.controls?.xu_for !== undefined) && !renderer_context?.strip_iteration_markers) {
|
|
26458
|
+
attr_pairs.push('data-xuda-xu-for="pending"');
|
|
26459
|
+
}
|
|
26460
|
+
|
|
26461
|
+
return attr_pairs.length ? ' ' + attr_pairs.join(' ') : '';
|
|
26462
|
+
};
|
|
26463
|
+
func.runtime.render.render_tree_children_to_string = async function (treeP, renderer_context) {
|
|
26464
|
+
if (!Array.isArray(treeP?.children) || !treeP.children.length) {
|
|
26465
|
+
return '';
|
|
26466
|
+
}
|
|
26467
|
+
let html = '';
|
|
26468
|
+
for (let index = 0; index < treeP.children.length; index++) {
|
|
26469
|
+
html += await func.runtime.render.render_tree_to_string(treeP.children[index], {
|
|
26470
|
+
...renderer_context,
|
|
26471
|
+
parent_tree: treeP,
|
|
26472
|
+
});
|
|
26473
|
+
}
|
|
26474
|
+
return html;
|
|
26475
|
+
};
|
|
26476
|
+
func.runtime.render.render_tree_to_string = async function (treeP, renderer_context = {}) {
|
|
26477
|
+
if (!treeP) {
|
|
26478
|
+
return '';
|
|
26479
|
+
}
|
|
26480
|
+
if (Array.isArray(treeP)) {
|
|
26481
|
+
let html = '';
|
|
26482
|
+
for (let index = 0; index < treeP.length; index++) {
|
|
26483
|
+
html += await func.runtime.render.render_tree_to_string(treeP[index], renderer_context);
|
|
26484
|
+
}
|
|
26485
|
+
return html;
|
|
26486
|
+
}
|
|
26487
|
+
|
|
26488
|
+
const ensured_tree = await func.runtime.render.ensure_tree_node({
|
|
26489
|
+
SESSION_ID: renderer_context?.SESSION_ID,
|
|
26490
|
+
nodeP: treeP,
|
|
26491
|
+
paramsP: renderer_context?.paramsP,
|
|
26492
|
+
parent_infoP: renderer_context?.parent_infoP,
|
|
26493
|
+
keyP: renderer_context?.keyP,
|
|
26494
|
+
parent_nodeP: renderer_context?.parent_nodeP,
|
|
26495
|
+
});
|
|
26496
|
+
|
|
26497
|
+
if (!ensured_tree || !func.runtime.render.should_render_tree_node(ensured_tree)) {
|
|
26498
|
+
return '';
|
|
26499
|
+
}
|
|
26500
|
+
|
|
26501
|
+
if (ensured_tree.kind === 'placeholder') {
|
|
26502
|
+
if (renderer_context?.include_placeholders) {
|
|
26503
|
+
return `<!--xuda-placeholder:${func.runtime.render.escape_html(ensured_tree.id || '')}-->`;
|
|
26504
|
+
}
|
|
26505
|
+
return '';
|
|
26506
|
+
}
|
|
26507
|
+
|
|
26508
|
+
if (ensured_tree.kind === 'text') {
|
|
26509
|
+
return func.runtime.render.render_tree_terminal_content(ensured_tree) || '';
|
|
26510
|
+
}
|
|
26511
|
+
|
|
26512
|
+
const tag_name = func.runtime.render.get_string_renderer_tag_name(ensured_tree);
|
|
26513
|
+
if (!tag_name || tag_name.toLowerCase() === 'script') {
|
|
26514
|
+
return '';
|
|
26515
|
+
}
|
|
26516
|
+
|
|
26517
|
+
const attributes = func.runtime.render.get_tree_string_attributes(ensured_tree, renderer_context);
|
|
26518
|
+
const terminal_content = func.runtime.render.render_tree_terminal_content(ensured_tree);
|
|
26519
|
+
let children_html = terminal_content !== null ? terminal_content : await func.runtime.render.render_tree_children_to_string(ensured_tree, renderer_context);
|
|
26520
|
+
|
|
26521
|
+
if (ensured_tree.kind === 'widget' && !children_html) {
|
|
26522
|
+
children_html = func.runtime.render.get_widget_fallback_markup(ensured_tree);
|
|
26523
|
+
}
|
|
26524
|
+
|
|
26525
|
+
if (func.runtime.render.is_html_void_tag(tag_name)) {
|
|
26526
|
+
return `<${tag_name}${attributes}>`;
|
|
26527
|
+
}
|
|
26528
|
+
|
|
26529
|
+
return `<${tag_name}${attributes}>${children_html}</${tag_name}>`;
|
|
26530
|
+
};
|
|
26531
|
+
func.runtime.render.render_to_string = async function (options = {}) {
|
|
26532
|
+
const treeP = await func.runtime.render.ensure_tree_node({
|
|
26533
|
+
SESSION_ID: options.SESSION_ID,
|
|
26534
|
+
nodeP: options.treeP || options.nodeP,
|
|
26535
|
+
paramsP: options.paramsP,
|
|
26536
|
+
parent_infoP: options.parent_infoP,
|
|
26537
|
+
keyP: options.keyP,
|
|
26538
|
+
parent_nodeP: options.parent_nodeP,
|
|
26539
|
+
});
|
|
26540
|
+
|
|
26541
|
+
return await func.runtime.render.render_tree_to_string(treeP, options);
|
|
26542
|
+
};
|
|
26543
|
+
func.runtime.render.get_server_render_mode = function (options = {}) {
|
|
26544
|
+
const normalized = func.runtime.render.normalize_runtime_bootstrap({
|
|
26545
|
+
app_computing_mode: options.app_computing_mode,
|
|
26546
|
+
app_render_mode: options.app_render_mode,
|
|
26547
|
+
app_client_activation: options.app_client_activation,
|
|
26548
|
+
});
|
|
26549
|
+
|
|
26550
|
+
return normalized;
|
|
26551
|
+
};
|
|
26552
|
+
func.runtime.render.build_server_render_params = async function (options = {}) {
|
|
26553
|
+
const SESSION_ID = options.SESSION_ID;
|
|
26554
|
+
const prog_id = options.prog_id;
|
|
26555
|
+
const dsSessionP = options.dsSessionP;
|
|
26556
|
+
const _session = SESSION_OBJ?.[SESSION_ID] || {};
|
|
26557
|
+
const _ds = _session?.DS_GLB?.[dsSessionP] || {};
|
|
26558
|
+
const viewDoc = options.viewDoc || (await func.utils?.VIEWS_OBJ?.get?.(SESSION_ID, prog_id));
|
|
26559
|
+
|
|
26560
|
+
if (!viewDoc?.properties) {
|
|
26561
|
+
throw new Error(`view document not found for ${prog_id}`);
|
|
26562
|
+
}
|
|
25751
26563
|
|
|
25752
|
-
|
|
25753
|
-
|
|
25754
|
-
|
|
25755
|
-
|
|
26564
|
+
const base_params = _ds?.screen_params ? func.runtime.render.safe_clone_tree_value(_ds.screen_params) : {};
|
|
26565
|
+
const screenId = options.screenId || base_params.screenId || `ssr_${prog_id}_${dsSessionP || '0'}`;
|
|
26566
|
+
const paramsP = {
|
|
26567
|
+
...base_params,
|
|
26568
|
+
prog_id,
|
|
26569
|
+
sourceScreenP: null,
|
|
26570
|
+
$callingContainerP: null,
|
|
26571
|
+
triggerIdP: null,
|
|
26572
|
+
callingDataSource_objP: _ds,
|
|
26573
|
+
rowIdP: typeof options.rowIdP !== 'undefined' ? options.rowIdP : (_ds?.currentRecordId || null),
|
|
26574
|
+
renderType: viewDoc.properties?.renderType,
|
|
26575
|
+
parameters_obj_inP: options.parameters_obj_inP || base_params.parameters_obj_inP || options.parameters_raw_obj || {},
|
|
26576
|
+
source_functionP: options.source_functionP || base_params.source_functionP || 'render_string',
|
|
26577
|
+
is_panelP: false,
|
|
26578
|
+
screen_type: options.screen_type || base_params.screen_type || 'render_string',
|
|
26579
|
+
screenInfo: viewDoc,
|
|
26580
|
+
call_screen_propertiesP: base_params.call_screen_propertiesP,
|
|
26581
|
+
parentDataSourceNoP: typeof _ds?.parentDataSourceNo === 'undefined' || _ds?.parentDataSourceNo === null ? 0 : _ds.parentDataSourceNo,
|
|
26582
|
+
parameters_raw_obj: options.parameters_raw_obj || base_params.parameters_raw_obj || {},
|
|
26583
|
+
dsSessionP,
|
|
26584
|
+
screenId,
|
|
26585
|
+
containerIdP: base_params.containerIdP || `ssr_container_${screenId}`,
|
|
26586
|
+
};
|
|
25756
26587
|
|
|
25757
|
-
|
|
25758
|
-
|
|
26588
|
+
if (_ds) {
|
|
26589
|
+
_ds.screen_params = paramsP;
|
|
26590
|
+
}
|
|
25759
26591
|
|
|
25760
|
-
|
|
25761
|
-
|
|
25762
|
-
|
|
25763
|
-
|
|
26592
|
+
return paramsP;
|
|
26593
|
+
};
|
|
26594
|
+
func.runtime.render.build_prog_tree = async function (options = {}) {
|
|
26595
|
+
const SESSION_ID = options.SESSION_ID;
|
|
26596
|
+
const prog_id = options.prog_id;
|
|
26597
|
+
const viewDoc = options.viewDoc || (await func.utils?.VIEWS_OBJ?.get?.(SESSION_ID, prog_id));
|
|
26598
|
+
|
|
26599
|
+
if (!viewDoc?.progUi?.length) {
|
|
26600
|
+
throw new Error(`progUi not found for ${prog_id}`);
|
|
25764
26601
|
}
|
|
25765
26602
|
|
|
25766
|
-
|
|
25767
|
-
|
|
26603
|
+
const paramsP = options.paramsP || (await func.runtime.render.build_server_render_params({
|
|
26604
|
+
...options,
|
|
26605
|
+
SESSION_ID,
|
|
26606
|
+
prog_id,
|
|
26607
|
+
viewDoc,
|
|
26608
|
+
}));
|
|
26609
|
+
const root_index = typeof options.root_index === 'number' ? options.root_index : 0;
|
|
26610
|
+
const root_node = func.runtime.render.safe_clone_tree_value(viewDoc.progUi[root_index]);
|
|
26611
|
+
const tree = await func.runtime.render.build_tree({
|
|
26612
|
+
SESSION_ID,
|
|
26613
|
+
nodeP: root_node,
|
|
26614
|
+
paramsP,
|
|
26615
|
+
});
|
|
26616
|
+
|
|
26617
|
+
return {
|
|
26618
|
+
tree,
|
|
26619
|
+
paramsP,
|
|
26620
|
+
viewDoc,
|
|
26621
|
+
};
|
|
25768
26622
|
};
|
|
26623
|
+
func.runtime.render.build_ssr_payload = function (render_program, options = {}) {
|
|
26624
|
+
const runtime_profile = func.runtime.render.get_server_render_mode(options);
|
|
26625
|
+
return {
|
|
26626
|
+
contract: 'xuda.ssr.v1',
|
|
26627
|
+
prog_id: options.prog_id,
|
|
26628
|
+
screenId: render_program.paramsP.screenId,
|
|
26629
|
+
containerId: render_program.paramsP.containerIdP,
|
|
26630
|
+
app_computing_mode: runtime_profile.app_computing_mode,
|
|
26631
|
+
app_render_mode: runtime_profile.app_render_mode,
|
|
26632
|
+
app_client_activation: runtime_profile.app_client_activation,
|
|
26633
|
+
tree_contract: func.runtime.render.TREE_CONTRACT_VERSION,
|
|
26634
|
+
};
|
|
26635
|
+
};
|
|
26636
|
+
func.runtime.render.build_ssr_screen_html = function (html, render_program, options = {}) {
|
|
26637
|
+
const payload = func.runtime.render.build_ssr_payload(render_program, options);
|
|
26638
|
+
const screenId = func.runtime.render.escape_html_attribute(payload.screenId || '');
|
|
26639
|
+
const containerId = func.runtime.render.escape_html_attribute(payload.containerId || '');
|
|
26640
|
+
const activation = func.runtime.render.escape_html_attribute(payload.app_client_activation || 'takeover');
|
|
26641
|
+
|
|
26642
|
+
return `<div data-xuda-ssr-embed="true" class="xu_embed_div"><div id="${screenId}" class="xu_embed_container" data-xuda-ssr-screen="true" data-xuda-ssr-screen-id="${screenId}" data-xuda-activation="${activation}" style="display: contents;"><div id="${containerId}" data-xuda-ssr-root-frame="true" data-xuda-ssr-screen-id="${screenId}" data-xuda-activation="${activation}" style="display: contents;">${html}</div></div></div>`;
|
|
26643
|
+
};
|
|
26644
|
+
func.runtime.render.render_prog_to_string = async function (options = {}) {
|
|
26645
|
+
const render_program = await func.runtime.render.build_prog_tree(options);
|
|
26646
|
+
const html = await func.runtime.render.render_to_string({
|
|
26647
|
+
...options,
|
|
26648
|
+
SESSION_ID: options.SESSION_ID,
|
|
26649
|
+
treeP: render_program.tree,
|
|
26650
|
+
paramsP: render_program.paramsP,
|
|
26651
|
+
});
|
|
26652
|
+
const ssr_payload = func.runtime.render.build_ssr_payload(render_program, options);
|
|
26653
|
+
const screen_html = func.runtime.render.build_ssr_screen_html(html, render_program, options);
|
|
25769
26654
|
|
|
25770
|
-
|
|
26655
|
+
return {
|
|
26656
|
+
prog_id: options.prog_id,
|
|
26657
|
+
dsSessionP: render_program.paramsP.dsSessionP,
|
|
26658
|
+
screenId: render_program.paramsP.screenId,
|
|
26659
|
+
html,
|
|
26660
|
+
screen_html,
|
|
26661
|
+
tree_json: func.runtime.render.serialize_tree(render_program.tree),
|
|
26662
|
+
paramsP: render_program.paramsP,
|
|
26663
|
+
ssr_payload,
|
|
26664
|
+
};
|
|
26665
|
+
};
|
|
25771
26666
|
func.runtime = func.runtime || {};
|
|
25772
26667
|
func.runtime.platform = func.runtime.platform || {};
|
|
25773
26668
|
|
|
@@ -28105,6 +29000,15 @@ func.runtime.ui.ensure_embed_container = function (SESSION_ID) {
|
|
|
28105
29000
|
const $root_element = func.runtime.ui.get_root_element(SESSION_ID);
|
|
28106
29001
|
let $embed_container = func.runtime.ui.find_by_selector($root_element, `#embed_${SESSION_ID}`, true);
|
|
28107
29002
|
|
|
29003
|
+
if (!$embed_container.length) {
|
|
29004
|
+
const $ssr_embed_container = func.runtime.ui.find_by_selector($root_element, `[data-xuda-ssr-embed="true"]`, true);
|
|
29005
|
+
const ssr_embed_node = func.runtime.ui.get_first_node($ssr_embed_container);
|
|
29006
|
+
if (ssr_embed_node) {
|
|
29007
|
+
ssr_embed_node.id = 'embed_' + SESSION_ID;
|
|
29008
|
+
$embed_container = func.runtime.ui._wrap_matches([ssr_embed_node]);
|
|
29009
|
+
}
|
|
29010
|
+
}
|
|
29011
|
+
|
|
28108
29012
|
if (!$embed_container.length) {
|
|
28109
29013
|
const embed_node = document.createElement('div');
|
|
28110
29014
|
embed_node.id = 'embed_' + SESSION_ID;
|
|
@@ -28140,12 +29044,44 @@ func.runtime.ui.get_root_tag_name = function () {
|
|
|
28140
29044
|
}
|
|
28141
29045
|
return root_tag_name;
|
|
28142
29046
|
};
|
|
29047
|
+
func.runtime.ui.find_ssr_screen_host = function ($container, screenId, containerId) {
|
|
29048
|
+
const container_node = func.runtime.ui.get_first_node($container);
|
|
29049
|
+
if (!container_node || !screenId) {
|
|
29050
|
+
return null;
|
|
29051
|
+
}
|
|
29052
|
+
|
|
29053
|
+
const dialog_node =
|
|
29054
|
+
container_node.querySelector?.(`#${CSS?.escape ? CSS.escape(screenId) : screenId}`) ||
|
|
29055
|
+
container_node.querySelector?.(`[data-xuda-ssr-screen-id="${screenId}"]`);
|
|
29056
|
+
if (!dialog_node) {
|
|
29057
|
+
return null;
|
|
29058
|
+
}
|
|
29059
|
+
|
|
29060
|
+
const root_frame_node =
|
|
29061
|
+
(containerId ? dialog_node.querySelector?.(`#${CSS?.escape ? CSS.escape(containerId) : containerId}`) : null) ||
|
|
29062
|
+
dialog_node.querySelector?.('[data-xuda-ssr-root-frame="true"]');
|
|
29063
|
+
if (!root_frame_node) {
|
|
29064
|
+
return null;
|
|
29065
|
+
}
|
|
29066
|
+
|
|
29067
|
+
return {
|
|
29068
|
+
$dialogDiv: func.runtime.ui._wrap_matches([dialog_node]),
|
|
29069
|
+
$rootFrame: func.runtime.ui._wrap_matches([root_frame_node]),
|
|
29070
|
+
reused_ssr_host: true,
|
|
29071
|
+
};
|
|
29072
|
+
};
|
|
28143
29073
|
func.runtime.ui.create_screen_host = function (SESSION_ID, screen_type, params, $callingContainerP, screenId) {
|
|
28144
29074
|
var $dialogDiv;
|
|
28145
29075
|
var $rootFrame;
|
|
29076
|
+
let reused_ssr_host = false;
|
|
28146
29077
|
|
|
28147
29078
|
switch (screen_type) {
|
|
28148
29079
|
case 'embed': {
|
|
29080
|
+
const ssr_host = func.runtime.ui.find_ssr_screen_host($callingContainerP, screenId, params?.containerIdP);
|
|
29081
|
+
if (ssr_host) {
|
|
29082
|
+
return ssr_host;
|
|
29083
|
+
}
|
|
29084
|
+
|
|
28149
29085
|
const dialogNode = document.createElement('div');
|
|
28150
29086
|
dialogNode.id = screenId;
|
|
28151
29087
|
dialogNode.setAttribute('ui_engine', UI_FRAMEWORK_INSTALLED);
|
|
@@ -28195,6 +29131,7 @@ func.runtime.ui.create_screen_host = function (SESSION_ID, screen_type, params,
|
|
|
28195
29131
|
return {
|
|
28196
29132
|
$dialogDiv,
|
|
28197
29133
|
$rootFrame,
|
|
29134
|
+
reused_ssr_host,
|
|
28198
29135
|
};
|
|
28199
29136
|
};
|
|
28200
29137
|
func.runtime.ui.find_xu_ui_in_root = function (SESSION_ID, xu_ui_id) {
|
|
@@ -28759,6 +29696,11 @@ func.runtime.ui.build_container_xu_data = function (options) {
|
|
|
28759
29696
|
func.runtime.ui.apply_container_meta = function ($div, options) {
|
|
28760
29697
|
const div_node = func.runtime.ui.get_first_node($div);
|
|
28761
29698
|
func.runtime.ui.set_attr(div_node, 'xu-ui-id', options.ui_id);
|
|
29699
|
+
func.runtime.ui.set_attr(div_node, 'data-xuda-kind', options.treeP?.kind || options.nodeP?.tagName || 'element');
|
|
29700
|
+
func.runtime.ui.set_attr(div_node, 'data-xuda-node-id', options.nodeP?.id || options.nodeP?.id_org || '');
|
|
29701
|
+
if (options.treeP?.meta?.tree_id !== null && typeof options.treeP?.meta?.tree_id !== 'undefined') {
|
|
29702
|
+
func.runtime.ui.set_attr(div_node, 'data-xuda-tree-id', options.treeP.meta.tree_id);
|
|
29703
|
+
}
|
|
28762
29704
|
const xuData = func.runtime.ui.build_container_xu_data(options);
|
|
28763
29705
|
if (options.parent_infoP?.iterate_info) {
|
|
28764
29706
|
xuData.iterate_info = options.parent_infoP.iterate_info;
|
|
@@ -28853,6 +29795,38 @@ func.runtime.ui.create_container_element = function (div_typeP, attr_str, prop,
|
|
|
28853
29795
|
}
|
|
28854
29796
|
return func.runtime.ui.create_element(div, attr_str);
|
|
28855
29797
|
};
|
|
29798
|
+
func.runtime.ui.find_hydration_candidate = function (options) {
|
|
29799
|
+
if (!func.runtime.render.is_hydration_mode(SESSION_OBJ?.[options.SESSION_ID])) {
|
|
29800
|
+
return null;
|
|
29801
|
+
}
|
|
29802
|
+
if (!func.runtime.render.should_use_ssr_payload(options.SESSION_ID, options.paramsP)) {
|
|
29803
|
+
return null;
|
|
29804
|
+
}
|
|
29805
|
+
if (options.is_placeholder || !options.treeP?.meta?.tree_id) {
|
|
29806
|
+
return null;
|
|
29807
|
+
}
|
|
29808
|
+
|
|
29809
|
+
const append_node = func.runtime.ui.get_first_node(options.$appendTo || options.$container);
|
|
29810
|
+
if (!append_node) {
|
|
29811
|
+
return null;
|
|
29812
|
+
}
|
|
29813
|
+
|
|
29814
|
+
const children = func.runtime.ui.get_children(append_node);
|
|
29815
|
+
for (let index = 0; index < children.length; index++) {
|
|
29816
|
+
const child = children[index];
|
|
29817
|
+
if (child?.__xuda_hydration_claimed) {
|
|
29818
|
+
continue;
|
|
29819
|
+
}
|
|
29820
|
+
if (func.runtime.ui.get_attr(child, 'data-xuda-tree-id') !== `${options.treeP.meta.tree_id}`) {
|
|
29821
|
+
continue;
|
|
29822
|
+
}
|
|
29823
|
+
child.__xuda_hydration_claimed = true;
|
|
29824
|
+
func.runtime.ui.set_attr(child, 'data-xuda-client-activation', 'hydrate');
|
|
29825
|
+
return child;
|
|
29826
|
+
}
|
|
29827
|
+
|
|
29828
|
+
return null;
|
|
29829
|
+
};
|
|
28856
29830
|
func.runtime.ui.build_xu_ui_id_seed = function (nodeP, dsSessionP, key_path, currentRecordId) {
|
|
28857
29831
|
const nodeId = nodeP.xu_tree_id || nodeP.id;
|
|
28858
29832
|
const elem_key = `${nodeId}-${key_path}-${currentRecordId}`;
|
|
@@ -28905,7 +29879,11 @@ func.runtime.ui.create_container = async function (options) {
|
|
|
28905
29879
|
try {
|
|
28906
29880
|
const key_path = func.runtime.ui.build_container_key_path(container_xu_data, options.keyP, options.parent_infoP, options.nodeP, options.parent_nodeP);
|
|
28907
29881
|
const elem_key = `${options.nodeP.xu_tree_id || options.nodeP.id}-${key_path}-${currentRecordId}`;
|
|
28908
|
-
const
|
|
29882
|
+
const hydration_candidate = func.runtime.ui.find_hydration_candidate({
|
|
29883
|
+
...options,
|
|
29884
|
+
$appendTo,
|
|
29885
|
+
});
|
|
29886
|
+
const $div = hydration_candidate || func.runtime.ui.create_container_element(options.div_typeP, options.attr_str, options.prop, options.nodeP, $appendTo);
|
|
28909
29887
|
const new_ui_id = await func.runtime.ui.generate_xu_ui_id(options.SESSION_ID, options.nodeP, options.$container, options.paramsP, options.keyP, {
|
|
28910
29888
|
container_xu_data,
|
|
28911
29889
|
currentRecordId,
|
|
@@ -28931,9 +29909,10 @@ func.runtime.ui.create_container = async function (options) {
|
|
|
28931
29909
|
parent_infoP: options.parent_infoP,
|
|
28932
29910
|
is_placeholder: options.is_placeholder,
|
|
28933
29911
|
classP: options.classP,
|
|
29912
|
+
treeP: options.treeP,
|
|
28934
29913
|
});
|
|
28935
29914
|
|
|
28936
|
-
if (options.div_typeP !== 'svg') {
|
|
29915
|
+
if (!hydration_candidate && options.div_typeP !== 'svg') {
|
|
28937
29916
|
func.runtime.ui.append_to($div, $appendTo);
|
|
28938
29917
|
}
|
|
28939
29918
|
return $div;
|
|
@@ -31614,9 +32593,10 @@ func.runtime.ui.init_screen = async function (options) {
|
|
|
31614
32593
|
|
|
31615
32594
|
const _session = SESSION_OBJ[SESSION_ID];
|
|
31616
32595
|
const screenInfo = structuredClone(screen_ret);
|
|
32596
|
+
const ssr_payload = func.runtime.render.should_use_ssr_payload(SESSION_ID, { prog_id }) ? func.runtime.render.get_ssr_payload(_session) : null;
|
|
31617
32597
|
|
|
31618
32598
|
const screen_type = source_functionP?.split('_')?.[1];
|
|
31619
|
-
const screenId = (glb.screen_num++).toString();
|
|
32599
|
+
const screenId = ssr_payload?.screenId || (glb.screen_num++).toString();
|
|
31620
32600
|
|
|
31621
32601
|
if (SCREEN_BLOCKER_OBJ[prog_id + (sourceScreenP ? '_' + sourceScreenP : '')]) {
|
|
31622
32602
|
const wait_for_SCREEN_BLOCKER_release = function () {
|
|
@@ -31658,6 +32638,8 @@ func.runtime.ui.init_screen = async function (options) {
|
|
|
31658
32638
|
call_screen_propertiesP,
|
|
31659
32639
|
parentDataSourceNoP: _session.DS_GLB?.[callingDataSource_objP?.dsSession]?.dsSession || callingDataSource_objP?.parentDataSourceNo || 0,
|
|
31660
32640
|
parameters_raw_obj,
|
|
32641
|
+
containerIdP: ssr_payload?.containerId || null,
|
|
32642
|
+
ssr_payload,
|
|
31661
32643
|
};
|
|
31662
32644
|
|
|
31663
32645
|
const screen_host = func.runtime.ui.create_screen_host(SESSION_ID, screen_type, params, $callingContainerP, screenId);
|
|
@@ -31690,6 +32672,10 @@ func.runtime.ui.init_screen = async function (options) {
|
|
|
31690
32672
|
func.runtime.ui.set_style($rootFrame, 'display', 'contents');
|
|
31691
32673
|
}
|
|
31692
32674
|
|
|
32675
|
+
if (screen_host.reused_ssr_host && func.runtime.render.is_takeover_mode(_session)) {
|
|
32676
|
+
func.runtime.ui.empty($rootFrame);
|
|
32677
|
+
}
|
|
32678
|
+
|
|
31693
32679
|
if (!is_panelP) func.UI.utils.indicator.screen.busy();
|
|
31694
32680
|
|
|
31695
32681
|
const ret = await func.datasource.create(
|
|
@@ -31731,7 +32717,24 @@ func.runtime.ui.init_screen = async function (options) {
|
|
|
31731
32717
|
}
|
|
31732
32718
|
let node = structuredClone(viewDoc.progUi);
|
|
31733
32719
|
if (!node.length) return console.warn('ui node empty');
|
|
31734
|
-
const
|
|
32720
|
+
const root_tree = await func.runtime.render.build_tree({
|
|
32721
|
+
SESSION_ID,
|
|
32722
|
+
nodeP: node[0],
|
|
32723
|
+
paramsP: params,
|
|
32724
|
+
});
|
|
32725
|
+
const ret_render_$container = await func.runtime.render.render_tree(root_tree, {
|
|
32726
|
+
SESSION_ID,
|
|
32727
|
+
$container: $rootFrame,
|
|
32728
|
+
parent_infoP: null,
|
|
32729
|
+
paramsP: params,
|
|
32730
|
+
jobNoP,
|
|
32731
|
+
is_skeleton: null,
|
|
32732
|
+
keyP: null,
|
|
32733
|
+
refreshed_ds: null,
|
|
32734
|
+
parent_nodeP: null,
|
|
32735
|
+
check_existP: null,
|
|
32736
|
+
$root_container: $rootFrame,
|
|
32737
|
+
});
|
|
31735
32738
|
|
|
31736
32739
|
if (!is_panelP) func.UI.utils.indicator.screen.normal();
|
|
31737
32740
|
|
|
@@ -32156,6 +33159,7 @@ func.runtime.ui.render_single_view_node = async function (options) {
|
|
|
32156
33159
|
parent_infoP: options.parent_infoP,
|
|
32157
33160
|
jobNoP: options.jobNoP,
|
|
32158
33161
|
keyP: options.keyP,
|
|
33162
|
+
treeP: options.treeP,
|
|
32159
33163
|
parent_nodeP: options.parent_nodeP,
|
|
32160
33164
|
prop: options.prop,
|
|
32161
33165
|
div_typeP: 'div',
|
|
@@ -32284,6 +33288,7 @@ func.runtime.ui.render_panel_node = async function (options) {
|
|
|
32284
33288
|
parent_infoP: options.parent_infoP,
|
|
32285
33289
|
jobNoP: options.jobNoP,
|
|
32286
33290
|
keyP: options.keyP,
|
|
33291
|
+
treeP: options.treeP,
|
|
32287
33292
|
parent_nodeP: options.parent_nodeP,
|
|
32288
33293
|
prop: options.prop,
|
|
32289
33294
|
$appendToP: $wrapper,
|
|
@@ -32613,6 +33618,14 @@ func.runtime.ui.screen_loading_done = async function (options) {
|
|
|
32613
33618
|
});
|
|
32614
33619
|
|
|
32615
33620
|
const _session = SESSION_OBJ[options.SESSION_ID];
|
|
33621
|
+
if (func.runtime.render.should_use_ssr_payload(options.SESSION_ID, options.paramsP)) {
|
|
33622
|
+
const root_node = func.runtime.ui.get_root_node(options.SESSION_ID);
|
|
33623
|
+
if (root_node) {
|
|
33624
|
+
func.runtime.ui.set_attr(root_node, 'data-xuda-client-activation', _session.opt.app_client_activation || 'none');
|
|
33625
|
+
func.runtime.ui.set_attr(root_node, 'data-xuda-ssr-status', _session.opt.app_client_activation === 'hydrate' ? 'hydrated' : 'taken-over');
|
|
33626
|
+
}
|
|
33627
|
+
func.runtime.render.mark_ssr_payload_consumed(options.SESSION_ID);
|
|
33628
|
+
}
|
|
32616
33629
|
func.events.delete_job(options.SESSION_ID, options.jobNoP);
|
|
32617
33630
|
func.UI.utils.screen_blocker(false, options.paramsP.prog_id + (options.paramsP.sourceScreenP ? '_' + options.paramsP.sourceScreenP : ''));
|
|
32618
33631
|
if (_session.prog_id === options.paramsP.prog_id) {
|
|
@@ -34455,6 +35468,9 @@ func.runtime.render.get_screen_context = function (SESSION_ID, $container, param
|
|
|
34455
35468
|
};
|
|
34456
35469
|
func.runtime.render.get_node_attributes = function (nodeP) {
|
|
34457
35470
|
try {
|
|
35471
|
+
if (func.runtime.render.is_tree_node?.(nodeP)) {
|
|
35472
|
+
return nodeP.attributes;
|
|
35473
|
+
}
|
|
34458
35474
|
return nodeP?.attributes;
|
|
34459
35475
|
} catch (error) {
|
|
34460
35476
|
return undefined;
|
|
@@ -34572,6 +35588,7 @@ func.runtime.render.prepare_draw_context = async function (options) {
|
|
|
34572
35588
|
parent_infoP: options.parent_infoP,
|
|
34573
35589
|
jobNoP: options.jobNoP,
|
|
34574
35590
|
keyP: options.keyP,
|
|
35591
|
+
treeP: options.treeP,
|
|
34575
35592
|
parent_nodeP: options.parent_nodeP,
|
|
34576
35593
|
prop: options.prop,
|
|
34577
35594
|
div_typeP: options.element,
|
|
@@ -34594,6 +35611,7 @@ func.runtime.render.prepare_draw_context = async function (options) {
|
|
|
34594
35611
|
parent_infoP: options.parent_infoP,
|
|
34595
35612
|
jobNoP: options.jobNoP,
|
|
34596
35613
|
keyP: options.keyP,
|
|
35614
|
+
treeP: options.treeP,
|
|
34597
35615
|
parent_nodeP: options.parent_nodeP,
|
|
34598
35616
|
prop: options.prop,
|
|
34599
35617
|
div_typeP: options.element,
|
|
@@ -35450,11 +36468,16 @@ func.runtime.widgets.render_node = async function (options) {
|
|
|
35450
36468
|
parent_infoP: options.parent_infoP,
|
|
35451
36469
|
jobNoP: options.jobNoP,
|
|
35452
36470
|
keyP: options.keyP,
|
|
36471
|
+
treeP: options.treeP,
|
|
35453
36472
|
parent_nodeP: options.parent_nodeP,
|
|
35454
36473
|
prop: options.prop,
|
|
35455
36474
|
classP: 'widget_wrapper',
|
|
35456
36475
|
});
|
|
35457
36476
|
|
|
36477
|
+
if (func.runtime.render.is_hydration_mode(SESSION_OBJ?.[options.SESSION_ID]) && func.runtime.render.should_use_ssr_payload(options.SESSION_ID, options.paramsP)) {
|
|
36478
|
+
func.runtime.ui.empty($div);
|
|
36479
|
+
}
|
|
36480
|
+
|
|
35458
36481
|
const widget_context = func.runtime.widgets.create_context(options.SESSION_ID, options.paramsP, options.prop);
|
|
35459
36482
|
const { plugin_name, method, propsP, plugin: _plugin } = widget_context;
|
|
35460
36483
|
const report_error = function (descP, warn) {
|
|
@@ -35557,9 +36580,306 @@ func.runtime.widgets = func.runtime.widgets || {};
|
|
|
35557
36580
|
|
|
35558
36581
|
// Browser-only special node renderers live here so the core render tree can stay focused.
|
|
35559
36582
|
|
|
36583
|
+
const normalize_runtime_tag_name = function (tag_name) {
|
|
36584
|
+
return `${tag_name || ''}`.trim().toLowerCase();
|
|
36585
|
+
};
|
|
36586
|
+
|
|
36587
|
+
const get_runtime_node_attributes = function (nodeP) {
|
|
36588
|
+
if (!nodeP?.attributes || typeof nodeP.attributes !== 'object') {
|
|
36589
|
+
return {};
|
|
36590
|
+
}
|
|
36591
|
+
|
|
36592
|
+
return nodeP.attributes;
|
|
36593
|
+
};
|
|
36594
|
+
|
|
36595
|
+
const get_runtime_node_content = function (nodeP) {
|
|
36596
|
+
if (typeof nodeP?.content === 'string') {
|
|
36597
|
+
return nodeP.content;
|
|
36598
|
+
}
|
|
36599
|
+
|
|
36600
|
+
if (typeof nodeP?.text === 'string') {
|
|
36601
|
+
return nodeP.text;
|
|
36602
|
+
}
|
|
36603
|
+
|
|
36604
|
+
if (!Array.isArray(nodeP?.children)) {
|
|
36605
|
+
return '';
|
|
36606
|
+
}
|
|
36607
|
+
|
|
36608
|
+
return nodeP.children
|
|
36609
|
+
.map(function (child) {
|
|
36610
|
+
if (typeof child === 'string') {
|
|
36611
|
+
return child;
|
|
36612
|
+
}
|
|
36613
|
+
if (typeof child?.content === 'string') {
|
|
36614
|
+
return child.content;
|
|
36615
|
+
}
|
|
36616
|
+
if (typeof child?.text === 'string') {
|
|
36617
|
+
return child.text;
|
|
36618
|
+
}
|
|
36619
|
+
return '';
|
|
36620
|
+
})
|
|
36621
|
+
.join('');
|
|
36622
|
+
};
|
|
36623
|
+
|
|
36624
|
+
const get_runtime_asset_key = function (options, tag_name) {
|
|
36625
|
+
const source_node = options.treeP || options.nodeP || {};
|
|
36626
|
+
const parts = [
|
|
36627
|
+
'xuda-html-asset',
|
|
36628
|
+
options.paramsP?.prog_id || '',
|
|
36629
|
+
tag_name,
|
|
36630
|
+
source_node.id || source_node.id_org || '',
|
|
36631
|
+
typeof options.keyP === 'undefined' || options.keyP === null ? '' : `${options.keyP}`,
|
|
36632
|
+
].filter(function (part) {
|
|
36633
|
+
return `${part || ''}`.trim() !== '';
|
|
36634
|
+
});
|
|
36635
|
+
|
|
36636
|
+
return parts.join(':');
|
|
36637
|
+
};
|
|
36638
|
+
|
|
36639
|
+
const get_runtime_asset_signature = function (attributes, content) {
|
|
36640
|
+
const normalized_attributes = {};
|
|
36641
|
+
const attr_keys = Object.keys(attributes || {}).sort();
|
|
36642
|
+
|
|
36643
|
+
for (let index = 0; index < attr_keys.length; index++) {
|
|
36644
|
+
const key = attr_keys[index];
|
|
36645
|
+
normalized_attributes[key] = attributes[key];
|
|
36646
|
+
}
|
|
36647
|
+
|
|
36648
|
+
return JSON.stringify({
|
|
36649
|
+
attributes: normalized_attributes,
|
|
36650
|
+
content: `${content || ''}`,
|
|
36651
|
+
});
|
|
36652
|
+
};
|
|
36653
|
+
|
|
36654
|
+
const escape_runtime_asset_selector_value = function (value) {
|
|
36655
|
+
const win = func.runtime.platform.get_window?.();
|
|
36656
|
+
if (win?.CSS?.escape) {
|
|
36657
|
+
return win.CSS.escape(value);
|
|
36658
|
+
}
|
|
36659
|
+
|
|
36660
|
+
return `${value || ''}`.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
36661
|
+
};
|
|
36662
|
+
|
|
36663
|
+
const find_runtime_head_asset = function (head, tag_name, asset_key) {
|
|
36664
|
+
if (!head?.querySelector || !asset_key) {
|
|
36665
|
+
return null;
|
|
36666
|
+
}
|
|
36667
|
+
|
|
36668
|
+
return head.querySelector(`${tag_name}[data-xuda-asset-key="${escape_runtime_asset_selector_value(asset_key)}"]`);
|
|
36669
|
+
};
|
|
36670
|
+
|
|
36671
|
+
const find_runtime_head_asset_by_attr = function (head, tag_name, attr_name, attr_value) {
|
|
36672
|
+
if (!head?.querySelectorAll || !attr_name || !attr_value) {
|
|
36673
|
+
return null;
|
|
36674
|
+
}
|
|
36675
|
+
|
|
36676
|
+
const candidates = Array.from(head.querySelectorAll(tag_name));
|
|
36677
|
+
return (
|
|
36678
|
+
candidates.find(function (candidate) {
|
|
36679
|
+
return candidate.getAttribute(attr_name) === attr_value || candidate[attr_name] === attr_value;
|
|
36680
|
+
}) || null
|
|
36681
|
+
);
|
|
36682
|
+
};
|
|
36683
|
+
|
|
36684
|
+
const wait_for_runtime_asset_load = function (node) {
|
|
36685
|
+
if (!node?.addEventListener) {
|
|
36686
|
+
return Promise.resolve(node);
|
|
36687
|
+
}
|
|
36688
|
+
|
|
36689
|
+
if (node.getAttribute?.('data-xuda-loaded') === 'true') {
|
|
36690
|
+
return Promise.resolve(node);
|
|
36691
|
+
}
|
|
36692
|
+
|
|
36693
|
+
if (!node.getAttribute?.('data-xuda-asset-key')) {
|
|
36694
|
+
return Promise.resolve(node);
|
|
36695
|
+
}
|
|
36696
|
+
|
|
36697
|
+
const tag_name = normalize_runtime_tag_name(node.tagName);
|
|
36698
|
+
if (tag_name !== 'script' && !(tag_name === 'link' && normalize_runtime_tag_name(node.getAttribute?.('rel')) === 'stylesheet')) {
|
|
36699
|
+
return Promise.resolve(node);
|
|
36700
|
+
}
|
|
36701
|
+
|
|
36702
|
+
return new Promise(function (resolve) {
|
|
36703
|
+
const done = function () {
|
|
36704
|
+
node.setAttribute?.('data-xuda-loaded', 'true');
|
|
36705
|
+
resolve(node);
|
|
36706
|
+
};
|
|
36707
|
+
|
|
36708
|
+
node.addEventListener('load', done, { once: true });
|
|
36709
|
+
node.addEventListener('error', done, { once: true });
|
|
36710
|
+
});
|
|
36711
|
+
};
|
|
36712
|
+
|
|
36713
|
+
const remove_runtime_head_asset = function (node) {
|
|
36714
|
+
if (node?.parentNode?.removeChild) {
|
|
36715
|
+
node.parentNode.removeChild(node);
|
|
36716
|
+
}
|
|
36717
|
+
};
|
|
36718
|
+
|
|
36719
|
+
const apply_runtime_asset_metadata = function (node, asset_key, signature) {
|
|
36720
|
+
if (!node?.setAttribute) {
|
|
36721
|
+
return node;
|
|
36722
|
+
}
|
|
36723
|
+
|
|
36724
|
+
if (asset_key) {
|
|
36725
|
+
node.setAttribute('data-xuda-asset-key', asset_key);
|
|
36726
|
+
}
|
|
36727
|
+
node.setAttribute('data-xuda-asset-signature', signature);
|
|
36728
|
+
return node;
|
|
36729
|
+
};
|
|
36730
|
+
|
|
36731
|
+
const create_runtime_head_element = function (doc, tag_name, attributes, asset_key, signature) {
|
|
36732
|
+
const node = doc.createElement(tag_name);
|
|
36733
|
+
apply_runtime_asset_metadata(node, asset_key, signature);
|
|
36734
|
+
func.runtime.platform.apply_element_attributes(node, attributes);
|
|
36735
|
+
return node;
|
|
36736
|
+
};
|
|
36737
|
+
|
|
36738
|
+
const upsert_runtime_head_element = async function (options) {
|
|
36739
|
+
const doc = func.runtime.platform.get_document?.();
|
|
36740
|
+
const head = doc?.head;
|
|
36741
|
+
const tag_name = normalize_runtime_tag_name(options.tag_name);
|
|
36742
|
+
|
|
36743
|
+
if (!doc?.createElement || !head?.appendChild || !tag_name) {
|
|
36744
|
+
return null;
|
|
36745
|
+
}
|
|
36746
|
+
|
|
36747
|
+
const asset_key = options.asset_key || '';
|
|
36748
|
+
const signature = options.signature || '';
|
|
36749
|
+
const attributes = options.attributes || {};
|
|
36750
|
+
const content = typeof options.content === 'string' ? options.content : '';
|
|
36751
|
+
|
|
36752
|
+
const existing_by_key = find_runtime_head_asset(head, tag_name, asset_key);
|
|
36753
|
+
if (existing_by_key && existing_by_key.getAttribute('data-xuda-asset-signature') === signature) {
|
|
36754
|
+
return options.await_load ? await wait_for_runtime_asset_load(existing_by_key) : existing_by_key;
|
|
36755
|
+
}
|
|
36756
|
+
|
|
36757
|
+
if (existing_by_key) {
|
|
36758
|
+
remove_runtime_head_asset(existing_by_key);
|
|
36759
|
+
}
|
|
36760
|
+
|
|
36761
|
+
if (options.find_existing_attr?.name && options.find_existing_attr?.value) {
|
|
36762
|
+
const existing_by_attr = find_runtime_head_asset_by_attr(head, tag_name, options.find_existing_attr.name, options.find_existing_attr.value);
|
|
36763
|
+
if (existing_by_attr) {
|
|
36764
|
+
apply_runtime_asset_metadata(existing_by_attr, asset_key, signature);
|
|
36765
|
+
existing_by_attr.setAttribute?.('data-xuda-loaded', 'true');
|
|
36766
|
+
return existing_by_attr;
|
|
36767
|
+
}
|
|
36768
|
+
}
|
|
36769
|
+
|
|
36770
|
+
const node = create_runtime_head_element(doc, tag_name, attributes, asset_key, signature);
|
|
36771
|
+
|
|
36772
|
+
if (tag_name === 'script' && attributes.src && !Object.prototype.hasOwnProperty.call(attributes, 'async')) {
|
|
36773
|
+
const script_type = normalize_runtime_tag_name(attributes.type);
|
|
36774
|
+
if (script_type !== 'module') {
|
|
36775
|
+
node.async = false;
|
|
36776
|
+
}
|
|
36777
|
+
}
|
|
36778
|
+
|
|
36779
|
+
if (tag_name === 'style' || (tag_name === 'script' && !attributes.src)) {
|
|
36780
|
+
node.textContent = content;
|
|
36781
|
+
}
|
|
36782
|
+
|
|
36783
|
+
head.appendChild(node);
|
|
36784
|
+
|
|
36785
|
+
if (tag_name !== 'script' && tag_name !== 'link') {
|
|
36786
|
+
node.setAttribute('data-xuda-loaded', 'true');
|
|
36787
|
+
}
|
|
36788
|
+
|
|
36789
|
+
return options.await_load ? await wait_for_runtime_asset_load(node) : node;
|
|
36790
|
+
};
|
|
36791
|
+
|
|
36792
|
+
const render_runtime_html_asset = async function (options) {
|
|
36793
|
+
if (options.is_skeleton) {
|
|
36794
|
+
return options.$container;
|
|
36795
|
+
}
|
|
36796
|
+
|
|
36797
|
+
const nodeP = options.treeP || options.nodeP || {};
|
|
36798
|
+
const tag_name = normalize_runtime_tag_name(nodeP.tagName);
|
|
36799
|
+
const attributes = { ...get_runtime_node_attributes(nodeP) };
|
|
36800
|
+
const content = get_runtime_node_content(nodeP);
|
|
36801
|
+
const asset_key = get_runtime_asset_key(options, tag_name);
|
|
36802
|
+
const signature = get_runtime_asset_signature(attributes, content);
|
|
36803
|
+
|
|
36804
|
+
switch (tag_name) {
|
|
36805
|
+
case 'title':
|
|
36806
|
+
func.runtime.platform.set_title(content);
|
|
36807
|
+
return options.$container;
|
|
36808
|
+
case 'style':
|
|
36809
|
+
await upsert_runtime_head_element({
|
|
36810
|
+
tag_name,
|
|
36811
|
+
attributes,
|
|
36812
|
+
content,
|
|
36813
|
+
asset_key,
|
|
36814
|
+
signature,
|
|
36815
|
+
});
|
|
36816
|
+
return options.$container;
|
|
36817
|
+
case 'meta':
|
|
36818
|
+
if (!Object.keys(attributes).length) {
|
|
36819
|
+
return options.$container;
|
|
36820
|
+
}
|
|
36821
|
+
await upsert_runtime_head_element({
|
|
36822
|
+
tag_name,
|
|
36823
|
+
attributes,
|
|
36824
|
+
asset_key,
|
|
36825
|
+
signature,
|
|
36826
|
+
});
|
|
36827
|
+
return options.$container;
|
|
36828
|
+
case 'link': {
|
|
36829
|
+
const href = `${attributes.href || ''}`.trim();
|
|
36830
|
+
if (!href) {
|
|
36831
|
+
return options.$container;
|
|
36832
|
+
}
|
|
36833
|
+
await upsert_runtime_head_element({
|
|
36834
|
+
tag_name,
|
|
36835
|
+
attributes,
|
|
36836
|
+
asset_key,
|
|
36837
|
+
signature,
|
|
36838
|
+
find_existing_attr: {
|
|
36839
|
+
name: 'href',
|
|
36840
|
+
value: href,
|
|
36841
|
+
},
|
|
36842
|
+
await_load: normalize_runtime_tag_name(attributes.rel) === 'stylesheet',
|
|
36843
|
+
});
|
|
36844
|
+
return options.$container;
|
|
36845
|
+
}
|
|
36846
|
+
case 'script': {
|
|
36847
|
+
const src = `${attributes.src || ''}`.trim();
|
|
36848
|
+
if (!src && !content.trim()) {
|
|
36849
|
+
return options.$container;
|
|
36850
|
+
}
|
|
36851
|
+
await upsert_runtime_head_element({
|
|
36852
|
+
tag_name,
|
|
36853
|
+
attributes,
|
|
36854
|
+
content,
|
|
36855
|
+
asset_key,
|
|
36856
|
+
signature,
|
|
36857
|
+
find_existing_attr: src
|
|
36858
|
+
? {
|
|
36859
|
+
name: 'src',
|
|
36860
|
+
value: src,
|
|
36861
|
+
}
|
|
36862
|
+
: null,
|
|
36863
|
+
await_load: !!src,
|
|
36864
|
+
});
|
|
36865
|
+
return options.$container;
|
|
36866
|
+
}
|
|
36867
|
+
default:
|
|
36868
|
+
return null;
|
|
36869
|
+
}
|
|
36870
|
+
};
|
|
36871
|
+
|
|
35560
36872
|
func.runtime.render.render_special_node = async function (options) {
|
|
35561
|
-
|
|
35562
|
-
|
|
36873
|
+
const treeP = options.treeP || null;
|
|
36874
|
+
const nodeP = options.nodeP || func.runtime.render.get_tree_source_node(treeP);
|
|
36875
|
+
const render_tag_name = treeP?.tagName || nodeP?.tagName;
|
|
36876
|
+
const normalized_render_tag_name = normalize_runtime_tag_name(render_tag_name);
|
|
36877
|
+
const is_native_html_asset = ['title', 'style', 'meta', 'link', 'script'].includes(normalized_render_tag_name);
|
|
36878
|
+
|
|
36879
|
+
if (!is_native_html_asset && treeP?.content && nodeP?.attributes) {
|
|
36880
|
+
nodeP.attributes['xu-content'] = treeP.content;
|
|
36881
|
+
} else if (!is_native_html_asset && nodeP?.content && nodeP.attributes) {
|
|
36882
|
+
nodeP.attributes['xu-content'] = nodeP.content;
|
|
35563
36883
|
}
|
|
35564
36884
|
|
|
35565
36885
|
const renderers = {
|
|
@@ -35569,6 +36889,7 @@ func.runtime.render.render_special_node = async function (options) {
|
|
|
35569
36889
|
SESSION_ID: options.SESSION_ID,
|
|
35570
36890
|
$container: options.$container,
|
|
35571
36891
|
$root_container: options.$root_container,
|
|
36892
|
+
treeP,
|
|
35572
36893
|
nodeP: options.nodeP,
|
|
35573
36894
|
parent_infoP: options.parent_infoP,
|
|
35574
36895
|
paramsP: options.paramsP,
|
|
@@ -35585,6 +36906,7 @@ func.runtime.render.render_special_node = async function (options) {
|
|
|
35585
36906
|
SESSION_ID: options.SESSION_ID,
|
|
35586
36907
|
$container: options.$container,
|
|
35587
36908
|
$root_container: options.$root_container,
|
|
36909
|
+
treeP,
|
|
35588
36910
|
nodeP: options.nodeP,
|
|
35589
36911
|
parent_infoP: options.parent_infoP,
|
|
35590
36912
|
paramsP: options.paramsP,
|
|
@@ -35604,6 +36926,7 @@ func.runtime.render.render_special_node = async function (options) {
|
|
|
35604
36926
|
SESSION_ID: options.SESSION_ID,
|
|
35605
36927
|
$container: options.$container,
|
|
35606
36928
|
$root_container: options.$root_container,
|
|
36929
|
+
treeP,
|
|
35607
36930
|
nodeP: options.nodeP,
|
|
35608
36931
|
parent_infoP: options.parent_infoP,
|
|
35609
36932
|
paramsP: options.paramsP,
|
|
@@ -35620,6 +36943,7 @@ func.runtime.render.render_special_node = async function (options) {
|
|
|
35620
36943
|
SESSION_ID: options.SESSION_ID,
|
|
35621
36944
|
$container: options.$container,
|
|
35622
36945
|
$root_container: options.$root_container,
|
|
36946
|
+
treeP,
|
|
35623
36947
|
nodeP: options.nodeP,
|
|
35624
36948
|
parent_infoP: options.parent_infoP,
|
|
35625
36949
|
paramsP: options.paramsP,
|
|
@@ -35631,9 +36955,24 @@ func.runtime.render.render_special_node = async function (options) {
|
|
|
35631
36955
|
refreshed_ds: options.refreshed_ds,
|
|
35632
36956
|
});
|
|
35633
36957
|
},
|
|
36958
|
+
title: async function () {
|
|
36959
|
+
return await render_runtime_html_asset(options);
|
|
36960
|
+
},
|
|
36961
|
+
style: async function () {
|
|
36962
|
+
return await render_runtime_html_asset(options);
|
|
36963
|
+
},
|
|
36964
|
+
meta: async function () {
|
|
36965
|
+
return await render_runtime_html_asset(options);
|
|
36966
|
+
},
|
|
36967
|
+
link: async function () {
|
|
36968
|
+
return await render_runtime_html_asset(options);
|
|
36969
|
+
},
|
|
36970
|
+
script: async function () {
|
|
36971
|
+
return await render_runtime_html_asset(options);
|
|
36972
|
+
},
|
|
35634
36973
|
};
|
|
35635
36974
|
|
|
35636
|
-
const renderer = renderers[
|
|
36975
|
+
const renderer = renderers[normalized_render_tag_name];
|
|
35637
36976
|
if (!renderer) {
|
|
35638
36977
|
return { handled: false };
|
|
35639
36978
|
}
|
|
@@ -35747,8 +37086,9 @@ func.runtime.widgets = func.runtime.widgets || {};
|
|
|
35747
37086
|
// Browser-only render tree entrypoints live here so draw/cache helpers can stay focused.
|
|
35748
37087
|
|
|
35749
37088
|
func.runtime.render.create_tree_runtime = function (options) {
|
|
37089
|
+
const render_node = options.nodeP || func.runtime.render.get_tree_source_node(options.treeP);
|
|
35750
37090
|
const render_context = func.runtime.render.get_screen_context(options.SESSION_ID, options.$container, options.paramsP, options.is_skeleton);
|
|
35751
|
-
const prop = func.runtime.render.get_node_attributes(options.
|
|
37091
|
+
const prop = func.runtime.render.get_node_attributes(options.treeP || render_node);
|
|
35752
37092
|
const is_mobile = render_context.is_mobile ? true : false;
|
|
35753
37093
|
const hover_handlers = func.runtime.render.create_hover_handlers({
|
|
35754
37094
|
SESSION_ID: options.SESSION_ID,
|
|
@@ -35763,13 +37103,22 @@ func.runtime.render.create_tree_runtime = function (options) {
|
|
|
35763
37103
|
return await func.runtime.ui.close_modal_session(options.SESSION_ID, modal_id);
|
|
35764
37104
|
};
|
|
35765
37105
|
const iterate_child = async function ($divP, nodeP, parent_infoP, $root_container, before_record_function) {
|
|
37106
|
+
const child_tree = await func.runtime.render.ensure_tree_node({
|
|
37107
|
+
SESSION_ID: options.SESSION_ID,
|
|
37108
|
+
nodeP: nodeP || options.treeP || render_node,
|
|
37109
|
+
parent_infoP,
|
|
37110
|
+
paramsP: options.paramsP,
|
|
37111
|
+
keyP: options.keyP,
|
|
37112
|
+
parent_nodeP: render_node,
|
|
37113
|
+
pathP: options.treeP?.meta?.path || [],
|
|
37114
|
+
});
|
|
35766
37115
|
return await func.runtime.render.iterate_children({
|
|
35767
37116
|
$divP,
|
|
35768
|
-
nodeP,
|
|
37117
|
+
nodeP: child_tree,
|
|
35769
37118
|
is_mobile,
|
|
35770
37119
|
before_record_function,
|
|
35771
37120
|
render_child: async function (key, child) {
|
|
35772
|
-
await options.render_child($divP, child, parent_infoP, key,
|
|
37121
|
+
await options.render_child($divP, child, parent_infoP, key, render_node, $root_container);
|
|
35773
37122
|
},
|
|
35774
37123
|
});
|
|
35775
37124
|
};
|
|
@@ -35799,7 +37148,7 @@ func.runtime.render.draw_node = async function (options) {
|
|
|
35799
37148
|
check_existP: options.check_existP,
|
|
35800
37149
|
$root_container: options.$root_container,
|
|
35801
37150
|
prop: options.prop,
|
|
35802
|
-
element: options.nodeP.tagName,
|
|
37151
|
+
element: options.treeP?.tagName || options.nodeP.tagName,
|
|
35803
37152
|
hover_handlers: options.hover_handlers,
|
|
35804
37153
|
include_hover_click: options.include_hover_click,
|
|
35805
37154
|
iterate_child: options.iterate_child,
|
|
@@ -35822,21 +37171,33 @@ func.runtime.render.draw_node = async function (options) {
|
|
|
35822
37171
|
nodeP: options.nodeP,
|
|
35823
37172
|
});
|
|
35824
37173
|
};
|
|
35825
|
-
func.runtime.render.
|
|
35826
|
-
if (!
|
|
35827
|
-
const
|
|
35828
|
-
func.runtime?.perf?.
|
|
37174
|
+
func.runtime.render.render_tree = async function (treeP, renderer_context) {
|
|
37175
|
+
if (!treeP) return;
|
|
37176
|
+
const nodeP = func.runtime.render.get_tree_source_node(treeP);
|
|
37177
|
+
const perf_end = func.runtime?.perf?.start?.(renderer_context.SESSION_ID, 'render_ui_tree');
|
|
37178
|
+
func.runtime?.perf?.increment_map?.(renderer_context.SESSION_ID, 'render_node_counts', treeP.id || nodeP?.id || nodeP?.id_org || treeP.tagName || 'unknown');
|
|
35829
37179
|
try {
|
|
35830
37180
|
const tree_runtime = func.runtime.render.create_tree_runtime({
|
|
35831
|
-
SESSION_ID,
|
|
35832
|
-
$container,
|
|
37181
|
+
SESSION_ID: renderer_context.SESSION_ID,
|
|
37182
|
+
$container: renderer_context.$container,
|
|
37183
|
+
treeP,
|
|
35833
37184
|
nodeP,
|
|
35834
|
-
parent_infoP,
|
|
35835
|
-
paramsP,
|
|
35836
|
-
jobNoP,
|
|
35837
|
-
is_skeleton,
|
|
37185
|
+
parent_infoP: renderer_context.parent_infoP,
|
|
37186
|
+
paramsP: renderer_context.paramsP,
|
|
37187
|
+
jobNoP: renderer_context.jobNoP,
|
|
37188
|
+
is_skeleton: renderer_context.is_skeleton,
|
|
37189
|
+
keyP: renderer_context.keyP,
|
|
35838
37190
|
render_child: async function ($divP, child, parent_infoP, key, parentNodeP, rootContainerP) {
|
|
35839
|
-
await func.runtime.render.
|
|
37191
|
+
await func.runtime.render.render_tree(child, {
|
|
37192
|
+
...renderer_context,
|
|
37193
|
+
$container: $divP,
|
|
37194
|
+
parent_infoP,
|
|
37195
|
+
keyP: key,
|
|
37196
|
+
refreshed_ds: null,
|
|
37197
|
+
parent_nodeP: parentNodeP,
|
|
37198
|
+
check_existP: null,
|
|
37199
|
+
$root_container: rootContainerP,
|
|
37200
|
+
});
|
|
35840
37201
|
},
|
|
35841
37202
|
});
|
|
35842
37203
|
const render_context = tree_runtime.render_context;
|
|
@@ -35848,23 +37209,24 @@ func.runtime.render.render_ui_tree = async function (SESSION_ID, $container, nod
|
|
|
35848
37209
|
const iterate_child = tree_runtime.iterate_child;
|
|
35849
37210
|
|
|
35850
37211
|
func.runtime.render.log_tree_debug({
|
|
35851
|
-
SESSION_ID,
|
|
35852
|
-
paramsP,
|
|
37212
|
+
SESSION_ID: renderer_context.SESSION_ID,
|
|
37213
|
+
paramsP: renderer_context.paramsP,
|
|
35853
37214
|
nodeP,
|
|
35854
37215
|
_ds,
|
|
35855
37216
|
});
|
|
35856
37217
|
const special_render = await func.runtime.render.render_special_node({
|
|
35857
|
-
SESSION_ID,
|
|
35858
|
-
$container,
|
|
35859
|
-
$root_container,
|
|
37218
|
+
SESSION_ID: renderer_context.SESSION_ID,
|
|
37219
|
+
$container: renderer_context.$container,
|
|
37220
|
+
$root_container: renderer_context.$root_container,
|
|
37221
|
+
treeP,
|
|
35860
37222
|
nodeP,
|
|
35861
|
-
parent_infoP,
|
|
35862
|
-
paramsP,
|
|
35863
|
-
jobNoP,
|
|
35864
|
-
is_skeleton,
|
|
35865
|
-
keyP,
|
|
35866
|
-
refreshed_ds,
|
|
35867
|
-
parent_nodeP,
|
|
37223
|
+
parent_infoP: renderer_context.parent_infoP,
|
|
37224
|
+
paramsP: renderer_context.paramsP,
|
|
37225
|
+
jobNoP: renderer_context.jobNoP,
|
|
37226
|
+
is_skeleton: renderer_context.is_skeleton,
|
|
37227
|
+
keyP: renderer_context.keyP,
|
|
37228
|
+
refreshed_ds: renderer_context.refreshed_ds,
|
|
37229
|
+
parent_nodeP: renderer_context.parent_nodeP,
|
|
35868
37230
|
prop,
|
|
35869
37231
|
render_context,
|
|
35870
37232
|
hover_handlers,
|
|
@@ -35872,22 +37234,23 @@ func.runtime.render.render_ui_tree = async function (SESSION_ID, $container, nod
|
|
|
35872
37234
|
close_modal,
|
|
35873
37235
|
});
|
|
35874
37236
|
if (special_render.handled) {
|
|
35875
|
-
func.runtime?.perf?.increment?.(SESSION_ID, 'render_special_node_hits');
|
|
37237
|
+
func.runtime?.perf?.increment?.(renderer_context.SESSION_ID, 'render_special_node_hits');
|
|
35876
37238
|
return special_render.result;
|
|
35877
37239
|
}
|
|
35878
37240
|
return await func.runtime.render.draw_node({
|
|
35879
|
-
SESSION_ID,
|
|
35880
|
-
$container,
|
|
35881
|
-
$root_container,
|
|
37241
|
+
SESSION_ID: renderer_context.SESSION_ID,
|
|
37242
|
+
$container: renderer_context.$container,
|
|
37243
|
+
$root_container: renderer_context.$root_container,
|
|
37244
|
+
treeP,
|
|
35882
37245
|
nodeP,
|
|
35883
|
-
parent_infoP,
|
|
35884
|
-
paramsP,
|
|
35885
|
-
jobNoP,
|
|
35886
|
-
is_skeleton,
|
|
35887
|
-
keyP,
|
|
35888
|
-
refreshed_ds,
|
|
35889
|
-
parent_nodeP,
|
|
35890
|
-
check_existP,
|
|
37246
|
+
parent_infoP: renderer_context.parent_infoP,
|
|
37247
|
+
paramsP: renderer_context.paramsP,
|
|
37248
|
+
jobNoP: renderer_context.jobNoP,
|
|
37249
|
+
is_skeleton: renderer_context.is_skeleton,
|
|
37250
|
+
keyP: renderer_context.keyP,
|
|
37251
|
+
refreshed_ds: renderer_context.refreshed_ds,
|
|
37252
|
+
parent_nodeP: renderer_context.parent_nodeP,
|
|
37253
|
+
check_existP: renderer_context.check_existP,
|
|
35891
37254
|
prop,
|
|
35892
37255
|
hover_handlers,
|
|
35893
37256
|
include_hover_click,
|
|
@@ -35896,6 +37259,31 @@ func.runtime.render.render_ui_tree = async function (SESSION_ID, $container, nod
|
|
|
35896
37259
|
} finally {
|
|
35897
37260
|
perf_end?.();
|
|
35898
37261
|
}
|
|
37262
|
+
};
|
|
37263
|
+
func.runtime.render.render_ui_tree = async function (SESSION_ID, $container, nodeP, parent_infoP, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $root_container) {
|
|
37264
|
+
if (!nodeP) return;
|
|
37265
|
+
const treeP = await func.runtime.render.ensure_tree_node({
|
|
37266
|
+
SESSION_ID,
|
|
37267
|
+
nodeP,
|
|
37268
|
+
parent_infoP,
|
|
37269
|
+
paramsP,
|
|
37270
|
+
keyP,
|
|
37271
|
+
parent_nodeP,
|
|
37272
|
+
});
|
|
37273
|
+
|
|
37274
|
+
return await func.runtime.render.render_tree(treeP, {
|
|
37275
|
+
SESSION_ID,
|
|
37276
|
+
$container,
|
|
37277
|
+
parent_infoP,
|
|
37278
|
+
paramsP,
|
|
37279
|
+
jobNoP,
|
|
37280
|
+
is_skeleton,
|
|
37281
|
+
keyP,
|
|
37282
|
+
refreshed_ds,
|
|
37283
|
+
parent_nodeP,
|
|
37284
|
+
check_existP,
|
|
37285
|
+
$root_container,
|
|
37286
|
+
});
|
|
35899
37287
|
};
|
|
35900
37288
|
func.runtime = func.runtime || {};
|
|
35901
37289
|
func.runtime.ui = func.runtime.ui || {};
|
|
@@ -37419,6 +38807,7 @@ func.runtime.render.handle_xu_panel_program = async function (options) {
|
|
|
37419
38807
|
parent_infoP: options.parent_infoP,
|
|
37420
38808
|
jobNoP: options.jobNoP,
|
|
37421
38809
|
keyP: options.keyP,
|
|
38810
|
+
treeP: options.treeP,
|
|
37422
38811
|
parent_nodeP: options.parent_nodeP,
|
|
37423
38812
|
prop: options.nodeP.attributes,
|
|
37424
38813
|
$appendToP: $wrapper,
|
|
@@ -44969,6 +46358,12 @@ function xuda(...args) {
|
|
|
44969
46358
|
if (typeof opt !== 'object') {
|
|
44970
46359
|
return console.error('Xuda Error - opt argument is not an object');
|
|
44971
46360
|
}
|
|
46361
|
+
|
|
46362
|
+
if (!opt.ssr_payload && func.runtime.platform.get_window()?.__XUDA_SSR__) {
|
|
46363
|
+
opt.ssr_payload = func.runtime.platform.get_window().__XUDA_SSR__;
|
|
46364
|
+
}
|
|
46365
|
+
func.runtime.render.apply_runtime_bootstrap_defaults(opt);
|
|
46366
|
+
|
|
44972
46367
|
glb.URL_PARAMS = func.common.getJsonFromUrl(platform.get_url_href());
|
|
44973
46368
|
|
|
44974
46369
|
glb.worker_type = 'Worker';
|