diff --git a/src/browser/tools.zig b/src/browser/tools.zig index 7d7e67082..8da9530c3 100644 --- a/src/browser/tools.zig +++ b/src/browser/tools.zig @@ -398,7 +398,7 @@ pub const Tool = enum { \\Extract structured data from the current page (navigate first). `schema` is a JSON object (passed as a string) mapping output field names to CSS-selector specs. It is NOT a JSON Schema — no "type"/"properties" wrappers; the keys ARE your output fields. Value shapes: \\ "" → first match's text (trimmed; null if no match) \\ [""] → every match's text (string[]) - \\ {"selector":"","attr":""} → first match's attribute value + \\ {"selector":"","attr":""} → first match's attribute value (href/src resolved to absolute URLs) \\ [{"selector":"","attr":""}] → every match's attribute (string[]) \\ [{"selector":"","fields":{…}}] → one object per match; field selectors resolve relative to that match and accept any shape above ("" = the match's own text; nest arrays for per-item sub-lists) \\Add "limit": N inside any array's object spec to cap matches. @@ -409,7 +409,7 @@ pub const Tool = enum { \\ {"karma": "#karma"} → {"karma":"42"} \\ {"items": [".story .title"]} → {"items":["Title 1","Title 2"]} \\ {"top3": [{"selector":".story .title","limit":3}]} → {"top3":["A","B","C"]} - \\ {"links": [{"selector":"a.title","attr":"href"}]} → {"links":["/a","/b"]} + \\ {"links": [{"selector":"a.title","attr":"href"}]} → {"links":["https://site/a","https://site/b"]} \\ {"stories": [{"selector":".athing","fields":{"title":".titleline","rank":".rank"}}]} → {"stories":[{"title":"Foo","rank":"1"}]} , .summary = "Extract structured data via a CSS-selector schema", @@ -884,7 +884,15 @@ const schema_walker_prefix = \\ for (const k in inner.fields) r[k] = ext(m, inner.fields[k]); \\ return r; \\ } - \\ if (inner.attr) return m.getAttribute(inner.attr); + \\ if (inner.attr) { + \\ const raw = m.getAttribute(inner.attr); + \\ // Resolve href/src like the DOM .href/.src properties do, so extracted + \\ // URLs are usable by goto. + \\ if (raw !== null && (inner.attr === 'href' || inner.attr === 'src')) { + \\ try { return new URL(raw, document.baseURI).href; } catch (e) { return raw; } + \\ } + \\ return raw; + \\ } \\ return m.textContent.trim(); \\ } \\ function ext(el, v){