@jinntec/fore 3.2.0 → 3.3.0
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/README.md +6 -9
- package/dist/fore-dev.js +14269 -34575
- package/dist/fore.js +13418 -31471
- package/index.js +1 -0
- package/package.json +3 -2
- package/resources/fore.css +22 -0
- package/src/ForeElementMixin.js +18 -0
- package/src/actions/abstract-action.js +94 -24
- package/src/actions/fx-insert.js +2 -2
- package/src/fx-bind.js +28 -0
- package/src/fx-fore.js +151 -38
- package/src/fx-instance.js +51 -4
- package/src/fx-model.js +189 -4
- package/src/fx-submission.js +29 -0
- package/src/modelitem.js +35 -0
- package/src/ui/abstract-control.js +2 -1
- package/src/ui/fx-control.js +93 -1
- package/src/ui/fx-include.js +34 -2
- package/src/ui/fx-items.js +3 -3
- package/src/xpath-evaluation.js +43 -0
package/src/fx-fore.js
CHANGED
|
@@ -102,6 +102,7 @@ export class FxFore extends HTMLElement {
|
|
|
102
102
|
},
|
|
103
103
|
/**
|
|
104
104
|
* merge-partial
|
|
105
|
+
* @deprecated
|
|
105
106
|
*/
|
|
106
107
|
mergePartial: {
|
|
107
108
|
type: Boolean,
|
|
@@ -346,15 +347,92 @@ export class FxFore extends HTMLElement {
|
|
|
346
347
|
this.initialRun = true;
|
|
347
348
|
this._scanForNewTemplateExpressionsNextRefresh = false;
|
|
348
349
|
this.repeatsFromAttributesCreated = false;
|
|
350
|
+
/*
|
|
349
351
|
this.validateOn = this.hasAttribute('validate-on')
|
|
350
352
|
? this.getAttribute('validate-on')
|
|
351
353
|
: 'update';
|
|
354
|
+
*/
|
|
352
355
|
// this.mergePartial = this.hasAttribute('merge-partial')? true:false;
|
|
353
356
|
this.mergePartial = false;
|
|
354
357
|
this.createNodes = this.hasAttribute('create-nodes') ? true : false;
|
|
355
358
|
this._localNamesWithChanges = new Set();
|
|
356
359
|
this.setAttribute('role', 'form'); // set aria role
|
|
357
360
|
this._pendingRefresh = false;
|
|
361
|
+
|
|
362
|
+
this.debugInfo = {
|
|
363
|
+
id: this.id || null,
|
|
364
|
+
debugId: crypto.randomUUID ? crypto.randomUUID() : `fore-${Date.now()}`,
|
|
365
|
+
createdAt: performance.now(),
|
|
366
|
+
readyAt: null,
|
|
367
|
+
modelConstructStartedAt: null,
|
|
368
|
+
modelConstructDoneAt: null,
|
|
369
|
+
refreshCount: 0,
|
|
370
|
+
lastRefreshAt: null,
|
|
371
|
+
lastRefreshForce: null,
|
|
372
|
+
lastRefresh: null,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
getDebugInfo() {
|
|
377
|
+
return {
|
|
378
|
+
...this.debugInfo,
|
|
379
|
+
id: this.id || null,
|
|
380
|
+
ready: this.ready,
|
|
381
|
+
lazyRefresh: this.lazyRefresh,
|
|
382
|
+
createNodes: this.createNodes,
|
|
383
|
+
|
|
384
|
+
initOn: this.getAttribute('init-on') || null,
|
|
385
|
+
initOnTarget: this.getAttribute('init-on-target') || null,
|
|
386
|
+
ignoreExpressions: this.getAttribute('ignore-expressions') || null,
|
|
387
|
+
|
|
388
|
+
model: this.model?.getDebugInfo?.() || null,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
getDebugSnapshot(options = {}) {
|
|
393
|
+
const model = this.model;
|
|
394
|
+
|
|
395
|
+
const debugRefElements = Array.from(this.querySelectorAll('[ref]'))
|
|
396
|
+
.filter(element => typeof element.getDebugInfo === 'function');
|
|
397
|
+
|
|
398
|
+
const bindingElements = debugRefElements
|
|
399
|
+
.filter(element => element.localName === 'fx-bind');
|
|
400
|
+
|
|
401
|
+
const boundElementNames = new Set([
|
|
402
|
+
'fx-control',
|
|
403
|
+
'fx-output',
|
|
404
|
+
'fx-upload',
|
|
405
|
+
'fx-group',
|
|
406
|
+
'fx-repeat',
|
|
407
|
+
'fx-switch',
|
|
408
|
+
]);
|
|
409
|
+
|
|
410
|
+
const boundUiElements = debugRefElements
|
|
411
|
+
.filter(element => boundElementNames.has(element.localName));
|
|
412
|
+
|
|
413
|
+
const bindings = bindingElements.map(element => element.getDebugInfo());
|
|
414
|
+
|
|
415
|
+
const boundElements = boundUiElements.map(element => element.getDebugInfo());
|
|
416
|
+
|
|
417
|
+
const submissions = Array.from(this.querySelectorAll('fx-submission'))
|
|
418
|
+
.filter(element => typeof element.getDebugInfo === 'function')
|
|
419
|
+
.map(element => element.getDebugInfo());
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
fore: this.getDebugInfo?.() || null,
|
|
423
|
+
|
|
424
|
+
model:
|
|
425
|
+
model?.getDebugInfo?.({
|
|
426
|
+
includeGraphs: options.includeGraphs === true,
|
|
427
|
+
}) || null,
|
|
428
|
+
|
|
429
|
+
instances: model?.instances?.map(instance => instance.getDebugInfo?.()) || [],
|
|
430
|
+
modelItems: model?.modelItems?.map(item => item.getDebugInfo?.()) || [],
|
|
431
|
+
|
|
432
|
+
bindings,
|
|
433
|
+
boundElements,
|
|
434
|
+
submissions
|
|
435
|
+
};
|
|
358
436
|
}
|
|
359
437
|
|
|
360
438
|
/**
|
|
@@ -387,7 +465,7 @@ export class FxFore extends HTMLElement {
|
|
|
387
465
|
return null;
|
|
388
466
|
}
|
|
389
467
|
|
|
390
|
-
_isReadyTarget(el) {
|
|
468
|
+
static _isReadyTarget(el) {
|
|
391
469
|
return !!(
|
|
392
470
|
el &&
|
|
393
471
|
(el.ready === true ||
|
|
@@ -396,6 +474,17 @@ export class FxFore extends HTMLElement {
|
|
|
396
474
|
);
|
|
397
475
|
}
|
|
398
476
|
|
|
477
|
+
/**
|
|
478
|
+
* Resolves once `fore` has dispatched its initial `ready` event (or
|
|
479
|
+
* immediately, if it's already ready).
|
|
480
|
+
*/
|
|
481
|
+
static waitUntilReady(fore) {
|
|
482
|
+
if (FxFore._isReadyTarget(fore)) {
|
|
483
|
+
return Promise.resolve();
|
|
484
|
+
}
|
|
485
|
+
return FxFore._waitForEvent(fore, 'ready', FxFore._isReadyTarget);
|
|
486
|
+
}
|
|
487
|
+
|
|
399
488
|
/**
|
|
400
489
|
* Collect all init gates derived from attributes.
|
|
401
490
|
*
|
|
@@ -433,7 +522,7 @@ export class FxFore extends HTMLElement {
|
|
|
433
522
|
return gates;
|
|
434
523
|
}
|
|
435
524
|
|
|
436
|
-
_waitForEvent(target, eventName, isSatisfiedFn = null) {
|
|
525
|
+
static _waitForEvent(target, eventName, isSatisfiedFn = null) {
|
|
437
526
|
// If a caller provides an explicit satisfaction check, honor it first.
|
|
438
527
|
if (typeof isSatisfiedFn === 'function' && isSatisfiedFn(target)) {
|
|
439
528
|
FxFore._markInitEventSeen(target, eventName);
|
|
@@ -495,20 +584,20 @@ export class FxFore extends HTMLElement {
|
|
|
495
584
|
_waitForInitGate({ event, targetSpec }) {
|
|
496
585
|
// Direct targets
|
|
497
586
|
if (targetSpec === 'self') {
|
|
498
|
-
const satisfied = event === 'ready' ? t =>
|
|
499
|
-
return
|
|
587
|
+
const satisfied = event === 'ready' ? t => FxFore._isReadyTarget(t) : null;
|
|
588
|
+
return FxFore._waitForEvent(this, event, satisfied);
|
|
500
589
|
}
|
|
501
590
|
if (targetSpec === 'document') {
|
|
502
|
-
return
|
|
591
|
+
return FxFore._waitForEvent(document, event);
|
|
503
592
|
}
|
|
504
593
|
if (targetSpec === 'window') {
|
|
505
|
-
return
|
|
594
|
+
return FxFore._waitForEvent(window, event);
|
|
506
595
|
}
|
|
507
596
|
|
|
508
597
|
// Special: closest fx-fore
|
|
509
598
|
if (targetSpec === 'closest') {
|
|
510
599
|
const recheckFn =
|
|
511
|
-
event === 'ready' ? () =>
|
|
600
|
+
event === 'ready' ? () => FxFore._isReadyTarget(this.closest('fx-fore')) : null;
|
|
512
601
|
|
|
513
602
|
const matchesFn = ev => {
|
|
514
603
|
const t = ev.target;
|
|
@@ -522,7 +611,7 @@ export class FxFore extends HTMLElement {
|
|
|
522
611
|
const selector = targetSpec;
|
|
523
612
|
|
|
524
613
|
const recheckFn =
|
|
525
|
-
event === 'ready' ? () =>
|
|
614
|
+
event === 'ready' ? () => FxFore._isReadyTarget(this._findBySelector(selector)) : null;
|
|
526
615
|
|
|
527
616
|
if (typeof recheckFn === 'function' && recheckFn()) {
|
|
528
617
|
return Promise.resolve();
|
|
@@ -627,7 +716,10 @@ export class FxFore extends HTMLElement {
|
|
|
627
716
|
const libs = Array.from(this.querySelectorAll('fx-functionlib'));
|
|
628
717
|
await Promise.all(libs.map(l => l.readyPromise || Promise.resolve()));
|
|
629
718
|
|
|
719
|
+
this.debugInfo.modelConstructStartedAt = performance.now();
|
|
630
720
|
await modelElement.modelConstruct();
|
|
721
|
+
this.debugInfo.modelConstructDoneAt = performance.now();
|
|
722
|
+
|
|
631
723
|
console.log('varbindings ', this._instanceVarBindings);
|
|
632
724
|
this._handleModelConstructDone();
|
|
633
725
|
}
|
|
@@ -702,9 +794,8 @@ export class FxFore extends HTMLElement {
|
|
|
702
794
|
// e.stopImmediatePropagation();
|
|
703
795
|
},true);
|
|
704
796
|
*/
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
: null;
|
|
797
|
+
const userIgnore = this.getAttribute('ignore-expressions');
|
|
798
|
+
this.ignoreExpressions = userIgnore ? `[pattern], ${userIgnore}` : '[pattern]';
|
|
708
799
|
|
|
709
800
|
this.lazyRefresh = this.hasAttribute('refresh-on-view');
|
|
710
801
|
if (this.lazyRefresh) {
|
|
@@ -945,6 +1036,11 @@ export class FxFore extends HTMLElement {
|
|
|
945
1036
|
async refresh(force) {
|
|
946
1037
|
// If we're already refreshing, do NOT drop the request.
|
|
947
1038
|
// Queue a hard refresh and return a promise that resolves when the next refresh finishes.
|
|
1039
|
+
|
|
1040
|
+
this.debugInfo.refreshCount += 1;
|
|
1041
|
+
this.debugInfo.lastRefreshAt = performance.now();
|
|
1042
|
+
this.debugInfo.lastRefreshForce = !!force;
|
|
1043
|
+
|
|
948
1044
|
if (this.isRefreshing) {
|
|
949
1045
|
// keep "strongest" request: any true means hard refresh
|
|
950
1046
|
this._pendingRefresh = this._pendingRefresh || force === true;
|
|
@@ -957,8 +1053,12 @@ export class FxFore extends HTMLElement {
|
|
|
957
1053
|
this.isRefreshing = true;
|
|
958
1054
|
this.isRefreshPhase = true;
|
|
959
1055
|
|
|
1056
|
+
const refreshStart = performance.now();
|
|
1057
|
+
const isFullRefresh = force === true || this.initialRun;
|
|
1058
|
+
const batchedCount = this.batchedNotifications.size;
|
|
1059
|
+
|
|
960
1060
|
try {
|
|
961
|
-
if (
|
|
1061
|
+
if (isFullRefresh) {
|
|
962
1062
|
performance.mark('force-refresh-start');
|
|
963
1063
|
console.log('🔄 🔴🔴🔴 ### full refresh() on ', this);
|
|
964
1064
|
await Fore.refreshChildren(this, force);
|
|
@@ -985,6 +1085,15 @@ export class FxFore extends HTMLElement {
|
|
|
985
1085
|
this.getModel().modelItems,
|
|
986
1086
|
);
|
|
987
1087
|
|
|
1088
|
+
// Record timing before dispatching 'refresh-done' since listeners (eg. fx-debugger)
|
|
1089
|
+
// may synchronously read this.debugInfo.lastRefresh in response to the event.
|
|
1090
|
+
this.debugInfo.lastRefresh = {
|
|
1091
|
+
timestamp: performance.now(),
|
|
1092
|
+
kind: isFullRefresh ? 'full' : 'partial',
|
|
1093
|
+
durationMs: performance.now() - refreshStart,
|
|
1094
|
+
batchedCount,
|
|
1095
|
+
};
|
|
1096
|
+
|
|
988
1097
|
Fore.dispatch(this, 'refresh-done', {});
|
|
989
1098
|
|
|
990
1099
|
const subFores = Array.from(this.querySelectorAll('fx-fore'));
|
|
@@ -1018,59 +1127,63 @@ export class FxFore extends HTMLElement {
|
|
|
1018
1127
|
}
|
|
1019
1128
|
|
|
1020
1129
|
/**
|
|
1021
|
-
* Process all batched notifications at the end of the refresh phase
|
|
1130
|
+
* Process all batched notifications at the end of the refresh phase.
|
|
1131
|
+
* Async so that all control refresh() calls (which are themselves async) are awaited
|
|
1132
|
+
* before refresh-done fires — prevents _isRefreshing from being true when the
|
|
1133
|
+
* next user input event arrives.
|
|
1022
1134
|
*/
|
|
1023
|
-
_processBatchedNotifications() {
|
|
1135
|
+
async _processBatchedNotifications() {
|
|
1024
1136
|
if (this.batchedNotifications.size > 0) {
|
|
1025
1137
|
console.log(`🔄 🎯 ### processing ${this.batchedNotifications.size} batched notifications`);
|
|
1026
1138
|
console.log('🔄 🎯 ### processing ', Array.from(this.batchedNotifications));
|
|
1027
1139
|
|
|
1028
|
-
|
|
1140
|
+
const refreshPromises = [];
|
|
1029
1141
|
|
|
1030
|
-
// Process all batched notifications
|
|
1142
|
+
// Process all batched notifications.
|
|
1143
|
+
// Note: Set.forEach visits items added during iteration (they are appended to the end),
|
|
1144
|
+
// so controls added via observer.update() (which calls addToBatchedNotifications) are
|
|
1145
|
+
// also visited and their refresh() promises collected.
|
|
1031
1146
|
this.batchedNotifications.forEach(entry => {
|
|
1032
|
-
// console.log('batched update', entry);
|
|
1033
|
-
// handle repeatitems created via data-ref
|
|
1034
1147
|
if (entry.classList && entry.classList.contains('fx-repeatitem')) {
|
|
1035
|
-
Fore.refreshChildren(entry, true);
|
|
1148
|
+
refreshPromises.push(Fore.refreshChildren(entry, true));
|
|
1036
1149
|
}
|
|
1037
1150
|
if (entry && typeof entry.refresh === 'function') {
|
|
1038
|
-
// Entry is a Ui Element
|
|
1039
|
-
// Force refresh for this whole subtree
|
|
1040
1151
|
const uiElement = /** @type {import('./ui/UIElement.js').UIElement} */ (entry);
|
|
1041
1152
|
if (!uiElement.ownerDocument.contains(uiElement)) {
|
|
1042
|
-
// Something already removed this ui element. Skip.
|
|
1043
1153
|
return;
|
|
1044
1154
|
}
|
|
1045
|
-
uiElement.refresh(true);
|
|
1155
|
+
refreshPromises.push(uiElement.refresh(true));
|
|
1046
1156
|
}
|
|
1047
1157
|
const nonrelevant = Array.from(this.querySelectorAll('[nonrelevant]'));
|
|
1048
|
-
// loop nonrelevant elements
|
|
1049
1158
|
if (nonrelevant) {
|
|
1050
|
-
nonrelevant.forEach(
|
|
1051
|
-
if (
|
|
1052
|
-
|
|
1159
|
+
nonrelevant.forEach(el => {
|
|
1160
|
+
if (el.refresh) {
|
|
1161
|
+
refreshPromises.push(el.refresh());
|
|
1053
1162
|
}
|
|
1054
1163
|
});
|
|
1055
1164
|
}
|
|
1056
1165
|
if (entry.observers) {
|
|
1057
|
-
// Item is a model item
|
|
1058
1166
|
entry.observers.forEach(observer => {
|
|
1059
|
-
// console.log('🔍 processing observer', observer);
|
|
1060
1167
|
if (typeof observer.update === 'function') {
|
|
1061
|
-
// console.log('updating observer', observer);
|
|
1062
1168
|
observer.update(entry);
|
|
1063
1169
|
}
|
|
1064
1170
|
});
|
|
1065
1171
|
}
|
|
1066
1172
|
});
|
|
1067
1173
|
|
|
1068
|
-
// Update template expressions after processing batched notifications
|
|
1069
|
-
// This ensures template expressions are re-evaluated when data changes
|
|
1070
1174
|
this._processTemplateExpressions();
|
|
1071
|
-
|
|
1072
|
-
// Clear the batch
|
|
1073
1175
|
this.batchedNotifications.clear();
|
|
1176
|
+
|
|
1177
|
+
if (refreshPromises.length > 0) {
|
|
1178
|
+
await Promise.all(refreshPromises);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// Items added to batchedNotifications during the async Promise.all phase
|
|
1182
|
+
// (e.g. by a second event listener that fired after the batch was cleared)
|
|
1183
|
+
// are picked up here so they aren't lost.
|
|
1184
|
+
if (this.batchedNotifications.size > 0) {
|
|
1185
|
+
await this._processBatchedNotifications();
|
|
1186
|
+
}
|
|
1074
1187
|
}
|
|
1075
1188
|
}
|
|
1076
1189
|
|
|
@@ -1230,10 +1343,8 @@ export class FxFore extends HTMLElement {
|
|
|
1230
1343
|
} // eslint-disable-next-line class-methods-use-this
|
|
1231
1344
|
_getTemplateExpression(node) {
|
|
1232
1345
|
if (this.ignoredNodes) {
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
}
|
|
1236
|
-
const found = this.ignoredNodes.find(n => n.contains(node));
|
|
1346
|
+
const checkNode = node.nodeType === Node.ATTRIBUTE_NODE ? node.ownerElement : node;
|
|
1347
|
+
const found = this.ignoredNodes.find(n => n.contains(checkNode));
|
|
1237
1348
|
if (found) return null;
|
|
1238
1349
|
}
|
|
1239
1350
|
if (node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
@@ -1252,6 +1363,7 @@ export class FxFore extends HTMLElement {
|
|
|
1252
1363
|
* @private
|
|
1253
1364
|
*/
|
|
1254
1365
|
_handleModelConstructDone() {
|
|
1366
|
+
this.debugInfo.modelConstructDoneAt = performance.now();
|
|
1255
1367
|
if (this.showConfirmation) {
|
|
1256
1368
|
window.addEventListener('beforeunload', event => {
|
|
1257
1369
|
if (this.dirtyState === dirtyStates.DIRTY) {
|
|
@@ -1418,6 +1530,7 @@ export class FxFore extends HTMLElement {
|
|
|
1418
1530
|
// console.log(`### <<<<< ${this.id} ready >>>>>`);
|
|
1419
1531
|
|
|
1420
1532
|
Fore.dispatch(this, 'ready', {});
|
|
1533
|
+
this.debugInfo.readyAt = performance.now();
|
|
1421
1534
|
// console.log('dataChanged', FxModel.dataChanged);
|
|
1422
1535
|
this.markAsClean();
|
|
1423
1536
|
|
package/src/fx-instance.js
CHANGED
|
@@ -9,7 +9,11 @@ async function handleResponse(fxInstance, response) {
|
|
|
9
9
|
alert(`response status: ${status} - failed to load data for '${fxInstance.src}' - stopping.`);
|
|
10
10
|
throw new Error(`failed to load data - status: ${status}`);
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
const responseContentType = response.headers
|
|
13
|
+
.get('content-type')
|
|
14
|
+
.split(';')[0]
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase();
|
|
13
17
|
|
|
14
18
|
if (responseContentType.startsWith('text/html')) {
|
|
15
19
|
return response.text().then(result => new DOMParser().parseFromString(result, 'text/html'));
|
|
@@ -49,6 +53,37 @@ export class FxInstance extends HTMLElement {
|
|
|
49
53
|
|
|
50
54
|
// JSON facade (only relevant for JSON instances)
|
|
51
55
|
this.domFacade = null;
|
|
56
|
+
|
|
57
|
+
this.debugInfo = {
|
|
58
|
+
debugId: `instance-${Math.random().toString(36).slice(2, 9)}`,
|
|
59
|
+
createdAt: performance.now(),
|
|
60
|
+
initializedAt: null,
|
|
61
|
+
loadCount: 0,
|
|
62
|
+
/*
|
|
63
|
+
mutationCount: 0,
|
|
64
|
+
lastMutationAt: null,
|
|
65
|
+
*/
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getDebugInfo() {
|
|
70
|
+
const defaultContext = this.getDefaultContext?.();
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
...this.debugInfo,
|
|
74
|
+
id: this.getAttribute('id') || null,
|
|
75
|
+
instanceId: this.instanceId,
|
|
76
|
+
type: this.type,
|
|
77
|
+
src: this.getAttribute('src') || null,
|
|
78
|
+
shared: this.hasAttribute('shared'),
|
|
79
|
+
hasData: !!this.instanceData,
|
|
80
|
+
hasNodeset: !!this.nodeset,
|
|
81
|
+
defaultContextType: defaultContext?.nodeType
|
|
82
|
+
? 'xml-node'
|
|
83
|
+
: defaultContext?.__jsonlens__
|
|
84
|
+
? 'json-lens'
|
|
85
|
+
: typeof defaultContext,
|
|
86
|
+
};
|
|
52
87
|
}
|
|
53
88
|
|
|
54
89
|
connectedCallback() {
|
|
@@ -61,7 +96,9 @@ export class FxInstance extends HTMLElement {
|
|
|
61
96
|
// If the author did not provide an id on that first instance, we set id="default".
|
|
62
97
|
// If the author provided an id on that first instance, we use that id instead.
|
|
63
98
|
const parentModel =
|
|
64
|
-
this.parentNode &&
|
|
99
|
+
this.parentNode &&
|
|
100
|
+
this.parentNode.nodeName &&
|
|
101
|
+
this.parentNode.nodeName.toUpperCase() === 'FX-MODEL'
|
|
65
102
|
? this.parentNode
|
|
66
103
|
: null;
|
|
67
104
|
|
|
@@ -92,7 +129,9 @@ export class FxInstance extends HTMLElement {
|
|
|
92
129
|
}
|
|
93
130
|
}
|
|
94
131
|
|
|
95
|
-
this.credentials = this.hasAttribute('credentials')
|
|
132
|
+
this.credentials = this.hasAttribute('credentials')
|
|
133
|
+
? this.getAttribute('credentials')
|
|
134
|
+
: 'same-origin';
|
|
96
135
|
if (!['same-origin', 'include', 'omit'].includes(this.credentials)) {
|
|
97
136
|
console.error(
|
|
98
137
|
`fx-submission: the value of credentials is not valid. Expected 'same-origin', 'include' or 'omit' but got '${this.credentials}'`,
|
|
@@ -144,6 +183,8 @@ export class FxInstance extends HTMLElement {
|
|
|
144
183
|
|
|
145
184
|
// Signal structure mutation (used by fx-fore for refresh decisions)
|
|
146
185
|
this.dispatchEvent(new CustomEvent('path-mutated', { bubbles: true, composed: true }));
|
|
186
|
+
// this.debugInfo.mutationCount += 1;
|
|
187
|
+
// this.debugInfo.lastMutationAt = performance.now();
|
|
147
188
|
}
|
|
148
189
|
|
|
149
190
|
/**
|
|
@@ -162,6 +203,8 @@ export class FxInstance extends HTMLElement {
|
|
|
162
203
|
}
|
|
163
204
|
|
|
164
205
|
reset() {
|
|
206
|
+
// this.debugInfo.mutationCount += 1;
|
|
207
|
+
// this.debugInfo.lastMutationAt = performance.now();
|
|
165
208
|
// use the setter so nodeset is rebuilt for JSON too
|
|
166
209
|
if (this.originalInstance && this.type === 'xml') {
|
|
167
210
|
this.instanceData = this.originalInstance.cloneNode(true);
|
|
@@ -193,6 +236,8 @@ export class FxInstance extends HTMLElement {
|
|
|
193
236
|
* legacy setter API: keep it, but forward to instanceData setter
|
|
194
237
|
*/
|
|
195
238
|
setInstanceData(data) {
|
|
239
|
+
// this.debugInfo.mutationCount += 1;
|
|
240
|
+
// this.debugInfo.lastMutationAt = performance.now();
|
|
196
241
|
this.instanceData = data;
|
|
197
242
|
}
|
|
198
243
|
|
|
@@ -224,6 +269,8 @@ export class FxInstance extends HTMLElement {
|
|
|
224
269
|
} else if (this.childNodes.length !== 0) {
|
|
225
270
|
this._useInlineData();
|
|
226
271
|
}
|
|
272
|
+
this.debugInfo.initializedAt = performance.now();
|
|
273
|
+
this.debugInfo.loadCount += 1;
|
|
227
274
|
}
|
|
228
275
|
|
|
229
276
|
createInstanceData() {
|
|
@@ -339,4 +386,4 @@ export class FxInstance extends HTMLElement {
|
|
|
339
386
|
|
|
340
387
|
if (!customElements.get('fx-instance')) {
|
|
341
388
|
customElements.define('fx-instance', FxInstance);
|
|
342
|
-
}
|
|
389
|
+
}
|