Browse Source

use fluent-langneg for subtag support

Danny Coates 7 years ago
parent
commit
bfcdf9340d

+ 3 - 3
app/templates/completed.js

@@ -15,9 +15,9 @@ module.exports = function(state, emit) {
         <div class="progress-text"></div>
       </div>
     </div>
-    <a class="send-new" data-state="completed" href="/" onclick=${sendNew}>${state.translate(
-    'sendYourFilesLink'
-  )}</a>
+    <a class="send-new" data-state="completed" href="/" onclick=${
+      sendNew
+    }>${state.translate('sendYourFilesLink')}</a>
   </div>
   `;
 

+ 11 - 3
app/templates/progress.js

@@ -10,10 +10,18 @@ module.exports = function(progressRatio) {
   const percent = Math.floor(progressRatio * 100);
   const div = html`
   <div class="progress-bar">
-    <svg id="progress" width="${oDiameter}" height="${oDiameter}" viewPort="0 0 ${oDiameter} ${oDiameter}" version="1.1">
+    <svg id="progress" width="${oDiameter}" height="${
+    oDiameter
+  }" viewPort="0 0 ${oDiameter} ${oDiameter}" version="1.1">
       <circle r="${radius}" cx="${oRadius}" cy="${oRadius}" fill="transparent"/>
-      <circle id="bar" r="${radius}" cx="${oRadius}" cy="${oRadius}" fill="transparent" transform="rotate(-90 ${oRadius} ${oRadius})" stroke-dasharray="${circumference}" stroke-dashoffset="${dashOffset}"/>
-      <text class="percentage" text-anchor="middle" x="50%" y="98"><tspan class="percent-number">${percent}</tspan><tspan class="percent-sign">%</tspan></text>
+      <circle id="bar" r="${radius}" cx="${oRadius}" cy="${
+    oRadius
+  }" fill="transparent" transform="rotate(-90 ${oRadius} ${
+    oRadius
+  })" stroke-dasharray="${circumference}" stroke-dashoffset="${dashOffset}"/>
+      <text class="percentage" text-anchor="middle" x="50%" y="98"><tspan class="percent-number">${
+        percent
+      }</tspan><tspan class="percent-sign">%</tspan></text>
     </svg>
   </div>
   `;

+ 3 - 1
app/templates/uploadPassword.js

@@ -5,7 +5,9 @@ module.exports = function(state, emit) {
   const div = html`
   <div class="selectPassword">
     <div id="addPasswordWrapper">
-      <input id="addPassword" type="checkbox" autocomplete="off" onchange=${togglePasswordInput}/>
+      <input id="addPassword" type="checkbox" autocomplete="off" onchange=${
+        togglePasswordInput
+      }/>
       <label for="addPassword">
         ${state.translate('requirePasswordCheckbox')}</label>
     </div>

+ 5 - 28
package-lock.json

@@ -42,15 +42,6 @@
         "through": "2.3.8"
       }
     },
-    "accept-language": {
-      "version": "3.0.18",
-      "resolved": "https://registry.npmjs.org/accept-language/-/accept-language-3.0.18.tgz",
-      "integrity": "sha1-9QJfF79lpGaoRYOMz5jNuHfYM4Q=",
-      "requires": {
-        "bcp47": "1.1.2",
-        "stable": "0.1.6"
-      }
-    },
     "accepts": {
       "version": "1.3.4",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
@@ -1236,11 +1227,6 @@
       "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
       "dev": true
     },
-    "bcp47": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz",
-      "integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4="
-    },
     "bel": {
       "version": "5.1.5",
       "resolved": "https://registry.npmjs.org/bel/-/bel-5.1.5.tgz",
@@ -1736,6 +1722,11 @@
         "chalk": "1.1.3"
       }
     },
+    "cldr-core": {
+      "version": "32.0.0",
+      "resolved": "https://registry.npmjs.org/cldr-core/-/cldr-core-32.0.0.tgz",
+      "integrity": "sha1-M7OO+WyaGD9SilZGBJRaqqTs6nE="
+    },
     "clean-css": {
       "version": "4.1.9",
       "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz",
@@ -3481,15 +3472,6 @@
         }
       }
     },
-    "express-request-language": {
-      "version": "1.1.15",
-      "resolved": "https://registry.npmjs.org/express-request-language/-/express-request-language-1.1.15.tgz",
-      "integrity": "sha512-KiLUdEZCcgwh8qfIvkCrhz1MMAFx/Xj4UcspN4zUxVdp+bp+yFvqUMmlyMHK2nC5JlQV7VK5uFOoS5LrArTL1A==",
-      "requires": {
-        "accept-language": "3.0.18",
-        "bcp47": "1.1.2"
-      }
-    },
     "extend": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
@@ -10864,11 +10846,6 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
-    "stable": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz",
-      "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA="
-    },
     "stack-trace": {
       "version": "0.0.10",
       "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",

+ 1 - 1
package.json

@@ -96,10 +96,10 @@
     "aws-sdk": "^2.149.0",
     "body-parser": "^1.18.2",
     "choo": "^6.5.1",
+    "cldr-core": "^32.0.0",
     "connect-busboy": "0.0.2",
     "convict": "^4.0.1",
     "express": "^4.16.2",
-    "express-request-language": "^1.1.15",
     "fluent": "^0.4.1",
     "fluent-langneg": "^0.1.0",
     "helmet": "^3.9.0",

+ 1 - 3
server/languages.js

@@ -4,11 +4,9 @@ const fs = require('fs');
 const path = require('path');
 
 function allLangs() {
-  const langs = fs.readdirSync(
+  return fs.readdirSync(
     path.join(__dirname, '..', 'dist', 'public', 'locales')
   );
-  langs.unshift('en-US'); // default first, TODO change for fluent-langneg
-  return langs;
 }
 
 if (config.l10n_dev) {

+ 27 - 7
server/routes/index.js

@@ -1,20 +1,40 @@
 const busboy = require('connect-busboy');
 const helmet = require('helmet');
 const bodyParser = require('body-parser');
-const requestLanguage = require('express-request-language');
 const languages = require('../languages');
 const storage = require('../storage');
 const config = require('../config');
 const pages = require('./pages');
-// const lang = require('fluent-langneg')
+const { negotiateLanguages } = require('fluent-langneg');
 const IS_DEV = config.env === 'development';
+const acceptLanguages = /(([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\*)(;q=[0-1](\.[0-9]+)?)?/g;
+const langData = require('cldr-core/supplemental/likelySubtags.json');
 
 module.exports = function(app) {
-  app.use(
-    requestLanguage({
-      languages
-    })
-  );
+  app.use(function(req, res, next) {
+    const header = req.headers['accept-language'] || 'en-US';
+    if (header.length > 255) {
+      req.language = 'en-US';
+      return next();
+    }
+    const langs = header.replace(/\s/g, '').match(acceptLanguages);
+    const preferred = langs
+      .map(l => {
+        const parts = l.split(';');
+        return {
+          locale: parts[0],
+          q: parts[1] ? parseFloat(parts[1].split('=')[1]) : 1
+        };
+      })
+      .sort((a, b) => b.q - a.q)
+      .map(x => x.locale);
+    req.language = negotiateLanguages(preferred, languages, {
+      strategy: 'lookup',
+      likelySubtags: langData.supplemental.likelySubtags,
+      defaultLocale: 'en-US'
+    })[0];
+    next();
+  });
   app.use(helmet());
   app.use(
     helmet.hsts({