Search code examples
javascriptxmlfirefoxfirefox-addonopensearch

Firefox says could not download the search plugin from


Backstory:
I'm trying to dynamically generate an OpenSearch search plugin for Firefox based on user entered values as part of a larger add-on. I'm not including the forms and cruft surrounding it, because I've narrowed it down to a simple failing test case trying to import any XML.

Code:
Simplified JS

var browserSearchService = Components
        .classes["@mozilla.org/browser/search-service;1"]
        .getService(Components.interfaces.nsIBrowserSearchService);

var EngineProperties = {
                xml :   'http://localhost/search.xml',
                dataType: 3,
                iconURL : 'http://localhost/logo.png',
                confirm : false,
                callback : function addEngineCallback(){
                    console.log('Jason is the greatest');           
                }
            }

browserSearchService.addEngine( EngineProperties.xml,
                                            EngineProperties.dataType,
                                            EngineProperties.iconURL,
                                            EngineProperties.confirm,
                                            EngineProperties.callback);

Actual XML

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
                       xmlns:moz="http://www.mozilla.org/2006/browser/search/">
  <ShortName>Jason</ShortName>
  <Description>Powered By Jason</Description>
  <InputEncoding>UTF-8</InputEncoding>
  <Image width="16" height="16" type="image/x-icon">http://localhost/logo.png</Image>

  <URL method="get" type="text/html" template="http://search.mywebsearch.com/mywebsearch/GGmain.jhtml?ptb=100000487&amp;ind=1406730191685&amp;n=14787A74345&amp;st=bar&amp;searchfor={searchTerms}" />
  <URL method="get" type="application/x-moz-keywordsearch" 
    template="http://search.mywebsearch.com/mywebsearch/GGmain.jhtml?&amp;ptb=100000487&amp;ind=1406730191685&amp;n=14787A74345&amp;st=bar&amp;searchfor={searchTerms}" />
  <Url method="get" type="application/x-suggestions+json" 
    template="http://ssmsp.ask.com/query?q={searchTerms}&amp;li=ff&amp;sstype=prefix"/>

  <moz:SearchForm>http://search.mywebsearch.com/mywebsearch/GGmain.jhtml</moz:SearchForm>
</OpenSearchDescription>

(From the Mycroft Project)

From what I've seen the error should indicate an invalid XML file, but for the life of me I can't find anything wrong with this. I've loaded it in Firefox fixed all the typos and syntactical errors I found (used to have & instead of &amp;, and the browser displays and parses it fine, but yet it won't load as an open search search engine.

Does FF not support localhost, maybe? I'm drawing a blank here.

Thanks in advance for any insight!


Solution

  • Problems:
    As indicated by Noitidart, dataType should be 1 even though it's opensearch.

    Second, cannot pass the iconURL in addEngine. Not sure if that's true for all icons, but definitely passing it a png or a data URI both failed.

    Third, callback needs to be an object of the form:

    callback={
        onError   : function(err){/**/},
        onSuccess : function(err){/**/}
    }
    

    Fourth the filetype should be .osdx, not .xml

    URL to url to Url does not matter, never changed and extension working.

    Lastly, when testing, ensure that you have browser.search.log set to true in about:config.

    You can see more info at the bug report here.

    Hope this helps the next guy stuck in Components.classes["@mozilla.org/browser/search-service;1"].getService(Components.interfaces.nsIBrowserSearchService).addEngine()-land.

    Update: Setting confirm to true results in:

    [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)
    [nsIURI.host]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  
    location: "JS frame :: resource://gre/components/nsSearchService.js :: 
    SRCH_SVC_confirmAddEngine :: line 1370"  
    data: no]
    

    So, don't do that.

    It's nice how that API is so easily accessible. :|