import { ITranslationMessagesFileFactory } from '../api/i-translation-messages-file-factory' ; import { ITranslationMessagesFile } from '../api/i-translation-messages-file' ; import { ITransUnit } from '../api/i-trans-unit' ; import { FORMAT_XTB , FILETYPE_XTB , FORMAT_XMB } from '../api/constants' ; import { format } from 'util' ; import { DOMUtilities } from './dom-utilities' ; import { AbstractTranslationMessagesFile } from './abstract-translation-messages-file' ; import { XtbTransUnit } from './xtb-trans-unit' ; import { AbstractTransUnit } from './abstract-trans-unit' ; /**
 * Created by martin on 23.05.2017.
 * xtb-File access.
 * xtb is the translated counterpart to xmb.
 */ export class XtbFile extends AbstractTranslationMessagesFile implements ITranslationMessagesFile { private _masterFile : ITranslationMessagesFile ; param _translationMessageFileFactory param xmlString param path param encoding param optionalMaster return constructor ( private _translationMessageFileFactory , xmlString , path , encoding , optionalMaster ? ) { super ( ) ; this . _warnings = [ ] ; this . _numberOfTransUnitsWithMissingId = 0 ; this . initializeFromContent ( xmlString , path , encoding , optionalMaster ) ; } private initializeFromContent ( xmlString , path , encoding , optionalMaster ? ) { this . parseContent ( xmlString , path , encoding ) ; if ( this . _parsedDocument . getElementsByTagName ( 'translationbundle' ) . length !== 1 ) { throw new Error ( format ( 'File "%s" seems to be no xtb file (should contain a translationbundle element)' , path ) ) ; } if ( optionalMaster ) { try { this . _masterFile = this . _translationMessageFileFactory . createFileFromFileContent ( FORMAT_XMB , optionalMaster . xmlContent , optionalMaster . path , optionalMaster . encoding ) ; const numberInMaster = this . _masterFile . numberOfTransUnits ( ) ; const myNumber = this . numberOfTransUnits ( ) ; if ( numberInMaster !== myNumber ) { this . _warnings . push ( format ( '%s trans units found in master, but this file has %s. Check if it is the correct master' , numberInMaster , myNumber ) ) ; } } catch ( error ) { throw new Error ( format ( 'File "%s" seems to be no xmb file. An xtb file needs xmb as master file.' , optionalMaster . path ) ) ; } } return this ; } protected initializeTransUnits ( ) { this . transUnits = [ ] ; const transUnitsInFile = this . _parsedDocument . getElementsByTagName ( 'translation' ) ; for ( let i = 0 ; i < transUnitsInFile . length ; i ++ ) { const msg = transUnitsInFile . item ( i ) ; const id = msg . getAttribute ( 'id' ) ; if ( ! id ) { this . _warnings . push ( format ( 'oops, msg without "id" found in master, please check file %s' , this . _filename ) ) ; } let masterUnit = null ; if ( this . _masterFile ) { masterUnit = this . _masterFile . transUnitWithId ( id ) ; } this . transUnits . push ( new XtbTransUnit ( msg , id , this , < AbstractTransUnit > masterUnit ) ) ; } } /**
     * File format as it is used in config files.
     * Currently 'xlf', 'xlf2', 'xmb', 'xtb'
     * Returns one of the constants FORMAT_..
     */ public i18nFormat ( ) { return FORMAT_XTB ; } /**
     * File type.
     * Here 'XTB'
     */ public fileType ( ) { return FILETYPE_XTB ; } /**
     * return tag names of all elements that have mixed content.
     * These elements will not be beautified.
     * Typical candidates are source and target.
     */ protected elementsWithMixedContent ( ) { return [ 'translation' ] ; } return public sourceLanguage ( ) { if ( this . _masterFile ) { return this . _masterFile . sourceLanguage ( ) ; } else { return null ; } } param language public setSourceLanguage ( language ) { } return public targetLanguage ( ) { const translationbundleElem = DOMUtilities . getFirstElementByTagName ( this . _parsedDocument , 'translationbundle' ) ; if ( translationbundleElem ) { return translationbundleElem . getAttribute ( 'lang' ) ; } else { return null ; } } param language public setTargetLanguage ( language ) { const translationbundleElem = DOMUtilities . getFirstElementByTagName ( this . _parsedDocument , 'translationbundle' ) ; if ( translationbundleElem ) { translationbundleElem . setAttribute ( 'lang' , language ) ; } } param foreignTransUnit param isDefaultLang param copyContent param importAfterElement return throws importNewTransUnit ( foreignTransUnit , isDefaultLang , copyContent , importAfterElement ? ) { if ( this . transUnitWithId ( foreignTransUnit . id ) ) { throw new Error ( format ( 'tu with id %s already exists in file, cannot import it' , foreignTransUnit . id ) ) ; } const newMasterTu = ( < AbstractTransUnit > foreignTransUnit ) . cloneWithSourceAsTarget ( isDefaultLang , copyContent , this ) ; const translationbundleElem = DOMUtilities . getFirstElementByTagName ( this . _parsedDocument , 'translationbundle' ) ; if ( ! translationbundleElem ) { throw new Error ( format ( 'File "%s" seems to be no xtb file (should contain a translationbundle element)' , this . _filename ) ) ; } const translationElement = translationbundleElem . ownerDocument . createElement ( 'translation' ) ; translationElement . setAttribute ( 'id' , foreignTransUnit . id ) ; let newContent = ( copyContent || isDefaultLang ) ? foreignTransUnit . sourceContent ( ) : '' ; if ( ! ( < AbstractTransUnit > foreignTransUnit ) . isICUMessage ( newContent ) ) { newContent = this . getNewTransUnitTargetPraefix ( ) + newContent + this . getNewTransUnitTargetSuffix ( ) ; } DOMUtilities . replaceContentWithXMLContent ( translationElement , newContent ) ; const newTu = new XtbTransUnit ( translationElement , foreignTransUnit . id , this , newMasterTu ) ; let inserted = false ; let isAfterElementPartOfFile = false ; if ( ! ! importAfterElement ) { const insertionPoint = this . transUnitWithId ( importAfterElement . id ) ; if ( ! ! insertionPoint ) { isAfterElementPartOfFile = true ; } } if ( importAfterElement === undefined || ( importAfterElement && ! isAfterElementPartOfFile ) ) { translationbundleElem . appendChild ( newTu . asXmlElement ( ) ) ; inserted = true ; } else if ( importAfterElement === null ) { const firstTranslationElement = DOMUtilities . getFirstElementByTagName ( this . _parsedDocument , 'translation' ) ; if ( firstTranslationElement ) { DOMUtilities . insertBefore ( newTu . asXmlElement ( ) , firstTranslationElement ) ; inserted = true ; } else { translationbundleElem . appendChild ( newTu . asXmlElement ( ) ) ; inserted = true ; } } else { const refUnitElement = DOMUtilities . getElementByTagNameAndId ( this . _parsedDocument , 'translation' , importAfterElement . id ) ; if ( refUnitElement ) { DOMUtilities . insertAfter ( newTu . asXmlElement ( ) , refUnitElement ) ; inserted = true ; } } if ( inserted ) { this . lazyInitializeTransUnits ( ) ; this . transUnits . push ( newTu ) ; this . countNumbers ( ) ; return newTu ; } else { return null ; } } param lang param filename param isDefaultLang param copyContent public createTranslationFileForLang ( lang , filename , isDefaultLang , copyContent ) { throw new Error ( format ( 'File "%s", xtb files are not translatable, they are already translations' , filename ) ) ; } }