Last active
February 4, 2020 00:21
-
-
Save harrtho/52526c70930faa58ccccb5e27e8f7d92 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
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) is not equal "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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment