@awesome-fe/translate
Version:
Translation utils
152 lines • 6.77 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.HtmlTranslator = void 0;
var abstract_translator_1 = require("./abstract-translator");
var dom_models_1 = require("../dom/parse5/dom-models");
var common_1 = require("../dom/common");
var same_except_whitespace_1 = require("./same-except-whitespace");
var HtmlTranslator = /** @class */ (function (_super) {
__extends(HtmlTranslator, _super);
function HtmlTranslator() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.selectors = dom_models_1.defaultSelectors;
return _this;
}
HtmlTranslator.prototype.parse = function (text, options) {
if (options === void 0) { options = { htmlFragment: true }; }
if (options.htmlFragment) {
return dom_models_1.DomDocumentFragment.parse(text);
}
else {
return dom_models_1.DomDocument.parse(text);
}
};
HtmlTranslator.prototype.serialize = function (doc) {
return doc.toHtml();
};
HtmlTranslator.prototype.translateDoc = function (doc) {
var _this = this;
if (doc instanceof dom_models_1.DomDocument) {
this.translateSentence(doc.title, 'html').then(function (translation) { return doc.title = translation; });
}
this.addWrapperForLi(doc);
var elements = this.selectors
.map(function (selector) { return Array.from(doc.querySelectorAll(selector)); })
.flat().filter(function (node) { var _a; return !((_a = node.previousElementSibling) === null || _a === void 0 ? void 0 : _a.hasAttribute('translation-result')); });
var originals = elements.map(function (it) { return it.innerHTML; });
originals.map(function (original, index) {
return _this.translateSentence(original, 'html').then(function (translation) {
_this.applyTranslation(elements[index], translation);
});
});
return doc;
};
HtmlTranslator.prototype.applyTranslation = function (origin, translation) {
var _a, _b, _c;
if (shouldIgnore(origin)) {
return;
}
// 如果译文和原文相同,则摘除原有的 translation-origin 属性,以免被错误的隐藏
if ((0, same_except_whitespace_1.sameExceptWhitespace)(origin.innerHTML, translation)) {
origin.removeAttribute('translation-origin');
return;
}
var spaces = ((_a = origin.previousSibling()) === null || _a === void 0 ? void 0 : _a.textContent) || '';
var resultNode = new dom_models_1.DomElement(origin.tagName);
resultNode.innerHTML = translation;
(_b = origin.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(resultNode, origin);
if (!spaces.trim()) {
var node = new dom_models_1.DomText(spaces);
(_c = origin.parentNode) === null || _c === void 0 ? void 0 : _c.insertBefore(node, origin);
}
// 交换 id
var id = origin.getAttribute('id');
if (id) {
resultNode.setAttribute('id', id);
origin.removeAttribute('id');
}
resultNode.setAttribute('translation-result', 'on');
origin.setAttribute('translation-origin', 'off');
};
HtmlTranslator.prototype.addWrapperForLi = function (body) {
var li = body.querySelectorAll(function (it) { return it.isTagOf('li', 'td', 'th'); });
li.forEach(function (it) {
it.childNodes = wrapChildren(it);
it.childNodes.forEach(function (child) {
child.parentNode = it;
});
});
};
return HtmlTranslator;
}(abstract_translator_1.AbstractTranslator));
exports.HtmlTranslator = HtmlTranslator;
function getSpacingNode(node, defaultText) {
if (isInlineNode(node) && isBlank(node)) {
node.remove();
return node;
}
else {
return new dom_models_1.DomText(defaultText);
}
}
function addToResult(wrapper, result, leadingSpaces) {
if (wrapper.childNodes.length) {
if (isBlank(wrapper)) {
result.push.apply(result, wrapper.childNodes);
}
else {
var leadingNode = getSpacingNode(wrapper.firstChild, "".concat(leadingSpaces, " "));
var tailingNode = getSpacingNode(wrapper.lastChild, "".concat(leadingSpaces));
result.push(leadingNode);
result.push(wrapper);
result.push(tailingNode);
}
}
}
function wrapChildren(node) {
var _a;
var wrapper = new dom_models_1.DomElement('p');
var result = [];
var leadingSpaces = ((_a = node.previousSibling()) === null || _a === void 0 ? void 0 : _a.textContent) || '';
node.childNodes.forEach(function (value, index) {
// 如果是内联,则收集内联节点
if (isInlineNode(value)) {
wrapper.appendChild(value);
}
else {
// 如果是块,则输出已收集了内联节点的包装,并创建新的包装
addToResult(wrapper, result, leadingSpaces);
wrapper = new dom_models_1.DomElement('p');
wrapper.parentNode = node;
result.push(value);
}
});
addToResult(wrapper, result, leadingSpaces);
return result;
}
function shouldIgnore(element) {
return !!element.querySelector(function (it) { return it.hasAttribute('translation-result'); }) || (0, common_1.containsChinese)(element.textContent);
}
function isInlineNode(value) {
return value instanceof dom_models_1.DomText || (value instanceof dom_models_1.DomElement && value.isTagOf('a', 'em', 'strong', 'span', 'sub', 'sup', 'del', 'code', 'img', 'input', 'br', 'kbd', 'label', 'u', 'i', 'b', 'big', 'small', 'ins', 'strike'));
}
function isBlank(node) {
var _a;
return !((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim());
}
//# sourceMappingURL=html-translator.js.map