Hi there,
Is it possible to take a screenshot of the entire web page in safari?
I need an applescript that will do this - the page itself would require scrolling in order to see the entire thing.
Thanks!
Hi there,
Is it possible to take a screenshot of the entire web page in safari?
I need an applescript that will do this - the page itself would require scrolling in order to see the entire thing.
Thanks!
Open Safari to the url you would like to get the image of. Then run this:
tell application "Safari"
activate
set winID to id of window 1
end tell
do shell script "screencapture -c -x -l " & winID
Thanks for your reply Halosurferdude,
But that script does nothing on my machine
It certainly worked : it put the screenshot in the clipboard.
The problem is that it captures only what is displayed on the screen, not the entire page.
If you want to get the entire page you may use Print in a PDF.
# Build the name of the PDF to fit your needs
set thePDFname to "beurk.pdf"
set thePDFPath to (path to documents folder as text) & "the PDFs:"
set posixFolderPath to POSIX path of thePDFPath
tell application "System Events"
set frontmostProcess to first process where it is frontmost -- this will be the script process
if name of frontmostProcess is in {"Script Editor", "AppleScript Editor"} then # CAUTION the name changed
set visible of frontmostProcess to false -- hide the script process
repeat while (frontmostProcess is frontmost) -- wait until the script is hiden
delay 0.2
end repeat
tell (first process where it is frontmost)
set theProcess to its name
set theApp to its file
end tell
set frontmost of frontmostProcess to true -- unhide the script process
else
tell frontmostProcess
set theProcess to its name
set theApp to its file
end tell
end if
set theApp to name of theApp
end tell
activate application theApp
tell application "System Events" to tell process theProcess
set nbw to count windows
keystroke "p" using command down
(*
Wait for the availability of the sheet *)
repeat
if exists sheet 1 of window 1 then exit repeat
end repeat
--name of menu buttons of sheet 1 of window 1
--> {"PDF"} # but I don't know if it's spelled this way worldwide
tell sheet 1 of window 1
set PDFButton to first menu button
click PDFButton
-- name of menu items of menu 1 of PDFButton
--> {"Ouvrir le PDF dans Aperçu", "Enregistrer au format PDFâŠ", "Enregistrer au format PostScriptâŠ", "Faxer le document PDFâŠ", missing value, "@ PDF-BAT.qfilter", "@ PDF-prĂ©presse CMJN.qfilter", "@ PDF-web.qfilter", "@ PDFX3-ISO.qfilter", "Add PDF to iTunes", "Envoyer le document PDF par courrier Ă©lectronique", "Enregistrer le document PDF dans le dossier de reçus web", missing value, "Modifier le menuâŠ"}
click menu item 2 of menu 1 of PDFButton
(*
Wait for the availability of the Print sheet *)
repeat
if exists sheet 1 then exit repeat
end repeat
(*
Set the name of the new PDF *)
tell sheet 1
# Set the Desktop as destination folder
set value of text field 1 to thePDFname
keystroke "g" using {command down, shift down}
repeat until exists sheet 1
delay 0.02
end repeat
tell sheet 1
# CAUTION. before 10.11 the target field was a text field. Now it's a combo box
if class of UI elements contains combo box then
--> {static text, combo box, button, button}
set value of combo box 1 to posixFolderPath
else
--> {static text, text field, button, button}
set value of text field 1 to posixFolderPath
end if
get name of buttons (*Aller, Annuler*)
keystroke return # ditto click button 1 (ou Aller)
end tell
get name of buttons
--> {missing value, missing value, missing value, "Enregistrer", "Nouveau dossier", "Annuler"}
--click button -3 -- ditto keystroke return
keystroke return
end tell # sheet 1 (the Save As one)
end tell # sheet 1 of window 1
end tell
# Now the pdf is available in the defined folder.
If you may have use for the screencapture feature, here are several instructions using it :
tell application "Safari"
activate
set winID to id of window 1
end tell
# store the screenshot in the clipboard
--do shell script "screencapture -c -x -l " & winID
# WARNING : I found no explanation about the -l parameter.
# store the screenshot in the defined location
--do shell script "screencapture -x " & quoted form of POSIX path of ((path to desktop as text) & "my screenshot.png") & space & winID
# store the screenshot in the defined location and open it in Preview
--do shell script "screencapture -x -P " & quoted form of POSIX path of ((path to desktop as text) & "my screenshot.png") & space & winID
# store the screenshot in the defined location and open it in Preview. It allow you to define interactively the area to capture.
do shell script "screencapture -x -i -P " & quoted form of POSIX path of ((path to desktop as text) & "my screenshot.png") & space & winID
I would interested if somebody may explain what the -l parameter is supposed to rule.
Yvan KOENIG running Sierra 10.12.6 in French (VALLAURIS, France) mercredi 2 aout 2017 18:44:21
Yvan,
Bonjour! (Well its day here and I lived in Bordeaux when in first and second grade.)
-l followed by the window ID specifies that screen capture operate on the specific window.
The call
do shell script "screencapture -c -x -l " & winID
specifies to copy to the clipboard (-c), no sound (-x), at specified window (-l).
Your solution to get the entire page and not just the screen shot is nicely done.
Best!
Thanks
I asked because there is no parameter -l in the man page.
I just found the parameter -i whose description is :
[format]-i Capture screen interactively, by selection or window. The con-
trol key will cause the screen shot to go to the clipboard. The
space key will toggle between mouse selection and window selec-
tion modes. The escape key will cancel the interactive screen
shot.[/format]
Yvan KOENIG running Sierra 10.12.6 in French (VALLAURIS, France) mercredi 2 aout 2017 21:25:17
For the fun I built an alternate version which extract the localized strings used from system resources.
# Build the name of the PDF to fit your needs
set thePDFname to "beurk.pdf"
set thePDFPath to (path to documents folder as text) & "the PDFs:"
set posixFolderPath to POSIX path of thePDFPath
# Extract the localized strings
set theBundle to (path to library folder from system domain as text) & "PrivateFrameworks:PrintingPrivate.framework:Versions:A:Plugins:PrintCocoaUI.bundle:Contents:Resources:"
set x to "64.title"
set SaveAsPDFellipsis_loc to localized string x from table "CocoaPrintWindow" in bundle (theBundle as «class furl») --> "Enregistrer au format PDFâŠ"
(*
set x to "64.ibExternalAccessibilityDescription"
set SaveAsPDF_loc to localized string x from table "CocoaPrintWindow" in bundle (theBundle as «class furl») --> "Enregistrer au format PDF" # I don't know where it's used
*)
set x to "65.title"
set PDF_loc to localized string x from table "CocoaPrintWindow" in bundle (theBundle as «class furl») --> "PDF"
tell application "System Events"
set frontmostProcess to first process where it is frontmost -- this will be the script process
if name of frontmostProcess is in {"Script Editor", "AppleScript Editor"} then # CAUTION the name changed
set visible of frontmostProcess to false -- hide the script process
repeat while (frontmostProcess is frontmost) -- wait until the script is hiden
delay 0.2
end repeat
tell (first process where it is frontmost)
set theProcess to its name
set theApp to its file
end tell
set frontmost of frontmostProcess to true -- unhide the script process
else
tell frontmostProcess
set theProcess to its name
set theApp to its file
end tell
end if
set theApp to name of theApp
end tell # System Events
activate application theApp
tell application "System Events" to tell process theProcess
--set nbw to count windows # unused
set frontmost to true
keystroke "p" using command down
(*
Wait for the availability of the sheet *)
repeat
if exists sheet 1 of window 1 then exit repeat
end repeat
--class of UI elements of sheet 1 of window 1
--> {group, static text, group, static text, pop up button, static text, pop up button, static text, text field, checkbox, static text, radio button, radio button, text field, static text, text field, static text, pop up button, static text, static text, radio group, static text, text field, pop up button, checkbox, checkbox, button, menu button, button, button, button}
--name of menu buttons of sheet 1 of window 1
--> {"PDF"} # but I don't know if it's spelled this way worldwide
tell sheet 1 of window 1
click menu button PDF_loc
-- name of menu items of menu 1 of PDFButton
--> {"Ouvrir le PDF dans Aperçu", "Enregistrer au format PDFâŠ", "Enregistrer au format PostScriptâŠ", "Faxer le document PDFâŠ", missing value, "@ PDF-BAT.qfilter", "@ PDF-prĂ©presse CMJN.qfilter", "@ PDF-web.qfilter", "@ PDFX3-ISO.qfilter", "Add PDF to iTunes", "Envoyer le document PDF par courrier Ă©lectronique", "Enregistrer le document PDF dans le dossier de reçus web", missing value, "Modifier le menuâŠ"}
click menu item SaveAsPDFellipsis_loc of menu 1 of menu button PDF_loc
(*
Wait for the availability of the Print sheet *)
repeat
if exists sheet 1 then exit repeat
end repeat
(*
Set the name of the new PDF *)
tell sheet 1
# Set the Desktop as destination folder
set value of text field 1 to thePDFname
keystroke "g" using {command down, shift down}
repeat until exists sheet 1
delay 0.02
end repeat
tell sheet 1
# CAUTION. before 10.11 the target field was a text field. Now it's a combo box
(*
if class of UI elements contains combo box then
--> {static text, combo box, button, button}
set value of combo box 1 to posixFolderPath
else
--> {static text, text field, button, button}
set value of text field 1 to posixFolderPath
end if
*)
# An alternate way would be
set value of UI element 2 to posixFolderPath
# But there is no guarantee that the index remains equal to 2
get name of buttons (*Aller, Annuler*)
keystroke return # ditto click button 1 (ou Aller)
end tell
get name of buttons
--> {missing value, missing value, missing value, "Enregistrer", "Nouveau dossier", "Annuler"}
--click button -3 -- ditto keystroke return
keystroke return
end tell # sheet 1 (the Save As one)
end tell # sheet 1 of window 1
end tell
# Now the pdf is in the defined folder.
Yvan KOENIG running Sierra 10.12.6 in French (VALLAURIS, France) jeudi 3 aout 2017 12:09:22
Thank you Yvan!
I made a small modification, so that it sets date and time as the filename and saves it into a screenshot folder on the desktop.
(my management of dates and times in applescript needs some work, I know.)
Your solution works perfectly!
set {year:y, month:m, day:d} to (current date)
set CurrentTime to (do shell script "date +\"%l %M %p\" | awk '{$1=$1;print}'")
set theDate to y & space & m & space & d as text
set ssfileName to theDate & " - " & CurrentTime & ".pdf"
set thePDFPath to (path to desktop folder as text) & "Screenshots"
set posixFolderPath to POSIX path of thePDFPath
tell application "Safari"
activate
delay 1
set the URL of the front document to "http://www.google.com"
delay 30
end tell
tell application "System Events"
set frontmostProcess to first process where it is frontmost -- this will be the script process
if name of frontmostProcess is in {"Script Editor", "AppleScript Editor"} then # CAUTION the name changed
set visible of frontmostProcess to false -- hide the script process
repeat while (frontmostProcess is frontmost) -- wait until the script is hidden
delay 0.2
end repeat
tell (first process where it is frontmost)
set theProcess to its name
set theApp to its file
end tell
set frontmost of frontmostProcess to true -- unhide the script process
else
tell frontmostProcess
set theProcess to its name
set theApp to its file
end tell
end if
set theApp to name of theApp
end tell
activate application theApp
tell application "System Events" to tell process theProcess
set nbw to count windows
keystroke "p" using command down
repeat
if exists sheet 1 of window 1 then exit repeat
end repeat
tell sheet 1 of window 1
set PDFButton to first menu button
click PDFButton
click menu item 2 of menu 1 of PDFButton
repeat
if exists sheet 1 then exit repeat
end repeat
tell sheet 1
# Set the Desktop as destination folder
set value of text field 1 to ssfileName
delay 2
keystroke "g" using {command down, shift down}
repeat until exists sheet 1
delay 2
end repeat
tell sheet 1
# CAUTION. before 10.11 the target field was a text field. Now it's a combo box
if class of UI elements contains combo box then
--> {static text, combo box, button, button}
set value of combo box 1 to posixFolderPath
else
--> {static text, text field, button, button}
set value of text field 1 to posixFolderPath
end if
get name of buttons
keystroke return
end tell
get name of buttons
keystroke return
end tell
end tell
end tell
Hereâs an alternative approach. It creates an invisible Web view of the same size, downloads the URL again, then saves it a PDF. About the only difference in the result is that the resulting PDF is a single page, no breaks.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
property theView : missing value -- the WebView
property pdfData : missing value -- the PDF data
property theTitle : missing value -- the frame title
property readyFlag : true -- flag that signifies done
use scripting additions
tell application "Safari"
tell (window 1 whose visible is true)
set {x1, y1, x2, y2} to bounds
set theURL to URL of tab 1 whose visible is true
end tell
end tell
if current application's NSThread's isMainThread() as boolean then
-- set up WebView
my setUpWebviewSized:{x2 - x1, y2 - y1}
-- load the URL
my processURL:theURL
else
-- set up WebView
my performSelectorOnMainThread:"setUpWebviewSized:" withObject:{x2 - x1, y2 - y1} waitUntilDone:true
-- load the URL
(my performSelectorOnMainThread:"processURL:" withObject:theURL waitUntilDone:true)
end if
repeat while not my readyFlag
delay 0.3
end repeat
set thePath to current application's NSString's stringWithFormat_("%@/%@.pdf", POSIX path of (path to desktop), theTitle)
pdfData's writeToFile:thePath atomically:true
display dialog "Finished" buttons {"OK"} default button 1
-- needs to be done on the main thread
on setUpWebviewSized:theSize
-- make a WebView
set my theView to current application's WebView's alloc()'s initWithFrame:{origin:{x:0, y:0}, |size|:theSize}
-- tell it to call delegate methods on me
theView's setFrameLoadDelegate:me
end setUpWebviewSized:
-- needs to be done on the main thread
on processURL:thePageURL
-- load the page
(my theView)'s setMainFrameURL:thePageURL
-- set ready flag to false
set my readyFlag to false
end processURL:
-- called when the WebView loads a frame
on WebView:aWebView didFinishLoadForFrame:webFrame
-- the main frame is our interest
if webFrame = aWebView's mainFrame() then
set my theTitle to aWebView's mainFrameTitle()'s stringByReplacingOccurrencesOfString:"/" withString:"_"
set docView to webFrame's frameView()'s documentView()
set my pdfData to docView's dataWithPDFInsideRect:(docView's frame())
set my readyFlag to true
end if
end WebView:didFinishLoadForFrame:
on WebView:WebView didFailLoadWithError:theError forFrame:webFrame
-- got an error, bail
WebView's stopLoading:me
error theError's localizedDescription() as text
end WebView:didFailLoadWithError:forFrame:
Thank you Shane.
Will be part of my library of scripts.
Yvan KOENIG running Sierra 10.12.6 in French (VALLAURIS, France) jeudi 3 aout 2017 15:38:48
I was asked about my old GUI scripting version because some details evolved.
Here is the updated version.
(*
http://www.macscripter.net/viewtopic.php?id=45871
*)
# Build the path of the folder storing the PDFs to fit your needs
set thePDFsRoot to (path to documents folder as text)
set theFolderName to "the PDFs"
set thePDFsFolder to thePDFsRoot & theFolderName
tell application "System Events"
# Grab the system version
set sys2 to (system attribute "sys2") as integer
if not (exists folder thePDFsFolder) then make new folder at end of folder thePDFsRoot with properties {name:theFolderName}
end tell
set posixPDFsFolder to POSIX path of thePDFsFolder
# Extract the localized strings
set theBundle to ((path to library folder from system domain as text) & "PrivateFrameworks:PrintingPrivate.framework:Versions:Current:Plugins:PrintCocoaUI.bundle:Contents:Resources:") as «class furl»
set x to "64.title"
set SaveAsPDF_loc to localized string x from table "CocoaPrintWindow" in bundle theBundle --> "Enregistrer au format PDFâŠ"
if SaveAsPDF_loc is x then
if sys2 < 13 then -- there is an ellipsis (or 3 dots) but I'm not sure that the resource is available
-- 10.10 appends ellipsis (or 3 dots) but the resource isn't available
set SaveAsPDF_loc to 2 -- use the index which will not be modified
else
set SaveAsPDF_loc to "Save as PDF"
end if
end if
set x to "65.title"
set PDF_loc to localized string x from table "CocoaPrintWindow" in bundle theBundle --> "PDF"
if PDF_loc is x then set PDF_loc to "PDF"
set x to "Save"
set save_loc to localized string x from table "Localizable" in bundle theBundle --> "Enregistrer"
tell application "System Events"
set frontmostProcess to first process where it is frontmost -- this will be the script process
if name of frontmostProcess is in {"Script Editor", "AppleScript Editor", "Script Debugger"} then # CAUTION the name changed
set visible of frontmostProcess to false -- hide the script process
repeat while (frontmostProcess is frontmost) -- wait until the script is hiden
delay 0.2
end repeat
tell (first process where it is frontmost)
set theProcess to its name
set theApp to its file
end tell
set frontmost of frontmostProcess to true -- unhide the script process
else
tell frontmostProcess
set theProcess to its name
set theApp to its file
end tell
end if
set theApp to name of theApp
end tell # System Events
if theProcess is "Finder" then error "Can't print Finder windows"
activate application theApp
tell application "System Events" to tell process theProcess
set frontmost to true
class of UI elements --> {window, menu bar}
set wName to name of window 1
set nbWindows to count windows
keystroke "p" using command down
-- Two behaviors exist
set gotIt to false
repeat 10 times
if (count windows) > nbWindows then
set gotIt to true
set targetItem to window 1 -- Firefox use this case
exit repeat
end if
if exists sheet 1 of window 1 then
set gotIt to true
set targetItem to sheet 1 of window 1 -- Safari use this case
exit repeat
end if
delay 0.2
end repeat
if not gotIt then error "No print sheet or window available"
tell targetItem
-- class of UI elements --> --> {static text, pop up button, static text, pop up button, static text, text field, checkbox, static text, radio button, radio button, text field, static text, text field, static text, pop up button, static text, static text, radio group, static text, text field, pop up button, static text, checkbox, checkbox, static text, checkbox, checkbox, static text, static text, static text, static text, static text, pop up button, pop up button, pop up button, pop up button, pop up button, pop up button, button, menu button, button, button, button, static text}
click menu button PDF_loc
-- name of menu items of menu 1 of menu button PDF_loc
--> {"Ouvrir le PDF dans Aperçu", "Enregistrer au format PDFâŠ", "Enregistrer au format PostScriptâŠ", "Faxer le document PDFâŠ", missing value, "@ PDF-BAT.qfilter", "@ PDF-prĂ©presse CMJN.qfilter", "@ PDF-web.qfilter", "@ PDFX3-ISO.qfilter", "Add PDF to iTunes", "Envoyer le document PDF par courrier Ă©lectronique", "Enregistrer le document PDF dans le dossier de reçus web", missing value, "Modifier le menuâŠ"}
-- use the index with 10.10
click menu item SaveAsPDF_loc of menu 1 of menu button PDF_loc
(*
Wait for the availability of the Print sheet *)
repeat
if exists sheet 1 then exit repeat
end repeat
(*
Set the name of the new PDF *)
tell sheet 1
-- class of UI elements --> {static text, text field, UI element, static text, text field, group, radio group, group, pop up button, text field, splitter group, text field, static text, button, text field, static text, text field, static text, static text, text field, button, button, button}
set thePDFname to wName & "_" & my dateTimeStamp() & ".pdf"
set thePDFname to my remplace(thePDFname, {"/", ":"}, "|") -- I know, I'm a bit paranoid
set value of text field 1 to thePDFname
keystroke "g" using {command down, shift down}
repeat until exists sheet 1
delay 0.02
end repeat
tell sheet 1
# CAUTION. before 10.11 the target field was a text field. Now it's a combo box
-- class of UI elements
--> {static text, text field, button, button} -- with 10.10 and older systems
--> {static text, combo box, button, button} -- 10.11, 10.12, 10.13, 10.14, 10.15
if exists combo box 1 then
set value of combo box 1 to posixPDFsFolder
else
set value of text field 1 to posixPDFsFolder
end if
get name of buttons (*Aller, Annuler*)
keystroke return # ditto click button 1 (ou Aller)
end tell
get name of buttons
--> {missing value, missing value, missing value, "Enregistrer", "Nouveau dossier", "Annuler"}
-- CAUTION, whith High Sierra and newer OS, the buttons are:
--> {"Options de sĂ©curitĂ©âŠ", "Nouveau dossier", "Annuler", "Enregistrer"}
-- So clicking button -3 no longer apply
-- we may apply click button save_loc or issue the shortcut 'return'
keystroke return
end tell # sheet 1 (the Save As one)
end tell # targetItem
end tell
# Now the pdf is in the defined folder.
#=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
local oTIDs, l
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d1}
set l to text items of t
set AppleScript's text item delimiters to d2
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end remplace
#=====
on dateTimeStamp()
tell (current date) to return (((its year) * 10000 + (its month) * 100 + (its day)) as text) & "_" & text 2 thru -1 of ((1000000 + (its hours) * 10000 + (its minutes) * 100 + (its seconds)) as text)
end dateTimeStamp
#=====
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 6 mars 2020 18:45:40
Edited to give a custom name to the created PDF.
My script isnât dedicated to Safari.
It apply to most applications.
Sometimes, the Print pane is a sheet but sometimes, the Print pane is a window.
I donât know what rules that but my script do the job in both cases.
I was really interested by Shaneâs proposal ⊠until I applied it upon a document containing 10 pages.
The result was a document displaying the entire doc in a single page making it perfectly unusable.
Maybe there is a way to urge the code to split the stamp in a document of several readable pages but I donât know it.
So, I returned to the brave old GUI scripting process.
Maybe because I never found the syntax required to use it. And I am not the unique being in this case.
set thePath to ((path to desktop as text) & "azer.pdf")
tell application "Safari"
activate
save document 1 in file thePath as "com.adobe.pdf"
end tell
issue : error âErreur dans Safari : document 1 ne comprend pas le message « save ».â number -1708 from document 1
Same behavior of I try to apply the save command to window 1 or if I try to save as âPDFâ.
Ditto if I define the path as a «class furl» object.
I never liked to play the sooth sayer so I use what I may work with.
Of course, if you know the correct incantation, I will be glad to learn it.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 6 mars 2020 21:19:07
Here is simple version, using Web Inspector:
tell application "Safari"
activate
open location "https://www.apple.com"
end tell
tell application "System Events" to tell application process "Safari"
repeat until (UI element "Reload this page" of group 2 of toolbar 1 of window 1 exists)
delay 0.1
end repeat
display notification "The webpage is fully loaded now." sound name "Frog"
click menu item "Show Web Inspector" of menu 1 of menu bar item "Develop" of menu bar 1
repeat until tab group 1 of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 exists
delay 0.1
end repeat
tell group 1 of tab group 1 of splitter group 1 of window 1
tell static text 1 of group 2 of group 2 of group 2 of UI element 1 of scroll area 1 of group 1 to perform action "AXShowMenu"
click menu item "Capture Screenshot" of menu 1
end tell
repeat until sheet 1 of window 1 exists
delay 0.1
end repeat
click button "Save" of sheet 1 of window 1
end tell
tell application "Safari" to close tab 1 of window 1
I will localize your proposal to test it.
My script works with all tested applications.
Firefox is one of those which doesnât use a sheet but a window.
I edited my message so that the script use a custom PDF name.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 7 mars 2020 11:18:48
@ KniazidisR
I did my best to localize your proposal.
I failed to find the resources describing the late menu so I trigger the wanted menu item by its index.
Would be good to check that itâs the correct index for the running operating system.
As you may see, I was forced to redesign the piece of code supposed to wait for the UI element âReload this pageâ.
On my machine, the wanted item is not in group 2 but in group 3 and it canât be identified by its name.
Some extraneous instructions display what is available here in group 2.
As I am pig headed I will continue to search for the resource describing the final menu but I am skeptical because my dedicated tools failed during my late attempts.
# Extract the localized strings
set theBundle to ((path to library folder from system domain as text) & "PrivateFrameworks:PrintingPrivate.framework:Versions:Current:Plugins:PrintCocoaUI.bundle:Contents:Resources:") as «class furl»
set x to "Save"
set save_loc to localized string x from table "Localizable" in bundle theBundle --> "Enregistrer"
set theBundle to ((path to library folder from system domain as text) & "PrivateFrameworks:Safari.framework:") as «class furl»
set x to "Reload this page"
set reloadThisPage_loc to localized string x from table "Localizable" in bundle theBundle --> "Recharger cette page"
set x to "Show Web Inspector"
set showWebInspector_loc to localized string x from table "Localizable" in bundle theBundle --> "Afficher lâinspecteur web"
set x to "Develop"
set develop_loc to localized string x from table "Localizable" in bundle theBundle --> "DĂ©veloppement"
(*
set x to "Capture Screenshot"
set captureScreenshot_loc to localized string x from table "Localizable" in bundle theBundle --> "Capture Screenshot" when it was supposed to return "Capturer lâaperçu" because there is no such resource
*)
tell application "Safari"
activate
open location "https://www.apple.com"
end tell
tell application "System Events" to tell application process "Safari"
set frontmost to true
repeat 100 times
if (description of UI elements of group -1 of toolbar 1 of window 1) contains reloadThisPage_loc then exit repeat
delay 0.1
end repeat
try
tell button 1 of UI element 1 of group 2 of toolbar 1 of window 1
its name --> missing value
its description --> "uBlock Safari Icon"
end tell
end try
display notification "The webpage is fully loaded now."
end tell
tell application "System Events" to tell application process "Safari"
--keystroke "i" using {command down, option down}
click menu item showWebInspector_loc of menu 1 of menu bar item develop_loc of menu bar 1
repeat until tab group 1 of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 exists
delay 0.1
end repeat
tell group 1 of tab group 1 of splitter group 1 of window 1
click static text 1 of group 2 of group 2 of group 2 of UI element 1 of scroll area 1 of group 1
tell static text 1 of group 2 of group 2 of group 2 of UI element 1 of scroll area 1 of group 1 to perform action "AXShowMenu"
(name of menu items of menu 1) --> {"Ajouter", "Modifier", "Copier", "Supprimer", "Activer/DĂ©sactiver la visibilitĂ©", missing value, "Pseudo-classes forcĂ©es", missing value, "SâarrĂȘter", missing value, "Consigner lâĂ©lĂ©ment", "Capturer lâaperçu", "Faire dĂ©filer dans la prĂ©sentation", missing value, "Tout dĂ©velopper", "Tout condenser"}
name of menu item -5 of menu 1 --> "Capturer lâaperçu"
name of menu item 12 of menu 1 --> "Capturer lâaperçu"
click menu item -5 of menu 1
end tell
repeat until sheet 1 of window 1 exists
delay 0.1
end repeat
click button save_loc of sheet 1 of window 1
end tell
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 7 mars 2020 14:14:33
I updated my script according to the last 3 comments.
Here is a point of departure.
# Extract the localized strings
set theBundle to ((path to library folder from system domain as text) & "Frameworks:WebKit.framework:Versions:Current:Frameworks:WebCore.framework:") as «class furl»
set x to "Inspect Element"
set inspectElement_loc to localized string x from table "Localizable" in bundle theBundle --> "Enregistrer"
tell application "Safari"
activate
end tell
tell application "System Events" to tell application process "Safari"
set frontmost to true
set {{x, y}, {w, h}} to {position, size} of window 1
tell me to do shell script "/usr/local/bin/cliclick rc:" & x + w div 2 & "," & y + h div 2
tell window 1
-- class of UI elements --> {splitter group, button, button, button, group, button, group, toolbar}
tell splitter group 1
-- class of UI elements --> {splitter, tab}
tell tab group 1
-- class of UI elements --> {group}
tell group 1
-- class of UI elements --> {group, menu}
tell menu 1
-- class of UI elements --> {menu item, menu item, menu item, menu item, menu item, menu item, menu item, menu item, menu item}
-- name of menu items--> {"PrĂ©cĂ©dent", "Recharger la page", "Ouvrir dans DashboardâŠ", missing value, "Afficher le code source de la page", "Enregistrer la page en tant queâŠ", "Imprimer la pageâŠ", missing value, "Inspecter lâĂ©lĂ©ment"}
click menu item inspectElement_loc
end tell
end tell
end tell
end tell
end tell
end tell
-- Now, the Web Inspector is open
But I donât understand what you want to do after reaching this point.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 8 mars 2020 16:59:09
I downloaded your examples but I donât understand how you selected the wanted block after revealing the inspector.
I take the opportunity to post an enhanced version of the KniazidisRâs proposal.
I built it because during my tests I clicked on the radio button [Resources] which modified the behavior of the Web Inspector and discovered that the setting remains as is as long as I didnât reset the original setting.
So I decided to urge the script to do the job.
As is, my version used the âdevelopedâ structure.
You are free to compact it if you want.
Of course we may add the new instructions in the code triggering the contextual menu.
Other interesting news, I found the file storing the name of the menu item triggered in KniazidisRâs script. Itâs a file named localizedStrings.js located in (path to library folder from system domain as text)& âPrivateFrameworks:WebInspectorUI.framework:Versions:A:Resources:fr.lproj:â (en.lproj for the English resource).
I have a script able to extract the localized version âon the flyâ but, in text format it uses 3154 bytes so Iâm not sure that itâs a good idea to embed it in main scripts.
I will work again to refine it and will post it here some times ago so everybody will be free to use it. I will also post the script scanning the available resource files to identify the interesting one.
Itâs boring because some files are encoded using utf8 but some others use ut16 :rolleyes:
-- https://macscripter.net/viewtopic.php?id=45871
----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
----------------------------------------------------------------
# Extract the localized strings
set theBundle to ((path to library folder from system domain as text) & "PrivateFrameworks:PrintingPrivate.framework:Versions:Current:Plugins:PrintCocoaUI.bundle:Contents:Resources:") as «class furl»
set x to "Save"
set save_loc to localized string x from table "Localizable" in bundle theBundle --> "Enregistrer"
set theBundle to ((path to library folder from system domain as text) & "PrivateFrameworks:Safari.framework:") as «class furl»
set x to "Add page to Reading List"
set addPageToReadingList_loc to localized string x from table "Localizable" in bundle theBundle --> "Ajouter la page Ă la liste de lecture"
set x to "Reload this page"
set reloadThisPage_loc to localized string x from table "Localizable" in bundle theBundle --> "Recharger cette page"
set x to "Show Web Inspector"
set showWebInspector_loc to localized string x from table "Localizable" in bundle theBundle --> "Afficher lâinspecteur web"
set x to "Hide Web Inspector"
set hideWebInspector_loc to localized string x from table "Localizable" in bundle theBundle --> "Masquer lâinspecteur web"
set x to "Develop"
set develop_loc to localized string x from table "Localizable" in bundle theBundle --> "DĂ©veloppement"
set x to "Capture Screenshot"
set captureScreenshot_loc to localized string x from table "Localizable" in bundle theBundle --> "DĂ©veloppement"
-- build the path to the resource file so we may reuse it if several strings are defined in it.
set theSource to my getResourceFile:((path to library folder from system domain as text) & "PrivateFrameworks:WebInspectorUI.framework:Versions:A:Resources:") fromTable:"localizedStrings.js"
set x to "Capture Screenshot"
set captureScreenshot_loc to my localize:x storedIn:theSource
tell application "Safari"
activate
open location "https://www.apple.com"
end tell
tell application "System Events" to tell application process "Safari"
set frontmost to true
repeat with i from 2 to (count groups of toolbar 1 of window 1)
try
if (description of UI elements of group i of toolbar 1 of window 1) contains addPageToReadingList_loc then exit repeat
--> i = 2 --> {"uBlock Safari Icon"}
--> i = 3 --> {"Ajouter la page Ă la liste de lecture", "Certificat de Validation Ă©tendue Apple Inc.", "Adresse et recherche", "Interrompre le chargement de cette page"}
--> i = 4 -- why not ?
end try
end repeat
-- Now i is the index of the group to check.
-- After all we may imagine a 3rd party item installing a group at index 4
-- as uBlock install its one at index 2
repeat 100 times
if (exists UI element reloadThisPage_loc of group i of toolbar 1 of window 1) then exit repeat
delay 0.1
end repeat
tell me to display notification "The webpage is fully loaded now."
end tell
# Build the path of the folder storing the screenshot to fit your needs
set thePictures to (path to pictures folder as text)
set theFolderName to "Screenshots"
set theScreenshotsFolder to thePictures & theFolderName
tell application "System Events"
if not (exists folder theScreenshotsFolder) then make new folder at end of folder thePictures with properties {name:theFolderName}
end tell
set posixScreenshotsFolder to POSIX path of theScreenshotsFolder
tell application "System Events" to tell application process "Safari"
set frontmost to true -- Useful if we don't use the block downloading the Web page
-- keystroke "i" using {command down, option down}
click menu item showWebInspector_loc of menu 1 of menu bar item develop_loc of menu bar 1
repeat until tab group 1 of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1 exists
delay 0.1
end repeat
tell group 1 of tab group 1 of splitter group 1 of window 1
-- class of UI elements --> {group}
tell group 1
-- class of UI elements --> {scroll area}
tell scroll area 1
-- class of UI elements --> {UI element}
tell UI element 1
-- class of UI elements --> {group, toolbar, tab, group, group, group, group, group}
tell tab group 1
-- class of UI elements --> {group, radio button, radio button, radio button, radio button, radio button, radio button, radio button, radio button, radio button, radio button, radio button}
-- name of radio buttons --> {"ĂlĂ©ments", "RĂ©seau", "DĂ©bogueur", "Ressources", "Chronologies", "Stockage", "Canvas", "Audit", "Console", missing value, missing value}
click radio button 1 -- reset the 'standard' behavior
end tell
tell group 2
-- class of UI elements --> {group, group}
tell group 2
-- class of UI elements --> {group, group, group}
tell group 2
-- class of UI elements --> {static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text, static text}
-- name of static text 1 --> "<"
tell static text 1 to perform action "AXShowMenu"
end tell
end tell
end tell
end tell
end tell
end tell
-- name of menu items of menu 1 --> {"Ajouter", "Modifier", "Copier", "Supprimer", "Activer/DĂ©sactiver la visibilitĂ©", missing value, "Pseudo-classes forcĂ©es", missing value, "SâarrĂȘter", missing value, "Consigner lâĂ©lĂ©ment", "Capturer lâaperçu", "Faire dĂ©filer dans la prĂ©sentation", missing value, "Tout dĂ©velopper", "Tout condenser"}
click menu item captureScreenshot_loc of menu 1
end tell
repeat until exists sheet 1 of window 1
delay 0.1
end repeat
keystroke "g" using {command down, shift down} -- to define the storage folder
repeat until exists sheet 1 of sheet 1 of window 1
delay 0.02
end repeat
tell sheet 1 of sheet 1 of window 1
# CAUTION. before 10.11 the target field was a text field. Now it's a combo box
-- class of UI elements
--> {static text, text field, button, button} -- with 10.10 and older systems
--> {static text, combo box, button, button} -- 10.11, 10.12, 10.13, 10.14, 10.15
if exists combo box 1 then
set value of combo box 1 to posixScreenshotsFolder
else
set value of text field 1 to posixScreenshotsFolder
end if
-- name of buttons (*Aller, Annuler*)
keystroke return # ditto click button 1 (ou Aller)
end tell
click button save_loc of sheet 1 of window 1
click menu item hideWebInspector_loc of menu 1 of menu bar item develop_loc of menu bar 1
end tell
#=====
on getResourceFile:path2resources fromTable:jsName
set thisLocale to current application's NSLocale's currentLocale()
set langX to thisLocale's localeIdentifier as text --> "fr_FR"
set lang2 to text 1 thru 2 of langX
if langX starts with "zh_Hans" then # "zh-Hans"
set path2lproj to path2resources & "zh_CN.lproj"
else if langX starts with "zh_Hant" then # "zh-Hant"
set path2lproj to path2resources & "zh_TW.lproj"
else if langX starts with "pt_PT" then -- "pt_PT"
set path2lproj to path2resources & "pt_PT.lproj"
else if langX starts with "pt_BR" then -- "pt_BR"
set path2lproj to path2resources & "pt_BR.lproj"
else if lang2 is in {"ar", "ca", "cs", "da", "el", "fi", "he", "hr", "hu", "id", "ko", "ms", "pl", "pt", "ro", "ru", "sk", "sv", "th", "tr", "uk", "vi"} then
set path2lproj to path2resources & lang2 & ".lproj"
else if lang2 is "de" then # {"de", "de-AT", "de-CH"}
set path2lproj to path2resources & "German.lproj"
else if lang2 is "en" then # {"en", "en_AU", "en_CA", "en_GB", "en_US"}
set path2lproj to path2resources & "English.lproj"
else if lang2 is "es" then # {"es", "es_419", "es_ES", "es_MX"}
set path2lproj to path2resources & "Spanish.lproj"
else if lang2 is "fr" then # {"fr_FR", "fr_CA", "fr_CH"}
tell application "System Events"
if exists folder (path2resources & "French.lproj") then
set path2lproj to path2resources & "French.lproj"
else
set path2lproj to path2resources & "fr.lproj"
end if
end tell
else if lang2 is "it" then
set path2lproj to path2resources & "Italian.lproj"
else if lang2 is "ja" then
set path2lproj to path2resources & "Japanese.lproj"
else if lang2 is "nb" then
set path2lproj to path2resources & "no.lproj"
else if lang2 is "nl" then # {"nl", "nl_BE"}
set path2lproj to path2resources & "Dutch.lproj"
end if
return (path2lproj & ":" & jsName) as «class furl»
end getResourceFile:fromTable:
#=====
on localize:the_Key storedIn:theFile
try
set itsText to read theFile as «class utf8»
on error
set itsText to read theFile as «class ut16»
end try
set theDelim to "localizedStrings[" & quote & the_Key & quote & "] = " & quote
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, theDelim}
set l to text items of itsText
set AppleScript's text item delimiters to oTIDs
set key_loc to paragraph 1 of (item 2 of l)
set key_loc to text 1 thru -3 of key_loc
return key_loc
end localize:storedIn:
#=====
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 8 mars 2020 21:56:14
To test I edited your code as :
(*
Elements window open, text is highlight, execute this.
*)
tell application "System Events" to tell application process "Safari"
set frontmost to true
tell window 1
tell splitter group 1
tell tab group 1
tell group 1
tell group 1
tell scroll area 1
tell UI element 1
perform action "AXShowMenu"
-- get the name of every attribute
end tell
end tell
end tell
tell menu 1 to click (first menu item whose name starts with "Capture")
end tell
end tell
end tell
end tell
end tell
I did that because the index of the wanted menu item may change according to the visited Web page.
With MacScripter itâs -5. With macForEver itâs -3.
With the edited version, according to the area where I clicked before opening the Web Inspector I may get two behaviors.
(1) the Capture menu item appears and the save sheet is displayed.
(2) I get an error saying that the menu item of menu 1 isnât available.
I really donât know how to get a clean behavior.
I will just edited the script so that it become able to localize the infamous menu item.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 9 mars 2020 16:11:09