Created AppleScript (markdown)

Cameron Kaiser 2019-02-18 05:34:19 +00:00
parent 6461564387
commit 13572c0510

147
AppleScript.md Normal file

@ -0,0 +1,147 @@
# AppleScript examples
**AppleScript support is experimental and may change in future versions of TenFourFox.**
TenFourFox FPR13 and later can be controlled via AppleScript. Using AppleScript, you can open and close browser windows and tabs, read selected text content for further handling, visit URLs, and access plaintext and HTML versions of their contents. If you enable GUI scripting, you can even send click and keyboard events to webpages and many TenFourFox internal widgets and interact with them programmatically. However, because of Firefox/Gecko's cross-platform nature, TenFourFox's AppleScript support uses slightly different idioms. This page assumes you have basic knowledge of AppleScript commands and concepts.
TenFourFox's AppleScript dictionary defines an **application**, which contains **windows** and **browser windows** (with a 1:1 correspondence to each other). Each browser window contains a variable number of **tabs**. The dictionary is viewable from within `Script Editor.app`.
Because window and network operations are asynchronous in TenFourFox, synchronization properties are provided to let a script know when it is safe to manipulate a property or fetch data. *Using these properties in your script is mandatory.* If you don't, at best you'll get an error, or at worst events or manipulation may go to the wrong window or tab and cause difficult-to-predict effects.
In the examples below, **substitute your TenFourFox application name for TheApp** (such as `TenFourFoxG5`).
## Example scripts
In the Event Log tab of `Script Editor`, this script shows every tab in every browser window, including its title (the `name` property) and URL (the `URL` property). Note that before querying each tab, it checks a synchronization property called `busy`. `busy` returns true when the tab is opening or currently downloading data. You should not change the tab's properties while it is busy. You can *read* properties while a tab is busy, but it may not be current, so this script will wait regardless even though it isn't changing anything.
```
tell application "TheApp"
repeat with w in every browser window
repeat with t in every tab of w
repeat while (t is busy)
delay 1
end repeat
get name of t
get URL of t
end repeat
end repeat
end tell
```
This script iterates through browser window objects. In the TenFourFox object model, only browser windows (not just plain windows) contain tabs. Every browser window corresponds to a window at a 1:1 relationship, but only certain operations can be done on each one due to limitations necessary to remain compatible with Tiger.
The next example opens a new window, opens a second tab within that window, makes it active, browses to the TenFourFox main page and displays the plaintext version of it (the tab's `plaintext` property) in the Event Log tab of the `Script Editor`. It then closes the window.
Notice that after commanding the browser to create a new browser window, the script checks another synchronization property called `opening`. `opening` returns true while the window is still in the process of being initialized. You should not manipulate the new window until `opening` is false. `opening` is at the application level, not the browser window level.
```
tell application "TheApp"
activate
make new browser window
repeat while (opening)
delay 1
end repeat
tell front browser window
set t to make new tab
repeat while (t is busy)
delay 1
end repeat
set current tab to t
set URL of t to "https://www.floodgap.com/software/tenfourfox/"
repeat while (t is busy)
delay 1
end repeat
get plaintext of t
close
end tell
end tell
```
The `plaintext` property returns the formatted plaintext of the rendered contents of that tab. If you want the actual HTML contents of the tab, then read the `HTML` property.
The `close` command has special powers: even if multiple tabs are open and you have the TenFourFox preference set to warn you if you are closing a window with multiple tabs, it will still close instantly from within a script. We do assume, after all, that you know what you're doing.
The next example opens a New York city traffic webcam image (the westbound Long Island Expressway) in a new browser, makes the window fullscreen, and reloads it every 15 seconds. Since the current tab is assumed, you can use the shorthand to set the URL shown here. We don't care about the contents of the tab, so we can just reload when the timer is up.
```
tell application "TheApp"
activate
make new browser window
repeat while (opening)
delay 1
end repeat
tell front browser window
set fullscreen to true
set URL to "https://511ny.org/map/Cctv/428834--20"
repeat
delay 15
reload current tab
end repeat
end tell
end tell
```
To stop this script, Alt-Tab to the Script Editor and click Stop, then return to TenFourFox and press Command-W to close the window.
## GUI scripting
When GUI scripting is enabled (make sure `Enable access for assistive devices` is checked in `System Preferences` and/or check `Enable GUI Scripting` in `AppleScript Utility.app`), you can manipulate some TenFourFox widgets and send clicks and keyboard events to the application. There is one irregularity in that the `System Events` target is `TenFourFox` always, not the filename of the actual browser (don't change that in these examples, just TheApp as before).
For example, this script will open the Downloads window. Note that the menu manipulation is just generically sent to `TenFourFox`, no matter what the name of the browser application is.
```
tell application "TheApp"
activate
end tell
tell application "System Events"
tell process "TenFourFox"
tell menu bar 1
tell menu bar item "Tools"
tell menu "Tools"
click menu item "Downloads"
end tell
end tell
end tell
end tell
end tell
```
Any click is forwarded to the application or underlying web page. However, since click events are global, you need a predictable location so you know what to click on. You can do that by enabling fullscreen mode as above, or you can move the window to a predicted location like this:
```
tell application "TheApp"
activate
make new browser window
repeat while (opening)
delay 1
end repeat
tell front window
set s to bounds
set the bounds to {0, 22, (item 3 of s) - (item 1 of s), (item 4 of s) - (item 2 of s)}
end tell
end tell
tell application "System Events"
tell process "TenFourFox"
click at {300, 100}
end tell
end tell
```
Notice that we create a new *browser window*, but it's the underlying *window* itself that we move by changing the bounds. Alternatively, now that we have the bounds coordinates, you could simply recalculate the click's coordinates instead.
## Don't do these things
Browser window indexes are by Z-order, not the order they were opened. You should avoid holding references to windows, especially ones you just made (e.g., "`set w to make new browser window`" will cause problems, because AppleScript will cache the incompletely built window), and you should avoid referring to them by index. For best results, simply say `front browser window` and you'll be guaranted to get the one in front.
Tabs can be referred to by index, but the index may change when the tab is closed, so you should avoid holding references to them as well. For example, don't do this:
```
(* this acts weird *)
repeat with t in every tab of front browser window
close
end repeat
```
You'd do better simply closing the front browser window, which will close all tabs at once and is more efficient anyway. In a like fashion, because the browser window indexes are variable, trying to do a `repeat with w in every browser window` followed by `close` to close all browser windows will probably cause an error.
AppleScript is currently a feature in development and may change in future versions.