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.esm.js
CHANGED
|
@@ -1794,6 +1794,18 @@ function serializeFormData(form, params, fieldEls) {
|
|
|
1794
1794
|
}
|
|
1795
1795
|
return result;
|
|
1796
1796
|
}
|
|
1797
|
+
function maybeConvertIsoDate(value, el) {
|
|
1798
|
+
const isoMatch = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
1799
|
+
if (!isoMatch)
|
|
1800
|
+
return value;
|
|
1801
|
+
if (el instanceof HTMLInputElement && el.type === "date")
|
|
1802
|
+
return value;
|
|
1803
|
+
const fieldHint = (el.name ?? el.id ?? "").toLowerCase();
|
|
1804
|
+
if (!/date/.test(fieldHint))
|
|
1805
|
+
return value;
|
|
1806
|
+
const [, year, month, day] = isoMatch;
|
|
1807
|
+
return `${month}/${day}/${year}`;
|
|
1808
|
+
}
|
|
1797
1809
|
function fillElement(el, value) {
|
|
1798
1810
|
if (el instanceof HTMLInputElement) {
|
|
1799
1811
|
const type = el.type.toLowerCase();
|
|
@@ -1808,7 +1820,7 @@ function fillElement(el, value) {
|
|
|
1808
1820
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1809
1821
|
}
|
|
1810
1822
|
} else {
|
|
1811
|
-
setReactValue(el, String(value ?? ""));
|
|
1823
|
+
setReactValue(el, maybeConvertIsoDate(String(value ?? ""), el));
|
|
1812
1824
|
}
|
|
1813
1825
|
} else if (el instanceof HTMLTextAreaElement) {
|
|
1814
1826
|
setReactValue(el, String(value ?? ""));
|
|
@@ -1867,7 +1879,7 @@ async function fillComboboxButton(el, value) {
|
|
|
1867
1879
|
console.log("[auto-webmcp] fillComboboxButton: clicking button, value=", JSON.stringify(text));
|
|
1868
1880
|
el.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
|
|
1869
1881
|
const listbox = await new Promise((resolve) => {
|
|
1870
|
-
const deadline = Date.now() +
|
|
1882
|
+
const deadline = Date.now() + 3e3;
|
|
1871
1883
|
const poll = () => {
|
|
1872
1884
|
const candidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
|
|
1873
1885
|
if (candidate) {
|
|
@@ -2025,6 +2037,8 @@ var reAnalysisTimers = /* @__PURE__ */ new Map();
|
|
|
2025
2037
|
var RE_ANALYSIS_DEBOUNCE_MS = 300;
|
|
2026
2038
|
var orphanRescanTimer = null;
|
|
2027
2039
|
var ORPHAN_RESCAN_DEBOUNCE_MS = 500;
|
|
2040
|
+
var orphanRescanDelayedTimer = null;
|
|
2041
|
+
var ORPHAN_RESCAN_DELAYED_MS = 2e3;
|
|
2028
2042
|
var registeredOrphanToolNames = /* @__PURE__ */ new Set();
|
|
2029
2043
|
function scheduleOrphanRescan(config) {
|
|
2030
2044
|
if (orphanRescanTimer)
|
|
@@ -2034,10 +2048,20 @@ function scheduleOrphanRescan(config) {
|
|
|
2034
2048
|
void scanOrphanInputs(config);
|
|
2035
2049
|
}, ORPHAN_RESCAN_DEBOUNCE_MS);
|
|
2036
2050
|
}
|
|
2051
|
+
function scheduleOrphanRescanDelayed(config) {
|
|
2052
|
+
if (orphanRescanDelayedTimer)
|
|
2053
|
+
clearTimeout(orphanRescanDelayedTimer);
|
|
2054
|
+
orphanRescanDelayedTimer = setTimeout(() => {
|
|
2055
|
+
orphanRescanDelayedTimer = null;
|
|
2056
|
+
void scanOrphanInputs(config);
|
|
2057
|
+
}, ORPHAN_RESCAN_DELAYED_MS);
|
|
2058
|
+
}
|
|
2037
2059
|
function isInterestingNode(node) {
|
|
2038
2060
|
const tag = node.tagName.toLowerCase();
|
|
2039
2061
|
if (tag === "input" || tag === "textarea" || tag === "select")
|
|
2040
2062
|
return true;
|
|
2063
|
+
if (tag.includes("-"))
|
|
2064
|
+
return true;
|
|
2041
2065
|
const role = node.getAttribute("role");
|
|
2042
2066
|
if (role && ARIA_ROLES_TO_SCAN.includes(role))
|
|
2043
2067
|
return true;
|
|
@@ -2118,6 +2142,9 @@ function startObserver(config) {
|
|
|
2118
2142
|
}
|
|
2119
2143
|
if (isInterestingNode(node) && !node.closest("form")) {
|
|
2120
2144
|
scheduleOrphanRescan(config);
|
|
2145
|
+
if (node.tagName.toLowerCase().includes("-")) {
|
|
2146
|
+
scheduleOrphanRescanDelayed(config);
|
|
2147
|
+
}
|
|
2121
2148
|
}
|
|
2122
2149
|
}
|
|
2123
2150
|
for (const node of mutation.removedNodes) {
|
|
@@ -2166,6 +2193,35 @@ var ORPHAN_EXCLUDED_TYPES = /* @__PURE__ */ new Set([
|
|
|
2166
2193
|
"button",
|
|
2167
2194
|
"image"
|
|
2168
2195
|
]);
|
|
2196
|
+
function collectShadowOrphanInputs(root, outerHost, visited = /* @__PURE__ */ new Set()) {
|
|
2197
|
+
if (visited.has(root))
|
|
2198
|
+
return [];
|
|
2199
|
+
visited.add(root);
|
|
2200
|
+
const results = [];
|
|
2201
|
+
for (const el of Array.from(root.querySelectorAll("*"))) {
|
|
2202
|
+
const sr = el.shadowRoot;
|
|
2203
|
+
if (!sr)
|
|
2204
|
+
continue;
|
|
2205
|
+
const host = outerHost ?? el;
|
|
2206
|
+
results.push(...collectShadowOrphanInputs(sr, host, visited));
|
|
2207
|
+
}
|
|
2208
|
+
if (root instanceof ShadowRoot) {
|
|
2209
|
+
const selector = 'input, textarea, select, [role="textbox"]:not(input):not(textarea), [role="searchbox"]:not(input):not(textarea), button[role="combobox"]';
|
|
2210
|
+
for (const el of Array.from(root.querySelectorAll(selector))) {
|
|
2211
|
+
if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase()))
|
|
2212
|
+
continue;
|
|
2213
|
+
if (el.closest("form"))
|
|
2214
|
+
continue;
|
|
2215
|
+
const rect = el.getBoundingClientRect();
|
|
2216
|
+
if (rect.width === 0 || rect.height === 0)
|
|
2217
|
+
continue;
|
|
2218
|
+
if (outerHost) {
|
|
2219
|
+
results.push({ el, shadowHost: outerHost });
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
return results;
|
|
2224
|
+
}
|
|
2169
2225
|
async function scanOrphanInputs(config) {
|
|
2170
2226
|
if (!isWebMCPSupported())
|
|
2171
2227
|
return;
|
|
@@ -2188,8 +2244,9 @@ async function scanOrphanInputs(config) {
|
|
|
2188
2244
|
}
|
|
2189
2245
|
return true;
|
|
2190
2246
|
});
|
|
2191
|
-
|
|
2192
|
-
|
|
2247
|
+
const shadowOrphans = collectShadowOrphanInputs(document.body, null);
|
|
2248
|
+
console.log(`[auto-webmcp] orphan: found ${orphanInputs.length} light-DOM + ${shadowOrphans.length} shadow-DOM orphan inputs`);
|
|
2249
|
+
if (orphanInputs.length === 0 && shadowOrphans.length === 0)
|
|
2193
2250
|
return;
|
|
2194
2251
|
const groups = /* @__PURE__ */ new Map();
|
|
2195
2252
|
for (const input of orphanInputs) {
|
|
@@ -2210,6 +2267,24 @@ async function scanOrphanInputs(config) {
|
|
|
2210
2267
|
groups.set(foundContainer, []);
|
|
2211
2268
|
groups.get(foundContainer).push(input);
|
|
2212
2269
|
}
|
|
2270
|
+
for (const { el, shadowHost } of shadowOrphans) {
|
|
2271
|
+
let container = shadowHost.parentElement;
|
|
2272
|
+
let foundContainer = shadowHost.parentElement ?? document.body;
|
|
2273
|
+
while (container && container !== document.body) {
|
|
2274
|
+
const hasSubmitBtn = container.querySelector(SUBMIT_BTN_GROUPING_SELECTOR) !== null || Array.from(container.querySelectorAll("button")).some(
|
|
2275
|
+
(b) => SUBMIT_TEXT_RE.test(b.textContent ?? "")
|
|
2276
|
+
);
|
|
2277
|
+
if (hasSubmitBtn) {
|
|
2278
|
+
foundContainer = container;
|
|
2279
|
+
break;
|
|
2280
|
+
}
|
|
2281
|
+
container = container.parentElement;
|
|
2282
|
+
}
|
|
2283
|
+
console.log(`[auto-webmcp] orphan (shadow): input (id="${el.id}") via host <${shadowHost.tagName.toLowerCase()}> grouped into container`, foundContainer);
|
|
2284
|
+
if (!groups.has(foundContainer))
|
|
2285
|
+
groups.set(foundContainer, []);
|
|
2286
|
+
groups.get(foundContainer).push(el);
|
|
2287
|
+
}
|
|
2213
2288
|
console.log(`[auto-webmcp] orphan: ${groups.size} group(s) found`);
|
|
2214
2289
|
for (const [container, inputs] of groups) {
|
|
2215
2290
|
const allCandidates = Array.from(
|