Bug 1617783 - Add JSWindowActors to about:welcome r=mconley,pdahiya

Differential Revision: https://phabricator.services.mozilla.com/D64082

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kate Hudson 2020-02-28 14:36:31 +00:00
Родитель b9ef3fbf74
Коммит fd8a3f0cf3
11 изменённых файлов: 313 добавлений и 60 удалений

Просмотреть файл

@ -1319,6 +1319,11 @@ pref("browser.newtabpage.activity-stream.discoverystream.personalization.modelKe
pref("trailhead.firstrun.branches", "");
// Separate about welcome
pref("browser.aboutwelcome.enabled", false);
// See Console.jsm LOG_LEVELS for all possible values
pref("browser.aboutwelcome.log", "warn");
// The pref that controls if the What's New panel is enabled.
pref("browser.messaging-system.whatsNewPanel.enabled", true);
// Used for CFR messages with scores. See Bug 1594422.

Просмотреть файл

@ -405,6 +405,51 @@ let LEGACY_ACTORS = {
},
};
// See Bug 1618306
// This should be moved to BrowserGlue.jsm and this file should be deleted
// when we turn on separate about:welcome for all users.
const ACTOR_CONFIG = {
parent: {
moduleURI: "resource:///actors/AboutWelcomeParent.jsm",
},
child: {
moduleURI: "resource:///actors/AboutWelcomeChild.jsm",
events: {
// This is added so the actor instantiates immediately and makes
// methods available to the page js on load.
DOMWindowCreated: {},
},
},
matches: ["about:welcome"],
};
const AboutWelcomeActorHelper = {
register() {
ChromeUtils.registerWindowActor("AboutWelcome", ACTOR_CONFIG);
},
unregister() {
ChromeUtils.unregisterWindowActor("AboutWelcome");
},
};
XPCOMUtils.defineLazyPreferenceGetter(
this,
"isSeparateAboutWelcome",
"browser.aboutwelcome.enabled",
false,
(prefName, prevValue, isEnabled) => {
if (isEnabled) {
AboutWelcomeActorHelper.register();
} else {
AboutWelcomeActorHelper.unregister();
}
}
);
if (isSeparateAboutWelcome) {
AboutWelcomeActorHelper.register();
}
(function earlyBlankFirstPaint() {
if (
AppConstants.platform == "macosx" ||

Просмотреть файл

@ -0,0 +1,91 @@
/* 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/. */
"use strict";
const EXPORTED_SYMBOLS = ["AboutWelcomeChild"];
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyGetter(this, "log", () => {
const { AboutWelcomeLog } = ChromeUtils.import(
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeLog.jsm"
);
return new AboutWelcomeLog("AboutWelcomeChild.jsm");
});
class AboutWelcomeChild extends JSWindowActorChild {
actorCreated() {
this.exportFunctions();
}
/**
* Send event that can be handled by the page
* @param {{type: string, data?: any}} action
*/
sendToPage(action) {
log.debug(`Sending to page: ${action.type}`);
const win = this.document.defaultView;
const event = new win.CustomEvent("AboutWelcomeChromeToContent", {
detail: Cu.cloneInto(action, win),
});
win.dispatchEvent(event);
}
/**
* Export functions that can be called by page js
*/
exportFunctions() {
let window = this.contentWindow;
Cu.exportFunction(this.AWGetStartupData.bind(this), window, {
defineAs: "AWGetStartupData",
});
Cu.exportFunction(this.AWSendEventTelemetry.bind(this), window, {
defineAs: "AWSendEventTelemetry",
});
Cu.exportFunction(this.AWSendToParent.bind(this), window, {
defineAs: "AWSendToParent",
});
}
/**
* Send initial data to page including experiment information
*/
AWGetStartupData() {
// TODO: Fetch this from Experiments
const experimentData = {};
return Cu.cloneInto(experimentData, this.contentWindow);
}
/**
* Send Event Telemetry
* @param {object} eventData
*/
AWSendEventTelemetry(eventData) {
// TODO: Send event Telemetry with Services.telemetry
log.debug("Sending event telemetry:", eventData);
}
/**
* Send message that can be handled by AboutWelcomeParent.jsm
* @param {string} type
* @param {any=} data
*/
AWSendToParent(type, data) {
this.sendAsyncMessage(`AWPage:${type}`, data);
}
/**
* @param {{type: string, detail?: any}} event
* @override
*/
handleEvent(event) {
log.debug(`Received page event ${event.type}`);
}
}

Просмотреть файл

@ -0,0 +1,63 @@
/* 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/. */
"use strict";
const EXPORTED_SYMBOLS = ["AboutWelcomeParent"];
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
MigrationUtils: "resource:///modules/MigrationUtils.jsm",
});
XPCOMUtils.defineLazyGetter(this, "log", () => {
const { AboutWelcomeLog } = ChromeUtils.import(
"resource://activity-stream/aboutwelcome/lib/AboutWelcomeLog.jsm"
);
return new AboutWelcomeLog("AboutWelcomeParent.jsm");
});
class AboutWelcomeParent extends JSWindowActorParent {
/**
* Handle messages from AboutWelcomeChild.jsm
*
* @param {string} type
* @param {any=} data
* @param {Browser} browser
* @param {Window} window
*/
onContentMessage(type, data, browser, window) {
log.debug(`Received content event: ${type}`);
switch (type) {
case "AWPage:SHOW_MIGRATION_WIZARD":
MigrationUtils.showMigrationWizard(window, [
MigrationUtils.MIGRATION_ENTRYPOINT_NEWTAB,
]);
break;
default:
log.debug(`Unexpected event ${type} was not handled.`);
}
}
/**
* @param {{name: string, data?: any}} message
* @override
*/
receiveMessage(message) {
const { name, data } = message;
let browser;
let window;
if (this.manager.rootFrameLoader) {
browser = this.manager.rootFrameLoader.ownerElement;
window = browser.ownerGlobal;
this.onContentMessage(name, data, browser, window);
} else {
log.warn(`Not handling ${name} because the browser doesn't exist.`);
}
}
}

Просмотреть файл

@ -113,9 +113,6 @@ __webpack_require__.r(__webpack_exports__);
class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
sendTelemetry(ping) {// TBD: Handle telemetry messages
}
render() {
const {
props
@ -129,14 +126,22 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
subtitle: props.subtitle
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_FxCards__WEBPACK_IMPORTED_MODULE_3__["FxCards"], {
cards: props.cards,
sendTelemetry: this.sendTelemetry
sendTelemetry: window.AWSendEventTelemetry
})));
}
}
AboutWelcome.defaultProps = _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["DEFAULT_WELCOME_CONTENT"];
react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(AboutWelcome, null), document.getElementById("root"));
function mount(settings) {
react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(AboutWelcome, {
title: settings.title,
subtitle: settings.subtitle
}), document.getElementById("root"));
}
mount(window.AWGetStartupData());
/***/ }),
/* 1 */
@ -196,23 +201,23 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
class FxCards extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
onCardAction(action) {
let actionUpdates = {};
let {
type,
data
} = action;
let UTMTerm = "utm_term_separate_welcome";
if (action.type === "OPEN_URL") {
let url = new URL(action.data.args);
Object(_asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_1__["addUtmParams"])(url, UTMTerm);
actionUpdates = {
data: { ...action.data,
args: url.toString()
}
data = { ...data,
args: url.toString()
};
}
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_3__["AboutWelcomeUtils"].handleUserAction({
data: { ...action,
...actionUpdates
}
type,
data
});
}
@ -347,14 +352,23 @@ __webpack_require__.r(__webpack_exports__);
* 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 AboutWelcomeUtils = {
handleUserAction({
data: action
}) {
handleUserAction(action) {
switch (action.type) {
case "OPEN_URL":
window.open(action.data.args);
break;
case "SHOW_MIGRATION_WIZARD":
window.AWSendToParent("SHOW_MIGRATION_WIZARD");
break;
}
},
sendEvent(type, detail) {
document.dispatchEvent(new CustomEvent(`AWPage:${type}`, {
bubbles: true,
detail
}));
}
};
@ -417,30 +431,31 @@ const DEFAULT_WELCOME_CONTENT = {
order: 2,
blockOnClick: false
}, {
id: "TRAILHEAD_CARD_11",
template: "onboarding",
bundled: 3,
order: 0,
content: {
title: {
string_id: "onboarding-mobile-phone-title"
string_id: "onboarding-import-browser-settings-title"
},
text: {
string_id: "onboarding-mobile-phone-text"
string_id: "onboarding-import-browser-settings-text"
},
icon: "mobile",
icon: "import",
primary_button: {
label: {
string_id: "onboarding-mobile-phone-button"
string_id: "onboarding-import-browser-settings-button"
},
action: {
type: "OPEN_URL",
data: {
args: "https://www.mozilla.org/firefox/mobile/",
where: "tabshifted"
}
type: "SHOW_MIGRATION_WIZARD"
}
}
},
id: "TRAILHEAD_CARD_6",
order: 6,
blockOnClick: false
targeting: "trailheadTriplet == 'dynamic_chrome'",
trigger: {
id: "showOnboarding"
}
}]
};

Просмотреть файл

@ -0,0 +1,22 @@
/* 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/. */
"use strict";
const EXPORTED_SYMBOLS = ["AboutWelcomeLog"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
const LOGGING_PREF = "browser.aboutwelcome.log";
class AboutWelcomeLog extends ConsoleAPI {
constructor(name) {
let consoleOptions = {
prefix: name,
maxLogLevel: Services.prefs.getCharPref(LOGGING_PREF, "warn"),
maxLogLevelPref: LOGGING_PREF,
};
super(consoleOptions);
}
}

Просмотреть файл

@ -9,17 +9,16 @@ import { FxCards } from "./components/FxCards";
import { DEFAULT_WELCOME_CONTENT } from "../lib/aboutwelcome-utils";
class AboutWelcome extends React.PureComponent {
sendTelemetry(ping) {
// TBD: Handle telemetry messages
}
render() {
const { props } = this;
return (
<div className="trailheadCards">
<div className="trailheadCardsInner">
<HeroText title={props.title} subtitle={props.subtitle} />
<FxCards cards={props.cards} sendTelemetry={this.sendTelemetry} />
<FxCards
cards={props.cards}
sendTelemetry={window.AWSendEventTelemetry}
/>
</div>
</div>
);
@ -28,4 +27,11 @@ class AboutWelcome extends React.PureComponent {
AboutWelcome.defaultProps = DEFAULT_WELCOME_CONTENT;
ReactDOM.render(<AboutWelcome />, document.getElementById("root"));
function mount(settings) {
ReactDOM.render(
<AboutWelcome title={settings.title} subtitle={settings.subtitle} />,
document.getElementById("root")
);
}
mount(window.AWGetStartupData());

Просмотреть файл

@ -9,18 +9,16 @@ import { AboutWelcomeUtils } from "../../lib/aboutwelcome-utils";
export class FxCards extends React.PureComponent {
onCardAction(action) {
let actionUpdates = {};
let { type, data } = action;
let UTMTerm = "utm_term_separate_welcome";
if (action.type === "OPEN_URL") {
let url = new URL(action.data.args);
addUtmParams(url, UTMTerm);
actionUpdates = { data: { ...action.data, args: url.toString() } };
data = { ...data, args: url.toString() };
}
AboutWelcomeUtils.handleUserAction({
data: { ...action, ...actionUpdates },
});
AboutWelcomeUtils.handleUserAction({ type, data });
}
render() {

Просмотреть файл

@ -3,13 +3,24 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
export const AboutWelcomeUtils = {
handleUserAction({ data: action }) {
handleUserAction(action) {
switch (action.type) {
case "OPEN_URL":
window.open(action.data.args);
break;
case "SHOW_MIGRATION_WIZARD":
window.AWSendToParent("SHOW_MIGRATION_WIZARD");
break;
}
},
sendEvent(type, detail) {
document.dispatchEvent(
new CustomEvent(`AWPage:${type}`, {
bubbles: true,
detail,
})
);
},
};
export const DEFAULT_WELCOME_CONTENT = {
@ -75,30 +86,21 @@ export const DEFAULT_WELCOME_CONTENT = {
blockOnClick: false,
},
{
id: "TRAILHEAD_CARD_11",
template: "onboarding",
bundled: 3,
order: 0,
content: {
title: {
string_id: "onboarding-mobile-phone-title",
},
text: {
string_id: "onboarding-mobile-phone-text",
},
icon: "mobile",
title: { string_id: "onboarding-import-browser-settings-title" },
text: { string_id: "onboarding-import-browser-settings-text" },
icon: "import",
primary_button: {
label: {
string_id: "onboarding-mobile-phone-button",
},
action: {
type: "OPEN_URL",
data: {
args: "https://www.mozilla.org/firefox/mobile/",
where: "tabshifted",
},
},
label: { string_id: "onboarding-import-browser-settings-button" },
action: { type: "SHOW_MIGRATION_WIZARD" },
},
},
id: "TRAILHEAD_CARD_6",
order: 6,
blockOnClick: false,
targeting: "trailheadTriplet == 'dynamic_chrome'",
trigger: { id: "showOnboarding" },
},
],
};

Просмотреть файл

@ -7,6 +7,7 @@ browser.jar:
res/activity-stream/lib/ (./lib/*)
res/activity-stream/common/ (./common/*)
res/activity-stream/aboutwelcome/ (./aboutwelcome/content/*)
res/activity-stream/aboutwelcome/lib/ (./aboutwelcome/lib/*)
res/activity-stream/vendor/Redux.jsm (./vendor/Redux.jsm)
res/activity-stream/vendor/react.js (./vendor/react.js)
res/activity-stream/vendor/react-dom.js (./vendor/react-dom.js)

Просмотреть файл

@ -26,6 +26,11 @@ EXTRA_JS_MODULES += [
'AboutNewTabService.jsm',
]
FINAL_TARGET_FILES.actors += [
'aboutwelcome/AboutWelcomeChild.jsm',
'aboutwelcome/AboutWelcomeParent.jsm',
]
XPCOM_MANIFESTS += [
'components.conf',
]