mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-09-10 13:01:23 +08:00
feat(extension): hover candidate pool
This commit is contained in:
@@ -77,6 +77,19 @@ describe("evaluateHoverTrigger", () => {
|
||||
expect(decision.eligible).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects labelled dropdown list items as hover triggers", () => {
|
||||
const decision = evaluateHoverTrigger({
|
||||
tag: "li",
|
||||
label: "文档C+D",
|
||||
attrs: { class: "dropdown-item", tabindex: "0" },
|
||||
rect: { x: 820, y: 48, w: 160, h: 32 },
|
||||
cursor: "pointer",
|
||||
pointerEvents: "auto",
|
||||
});
|
||||
|
||||
expect(decision.eligible).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects ordinary controls without hover popup signals", () => {
|
||||
const decision = evaluateHoverTrigger({
|
||||
tag: "button",
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface HoverTriggerDecision {
|
||||
const HOVER_TRIGGER_MIN_SCORE = 45;
|
||||
const HOVER_POPUP_SIGNAL_RE =
|
||||
/(menu|dropdown|popover|popup|avatar|profile|account|user|more|ellipsis|caret)/;
|
||||
const HOVER_TEXT_ITEM_RE = /(^|[\s_-])(dropdown-item|menu-item|context-menu-item|option)($|[\s_-])/;
|
||||
|
||||
function attr(signals: HoverTriggerSignals, name: string): string | undefined {
|
||||
return signals.attrs?.[name.toLowerCase()];
|
||||
@@ -59,6 +60,14 @@ export function hasHoverPopupSignal(signals: HoverTriggerSignals): boolean {
|
||||
return HOVER_POPUP_SIGNAL_RE.test(haystack);
|
||||
}
|
||||
|
||||
export function hasStrongHoverExpansionSignal(signals: HoverTriggerSignals): boolean {
|
||||
return (
|
||||
signals.cssHoverMatch === true ||
|
||||
attr(signals, "aria-haspopup") !== undefined ||
|
||||
(attr(signals, "aria-expanded") ?? "").toLowerCase() === "false"
|
||||
);
|
||||
}
|
||||
|
||||
export function hasDirectHoverInteractiveSignal(signals: HoverTriggerSignals): boolean {
|
||||
const tag = signals.tag.toLowerCase();
|
||||
const role = (signals.role ?? "").toLowerCase();
|
||||
@@ -104,7 +113,12 @@ export function evaluateHoverTrigger(signals: HoverTriggerSignals): HoverTrigger
|
||||
const directInteractive = hasDirectHoverInteractiveSignal(signals);
|
||||
const popupSignal = hasHoverPopupSignal(signals);
|
||||
const isTextNavigationItem =
|
||||
(tag === "a" || role === "link" || role.startsWith("menuitem")) &&
|
||||
(tag === "a" ||
|
||||
tag === "li" ||
|
||||
role === "link" ||
|
||||
role === "option" ||
|
||||
role.startsWith("menuitem") ||
|
||||
HOVER_TEXT_ITEM_RE.test(attr(signals, "class") ?? "")) &&
|
||||
!graphic &&
|
||||
!!label &&
|
||||
label.toLowerCase() !== "image";
|
||||
@@ -118,9 +132,7 @@ export function evaluateHoverTrigger(signals: HoverTriggerSignals): HoverTrigger
|
||||
const surfaceTriggerEvidence =
|
||||
(popupSignal && !isTextNavigationItem) ||
|
||||
compactTopbarIcon ||
|
||||
signals.cssHoverMatch === true ||
|
||||
attr(signals, "aria-haspopup") !== undefined ||
|
||||
(attr(signals, "aria-expanded") ?? "").toLowerCase() === "false";
|
||||
hasStrongHoverExpansionSignal(signals);
|
||||
if (!directInteractive || !surfaceTriggerEvidence) {
|
||||
return { eligible: false, score: 0, reasons: [] };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user