ztxkutils 2.10.66-15 → 2.10.66-16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/{request-ba8abf99.js → request-588c90ec.js} +92 -18
- package/dist/{request-0cc024b1.js → request-dc69f021.js} +68 -13
- package/dist/request.js +1 -1
- package/package.json +1 -1
- package/zti18n-cli/bin/index.js +3 -3
- package/zti18n-cli/index.js +23 -23
- package/zti18n-cli/src/command/convert.js +17 -17
- package/zti18n-cli/src/command/convert2.js +35 -35
- package/zti18n-cli/src/command/initFileConf.js +133 -133
- package/zti18n-cli/src/command/publish.js +24 -24
- package/zti18n-cli/src/conf/BaseConf.js +21 -21
- package/zti18n-cli/src/conf/FileConf.js +116 -116
- package/zti18n-cli/src/index.js +75 -75
- package/zti18n-cli/src/translate/google.js +6 -6
- package/zti18n-cli/src/utils/isChinese.js +3 -3
- package/zti18n-cli/src/utils/log.js +8 -8
- package/zti18n-cli/src/utils/mergeOptions.js +45 -45
- package/zti18n-cli/src/utils/reactOptions.js +73 -73
- package/zti18n-cli/src/utils/vueOptions.js +69 -69
- package/zti18n-core/index.js +1 -1
- package/zti18n-core/src/index.js +5 -5
- package/zti18n-core/src/plugin/reactIntlToReactIntlUniversal.js +224 -224
- package/zti18n-core/src/plugin/reactIntlUniversalToDi18n.js +64 -64
- package/zti18n-core/src/transform/defaultPkMap.js +79 -79
- package/zti18n-core/src/transform/transformHtml.js +271 -271
- package/zti18n-core/src/transform/transformPug.js +272 -272
- package/zti18n-core/src/transform/transformReactIntlToReactIntlUniversal.js +96 -96
- package/zti18n-core/src/transform/transformReactIntlUniveralToDi18n.js +90 -90
- package/zti18n-core/src/transform/transformToDi18n.js +22 -22
- package/zti18n-core/src/transform/transformTs.js +41 -41
- package/zti18n-core/src/transform/transformVue.js +126 -126
- package/zti18n-core/src/translate/google.js +6 -6
- package/zti18n-core/src/utils/constants.js +3 -3
- package/zti18n-core/src/utils/getIgnoreLines.js +14 -14
- package/zti18n-core/src/utils/isChinese.js +3 -3
- package/zti18n-core/src/utils/log.js +8 -8
- package/dist/authority-e6bde99f.js +0 -423
- package/dist/reqUrl-3792afcd.js +0 -82
- package/dist/reqUrl-787dd9e5.js +0 -82
- package/dist/request-ef290b9a.js +0 -2838
- package/dist/tools-09a4d620.js +0 -2445
- package/dist/tools-0ca888cd.js +0 -2473
- package/dist/validate-6e735536.js +0 -79
- package/dist/zti18n-cli/bin/index.d.ts +0 -2
- package/dist/zti18n-cli/index.d.ts +0 -1
- package/dist/zti18n-cli/src/command/collect.d.ts +0 -2
- package/dist/zti18n-cli/src/command/convert.d.ts +0 -2
- package/dist/zti18n-cli/src/command/convert2.d.ts +0 -2
- package/dist/zti18n-cli/src/command/initFileConf.d.ts +0 -2
- package/dist/zti18n-cli/src/command/publish.d.ts +0 -2
- package/dist/zti18n-cli/src/conf/BaseConf.d.ts +0 -8
- package/dist/zti18n-cli/src/conf/FileConf.d.ts +0 -6
- package/dist/zti18n-cli/src/index.d.ts +0 -1
- package/dist/zti18n-cli/src/translate/google.d.ts +0 -2
- package/dist/zti18n-cli/src/utils/isChinese.d.ts +0 -2
- package/dist/zti18n-cli/src/utils/log.d.ts +0 -4
- package/dist/zti18n-cli/src/utils/mergeOptions.d.ts +0 -24
- package/dist/zti18n-cli/src/utils/reactOptions.d.ts +0 -21
- package/dist/zti18n-cli/src/utils/vueOptions.d.ts +0 -17
- package/dist/zti18n-core/index.d.ts +0 -2
- package/dist/zti18n-core/src/index.d.ts +0 -8
- package/dist/zti18n-core/src/plugin/reactIntlToReactIntlUniversal.d.ts +0 -19
- package/dist/zti18n-core/src/plugin/reactIntlUniversalToDi18n.d.ts +0 -9
- package/dist/zti18n-core/src/transform/defaultPkMap.d.ts +0 -75
- package/dist/zti18n-core/src/transform/transformHtml.d.ts +0 -5
- package/dist/zti18n-core/src/transform/transformJs.d.ts +0 -5
- package/dist/zti18n-core/src/transform/transformPug.d.ts +0 -5
- package/dist/zti18n-core/src/transform/transformReactIntlToReactIntlUniversal.d.ts +0 -2
- package/dist/zti18n-core/src/transform/transformReactIntlUniveralToDi18n.d.ts +0 -2
- package/dist/zti18n-core/src/transform/transformToDi18n.d.ts +0 -5
- package/dist/zti18n-core/src/transform/transformTs.d.ts +0 -5
- package/dist/zti18n-core/src/transform/transformVue.d.ts +0 -5
- package/dist/zti18n-core/src/transform/transformZeroToDi18n.d.ts +0 -2
- package/dist/zti18n-core/src/translate/google.d.ts +0 -2
- package/dist/zti18n-core/src/utils/constants.d.ts +0 -3
- package/dist/zti18n-core/src/utils/getIgnoreLines.d.ts +0 -2
- package/dist/zti18n-core/src/utils/isChinese.d.ts +0 -2
- package/dist/zti18n-core/src/utils/log.d.ts +0 -4
@@ -1,271 +1,271 @@
|
|
1
|
-
const parse5 = require('parse5');
|
2
|
-
const Serializer = require('parse5/lib/serializer');
|
3
|
-
const { NAMESPACES: NS } = require('parse5/lib/common/html');
|
4
|
-
const prettier = require('prettier');
|
5
|
-
const mustache = require('mustache');
|
6
|
-
const transformJs = require('./transformJs');
|
7
|
-
const getIgnoreLines = require('../utils/getIgnoreLines');
|
8
|
-
const defaultPkMap = require('./defaultPkMap');
|
9
|
-
|
10
|
-
class MySerializer extends Serializer {
|
11
|
-
_serializeAttributes(node) {
|
12
|
-
const attrs = this.treeAdapter.getAttrList(node);
|
13
|
-
|
14
|
-
for (let i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
|
15
|
-
const attr = attrs[i];
|
16
|
-
const value = Serializer.escapeString(attr.value, true);
|
17
|
-
|
18
|
-
this.html += ' ';
|
19
|
-
|
20
|
-
if (!attr.namespace) {
|
21
|
-
this.html += attr.name;
|
22
|
-
} else if (attr.namespace === NS.XML) {
|
23
|
-
this.html += 'xml:' + attr.name;
|
24
|
-
} else if (attr.namespace === NS.XMLNS) {
|
25
|
-
if (attr.name !== 'xmlns') {
|
26
|
-
this.html += 'xmlns:';
|
27
|
-
}
|
28
|
-
|
29
|
-
this.html += attr.name;
|
30
|
-
} else if (attr.namespace === NS.XLINK) {
|
31
|
-
this.html += 'xlink:' + attr.name;
|
32
|
-
} else {
|
33
|
-
this.html += attr.prefix + ':' + attr.name;
|
34
|
-
}
|
35
|
-
|
36
|
-
// 避免出现 <p v-else="">xxx</p> 的情况
|
37
|
-
if (value) {
|
38
|
-
this.html += '="' + value + '"';
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
function parse5Serialize(node, options) {
|
45
|
-
const serializer = new MySerializer(node, options);
|
46
|
-
|
47
|
-
return serializer.serialize();
|
48
|
-
}
|
49
|
-
|
50
|
-
function toKebab(tpl, pkMap = {}) {
|
51
|
-
pkMap = { ...defaultPkMap, ...pkMap };
|
52
|
-
|
53
|
-
Object.keys(pkMap).forEach((i) => {
|
54
|
-
tpl = tpl
|
55
|
-
.replace(new RegExp(`<${i}(?![a-zA-Z0-9-])`, 'g'), `<${pkMap[i]}`)
|
56
|
-
.replace(new RegExp(`</${i}>`, 'g'), `</${pkMap[i]}>`);
|
57
|
-
});
|
58
|
-
return tpl;
|
59
|
-
}
|
60
|
-
|
61
|
-
function toPascal(tpl, pkMap = {}) {
|
62
|
-
pkMap = { ...defaultPkMap, ...pkMap };
|
63
|
-
|
64
|
-
Object.keys(pkMap).forEach((i) => {
|
65
|
-
tpl = tpl
|
66
|
-
.replace(new RegExp(`<${pkMap[i]}(?![a-zA-Z0-9-])`, 'g'), `<${i}`)
|
67
|
-
.replace(new RegExp(`</${pkMap[i]}>`, 'g'), `</${i}>`);
|
68
|
-
});
|
69
|
-
return tpl;
|
70
|
-
}
|
71
|
-
|
72
|
-
function traverseHtml(ast, { primaryRegx, i18nMethod, ignoreLines }, returns) {
|
73
|
-
const { allTranslated, allUpdated, allUsedKeys } = returns;
|
74
|
-
const existValues = Object.keys(allTranslated);
|
75
|
-
|
76
|
-
function shouldIgnore(node) {
|
77
|
-
return (
|
78
|
-
node.sourceCodeLocation &&
|
79
|
-
ignoreLines.includes(node.sourceCodeLocation.startLine)
|
80
|
-
);
|
81
|
-
}
|
82
|
-
|
83
|
-
function isPrimary(str) {
|
84
|
-
return primaryRegx.test(str);
|
85
|
-
}
|
86
|
-
|
87
|
-
function formatValue(value) {
|
88
|
-
// 去掉首尾空白字符,中间的连续空白字符替换成一个空格
|
89
|
-
value = value.trim().replace(/\s+/g, ' ');
|
90
|
-
|
91
|
-
// 去掉首尾引号
|
92
|
-
if (['"', "'"].includes(value.charAt(0))) {
|
93
|
-
value = value.substring(1, value.length - 1);
|
94
|
-
}
|
95
|
-
|
96
|
-
return value;
|
97
|
-
}
|
98
|
-
|
99
|
-
// 更新2个 `all*` 数组
|
100
|
-
function updateLocaleInfo(key, value) {
|
101
|
-
if (!Array.isArray(allTranslated[value])) {
|
102
|
-
// 如果该文字没有存在于已翻译列表
|
103
|
-
allTranslated[value] = [key];
|
104
|
-
existValues.push(key);
|
105
|
-
}
|
106
|
-
|
107
|
-
if (!allUsedKeys.includes(key)) {
|
108
|
-
allUsedKeys.push(key);
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
function transformJsExpression(source) {
|
113
|
-
const { source: source1, hasTouch } = transformJs(
|
114
|
-
source,
|
115
|
-
{
|
116
|
-
allTranslated,
|
117
|
-
allUpdated,
|
118
|
-
allUsedKeys,
|
119
|
-
},
|
120
|
-
{
|
121
|
-
primaryRegx,
|
122
|
-
i18nObject: '',
|
123
|
-
i18nMethod,
|
124
|
-
importCode: '',
|
125
|
-
}
|
126
|
-
);
|
127
|
-
|
128
|
-
if (!hasTouch) return source;
|
129
|
-
|
130
|
-
return prettier
|
131
|
-
.format(source1, {
|
132
|
-
parser: 'babel',
|
133
|
-
singleQuote: true,
|
134
|
-
semi: false,
|
135
|
-
})
|
136
|
-
.trim();
|
137
|
-
}
|
138
|
-
|
139
|
-
function traverse(node) {
|
140
|
-
if (node.childNodes) {
|
141
|
-
node.childNodes.forEach((childNode) => traverse(childNode));
|
142
|
-
}
|
143
|
-
|
144
|
-
// 处理属性
|
145
|
-
if (!shouldIgnore(node) && node.attrs) {
|
146
|
-
node.attrs.forEach((attr) => {
|
147
|
-
const { name, value } = attr;
|
148
|
-
|
149
|
-
// 非主语言或空,跳过
|
150
|
-
if (!isPrimary(value) || !value) return;
|
151
|
-
|
152
|
-
if (
|
153
|
-
name.startsWith('v-') ||
|
154
|
-
name.startsWith(':') ||
|
155
|
-
name.startsWith('@')
|
156
|
-
) {
|
157
|
-
// vue 指令
|
158
|
-
// 引号里是 js 表达式,直接调用 transformJs 来转换
|
159
|
-
const source = transformJsExpression(value);
|
160
|
-
|
161
|
-
if (value !== source) {
|
162
|
-
attr.value = source;
|
163
|
-
returns.hasTouch = true;
|
164
|
-
}
|
165
|
-
} else {
|
166
|
-
// 普通属性(不考虑事件)
|
167
|
-
let key = formatValue(value);
|
168
|
-
|
169
|
-
if (allUpdated.hasOwnProperty(key)) {
|
170
|
-
key = allUpdated[key];
|
171
|
-
}
|
172
|
-
|
173
|
-
attr.value = `${i18nMethod}('${key}')`;
|
174
|
-
attr.name = `:${name}`;
|
175
|
-
returns.hasTouch = true;
|
176
|
-
|
177
|
-
updateLocaleInfo(key, key);
|
178
|
-
}
|
179
|
-
});
|
180
|
-
}
|
181
|
-
|
182
|
-
// 处理 innerText
|
183
|
-
if (!shouldIgnore(node) && node.nodeName === '#text') {
|
184
|
-
if (!isPrimary(node.value)) return;
|
185
|
-
|
186
|
-
let value = '';
|
187
|
-
const tokens = mustache.parse(node.value);
|
188
|
-
|
189
|
-
for (const token of tokens) {
|
190
|
-
// token 结构:[类型(text|name), 值, 起始位置(包含), 终止位置(不包含)]
|
191
|
-
if (!isPrimary(token[1])) {
|
192
|
-
if (token[0] === 'text') value += token[1];
|
193
|
-
else if (token[0] === 'name') value += `{{${token[1]}}}`;
|
194
|
-
} else {
|
195
|
-
if (token[0] === 'text') {
|
196
|
-
const key = token[1].trim();
|
197
|
-
value += `{{${i18nMethod}('${key}')}}`;
|
198
|
-
|
199
|
-
updateLocaleInfo(key, key);
|
200
|
-
} else if (token[0] === 'name') {
|
201
|
-
value += `{{${transformJsExpression(token[1])}}}`;
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
|
206
|
-
if (node.value !== value) {
|
207
|
-
node.value = value;
|
208
|
-
returns.hasTouch = true;
|
209
|
-
}
|
210
|
-
}
|
211
|
-
}
|
212
|
-
|
213
|
-
// 可能有 #comment 节点,需要找到 html 节点
|
214
|
-
const html = ast.childNodes.find((nd) => nd.nodeName === 'html');
|
215
|
-
|
216
|
-
if (html) {
|
217
|
-
// 再找 body 节点
|
218
|
-
const body = html.childNodes.find((nd) => nd.nodeName === 'body');
|
219
|
-
|
220
|
-
// 遍历
|
221
|
-
if (body) traverse(body);
|
222
|
-
}
|
223
|
-
}
|
224
|
-
|
225
|
-
module.exports = function transformHtml(source, localeInfo = {}, options = {}) {
|
226
|
-
const { allTranslated = {}, allUpdated = {}, allUsedKeys = [] } = localeInfo;
|
227
|
-
|
228
|
-
const {
|
229
|
-
primaryRegx = /[\u4e00-\u9fa5]/,
|
230
|
-
i18nMethod = '$t',
|
231
|
-
pkMap = {},
|
232
|
-
|
233
|
-
/* 以下暂时不需要
|
234
|
-
i18nObject = '',
|
235
|
-
importCode = '',
|
236
|
-
babelPresets = [],
|
237
|
-
babelPlugins = [],
|
238
|
-
ignoreComponents = [],
|
239
|
-
ignoreMethods = [],
|
240
|
-
以上暂时不需要 */
|
241
|
-
} = options;
|
242
|
-
|
243
|
-
const opts = {
|
244
|
-
primaryRegx,
|
245
|
-
i18nMethod,
|
246
|
-
ignoreLines: [],
|
247
|
-
};
|
248
|
-
|
249
|
-
const r = {
|
250
|
-
allTranslated,
|
251
|
-
allUpdated,
|
252
|
-
allUsedKeys,
|
253
|
-
hasTouch: false,
|
254
|
-
};
|
255
|
-
|
256
|
-
opts.ignoreLines = getIgnoreLines(source);
|
257
|
-
|
258
|
-
const ast = parse5.parse(toKebab(source, pkMap), {
|
259
|
-
sourceCodeLocationInfo: true,
|
260
|
-
});
|
261
|
-
traverseHtml(ast, opts, r);
|
262
|
-
|
263
|
-
let code = toPascal(parse5Serialize(ast), pkMap);
|
264
|
-
|
265
|
-
// 只需要 body 内的
|
266
|
-
code = code.split('<body>')[1].split('</body>')[0];
|
267
|
-
|
268
|
-
code = r.hasTouch ? code : source;
|
269
|
-
|
270
|
-
return { source: code, hasTouch: r.hasTouch };
|
271
|
-
};
|
1
|
+
const parse5 = require('parse5');
|
2
|
+
const Serializer = require('parse5/lib/serializer');
|
3
|
+
const { NAMESPACES: NS } = require('parse5/lib/common/html');
|
4
|
+
const prettier = require('prettier');
|
5
|
+
const mustache = require('mustache');
|
6
|
+
const transformJs = require('./transformJs');
|
7
|
+
const getIgnoreLines = require('../utils/getIgnoreLines');
|
8
|
+
const defaultPkMap = require('./defaultPkMap');
|
9
|
+
|
10
|
+
class MySerializer extends Serializer {
|
11
|
+
_serializeAttributes(node) {
|
12
|
+
const attrs = this.treeAdapter.getAttrList(node);
|
13
|
+
|
14
|
+
for (let i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
|
15
|
+
const attr = attrs[i];
|
16
|
+
const value = Serializer.escapeString(attr.value, true);
|
17
|
+
|
18
|
+
this.html += ' ';
|
19
|
+
|
20
|
+
if (!attr.namespace) {
|
21
|
+
this.html += attr.name;
|
22
|
+
} else if (attr.namespace === NS.XML) {
|
23
|
+
this.html += 'xml:' + attr.name;
|
24
|
+
} else if (attr.namespace === NS.XMLNS) {
|
25
|
+
if (attr.name !== 'xmlns') {
|
26
|
+
this.html += 'xmlns:';
|
27
|
+
}
|
28
|
+
|
29
|
+
this.html += attr.name;
|
30
|
+
} else if (attr.namespace === NS.XLINK) {
|
31
|
+
this.html += 'xlink:' + attr.name;
|
32
|
+
} else {
|
33
|
+
this.html += attr.prefix + ':' + attr.name;
|
34
|
+
}
|
35
|
+
|
36
|
+
// 避免出现 <p v-else="">xxx</p> 的情况
|
37
|
+
if (value) {
|
38
|
+
this.html += '="' + value + '"';
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
function parse5Serialize(node, options) {
|
45
|
+
const serializer = new MySerializer(node, options);
|
46
|
+
|
47
|
+
return serializer.serialize();
|
48
|
+
}
|
49
|
+
|
50
|
+
function toKebab(tpl, pkMap = {}) {
|
51
|
+
pkMap = { ...defaultPkMap, ...pkMap };
|
52
|
+
|
53
|
+
Object.keys(pkMap).forEach((i) => {
|
54
|
+
tpl = tpl
|
55
|
+
.replace(new RegExp(`<${i}(?![a-zA-Z0-9-])`, 'g'), `<${pkMap[i]}`)
|
56
|
+
.replace(new RegExp(`</${i}>`, 'g'), `</${pkMap[i]}>`);
|
57
|
+
});
|
58
|
+
return tpl;
|
59
|
+
}
|
60
|
+
|
61
|
+
function toPascal(tpl, pkMap = {}) {
|
62
|
+
pkMap = { ...defaultPkMap, ...pkMap };
|
63
|
+
|
64
|
+
Object.keys(pkMap).forEach((i) => {
|
65
|
+
tpl = tpl
|
66
|
+
.replace(new RegExp(`<${pkMap[i]}(?![a-zA-Z0-9-])`, 'g'), `<${i}`)
|
67
|
+
.replace(new RegExp(`</${pkMap[i]}>`, 'g'), `</${i}>`);
|
68
|
+
});
|
69
|
+
return tpl;
|
70
|
+
}
|
71
|
+
|
72
|
+
function traverseHtml(ast, { primaryRegx, i18nMethod, ignoreLines }, returns) {
|
73
|
+
const { allTranslated, allUpdated, allUsedKeys } = returns;
|
74
|
+
const existValues = Object.keys(allTranslated);
|
75
|
+
|
76
|
+
function shouldIgnore(node) {
|
77
|
+
return (
|
78
|
+
node.sourceCodeLocation &&
|
79
|
+
ignoreLines.includes(node.sourceCodeLocation.startLine)
|
80
|
+
);
|
81
|
+
}
|
82
|
+
|
83
|
+
function isPrimary(str) {
|
84
|
+
return primaryRegx.test(str);
|
85
|
+
}
|
86
|
+
|
87
|
+
function formatValue(value) {
|
88
|
+
// 去掉首尾空白字符,中间的连续空白字符替换成一个空格
|
89
|
+
value = value.trim().replace(/\s+/g, ' ');
|
90
|
+
|
91
|
+
// 去掉首尾引号
|
92
|
+
if (['"', "'"].includes(value.charAt(0))) {
|
93
|
+
value = value.substring(1, value.length - 1);
|
94
|
+
}
|
95
|
+
|
96
|
+
return value;
|
97
|
+
}
|
98
|
+
|
99
|
+
// 更新2个 `all*` 数组
|
100
|
+
function updateLocaleInfo(key, value) {
|
101
|
+
if (!Array.isArray(allTranslated[value])) {
|
102
|
+
// 如果该文字没有存在于已翻译列表
|
103
|
+
allTranslated[value] = [key];
|
104
|
+
existValues.push(key);
|
105
|
+
}
|
106
|
+
|
107
|
+
if (!allUsedKeys.includes(key)) {
|
108
|
+
allUsedKeys.push(key);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
function transformJsExpression(source) {
|
113
|
+
const { source: source1, hasTouch } = transformJs(
|
114
|
+
source,
|
115
|
+
{
|
116
|
+
allTranslated,
|
117
|
+
allUpdated,
|
118
|
+
allUsedKeys,
|
119
|
+
},
|
120
|
+
{
|
121
|
+
primaryRegx,
|
122
|
+
i18nObject: '',
|
123
|
+
i18nMethod,
|
124
|
+
importCode: '',
|
125
|
+
}
|
126
|
+
);
|
127
|
+
|
128
|
+
if (!hasTouch) return source;
|
129
|
+
|
130
|
+
return prettier
|
131
|
+
.format(source1, {
|
132
|
+
parser: 'babel',
|
133
|
+
singleQuote: true,
|
134
|
+
semi: false,
|
135
|
+
})
|
136
|
+
.trim();
|
137
|
+
}
|
138
|
+
|
139
|
+
function traverse(node) {
|
140
|
+
if (node.childNodes) {
|
141
|
+
node.childNodes.forEach((childNode) => traverse(childNode));
|
142
|
+
}
|
143
|
+
|
144
|
+
// 处理属性
|
145
|
+
if (!shouldIgnore(node) && node.attrs) {
|
146
|
+
node.attrs.forEach((attr) => {
|
147
|
+
const { name, value } = attr;
|
148
|
+
|
149
|
+
// 非主语言或空,跳过
|
150
|
+
if (!isPrimary(value) || !value) return;
|
151
|
+
|
152
|
+
if (
|
153
|
+
name.startsWith('v-') ||
|
154
|
+
name.startsWith(':') ||
|
155
|
+
name.startsWith('@')
|
156
|
+
) {
|
157
|
+
// vue 指令
|
158
|
+
// 引号里是 js 表达式,直接调用 transformJs 来转换
|
159
|
+
const source = transformJsExpression(value);
|
160
|
+
|
161
|
+
if (value !== source) {
|
162
|
+
attr.value = source;
|
163
|
+
returns.hasTouch = true;
|
164
|
+
}
|
165
|
+
} else {
|
166
|
+
// 普通属性(不考虑事件)
|
167
|
+
let key = formatValue(value);
|
168
|
+
|
169
|
+
if (allUpdated.hasOwnProperty(key)) {
|
170
|
+
key = allUpdated[key];
|
171
|
+
}
|
172
|
+
|
173
|
+
attr.value = `${i18nMethod}('${key}')`;
|
174
|
+
attr.name = `:${name}`;
|
175
|
+
returns.hasTouch = true;
|
176
|
+
|
177
|
+
updateLocaleInfo(key, key);
|
178
|
+
}
|
179
|
+
});
|
180
|
+
}
|
181
|
+
|
182
|
+
// 处理 innerText
|
183
|
+
if (!shouldIgnore(node) && node.nodeName === '#text') {
|
184
|
+
if (!isPrimary(node.value)) return;
|
185
|
+
|
186
|
+
let value = '';
|
187
|
+
const tokens = mustache.parse(node.value);
|
188
|
+
|
189
|
+
for (const token of tokens) {
|
190
|
+
// token 结构:[类型(text|name), 值, 起始位置(包含), 终止位置(不包含)]
|
191
|
+
if (!isPrimary(token[1])) {
|
192
|
+
if (token[0] === 'text') value += token[1];
|
193
|
+
else if (token[0] === 'name') value += `{{${token[1]}}}`;
|
194
|
+
} else {
|
195
|
+
if (token[0] === 'text') {
|
196
|
+
const key = token[1].trim();
|
197
|
+
value += `{{${i18nMethod}('${key}')}}`;
|
198
|
+
|
199
|
+
updateLocaleInfo(key, key);
|
200
|
+
} else if (token[0] === 'name') {
|
201
|
+
value += `{{${transformJsExpression(token[1])}}}`;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
if (node.value !== value) {
|
207
|
+
node.value = value;
|
208
|
+
returns.hasTouch = true;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
// 可能有 #comment 节点,需要找到 html 节点
|
214
|
+
const html = ast.childNodes.find((nd) => nd.nodeName === 'html');
|
215
|
+
|
216
|
+
if (html) {
|
217
|
+
// 再找 body 节点
|
218
|
+
const body = html.childNodes.find((nd) => nd.nodeName === 'body');
|
219
|
+
|
220
|
+
// 遍历
|
221
|
+
if (body) traverse(body);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
module.exports = function transformHtml(source, localeInfo = {}, options = {}) {
|
226
|
+
const { allTranslated = {}, allUpdated = {}, allUsedKeys = [] } = localeInfo;
|
227
|
+
|
228
|
+
const {
|
229
|
+
primaryRegx = /[\u4e00-\u9fa5]/,
|
230
|
+
i18nMethod = '$t',
|
231
|
+
pkMap = {},
|
232
|
+
|
233
|
+
/* 以下暂时不需要
|
234
|
+
i18nObject = '',
|
235
|
+
importCode = '',
|
236
|
+
babelPresets = [],
|
237
|
+
babelPlugins = [],
|
238
|
+
ignoreComponents = [],
|
239
|
+
ignoreMethods = [],
|
240
|
+
以上暂时不需要 */
|
241
|
+
} = options;
|
242
|
+
|
243
|
+
const opts = {
|
244
|
+
primaryRegx,
|
245
|
+
i18nMethod,
|
246
|
+
ignoreLines: [],
|
247
|
+
};
|
248
|
+
|
249
|
+
const r = {
|
250
|
+
allTranslated,
|
251
|
+
allUpdated,
|
252
|
+
allUsedKeys,
|
253
|
+
hasTouch: false,
|
254
|
+
};
|
255
|
+
|
256
|
+
opts.ignoreLines = getIgnoreLines(source);
|
257
|
+
|
258
|
+
const ast = parse5.parse(toKebab(source, pkMap), {
|
259
|
+
sourceCodeLocationInfo: true,
|
260
|
+
});
|
261
|
+
traverseHtml(ast, opts, r);
|
262
|
+
|
263
|
+
let code = toPascal(parse5Serialize(ast), pkMap);
|
264
|
+
|
265
|
+
// 只需要 body 内的
|
266
|
+
code = code.split('<body>')[1].split('</body>')[0];
|
267
|
+
|
268
|
+
code = r.hasTouch ? code : source;
|
269
|
+
|
270
|
+
return { source: code, hasTouch: r.hasTouch };
|
271
|
+
};
|