Skip to content

Commit

Permalink
Fix more problems caused by the ESM migration
Browse files Browse the repository at this point in the history
  • Loading branch information
filips123 committed Feb 15, 2025
1 parent 63d99a9 commit e15c9d9
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 128 deletions.
131 changes: 131 additions & 0 deletions native/userchrome/profile/chrome/pwa/boot.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ import { AppConstants } from 'resource://gre/modules/AppConstants.sys.mjs';
import { NetUtil } from 'resource://gre/modules/NetUtil.sys.mjs';
import { nsContentDispatchChooser } from 'resource://gre/modules/ContentDispatchChooser.sys.mjs';
import { nsDefaultCommandLineHandler, nsBrowserContentHandler } from 'resource:///modules/BrowserContentHandler.sys.mjs';
import { BrowserGlue } from 'resource:///modules/BrowserGlue.sys.mjs';
import { BrowserWindowTracker } from 'resource:///modules/BrowserWindowTracker.sys.mjs';
import { WebProtocolHandlerRegistrar } from 'resource:///modules/WebProtocolHandlerRegistrar.sys.mjs';
import { OnboardingMessageProvider } from 'resource:///modules/asrouter/OnboardingMessageProvider.sys.mjs';

import { applySystemIntegration } from 'resource://pwa/utils/systemIntegration.sys.mjs';

const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
sendNativeMessage: 'resource://pwa/utils/nativeMessaging.sys.mjs',
sanitizeString: 'resource://pwa/utils/common.sys.mjs',
});

/**
* Reads the PWAsForFirefox config file and parses it as JSON.
*
Expand Down Expand Up @@ -117,9 +127,18 @@ Services.prefs.getDefaultBranch(null).setBoolPref('browser.sessionstore.resume_f
Services.prefs.getDefaultBranch(null).setIntPref('browser.sessionstore.max_resumed_crashes', 0);
Services.prefs.getDefaultBranch(null).setIntPref('browser.sessionstore.max_tabs_undo', 0);
Services.prefs.getDefaultBranch(null).setIntPref('browser.sessionstore.max_windows_undo', 0);
Services.prefs.getDefaultBranch(null).setBoolPref('browser.shell.checkDefaultBrowser', false);
Services.prefs.getDefaultBranch(null).setBoolPref('browser.startup.upgradeDialog.enabled', false);
Services.prefs.getDefaultBranch(null).setBoolPref('browser.privateWindowSeparation.enabled', false);
Services.prefs.getDefaultBranch(null).setBoolPref('browser.privacySegmentation.createdShortcut', true);

// Disable default browser prompt
BrowserGlue.prototype._maybeShowDefaultBrowserPrompt = async () => null;

// Disable onboarding messages
OnboardingMessageProvider.getMessages = async () => [];
OnboardingMessageProvider.getUntranslatedMessages = async () => [];

// Override command line helper to intercept PWAsForFirefox arguments and start loading the site
nsDefaultCommandLineHandler.prototype._handle = nsDefaultCommandLineHandler.prototype.handle;
nsDefaultCommandLineHandler.prototype.handle = function (cmdLine) {
Expand Down Expand Up @@ -196,6 +215,118 @@ nsContentDispatchChooser.prototype._hasProtocolHandlerPermission = function(sche
return this._hasProtocolHandlerPermissionOriginal(scheme, principal, triggeredExternally);
};

// Handle opening new window from keyboard shortcuts
BrowserWindowTracker._openWindow = BrowserWindowTracker.openWindow;
BrowserWindowTracker.openWindow = function (options) {
if (options.openerWindow && options.openerWindow.gFFPWASiteConfig && !options.args) {
options.args = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
options.args.data = options.openerWindow.HomePage.get(options.openerWindow);
}
return BrowserWindowTracker._openWindow(options);
};

// Some checks for protocol handlers are directly based on the Firefox code, licensed under MPL 2.0
// Original source: https://github.com/mozilla/gecko-dev/blob/a62618baa72cd0ba6c0a5f5fc0b1d63f2866b7c6/browser/components/protocolhandler/WebProtocolHandlerRegistrar.jsm

// Handle registering custom protocol handlers
WebProtocolHandlerRegistrar.prototype.registerProtocolHandler = function (protocol, url, title, documentURI, browserOrWindow) {
protocol = (protocol || '').toLowerCase();
if (!url || !documentURI) return;

// Some special handling for e10s and non-e10s
let browser = browserOrWindow;
if (browserOrWindow instanceof Ci.nsIDOMWindow) {
let rootDocShell = browserOrWindow.docShell.sameTypeRootTreeItem;
browser = rootDocShell.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
}

// Get the browser window
let browserWindow = browser.ownerGlobal;

// Check if protocol handler is allowed
try { browser.ownerGlobal.navigator.checkProtocolHandlerAllowed(protocol, url, documentURI) }
catch (_) { return }

// If the protocol handler is already registered, just return early
// We only allow one handler (either manifest or custom) per protocol scheme
const existingHandlers = new Set([
...browserWindow.gFFPWASiteConfig.config.custom_protocol_handlers,
...browserWindow.gFFPWASiteConfig.manifest.protocol_handlers
].map(handler => lazy.sanitizeString(handler.protocol)).filter(handler => handler).sort());
if (existingHandlers.has(protocol)) return;

// Now ask the user and provide the proper callback
const message = this._getFormattedString('addProtocolHandlerMessage', [url.host, protocol,]);

const notificationBox = browser.getTabBrowser().getNotificationBox(browser);
const notificationIcon = url.prePath + '/favicon.ico';
const notificationValue = 'Protocol Registration: ' + protocol;

const addButton = {
label: this._getString('addProtocolHandlerAddButton'),
accessKey: this._getString('addProtocolHandlerAddButtonAccesskey'),
protocolInfo: { site: browserWindow.gFFPWASiteConfig.ulid, protocol: protocol, url: url.spec },

async callback (notification, buttonInfo) {
// Send a request to the native program to register the handler
const response = await lazy.sendNativeMessage({
cmd: 'RegisterProtocolHandler',
params: {
site: buttonInfo.protocolInfo.site,
protocol: buttonInfo.protocolInfo.protocol,
url: buttonInfo.protocolInfo.url,
}
});
if (response.type === 'Error') throw new Error(response.data);
if (response.type !== 'ProtocolHandlerRegistered') throw new Error(`Received invalid response type: ${response.type}`);

// Reset the handlerInfo to ask before the next use
const eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
const handlerInfo = eps.getProtocolHandlerInfo(buttonInfo.protocolInfo.protocol);
handlerInfo.alwaysAskBeforeHandling = true;

const hs = Cc['@mozilla.org/uriloader/handler-service;1'].getService(Ci.nsIHandlerService);
hs.store(handlerInfo);

// Hide the notification
notificationBox.currentNotification.close();
},
};

notificationBox.appendNotification(
notificationValue,
{
label: message,
image: notificationIcon,
priority: notificationBox.PRIORITY_INFO_LOW
},
[addButton]
);
};

// Handle unregistering custom protocol handlers
// Disabled for now until we figure out how to access window from here
// WebProtocolHandlerRegistrar.prototype.removeProtocolHandler = function (protocol, url) {
// (async () => {
// // Send a request to the native program to unregister the handler
// const response = await lazy.sendNativeMessage({
// cmd: 'UnregisterProtocolHandler',
// params: {
// site: window.gFFPWASiteConfig.ulid,
// protocol,
// url,
// }
// });
// if (response.type === 'Error') throw new Error(response.data);
// if (response.type !== 'ProtocolHandlerUnregistered') throw new Error(`Received invalid response type: ${response.type}`);
//
// // Reset the handlerInfo to ask before the next use
// const eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
// const handlerInfo = eps.getProtocolHandlerInfo(protocol);
// handlerInfo.alwaysAskBeforeHandling = true;
// })()
// };

// Register a localization source for the packaged locales
Services.obs.addObserver(async () => {
const languages = Services.locale.packagedLocales;
Expand Down
128 changes: 0 additions & 128 deletions native/userchrome/profile/chrome/pwa/content/browser.sys.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { OnboardingMessageProvider } from 'resource:///modules/asrouter/OnboardingMessageProvider.sys.mjs';
import { WebNavigationManager } from 'resource://gre/modules/WebNavigation.sys.mjs';
import { XPCOMUtils } from 'resource://gre/modules/XPCOMUtils.sys.mjs';
import { BrowserGlue } from 'resource:///modules/BrowserGlue.sys.mjs';
import { BrowserWindowTracker } from 'resource:///modules/BrowserWindowTracker.sys.mjs';
import { WebProtocolHandlerRegistrar } from 'resource:///modules/WebProtocolHandlerRegistrar.sys.mjs';

import { sanitizeString } from 'resource://pwa/utils/common.sys.mjs';
import { hookFunction } from 'resource://pwa/utils/hookFunction.sys.mjs';
Expand All @@ -12,7 +8,6 @@ import { xPref } from 'resource://pwa/utils/xPref.sys.mjs';
const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
sendNativeMessage: 'resource://pwa/utils/nativeMessaging.sys.mjs',
applyDynamicThemeColor: 'resource://pwa/utils/systemIntegration.sys.mjs',
applySystemIntegration: 'resource://pwa/utils/systemIntegration.sys.mjs',
buildIconList: 'resource://pwa/utils/systemIntegration.sys.mjs',
Expand Down Expand Up @@ -47,7 +42,6 @@ class PwaBrowser {
this.switchPopupSides();
this.makeUrlBarReadOnly();
setTimeout(() => { this.setDisplayModeStandalone() });
this.handleRegisteringProtocols();
this.handleOutOfScopeNavigation();
this.handleOpeningNewWindow();
this.handleDisablingShortcuts();
Expand Down Expand Up @@ -368,105 +362,6 @@ class PwaBrowser {
hookCurrentBrowser();
}

handleRegisteringProtocols () {
// Overwrites original Firefox functions with our custom installation process
// Some checks here are directly based on the Firefox code, licensed under MPL 2.0
// Original source: https://github.com/mozilla/gecko-dev/blob/a62618baa72cd0ba6c0a5f5fc0b1d63f2866b7c6/browser/components/protocolhandler/WebProtocolHandlerRegistrar.jsm

WebProtocolHandlerRegistrar.prototype.registerProtocolHandler = function (protocol, url, title, documentURI, browserOrWindow) {
protocol = (protocol || '').toLowerCase();
if (!url || !documentURI) return;

// Some special handling for e10s and non-e10s
let browser = browserOrWindow;
if (browserOrWindow instanceof Ci.nsIDOMWindow) {
let rootDocShell = browserOrWindow.docShell.sameTypeRootTreeItem;
browser = rootDocShell.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
}

// Check if protocol handler is allowed
try { browser.ownerGlobal.navigator.checkProtocolHandlerAllowed(protocol, url, documentURI) }
catch (_) { return }

// If the protocol handler is already registered, just return early
// We only allow one handler (either manifest or custom) per protocol scheme
const existingHandlers = new Set([
...window.gFFPWASiteConfig.config.custom_protocol_handlers,
...window.gFFPWASiteConfig.manifest.protocol_handlers
].map(handler => sanitizeString(handler.protocol)).filter(handler => handler).sort());
if (existingHandlers.has(protocol)) return;

// Now ask the user and provide the proper callback
const message = this._getFormattedString('addProtocolHandlerMessage', [url.host, protocol,]);

const notificationBox = browser.getTabBrowser().getNotificationBox(browser);
const notificationIcon = url.prePath + '/favicon.ico';
const notificationValue = 'Protocol Registration: ' + protocol;

const addButton = {
label: this._getString('addProtocolHandlerAddButton'),
accessKey: this._getString('addProtocolHandlerAddButtonAccesskey'),
protocolInfo: { site: window.gFFPWASiteConfig.ulid, protocol: protocol, url: url.spec },

async callback (notification, buttonInfo) {
// Send a request to the native program to register the handler
const response = await lazy.sendNativeMessage({
cmd: 'RegisterProtocolHandler',
params: {
site: buttonInfo.protocolInfo.site,
protocol: buttonInfo.protocolInfo.protocol,
url: buttonInfo.protocolInfo.url,
}
})
if (response.type === 'Error') throw new Error(response.data)
if (response.type !== 'ProtocolHandlerRegistered') throw new Error(`Received invalid response type: ${response.type}`)

// Reset the handlerInfo to ask before the next use
const eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
const handlerInfo = eps.getProtocolHandlerInfo(buttonInfo.protocolInfo.protocol);
handlerInfo.alwaysAskBeforeHandling = true;

const hs = Cc['@mozilla.org/uriloader/handler-service;1'].getService(Ci.nsIHandlerService);
hs.store(handlerInfo);

// Hide the notification
notificationBox.currentNotification.close();
},
};

notificationBox.appendNotification(
notificationValue,
{
label: message,
image: notificationIcon,
priority: notificationBox.PRIORITY_INFO_LOW
},
[addButton]
);
}

WebProtocolHandlerRegistrar.prototype.removeProtocolHandler = function (protocol, url) {
(async () => {
// Send a request to the native program to unregister the handler
const response = await lazy.sendNativeMessage({
cmd: 'UnregisterProtocolHandler',
params: {
site: window.gFFPWASiteConfig.ulid,
protocol,
url,
}
})
if (response.type === 'Error') throw new Error(response.data)
if (response.type !== 'ProtocolHandlerUnregistered') throw new Error(`Received invalid response type: ${response.type}`)

// Reset the handlerInfo to ask before the next use
const eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
const handlerInfo = eps.getProtocolHandlerInfo(protocol);
handlerInfo.alwaysAskBeforeHandling = true;
})()
}
}

handleOutOfScopeNavigation () {
function matchWildcard(wildcard, string) {
const pattern = wildcard
Expand Down Expand Up @@ -572,18 +467,6 @@ class PwaBrowser {
// Return a new window
return win;
};

// Handle opening new window from keyboard shortcuts
if (!('_openWindow' in BrowserWindowTracker)) {
BrowserWindowTracker._openWindow = BrowserWindowTracker.openWindow;
BrowserWindowTracker.openWindow = function (options) {
if (options.openerWindow && options.openerWindow.gFFPWASiteConfig && !options.args) {
options.args = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
options.args.data = options.openerWindow.HomePage.get(options.openerWindow);
}
return BrowserWindowTracker._openWindow(options);
}
}
}

handleDisablingShortcuts () {
Expand Down Expand Up @@ -1813,7 +1696,6 @@ class PwaBrowser {
configureAll () {
this.configureLayout();
this.configureSettings();
this.disableOnboarding();

setTimeout(() => { this.configureWidgets() });
}
Expand Down Expand Up @@ -2067,16 +1949,6 @@ class PwaBrowser {
}
}

disableOnboarding () {
// Disable default browser prompt
BrowserGlue.prototype._maybeShowDefaultBrowserPrompt = async () => null;

// Disable onboarding messages
OnboardingMessageProvider.getMessages = async () => [];
OnboardingMessageProvider.getUntranslatedMessages = async () => [];
OnboardingMessageProvider.getUntranslatedMessages = async () => null;
}

//////////////////////////////
// Utils
//////////////////////////////
Expand Down

0 comments on commit e15c9d9

Please sign in to comment.