auto-webmcp 0.3.9 → 0.3.10
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/analyzer.d.ts +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/auto-webmcp.cjs.js +52 -7
- package/dist/auto-webmcp.cjs.js.map +3 -3
- package/dist/auto-webmcp.esm.js +52 -7
- package/dist/auto-webmcp.esm.js.map +3 -3
- package/dist/auto-webmcp.iife.js +1 -1
- package/dist/auto-webmcp.iife.js.map +3 -3
- package/dist/discovery.d.ts.map +1 -1
- package/dist/interceptor.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/auto-webmcp.esm.js
CHANGED
|
@@ -631,6 +631,19 @@ function resolveNativeControlFallbackKey(control) {
|
|
|
631
631
|
}
|
|
632
632
|
return null;
|
|
633
633
|
}
|
|
634
|
+
function resolveAriaElementKey(el) {
|
|
635
|
+
if (el.dataset["webmcpName"])
|
|
636
|
+
return sanitizeName(el.dataset["webmcpName"]);
|
|
637
|
+
if (el.id && !AUTO_GENERATED_ID_RE.test(el.id))
|
|
638
|
+
return sanitizeName(el.id);
|
|
639
|
+
const label = el.getAttribute("aria-label");
|
|
640
|
+
if (label)
|
|
641
|
+
return sanitizeName(label);
|
|
642
|
+
const placeholder = el.getAttribute("placeholder");
|
|
643
|
+
if (placeholder)
|
|
644
|
+
return sanitizeName(placeholder);
|
|
645
|
+
return null;
|
|
646
|
+
}
|
|
634
647
|
function collectAriaControls(form) {
|
|
635
648
|
const selector = ARIA_ROLES_TO_SCAN.map((r) => `[role="${r}"]`).join(", ");
|
|
636
649
|
const rawResults = [];
|
|
@@ -889,6 +902,22 @@ function buildSchemaFromInputs(inputs) {
|
|
|
889
902
|
const processedRadioGroups = /* @__PURE__ */ new Set();
|
|
890
903
|
const processedCheckboxGroups = /* @__PURE__ */ new Set();
|
|
891
904
|
for (const control of inputs) {
|
|
905
|
+
if (!(control instanceof HTMLInputElement) && !(control instanceof HTMLTextAreaElement) && !(control instanceof HTMLSelectElement)) {
|
|
906
|
+
const fieldKey2 = resolveAriaElementKey(control);
|
|
907
|
+
if (!fieldKey2)
|
|
908
|
+
continue;
|
|
909
|
+
if (!isControlVisible(control))
|
|
910
|
+
continue;
|
|
911
|
+
const prop = { type: "string" };
|
|
912
|
+
prop.title = control.getAttribute("aria-label") ?? fieldKey2;
|
|
913
|
+
const desc2 = control.getAttribute("aria-description") ?? control.getAttribute("aria-describedby") ? null : null;
|
|
914
|
+
if (desc2)
|
|
915
|
+
prop.description = desc2;
|
|
916
|
+
properties[fieldKey2] = prop;
|
|
917
|
+
fieldElements.set(fieldKey2, control);
|
|
918
|
+
required.push(fieldKey2);
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
892
921
|
const rawName = control.name;
|
|
893
922
|
const fieldKey = (rawName ? sanitizeName(rawName) : null) || resolveNativeControlFallbackKey(control);
|
|
894
923
|
if (!fieldKey)
|
|
@@ -1284,10 +1313,17 @@ function fillAriaField(el, value) {
|
|
|
1284
1313
|
}
|
|
1285
1314
|
const htmlEl = el;
|
|
1286
1315
|
if (htmlEl.isContentEditable) {
|
|
1287
|
-
htmlEl.
|
|
1316
|
+
htmlEl.focus();
|
|
1317
|
+
const range = document.createRange();
|
|
1318
|
+
range.selectNodeContents(htmlEl);
|
|
1319
|
+
const sel = window.getSelection();
|
|
1320
|
+
sel?.removeAllRanges();
|
|
1321
|
+
sel?.addRange(range);
|
|
1322
|
+
document.execCommand("insertText", false, String(value ?? ""));
|
|
1323
|
+
} else {
|
|
1324
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1325
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1288
1326
|
}
|
|
1289
|
-
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1290
|
-
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1291
1327
|
}
|
|
1292
1328
|
function serializeFormData(form, params, fieldEls) {
|
|
1293
1329
|
const result = {};
|
|
@@ -1560,10 +1596,10 @@ async function scanOrphanInputs(config) {
|
|
|
1560
1596
|
return;
|
|
1561
1597
|
const SUBMIT_BTN_SELECTOR = '[type="submit"]:not([disabled]), button[data-variant="primary"]:not([disabled])';
|
|
1562
1598
|
const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"], button[data-variant="primary"]';
|
|
1563
|
-
const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search/i;
|
|
1599
|
+
const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search|post|tweet|publish/i;
|
|
1564
1600
|
const orphanInputs = Array.from(
|
|
1565
1601
|
document.querySelectorAll(
|
|
1566
|
-
|
|
1602
|
+
'input:not(form input), textarea:not(form textarea), select:not(form select), [role="textbox"]:not(form [role="textbox"]):not(input):not(textarea), [role="searchbox"]:not(form [role="searchbox"]):not(input):not(textarea), [contenteditable="true"]:not(form [contenteditable="true"]):not(input):not(textarea)'
|
|
1567
1603
|
)
|
|
1568
1604
|
).filter((el) => {
|
|
1569
1605
|
if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase())) {
|
|
@@ -1619,6 +1655,15 @@ async function scanOrphanInputs(config) {
|
|
|
1619
1655
|
if (submitBtn)
|
|
1620
1656
|
console.log(`[auto-webmcp] orphan: using disabled submit button as reference: "${submitBtn.textContent?.trim()}"`);
|
|
1621
1657
|
}
|
|
1658
|
+
if (!submitBtn) {
|
|
1659
|
+
const containerBtns = Array.from(container.querySelectorAll("button")).filter((b) => {
|
|
1660
|
+
const r = b.getBoundingClientRect();
|
|
1661
|
+
return r.width > 0 && r.height > 0 && !b.disabled && SUBMIT_TEXT_RE.test(b.textContent ?? "");
|
|
1662
|
+
});
|
|
1663
|
+
submitBtn = containerBtns[containerBtns.length - 1] ?? null;
|
|
1664
|
+
if (submitBtn)
|
|
1665
|
+
console.log(`[auto-webmcp] orphan: using text-matched button in container: "${submitBtn.textContent?.trim()}"`);
|
|
1666
|
+
}
|
|
1622
1667
|
if (!submitBtn) {
|
|
1623
1668
|
const pageBtns = Array.from(document.querySelectorAll("button")).filter(
|
|
1624
1669
|
(b) => {
|
|
@@ -1638,10 +1683,10 @@ async function scanOrphanInputs(config) {
|
|
|
1638
1683
|
const AUTO_ID_RE = /^_r_[0-9a-z]+_$/i;
|
|
1639
1684
|
for (const el of inputs) {
|
|
1640
1685
|
const id = el.id && !AUTO_ID_RE.test(el.id) ? el.id : null;
|
|
1641
|
-
const key = el.name || el.dataset["webmcpName"] || id || el.getAttribute("aria-label") ||
|
|
1686
|
+
const key = el.name || el.getAttribute("name") || el.dataset["webmcpName"] || id || el.getAttribute("aria-label") || el.getAttribute("placeholder") || null;
|
|
1642
1687
|
const safeKey = key ? key.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) : null;
|
|
1643
1688
|
const matched = !!(safeKey && schemaProps[safeKey]);
|
|
1644
|
-
console.log(`[auto-webmcp] orphan: field (name="${el.name}" id="${el.id}") rawKey="${key}" safeKey="${safeKey}" matched=${matched}`);
|
|
1689
|
+
console.log(`[auto-webmcp] orphan: field (name="${el.name ?? ""}" id="${el.id}") rawKey="${key}" safeKey="${safeKey}" matched=${matched}`);
|
|
1645
1690
|
if (matched) {
|
|
1646
1691
|
inputPairs.push({ key: safeKey, el });
|
|
1647
1692
|
}
|