Hey, I’ve got a script GUI script for the safari save menu with tab & 0.1 delay repeated 22 times in total (not sure if the delay’s necessary in GUI scripts do tell). It would be better to write it more concisely how could I write, (press tab)*7times or (press tab, delay 0.1)*7times in one line?
THIS IS THE CODE I’M TRYING TO MAKE AS SHORT AS POSSIBLE:
Do I need the delays? How can I repeat tab or tab, delay more concisely.
tell application "Safari"
activate
delay 0.1
tell application "System Events"
tell process "Safari"
--this will only save stuff in one place
click menu item "Save As." of menu 1 of menu bar item "File" of menu bar 1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke (ASCII character 31) --> down arrow
delay 0.1
keystroke "pa"
delay 0.1
keystroke return
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke pOSIXPathOfTargetFile
key down return
key up return
delay 0.2
key down return
key up return
end tell
tell process "Safari"
--this will only save stuff in one place
click menu item "Save As." of menu 1 of menu bar item "File" of menu bar 1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke (ASCII character 31) --> down arrow
delay 0.1
keystroke "we"
delay 0.1
keystroke return
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke tab
delay 0.1
keystroke pOSIXPathOfTargetFile
key down return
key up return
delay 0.2
key down return
key up return
end tell
end tell
end tell
My first answer would be impossible because it makes your code unreadable. But of course it is not impossible. First of all you need to overwrite the delay command in AppleScript so it returns a value. Then you can do multiple commands on one line to set them in an list.
{delay 1, display dialog "hello"}
on delay __seconds
continue delay __seconds
return null
end delay
great, thanks! do you need the delays for maneuvering the GUI with tab, enter, arrow keys etc? It works without them but I’m not sure if it’s as robust.
The following is working reasonably well in Tiger 10.4.11. Maybe you can actually get it to work in your environment.
tell application "Safari"
activate
set doc_name to name of window 1
set doc_type to URL of document 1
if doc_name ends with ".com" then
set corrected_doc_name to characters 1 through -5 of doc_name as string
else
set corrected_doc_name to doc_name
end if
if doc_type ends with ".webarchive" then
set web_archive to "True"
set doc_source to source of document 1
else
set web_archive to "False"
end if
end tell
tell application "Safari" to activate
--
if web_archive is "True" then
tell me to activate
display dialog "Save Web Archive as..." default answer corrected_doc_name buttons {"Cancel", "PDF", "Source"} default button 3 with title "Safari - Save Document"
copy the result as list to {text_returned, button_returned}
set preferred_doc_name to text_returned
tell application "Safari" to activate
--
if button_returned is "Source" then
set output_file to (path to desktop as text) & preferred_doc_name & ".html"
try
open for access file output_file with write permission
write doc_source & return to file output_file starting at eof as «class utf8»
close access file output_file
on error
close access file output_file
end try
end if
tell application "Safari" to activate
--
if button_returned is "PDF" then
tell application "Safari" to activate
tell application "System Events"
tell process "Safari" -- save as PDF
try
-- repeat until sheet 1 of window 1 exists
keystroke "p" using command down -- print dialog appears
-- end repeat
end try
set PDF_button to UI element 6 of UI element 4 of sheet 1 of window 1
set {ButtonLeft, ButtonTop} to position of PDF_button
set {ButtonWidth, ButtonHeight} to size of PDF_button
set clickX to ButtonLeft + (ButtonWidth div 2)
set clickY to ButtonTop + (ButtonHeight div 2)
click at {clickX, clickY}
delay 1
keystroke (ASCII character 31)
keystroke (ASCII character 3)
delay 1.4 -- save dialog appears
keystroke "d" using command down
delay 0.2
if doc_name ends with ".com" or preferred_doc_name is not corrected_doc_name then
keystroke preferred_doc_name -- else leave page name as is...
delay 0.2
end if
delay 1
keystroke (ASCII character 3)
end tell
end tell
tell application "Safari" to activate
end if
end if
tell application "Safari" to activate
----------
if web_archive is not "True" then
if page_loaded(30) then
tell me to activate
display dialog "Save as..." default answer corrected_doc_name buttons {"PDF", "Source", "Archive"} default button 3 with title "Safari - Save Document"
copy the result as list to {text_returned, button_returned}
set preferred_doc_name to text_returned
tell application "Safari" to activate
end if
tell application "Safari" to activate
--
if button_returned is "PDF" then
tell application "Safari" to activate
tell application "System Events"
tell process "Safari" -- save as PDF
try
-- repeat until sheet 1 of window 1 exists
keystroke "p" using command down -- print dialog appears
-- end repeat
end try
set PDF_button to UI element 6 of UI element 4 of sheet 1 of window 1
set {ButtonLeft, ButtonTop} to position of PDF_button
set {ButtonWidth, ButtonHeight} to size of PDF_button
set clickX to ButtonLeft + (ButtonWidth div 2)
set clickY to ButtonTop + (ButtonHeight div 2)
click at {clickX, clickY}
delay 1
keystroke (ASCII character 31)
keystroke (ASCII character 3)
delay 1.4 -- save dialog appears
keystroke "d" using command down
delay 0.2
if doc_name ends with ".com" or preferred_doc_name is not corrected_doc_name then
keystroke preferred_doc_name -- else leave page name as is...
delay 0.2
end if
delay 1
keystroke (ASCII character 3)
end tell
end tell
tell application "Safari" to activate
end if
tell application "Safari" to activate
--
if button_returned is "Source" then
tell application "Safari" to activate
tell application "System Events"
tell process "Safari" -- save as Source
try
-- repeat until sheet 1 of window 1 exists
keystroke "s" using command down -- save dialog appears
-- end repeat
end try
set save_as to get value of pop up button 1 of group 1 of sheet 1 of window 1
if save_as is "Web Archive" then
click pop up button 1 of group 1 of sheet 1 of window 1
delay 0.2
keystroke (ASCII character 30)
keystroke (ASCII character 3)
delay 0.4
end if
delay 0.2
keystroke "d" using command down
delay 0.2
if doc_name ends with ".com" or preferred_doc_name is not corrected_doc_name then
keystroke preferred_doc_name -- else leave page name as is...
delay 0.2
end if
delay 1
click button 1 of sheet 1 of window 1 -- worth a try...
-- keystroke (ASCII character 3) -- if keystroked doc name is long, often won't dismiss dialog
end tell
end tell
tell application "Safari" to activate
end if
tell application "Safari" to activate
--
if button_returned is "Archive" then
tell application "Safari" to activate
tell application "System Events"
tell process "Safari" -- save as Archive
try
-- repeat until sheet 1 of window 1 exists
keystroke "s" using command down -- save dialog appears
-- end repeat
end try
set save_as to get value of pop up button 1 of group 1 of sheet 1 of window 1
if save_as is "Page Source" then
click pop up button 1 of group 1 of sheet 1 of window 1
delay 0.2
keystroke (ASCII character 31)
keystroke (ASCII character 3)
delay 0.4
end if
delay 0.2
keystroke "d" using command down
delay 0.2
if doc_name ends with ".com" or preferred_doc_name is not corrected_doc_name then
keystroke preferred_doc_name -- else leave page name as is...
delay 0.2
end if
delay 1
click button 1 of sheet 1 of window 1 -- worth a try...
-- keystroke (ASCII character 3) -- if keystroked doc name is long, often won't dismiss dialog
end tell
end tell
tell application "Safari" to activate
end if
--
tell application "Safari" to activate
end if
tell application "Safari" to activate
-----
on page_loaded(timeout_value) -- in seconds
--delay 2
repeat with i from 1 to timeout_value
tell application "Safari"
if name of current tab of window 1 is not "Loading" then exit repeat
end tell
--delay 1
end repeat
if i is timeout_value then return false
tell application "Safari"
repeat until (do JavaScript "document.readyState" in document 1) is "complete"
delay 0.5
end repeat
end tell
return true
end page_loaded
(The page load routine borrows heavily from one by StefanK…)
Hmm. Safari’s AppleScript ‘save’ command appears to be pretty ineffective ” with version 5.1 in Snow Leopard anyway.
The effect of all that tabbing in Ole’s script depends on a setting at the bottom of the “Keyboard Shortcuts” tab in the user’s “Keyboard” preferences. If the setting’s “Text boxes and lists only”, as on my machine, the effect is utter rubbish. If it’s “All controls” ” and a suitable delay is inserted to ensure that the “Save As.” dialog has opened before the tabbing begins ” the focus will eventually end up on the pop-up button which allows the choice between saving as “Page Source” or as “Web Archive”. Presumably that’s the situation on Ole’s machine.
The number of tabs can be reduced from 7 to 4 by back-tabbing:
tell application "System Events"
repeat 4 times
keystroke tab using {shift down}
end repeat
end tell
However, things go faster if the button and its menu are addressed directly:
tell application "System Events"
tell application process "Safari"
set frontmost to true
keystroke "s" using {command down}
tell sheet 1 of window 1
repeat until (it exists)
delay 0.2
end repeat
tell pop up button 1 of group 1
click
click menu item "Web Archive" of menu 1 -- Assuming an English language display.
end tell
end tell
end tell
end tell
This has the additional advantage of being independent of the user’s keyboard preferences, although like Ole’s script, it’s language dependent and (probably) system-version dependent.
That still leaves the problem of saving the document in the right place. If I type a POSIX path into the “Export As:” field, the file appears wherever the dialog’s pointing at that moment with the entire POSIX path as its name. The POSIX path has to go into the additional sheet which appears in response to the Shift-Command-“g” keystroke.
set pOSIXPathOfTargetFile to POSIX path of (path to desktop) & "Test" -- Just for testing,
tell application "System Events"
tell application process "Safari"
set frontmost to true
keystroke "s" using {command down}
tell sheet 1 of window 1
-- Wait for the "Save As." dialog sheet.
repeat until (it exists)
delay 0.2
end repeat
-- Set the "Page Source/Web Archive" pop-up.
tell pop up button 1 of group 1
click
click menu item "Web Archive" of menu 1 -- Assuming an English language display.
end tell
keystroke "g" using {shift down, command down} -- or of course: keystroke "G" using {command down}
tell sheet 1 -- sheet 1 of sheet 1 of group window 1
-- Wait for the "Go to folder:" sheet.
repeat until (it exists)
delay 0.2
end repeat
-- Set the value of the text field.
set value of text field 1 to pOSIXPathOfTargetFile
-- Dismiss the sheet and wait for it to go.
keystroke return
repeat while (it exists)
delay 0.2
end repeat
end tell
-- The folder from the path has been selected (assuming it exists) and the file name has been entered into the "Save As." sheet's "Export As:" text field with the appropriate extension.
-- Hit return to dismiss the dialog and perform the save.
keystroke return
end tell
end tell
end tell
You could write something similar for saving the page source, but this is faster and less obtrusive:
set pOSIXPathOfTargetFile to POSIX path of (path to desktop) & "Test.html"
tell application "Safari" to set sourceText to source of document 1
set fRef to (open for access pOSIXPathOfTargetFile with write permission)
try
set eof fRef to 0
write sourceText as string to fRef
end try
close access fRef
Never coerce a record to list and assume that the items will be in any particular order! (Unless it’s a one-property record, of course. ;)) Use:
display dialog "Save Web Archive as..." default answer "" buttons {"Cancel", "PDF", "Source"} default button 3 with title "Safari - Save Document"
set {text_returned, button_returned} to {text returned, button returned} of result
Or:
display dialog "Save Web Archive as..." default answer "" buttons {"Cancel", "PDF", "Source"} default button 3 with title "Safari - Save Document"
set {text returned:text_returned, button returned:button_returned} to result