25

I'm curious if AppleScript can access each specific tab in a browser and execute some javascript in them.

Anyone have ideas?

studgeek
  • 14,272
  • 6
  • 84
  • 96
Allan
  • 2,586
  • 5
  • 26
  • 22
  • I know safari can execute javascript commands and you have access to the tabs in a window. My guess would be that you can't do this in other browsers because most of them are not apple-scriptable. – regulus6633 Feb 27 '11 at 21:28

4 Answers4

46

For Google Chrome, use execute from AppleScript Chromium Suite:

execute v : Execute a piece of javascript.

execute specifier : The tab to execute the command in.

javascript text : The javascript code to execute.

Example:

tell application "Google Chrome"
    execute front window's active tab javascript "alert('example');"
end tell

Can be done in Safari either:

tell application "Safari" to do JavaScript "alert('example')" in document 1

For other browsers, check the functions at File -> Open Dictionary on AppleScript editor.

Community
  • 1
  • 1
Fábio Perez
  • 23,850
  • 22
  • 76
  • 100
  • Very helpful. It's a shame bookmarks can't do this. A small tip: put this as a here document for testing: `cat < – Sridhar Sarnobat Jul 12 '18 at 01:08
  • 6
    Note: As of August 2018, you may need to navigate to _View_ → _Developer_ → _Allow JavaScript from Apple Events_ for `execute javascript` to work. [More info here.](https://sites.google.com/a/chromium.org/dev/developers/applescript?visit_id=1-636693438565536471-746766917&p=applescript&rd=1) – rubik's sphere Aug 08 '18 at 17:02
1

The function below runs JavaScript in each tab of the frontmost window in Chrome and concatenates the output. To run JavaScript in in all windows, replace window 1 with windows.

xjss(){ osascript -e'on run {a}
    set o to ""
    tell app "Google Chrome" to repeat with t in (get tabs of window 1)
        tell t to set o to o & (execute JavaScript a) & linefeed
    end
end' -- "$1"; }

This runs JavaScript in only the frontmost tab:

xjs(){ osascript -e'on run {a}
    tell app "Google Chrome" to tell active tab of window 1 to execute JavaScript a
end' -- "$1"; }

Here are similar functions for Safari:

sjss(){ osascript -e'on run {a}
    set o to ""
    tell app "Safari" to repeat with t in (get tabs of window 1)
        tell t to set o to o & (do JavaScript a) & linefeed
    end
end' -- "$1"; }

sjs(){ osascript -e'on run {a}
    tell app "Safari" to tell document 1 to do JavaScript a
end' -- "$1"; }

Since some version of Chrome released in 2018, an error like this is shown by default when running an execute JavaScript command:

78:98: execution error: Google Chrome got an error: Executing JavaScript through AppleScript is turned off. To turn it on, from the menu bar, go to View > Developer > Allow JavaScript from Apple Events. For more information: https://support.google.com/chrome/?p=applescript (12)

Safari has a similar preference in "Develop > Allow JavaScript from Apple Events" which was turned off by default in macOS version 10.11.5 (released in 2016-05-16).

nisetama
  • 7,764
  • 1
  • 34
  • 21
0

Recently Google Chrome disabled the ability to execute JavaScript via AppleScript. I'm having trouble finding a reference link, but in Chrome Canary v59 it doesn't work and gives a message saying it's disabled, and I'm seeing it still work in Chrome v57 so it's got to be very new.

Evan Lovely
  • 103
  • 1
  • 7
0

You can also paste some Javascript in the console, I got this working for Firefox.

property P_JAVA_SCRIPT : "/Users/username/Desktop/myscript.js"
tell application "Firefox"
    activate
    tell application "System Events" to tell process "Firefox"
        set the clipboard to (read P_JAVA_SCRIPT)
        keystroke "k" using {command down, option down} -- open console
        delay 1
        keystroke "v" using {command down} -- paste clipboard           
        keystroke return
        delay 3
        keystroke "i" using {command down, option down} -- close dev tools
    end tell
end tell

It get's a whole lot trickier if you want to get the return value from the Javascript back in!

In my case I used this before closing the dev tools: set returnString to value of static text 1 of group 2 of group 2 of group 1 of group 1 of group 1 of UI element 1 of scroll area 1 of group 1 of group 1 of UI element 1 of scroll area 2 of group 1 of group 1 of group 1 of window 1

I used UI Browser.app for that, which is unfortunately no longer maintained.

FFish
  • 10,964
  • 34
  • 95
  • 136