diff --git a/sentience/extension/injected_api.js b/sentience/extension/injected_api.js index abaee4b..0778094 100644 --- a/sentience/extension/injected_api.js +++ b/sentience/extension/injected_api.js @@ -157,6 +157,21 @@ } return null; } + function normalizeNearbyText(text) { + return text ? text.replace(/\s+/g, " ").trim() : ""; + } + function isInteractableElement(el) { + if (!el || !el.tagName) return !1; + const tag = el.tagName.toLowerCase(), role = el.getAttribute ? el.getAttribute("role") : null, hasTabIndex = !!el.hasAttribute && el.hasAttribute("tabindex"), hasHref = "A" === el.tagName && !!el.hasAttribute && el.hasAttribute("href"); + if ([ "button", "input", "textarea", "select", "option", "details", "summary", "a" ].includes(tag)) return !("a" === tag && !hasHref); + if (role && [ "button", "link", "tab", "menuitem", "checkbox", "radio", "switch", "slider", "combobox", "textbox", "searchbox", "spinbutton" ].includes(role.toLowerCase())) return !0; + if (hasTabIndex) return !0; + if (el.onclick || el.onkeydown || el.onkeypress || el.onkeyup) return !0; + if (el.getAttribute) { + if (el.getAttribute("onclick") || el.getAttribute("onkeydown") || el.getAttribute("onkeypress") || el.getAttribute("onkeyup")) return !0; + } + return !1; + } function getText(el) { if (el.getAttribute("aria-label")) return el.getAttribute("aria-label"); if ("INPUT" === el.tagName) { @@ -391,11 +406,7 @@ }), textVal = semanticText.text || getText(el), inferredRole = function(el, options = {}) { const {enableInference: enableInference = !0} = options; if (!enableInference) return null; - if (!function(el) { - if (!el || !el.tagName) return !1; - const tag = el.tagName.toLowerCase(), role = el.getAttribute ? el.getAttribute("role") : null, hasTabIndex = !!el.hasAttribute && el.hasAttribute("tabindex"), hasHref = "A" === el.tagName && !!el.hasAttribute && el.hasAttribute("href"); - return [ "button", "input", "textarea", "select", "option", "details", "summary", "a" ].includes(tag) ? !("a" === tag && !hasHref) : !(!role || ![ "button", "link", "tab", "menuitem", "checkbox", "radio", "switch", "slider", "combobox", "textbox", "searchbox", "spinbutton" ].includes(role.toLowerCase())) || (!!hasTabIndex || (!!(el.onclick || el.onkeydown || el.onkeypress || el.onkeyup) || !(!el.getAttribute || !(el.getAttribute("onclick") || el.getAttribute("onkeydown") || el.getAttribute("onkeypress") || el.getAttribute("onkeyup"))))); - }(el)) return null; + if (!isInteractableElement(el)) return null; const hasAriaLabel = el.getAttribute ? el.getAttribute("aria-label") : null, hasExplicitRole = el.getAttribute ? el.getAttribute("role") : null; if (hasAriaLabel || hasExplicitRole) return null; const tag = el.tagName.toLowerCase(); @@ -478,7 +489,33 @@ } const title = el.getAttribute("title"); return title && title.trim() ? title.trim().substring(0, 200) : ""; - }(el) || null); + }(el) || null), nearbyText = isInteractableElement(el) ? function(el, options = {}) { + if (!el) return null; + const maxLen = "number" == typeof options.maxLen ? options.maxLen : 80, ownText = normalizeNearbyText(el.innerText || ""), candidates = [], collect = node => { + if (!node) return; + let text = ""; + try { + text = normalizeNearbyText(node.innerText || node.textContent || ""); + } catch (e) { + text = ""; + } + text && text !== ownText && candidates.push(text); + }; + if (collect(el.previousElementSibling), collect(el.nextElementSibling), 0 === candidates.length && el.parentElement) { + let parentText = ""; + try { + parentText = normalizeNearbyText(el.parentElement.innerText || ""); + } catch (e) { + parentText = ""; + } + parentText && parentText !== ownText && parentText.length <= 120 && candidates.push(parentText); + } + if (0 === candidates.length) return null; + let text = candidates[0]; + return text.length > maxLen && (text = text.slice(0, maxLen).trim()), text || null; + }(el, { + maxLen: 80 + }) : null; rawData.push({ id: idx, tag: tagName, @@ -509,6 +546,7 @@ inferred_label: semanticText?.source && ![ "explicit_aria_label", "input_value", "img_alt", "inner_text" ].includes(semanticText.source) ? toSafeString(semanticText.text) : null, label_source: semanticText?.source || null, inferred_role: inferredRole ? toSafeString(inferredRole) : null, + nearby_text: toSafeString(nearbyText), href: toSafeString(el.href || el.getAttribute("href") || el.closest && el.closest("a")?.href || null), class: toSafeString(getClassName(el)), value: null !== safeValue ? toSafeString(safeValue) : null, diff --git a/sentience/extension/manifest.json b/sentience/extension/manifest.json index b497bf3..1be2d29 100644 --- a/sentience/extension/manifest.json +++ b/sentience/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Sentience Semantic Visual Grounding Extractor", - "version": "2.4.1", + "version": "2.6.0", "description": "Extract semantic visual grounding data from web pages", "permissions": ["activeTab", "scripting"], "host_permissions": [""], diff --git a/sentience/extension/pkg/sentience_core_bg.wasm b/sentience/extension/pkg/sentience_core_bg.wasm index e6284e4..a802ced 100644 Binary files a/sentience/extension/pkg/sentience_core_bg.wasm and b/sentience/extension/pkg/sentience_core_bg.wasm differ diff --git a/sentience/extension/release.json b/sentience/extension/release.json index f41e668..4eb11e9 100644 --- a/sentience/extension/release.json +++ b/sentience/extension/release.json @@ -1,9 +1,9 @@ { - "url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/276945051", - "assets_url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/276945051/assets", - "upload_url": "https://uploads.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/276945051/assets{?name,label}", - "html_url": "https://github.com/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/tag/v2.5.0", - "id": 276945051, + "url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/277691523", + "assets_url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/277691523/assets", + "upload_url": "https://uploads.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/277691523/assets{?name,label}", + "html_url": "https://github.com/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/tag/v2.6.0", + "id": 277691523, "author": { "login": "rcholic", "id": 135060, @@ -25,21 +25,21 @@ "user_view_type": "public", "site_admin": false }, - "node_id": "RE_kwDOQshiJ84Qgdib", - "tag_name": "v2.5.0", + "node_id": "RE_kwDOQshiJ84QjTyD", + "tag_name": "v2.6.0", "target_commitish": "main", - "name": "Release v2.5.0", + "name": "Release v2.6.0", "draft": false, "immutable": false, "prerelease": false, - "created_at": "2026-01-15T05:36:52Z", - "updated_at": "2026-01-15T05:37:59Z", - "published_at": "2026-01-15T05:37:19Z", + "created_at": "2026-01-18T08:03:53Z", + "updated_at": "2026-01-18T08:05:04Z", + "published_at": "2026-01-18T08:04:24Z", "assets": [ { - "url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/assets/340810705", - "id": 340810705, - "node_id": "RA_kwDOQshiJ84UUFvR", + "url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/assets/342221644", + "id": 342221644, + "node_id": "RA_kwDOQshiJ84UZeNM", "name": "extension-files.tar.gz", "label": "", "uploader": { @@ -65,17 +65,17 @@ }, "content_type": "application/gzip", "state": "uploaded", - "size": 75548, - "digest": "sha256:8cfe2dd1bc2b927b9fbbc7c670b72943cb3704f830bce147606c9dd8b24ccc20", - "download_count": 6, - "created_at": "2026-01-15T05:37:59Z", - "updated_at": "2026-01-15T05:37:59Z", - "browser_download_url": "https://github.com/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/download/v2.5.0/extension-files.tar.gz" + "size": 77212, + "digest": "sha256:82d79bfb011dbdf6ecd81b30689da13ee2045ac3df93534bee4b3c9ae3717670", + "download_count": 0, + "created_at": "2026-01-18T08:05:04Z", + "updated_at": "2026-01-18T08:05:04Z", + "browser_download_url": "https://github.com/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/download/v2.6.0/extension-files.tar.gz" }, { - "url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/assets/340810706", - "id": 340810706, - "node_id": "RA_kwDOQshiJ84UUFvS", + "url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/assets/342221645", + "id": 342221645, + "node_id": "RA_kwDOQshiJ84UZeNN", "name": "extension-package.zip", "label": "", "uploader": { @@ -101,15 +101,15 @@ }, "content_type": "application/zip", "state": "uploaded", - "size": 77323, - "digest": "sha256:6be50503ddda9f0457b05b4399159de5e456d3fa3c5a6f6f18d8d287d52b5546", + "size": 79031, + "digest": "sha256:1f8fe71aeedf7143064afafadc19d83577932d125b66de3eb70e1f302173d172", "download_count": 0, - "created_at": "2026-01-15T05:37:59Z", - "updated_at": "2026-01-15T05:37:59Z", - "browser_download_url": "https://github.com/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/download/v2.5.0/extension-package.zip" + "created_at": "2026-01-18T08:05:04Z", + "updated_at": "2026-01-18T08:05:04Z", + "browser_download_url": "https://github.com/SentienceAPI/Sentience-Geometry-Chrome-Extension/releases/download/v2.6.0/extension-package.zip" } ], - "tarball_url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/tarball/v2.5.0", - "zipball_url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/zipball/v2.5.0", + "tarball_url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/tarball/v2.6.0", + "zipball_url": "https://api.github.com/repos/SentienceAPI/Sentience-Geometry-Chrome-Extension/zipball/v2.6.0", "body": "" }