Spaces:
Sleeping
Sleeping
| """Utility functions for browser tools.""" | |
| from browser_use.dom.service import EnhancedDOMTreeNode | |
| def get_click_description(node: EnhancedDOMTreeNode) -> str: | |
| """Get a brief description of the clicked element for memory.""" | |
| parts = [] | |
| # Tag name | |
| parts.append(node.tag_name) | |
| # Add type for inputs | |
| if node.tag_name == 'input' and node.attributes.get('type'): | |
| input_type = node.attributes['type'] | |
| parts.append(f'type={input_type}') | |
| # For checkboxes, include checked state | |
| if input_type == 'checkbox': | |
| is_checked = node.attributes.get('checked', 'false').lower() in ['true', 'checked', ''] | |
| # Also check AX node | |
| if node.ax_node and node.ax_node.properties: | |
| for prop in node.ax_node.properties: | |
| if prop.name == 'checked': | |
| is_checked = prop.value is True or prop.value == 'true' | |
| break | |
| state = 'checked' if is_checked else 'unchecked' | |
| parts.append(f'checkbox-state={state}') | |
| # Add role if present | |
| if node.attributes.get('role'): | |
| role = node.attributes['role'] | |
| parts.append(f'role={role}') | |
| # For role=checkbox, include state | |
| if role == 'checkbox': | |
| aria_checked = node.attributes.get('aria-checked', 'false').lower() | |
| is_checked = aria_checked in ['true', 'checked'] | |
| if node.ax_node and node.ax_node.properties: | |
| for prop in node.ax_node.properties: | |
| if prop.name == 'checked': | |
| is_checked = prop.value is True or prop.value == 'true' | |
| break | |
| state = 'checked' if is_checked else 'unchecked' | |
| parts.append(f'checkbox-state={state}') | |
| # For labels/spans/divs, check if related to a hidden checkbox | |
| if node.tag_name in ['label', 'span', 'div'] and 'type=' not in ' '.join(parts): | |
| # Check children for hidden checkbox | |
| for child in node.children: | |
| if child.tag_name == 'input' and child.attributes.get('type') == 'checkbox': | |
| # Check if hidden | |
| is_hidden = False | |
| if child.snapshot_node and child.snapshot_node.computed_styles: | |
| opacity = child.snapshot_node.computed_styles.get('opacity', '1') | |
| if opacity == '0' or opacity == '0.0': | |
| is_hidden = True | |
| if is_hidden or not child.is_visible: | |
| # Get checkbox state | |
| is_checked = child.attributes.get('checked', 'false').lower() in ['true', 'checked', ''] | |
| if child.ax_node and child.ax_node.properties: | |
| for prop in child.ax_node.properties: | |
| if prop.name == 'checked': | |
| is_checked = prop.value is True or prop.value == 'true' | |
| break | |
| state = 'checked' if is_checked else 'unchecked' | |
| parts.append(f'checkbox-state={state}') | |
| break | |
| # Add short text content if available | |
| text = node.get_all_children_text().strip() | |
| if text: | |
| short_text = text[:30] + ('...' if len(text) > 30 else '') | |
| parts.append(f'"{short_text}"') | |
| # Add key attributes like id, name, aria-label | |
| for attr in ['id', 'name', 'aria-label']: | |
| if node.attributes.get(attr): | |
| parts.append(f'{attr}={node.attributes[attr][:20]}') | |
| return ' '.join(parts) | |