Skip to content

Commit

Permalink
Add support for other Firefox browsers. Closes #2
Browse files Browse the repository at this point in the history
Added support for Firefox Nightly and Developer Edition.

The workflow detects which browser it's connected to and opens URLs in
that browser, and activates that browser when a tab is activated.
  • Loading branch information
deanishe committed Feb 20, 2020
1 parent da8b935 commit d172585
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 86 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ Search and manipulate Firefox's bookmarks, history and tabs from Alfred.

![Animated demo of workflow in use][demo]

The workflow can be easily extended with your own actions.
The workflow can be easily [extended with your own actions][scripts].

Installation
------------

The extension supports (at least) Firefox, Firefox Nightly and Firefox Developer Edition.

1. Download and install the [latest version of the workflow][workflow].
2. Run `ffass` in Alfred and choose `Install Firefox Extension` to get [the Firefox extension][addon].


See [the setup documentation][setup] for more details.


Expand Down Expand Up @@ -61,6 +62,7 @@ It is written in [Go][go] and heavily based on the [AwGo library][awgo]. The ico
[workflow]: https://github.com/deanishe/alfred-firefox/releases/latest
[demo]: https://github.com/deanishe/alfred-firefox/blob/master/demo.gif
[docs]: https://github.com/deanishe/alfred-firefox/blob/master/doc/index.md
[scripts]: https://github.com/deanishe/alfred-firefox/blob/master/doc/scripts.md
[integration]: https://github.com/deanishe/alfred-firefox/blob/master/doc/integration.md
[usage]: https://github.com/deanishe/alfred-firefox/blob/master/doc/usage.md
[setup]: https://github.com/deanishe/alfred-firefox/blob/master/doc/setup.md
Expand Down
6 changes: 5 additions & 1 deletion actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (a tAction) Run(tabID int) error {
c := mustClient()
switch a.action {
case "activate":
_, err := util.RunAS(`tell application "Firefox" to activate`)
_, err := util.RunAS(fmt.Sprintf(`tell application "%s" to activate`, c.appName))
if err != nil {
return err
}
Expand All @@ -129,6 +129,10 @@ type uAction struct {
func (a uAction) Name() string { return a.name }
func (a uAction) Icon() *aw.Icon { return a.icon }
func (a uAction) Run(URL string) error {
c, err := newClient()
if err == nil {
os.Setenv("BROWSER", c.appName)
}
data, err := util.Run(a.script, URL)
if err != nil {
return err
Expand Down
26 changes: 13 additions & 13 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
Name: "history",
Usage: "alfred-firefox -query <query> history",
ShortHelp: "search browsing history",
LongHelp: wrap(`Search Firefox browsing history.`),
LongHelp: wrap(`Search browser history.`),
Exec: runHistory,
}

Expand All @@ -31,7 +31,7 @@ var (
Name: "downloads",
Usage: "alfred-firefox -query <query> downloads",
ShortHelp: "search downloads",
LongHelp: wrap(`Search Firefox downloads.`),
LongHelp: wrap(`Search browser downloads.`),
Exec: runDownloads,
}

Expand All @@ -40,7 +40,7 @@ var (
Name: "bookmarks",
Usage: "alfred-firefox -query <query> bookmarks",
ShortHelp: "search bookmarks",
LongHelp: wrap(`Search Firefox bookmarks.`),
LongHelp: wrap(`Search browser bookmarks.`),
Exec: runBookmarks,
}

Expand All @@ -49,7 +49,7 @@ var (
Name: "bookmarklets",
Usage: "alfred-firefox -query <query> bookmarklets",
ShortHelp: "search bookmarklets",
LongHelp: wrap(`Search Firefox bookmarklets and execute in frontmost tab.`),
LongHelp: wrap(`Search bookmarklets and execute in frontmost tab.`),
Exec: runBookmarklets,
}

Expand Down Expand Up @@ -81,8 +81,8 @@ var (
tabsCmd = &ffcli.Command{
Name: "tabs",
Usage: "alfred-firefox [-query <query>] tabs",
ShortHelp: "filter Firefox tabs",
LongHelp: wrap(`Filter Firefox tabs and perform actions on them.`),
ShortHelp: "filter browser tabs",
LongHelp: wrap(`Filter browser tabs and perform actions on them.`),
Exec: runTabs,
}

Expand Down Expand Up @@ -528,34 +528,34 @@ func runUpdate(_ []string) error {
// show workflow status and options
func runStatus(_ []string) error {
if c, err := newClient(); err != nil {
wf.NewItem("No Connection to Firefox").
wf.NewItem("No Connection to Browser").
Subtitle(err.Error()).
Icon(iconError)
} else {
if err := c.Ping(); err != nil {
wf.NewItem("No Connection to Firefox").
wf.NewItem("No Connection to Browser").
Subtitle(err.Error()).
Icon(iconError)

} else {
wf.NewItem("Connected to Firefox").
wf.NewItem("Connected to Browser").
Subtitle("Extension is installed and running")
}
}

wf.NewItem("Register Workflow with Firefox").
wf.NewItem("Register Workflow with Browser").
Subtitle("Use if you've updated or moved the workflow and it isn't working").
Autocomplete("workflow:register").
Icon(iconInstall).
Valid(false)

wf.NewItem("Install Firefox Extension").
Subtitle("Get the Firefox extension to integrate this workflow with Firefox").
wf.NewItem("Install Browser Extension").
Subtitle("Get the browser extension to integrate this workflow with Firefox").
Arg(addonURL).
Valid(true).
Icon(iconAddon).
Var("CMD", "url").
Var("ACTION", "Open in Firefox").
Var("ACTION", urlDefault).
Var("URL", addonURL)

if wf.UpdateAvailable() {
Expand Down
12 changes: 12 additions & 0 deletions doc/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Place your custom scripts in the `scripts` subdirectory of the workflow's data d
<!-- vim-markdown-toc GFM -->

* [How URL scripts work](#how-url-scripts-work)
* [Current browser](#current-browser)
* [Script icons](#script-icons)
* [Advanced scripting](#advanced-scripting)
* [Running actions](#running-actions)
Expand Down Expand Up @@ -36,6 +37,17 @@ Modifier keys (`OPT`, `CMD`, `SHIFT`, `CTRL`) can be arbitrarily combined by joi
You can quickly grab the name of a script by using `CMD+C` (copy) on an action in the `Other Actions…` list, which will copy the script's name to the clipboard.


### Current browser ###

As the workflow supports different versions of Firefox (Firefox, Firefox Nightly, Firefox Developer Edition), the name of the application it's currently connected to will be specifed in the `BROWSER` environment variable. The default `Open in Firefox.sh` script, for example, uses the command

```bash
/usr/bin/open -a "$BROWSER" "$1"
```

to open the URL in the browser the URL came from.


### Script icons ###

You can optionally assign a custom icon to a script by putting an image file with the same basename (i.e. excluding extension) in the `scripts` directory. Icons of type PNG, GIF, JPG and ICNS are supported.
Expand Down
5 changes: 4 additions & 1 deletion doc/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ Setup

Unfortunately, this workflow requires a slightly complex setup :(

Due to Firefox's preposterous lack of support for AppleScript, the workflow needs to install a browser extension to communicate with Firefox.
Due to Firefox's egregious lack of support for AppleScript, the workflow needs to install a browser extension to communicate with Firefox.

Setup is easier if you install [the workflow][workflow] first, and then the [browser extension][addon].

The extension supports (at least) Firefox, Firefox Nightly and Firefox Developer Edition, but please note that it can only connect to one browser at a time.

If you open a second Firefox, the first will be disconnected. Click on the extension icon to reconnect that browser (and disconnect others).

<!-- vim-markdown-toc GFM -->

Expand Down
67 changes: 37 additions & 30 deletions extension/alfred.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ const Tab = tab => {

tab = tab || {};

obj.id = tab.id || 0;
obj.windowId = tab.windowId || 0;
obj.index = tab.index || 0;
obj.title = tab.title || '';
obj.url = new URL(tab.url || '');
// obj.favicon = tab.favIconUrl || '';
obj.active = tab.active || false;
obj.id = tab.id || 0;
obj.windowId = tab.windowId || 0;
obj.index = tab.index || 0;
obj.title = tab.title || '';
obj.url = new URL(tab.url || '');
// obj.favicon = tab.favIconUrl || '';
obj.active = tab.active || false;

obj.toString = function() {
return `#${this.id} (${this.windowId}x${this.index}) "${this.title}" - ${this.url}`;
Expand All @@ -43,12 +43,12 @@ const Bookmark = bm => {
let obj = {};
bm = bm || {};

obj.id = bm.id || 0;
obj.index = bm.index || 0;
obj.title = bm.title || '';
obj.id = bm.id || 0;
obj.index = bm.index || 0;
obj.title = bm.title || '';
obj.parentId = bm.parentId || 0;
obj.type = bm.type || '';
obj.url = bm.url || '';
obj.type = bm.type || '';
obj.url = bm.url || '';

obj.toString = function() {
return `#${this.id} "${this.title}" - ${this.url}`;
Expand All @@ -66,8 +66,8 @@ const HistoryEntry = hi => {
let obj = {};
hi = hi || {};

obj.id = hi.id || 0;
obj.url = hi.url || '';
obj.id = hi.id || 0;
obj.url = hi.url || '';
obj.title = hi.title || hi.url;

obj.toString = function() {
Expand All @@ -86,13 +86,13 @@ const Download = di => {
let obj = {};
di = di || {};

obj.id = di.id || 0;
obj.path = di.filename || '';
obj.size = di.fileSize || 0;
obj.url = di.url || '';
obj.mime = di.mime || '';
obj.exists = di.exists || false;
obj.error = di.error || '';
obj.id = di.id || 0;
obj.path = di.filename || '';
obj.size = di.fileSize || 0;
obj.url = di.url || '';
obj.mime = di.mime || '';
obj.exists = di.exists || false;
obj.error = di.error || '';

obj.toString = function() {
return `#${this.id} "${this.path}" - ${this.url}`;
Expand All @@ -106,9 +106,10 @@ const Download = di => {
* @constructor
*/
const Background = function() {
var self = this;
const self = this;

self.port = null,
self.nativePort = null,
self.connected = false;

self.onConnected = port => {
Expand All @@ -133,19 +134,21 @@ const Background = function() {
console.debug('reconnecting to native app ...');
self.connectNative();
return;
case 'reload':
console.debug('reloading extension ...');
browser.runtime.reload();
return;
}
}
};

self.nativePort = null;

self.connectNative = () => {
self.connected = false;

let listener = payload => {
if (!self.connected) {
self.connected = true;
self.nativePort.onDisconnect.removeListener(self.connectNativeFailed);
// self.nativePort.onDisconnect.removeListener(self.connectNativeFailed);
self.onConnectedNative();
}
self.receiveNative(payload);
Expand Down Expand Up @@ -267,12 +270,16 @@ const Background = function() {
* @param {string} msg.error - Error message if command failed.
*/
self.sendNative = msg => {
try {
self.nativePort.postMessage(msg);
} catch (err) {
console.error(`send error: ${err.message}`);
if (self.nativePort) {
self.nativePort.postMessage(msg)
.then(resp => {
console.log(`sent:`, msg);
console.log(`response:`, resp);
})
.catch(err => {
console.error(`send error: ${err.message}`);
});
}
console.log(`sent:`, msg);
};

/**
Expand Down
2 changes: 1 addition & 1 deletion extension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

"manifest_version": 2,
"name": "Alfred Integration",
"version": "1.1.0",
"version": "1.1.1",
"description": "Integrates Firefox with Alfred."
}

25 changes: 25 additions & 0 deletions extension/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,31 @@ hr {
width: 100%;
}

/*
.controls {
text-align: center;
}
.controls button {
box-shadow: 1px 1px 0px 0px #efefef;
background-color: #fff;
border-radius: 5px;
border: 1px solid #ddd;
display: inline-block;
cursor: pointer;
color: #444;
font-size: .95em;
padding: 6px 30px;
text-decoration: none;
}
.controls button:active {
box-shadow: none;
position: relative;
top: 1px;
}
*/

#connected {
color: #090;
}
Expand Down
Loading

0 comments on commit d172585

Please sign in to comment.