UNPKG

ngx-i18nsupport-lib

Version:

A Typescript library to work with Angular generated i18n files (xliff, xmb)

490 lines 20.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var parsed_message_part_1 = require("./parsed-message-part"); var parsed_message_part_text_1 = require("./parsed-message-part-text"); var parsed_message_part_placeholder_1 = require("./parsed-message-part-placeholder"); var parsed_message_part_start_tag_1 = require("./parsed-message-part-start-tag"); var parsed_message_part_end_tag_1 = require("./parsed-message-part-end-tag"); var dom_utilities_1 = require("./dom-utilities"); var util_1 = require("util"); var parsed_message_part_icu_message_1 = require("./parsed-message-part-icu-message"); var parsed_message_part_icu_message_ref_1 = require("./parsed-message-part-icu-message-ref"); var parsed_message_part_empty_tag_1 = require("./parsed-message-part-empty-tag"); /** * Created by martin on 05.05.2017. * A message text read from a translation file. * Can contain placeholders, tags, text. * This class is a representation independent of the concrete format. */ var ParsedMessage = /** @class */ (function () { function ParsedMessage(parser, sourceMessage) { this._parser = parser; this.sourceMessage = sourceMessage; this._parts = []; } /** * Get the parser (for tests only, not part of API) * @return {IMessageParser} */ ParsedMessage.prototype.getParser = function () { return this._parser; }; /** * Create a new normalized message as a translation of this one. * @param normalizedString the translation in normalized form. * If the message is an ICUMessage (getICUMessage returns a value), use translateICUMessage instead. * @throws an error if normalized string is not well formed. * Throws an error too, if this is an ICU message. */ ParsedMessage.prototype.translate = function (normalizedString) { if (util_1.isNullOrUndefined(this.getICUMessage())) { return this._parser.parseNormalizedString(normalizedString, this); } else { throw new Error(util_1.format('cannot translate ICU message with simple string, use translateICUMessage() instead ("%s", "%s")', normalizedString, this.asNativeString())); } }; /** * Create a new normalized icu message as a translation of this one. * @param icuTranslation the translation, this is the translation of the ICU message, * which is not a string, but a collections of the translations of the different categories. * The message must be an ICUMessage (getICUMessage returns a value) * @throws an error if normalized string is not well formed. * Throws an error too, if this is not an ICU message. */ ParsedMessage.prototype.translateICUMessage = function (icuTranslation) { var icuMessage = this.getICUMessage(); if (util_1.isNullOrUndefined(icuMessage)) { throw new Error(util_1.format('this is not an ICU message, use translate() instead ("%s", "%s")', icuTranslation, this.asNativeString())); } else { var translatedICUMessage = icuMessage.translate(icuTranslation); return this._parser.parseICUMessage(translatedICUMessage.asNativeString(), this); } }; /** * Create a new normalized message from a native xml string as a translation of this one. * @param nativeString xml string in the format of the underlying file format. * Throws an error if native string is not acceptable. */ ParsedMessage.prototype.translateNativeString = function (nativeString) { return this._parser.createNormalizedMessageFromXMLString(nativeString, this); }; /** * normalized message as string. * @param format optional way to determine the exact syntax. * Allowed formats are defined as constants NORMALIZATION_FORMAT... */ ParsedMessage.prototype.asDisplayString = function (format) { return this._parts.map(function (part) { return part.asDisplayString(format); }).join(''); }; /** * Returns the message content as format dependent native string. * Includes all format specific markup like <ph id="INTERPOLATION" ../> .. */ ParsedMessage.prototype.asNativeString = function () { if (util_1.isNullOrUndefined(this.getICUMessage())) { return dom_utilities_1.DOMUtilities.getXMLContent(this._xmlRepresentation); } else { return this.getICUMessage().asNativeString(); } }; /** * Validate the message. * @return null, if ok, error object otherwise. */ ParsedMessage.prototype.validate = function () { var hasErrors = false; var errors = {}; var e; e = this.checkPlaceholderAdded(); if (!util_1.isNullOrUndefined(e)) { errors.placeholderAdded = e; hasErrors = true; } e = this.checkICUMessageRefRemoved(); if (!util_1.isNullOrUndefined(e)) { errors.icuMessageRefRemoved = e; hasErrors = true; } e = this.checkICUMessageRefAdded(); if (!util_1.isNullOrUndefined(e)) { errors.icuMessageRefAdded = e; hasErrors = true; } return hasErrors ? errors : null; }; /** * Validate the message, check for warnings only. * A warning shows, that the message is acceptable, but misses something. * E.g. if you remove a placeholder or a special tag from the original message, this generates a warning. * @return null, if no warning, warnings as error object otherwise. */ ParsedMessage.prototype.validateWarnings = function () { var hasWarnings = false; var warnings = {}; var w; w = this.checkPlaceholderRemoved(); if (!util_1.isNullOrUndefined(w)) { warnings.placeholderRemoved = w; hasWarnings = true; } w = this.checkTagRemoved(); if (!util_1.isNullOrUndefined(w)) { warnings.tagRemoved = w; hasWarnings = true; } w = this.checkTagAdded(); if (!util_1.isNullOrUndefined(w)) { warnings.tagAdded = w; hasWarnings = true; } return hasWarnings ? warnings : null; }; /** * If this message is an ICU message, returns its structure. * Otherwise this method returns null. * @return ICUMessage or null. */ ParsedMessage.prototype.getICUMessage = function () { if (this._parts.length === 1 && this._parts[0].type === parsed_message_part_1.ParsedMessagePartType.ICU_MESSAGE) { var icuPart = this._parts[0]; return icuPart.getICUMessage(); } else { return null; } }; /** * Check for added placeholder. * @return null or message, if fulfilled. */ ParsedMessage.prototype.checkPlaceholderAdded = function () { var e = null; var suspiciousIndexes = []; if (this.sourceMessage) { var sourcePlaceholders_1 = this.sourceMessage.allPlaceholders(); var myPlaceholders = this.allPlaceholders(); myPlaceholders.forEach(function (index) { if (!sourcePlaceholders_1.has(index)) { suspiciousIndexes.push(index); } }); } if (suspiciousIndexes.length === 1) { e = 'added placeholder ' + suspiciousIndexes[0] + ', which is not in original message'; } else if (suspiciousIndexes.length > 1) { var allSuspiciousIndexes_1 = ''; var first_1 = true; suspiciousIndexes.forEach(function (index) { if (!first_1) { allSuspiciousIndexes_1 = allSuspiciousIndexes_1 + ', '; } allSuspiciousIndexes_1 = allSuspiciousIndexes_1 + index; first_1 = false; }); e = 'added placeholders ' + allSuspiciousIndexes_1 + ', which are not in original message'; } return e; }; /** * Check for removed placeholder. * @return null or message, if fulfilled. */ ParsedMessage.prototype.checkPlaceholderRemoved = function () { var w = null; var suspiciousIndexes = []; if (this.sourceMessage) { var sourcePlaceholders = this.sourceMessage.allPlaceholders(); var myPlaceholders_1 = this.allPlaceholders(); sourcePlaceholders.forEach(function (index) { if (!myPlaceholders_1.has(index)) { suspiciousIndexes.push(index); } }); } if (suspiciousIndexes.length === 1) { w = 'removed placeholder ' + suspiciousIndexes[0] + ' from original message'; } else if (suspiciousIndexes.length > 1) { var allSuspiciousIndexes_2 = ''; var first_2 = true; suspiciousIndexes.forEach(function (index) { if (!first_2) { allSuspiciousIndexes_2 = allSuspiciousIndexes_2 + ', '; } allSuspiciousIndexes_2 = allSuspiciousIndexes_2 + index; first_2 = false; }); w = 'removed placeholders ' + allSuspiciousIndexes_2 + ' from original message'; } return w; }; /** * Check for added ICU Message Refs. * @return null or message, if fulfilled. */ ParsedMessage.prototype.checkICUMessageRefAdded = function () { var e = null; var suspiciousIndexes = []; if (this.sourceMessage) { var sourceICURefs_1 = this.sourceMessage.allICUMessageRefs(); var myICURefs = this.allICUMessageRefs(); myICURefs.forEach(function (index) { if (!sourceICURefs_1.has(index)) { suspiciousIndexes.push(index); } }); } if (suspiciousIndexes.length === 1) { e = 'added ICU message reference ' + suspiciousIndexes[0] + ', which is not in original message'; } else if (suspiciousIndexes.length > 1) { var allSuspiciousIndexes_3 = ''; var first_3 = true; suspiciousIndexes.forEach(function (index) { if (!first_3) { allSuspiciousIndexes_3 = allSuspiciousIndexes_3 + ', '; } allSuspiciousIndexes_3 = allSuspiciousIndexes_3 + index; first_3 = false; }); e = 'added ICU message references ' + allSuspiciousIndexes_3 + ', which are not in original message'; } return e; }; /** * Check for removed ICU Message Refs. * @return null or message, if fulfilled. */ ParsedMessage.prototype.checkICUMessageRefRemoved = function () { var e = null; var suspiciousIndexes = []; if (this.sourceMessage) { var sourceICURefs = this.sourceMessage.allICUMessageRefs(); var myICURefs_1 = this.allICUMessageRefs(); sourceICURefs.forEach(function (index) { if (!myICURefs_1.has(index)) { suspiciousIndexes.push(index); } }); } if (suspiciousIndexes.length === 1) { e = 'removed ICU message reference ' + suspiciousIndexes[0] + ' from original message'; } else if (suspiciousIndexes.length > 1) { var allSuspiciousIndexes_4 = ''; var first_4 = true; suspiciousIndexes.forEach(function (index) { if (!first_4) { allSuspiciousIndexes_4 = allSuspiciousIndexes_4 + ', '; } allSuspiciousIndexes_4 = allSuspiciousIndexes_4 + index; first_4 = false; }); e = 'removed ICU message references ' + allSuspiciousIndexes_4 + ' from original message'; } return e; }; /** * Get all indexes of placeholders used in the message. */ ParsedMessage.prototype.allPlaceholders = function () { var result = new Set(); this.parts().forEach(function (part) { if (part.type === parsed_message_part_1.ParsedMessagePartType.PLACEHOLDER) { var index = part.index(); result.add(index); } }); return result; }; /** * Return the disp-Attribute of placeholder * @param {number} index of placeholder * @return {string} disp or null */ ParsedMessage.prototype.getPlaceholderDisp = function (index) { var placeHolder = null; this.parts().forEach(function (part) { if (part.type === parsed_message_part_1.ParsedMessagePartType.PLACEHOLDER) { var phPart = part; if (phPart.index() === index) { placeHolder = phPart; } } }); return placeHolder ? placeHolder.disp() : null; }; /** * Get all indexes of ICU message refs used in the message. */ ParsedMessage.prototype.allICUMessageRefs = function () { var result = new Set(); this.parts().forEach(function (part) { if (part.type === parsed_message_part_1.ParsedMessagePartType.ICU_MESSAGE_REF) { var index = part.index(); result.add(index); } }); return result; }; /** * Return the disp-Attribute of icu message ref * @param {number} index of ref * @return {string} disp or null */ ParsedMessage.prototype.getICUMessageRefDisp = function (index) { var icuMessageRefPart = null; this.parts().forEach(function (part) { if (part.type === parsed_message_part_1.ParsedMessagePartType.ICU_MESSAGE_REF) { var refPart = part; if (refPart.index() === index) { icuMessageRefPart = refPart; } } }); return icuMessageRefPart ? icuMessageRefPart.disp() : null; }; /** * Check for added tags. * @return null or message, if fulfilled. */ ParsedMessage.prototype.checkTagAdded = function () { var e = null; var suspiciousTags = []; if (this.sourceMessage) { var sourceTags_1 = this.sourceMessage.allTags(); var myTags = this.allTags(); myTags.forEach(function (tagName) { if (!sourceTags_1.has(tagName)) { suspiciousTags.push(tagName); } }); } if (suspiciousTags.length === 1) { e = 'added tag <' + suspiciousTags[0] + '>, which is not in original message'; } else if (suspiciousTags.length > 1) { var allSuspiciousTags_1 = ''; var first_5 = true; suspiciousTags.forEach(function (tag) { if (!first_5) { allSuspiciousTags_1 = allSuspiciousTags_1 + ', '; } allSuspiciousTags_1 = allSuspiciousTags_1 + '<' + tag + '>'; first_5 = false; }); e = 'added tags ' + allSuspiciousTags_1 + ', which are not in original message'; } return e; }; /** * Check for removed tags. * @return null or message, if fulfilled. */ ParsedMessage.prototype.checkTagRemoved = function () { var w = null; var suspiciousTags = []; if (this.sourceMessage) { var sourceTags = this.sourceMessage.allTags(); var myTags_1 = this.allTags(); sourceTags.forEach(function (tagName) { if (!myTags_1.has(tagName)) { suspiciousTags.push(tagName); } }); } if (suspiciousTags.length === 1) { w = 'removed tag <' + suspiciousTags[0] + '> from original message'; } else if (suspiciousTags.length > 1) { var allSuspiciousTags_2 = ''; var first_6 = true; suspiciousTags.forEach(function (tag) { if (!first_6) { allSuspiciousTags_2 = allSuspiciousTags_2 + ', '; } allSuspiciousTags_2 = allSuspiciousTags_2 + '<' + tag + '>'; first_6 = false; }); w = 'removed tags ' + allSuspiciousTags_2 + ' from original message'; } return w; }; /** * Get all tag names used in the message. */ ParsedMessage.prototype.allTags = function () { var result = new Set(); this.parts().forEach(function (part) { if (part.type === parsed_message_part_1.ParsedMessagePartType.START_TAG || part.type === parsed_message_part_1.ParsedMessagePartType.EMPTY_TAG) { var tagName = part.tagName(); result.add(tagName); } }); return result; }; ParsedMessage.prototype.parts = function () { return this._parts; }; ParsedMessage.prototype.setXmlRepresentation = function (xmlRepresentation) { this._xmlRepresentation = xmlRepresentation; }; ParsedMessage.prototype.addText = function (text) { this._parts.push(new parsed_message_part_text_1.ParsedMessagePartText(text)); }; ParsedMessage.prototype.addPlaceholder = function (index, disp) { this._parts.push(new parsed_message_part_placeholder_1.ParsedMessagePartPlaceholder(index, disp)); }; ParsedMessage.prototype.addStartTag = function (tagname, idcounter) { this._parts.push(new parsed_message_part_start_tag_1.ParsedMessagePartStartTag(tagname, idcounter)); }; ParsedMessage.prototype.addEndTag = function (tagname) { // check if well formed var openTag = this.calculateOpenTagName(); if (!openTag || openTag !== tagname) { // oops, not well formed throw new Error(util_1.format('unexpected close tag %s (currently open is %s, native xml is "%s")', tagname, openTag, this.asNativeString())); } this._parts.push(new parsed_message_part_end_tag_1.ParsedMessagePartEndTag(tagname)); }; ParsedMessage.prototype.addEmptyTag = function (tagname, idcounter) { this._parts.push(new parsed_message_part_empty_tag_1.ParsedMessagePartEmptyTag(tagname, idcounter)); }; ParsedMessage.prototype.addICUMessageRef = function (index, disp) { this._parts.push(new parsed_message_part_icu_message_ref_1.ParsedMessagePartICUMessageRef(index, disp)); }; ParsedMessage.prototype.addICUMessage = function (text) { this._parts.push(new parsed_message_part_icu_message_1.ParsedMessagePartICUMessage(text, this._parser)); }; /** * Determine, wether there is an open tag, that is not closed. * Returns the latest one or null, if there is no open tag. */ ParsedMessage.prototype.calculateOpenTagName = function () { var _this = this; var openTags = []; this._parts.forEach(function (part) { switch (part.type) { case parsed_message_part_1.ParsedMessagePartType.START_TAG: openTags.push(part.tagName()); break; case parsed_message_part_1.ParsedMessagePartType.END_TAG: var tagName = part.tagName(); if (openTags.length === 0 || openTags[openTags.length - 1] !== tagName) { // oops, not well formed var openTag = (openTags.length === 0) ? 'nothing' : openTags[openTags.length - 1]; throw new Error(util_1.format('unexpected close tag %s (currently open is %s, native xml is "%s")', tagName, openTag, _this.asNativeString())); } openTags.pop(); } }); return openTags.length === 0 ? null : openTags[openTags.length - 1]; }; return ParsedMessage; }()); exports.ParsedMessage = ParsedMessage; //# sourceMappingURL=S:/experimente/ngx-i18nsupport-lib/src/impl/parsed-message.js.map