@xuda.io/xuda-worker-bundle 1.3.2694 → 1.3.2696
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/index.js +207 -8
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -291,7 +291,30 @@ func.runtime.platform.emit = function (name, data) {
|
|
|
291
291
|
};
|
|
292
292
|
|
|
293
293
|
// ── Platform helpers for DOM-independent resource loading ──
|
|
294
|
-
func.runtime.platform.
|
|
294
|
+
func.runtime.platform.apply_element_attributes = function (node, attributes, excluded_keys = []) {
|
|
295
|
+
if (!node?.setAttribute || !attributes) {
|
|
296
|
+
return node;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const excluded = new Set(excluded_keys || []);
|
|
300
|
+
const attr_keys = Object.keys(attributes);
|
|
301
|
+
for (let index = 0; index < attr_keys.length; index++) {
|
|
302
|
+
const key = attr_keys[index];
|
|
303
|
+
if (!key || excluded.has(key)) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const value = attributes[key];
|
|
308
|
+
if (value === false || typeof value === 'undefined') {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
node.setAttribute(key, value === null ? '' : `${value}`);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return node;
|
|
316
|
+
};
|
|
317
|
+
func.runtime.platform.load_script = function (url, type, callback, attributes) {
|
|
295
318
|
const doc = func.runtime.platform.get_document();
|
|
296
319
|
if (!doc?.createElement || !doc?.head?.appendChild) {
|
|
297
320
|
if (callback) {
|
|
@@ -299,19 +322,63 @@ func.runtime.platform.load_script = function (url, type, callback) {
|
|
|
299
322
|
}
|
|
300
323
|
return;
|
|
301
324
|
}
|
|
325
|
+
const find_existing_script = function () {
|
|
326
|
+
const asset_key = attributes?.['data-xuda-asset-key'];
|
|
327
|
+
const scripts = doc.querySelectorAll ? Array.from(doc.querySelectorAll('script')) : [];
|
|
328
|
+
return scripts.find(function (script) {
|
|
329
|
+
if (asset_key && script.getAttribute('data-xuda-asset-key') === asset_key) {
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
return !!(url && script.getAttribute('src') === url);
|
|
333
|
+
}) || null;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const existing_script = find_existing_script();
|
|
337
|
+
if (existing_script) {
|
|
338
|
+
if (callback) {
|
|
339
|
+
if (existing_script.getAttribute('data-xuda-loaded') === 'true' || !url) {
|
|
340
|
+
callback();
|
|
341
|
+
} else {
|
|
342
|
+
existing_script.addEventListener('load', callback, { once: true });
|
|
343
|
+
existing_script.addEventListener('error', callback, { once: true });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return existing_script;
|
|
347
|
+
}
|
|
348
|
+
|
|
302
349
|
const script = doc.createElement('script');
|
|
303
350
|
script.src = url;
|
|
304
351
|
if (type) script.type = type;
|
|
305
|
-
script
|
|
352
|
+
func.runtime.platform.apply_element_attributes(script, attributes, ['src', 'type']);
|
|
353
|
+
script.onload = function () {
|
|
354
|
+
script.setAttribute('data-xuda-loaded', 'true');
|
|
355
|
+
if (callback) {
|
|
356
|
+
callback();
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
script.onerror = function () {
|
|
360
|
+
if (callback) {
|
|
361
|
+
callback();
|
|
362
|
+
}
|
|
363
|
+
};
|
|
306
364
|
doc.head.appendChild(script);
|
|
365
|
+
return script;
|
|
307
366
|
};
|
|
308
|
-
func.runtime.platform.load_css = function (href) {
|
|
367
|
+
func.runtime.platform.load_css = function (href, attributes) {
|
|
309
368
|
const doc = func.runtime.platform.get_document();
|
|
310
369
|
if (!doc?.createElement || !doc?.head) {
|
|
311
370
|
return;
|
|
312
371
|
}
|
|
313
372
|
try {
|
|
314
|
-
|
|
373
|
+
const asset_key = attributes?.['data-xuda-asset-key'];
|
|
374
|
+
const existing_links = doc.querySelectorAll ? Array.from(doc.querySelectorAll('link')) : [];
|
|
375
|
+
const existing = existing_links.find(function (link) {
|
|
376
|
+
if (asset_key && link.getAttribute('data-xuda-asset-key') === asset_key) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
return !!(href && link.getAttribute('href') === href);
|
|
380
|
+
});
|
|
381
|
+
if (existing) return existing;
|
|
315
382
|
} catch (err) {
|
|
316
383
|
return;
|
|
317
384
|
}
|
|
@@ -319,7 +386,9 @@ func.runtime.platform.load_css = function (href) {
|
|
|
319
386
|
link.rel = 'stylesheet';
|
|
320
387
|
link.type = 'text/css';
|
|
321
388
|
link.href = href;
|
|
389
|
+
func.runtime.platform.apply_element_attributes(link, attributes, ['href']);
|
|
322
390
|
doc.head.insertBefore(link, doc.head.firstChild);
|
|
391
|
+
return link;
|
|
323
392
|
};
|
|
324
393
|
func.runtime.platform.remove_js_css = function (filename, filetype) {
|
|
325
394
|
const doc = func.runtime.platform.get_document();
|
|
@@ -353,6 +422,128 @@ func.runtime.platform.set_cursor = function (element, cursor) {
|
|
|
353
422
|
node.style.cursor = cursor;
|
|
354
423
|
}
|
|
355
424
|
};
|
|
425
|
+
func.runtime.program.normalize_doc_for_runtime = function (doc) {
|
|
426
|
+
if (!doc || doc.__xudaRuntimeNormalized || !Array.isArray(doc.progUi) || !doc.progUi.length) {
|
|
427
|
+
return doc;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const normalize_tag_name = function (tag_name) {
|
|
431
|
+
return `${tag_name || ''}`.trim().toLowerCase();
|
|
432
|
+
};
|
|
433
|
+
const merge_attributes = function (target, source) {
|
|
434
|
+
const merged = { ...(target || {}) };
|
|
435
|
+
const source_attributes = source || {};
|
|
436
|
+
const keys = Object.keys(source_attributes);
|
|
437
|
+
|
|
438
|
+
for (let index = 0; index < keys.length; index++) {
|
|
439
|
+
const key = keys[index];
|
|
440
|
+
const value = source_attributes[key];
|
|
441
|
+
if (typeof value === 'undefined') {
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (key === 'class' && merged.class && value) {
|
|
446
|
+
const next_value = `${merged.class} ${value}`.trim();
|
|
447
|
+
merged.class = Array.from(new Set(next_value.split(/\s+/).filter(Boolean))).join(' ');
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (key === 'style' && merged.style && value) {
|
|
452
|
+
merged.style = `${merged.style}; ${value}`.trim();
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (typeof merged[key] === 'undefined') {
|
|
457
|
+
merged[key] = value;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return merged;
|
|
462
|
+
};
|
|
463
|
+
const normalize_nodes = function (nodes, state) {
|
|
464
|
+
const normalized_nodes = [];
|
|
465
|
+
|
|
466
|
+
for (let index = 0; index < (nodes || []).length; index++) {
|
|
467
|
+
const node = nodes[index];
|
|
468
|
+
if (!node || typeof node !== 'object') {
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const tag_name = normalize_tag_name(node.tagName);
|
|
473
|
+
|
|
474
|
+
if (tag_name === '!doctype') {
|
|
475
|
+
state.changed = true;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (tag_name === 'html') {
|
|
480
|
+
state.changed = true;
|
|
481
|
+
state.root_attributes = merge_attributes(state.root_attributes, node.attributes);
|
|
482
|
+
normalized_nodes.push.apply(normalized_nodes, normalize_nodes(node.children, state));
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (tag_name === 'head') {
|
|
487
|
+
state.changed = true;
|
|
488
|
+
normalized_nodes.push.apply(normalized_nodes, normalize_nodes(node.children, state));
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (tag_name === 'body') {
|
|
493
|
+
state.changed = true;
|
|
494
|
+
state.root_attributes = merge_attributes(state.root_attributes, node.attributes);
|
|
495
|
+
normalized_nodes.push.apply(normalized_nodes, normalize_nodes(node.children, state));
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
let next_node = node;
|
|
500
|
+
if (Array.isArray(node.children) && node.children.length) {
|
|
501
|
+
const next_children = normalize_nodes(node.children, state);
|
|
502
|
+
if (next_children !== node.children) {
|
|
503
|
+
next_node = {
|
|
504
|
+
...node,
|
|
505
|
+
children: next_children,
|
|
506
|
+
};
|
|
507
|
+
state.changed = true;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
normalized_nodes.push(next_node);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return normalized_nodes;
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
const [root_node, ...extra_nodes] = doc.progUi;
|
|
518
|
+
if (!root_node || typeof root_node !== 'object') {
|
|
519
|
+
return doc;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const state = {
|
|
523
|
+
changed: false,
|
|
524
|
+
root_attributes: {},
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
const normalized_children = normalize_nodes([...(root_node.children || []), ...extra_nodes], state);
|
|
528
|
+
const merged_attributes = merge_attributes(root_node.attributes, state.root_attributes);
|
|
529
|
+
|
|
530
|
+
if (!state.changed && !Object.keys(state.root_attributes).length) {
|
|
531
|
+
doc.__xudaRuntimeNormalized = true;
|
|
532
|
+
return doc;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return {
|
|
536
|
+
...doc,
|
|
537
|
+
__xudaRuntimeNormalized: true,
|
|
538
|
+
progUi: [
|
|
539
|
+
{
|
|
540
|
+
...root_node,
|
|
541
|
+
attributes: merged_attributes,
|
|
542
|
+
children: normalized_children,
|
|
543
|
+
},
|
|
544
|
+
],
|
|
545
|
+
};
|
|
546
|
+
};
|
|
356
547
|
|
|
357
548
|
func.runtime.env = {
|
|
358
549
|
get_url_params: function () {
|
|
@@ -1154,10 +1345,10 @@ func.runtime.resources.load_cdn = async function (SESSION_ID, resource) {
|
|
|
1154
1345
|
await func.utils.load_js_on_demand(normalized_resource.src);
|
|
1155
1346
|
break;
|
|
1156
1347
|
case 'css':
|
|
1157
|
-
|
|
1348
|
+
func.runtime.platform.load_css(normalized_resource.src);
|
|
1158
1349
|
break;
|
|
1159
1350
|
case 'module':
|
|
1160
|
-
func.utils.load_js_on_demand(normalized_resource.src, 'module');
|
|
1351
|
+
await func.utils.load_js_on_demand(normalized_resource.src, 'module');
|
|
1161
1352
|
break;
|
|
1162
1353
|
default:
|
|
1163
1354
|
await func.utils.load_js_on_demand(normalized_resource.src);
|
|
@@ -6886,6 +7077,13 @@ func.utils.DOCS_OBJ = {};
|
|
|
6886
7077
|
func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
|
|
6887
7078
|
if (!idP || idP === '0') return;
|
|
6888
7079
|
|
|
7080
|
+
const normalize_runtime_doc = function (doc) {
|
|
7081
|
+
if (!doc || !func.runtime.program?.normalize_doc_for_runtime) {
|
|
7082
|
+
return doc;
|
|
7083
|
+
}
|
|
7084
|
+
return func.runtime.program.normalize_doc_for_runtime(doc);
|
|
7085
|
+
};
|
|
7086
|
+
|
|
6889
7087
|
var _session = SESSION_OBJ[SESSION_ID];
|
|
6890
7088
|
const _app_id = _session.app_id;
|
|
6891
7089
|
if (!DOCS_OBJ[_app_id]) {
|
|
@@ -6907,7 +7105,8 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
|
|
|
6907
7105
|
}
|
|
6908
7106
|
let val = _session.project_data?.programs?.[idP];
|
|
6909
7107
|
if (val) {
|
|
6910
|
-
|
|
7108
|
+
DOCS_OBJ[_app_id][idP] = normalize_runtime_doc(val);
|
|
7109
|
+
return DOCS_OBJ[_app_id][idP];
|
|
6911
7110
|
}
|
|
6912
7111
|
}
|
|
6913
7112
|
|
|
@@ -6915,7 +7114,7 @@ func.utils.DOCS_OBJ.get = async function (SESSION_ID, idP) {
|
|
|
6915
7114
|
const module = await func.common.get_module(SESSION_ID, `xuda-progs-loader-module.mjs`);
|
|
6916
7115
|
|
|
6917
7116
|
if (idP !== 'system') {
|
|
6918
|
-
DOCS_OBJ[_app_id][idP] = await module.DOCS_OBJ_get(SESSION_ID, idP);
|
|
7117
|
+
DOCS_OBJ[_app_id][idP] = normalize_runtime_doc(await module.DOCS_OBJ_get(SESSION_ID, idP));
|
|
6919
7118
|
if (DOCS_OBJ[_app_id][idP] && xu_isEmpty(DOCS_OBJ[_app_id][idP])) {
|
|
6920
7119
|
await func.utils.remove_cached_objects(SESSION_ID);
|
|
6921
7120
|
|