Safari says it has no popup in a sheet which has...?

I have the following line:

display dialog (the value of text area 1 of pop up button 1) as string

This is after I activate Safari, open a URL location, and go to the Save As… sheet. There are two popups that concern me on the sheet, but when that line comes up, I get an error:

error “System Events got an error: Can’t get pop up button 1 of process "Safari". Invalid index.” number -1719 from pop up button 1 of process “Safari”

What am I doing wrong?

Thanks.

Model: Mac Pro 2.8 Dual
AppleScript: 2.1
Browser: Safari 531.9
Operating System: Mac OS X (10.6)

Hi,

the reference is incomplete. To access an UI element the full reference is required

the popup button is an element of the sheet which is an element of a window.


tell application "System Events"
	tell process "Safari"
		set textAreaValue to value of text area 1 of pop up button 1 of sheet 1 of window 1
	end tell
end tell
display dialog textAreaValue

Note: It’s recommended not to use Standard Additions commands within application tell blocks

Hi, Stefan–

Looks like I’m getting the same error. Here’s my whole script:

set the target_URL to "http://jott.com/notes.aspx?page=241"
set the destination_file to "Macintosh HD:Users:jeffrey:Downloads:jotts:" & "241.txt"
set the fileName to "241.html"
activate application "Safari"
open location target_URL
delay 5
tell application "System Events"
	tell process "Safari"
		click menu item "Save As." of menu 1 of menu bar item "File" of menu bar 1
		delay 0.2
		set textAreaValue to value of text area 1 of pop up button 1 of sheet 1 of window 1
		delay 5
		set value of text field 1 of sheet 1 of window 1 to fileName
		click button "Save" of sheet 1 of window 1
	end tell
end tell
display dialog textAreaValue

And here’s the error after adding your line:

error “System Events got an error: Can’t get pop up button 1 of sheet 1 of window 1 of process "Safari". Invalid index.” number -1719 from pop up button 1 of sheet 1 of window 1 of process “Safari”

I don’t know which pop button you mean.
There are two of them and the parent element of both is group

this refers to the Format popup button


.
set textAreaValue to value of pop up button 1 of group 1 of sheet 1 of window 1
.

Hi, Stefan–

I’m actually looking for both, but the most important is the Where: popup.

the other popup button is an element of group 2

You can specify a folder by pressing ⇧⌘G and entering a POSIX path

Sorry for being a n00b, but could you post that script step, just for a sample file?


set destinationFolder to POSIX path of (path to documents folder)

activate application "Safari"
tell application "System Events"
	tell process "Safari"
		click menu item "Save As." of menu 1 of menu bar item "File" of menu bar 1
		tell window 1
			repeat until exists sheet 1
				delay 0.2
			end repeat
			tell sheet 1
				keystroke "g" using {command down, shift down}
				repeat until exists sheet 1
					delay 0.2
				end repeat
				tell sheet 1
					set value of text field 1 to destinationFolder
					click button "Go"
				end tell
			end tell
		end tell
	end tell
end tell

Stefan–

That works perfectly. I can’t thank you enough. :slight_smile:

Here’s my finished version. I hope it meets with your approval:

set the target_URL to "http://jott.com/notes.aspx?page=241"
set the destination_file to POSIX path of "Macintosh HD:Users:jeffrey:Downloads:jotts:" & "241.html"
activate application "Safari"
open location target_URL
delay 5
tell application "System Events"
	tell process "Safari"
		click menu item "Save As." of menu 1 of menu bar item "File" of menu bar 1
		tell window 1
			repeat until exists sheet 1
				delay 0.2
			end repeat
			tell sheet 1
				keystroke "g" using {command down, shift down}
				repeat until exists sheet 1
					delay 0.2
				end repeat
				tell sheet 1
					set value of text field 1 to destination_file
					click button "Go"
				end tell
			end tell
		end tell
		click button "Save" of sheet 1 of window 1
	end tell
end tell

Hello.

I have wanted a script that saved all the tabs in a window for some time now. Well, that isn’t particularily easy to do with just AppleScript. I actually did take the trouble of trying, hard with wget, but it was just too impractical, and the webarchives isn’t that easy to make as good with textutil as with Safari.

Well, thanks for the snippet StefanK, here it is, it has properties that you can set for whether you like it to overwrite pages with the same name in a folder, and if you want it to close the tabs after it has saved it, with some tinkering you may have two scripts, or one according to your taste.

If you have regular files open in your browser, those will be aliased into the folder you want as a destination folder.

I have minimized the UI scripting as much as I could, but it handles overwrites of files presumably the way you want it, with UI scripting. The current configuration is to overwrite tabs. and not to close saved windows.

This is tested, but you can see it has release 1.0.0, I’ll update it asap, if I find any bugs. I hope this is useful for more people than just me.



property tlvl : me
# Release 1.0.1
# © 2012 McUsr and  put in Public Domain under GPL 1.0
# Please refer to this post: http://macscripter.net/post.php?tid=30892
property shallClose : false # set this to false if you don't want to close the windows, just saving them
property dontOverWriteSavedTabs : false # set this to true if you don't want to overwrite already saved tabs in the folder 
script saveTabsInSafariWindowsToFolder
	property parent : AppleScript
	
	property scripttitle : "SafariSaveTabs"
	on run
		if downloadWindowInFront() then return 0 # activates Safari
		
		local script_cache
		set script_cache to my storage's scriptCache()
		
		set saveFolder to POSIX path of (getHFSFolder({theMessage:"Choose or create folder to save Safari-tabs in.", hfsPath:DefaultLocation of script_cache as alias}))
		if saveFolder = false then return 0 -- we were obviously mistaken, about what we wanted to do.
		
		my storage's saveParenFolderInScriptCache(saveFolder, script_cache)
		
		tell application "Safari"
			tell its window 1
				local tabc, oldidx
				set tabc to count tabs of it
				if not tlvl's shallClose then
					set oldidx to index of current tab
					tell tab tabc to do JavaScript "self.focus()"
				end if
				local saveCounter
				set saveCounter to 1 -- regulates setting of save folder to only first time in Safari.
				repeat while tabc > 0
					local theUrl, theIdx, theProtocol, alreadyClosed
					
					set {theUrl, theIdx, alreadyClosed} to {URL of its current tab, index of its current tab, false}
					
					if my isntAduplicateTab(theIdx, it) then
						
						set theProtocol to my urlprotocol(theUrl)
						if theProtocol is in {"http", "https"} then
							# save it
							set saveCounter to my saveCurrentTab(saveFolder, saveCounter)
						else if theProtocol is "file" then
							# make an alias of it 
							my makeAliasForAFurl(saveFolder, theUrl)
						end if
					else
						if tlvl's shallClose then
							close current tab
							set alreadyClosed to true
						end if
					end if
					
					if not alreadyClosed and tlvl's shallClose then
						close current tab of it
						set tabc to tabc - 1
					else if not tlvl's shallClose then
						set tabc to tabc - 1
						if tabc > 0 then tell tab tabc to do JavaScript "self.focus()"
					end if
				end repeat
				# move forwards
				if not tlvl's shallClose then
					tell tab oldidx to do JavaScript "self.focus()"
				end if
			end tell
		end tell
	end run
	
	
	to makeAliasForAFurl(destinationFolder, furl)
		local ti, tids, thefilePath
		set ti to "file://"
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ti}
		set thefilePath to text item 2 of furl
		set AppleScript's text item delimiters to tids
		set theFile to POSIX file thefilePath as alias
		set theFolder to POSIX file destinationFolder
		tell application "Finder"
			make alias at theFolder to theFile
			# I don't care if there was one there from before, as it could equally
			# be a file with the same name.
		end tell
	end makeAliasForAFurl
	
	to saveCurrentTab(destinationFolder, timeNumber)
		tell application id "sfri" to activate
		tell application "System Events"
			set UI elements enabled to true
			tell process "Safari"
				keystroke "s" using {command down}
				tell window 1
					repeat until exists sheet 1
						delay 0.2
					end repeat
					tell sheet 1
						if timeNumber = 1 then -- We'll set the savepath upon first call
							keystroke "g" using {command down, shift down}
							repeat until exists sheet 1
								delay 0.2
							end repeat
							tell sheet 1
								set value of text field 1 to destinationFolder
								click button 1
								delay 0.1
							end tell
						end if
						keystroke return
						delay 0.2
						if exists sheet 1 then -- We are being asked if we want to overwrite already saved tab
							if dontOverWriteSavedTabs then
								keystroke return # if it was already saved. We don't overwrite it
								click button 3
							else
								keystroke tab
								keystroke space # we are  to overwrite
							end if
						else
							try
								set dummy to focused of sheet 1
							on error
								# click button 1 of panel of application "Safari"
								keystroke return
								
								delay 0.2
								if exists sheet 1 then -- We are being asked if we want to overwrite already saved tab
									if dontOverWriteSavedTabs then
										keystroke return # if it was already saved. We don't overwrite it
										click button 3
									else
										keystroke tab
										keystroke space # we are  to overwrite
									end if
								end if
							end try
						end if
					end tell
				end tell
			end tell
		end tell
		set timeNumber to timeNumber + 1
		return timeNumber
	end saveCurrentTab
	
	on downloadWindowInFront()
		tell application "Safari"
			activate
			set tabCount to count tabs of its window 1
			if tabCount < 1 then
				tell application "SystemUIServer" to activate
				activate
				return true # Downloads window or somethingelse
			end if
		end tell
		return false
	end downloadWindowInFront
	
	on isntAduplicateTab(idxOfCurrentTab, theWin)
		using terms from application "Safari"
			tell theWin
				set curTabname to name of tab idxOfCurrentTab
				set curTabUrl to URL of tab idxOfCurrentTab
				repeat with i from (idxOfCurrentTab - 1) to 1 by -1
					if name of tab i = curTabname and URL of tab i = curTabUrl then return false
				end repeat
				return true
			end tell
		end using terms from
	end isntAduplicateTab
	
	on getHFSFolder(R) -- Returns hfsPathAsText
		-- R : {Amessage:theMessage,hfsPath:aStartPath}
		local new_path, failed
		set failed to false
		tell application "SystemUIServer"
			activate
			repeat while true
				try
					set new_path to (choose folder with prompt (theMessage of R) default location (hfsPath of R) without invisibles) as text
				on error e number n
					if n is -128 then
						set failed to true
						exit repeat
					end if
				end try
				exit repeat
			end repeat
		end tell
		if failed is true then
			return false
		else
			return new_path
		end if
	end getHFSFolder
	
	on urlprotocol(anUrl)
		# returns the protocol of an Url, i.e. http, https, file, localhost etc.
		local tids, theProtocol
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "://"}
		set theProtocol to text item 1 of anUrl
		set AppleScript's text item delimiters to tids
		return theProtocol
	end urlprotocol
	
	to parentfolder for aPath
		local colons, slashes, origDelims
		set {colons, slashes} to {false, false}
		
		if (offset of ":" in aPath) > 0 then set colons to true
		if (offset of "/" in aPath) > 0 then set slashes to true
		
		if colons and slashes then
			return null
		else if colons then
			set origDelims to ":"
		else if slashes then
			set origDelims to "/"
		else
			return null
		end if
		local tids
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, origDelims}
		if aPath = "/" then
			-- we return root when we get root
			set AppleScript's text item delimiters to tids
			return "/"
		end if
		local theParentFolder
		if text -1 of aPath is in {":", "/"} then
			set theParentFolder to text items 1 thru -2 of text 1 thru -2 of aPath
		else
			set theParentFolder to text items 1 thru -2 of aPath
		end if
		set theParentFolder to theParentFolder as text
		if slashes and theParentFolder = "" then set theParentFolder to "/"
		-- sets the root path if we got a folder one level below it
		if colons and (":" is not in theParentFolder) then set theParentFolder to theParentFolder & ":"
		-- we return volumename, if we are given volumename 
		set AppleScript's text item delimiters to tids
		return theParentFolder
	end parentfolder
	
	
	script storage
		property cachespath : ((path to library folder from user domain as text) & "caches:" & "net.mcusr." & scripttitle)
		
		on scriptCache()
			
			local script_cache
			try
				set script_cache to load script alias (my cachespath)
			on error
				script newScriptCache
					property DefaultLocation : (path to desktop folder as text)
					# edit any of those with default values
				end script
				
				set script_cache to newScriptCache
			end try
			return script_cache
		end scriptCache
		
		to saveScriptCache(theCache)
			store script theCache in my cachespath replacing yes
		end saveScriptCache
		
		to saveParenFolderInScriptCache(theFolderToSaveIn, script_cache)
			local containingFolder
			set containingFolder to (parentfolder of saveTabsInSafariWindowsToFolder for theFolderToSaveIn) & "/"
			local theLoc
			set theLoc to POSIX file containingFolder as alias
			set DefaultLocation of script_cache to theLoc
			my saveScriptCache(script_cache)
		end saveParenFolderInScriptCache
	end script
end script
tell saveTabsInSafariWindowsToFolder to run

property tlvl : me
# Release 1.0.1
# © 2012 McUsr and  put in Public Domain under GPL 1.0
# Please refer to this post: http://macscripter.net/post.php?tid=30892
property shallClose : false # set this to false if you don't want to close the windows, just saving them
property dontOverWriteSavedTabs : false # set this to true if you don't want to overwrite already saved tabs in the folder 
script saveTabsInSafariWindowsToFolder
	property parent : AppleScript
	
	property scripttitle : "SafariSaveTabs"
	on run
		if downloadWindowInFront() then return 0 # activates Safari
		
		local script_cache
		set script_cache to my storage's scriptCache()
		
		set saveFolder to POSIX path of (getHFSFolder({theMessage:"Choose or create folder to save Safari-tabs in.", hfsPath:DefaultLocation of script_cache as alias}))
		if saveFolder = false then return 0 -- we were obviously mistaken, about what we wanted to do.
		
		my storage's saveParenFolderInScriptCache(saveFolder, script_cache)
		
		tell application "Safari"
			tell its window 1
				local tabc, oldidx
				set tabc to count tabs of it
				if not tlvl's shallClose then
					set oldidx to index of current tab
					tell tab tabc to do JavaScript "self.focus()"
				end if
				local saveCounter
				set saveCounter to 1 -- regulates setting of save folder to only first time in Safari.
				repeat while tabc > 0
					local theUrl, theIdx, theProtocol, alreadyClosed
					
					set {theUrl, theIdx, alreadyClosed} to {URL of its current tab, index of its current tab, false}
					
					if my isntAduplicateTab(theIdx, it) then
						
						set theProtocol to my urlprotocol(theUrl)
						if theProtocol is in {"http", "https"} then
							# save it
							set saveCounter to my saveCurrentTab(saveFolder, saveCounter)
						else if theProtocol is "file" then
							# make an alias of it 
							my makeAliasForAFurl(saveFolder, theUrl)
						end if
					else
						if tlvl's shallClose then
							close current tab
							set alreadyClosed to true
						end if
					end if
					
					if not alreadyClosed and tlvl's shallClose then
						close current tab of it
						set tabc to tabc - 1
					else if not tlvl's shallClose then
						set tabc to tabc - 1
						if tabc > 0 then tell tab tabc to do JavaScript "self.focus()"
					end if
				end repeat
				# move forwards
				if not tlvl's shallClose then
					tell tab oldidx to do JavaScript "self.focus()"
				end if
			end tell
		end tell
	end run
	
	
	to makeAliasForAFurl(destinationFolder, furl)
		local ti, tids, thefilePath
		set ti to "file://"
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ti}
		set thefilePath to text item 2 of furl
		set AppleScript's text item delimiters to tids
		set theFile to POSIX file thefilePath as alias
		set theFolder to POSIX file destinationFolder
		tell application "Finder"
			make alias at theFolder to theFile
			# I don't care if there was one there from before, as it could equally
			# be a file with the same name.
		end tell
	end makeAliasForAFurl
	
	to saveCurrentTab(destinationFolder, timeNumber)
		tell application id "sfri" to activate
		tell application "System Events"
			set UI elements enabled to true
			tell process "Safari"
				keystroke "s" using {command down}
				tell window 1
					repeat until exists sheet 1
						delay 0.2
					end repeat
					tell sheet 1
						if timeNumber = 1 then -- We'll set the savepath upon first call
							keystroke "g" using {command down, shift down}
							repeat until exists sheet 1
								delay 0.2
							end repeat
							tell sheet 1
								set value of text field 1 to destinationFolder
								click button 1
								delay 0.1
							end tell
						end if
						keystroke return
						delay 0.2
						if exists sheet 1 then -- We are being asked if we want to overwrite already saved tab
							if dontOverWriteSavedTabs then
								keystroke return # if it was already saved. We don't overwrite it
								click button 3
							else
								keystroke tab
								keystroke space # we are  to overwrite
							end if
						else
							try
								set dummy to focused of sheet 1
							on error
								# click button 1 of panel of application "Safari"
								keystroke return
								
								delay 0.2
								if exists sheet 1 then -- We are being asked if we want to overwrite already saved tab
									if dontOverWriteSavedTabs then
										keystroke return # if it was already saved. We don't overwrite it
										click button 3
									else
										keystroke tab
										keystroke space # we are  to overwrite
									end if
								end if
							end try
						end if
					end tell
				end tell
			end tell
		end tell
		set timeNumber to timeNumber + 1
		return timeNumber
	end saveCurrentTab
	
	on downloadWindowInFront()
		tell application "Safari"
			activate
			set tabCount to count tabs of its window 1
			if tabCount < 1 then
				tell application "SystemUIServer" to activate
				activate
				return true # Downloads window or somethingelse
			end if
		end tell
		return false
	end downloadWindowInFront
	
	on isntAduplicateTab(idxOfCurrentTab, theWin)
		using terms from application "Safari"
			tell theWin
				set curTabname to name of tab idxOfCurrentTab
				set curTabUrl to URL of tab idxOfCurrentTab
				repeat with i from (idxOfCurrentTab - 1) to 1 by -1
					if name of tab i = curTabname and URL of tab i = curTabUrl then return false
				end repeat
				return true
			end tell
		end using terms from
	end isntAduplicateTab
	
	on getHFSFolder(R) -- Returns hfsPathAsText
		-- R : {Amessage:theMessage,hfsPath:aStartPath}
		local new_path, failed
		set failed to false
		tell application "SystemUIServer"
			activate
			repeat while true
				try
					set new_path to (choose folder with prompt (theMessage of R) default location (hfsPath of R) without invisibles) as text
				on error e number n
					if n is -128 then
						set failed to true
						exit repeat
					end if
				end try
				exit repeat
			end repeat
		end tell
		if failed is true then
			return false
		else
			return new_path
		end if
	end getHFSFolder
	
	on urlprotocol(anUrl)
		# returns the protocol of an Url, i.e. http, https, file, localhost etc.
		local tids, theProtocol
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "://"}
		set theProtocol to text item 1 of anUrl
		set AppleScript's text item delimiters to tids
		return theProtocol
	end urlprotocol
	
	to parentfolder for aPath
		local colons, slashes, origDelims
		set {colons, slashes} to {false, false}
		
		if (offset of ":" in aPath) > 0 then set colons to true
		if (offset of "/" in aPath) > 0 then set slashes to true
		
		if colons and slashes then
			return null
		else if colons then
			set origDelims to ":"
		else if slashes then
			set origDelims to "/"
		else
			return null
		end if
		local tids
		set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, origDelims}
		if aPath = "/" then
			-- we return root when we get root
			set AppleScript's text item delimiters to tids
			return "/"
		end if
		local theParentFolder
		if text -1 of aPath is in {":", "/"} then
			set theParentFolder to text items 1 thru -2 of text 1 thru -2 of aPath
		else
			set theParentFolder to text items 1 thru -2 of aPath
		end if
		set theParentFolder to theParentFolder as text
		if slashes and theParentFolder = "" then set theParentFolder to "/"
		-- sets the root path if we got a folder one level below it
		if colons and (":" is not in theParentFolder) then set theParentFolder to theParentFolder & ":"
		-- we return volumename, if we are given volumename 
		set AppleScript's text item delimiters to tids
		return theParentFolder
	end parentfolder
	
	
	script storage
		property cachespath : ((path to library folder from user domain as text) & "caches:" & "net.mcusr." & scripttitle)
		
		on scriptCache()
			
			local script_cache
			try
				set script_cache to load script alias (my cachespath)
			on error
				script newScriptCache
					property DefaultLocation : (path to desktop folder as text)
					# edit any of those with default values
				end script
				
				set script_cache to newScriptCache
			end try
			return script_cache
		end scriptCache
		
		to saveScriptCache(theCache)
			store script theCache in my cachespath replacing yes
		end saveScriptCache
		
		to saveParenFolderInScriptCache(theFolderToSaveIn, script_cache)
			local containingFolder
			set containingFolder to (parentfolder of saveTabsInSafariWindowsToFolder for theFolderToSaveIn) & "/"
			local theLoc
			set theLoc to POSIX file containingFolder as alias
			set DefaultLocation of script_cache to theLoc
			my saveScriptCache(script_cache)
		end saveParenFolderInScriptCache
	end script
end script
tell saveTabsInSafariWindowsToFolder to run

Hello.

I have now bypassed the question about what file-extension to use under saving of a webarchieve. Hopefully I got it right. :slight_smile: (I think I have.) So, It is version 1.0.1 in the post above me. Knock knock…

Hello.

I came across the utility webarchieve some days ago, ( I really had to search to find it. It can be found at This github repository and alleviates UI Scripting of Safari for saving url as web archieves, and how great isn’t that?

Don’t let github scare you off, you need Developer tools to follow the instructions of installing it from macports in the readme file. If somebody really wants it, I can provide a binary, that you’ll install in your own path.

Here is a little demo of using it in a script: I don’t know if works yet, as I don’t have a filemaker database with Urls.
And, since it it is installed at macports, I assume the utility to work as it should.


set specificFolder to POSIX path of (choose folder) -- *** destination folder ***--

tell application "FileMaker Pro"
	tell database "fictiveUrls"
		tell table 1
			set theseURLs to field "Link" -- get all URL
			set theseNames to field "Name"
		end tell
	end tell
end tell
repeat with i from 1 to (count theseURLs)	
	set outpath to quoted form of (specificFolder & item i of theseNames)
	do shell script "webarchiver -url " & item i of theseulrs & " -output " & outpath
end repeat


One more time the author assumes that everybody knows how to use Xcode.
At this time I don’t know what must be downloaded from GitHub.

KOENIG Yvan (VALLAURIS, France) dimanche 7 juillet 2013 19:09:34