auto-webmcp 0.3.18 → 0.3.20
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/auto-webmcp.cjs.js +79 -4
- package/dist/auto-webmcp.cjs.js.map +2 -2
- package/dist/auto-webmcp.esm.js +79 -4
- package/dist/auto-webmcp.esm.js.map +2 -2
- 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 +0 -4
- package/dist/interceptor.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/auto-webmcp.cjs.js
CHANGED
|
@@ -1820,6 +1820,18 @@ function serializeFormData(form, params, fieldEls) {
|
|
|
1820
1820
|
}
|
|
1821
1821
|
return result;
|
|
1822
1822
|
}
|
|
1823
|
+
function maybeConvertIsoDate(value, el) {
|
|
1824
|
+
const isoMatch = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
1825
|
+
if (!isoMatch)
|
|
1826
|
+
return value;
|
|
1827
|
+
if (el instanceof HTMLInputElement && el.type === "date")
|
|
1828
|
+
return value;
|
|
1829
|
+
const fieldHint = (el.name ?? el.id ?? "").toLowerCase();
|
|
1830
|
+
if (!/date/.test(fieldHint))
|
|
1831
|
+
return value;
|
|
1832
|
+
const [, year, month, day] = isoMatch;
|
|
1833
|
+
return `${month}/${day}/${year}`;
|
|
1834
|
+
}
|
|
1823
1835
|
function fillElement(el, value) {
|
|
1824
1836
|
if (el instanceof HTMLInputElement) {
|
|
1825
1837
|
const type = el.type.toLowerCase();
|
|
@@ -1834,7 +1846,7 @@ function fillElement(el, value) {
|
|
|
1834
1846
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1835
1847
|
}
|
|
1836
1848
|
} else {
|
|
1837
|
-
setReactValue(el, String(value ?? ""));
|
|
1849
|
+
setReactValue(el, maybeConvertIsoDate(String(value ?? ""), el));
|
|
1838
1850
|
}
|
|
1839
1851
|
} else if (el instanceof HTMLTextAreaElement) {
|
|
1840
1852
|
setReactValue(el, String(value ?? ""));
|
|
@@ -1893,7 +1905,7 @@ async function fillComboboxButton(el, value) {
|
|
|
1893
1905
|
console.log("[auto-webmcp] fillComboboxButton: clicking button, value=", JSON.stringify(text));
|
|
1894
1906
|
el.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
|
|
1895
1907
|
const listbox = await new Promise((resolve) => {
|
|
1896
|
-
const deadline = Date.now() +
|
|
1908
|
+
const deadline = Date.now() + 3e3;
|
|
1897
1909
|
const poll = () => {
|
|
1898
1910
|
const candidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
|
|
1899
1911
|
if (candidate) {
|
|
@@ -2051,6 +2063,8 @@ var reAnalysisTimers = /* @__PURE__ */ new Map();
|
|
|
2051
2063
|
var RE_ANALYSIS_DEBOUNCE_MS = 300;
|
|
2052
2064
|
var orphanRescanTimer = null;
|
|
2053
2065
|
var ORPHAN_RESCAN_DEBOUNCE_MS = 500;
|
|
2066
|
+
var orphanRescanDelayedTimer = null;
|
|
2067
|
+
var ORPHAN_RESCAN_DELAYED_MS = 2e3;
|
|
2054
2068
|
var registeredOrphanToolNames = /* @__PURE__ */ new Set();
|
|
2055
2069
|
function scheduleOrphanRescan(config) {
|
|
2056
2070
|
if (orphanRescanTimer)
|
|
@@ -2060,10 +2074,20 @@ function scheduleOrphanRescan(config) {
|
|
|
2060
2074
|
void scanOrphanInputs(config);
|
|
2061
2075
|
}, ORPHAN_RESCAN_DEBOUNCE_MS);
|
|
2062
2076
|
}
|
|
2077
|
+
function scheduleOrphanRescanDelayed(config) {
|
|
2078
|
+
if (orphanRescanDelayedTimer)
|
|
2079
|
+
clearTimeout(orphanRescanDelayedTimer);
|
|
2080
|
+
orphanRescanDelayedTimer = setTimeout(() => {
|
|
2081
|
+
orphanRescanDelayedTimer = null;
|
|
2082
|
+
void scanOrphanInputs(config);
|
|
2083
|
+
}, ORPHAN_RESCAN_DELAYED_MS);
|
|
2084
|
+
}
|
|
2063
2085
|
function isInterestingNode(node) {
|
|
2064
2086
|
const tag = node.tagName.toLowerCase();
|
|
2065
2087
|
if (tag === "input" || tag === "textarea" || tag === "select")
|
|
2066
2088
|
return true;
|
|
2089
|
+
if (tag.includes("-"))
|
|
2090
|
+
return true;
|
|
2067
2091
|
const role = node.getAttribute("role");
|
|
2068
2092
|
if (role && ARIA_ROLES_TO_SCAN.includes(role))
|
|
2069
2093
|
return true;
|
|
@@ -2144,6 +2168,9 @@ function startObserver(config) {
|
|
|
2144
2168
|
}
|
|
2145
2169
|
if (isInterestingNode(node) && !node.closest("form")) {
|
|
2146
2170
|
scheduleOrphanRescan(config);
|
|
2171
|
+
if (node.tagName.toLowerCase().includes("-")) {
|
|
2172
|
+
scheduleOrphanRescanDelayed(config);
|
|
2173
|
+
}
|
|
2147
2174
|
}
|
|
2148
2175
|
}
|
|
2149
2176
|
for (const node of mutation.removedNodes) {
|
|
@@ -2192,6 +2219,35 @@ var ORPHAN_EXCLUDED_TYPES = /* @__PURE__ */ new Set([
|
|
|
2192
2219
|
"button",
|
|
2193
2220
|
"image"
|
|
2194
2221
|
]);
|
|
2222
|
+
function collectShadowOrphanInputs(root, outerHost, visited = /* @__PURE__ */ new Set()) {
|
|
2223
|
+
if (visited.has(root))
|
|
2224
|
+
return [];
|
|
2225
|
+
visited.add(root);
|
|
2226
|
+
const results = [];
|
|
2227
|
+
for (const el of Array.from(root.querySelectorAll("*"))) {
|
|
2228
|
+
const sr = el.shadowRoot;
|
|
2229
|
+
if (!sr)
|
|
2230
|
+
continue;
|
|
2231
|
+
const host = outerHost ?? el;
|
|
2232
|
+
results.push(...collectShadowOrphanInputs(sr, host, visited));
|
|
2233
|
+
}
|
|
2234
|
+
if (root instanceof ShadowRoot) {
|
|
2235
|
+
const selector = 'input, textarea, select, [role="textbox"]:not(input):not(textarea), [role="searchbox"]:not(input):not(textarea), button[role="combobox"]';
|
|
2236
|
+
for (const el of Array.from(root.querySelectorAll(selector))) {
|
|
2237
|
+
if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase()))
|
|
2238
|
+
continue;
|
|
2239
|
+
if (el.closest("form"))
|
|
2240
|
+
continue;
|
|
2241
|
+
const rect = el.getBoundingClientRect();
|
|
2242
|
+
if (rect.width === 0 || rect.height === 0)
|
|
2243
|
+
continue;
|
|
2244
|
+
if (outerHost) {
|
|
2245
|
+
results.push({ el, shadowHost: outerHost });
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
return results;
|
|
2250
|
+
}
|
|
2195
2251
|
async function scanOrphanInputs(config) {
|
|
2196
2252
|
if (!isWebMCPSupported())
|
|
2197
2253
|
return;
|
|
@@ -2214,8 +2270,9 @@ async function scanOrphanInputs(config) {
|
|
|
2214
2270
|
}
|
|
2215
2271
|
return true;
|
|
2216
2272
|
});
|
|
2217
|
-
|
|
2218
|
-
|
|
2273
|
+
const shadowOrphans = collectShadowOrphanInputs(document.body, null);
|
|
2274
|
+
console.log(`[auto-webmcp] orphan: found ${orphanInputs.length} light-DOM + ${shadowOrphans.length} shadow-DOM orphan inputs`);
|
|
2275
|
+
if (orphanInputs.length === 0 && shadowOrphans.length === 0)
|
|
2219
2276
|
return;
|
|
2220
2277
|
const groups = /* @__PURE__ */ new Map();
|
|
2221
2278
|
for (const input of orphanInputs) {
|
|
@@ -2236,6 +2293,24 @@ async function scanOrphanInputs(config) {
|
|
|
2236
2293
|
groups.set(foundContainer, []);
|
|
2237
2294
|
groups.get(foundContainer).push(input);
|
|
2238
2295
|
}
|
|
2296
|
+
for (const { el, shadowHost } of shadowOrphans) {
|
|
2297
|
+
let container = shadowHost.parentElement;
|
|
2298
|
+
let foundContainer = shadowHost.parentElement ?? document.body;
|
|
2299
|
+
while (container && container !== document.body) {
|
|
2300
|
+
const hasSubmitBtn = container.querySelector(SUBMIT_BTN_GROUPING_SELECTOR) !== null || Array.from(container.querySelectorAll("button")).some(
|
|
2301
|
+
(b) => SUBMIT_TEXT_RE.test(b.textContent ?? "")
|
|
2302
|
+
);
|
|
2303
|
+
if (hasSubmitBtn) {
|
|
2304
|
+
foundContainer = container;
|
|
2305
|
+
break;
|
|
2306
|
+
}
|
|
2307
|
+
container = container.parentElement;
|
|
2308
|
+
}
|
|
2309
|
+
console.log(`[auto-webmcp] orphan (shadow): input (id="${el.id}") via host <${shadowHost.tagName.toLowerCase()}> grouped into container`, foundContainer);
|
|
2310
|
+
if (!groups.has(foundContainer))
|
|
2311
|
+
groups.set(foundContainer, []);
|
|
2312
|
+
groups.get(foundContainer).push(el);
|
|
2313
|
+
}
|
|
2239
2314
|
console.log(`[auto-webmcp] orphan: ${groups.size} group(s) found`);
|
|
2240
2315
|
for (const [container, inputs] of groups) {
|
|
2241
2316
|
const allCandidates = Array.from(
|