Bug 1896837 - Only sync import widget modules after DOMContentLoaded r=reusable-components-reviewers,settings-reviewers,mconley,hjones

Co-author/investigator: Tim Giles <tgiles@mozilla.com>

Delay sychronous loading of ESM based custom elements until the
DOMContentLoaded event. With D212190--which this patch depends on--the
components that have already been used on the page will be synchronously
loaded when customElements.setElementCreationCallback is registered.

Differential Revision: https://phabricator.services.mozilla.com/D212191
This commit is contained in:
Mark Striemer 2024-06-04 23:18:01 +00:00
parent 314d144c3a
commit 61d3478f4a
3 changed files with 54 additions and 33 deletions

View file

@ -80,13 +80,7 @@
<script src="chrome://browser/content/preferences/preferences.js"/>
<script src="chrome://browser/content/preferences/extensionControlled.js"/>
<script src="chrome://browser/content/preferences/findInPage.js"/>
<script type="module" src="chrome://global/content/elements/moz-support-link.mjs"/>
<script src="chrome://browser/content/migration/migration-wizard.mjs" type="module"></script>
<script type="module" src="chrome://global/content/elements/moz-toggle.mjs"/>
<script type="module" src="chrome://global/content/elements/moz-message-bar.mjs" />
<script type="module" src="chrome://global/content/elements/moz-label.mjs"/>
<script type="module" src="chrome://global/content/elements/moz-card.mjs"></script>
<script type="module" src="chrome://global/content/elements/moz-button.mjs"></script>
<script type="module" src="chrome://browser/content/backup/backup-settings.mjs"></script>
</head>

View file

@ -113,7 +113,13 @@ 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. 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.
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.
**Note** Since [bug 1896837](https://bugzilla.mozilla.org/show_bug.cgi?id=1896837)
lazy loaded UI widgets are loaded at the DOMContentLoaded event. Please notify
the Reusable Components team if you see weirdness due to this.
You can import the component directly into `html`/`xhtml` files via a
`script` tag with `type="module"`:

View file

@ -805,37 +805,58 @@
"chrome://global/content/elements/autocomplete-input.js",
],
["editor", "chrome://global/content/elements/editor.js"],
["moz-button", "chrome://global/content/elements/moz-button.mjs"],
[
"moz-button-group",
"chrome://global/content/elements/moz-button-group.mjs",
],
["moz-card", "chrome://global/content/elements/moz-card.mjs"],
["moz-checkbox", "chrome://global/content/elements/moz-checkbox.mjs"],
["moz-fieldset", "chrome://global/content/elements/moz-fieldset.mjs"],
["moz-five-star", "chrome://global/content/elements/moz-five-star.mjs"],
[
"moz-message-bar",
"chrome://global/content/elements/moz-message-bar.mjs",
],
["moz-page-nav", "chrome://global/content/elements/moz-page-nav.mjs"],
["moz-radio", "chrome://global/content/elements/moz-radio.mjs"],
["moz-radio-group", "chrome://global/content/elements/moz-radio.mjs"],
[
"moz-support-link",
"chrome://global/content/elements/moz-support-link.mjs",
],
["moz-toggle", "chrome://global/content/elements/moz-toggle.mjs"],
]) {
customElements.setElementCreationCallback(tag, () => {
if (script.endsWith(".mjs")) {
ChromeUtils.importESModule(script, { global: "current" });
} else {
Services.scriptloader.loadSubScript(script, window);
}
Services.scriptloader.loadSubScript(script, window);
});
}
document.addEventListener(
"DOMContentLoaded",
() => {
// Only sync-import widgets once the document has loaded. If a widget is
// used before DOMContentLoaded it will be imported and upgraded when
// registering the customElements.setElementCreationCallback().
for (let [tag, script] of [
["moz-button", "chrome://global/content/elements/moz-button.mjs"],
[
"moz-button-group",
"chrome://global/content/elements/moz-button-group.mjs",
],
["moz-card", "chrome://global/content/elements/moz-card.mjs"],
["moz-checkbox", "chrome://global/content/elements/moz-checkbox.mjs"],
["moz-fieldset", "chrome://global/content/elements/moz-fieldset.mjs"],
[
"moz-five-star",
"chrome://global/content/elements/moz-five-star.mjs",
],
["moz-label", "chrome://global/content/elements/moz-label.mjs"],
[
"moz-message-bar",
"chrome://global/content/elements/moz-message-bar.mjs",
],
["moz-page-nav", "chrome://global/content/elements/moz-page-nav.mjs"],
["moz-radio", "chrome://global/content/elements/moz-radio.mjs"],
["moz-radio-group", "chrome://global/content/elements/moz-radio.mjs"],
[
"moz-support-link",
"chrome://global/content/elements/moz-support-link.mjs",
],
["moz-toggle", "chrome://global/content/elements/moz-toggle.mjs"],
]) {
if (!customElements.get(tag)) {
customElements.setElementCreationCallback(
tag,
function customElementCreationCallback() {
ChromeUtils.importESModule(script, { global: "current" });
}
);
}
}
},
{ once: true }
);
// Immediately load the following elements
for (let script of [
"chrome://global/content/elements/arrowscrollbox.js",