Bug 1803678 - enable lazy loading of ESModule based moz- custom elements r=reusable-components-reviewers,pip-reviewers,credential-management-reviewers,translations-reviewers,kpatenio,issammani,mstriemer

Differential Revision: https://phabricator.services.mozilla.com/D207445
This commit is contained in:
Hanna Jones
2024-04-23 19:28:47 +00:00
parent 33a3dc43a5
commit 9413513b0d
22 changed files with 49 additions and 112 deletions

View File

@@ -403,7 +403,6 @@ export const ContentAnalysis = {
},
async showPanel(element, panelUI) {
element.ownerGlobal.ensureCustomElements("moz-support-link");
await element.ownerDocument.l10n.setAttributes(
lazy.PanelMultiView.getViewNode(
element.ownerDocument,

View File

@@ -150,7 +150,6 @@ add_setup(async function () {
gLink.innerText = "gLink";
gLink.id = "gLink";
gMainView.appendChild(gLink);
await window.ensureCustomElements("moz-toggle");
gToggle = document.createElement("moz-toggle");
gToggle.label = "Test label";
gMainView.appendChild(gToggle);

View File

@@ -97,8 +97,6 @@ var DownloadsPanel = {
window.addEventListener("unload", this.onWindowUnload);
window.ensureCustomElements("moz-button-group");
// Load and resume active downloads if required. If there are downloads to
// be shown in the panel, they will be loaded asynchronously.
DownloadsCommon.initializeAllDataLinks();

View File

@@ -235,8 +235,6 @@ export class ExtensionControlledPopup {
return;
}
win.ownerGlobal.ensureCustomElements("moz-support-link");
// Find the elements we need.
let doc = win.document;
let panel = ExtensionControlledPopup._getAndMaybeCreatePanel(doc);

View File

@@ -23,8 +23,6 @@ class ScreenshotsPreview extends HTMLElement {
// we get passed the <browser> as a param via TabDialogBox.open()
this.openerBrowser = window.arguments[0];
window.ensureCustomElements("moz-button");
let [downloadKey, copyKey] =
lazy.screenshotsLocalization.formatMessagesSync([
{ id: "screenshots-component-download-key" },

View File

@@ -30,8 +30,8 @@ Please refer to the existing [UA widgets documentation](https://firefox-source-d
### How to use existing Mozilla Custom Elements
The existing Mozilla Custom Elements are automatically imported into all chrome privileged documents.
These existing elements do not need to be imported individually via `<script>` tag or by using `window.ensureCustomElements()` when in a privileged main process document.
The existing Mozilla Custom Elements are either [automatically imported](https://searchfox.org/mozilla-central/rev/d23849dd6d83edbe681d3b4828700256ea34a654/toolkit/content/customElements.js#853-878) into all chrome privileged documents, or are [lazy loaded](https://searchfox.org/mozilla-central/rev/d23849dd6d83edbe681d3b4828700256ea34a654/toolkit/content/customElements.js#789-809) and get automatically imported when first used.
In either case, these existing elements do not need to be imported individually via `<script>` tag.
As long as you are working in a chrome privileged document, you will have access to the existing Mozilla Custom Elements.
You can dynamically create one of the existing custom elements by using `document.createDocument("customElement)` or `document.createXULElement("customElement")` in the relevant JS file, or by using the custom element tag in the relevant XHTML document.
For example, `document.createXULElement("checkbox")` creates an instance of [widgets/checkbox.js](https://searchfox.org/mozilla-central/source/toolkit/content/widgets/checkbox.js) while using `<checkbox>` declares an instance in the XUL document.
@@ -74,11 +74,10 @@ Just like with the UI widgets, [the `browser_all_files_referenced.js` will fail
### Using new domain-specific widgets
This is effectively the same as [using new design system components](#using-new-design-system-components).
You will need to import your widget into the relevant `html`/`xhtml` files via a `script` tag with `type="module"`:
This is effectively the same as [using new design system components](#using-new-design-system-components). In general you should be able to rely on these elements getting lazily loaded at the time of first use, similar to how existing custom elements are imported.
Outside of chrome privileged documents you may need to import your widget into the relevant `html`/`xhtml` files via a `script` tag with `type="module"`:
```html
<script type="module" src="chrome://browser/content/<domain-directory>/<your-widget>.mjs"></script>
```
Or use `window.ensureCustomElements("<your-widget>")` as previously stated in [the using new design system components section.](#using-new-design-system-components)

View File

@@ -111,17 +111,16 @@ by updating [this array](https://searchfox.org/mozilla-central/rev/5c922d8b93b43
Once you've added a new component to `toolkit/content/widgets` and created
`chrome://` URLs via `toolkit/content/jar.mn` you should be able to start using it
throughout Firefox. You can import the component into `html`/`xhtml` files via a
throughout Firefox. In most cases, you should be able to rely on your custom element getting lazy loaded at the time of first use, provided you are working in a privileged context where `customElements.js` is available.
You can import the component directly into `html`/`xhtml` files via a
`script` tag with `type="module"`:
```html
<script type="module" src="chrome://global/content/elements/your-component-name.mjs"></script>
```
If you are unable to import the new component in html, you can use [`ensureCustomElements()` in customElements.js](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/toolkit/content/customElements.js#865) in the relevant JS file.
For example, [we use `window.ensureCustomElements("moz-button-group")` in `browser-siteProtections.js`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/browser/base/content/browser-siteProtections.js#1749).
**Note** you will need to add your new widget to [the switch in importCustomElementFromESModule](https://searchfox.org/mozilla-central/rev/85b4f7363292b272eb9b606e00de2c37a6be73f0/toolkit/content/customElements.js#845-859) for `ensureCustomElements()` to work as expected.
Once [Bug 1803810](https://bugzilla.mozilla.org/show_bug.cgi?id=1803810) lands, this process will be simplified: you won't need to use `ensureCustomElements()` and you will [add your widget to the appropriate array in customElements.js instead of the switch statement](https://searchfox.org/mozilla-central/rev/85b4f7363292b272eb9b606e00de2c37a6be73f0/toolkit/content/customElements.js#818-841).
**Note** you will need to add your new widget to [this array in customElements.js](https://searchfox.org/mozilla-central/rev/cde3d4a8d228491e8b7f1bd94c63bbe039850696/toolkit/content/customElements.js#791-810) to ensure it gets lazy loaded on creation.
## Common pitfalls

View File

@@ -1043,8 +1043,6 @@ var FullPageTranslationsPanel = new (class {
isFirstUserInteraction = null,
}
) {
await window.ensureCustomElements("moz-button-group");
const { panel, appMenuButton } = this.elements;
const openedFromAppMenu = target.id === appMenuButton.id;
const { docLangTag } = await this.#getCachedDetectedLanguages();
@@ -1109,10 +1107,6 @@ var FullPageTranslationsPanel = new (class {
return;
}
const window =
gBrowser.selectedBrowser.browsingContext.top.embedderElement.ownerGlobal;
window.ensureCustomElements("moz-support-link");
const { button } = this.buttonElements;
const { requestedTranslationPair } =

View File

@@ -393,7 +393,7 @@ var SelectTranslationsPanel = new (class {
);
}
await this.#openPopup(event, screenX, screenY);
this.#openPopup(event, screenX, screenY);
}
/**
@@ -403,10 +403,7 @@ var SelectTranslationsPanel = new (class {
* @param {number} screenX - The x-axis location of the screen at which to open the popup.
* @param {number} screenY - The y-axis location of the screen at which to open the popup.
*/
async #openPopup(event, screenX, screenY) {
await window.ensureCustomElements("moz-button-group");
await window.ensureCustomElements("moz-message-bar");
#openPopup(event, screenX, screenY) {
this.console?.log("Showing SelectTranslationsPanel");
const { panel } = this.elements;
panel.openPopupAtScreen(screenX, screenY, /* isContextMenu */ false, event);