Bug 1310702 - use webpack-like require.context in devtools l10n; r?jryans
MozReview-Commit-ID: 5noH0y0MgaK
--- a/addon-sdk/source/lib/toolkit/loader.js
+++ b/addon-sdk/source/lib/toolkit/loader.js
@@ -900,16 +900,24 @@ const Require = iced(function Require(lo
}
// Expose the `resolve` function for this `Require` instance
require.resolve = _require.resolve = function resolve(id) {
let { uri } = getRequirements(id);
return uri;
}
+ // This is like webpack's require.context. It returns a new require
+ // function that prepends the prefix to any requests.
+ require.context = prefix => {
+ return id => {
+ return require(prefix + id);
+ };
+ };
+
// Make `require.main === module` evaluate to true in main module scope.
require.main = loader.main === requirer ? requirer : undefined;
return iced(require);
});
Loader.Require = Require;
const main = iced(function main(loader, id) {
// If no main entry provided, and native loader is used,
--- a/devtools/client/inspector/rules/test/head.js
+++ b/devtools/client/inspector/rules/test/head.js
@@ -15,17 +15,18 @@ registerCleanupFunction(() => {
});
var {getInplaceEditorForSpan: inplaceEditor} =
require("devtools/client/shared/inplace-editor");
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
-const STYLE_INSPECTOR_L10N = new LocalizationHelper("chrome://devtools-shared/locale/styleinspector.properties");
+const STYLE_INSPECTOR_L10N
+ = new LocalizationHelper("devtools-shared/locale/styleinspector.properties");
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.defaultColorUnit");
});
/**
* The rule-view tests rely on a frame-script to be injected in the content test
* page. So override the shared-head's addTab to load the frame script after the
--- a/devtools/client/inspector/shared/test/head.js
+++ b/devtools/client/inspector/shared/test/head.js
@@ -16,17 +16,18 @@ var {getInplaceEditorForSpan: inplaceEdi
const {getColor: getThemeColor} = require("devtools/client/shared/theme");
const TEST_URL_ROOT =
"http://example.com/browser/devtools/client/inspector/shared/test/";
const TEST_URL_ROOT_SSL =
"https://example.com/browser/devtools/client/inspector/shared/test/";
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
-const STYLE_INSPECTOR_L10N = new LocalizationHelper("chrome://devtools-shared/locale/styleinspector.properties");
+const STYLE_INSPECTOR_L10N =
+ new LocalizationHelper("devtools-shared/locale/styleinspector.properties");
// Clean-up all prefs that might have been changed during a test run
// (safer here because if the test fails, then the pref is never reverted)
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.defaultColorUnit");
});
/**
--- a/devtools/shared/l10n.js
+++ b/devtools/shared/l10n.js
@@ -3,27 +3,68 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const parsePropertiesFile = require("devtools/shared/node-properties/node-properties");
const { sprintf } = require("devtools/shared/sprintfjs/sprintf");
const propertiesMap = {};
+// We need some special treatment here for webpack.
+//
+// Webpack doesn't always handle dynamic requires in the best way. In
+// particular if it sees an unrestricted dynamic require, it will try
+// to put all the files it can find into the generated pack. (It can
+// also try a bit to parse the expression passed to require, but in
+// our case this doesn't work, because our call below doesn't provide
+// enough information.)
+//
+// Webpack also provides a way around this: require.context. The idea
+// here is to tell webpack some constraints so that it can include
+// fewer files in the pack.
+//
+// Here we introduce new require contexts for each possible locale
+// directory. Then we use the correct context to load the property
+// file. In the webpack case this results in just the locale property
+// files being included in the pack; and in the devtools case this is
+// a wordy no-op.
+const reqShared = require.context("raw!devtools-shared/locale/",
+ true, /^.*\.properties$/);
+const reqClient = require.context("raw!devtools/locale/",
+ true, /^.*\.properties$/);
+const reqGlobal = require.context("raw!global/locale/",
+ true, /^.*\.properties$/);
+
/**
* Memoized getter for properties files that ensures a given url is only required and
* parsed once.
*
* @param {String} url
* The URL of the properties file to parse.
* @return {Object} parsed properties mapped in an object.
*/
function getProperties(url) {
if (!propertiesMap[url]) {
- propertiesMap[url] = parsePropertiesFile(require(`raw!${url}`));
+ // See the comment above about webpack and require contexts. Here
+ // we take an input like "devtools-shared/locale/debugger.properties"
+ // and decide which context require function to use. Despite the
+ // string processing here, in the end a string identical to |url|
+ // ends up being passed to "require".
+ let index = url.lastIndexOf("/");
+ // Turn "mumble/locale/resource.properties" => "./resource.properties".
+ let baseName = "." + url.substr(index);
+ let reqFn;
+ if (/^global/.test(url)) {
+ reqFn = reqGlobal;
+ } else if (/^devtools-shared/.test(url)) {
+ reqFn = reqShared;
+ } else {
+ reqFn = reqClient;
+ }
+ propertiesMap[url] = parsePropertiesFile(reqFn(baseName));
}
return propertiesMap[url];
}
/**
* Localization convenience methods.
*