How to (kind of) use AppleScript with Firefox and make useful Firefox Touch Bar widgets/buttons

If you, like me, like to create Touch Bar widgets/buttons and use Firefox as your preferred browser, you probably came to realize by now that Firefox, unlike Safari or Chrome, unfortunately, is not scriptable with AppleScript. Here are a few workarounds I have found:

  • Keyboard shortcuts
  • Conditional activation groups (CAGs)
  • CAGs with URLs
  • Basic AppleScript scripting
  • AX scripting

You probably already know about at least the first two, but for completeness I wanted to include them too.

Note: You will need some basic AppleScript knowledge to make use of most of what I write here, sorry! Also, I wrote these scripts a while back and don't use all of them anymore. Some of them might not work anymore exactly like I share them here, or there might even be some small mistakes in the code. Therefore, please consider this more as an inspiration for your own scripting than a 100% accurate tutorial :slight_smile:

Keyboard shortcuts

In BTT you can assign the action "send keyboard shortcut" to any type of button/widget/trigger. Firefox offers many keyboard shortcuts, you can look them up [here](https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly). By assigning these shortcuts to buttons, you can, for example, create a Touch Bar setup like this:

Here I have created buttons for back, forward, show/hide bookmarks sidebar, reload page, focus adress bar, create new tab, undo close tab, open developer tools.

Conditional activation groups (CAG)

In the bottom left corner of the BTT window, you can click on the plus and select "create conditional activation group". This allows you to set triggers that activate only if specific conditions apply. This can be used to create buttons that appear e. g. only when browsing a specific website. Example: To create a CAG that activates when you are watching a YouTube video in Firefox, set the condidtions to:

All of the following are true:
App Name is "Firefox"
Window Name ends with "- Youtube"

Now you can create buttons for YouTube that trigger keyboard shortcuts, e. g. "f" for fullscreen toggle, "k" for play/pause, "shift + n" for next video. See all YouTube Shortcuts here.

CAG: create conditions for URLs

In this example we have the problem that pages like the trending page Trends - YouTube also have a window title that ends with "- YouTube" and we can't distinguish these from the site where we watch a video. Similarly, as another example, when we try to create a CAG that activates when watching a movie on Netflix, we can't distinguish the site where we watch a video www.netflix.com/watch/xyz from the main Netflix site Netflix because the window title is always just "Netflix".

So what we would need is a CAG condition like "URL contains ...". Unfortunately, this is not possible. It is also not possible to get the current URL from Firefox via AppleScript. But there is a smooth workaround: There are addons for Firefox which put the current URL in the tab/window title. I would highly recommend this one, as it has two advantages over similar addons:

  1. It only puts the URL in the window title, not in the tab title, so you don't see it in your tab bar in Firefox.
  2. At least for me, it works faster/more reliable.

Make sure that in the KeePass settings, at least Hostname and Path are activated.

If you have an addon like this installed, you can make a YouTube-video-CAG with these conditions:

All of the following are true:
App Name is "Firefox"
Window Name contains "YouTube"

Or a Netflix-video-CAG with these conditions:

All of the following are true:
App Name is "Firefox"
Window Name contains "Von Netflix unterstützte Geräte | Netflix auf Ihrem Smartphone, Fernseher oder Lieblingsgerät genießen"

Netflix also offers a few keyboard shortcuts you can use for buttons.

Basic AppleScript scripting

You can look up the AppleScript commands/elements/etc. that an app supports if you open the script editor app and then under "File", choose "Open Dictionary...". There you will see that Firefox does actually support some very basic AppleScript scripting ("Standard Suite"). Mainly, you can get some properties from Firefox windows. Here is a script that gets most of these properties from the currently active window and returns them:
if application "Firefox" is running then
	try
		tell application "Firefox"
			set bounds1 to (bounds of front window) as text
			set floating1 to (floating of front window) as text
			set id1 to (id of front window) as text
			set index1 to (index of front window) as text
			set miniaturizable1 to (miniaturizable of front window) as text
			set modal1 to (modal of front window) as text
			set name1 to (name of front window) as text
			set resizable1 to (resizable of front window) as text
			set titled1 to (titled of front window) as text
			set visible1 to (visible of front window) as text
			set zoomable1 to (zoomable of front window) as text
			set zoomed1 to (zoomed of front window) as text
			return "bounds: " & bounds1 & "   floating: " & floating1 & "   id: " & id1 & "   index: " & index1 & "   miniaturizable: " & miniaturizable1 & "   modal: " & modal1 & "   resizable: " & resizable1 & "   titled: " & titled1 & "   visible: " & visible1 & "   zoomable: " & zoomable1 & "   zoomed: " & zoomed1 & "
name: " & name1
		end tell
	end try
end if

For example, "bounds" returns data about the size of the window and "name" returns the window title. Most of these properties don't seem to be very useful though.

One thing that you can do is to show the current windwo title, or parts of it, like the title of the currently playing YouTube Video, in the Touch Bar. But actually, this can be done in another way, which I think is a little better. This brings us to my last part:

AX Scripting

You can get some of the properties of the current content of the screen with ApplScript if you use the Accessbility (AX) service. Here is a script that gets most of these properties from the currently active window and returns them:
tell application "System Events"
	tell process "Firefox"
		set axfocused to value of attribute "AXFocused" of window 1
		set axfullscreen to value of attribute "AXFullscreen" of window 1
		set axtitle to value of attribute "AXTitle" of window 1
		set axchildreninnavigationorder to value of attribute "AXChildrenInNavigationOrder" of window 1
		set axposition to value of attribute "AXPosition" of window 1
		set axgrowarea to value of attribute "AXGrowArea" of window 1
		set axdocument to value of attribute "AXDocument" of window 1
		set axmain to value of attribute "AXMain" of window 1
		set axproxy to value of attribute "AXProxy" of window 1
		set axdefaultbutton to value of attribute "AXDefaultButton" of window 1
		set axminimized to value of attribute "AXMinimized" of window 1
		set axcancelbutton to value of attribute "AXCancelButton" of window 1
		set axmodal to value of attribute "AXModal" of window 1
		set axsize to value of attribute "AXSize" of window 1
		set axtoolbarbutton to value of attribute "AXToolbarButton" of window 1
		set axframe to value of attribute "AXFrame" of window 1
		
		return "AX: Focused: " & axfocused & "; Fullscreen: " & axfullscreen & "; Title: " & axtitle & "; ChInNavOrd: " & axchildreninnavigationorder & "; Position: " & axposition & "; GrowArea: " & axgrowarea & "; Document: " & axdocument & "; Main: " & axmain & "
Proxy: " & axproxy & "; DefaultButton: " & axdefaultbutton & "; Minimized: " & axminimized & "; CancelButton: " & axcancelbutton & "; Modal: " & axmodal & "; Size: " & axsize & "; ToolbarButton: " & axtoolbarbutton & "; Frame: " & axframe
	end tell
end tell

I have found two ways to make use of these properties.

  1. With the AXFullscreen attribute, you can make a button which enters and exits fullscreen while it shows you whether the current app is currently in fullscreen mode. This does not only work for Firefox, but (at least for me) for almost all apps. You can use the foolowing code:
try
	tell application "System Events" to tell (process 1 where frontmost is true)
		if (value of attribute "AXFocused" of window 1) is true then
			return (value of attribute "AXFullScreen" of window 1)
		end if
	end tell
end try

then for alternate color regex, use true/false and set corresponding icons.

  1. With the AXTitle attribute, you can show the current window title in the Touch Bar. For example, you can show the title of the currently playing YouTube video with the following code:
try
	tell application "System Events" to tell process "Firefox"
		if (value of attribute "AXFocused" of window 1) is true then
		return text 25 thru -11 of ((value of attribute "AXTitle" of window 1) as text)
		end if
	end tell
end try

The "text 25 thru -11" part applies if you use the addon I recommended above, with the same settings as me (show hostname and path). This might be a little different for you.

Now, you might have noticed that in the last two scripts I put "if (value of attribute "AXFocused" of window 1) is true then ...". To be honest, I don't quite recall why exactly I put this in the code (I wrote it a while back). It somehow worked better this way. If you want, try it without this part and see if it makes a difference.

If you find other use cases for some of the attributes you can get via the Standard Suite (basic AppleScript scripting) or via AX Scripting, please feel free to share them in this thread!

Conclusion

I hope you got some ideas or inspiration from this post that you can use to make some triggers for Firefox. If you come up with other possibilities that I have not covered, please share them in this thread :slight_smile:

And again, not everything in this tutorial might be 100% accurate. If you have trouble implementing some of the stuff, feel free to ask here and I will try to look into it if I have the time.