As of this writing, Nightingale ships with two default views: a simple traditional playlist view, and a second playlist view incorporating three filter panes across the top for choosing a subset of your music. Views can be extended via extensions that implement Media Pages. Developers can easily create new views as HTML pages or XUL pages which provide custom visual interfaces to Nightingale libraries, and playlists.
When a media page is loaded, it is passed the current MediaListView. This object is controlled by the page. Media pages are registered in an install.rdf file to work with media lists that have certain properties. For example, a media page can be set to support all media lists (the default), to target only media lists with a certain customtype (for example, “download”), or even to target a media list with a given GUID.
Certain other operations will call methods on the sbIMediaPage interface, such as dropping a selection onto a media page, attempting to highlight the current track, or initiating playback. Most media pages will include a <sb-playlist/> object which should be passed any calls you do not handle specially. The default media page created by the extension wizard will do this by default.
As usual, the Nightingale Developer Tools Add-on greatly simplifies the process for developers. Using the Extension Wizard (accessed via the Tools menu under Create Extension…), you can create the skeleton/framework for your media page quickly and easily. The Extension Wizard takes care of setting up your install.rdf media page registration, and creating the basic “Hello World” media page.
When creating a new media page, you must add a
<mediaPage> block to the install.rdf for that extension. It must include a
<contentTitle/> and a
<contentUrl/> which define the title shown in the menu and the document to load. It may optionally also include any number of
Because some media pages may be specific to certain kinds of playlists, you may provide any number of
<match/> elements to target particular kinds of lists. You can target “type”, “customtype” or any SBProperty of the MediaList within the view.
Match any “simple” media list:
Match only the downloads list:
Match simple media lists which have a custom property added by your extension:
Because media pages can come from many sources, we have provided a mechanism to allow extension developers to specify that a particular MediaList would like to “opt out” of the generic media lists and only support custom media lists specially targetting them.
We have specified that any
<mediaPage> rule which has no match rules, or any match rule which only targets the “type” property of a media list can be excluded by setting the “onlyCustomMediaPages” property of the list to true.
The example uses a mediaList with these properties: mediaList.type == “simple” && mediaList.customtype == “downloads”
|(none provided)||false||matches||matches all|
|(none provided)||true||does not match (opt-outable rule)||opted out|
|type:simple||true||does not match (opt-outable rule)||opted out|
|customtype:download||true||matches (not opt-outable)||same customtype|
|type:simple ; customtype:other||true/false||no match||does not match customtype|
If there are multiple
<match/> rules, any rule which completely matches the list will cause the page to appear in the menu for that item.
Media pages can be implemented in either XUL or HTML. The easier method, and the one covered here, is implementing them via XUL. At its core, a media page is as simple as the following (as excerpted from the standard media-page.xul generated by the Extension Wizard)
The above media page is a simple recreation of the standard playlist view. You can see it defines a
<page/> element of windowtype
Songbird:MediaPage, and adds onload & onunload handlers to call the media page registration.
The media page should also define a
window.mediaPage object which implements the sbIMediaPage interface. The above XUL implements this in the
media-page.js file. The three methods the media page should implement are
onDrop() which implement the behaviour the media page should take when items are highlighted or dropped.
highlightItem() is called when the item should be highlighted, e.g. when the user clicks on the playing track in the faceplate to jump the playlist to the currently playing track.
canDrop() is called when something is dragged on top of the tabbrowser tab (note this is the tab selector underneath the web navigation bar)
onDrop() is called when something is actually dropped onto the tabbrowser tab.
The following code is the media-page.js file referenced above: