Bug 1620282 - Enable optional localization of text fields in about:welcome r=andreio,pdahiya

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kate Hudson 2020-03-10 03:11:08 +00:00
Родитель 8efc792cc9
Коммит fa86502014
5 изменённых файлов: 155 добавлений и 41 удалений

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

@ -101,8 +101,9 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _components_HeroText__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
/* harmony import */ var _components_FxCards__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7);
/* harmony import */ var _components_FxCards__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
/* harmony import */ var _components_MSLocalized__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4);
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8);
/* 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/. */
@ -112,6 +113,7 @@ __webpack_require__.r(__webpack_exports__);
class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
constructor(props) {
super(props);
@ -140,7 +142,7 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
}
handleStartBtnClick() {
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["AboutWelcomeUtils"].handleUserAction(this.props.startButton.action);
_lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_5__["AboutWelcomeUtils"].handleUserAction(this.props.startButton.action);
const ping = {
event: "CLICK_BUTTON",
message_id: this.props.startButton.message_id,
@ -164,25 +166,24 @@ class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
cards: props.cards,
metricsFlowUri: this.state.metricsFlowUri,
sendTelemetry: window.AWSendEventTelemetry
}), props.startButton && props.startButton.string_id && react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_MSLocalized__WEBPACK_IMPORTED_MODULE_4__["Localized"], {
text: props.startButton.label
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
className: "start-button",
"data-l10n-id": props.startButton.string_id,
onClick: this.handleStartBtnClick
}))));
})))));
}
}
AboutWelcome.defaultProps = _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_4__["DEFAULT_WELCOME_CONTENT"];
AboutWelcome.defaultProps = _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_5__["DEFAULT_WELCOME_CONTENT"];
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"));
async function mount() {
const settings = await window.AWGetStartupData();
react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(AboutWelcome, settings), document.getElementById("root"));
}
mount(window.AWGetStartupData());
mount();
/***/ }),
/* 1 */
@ -205,32 +206,93 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HeroText", function() { return HeroText; });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
/* 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 HeroText = props => {
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
className: "welcome-title",
"data-l10n-id": props.title.string_id
}), props.subtitle && props.subtitle.string_id && react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", {
className: "welcome-subtitle",
"data-l10n-id": props.subtitle.string_id
}));
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
text: props.title
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h1", {
className: "welcome-title"
})), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__["Localized"], {
text: props.subtitle
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h2", {
className: "welcome-subtitle"
})));
};
/***/ }),
/* 4 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Localized", function() { return Localized; });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* 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 MS_STRING_PROP = "string_id";
/**
* Based on the .text prop, localizes an inner element if a string_id
* is provided, OR renders plain text, OR hides it if nothing is provided.
*
* Examples:
*
* Localized text
* ftl:
* title = Welcome
* jsx:
* <Localized text={{string_id: "title"}}><h1 /></Localized>
* output:
* <h1 data-l10n-id="title">Welcome</h1>
*
* Unlocalized text
* jsx:
* <Localized text="Welcome"><h1 /></Localized>
* output:
* <h1>Welcome</h1>
*/
const Localized = ({
text,
children
}) => {
if (!text) {
return null;
}
let props = children ? children.props : {};
let textNode;
if (typeof text === "object" && text[MS_STRING_PROP]) {
props = { ...props
};
props["data-l10n-id"] = text[MS_STRING_PROP];
} else if (typeof text === "string") {
textNode = text;
}
return children ? react__WEBPACK_IMPORTED_MODULE_0___default.a.cloneElement(children, props, textNode) : react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", props, textNode);
};
/***/ }),
/* 5 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FxCards", function() { return FxCards; });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
/* harmony import */ var _asrouter_templates_OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7);
/* harmony import */ var _asrouter_templates_FirstRun_addUtmParams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
/* harmony import */ var _asrouter_templates_OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
/* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8);
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -340,7 +402,7 @@ class FxCards extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent
}
/***/ }),
/* 5 */
/* 6 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -381,7 +443,7 @@ function addUtmParams(url, utmTerm) {
}
/***/ }),
/* 6 */
/* 7 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -441,7 +503,7 @@ class OnboardingCard extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCo
}
/***/ }),
/* 7 */
/* 8 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -479,7 +541,9 @@ const DEFAULT_WELCOME_CONTENT = {
string_id: "onboarding-welcome-header"
},
startButton: {
string_id: "onboarding-start-browsing-button-label",
label: {
string_id: "onboarding-start-browsing-button-label"
},
message_id: "START_BROWSING_BUTTON",
action: {
type: "OPEN_AWESOME_BAR"

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

@ -6,6 +6,8 @@ import React from "react";
import ReactDOM from "react-dom";
import { HeroText } from "./components/HeroText";
import { FxCards } from "./components/FxCards";
import { Localized } from "./components/MSLocalized";
import {
AboutWelcomeUtils,
DEFAULT_WELCOME_CONTENT,
@ -56,13 +58,12 @@ class AboutWelcome extends React.PureComponent {
metricsFlowUri={this.state.metricsFlowUri}
sendTelemetry={window.AWSendEventTelemetry}
/>
{props.startButton && props.startButton.string_id && (
<Localized text={props.startButton.label}>
<button
className="start-button"
data-l10n-id={props.startButton.string_id}
onClick={this.handleStartBtnClick}
/>
)}
</Localized>
</main>
</div>
</div>
@ -72,11 +73,12 @@ class AboutWelcome extends React.PureComponent {
AboutWelcome.defaultProps = DEFAULT_WELCOME_CONTENT;
function mount(settings) {
async function mount() {
const settings = await window.AWGetStartupData();
ReactDOM.render(
<AboutWelcome title={settings.title} subtitle={settings.subtitle} />,
<AboutWelcome {...settings} />,
document.getElementById("root")
);
}
mount(window.AWGetStartupData());
mount();

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

@ -3,17 +3,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
import React from "react";
import { Localized } from "./MSLocalized";
export const HeroText = props => {
return (
<React.Fragment>
<h1 className="welcome-title" data-l10n-id={props.title.string_id} />
{props.subtitle && props.subtitle.string_id && (
<h2
className="welcome-subtitle"
data-l10n-id={props.subtitle.string_id}
/>
)}
<Localized text={props.title}>
<h1 className="welcome-title" />
</Localized>
<Localized text={props.subtitle}>
<h2 className="welcome-subtitle" />
</Localized>
</React.Fragment>
);
};

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

@ -0,0 +1,46 @@
/* 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/. */
import React from "react";
const MS_STRING_PROP = "string_id";
/**
* Based on the .text prop, localizes an inner element if a string_id
* is provided, OR renders plain text, OR hides it if nothing is provided.
*
* Examples:
*
* Localized text
* ftl:
* title = Welcome
* jsx:
* <Localized text={{string_id: "title"}}><h1 /></Localized>
* output:
* <h1 data-l10n-id="title">Welcome</h1>
*
* Unlocalized text
* jsx:
* <Localized text="Welcome"><h1 /></Localized>
* output:
* <h1>Welcome</h1>
*/
export const Localized = ({ text, children }) => {
if (!text) {
return null;
}
let props = children ? children.props : {};
let textNode;
if (typeof text === "object" && text[MS_STRING_PROP]) {
props = { ...props };
props["data-l10n-id"] = text[MS_STRING_PROP];
} else if (typeof text === "string") {
textNode = text;
}
return children
? React.cloneElement(children, props, textNode)
: React.createElement("span", props, textNode);
};

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

@ -30,7 +30,9 @@ export const DEFAULT_WELCOME_CONTENT = {
string_id: "onboarding-welcome-header",
},
startButton: {
string_id: "onboarding-start-browsing-button-label",
label: {
string_id: "onboarding-start-browsing-button-label",
},
message_id: "START_BROWSING_BUTTON",
action: {
type: "OPEN_AWESOME_BAR",