Adapt to Changes in Thunderbird 61-68
This document tries to cover all the changes that may by needed to make add-ons compatible with Thunderbird 68. If you find stuff that is no longer working but is not yet on this list, check our communication channels.
The changes are grouped by category and are listed in the order we became aware of them.
Removed global Variables
A bunch of global variables available in some window scopes were removed. If you have used any of these, there are still available as the same names underneath Components.interfaces.
main window
nsMsgFolderFlags
message composition window
nsIMsgCompDeliverMode
nsIMsgCompSendFormat
nsIMsgCompConvertible
nsIMsgCompType
nsIMsgCompFormat
nsIAbPreferMailFormat
nsIPlaintextEditorMail
nsISupportsString
mozISpellCheckingEngine
Removed XBL bindings
XBL is on death row. Many XBL bindings have been replaced or simply no longer exist. The remainder are being removed. This may result in slight behavior changes for some UI components.
With this query, you can see all the bugs related to de-XBL-ing Thunderbird, and see how the removal of each binding is handled.
If you have your own XBL bindings, you can convert them to custom elements. Here are some notes on the process of converting an XBL binding into a custom element.
As part of the de-XBL effort, the usage of the nsIDOMDocumentXBL Interface has also been deprecated. This includes:
getAnonymousElementByAttribute()
getAnonymousNodes()
They have to be replaced by document.getElementById(), document.querySelectorAll() or similar methods. The documents these methods have been used with have probably changed dramatically. Check out searchfox.org to learn about the current layouts.
Removed XUL elements
Some XUL elements (or some of their attributes) no longer exist and must be replaced by an HTML element or some other XUL element. It does not matter, if you use these elements in a XUL file (as in overlay extensions) or create them via JavaScript (as in bootstrapped extensions).
In order to use HTML elements in a XUL file, you must load the HTML namespace into your overlay or dialog:
The following list also includes deprecated elements, which could still be used but Thunderbird has already started to purge their usage. In that case you must update your overlay files which are overlaying such elements, otherwise your overlay will not be applied. Check SearchFox for the current state of the files you are overlaying.
The replacements listed here might work in subtly different ways. Check your functionality!
<colorpicker>
Removed. Use
<progressmeter>
Removed. Use
<listbox>, <listitem>, <listcell> and <listcols>
All <listbox>
related elements have been removed. Use instead. A <richlistbox>
does not support cells or columns, just one <richlistitem>
per row (which can contain multiple other elements like hbox
, vbox
, label
or image
elements)
Furthermore, a few dedicated listbox/richtlistbox
methods have been removed and can be replaced as follows:
listbox.appendItem(label, value)
:
listbox.insertItemAt(index, label, value)
:
listbox.removeItemAt(index)
:
<textbox multiline="true">
Removed. Use
<prefwindow>, <prefpane>, <preferences> and <preference>
All preference related XUL elements have been removed. If you have something like this in your add-on:
it must be replaced by a dialog
as follows:
Note that the DOCTYPE
changed and the preference
attribute now contains the full ID of the preference. If you used more than one prefpane
you need to rework the UI into tabs.
Furthermore, note the included JavaScript file preferencesBindings.js at the bottom, which is mandatory to recreate the functionality of the preference
attribute. It is also mandatory, that you include a custom JavaScript file (aspreferences.js
in the above example) afterwards, which defines the types of the used preferences (which was formerly done inside the preferences
tag). The file can be as short as this:
Per default, all preferences will be saved instantly after they have been changed. If you want to postpone saving until the user clicks the OK button, add a type
attribute and a cancel button to the dialog:
If you are doing or plan to do any advanced stuff with the preferences in JavaScript, like validating user entered values and such, it is recommended to abandon the usage of the preference
attribute (and preferencesBindings.js
) and directly use the preferences service instead.
<stringbundleset> and <stringbundle>
Both elements have been removed. To load and access your own string property files, include the following in your JavaScript:
<statusbar> and <statusbarpanel>
Both elements are deprecated and its usage in Thunderbird is removed. They can be replaced by hbox
elements with an appropriate class
identifier:
You may actually use other elements besides hbox
as a replacement for the statusbarpanel
, like label
or image
.
<menulist editable="true">
The XUL element menulist
no longer supports the editable
attribute. However, editable menulists have been re-implemented as custom elements. To be able to use it, you need some extra files to be linked from your document:
An editable menulist can also be created via JavaScript:
<menulist> and <menupopup>
Even though the menupopup
element is defined as a direct child of the menulist
element in the above example, it cannot be accessed by
anymore. You may assign its own ID to the menupop
element, or get it by
You may use the inspector of the developer tools to see the full DOM structure of the menulist
element.
<groupbox> and <caption>
These two do not display as before. You now need to include the following css file:
While the groupbox
tag continues to work, the caption
tag has been removed. Use the following now:
In the current Thunderbird 68 Beta, this still looks a bit wrong, but will be fixed in Beta 3. More details can be found in bug 1559964.
<datepicker> and <timepicker>
Removed. Currently there is no working replacement part of Thunderbird itself, but Lightning has its own datetimepicker
, which can be used.
Its value is a JavaScript Date
object:
To be able to use the datetimepicker
, the following CSS files need to be included:
The following JavaScript files also need to be included:
If you do not want to be dependent on Lightning being installed, you need to include the above files with your add-on.
<notificationbox>
Removed. Thunderbird now has fixed build in notification boxes, where notifications can be added. The following list shows how to access some of them:
Main window:
let notifyBox = specialTabs.msgNotificationBar;
Message composer window:
let notifyBox = gNotification.notificationbox;
Below the recipient list in the message composer window:
let notifyBox = gMessageNotificationBar.msgNotificationBar;
Most calendar dialogs:
let notifyBox = gNotification.notificationbox;
Since you no longer "own" notification boxes, you should not clear them by calling
notifyBox.removeAllNotifications();
as that would remove notifications added by others. You can get a specific notification by calling
let notification = notifyBox.getNotificationWithValue(value);
and remove only that via
notificationbox.removeNotification(notification);
You can still add notification boxes wherever you want, if you do not want to use the build in notification boxes (or if there is none). More details can be found here.
<textbox type="search">
Removed. Use:
Renamed XUL elements
<mail-multi-emailHeaderField>
The element mail-multi-emailHeaderField
has been renamed into mail-multi-emailheaderfield
(no camelCase anymore).
See e.g. https://searchfox.org/comm-esr68/source/mail/base/content/msgHdrView.inc.xul#282
Changed XUL elements
<treecol>
Each treecol
can be either shown or hidden via the column picker. Up to TB68 the column picker closed after a column had been selected/toggled. By adding closemenu="none"
to a treecol
, the column picker stays open after the display state of associated treecol
has been toggled.
Changed event behavior
<dialog> events
Previously, if you had a <dialog>
and you wanted to respond to the buttons being pressed, you’d have something like this:
The event handler would return true if the dialog should close, or false to prevent closing. This no longer works. Instead, add the event handlers in JavaScript:
To prevent closing of the dialog, call preventDefault()
. A return value is not needed.
This is valid for ondialogaccept
, ondialogextra1
, ondialogextra2
and ondialogcancel
.
<wizard> and <wizardpage> events
The section about <dialog>
events also applies to all onwizard…
events on <wizard>
, and onpage…
events on <wizardpage>
.
Changes to Geko JavaScript Engine
As JavaScript itself evolves, browser engines will change accordingly. The following changes represent changes that affect JavaScript extension developers.
String Generic Methods Deprecated
The nonstandard generic string methods have been deprecated and removed in the Geko engine and therefore Thunderbird 68+. A deprecation exception is issued if any methods are used. The updated paradigm uses String instance methods allowing for the use on any object.
Deprecated Generics Syntax:
Instance Method Replacement:
The following String methods are affected by the change:
(All other String methods use the instance paradigm already)
Changes for JavaScript modules
Renamed JavaScript modules
A number of JavaScript modules have been renamed with the .jsm
extension. Most notably:
mailServices.js
has been renamed toMailServices.jsm
. This change was originally backwards-compatible with a deprecation warning, but the changes to module importing (see below) made that pointless and the old file has now been removed completely.MailUtils.js
is nowMailUtils.jsm
.MailUtils.getFolderForUri
was renamed toMailUtils.getExistingFolder
.
Changed import of JavaScript modules
In Thunderbird 67, a major backwards-incompatible change was made to importing JavaScript modules. Where once you used any of these:
Or the two-argument variation:
You should now do this:
ChromeUtils.import
is a replacement for Components.utils.import
(which was also changed in this way). Note that no second argument is supplied. The returned object is a dictionary of only the objects listed in EXPORTED_SYMBOLS
.
Changed API
LoginManager
The function to retrieve passwords has lost its first parameter. Instead of
call it as
document.persist(id, attribute)
Removed, use:
Note: document.persist()
used the ID attribute whereas xulStore.persist()
uses the actual DOM node. More details in bug 1476678.
AddonManager
All methods of the AddonManager API now return a Promise instead of executing a callback. Instead of calling it as
you need to call it as
nsIMsgAccountManager
The defaultAccount
member can (since TB 65) have a null
value - if for some reason it doesn't have, or can't work out, the default account.
Hence you need to null-check it, and possibly handle not having an account at all (if in no other way than by an error message).
nsIStringBundleService
Removed. Use
nsIStreamListener
The onDataAvailable
method lost its context
argument. This was removed in bug 1525319 which breaks the API.
To be backward compatible you need to probe the parameters. In case the third parameter is an nsIInputStream it is the old API. If the second one is an input stream it is the new API.
nsIRequestObserver
The onStartRequest
and onStopRequest
methods also no longer have a context
argument, which could be detected in a similar way.
nsIProtocolHandler
The obsolete method newChannel
was removed and newChannel2
was renamed to newChannel
. (Bug 1528971.)
As newChannel
has been unused for a long time it should be safe to just replace the old newChannel
implementation with the newChannel2
and forward calls from newChannel2
.
nsIScriptableUnicodeConverter
The method convertFromByteArray
has been removed. The new preferred way to deal with unicode is through the TextEncoder
and TextDecoder
classes.
To convert byte arrays to different charsets, use
nsIDOMElement, nsIDOMNode and other basic DOM interfaces
Removed. Use Element
, Node
, etc. instead, which are now available in all scopes.
nsIDOMParser, nsIDOMSerializer, nsIXMLHttpRequest
These no longer need to be created by Cc[...].createInstance(Ci....)
, but simply via the new
keyword:
new DOMParser();
new XMLSerializer();
new XMLHttpRequest();
They should be available in all scopes now. If not, the following is needed:
Cu.importGlobalProperties(["DOMParser"]);
Cu.importGlobalProperties(["XMLSerializer"]);
Cu.importGlobalProperties(["XMLHttpRequest"]);
nsITreeBoxObject, nsITreeColumn, nsITreeView
Trees have changed a lot. The tree
object is now a XULTreeElement
. It has lost thetreeBoxObject
property, because the nsITreeBoxObject
has been removed. Most of its methods can now be accessed directly through the tree
object. For example:
Furthermore, nsITreeColumn
has been replaced by the TreeColumn
object. Even though their interfaces look the same, they could behave differently. Check your implementation, as this affects almost all methods of nsITreeView
.
Some noteworthy changes:
tree.getCellAt() now returns a TreeCellInfo.
If a method requires a
TreeColumn
parameter, a simple{ id: columnName }
object no longer works. Get a properTreeColumn
object viatree.columns.getNamedColumn(columnName)
.Trees no longer support selecting individual cells. The
TreeColumn
object no longer has aselectable
attribute andnsITreeView
has lost itsisSelectable()
method.
In general, check searchfox.com to see the current definitions of tree related implementations:
XPCOMUtils.generateQI()
Removed. Use
Services.io.newChannelFromURI2()
Renamed to
A long time ago newChannelFromURI2() has been added as an alternative to newChannelFromURI(), which as become deprecated by now. With ESR68 the old name is used again.
Last updated