diff --git a/.gitignore b/.gitignore index 015a031..0de9aaf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,3 @@ node_modules/ .idea .sass-cache *.map -js/lang.js diff --git a/dump_js_lang.php b/dump_js_lang.php deleted file mode 100755 index 80196de..0000000 --- a/dump_js_lang.php +++ /dev/null @@ -1,28 +0,0 @@ - match[1]) + } else { + // double-quoted string + // \n -> 0x0A + // \r -> 0x0D + // \t -> 0x09 + // \v -> 0x0B + // \e -> 0x1B + // \f -> 0x0C + // \\ -> \ + // \$ -> $ + // \" -> " + // \[0-7]{1,3} -> char + // \x[\da-f]{1,2} -> char + // \u{[\da-f]+} -> char + let content = token.content + content = content.replace(/\\[nrtvef\\$"]/g, match => match[1]) + content = content.replace(/\\[0-7]{1,3}/g, match => { + return String.fromCodePoint(parseInt(match.substr(1), 8) % 0xFF) + }) + content = content.replace(/\\x[\da-f]{1,2}/ig, match => { + return String.fromCodePoint(parseInt(match.substr(1), 16) % 0xFF) + }) + content = content.replace(/\\u{[\da-f]+}/ig, match => { + return String.fromCodePoint(parseInt(match.substr(1), 16)) + }) + return content + } +} + +module.exports = function (source) { + let originalSource = source + + // remove PHP header + source = source.replace(/^\s*<\?(?:php)?\s*/, '') + + // remove return statement + source = source.replace(/^return\s*/, '') + + // remove trailing semicolon + source = source.replace(/;\s*$/, '') + + // strings + let tokens = tokenizeRest([source], tokenizers.simpleType, /(['"])((?:\\.|[^\\\1])*?)\1/, 'string', 2) + + // comments + tokenizeRest(tokens, tokenizers.simpleType, /\/\/(.*)/, 'comment') + + // map delimiters + tokenizeRest(tokens, tokenizers.simpleType, /([[\]])/, 'map') + + // arrows + tokenizeRest(tokens, tokenizers.simpleType, /(=>)/, 'arrow') + + // commas + tokenizeRest(tokens, tokenizers.simpleType, /(,)/, 'comma') + + // whitespace + tokenizeRest(tokens, tokenizers.simpleType, /(\s+)/, 'whitespace') + + // remove whitespace tokens and comments + tokens = tokens.filter(token => !(['whitespace', 'comment'].includes(token.type))) + + // split tokens into an array of items, separated by commas + let currentItem = [] + let items = [currentItem] + + for (let token of tokens) { + let { type } = token + + if (type === 'map') continue + if (type === 'comma') items.push(currentItem = []) + else currentItem.push(token) + } + + // remove null items + items = items.filter(item => item.length) + + // assume that every item will contain [string, arrow, string] and create + // an object + let data = {} + + for (let item of items) { + let key = item[0] + let value = item[2] + + if (!key || !value) { + console.error('Item has no key or value!', item) + continue + } + + data[unescapeString(key)] = unescapeString(value) + } + + let result = {} + + // put selected keys in result + for (let key of selectedKeys) { + result[key] = data[key] + } + + // adapted from webpack/loader-utils + let remainingRequest = this.remainingRequest + if (!remainingRequest) { + remainingRequest = this.loaders.slice(this.loaderIndex + 1) + .map(obj => obj.request) + .concat([this.resource]).join('!') + } + + let currentRequest = this.currentRequest + if (!currentRequest) { + remainingRequest = this.loaders.slice(this.loaderIndex) + .map(obj => obj.request) + .concat([this.resource]).join('!') + } + + let map = { + version: 3, + file: currentRequest, + sourceRoot: '', + sources: [remainingRequest], + sourcesContent: [originalSource], + names: [], + mappings: 'AAAA;AAAA' + } + + this.callback(null, `/* Generated language file */ +module.exports=${JSON.stringify(result)}`, map) +} diff --git a/webpack.config.js b/webpack.config.js index e332745..94b9866 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,6 +20,13 @@ plugins.push(new webpack.optimize.UglifyJsPlugin({ sourceMap: devtool === 'source-map' })) +// replace "locale-data" with path to locale data +let locale = process.env.LOCALE || 'en' +plugins.push(new webpack.NormalModuleReplacementPlugin( + /^locale-data$/, + path.resolve(`lang/${locale}.php`) +)) + module.exports = { entry: './js', output: { @@ -34,6 +41,10 @@ module.exports = { path.resolve(__dirname, 'node_modules') ], loader: 'babel-loader' + }, + { + test: /lang\/.+?\.php$/, + loader: './lang/lang-loader.js' } ] },