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


Click here to return to the 'Saving and Restoring Tabs in Safari - Documented and Improved' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Saving and Restoring Tabs in Safari - Documented and Improved
Authored by: papley on Mar 30, '05 08:12:46PM

-- Save all tabs in Safari, choosing a file to write URL collection. 

(* This script was found in http://www.macosxhints.com/article.php?story=20030913153245341
I found a few problems with the versions in the thread and fixed all of the issues below.

 1. If you have 2 tabs in the same window, one of which is the first tab 
and both have the same url in them, you'll stop collecting url's when you 
hit the second copy of the first tab. You could lose a whole lot of stuff 
without noticing it. Instead I now check to see if the first tab 
is selected.

 2. There's a big problem with PDF files and presumably other file types 
which may be loaded into Safari. When Safari loads these files it significantly 
changes the way it structures its list of windows, placing a new window in 
the list of active windows. The way this code is written it gets an unhandled 
exception when it tries to extract the url from such a page.

 3. Another thing which would confuse this code is if you have a Download 
window opened. It will try to get a URL from that and get an unhandled exception.

 4. Since the code finds windows by using the name of each browser window 
from it's description in the window menu, it can confuse two windows with 
one-another if they have the same name. If there are two windows which 
have the current tab set to a file whose title starts the same, this will 
happen and the same window will be processed twice, and the other window skipped.

 I'd love to hear if anyone actually uses this or has further comments. *)

-- localizations 
property windowMenu : "Window"
property nextTabMenuItem : "Select Next Tab"
-- end localizations 

property url_list : {}
property docCount : 0
property browserButtons : {}

tell application "Safari"
	activate
	-- docCount is actually the count of standard browser windows.
	set docCount to count of documents
end tell

tell application "System Events"
	tell process "Safari"
		-- menuItemCount is the number of menu items in the window menu,
		-- including a bunch of junk, then browser windows + download window
		-- and possibly others, but not the activity window.
		set menuItemCount to count of menu items of menu windowMenu of ¬
			menu bar 1
		
		-- menuItemOffset is the menu index where the user-visible window list
		-- begins. Again, the download window and possibly others may be 
		-- here as well.
		set menuItemOffset to menuItemCount - docCount
		
		set url_list to {}
		
		-- count the windows
		-- winCount includes browser windows, and if present:
		-- download window, activity window, and special windows 
		-- e.g. pdf plugin window. This number can change
		--when changing tabs adds or removes a pdf plugin window.
		
		set winCount to count of windows
		-- loop through the browser windows, driving from the menu.
		-- Make a list of menu items.
		
		--Note the names will not be unique if the first 20 characters of 
		--the url or document title is not unique across browser windows.
		--This would not be the case if the current tab of two browser windows
		--each had the same document or one whose name was similar.
		--Therefore, it's better to iterate through the menu items
		--directly, and just skip any items, such as "Downloads" which
		--have no URLs. So we collect the indices here.
		repeat with j from menuItemOffset + 1 to menuItemCount
			set mbut to menu item j of menu windowMenu of menu bar 1
			if ((title of mbut) ¬
				does not start with "Downloads") then
				set browserButtons to browserButtons & {j}
			end if
		end repeat
		
		--Iterate through the list of browser window indexes.
		repeat with x in browserButtons
			-- Activate each valid browser window in turn.
			-- Here we will lose the order of the windows on the current desktop.
			click menu item x of menu windowMenu of menu bar 1
			set winTitle to title of window (my discoverWinNum(1))
			my collectURLsFromTabs(1)
		end repeat
	end tell
end tell

-- convert url list  to text
set old_delim to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set url_list_text to url_list as text
set AppleScript's text item delimiters to old_delim

-- get path to prefs file where URLs will be stored
--this tell block will bring the save dialog up front as the active window
tell application "System Events"
	activate
end tell

choose file name

set prefs_file to result as string

try
	set open_file to ¬
		open for access file prefs_file with write permission
	-- erase current contents of file:
	set eof of open_file to 0
	write url_list_text to open_file starting at eof
	close access open_file
on error
	try
		close access file prefs_file
	end try
end try

tell application "Safari"
	activate
	display dialog "All Done" buttons {"OK"} default button 1
end tell

-- This used to assume urls don't repeat within a set of tabs. Not any more. 
-- Now we get the URL from every tab.
property firstTabButton : null
on collectURLsFromTabs(winNum)
	tell application "Safari" to activate
	tell application "System Events"
		tell process "Safari"
			set firstUrl to ""
			
			-- check for browser window 
			set buttonCount to (count of radio buttons of window (my discoverWinNum(winNum)))
			if buttonCount > 0 then
				--If there are no tabs at all then then we won't get the contents of this window.
				set firstTabButton to radio button 1 of window (my discoverWinNum(winNum))
				-- Activate the first tab 
				click firstTabButton
				
				-- Get url of first tab
				set firstUrl to my urlOfTab(winNum)
				
				-- save the url
				set url_list to url_list & firstUrl
				
				-- Select the next tab, whether or not there's a radio button for it.				
				my nextTab()
				
				-- Get url of the tab
				set nextUrl to my urlOfTab(winNum)
				
				-- The value of the radio button is magically 1 if it's the current tab,
				-- so we iterate around the 'tab ring' till we get back to the 
				-- beginning.
				repeat until value of (radio button 1 of window (my discoverWinNum(winNum))) is 1
					-- save the url
					set url_list to url_list & nextUrl
					-- Select the next tab and get it's url.
					my nextTab()
					
					-- url of next tab
					set nextUrl to my urlOfTab(winNum)
				end repeat
				-- Append an empty line to separate this window from the next.
				set url_list to url_list & ""
				return
			end if
		end tell
	end tell
end collectURLsFromTabs

on urlOfTab(winNum)
	-- Get the URL from the tab. If necessary wait for the window to finish
	-- initializing before returning the value.
	tell application "System Events"
		tell process "Safari"
			try
				set t1 to title of window (my discoverWinNum(winNum))
				set v1 to value of text field 1 of group 1 ¬
					of splitter group 1 of window (my discoverWinNum(winNum))
				-- return "<" & v1 & ">" & t1 -- Experimenting with output formats.
				return v1
			on error
				try
					-- Sometimes the URL isn't there immediately so there's a delay.
					-- This could infinite loop if there's something more seriously wrong.
					-- Should figure out a way to terminate this recursion gracefully.
					delay 2
					return my urlOfTab(winNum)
				end try
			end try
		end tell
	end tell
end urlOfTab

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
		end tell
	end tell
end nextTab

on discoverWinNum(winNum)
	tell application "System Events"
		tell process "Safari"
			set subroleStr to ""
			if subrole of window winNum exists then
				set subroleStr to subrole of window winNum
			end if
			-- a bit nasty, but the front window is always number 1 except when it's window 2 
			-- which happens when displaying a pdf and possibly other special formats in the browser.
			if (subroleStr is "AXStandardWindow") then
				return winNum
			else
				return winNum + 1
			end if
		end tell
	end tell
end discoverWinNum

-- Restore Tabs in Safari


--Restore

tell application "Safari" to activate

-- get path to prefs file where URLs are stored
tell application "System Events" --This tell block brings the Choose File dialog up front as the active window
	activate
end tell

choose file

set prefs_file to result as string

try
	-- read the saved urls
	set open_file to ¬
		open for access file prefs_file without write permission
	set url_list to read open_file using delimiter return
	close access open_file
	
	set tmpList to {}
	set newUrl_list to {}
	-- make urls from file into a list of lists
	-- each window is a seperate list in the big list
	repeat with aUrl in url_list
		if aUrl & "x" is "x" then
			set newUrl_list to newUrl_list & {tmpList}
			set tmpList to {}
		else
			set tmpList to tmpList & aUrl
		end if
	end repeat
	
	-- don't forget the last list, or maybe the only
	set newUrl_list to newUrl_list & {tmpList}
	tell application "Safari"
		
		-- loop through the list of windows
		repeat with urls in newUrl_list
			
			my new_window()
			set emptyWindow to true
			
			-- loop through the list of tabs
			repeat with aUrl in urls
				if emptyWindow then
					set emptyWindow to false
				else
					my new_tab()
				end if
				
				-- open the url
				set URL of document 1 to aUrl
				
			end repeat
			
		end repeat
	end tell
on error
	try
		close access file prefs_file
	end try
end try

-- let the user know we are done.
tell application "Safari"
	activate
	display dialog "All Done" buttons {"OK"} default button 1
end tell

on new_tab()
	tell application "Safari" to activate
	tell application "System Events"
		tell process "Safari"
			click menu item "New Tab" of menu "File" of menu bar 1
		end tell
	end tell
end new_tab

on new_window()
	tell application "Safari" to activate
	tell application "System Events"
		tell process "Safari"
			click menu item "New Window" of menu "File" of menu bar 1
		end tell
	end tell
end new_window

Do let me know if you find this useful or you have any additional improvements.



[ Reply to This | # ]

Saving and Restoring Tabs in Safari - Documented and Improved
Authored by: papley on Apr 26, '05 01:58:47PM

I just spent a couple of hours trying to figure out why these scripts I wrote no longer works in version 1.3 (current version as of this date) of Safari. I found several things that have changed. The one detail I can't seem to get is to figure out whether a particular tab is selected. The tab object used to have a value of true if it was the current tab. This is no longer the case, and I can't figure out how to get around this. If anyone knows how to detect whether the first tab in the window is selected please let me know. Comparing the url doesn't work because the url may not be unique.



[ Reply to This | # ]
Saving and Restoring Tabs in Safari - Documented and Improved
Authored by: ehouwink on Jun 28, '05 05:24:15AM
I added some checks on the url field and tab field indexes (that may change with Safari's different view options). Also: modified the prefs file dialog to be more configurable. For the time being, the script works (until Apple, in their wildest fantasies, change Safari's dicitonary again) for Safari 1.3+ int.

-- Save all tabs in Safari, choosing a file to write URL collection. 

(* This script was found in http://www.macosxhints.com/article.php?story=20030913153245341
I found a few problems with the versions in the thread and fixed all of the issues below.

 1. If you have 2 tabs in the same window, one of which is the first tab 
and both have the same url in them, you'll stop collecting url's when you 
hit the second copy of the first tab. You could lose a whole lot of stuff 
without noticing it. Instead I now check to see if the first tab 
is selected.

 2. There's a big problem with PDF files and presumably other file types 
which may be loaded into Safari. When Safari loads these files it significantly 
changes the way it structures its list of windows, placing a new window in 
the list of active windows. The way this code is written it gets an unhandled 
exception when it tries to extract the url from such a page.

 3. Another thing which would confuse this code is if you have a Download 
window opened. It will try to get a URL from that and get an unhandled exception.

 4. Since the code finds windows by using the name of each browser window 
from it's description in the window menu, it can confuse two windows with 
one-another if they have the same name. If there are two windows which 
have the current tab set to a file whose title starts the same, this will 
happen and the same window will be processed twice, and the other window skipped.

 I'd love to hear if anyone actually uses this or has further comments. *)

-- localizations 
property windowMenu : "Window"
property nextTabMenuItem : "Select Next Tab"
-- end localizations 

property url_list : {}
property docCount : 0
property browserWds : {}
-- This used to assume urls don't repeat within a set of tabs. Not any more. 
-- Now we get the URL from every tab.
property firstTabButton : null

global winTitle, tabgroupNo

tell application "Safari"
	activate
	-- docCount is actually the count of standard browser windows.
	set docCount to count of documents
end tell

tell application "System Events"
	tell process "Safari"
		-- menuItemCount is the number of menu items in the window menu,
		-- including a bunch of junk, then browser windows + download window
		-- and possibly others, but not the activity window.
		set menuItemCount to count of menu items of menu windowMenu of ¬
			menu bar 1
		
		-- menuItemOffset is the menu index where the user-visible window list
		-- begins. Again, the download window and possibly others may be 
		-- here as well.
		set menuItemOffset to menuItemCount - docCount
		
		set url_list to {}
		
		-- count the windows
		-- winCount includes browser windows, and if present:
		-- download window, activity window, and special windows 
		-- e.g. pdf plugin window. This number can change
		--when changing tabs adds or removes a pdf plugin window.
		
		set winCount to count of windows
		-- loop through the browser windows, driving from the menu.
		-- Make a list of menu items.
		
		--Note the names will not be unique if the first 20 characters of 
		--the url or document title is not unique across browser windows.
		--This would not be the case if the current tab of two browser windows
		--each had the same document or one whose name was similar.
		--Therefore, it's better to iterate through the menu items
		--directly, and just skip any items, such as "Downloads" which
		--have no URLs. So we collect the indices here.
		repeat with j from menuItemOffset to menuItemCount -- was menuitemOffset + 1
			set mbut to menu item j of menu windowMenu of menu bar 1
			
			if ((title of mbut) ¬
				does not start with "Downloads") then
				set browserWds to browserWds & {j}
			end if
			
			--	display dialog ("title " & title of mbut & return & return & "browserWds " & browserWds) as string
		end repeat
		--Iterate through the list of browser window indexes.
		repeat with x in browserWds
			-- Activate each valid browser window in turn.
			-- Here we will lose the order of the windows on the current desktop.
			click menu item x of menu windowMenu of menu bar 1
			set winTitle to title of window (my discoverWinNum(1))
			my collectURLsFromTabs(1)
		end repeat
	end tell
end tell
-- convert url list  to text
set old_delim to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set url_list to url_list as text
set AppleScript's text item delimiters to old_delim
-- Ask user to name a  file where URLs will be stored
set prefs_folder to (path to preferences folder as string) & "Safari:"
set prefs_fold to prefs_folder & "Saved Tabs"
tell application "Finder"
	if not (exists folder prefs_fold) then
		make new folder at prefs_folder with properties {name:"Saved Tabs"}
	end if
	set tNumb to (number of items in folder prefs_fold) + 1
end tell

tell application "Safari"
	activate
	beep
	set fName to text returned of (display dialog "Enter a name…" buttons {"Cancel", "OK"} default button 2 default answer "Safari tabs " & tNumb) --& ".rtf"
end tell

tell application "Finder"
	set prefs_file to make new file with properties {name:fName} at prefs_fold
	set prefs_name to prefs_file as string
	
	set open_file to open for access alias prefs_name with write permission
	-- erase current contents of file:
	set eof of open_file to 0
	write url_list to alias prefs_name starting at eof
	close access open_file
	
	try
		close access file prefs_file
	end try
end tell


tell application "Safari"
	activate
	beep
	set tB to button returned of (display dialog "Your Bookmarks were saved !!" buttons {"Show in Finder", "OK"} default button 2)
	if "Show" is in tB then
		tell application "Finder"
			activate
			open alias prefs_fold
		end tell
	end if
end tell


on collectURLsFromTabs(winNum)
	tell application "Safari" to activate
	tell application "System Events"
		tell process "Safari"
			repeat with tabgroupNo from 1 to 15
				set bNames to name of buttons of group tabgroupNo of window (my discoverWinNum(winNum))
				if "missing value" is not in bNames as string and {} is not bNames then exit repeat
			end repeat
			(*	repeat with urlgroupNo from 1 to 15
				if exists splitter 1 of splitter group 1 of group urlgroupNo of window (my discoverWinNum(winNum)) then exit repeat
			end repeat *)
			set urlgroupNo to 2
			---->>> vooralsnog altijd group2!!! 
			
			
			set firstUrl to ""
			
			-- check for browser window 
			set buttonCount to (count of buttons of group tabgroupNo of window (my discoverWinNum(winNum)))
			if buttonCount > 1 then
				-- lukt niet meer bij Tiger if buttonCount > 0 then
				
				--try
				
				set firstTabButton to button 1 of group tabgroupNo of window (my discoverWinNum(winNum))
				-- Activate the first tab 
				click firstTabButton
				
				-- Get url of first tab
				set firstUrl to my urlOfTab(winNum, urlgroupNo)
				--display dialog firstUrl
				-- save the url
				set url_list to url_list & firstUrl
				
				-- Select the next tab, whether or not there's a radio button for it.                           
				my nextTab()
				
				-- Get url of the tab
				set nextUrl to my urlOfTab(winNum, urlgroupNo)
				
				-- The value of the radio button is magically 1 if it's the current tab,
				-- so we iterate around the 'tab ring' till we get back to the 
				-- beginning.
				set i to 0
				repeat until nextUrl is firstUrl or i > 30 -- werkt niet meer until value of (button 1 of group tabgroupNo of window (my discoverWinNum(winNum))) is 1
					-- save the url
					set i to i + 1
					set url_list to url_list & nextUrl
					-- Select the next tab and get it's url.
					my nextTab()
					-- url of next tab
					set nextUrl to my urlOfTab(winNum, urlgroupNo)
					if nextUrl is firstUrl then
						--say "Go next window"
						exit repeat
					end if
				end repeat
				-- Append an empty line to separate this window from the next.
				set url_list to url_list & ""
				(*on error
					return
				end try*)
			end if
		end tell
	end tell
end collectURLsFromTabs

on urlOfTab(winNum, urlgroupNo)
	-- Get the URL from the tab. If necessary wait for the window to finish
	-- initializing before returning the value.
	
	tell application "System Events"
		tell process "Safari"
			try
				set t1 to title of window (my discoverWinNum(winNum))
				set v1 to value of text field 1 of group 1 of splitter group 1 of group urlgroupNo of window (my discoverWinNum(winNum))
				-- was:value of text field 1 of group 1 	of splitter group 1 of window (my discoverWinNum(winNum))
				-- return "<" & v1 & ">" & t1 -- Experimenting with output formats.
				return v1
			on error
				try
					-- Sometimes the URL isn't there immediately so there's a delay.
					-- This could infinite loop if there's something more seriously wrong.
					-- Should figure out a way to terminate this recursion gracefully.
					delay 2
					return my urlOfTab(winNum, urlgroupNo)
				end try
			end try
		end tell
	end tell
end urlOfTab

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
		end tell
	end tell
end nextTab

on discoverWinNum(winNum)
	tell application "System Events"
		tell process "Safari"
			set subroleStr to ""
			if subrole of window winNum exists then
				set subroleStr to subrole of window winNum
			end if
			-- a bit nasty, but the front window is always number 1 except when it's window 2 
			-- which happens when displaying a pdf and possibly other special formats in the browser.
			try
				if (subroleStr is "AXStandardWindow") then
					return winNum
				else
					return winNum + 1
				end if
			on error
				say winTitle as string
			end try
		end tell
	end tell
end discoverWinNum
Eelco Houwink

[ Reply to This | # ]
Saving and Restoring Tabs in Safari - Documented and Improved
Authored by: ehouwink on Jun 28, '05 05:31:32AM
The "restore" script that adheres to this prefs-file location is:


tell application "Safari" to activate

-- Ask user for  file where Tabs were stored
set prefs_folder to (path to preferences folder as string) & "Safari:"
set prefs_fold to prefs_folder & "Saved Tabs:"
set choices to {}
tell application "Finder"
	set lizt to list folder prefs_fold
	if lizt is not "" then
		repeat with i from 1 to number of items in lizt
			if ".DS" is not in item i of lizt then ¬
				set choices to choices & item i of lizt
		end repeat
	end if
end tell
tell application "Safari" to set tFile to (choose from list choices default items (item 1 of choices) ¬
	OK button name "Get these" cancel button name ¬
	"Cancel" without multiple selections allowed)
set tFile to prefs_fold & text items of tFile as string


--try
-- read the saved urls
set open_file to ¬
	open for access alias tFile without write permission
set url_list to read alias tFile using delimiter return
close access open_file

set tmpList to {}
set newUrl_list to {}

-- make urls from file into a list of lists
-- each window is a seperate list in the big list
repeat with aUrl in url_list
	if aUrl & "x" is "x" then
		set newUrl_list to newUrl_list & {tmpList}
		set tmpList to {}
	else
		set tmpList to tmpList & aUrl
	end if
end repeat

-- don't forget the last list, or maybe the only
set newUrl_list to newUrl_list & {tmpList}

tell application "Safari"
	-- loop through the list of windows
	repeat with urls in newUrl_list
		my new_window()
		set emptyWindow to true
		-- loop through the list of tabs
		repeat with aUrl in urls
			if emptyWindow then
				set emptyWindow to false
			else
				my new_tab()
			end if
			-- open the url
			set URL of document 1 to aUrl
		end repeat
	end repeat
end tell
--on error
try
	close access file prefs_file
end try
--end try

-- let the user know we are done.
tell application "Safari"
	activate
	display dialog "All Done !" buttons {"OK"} default button 1
end tell

on new_tab()
	tell application "Safari" to activate
	tell application "System Events"
		tell process "Safari"
			click menu item "New Tab" of menu "File" of menu bar 1
		end tell
	end tell
end new_tab

on new_window()
	tell application "Safari" to activate
	tell application "System Events"
		tell process "Safari"
			click menu item "New Window" of menu "File" of menu bar 1
		end tell
	end tell
end new_window


[ Reply to This | # ]
Saving and Restoring Tabs in Safari - Documented and Improved
Authored by: lrivers on Aug 24, '05 03:37:23PM

This script stalls out and does not progress past the first tab. It seems to loop without incrementing the tab.

There's no split group that I can tell, for one. I can't figure out how to make it work, though.



[ Reply to This | # ]