(node: 'MacElementNode', depth: int)
| 79 | formatted_text = [] |
| 80 | |
| 81 | def process_node(node: 'MacElementNode', depth: int) -> None: |
| 82 | # Build attributes string |
| 83 | attrs_str = '' |
| 84 | important_attrs = ['title', 'value', 'description', 'enabled'] |
| 85 | for key in important_attrs: |
| 86 | if key in node.attributes: |
| 87 | attrs_str += f' {key}="{node.attributes[key]}"' |
| 88 | |
| 89 | # Add actions if available |
| 90 | if node.actions: |
| 91 | attrs_str += f' actions="{", ".join(node.actions)}"' |
| 92 | |
| 93 | # Include both interactive and context elements |
| 94 | if node.highlight_index is not None: |
| 95 | # Interactive element with numeric index |
| 96 | formatted_text.append( |
| 97 | f'{node.highlight_index}[:]<{node.role}{attrs_str}> [interactive]' |
| 98 | ) |
| 99 | # Check if this is a context element (non-interactive AXStaticText or read-only AXTextField) |
| 100 | elif (node.role in ['AXStaticText', 'AXTextField'] and |
| 101 | not node.is_interactive and |
| 102 | (node.parent is None or node.parent.role == 'AXWindow' or node.parent.is_interactive)): |
| 103 | # Context element with "_" index |
| 104 | formatted_text.append( |
| 105 | f'_[:]<{node.role}{attrs_str}> [context]' |
| 106 | ) |
| 107 | |
| 108 | for child in node.children: |
| 109 | process_node(child, depth + 1) |
| 110 | |
| 111 | process_node(self, 0) |
| 112 | return '\n'.join(formatted_text) |
nothing calls this directly
no outgoing calls
no test coverage detected