(* Written by hypert. Based on Sean Long's "Copy Safari Tabs" (http://www.macosxhints.com/article.php?story=20060129175300877), Mark Hunte's "Save Safari Tabs" (http://www.macosxhints.com/article.php?story=20051121170745971), and Adam Brin's "Safari Tabs" (http://www.macosxhints.com/article.php?story=20040917211924222). *) property NEW_FOLDER_KEY : "n" property PASTE_KEY : "v" property CLOSE_TAB_KEY : "w" property NEXT_TAB_KEY : "}" property MORE_TABS : 0 property TAB_CHECK : 50 property DEBUG : false on run {} tell application "Safari" activate set windowName to my GetWindowName() if DEBUG then display dialog windowName my give_window_focus(windowName) -- Get the Bookmarks folder name set folderName to the text returned of (display dialog "Enter the bookmark folder name" default answer windowName) -- get urls for tabs; urls is a list which is setup as "pairs" of info, the 1st part of the pair is the address, the 2nd part is the title set urls to my get_urls_for_tabs(windowName) -- Adding the bookmark folder doesn't work if the frontmost window/tab is the Bookmarks window -- Check for it & close it if necessary my CheckForBookmarksTab() -- Create the Bookmarks folder my CreateBookmarkFolder(folderName) -- Add the URLs for each of the tabs in the Bookmarks folde my AddBookmarksToFolder(urls) display dialog "Bookmarks stored in folder '" & folderName & "'" buttons {"OK"} default button "OK" end tell end run on GetWindowName() tell application "Safari" -- I prefer to bookmark the tabs in just the front window: return ((name of window 1) as string) -- Alternately, you could comment out the above return() and prompt the user to pick a window: set safari_win_name_list to {} repeat with i from 1 to number of items in windows set this_win to item i of windows if ((name of this_win) as string) ? "downloads" then set end of safari_win_name_list to (name of this_win) as string end if end repeat set tab_source_win to (choose from list safari_win_name_list  with title "Choose Safari Window" with prompt  "Bookmark all tabs from this window:") return tab_source_win -- could be "false" if they hit "Cancel"! end tell end GetWindowName on CheckForBookmarksTab() tell application "Safari" if (name of window 1) as string is equal to "Bookmarks" then tell application "System Events" tell process "Safari" keystroke CLOSE_TAB_KEY using [command down] end tell end tell end if end tell end CheckForBookmarksTab on CreateBookmarkFolder(folderName) tell application "System Events" tell process "Safari" -- add bookmark folder keystroke NEW_FOLDER_KEY using [shift down, command down] keystroke folderName keystroke return delay 2 keystroke (ASCII character 9) delay 1 end tell end tell end CreateBookmarkFolder on AddBookmarksToFolder(urls) tell application "Safari" set i to 1 repeat while i is less than number of items in urls set this_url to item i of urls set this_title to item (i + 1) of urls if (this_url is not equal to "bookmarks://") then set the clipboard to this_url tell application "System Events" tell process "Safari" -- It's possible we might need to add "delay 1" commands before and/or after pasting in this_url keystroke PASTE_KEY using {command down} end tell end tell set the clipboard to this_title tell application "System Events" tell process "Safari" -- It's possible we might need to add "delay 1" commands before and/or after pasting in this_title keystroke return keystroke PASTE_KEY using {command down} keystroke return end tell end tell end if set i to i + 2 end repeat end tell end AddBookmarksToFolder on get_urls_for_tabs(window_name) -- tab_list will contain "pairs" of info, the 1st part of the pair is the address, the 2nd part is the title set tab_list to {} tell application "Safari" -- get number of tabs set num_tabs to my get_num_tabs(window_name) -- get current page URL if not tabs and bail if num_tabs = 0 then set end of tab_list to URL of document of window named window_name set end of tab_list to (name of window window_name) as string else -- loop thru every tab if DEBUG then display dialog "Number of tabs: " & num_tabs set group_num to my get_group_num_for_tabs(window_name) set loopedAround to false set tabNum to 0 -- Select 1st tab: my click_tab(window_name, group_num, 1) set firstTabAddress to (URL of document of window 1) as string repeat until loopedAround set window_name to name of window 1 set address to (URL of document of window window_name) as string if address is not equal to "" then if DEBUG then display dialog "Address is " & address if DEBUG then display dialog "Title is " & (name of window window_name) as string set end of tab_list to address set end of tab_list to (name of window window_name) as string end if my nextTab() set tabNum to tabNum + 1 if (tabNum > TAB_CHECK) then -- That's a LOT of tabs. Check w/ user to make sure we're not in an infinite loop. display dialog "We've gone through " & TAB_CHECK & " tabs without looping back to the beginning. Keep going?" end if -- Checked if we've looped around to the first tab again. if MORE_TABS = 1 then -- The "More Tabs" menu was found, indicating that there are more tabs than can be displayed at once. if tabNum > num_tabs then set address to (URL of document of window 1) as string -- If the current tab's address is the same as firstTabAddress, chances are we've looped back to the first tab. -- Wish I could truly find a way to pick tabs in the "More Tabs" section, or query which tab number is currently -- selected, then I wouldn't need to compare addresses (and we'd handle all duplicate addresses). if address is equal to firstTabAddress then set loopedAround to true end if end if else -- The "More Tabs" menu was not found, so we can just stop after going thru all the tabs. if tabNum > num_tabs then set loopedAround to true end if end if end repeat end if end tell return tab_list end get_urls_for_tabs on click_tab(window_name, group_num, button_num) tell application "System Events" tell process "Safari" click button button_num of group group_num of window named window_name end tell end tell end click_tab on get_num_tabs(window_name) set tabs to 0 tell application "System Events" tell process "Safari" set group_num to my get_group_num_for_tabs(window_name) if group_num > 0 then set tabs to (count buttons) of group group_num of window named window_name set MORE_TABS to (count menu buttons) of group group_num of window named window_name end if end tell end tell return tabs end get_num_tabs on give_window_focus(window_name) tell application "System Events" tell process "Safari" perform action "AXRaise" of window named window_name end tell end tell end give_window_focus on get_group_num_for_tabs(window_name) set ret_val to 0 tell application "System Events" tell process "Safari" -- Tabs are usually in the second to last group set group_num to (count groups) of window named window_name set group_num to group_num - 1 -- But if there are no tabs the second to last group is possibly the bookmark bar set num_buttons to (count buttons) of group group_num of window named window_name if num_buttons > 0 then set help_txt to help of button 1 of group group_num of window named window_name set bookmark_test to offset of "Show all bookmarks" in help_txt if bookmark_test > 0 then --we are in the bookmark group (no tabs) set ret_val to 0 else set ret_val to group_num end if end if end tell end tell return ret_val end get_group_num_for_tabs on nextTab() tell application "Safari" to activate tell application "System Events" tell process "Safari" --click menu item nextTabMenuItem of menu windowMenu of menu bar 1 keystroke NEXT_TAB_KEY using [command down] end tell end tell end nextTab