ADR 0001 Technology Transitions

In-Progress Technology Transitions

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:imagehtml:img

  • xul:labelhtml:span

  • xul:box, xul:vbox, xul:hboxhtml:div

  • xul:buttonhtml:button[type="button"]

  • xul:inputhtml:input

  • xul:menulisthtml: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.