ADR 0001 Technology Transitions
In-Progress Technology Transitions
Links
Status
Status: Accepted
Context
This ADR is a catch-all to document past decisions for technology changes we’re already working on, but haven’t completed yet. This means the code base typically has both approaches present and it is not obvious which one should be preferred.
Past records of information for these changes are collected where available, but some of these changes have been fairly informal, or simply forced by the upstream code in mozilla-central. If the change comes from mozilla-central the related execution documentation from mozilla-central is linked.
The primary purpose of this ADR is to document these pre-existing decisions.
Decision
Use Fluent for localization
The existing localization systems using DTD in XML and properties in JS are replaced with Fluent. To migrate existing strings, there’s tooling for Fluent Migrations. Fluent encourages formatting as late as possible and giving translators the freedoms required to adapt the displayed strings to fit their language. To enable this, some previous practices should be broken, including handling of placeables and reducing passing around formatted localized strings in code.
References
Transitioning XUL to (X)HTML
Whenever possible, HTML elements should be preferred over their XUL equivalents.
We also prefer documents to be (X)HTML first, and explicitly use XUL in a
namespace when needed. However, many older documents still work the other way
around. We’ve completed converting the documents themselves to be (X)HTML
documents instead of XUL documents (so with a <html>
root element).
Here a list of example XUL elements and their preferred equivalents (with namespaces for clarity):
xul:image
→html:img
xul:label
→html:span
xul:box
,xul:vbox
,xul:hbox
→html:div
xul:button
→html:button[type="button"]
xul:input
→html:input
xul:menulist
→html:select
Notably not all replacements are one to one and sometimes the XUL element might have features that can’t be replicated in HTML. In those cases, we still use the XUL element.
A special case is the xul:tree
element (and its descendants), for which we have
a custom element replacement solution.
References
Avoid XPCOM
This is a very handwavy rule, but compared to many years ago, when some of this code was written, we try to only use XPCOM when necessary. That usually means when languages need to mix, either for implementations or because we’re crossing from the native backend toward the JavaScript frontend.
References
CSS Nesting
We try to use CSS nesting to group together relates CSS rules. A lot of existing stylesheets have already been converted, but many more remain.
References
CSS Custom Properties
We use custom properties in CSS to share values, instead of hard coding them.
CSS files like colors.css
provide a bunch of “tokens” with values to use,
though sometimes we’ll still want to have another layer of custom properties to
make it easier to handle different variations for theming or states.
JS Doc
In JavaScript we try to document our functions, methods, class fields and types using inline JSDoc. The linter tries to ensure the JSDoc looks sensible - however there are some conflicts around type formatting required by tooling in our codebase. Generally we’re not consuming JSDoc with much more than the linter at this time, so as long as linting is fine, the JSDoc is probably ok.
For custom element implementations we use some additional JSDoc properties that are consumed by Storybook for documentation generation.
References
Prefer modules for front-end JavaScript
New JavaScript code should generally be placed in an ES module (.mjs) instead of a normal script file (.js). This helps us break the code into smaller, more manageable chunks and also enforces some containment, especially around globals. Modules also enforce explicit dependency declaration by users of exported features, making it easier to understand where code is used.
Custom elements help further with managing the life-cycle of front-end code by binding it to the element.
References
Content Security Policy
Most of our documents have a content security policy, enforcing primarily the sources of styles and media loaded in the document.
We currently can’t restrict JS much, since we often use inline listeners in HTML. To eventually tighten the policies new inline listeners should be avoided.
References
Use mach vendor for Third Party Dependencies and Place them in the third_party Folder
Third party code should be vendored into the third_party
directory in the root
of the repository. To help with vendoring,
mach vendor
should be used. It automates the vendoring to make it repeatable, which is
useful when vendored code needs to be updated. It can even be used to
automatically update vendored code.
References
Tabs Contain Documents
Currently, a bunch of our tabs are not their own document, but instead are part of the main window. All tabs should be their own document, so their code is only loaded when the tab is used.
To ask a tab to do something from outside the tab, “XUL” commands should be sent to the tab.
Omit a
prefix for function arguments
Older code style guidance was to prefix all arguments in JavaScript and C++
functions with a
, so an example argument name was aParam
. The prefix is
no longer wanted, so new functions should omit it, which makes the example
argument name just param
.
Prefer moz-src for JS modules
JS modules should be loaded when possible with the moz-src://
protocol, which has
a path matching the location in the source repository instead of an arbitrary
mapping. This is easier for developers and tooling alike. For now this primarily
affects modules loaded via resource://
protocol.
References
Consequences and Risks
Positive Consequences
Continuous modernization of the code base
These changes typically improve the developer experience
Potential Risks
All changes make uplifting more complicated, especially to ESR
Changes like these are hard to fully roll out
We might be too slow to adopt some of the changes from mozilla-central and have to switch target mid-transition
Alternatives
As these are already in progress, alternatives are not considered here.
Security Considerations
None.
Rollout Plan
As mentioned, all of these changes are already in-progress in the code base, mostly on a “when you touch it, improve it” basis. However, some of the changes might need more urgent updates as mozilla-central changes availability of the status quo.
This also means that some of the changes might be completed, while others are still being worked on.