Files
sousa-gecko/browser/components/tabnotes/CanonicalURLChild.sys.mjs
T
Stephen Thompson 645ccfc92d Bug 2008036 Part 2 - start/stop tab notes cleanly on pref change r=dwalker,tabbrowser-reviewers
The TabNotesController and TabNotes machinery currently assumes that `browser.tabs.notes.enabled` is either enabled or disabled during a user's entire session.

This patch does a few things:
1. instead of just relying on the category manager to govern the life cycle for TabNotesController, that class also reacts to changes in the tab notes pref
2. since the TabNotesController depends on the CanonicalURL actor being ready after enabling the tab notes pref, the communication chain is pref -> DesktopActorRegistry -> TabNotesController instead of pref -> TabNotesController.
3. When turned on while the browser is running, we connect to TabNotes storage and ask all open tabs to parse for their canonical URLs. When turned off while the browser is running, we disconnect from TabNotes storage and clear all canonical URL/tab notes state on all tabs.

Differential Revision: https://phabricator.services.mozilla.com/D279983
2026-02-13 18:21:14 +00:00

76 lines
2.3 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
cleanNoncanonicalUrl:
"moz-src:///browser/components/tabnotes/CanonicalURL.sys.mjs",
findCandidates: "moz-src:///browser/components/tabnotes/CanonicalURL.sys.mjs",
pickCanonicalUrl:
"moz-src:///browser/components/tabnotes/CanonicalURL.sys.mjs",
});
/**
* Identifies the canonical URL in a top-level content frame, if possible,
* and notifies the parent process about it.
*/
export class CanonicalURLChild extends JSWindowActorChild {
/**
* @param {Event} event
*/
handleEvent(event) {
switch (event.type) {
case "DOMContentLoaded":
case "pageshow":
this.#discoverCanonicalUrl();
break;
case "popstate":
/**
* `document` does not fully reflect the new state of the page when
* `popstate` is emitted. An immediate timeout is enough for some,
* but not all, web sites to update their documents.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event#the_history_stack
*/
this.contentWindow.setTimeout(() => this.#discoverCanonicalUrl(), 0);
break;
}
}
/**
* Called when a message is received from the parent process.
*
* @param {ReceiveMessageArgument} msg
*/
receiveMessage(msg) {
switch (msg.name) {
case "CanonicalURL:Detect":
this.#discoverCanonicalUrl();
break;
case "CanonicalURL:DetectFromPushState":
this.sendAsyncMessage("CanonicalURL:Identified", {
canonicalUrl: lazy.cleanNoncanonicalUrl(msg.data.pushStateUrl),
canonicalUrlSources: ["pushState"],
});
break;
}
}
/**
* Find a canonical URL in the document and tell the parent about it.
*/
#discoverCanonicalUrl() {
const candidates = lazy.findCandidates(this.document);
const canonicalUrl = lazy.pickCanonicalUrl(candidates);
const canonicalUrlSources = Object.keys(candidates).filter(
candidate => candidates[candidate]
);
this.sendAsyncMessage("CanonicalURL:Identified", {
canonicalUrl,
canonicalUrlSources,
});
}
}