@geometra/proxy 1.65.3 → 1.65.4
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/dist/dom-actions.d.ts.map +1 -1
- package/dist/dom-actions.js +158 -26
- package/dist/dom-actions.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom-actions.d.ts","sourceRoot":"","sources":["../src/dom-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAkC,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAE/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEnE,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;AAgDvE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;IACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;IACrC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;CACvC;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CAMvD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAIjE;
|
|
1
|
+
{"version":3,"file":"dom-actions.d.ts","sourceRoot":"","sources":["../src/dom-actions.ts"],"names":[],"mappings":"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"}
|
package/dist/dom-actions.js
CHANGED
|
@@ -2429,26 +2429,67 @@ async function readFormLevelInvalidState(handle, opts) {
|
|
|
2429
2429
|
const form = el.closest('form');
|
|
2430
2430
|
if (!form)
|
|
2431
2431
|
return false;
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
const
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2432
|
+
function rootScopedElementById(owner, id) {
|
|
2433
|
+
const root = owner.getRootNode();
|
|
2434
|
+
if (root instanceof ShadowRoot)
|
|
2435
|
+
return root.getElementById(id);
|
|
2436
|
+
if (root instanceof Document)
|
|
2437
|
+
return root.getElementById(id);
|
|
2438
|
+
return null;
|
|
2439
|
+
}
|
|
2440
|
+
function linkedLabels(control) {
|
|
2441
|
+
const labels = new Set();
|
|
2442
|
+
for (const id of (control.getAttribute('aria-labelledby') ?? '').split(/\s+/).filter(Boolean)) {
|
|
2443
|
+
const label = rootScopedElementById(control, id);
|
|
2444
|
+
if (label)
|
|
2445
|
+
labels.add(label);
|
|
2446
|
+
}
|
|
2447
|
+
if (control instanceof HTMLInputElement || control instanceof HTMLSelectElement || control instanceof HTMLTextAreaElement) {
|
|
2448
|
+
for (const label of Array.from(control.labels ?? []))
|
|
2449
|
+
labels.add(label);
|
|
2450
|
+
}
|
|
2451
|
+
return [...labels];
|
|
2452
|
+
}
|
|
2453
|
+
function linkedFieldWrapper(control) {
|
|
2454
|
+
let best = null;
|
|
2455
|
+
for (const label of linkedLabels(control)) {
|
|
2456
|
+
let candidate = control;
|
|
2457
|
+
let depth = 0;
|
|
2458
|
+
while (candidate && candidate !== form && depth < 12) {
|
|
2459
|
+
if (candidate.contains(label) && (!best || depth < best.depth)) {
|
|
2460
|
+
best = { wrapper: candidate, depth };
|
|
2461
|
+
break;
|
|
2462
|
+
}
|
|
2463
|
+
candidate = candidate.parentElement;
|
|
2464
|
+
depth++;
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
return best?.wrapper ?? null;
|
|
2468
|
+
}
|
|
2469
|
+
// Prefer an ancestor that jointly owns this exact control and its
|
|
2470
|
+
// explicitly linked label. Looking for any descendant <label> can pull
|
|
2471
|
+
// an unrelated required field into the verification scope.
|
|
2472
|
+
let wrapper = linkedFieldWrapper(el);
|
|
2473
|
+
if (!wrapper) {
|
|
2474
|
+
const semanticGroup = el.closest('fieldset, [role="group"]');
|
|
2475
|
+
if (semanticGroup && semanticGroup !== form)
|
|
2476
|
+
wrapper = semanticGroup;
|
|
2477
|
+
}
|
|
2478
|
+
if (!wrapper) {
|
|
2479
|
+
let candidate = el;
|
|
2480
|
+
let depth = 0;
|
|
2481
|
+
while (candidate && candidate !== form && depth < 8) {
|
|
2482
|
+
const className = (candidate.getAttribute('class') ?? '').toLowerCase();
|
|
2483
|
+
if (className.includes('field') ||
|
|
2484
|
+
className.includes('form-group') ||
|
|
2485
|
+
className.includes('form-control') ||
|
|
2486
|
+
className.includes('input-wrapper')) {
|
|
2487
|
+
wrapper = candidate;
|
|
2488
|
+
break;
|
|
2489
|
+
}
|
|
2490
|
+
candidate = candidate.parentElement;
|
|
2491
|
+
depth++;
|
|
2492
|
+
}
|
|
2452
2493
|
}
|
|
2453
2494
|
if (!wrapper || wrapper === form)
|
|
2454
2495
|
wrapper = el.parentElement ?? el;
|
|
@@ -3284,6 +3325,7 @@ async function beginFileInputCommitGuard(handle) {
|
|
|
3284
3325
|
validFileInput: Boolean(input?.isConnected),
|
|
3285
3326
|
blockReason: input ? mutationBlockReason(input) : 'detached or no longer a file input',
|
|
3286
3327
|
accept: input?.getAttribute('accept') ?? null,
|
|
3328
|
+
multiple: input?.multiple ?? false,
|
|
3287
3329
|
names: input ? Array.from(input.files ?? []).map(file => file.name) : [],
|
|
3288
3330
|
};
|
|
3289
3331
|
const state = {
|
|
@@ -3391,7 +3433,84 @@ async function clearAmbiguousRetainedFiles(handle, actualNames, initialNames) {
|
|
|
3391
3433
|
}
|
|
3392
3434
|
return 'the changed selection was cleared best-effort without trying another candidate';
|
|
3393
3435
|
}
|
|
3394
|
-
async function
|
|
3436
|
+
async function confirmSameKeyFileInputSuccessor(page, original, fieldKey, paths, initial) {
|
|
3437
|
+
const expectedNames = expectedUploadNames(paths);
|
|
3438
|
+
const deadline = Date.now() + 1_500;
|
|
3439
|
+
while (Date.now() < deadline) {
|
|
3440
|
+
let successor;
|
|
3441
|
+
try {
|
|
3442
|
+
successor = await findAuthoredFieldByKeyInPage(page, fieldKey, 'file');
|
|
3443
|
+
}
|
|
3444
|
+
catch {
|
|
3445
|
+
// Duplicate authored keys are terminal ambiguity, not a reason to pick
|
|
3446
|
+
// one candidate or try another uploader.
|
|
3447
|
+
return false;
|
|
3448
|
+
}
|
|
3449
|
+
if (!successor) {
|
|
3450
|
+
await delay(50);
|
|
3451
|
+
continue;
|
|
3452
|
+
}
|
|
3453
|
+
const state = await successor.evaluate((input, prior) => {
|
|
3454
|
+
if (!(input instanceof HTMLInputElement) || input.type !== 'file' || !input.isConnected)
|
|
3455
|
+
return null;
|
|
3456
|
+
return {
|
|
3457
|
+
isSuccessor: input !== prior,
|
|
3458
|
+
accept: input.getAttribute('accept'),
|
|
3459
|
+
multiple: input.multiple,
|
|
3460
|
+
names: Array.from(input.files ?? []).map(file => file.name),
|
|
3461
|
+
};
|
|
3462
|
+
}, original).catch(() => null);
|
|
3463
|
+
if (!state?.isSuccessor) {
|
|
3464
|
+
await delay(50);
|
|
3465
|
+
continue;
|
|
3466
|
+
}
|
|
3467
|
+
// Only accept a stable successor whose authored contract still permits
|
|
3468
|
+
// this upload and whose exact FileList proves that this upload, rather
|
|
3469
|
+
// than a sibling input, survived.
|
|
3470
|
+
if (state.multiple !== initial.multiple)
|
|
3471
|
+
return false;
|
|
3472
|
+
try {
|
|
3473
|
+
assertPathsMatchFileAccept(paths, state.accept);
|
|
3474
|
+
}
|
|
3475
|
+
catch {
|
|
3476
|
+
return false;
|
|
3477
|
+
}
|
|
3478
|
+
if (!uploadedNamesMatch(state.names, expectedNames)) {
|
|
3479
|
+
await delay(50);
|
|
3480
|
+
continue;
|
|
3481
|
+
}
|
|
3482
|
+
await delay(40);
|
|
3483
|
+
let confirmed;
|
|
3484
|
+
try {
|
|
3485
|
+
confirmed = await findAuthoredFieldByKeyInPage(page, fieldKey, 'file');
|
|
3486
|
+
}
|
|
3487
|
+
catch {
|
|
3488
|
+
return false;
|
|
3489
|
+
}
|
|
3490
|
+
if (!confirmed)
|
|
3491
|
+
return false;
|
|
3492
|
+
const stable = await confirmed.evaluate((input, payload) => {
|
|
3493
|
+
if (!(input instanceof HTMLInputElement) ||
|
|
3494
|
+
input.type !== 'file' ||
|
|
3495
|
+
!input.isConnected ||
|
|
3496
|
+
input === payload.prior ||
|
|
3497
|
+
input.getAttribute('accept') !== payload.accept ||
|
|
3498
|
+
input.multiple !== payload.multiple)
|
|
3499
|
+
return false;
|
|
3500
|
+
const names = Array.from(input.files ?? []).map(file => file.name);
|
|
3501
|
+
return names.length === payload.names.length &&
|
|
3502
|
+
names.every((name, index) => name === payload.names[index]);
|
|
3503
|
+
}, {
|
|
3504
|
+
prior: original,
|
|
3505
|
+
accept: state.accept,
|
|
3506
|
+
multiple: initial.multiple,
|
|
3507
|
+
names: expectedNames,
|
|
3508
|
+
}).catch(() => false);
|
|
3509
|
+
return stable;
|
|
3510
|
+
}
|
|
3511
|
+
return false;
|
|
3512
|
+
}
|
|
3513
|
+
async function commitFilesToExactInput(handle, paths, targetName, opts) {
|
|
3395
3514
|
const { guard, initial } = await beginFileInputCommitGuard(handle);
|
|
3396
3515
|
try {
|
|
3397
3516
|
if (!initial.validFileInput) {
|
|
@@ -3411,7 +3530,7 @@ async function commitFilesToExactInput(handle, paths, targetName, setFiles = asy
|
|
|
3411
3530
|
}
|
|
3412
3531
|
let operationError;
|
|
3413
3532
|
try {
|
|
3414
|
-
await setFiles(paths);
|
|
3533
|
+
await (opts?.setFiles ?? (async (selectedPaths) => handle.setInputFiles(selectedPaths)))(paths);
|
|
3415
3534
|
}
|
|
3416
3535
|
catch (error) {
|
|
3417
3536
|
operationError = error;
|
|
@@ -3424,7 +3543,16 @@ async function commitFilesToExactInput(handle, paths, targetName, setFiles = asy
|
|
|
3424
3543
|
names: [],
|
|
3425
3544
|
}));
|
|
3426
3545
|
const retained = uploadedNamesMatch(final.names, expectedUploadNames(paths));
|
|
3427
|
-
|
|
3546
|
+
const originalConnected = await handle.evaluate(input => input.isConnected).catch(() => false);
|
|
3547
|
+
if (!operationError && !final.invalidReason && retained && originalConnected)
|
|
3548
|
+
return;
|
|
3549
|
+
const identityChanged = final.invalidReason === 'the exact target identity changed during commit' ||
|
|
3550
|
+
final.invalidReason === 'the exact target detached during commit' ||
|
|
3551
|
+
(!final.invalidReason && !originalConnected);
|
|
3552
|
+
if (!operationError &&
|
|
3553
|
+
identityChanged &&
|
|
3554
|
+
opts?.successor &&
|
|
3555
|
+
await confirmSameKeyFileInputSuccessor(opts.successor.page, handle, opts.successor.fieldKey, paths, initial))
|
|
3428
3556
|
return;
|
|
3429
3557
|
const cleanupOutcome = await clearAmbiguousRetainedFiles(handle, final.names, initial.names);
|
|
3430
3558
|
const operationReason = operationError instanceof Error
|
|
@@ -3446,7 +3574,9 @@ async function attachHiddenInAllFrames(page, paths, opts) {
|
|
|
3446
3574
|
const handle = await labeled.elementHandle();
|
|
3447
3575
|
if (!handle)
|
|
3448
3576
|
throw new Error('file: matched input detached before upload');
|
|
3449
|
-
await commitFilesToExactInput(handle, paths, 'matched input'
|
|
3577
|
+
await commitFilesToExactInput(handle, paths, 'matched input', {
|
|
3578
|
+
successor: opts?.fieldKey ? { page, fieldKey: opts.fieldKey } : undefined,
|
|
3579
|
+
});
|
|
3450
3580
|
return true;
|
|
3451
3581
|
}
|
|
3452
3582
|
return false;
|
|
@@ -3486,8 +3616,10 @@ async function attachViaChooser(page, paths, clickX, clickY) {
|
|
|
3486
3616
|
]);
|
|
3487
3617
|
const input = chooser.element();
|
|
3488
3618
|
try {
|
|
3489
|
-
await commitFilesToExactInput(input, paths, 'chooser input',
|
|
3490
|
-
|
|
3619
|
+
await commitFilesToExactInput(input, paths, 'chooser input', {
|
|
3620
|
+
setFiles: async (selectedPaths) => {
|
|
3621
|
+
await chooser.setFiles(selectedPaths);
|
|
3622
|
+
},
|
|
3491
3623
|
});
|
|
3492
3624
|
}
|
|
3493
3625
|
finally {
|