| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866 |
- 'use strict';
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
- var path = _interopDefault(require('path'));
- var through = _interopDefault(require('through2'));
- var PluginError = _interopDefault(require('plugin-error'));
- /*! *****************************************************************************
- Copyright (c) Microsoft Corporation.
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
- ***************************************************************************** */
- /* global Reflect, Promise */
- var extendStatics = function(d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- function __extends(d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- }
- function __values(o) {
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
- if (m) return m.call(o);
- if (o && typeof o.length === "number") return {
- next: function () {
- if (o && i >= o.length) o = void 0;
- return { value: o && o[i++], done: !o };
- }
- };
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
- }
- function __read(o, n) {
- var m = typeof Symbol === "function" && o[Symbol.iterator];
- if (!m) return o;
- var i = m.call(o), r, ar = [], e;
- try {
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
- }
- catch (error) { e = { error: error }; }
- finally {
- try {
- if (r && !r.done && (m = i["return"])) m.call(i);
- }
- finally { if (e) throw e.error; }
- }
- return ar;
- }
- function __spread() {
- for (var ar = [], i = 0; i < arguments.length; i++)
- ar = ar.concat(__read(arguments[i]));
- return ar;
- }
- var CharCodes;
- (function (CharCodes) {
- CharCodes[CharCodes["LEFT_CURLY_BRACE"] = 123] = "LEFT_CURLY_BRACE";
- CharCodes[CharCodes["RIGHT_CURLY_BRACE"] = 125] = "RIGHT_CURLY_BRACE";
- CharCodes[CharCodes["SINGLE_QUOTE"] = 39] = "SINGLE_QUOTE";
- CharCodes[CharCodes["DOUBLE_QUOTE"] = 34] = "DOUBLE_QUOTE";
- CharCodes[CharCodes["BACK_QUOTE"] = 96] = "BACK_QUOTE";
- CharCodes[CharCodes["BACK_SLASH"] = 92] = "BACK_SLASH";
- CharCodes[CharCodes["SLASH"] = 47] = "SLASH";
- CharCodes[CharCodes["LESS_THAN"] = 60] = "LESS_THAN";
- CharCodes[CharCodes["GREATER_THAN"] = 62] = "GREATER_THAN";
- CharCodes[CharCodes["MINUS"] = 45] = "MINUS";
- CharCodes[CharCodes["UNDER_LINE"] = 95] = "UNDER_LINE";
- CharCodes[CharCodes["EQUALS"] = 61] = "EQUALS";
- CharCodes[CharCodes["EXCLAMATION"] = 33] = "EXCLAMATION";
- CharCodes[CharCodes["COLON"] = 58] = "COLON";
- CharCodes[CharCodes["LEFT_PAREN"] = 40] = "LEFT_PAREN";
- CharCodes[CharCodes["RIGHT_PAREN"] = 41] = "RIGHT_PAREN";
- CharCodes[CharCodes["DOT"] = 46] = "DOT";
- CharCodes[CharCodes["ASTERISK"] = 42] = "ASTERISK";
- CharCodes[CharCodes["TAB"] = 9] = "TAB";
- CharCodes[CharCodes["LINE_FEED"] = 10] = "LINE_FEED";
- CharCodes[CharCodes["CARRIAGE_RETURN"] = 13] = "CARRIAGE_RETURN";
- CharCodes[CharCodes["SPACE"] = 32] = "SPACE";
- CharCodes[CharCodes["UPPER_A"] = 65] = "UPPER_A";
- CharCodes[CharCodes["UPPER_Z"] = 90] = "UPPER_Z";
- CharCodes[CharCodes["LOWER_A"] = 97] = "LOWER_A";
- CharCodes[CharCodes["LOWER_Z"] = 122] = "LOWER_Z";
- CharCodes[CharCodes["_0"] = 48] = "_0";
- CharCodes[CharCodes["_9"] = 57] = "_9";
- CharCodes[CharCodes["$"] = 36] = "$";
- })(CharCodes || (CharCodes = {}));
- var WXS_LITERAL = 'wxs';
- function isWhitespace(code) {
- // TODO: other whitespaces
- return CharCodes.SPACE === code ||
- CharCodes.TAB === code ||
- CharCodes.LINE_FEED === code ||
- CharCodes.CARRIAGE_RETURN === code;
- }
- function isLetter(code) {
- return (code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z) || // A-Z
- (code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z) || // a-z
- code === CharCodes.MINUS || // -
- code === CharCodes.UNDER_LINE; // _
- }
- function isNumber(code) {
- return code >= CharCodes._0 && code <= CharCodes._9; // 0-9
- }
- function isValidFunctionLiteralChar(code) {
- return isNumber(code) ||
- (code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z) ||
- (code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z) ||
- code === CharCodes.UNDER_LINE ||
- code === CharCodes.$;
- }
- var Parser = /** @class */ (function () {
- function Parser(source, fileName) {
- this.source = source;
- this.fileName = fileName;
- this.pos = 0;
- this.line = 1;
- this.column = 1;
- }
- Parser.prototype.consumeChar = function () {
- var ch = this.source.charCodeAt(this.pos);
- this.advance();
- return ch;
- };
- Parser.prototype.consumeQuoteString = function (resultRef) {
- if (resultRef === void 0) { resultRef = {}; }
- var start = this.pos;
- if (this.match(CharCodes.SINGLE_QUOTE) || this.match(CharCodes.DOUBLE_QUOTE) || this.match(CharCodes.BACK_QUOTE)) {
- var quoteType = this.consumeChar();
- while (!this.eof() && !this.match(quoteType)) {
- if (this.match(CharCodes.BACK_SLASH) && this.match(quoteType, this.pos + 1)) {
- this.advance(2);
- }
- else
- this.advance();
- }
- if (this.match(quoteType))
- this.advance();
- resultRef.result = this.source.substring(start, this.pos);
- return true;
- }
- return false;
- };
- Parser.prototype.advance = function (step) {
- var _this = this;
- var _advanceOnce = function () {
- if (_this.source[_this.pos] === '\n') {
- _this.column = 1;
- _this.line++;
- }
- else {
- _this.column++;
- }
- _this.pos++;
- };
- if (!step) {
- _advanceOnce();
- }
- else {
- while (step-- > 0)
- _advanceOnce();
- }
- };
- Parser.prototype.eof = function () {
- return this.pos >= this.source.length;
- };
- Parser.prototype.match = function (code, pos) {
- return this.source.charCodeAt(pos && pos !== -1 ? pos : this.pos) === code;
- };
- Parser.prototype.currentChar = function () {
- return this.source[this.pos];
- };
- Parser.prototype.peekCharCode = function () {
- return this.source.charCodeAt(this.pos);
- };
- Parser.prototype.consumeWhitespace = function () {
- this.consumeWhile(isWhitespace);
- };
- Parser.prototype.consumeWhile = function (checkFunc) {
- var result = [];
- while (!this.eof() && checkFunc(this.source.charCodeAt(this.pos))) {
- var ch = this.source[this.pos];
- this.advance();
- result.push(ch);
- }
- return result.join('');
- };
- Parser.prototype.currentContext = function () {
- var MAX_NEXT_LINE = 2;
- var answer = '';
- var _pos = this.pos - 1, accumulateNextLine = 0;
- while (_pos >= 0 && accumulateNextLine < MAX_NEXT_LINE + 2) {
- if (this.source[_pos] === '\n') {
- accumulateNextLine++;
- }
- answer = this.source[_pos] + answer;
- _pos--;
- }
- if (this.pos < this.source.length) {
- answer += this.source[this.pos];
- }
- _pos = this.pos + 1, accumulateNextLine = 0;
- while (_pos < this.source.length && accumulateNextLine < MAX_NEXT_LINE) {
- if (this.source[_pos] === '\n') {
- accumulateNextLine++;
- }
- answer += this.source[_pos];
- _pos++;
- }
- return answer;
- };
- return Parser;
- }());
- var Expression = /** @class */ (function () {
- function Expression(start, end, expression) {
- if (start === void 0) { start = 0; }
- if (end === void 0) { end = 0; }
- if (expression === void 0) { expression = ''; }
- this.start = start;
- this.end = end;
- this.expression = expression;
- }
- return Expression;
- }());
- var CallExpression = /** @class */ (function (_super) {
- __extends(CallExpression, _super);
- function CallExpression(start, end, expression, functionNameStart, functionNameEnd, parameters, childFunctionExpressions) {
- if (start === void 0) { start = 0; }
- if (end === void 0) { end = 0; }
- if (expression === void 0) { expression = ''; }
- if (functionNameStart === void 0) { functionNameStart = 0; }
- if (functionNameEnd === void 0) { functionNameEnd = 0; }
- if (parameters === void 0) { parameters = ''; }
- if (childFunctionExpressions === void 0) { childFunctionExpressions = []; }
- var _this = _super.call(this, start, end, expression) || this;
- _this.functionNameStart = functionNameStart;
- _this.functionNameEnd = functionNameEnd;
- _this.parameters = parameters;
- _this.childFunctionExpressions = childFunctionExpressions;
- return _this;
- }
- return CallExpression;
- }(Expression));
- /**
- * ExpressionParser helps parsing expressions inside wxml interpolation block
- */
- var ExpressionParser = /** @class */ (function (_super) {
- __extends(ExpressionParser, _super);
- function ExpressionParser(source, fileName) {
- if (fileName === void 0) { fileName = ''; }
- var _this = _super.call(this, source, fileName) || this;
- _this.source = source;
- _this.fileName = fileName;
- _this.blockStart = -1;
- _this.expressions = [];
- _this.callExpressions = [];
- return _this;
- }
- ExpressionParser.prototype.parse = function () {
- try {
- var expr = this._parse();
- return expr;
- }
- catch (e) {
- if (this.fileName) {
- e.message += "\nfile: " + this.fileName;
- }
- e.message += "\nline: " + this.line + ", column: " + this.column + "\n\n" + this.currentContext();
- throw e;
- }
- };
- ExpressionParser.prototype._parse = function () {
- while (!this.eof()) {
- if (this.match(CharCodes.LEFT_CURLY_BRACE) && this.match(CharCodes.LEFT_CURLY_BRACE, this.pos + 1)) {
- this.advance(2);
- this.enterInterpolationBlock();
- // TODO: parse function calls and pass it to transfomers
- this.parseInterpolationExpression();
- continue;
- }
- this.advance();
- }
- return { expression: this.expressions, callExpressions: this.callExpressions };
- };
- /**
- * Parse expressions in wxml, it only cares about function calls
- * and ignore other expressions since it's trivial for i18n
- */
- ExpressionParser.prototype.parseInterpolationExpression = function () {
- while (!this.eof()) {
- this.consumeQuoteString();
- if (this.match(CharCodes.RIGHT_CURLY_BRACE) && this.match(CharCodes.RIGHT_CURLY_BRACE, this.pos + 1)) {
- var _a = this.exitInterpolationBlock(), start = _a.start, end = _a.end, block = _a.block;
- this.advance(2);
- if (end > start && start !== -1) {
- this.expressions.push(new Expression(start, end, block));
- }
- return;
- }
- // maybe function call expression
- if (this.match(CharCodes.LEFT_PAREN)) {
- var start = this.isFunctionCallExpression(this.pos);
- if (start !== -1) {
- var exprs = this.parseFunctionCallExpression(start);
- this.callExpressions.push(exprs);
- continue;
- }
- }
- this.advance();
- }
- };
- ExpressionParser.prototype.parseObjectDecl = function () {
- var callFunctions = [];
- while (!this.eof()) {
- this.consumeQuoteString();
- if (this.match(CharCodes.RIGHT_CURLY_BRACE)) {
- this.advance();
- return callFunctions;
- }
- if (this.match(CharCodes.LEFT_PAREN)) {
- var start = this.isFunctionCallExpression(this.pos);
- if (start !== -1) {
- var expr = this.parseFunctionCallExpression(start);
- callFunctions.push(expr);
- }
- }
- if (this.match(CharCodes.LEFT_CURLY_BRACE)) {
- this.advance();
- callFunctions.push.apply(callFunctions, __spread(this.parseObjectDecl()));
- continue;
- }
- this.advance();
- }
- return callFunctions;
- };
- ExpressionParser.prototype.parseFunctionCallExpression = function (start) {
- var childFunctions = [];
- var functionNameEnd = this.pos;
- if (this.consumeChar() !== CharCodes.LEFT_PAREN) {
- throw new Error('expected a left paren for a function call');
- }
- while (!this.eof()) {
- this.consumeQuoteString();
- if (this.match(CharCodes.LEFT_CURLY_BRACE)) {
- // JavaScript block should be ignored
- this.advance();
- var expr = this.parseObjectDecl();
- childFunctions.push.apply(childFunctions, __spread(expr));
- }
- if (this.consumeChar() === CharCodes.RIGHT_PAREN) {
- break;
- }
- }
- return new CallExpression(start, this.pos, this.source.substring(start, functionNameEnd), start, functionNameEnd, this.source.substring(functionNameEnd + 1, this.pos - 1).trim(), childFunctions);
- };
- ExpressionParser.prototype.enterInterpolationBlock = function () {
- // Already in an translation block, this must not be
- // valid translation block
- if (this.blockStart !== -1)
- return;
- this.blockStart = this.pos;
- };
- ExpressionParser.prototype.exitInterpolationBlock = function () {
- var start = this.blockStart;
- var end = this.pos;
- var block = this.source.substring(start, end);
- this.blockStart = -1;
- return { start: start, end: end, block: block };
- };
- ExpressionParser.prototype.matchNextChar = function (code) {
- return this.source.charCodeAt(++this.pos) === code;
- };
- ExpressionParser.prototype.isFunctionCallExpression = function (pos) {
- while (--pos >= 0) {
- // maybe wxs call {{ a.b() }}
- if (this.match(CharCodes.DOT, pos))
- return -1;
- if (!isValidFunctionLiteralChar(this.source.charCodeAt(pos)))
- break;
- }
- return pos + 1;
- };
- return ExpressionParser;
- }(Parser));
- var parse = require('format-message-parse');
- var Node = /** @class */ (function () {
- function Node(tagName) {
- this.tagName = tagName;
- }
- Node.prototype.dump = function () {
- return { type: this.tagName };
- };
- return Node;
- }());
- var AttributeValue = /** @class */ (function () {
- function AttributeValue(value, start, end) {
- this.value = value;
- this.start = start;
- this.end = end;
- }
- return AttributeValue;
- }());
- var Element = /** @class */ (function (_super) {
- __extends(Element, _super);
- function Element(tagName, attributes, children) {
- var _this = _super.call(this, tagName) || this;
- _this.attributes = attributes;
- _this.children = children;
- return _this;
- }
- Element.prototype.dump = function () {
- var e_1, _a;
- var attributes = {};
- if (this.attributes) {
- try {
- for (var _b = __values(this.attributes), _c = _b.next(); !_c.done; _c = _b.next()) {
- var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
- if (value && value.value) {
- attributes[key] = value.value;
- }
- else {
- attributes[key] = null;
- }
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
- }
- finally { if (e_1) throw e_1.error; }
- }
- }
- var children = this.children.map(function (child) { return child.dump(); });
- return { type: this.tagName, attributes: attributes, children: children };
- };
- return Element;
- }(Node));
- var Text = /** @class */ (function (_super) {
- __extends(Text, _super);
- function Text(content, start, end) {
- var _this = _super.call(this, Text.tagName) || this;
- _this.content = content;
- _this.start = start;
- _this.end = end;
- return _this;
- }
- Text.prototype.dump = function () {
- return { type: this.tagName, content: this.content };
- };
- Text.tagName = 'text';
- return Text;
- }(Node));
- var WxmlState;
- (function (WxmlState) {
- WxmlState[WxmlState["NORMAL"] = 1] = "NORMAL";
- WxmlState[WxmlState["WXS"] = 2] = "WXS";
- WxmlState[WxmlState["INT"] = 4] = "INT";
- })(WxmlState || (WxmlState = {}));
- /**
- * Simple wxml parser
- */
- var WxmlParser = /** @class */ (function (_super) {
- __extends(WxmlParser, _super);
- function WxmlParser(source, fileName) {
- if (fileName === void 0) { fileName = ''; }
- var _this = _super.call(this, source, fileName) || this;
- _this.source = source;
- _this.fileName = fileName;
- _this.state = WxmlState.NORMAL;
- return _this;
- }
- WxmlParser.prototype.parse = function () {
- try {
- var nodes = this._parse();
- return nodes;
- }
- catch (e) {
- if (this.fileName) {
- e.message += "\nfile: " + this.fileName;
- }
- e.message += "\nline: " + this.line + ", column: " + this.column + "\n\n" + this.currentContext();
- throw e;
- }
- };
- WxmlParser.prototype._parse = function () {
- var nodes = [];
- while (!this.eof()) {
- this.consumeWhitespace();
- if (this.match(CharCodes.LESS_THAN) && this.match(CharCodes.SLASH, this.pos + 1)) {
- break;
- }
- // Ignore comments
- if (this.match(CharCodes.LESS_THAN, this.pos) &&
- this.match(CharCodes.EXCLAMATION, this.pos + 1) &&
- this.match(CharCodes.MINUS, this.pos + 2) &&
- this.match(CharCodes.MINUS, this.pos + 3)) {
- this.advance(4);
- this.parseComments();
- continue;
- }
- if (this.match(CharCodes.LESS_THAN)) {
- var node = this.parseWxmlTag();
- nodes.push(node);
- continue;
- }
- var textNode = this.parseText();
- if (textNode.content.length > 0)
- nodes.push(textNode);
- }
- return nodes;
- };
- WxmlParser.prototype.parseWxmlTag = function () {
- if (this.consumeChar() !== CharCodes.LESS_THAN) {
- throw new Error('unexpected character for wxml start tag');
- }
- this.consumeWhitespace();
- var tagName = this.parseTagName();
- if (!tagName || tagName.length === 0) {
- throw new Error("unexpected tag name " + this.currentChar());
- }
- var attributes = this.parseAttributes();
- // self-closing tag
- if (this.match(CharCodes.SLASH)) {
- this.advance();
- if (this.consumeChar() !== CharCodes.GREATER_THAN) {
- throw new Error('unexpected character ' + this.currentChar());
- }
- return new Element(tagName, attributes, []);
- }
- if (this.consumeChar() !== CharCodes.GREATER_THAN) {
- throw new Error('expected character > to close a tag');
- }
- if (tagName.toLowerCase() === WXS_LITERAL) {
- this.state = WxmlState.WXS;
- }
- var childNodes = this.parse();
- if (this.consumeChar() !== CharCodes.LESS_THAN) {
- throw new Error('expected char ' + String.fromCharCode(CharCodes.LESS_THAN) + ' but got ' + this.currentChar());
- }
- if (this.consumeChar() !== CharCodes.SLASH) {
- throw new Error('expected char ' + String.fromCharCode(CharCodes.SLASH) + ' but got ' + this.currentChar());
- }
- this.consumeWhitespace();
- var endTagName = this.parseTagName();
- if (endTagName !== tagName) {
- throw new Error("expected tag name " + tagName + " but got " + endTagName);
- }
- this.consumeWhitespace();
- if (!this.match(CharCodes.GREATER_THAN)) {
- throw new Error('expected char ' + String.fromCharCode(CharCodes.GREATER_THAN) + ' but got ' + this.currentChar());
- }
- this.advance();
- if (tagName.toLowerCase() === WXS_LITERAL) {
- this.state = WxmlState.NORMAL;
- }
- return new Element(tagName, attributes, childNodes);
- };
- WxmlParser.prototype.parseText = function () {
- var start = this.pos;
- if (this.state === WxmlState.WXS) {
- while (!this.eof() && !(this.match(CharCodes.LESS_THAN) && this.match(CharCodes.SLASH, this.pos + 1))) {
- if (!this.consumeQuoteString() && !this.consumeWXSComments()) {
- this.advance();
- }
- }
- return new Text(this.source.substring(start, this.pos), start, this.pos);
- }
- return new Text(this.parseTextContents(), start, this.pos);
- };
- WxmlParser.prototype.parseTextContents = function () {
- var result = [];
- while (!this.eof() && (!this.match(CharCodes.LESS_THAN) || this.state === WxmlState.INT)) {
- if (this.match(CharCodes.LEFT_CURLY_BRACE) && this.match(CharCodes.LEFT_CURLY_BRACE, this.pos + 1)) {
- this.state = WxmlState.INT;
- }
- if (this.match(CharCodes.RIGHT_CURLY_BRACE) && this.match(CharCodes.RIGHT_CURLY_BRACE, this.pos + 1)) {
- this.state = WxmlState.NORMAL;
- }
- var quoteStringRef = { result: '' };
- if (this.consumeQuoteString(quoteStringRef)) {
- result.push(quoteStringRef.result);
- continue;
- }
- var ch = this.source[this.pos];
- result.push(ch);
- this.advance();
- }
- return result.join('');
- };
- /**
- * Ignore comments
- */
- WxmlParser.prototype.parseComments = function () {
- while (!this.eof()) {
- if (this.match(CharCodes.MINUS, this.pos) &&
- this.match(CharCodes.MINUS, this.pos + 1) &&
- this.match(CharCodes.GREATER_THAN, this.pos + 2)) {
- this.advance(3);
- return;
- }
- this.advance();
- }
- };
- WxmlParser.prototype.parseTagName = function () {
- // loosy check
- // TODO: prevent number as first letter
- return this.consumeWhile(function (c) { return isLetter(c) || isNumber(c); });
- };
- WxmlParser.prototype.parseAttributeName = function () {
- // loosy check
- // TODO: prevent number as first letter
- // Note: can have colon (:) in between
- return this.consumeWhile(function (c) { return isLetter(c) || isNumber(c) || c === CharCodes.COLON; });
- };
- WxmlParser.prototype.parseAttributes = function () {
- var attrs = new Map();
- while (!this.eof()) {
- this.consumeWhitespace();
- if (this.match(CharCodes.SLASH) || this.match(CharCodes.GREATER_THAN))
- break;
- if (!isLetter(this.peekCharCode()) && !this.match(CharCodes.COLON))
- break;
- var _a = this.parseAttribute(), name = _a.name, value = _a.value;
- attrs.set(name, value);
- }
- return attrs;
- };
- WxmlParser.prototype.parseAttribute = function () {
- var name = this.parseAttributeName();
- this.consumeWhitespace();
- if (!this.match(CharCodes.EQUALS)) {
- return { name: name, value: null };
- }
- this.advance();
- this.consumeWhitespace();
- var value = this.parseAttrValue();
- return { name: name, value: value };
- };
- WxmlParser.prototype.parseAttrValue = function () {
- var leftQuote = this.consumeChar();
- var start = this.pos;
- if (leftQuote !== CharCodes.SINGLE_QUOTE && leftQuote !== CharCodes.DOUBLE_QUOTE) {
- throw new Error("expected char " + String.fromCharCode(CharCodes.SINGLE_QUOTE) + " or " + String.fromCharCode(CharCodes.DOUBLE_QUOTE) + " " +
- ("but got " + String.fromCharCode(leftQuote)));
- }
- var value = this.consumeWhile(function (ch) { return ch !== leftQuote; });
- var end = this.pos;
- if (this.consumeChar() !== leftQuote) {
- throw new Error('expected char ' + String.fromCharCode(leftQuote) + ' to close an attribute');
- }
- var attribute = new AttributeValue(value, start, end);
- return attribute;
- };
- WxmlParser.prototype.consumeWXSComments = function () {
- if (this.match(CharCodes.SLASH) && this.match(CharCodes.SLASH, this.pos + 1)) {
- while (!this.eof()) {
- if (this.match(CharCodes.LINE_FEED)) {
- this.advance();
- break;
- }
- if (this.match(CharCodes.CARRIAGE_RETURN) && this.match(CharCodes.LINE_FEED)) {
- this.advance(2);
- break;
- }
- // If no line end is met we should end at this point
- if (this.match(CharCodes.LESS_THAN) && this.match(CharCodes.SLASH, this.pos + 1)) {
- return false;
- }
- this.advance();
- }
- return true;
- }
- else if (this.match(CharCodes.SLASH) && this.match(CharCodes.ASTERISK, this.pos + 1)) {
- while (!this.eof()) {
- if (this.match(CharCodes.ASTERISK) && this.match(CharCodes.SLASH, this.pos + 1)) {
- this.advance(2);
- break;
- }
- this.advance();
- }
- return true;
- }
- return false;
- };
- return WxmlParser;
- }(Parser));
- var TranslationFunction;
- (function (TranslationFunction) {
- TranslationFunction["default"] = "t";
- })(TranslationFunction || (TranslationFunction = {}));
- var I18nModuleName;
- (function (I18nModuleName) {
- I18nModuleName["default"] = "i18n";
- })(I18nModuleName || (I18nModuleName = {}));
- var LocaleVariable;
- (function (LocaleVariable) {
- LocaleVariable["default"] = "$_locale";
- })(LocaleVariable || (LocaleVariable = {}));
- var BLOCK_DELIMITER_START = '{{';
- /**
- * Transform miniprogram templates (WXML) to import i18n data and transform i18n invocations
- * i18n data will be imported via WXS mechanism while i18n invocations will be transformed
- * to normal WXS calls, e.g. t(key, val) will be transformed to something like $i18n.t(key, val)
- */
- var TranslationFunctionTransformer = /** @class */ (function () {
- function TranslationFunctionTransformer(translationFunctionName, i18nModuleName, currentLocaleVariableName) {
- if (translationFunctionName === void 0) { translationFunctionName = TranslationFunction.default; }
- if (i18nModuleName === void 0) { i18nModuleName = I18nModuleName.default; }
- if (currentLocaleVariableName === void 0) { currentLocaleVariableName = LocaleVariable.default; }
- this.translationFunctionName = translationFunctionName;
- this.i18nModuleName = i18nModuleName;
- this.currentLocaleVariableName = currentLocaleVariableName;
- this.source = '';
- }
- /**
- * Given a piece of wxml source code, transform its i18n function calls into normal wxs function calls
- */
- TranslationFunctionTransformer.prototype.transform = function (source, fileName) {
- if (fileName === void 0) { fileName = ''; }
- this.source = source;
- var parser = new WxmlParser(source, fileName);
- var nodes = parser.parse();
- // Transform function call expressions in place
- this.transformNodes(nodes, fileName);
- return this.source;
- };
- TranslationFunctionTransformer.prototype.transformNodes = function (nodes, fileName) {
- var e_1, _a;
- // walk through wxml nodes to pick up interpolation blocks
- for (var i = nodes.length - 1; i >= 0; i--) {
- var node = nodes[i];
- if (node instanceof Text) {
- if (node.content.includes(BLOCK_DELIMITER_START)) {
- var _b = this.transformFunctionCallExpr(node.content, fileName), content = _b.content, transformed = _b.transformed;
- if (transformed) {
- var head = this.source.substring(0, node.start);
- var rear = this.source.substring(node.end);
- this.source = head + content + rear;
- }
- }
- }
- else if (node instanceof Element) {
- this.transformNodes(node.children, fileName);
- var attributes = this.sortAttributesByStartPos(node.attributes);
- try {
- for (var attributes_1 = (e_1 = void 0, __values(attributes)), attributes_1_1 = attributes_1.next(); !attributes_1_1.done; attributes_1_1 = attributes_1.next()) {
- var attrValue = attributes_1_1.value;
- if (attrValue && attrValue.value.includes(BLOCK_DELIMITER_START)) {
- var _c = this.transformFunctionCallExpr(attrValue.value, fileName), content = _c.content, transformed = _c.transformed;
- if (transformed) {
- var head = this.source.substring(0, attrValue.start);
- var rear = this.source.substring(attrValue.end);
- this.source = head + content + rear;
- }
- }
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (attributes_1_1 && !attributes_1_1.done && (_a = attributes_1.return)) _a.call(attributes_1);
- }
- finally { if (e_1) throw e_1.error; }
- }
- }
- }
- };
- TranslationFunctionTransformer.prototype.transformFunctionCallExpr = function (source, fileName) {
- var parser = new ExpressionParser(source, fileName);
- var expr = parser.parse();
- return this.transformFunctionCallExprRecursively(source, expr.callExpressions);
- };
- TranslationFunctionTransformer.prototype.transformFunctionCallExprRecursively = function (source, callExpressions) {
- var transformed = false;
- for (var i = callExpressions.length - 1; i >= 0; i--) {
- var callExpr = callExpressions[i];
- if (callExpr.expression === this.translationFunctionName) {
- // Inject currentLocale variable
- var end = callExpr.end - 1;
- var localeVarDecl = callExpr.parameters.length > 0 ? ", " + this.currentLocaleVariableName : this.currentLocaleVariableName;
- source = source.substring(0, end) + localeVarDecl + source.substring(end);
- var child = this.transformFunctionCallExprRecursively(source, callExpr.childFunctionExpressions);
- transformed = transformed || child.transformed;
- source = child.content;
- var head = source.substring(0, callExpr.functionNameStart);
- var rear = source.substring(callExpr.functionNameEnd);
- source = head + this.i18nModuleName + '.' + TranslationFunction.default + rear;
- transformed = true;
- }
- }
- return { transformed: transformed, content: source };
- };
- TranslationFunctionTransformer.prototype.sortAttributesByStartPos = function (attributes) {
- // descendent
- return Array.from(attributes.values()).filter(function (a) { return !!a; }).sort(function (a, b) { return b.start - a.start; });
- };
- return TranslationFunctionTransformer;
- }());
- var PLUGIN_NAME = '@miniprogram-i18n/gulp-i18n-wxml';
- // Assume source folder is src
- var DEFAULT_WXS_PATH = path.resolve('src/i18n/locales.wxs');
- var getWxsTag = function (path$$1, moduleName) { return "<wxs src=\"" + path$$1 + "\" module=\"" + moduleName + "\" />\n"; };
- var gulpI18nWxmlTransformer = function (options) { return through.obj(function (file, _, cb) {
- var opts = options || { wxsPath: '', wxsModuleName: '', i18nFunctionName: '' };
- var wxsPath = opts.wxsPath || DEFAULT_WXS_PATH;
- var wxsModuleName = opts.wxsModuleName || I18nModuleName.default;
- var i18nFunctionName = opts.i18nFunctionName || TranslationFunction.default;
- // Ignore empty file or not wxml files
- if (file.isNull() || path.extname(file.path) !== '.wxml') {
- return cb(null, file);
- }
- if (file.isStream()) {
- return cb(new PluginError(PLUGIN_NAME, 'Streaming data is not supported'));
- }
- // TODO: read functionn name from options
- var transfomer = new TranslationFunctionTransformer(i18nFunctionName, wxsModuleName);
- if (!file.contents) {
- return cb(null, file);
- }
- try {
- var transformedContents = transfomer.transform(file.contents.toString('utf-8'), file.path);
- var relativeWxsPath = path.relative(path.dirname(file.path), wxsPath);
- if (process.platform === 'win32') {
- relativeWxsPath = relativeWxsPath.replace(/\\/g, '/');
- }
- var wxsTag = getWxsTag(relativeWxsPath, wxsModuleName);
- if (transformedContents.indexOf(wxsTag) !== -1) {
- // has already write wxs tag into wxml.
- file.contents = Buffer.from(transformedContents);
- return cb(null, file);
- }
- file.contents = Buffer.concat([Buffer.from(wxsTag), Buffer.from(transformedContents)]);
- }
- catch (err) {
- console.log('error:', err);
- return cb(new PluginError(PLUGIN_NAME, err));
- }
- return cb(null, file);
- }); };
- module.exports = gulpI18nWxmlTransformer;
|