rLanguageMismatch", } ); Cu.exportFunction(this.AWSetRequestedLocales.bind(this), window, { defineAs: "AWSetRequestedLocales", }); Cu.exportFunction(this.AWSendToDeviceEmailsSupported.bind(this), window, { defineAs: "AWSendToDeviceEmailsSupported", }); Cu.exportFunction(this.AWNewScreen.bind(this), window, { defineAs: "AWNewScreen", }); Cu.exportFunction(this.AWGetUnhandledCampaignAction.bind(this), window, { defineAs: "AWGetUnhandledCampaignAction", }); Cu.exportFunction( this.AWFindBackupsInWellKnownLocations.bind(this), window, { defineAs: "AWFindBackupsInWellKnownLocations" } ); Cu.exportFunction(this.RPMGetFormatURLPref.bind(this), window, { defineAs: "RPMGetFormatURLPref", }); } /** * Wrap a promise so content can use Promise methods. */ wrapPromise(promise) { return new this.contentWindow.Promise((resolve, reject) => promise.then(resolve, reject) ); } /** * Clones the result of the query into the content window. */ sendQueryAndCloneForContent(...sendQueryArgs) { return this.wrapPromise( (async () => { return Cu.cloneInto( await this.sendQuery(...sendQueryArgs), this.contentWindow ); })() ); } AWSelectTheme(data) { return this.wrapPromise( this.sendQuery("AWPage:SELECT_THEME", data.toUpperCase()) ); } AWEvaluateScreenTargeting(data) { return this.sendQueryAndCloneForContent( "AWPage:EVALUATE_SCREEN_TARGETING", data ); } AWEvaluateAttributeTargeting(data) { return this.wrapPromise( this.sendQuery("AWPage:EVALUATE_ATTRIBUTE_TARGETING", data) ); } AWAddScreenImpression(screen) { return this.wrapPromise( this.sendQuery("AWPage:ADD_SCREEN_IMPRESSION", screen) ); } AWFindBackupsInWellKnownLocations(data) { return this.sendQueryAndCloneForContent( "AWPage:BACKUP_FIND_WELL_KNOWN", data ); } /** * Send initial data to page including experiment information */ async getAWContent() { let attributionData = await this.sendQuery("AWPage:GET_ATTRIBUTION_DATA"); let experimentMetadata = lazy.NimbusFeatures.aboutwelcome.getEnrollmentMetadata( lazy.EnrollmentType.EXPERIMENT ) ?? {}; lazy.log.debug( `Loading about:welcome with ${ experimentMetadata?.slug ?? "no" } experiment` ); let featureConfig = lazy.NimbusFeatures.aboutwelcome.getAllVariables(); featureConfig.needDefault = await this.sendQuery("AWPage:NEED_DEFAULT"); featureConfig.needPin = await this.sendQuery("AWPage:DOES_APP_NEED_PIN"); if (featureConfig.languageMismatchEnabled) { featureConfig.appAndSystemLocaleInfo = await this.sendQuery( "AWPage:GET_APP_AND_SYSTEM_LOCALE_INFO" ); } // FeatureConfig (from experiments) has higher precendence // to defaults. But the `screens` property isn't defined we shouldn't // override the default with `null` let defaults = lazy.AboutWelcomeDefaults.getDefaults(); const content = await lazy.AboutWelcomeDefaults.prepareContentForReact({ ...attributionData, ...experimentMetadata, ...defaults, ...featureConfig, screens: featureConfig.screens ?? defaults.screens, backdrop: featureConfig.backdrop ?? defaults.backdrop, }); return Cu.cloneInto(content, this.contentWindow); } AWGetFeatureConfig() { return this.wrapPromise(this.getAWContent()); } AWGetFxAMetricsFlowURI() { return this.wrapPromise(this.sendQuery("AWPage:FXA_METRICS_FLOW_URI")); } AWGetSelectedTheme() { return this.wrapPromise(this.sendQuery("AWPage:GET_SELECTED_THEME")); } /** * Send Event Telemetry * * @param {object} eventData */ AWSendEventTelemetry(eventData) { if (lazy.toolbarEntrypoint) { eventData.event_context.entrypoint = lazy.toolbarEntrypoint; } this.AWSendToParent("TELEMETRY_EVENT", { ...eventData, event_context: { ...eventData.event_context, }, }); } /** * Send message that can be handled by AboutWelcomeParent.sys.mjs * * @param {string} type * @param {any=} data * @returns {Promise} */ AWSendToParent(type, data) { return this.sendQueryAndCloneForContent(`AWPage:${type}`, data); } AWWaitForMigrationClose() { return this.wrapPromise(this.sendQuery("AWPage:WAIT_FOR_MIGRATION_CLOSE")); } setDidSeeFinalScreen() { this.AWSendToParent("SPECIAL_ACTION", { type: "SET_PREF", data: { pref: { name: DID_SEE_FINAL_SCREEN_PREF, value: true, }, }, }); } focusUrlBar() { this.AWSendToParent("SPECIAL_ACTION", { type: "FOCUS_URLBAR", }); } AWFinish() { this.setDidSeeFinalScreen(); this.contentWindow.location.href = "about:home"; this.focusUrlBar(); } AWEnsureAddonInstalled(addonId) { return this.wrapPromise( this.sendQuery("AWPage:ENSURE_ADDON_INSTALLED", addonId) ); } AWGetInstalledAddons() { return this.wrapPromise( this.sendQueryAndCloneForContent("AWPage:GET_INSTALLED_ADDONS") ); } AWEnsureLangPackInstalled(negotiated, screenContent) { const content = Cu.cloneInto(screenContent, {}); return this.wrapPromise( this.sendQuery( "AWPage:ENSURE_LANG_PACK_INSTALLED", negotiated.langPack ).then(() => { const formatting = []; const l10n = new Localization( ["branding/brand.ftl", "browser/newtab/onboarding.ftl"], false, undefined, // Use the system-ish then app then default locale. [...negotiated.requestSystemLocales, "en-US"] ); // Add the negotiated language name as args. function addMessageArgsAndUseLangPack(obj) { for (const value of Object.values(obj)) { if (value?.string_id) { value.args = { ...value.args, negotiatedLanguage: negotiated.langPackDisplayName, }; // Expose fluent strings wanting lang pack as raw. if (value.useLangPack) { formatting.push( l10n.formatValue(value.string_id, value.args).then(raw => { delete value.string_id; value.raw = raw; }) ); } } } } addMessageArgsAndUseLangPack(content.languageSwitcher); addMessageArgsAndUseLangPack(content); return Promise.all(formatting).then(() => Cu.cloneInto(content, this.contentWindow) ); }) ); } AWSetRequestedLocales(requestSystemLocales) { return this.sendQueryAndCloneForContent( "AWPage:SET_REQUESTED_LOCALES", requestSystemLocales ); } AWNegotiateLangPackForLanguageMismatch(appAndSystemLocaleInfo) { return this.sendQueryAndCloneForContent( "AWPage:NEGOTIATE_LANGPACK", appAndSystemLocaleInfo ); } AWSendToDeviceEmailsSupported() { return this.wrapPromise( this.sendQuery("AWPage:SEND_TO_DEVICE_EMAILS_SUPPORTED") ); } AWNewScreen(screenId) { return this.wrapPromise(this.sendQuery("AWPage:NEW_SCREEN", screenId)); } AWGetUnhandledCampaignAction() { return this.sendQueryAndCloneForContent( "AWPage:GET_UNHANDLED_CAMPAIGN_ACTION" ); } RPMGetFormatURLPref(formatURL) { return Services.urlFormatter.formatURLPref(formatURL); } /** * @param {{type: string, detail?: any}} event * @override */ handleEvent(event) { lazy.log.debug(`Received page event ${event.type}`); } } PK