auto-webmcp 0.3.12 → 0.3.13

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.
@@ -1312,6 +1312,14 @@ function fillAriaField(el, value) {
1312
1312
  return;
1313
1313
  }
1314
1314
  const htmlEl = el;
1315
+ console.log("[auto-webmcp] fillAriaField", {
1316
+ tag: el.tagName,
1317
+ role,
1318
+ isContentEditable: htmlEl.isContentEditable,
1319
+ id: el.id,
1320
+ ariaLabel: el.getAttribute("aria-label"),
1321
+ textContentBefore: (htmlEl.textContent ?? "").slice(0, 80)
1322
+ });
1315
1323
  if (htmlEl.isContentEditable) {
1316
1324
  htmlEl.focus();
1317
1325
  const range = document.createRange();
@@ -1319,23 +1327,61 @@ function fillAriaField(el, value) {
1319
1327
  const sel = window.getSelection();
1320
1328
  sel?.removeAllRanges();
1321
1329
  sel?.addRange(range);
1322
- let handled = false;
1330
+ const text = String(value ?? "");
1331
+ console.log("[auto-webmcp] fillAriaField: text to insert:", JSON.stringify(text));
1332
+ let inserted = false;
1323
1333
  try {
1324
1334
  const dt = new DataTransfer();
1325
- dt.setData("text/plain", String(value ?? ""));
1326
- const ev = new ClipboardEvent("paste", {
1335
+ dt.setData("text/plain", text);
1336
+ htmlEl.dispatchEvent(new ClipboardEvent("paste", {
1327
1337
  bubbles: true,
1328
1338
  cancelable: true,
1329
1339
  composed: true,
1330
1340
  clipboardData: dt
1331
- });
1332
- handled = !htmlEl.dispatchEvent(ev);
1333
- } catch {
1341
+ }));
1342
+ inserted = (htmlEl.textContent ?? "").trim().length > 0;
1343
+ console.log("[auto-webmcp] fillAriaField: S1 paste result:", inserted, JSON.stringify((htmlEl.textContent ?? "").slice(0, 80)));
1344
+ } catch (e) {
1345
+ console.log("[auto-webmcp] fillAriaField: S1 paste threw:", e);
1346
+ }
1347
+ if (!inserted) {
1348
+ const ok = document.execCommand("insertText", false, text);
1349
+ inserted = (htmlEl.textContent ?? "").trim().length > 0;
1350
+ console.log("[auto-webmcp] fillAriaField: S2 execCommand result:", ok, "inserted:", inserted, JSON.stringify((htmlEl.textContent ?? "").slice(0, 80)));
1351
+ }
1352
+ if (!inserted) {
1353
+ try {
1354
+ htmlEl.dispatchEvent(new InputEvent("beforeinput", {
1355
+ bubbles: true,
1356
+ cancelable: true,
1357
+ composed: true,
1358
+ inputType: "insertText",
1359
+ data: text
1360
+ }));
1361
+ inserted = (htmlEl.textContent ?? "").trim().length > 0;
1362
+ console.log("[auto-webmcp] fillAriaField: S3 beforeinput result:", inserted, JSON.stringify((htmlEl.textContent ?? "").slice(0, 80)));
1363
+ } catch (e) {
1364
+ console.log("[auto-webmcp] fillAriaField: S3 beforeinput threw:", e);
1365
+ }
1334
1366
  }
1335
- if (!handled) {
1336
- document.execCommand("insertText", false, String(value ?? ""));
1367
+ if (!inserted) {
1368
+ htmlEl.textContent = text;
1369
+ const r2 = document.createRange();
1370
+ r2.selectNodeContents(htmlEl);
1371
+ r2.collapse(false);
1372
+ sel?.removeAllRanges();
1373
+ sel?.addRange(r2);
1374
+ console.log("[auto-webmcp] fillAriaField: S4 textContent assignment done, textContent:", JSON.stringify((htmlEl.textContent ?? "").slice(0, 80)));
1337
1375
  }
1376
+ htmlEl.dispatchEvent(new InputEvent("input", {
1377
+ bubbles: true,
1378
+ cancelable: true,
1379
+ inputType: "insertText",
1380
+ data: text
1381
+ }));
1382
+ console.log("[auto-webmcp] fillAriaField: done, final textContent:", JSON.stringify((htmlEl.textContent ?? "").slice(0, 80)));
1338
1383
  } else {
1384
+ console.log("[auto-webmcp] fillAriaField: not contentEditable, dispatching input/change only");
1339
1385
  el.dispatchEvent(new Event("input", { bubbles: true }));
1340
1386
  el.dispatchEvent(new Event("change", { bubbles: true }));
1341
1387
  }
@@ -1681,6 +1727,31 @@ async function scanOrphanInputs(config) {
1681
1727
  if (submitBtn)
1682
1728
  console.log(`[auto-webmcp] orphan: using text-matched button in container: "${submitBtn.textContent?.trim()}"`);
1683
1729
  }
1730
+ if (!submitBtn) {
1731
+ const dialog = container.closest('[role="dialog"], [aria-modal="true"]');
1732
+ if (dialog) {
1733
+ const allDialogBtns = Array.from(
1734
+ dialog.querySelectorAll('button, [role="button"]')
1735
+ ).filter((b) => {
1736
+ const r = b.getBoundingClientRect();
1737
+ return r.width > 0 && r.height > 0 && SUBMIT_TEXT_RE.test(b.textContent ?? "");
1738
+ });
1739
+ console.log(
1740
+ `[auto-webmcp] orphan: dialog buttons matching submit text:`,
1741
+ allDialogBtns.map((b) => `"${b.textContent?.trim().slice(0, 30)}" disabled=${b.disabled} aria-disabled=${b.getAttribute("aria-disabled")}`)
1742
+ );
1743
+ const disabledBtns = allDialogBtns.filter(
1744
+ (b) => b.disabled || b.getAttribute("aria-disabled") === "true"
1745
+ );
1746
+ const enabledBtns = allDialogBtns.filter(
1747
+ (b) => !b.disabled && b.getAttribute("aria-disabled") !== "true"
1748
+ );
1749
+ const dialogBtns = disabledBtns.length > 0 ? disabledBtns : enabledBtns;
1750
+ submitBtn = dialogBtns[dialogBtns.length - 1] ?? null;
1751
+ if (submitBtn)
1752
+ console.log(`[auto-webmcp] orphan: using text-matched button in dialog: "${submitBtn.textContent?.trim().slice(0, 40)}" disabled=${submitBtn.disabled} aria-disabled=${submitBtn.getAttribute("aria-disabled")}`);
1753
+ }
1754
+ }
1684
1755
  if (!submitBtn) {
1685
1756
  const pageBtns = Array.from(
1686
1757
  document.querySelectorAll('button, [role="button"]')