extension(browser): v1.9.18 — propagate page-side throws, fix textarea fill
Two bugs caught while driving the SEC TCR form:
1) runFunc silently swallowed page-side errors.
scripting.executeScript returns [{result, error, frameId}] per frame.
We were mapping to r?.result which dropped the `error` field — when a
page-side function threw, callers saw null instead of an error.
Fix: keep the full InjectionResult shape and throw on first.error.
2) hanzo.fill called HTMLInputElement's value setter on a TEXTAREA.
That throws TypeError "Illegal invocation" silently (now visible
thanks to fix #1). The chained `|| HTMLTextAreaElement.prototype...`
never executed because the first ?.set was truthy.
Fix: per-tag dispatch — pick the matching prototype's native setter
(INPUT/TEXTAREA/SELECT each get their own). Wrapped in try/catch with
plain `el.value = value` as last resort.
Verified on www.sec.gov/forms/tcr-external-form:
- hanzo.fill on textarea[name^="in_your_own_words"] now sets the value
- hanzo.clear on same textarea now works
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hanzo/browser-extension",
|
||||
"version": "1.9.17",
|
||||
"version": "1.9.18",
|
||||
"description": "Hanzo AI Browser Extension",
|
||||
"main": "dist/background.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -401,7 +401,10 @@ class HanzoFirefoxExtension {
|
||||
args,
|
||||
func: fn,
|
||||
});
|
||||
return Array.isArray(results) ? results.map((r: any) => r?.result) : [results];
|
||||
// Keep the full InjectionResult shape ({result, error, frameId}) so
|
||||
// we can propagate page-side throws (1.9.18). Previously we mapped
|
||||
// to r?.result which silently dropped errors → callers saw null.
|
||||
return Array.isArray(results) ? results : [results];
|
||||
};
|
||||
let out: any[];
|
||||
try {
|
||||
@@ -414,7 +417,11 @@ class HanzoFirefoxExtension {
|
||||
`runFunc returned no frames for tab ${tabId} — page may be privileged or unloaded.`,
|
||||
);
|
||||
}
|
||||
const result = out[0];
|
||||
const first = out[0] || {};
|
||||
if (first.error) {
|
||||
throw new Error(`runFunc page-side error: ${first.error}`);
|
||||
}
|
||||
const result = first.result;
|
||||
if (result && typeof result === 'object' && (result as any).__hanzo_error) {
|
||||
throw new Error((result as any).__hanzo_error);
|
||||
}
|
||||
@@ -793,16 +800,26 @@ class HanzoFirefoxExtension {
|
||||
const el = document.querySelector(selector) as HTMLInputElement | HTMLTextAreaElement | HTMLElement | null;
|
||||
if (!el) return false;
|
||||
try { (el as HTMLElement).scrollIntoView({ block: 'center', behavior: 'instant' as ScrollBehavior }); } catch (e) {}
|
||||
(el as HTMLElement).focus();
|
||||
try { (el as HTMLElement).focus(); } catch (e) {}
|
||||
const tag = (el as HTMLElement).tagName;
|
||||
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') {
|
||||
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set
|
||||
|| Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value')?.set;
|
||||
if (setter && (tag === 'INPUT' || tag === 'TEXTAREA')) {
|
||||
setter.call(el, value);
|
||||
} else {
|
||||
(el as HTMLInputElement).value = value;
|
||||
}
|
||||
// React-compatible: per-tag native setter. Calling
|
||||
// HTMLInputElement's setter on a TEXTAREA throws "Illegal
|
||||
// invocation" — was the silent failure on SEC TCR (1.9.18 fix).
|
||||
let setter: any = null;
|
||||
try {
|
||||
if (tag === 'TEXTAREA') {
|
||||
setter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value')?.set;
|
||||
} else if (tag === 'INPUT') {
|
||||
setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
|
||||
} else if (tag === 'SELECT') {
|
||||
setter = Object.getOwnPropertyDescriptor(window.HTMLSelectElement.prototype, 'value')?.set;
|
||||
}
|
||||
} catch (e) { setter = null; }
|
||||
try {
|
||||
if (setter) setter.call(el, value);
|
||||
else (el as HTMLInputElement).value = value;
|
||||
} catch (e) { (el as HTMLInputElement).value = value; }
|
||||
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
el.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Hanzo AI",
|
||||
"version": "1.9.17",
|
||||
"version": "1.9.18",
|
||||
"description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
|
||||
"permissions": [
|
||||
"activeTab",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Hanzo AI",
|
||||
"version": "1.9.17",
|
||||
"version": "1.9.18",
|
||||
"description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
|
||||
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfXGh0lPUT5m04GKfjUwrLsV6pLaK3VcZuFRPogqAir2tzyLYnQPRtHynue9yvDyguIVnlkwvcwfDOYZrvH76zbw4s6onPBG8HqTKO6LQ9K3kdO1qBBkMMjdOgULQ1MrWThEbpU7NSTiwLYpEta/jAvrKRCAeKIlQE8p6htZmPy9aRUZuae66JgLcAlzD2vviX9sVB1asFABJVswL1RgZ55/8IzZaUrFjzOo9OHK4hmEOtudzkML+5silsAYdC+1BZugph2x94ai17YmZTCL1XyUa5Ke4q80cj+i9rOTgzhZs+mruyhL/AvNVOXilsgqCdNqSz77naWzC3pVGbxOewIDAQAB",
|
||||
"permissions": [
|
||||
|
||||
Reference in New Issue
Block a user