I am trying to recursively traverse the element tree of a window. Problem is, I don’t know how to get a parent’s element child elements without the extended syntax (text field 1 of window 1 of application xpto)
Right now I am doing : set children to contents of parent.
But ‘contents of parent’ is giving me parent itself.
Is this even possible ?
Code below:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set all_names to ""
tell application "System Events"
tell process "Colloquy"
activate
set root_element to window 1
my list_every_item_of(root_element, all_names)
end tell
end tell
on list_every_item_of(parent, all_names)
tell "System Events"
set window_items to contents of parent
set theIndex to length of window_items
repeat length of window_items times
set window_item to item theIndex of window_items
set all_names to all_names & "
" & window_item
if window_item is not equal to parent then
my list_every_item_of(window_item, all_names)
end if
end repeat
end tell
end list_every_item_of
Do you want to get file / folder hierarchy?
Or do you want to get Finder window’s GUI elements?
What I am trying to do is get any application’s window GUI element hierarchy
Here is a script I wrote awhile back to get all the UI Elements of process.
It is best to run it in Script Debugger so you can peruse the results easily as it is a nested list.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
--use script "ListSortingLib" -- script library
property UI_Elements : missing value
tell application "System Events"
set processList to name of every process where background only is false
end tell
set appname to choose from list processList with title "Running Programs" with prompt "Choose running program…"
if class of appname is list then
set appname to item 1 of appname
getSubItems(appname)
end if
on getSubItems(progName)
local cc, ct, curItem --, parentItem, plist, uiList
script m
property plist : {}
property uiList : missing value
property parentItem : missing value
property tmplist : missing value
--property curItem : {}
end script
tell application "System Events"
set curItem to application process progName
set m's uiList to windows of curItem --UI elements of curItem --windows of curItem
end tell
set cc to count m's uiList
set m's parentItem to m's uiList
repeat
if cc = 0 then
if (count m's plist) = 0 then exit repeat
set {m's parentItem, cc} to item 1 of m's plist
set m's plist to rest of m's plist
else
set curItem to item cc of m's parentItem
tell application "System Events"
set m's tmplist to UI elements of curItem
end tell
set ct to count m's tmplist
if ct > 0 then
set item cc of m's parentItem to {curItem, m's tmplist}
set beginning of m's plist to {m's parentItem, cc - 1}
set m's parentItem to item 2 of item cc of m's parentItem
set cc to ct
else
set cc to cc - 1
end if
end if
end repeat
return m's uiList
end getSubItems
I also found a recursive version.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
--use script "ListSortingLib" -- script library
property UI_Elements : missing value
property appName : missing value
local anElement
tell application "System Events"
set processList to name of every process where background only is false
end tell
set appName to choose from list processList with title "Running Programs" with prompt "Choose running program…"
if class of appName is list then
set appName to item 1 of appName
tell application "System Events" to tell application process appName
set anElement to window 1
end tell
set my UI_Elements to getSubItemsR(anElement)
end if
on getSubItemsR(theElement) -- recursive • Best
local i, c
script m
property elementList : {}
end script
--=m
tell application "System Events" to tell application process appName
set m's elementList to UI elements of theElement
end tell
set c to count m's elementList
if c = 0 then return theElement
repeat with i from 1 to c
set item i of m's elementList to getSubItemsR(item i of m's elementList)
end repeat
return {theElement, m's elementList}
end getSubItemsR
Thanks for your scripts. It helped me fix mine, and I learned a lot from them.
Clever algorithm that traverses the component tree without resorting to recursion.
I will keep these in my library for sure.