translation-function-transformer.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. "use strict";
  2. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
  3. if (k2 === undefined) k2 = k;
  4. Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  5. }) : (function(o, m, k, k2) {
  6. if (k2 === undefined) k2 = k;
  7. o[k2] = m[k];
  8. }));
  9. var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
  10. Object.defineProperty(o, "default", { enumerable: true, value: v });
  11. }) : function(o, v) {
  12. o["default"] = v;
  13. });
  14. var __importStar = (this && this.__importStar) || function (mod) {
  15. if (mod && mod.__esModule) return mod;
  16. var result = {};
  17. if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  18. __setModuleDefault(result, mod);
  19. return result;
  20. };
  21. var __values = (this && this.__values) || function(o) {
  22. var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
  23. if (m) return m.call(o);
  24. if (o && typeof o.length === "number") return {
  25. next: function () {
  26. if (o && i >= o.length) o = void 0;
  27. return { value: o && o[i++], done: !o };
  28. }
  29. };
  30. throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
  31. };
  32. var __importDefault = (this && this.__importDefault) || function (mod) {
  33. return (mod && mod.__esModule) ? mod : { "default": mod };
  34. };
  35. Object.defineProperty(exports, "__esModule", { value: true });
  36. exports.TranslationFunctionTransformer = void 0;
  37. var wxml_parser_1 = __importStar(require("../parser/wxml-parser"));
  38. var expression_parser_1 = __importDefault(require("../parser/expression-parser"));
  39. var BLOCK_DELIMITER_START = '{{';
  40. /**
  41. * Transform miniprogram templates (WXML) to import i18n data and transform i18n invocations
  42. * i18n data will be imported via WXS mechanism while i18n invocations will be transformed
  43. * to normal WXS calls, e.g. t(key, val) will be transformed to something like $i18n.t(key, val)
  44. */
  45. var TranslationFunctionTransformer = /** @class */ (function () {
  46. function TranslationFunctionTransformer(translationFunctionName, i18nModuleName, currentLocaleVariableName) {
  47. if (translationFunctionName === void 0) { translationFunctionName = "t" /* default */; }
  48. if (i18nModuleName === void 0) { i18nModuleName = "i18n" /* default */; }
  49. if (currentLocaleVariableName === void 0) { currentLocaleVariableName = "$_locale" /* default */; }
  50. this.translationFunctionName = translationFunctionName;
  51. this.i18nModuleName = i18nModuleName;
  52. this.currentLocaleVariableName = currentLocaleVariableName;
  53. this.source = '';
  54. }
  55. /**
  56. * Given a piece of wxml source code, transform its i18n function calls into normal wxs function calls
  57. */
  58. TranslationFunctionTransformer.prototype.transform = function (source, fileName) {
  59. if (fileName === void 0) { fileName = ''; }
  60. this.source = source;
  61. var parser = new wxml_parser_1.default(source, fileName);
  62. var nodes = parser.parse();
  63. // Transform function call expressions in place
  64. this.transformNodes(nodes, fileName);
  65. return this.source;
  66. };
  67. TranslationFunctionTransformer.prototype.transformNodes = function (nodes, fileName) {
  68. var e_1, _a;
  69. // walk through wxml nodes to pick up interpolation blocks
  70. for (var i = nodes.length - 1; i >= 0; i--) {
  71. var node = nodes[i];
  72. if (node instanceof wxml_parser_1.Text) {
  73. if (node.content.includes(BLOCK_DELIMITER_START)) {
  74. var _b = this.transformFunctionCallExpr(node.content, fileName), content = _b.content, transformed = _b.transformed;
  75. if (transformed) {
  76. var head = this.source.substring(0, node.start);
  77. var rear = this.source.substring(node.end);
  78. this.source = head + content + rear;
  79. }
  80. }
  81. }
  82. else if (node instanceof wxml_parser_1.Element) {
  83. this.transformNodes(node.children, fileName);
  84. var attributes = this.sortAttributesByStartPos(node.attributes);
  85. try {
  86. 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()) {
  87. var attrValue = attributes_1_1.value;
  88. if (attrValue && attrValue.value.includes(BLOCK_DELIMITER_START)) {
  89. var _c = this.transformFunctionCallExpr(attrValue.value, fileName), content = _c.content, transformed = _c.transformed;
  90. if (transformed) {
  91. var head = this.source.substring(0, attrValue.start);
  92. var rear = this.source.substring(attrValue.end);
  93. this.source = head + content + rear;
  94. }
  95. }
  96. }
  97. }
  98. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  99. finally {
  100. try {
  101. if (attributes_1_1 && !attributes_1_1.done && (_a = attributes_1.return)) _a.call(attributes_1);
  102. }
  103. finally { if (e_1) throw e_1.error; }
  104. }
  105. }
  106. }
  107. };
  108. TranslationFunctionTransformer.prototype.transformFunctionCallExpr = function (source, fileName) {
  109. var parser = new expression_parser_1.default(source, fileName);
  110. var expr = parser.parse();
  111. return this.transformFunctionCallExprRecursively(source, expr.callExpressions);
  112. };
  113. TranslationFunctionTransformer.prototype.transformFunctionCallExprRecursively = function (source, callExpressions) {
  114. var transformed = false;
  115. for (var i = callExpressions.length - 1; i >= 0; i--) {
  116. var callExpr = callExpressions[i];
  117. if (callExpr.expression === this.translationFunctionName) {
  118. // Inject currentLocale variable
  119. var end = callExpr.end - 1;
  120. var localeVarDecl = callExpr.parameters.length > 0 ? ", " + this.currentLocaleVariableName : this.currentLocaleVariableName;
  121. source = source.substring(0, end) + localeVarDecl + source.substring(end);
  122. var child = this.transformFunctionCallExprRecursively(source, callExpr.childFunctionExpressions);
  123. transformed = transformed || child.transformed;
  124. source = child.content;
  125. var head = source.substring(0, callExpr.functionNameStart);
  126. var rear = source.substring(callExpr.functionNameEnd);
  127. source = head + this.i18nModuleName + '.' + "t" /* default */ + rear;
  128. transformed = true;
  129. }
  130. }
  131. return { transformed: transformed, content: source };
  132. };
  133. TranslationFunctionTransformer.prototype.sortAttributesByStartPos = function (attributes) {
  134. // descendent
  135. return Array.from(attributes.values()).filter(function (a) { return !!a; }).sort(function (a, b) { return b.start - a.start; });
  136. };
  137. return TranslationFunctionTransformer;
  138. }());
  139. exports.TranslationFunctionTransformer = TranslationFunctionTransformer;