Skip to content

Commit

Permalink
reimplemented l10n using dynamic import() (mozilla#1012)
Browse files Browse the repository at this point in the history
this should greatly reduce the complexity of the l10n code
and build pipeline and eliminate the most common error
seen in sentry logs (no translate function)
  • Loading branch information
dannycoates authored and Donovan Preston committed Nov 20, 2018
1 parent 5afa4e5 commit 1e62aa9
Show file tree
Hide file tree
Showing 28 changed files with 145 additions and 280 deletions.
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ node_modules
firefox
assets
docs
public
test
coverage
.nyc_output
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ dist
assets
firefox
coverage
app/locale.js
app/capabilities.js
55 changes: 28 additions & 27 deletions android/android.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import Raven from 'raven-js';
import { setApiUrlPrefix } from '../app/api';
import assets from '../common/assets';
import Header from '../app/ui/header';
import locale from '../common/locales';
import storage from '../app/storage';
import controller from '../app/controller';
import User from './user';
Expand All @@ -36,9 +35,9 @@ import upload from './pages/upload';
import share from './pages/share';
import preferences from './pages/preferences';
import error from './pages/error';
import { getTranslator } from '../app/locale';

if (navigator.userAgent === 'Send Android') {
assets.setPrefix('/android_asset');
setApiUrlPrefix('https://send2.dev.lcip.org');
}

Expand Down Expand Up @@ -71,30 +70,32 @@ function body(main) {
}
};
}
(async function start() {
const translate = await getTranslator('en-US');
app.use(async (state, emitter) => {
state.translate = translate;
state.capabilities = {
account: true
}; //TODO
state.storage = storage;
state.user = new User(storage);
state.raven = Raven;

app.use((state, emitter) => {
state.translate = locale.getTranslator();
state.capabilities = {
account: true
}; //TODO
state.storage = storage;
state.user = new User(storage);
state.raven = Raven;
window.finishLogin = async function(accountInfo) {
await state.user.finishLogin(accountInfo);
emitter.emit('render');
};

window.finishLogin = async function(accountInfo) {
await state.user.finishLogin(accountInfo);
emitter.emit('render');
};

// for debugging
window.appState = state;
window.appEmit = emitter.emit.bind(emitter);
});
app.route('/', body(home));
app.route('/upload', upload);
app.route('/share/:id', share);
app.route('/preferences', preferences);
app.route('/error', error);
//app.route('/debugging', require('./pages/debugging').default);
// add /api/filelist
app.mount('body');
// for debugging
window.appState = state;
window.appEmit = emitter.emit.bind(emitter);
});
app.route('/', body(home));
app.route('/upload', upload);
app.route('/share/:id', share);
app.route('/preferences', preferences);
app.route('/error', error);
//app.route('/debugging', require('./pages/debugging').default);
// add /api/filelist
app.mount('body');
})();
3 changes: 1 addition & 2 deletions android/app/buildAssets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
npm run build
rm -rf src/main/assets
mkdir -p src/main/assets
cp -R ../../dist/* src/main/assets
sed -i '' 's/url(/url(\/android_asset/g' src/main/assets/app.*.css
cp -R ../../dist/* src/main/assets
9 changes: 6 additions & 3 deletions app/capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ function checkStreams() {
}
}

function polyfillStreams() {
async function polyfillStreams() {
try {
require('@mattiasbuelens/web-streams-polyfill');
await import('@mattiasbuelens/web-streams-polyfill');
return true;
} catch (e) {
return false;
Expand All @@ -64,7 +64,10 @@ function polyfillStreams() {
export default async function capabilities() {
const crypto = await checkCrypto();
const nativeStreams = checkStreams();
const polyStreams = nativeStreams ? false : polyfillStreams();
let polyStreams = false;
if (!nativeStreams) {
polyStreams = await polyfillStreams();
}
let account = typeof AUTH_CONFIG !== 'undefined';
try {
account = account && !!localStorage;
Expand Down
26 changes: 26 additions & 0 deletions app/locale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { FluentBundle } from 'fluent';

function makeBundle(locale, ftl) {
const bundle = new FluentBundle(locale, { useIsolating: false });
bundle.addMessages(ftl);
return bundle;
}

export async function getTranslator(locale) {
const bundles = [];
const { default: en } = await import('../public/locales/en-US/send.ftl');
if (locale !== 'en-US') {
const {
default: ftl
} = await import(`../public/locales/${locale}/send.ftl`);
bundles.push(makeBundle(locale, ftl));
}
bundles.push(makeBundle('en-US', en));
return function(id, data) {
for (let bundle of bundles) {
if (bundle.hasMessage(id)) {
return bundle.format(bundle.getMessage(id), data);
}
}
};
}
8 changes: 6 additions & 2 deletions app/main.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* global LOCALE */
import 'core-js';
import 'fast-text-encoding'; // MS Edge support
import 'fluent-intl-polyfill';
import choo from 'choo';
import nanotiming from 'nanotiming';
import routes from './routes';
import capabilities from './capabilities';
import locale from '../common/locales';
import controller from './controller';
import dragManager from './dragManager';
import pasteManager from './pasteManager';
Expand All @@ -14,6 +15,7 @@ import experiments from './experiments';
import Raven from 'raven-js';
import './main.css';
import User from './user';
import { getTranslator } from './locale';

(async function start() {
const app = routes(choo());
Expand All @@ -28,11 +30,13 @@ import User from './user';
navigator.serviceWorker.register('/serviceWorker.js');
}

const translate = await getTranslator(LOCALE);

app.use((state, emitter) => {
state.capabilities = capa;
state.transfer = null;
state.fileInfo = null;
state.translate = locale.getTranslator();
state.translate = translate;
state.storage = storage;
state.raven = Raven;
state.user = new User(storage);
Expand Down
13 changes: 1 addition & 12 deletions build/android_index_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ function chunkFileNames(compilation) {
}
class AndroidIndexPlugin {
apply(compiler) {
const assets = {};
compiler.hooks.compilation.tap(NAME, compilation => {
compilation.hooks.moduleAsset.tap(NAME, (mod, file) => {
if (mod.userRequest) {
assets[
path.join(path.dirname(file), path.basename(mod.userRequest))
] = file;
}
});
});
compiler.hooks.emit.tap(NAME, compilation => {
const files = chunkFileNames(compilation);
const page = html`
Expand All @@ -36,9 +26,8 @@ class AndroidIndexPlugin {
name="viewport"
content="width=device-width, initial-scale=1"
/>
<base href="file:///android_asset/" />
<link href="${files['app.css']}" rel="stylesheet" />
<script src="${files['vendor.js']}"></script>
<script src="${assets['public/locales/en-US/send.ftl']}"></script>
<script src="${files['android.js']}"></script>
</head>
<body></body>
Expand Down
62 changes: 0 additions & 62 deletions build/fluent_loader.js

This file was deleted.

33 changes: 0 additions & 33 deletions build/generate_l10n_map.js

This file was deleted.

8 changes: 0 additions & 8 deletions build/readme.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
# Custom Loaders

## Fluent Loader

The fluent loader "compiles" `.ftl` files into `.js` files directly usable by both the frontend and server for localization.

## Generate Asset Map

This loader enumerates all the files in `assets/` so that `common/assets.js` can provide mappings from the source filename to the hashed filename used on the site.

## Generate L10N Map

This loader enumerates all the ftl files in `public/locales` so that the fluent loader can create it's js files.

## Version Plugin

Creates a `version.json` file that gets exposed by the `/__version__` route from the `package.json` file and current git commit hash.
Expand Down
52 changes: 0 additions & 52 deletions common/locales.js

This file was deleted.

2 changes: 1 addition & 1 deletion common/readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Common Code

This directory contains code loaded by both the frontend `app` and backend `server`. The code here can be challenging to understand at first because the contexts for the two (three counting the dev server) environments that include them are quite different, but the purpose of these modules are quite simple, to provide mappings from the source assets (`copy-16.png`) to the concrete production assets (`copy-16.db66e0bf.svg`), similarly for localizations.
This directory contains code loaded by both the frontend `app` and backend `server`. The code here can be challenging to understand at first because the contexts for the two (three counting the dev server) environments that include them are quite different, but the purpose of these modules are quite simple, to provide mappings from the source assets (`copy-16.png`) to the concrete production assets (`copy-16.db66e0bf.svg`).
Loading

0 comments on commit 1e62aa9

Please sign in to comment.