XUL/XBL Replacement Newsletter 7
This is the seventh edition of the XUL/XBL Replacement Newsletter. Since the last edition, we’ve gotten some tooling improvements, landed an experimental HTML browser window and removed a bunch of listbox code.
Web Components Support in DevTools
One of these features that I’d like to mention is called “Show Custom Element definition”. A badge appears next to a Custom Element in the Inspector, and when you click on that it takes you directly to your Custom Element class in the Debugger. This also works in the Browser Toolbox and can be seen on any of the Custom Elements we currently ship in the browser window. For example: search for “moz-input-box” nodes in the Inspector to try it.
This highlights some benefits to using web standard tech within the Firefox frontend. We get to use the same DevTools features that we’re shipping to web devs. And (at least in my experience) Firefox devs are quite likely to give feedback and file bugs on tools, which ends up improving those same features.
Finally, I’d like to point out that coordinating the release of a complex platform feature and tooling to go with it is hard to do. It takes a lot of planning and cooperation between the the DOM and DevTools teams. Thanks to Julian Descottes, Belén Albeza, Emilio Cobos Álvarez, Jim Blandy, and many others for making this happen.
The main browser window is currently a XUL document with (mostly) XUL elements in the DOM. We’d ultimately like to support an HTML document with (mostly) HTML elements in the DOM. That’s a long road, though. One milestone we hope to hit along the way is loading an HTML document with (mostly) XUL elements in the DOM.
Practically, this can be done by loading a browser.xhtml file with the same markup as browser.xul. This will allow us to audit and fix issues affecting top-level HTML windows without rewriting the browser window from scratch. And since we have a large suite of browser tests to track progress against, we can be pretty confident about what’s working and what’s still broken. We’ll be tracking that in the top-level HTML metabug
An experimental version of this has now landed. you can try it out by adding this to your
mk_add_options 'export MOZ_BROWSER_XHTML=1'. It’s worth calling out some of the changes we made to set thi up, so I’ve split them into two groups below.
First group: burning down XULDocument.webidl so that the browser JS doesn’t rely on XUL-specific APIs. This is now finished - see the webidl file when we started vs now. Here are some notable changes:
- Migrated all calls of
Services.xulStore.persist(bug 1476030, firefox-dev post).
document.heightfrom XULDocument (bug 1475305).
document.getElementsByAttribute[NS]from XULDocument to ParentNode, so it supports all chrome documents and elements (bug 1475342).
tooltipNodefrom XULDocument to Document (bug 1480206).
Second group: adapting the frontend to work while running inside of an HTML document. This is ongoing, here are some of the changes so far:
- Added support for XUL Custom Elements inside of chrome HTML documents (bug 1480465).
- Rewrote callers of
document.createElementin browser JS to
document.createXULElementto explicitly construct XUL elements even when the document namespace is HTML (bug 1479050).
- Updated all references to “browser.xul” to `AppConstants.BROWSER_CHROME_URL, which lets us change the URL in one place (bug 1476333, firefox-dev post).
- XUL documents drop whitespace when parsing, so we frequently refer to APIs like
node.firstChildand assume it’s an element. For that to work in HTML documents callers were rewritten as
node.firstElementChild(bug 1479125, firefox-dev post).
- Stopped using
<observer>(which only work in XUL documents) in browser.xul (bug 1479908).
Thanks to everyone who’s helped with planning, patches, and reviews so far. In particular I’d like to acknowledge Brendan Dahl and Mossop for pushing this forward.
We don’t have any
<listbox> elements in Firefox anymore. If that sounds surprising, like saying “we don’t have any buttons in Firefox anymore”, there’s a distinction to be made as we still use a lot of lists in the UI.
Previously, there were two main widgets to choose from when rendering a list in chrome:
<richlistbox>. Richlistbox is more powerful and more “webby”, and over the course of time most of the UI was updated to use it. Listbox relied on custom layout code to guarantee that the height of a list was a multiple of the height of a row, and handle scrolling differently. This can be useful, but it just wasn’t required for the remaining consumers.
Since only a few
<listbox> elements were left, it was a pretty easy decision to remove it and unify on a single list widget. Being able to support just
richlistbox lets us focus effort on it and makes it easier to decide what to use when adding new UI. It also allowed us to delete around 3K lines of platform code and 2K lines of frontend code.
Finally, it’s worth mentioning that the
<tree> element is implemented similarly to
<listbox>, but with more features. This element is on our radar for replacement in the coming year, but it will be more work because we have many instances of trees in Firefox and those UIs are more complex and performance sensitive than listboxes.
There are 161 bindings left, compared to 176 from the last update and 300 from the start of the project. Here’s a list of changes:
- I migrated the
editorbinding to a Custom Element, with help from Mossop who made it so we can extend XULFrameElement with Custom Elements, which will come in handy for converting the
- I migrated the
input-box-spellto Custom Elements. These are part of the anonymous content used to build XUL
- I removed the
tabbrowser-tabpanelsbinding along with the
tabbrowser-remove-browserbindings by moving the logic directly into tabbrowser.
- Paolo removed the
tab-basebinding by loading the stylesheet into children bindings directly.
- Paolo removed
<listbox>, as referenced above. This allowed us to remove a bunch of bindings:
listhead(bug 1476611, bug 1474258, bug 1472555).