Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Yet another Safari bookmark-all-tabs AppleScript Web Browsers
There have been several hints published in the past, as noted below, to save/copy all open Safari tabs, either saved to a file, saved to a Bookmark folder, or copied to another Safari window. I wanted a script that did a little more than the others that I found, so I 'wrote' my own. My script is heavily based on the other Safari tabs scripts: Sean Long's 'Copy Safari Tabs', Mark Hunte's 'Save Safari Tabs' , and Adam Brin's 'Safari Tabs'.

I started with Sean's version, but then found Mark's and Adam's when I was looking for a way to create a Bookmark folder. The original bits I've added are:
  • The title of each tab is also pasted as the name of each bookmark (something all the others didn't seem to do).
  • The Bookmark folder name is entered by the user (defaults to title of current tab).
  • Handle the 'More Tabs' menu (when there are more tabs than can be displayed).
  • Handle multiple tabs with the same address as the first tab (except once we cross into the 'More Tabs' section, where a tab with the same address as the first tab will cause the script to think we've reached the first tab again).
  • Some new error checking.
If you see weird problems with the Bookmark URL/titles pasting on top of each other, you may need to add additional delay statements as indicated in the comments.
    •    
  • Currently 3.33 / 5
  You rated: 2 / 5 (6 votes cast)
 
[22,236 views]  

Yet another Safari bookmark-all-tabs AppleScript | 12 comments | Create New Account
Click here to return to the 'Yet another Safari bookmark-all-tabs AppleScript' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Yet another Safari bookmark-all-tabs AppleScript
Authored by: thiefhunter on Mar 03, '06 08:56:36AM

I'm getting an if-then error with this script, but I don't know enough about scripting to recognize the mistake.



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: lunarthar on Mar 03, '06 11:44:10AM

Repalce the "?" by "is equal to" and the script should compile and work!



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: thiefhunter on Mar 03, '06 05:06:01PM

Assuming you mean =

Did that. Now it doesn't like Â

Any more ideas?



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: davidro on Mar 03, '06 06:17:00PM

Just delete those Ä things, and the extra spaces so you end up with one long line that looks like this:

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:")

Then it compiles!

Dave



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: thiefhunter on Mar 04, '06 12:49:48AM

Thanks so much! That worked. Such good people lurk around this forum.



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: verdon on Mar 04, '06 07:24:18AM

I'm still having trouble compiling after following these directions. It's still failing on the same line with the error ...

Expected "given", "with", "without", other parameter name, etc. but found ".

... and the highlight on the opening double-quote just before Choose ...

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:")

I am using OSX 10.3.9 and Script Editor 2.0 with AS version 1.9.3

Any thoughts?



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: hypert on Mar 04, '06 11:48:46AM
Some AppleScript characters don't paste well into HTML forms. Sorry I didn't notice that before. Here's the code again with all (?) of the bad characters fixed:

(*
	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


[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: hibou on Mar 04, '06 02:55:29PM

I was able to compile the script, but got an error message when I tried to run it:

AppleScript Error:
System Events got an error:
NSReceiverEvaluationScriptError: 4



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: hypert on Mar 05, '06 09:14:15PM

I meant to type this in the hint, but forgot. Like all the other scripts from which I pulled code, you need to go to the Universal Access pref-pane and check "Enable access for assistive devices". This turns on Mac OS X's GUI scripting.

Sean Long's script has a test for this, which I should have included in this published version. But, I consider it a waste of (run) time on my own copy, and on anyone else's who has this turned on already (which I highly recommend in general).



[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: hypert on Mar 05, '06 09:17:35PM
Drat. A change I made just before publishing this included a bug. Near the end, in the get_urls_for_tabs() routine, please change the two lines which read

if tabNum > num_tabs then
to

if tabNum= num_tabs then

Sorry about the bother. if you don't make the change, your first tab will show up first AND last in your Bookmark folder!

[ Reply to This | # ]

Yet another Safari bookmark-all-tabs AppleScript
Authored by: Anonymous on Mar 04, '06 12:59:53PM
Although it is certainly good to refine a free way to do this, it's also worthwhile to note that Saft offers this functionality.

[ Reply to This | # ]
Yet another Safari bookmark-all-tabs AppleScript
Authored by: hypert on Mar 05, '06 09:21:06PM

Yes, and SafariStand offers something similar, too. Saft isn't free, although I hear it's worth the $10 or so. SafariStand can create a "workspace", but it remembers every tab from every window I believe, which isn't my preference. Also, it doesn't store the tabs in your Bookmarks, but rather in SafariStand's Bookmark Shelf, which isn't something I usually leave up.



[ Reply to This | # ]