LogoLogo
  • About Thunderbird
  • Contributing to Thunderbird
    • Getting Started Contributing
    • Setting Up A Build Environment
    • Building Thunderbird
      • Windows Build Prerequisites
      • Linux Build Prerequisites
      • macOS Build Prerequisites
      • Artifact Builds
    • Codebase Overview
      • Account Configuration
      • Address Book
      • Chat Core
        • Notifications
        • Message Styles
        • Keyboard shortcuts
        • Chat Core Protocols
        • Contacts
      • Mail Front-End
    • Tutorials and Examples
      • Hello World Example
      • Thunderbird Live Development Videos
    • Fixing a Bug
      • Bug Triaging 101
        • Bug Status Classicification
        • Bug Types
        • Garbage Collection
        • Narrow the Scope
      • Using Mercurial Bookmarks
      • Using Mercurial Queues
      • Lint and Format Code
      • Using ESLint to Format Javascript Code
      • Try Server
      • Landing a Patch
      • Care and Feeding of the Tree
    • Testing
      • Running Tests
      • Adding Tests
      • Writing Mochitest Tests
  • Planning
    • Roadmap
    • Android Roadmap
    • Supported Standards
  • Add-on Development
    • Introduction
    • What's new?
      • Manifest Version 3
    • A "Hello World" Extension Tutorial
      • Using WebExtension APIs
      • Using a Background Page
      • Using Content Scripts
    • A Guide to Extensions
      • Supported Manifest Keys
      • Supported UI Elements
      • Supported WebExtension APIs
      • Thunderbird's WebExtension API Documentation
      • Thunderbird WebExtension Examples
      • Introducing Experiments
    • A Guide to Themes
    • Developer Community
    • Documentation & Resources
      • Tips and Tricks
    • Add-on Update Guides
      • Update for Thunderbird 128
      • Update for Thunderbird 115
        • Adapt to Changes in Thunderbird 103-115
      • Update for Thunderbird 102
        • Adapt to Changes in Thunderbird 92-102
      • Update for Thunderbird 91
        • Adapt to Changes in Thunderbird 79-91
      • Update for Thunderbird 78
        • Adapt to Changes in Thunderbird 69-78
      • Update for Thunderbird 68
        • Adapt to Changes in Thunderbird 61-68
      • How to convert legacy extensions?
        • Convert wrapped WebExtensions to modern WebExtensions
        • Convert legacy WebExtensions to modern WebExtensions
        • Convert legacy overlay extension to legacy WebExtension
        • Convert legacy bootstrapped extension to legacy WebExtension
  • Releases
    • Thunderbird Channels
    • Release Cadence
    • Uplifting Fixes
    • Feature Flags
    • Tracking Fixes for Releases
    • Contributing to Release Notes
Powered by GitBook
On this page
  • Changed XUL elements
  • <textbox>
  • <toolbar customizable="true">
  • <wizard>
  • <wizardpage>
  • <richlistbox>
  • Changed API
  • document.createElement()
  • nsISocketTransportService
  • nsICookie2
  • window.QueryInterface()
  • Services.scriptSecurityManager.createCodebasePrincipal()
  • nsIStringBundle.formatStringFromName()
  • IOUtils.js
  • AddRecipient()
  • MailServices.headerParser.parseHeadersWithArray()
  • nsIPromptService.select()
  • nsIEditorStyleSheets has been removed
  • getAnonymousElementByAttribute() and getAnonymousNodes() have been removed
  • Changes to the Address Book
  • Searching a nsIAbDirectory
  • Changes to the Preference System
  • Removal of onsyncfrompreference and onsynctopreference Attributes

Was this helpful?

Edit on GitHub
Export as PDF
  1. Add-on Development
  2. Add-on Update Guides
  3. Update for Thunderbird 78

Adapt to Changes in Thunderbird 69-78

PreviousUpdate for Thunderbird 78NextUpdate for Thunderbird 68

Last updated 7 months ago

Was this helpful?

This document tries to cover all the internal changes that may be needed to make add-ons compatible with Thunderbird 78. If you find changes which are not yet listed on this page, you can ask for help and advice in one of our .

The changes are grouped by category and are listed in the order we became aware of them.

Changed XUL elements

As of Thunderbird 74, the built-in overlay loader has been removed, which means XUL overlay files are no longer supported. The preferred way to interact with Thunderbird is through WebExtension and MailExtension APIs, which only support HTML/CSS.

However, Thunderbird itself is still using XUL for its UI, and it is still possible to interact with that XUL based UI through experimental APIs. More information can be found in the .

Since XUL is still usable, this document includes information about deprecated and removed XUL elements.

Some XUL elements have been converted to , which have an additional is="something" attribute. If such a custom element is to be created with createXULElement(), the is parameter needs to be passend in via the second argument:

let toolbar = document.createXULElement(
    "toolbar", 
    { is : "customizable-toolbar" }
);
toolbar.setAttribute("is", "customizable-toolbar");

<textbox>

Removed completely in TB71. Use

<html:input>

All former values of the type parameter of the textbox element are supported by html:input as well. For proper styling include the following CSS file: chrome://messenger/skin/input-fields.css

The flex parameter is no longer supported and should be removed. Attach the input-container class to a surrounding hbox to force the input field to behave like a former flex="1" textbox.

If the input fields context menu is not working, you need to include two JavaScript files by adding:

<script src="chrome://global/content/globalOverlay.js"/>
<script src="chrome://global/content/editMenuOverlay.js"/>

JavaScript methods that are using element.localName == "textbox" , getElementsByTagName("textbox")or similar need to be updated as well.

Visually compare the fields before and after the conversion to be sure the UI, sizing, and spacing doesn't change.

<toolbar customizable="true">

<!-- Note the additional "is" attribute: -->
<toolbar is="customizable-toolbar"
   id="event-toolbar"
	 customizable="true"   
	 toolboxid="event-toolbox"
	 class="chromeclass-toolbar"
	 labelalign="end"
	 defaultlabelalign="end"
	 context="event-dialog-toolbar-context-menu"
	 defaultset="button-url,button-delete"/>

<wizard>

In TB78, the XUL element wizard may no longer be a top level element, but must be encapsulated by a window element which includes some fluent locales:

<window 
      width="600"
      height="600"
      title="Wizard Title"
      xmlns:html="http://www.w3.org/1999/xhtml"
      xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

  <linkset>
    <html:link rel="localization" href="toolkit/global/wizard.ftl"/>
  </linkset>

  <wizard>
  ...
  </wizard>
</window>

If you have referred to the wizard element by document.documentElement.*, this is now referring to the window element. Use getElementById() instead.

<wizardpage>

If you set the label of a wizardpage element via JavaScript during wizard load, it will be ignored. You have to manually call _adjustWizardHeader after the label has been set. :

document.getElementById(wizardID)._adjustWizardHeader();

<richlistbox>

With TB78, the method scrollToIndex(idx) has been removed, replace it with:

richlistbox.ensureElementIsVisible(listbox.getItemAtIndex(idx),true);

Changed API

document.createElement()

With TB69, the default namespace for createElement has switched from XUL to HTML. So you can no longer create XUL elements with document.createElement() (but HTML elements). To create XUL elements, use:

document.createXULElement();

nsISocketTransportService

The first parameter used to be an array and the second one its length. This length parameter has been dropped, causing all subsequent arguments to shift by one. Furthermore, to create a default socket, you now have to pass an empty array as the first parameter, instead of null.

To stay backward compatible, check the argument count of "createTransport". In case it is 4 it is the new interface, in case it is 5 you got the old interface. Alternatively, you may also check if the version of Thunderbird is 69 or later.

   if (transportService.createTransport.length === 4)
      return transportService.createTransport(((secure) ? ["starttls"] : []), host, port, proxyInfo);

    if (transportService.createTransport.length === 5) {
      if (secure)
        return transportService.createTransport(["starttls"], 1, host, port, proxyInfo);

      return transportService.createTransport(null, 0, host, port, proxyInfo);
   }

   throw new Error("Unknown Create Transport signature");

nsICookie2

Merged into nsICookie.

window.QueryInterface()

With TB70, window objects don't need to be and cannot be QI'ed to nsIDOMChromeWindow, nsIDOMWindow and nsIInterfaceRequestor. You can just remove its usage, this is backwards compatible to TB 68.

This does not apply to nsIXULWindow, which for example is used in nsIWindowMediatorListener.onOpenWindow(xulWindow).

Equally, TreeColumns and TreeContentView don't need to be and cannot be QI'ed to nsITreeView.

Services.scriptSecurityManager.createCodebasePrincipal()

Renamed. Use

Services.scriptSecurityManager.createContentPrincipal()

nsIStringBundle.formatStringFromName()

IOUtils.js

Module file extension changed in TB78 from js to jsm, now available via

const { IOUtils } = ChromeUtils.import("resource:///modules/IOUtils.jsm");

AddRecipient()

In TB78 the function AddRecipient() in the contact sidebar has been renamed to awAddRecipientsArray().

MailServices.headerParser.parseHeadersWithArray()

In TB71 MailServices.headerParser.parseHeadersWithArray() has been removed. Instead, use:

let addresses = MailServices.headerParser.parseEncodedHeader(address);
for (let addr of addresses) {
  let email = addr.email
  let name = addr.name
  let fullname = addr.toString();
}

nsIPromptService.select()

nsIEditorStyleSheets has been removed

  • nsIEditorStyleSheets.addOverrideStyleSheet(uri) -> windowUtils.loadSheetUsingURIString(uri, windowUtils.AGENT_SHEET)\

  • nsIEditorStyleSheets.removeOverrideStyleSheet(uri) -> windowUtils.removeSheet(uri, windowUtils.AGENT_SHEET)\

  • nsIEditorStyleSheets.enableStyleSheet(uri, enable) Either manually load or remove the stylesheet: -> windowUtils.loadStyleSheetUsingURIString(uri, windowUtils.AGENT_SHEET) -> windowUtils.removeSheet(uri, windowUtils.AGENT_SHEET)

getAnonymousElementByAttribute() and getAnonymousNodes() have been removed

Changes to the Address Book

Searching a nsIAbDirectory

In TB68 a nsIAbDirectory could be searched by simply attaching a search query to the URI of the directory when calling getDirectory():

let cards = MailServices.ab.getDirectory(URI + "?" + searchQuery).childCards;
while (cards.hasMoreElements()) {
  let card = cards.getNext().QueryInterface(Components.interfaces.nsIAbCard);
  ...
}

In TB78 getDirectory() no longer accepts search queries and throws an error. Instead, use the search() method, which uses an nsIAbDirSearchListener. A simple promisified implementation could look like so:

searchDirectory: function (uri, search) {
  return new Promise((resolve, reject) => {
    let listener = {
      cards : [],
      onSearchFinished(aResult, aErrorMsg) {
        resolve(this.cards);
      },
      onSearchFoundCard(aCard) {
        this.cards.push(aCard.QueryInterface(Components.interfaces.nsIAbCard));
      }
    }
    MailServices.ab.getDirectory(uri).search(search, listener);
  });
}

let cards = await searchDirectory(URI, searchQuery);
for (let card of cards) {
  ...
}

MailServices.ab.getDirectory(uri).search(search, listener) will not return anything, if search is empty.

Changes to the Preference System

Removal of onsyncfrompreference and onsynctopreference Attributes

With TB70, these two attributes have been removed from XUL elements like textbox, radio, checkbox and friends. This is no longer supported:

<textbox
    id="my-textbox"
    preference="some.preference.name"
    onsynctopreference="return onToPref();"
    onsyncfrompreference="return onFromPref();"/>
Preferences.addSyncFromPrefListener(
     document.getElementById("my-textbox"),
     function() { return onFromPref() });

Preferences.addSyncToPrefListener(
     document.getElementById("my-textbox"),
     function() { return onToPref() });

In TB78, the XUL element toolbar with attribute customizable has been re-implemented as a . It needs an additional is attribute. The following example is taken from the :

Bug introduced a breaking change to the nsISocketTransportService interface:

The 3rd parameter has been dropped, which was the length of the array passed in as the 2nd parameter. See the .

Since TB69 nsIPromptService.select() / Services.prompt.select() has dropped the parameter which specifies the length of the array of the item list which the user can choose from. See the .

The in TB77 necessitates the following changes:

These two methods are leftovers from de-XBL effort and have not been working since TB68. In TB72 they have been removed completely and using them will now throw an error. They have to be replaced by , or similar methods.

The documents these methods have been used with have probably changed dramatically. Check out to learn about the current layouts.

Most of the XUL based preferences system has been long removed and had to be replaced by either using the or by manually reimplementing that functionality using thensIPrefService.

The second approach is not affected by this change, as it has full control over the load and save process for all its preferences. The has been updated and now supports:

The nsIPrefServiceis not available via WebExtension APIs. It is therefore advised to move away from storing addon preferences in a preference branch and instead use the local storage via the API. More information can be found in the .

custom element
source of the Thunderbird calendar
1558726
patch applied to Thunderbird itself
patch applied to Thunderbird itself
removal of nsIEditorStyleSheets
document.getElementById()
document.querySelectorAll()
searchfox.org
preferencesBindings.js
wrapper
preferencesBindings.js
wrapper
storage
update guide
communication channels
custom elements
update guide for Thunderbird 78