XUL/XBL Replacement Newsletter 6

This is the sixth edition of the XUL/XBL Replacement Newsletter. A quick note before starting: in addition to the ongoing XBL work, there’s been notable progress on other XUL projects. All of this work is interrelated enough that I think it makes sense to talk about it together, so I’ve updated the title to reflect that.

Since the last update we’ve shipped the first few Custom Elements in browser chrome, added better support for top-level HTML documents, and taken a decision on how to handle XBL stylesheets.

Custom Elements

I’m happy to say that we’ve now shipped the first Custom Elements in browser chrome, which is the culmination of a lot of effort from the XBL and DOM teams. So, how does it work? Whenever a new chrome document gets created in the main process, we load a script called customElements.js which defines a base JS class (MozXULElement) and ultimately calls customElements.define for each element that we’ve implemented.

We are using normal web-exposed Custom Element APIs, with two chrome-only additions:

  1. We added a new setElementCreationCallback function, so we can wait to load scripts until the specified tag name is encountered. This will be especially important for elements that aren’t created in the startup path and take some time to load and parse (for instance, the findbar).
  2. The Custom Element spec only allows one element per tag name for “autonomous” elements, although it does allow customizing a few built-in elements. After discussing how to deal with tags that have multiple XBL bindings attached, we realized we needed more flexibility to ease migration and avoid rewriting major parts of the frontend. So we ported the “customized built-in” capability to XUL, while treating every XUL tag name as a “built-in”. This allows us to have different Custom Elements defined for <textbox>, <textbox is="number"> and <textbox is="search">, for example.

Top Level HTML Support

When you open the Browser Console window, it now directly loads an HTML document. We used to first open a XUL wrapper document that would iframe the HTML document in order to support things like like window management, context menus, and tooltips. These features are now supported directly in top-level chrome HTML documents. This work is being continued in order to support the main browser window as HTML, and can be tracked in this metabug.

XBL stylesheets

As Paolo explains in the XBL Replacement Newsletter Special Edition, we’ve taken a decision on how to migrate XBL stylesheets to standard document sheets. This will likely be spread out over two releases to give us time to fix any resulting regressions. The first set of work has landed, changing the sheets that were previously migrated as UA sheets to document sheets in widgets.css.


There are 176 bindings left, compared to 196 from the last update and 300 from the start of the project. Here’s a list of changes:

XBL Replacement Newsletter 5

This is the fifth edition of the XBL Replacement Newsletter. Since the last update we’ve moved below 200 bindings, so we’ve removed just over one third of the bindings. We’ve also been making progress on in-content bindings and doing some cleanup that’s been enabled by the work so far. The easiest way to follow along with this work is to watch the main meta bug.

In Content XBL

Stopping use of XBL in the content process will be a big milestone for the project, and it’ll let us remove a lot of complexity that exists to make these elements secure. We’ve come up with an outline for how to replace in-content bindings that require DOM/JS in the content process: the basic idea is to use a “User Agent” Shadow DOM that’s only accessible to chrome code and to run the JS in a new limited privileged scope. You can see a more detailed proposal on the bug.

In addition to this, we’ve been making progress on removing and simplifying the current in-content bindings:

  • We no longer use XBL for scrollbars! Tim removed the scrollbar binding, and we instead build up native anonymous content to render them. This unblocks further improvements such as using a single element instead of a full DOM tree for scrollbars.
  • The “resizer” is the little grippy icon that shows up on the corner of textareas to let you resize them. Tim removed the resizer binding and we now use native anonymous content instead.
  • touchControls and suppressChangeEvent were separate bindings for mobile that extended the videocontrols binding. Tim removed them and now we now share a single binding with different styling for mobile.
  • XML pretty printing used to require JS to expand and collapse tags. Ian Moody changed this by rendering the tree with HTML <details> and <summary> tags instead. We still use a XBL binding to mount the content into the page, but there’s a bug on file to stop doing that.


  • There was a feature called NODE_FORCE_XBL_BINDINGS that would eagerly attach XBL to a cloned node even before it was added to the DOM. We no longer rely on that feature, so it was removed.
  • We no longer load xul.css in content documents. This used to get loaded when we rendered touchControls, among other things. We still load minimal-xul.css in all content documents, but there’s a new metabug tracking removal of in-content xul to ratchet this down.
  • We’ve been removing nsIDOMXUL* stuff, which also aligns with :bz’s work to remove nsIDOM* stuff. We removed nsIDOMXULTreeElement, nsIDOMXULTextBoxElement, and everything but one attribute from nsIDOMXULCheckboxElement.
  • Neil simplified the XBL implementation of popups by allowing nsXULElement to be subclassed and then using a subclass for menupopup, popup, panel, and tooltip elements.
  • There have been some nice cleanups to the gBrowser object since migrating away from XBL. Dão did a bunch of refactoring, which can be seen in bugs inside the ‘Blocks’ field of the JS migration bug. We also saw a tabpaint perf win when deleting the tabbrowser binding.

Binding Removals

There are 196 more bindings left, compared to 215 from the last update and 300 from the start of the project. Here’s a list of changes:

XBL Replacement Newsletter 4

This is the fourth edition of the XBL Replacement Newsletter. Since the last update we’ve continued to remove bindings and have been making progress on accessibility, autocomplete widgets, and migrating XBL to JS. The easiest way to follow along with this work is to watch the main meta bug.

Accessibility No Longer Relies on XBL

We moved all of the remaining [role] attributes out of XBL and into the accessibility platform code. This work can be seen in Bug 1428930 and blockers. This is a big milestone since we will now be able to migrate any binding to a Custom Element and maintain accessibility. Also, we were able to delete the XBL accessibility platform integration and eliminate a few more bindings that were only used to attach roles to elements.

Autocomplete and Trees

We used to have two separate implementations of the “autocomplete” popup, which is used for combo boxes and for text input fields with an attached drop-down. The older implementation was based on the <tree> element, and in the past few years we’ve been replacing more and more of its uses with the new implementation based on the <richlistbox> element, to overcome the styling and layout limitations of <tree>.

It turned out that the separate search bar in the toolbar was the only instance that still depended on the intricacies of the <tree> version, and once that was fixed we could convert all the other autocomplete popups to use the <richlistbox> version, and remove the bindings that implemented a customized <tree> for this use case.

Tabbrowser XBL to JS Migration

Our largest binding (tabbrowser) was translated into a JS class using the converter script plus manual fixups. Thanks to the reviewers in that bug for sticking with it, and to Potch for upgrading his xmlom package to include XML comments. I’m hoping this same approach can apply to other large bindings, like <browser>.

Binding Removals

There are 215 more bindings left, compared to 240 from the last update and 300 from the start of the project. Here are the list of changes:

XBL Replacement Newsletter 3

This is the third edition of the XBL Replacement Newsletter. Since the last update, we’ve removed 27 bindings and have been preparing to migrate bindings to Custom Elements.

Just a reminder that easiest way to follow along with the work is to follow the main meta bug. If you’d like to help, we are tagging bugs that are unblocked and ready to be worked on with xbl-available.

Custom Elements

Custom Elements have been enabled in Nightly by default, which is a big step towards being able to use them in the browser chrome. Mossop has landed initial Custom Element support for XUL elements, and we have a couple of follow-ups on file before we can start using them. We are also working to find the best way to include Custom Element scripts (bug 1411707) and styles (bug 1420229) in XUL documents.

Accessibility Roles

One of the features that XBL provides is a way to assign a ‘role’ to elements that have a particular binding attached. For example: <binding id="toolbar" role="xul:toolbar"> will attach the XULToolbarAccessible class to all toolbar elements with that binding attached.

We needed to come up with a new solution to continue supporting the accessibility roles, and initial work for that landed in bug 1403231 when we removed the image binding. This created a new XULMap.h file in which tag names get mapped to roles. The current implementation won’t handle every case, like when bindings are attached using more complex CSS selectors, but Paolo has done a thorough analysis of which bindings we can migrate right away.

Binding Removals

There are 240 more bindings left, down from 300 at the start of the project. We’ve also started to put a dent in the number of lines of code, passing below 90%. Here’s a list of the changes:

XBL Replacement Newsletter 2

This is the second edition of the XBL Replacement Newsletter. Since the last update, we’ve continued to remove unused or unnecessary bindings and improved tooling to make it easier to keep track of the work and to help find candidates for removal.

Just a reminder that easiest way to follow along with the work is to follow the main meta bug. If you’d like to help by removing a binding, I’ve added a whiteboard tag [xbl-available] to mark bugs that are unblocked and have instructions in them. The list is a bit short for now but I expect that more bindings will fit that description over time, especially once Custom Element support is ready.

Binding Removals

There are 267 more bindings left, compared to 289 from the last update and 300 from the start of the project.

  • Mossop removed the inline options feature that was only used by legacy add-ons, and as a result the mobile/ directory is the first top level directory to go down to zero bindings! Here’s the list of bindings removed by this change: setting-base, setting-bool, setting-boolint, setting-localized-bool, setting-integer, setting-control, setting-string, setting-color, setting-path, setting-multi, setting-fulltoggle-bool, setting-fulltoggle-boolint, setting-fulltoggle-localized-bool, android-checkbox-with-spacing.
  • New contributor 86ecce74 removed the searchbar-treebody binding by migrating the behavior into an attribute on the autocomplete-treebody binding.
  • 86ecce74 also removed the control-item binding by moving the one property it defined onto its three child bindings.
  • Paolo has merged together the panelmultiview and photonpanelmultiview bindings. This required doing some post-photon cleanup first, like updating the site identity panel to use the new photon style.
  • Paolo also removed the download-toolbarbutton binding by allowing child content inside the toolbarbutton-badged binding that it was extending.
  • I removed the menucaption-inmenulist binding by moving its implementation into the menucaption binding. It turns out that the only place we use menucaptions are for <optgroup>s, and they always were being bound to the inmenulist variation of the binding.
  • I also removed three unused statusbarpanel related bindings. Some followup work to that is going to be removing the statusbar and statusbarpanel bindings.
  • I also removed the menuseparator binding by moving the accessibility role detection into C++ and loading the CSS via global.css instead of through <resources>. This surfaced an issue in which we are relying on what appears to be non-standard behavior of stylesheets loaded by XBL, in which the application order of selectors is different. There’s still some discussion to be had about how to handle this situation, but moving to the standard behavior and improving tooling to detect potential issues before landing seems pretty reasonable.

Improved Tooling

Here are some noteworthy improvements to the tools and website since the last update:

  • The bug number and the “type” of each removal get printed on the timeline. To make that easier, I’ve started a spreadsheet to track which bindings are being removed in which bugs, and which type of removal they are.
  • There are new graphs looking at the # of bindings per directory and LOC per directory
  • The tree includes links to search m-c for each binding which makes it easier to find out where a binding is used
  • Binding usage data is now being gathered in Nightly builds in taskcluster as the “browser-instrumentation” job. Thanks to Joel Maher and his team for making it easy to gather this data with activedata and taskcluster artifacts.