Programmatically add search engines to firefox
firefox ?? Comments Sat 07 June 2014 Chris PerivolaropoulosWhat we are doing here is adding a search engine to firefox like real men ie programmatically. This is nice because you can then write scripts to do interesting stuff with them. First of all let's see what we can find out without looking at code.
(py)fakedrake@monolith ~/.mozilla/firefox/gsz5q06m.default $ find -name "*search*"
./search-metadata.json
./search.json
./searchplugins
search.json has some general info about the engines and seems to be pointing firefox to searchplugins/ for more details.
(py)fakedrake@monolith ~/.mozilla/firefox/gsz5q06m.default $ ls searchplugins
duckduckgo.xml imdb.xml spotify1.xml youtube.xml
Right what I was looking for. Let's take a look inside one of them
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<os:ShortName>DuckDuckGo</os:ShortName>
<os:Description>Search DuckDuckGo</os:Description>
<os:InputEncoding>UTF-8</os:InputEncoding>
<os:Image width="16" height="16">data:image/x-icon;base64,AAABAAMAEBAAAA[...]</os:Image>
<os:Url type="text/html" method="GET" template="https://duckduckgo.com/">
<os:Param name="q" value="{searchTerms}"/>
</os:Url><os:Url type="application/x-suggestions+json" method="GET" template="https://duckduckgo.com/ac/">
<os:Param name="q" value="{searchTerms}"/>
<os:Param name="type" value="list"/>
</os:Url>
</SearchPlugin>
Awesome, now lets see what interfaces we can get to loading this code. We will need access to the search service, so
var bss = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService)
Now to me at least the documentation was not extremely obvious so I had to check out the implementation which I encourage you to take a look at but it wont be really necessary. After snooping around a bit I came up with.
bss.addEngine("file:///home/fakedrake/Projects/Javascript/spotify.xml", Ci.nsISearchEngine.DATA_XML, null, null)
Where the contents of spotify.xml are
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<os:ShortName>Spotify</os:ShortName>
<os:Description>Search Spotify</os:Description>
<os:InputEncoding>UTF-8</os:InputEncoding>
<os:Url type="text/html" method="GET" template="https://play.spotify.com/search/{searchTerms}"/>
</SearchPlugin>
And to my delight vimperator recognizes my custom spotify search engine!
And not only that, but firefox was kind enough to add my xml to the right place so it is permanent.
(py)fakedrake@monolith ~/.mozilla/firefox/gsz5q06m.default/searchplugins $ ls
duckduckgo.xml imdb.xml spotify.xml youtube.xml
Now if you need more direct control over this. An equivalent to the above would be:
bss.addEngineWithDetails("Spotify",null, "spotify", "Search spotify", "GET", "https://play.spotify.com/search/{searchTerms}")
Note: this wont work if the aliases of the search engines conflict like they do here.
This does exactly the same thing as having the data in an XML file and
loading it with addEngine()
. If you want to remove an engine you
can do it with:
bss.removeEngine(bss.getEngineByAlias("spotify"))
There's more you can do with the browser search service but I think I would just be repeating the documentation from now on, I hope this is a good example to get you started.
Tags: firefox javascript