auto-webmcp 0.3.9 → 0.3.11
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 +67 -7
- package/dist/auto-webmcp.cjs.js.map +3 -3
- package/dist/auto-webmcp.esm.js +67 -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/analyzer.d.ts
CHANGED
|
@@ -25,5 +25,5 @@ export declare function analyzeForm(form: HTMLFormElement, override?: FormOverri
|
|
|
25
25
|
* Derive ToolMetadata from a group of form controls that are NOT inside a <form>.
|
|
26
26
|
* Used by discovery.ts's orphan-input scanner for pages like newsletter landing pages.
|
|
27
27
|
*/
|
|
28
|
-
export declare function analyzeOrphanInputGroup(container: Element, inputs: Array<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>, submitBtn: HTMLButtonElement | HTMLInputElement | null): ToolMetadata;
|
|
28
|
+
export declare function analyzeOrphanInputGroup(container: Element, inputs: Array<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | HTMLElement>, submitBtn: HTMLButtonElement | HTMLInputElement | null): ToolMetadata;
|
|
29
29
|
//# sourceMappingURL=analyzer.d.ts.map
|
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAmJ,MAAM,aAAa,CAAC;AAC1L,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,6FAA6F;IAC7F,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAKD,iDAAiD;AACjD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAOxF;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAmJ,MAAM,aAAa,CAAC;AAC1L,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,6FAA6F;IAC7F,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAKD,iDAAiD;AACjD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAOxF;AAiqBD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,KAAK,CAAC,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,WAAW,CAAC,EACvF,SAAS,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,IAAI,GACrD,YAAY,CAMd"}
|
package/dist/auto-webmcp.cjs.js
CHANGED
|
@@ -650,6 +650,19 @@ function resolveNativeControlFallbackKey(control) {
|
|
|
650
650
|
}
|
|
651
651
|
return null;
|
|
652
652
|
}
|
|
653
|
+
function resolveAriaElementKey(el) {
|
|
654
|
+
if (el.dataset["webmcpName"])
|
|
655
|
+
return sanitizeName(el.dataset["webmcpName"]);
|
|
656
|
+
if (el.id && !AUTO_GENERATED_ID_RE.test(el.id))
|
|
657
|
+
return sanitizeName(el.id);
|
|
658
|
+
const label = el.getAttribute("aria-label");
|
|
659
|
+
if (label)
|
|
660
|
+
return sanitizeName(label);
|
|
661
|
+
const placeholder = el.getAttribute("placeholder");
|
|
662
|
+
if (placeholder)
|
|
663
|
+
return sanitizeName(placeholder);
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
653
666
|
function collectAriaControls(form) {
|
|
654
667
|
const selector = ARIA_ROLES_TO_SCAN.map((r) => `[role="${r}"]`).join(", ");
|
|
655
668
|
const rawResults = [];
|
|
@@ -908,6 +921,22 @@ function buildSchemaFromInputs(inputs) {
|
|
|
908
921
|
const processedRadioGroups = /* @__PURE__ */ new Set();
|
|
909
922
|
const processedCheckboxGroups = /* @__PURE__ */ new Set();
|
|
910
923
|
for (const control of inputs) {
|
|
924
|
+
if (!(control instanceof HTMLInputElement) && !(control instanceof HTMLTextAreaElement) && !(control instanceof HTMLSelectElement)) {
|
|
925
|
+
const fieldKey2 = resolveAriaElementKey(control);
|
|
926
|
+
if (!fieldKey2)
|
|
927
|
+
continue;
|
|
928
|
+
if (!isControlVisible(control))
|
|
929
|
+
continue;
|
|
930
|
+
const prop = { type: "string" };
|
|
931
|
+
prop.title = control.getAttribute("aria-label") ?? fieldKey2;
|
|
932
|
+
const desc2 = control.getAttribute("aria-description") ?? control.getAttribute("aria-describedby") ? null : null;
|
|
933
|
+
if (desc2)
|
|
934
|
+
prop.description = desc2;
|
|
935
|
+
properties[fieldKey2] = prop;
|
|
936
|
+
fieldElements.set(fieldKey2, control);
|
|
937
|
+
required.push(fieldKey2);
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
911
940
|
const rawName = control.name;
|
|
912
941
|
const fieldKey = (rawName ? sanitizeName(rawName) : null) || resolveNativeControlFallbackKey(control);
|
|
913
942
|
if (!fieldKey)
|
|
@@ -1303,10 +1332,32 @@ function fillAriaField(el, value) {
|
|
|
1303
1332
|
}
|
|
1304
1333
|
const htmlEl = el;
|
|
1305
1334
|
if (htmlEl.isContentEditable) {
|
|
1306
|
-
htmlEl.
|
|
1335
|
+
htmlEl.focus();
|
|
1336
|
+
const range = document.createRange();
|
|
1337
|
+
range.selectNodeContents(htmlEl);
|
|
1338
|
+
const sel = window.getSelection();
|
|
1339
|
+
sel?.removeAllRanges();
|
|
1340
|
+
sel?.addRange(range);
|
|
1341
|
+
let handled = false;
|
|
1342
|
+
try {
|
|
1343
|
+
const dt = new DataTransfer();
|
|
1344
|
+
dt.setData("text/plain", String(value ?? ""));
|
|
1345
|
+
const ev = new ClipboardEvent("paste", {
|
|
1346
|
+
bubbles: true,
|
|
1347
|
+
cancelable: true,
|
|
1348
|
+
composed: true,
|
|
1349
|
+
clipboardData: dt
|
|
1350
|
+
});
|
|
1351
|
+
handled = !htmlEl.dispatchEvent(ev);
|
|
1352
|
+
} catch {
|
|
1353
|
+
}
|
|
1354
|
+
if (!handled) {
|
|
1355
|
+
document.execCommand("insertText", false, String(value ?? ""));
|
|
1356
|
+
}
|
|
1357
|
+
} else {
|
|
1358
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1359
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1307
1360
|
}
|
|
1308
|
-
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1309
|
-
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1310
1361
|
}
|
|
1311
1362
|
function serializeFormData(form, params, fieldEls) {
|
|
1312
1363
|
const result = {};
|
|
@@ -1579,10 +1630,10 @@ async function scanOrphanInputs(config) {
|
|
|
1579
1630
|
return;
|
|
1580
1631
|
const SUBMIT_BTN_SELECTOR = '[type="submit"]:not([disabled]), button[data-variant="primary"]:not([disabled])';
|
|
1581
1632
|
const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"], button[data-variant="primary"]';
|
|
1582
|
-
const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search/i;
|
|
1633
|
+
const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search|post|tweet|publish/i;
|
|
1583
1634
|
const orphanInputs = Array.from(
|
|
1584
1635
|
document.querySelectorAll(
|
|
1585
|
-
|
|
1636
|
+
'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)'
|
|
1586
1637
|
)
|
|
1587
1638
|
).filter((el) => {
|
|
1588
1639
|
if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase())) {
|
|
@@ -1638,6 +1689,15 @@ async function scanOrphanInputs(config) {
|
|
|
1638
1689
|
if (submitBtn)
|
|
1639
1690
|
console.log(`[auto-webmcp] orphan: using disabled submit button as reference: "${submitBtn.textContent?.trim()}"`);
|
|
1640
1691
|
}
|
|
1692
|
+
if (!submitBtn) {
|
|
1693
|
+
const containerBtns = Array.from(container.querySelectorAll("button")).filter((b) => {
|
|
1694
|
+
const r = b.getBoundingClientRect();
|
|
1695
|
+
return r.width > 0 && r.height > 0 && !b.disabled && SUBMIT_TEXT_RE.test(b.textContent ?? "");
|
|
1696
|
+
});
|
|
1697
|
+
submitBtn = containerBtns[containerBtns.length - 1] ?? null;
|
|
1698
|
+
if (submitBtn)
|
|
1699
|
+
console.log(`[auto-webmcp] orphan: using text-matched button in container: "${submitBtn.textContent?.trim()}"`);
|
|
1700
|
+
}
|
|
1641
1701
|
if (!submitBtn) {
|
|
1642
1702
|
const pageBtns = Array.from(document.querySelectorAll("button")).filter(
|
|
1643
1703
|
(b) => {
|
|
@@ -1657,10 +1717,10 @@ async function scanOrphanInputs(config) {
|
|
|
1657
1717
|
const AUTO_ID_RE = /^_r_[0-9a-z]+_$/i;
|
|
1658
1718
|
for (const el of inputs) {
|
|
1659
1719
|
const id = el.id && !AUTO_ID_RE.test(el.id) ? el.id : null;
|
|
1660
|
-
const key = el.name || el.dataset["webmcpName"] || id || el.getAttribute("aria-label") ||
|
|
1720
|
+
const key = el.name || el.getAttribute("name") || el.dataset["webmcpName"] || id || el.getAttribute("aria-label") || el.getAttribute("placeholder") || null;
|
|
1661
1721
|
const safeKey = key ? key.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) : null;
|
|
1662
1722
|
const matched = !!(safeKey && schemaProps[safeKey]);
|
|
1663
|
-
console.log(`[auto-webmcp] orphan: field (name="${el.name}" id="${el.id}") rawKey="${key}" safeKey="${safeKey}" matched=${matched}`);
|
|
1723
|
+
console.log(`[auto-webmcp] orphan: field (name="${el.name ?? ""}" id="${el.id}") rawKey="${key}" safeKey="${safeKey}" matched=${matched}`);
|
|
1664
1724
|
if (matched) {
|
|
1665
1725
|
inputPairs.push({ key: safeKey, el });
|
|
1666
1726
|
}
|