With the upcoming Nightingale 1.12 release, we will be introducing the first changes to our API. Don’t worry, as they should not break the majority of our add-ons. These changes are a result of our decision to upgrade to a completely unpatched, vanilla XULRunner 1.9.2.28 — thus removing some additional patches by POTI. The patch with the most impact affects search engines. If you aren’t an add-on developer, you may not want to read on, since this post is mainly an informative post about the changes I made.

Songbird offered tags for search engines, allowing developers to make a search engine request be handled by a component (also known as “internal search engine”), firing a search event on every keyup (also known as “live search”). In order to read the songbird:livesearch and songbird:internal tag, POTI modified parts of XULRunner. With that patch gone, we had to rethink the way you can register internal search engines. In the new approach you have to register an internal search engine with a component. You can also specify, whether it should be in livesearch mode or not.
The component has the contractID @getnightingale.com/Nightingale/internal-search-service;1 and implements the ngIInternalSearchEnginesService interface. The interface defines three methods:

The boolean liveSearch specifies whether or not livesearch should be enabled for this engine. The method returns true if the registration was successful. False is returned if the engine is already registered or doesn’t exist. If the engine was hidden when it got registered, it will be shown.

unregisterInternalSearchEngine(AString searchEngineName)

If the engine was hidden, before it was registered, it will be hidden again.

getInternalSearchEngine(AString searchEngineName)

Returns an object with three attributes: liveSearch, contractID and wasHidden. liveSearch and wasHidden are both booleans, while contractID represents the string passed while registering the engine.

Registering a search engine with the name “Song Search” with enabled live search would look like the following code:

The component handling the internal search request still has to implement sbISearchEngine. The contractID needs to have the following format now: @songbirdnest.com/Songbird/[issContractID];1. [issContractID] is the contractID argument earlier passed to registerInternalSearchEngine().

While this new API would allow an add-on to hijack any search engine, I don’t think it is a big issue. It allows more flexibility, in my opinion. For example, an Amazon store integration could now check if there already is an Amazon mp3 search engine and if not, add its own. In any case you would only have one Amazon mp3 search engine in the end, and it would always lead to the native Amazon store integration.

Registering internal search engines is not the only thing that changed. Songbird, thus respectively, Nightingale, allows you to define a specific default search engine for a node with the searchtype attribute. While this previously had to contain a string which would be but between songbird- and -search and then used as alias for the search engine, you now simply define your search engine’s name. Please note though, that “internal” is still reserved for the library search. You can register a search engine with the name “internal”, but it will be ignored by the searchtype attribute.