This is the twelfth edition of the XUL/XBL Replacement Newsletter. Since the last edition, we’ve Custom-Element’ified XUL trees, removed a complex XBL platform feature, and removed a bunch of bindings.
XUL <tree>
elements are used for rendering important parts of Firefox, like the Places UI. They are implemented partly in C++ and partly in JS. Though similar functionality and performance can now be achieved in JS alone, the full migration away from this element is a big project that relies on a number of moving parts. Victor Porof has put together a more detailed document outlining the state of things here.
Because of this, we decided it would be helpful to migrate the JS portion of XUL trees out of XBL and into Custom Elements to unblock the XBL removal project. This was after already having removed bindings for child elements over the last few months (including tree-base
, treecols
, treecol-base
, treecol
, treecol-image
, columnpicker
, treerows
, and treebody
).
One challenge with this element was that it was using XBL <children />
slotting that was hard to work around with light DOM alone. We’d tried to use Shadow DOM on other XBL migrations in the past, but struggled to make it work because we can’t nest a XBL element with <children />
inside of a Shadow DOM <slot />
. This means we can only use Shadow DOM if we know there’s never XBL slotted into the element, which is hard to guarantee in the general case. Luckily, <tree>
has a templated structure, we’ve de-XBL’ed its children, and instrumented the code at runtime to ensure no unsupported elements are inserted. So this means that <tree>
is the now first consumer of Shadow DOM in our chrome Custom Elements.
The migrated source can be seen in the MozTree class in tree.js and the MozPlacesTree class in places-tree.js.
XBL had a feature which allowed a binding to override the node name of an element. For example, if there was a <tab>
element that had <binding display="xul:button">
attached to it, then the element would pretend to be a <button>
.This was done by adding the [display="xul:element"]
attribute, and also the [extends="xul:element"]
syntax which (confusingly) did mostly the same thing.
This feature didn’t have an equivalent in the Web platform, was applied inconsistently inside Gecko, and wasn’t well understood. So Emilio Cobos Álvarez filed bug 1450652 to track the work required to remove it.
Over time, we’ve either removed the bindings using this feature or removed the need for it within the binding. Usually this meant wiring up the proper CSS frame based on the real node name rather than the one defined in XBL, but there were lots of small mysteries to figure out for individual bindings along the way. Last week, Emilio removed the final consumer and also removed the platform implementation.
There are 55 bindings left, compared to 78 from the last update and 300 from the start of the project. Here’s a list of changes:
browser-search-autocomplete-result-popup
binding by converting it to a Custom Element. This also removed dependencies on the autocomplete-rich-result-popup
and urlbar-rich-result-popup
bindings, so they can now be deleted when QuantumBar ships.wizardpage
binding by converting it to a Custom Element.checkbox
binding by converting it to a Custom Element.text-link
binding by converting it to a Custom Element that extends the label
element with [is]
.handler
binding by converting it to a Custom Element that extends the richlistitem
element with [is]
.autocomplete-richlistitem
and autocomplete-richlistitem-insecure-field
bindings by converting them to Custom Elements that extend the richlistitem
element with [is]
.autocomplete-profile-listitem-base
, autocomplete-profile-listitem
, autocomplete-profile-listitem-footer
, autocomplete-creditcard-insecure-field
, and autocomplete-profile-listitem-clear-button
bindings by converting them to Custom Elements that extend the richlistitem
element with [is]
.textarea
binding by replacing instances directly with <html:textarea>
, a pattern we are planning to follow for more xul textbox elements.toolbarbutton-dropdown
binding by implementing it in CSS.hardblockedaddon
and softblockedaddon
bindings by creating the DOM in JS from their single consumer.tree
and places-tree
bindings by converting them to Custom Elements.menucaption
binding by converting it to a Custom Element.popup-notification
and addon-progress-notification
bindings by converting them to Custom Elements.menulist
binding by converting it to a Custom Element.menulist-popuponly
binding by converting it to a Custom Element.